• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)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  */
wgetch(WINDOW * win)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  */
wgetnstr(WINDOW * win,char * str,int n)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  */
echo(void)132 int echo ( void ) {
133 	m_echo = TRUE;
134 	return OK;
135 }
136 
137 /**
138  *
139  */
noecho(void)140 int noecho ( void ) {
141 	m_echo = FALSE;
142 	return OK;
143 }
144