Read 1 of 2 keyboards connected

Hi all experts in linux and programming!

I want to make work the following setup:
2 usb keyboards connected to a normal x86
One keyboard working as usual in xorg, but I need that the other one doesn't send anything to xorg but instead I want to process its keystrokes with some kind of background process.

How can it be done? :o

First a bit of theory: you communicate with a UNIX system by using a "tty": a "terminal" consisting of a keyboard and a screen, usually connected via a serial line.

If you connect to a UNIX system over a network you use a so-called "terminal emulator program" (many times "xterm", but that is not the only one) to emulate such a terminal and its serial connection is emulated via the network connection.

There is a special form of a tty , which is called console . This is not connected via the standard serial line but directly attached to the computer. Perhaps the local screen attached to your VGA-card and the (first) keyboard form this console.

Now, after that much theory, to your specific question: this might work, but not necessarily with a USB-attached keyboard and definitely not with a background process. Background processes are part of a process hierarchy, headed by some foreground process: this is usually the shell from which you initiated the background process, typically by issuing the command:

$ /path/to/command -someoptions &

Since the shell you typed that in was already connected to some tty (the one which keyboard you used to type it, probably the console) the background process inherited this connection. You can cut it off from this (by using the nohup command) but per default itis attached to the one you used to call it. Furthermore, a single USB-attached keyboard is not a terminal.

I hope this helps.

bakunin

1 Like

There are devices such as bar code readers that can be connected to act like a keyboard. So - in principle, I guess your request should be doable, while I don't have a solution at hand.
Does it make sense to connect a keyboard without a screen enabling people control over what they typed in?

Before attempting ANYTHING that hits the hardware hard, read up on any protocols required for the USB ports, plus how they work and this includes the keyboard and mouse for those ports too. KB and mouse use USB version 1.1, [1.0?], minimum and do not require I/O speeds greater than about 1.5Mbs data rate.

In Linux flavours, or at least most, there are __accessable__ devices that can be read from and/or written to. I have no idea if this is true of professional UNIX tools however. The protocol for the keyboards being sent and received can be read easily using basic code in differing languages but not necessarily sync'd at all. The data being sent by the KB has many bytes in it in binary form; the same goes for the pointing device,(mouse).

Writing to a USB port via one of these devices is not the same animal however.

Unless you have at least studied how this/these __serial__ interfaces work be careful as they are __effectively__ in __parallel__. As bakunin has implied these could be allocated tty[?] device names in the UNIX domain but can be COM[?], usually COM1 and COM2 for KB and mouse respectively, in the Windows domain, but I have no idea what they are in the Apple OSX !0.7.x and above domain, perhaps also tty[?]. The Linux domains could be special devices and/or tty[?].

IMO it is certainly not an easy task for a novice to intercept a second KB's I/O and redirect from its main duty as user input on any machine in question.

(I would like to be proven wrong however.)

Bazza.

I can't say anything about Linux, but in FreeBSD it would not be really hard.

You just have to tell devd (and possibly Xorg) to ignore that specific keyboard. If can do that, you are free to read /dev/ukbd0 (or ukbd1) as you please. What you get from there might be ascii or scancodes, or you might be able to choose.

It should be similar in Linux, devd is called udev there, I think.

Juha

1 Like

Here is a snapshot of reading KB event6 in Ubuntu 16.04 64 bit...
It is in /dev/input/ ...
As I quoted in most Linux flavours reading is easy, understanding the protocol is NOT!
As you can see with this snapshot of the 'Ubuntu Terminal', to run it from the '/dev/input/' directory requires 'sudo'...
sudo cat event6
Note there were only 3 keys pressed and 1 combination of keys...
Now see how difficult it is to monitor any KB knowing its device, just think how difficult it is if you have disabled said KB and required data from it.

Okay, I was assuming too much.

Juha

If i remember correctly the original PC keyboard was built on the Intel MCS-48 microcontroller, namely the 8042, all PC hardware still reflects that. The mcirocontroller sends so-called "make-" and "break-codes" to the main computer, which basically reflect pressing and releasing a key. Scancodes tell which key exactly was pressed (at this level is i.e. possible to separate the left from the right SHIFT key being pressed, etc.)

