2008-11-12 5 views
12

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

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

+0

Может быть, вы должны спросить о программном пути различать клавиатуру? – 2008-11-12 23:04:44

ответ

1

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

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

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

2

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

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

1

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

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

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

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

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

4

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

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

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

xinput float 13

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

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

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

idVendor и idProduct для сканера можно найти, исследуя выход dmesg после подключения сканера в

 Смежные вопросы

  • Нет связанных вопросов^_^