Linux – How to distinguish input from different keyboards

keyboardlinuxusb

I want to write an application in Python that you can use with your default keyboard and a specially designed one for the application. I will design it simply by using a small numerical keyboard with stickers to give actions to the different keys. Both keyboards will be attached by USB.

However, when these keys are pressed, just their regular signals (numbers, operators and enters), will be send to Python and it will not be able to distinguish between the signals from the main keyboard and the special keyboard.

Because Python has (as far as I could find) no method for making this distinguishment, I want to do it on the OS itself. I will be programming it for the Raspberry Pi, so it will be Linux.

So, the main question: How can I remap the keys of a specific keyboard to other keycodes. I thought about using the F-keys which I won't use for other purposes; or just some characters that are not present on any keyboard (supposing that there are such).

Is this possible in Linux/Unix? And if so, how can I do it?

Best Answer

If you're using Linux, the best way to distinguish between input devices is to use the Linux Event Interface. After a device's hardware-specific input is decoded, it's converted to an intermediate Linux-specific event structure and made available by reading one or more of the character devices under /dev/input/. This is completely independent of the programming language you use, by the way.

Each hardware device gets its own /dev/input/eventX device, and there are also aggregates (e.g. /dev/input/mice which represents the motion of all mice in the system). Your system may also have /dev/input/by-path and /dev/input/by-id.

There's an ioctl called EVIOCGNAME which returns the name of the device as a humanly-readable string, or you can use something like /dev/input/by-id/usb-Logitech_USB_Gaming_Mouse-mouse.

You open the device, and every time an event arrives from the input hardware, you'll get a packet of data. If you can read C, you can study the file /usr/include/linux/input.h which shows exactly how this stuff works. If you don't, you could read this question which provides all the information you need.

The good thing about the event interface is that you just find out what device you need, and you can read input from that input device only, ignoring all others. You'll also get notifications about keys, buttons and controls you normally wouldn't by just reading the ‘cooked’ character stream from a terminal: even dead keys like Shift, etc.

The bad thing is that the event interface doesn't return ‘cooked’ characters, it just uses numeric codes for keys (the codes corresponding to each key are found in the aforementioned header file — but also in the Python source of event.py. If your input device has unusual keys/buttons, you may need to experiment a bit till you get the right numbers.

Related Question