Saturday, April 26, 2008

Rerouting input events on Linux

In the last days I have turned what began as a XBox360 userspace driver into a full blown event router. This means you can not only remap a few buttons, but have virtually total freedom in how to translate your input events. You can turn your dpad into axis, change the order of axis, add auto-fire, turn a normal button into a toggle button, merge multiple axis into one, do mouse emulation, emit keyboard events or pretty much whatever you like.

The basic idea behind the thing is that you simply take any input event you can find on your system and then reroute it through as many control nodes as you like to turn it into something else and then output it via the uinput kernel service. The little picture on the right gives you a view of how such a routing network might look like. At this time there is support for recieving events from /dev/input/eventX as well as from XBox360 gamepads, but future extensions are quite possible and likely. There are of course also plenty of things missing, such as changing the configuration on the fly and abs events that have different ranges aren't handled well either, but overall it already works quite nicely and if you need to change mappings for a game that doesn't support it, you know can.

One thing I haven't figured out yet is how to best swap /dev/input/jsX devices, since the event rerouter naturally comes last, it will end up as /dev/input/js1 instead of /dev/input/js0, which some games might not like. Just using 'mv' of course works, but has some ugly sideeffects, since udev doesn't seem to register it.

Anyway, the thing is floating around as inputdrv in the current xboxdrv git repository. If you want to play with it, have fun.

No comments: