95. It works!
Web page:
http://www.thinkwiki.org/wiki/Sample_Fn-F7_script
a. 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
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
3 comments:
Actually it doesn't work on Ubuntu 8.04. The bigger monitor doesn't know the resolution and it detects 800x600. So practically you cannot work on the bigger monitor.
Try to add in /etc/modules acpi support:
in /etc/modules
#Add this line, to enable some thinkpad features
ibm_acpi
http://www.klabs.be/~fpiat/linux/debian/Etch_on_Thinkpad_X31.html
Now at least when you boot the computer with your second monitor connected to the laptop you can see the right something on your secondary (non-laptop) monitor
Since my secondary monitor supports 1280x1024 then I needed to add a line in my /etc/X11/xorg.conf
SubSection "Display"
Depth 24
# I added one more mode 1280x1024
# that I defined below
Modes "1280x1024" "1024x768@60" "800x600@60" "800x600@56" "640x480@60"
EndSubSection
Section "monitor" #
Identifier "monitor1"
Vendorname "Generic LCD Display"
Modelname "LCD Panel 1024x768"
Horizsync 31.5-48.0
Vertrefresh 56.0 - 65.0
modeline "640x480@60" 25.2 640 656 752 800 480 490 492 525 -vsync -hsync
modeline "800x600@56" 36.0 800 824 896 1024 600 601 603 625 +hsync +vsync
modeline "800x600@60" 40.0 800 840 968 1056 600 601 605 628 +hsync +vsync
modeline "1024x768@60" 65.0 1024 1048 1184 1344 768 771 777 806 -vsync -hsync
# I added this line (copied from my
# standalone Ubuntu workstation
# after obtaining from the xvidtune program
modeline "1280x1024" 135.00 1280 1296 1440 1688 1024 1025 1028 1066 +hsync +vsync
Gamma 1.0
EndSection
Now I have the right resolution although my original laptop monitor is blank.
Post a Comment