uhidvkbdd – Driver for USB media keys


uhidvkbdd [−d] device


The uhidvkbdd daemon is a simple way to get media keys on some keyboards working in X11. Such keyboards present separate interfaces: a basic USB keyboard which is handled by the kernel ukbd(4) driver and a USB HID device that reports the media keys which is handled by the generic uhid(4) driver. uhidvkbdd reads consumer control inputs from the latter and translates them via vkbd(4) into conventional media keyboard scancodes, which are mapped in X11 by default.

On startup the daemon opens device and checks its report descriptor for relevant consumer inputs. If there are none, it exits. Otherwise, it continues running in the background and translates inputs. Note that the report descriptor may list more inputs than the device can actually generate, so the daemon may continue running for some irrelevant devices.

The option is:


Run in the foreground. This will print information about available consumer inputs and generated keyboard scancodes.

Setting up

First, check whether your keyboard is compatible. Run the daemon with −d for each uhid* device and check the output.

Here is an example of an irrelevant device (a webcam with a few buttons that don't have mapped scancodes):

# ./uhidvkbdd -d uhid0
report: application b0001, usage b0020 - ignored
report: application b0001, usage b0024 - ignored
report: application b0001, usage b002f - ignored
report: application b0001, usage b0050 - ignored
report: application b0001, usage c00b2 - ignored
report: application b0001, usage c00b7 - ignored
uhidvkbdd: uhid0: no mapped consumer inputs found

And here is an example of media keys on a keyboard, and what happens when they are pressed:

# ./uhidvkbdd -d uhid1
report: application c0001, usage c0000-c0fff - mapped
input: usage c00cd = 1
scancodes: e0 22
input: usage c00cd = 0
scancodes: e0 a2
input: usage c00e9 = 1
scancodes: e0 30
input: usage c00e9 = 0
scancodes: e0 b0

You can also use usbhidctl(1) to get more information about the device:

# usbhidctl -f uhid1 -vrla

uhidvkbdd comes with an rc.d script that automatically runs the daemon for every existing uhid* device and a devd(8) configuration file that runs the daemon for every newly attached device. The intent is to avoid additional configuration even if device unit numbers change. Since the daemon checks for relevant consumer inputs on startup, irrelevant devices like joysticks will still be accessible to other programs.

Enable this behavior in /etc/rc.conf:


Then start it with

# service uhidvkbdd start

If everything worked, you should see at least one uhidvkbdd process running, and a new virtual kbd* device in dmesg(8) .

Now, check the current X11 keyboard configuration with

$ setxkbmap -print

The scancodes generated by the daemon match the default X11 keyboard model pc105, so they should already be mapped to X11 symbols like XF86AudioPlay. When this is the case, the xkb_symbols setting displayed mentions +inet(pc105) or a similar mapping like +inet(media_nav_common).

Finally, check that the keys actually work and generate appropriate symbols with

$ xev -events keyboard

One hitch is that on FreeBSD some of the scancodes are remapped by an extra xf86-input-keyboard port patch. To undo its effect, use the following ~/.Xmodmap:

keycode 140 = XF86AudioMute
keycode 152 = XF86Search
keycode 154 = XF86Reload

What next

Enjoy your awesome keyboard and the additional level of control.

Some programs work with multimedia keys automatically. For instance, the Xfce audio mixer panel applet captures and handles the volume keys when installed with the KEYBIND port option.


usbhidaction(1) can be configured to map arbitrary USB HID inputs to commands, including mixer(8) controls and writing scancodes to /dev/vkbdctl0.

uhidd(8) also translates media keys into scancodes, but handles the entire USB endpoint (ugen*.*), not just one interface (uhid*), so it has to replace the kernel ukbd(4) driver for the main keys too.

See also


uhidvkbdd was written by Andrey Zholos.