Ubuntu 9.10 HAL FDI: Input Device Configuration – Kensington Expert Mouse FAIL

The recent Ubuntu 9.10 release uses HAL & UDEV to permit hotplugging USB mice / trackballs / tablets without killing the X server. This is a vast improvement over the Bad Old Days, with two minor issues:

  1. You must now write an FDI file to configure your widget
  2. There is absolutely no documentation on how to do that

Basically, you’re left to find a blog post somewhere that describes an fdi file for something similar to your widget, then puzzle out how to get from there to what you have. If you’re reading this (and you’re not one of the few dozen folks who read my posts for their pure amusement value), then you’ve probably stalled on Step 2 and arrived here via search engine.

So, here’s how the rest of the story goes down. I assume you’ve read all the various posts scattered here & there and have a vague notion of what goes into an fdi file and why it’s needed. I am not an expert on this stuff, but I did manage to get a few things working with an afternoon of concerted heads-down effort.

Start with the widget plugged in. Type:

lshal | less

Then rummage through that steaming pile until you find the stanzas that (seem to) have something to do with the widget. One stanza should mention a driver that sounds familiar: evdev, wacom, whatever you formerly found in /etc/X11/xorg.conf.

For example, I want to flip the buttons on my Kensington Expert Mouse (it’s really a trackball) to make it left-handed. The userland GUI mouse configuration isn’t relevant, because I also have a tablet and another trackball that must remain right-handed.

Here’s the appropriate stanza for the trackball, with the key lines highlighted:

udi = '/org/freedesktop/Hal/devices/usb_device_47d_1020_noserial_if0_logicaldev_input'
 info.capabilities = {'input', 'input.mouse'} (string list)
 info.category = 'input'  (string)
 info.parent = '/org/freedesktop/Hal/devices/usb_device_47d_1020_noserial_if0'  (string)
 info.product = 'Kensington      Kensington Expert Mouse'  (string)
 info.subsystem = 'input'  (string)
 info.udi = '/org/freedesktop/Hal/devices/usb_device_47d_1020_noserial_if0_logicaldev_input'  (string)
 input.device = '/dev/input/event7'  (string)
 input.originating_device = '/org/freedesktop/Hal/devices/usb_device_47d_1020_noserial_if0'  (string)
 input.product = 'Kensington      Kensington Expert Mouse'  (string)
 input.x11_driver = 'evdev'  (string)
 linux.device_file = '/dev/input/event7'  (string)
 linux.hotplug_type = 2  (0x2)  (int)
 linux.subsystem = 'input'  (string)
 linux.sysfs_path = '/sys/devices/pci0000:00/0000:00:1d.3/usb5/5-1/5-1:1.0/input/input20/event7'  (string)

I don’t know what the difference between info.product and input.product might be, but it looks like the same string for both.

Most of the fdi files I’ve seen try to match the largest possible number of different devices. I take the other tack: I only have one of the things and if I get something similar, it’ll likely be configured entirely differently. So, my fdi files assume one widget of that type, match its name directly without thinking, and are pared to the bare minimum.

I called the file 10-expertmouse.fdi and plunked it in /usr/share/hal/fdi/policy/20thirdparty. The proper directory seems to move around, the files get renamed, and so forth and so on. This was the correct file in the correct spot for the current Ubuntu 9.10 configuration…

<?xml version="1.0" encoding="ISO-8859-1"?>
<deviceinfo version="0.2">
 <match key="input.product" string="Kensington      Kensington Expert Mouse">
 <merge key="input.x11_options.ButtonMapping" type="string">3 8 1 4 5 6 7 2</merge>

You get the X button numbers using xev; write them on the trackball for future reference.

The default Expert Mouse trackball buttons are:

  • upper-left = 2 — middle mouse button
  • upper-right = 8 — page back in browsers, mostly
  • lower-left = 1 — left mouse button
  • lower-right = 3 — right mouse button

So the ButtonMapping line swaps (2 & 8) and (1 & 3). If you prefer not interchanging the 2 and 8 buttons, so as to keep the “page back” button on the upper-left corner, then 3 2 1 will suffice.

The scroll ring emits buttons 4 and 5 as usual. If you don’t like the rotation-to-up/down mapping you can (presumably) swap those using ZAxisMapping as you did before.

The syntax for, say, button mapping is whatever the driver expects and if you can find that doc, great. I used whatever I used in xorg.conf and that seems to work; it matches what the current evdev doc suggests. Leaving out all the config other than the button mapping line seems to work, but I’m sure that’s not a general rule. Maybe it only works with devices that are already automagically recognized as some sort of mouse or tablet.

