Desde el espacio de usuario de Linux, ¿cómo puedo obtener el tipo (es decir, mouse o teclado) de un dispositivo evdev/input_event?
Sé que puedo enumerarlos leyendo /proc/bus/input/handlers
o enumerando, /sys/class/input/
pero no está claro qué dispositivos son ratones o teclados.
Las líneas /proc/bus/input/handlers
similares H: Handlers=sysrq kbd event3 leds
parecen sugerir que se trata de un teclado con la presencia de 'kbd', pero no puedo encontrar ninguna documentación real al respecto.
Respuesta1
El núcleo realmente no razona en términos de tipos de dispositivos, sino más bien en términos de los tipos de eventos que los dispositivos pueden producir (verla documentación de códigos de eventoen el núcleo).
Como resultado, se necesitan algunas heurísticas para identificar los tipos de dispositivos. Muchos dispositivos pueden producir eventos clave; Los teclados tienen la particularidad de producir tanto eventos de teclas ( EV_KEY
) como eventos repetidos ( EV_REP
). Creo que los ratones son los únicos dispositivos que producen eventos relativos ( EV_REL
).
Los dispositivos exponen los tipos de eventos que pueden generar en el ev
archivo de su capabilities
directorio de clase. Cada tipo par tiene un desplazamiento de bits determinado, definido en /usr/include/linux/input-event-codes.h
; EV_KEY
es 1, EV_REP
20, EV_REL
2. Puede buscar esos bits en los valores dados por /sys/class/input/input*/capabilities/ev
para encontrar los dispositivos que le interesan.
Respuesta2
Para encontrar detalles de cualquier dispositivo (yo uso event22), puedes ejecutar esto (en terminal/python/C++):
udevadm info -a -n /dev/input/event22
El resultado es una lista enorme de detalles, de los cuales sólo 2 son importantes: el producto y el proveedor:
ATTRS{idProduct}=="0100"
ATTRS{idVendor}=="04b4"
Cuando usas lsusb en una terminal, también ves estos números mágicos. Al eliminar/agregar, puede encontrar fácilmente los números de su dispositivo, por ejemplo, un mouse, un dispositivo Bluetooth o un lector de códigos de barras. Para mí obtuve el siguiente resultado:
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 8087:0a2b Intel Corp.
Bus 001 Device 061: ID 04b4:0100 Cypress Semiconductor Corp. Cino FuzzyScan F760-B
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Cuando quito mi lector de código de barras y lo ejecuto nuevamente, el dispositivo Fuzzyscan desaparece. Entonces sé que mi lector de códigos de barras es 04b4:0100.
Ahora en la biblioteca Evdev también puedo encontrar estos números. Primero creo un programa para ejecutar udevadm info para todos y cada uno de los dispositivos. En algún momento encuentro un dispositivo con 04b4 y 0100. El nombre del dispositivo se puede usar para evdev. En C++ puedo ejecutar:
int fd = open("/dev/input/event22", O_RDONLY|O_NONBLOCK)
int rc = libevdev_new_from_fd(fd, &m_evDev);
int vendor = libevdev_get_id_vendor(m_evDev),
int productId = libevdev_get_id_product(m_evDev);
if (vendor == 0x4b4 && productId == 0x100)
printf("Wooow, you find the barcode scanner!");
Observación: Tal vez este dispositivo no esté permitido para el usuario, entonces necesita agregar derechos de lectura/escritura como este:
sudo chmod a+=wr /dev/input/event22
Me doy cuenta de que no son muy detallados, no dudes en preguntar más.