There are countless mechanical keyboards and parts available online including many limited releases. Prohibitively expensive, yet beautifully designed keyboards are made by RAMA WORKS, which also dabbles in everything from clothing to computer cases. Two groups, KONO and Input Club seem loosely affiliated. Massdrop is a website that sells curated goods including mechanical keyboards, however they are now at odds with Input Club after a controversial release. KBDfans sells a variety of parts. The most popular firmware for mechanical keyboards seems to be QMK firmware. Desk Candy made a modern version of the Apple M0110. Dixie Mech has organized a bracket based competition for the best keyboards, keycaps and deskmats of 2020 named Mech Madness 2020.

coseyfannitutti on Github has designed numerous fully open through hole PCBs that can be used to assemble a keyboard.


Wooting Two

For a while I considered buying a Apple M0110 and then a Razer Huntsman Tournament Edition, but finally purchased a brand new Wooting Two on eBay in January, 2020 when a seller started auctioning off one every few days.

Wooting has developed a pair of libraries in C to interface with their keyboards. They are documented on their developer portal.


The following device files are created when plugging in my Wooting Two:

Running evtest as root lists the Wooting keyboard, as well as a bunch of event types and codes. Selecting DirectInput in Wootility, configuring a few keys and typing resulting in a stream of events with every keystroke. And the normal keyboard events are available under /dev/input/by-id/usb-Wooting*-event-kbd.

I would love to configure X to recognize the keyboard in analog mode as a mouse. The input events generated by the analog mode configured with DirectInput include ABS_X, ABS_Y, and ABS_Z (-32768, 32767), while my mouse emits REL_X and REL_Y. ABS stands for absolute, while REL is relative (see kernel input event codes).

A StackExchange on using a joystick as a mouse with Fedora recommends creating a config under /etc/X11/xorg.conf.d/ with the SendCoreEvents option, but it has been deprecated in favor of Floating. Although that seems to require that devices support the X Input Extension API.

There appear to be two types of section types that are applicable, InputDevice and InputClass. They shouldn’t be necessary since xorg leverages HAL and udev if AutoAddDevices is enabled and will ignore InputDevice sections in that case. The Arch Linux wiki states that it defaults to libinput before evdev, which is the generic input event interface. Oddly, systemd-localed appears to have generated a 00-keyboard.conf.

Apparently xorg reads from /dev/console.

A number of different pages cover stopping a joystick from controlling a cursor including the Arch Linux wiki page on gamepads.

A helpful tool when debugging may be /dev/uinput (see uinput module). It emulates input devices from userspace. The userspace xboxdrv application appears to map events from one type to another using uinput.

xev will output X events including mouse events. It is wrapped by xbindkeys, which just outputs keycodes.

Mouse keys refers to a feature that allows the numpad to be used to control a cursor. I tried the following, but it didn’t seem to have an effect:

setxkbmap -option keypad:pointerkeys

Mouse control using XKB seems to be possible.

xmodmap is a utility for modifying keymaps and pointer button mappings in X.

It may make the most sense to write a udev rule, which is independent of the display server. The symlinks in /dev/input/by-id are created by /usr/lib/udev/rules.d/60-persistent-input.rules based on the input class of the device. That class doesn’t seem to appear in the output of udevadm monitor -k.

Note there are also mice, mouse0 and mouse1 in /dev/input/.


Apparently, absolute events are converted to relative events by libinput. For some reason xinput list does not list the joystick device.

tail -f ~/.local/share/xorg/Xorg.0.log