With that fdi file in place, you just unplug and replug the trackball: no need to reboot or restart X or whatever you’re thinking.

Here’s the new stanza…

udi = '/org/freedesktop/Hal/devices/usb_device_47d_1020_noserial_if0_logicaldev_input'
 info.capabilities = {'input', 'input.mouse'} (string list)
 info.category = 'input'  (string)
 info.parent = '/org/freedesktop/Hal/devices/usb_device_47d_1020_noserial_if0'  (string)
 info.product = 'Kensington      Kensington Expert Mouse'  (string)
 info.subsystem = 'input'  (string)
 info.udi = '/org/freedesktop/Hal/devices/usb_device_47d_1020_noserial_if0_logicaldev_input'  (string)
 input.device = '/dev/input/event7'  (string)
 input.originating_device = '/org/freedesktop/Hal/devices/usb_device_47d_1020_noserial_if0'  (string)
 input.product = 'Kensington      Kensington Expert Mouse'  (string)
 input.x11_driver = 'evdev'  (string)
 input.x11_options.ButtonMapping = '3 8 1 4 5 6 7 2'  (string)
 linux.device_file = '/dev/input/event7'  (string)
 linux.hotplug_type = 2  (0x2)  (int)
 linux.subsystem = 'input'  (string)
 linux.sysfs_path = '/sys/devices/pci0000:00/0000:00:1d.3/usb5/5-1/5-1:1.0/input/input21/event7'  (string)

Shazam! Suddenly, the trackball is completely left-handed and that configuration survives hotplugging and all that happens without killing X.

Well, at least that’s what you’d expect, based on all the doc you can find on the Web.

As it turns out, something in the Ubuntu 9.10 udev mouse event hal X input button stack absolutely prohibits swapping buttons 1 and 3. You can verify this by looking at what the X button IDs are, using xinput:

xinput list --short
"Virtual core pointer"    id=0    [XPointer]
"Virtual core keyboard"    id=1    [XKeyboard]
"Logitech Logitech USB Headset"    id=2    [XExtensionKeyboard]
"Microsoft Comfort Curve Keyboard 2000"    id=3    [XExtensionKeyboard]
"stylus"    id=4    [XExtensionKeyboard]
"stylus cursor"    id=5    [XExtensionKeyboard]
"eraser"    id=6    [XExtensionKeyboard]
"Microsoft Comfort Curve Keyboard 2000"    id=7    [XExtensionKeyboard]
"Power Button"    id=8    [XExtensionKeyboard]
"Power Button"    id=9    [XExtensionKeyboard]
"Macintosh mouse button emulation"    id=10    [XExtensionPointer]
"Logitech USB Receiver"    id=12    [XExtensionPointer]
"Kensington      Kensington Expert Mouse"    id=11    [XExtensionPointer]

xinput get-button-map "Kensington      Kensington Expert Mouse"
1 8 3 4 5 6 7 2 9 10 11 12

Notice that buttons 2 and 8 are swapped, so you know the fdi file is in full effect.

You can force the button mapping using xinput like this (leaving 2 and 8 unswapped, for effect):

xinput set-button-map "Kensington      Kensington Expert Mouse"  3 2 1 4 5 6 7 8
xinput get-button-map "Kensington      Kensington Expert Mouse"
3 2 1 4 5 6 7 8 9 10 11 12

As you might expect by now, whenever the trackball disconnects itself, the xinput mapping Goes Away and the button handedness changes. That completely defeats the entire purpose of the whole obscene-gerund HAL fdi concept.

You might then think you could whip up a nice udev rule that would fire off xinput when the trackball reappears, but udev scripts execute outside the entire user-terminal-X paradigm: xinput complains that it can’t talk to the X server. Of course, you can’t hear it scream, because it’s not connected to a terminal…

Game over. Thanks for playing.

Equally of course, there’s no documentation for the Officially Approved way to configure these devices, if, indeed, there is a way.

Oh, and the real punch line? HAL is (about to be?) Officially Deprecated, so all this information is (or should be, shortly, we’re told) completely obsolete.

I would love to be proved wrong. Let me know…

Surprisingly, Xubuntu 9.10 not only enumerates all the mouse-like objects, but also allows you to set their handedness. That part works fine, but occasionally the Kensington trackball’s scroll ring stops working for a while: xev reports no “button” events happening. Then, unpredictably, it starts up again and works fine. I’d love to believe it’s a hardware problem, but I have two of the things and it happens with both of ’em.

