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