#include <stdio.h>
#include <unistd.h>
#include <termios.h>

enum{ERROR=-1,SUCCESS,ONEBYTE};

static struct termios BACKUP_TTY; /*Altes Terminal wiederherstellen*/


/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/

/*Eingabekanal wird so umgeändert damit die Tasten einzeln*/
/*abgefragt werden können*/

int new_tty(int fd)
{
 struct termios buffer;

/*Wir erfragen nach den Attributen des Terminals und übergeben diese*/
/*dann an buffer. BACKUP_TTY dient bei Programmende zur wiederherstellung*/
/* der alten Attribute und bleibt somit unberührt.*/

 if((tcgetattr(fd, &BACKUP_TTY)) == ERROR)
     return ERROR;

 buffer = BACKUP_TTY;

/*Lokale Flags werden gelö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üssen, bevor read() zurückkehrt*/
/*   In unserem Beispiel 1Byte für 1 Zeichen*/

 buffer.c_cc[VMIN] = 1;

/*Wir setzen jetzt die von uns gewünschten Attribute*/

 if((tcsetattr(fd, TCSAFLUSH, &buffer)) == ERROR)
     return ERROR;

 return SUCCESS;
}

/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/

/*Ursprüngliches Terminal wiederherstellen*/

int restore_tty(int fd)
{
 if((tcsetattr(fd, TCSAFLUSH, &BACKUP_TTY)) == ERROR)
    return ERROR;

 return SUCCESS;
}

/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/

int main(int argc, char **argv)
{
 int rd;
 char c, buffer[10];

/*Setzen des neuen Modus*/

 if(new_tty(STDIN_FILENO) == ERROR)
   {
     printf("Fehler bei der Funktion new_tty().....\n");
     exit(0);
   }

/*Erste Zeichen lesen*/

 if(read(STDIN_FILENO, &c, 1) < ONEBYTE)
   {
     printf("Fehler bei read.....\n");
     restore_tty(STDIN_FILENO);
     exit(0);
   }


/*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);
     buffer[rd]='\0';        /*String terminieren*/

/*Folgende Werte haben die Funktionstasten in der Term */
/*   F1 = \E[[A  */
/*   F2 = \E[[B   */
/*   PFEIL RECHTS= \E[C  */
/*   PFEIL LINKS = \E[D  */
/*   PFEIL RUNTER= \E[B  */
/*   PFEIL HOCH = \E[A   */
/*   POS 1 = \E[1~       */
/*   BILD RUNTER = \E[6~ */
/*   BILD HOCH = \E[5~ */

     if(strcmp(buffer,"[[A") == SUCCESS)
          printf("F1\n");
     if(strcmp(buffer,"[[B") == SUCCESS)
         printf("F2\n");
      if(strcmp(buffer,"[C") == SUCCESS)
         printf("->\n");
      if(strcmp(buffer,"[D") == SUCCESS)
         printf("<-\n");
      if(strcmp(buffer,"[B") == SUCCESS)
         printf("V\n");
      if(strcmp(buffer,"[A") == SUCCESS)
         printf("^\n");
      if(strcmp(buffer,"[1~") == SUCCESS)
         printf("POS 1\n");
      if(strcmp(buffer,"[6~") == SUCCESS)
         printf("BILD RUNTER\n");
      if(strcmp(buffer,"[5~") == SUCCESS)
         printf("BILD HOCH\n");

/*Nein kein ESC..............*/
   }
 else
   {
     if((c<32) || (c==127))
          printf("%d\n",c); /*Numerischen Wert Ausgeben*/
     else
          printf("%c\n",c); /*Zeichen ausgeben*/
   }
 restore_tty(STDIN_FILENO);

 return SUCCESS;
}
