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