Keyboard- und Tastencodes

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 herunter
  • 4 links
  • 6 rechts
  • 8 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 und 72
  • Down: 00 und 80
  • Left: 00 und 75
  • Right: 00 und 77

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.

📧 📋 🐘 | 🔔
 

Meine Dokus über:
 
Weitere externe Links zu:
Alle extern verlinkten Webseiten stehen nicht in Zusammenhang mit opengate.at.
Für deren Inhalt wird keine Haftung übernommen.



Wenn sich eine triviale Erkenntnis mit Dummheit in der Interpretation paart, dann gibt es in der Regel Kollateralschäden in der Anwendung.
frei zitiert nach A. Van der Bellen
... also dann paaren wir mal eine komplexe Erkenntnis mit Klugheit in der Interpretation!