05.11.2010

Automatic screen rotation on HP touchsmart notebooks

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:
  1. Find out the scan code - turn the display, put it down, pull it back up and inspect the messages:
    Code:
    $ dmesg
    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.
  2. 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.
  3. 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
  4. 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"
  5. 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!

30.10.2010

HP touchsmart notebook, Intel Centrino Wireless N-1000 and no wifi

I recently tried to use my wifi card the first time on Ubuntu 10.10. I noticed that I couldn't connect to any wifi network, no matter what mode the network was (a/b/g/n) or what encryption it used. I looked around and found Ubuntu Bug #630748 and the related Kernel bug #16691 which I thought had something to do with my issue.
I couldn't be more wrong.
It turned out I couldn't get a wifi connection, because bluetooth was disabled using that small GNOME Bluetooth indicator. While bluetooth was disabled, my wifi card was able to list networks and NetworkManager could try connecting to one, however, it never succeeded. dmesg spit out some messages like "direct probe to (access point MAC address) timed out" and after some time even "iwlagn 0000:03:00.0: Microcode SW error detected. Restarting 0x2000000.".
Thanks to Zander Hill's comment in my bug report #663298, I found out that by enabling bluetooth, I could connect to wifi networks again with no problems.

So if You ever run into connectivity problems, feel free to try out everything completely unrelated to Your wifi card just to be sure.

"Modern" touchpads V2

Ubuntu 10.10 came out about 2 weeks ago. There were no big changes, at least no visibly remarkable ones. However, some things that worked in 10.04 stopped working in Maverick. One example are the new Synaptic ClickPads integrated into many of the newer notebooks such as my HP TouchSmart tm2-1090eg. According to the comments in Bug #582809, the psmouse driver module does not correctly recognize the ClickPad and treats it as a "regular" Synaptics Touchpad. Fortunately, someone going by the name of "pauls" uploaded a patched source archive for the psmouse module and posted a detailed guide how to install the new module.
I tried it and it works™!
Here's how (copied from pauls' comment in the linked bug report):
Note: You need root privileges to do most of the things
  1. Download the patched source archive
    Code:
    $ wget https://bugs.launchpad.net/ubuntu/+source/linux/+bug/582809/+attachment/1675262/+files/psmouse-2.6.35-22-generic-patched.tar.bz2
  2. Unpack the source to /usr/src/
    Code:
    $ tar -xjv -C /usr/src/ -f psmouse-2.6.35-22-generic-patched.tar.bz2
  3. Install dkms
    Code:
    $ apt-get install dkms
  4. Add the source to dkms, build it and install the module
    Code:
    $ dkms add -m psmouse -v 2.6.35-22-generic
    $ dkms build -m psmouse -v 2.6.35-22-generic
    $ dkms install -m psmouse -v 2.6.35-22-generic
  5. Reboot.
You can always check wether the module is installed using
Code:
$ dkms status -m psmouse -v 2.6.35-22-generic
If the module is not installed, You can use the steps again to rebuild and reinstall it.
You can also remove the module when a fixed kernel has been released:
Code:
$ sudo dkms uninstall -m psmouse -v 2.6.35-22-generic
$ sudo dkms remove -m psmouse -v 2.6.35-22-generic --all
For more information, updates and troubleshooting, consult the bug report and its comments.
That's it! You're done!

15.09.2010

"Modern" touchpads

My new laptop has a fancy new touchpad. The buttons are part of the pad themselves. The whole pad is a button, the action depends on where you press it down. The only thing that separates the buttons from the rest of the touchpad is a small white line (so basically nothing). The touchpad supports multitouch, which works quite well on Windows but doesn't work at all on Linux. When staying on the "button area" with one finger while trying to move the cursor with another finger, the result is a jumping pointer which does everything but move the way I want it to. I finally found a workaround.
This has been tested on my Synaptics touchpad and I have no idea wether it works for anyone else.
  1. Check your synclient values and save them somewhere.
    Code:
    $ synclient -l > synclient-values
  2. Make the touchpad area smaller so that moving the finger over the buttons doesn't move the cursor.
    Code:
    $ synclient AreaBottomEdge=<value>
    where <value> is a value between the values of BottomEdge and TopEdge. Experiment with the values until you reach the optimal result. Mine was 3836
  3. Change the value of JumpyCursorThreshold. I have no idea what exactly this value is or what exact effect changes on this value have. I only know that setting this value to 100 made my pointer much calmer than before.
    Code:
    $ synclient JumpyCursorThreshold=100
    You may find that other values provide better results for Your laptop and Your touchpad. Feel free to experiment, You can always reset the values either manually or by rebooting.
