Home | History | Annotate | Download | only in mucurses
      1 #include <curses.h>
      2 #include <stddef.h>
      3 #include <unistd.h>
      4 #include "mucurses.h"
      5 
      6 /** @file
      7  *
      8  * MuCurses keyboard input handling functions
      9  */
     10 
     11 #define INPUT_DELAY 		200 // half-blocking delay timer resolution (ms)
     12 #define INPUT_DELAY_TIMEOUT 	1000 // half-blocking delay timeout
     13 
     14 int m_delay; /*
     15 		< 0 : blocking read
     16 		0   : non-blocking read
     17 		> 0 : timed blocking read
     18 	     */
     19 bool m_echo;
     20 bool m_cbreak;
     21 
     22 static int _wgetc ( WINDOW *win ) {
     23 	int timer, c;
     24 
     25 	if ( win == NULL )
     26 		return ERR;
     27 
     28 	timer = INPUT_DELAY_TIMEOUT;
     29 	while ( ! win->scr->peek( win->scr ) ) {
     30 		if ( m_delay == 0 ) // non-blocking read
     31 			return ERR;
     32 		if ( timer > 0 ) {  // time-limited blocking read
     33 			if ( m_delay > 0 )
     34 				timer -= INPUT_DELAY;
     35 			mdelay( INPUT_DELAY );
     36 		} else { return ERR; } // non-blocking read
     37 	}
     38 
     39 	c = win->scr->getc( win->scr );
     40 
     41 	if ( m_echo && ( c >= 32 && c <= 126 ) ) // printable ASCII characters
     42 		_wputch( win, (chtype) ( c | win->attrs ), WRAP );
     43 
     44 	return c;
     45 }
     46 
     47 /**
     48  * Pop a character from the FIFO into a window
     49  *
     50  * @v *win	window in which to echo input
     51  * @ret c	char from input stream
     52  */
     53 int wgetch ( WINDOW *win ) {
     54 	int c;
     55 
     56 	c = _wgetc( win );
     57 
     58 	if ( m_echo ) {
     59 		if ( c >= KEY_MIN ) {
     60 			switch(c) {
     61 			case KEY_LEFT :
     62 			case KEY_BACKSPACE :
     63 				_wcursback( win );
     64 				wdelch( win );
     65 				break;
     66 			default :
     67 				beep();
     68 				break;
     69 			}
     70 		} else {
     71 			_wputch( win, (chtype)( c | win->attrs ), WRAP );
     72 		}
     73 	}
     74 
     75 	return c;
     76 }
     77 
     78 /**
     79  * Read at most n characters from the FIFO into a window
     80  *
     81  * @v *win	window in which to echo input
     82  * @v *str	pointer to string in which to store result
     83  * @v n		maximum number of characters to read into string (inc. NUL)
     84  * @ret rc	return status code
     85  */
     86 int wgetnstr ( WINDOW *win, char *str, int n ) {
     87 	char *_str;
     88 	int c;
     89 
     90 	if ( n == 0 ) {
     91 		str = '\0';
     92 		return OK;
     93 	}
     94 
     95 	_str = str;
     96 
     97 	while ( ( c = _wgetc( win ) ) != ERR ) {
     98 		/* termination enforcement - don't let us go past the
     99 		   end of the allocated buffer... */
    100 		if ( n == 0 && ( c >= 32 && c <= 126 ) ) {
    101 			_wcursback( win );
    102 			wdelch( win );
    103 		} else {
    104 			if ( c >= KEY_MIN ) {
    105 				switch(c) {
    106 				case KEY_LEFT :
    107 				case KEY_BACKSPACE :
    108 					_wcursback( win );
    109 					wdelch( win );
    110 					break;
    111 				case KEY_ENTER :
    112 					*_str = '\0';
    113 					return OK;
    114 				default :
    115 					beep();
    116 					break;
    117 				}
    118 			}
    119 			if ( c >= 32 && c <= 126 ) {
    120 				*(_str++) = c; n--;
    121 			}
    122 		}
    123 	}
    124 
    125 	return ERR;
    126 }
    127 
    128 
    129 /**
    130  *
    131  */
    132 int echo ( void ) {
    133 	m_echo = TRUE;
    134 	return OK;
    135 }
    136 
    137 /**
    138  *
    139  */
    140 int noecho ( void ) {
    141 	m_echo = FALSE;
    142 	return OK;
    143 }
    144