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 _wgetc(WINDOW * win)22static 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 */ wgetch(WINDOW * win)53int 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 */ wgetnstr(WINDOW * win,char * str,int n)86int 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 */ echo(void)132int echo ( void ) { 133 m_echo = TRUE; 134 return OK; 135 } 136 137 /** 138 * 139 */ noecho(void)140int noecho ( void ) { 141 m_echo = FALSE; 142 return OK; 143 } 144