Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trapping second keyboard input in (ubuntu) linux

I have written a program that gets input from a usb second keyboard (actually a barcode scanner). The problem is that if another window is active the data is input there rather than in my program. Could someone give me advice on what I'm doing wrong?

#include <stdio.h>
#include <string.h>

int main(int argc, char * argv[]){
   FILE * fp_in;
   char * data;
   fp_in = fopen("/dev/input/by-id/usb-04d9_1400-event-kbd","r");

   if(fp_in == NULL){
      fprintf(stderr,"Failed to open input by id\n");
   }

   fp_in = fopen("/dev/input/by-path/pci-0000:00:1d.1-usb-0:2:1.0-event-kbd","r");

   if(fp_in == NULL){
      fprintf(stderr,"Failed to open input by path\n");
      return 1;
   }

  while(1){
      fscanf(fp_in,data,"%s");
      fprintf(stderr,"%s",data);
  }
  return 0;
}

thanks


If I may be so bold as to rephrase the question on Confuzzled's behalf:

How can I write a program under Linux that attaches itself to an input device, in this case a barcode scanner, so that the input does not go to the program that has the keyboard focus?

like image 560
Confuzzled Avatar asked Nov 12 '08 22:11

Confuzzled


3 Answers

I was trying to do the same thing, What I did was to "float" that device using xinput. In my case, xinput list shows (among other things)

HID Keyboard Device HID Keyboard Device id=13 [slave keyboard (3)]

This is the device the corresponds to the barcode scanner. You can then simply type

xinput float 13

into a terminal. Keystrokes from the scanner will no longer get entered into the focused window, but they can still be read from the device file. However, you will need to decode the events you read from the file to get the information you want(the barcode). See format of /dev/input/event*? for some information on how to do this.

Finally, to read the device file without root privileges, just add a udev rule for the scanner. For me, it's something like this:

SUBSYSTEM=="input", ATTRS{idVendor}=="1d57", ATTRS{idProduct}=="001c" MODE="0644"

The idVendor and idProduct for your scanner can be found by examining the output of dmesg after plugging the scanner in.

like image 62
admiralswan Avatar answered Nov 10 '22 17:11

admiralswan


It's been a while since this question has been asked :) Anyway, I think what you should do is to use the linux input device subsystem API.

http://www.linuxjournal.com/article/6429 here's a good introduction.

like image 28
rgngl Avatar answered Nov 10 '22 17:11

rgngl


I'll get started with a list of common problems surrounding your task, I don't have the answer, but I can at least provide some light on why you are having problems.

  1. Keyboard devices, for obvious security reasons, have access control restrictions on them. For obvious reasons, if arbitrary applications could sniff/hook the keyboard without the right permission, it could have fatal consequences, AKA: Keyboard Logger.

  2. Sometimes, when one application ( in your case X ) has gained control of an input device, it eats up all the bytes being sent to it. So if you managed to get around the permissions problem, you still have a problem in that some other software is consuming the datastream before you.

like image 1
Kent Fredric Avatar answered Nov 10 '22 17:11

Kent Fredric