The general idea is to use keystrokes plucked from a cheap numeric keypad to control mplayer
, with the intent of replacing some defunct CD players and radios and suchlike. The keypads look about like you’d expect:

The keypad layouts are, of course, slightly different (19 vs 18 keys!) and they behave differently with regard to their NumLock
state, but at least they produce the same scancodes for the corresponding keys. The black (wired) keypad has a 000
button that sends three 0
events in quick succession, which isn’t particularly useful in this application.
With the appropriate udev rule in full effect, this Python program chews its way through incoming events and reports only the key-down events that will eventually be useful:
from evdev import InputDevice,ecodes,KeyEvent | |
k=InputDevice('/dev/input/keypad') | |
for e in k.read_loop(): | |
if (e.type == ecodes.EV_KEY) and (KeyEvent(e).keystate == 1): | |
if (KeyEvent(e).keycode == 'KEY_NUMLOCK'): | |
continue # we don't care about the NumLock state | |
else: | |
print KeyEvent(e).scancode, KeyEvent(e).keycode |
Pressing the keys on the white keypad in an obvious sequence produces the expected result:
82 KEY_KP0 79 KEY_KP1 80 KEY_KP2 81 KEY_KP3 75 KEY_KP4 76 KEY_KP5 77 KEY_KP6 71 KEY_KP7 72 KEY_KP8 73 KEY_KP9 98 KEY_KPSLASH 55 KEY_KPASTERISK 14 KEY_BACKSPACE 74 KEY_KPMINUS 78 KEY_KPPLUS 96 KEY_KPENTER 83 KEY_KPDOT
Observations
KeyEvent(e).keycode
is a string:'KEY_KP0'
e.type
is numeric, so just compare againstevcodes.EV_KEY
KeyEvent(e).scancode
is the numeric key identifierKeyEvent(e).keystate
= 1 for the initial press- Those
KeyEvent(e).key_down/up/hold
values don’t change
If you can type KEY_KP0
correctly, wrapping it in quotes isn’t such a big stretch, so I don’t see much point to running scancodes through ecodes.KEY[KeyEvent(e).scancode]
just to compare the enumerations.
I’m surely missing something Pythonic, but I don’t get the point of attaching key_down/up/hold
constants to the key event class. I suppose that accounts for changed numeric values inside inherited classes, but … sheesh.
Anyhow, that loop looks like a good starting point.
I’m imagining custom keycaps (probably stickers) at some point in the future. I follow your logic about converting keycode strings to scancodes. Using keycodes is less (computer) efficient but more readable and future-proof (and therefore more programmer efficient), and programmer efficiency trumps computer efficiency for this task.
The event interface emits a raw scancode-per-key, along with an indication of the key state change, rather than the cooked result from the usual keyboard handler. That turns the keypad into a button array: the Backspace key doesn’t do buffer editing and the NumLock state doesn’t change anything.
You’ll see crude sticker labels tomorrow and better ones later on; we’re definitely not talking commercial quality, but it’s much easier than conjuring up my own wireless button array!