You are viewing cyli

c y l i - Woots, rotation and navigation keys work on the XO.

Ying Li
Date: 2008-03-06 14:04
Subject: Woots, rotation and navigation keys work on the XO.
Security: Public
Tags:ubuntu olpc x11
Now I can use the XO as an ebook reader (in tablet mode) when using Ubuntu.

I was having problems before because the rotation key on the XO, as well as the directional keypad (see this image, although the rotation key is labeled as "backlight control" for some reason). xev didn't even register anything when I hit the keys (oddly enough it did register the gamepad buttons). I knew that that the kernel recognized the key presses, since od /dev/input/event3 register events when the directional pad keys and rotation button (and any other key on the keyboard) is pressed. However, thanks to's tutorial, I got it working.

Getting X to see the keys

Basically, I used tail -f /var/log/kern.log to get the number (?) of the unknown keys (it on my machine it was 65-69). Then I did dumpkeys --keys-only to figure out which keycodes were free, and I mapped those keys to keycodes 120-124 using setkeycode <key number> <keycode>. I put the setkeycode commands in /etc/init.d/

# rockerpad up
setkeycodes 65 120

# rockerpad right
setkeycodes 68 121

# rockerpad down
setkeycodes 66 122

# rockerpad left
setkeycodes 67 123

# rotate button
setkeycodes 69 124
and ran update-rc.d start 99 2 3 4 5 . (Apparently this is the recommended way in Ubuntu to set up startup scripts?)

So yay, xev recognizes the keys (although oddly enough the keycodes given it gives are not in the 120-124 range - I guess X uses a different set of keycodes?) , which means that I can use's instructions to bind that button to my rotate script (more later) using xbindkeys.

Getting rotate to work

I want to remap the directional pads every time the screen rotates, because I don't want to have to mentally translate up to right when the screen rotates 90 degrees. suggests key mappings are most easily done with xmodmap. The script given in by simply rotates the screen so you have to change the it so that it remaps those keys as well as rotates.

I haven't figured out what I'm going to do with the game pad keys yet, so I only want to map 4 keys. I wanted to be able to map the other keys if I figured out what to do with them, but without having to do a lot of editing. So I changed the rotation script to:
# Rotates the screen 90 degrees on the olpc

import os, sys, re

# Get current screen orientation
xr = os.popen("xrandr -q").read()
m ='\+\d\s+(.*?)\s*\(',xr)
if not m:
    raise "No match!"
rotation =

# Generate new orientation
# orientations:  0 is normal, 1 is left, 2 is inverted, and 3 is right
#   If we want to rotate 90 degrees we need to subtract 1, so the new
#   orientations would be [3, 0, 1, 2] (current = [0, 1, 2, 3])
new_orientations = ["right", "", "left", "inverted"]
val = new_orientations.index(rotation)
if val < 0:
    raise "xrandr output is not what's expected"

commands = ["xrandr -o %d" % val]

# Get the keycodes for the directional pad and game pad and cause them to 
# rotate as well
if len(sys.argv) > 1:
    if not os.path.isfile(sys.argv[1]):
        raise "%s either doesn't exist or isn't a regular file" % sys.argv[1]
    f = open(sys.argv[1])
    data ="\n\n")
    for cluster_data in data:
        keycodes = []
        keysyms = []
        for line in cluster_data.split("\n"):
            if line.strip() and not line.startswith("#"):
                kc, ks = line.split("=", 1)
        for i in range(len(keycodes)):
            commands.append('xmodmap -e "keycode %s = %s"' % ( 
                    keycodes[i], keysyms[(i-val) % len(keycodes)]))

os.system("; ".join(commands))
Not the most elegant or robust script, but meh, it works and it makes changing key mappings easy. It takes a single configuration file, which is passed to it on the command line. The configuration file simply maps clusters of keys to their keysyms/values. I found the values by running xev and pressing the normal keyboard directional keys. Mine configuration file, for instance, is:
139 = Left 
134 = Up
210 = Right
209 = Down
If I wanted to later add mappings for the game pad keys, I just need to throw in a few extra empty lines (yes, my cluster of keys are determined by white space. blah blah...) and then put the keys values for them in. So for example:
139 = Left 
134 = Up
210 = Right
209 = Down

# yay, my script ignores comments

1 = a
2 = b
3 = c
4 = d 
As you can see, I completely made up the key numbers and key values for the directional pads. If you want to map something to space, however, you will need to use the keysym (not the value " " since I ignore whitespace there).

An alternative to using my script is using the scripts at this OLPC News forum post, with key numbers and keysyms/values changed (note: I don't think KP_UP, etc. are recognized symbols in Ubuntu on the OLPC without some xkb tweaking).

Also for some reason, I have to run xbindkeys after I start xfce4 in order for anything to work. I guess I need to modify some startup file.
Post A Comment | 3 Comments | Add to Memories | Share | Link

User: deeptape
Date: 2008-03-07 04:44 (UTC)
Subject: so...
why ubuntu on XO?
Reply | Thread | Link

Ying Li
User: cyli
Date: 2008-03-07 21:09 (UTC)
Subject: Re: so...
Hmm... this is hard to answer properly. I basically participated in the G1G1 program (A) because I thought it was an interesting project, (B) because I think providing access to and education about computers to underprivileged children is a good idea, and (C) because I thought the XO would make a more flexible and hackable eBook reader than Sony's or the Kindle.

Sugar has some cool features and toys, but is somewhat annoying for the purposes I want - which is to poke around on the command line and read documents in lots of different formats. When you start the terminal activity, the cursor goes right to the title-bar so you can name that session of the activity for your logs. I guess this is an interesting idea for children learning to interact with a machine, but annoying for someone who just wants to run a few quick commands. Opening files on disk is also somewhat of a hassle.

I could install Opera, and use Xfce or fluxbox instead of Sugar, but then basically it'd just be a RedHat machine. And if I'm going to just use it as a linux laptop anyway, I may as well use a distro that I'm used to and like. :)
Reply | Parent | Thread | Link

User: (Anonymous)
Date: 2008-03-31 02:44 (UTC)
Subject: Re: so...
why ubuntu over redhat?

if only puppy had won the olpc bid :)
Reply | Parent | Thread | Link

my journal
May 2009