Difference between revisions of "Sample Fn-F7 script"

From ThinkWiki
Jump to: navigation, search
(change LVDS and VGA to use user-defined constants)
(Cleanups to the script, added mirror mode, and use --auto as noted in the Talk page)
Line 18: Line 18:
  
 
EXTERNAL_OUTPUT=VGA
 
EXTERNAL_OUTPUT=VGA
EXTERNAL_MODE=1600x1200
 
 
 
INTERNAL_OUTPUT=LVDS
 
INTERNAL_OUTPUT=LVDS
INTERNAL_MODE=1024x768
 
  
DO=$(basename $0)
+
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"
 
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}')
 
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;
 
STATE_FILE=/var/lib/thinkpad/screen.state;
 
if [ ! -e $STATE_FILE ]; then
 
if [ ! -e $STATE_FILE ]; then
Line 37: Line 36:
 
function screen_external(){
 
function screen_external(){
 
         $SU "xrandr --output $INTERNAL_OUTPUT --off"
 
         $SU "xrandr --output $INTERNAL_OUTPUT --off"
         $SU "xrandr --output $EXTERNAL_OUTPUT --mode $EXTERNAL_MODE --left-of $INTERNAL_OUTPUT"
+
         $SU "xrandr --output $EXTERNAL_OUTPUT --auto"
 
         echo "external" > $STATE_FILE
 
         echo "external" > $STATE_FILE
 
}
 
}
Line 43: Line 42:
 
function screen_internal(){
 
function screen_internal(){
 
         $SU "xrandr --output $EXTERNAL_OUTPUT --off"
 
         $SU "xrandr --output $EXTERNAL_OUTPUT --off"
         $SU "xrandr --output $INTERNAL_OUTPUT --mode $INTERNAL_MODE --right-of $EXTERNAL_OUTPUT"
+
         $SU "xrandr --output $INTERNAL_OUTPUT --auto"
 
         echo "internal" > $STATE_FILE
 
         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(){
 
function screen_both(){
         $SU "xrandr --output $EXTERNAL_OUTPUT --mode $EXTERNAL_MODE --left-of $INTERNAL_OUTPUT"
+
         $SU "xrandr --output $INTERNAL_OUTPUT --auto"
         $SU "xrandr --output $INTERNAL_OUTPUT --mode $INTERNAL_MODE --right-of $EXTERNAL_OUTPUT"
+
         $SU "xrandr --output $EXTERNAL_OUTPUT --auto $EXTERNAL_LOCATION"
 
         echo "both" > $STATE_FILE
 
         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
 
case "$DO" in
         thinkpad-fn-f7)
+
         toggle|thinkpad-fn-f7)
                 case "$STATE" in
+
                 echo wtf
                        internal)
+
                 screen_toggle
                                screen_external
 
                                ;;
 
                        external)
 
                                screen_both
 
                                ;;
 
                        both)
 
                                screen_internal
 
                                ;;
 
                        *)
 
                                screen_internal
 
                                ;;
 
                 esac
 
 
                 ;;
 
                 ;;
         thinkpad-internal)
+
         internal)
 
                 screen_internal
 
                 screen_internal
 
                 ;;
 
                 ;;
         thinkpad-external)
+
         external)
 
                 screen_external
 
                 screen_external
 
                 ;;
 
                 ;;
         thinkpad-both)
+
         mirror)
 +
                screen_mirror
 +
                ;;
 +
        both)
 
                 screen_both
 
                 screen_both
 +
                ;;
 +
        status)
 +
                echo $STATE
 
                 ;;
 
                 ;;
 
         *)
 
         *)
                 echo "usage: rename to thinkpad-internal, thinkpad-external, or thinkpad-both" >&2
+
                 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
 
esac

Revision as of 16:38, 12 November 2007

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

Note: you will need to change the internal and external resolution until someone fixes this script to figure it out from xrandr, you may also need to change output names from "VGA" and "LVDS" to what your xrandr tells you.

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

  1. fn-F7

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

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

  1. !/bin/sh
  2. @ seva sevatech.com

EXTERNAL_OUTPUT=VGA INTERNAL_OUTPUT=LVDS

EXTERNAL_LOCATION="--left-of $INTERNAL_OUTPUT"

  1. 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}')

  1. 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

}

  1. 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