Obtendo o tipo de dispositivo evdev

Obtendo o tipo de dispositivo evdev

No espaço de usuário do Linux, como posso obter o tipo (ou seja, mouse ou teclado) de um dispositivo evdev/input_event?

Eu sei que posso enumerá-los lendo /proc/bus/input/handlersou listando /sys/class/input/, mas não está claro quais dispositivos são mouses ou teclados.

linhas /proc/bus/input/handlerssemelhantes H: Handlers=sysrq kbd event3 ledsparecem sugerir que este é um teclado com a presença de 'kbd', mas não consigo encontrar nenhuma documentação real nesse sentido.

Responder1

O kernel realmente não raciocina em termos de tipos de dispositivos, mas mais em termos dos tipos de eventos que os dispositivos podem produzir (vejaa documentação dos códigos de eventono núcleo).

Como resultado, você precisa de algumas heurísticas para identificar os tipos de dispositivos. Muitos dispositivos podem produzir eventos importantes; os teclados têm a particularidade de produzir eventos de teclas ( EV_KEY) e eventos repetidos ( EV_REP). Os ratos são, penso eu, os únicos dispositivos que produzem eventos relativos ( EV_REL).

Os dispositivos expõem os tipos de eventos que podem gerar no evarquivo em seu capabilitiesdiretório de classe. Cada tipo par possui um determinado deslocamento de bit, definido em /usr/include/linux/input-event-codes.h; EV_KEYé 1, EV_REP20, EV_REL2. Você pode procurar esses bits nos valores fornecidos por /sys/class/input/input*/capabilities/evpara encontrar os dispositivos de seu interesse.

Responder2

Para encontrar detalhes de qualquer dispositivo (eu uso event22), você pode executar isto (em terminal/python/C++):

udevadm info -a -n /dev/input/event22

O resultado é uma lista enorme de detalhes, dos quais apenas 2 são importantes: produto e fornecedor:

ATTRS{idProduct}=="0100"
ATTRS{idVendor}=="04b4"

Ao usar lsusb em um terminal, você também vê esses números mágicos. Ao remover/adicionar você pode descobrir facilmente os números do seu dispositivo, por exemplo, um mouse, dispositivo bluetooth ou leitor de código de barras. Para mim, obtive o seguinte 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

Quando removo meu leitor de código de barras e executo novamente, o dispositivo Fuzzyscan desaparece. Então sei que meu leitor de código de barras é 04b4:0100.

Agora na Biblioteca Evdev também posso encontrar esses números. Primeiro eu faço um programa para executar informações do udevadm para cada dispositivo. Em algum momento encontro um dispositivo com 04b4 e 0100. O nome do dispositivo pode ser usado para evdev. Em C++ posso executar:

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!");

Observação: Talvez este dispositivo não seja permitido para o usuário, então você precisa adicionar direitos de leitura/gravação como este:

sudo chmod a+=wr /dev/input/event22

Sei que não são muito detalhados, fique à vontade para perguntar mais.

informação relacionada