Geräte erhalten höchstwahrscheinlich eine Datei mit dem /dev/input/
Namen, eventN
in der N die verschiedenen Geräte wie Maus, Tastatur, Buchse, Ein- / Ausschalter usw. sind.
ls -l /dev/input/by-{path,id}/
sollte dir einen Hinweis geben.
Siehe auch:
cat /proc/bus/input/devices
Wo Sysfs
Wert ist Pfad unter /sys
.
Sie können zB testen
cat /dev/input/event2 # if 2 is kbd.
Verwenden Sie zur Implementierung ioctl und überprüfen Sie Geräte + Monitor.
EDIT 2:
IN ORDNUNG. Ich erweitere diese Antwort basierend auf der Annahme/dev/input/eventN
verwendet wird.
Ein Weg könnte sein:
Bei der Startschleife werden alle event
Dateien in gefunden /dev/input/
. Verwenden Sie ioctl()
diese Option , um Ereignisbits anzufordern:
ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), &evbit);
dann überprüfe ob EV_KEY
-bit gesetzt ist.
IFF gesetzt, dann nach Schlüsseln suchen:
ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), &keybit);
Wenn zB Zifferntasten interessant sind, dann prüfen Sie, ob Bits für KEY_0
- KEY9
und KEY_KP0
bis vorhanden sind KEY_KP9
.
Gefundene IFF-Schlüssel starten dann die Überwachung der Ereignisdatei im Thread.
Zurück zu 1.
Auf diese Weise sollten Sie alle Geräte überwachen können, die die gewünschten Kriterien erfüllen. Sie können nicht nur prüfen, ob EV_KEY
zB beim Ein- / Ausschalten dieses Bit gesetzt ist, sondern offensichtlich auch nicht KEY_A
usw. gesetzt ist.
Ich habe False Positives für exotische Schlüssel gesehen, aber für normale Schlüssel sollte dies ausreichen. Es schadet nicht, wenn Sie zB eine Ereignisdatei für den Netzschalter oder eine Buchse überwachen, aber Sie geben keine fraglichen Ereignisse aus (auch bekannt als schlechter Code).
Mehr im Detail weiter unten.
EDIT 1:
In Bezug auf "Erkläre diese letzte Aussage ..." . Hier im Stackoverflow landen ... aber:
Ein schnelles und unsauberes Beispiel in C. Sie müssen verschiedene Codes implementieren, um zu überprüfen, ob Sie das richtige Gerät erhalten, den Ereignistyp, den Code und den Wert übersetzen. Typischerweise Tastendruck, Tastendruck, Tastenwiederholung, Tastencode usw.
Ich habe keine Zeit (und es ist zu viel hier), um den Rest hinzuzufügen.
Check out linux/input.h
, Programme wie dumpkeys
, Kernel-Code usw. für Mapping-Codes. Z.Bdumpkeys -l
Jedenfalls:
Ausführen als zB:
# ./testprog /dev/input/event2
Code:
#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 (Fortsetzung):
Beachten Sie, dass Sie beim Betrachten /proc/bus/input/devices
einen Buchstaben am Anfang jeder Zeile haben. Hier B
bedeutet Bitmap. Das ist zum Beispiel:
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
Jedes dieser Bits entspricht einer Eigenschaft des Geräts. Mit Bitmap-Mitteln bedeutet 1, dass eine Eigenschaft vorhanden ist, wie in definiert 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
Schauen Sie sich /drivers/input/input.{h,c}
im Kernel Source Tree um. Viel guter Code da. (ZB werden die Geräteeigenschaften von dieser Funktion erzeugt .)
Jede dieser Eigenschaftskarten kann von erhalten werden ioctl
. Wenn Sie beispielsweise überprüfen möchten, welche LED-Eigenschaften verfügbar sind, gehen Sie wie folgt vor:
ioctl(fd, EVIOCGBIT(EV_LED, sizeof(ledbit)), &ledbit);
Schauen Sie sich die Definition von struct input_dev
in an, input.h
um herauszufinden, wie sie ledbit
definiert sind.
So überprüfen Sie den Status von LEDs:
ioctl(fd, EVIOCGLED(sizeof(ledbit)), &ledbit);
Wenn Bit 1 in ledbit
1 ist, leuchtet die Num-Taste. Wenn Bit 2 1 ist, leuchtet die Feststelltaste usw.
input.h
hat die verschiedenen definiert.
Hinweise zur Ereignisüberwachung:
Pseudocode für die Überwachung könnte in die folgende Richtung weisen:
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
Einige verwandte Dokumente:
Documentation/input/input.txt
, esp. Abschnitt 5 beachten.
Documentation/input/event-codes.txt
, Beschreibung verschiedener Ereignisse etc. Beachten Sie, was unter zB EV_SYN
über erwähnt wirdSYN_DROPPED
Documentation/input
... lesen Sie den Rest nach, wenn Sie möchten.
/dev/disk/by-id/
werden erstellt vonudev
- Frage ist, ob dies in diesem speziellen Fall verfügbar ist (eingebettete Plattform).by-id
ist richtig. Zum Beispiel ist meine USB-Tastatur als/dev/input/by-id/usb-_USB_Keyboard-event-kbd
und verfügbar/dev/input/by-path/pci-0000:00:1d.2-usb-0:2:1.0-event-kbd
.