Keyboard- und Tastencodes
« | 15 Apr 2023 | »A
bis Z
und 0
bis 9
wird von jedem OS auf
ASCII
bzw. Unicodezeichen abgebildet.
Das gilt auch für die Konsole.
Aber wie bekommt man z.B. Pfeiltasten per read(stdin)
geliefert?
Meine uralten Basic-Beispiele machten sich die Sache für kleine Spielchen leicht: Man ging vom Zahlenblock aus und nutzte die Tasten
2
herunter4
links6
rechts8
hinauf
So umging man schon unter DOS die interessante Frage, wie man eigentlich an die “richtigen” Pfeiltasten kommt.
Leider ist das alles andere als einfach … oder anders gesagt, es hängt vom OS ab. Im C Standard sind solche Tastenübersetzungen jedenfalls nicht definiert.
BIOS und DOS
Im PC BIOS und nachfolgend auch unter
DOS wurden solche Tastenanschläge in zwei-Bytes-Sequenzen kodiert.
Das erste Byte zeigte an, dass das nachfolgende Byte eine Spezialtaste war.
Und so ergeben sich z.B.: für die Pfeiltasten:
- Up:
00
und72
- Down:
00
und80
- Left:
00
und75
- Right:
00
und77
Windows
Die Windows Konsole reagiert hier “eigen”, denn ein normales ReadFile(STDIN)
interpretiert die Tasten nicht, das Konsolenfenster jedoch schon und
“verbessert” eigenmächtig das UI, indem es eine History der letzten Eingaben
über die Pfeiltasten auslesen lässt.
Man kann jedoch über die Konsolen-API
ReadConsoleInput
alle Tastenereignisse abfangen und selbst interpretieren. Was sich nach
Unicode abbilden lässt, erledigt Windows für uns, doch Sondertasten
bekommen den Wert 0
.
In dem Fall muss man den VKEY
-Code interpretieren, der mitgeliefert wird und
dort haben so gut wie alle üblichen Tasten eine Entsprechung.
POSIX (Linux)
Unix Varianten treten das Erbe von VT-100 an und kodieren Sondertasten mit Escape-Sequenzen
- Up:
0x1b 0x5b 0x41
=^[[A
- Down:
0x1b 0x5b 0x42
=^[[B
- Right:
0x1b 0x5b 0x43
=^[[C
- Left:
0x1b 0x5b 0x44
=^[[D
Schlimmer ist hier, dass die Standard-Konsole auf ENTER
wartet, bevor ein
read(STDIN)
Eingaben lasen kann.
Um also einzelne Tasten direkt lesen zu können, muss man über termios.h
und
tcsetattr() die “Line-Discipline”
ausschalten. Das wichtigste auszuschaltende Flag heißt ICANON
.
Danach kann man die Escape-Sequenzen selbst abprüfen.
GATE Implementierung
Einerseits sollte die Konsolen-API genau die Zeichen zurückgeben, die das System liefert. Andererseits sind abstrakte Symbole für z.B. die Pfeiltasten aber sehr notwendig um portable Programme zu schreiben.
Der Kompromiss sieht also so aus, dass es eine native Schnittstelle zum Lesen einzelner Zeichen gibt und einen “Input-Parser”, der aus den nativen Zeichen wieder Tastenanschläge zusammensetzt.
Für DOS und Linux war das relative einfach, weil man direkte Mapping-Tabellen für die Zeichenübersetzung erstellen kann.
Windows hingegen verdoppelte den Aufwand, denn zuerst musste ich mal die
VKEYS
in Unicode-Zeichen umwandeln, bevor diese dann per Mapping-Tabelle
in abstrakte Tasten konvertiert werden können.
Ich entschied mich für die neuen Icon-Zeichen in Unicode, wo die
Pfeiltasten-VKeys auf grafische Pfeile abgebildet werden, denn ich glaube
nicht, dass es in naher Zukunft Tastaturen geben wird, die diese Zeichencodes
direkt antippbar bereitstellen werden.
Fazit
Der kleinste gemeinsame Nenner zwischen mehreren Systemen wird bei solchen Aufgaben unerwartet groß, soll heißen: Die Unterschiede sind sehr groß.
Meine Erwartung, dass es einen übergreifenden Standard gibt, hat sich nicht erfüllt.
Aber mit etwas Aufwand und 4 separaten Implementierungen (Windows, POSIX, DOS und EFI) habe ich nun meine eigene Konsolen- und Tastaturschnittstelle geschaffen, die für mein Vorhaben ausreicht.