In the original design (but i have long since stopped to update my PC hardware knowledge) it used not only the BIOS-interrupt 09h, it also controlled the A20 gate, which was done because of a bug in the 80286 design (it couldn't get back from protected to real mode without a reboot).

I hope this helps.

bakunin

See here:-
http://www.unix.com/programming/268217-usb_kb-io.html\#post302980993
However we are not talking BIOS interrupts which are immaterial in this thread but HID USB protocols, disabling a USB port to re-enable it again, but, redirected to a background process. Not as easy task for the big guns let alone amateurs like me.

Many thanks to all of you!
Now. I think you are overthinking the things.

Someone told something about a barcode scan reader and he got it -That is exactly my case.

I have my normal keyboard and also I have this barcode reader that enter text like a keyboard.

What I want is to read the text from the scanner in asynchronous mode and avoid this one mess with the real keyboard input that I want to let work as usual.

Why this thing has to be so complicated?
I don't think we have to deal with interrupts and all of that. It would need to be done in the unix way, by just reading files.

Erm, now I am confused.
Your OP -

  • so now you don't want 2 keyboards but a USB barcode scanner instead!?
    The barcode scanner will probably have its own device _name_ inside the '/dev' drawer.
    You will still need to know its protocol to extract the relevant data. You will have to research that part yourself.
    To see the data coming from the barcode scanner you can start by using cat /dev/barcode_scanner_devicename but this might hang or do nothing as the I/O might just be another section in the '/dev' drawer; see post #6...

As I don't have a barcode scanner to test with then my reply has to be limited.

1 Like

The barcode scanner works as a keyboard -That is one reason why at first I named them as 2 keyboards.

I can read the scanner/keyboard by "tail" on his /dev/input
The problem is that I want to monitor this input apart in a bakground process and not disturb the working of the normal keyboard in xorg.

I'm fairly sure you can do it, but there's a gotcha -- you'd end up processing raw key codes, not the ASCII you'd get from /dev/input.

My old tablet came with touch screen and wacom tablet screen, and those devices ended up fighting each other all the time so I had to disable one, which I did by 'grabbing' the raw mouse device so the generic /dev/mouse couldn't get it. I suspect keyboard will behave the same. I think you'll need to run the 'grabbing' part as root, perhaps not the rest of it.

Here's a slightly modified version of that code which reads data and prints to standard output:

/**
 *      grab.c
 *      grabs an evdev device to prevent it from sending events
 *      to /dev/input/mice.
 */
#include <sys/types.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>

#include <linux/input.h>

#include <stdio.h>

int main(int argc, char *argv[])
{
        char buf[512];
        ssize_t bytes;
        int fd;

        if(argc != 2)
        {
                fprintf(stderr, "Syntax:  %s device-to-lock\n", argv[0]);
                return(1);
        }

        fd=open(argv[1], O_RDONLY);
        if(fd < 0)
        {
                perror("Couldn't open");
                return(1);
        }

        if(ioctl(fd, EVIOCGRAB, (void *)1))
        {
                perror("Couldn't grab");
                close(fd);
                return(1);
        }

        while((bytes = read(fd, buf, 512)) > 0)
        {
                write(STDOUT_FILENO, buf, bytes);
        }

        close(fd);
        return(0);
}

NO! The barcode scanner, as RudiC quoted, "acts LIKE a keyboard". It has a limited ASCII set and uses the KB event, BUT, have you found out whether it has a separate device in the '/dev/' drawer?

Not sure how you are able to read '/dev/input' as this is a directory on Ubuntu 16.04 64 bit
OS. You must be reading the 'event' which is 'event6' on said OS.

With the barcode scanner NOT plugged in do:-
ls /dev > devlist1.txt
Then plug the barcode scanner in, wait a few seconds and do:-
ls /dev > devlist2.txt
Then find the difference between the two...

If so, you could try the 'xinput' command as xinput list keyboard or something similar, assuming the binaries are in the $PATH and disable the barcode scanner and see if that still produces an output at the event handler. If not see if it can be read from its separate driver that you would have found from above. I am sure it is capable of having a separate driver for other possible uses -- BUT -- I have NOT got one so my help IS limited.

If successful you WILL still need to understand the protocol that comes from the barcode scanner, which sould closely follow a subset of that of the keyboard...

It seems that EVIOCGRAB is the key!

I'm going to test the Corona688's code after checking all that wisecracker has said.

After some testing, I will be back again.
Many thanks to you!

Hi SerKan...

Did you sucessfully get any code working?
If so could you please share with the rest of us as it would be useful for others needing a similar solution.

Many thanks...
Bazza.