I have usb barcode scanner that emulates keyboard. When it is connected, X gets the control and handles it as an usual keyboard and sends keyboard events to the current focused window.

This is not what I want to do. I have a program that read barcodes from ascii input stream and process them. This program runs at background and has no user interface at all.

How to configure Linux to not use this usb keyboard in X, but map it as a ascii stream device. This way, I will be able to redirect it as an input device for my program and to provide reading the barcodes, regardless of the input focus changes. And the barcodes should not be passed to the currently focused window at all.

In addition, it is better to not run the barcode handling program as a root, so the keyboard device should have read permissions for everyone.


1) How to configure X to ignore the keyboard

Use lsusb to find the ID of your barcode scanner (in format 0123:4567). Create or modify an xorg.conf file (usually in /etc/X11/). Add a InputClass section with the ID you just found:

Section "InputClass"
    Identifier "barcode"
    MatchUSBID "0123:4567"
    Option "Ignore" "true"

Restart X, verify in Xorg.log that your device is recognized by this section and ignored.

2) The conversion from keypresses to ASCII (or other) codes is pretty involved, to allow for different keyboard layouts, dead keys, customizations etc. Now that you disabled the X conversion layer, you can receive keypress and keyrelease events from the appropriate /dev/input/eventX device. The number can change; for your barcode reader, there will be a symlink in /dev/input/by-id/ which doesn't change. So use the symlink.

You can run evtest on this file to see what kind of events it generates. They mapping for your barcode reader will be simple, so a table lookup from keysym to ASCII code will do. You can process these events in your own program, see the evtest source, or e.g. here. You can also write a small C program which just reads this device and produces ASCII on stdout, and then integrate it into your application using a pipe etc.

"Mapping it as an ASCII stream device" is not possible, such devices don't exist in the Linux kernel.

3) Setting permissions

You need to write a custom udev rule to set permissions for your input device. SUBSYSTEM must match input, ACTION must match ADD, the environment ENV should contain information to match the device (use udevadm to find out details), and you can set OWNER, GROUP and MODE for the newly created /dev/input/eventX device. Here's a somewhat general howto , I couldn't find a more specific one. Google for better tutorials.

  • "such devices don't exist in the Linux kernel" Maybe I am wording wrong. I mean, the kernel can decode scan codes into ascii chars - this way are created /dev/stdin and /dev/console when there is no X running. Isn't it possible to configure such ascii device instead of manually reading the event devices? Also, how to configure the access? Now all these devices need root access. – johnfound Feb 7 '17 at 9:44
  • See edit for permissions. /dev/stdin is just a symlink to the first file descriptor of the process (have a look with ls -l). I'm not sure about the details how the kernel keymapping works, but I assume it's tied to the current virtual console, and it wouldn't be possible to use another one without using a fresh virtual console. That means a lot of overhead, and also your display would switch. I don't think you can just attach it to a pseudo tty somehow, though that would be a cool thing to do. – dirkt Feb 7 '17 at 10:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.