Script for Dynamic Display Management with fglrx

From ThinkWiki
Revision as of 00:49, 19 January 2009 by Akw (Talk | contribs) (Category)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

The proprietary fglrx driver from ATI allows dynamic display switching, e.g. to switch to an external display for a presentation. Xorg RandR 1.2 allows the same, but sometimes the newer version is not available, or not compatible e.g. when the proprietary ATI driver needs to be used for some reasons. The current version of it does not support the dynamic switching capabilities of XRandR 1.2.

In these cases, the following switching script provides the same functionality, which you can bind to a keypress such as Fn-F7. The script uses ATI's aticonfig tool for switching, XRandR for resolution adjustment, and Xosd for displaying OSD status messages. Thus, it should work on most Linux-running laptops whith ATI graphics cards (tested with Ubuntu 7.04 and Ubuntu 7.10 on a Thinkpad T43). When an external display is connected, the script switches from internal to both internal and extarnal, then to external only, and finally back to internal display only.

The Script


  1. !/bin/bash
  2. Script to switch displays, e.g. by pressing Fn-F7 on Thinkpad Laptops.
  3. Uses aticonfig from the ATI fglrx driver for dynamic switching, and
  4. xrandr for resolution changing. OSD done with, which uses
  5. osd_cat from Xosd.
  6. Author: Armin Hornung --
  7. Date: 2008-05-01
  8. Partly based on a display switching script from SuSE 10.1
  1. path to, change to "echo" if not installed


  1. path to xrandr


INTERNAL="lvds" # internal LCD of Laptop EXTERNAL="crt1" # external monitor, CRT or TFT

  1. Determine X user, script usually runs as root:

getXuser() {

       user=`finger| grep -m1 ":$displaynum " | awk '{print $1}'`
       if [ x"$user" = x"" ]; then
               user=`finger| grep -m1 ":$displaynum" | awk '{print $1}'`
       if [ x"$user" != x"" ]; then
               userhome=`getent passwd $user | cut -d: -f6`
               export XAUTHORITY=$userhome/.Xauthority
               export XAUTHORITY=""


for x in /tmp/.X11-unix/*; do

   displaynum=`echo $x | sed s#/tmp/.X11-unix/X##`
   if [ x"$XAUTHORITY" != x"" ]; then
       # extract current state

export DISPLAY=":$displaynum" _enabled_monitors=`su $user -c "aticonfig --query-monitor | grep Enabled"` _connected_monitors=`su $user -c "aticonfig --query-monitor | grep Connected"`



  1. determine if internal is active

echo "${_enabled_monitors}" | grep $INTERNAL > /dev/null 2>&1 if [ $? -eq 0 ]; then





  1. determine if external is connected
  2. (LVDS always assumed to be connected)

echo "${_connected_monitors}" | grep $EXTERNAL > /dev/null 2>&1 if [ $? -eq 0 ]; then





  1. determine if external is active

_external_enabled=no echo "${_enabled_monitors}" | grep $EXTERNAL > /dev/null 2>&1 if [ $? -eq 0 ]; then



        1. display switching part ####

if [ "${_internal_enabled}" = "yes" ]; then

 if [ "${_external_connected}" = "yes" ]; then
   if [ "${_external_enabled}" = "yes" ]; then
     # switch to external only, after both enabled:
     $xosd "Enabling $EXTERNAL" &
     su $user -c "aticonfig --enable-monitor $EXTERNAL"
     # adjust resolution back to standard:
     $xrandr -s 1280x1024 -r 60
     # switch to both enabled, after external only
     $xosd "Enabling $INTERNAL & $EXTERNAL" &
     su $user -c "aticonfig --enable-monitor $INTERNAL,$EXTERNAL"
     # adjust resolution:
     $xrandr -s 1280x1024 -r 60
   $xosd "No external display connected" &
   if [ "${_external_enabled}" = "yes" ]; then
     # switch back just if external display got disconnected
     su $user -c "aticonfig --enable-monitor $INTERNAL"
     $xrandr -s 1400x1050 -r 60


 # switch back to internal only, after external enabled:
 $xosd "Enabling $INTERNAL" &
 su $user -c "aticonfig --enable-monitor $INTERNAL"
 # adjust resolution back to standard:
 $xrandr -s 1400x1050 -r 60


exit 0 </bash>


Using the helper script below, Xosd can be used for displaying status messages.

/usr/local/bin/ <bash>

  1. !/bin/bash
  2. 2006-03-09 <>
  3. displays text in arguments on X screen using osd_cat (in some nicely preconfigured style)

OSD_CAT=`which osd_cat` XOSD="${OSD_CAT} --delay=2 --age=0 --lines=2 --pos=bottom --align=center --font=-adobe-helvetica-bold-r-normal-*-*-180-*-*-p-*-*-* --colour=green --shadow=1 --offset=25 --indent=25"

  1. get user running X display (needed when run by script)

XUSER=`ps -C Xsession -o user h`

if [ "${USER}" == "${XUSER}" ]; then

   echo $@ | ${XOSD}


   echo $@ |su ${XUSER} -c "DISPLAY=${DISPLAY:-:0.0} ${XOSD}"

fi </bash>


Place the switching script at /etc/acpi/ and create /usr/local/bin/ Finally, the script needs to be bound to the key Fn-F7 by creating or editing /etc/acpi/events/ibm-videobtn to: <bash>

  1. /etc/acpi/events/ibm-videobtn
  2. This is called when the user presses the video button.

event=ibm/hotkey HKEY 00000080 00001007 action=/etc/acpi/ </bash>

Set permissions and restart acpi

As root, or using sudo run the following commands, <bash>

  1. Make the files executable

sudo chmod 755 /etc/acpi/ sudo chmod 755 /usr/local/bin/

  1. Restart the ACPI service

sudo /etc/init.d/acpid restart </bash> You should be ready to go, just press Fn-F7 to try.

References - Source, has scripts available for download

Sample Fn-F7 script - A similar script using XRandR 1.2 for switching