para - se desconfiguro mi teclado en linux
Atrapando la segunda entrada de teclado en(ubuntu) linux (4)
He escrito un programa que recibe información de un segundo teclado usb (en realidad, un escáner de código de barras). El problema es que si otra ventana está activa, los datos se ingresan allí en lugar de en mi programa. ¿Podría alguien darme consejos sobre lo que estoy haciendo mal?
#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;
}
Gracias
Si puedo ser tan audaz como para reformular la pregunta en nombre de Confucio:¿Cómo puedo escribir un programa en Linux que se adjunte a un dispositivo de entrada, en este caso un escáner de código de barras, para que la entrada no vaya al programa que tiene el foco del teclado?
Comenzaré con una lista de problemas comunes que rodean su tarea, no tengo la respuesta, pero al menos puedo aclarar por qué tiene problemas.
Los dispositivos de teclado, por razones obvias de seguridad, tienen restricciones de control de acceso sobre ellos. Por razones obvias, si las aplicaciones arbitrarias pudieran olfatear / enganchar el teclado sin el permiso correcto, podría tener consecuencias fatales, AKA: Keyboard Logger.
A veces, cuando una aplicación (en su caso X) ha obtenido el control de un dispositivo de entrada, se come todos los bytes que se le envían. Por lo tanto, si logró sortear el problema de los permisos, aún tiene un problema porque algún otro software está consumiendo el flujo de datos que tiene delante.
Ha pasado un tiempo desde que se hizo esta pregunta :) De todos modos, creo que lo que debes hacer es usar la API del subsistema del dispositivo de entrada de Linux.
http://www.linuxjournal.com/article/6429 aquí hay una buena introducción.
Si he entendido bien su pregunta, puede haber algunos problemas que corresponden a lo que desea hacer.
1) Para leer de estos archivos en la carpeta / dev, necesita tener permisos de root.
2) (No estoy muy seguro de esto) pero creo que estos son archivos especiales y, por lo tanto, no puede leerlos como lo haría con un archivo normal.
Suponiendo que haya solucionado estos dos problemas, aún no resolverá su problema porque los eventos X son manejados por el servidor X, que puede pensar que está leyendo simultáneamente el mismo archivo. Es el que captura estos eventos y los maneja en consecuencia llamando a los manejadores de eventos relevantes, si los hay, para un evento particular en la ventana activa más alta. Todas las ventanas hablan con el servidor X que dice si algo ha sido escrito. Entonces, incluso si tiene una ventana de terminal abierta con un programa en ejecución, primero el servidor X debe indicar a la ventana sobre las pulsaciones de tecla que luego se pasarán al programa que se ejecuta en la terminal.
Otro código que hace un trabajo similar se puede encontrar aquí .
Estaba tratando de hacer lo mismo, lo que hice fue "flotar" ese dispositivo usando xinput. En mi caso, la xinput list
muestra (entre otras cosas)
HID Keyboard Device HID Keyboard Device id=13 [slave keyboard (3)]
Este es el dispositivo que corresponde al escáner de código de barras. A continuación, puede simplemente escribir
xinput float 13
en una terminal. Las pulsaciones del escáner ya no se ingresarán en la ventana enfocada, pero aún se pueden leer desde el archivo del dispositivo. Sin embargo, deberá decodificar los eventos que lee del archivo para obtener la información que desea (el código de barras). Ver formato de / dev / input / event *? para obtener información sobre cómo hacer esto.
Finalmente, para leer el archivo del dispositivo sin privilegios de root, simplemente agregue una regla udev para el escáner. Para mí, es algo como esto:
SUBSYSTEM=="input", ATTRS{idVendor}=="1d57", ATTRS{idProduct}=="001c" MODE="0644"
El idVendor y idProduct para su escáner se pueden encontrar examinando la salida de dmesg
después de enchufar el escáner.