STRG - Tastendruck Curses

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Hallo liebes Forum,

Ich habe da mal eine Frage zu Curses:

das abfangen von Tasten die gedrückt werden ist soweit ja kein Problem.
STRG+Buchstabe ergibt auch eine andere Taste als nur Buchstabe.

Ich würde aber gerne darauf reagieren wenn jemand nur die STRG-Taste drückt, und wenn er sie wieder los lässt.
Sprich: ich möchte, dass mein Programm Teile des Bildschirms ändert um darauf aufmerksam zu machen, dass mit STRG-Kombination andere Eingaben möglich sind.

Kann mir da jemand weiterhelfen?

Gruß
sparrow
jtk
User
Beiträge: 37
Registriert: Montag 19. November 2007, 17:16

beim "spiel" overkill (ascii art shooter) wird im Textmodus die strg taste abgefangen, in der graphik aber nicht
da müsste also im source stehen, wie das geht,
mit getkey oder getch hab ichs nicht geschafft :(
jtk
User
Beiträge: 37
Registriert: Montag 19. November 2007, 17:16

der benutzt da aber et curses - und leider muss ein terminal die ctrltaste nur in kombi auswerten, also geht es auf "normalem" wege nicht

ich will dich nicht entmutigen, wenn du was findest würde es mich interessieren!:)
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

STRG+Taste ergeben einen eigenen Keycode.
Aber eine Möglichkeit zu erfahren wann eine Taste gedrückt und wann freigegeben wird habe ich noch nicht gefunden.

Ich forsche weiter :)
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Für curses ist das lediglich ein MODIFIER, d.h. Ctrl, Alt, Shift ergeben für sich keine Keycodes. Das muss anders gelöst werden.
ichisich
User
Beiträge: 134
Registriert: Freitag 1. Januar 2010, 11:52

Hi,

falls es plattformabhängig sein darf fällt mir
pyHook ein (Windows).
Bin ich mal drüber gestolpert hab es selber aber noch nie benutzt.
Hab gerade gesehen das es hier im Forum auch schon Diskussionen dazu gab.

Gruß
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

@ichisich
Ist curses nicht schon Unix abhängig ?
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
ichisich
User
Beiträge: 134
Registriert: Freitag 1. Januar 2010, 11:52

Hatte ich nicht drüber nachgedacht.

Dem ist so.

Somit war mein Vorschlag für die Katz ;-)

Nichts für ungut :K
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Curses-Terminals setzen auf dem ACSII-Modus (xlate) auf, d.h. die Auswertung der scan codes (raw) geschieht innerhalb des Tastaturtreibers (kernelseitig). Der Druck eines einzelnen modifier keys wird curses (oder besser dem Terminal) nicht mitgeteilt. Vielmehr setzt der Treiber ein entsprechendes Flag und erst mit dem Druck einer zweiten Taste wird ein Zeichen generiert, welches am Terminal ankommt.
Terminals sind für den Austausch von kodierten Zeichen (ASCII) konzipiert worden (von Fernschreibern herkommend - tty), daher macht es Sinn, die Tasten standardmäßig als ASCII-Zeichen weiterzureichen. Die Steuerkommandos des Terminals sind dann nichts weiter als eine bestimmte Abfolge von Zeichen, die das Terminal entsprechend interpretiert. Das Terminal selbst unterstützt eine Reihe von Arbeitsmodi, mit denen Funktionalität hinzu- oder abgeschaltet werden können. So weist z.B. das kanonische Flag (ICANON) das Terminal an, den internen Zeilerpuffer zu verwenden und die Eingabe erst mit dem Zeilenende an die Anwendung weiterzugeben.
Bibliotheken wie curses "bügeln" die Funktionvielfalt und Eigenheiten der Terminals halbwegs glatt. Hierzu wird in der Regel die Eingabe auf "dumm" gestellt (raw-Modus des Terminals - Zeichen werden 1:1 weitergegeben) und die Ausgabe wird terminaltypgerecht aufbereitet (mit Escapecodes versehen usw.).

Zurück zu Deiner Frage:
Mit ioctl() kann man das Terminal anweisen, nicht die ASCII-Kodierung sondern die scan codes (raw) oder die key codes (medium raw) vom Tastaturtreiber zu erhalten. Der Raw-Modus der Tastatureingabe ist nicht zu verwechseln mit dem raw-Modus des Terminals. Ersteres entscheidet darüber, wie das Terminal die Eingabe erhält, letzteres was es mit der Eingabe macht.