Tomorrow: fun with a Wacom tablet.


  1. #1 by Jeremy Impson on 2010-02-25 - 16:27

    Thanks! I have nothing informative to add, just wanted to confirm that my story followed the path exactly as you described in your first few paragraphs, and the rest of your article helped me get button mapping to work correctly on my Logitech USB Receiver-based wireless mouse.

    I hope something similar will help me re-enable system-wide Ctrl-Alt-Backspace as a way to terminate X with prejudice. It used to be on by default in X, but now it’s off. I understand it’s an XBD option and thus apparently ignored if set in xorg.conf. I’ve seen it referred to as input.x11_options.xkboptions = “terminate:ctrl_alt_bksp”, but at the time I didn’t understand the context. Now that you’ve showed me this fdi thing, maybe the previous reference will make more sense.

    I will say that I feel like, between HAL, udev, d-bus, and the overly-interdepedent gnome-* packages, Linux distributions like Ubuntu are trying too hard to be just like Windows, and are incurring all the overhead and complexity of doing so, all in the alleged name of user friendliness. Things are too hard to debug if you’re not intimately aware with the code like a developer, and there are too many points of failure (or at least, too many undocumented interfaces).

    Years ago I switched from Windows to Linux (at home) because I didn’t like Windows, and I did like having the full control over my system that Linux gave me. Part of that was knowing there was reliable documentation telling me how to do what I want.

    Maybe it’s time I switch back to Slackware?

    • #2 by Ed on 2010-02-25 - 20:50

      re-enable system-wide Ctrl-Alt-Backspace as a way to terminate X with prejudice.

      Evidently you can set up a keyboard shortcut in (at least) Xubuntu that feeds the proper command into the side of the X server, but I haven’t tried that yet.

      Most often, when something I do makes X go toes-up, it takes the USB keyboard down along with it. At that point, there’s no alternative but to ssh in from another box and (try to) give X a shot in the head.

      Maybe it’s time I switch back to Slackware?

      There’s at least one vote in favor of that already.

      I’ve been tinkering with Arch Linux; the details are upcoming as I sort out my notes. So far, it’s working quite well, with very few obscure problems… which is exceedingly encouraging.

      All I know is there are far more distros than time to try ’em all out!

  2. #3 by Lee on 2010-03-12 - 01:11

    As a fellow lefty using a Kensington trackball I would like to say thanks for this post…;)

    Google led me here and although your post didn’t do exactly what I wanted, it gave me the outline and after some trial and error I managed to get the basic functionality from my expert track ball with the ring. My goal was to use the top buttons for right and left click and the bottom buttons for misc. I managed it with this:

    8 3 2 4 5 6 7 1 9 10 11 12

    I’m not sure what buttons 9-12 do but I kept them in there since xinput spit them out.

    • #4 by Ed on 2010-03-12 - 08:19

      I’m not sure what buttons 9-12 do

      As nearly as I can tell, mice & trackballs report the absolute maximum number of buttons they could possibly produce, then actually use only a few.

      Perhaps they use common firmware across several models and, if you could figure out which microcontroller pins to wiggle (and manage to solder wires to those pins!), you could add a ton o’ buttons. That might be an interesting project for a cold winter night.

      after some trial and error I managed to get the basic functionality

      There’s a whole lot of that going around… glad I could help.

      Click on!

  3. #5 by Georg on 2010-08-04 - 08:07

    I can confirm that your solution works out of the box under Gentoo Linux. I have a laptop with an attached Wacom tablet (right hand) and a Kensington ExpertMouse USB (left hand, model 64325) and was about to reconfigure my xorg.conf when I found your post.

    The only thing I did to successfully swap the buttons according to how I’d like it was to add the policy file and enter the correct button order (just as with xmodmap). After that, I replugged the trackball and it just worked :-)

    Thanks a lot.

    • #6 by Ed on 2010-08-04 - 08:44

      After that, I replugged the trackball and it just worked :-)

      Now that is a miracle of rare device!

      Remember: all the HAL stuff Goes Away with Xorg 1.8, so get ready to move the config (back) into xorg.conf. An Arch Linux “rolling release” update delivered 1.8 to me a while ago: changes for tablet & trackball.

      Glad to hear you’re on the air again!

  1. Xubuntu 9.10: Quasi-functional Kensington Trackball Configuration « The Smell of Molten Projects in the Morning
  2. Arch Linux: Kensington Expert Mouse FDI File « The Smell of Molten Projects in the Morning