Advertisements

Archive for January 26th, 2010

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">
 <device>
 <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>
 </match>
 </device>
</deviceinfo>

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.

Advertisements

8 Comments