Поймать второй ввод с клавиатуры в (Ubuntu) Linux - PullRequest
12 голосов
/ 13 ноября 2008

Я написал программу, которая получает данные от второй клавиатуры USB (на самом деле сканер штрих-кода). Проблема в том, что если другое окно активно, то данные вводятся туда, а не в мою программу. Может ли кто-нибудь дать мне совет, что я делаю неправильно?

#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;
}

спасибо


Если я могу быть настолько смелым, чтобы перефразировать вопрос от имени Confuzzled:

Как я могу написать программу под Linux, которая присоединяется к устройству ввода, в данном случае сканеру штрих-кода, чтобы ввод не шел к программе, имеющей фокус клавиатуры?

Ответы [ 4 ]

4 голосов
/ 17 февраля 2014

Я пытался сделать то же самое, то, что я сделал, это «запустил» это устройство, используя xinput. В моем случае xinput list показывает (между прочим)

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

Это устройство соответствует сканеру штрих-кода. Затем вы можете просто набрать

xinput float 13

в терминал. Клавиши со сканера больше не будут вводиться в окне, находящемся в фокусе, но их все равно можно будет прочитать из файла устройства. Однако вам нужно будет декодировать события, которые вы прочитали из файла, чтобы получить необходимую информацию (штрих-код). См. формат / dev / input / event *? для получения дополнительной информации о том, как это сделать.

Наконец, чтобы прочитать файл устройства без привилегий root, просто добавьте правило udev для сканера. Для меня это примерно так:

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

Идентификатор idVendor и idProduct для вашего сканера можно найти, изучив вывод dmesg после подключения сканера.

2 голосов
/ 12 января 2010

Прошло много времени с тех пор, как этот вопрос был задан :). В любом случае, я думаю, вам следует использовать API подсистемы устройства ввода linux.

http://www.linuxjournal.com/article/6429 вот хорошее введение.

1 голос
/ 23 октября 2011

Если я правильно понял ваш вопрос, может быть несколько проблем, соответствующих тому, что вы хотите сделать.

1) Для чтения из этих файлов в папке / dev вам необходимы права root.

2) (я не слишком уверен в этом), но я считаю, что это особые файлы, и поэтому вы не можете читать их, как обычный файл.

Если вы позаботились об этих двух проблемах, это все равно не решит вашу проблему, потому что X-события обрабатываются X-сервером, который вы можете рассматривать как одновременное чтение одного и того же файла. Это тот, который захватывает эти события и обрабатывает их соответственно, вызывая соответствующие обработчики событий, если таковые имеются, для определенного события в верхнем активном окне. Все окна общаются с X-сервером, который сообщает, что что-то было напечатано. Поэтому, даже если у вас открыто окно терминала с запущенной программой, сначала X-сервер должен сообщить окну о нажатиях клавиш, которые затем будут переданы программе, работающей в терминале.

Другой код, который выполняет аналогичную работу, можно найти здесь .

1 голос
/ 13 ноября 2008

Я начну со списка типичных проблем, связанных с вашей задачей, у меня нет ответа, но я, по крайней мере, могу пролить свет на , почему у вас проблемы.

  1. Клавиатурные устройства по понятным соображениям безопасности имеют ограничения контроля доступа к ним. По очевидным причинам, если произвольные приложения могут прослушивать / перехватывать клавиатуру без правильного разрешения, это может иметь фатальные последствия, AKA: Keyboard Logger.

  2. Иногда, когда одно приложение (в вашем случае X) получает контроль над устройством ввода, оно съедает все байты, отправленные ему. Так что, если вам удалось обойти проблему с разрешениями, у вас все еще есть проблема в том, что какое-то другое программное обеспечение потребляет поток данных перед вами.

...