Urządzenia najprawdopodobniej otrzymują plik o /dev/input/
nazwie, eventN
gdzie N oznacza różne urządzenia, takie jak mysz, klawiatura, gniazdo, przyciski zasilania itp.
ls -l /dev/input/by-{path,id}/
powinien dać ci wskazówkę.
Zobacz także:
cat /proc/bus/input/devices
Gdzie Sysfs
wartość jest ścieżką poniżej /sys
.
Możesz przetestować np
cat /dev/input/event2 # if 2 is kbd.
Aby wdrożyć, użyj ioctl i sprawdź urządzenia + monitor.
EDYCJA 2:
DOBRZE. Rozwijam tę odpowiedź w oparciu o przyjęte założenie /dev/input/eventN
.
Jednym ze sposobów może być:
Podczas uruchamiania pętli wszystkie event
pliki znalezione w /dev/input/
. Służy ioctl()
do żądania bitów zdarzeń:
ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), &evbit);
następnie sprawdź, czy EV_KEY
ustawiono opcję -bit.
Ustawiony IFF, a następnie sprawdź klucze:
ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), &keybit);
Np. Jeśli klawisze numeryczne są interesujące, sprawdź, czy bity dla KEY_0
- KEY9
i KEY_KP0
do KEY_KP9
.
Znaleziono klucze IFF, a następnie rozpocznij monitorowanie pliku zdarzeń w wątku.
Powrót do 1.
W ten sposób powinieneś monitorować wszystkie urządzenia spełniające wybrane kryteria. Nie można tylko sprawdzić, czy EV_KEY
np. Przycisk zasilania będzie miał ustawiony ten bit, ale oczywiście nie będzie miał KEY_A
ustawionego itd.
Widziałem fałszywe alarmy dla kluczy egzotycznych, ale dla zwykłych kluczy to powinno wystarczyć. Monitorowanie nie ma bezpośredniej szkody, np. Plik zdarzenia dla przycisku zasilania lub gniazda, ale nie będą one emitować danych zdarzeń (np. Zły kod).
Więcej szczegółów poniżej.
EDYCJA 1:
W odniesieniu do „Wyjaśnij to ostatnie zdanie…” . Przechodzenie w stosie przepływu ląduje tutaj… ale:
Szybka i brudna próbka w C. Musisz zaimplementować różne kody, aby sprawdzić, czy faktycznie otrzymujesz prawidłowe urządzenie, przetłumacz typ zdarzenia, kod i wartość. Zwykle klawiszowanie, klawiszowanie, powtarzanie klawiszy, kod klucza itp.
Nie mam czasu (i jest tu za dużo), aby dodać resztę.
Sprawdź linux/input.h
, programy takie jak dumpkeys
, kod jądra itp. Do mapowania kodów. Na przykładdumpkeys -l
W każdym razie:
Uruchom jako np .:
# ./testprog /dev/input/event2
Kod:
#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;
}
EDYCJA 2 (ciąg dalszy):
Zauważ, że jeśli na to spojrzysz /proc/bus/input/devices
, masz literę na początku każdej linii. Tutaj B
oznacza bit-mapy. To jest na przykład:
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
Każdy z tych bitów odpowiada właściwości urządzenia. Co za pomocą mapy bitowej oznacza 1, że właściwość jest obecna, jak zdefiniowano w 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
Spójrz na /drivers/input/input.{h,c}
drzewo źródeł jądra. Dużo dobrego kodu. (Np. Właściwości urządzenia są wytwarzane przez tę funkcję .)
Każda z tych map właściwości może być osiągnięta przez ioctl
. Na przykład, jeśli chcesz sprawdzić, jakie właściwości LED są dostępne, powiedz:
ioctl(fd, EVIOCGBIT(EV_LED, sizeof(ledbit)), &ledbit);
Spójrz na definicję struct input_dev
w, input.h
jak ledbit
są zdefiniowane.
Aby sprawdzić status diod LED, powiedz:
ioctl(fd, EVIOCGLED(sizeof(ledbit)), &ledbit);
Jeśli bit 1 ledbit
jest równy 1, wówczas świeci num-lock. Jeśli bit 2 ma wartość 1, oznacza to, że klawisz Caps Lock świeci itp.
input.h
ma różne definicje.
Uwagi dotyczące monitorowania zdarzeń:
Pseudo-kod do monitorowania może być czymś w kierunku:
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
Niektóre powiązane dokumenty:
Documentation/input/input.txt
, esp. uwaga sekcja 5.
Documentation/input/event-codes.txt
, opis różnych wydarzeń itp. Zwróć uwagę na to, co wspomniano np. EV_SYN
oSYN_DROPPED
Documentation/input
... czytaj dalej, jeśli chcesz.
/dev/disk/by-id/
są imho tworzone przezudev
- pytanie brzmi, czy jest to dostępne w tym konkretnym przypadku (platforma wbudowana).by-id
jest poprawne. Na przykład moja klawiatura USB jest dostępna jako/dev/input/by-id/usb-_USB_Keyboard-event-kbd
i/dev/input/by-path/pci-0000:00:1d.2-usb-0:2:1.0-event-kbd
.