4a039ffbc4d355d5e7d8f0f59edc5a691810ee30
[coreboot.git] / payloads / libpayload / curses / pdcurses-backend / pdckbd.c
1 /* Public Domain Curses */
2                           
3 #include "lppdc.h"
4 #include <usb/usb.h>
5
6 unsigned long pdc_key_modifiers = 0L;
7
8 #ifdef CONFIG_SERIAL_CONSOLE
9 /* We treat serial like a vt100 terminal.  For now we
10    do the cooking in here, but we should probably eventually
11    pass it to dedicated vt100 code */
12
13 static int getkeyseq(char *buffer, int len, int max)
14 {
15         int i;
16
17         while (1) {
18                 for(i = 0; i < 75; i++) {
19                         if (serial_havechar())
20                                 break;
21                         mdelay(1);
22                 }
23
24                 if (i == 75)
25                         return len;
26
27                 buffer[len++] = serial_getchar();
28                 if (len == max)
29                         return len;
30         }
31 }
32
33 static struct {
34         const char *seq;
35         int key;
36 } escape_codes[] = {
37         { "[A", KEY_UP },
38         { "[B", KEY_DOWN },
39         { "[C", KEY_RIGHT },
40         { "[D", KEY_LEFT },
41         { "[F", KEY_END },
42         { "[H", KEY_HOME },
43         { "[2~", KEY_IC },
44         { "[3~", KEY_DC },
45         { "[5~", KEY_PPAGE },
46         { "[6~", KEY_NPAGE },
47         { "OP", KEY_F(1) },
48         { "OQ", KEY_F(2) },
49         { "OR", KEY_F(3) },
50         { "OS", KEY_F(4) },
51         { "[15~", KEY_F(5) },
52         { "[17~", KEY_F(6) },
53         { "[18~", KEY_F(7) },
54         { "[19~", KEY_F(8) },
55         { "[20~", KEY_F(9) },
56         { "[21~", KEY_F(10) },
57         { "[23~", KEY_F(11) },
58         { "[24~", KEY_F(12) },
59         { NULL },
60 };
61
62 static int handle_escape(void)
63 {
64         char buffer[5];
65         int len = getkeyseq(buffer, 0, sizeof(buffer));
66         int i, t;
67
68         if (len == 0)
69                 return 27;
70
71         for(i = 0; escape_codes[i].seq != NULL; i++) {
72                 const char *p = escape_codes[i].seq;
73
74                 for(t = 0; t < len; t++) {
75                         if (!*p || *p != buffer[t])
76                                 break;
77                         p++;
78                 }
79
80                 if (t == len)
81                         return escape_codes[i].key;
82         }
83
84         return 0;
85 }
86
87 static int cook_serial(unsigned char ch)
88 {
89         switch(ch) {
90         case 8:
91                 return KEY_BACKSPACE;
92
93         case 27:
94                 return handle_escape();
95
96         default:
97                 return ch;
98         }
99 }
100 #endif
101
102 void PDC_set_keyboard_binary(bool on)
103 {
104     PDC_LOG(("PDC_set_keyboard_binary() - called\n"));
105 }
106
107 /* check if a key event is waiting */
108
109 bool PDC_check_key(void)
110 {
111 #ifdef CONFIG_USB_HID
112     usb_poll();
113     if ((curses_flags & F_ENABLE_CONSOLE) &&
114         usbhid_havechar()) {
115         return TRUE;
116     }
117 #endif
118
119 #ifdef CONFIG_PC_KEYBOARD
120     if ((curses_flags & F_ENABLE_CONSOLE) &&
121         keyboard_havechar()) {
122         return TRUE;
123     }
124 #endif
125
126 #ifdef CONFIG_SERIAL_CONSOLE
127     if ((curses_flags & F_ENABLE_SERIAL) &&
128         serial_havechar()) {
129         return TRUE;
130     }
131 #endif
132
133     return FALSE;
134 }
135
136 /* return the next available key event */
137
138 int PDC_get_key(void)
139 {
140     int c = 0;
141
142 #ifdef CONFIG_USB_HID
143     usb_poll();
144     if ((curses_flags & F_ENABLE_CONSOLE) &&
145         usbhid_havechar()) {
146         c = usbhid_getchar();
147     }
148 #endif
149
150 #ifdef CONFIG_PC_KEYBOARD
151     if ((curses_flags & F_ENABLE_CONSOLE) &&
152         keyboard_havechar()) {
153         c = keyboard_getchar();
154     }
155 #endif
156
157 #ifdef CONFIG_SERIAL_CONSOLE
158     if ((curses_flags & F_ENABLE_SERIAL) &&
159         serial_havechar()) {
160         c = cook_serial(serial_getchar());
161     }
162 #endif
163
164     SP->key_code = FALSE;
165
166     if (c == 0) {
167         c = ERR;
168     }
169     if (c >= KEY_MIN) {
170         SP->key_code = TRUE;
171     }
172
173     return c;
174 }
175
176 /* discard any pending keyboard input -- this is the core 
177    routine for flushinp() */
178
179 void PDC_flushinp(void)
180 {
181     PDC_LOG(("PDC_flushinp() - called\n"));
182
183     while (PDC_check_key()) PDC_get_key();
184 }
185
186 int PDC_mouse_set(void)
187 {
188     return ERR;
189 }
190
191 int PDC_modifiers_set(void)
192 {
193     return OK;
194 }