You can write a shell script and add it to Your startup programs if You want to keep the settings.
Hint: It is not possible to rotate Your touchpad orientation (could be useful if screen can be rotated), since synclient prevents You from setting values for BottomEdge that are smaller than the value of TopEdge and so on...
Hint 2: It is also impossible to change the area of the buttons. If You need to always press the bottom 0.1mm of the touchpad to perform a click, You better get used to it (or write a patch for the synaptics driver).
That's it! You're done!

28.08.2010

Ubuntu on a tablet computer

I installed Ubuntu on my new HP TouchSmart tm2-1090eg laptop. It has a cool tablet function (including a pen). Using the pen works out-of-the-box with Ubuntu 10.04. However, using the thumb-button as a right mouse click, does not. Another flaw is that the pressure curve of the pen (the curve which describes the way the default pressure on the tablet is translated into pressure of brushes in the gimp or whatever) sucks really hard. It's like an on-off-switch, but has nothing to do with pressure. Here is how to fix both things:
  1. Fix the thumb button: Edit the file /usr/lib/X11/xorg.conf.d/10-wacom.conf and in the first InputClass-Section, add the Option:
    Code:
    Option "Button2" "3"
  2. For the pressure curve, edit the same file and add something to the same section. Try out the following options (restarting X every time to see the effect) and choose the one You like the most:
    Code:
    Option "PressCurve" "0,75,25,100" # softest
    Option "PressCurve" "0,50,50,100"
    Option "PressCurve" "0,25,75,100"
    Option "PressCurve" "0,0,100,100 # linear (default)"
    Option "PressCurve" "25,0,100,75"
    Option "PressCurve" "50,0,100,50"
    Option "PressCurve" "75,0,100,25 # firmest"
    For interested users: The numbers describe a bezier curve and You can also change the values of the options via the command-line-tool xsetwacom. By using xsetwacom, the changes take effect immediately, but will be reset upon machine reboot (or driver reload).
Another side note: I managed to get the thumb button working like in Windows (only acts as right click if held down and then pressing the pen on the screen), but I don't know how and I didn't manage to save that behavior. If You know how to do this, tell me!
That's it! You're done!

No ttys after update

I installed ubuntu on a brand new laptop. I got it to work. I downloaded updates. My ttys (Ctrl-Alt-F[1-6]) were gone. Wtf? Now guess why. No, it had nothing to do with the new video card driver I installed. It didn't have anything to do with kernel modules at all.
I found the solution in some forum. I'm glad I tested it, because from what the text said, the problem that guy had fixed was something else than what I had experienced.

  1. Update the configuration for Your initrd. Edit (create if it doesn't exist) the file /etc/initramfs-tools/conf.d/splash and insert (or change if the key already exists): FRAMEBUFFER=y. Quick'n'Dirty:
    Code:
    $ echo "FRAMEBUFFER=y" >> /etc/initramfs-tools/conf.d/splash
  2. Rebuild your initrd with the new configuration:
    Code:
    $ update-initramfs -u
  3. Reboot.
  4. Look at the beautiful ttys in awe.

That's it! You're done!

UPDATE: It seems like You have to run update-initramfs every time You update Your kernel, since the initrd from the package is prebuilt without the FRAMEBUFFER=y option.
UPDATE 2: I sometimes lose my ttys even though I rebuild the initrd. No idea why.

gnome-terminal background transparency

When using gnome-terminal with unmodified settings (which means unmodified terminal profile, unmodified gnome theme and compiz activated), You might notice that the background of the terminal is slightly transparent. This is the case even if though "Solid background" is selected in the profile preferences. Wonder why? gconf is at it again! Want the background to be really solid?
/apps/gnome-terminal/profiles/Default/use_theme_background must be set to false:
Code:
$ gconftool-2 -t bool -s /apps/gnome-terminal/profiles/Default/use_theme_background false
That's it! You're done!