Zugriff auf Schlüssel vom Linux-Eingabegerät
Was ich versuche zu tun,
So, ich habe versucht, Zugriff auf Tastatur-Eingabe unter Linux. Speziell muss ich in der Lage, access-modifier-Taste drückt ohne anderen Tasten gedrückt werden. Darüber hinaus möchte ich in der Lage sein, dies zu tun ohne ein X-system ausgeführt werden.
Also, kurz gesagt, meine Anforderungen sind diese:
- Funktioniert unter Linux
- Nicht braucht X11
- Abrufen können modifier-Taste drücken ohne andere Tasten gedrückt werden müssen
- Diese enthält die folgenden Schlüssel:
- Shift
- Kontrolle
- Alt
- Alles was ich brauche ist eine einfache
0 = not pressed
1 = currently pressed
lassen Sie mich wissen, wenn
die Taste wird gedrückt, wenn die Tastatur aktiviert ist
- Diese enthält die folgenden Schlüssel:
Mein computer setup
Meinem normalen Linux-Maschine ist auf einem LKW in Richtung meiner neuen Wohnung; also, ich habe nur ein Macbook Air zu arbeiten, gerade jetzt. Also, bei mir läuft Linux in einer VM zu testen.
Virtuelle Maschine in VirtualBox
- OS: Linux Mint 16
- Desktop-Umgebung: XFCE
Alles, was unten geschehen war in dieser Umgebung. Ich habe versucht, sowohl die mit X laufen und in einem der anderen ttys.
Meine Gedanken
Werde ich ändern, wenn jemand kann mich korrigieren.
Ich habe ein gutes Stück zu Lesen, um zu erkennen, dass höher-level-Bibliotheken, die nicht bieten diese Art von Funktionalität. Modifier-Tasten mit anderen Tasten, um eine Alternative Schlüssel-code. Zugriff auf die Sondertasten, die sich durch eine high-level-Bibliothek in Linux ist nicht so einfach. Oder vielmehr, ich habe nicht gefunden, eine high-level-API für Linux.
Dachte ich libtermkey wäre die Antwort, aber es scheint nicht zu unterstützen, die Shift-Taste besser, als normalen Tastendruck abrufen. Ich bin mir auch nicht sicher, ob es funktioniert, ohne X.
Während der Arbeit mit libtermkey (bevor ich erkannte, dass es nicht bekommen Verlagerung in Fällen wie Shift-Return), ich wurde planning zu schreiben, ein daemon, die ausgeführt würde, zu sammeln, Tastatur-Ereignisse. Laufen Kopien des daemon-Programm würde einfach die Pfeife Anfragen für Tastatur-Daten und empfangen von Tastatur-Daten in der Antwort. Ich konnte mit diesem setup etwas zu haben, was immer im hintergrund läuft, falls ich nicht prüfen, Schlüssel-code-Zustände zu bestimmten Zeiten (haben, erhalten key-codes, wie Sie geschehen).
Unten sind meine zwei versuche, ein Programm zu schreiben, das Lesen kann, von den Linux-Tastatur-Gerät. Ich habe auch meinen kleinen zu überprüfen, um sicherzustellen, dass ich hatte das richtige Gerät.
Versuch #1
Habe ich versucht, Zugriff auf die Tastatur Gerät direkt, aber ich bin der Begegnung mit Fragen. Ich habe versucht den Vorschlag hier in einem anderen Stack-Overflow-thread. Es gab mir ein "segmentation fault"; so, ich habe es von fopen zu öffnen:
//...
int fd;
fd = open("/dev/input/by-path/platform-i8042-serio-0-event-kbd", O_RDONLY);
char key_map[KEY_MAX/8 + 1];
memset(key_map, 0, sizeof(key_map));
ioctl(fd, EVIOCGKEY(sizeof key_map), key_map);
//...
Zwar gab es keine "segmentation fault", es war kein Indikator für eine beliebige Taste drücken (und nicht nur modifier-keys). Getestet habe ich dies mit:
./foo && echo "TRUE" || echo "FALSE"
Habe ich verwendet, um zu testen, für eine erfolgreiche Rückkehr-codes von Befehlen, eine ganze Menge; also, ich weiß, das ist in Ordnung. Hab ich auch ausgegeben die Schlüssel (immer 0) und Maske (0100) zu überprüfen. Es funktioniert einfach nicht scheinen, nichts erkennen.
Versuch #2
Hier, ich dachte, ich würde versuchen einen etwas anderen Ansatz. Ich wollte herausfinden, was ich falsch machte. Folgende diese - Seite mit einem Ausschnitt demonstriert den Druck von wichtigen codes, die ich gebündelt in einem Programm:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <linux/input.h>
int main(int argc, char** argv) {
uint8_t keys[128];
int fd;
fd = open("/dev/input/by-path/platform-i8042-serio-event-kbd", O_RDONLY);
for (;;) {
memset(keys, 0, 128);
ioctl (fd, EVIOCGKEY(sizeof keys), keys);
int i, j;
for (i = 0; i < sizeof keys; i++)
for (j = 0; j < 8; j++)
if (keys[i] & (1 << j))
printf ("key code %d\n", (i*8) + j);
}
return 0;
}
Zuvor hatte ich die Größe von 16 bytes, anstelle von 128 bytes. Ich sollte ehrlich, verbringen ein bisschen mehr Zeit, Verständnis ioctl und EVIOCGKEY. Ich weiß nur, dass es angeblich Karten bits, um bestimmte Tasten, um anzuzeigen, drückt, oder so ähnlich (mich korrigieren, wenn ich falsch bin, bitte!!!).
Ich auch nicht über eine loop-anfangs, und würde nur halten Sie verschiedene Tasten, um zu sehen, wenn Sie einen Schlüssel-code erschien. Ich erhielt nichts; ich dachte mir, eine Schleife machen könnte, die Prüfung leichter zu testen im Falle einer verpassten etwas.
Wie ich weiß, das input-Gerät das richtige
Ich testete es, indem cat
auf dem Eingabegerät. Speziell:
$ sudo cat /dev/input/by-path/platform-i8042-serio-0-event-kbd
Müll ASCII geschickt wurde, um mein terminal auf die Taste drücken und loslassen-Ereignisse, beginnend mit der return (enter) - Taste, wenn ich begann die Ausgabe mit cat. Ich weiß auch, dass dies scheint zu funktionieren gut mit modifier-Tasten wie shift, Steuerung, Funktion, und auch apples command-Taste auf meinem Macbook läuft eine Linux-VM. Ausgabe erschienen ist, wenn eine Taste gedrückt wurde, zu erscheinen begannen rasch aus den nachfolgenden Signalen durch halten Sie die Taste gedrückt, ausgegeben mehr Daten, wenn eine Taste wurde losgelassen.
So, während mein Ansatz ist vielleicht nicht das richtige (ich bin bereit zu hören, alle alternative), das Gerät scheint das zu bieten, was ich brauche.
Außerdem, ich weiß, dass dieses Gerät ist nur ein link auf /dev/input/event2 ausgeführt:
$ ls -l /dev/input/by-path/platform-i8042-serio-0-event-kbd
Ich habe versucht beide Programme oben mit /dev/input/event2 und erhielt keine Daten. Läuft die Katze auf /dev/input/event2, sofern Sie die gleiche Ausgabe wie mit dem link.
InformationsquelleAutor der Frage Senkwich | 2014-01-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Öffnen Sie das Eingabe-Gerät,
dann Lesen Tastatur-Ereignisse aus dem Gerät:
Den obigen Schnipsel bricht aus der Schleife, wenn ein Fehler Auftritt, oder wenn die userspace-erhält nur eine partielle event-Struktur (das sollte nicht passieren, aber vielleicht in einiger Zukunft/buggy-Kernel). Sie möglicherweise verwenden möchten, ein robuster Lesen loop; ich persönlich wäre damit zufrieden, durch das ersetzen der letzten
break
mitcontinue
so dass teilweise Ereignis-Strukturen werden ignoriert.Können Sie dann prüfen, die
ev
event-Struktur, um zu sehen, was sich ereignete, und beenden Sie das Programm:Für einen Tastendruck,
ev.time
: Zeit der Veranstaltung (struct timeval
Typ)ev.type
:EV_KEY
ev.code
:KEY_*
Schlüsselkennung; siehe vollständige Liste in/usr/include/linux/input.h
ev.value
:0
wenn Taste loslassen,1
wenn die Taste drücken,2
wenn autorepeat TastendruckSehen Documentation/input/input.txt in den Linux Kernelquellen für weitere details.
Die benannten Konstanten in
/usr/include/linux/input.h
sind Recht stabil, weil es ein kernel-userspace-Schnittstelle, und die kernel-Entwickler versuchen sehr hart, die Kompatibilität zu wahren. (Das heißt, Sie können es erwarten, werden neue codes, jeden jetzt und dann, aber vorhandenen codes, die sich selten ändern.)InformationsquelleAutor der Antwort Nominal Animal