How do I set up a new uinput device so that it can emit arbitrary key events?

240 views Asked by At

The Linux kernel's HTML documentation provides an example that shows how I can set up a user-space keyboard input device using uinput. However, the way the example does it requires that I call ioctl(fd, UI_SET_KEYBIT, ...); for each key event I will emit. In the example, they only emit KEY_SPACE events so only one call is made.

This is both brittle - in the sence that I need to maintain and update my 100s of calls every time a new key is added - and is also redundant. Is there a better way I can set up the new device so that it can emit any key event without me having to specify each key individually?

The header file linux/uinput.h doesn't contain anything that looks like it could help. The kernel's HTML documentation doesn't mention anything relevant either. Any help would be much appreciated.

1

There are 1 answers

0
Tenders McChiken On

Using tricks like adding all defined keys by looping through KEY_ESC to KEY_MAX may work but can lead to the input device being unusable in certain situations.

One technique I found, employed in evemu-tools, is to clone from an existing input device when setting up a new uinput device. While this will not allow arbitrary events to be emitted by the new device, it will allow the emitting of all keyboard events supported by the cloned device.

For the sake of completeness, I've included a superset of Key Events that I sampled from a few keyboards across multiple kernels, hardware configurations (builtin/usb), and keyboard brands. This superset should be serve as a valid fallback if no other keyboard input device is present on the device to clone from (e.g. mobile phones):

KEY_ESC                 KEY_F1                      KEY_PAUSE
KEY_1                   KEY_F2                      KEY_KPCOMMA
KEY_2                   KEY_F3                      KEY_HANGEUL
KEY_3                   KEY_F4                      KEY_HANJA
KEY_4                   KEY_F5                      KEY_YEN
KEY_5                   KEY_F6                      KEY_LEFTMETA
KEY_6                   KEY_F7                      KEY_RIGHTMETA
KEY_7                   KEY_F8                      KEY_COMPOSE
KEY_8                   KEY_F9                      KEY_STOP
KEY_9                   KEY_F10                     KEY_AGAIN
KEY_0                   KEY_NUMLOCK                 KEY_PROPS
KEY_MINUS               KEY_SCROLLLOCK              KEY_UNDO
KEY_EQUAL               KEY_KP7                     KEY_FRONT
KEY_BACKSPACE           KEY_KP8                     KEY_COPY
KEY_TAB                 KEY_KP9                     KEY_OPEN
KEY_Q                   KEY_KPMINUS                 KEY_PASTE
KEY_W                   KEY_KP4                     KEY_FIND
KEY_E                   KEY_KP5                     KEY_CUT
KEY_R                   KEY_KP6                     KEY_HELP
KEY_T                   KEY_KPPLUS                  KEY_CALC
KEY_Y                   KEY_KP1                     KEY_SLEEP
KEY_U                   KEY_KP2                     KEY_WAKEUP
KEY_I                   KEY_KP3                     KEY_MAIL
KEY_O                   KEY_KP0                     KEY_BOOKMARKS
KEY_P                   KEY_KPDOT                   KEY_COMPUTER
KEY_LEFTBRACE           KEY_ZENKAKUHANKAKU          KEY_WWW
KEY_RIGHTBRACE          KEY_102ND                   KEY_COFFEE
KEY_ENTER               KEY_F11                     KEY_BACK
KEY_LEFTCTRL            KEY_F12                     KEY_FORWARD
KEY_A                   KEY_RO                      KEY_EJECTCD
KEY_S                   KEY_KATAKANA                KEY_NEXTSONG
KEY_D                   KEY_HIRAGANA                KEY_PLAYPAUSE
KEY_F                   KEY_HENKAN                  KEY_PREVIOUSSONG
KEY_G                   KEY_KATAKANAHIRAGANA        KEY_STOPCD
KEY_H                   KEY_MUHENKAN                KEY_HOMEPAGE
KEY_J                   KEY_KPJPCOMMA               KEY_REFRESH
KEY_K                   KEY_KPENTER                 KEY_EDIT
KEY_L                   KEY_RIGHTCTRL               KEY_SCROLLUP
KEY_SEMICOLON           KEY_KPSLASH                 KEY_SCROLLDOWN
KEY_APOSTROPHE          KEY_SYSRQ                   KEY_KPLEFTPAREN
KEY_GRAVE               KEY_RIGHTALT                KEY_KPRIGHTPAREN
KEY_LEFTSHIFT           KEY_HOME                    KEY_F13
KEY_BACKSLASH           KEY_UP                      KEY_F14
KEY_Z                   KEY_PAGEUP                  KEY_F15
KEY_X                   KEY_LEFT                    KEY_F16
KEY_C                   KEY_RIGHT                   KEY_F17
KEY_V                   KEY_END                     KEY_F18
KEY_B                   KEY_DOWN                    KEY_F19
KEY_N                   KEY_PAGEDOWN                KEY_F20
KEY_M                   KEY_INSERT                  KEY_F21
KEY_COMMA               KEY_DELETE                  KEY_F22
KEY_DOT                 KEY_MACRO                   KEY_F23
KEY_SLASH               KEY_MUTE                    KEY_F24
KEY_RIGHTSHIFT          KEY_VOLUMEDOWN              KEY_SEARCH
KEY_KPASTERISK          KEY_VOLUMEUP                KEY_MEDIA
KEY_LEFTALT             KEY_POWER                   KEY_UNKNOWN
KEY_SPACE               KEY_KPEQUAL
KEY_CAPSLOCK            KEY_KPPLUSMINUS

I'm aware that this answer doesn't doesn't cover the general case of arbitrary keyboard events (the title of this question) so I'll be leaving this question open in hope for a proper answer.