2007-12-01
95. It works!
Web page:
http://www.thinkwiki.org/wiki/Sample_Fn-F7_scripta. configure virtual screen size
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 if you have 1600x1200 monitor to the left of your internal 1024x768 monitor,
your total max resolution is 2624x1200
Section "Screen"
Identifier "Screen0"
Device "Videocard0"
DefaultDepth 24
SubSection "Display"
Viewport 0 0
Depth 24
Virtual 2624 1200
EndSubSection
EndSection
b. configure acpi
Modify:
/etc/acpi/events/ibm-videobtn
# /etc/acpi/events/ibm-videobtn
# This is called when the user presses the video button. It is currently
# a placeholder.
event=ibm/hotkey HKEY 00000080 00001007
action=/usr/local/sbin/thinkpad-fn-f7
# action=/bin/true
c. You may need to enable ibm-hotkeys
/etc/rc.local
#!/bin/bash
# enable ibm-hotkeys (specifically Fn2, Fn7)
# 12 bit mask, little end is F1 default 0x080c = F12+F4+F3
echo enable,0x084e > /proc/acpi/ibm/hotkey
and after suspending to disk RAM
/etc/acpi/resume.d/91-ibm-hotkey-enable.sh
#!/bin/bash
# enable ibm-hotkeys (specifically Fn2, Fn7)
# 12 bit mask, little end is F1 default 0x080c = F12+F4+F3
echo enable,0x084e > /proc/acpi/ibm/hotkey
chmod 755 91-ibm-hotkey-enable.sh
d. identify output devices
Note the names of your output devices as you will have to change EXTERNAL_OUTPUT and INTERNAL_OUTPUT
to what xrandr shows, for example VGA and LVDS in this case:
$ xrandr -q
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)
e. create the bash script
Create /usr/local/sbin/thinkpad-fn-f7, you can set EXTERNAL_LOCATION to one of: left, right, above, or below.
#!/bin/bash
# External output may be "VGA" or "VGA-0" or "DVI-0"
EXTERNAL_OUTPUT="VGA"
INTERNAL_OUTPUT="LVDS"
EXTERNAL_LOCATION="left"
# Figure out which user and X11 display to work on
# TODO there has to be a better way to do this?
X_USER=$(w -h -s | grep ":[0-9]" | head -1 | awk '{print $1}')
export DISPLAY=$(w -h -s | grep ":[0-9]" | head -1 | awk '{print $3}')
# Switch to X user if necessary
if [ "$X_USER" != "$USER" ]; then
SU="su $X_USER -c"
fi
case "$EXTERNAL_LOCATION" in
left|LEFT)
EXTERNAL_LOCATION="--left-of $INTERNAL_OUTPUT"
;;
right|RIGHT)
EXTERNAL_LOCATION="--right-of $INTERNAL_OUTPUT"
;;
top|TOP|above|ABOVE)
EXTERNAL_LOCATION="--above $INTERNAL_OUTPUT"
;;
bottom|BOTTOM|below|BELOW)
EXTERNAL_LOCATION="--below $INTERNAL_OUTPUT"
;;
*)
EXTERNAL_LOCATION="--left-of $INTERNAL_OUTPUT"
;;
esac
# Figure out current state
INTERNAL_STATE=$($SU xrandr | grep ^$INTERNAL_OUTPUT | grep con | sed "s/.*connected //" | sed "s/(.*//")
EXTERNAL_STATE=$($SU xrandr | grep ^$EXTERNAL_OUTPUT | grep con | sed "s/.*connected //" | sed "s/(.*//")
if [ -z "$INTERNAL_STATE" ]; then
STATE="external"
elif [ -z "$EXTERNAL_STATE" ]; then
STATE="internal"
else
INTERNAL_STATE=$(echo $INTERNAL_STATE | sed "s/[0-9]*x[0-9]*//")
EXTERNAL_STATE=$(echo $EXTERNAL_STATE | sed "s/[0-9]*x[0-9]*//")
if [ "$INTERNAL_STATE" = "$EXTERNAL_STATE" ]; then
STATE="mirror"
else
STATE="both"
fi
fi
function screen_external(){
$SU "xrandr --output $INTERNAL_OUTPUT --off"
$SU "xrandr --output $EXTERNAL_OUTPUT --auto"
}
function screen_internal(){
$SU "xrandr --output $EXTERNAL_OUTPUT --off"
$SU "xrandr --output $INTERNAL_OUTPUT --auto"
}
function screen_mirror(){
$SU "xrandr --output $INTERNAL_OUTPUT --auto"
$SU "xrandr --output $EXTERNAL_OUTPUT --auto --same-as $INTERNAL_OUTPUT"
}
function screen_both(){
$SU "xrandr --output $INTERNAL_OUTPUT --auto"
$SU "xrandr --output $EXTERNAL_OUTPUT --auto $EXTERNAL_LOCATION"
}
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
if [ $(basename $0) = "thinkpad-fn-f7" ]; then
DO="toggle"
fi
fi
case "$DO" in
toggle)
screen_toggle
;;
internal)
screen_internal
;;
external)
screen_external
;;
mirror)
screen_mirror
;;
both)
screen_both
;;
status)
echo "Current Fn-F7 state is: $STATE"
echo
echo "Attached monitors:"
$SU xrandr | grep "\Wconnected" | sed "s/^/ /"
;;
*)
echo "usage: $0
" >&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
;;
esac
chmod 755 thinkpad-fn-f7
$ sudo chmod 755 /usr/local/sbin/thinkpad-fn-f7
$ sudo service acpid restart
OR
$ sudo /etc/init.d/acpid restart