Update 3: Apparently the python script which is advertised on some sites got more attention than it had when I first read about it and has even been set up as a
Launchpad project. The huge CPU overhead has been taken care of (it's now event-based) and it supports more than just one laptop model. I haven't tried a new version of the script, but I guess it does the job just as fine as my script does (I can't tell which script is better). Feel free to test out both ways, I'd be happy to hear of some comparisons!
Update 2: There's a new article on this topic. I've managed to build a package out of the stuff I wrote here and made it available in my Launchpad PPA. It should be much easier to just install and configure it than to follow this whole guide. Here's the direct link to the article:
http://linuxquirks.blogspot.com/2010/11/freddeb.html
Update: According to feedback, this solution is not yet guaranteed to work, even for similar laptops. Feel free to test it and report any errors (helps me a lot), though. I will try to create an installable package out of all this, but this will take some time.
As I wrote in an earlier article, I possess an HP touchsmart tm2-1090eg notebook whichcan be turned into a tablet PC. Since the automatic screen rotation is not working out-of-the-box on Ubuntu and since I couldn't get the rotate-screen-button on the right side of the display to work yet, I've been getting by with a hand-written script. I wrote a Tcl/Tk program which uses
xrandr
and
xsetwacom
to rotate the screen according to my wishes.
By request of Felix, the first person to write a comment to this blog :), I looked into possibilities to automatically rotate the screen upon turning the display. I thought that since I managed to write an ACPI handler for CPU frequency scaling depending on the status of the power supply (there will be a post on this, too), I might give it a try. And guess what? I did it!
Unfortunately, my first guess was wrong. Turning around the display and putting it on top of the keyboard didn't create any ACPI events. However, I noticed some strange noise on
dmesg
:
atkbd serio0: Use 'setkeycodes e058 ' to make it known
atkbd serio0: Unknown key pressed (translated set 2, code 0xd9 on isa0060/serio0).
atkbd serio0: Use 'setkeycodes e059 ' to make it known.
atkbd serio0: Unknown key released (translated set 2, code 0xd9 on isa0060/serio0).
Hell yes,
dmesg
even told me what to do! Here's what I did:
- Find out the scan code - turn the display, put it down, pull it back up and inspect the messages:
There should be some messages like the ones I received. The first one is the key code from putting down the display, the second one is the code from pulling it back up.
Note: If You don't get any messages like those, chances are that Your kernel already knows the keys. Try to bind something to them using the GNOME "Keyboard Shortcuts" or see if they generate key events by using xev
.
- Find out which key code is available for mapping. There's no patented way for doing this. I just tried out some codes and looked what the GNOME "Keyboard Shortcuts" called the code. For me, the codes 220 and 221 worked well, since there is no button issuing these codes.
- Create an upstart script to set the keycodes on system startup. Setting the codes is not persistens, so You have to do it after each reboot. Use an upstart script to accomplish the job. As root, create a file
/etc/init/tablet-mode.conf
and put something like this inside:
Code: |
# tablet-mode
#
# Map key codes to the scan codes emitted by the display when putting it down on
# the keyboard.
description "Tablet PC mode"
author "Frederik Möllers"
start on local-filesystems
script
setkeycodes e058 220
setkeycodes e059 221
end script |
- Create a program to rotate the screen. Basically You just need to use
xrandr
to rotate the screen and xsetwacom
to turn the tablet orientation. You can also use my Tcl/Tk program (requires wish
to run, install the package if You want to use it) which also offers a GUI to use manually. Put the following code in a file (e.g. /usr/local/bin/rotatescreen
, make it executable and You can call it with rotatescreen tableton
and rotatescreen tabletoff
. It not only turns the display and the tablet orientation but also disables the touch mode. This prevents the cursor from jumping around when You write with the stylus and touch the display with Your hand. Of course, You can customize the Tcl/Tk program to fit Your wishes. Even if You're not experienced in Tcl or Tk, the syntax should be quite easy. So here's the code:
Code: |
#! /bin/bash
#\
exec wish "$0" "$@"
proc rotate_0 {} {
exec xrandr --output LVDS1 --rotate normal
exec xsetwacom --set 11 rotate NONE
exec xsetwacom --set 12 rotate NONE
exec xsetwacom --set 13 rotate NONE
}
proc rotate_90 {} {
exec xrandr --output LVDS1 --rotate left
exec xsetwacom --set 11 rotate CCW
exec xsetwacom --set 12 rotate CCW
exec xsetwacom --set 13 rotate CCW
}
proc rotate_180 {} {
exec xrandr --output LVDS1 --rotate inverted
exec xsetwacom --set 11 rotate HALF
exec xsetwacom --set 12 rotate HALF
exec xsetwacom --set 13 rotate HALF
}
proc rotate_270 {} {
exec xrandr --output LVDS1 --rotate right
exec xsetwacom --set 11 rotate CW
exec xsetwacom --set 12 rotate CW
exec xsetwacom --set 13 rotate CW
}
proc touch_on {} {
exec xsetwacom --set 11 Touch on
}
proc touch_off {} {
exec xsetwacom --set 11 Touch off
}
proc quit {} {
destroy .
exit
}
if {$argc > 0} {
switch "[lindex $argv 0]" {
"0" {
rotate_0
}
"90" {
rotate_90
}
"180" {
rotate_180
}
"270" {
rotate_270
}
"tableton" {
rotate_180
touch_off
}
"tabletoff" {
rotate_0
touch_on
}
default {
puts "Cannot rotate [lindex $argv 0] degrees!"
}
}
exit
}
wm title . "Screen rotation"
wm geometry . +605+300
frame .deg
button .deg.0 -text "0°" -command "rotate_0; quit"
button .deg.90 -text "90°" -command "rotate_90; quit"
button .deg.180 -text "180°" -command "rotate_180; quit"
button .deg.270 -text "270°" -command "rotate_270; quit"
pack .deg.0 .deg.90 .deg.180 .deg.270 -in .deg -pady 3 -side top
frame .touch
button .touch.ton -text "Touch on" -command "touch_on; quit"
button .touch.toff -text "Touch off" -command "touch_off; quit"
pack .touch.ton .touch.toff -in .touch -pady 3 -side top
button .cancel -text "Cancel" -command "quit"
pack .deg .touch .cancel -pady 6 -side top
bind . "rotate_0; quit"
bind . "rotate_90; quit"
bind . "rotate_180; quit"
bind . "rotate_270; quit"
bind . "quit"
bind . "quit"
bind . "quit" |
- Bind the keys to the program using GNOME "Keyboard Shortcuts" (or the equivalent for Your desktop manager). Create a binding with the command
rotatescreen tableton
and one with the command rotatescreen tabletoff
and set the bindings by turning Your display, putting it down and pulling it back up.
Thanks again to Felix who told me to search for a way. I had already given up on this and didn't think I would find a way to get the screen rotation to work automatically.
That's it! You're done!