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 waba.be'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/olpckeys-setup.sh:
#/bin/sh # rockerpad up setkeycodes 65 120 # rockerpad right setkeycodes 68 121 # rockerpad down setkeycodes 66 122 # rockerpad left setkeycodes 67 123 # rotate button setkeycodes 69 124and ran update-rc.d olpckeys-setup.sh 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 wiki.laptop.org'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. waba.be suggests key mappings are most easily done with xmodmap. The script given in by wiki.laptop.org 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:
#!/usr/bin/python # Rotates the screen 90 degrees on the olpc import os, sys, re # Get current screen orientation xr = os.popen("xrandr -q").read() m = re.search(r'\+\d\s+(.*?)\s*\(',xr) if not m: raise "No match!" rotation = m.group(1) # 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): raise "%s either doesn't exist or isn't a regular file" % sys.argv f = open(sys.argv) data = f.read().split("\n\n") f.close() 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) keycodes.append(kc.strip()) keysyms.append(ks.strip()) 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 = DownIf 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 = dAs 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.