Friday, June 3, 2011

Linking kernel and X devices

XI2 has made it possible to access any device the X server knows about and get events from those devices. Alas, one piece was missing: short of parsing the Xorg.log file it was so far impossible to link the system devices with kernel device. You had to guess that /dev/input/event3 was your "AT Translated Set 2 keyboard" with the X device ID of 6.

Why would one need this? Some properties of a device are not exported in X. These included for example anything in sysfs.

I've now pushed patches to evdev, synaptics and the wacom driver to export the device node as a simple string property. From this device node, a client can navigate to the matching sysfs dir, get other events out of the kernel or do whatever they like to do.

The property name is "Device Node" and it is a standard char* that contains the device path. The path is set by the driver, so even if you use e.g. auto-dev on synaptics, the value will be filled in correctly. On the downside, if the driver doesn't support it, the property will not be available on a device. If you write clients that require this information, ensure that you can cope with a missing property and remember that several X devices may share the same device node (e.g. wacom).

These patches do not require a new server, though we have added a #define XI_PROP_DEVICE_NODE to the server to make it easier for others to use this property without misspelling it.

Another property that was pushed in the same series was the "Device Product ID" property (#define XI_PROP_PRODUCT_ID once the new server is out). This property contains two unsigned 32-bit values: vendor ID and product ID. Having this information available makes it simpler for X clients to apply configuration based on specific devices. This can come in handy if you e.g. need different acceleration for a set of mice or you simply want to remap buttons on a specific device.
Again, the two values are set by the driver and all the above rules apply.

I may end up writing those patches for mouse and keyboard too but feel free to help me out with it.

The obligatory not-quite-a screenshot:

:: whot@barra:~> xinput list-props "SynPS/2 Synaptics TouchPad"
Device 'SynPS/2 Synaptics TouchPad':
Device Product ID (252): 2, 7
Device Node (253): "/dev/input/event4"

Update June 7 2011: As Peter pointed out in the comments, the device node is always local to the host the server runs on. It is up to the client to figure out if it runs on the same host.


Lennart said...

This should be exactly what we need to match up volume keypress events with the usb audio devices they originate from. Thanks!

Rob said...

Awesome. I needed to do something that needed this data just the other day. Had to hack around with X configs to get the behaviour I wanted. No restarting of X is what I wanted, thanks!

Peter said...

Important to notice is naturally that clients also need to realize that the device node is a path on the server, which may be another machine than the client.