Подтвердить что ты не робот

Ловушка второго ввода клавиатуры в (ubuntu) linux

Я написал программу, которая вводится с второй клавиатуры 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, которая присоединяется к устройству ввода, в данном случае сканеру штрих-кода, чтобы вход не попадал в программу с фокусом клавиатуры?

4b9b3361

Ответ 1

Я пытался сделать то же самое, что я сделал, чтобы "плавать" на этом устройстве с помощью 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

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

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

Ответ 3

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

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

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

Ответ 4

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

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

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

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

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