I dispositivi più probabile ottenere un file in /dev/input/
nome eventN
dove N è i vari dispositivi come mouse, tastiera, presa, pulsanti di potenza etc.
ls -l /dev/input/by-{path,id}/
dovrebbe darti un suggerimento.
Guarda anche:
cat /proc/bus/input/devices
Dove Sysfs
valore è percorso sotto /sys
.
Puoi testare ad es
cat /dev/input/event2 # if 2 is kbd.
Per implementare utilizzare ioctl e controllare dispositivi + monitor.
MODIFICA 2:
OK. Mi sto espandendo su questa risposta in base al presupposto che /dev/input/eventN
viene utilizzato.
Un modo potrebbe essere:
Al ciclo di avvio tutti i event
file trovati in /dev/input/
. Utilizzare ioctl()
per richiedere bit di eventi:
ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), &evbit);
quindi controlla se EV_KEY
-bit è impostato.
IFF impostato quindi controllare la presenza di chiavi:
ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), &keybit);
Ad esempio, se i tasti numerici sono interessanti, quindi verificare se i bit per KEY_0
- KEY9
e KEY_KP0
per KEY_KP9
.
Le chiavi IFF trovate quindi iniziano a monitorare il file degli eventi nel thread.
Torna a 1.
In questo modo dovresti riuscire a monitorare tutti i dispositivi che soddisfano i criteri desiderati. Non si può solo verificare, ad EV_KEY
esempio, se il pulsante di accensione avrà questo bit impostato, ma ovviamente non sarà KEY_A
impostato ecc.
Ho visto falsi positivi per chiavi esotiche, ma per chiavi normali questo dovrebbe essere sufficiente. Non vi è alcun danno diretto nel monitoraggio, ad esempio il file di eventi per il pulsante di accensione o un jack, ma quelli non emetteranno eventi in questione (ovvero codice errato).
Più in dettaglio di seguito.
MODIFICA 1:
Per quanto riguarda "Spiega quell'ultima affermazione ..." . Andando oltre nella terra dello stackoverflow qui ... ma:
Un esempio rapido e sporco in C. Dovrai implementare vari codici per verificare che tu abbia effettivamente il dispositivo corretto, tradurre il tipo di evento, il codice e il valore. Tipicamente key-down, key-up, key-repeat, key-code, ecc.
Non ho tempo (ed è troppo qui), per aggiungere il resto.
Dai un'occhiata linux/input.h
, programmi come dumpkeys
, codice del kernel ecc. Per i codici di mappatura. Per esempiodumpkeys -l
Comunque:
Esegui come ad esempio:
# ./testprog /dev/input/event2
Codice:
#include <stdio.h>
#include <string.h> /* strerror() */
#include <errno.h> /* errno */
#include <fcntl.h> /* open() */
#include <unistd.h> /* close() */
#include <sys/ioctl.h> /* ioctl() */
#include <linux/input.h> /* EVIOCGVERSION ++ */
#define EV_BUF_SIZE 16
int main(int argc, char *argv[])
{
int fd, sz;
unsigned i;
/* A few examples of information to gather */
unsigned version;
unsigned short id[4]; /* or use struct input_id */
char name[256] = "N/A";
struct input_event ev[EV_BUF_SIZE]; /* Read up to N events ata time */
if (argc < 2) {
fprintf(stderr,
"Usage: %s /dev/input/eventN\n"
"Where X = input device number\n",
argv[0]
);
return EINVAL;
}
if ((fd = open(argv[1], O_RDONLY)) < 0) {
fprintf(stderr,
"ERR %d:\n"
"Unable to open `%s'\n"
"%s\n",
errno, argv[1], strerror(errno)
);
}
/* Error check here as well. */
ioctl(fd, EVIOCGVERSION, &version);
ioctl(fd, EVIOCGID, id);
ioctl(fd, EVIOCGNAME(sizeof(name)), name);
fprintf(stderr,
"Name : %s\n"
"Version : %d.%d.%d\n"
"ID : Bus=%04x Vendor=%04x Product=%04x Version=%04x\n"
"----------\n"
,
name,
version >> 16,
(version >> 8) & 0xff,
version & 0xff,
id[ID_BUS],
id[ID_VENDOR],
id[ID_PRODUCT],
id[ID_VERSION]
);
/* Loop. Read event file and parse result. */
for (;;) {
sz = read(fd, ev, sizeof(struct input_event) * EV_BUF_SIZE);
if (sz < (int) sizeof(struct input_event)) {
fprintf(stderr,
"ERR %d:\n"
"Reading of `%s' failed\n"
"%s\n",
errno, argv[1], strerror(errno)
);
goto fine;
}
/* Implement code to translate type, code and value */
for (i = 0; i < sz / sizeof(struct input_event); ++i) {
fprintf(stderr,
"%ld.%06ld: "
"type=%02x "
"code=%02x "
"value=%02x\n",
ev[i].time.tv_sec,
ev[i].time.tv_usec,
ev[i].type,
ev[i].code,
ev[i].value
);
}
}
fine:
close(fd);
return errno;
}
EDIT 2 (continua):
Nota che se guardi /proc/bus/input/devices
hai una lettera all'inizio di ogni riga. Qui B
significa bitmap. Questo è ad esempio:
B: PROP=0
B: EV=120013
B: KEY=20000 200 20 0 0 0 0 500f 2100002 3803078 f900d401 feffffdf ffefffff ffffffff fffffffe
B: MSC=10
B: LED=7
Ciascuno di quei bit corrisponde a una proprietà del dispositivo. Che significa bitmap, 1 indica che è presente una proprietà, come definito in linux/input.h
. :
B: PROP=0 => 0000 0000
B: EV=120013 => 0001 0010 0000 0000 0001 0011 (Event types sup. in this device.)
| | | ||
| | | |+-- EV_SYN (0x00)
| | | +--- EV_KEY (0x01)
| | +------- EV_MSC (0x04)
| +----------------------- EV_LED (0x11)
+--------------------------- EV_REP (0x14)
B: KEY=20... => OK, I'm not writing out this one as it is a bit huge.
B: MSC=10 => 0001 0000
|
+------- MSC_SCAN
B: LED=7 => 0000 0111 , indicates what LED's are present
|||
||+-- LED_NUML
|+--- LED_CAPSL
+---- LED_SCROLL
Dai un'occhiata /drivers/input/input.{h,c}
all'albero dei sorgenti del kernel. Un sacco di buon codice lì. (Ad esempio le proprietà dei dispositivi sono prodotte da questa funzione .)
Ognuna di queste mappe di proprietà può essere raggiunta da ioctl
. Ad esempio, se si desidera verificare quali proprietà dei LED sono disponibili, dire:
ioctl(fd, EVIOCGBIT(EV_LED, sizeof(ledbit)), &ledbit);
Guarda la definizione di struct input_dev
in input.h
per come ledbit
sono definiti.
Per verificare lo stato dei LED, dire:
ioctl(fd, EVIOCGLED(sizeof(ledbit)), &ledbit);
Se i bit 1 in ledbit
sono 1, allora il blocco numerico è acceso. Se il bit 2 è 1, il blocco maiuscole è acceso ecc.
input.h
ha le varie definizioni.
Note sul monitoraggio degli eventi:
Lo pseudo-codice per il monitoraggio potrebbe essere qualcosa nella direzione di:
WHILE TRUE
READ input_event
IF event->type == EV_SYN THEN
IF event->code == SYN_DROPPED THEN
Discard all events including next EV_SYN
ELSE
This marks EOF current event.
FI
ELSE IF event->type == EV_KEY THEN
SWITCH ev->value
CASE 0: Key Release (act accordingly)
CASE 1: Key Press (act accordingly)
CASE 2: Key Autorepeat (act accordingly)
END SWITCH
FI
END WHILE
Alcuni documenti correlati:
Documentation/input/input.txt
, esp. nota sezione 5.
Documentation/input/event-codes.txt
, Descrizione dei vari eventi, ecc prendere atto di ciò che è citato in esempio EV_SYN
suSYN_DROPPED
Documentation/input
... leggi il resto se vuoi.
/dev/disk/by-id/
sono create daudev
- la domanda è se questo è disponibile in questo caso partcular (piattaforma integrata).