Mit dem Befehl showkey kannst Du an der Shell testen, ob Deine Konfiguration überhaupt den Eingriff in den Tastaturtreiber zulässt. Im Quellcode findest Du auch die nötige Vorgehensweise.

Ich weiss leider nicht, inwieweit die Sache per POSIX standardisiert ist. Es kann daher sein, dass das nur für Linux gilt, oder scan und key codes plattformabhängig sind. Windows geht hier einen ganz anderen Weg, da Du aber von curses sprachst, hab ich das aussen vor gelassen.

Edit:
Hab grad mal nachgeschaut, zumindest im Teil der Terminalspezifikation von POSIX konnte ich nichts über eine Standardisierung der Tastatureingabe finden. Falls nicht alle Unices von einander abgeschrieben haben, dürften die codes und die Zugriffsmöglichkeit hierauf sehr verschieden sein.

Edit2:
Fast hätt ichs vergessen - unter X kommst du so nicht zum Ziel, da X seinerseits an der Systemkonsole (/dev/console) im raw-Modus lauscht und die scan modes in Events übersetzt. Du könntest aber die Keyboardevents im X abfangen. Ob die ganze Sache den Aufwand wert ist, musst Du selber wissen. ;)
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Hallo Jerch,

vielen Dank für deine ausführliche Antwort.

Zum Einsatz von curses: ich will ein Programm schreiben, dass ohne große Abhängigkeiten in der Konsole eines *nix laufen kann. Gut, man kann jetzt darüber streiten ob Python eine große Abhängigkeit ist, aber Just for Fun werkel ich im Augenblick lieber unter Python als in C oder C++.
Windows muss das nicht unterstützen, vor allem auch weil es viel mit dem Dateisystem tun wird, und da eh zu große Unterschiede zwischen der Posix- und der Windows-Welt gibt.

Das Programm soll unabhängig von X arbeiten können, sonst könnte ich auch direkt auf ein Toolkit ausweichen. Es soll aber vor allem die Arbeit in der Shell vereinfachen. Ich mag ja Fenster und nettes aussehen, aber auf Servern ist das nicht immer der Fall und da soll das Programm im Zweifelsfall auch laufen.


Gruß
Sparrow
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Unter X sind auch die Terminalemulatoren betroffen. Falls Du lokal root-Rechte hast, kannst Du showkey ja mal ausprobieren unter X. Du solltest allerdings vorher alle Daten speichern und ein sync machen, da Du X höchstwahrscheinlich neu starten musst. Während showkey als root läuft, bekommt X keine Eingabe mehr - das hilft Dir nicht weiter.
Im Prinzip erhalten xterm & Co die Eingabe über X:
- X startet und heftet sich an /dev/console (im raw-Modus)
- Du startest xterm
- X liest Tastureingabe von /dev/console und generiert keyboard event
- X routet Fokusregeln entsprechend die Events zum Zielclient (hier xterm)
- Client wertet Events aus (Terminalemulator fragt Events ab und generiert nach eigenem Regelset Zeichen, die in den Master des Pseudoterminals geschrieben werden)
- Shell/Anwendung XY am Slave kann die Eingabe nun erhalten
Die Übersetzung der XEvents passiert viel früher, nämlich im Terminalemulator selbst. Abhilfe schafft da ein eigener Terminalemulator ;)

@remote:
Über ssh geht das leider auch nicht, da das Terminal ASCII ;) weiterreicht. Pseudoterminals erhalten generell nur indirekt die Tastatureingabe über /dev/console (unter Linux).

Ich würde Dir raten, von einer solche Funktionalität abzusehen. Die Implementation ist viel zu schwierig umzusetzen und der Gewinn an Bedienkomfort marginal.
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Hallo Jerch,

nochmal vielen Dank für deine Mühe.

Ich schätze ich werde das einfach so lösen, dass ich Optionale Funktionen so einbinde, dass ich mit den Funktionstasten zwischen den "Menüs" hin und her springen kann.
Das ist dann leicht veränderte User-Experience... aber hey, wir sind in einem Terminal.


Gruß
Sparrow
Antworten