Sample Fn-F7 script

From ThinkWiki
Revision as of 16:50, 12 November 2007 by Seva (Talk | contribs)
Jump to: navigation, search

This setup will let you use fn-F7 key combination to toggle between internal, mirror, external, or both screens. Tested on ThinkPad X60s running Fedora 8.

Add a "Virtual" statement to your /etc/X11/xorg.conf, the total resolution should be large enough to fit all your screens in the configuration you want, for example I have 1600x1200 monitor to the left of my internal 1024x768 monitor for a total max resolution of 2624x1200:

Section "Screen"

       Identifier "Screen0"
       Device     "Videocard0"
       DefaultDepth     24
       SubSection "Display"
               Viewport   0 0
               Depth     24
               Virtual   2624 1200
       EndSubSection

EndSection


Create /etc/acpi/events/thinkpad.conf:

# fn-F7
event=ibm/hotkey HKEY 00000080 00001007
action=/usr/local/sbin/thinkpad-fn-f7

Create /usr/local/sbin/thinkpad-fn-f7:

Note: you will have change EXTERNAL_OUTPUT and INTERNAL_OUTPUT to what xrandr shows, for example VGA and LVDS in this case:

xrandr | grep connected
VGA connected 1600x1200+0+0 (normal left inverted right x axis y axis) 432mm x 324mm
LVDS connected (normal left inverted right x axis y axis)

#!/bin/sh
#@ seva sevatech.com

EXTERNAL_OUTPUT=VGA
INTERNAL_OUTPUT=LVDS


EXTERNAL_LOCATION="--left-of $INTERNAL_OUTPUT"

# This is to figure out which X11 display to work on
SU="su $(w -h -s | grep ":[0-9]" | head -1 | awk '{print $1}') -c"
export DISPLAY=$(w -h -s | grep ":[0-9]" | head -1 | awk '{print $3}')

# Save the state to the file until we can figure it out by running xrandr
STATE_FILE=/var/lib/thinkpad/screen.state;
if [ ! -e $STATE_FILE ]; then
       echo "internal" > $STATE_FILE
fi

STATE=$(cat $STATE_FILE)

function screen_external(){
       $SU "xrandr --output $INTERNAL_OUTPUT --off"
       $SU "xrandr --output $EXTERNAL_OUTPUT --auto"
       echo "external" > $STATE_FILE
}

function screen_internal(){
       $SU "xrandr --output $EXTERNAL_OUTPUT --off"
       $SU "xrandr --output $INTERNAL_OUTPUT --auto"
       echo "internal" > $STATE_FILE
}

function screen_mirror(){
       $SU "xrandr --output $INTERNAL_OUTPUT --auto"
       $SU "xrandr --output $EXTERNAL_OUTPUT --auto --same-as $INTERNAL_OUTPUT"
       echo "mirror" > $STATE_FILE
}

function screen_both(){
       $SU "xrandr --output $INTERNAL_OUTPUT --auto"
       $SU "xrandr --output $EXTERNAL_OUTPUT --auto $EXTERNAL_LOCATION"
       echo "both" > $STATE_FILE
}

function screen_toggle(){
       case "$STATE" in
               internal)
                       screen_mirror
                       ;;
               mirror)
                       screen_external
                       ;;
               external)
                       screen_both
                       ;;
               both)
                       screen_internal
                       ;;
               *)
                       screen_internal
                       ;;
       esac
}

# What should we do?
DO="$1"
if [ -z "$DO" ]; then
       DO=$(basename $0)
fi
if [ -z "$DO" ]; then
       DO="internal"
fi

case "$DO" in
       toggle|thinkpad-fn-f7)
               echo wtf
               screen_toggle
               ;;
       internal)
               screen_internal
               ;;
       external)
               screen_external
               ;;
       mirror)
               screen_mirror
               ;;
       both)
               screen_both
               ;;
       status)
               echo $STATE
               ;;
       *)
               echo "usage: $0 <command>" >&2
               echo >&2
               echo "  commands:" >&2
               echo "          status" >&2
               echo "          internal" >&2
               echo "          external" >&2
               echo "          mirror" >&2
               echo "          both" >&2
               echo "          toggle" >&2
               echo >&2
               echo "  If no command is given default is internal" >&2
               ;;
esac

As root,

mkdir -p /var/lib/thinkpad
echo "internal" > /var/lib/thinkpad/screen.state
chmod 755 /usr/local/sbin/thinkpad-fn-f7
service acpid restart