xref: /aosp_15_r20/external/coreboot/payloads/libpayload/curses/pdcurses-backend/pdckbd.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* Public Domain Curses */
2 
3 #include "lppdc.h"
4 #include <usb/usb.h>
5 
6 unsigned long pdc_key_modifiers = 0L;
7 
8 #if CONFIG(LP_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 
getkeyseq(char * buffer,int len,int max)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 
handle_escape(void)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 
cook_serial(unsigned char ch)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 
PDC_set_keyboard_binary(bool on)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 
PDC_check_key(void)109 bool PDC_check_key(void)
110 {
111 #if CONFIG(LP_USB_HID)
112     usb_poll();
113     if ((curses_flags & F_ENABLE_CONSOLE) &&
114         usbhid_havechar()) {
115         return TRUE;
116     }
117 #endif
118 
119 #if CONFIG(LP_PC_KEYBOARD)
120     if ((curses_flags & F_ENABLE_CONSOLE) &&
121         keyboard_havechar()) {
122         return TRUE;
123     }
124 #endif
125 
126 #if CONFIG(LP_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 
PDC_get_key(void)138 int PDC_get_key(void)
139 {
140     int c = 0;
141 
142 #if CONFIG(LP_USB_HID)
143     usb_poll();
144     if ((curses_flags & F_ENABLE_CONSOLE) &&
145         usbhid_havechar()) {
146         c = usbhid_getchar();
147     }
148 #endif
149 
150 #if CONFIG(LP_PC_KEYBOARD)
151     if ((curses_flags & F_ENABLE_CONSOLE) &&
152         keyboard_havechar() && (c == 0)) {
153         c = keyboard_getchar();
154     }
155 #endif
156 
157 #if CONFIG(LP_SERIAL_CONSOLE)
158     if ((curses_flags & F_ENABLE_SERIAL) &&
159         serial_havechar() && (c == 0)) {
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 
PDC_flushinp(void)179 void PDC_flushinp(void)
180 {
181     PDC_LOG(("PDC_flushinp() - called\n"));
182 
183     while (PDC_check_key()) PDC_get_key();
184 }
185 
PDC_mouse_set(void)186 int PDC_mouse_set(void)
187 {
188     return ERR;
189 }
190 
PDC_modifiers_set(void)191 int PDC_modifiers_set(void)
192 {
193     return OK;
194 }
195