#include <termios.h>
#include <stdio.h>

static struct termios old, new;

/* Initialize new terminal i/o settings */
void initTermios(int echo) 
{
  tcgetattr(0, &old);           /* toma la configuración antigua de i/o de la terminal (grab old terminal i/o settings) */
  new = old;                    /* genera una nueva estructura de configuración igual a la antigua (make new settings same as old settings) */
  new.c_lflag &= ~ICANON;       /* disable buffered i/o */
  if (echo) {
      new.c_lflag |= ECHO;      /* setea en ON el modo ECO (set echo mode) */
  } else {
      new.c_lflag &= ~ECHO;     /* setea en Off el modo ECO (set no echo mode) */
  }
  tcsetattr(0, TCSANOW, &new);  /* setea la terminal con los nuevos atributos (use these new terminal i/o settings now) */
}

/* Resetea la terminal a la configuración antigua (Restore old terminal i/o settings) */
void resetTermios(void) 
{
  tcsetattr(0, TCSANOW, &old);
}

/* Read 1 character - echo defines echo mode */
char getch_(int echo) 
{
  char ch;
  initTermios(echo);            /* inicializa la terminal con el modo de ECO pasado como parametro */
  ch = getchar();               /* lee un nuevo caracter */
  resetTermios();               /* restaura la terminal a su configuracion previa a la ejecucion del programa */
  return ch;                    
}

/* Read 1 character without echo */
char getch(void) 
{
  return getch_(0);
}

/* Read 1 character with echo */
char getche(void) 
{
  return getch_(1);
}

/* Let's test it out */
int main(void) {
  char c;
  printf("(getche example) please type a letter: ");
  c = getche();                 /* la funcion getche() lee un caracter con ECO */
  printf("\nYou typed: %c\n", c);
  printf("(getch example) please type a letter...");
  c = getch();                  /* la funcion getch() lee un caracter sin ECO */
  printf("\nYou typed: %c\n", c);
  return 0;
} 
