Code-remapping for xf86-input-evdev

Other languages

There's a better way!

These days, the recommended input driver for X11 is xf86-input-libinput, so I've stopped maintaining this patch.

Fortunately, there's a much simpler way to get the same result: you can tell the kernel to remap codes for you, independently for each keyboard you may have, via the udev "HW DB".

In /etc/udev/hwdb.d/50-apple-kbd.hwdb I have:

 KEYBOARD_KEY_ff0003=insert # fn -> insert

(Important: the second line starts with exactly 1 space (0x20) character)

This Arch documentation page has all the details.

The standard xf86-input-evdev driver that comes with xorg only uses keycodes between 8 and 255, dropping all others. This is fine most of the time (who ever saw a keyboard with more than 247 keys on it?), but it causes problems when the keycodes generated are not compact.

For example, the Apple Aluminum Keyboard (USB ID 05ac:0221) produces at least one code above 255: the "fn" key is 464. People have found other cases, and have reported them as a bug.

Since I needed my keyboard to work as I want it, I did the only sensible thing: I cloned the repository and patched the code.

My patch adds a configuration option, called event_key_remap. Its value must be a (whitespace-separated) list of "assignments" of the format $evdev_code = $x11_code; the $evdev_code can be obtained with showkey -k, the $x11_code can be found in /usr/share/X11/xkb/keycodes/evdev (or wherever your distribution put it).

The implementation is rather simple, creating a look-up table from the configuration; the table is not implemented as a simple array, since that would have meant taking 64KiB for each device (evdev uses 16 bits for a key event). Instead, I allocate "pages" of 256 bytes, and only the pages needed. This way, devices with no remapping use only one more pointer in their structures, and devices with very few codes to remap use only 256 bytes.

Of course, the configuration can be set in the xorg.conf file. Mine contains:

Section "InputClass"
 Identifier "keyboard-generic"
 Driver "evdev"
 Option "XkbOptions" "compose:ralt,altwin:meta_win,terminate:ctrl_alt_bksp"

 MatchIsKeyboard "on"

Section "InputClass"
 Identifier "keyboard-apple-alu"
 Driver "evdev"
 Option "XkbLayout"  "dakkar"
 Option "XkbModel"   "applealu_iso"
 Option "XkbVariant" "dvorak-apple-al"
 Option "event_key_remap" "464=118 120=210 204=211"

 MatchIsKeyboard "on"
 MatchProduct    "Apple, Inc Apple Keyboard"

(Details about my keyboard layout are elsewhere.

DatesCreated: 2009-09-15 12:49:41 Last modification: 2023-02-10 12:45:24