/*
 * 02-tecla.c
 *
 * Demuestra el uso de nodelay() para obtener las teclas
 * que se apretan, sin esperar a que se toque una.
 *
 * Si toca la 'q' o Ctrl-C el programa termina.
 * Si toca la barra espaciadora, se limpia la pantalla.
 * Si no toca ninguna tecla se escibe un punto.
 */

#include <curses.h>
#include <signal.h>
#include <stdlib.h>

static void finish(int sig);

int
main(int argc, char *argv[])
{
	int num = 0;

	/* initialize your non-curses data structures here */

	(void) signal(SIGINT, finish);      /* arrange interrupts to terminate */

	(void) initscr();      /* initialize the curses library */
 	keypad(stdscr, TRUE);  /* enable keyboard mapping */
/*	nodelay(stdscr, TRUE); / * getch() is now a non-bblocking call */
	(void) nonl();         /* tell curses not to do NL->CR/NL on output */
/*	(void) cbreak();       / * take input chars one at a time, no wait for \n */
	(void) noecho();       /* sin echo input - in color */

	if (has_colors())
	{
		start_color();

		/*
		 * Simple color assignment, often all we need.  Color pair 0 cannot
		 * be redefined.  This example uses the same value for the color
		 * pair as for the foreground color, though of course that is not
		 * necessary:
		 */
		init_pair(1, COLOR_RED,     COLOR_BLACK);
		init_pair(2, COLOR_GREEN,   COLOR_BLACK);
		init_pair(3, COLOR_YELLOW,  COLOR_BLACK);
		init_pair(4, COLOR_BLUE,    COLOR_BLACK);
		init_pair(5, COLOR_CYAN,    COLOR_BLACK);
		init_pair(6, COLOR_MAGENTA, COLOR_BLACK);
		init_pair(7, COLOR_WHITE,   COLOR_BLACK);
	}

	for (;;)
	{
		int c, n;
		char * msg;
		char buf[20];
		
		while ( 'q' != (c= getch()) ) {
			if (c == ERR) {
				c= '.';
			} else {
				attrset(COLOR_PAIR(num % 8));
				num++;
			}

		if (c == ' ')
			clear();
		else
			/* process the command keystroke */
			addch(c);
		}
		if (c == 'q')
				break;

		printw("{%d} ", c);
		switch(c) {

				case KEY_F(1):		msg="F1"; break;
				case KEY_BREAK:		msg="Break key"; break;
				case KEY_DOWN:		msg="down arrow key"; break;
				case KEY_UP:		msg="up arrow key"; break;
				case KEY_LEFT:		msg="left arrow key"; break;
				case KEY_RIGHT:		msg="right arrow key"; break;
				case KEY_HOME:		msg="Home key (upward+left arrow)"; break;
				case KEY_BACKSPACE:	msg="Backspace"; break;
				case KEY_DL:		msg="Delete line"; break;
				case KEY_IL:		msg="Insert line"; break;
				case KEY_DC:		msg="Delete character"; break;
				case KEY_IC:		msg="Insert char or enter insert mode"; break;
				case KEY_EIC:		msg="Exit insert char mode"; break;
				case KEY_CLEAR:		msg="Clear screen"; break;
				case KEY_EOS:		msg="Clear to end of screen"; break;
				case KEY_EOL:		msg="Clear to end of line"; break;
				case KEY_SF:		msg="Scroll 1 line forward"; break;
				case KEY_SR:		msg="Scroll 1 line backward (reverse)"; break;
				case KEY_NPAGE:		msg="Next page"; break;
				case KEY_PPAGE:		msg="Previous page"; break;
				case KEY_STAB:		msg="Set tab"; break;
				case KEY_CTAB:		msg="Clear tab"; break;
				case KEY_CATAB:		msg="Clear all tabs"; break;
				case KEY_ENTER:		msg="Enter or send"; break;
				case KEY_SRESET:	msg="Soft (partial) reset"; break;
				case KEY_RESET:		msg="Reset or hard reset"; break;
				case KEY_PRINT:		msg="Print or copy"; break;
				case KEY_LL:		msg="Home down or bottom (lower left)"; break;
				case KEY_A1:		msg="Upper left of keypad"; break;
				case KEY_A3:		msg="Upper right of keypad"; break;
				case KEY_B2:		msg="Center of keypad"; break;
				case KEY_C1:		msg="Lower left of keypad"; break;
				case KEY_C3:		msg="Lower right of keypad"; break;
				case KEY_BTAB:		msg="Back tab key"; break;
				case KEY_BEG:		msg="Beg(inning) key"; break;
				case KEY_CANCEL:	msg="Cancel key"; break;
				case KEY_CLOSE:		msg="Close key"; break;
				case KEY_COMMAND:	msg="Cmd (command) key"; break;
				case KEY_COPY:		msg="Copy key"; break;
				case KEY_CREATE:	msg="Create key"; break;
				case KEY_END:		msg="End key"; break;
				case KEY_EXIT:		msg="Exit key"; break;
				case KEY_FIND:		msg="Find key"; break;
				case KEY_HELP:		msg="Help key"; break;
				case KEY_MARK:		msg="Mark key"; break;
				case KEY_MESSAGE:	msg="Message key"; break;
				case KEY_MOUSE:		msg="Mouse event read"; break;
				case KEY_MOVE:		msg="Move key"; break;
				case KEY_NEXT:		msg="Next object key"; break;
				case KEY_OPEN:		msg="Open key"; break;
				case KEY_OPTIONS:	msg="Options key"; break;
				case KEY_PREVIOUS:	msg="Previous object key"; break;
				case KEY_REDO:		msg="Redo key"; break;
				case KEY_REFERENCE:	msg="Ref(erence) key"; break;
				case KEY_REFRESH:	msg="Refresh key"; break;
				case KEY_REPLACE:	msg="Replace key"; break;
				case KEY_RESIZE:	msg="Screen resized"; break;
				case KEY_RESTART:	msg="Restart key"; break;
				case KEY_RESUME:	msg="Resume key"; break;
				case KEY_SAVE:		msg="Save key"; break;
				case KEY_SBEG:		msg="Shifted beginning key"; break;
				case KEY_SCANCEL:	msg="Shifted cancel key"; break;
				case KEY_SCOMMAND:	msg="Shifted command key"; break;
				case KEY_SCOPY:		msg="Shifted copy key"; break;
				case KEY_SCREATE:	msg="Shifted create key"; break;
				case KEY_SDC:		msg="Shifted delete char key"; break;
				case KEY_SDL:		msg="Shifted delete line key"; break;
				case KEY_SELECT:	msg="Select key"; break;
				case KEY_SEND:		msg="Shifted end key"; break;
				case KEY_SEOL:		msg="Shifted clear line key"; break;
				case KEY_SEXIT:		msg="Shifted exit key"; break;
				case KEY_SFIND:		msg="Shifted find key"; break;
				case KEY_SHELP:		msg="Shifted help key"; break;
				case KEY_SHOME:		msg="Shifted home key"; break;
				case KEY_SIC:		msg="Shifted input key"; break;
				case KEY_SLEFT:		msg="Shifted left arrow key"; break;
				case KEY_SMESSAGE:	msg="Shifted message key"; break;
				case KEY_SMOVE:		msg="Shifted move key"; break;
				case KEY_SNEXT:		msg="Shifted next key"; break;
				case KEY_SOPTIONS:	msg="Shifted options key"; break;
				case KEY_SPREVIOUS:	msg="Shifted prev key"; break;
				case KEY_SPRINT:	msg="Shifted print key"; break;
				case KEY_SREDO:		msg="Shifted redo key"; break;
				case KEY_SREPLACE:	msg="Shifted replace key"; break;
				case KEY_SRIGHT:	msg="Shifted right arrow"; break;
				case KEY_SRSUME:	msg="Shifted resume key"; break;
				case KEY_SSAVE:		msg="Shifted save key"; break;
				case KEY_SSUSPEND:	msg="Shifted suspend key"; break;
				case KEY_SUNDO:		msg="Shifted undo key"; break;
				case KEY_SUSPEND:	msg="Suspend key"; break;
				case KEY_UNDO:		msg="Undo key"; break;
				default:
		  /* KEY_F0	  Function keys; space for 64 keys is reserved.*/
					for (n=0; n<64; ++n)
						if( c == KEY_F(n) ) {
							sprintf(buf, "KEY_F%02d", n);
							break;
					}

					if ( n == 64 )
						msg="unknown key";
					else
						msg=(char *)buf;

		}
		printw("pepe ");
/*		printw("[%s] ", msg); */
		refresh();
	}

	finish(0);               /* we're done */
	return 0;	/*NOTREACHED*/
}

static void finish(int sig)
{
	endwin();

	/* do your non-curses wrapup here */

	exit(0);
}

/* EOF 02-tecla.c */
