How to distinguish input from different keyboards?

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.


An alternative approach (if your "keyboard" doesn't have many keys - many devices pretend to be keyboards) is to apply a keymapping to each keyboard specifically and ensure that keys are distinguished.

This is outlined here: https://superuser.com/questions/760602/how-to-remap-keys-under-linux-for-a-specific-keyboard-only. The main point being the setxkbmap takes a device argument.

If you are using the raw input approach the lsinput will find your raw device for you.