8f46bf67b9b373e3a648ee51160a9fa1dd6fc992
[people/indolent/gpxe.git/.git] / src / hci / mucurses / kb.c
1 #include <curses.h>
2 #include <stddef.h>
3 #include <timer.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 static bool m_echo;
20 bool m_cbreak;
21
22 #if 0
23 /**
24  * Check KEY_ code supported status
25  *
26  * @v kc        keycode value to check
27  * @ret TRUE    KEY_* supported
28  * @ret FALSE   KEY_* unsupported
29  */
30 int has_key ( int kc __unused ) {
31         return TRUE;
32
33 #endif
34
35 static
36 int _wgetc ( WINDOW *win ) {
37         int timer, c;
38
39         if ( win == NULL )
40                 return ERR;
41
42         timer = INPUT_DELAY_TIMEOUT;
43         while ( ! win->scr->peek( win->scr ) ) {
44                 if ( m_delay == 0 ) // non-blocking read
45                         return ERR;
46                 if ( timer > 0 ) {  // time-limited blocking read
47                         if ( m_delay > 0 )
48                                 timer -= INPUT_DELAY;
49                         mdelay( INPUT_DELAY );
50                 } else { return ERR; } // non-blocking read
51         }
52
53         c = win->scr->getc( win->scr );
54
55         if ( m_echo && ( c >= 32 && c <= 126 ) ) // printable ASCII characters
56                 _wputch( win, (chtype) ( c | win->attrs ), WRAP );
57
58         return c;
59 }
60
61 /**
62  * Pop a character from the FIFO into a window
63  *
64  * @v *win      window in which to echo input
65  * @ret c       char from input stream
66  */
67 int wgetch ( WINDOW *win ) {
68         int c;
69
70         c = _wgetc( win );
71
72         if ( m_echo ) {
73                 if ( c >= KEY_MIN ) {
74                         switch(c) {
75                         case KEY_LEFT :
76                         case KEY_BACKSPACE :
77                                 _wcursback( win );
78                                 wdelch( win );
79                                 break;
80                         default :
81                                 beep();
82                                 break;
83                         }
84                 } else {
85                         _wputch( win, (chtype)( c | win->attrs ), WRAP );
86                 }
87         }
88
89         return c;
90 }
91
92 /**
93  * Read at most n characters from the FIFO into a window
94  *
95  * @v *win      window in which to echo input
96  * @v *str      pointer to string in which to store result
97  * @v n         maximum number of characters to read into string (inc. NUL)
98  * @ret rc      return status code
99  */
100 int wgetnstr ( WINDOW *win, char *str, int n ) {
101         char *_str;
102         int c;
103
104         if ( n == 0 ) {
105                 str = '\0';
106                 return OK;
107         }
108
109         _str = str;
110
111         while ( ( c = _wgetc( win ) ) != ERR ) {
112                 /* termination enforcement - don't let us go past the
113                    end of the allocated buffer... */
114                 if ( n == 0 && ( c >= 32 && c <= 126 ) ) {
115                         _wcursback( win );
116                         wdelch( win );
117                 } else {
118                         if ( c >= KEY_MIN ) {
119                                 switch(c) {
120                                 case KEY_LEFT :
121                                 case KEY_BACKSPACE :
122                                         _wcursback( win );
123                                         wdelch( win );
124                                         break;
125                                 case KEY_ENTER :
126                                         *_str = '\0';
127                                         return OK;
128                                 default :
129                                         beep();
130                                         break;
131                                 }
132                         }
133                         if ( c >= 32 && c <= 126 ) {
134                                 *(_str++) = c; n--;
135                         }
136                 }
137         }
138
139         return ERR;
140 }
141
142
143 /**
144  *
145  */
146 int echo ( void ) {
147         m_echo = TRUE;
148         return OK;
149 }
150
151 /**
152  *
153  */
154 int noecho ( void ) {
155         m_echo = FALSE;
156         return OK;
157 }