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.
If you are reading from /dev/input/eventX
anyway, just do an EVIOCGRAB
ioctl on it. You can issue ioctl's in Perl easily. Don't forget to release the grab when your program quits.
The grab will prevent all other devices, including X, from reading events from this device.
That's cleaner than xinput
, because you also exclude other applications that may want to read directly from the device, and you also can control the duration of the exclusion (as long as your application runs).
Best Answer
Simplest way is probably to write an
xorg.conf
and configure the "other keyboard" with optionGrabDevice
astrue
. This will make sure the kernel input layer only outputs events from this device to X, which means the console won't see them.You can test the effect of the grab with
evtest --grab /dev/input/...
(which will makeevtest
grab it, of course).See
man evdev
for details, seeInputclass
andInputdevice
inman xorg.conf
on how to match your keyboard using hardware ids (or google, there are plenty of tutorials).