Hallo
Brauch bitte hilfe von einem der vielen C Profis hier.
Ich möchte in einem C Programm auf bestimmte Tastatur eingaben reagieren. Habe dazu ein Beispiel gefunden und es angepasst, dass es auf /dev/TTY9 horcht.
/* getkey.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
# define TERM_DEVICE "/dev/tty9"
enum
{
ERROR=-1, SUCCESS, ONEBYTE
}
;
/*Altes Terminal wiederherstellen*/
static struct termios BACKUP_TTY; /*Altes Terminal wiederherstellen*/
/* Eingabekanal wird so umge<E4>ndert, damit die Tasten einzeln */
/* abgefragt werden k<F6>nnen */
int new_tty(int fd)
{
struct termios buffer;
/* Wir fragen nach den Attributen des Terminals und <FC>bergeben */
/* diese dann an buffer. BACKUP_TTY dient bei Programmende zur */
/* Wiederherstellung der alten Attribute und bleibt unber<FC>hrt. */
if((tcgetattr(fd, &BACKUP_TTY)) == ERROR)
return ERROR;
buffer = BACKUP_TTY;
/* Lokale Flags werden gel<F6>scht : */
/* ECHO = Zeichenausgabe auf Bildschirm */
/* ICANON = Zeilenorientierter Eingabemodus */
/* ISIG = Terminal Steuerzeichen */
buffer.c_lflag = buffer.c_lflag & ~(ECHO|ICANON|ISIG);
/* VMIN=Anzahl der Bytes, die gelesen werden m<FC>ssen, bevor */
/* read() zur<FC>ckkehrt In unserem Beispiel 1Byte f<FC>r 1 Zeichen */
buffer.c_cc[VMIN] = 1;
/* Wir setzen jetzt die von uns gew<FC>nschten Attribute */
if((tcsetattr(fd, TCSAFLUSH, &buffer)) == ERROR)
return ERROR;
return SUCCESS;
}
/* Urspr<FC>ngliches Terminal wiederherstellen */
int restore_tty(int fd)
{
if((tcsetattr(fd, TCSAFLUSH, &BACKUP_TTY)) == ERROR)
return ERROR;
return SUCCESS;
}
int main(int argc, char **argv)
{
int rd, fd;
char c, buffer[10];
/* TTYx <D6>ffnen */
if ((fd = open(TERM_DEVICE, O_RDONLY)) == -1)
{
printf("terminal: Can't open device " TERM_DEVICE);
exit(EXIT_FAILURE);
}
/* Setzen des neuen Modus */
// if(new_tty(STDIN_FILENO) == ERROR)
if(new_tty(fd) == ERROR)
{
printf("Fehler bei der Funktion new_tty()\n");
exit(EXIT_FAILURE);
}
/* Erste Zeichen lesen */
//if(read(STDIN_FILENO, &c, 1) < ONEBYTE)
if(read(fd, &c, 1) < ONEBYTE)
{
printf("Fehler bei read()\n");
//restore_tty(STDIN_FILENO);
restore_tty(fd);
exit(EXIT_FAILURE);
}
/* Haben wir ein ESC ('\E') gelesen? */
if(c == 27)
{
/* Jep eine Escape-Sequenz, wir wollen den Rest */
/* der Zeichen auslesen */
// rd=read(STDIN_FILENO, buffer, 4);
rd=read(fd, buffer, 4);
/*String terminieren*/
buffer[rd]='\0';
/* Hier erfolgt die <DC>berpr<FC>fung des Tastendrucks*/
/* Wars der Pfeil-nach-oben \E[A */
if(strcmp(buffer,"[A") == SUCCESS)
printf("Pfeil-nach-oben bet<E4>tigt\n");
/* Nein, keine Escape-Sequenz */
}
else
{
if((c < 32) || (c == 127))
printf("--> %d\n",c); /* Numerischen Wert ausgeben */
else
printf("--> %c\n",c); /* Zeichen ausgeben */
}
//restore_tty(STDIN_FILENO);
restore_tty(fd);
return EXIT_SUCCESS;
}
Alles anzeigen
wenn ich normale Tasten drücke, die einen Byte senden, funktioniert es auch.
Aber wie kann ich Feststellen ob ein ESC oder F Key ... gedrückt wurde.
Die Sondertasten fangen ja alle mit einer Esc Sequenz an.
In der Funktion read(fd, &c, 1) muss ich ja wissen wie viele byte ich lesen will.
Ich kann also nie wissen ob es sich um ein Esc oder ein Sondertaste handelt.
read(fd, &c, 1) bleibt auch so lange stehen bis es die angegebene länge gelesen hat also kann ich nach einem ESC nicht nochmal read starten weil sonst bleibt das Programm stehen wenn es nur ein ESC war.
Gibt es bessere Funktionen um das zu bewekstelligen?