drivers/wifi: Remove unnecessary data structure copy
[coreboot2.git] / payloads / libpayload / curses / PDCurses / dos / pdckbd.c
blobc44393fc0f859049cab55c38fcd089de5ff3aae6
1 /* Public Domain Curses */
3 /* MS C doesn't return flags from int86() */
4 #ifdef MSC
5 # define USE_KBHIT
6 #endif
8 #ifdef USE_KBHIT
9 # include <conio.h>
10 #endif
12 #include "pdcdos.h"
14 RCSID("$Id: pdckbd.c,v 1.87 2008/07/13 16:08:17 wmcbrine Exp $")
16 /*man-start**************************************************************
18 Name: pdckbd
20 Synopsis:
21 unsigned long PDC_get_input_fd(void);
23 Description:
24 PDC_get_input_fd() returns the file descriptor that PDCurses
25 reads its input from. It can be used for select().
27 Portability X/Open BSD SYS V
28 PDC_get_input_fd - - -
30 **man-end****************************************************************/
32 #ifdef __DJGPP__
33 # include <fcntl.h>
34 # include <io.h>
35 # include <signal.h>
36 #endif
38 /************************************************************************
39 * Table for key code translation of function keys in keypad mode *
40 * These values are for strict IBM keyboard compatibles only *
41 ************************************************************************/
43 static short key_table[] =
45 -1, ALT_ESC, -1, 0,
46 -1, -1, -1, -1,
47 -1, -1, -1, -1,
48 -1, -1, ALT_BKSP, KEY_BTAB,
49 ALT_Q, ALT_W, ALT_E, ALT_R,
50 ALT_T, ALT_Y, ALT_U, ALT_I,
51 ALT_O, ALT_P, ALT_LBRACKET, ALT_RBRACKET,
52 ALT_ENTER, -1, ALT_A, ALT_S,
53 ALT_D, ALT_F, ALT_G, ALT_H,
54 ALT_J, ALT_K, ALT_L, ALT_SEMICOLON,
55 ALT_FQUOTE, ALT_BQUOTE, -1, ALT_BSLASH,
56 ALT_Z, ALT_X, ALT_C, ALT_V,
57 ALT_B, ALT_N, ALT_M, ALT_COMMA,
58 ALT_STOP, ALT_FSLASH, -1, ALT_PADSTAR,
59 -1, -1, -1, KEY_F(1),
60 KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5),
61 KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9),
62 KEY_F(10), -1, -1, KEY_HOME,
63 KEY_UP, KEY_PPAGE, ALT_PADMINUS, KEY_LEFT,
64 KEY_B2, KEY_RIGHT, ALT_PADPLUS, KEY_END,
65 KEY_DOWN, KEY_NPAGE, KEY_IC, KEY_DC,
66 KEY_F(13), KEY_F(14), KEY_F(15), KEY_F(16),
67 KEY_F(17), KEY_F(18), KEY_F(19), KEY_F(20),
68 KEY_F(21), KEY_F(22), KEY_F(25), KEY_F(26),
69 KEY_F(27), KEY_F(28), KEY_F(29), KEY_F(30),
70 KEY_F(31), KEY_F(32), KEY_F(33), KEY_F(34),
71 KEY_F(37), KEY_F(38), KEY_F(39), KEY_F(40),
72 KEY_F(41), KEY_F(42), KEY_F(43), KEY_F(44),
73 KEY_F(45), KEY_F(46), -1, CTL_LEFT,
74 CTL_RIGHT, CTL_END, CTL_PGDN, CTL_HOME,
75 ALT_1, ALT_2, ALT_3, ALT_4,
76 ALT_5, ALT_6, ALT_7, ALT_8,
77 ALT_9, ALT_0, ALT_MINUS, ALT_EQUAL,
78 CTL_PGUP, KEY_F(11), KEY_F(12), KEY_F(23),
79 KEY_F(24), KEY_F(35), KEY_F(36), KEY_F(47),
80 KEY_F(48), CTL_UP, CTL_PADMINUS, CTL_PADCENTER,
81 CTL_PADPLUS, CTL_DOWN, CTL_INS, CTL_DEL,
82 CTL_TAB, CTL_PADSLASH, CTL_PADSTAR, ALT_HOME,
83 ALT_UP, ALT_PGUP, -1, ALT_LEFT,
84 -1, ALT_RIGHT, -1, ALT_END,
85 ALT_DOWN, ALT_PGDN, ALT_INS, ALT_DEL,
86 ALT_PADSLASH, ALT_TAB, ALT_PADENTER, -1
89 unsigned long pdc_key_modifiers = 0L;
91 static struct {unsigned short pressed, released;} button[3];
93 static bool mouse_avail = FALSE, mouse_vis = FALSE, mouse_moved = FALSE,
94 mouse_button = FALSE, key_pressed = FALSE;
96 static unsigned char mouse_scroll = 0;
97 static PDCREGS ms_regs, old_ms;
98 static unsigned short shift_status, old_shift = 0;
99 static unsigned char keyboard_function = 0xff, shift_function = 0xff,
100 check_function = 0xff;
102 static const unsigned short button_map[3] = {0, 2, 1};
104 unsigned long PDC_get_input_fd(void)
106 PDC_LOG(("PDC_get_input_fd() - called\n"));
108 return (unsigned long)fileno(stdin);
111 void PDC_set_keyboard_binary(bool on)
113 PDC_LOG(("PDC_set_keyboard_binary() - called\n"));
115 #ifdef __DJGPP__
116 setmode(fileno(stdin), on ? O_BINARY : O_TEXT);
117 signal(SIGINT, on ? SIG_IGN : SIG_DFL);
118 #endif
121 /* check if a key or mouse event is waiting */
123 bool PDC_check_key(void)
125 PDCREGS regs;
127 if (shift_function == 0xff)
129 int scan;
131 /* get shift status for all keyboards */
133 regs.h.ah = 0x02;
134 PDCINT(0x16, regs);
135 scan = regs.h.al;
137 /* get shift status for enhanced keyboards */
139 regs.h.ah = 0x12;
140 PDCINT(0x16, regs);
142 if (scan == regs.h.al && getdosmembyte(0x496) == 0x10)
144 keyboard_function = 0x10;
145 check_function = 0x11;
146 shift_function = 0x12;
148 else
150 keyboard_function = 0;
151 check_function = 1;
152 shift_function = 2;
156 regs.h.ah = shift_function;
157 PDCINT(0x16, regs);
159 shift_status = regs.W.ax;
161 if (mouse_vis)
163 unsigned short i;
165 ms_regs.W.ax = 3;
166 PDCINT(0x33, ms_regs);
168 mouse_button = FALSE;
170 for (i = 0; i < 3; i++)
172 regs.W.ax = 6;
173 regs.W.bx = button_map[i];
174 PDCINT(0x33, regs);
175 button[i].released = regs.W.bx;
176 if (regs.W.bx)
178 ms_regs.W.cx = regs.W.cx;
179 ms_regs.W.dx = regs.W.dx;
180 mouse_button = TRUE;
183 regs.W.ax = 5;
184 regs.W.bx = button_map[i];
185 PDCINT(0x33, regs);
186 button[i].pressed = regs.W.bx;
187 if (regs.W.bx)
189 ms_regs.W.cx = regs.W.cx;
190 ms_regs.W.dx = regs.W.dx;
191 mouse_button = TRUE;
195 mouse_scroll = ms_regs.h.bh;
197 mouse_moved = !mouse_button && ms_regs.h.bl &&
198 ms_regs.h.bl == old_ms.h.bl &&
199 (((ms_regs.W.cx ^ old_ms.W.cx) >> 3) ||
200 ((ms_regs.W.dx ^ old_ms.W.dx) >> 3));
202 if (mouse_scroll || mouse_button || mouse_moved)
203 return TRUE;
206 if (old_shift && !shift_status) /* modifier released */
208 if (!key_pressed && SP->return_key_modifiers)
209 return TRUE;
211 else if (!old_shift && shift_status) /* modifier pressed */
212 key_pressed = FALSE;
214 old_shift = shift_status;
216 #ifndef USE_KBHIT
217 regs.h.ah = check_function;
218 PDCINT(0x16, regs);
220 return !(regs.W.flags & 64);
221 #else
222 return kbhit();
223 #endif
226 static int _process_mouse_events(void)
228 int i;
229 short shift_flags = 0;
231 memset(&pdc_mouse_status, 0, sizeof(pdc_mouse_status));
233 key_pressed = TRUE;
234 old_shift = shift_status;
235 SP->key_code = TRUE;
237 /* Set shift modifiers */
239 if (shift_status & 3)
240 shift_flags |= BUTTON_SHIFT;
242 if (shift_status & 4)
243 shift_flags |= BUTTON_CONTROL;
245 if (shift_status & 8)
246 shift_flags |= BUTTON_ALT;
248 /* Scroll wheel support for CuteMouse */
250 if (mouse_scroll)
252 pdc_mouse_status.changes = mouse_scroll & 0x80 ?
253 PDC_MOUSE_WHEEL_UP : PDC_MOUSE_WHEEL_DOWN;
255 pdc_mouse_status.x = -1;
256 pdc_mouse_status.y = -1;
258 return KEY_MOUSE;
261 if (mouse_moved)
263 pdc_mouse_status.changes = PDC_MOUSE_MOVED;
265 for (i = 0; i < 3; i++)
267 if (ms_regs.h.bl & (1 << button_map[i]))
269 pdc_mouse_status.button[i] = BUTTON_MOVED | shift_flags;
270 pdc_mouse_status.changes |= (1 << i);
274 else /* button event */
276 for (i = 0; i < 3; i++)
278 if (button[i].pressed)
280 /* Check for a click -- a PRESS followed
281 immediately by a release */
283 if (!button[i].released)
285 if (SP->mouse_wait)
287 PDCREGS regs;
289 napms(SP->mouse_wait);
291 regs.W.ax = 6;
292 regs.W.bx = button_map[i];
293 PDCINT(0x33, regs);
295 pdc_mouse_status.button[i] = regs.W.bx ?
296 BUTTON_CLICKED : BUTTON_PRESSED;
298 else
299 pdc_mouse_status.button[i] = BUTTON_PRESSED;
301 else
302 pdc_mouse_status.button[i] = BUTTON_CLICKED;
305 if (button[i].pressed || button[i].released)
307 pdc_mouse_status.button[i] |= shift_flags;
308 pdc_mouse_status.changes |= (1 << i);
313 pdc_mouse_status.x = ms_regs.W.cx >> 3;
314 pdc_mouse_status.y = ms_regs.W.dx >> 3;
316 old_ms = ms_regs;
318 return KEY_MOUSE;
321 /* return the next available key or mouse event */
323 int PDC_get_key(void)
325 PDCREGS regs;
326 int key, scan;
328 pdc_key_modifiers = 0;
330 if (mouse_vis && (mouse_scroll || mouse_button || mouse_moved))
331 return _process_mouse_events();
333 /* Return modifiers as keys? */
335 if (old_shift && !shift_status)
337 key = -1;
339 if (old_shift & 1)
340 key = KEY_SHIFT_R;
342 if (old_shift & 2)
343 key = KEY_SHIFT_L;
345 if (shift_function == 0x12)
347 if (old_shift & 0x400)
348 key = KEY_CONTROL_R;
350 if (old_shift & 0x100)
351 key = KEY_CONTROL_L;
353 if (old_shift & 0x800)
354 key = KEY_ALT_R;
356 if (old_shift & 0x200)
357 key = KEY_ALT_L;
359 else
361 if (old_shift & 4)
362 key = KEY_CONTROL_R;
364 if (old_shift & 8)
365 key = KEY_ALT_R;
368 key_pressed = FALSE;
369 old_shift = shift_status;
371 SP->key_code = TRUE;
372 return key;
375 regs.h.ah = keyboard_function;
376 PDCINT(0x16, regs);
377 key = regs.h.al;
378 scan = regs.h.ah;
380 if (SP->save_key_modifiers)
382 if (shift_status & 3)
383 pdc_key_modifiers |= PDC_KEY_MODIFIER_SHIFT;
385 if (shift_status & 4)
386 pdc_key_modifiers |= PDC_KEY_MODIFIER_CONTROL;
388 if (shift_status & 8)
389 pdc_key_modifiers |= PDC_KEY_MODIFIER_ALT;
391 if (shift_status & 0x20)
392 pdc_key_modifiers |= PDC_KEY_MODIFIER_NUMLOCK;
395 if (scan == 0x1c && key == 0x0a) /* ^Enter */
396 key = CTL_ENTER;
397 else if (scan == 0xe0 && key == 0x0d) /* PadEnter */
398 key = PADENTER;
399 else if (scan == 0xe0 && key == 0x0a) /* ^PadEnter */
400 key = CTL_PADENTER;
401 else if (scan == 0x37 && key == 0x2a) /* Star */
402 key = PADSTAR;
403 else if (scan == 0x4a && key == 0x2d) /* Minus */
404 key = PADMINUS;
405 else if (scan == 0x4e && key == 0x2b) /* Plus */
406 key = PADPLUS;
407 else if (scan == 0xe0 && key == 0x2f) /* Slash */
408 key = PADSLASH;
409 else if (key == 0x00 || (key == 0xe0 && scan > 53 && scan != 86))
410 key = (scan > 0xa7) ? -1 : key_table[scan];
412 if (shift_status & 3)
414 switch (key)
416 case KEY_HOME: /* Shift Home */
417 key = KEY_SHOME;
418 break;
419 case KEY_UP: /* Shift Up */
420 key = KEY_SUP;
421 break;
422 case KEY_PPAGE: /* Shift PgUp */
423 key = KEY_SPREVIOUS;
424 break;
425 case KEY_LEFT: /* Shift Left */
426 key = KEY_SLEFT;
427 break;
428 case KEY_RIGHT: /* Shift Right */
429 key = KEY_SRIGHT;
430 break;
431 case KEY_END: /* Shift End */
432 key = KEY_SEND;
433 break;
434 case KEY_DOWN: /* Shift Down */
435 key = KEY_SDOWN;
436 break;
437 case KEY_NPAGE: /* Shift PgDn */
438 key = KEY_SNEXT;
439 break;
440 case KEY_IC: /* Shift Ins */
441 key = KEY_SIC;
442 break;
443 case KEY_DC: /* Shift Del */
444 key = KEY_SDC;
448 key_pressed = TRUE;
449 SP->key_code = ((unsigned)key >= 256);
451 return key;
454 /* discard any pending keyboard or mouse input -- this is the core
455 routine for flushinp() */
457 void PDC_flushinp(void)
459 PDC_LOG(("PDC_flushinp() - called\n"));
461 /* Force the BIOS keyboard buffer head and tail pointers to be
462 the same... Real nasty trick... */
464 setdosmemword(0x41a, getdosmemword(0x41c));
467 int PDC_mouse_set(void)
469 PDCREGS regs;
470 unsigned long mbe = SP->_trap_mbe;
472 if (mbe && !mouse_avail)
474 regs.W.ax = 0;
475 PDCINT(0x33, regs);
477 mouse_avail = !!(regs.W.ax);
480 if (mbe)
482 if (mouse_avail && !mouse_vis)
484 memset(&old_ms, 0, sizeof(old_ms));
486 regs.W.ax = 1;
487 PDCINT(0x33, regs);
489 mouse_vis = TRUE;
492 else
494 if (mouse_avail && mouse_vis)
496 regs.W.ax = 2;
497 PDCINT(0x33, regs);
499 mouse_vis = FALSE;
503 return (mouse_avail || !mbe) ? OK : ERR;
506 int PDC_modifiers_set(void)
508 key_pressed = FALSE;
510 return OK;