libpayload: remove trailing whitespace and run dos2unix
[coreboot.git] / payloads / libpayload / curses / PDCurses-3.4 / dos / pdckbd.c
1 /* Public Domain Curses */
2
3 /* MS C doesn't return flags from int86() */
4 #ifdef MSC
5 # define USE_KBHIT
6 #endif
7
8 #ifdef USE_KBHIT
9 # include <conio.h>
10 #endif
11
12 #include "pdcdos.h"
13
14 RCSID("$Id: pdckbd.c,v 1.87 2008/07/13 16:08:17 wmcbrine Exp $")
15
16 /*man-start**************************************************************
17
18   Name:                                                         pdckbd
19
20   Synopsis:
21         unsigned long PDC_get_input_fd(void);
22
23   Description:
24         PDC_get_input_fd() returns the file descriptor that PDCurses
25         reads its input from. It can be used for select().
26
27   Portability                                X/Open    BSD    SYS V
28         PDC_get_input_fd                        -       -       -
29
30 **man-end****************************************************************/
31
32 #ifdef __DJGPP__
33 # include <fcntl.h>
34 # include <io.h>
35 # include <signal.h>
36 #endif
37
38 /************************************************************************
39  *    Table for key code translation of function keys in keypad mode    *
40  *    These values are for strict IBM keyboard compatibles only         *
41  ************************************************************************/
42
43 static short key_table[] =
44 {
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
87 };
88
89 unsigned long pdc_key_modifiers = 0L;
90
91 static struct {unsigned short pressed, released;} button[3];
92
93 static bool mouse_avail = FALSE, mouse_vis = FALSE, mouse_moved = FALSE,
94             mouse_button = FALSE, key_pressed = FALSE;
95
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;
101
102 static const unsigned short button_map[3] = {0, 2, 1};
103
104 unsigned long PDC_get_input_fd(void)
105 {
106     PDC_LOG(("PDC_get_input_fd() - called\n"));
107
108     return (unsigned long)fileno(stdin);
109 }
110
111 void PDC_set_keyboard_binary(bool on)
112 {
113     PDC_LOG(("PDC_set_keyboard_binary() - called\n"));
114
115 #ifdef __DJGPP__
116     setmode(fileno(stdin), on ? O_BINARY : O_TEXT);
117     signal(SIGINT, on ? SIG_IGN : SIG_DFL);
118 #endif
119 }
120
121 /* check if a key or mouse event is waiting */
122
123 bool PDC_check_key(void)
124 {
125     PDCREGS regs;
126
127     if (shift_function == 0xff)
128     {
129         int scan;
130
131         /* get shift status for all keyboards */
132
133         regs.h.ah = 0x02;
134         PDCINT(0x16, regs);
135         scan = regs.h.al;
136
137         /* get shift status for enhanced keyboards */
138
139         regs.h.ah = 0x12;
140         PDCINT(0x16, regs);
141
142         if (scan == regs.h.al && getdosmembyte(0x496) == 0x10)
143         {
144             keyboard_function = 0x10;
145             check_function = 0x11;
146             shift_function = 0x12;
147         }
148         else
149         {
150             keyboard_function = 0;
151             check_function = 1;
152             shift_function = 2;
153         }
154     }
155
156     regs.h.ah = shift_function;
157     PDCINT(0x16, regs);
158
159     shift_status = regs.W.ax;
160
161     if (mouse_vis)
162     {
163         unsigned short i;
164
165         ms_regs.W.ax = 3;
166         PDCINT(0x33, ms_regs);
167
168         mouse_button = FALSE;
169
170         for (i = 0; i < 3; i++)
171         {
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)
177             {
178                 ms_regs.W.cx = regs.W.cx;
179                 ms_regs.W.dx = regs.W.dx;
180                 mouse_button = TRUE;
181             }
182
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)
188             {
189                 ms_regs.W.cx = regs.W.cx;
190                 ms_regs.W.dx = regs.W.dx;
191                 mouse_button = TRUE;
192             }
193         }
194
195         mouse_scroll = ms_regs.h.bh;
196
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));
201
202         if (mouse_scroll || mouse_button || mouse_moved)
203             return TRUE;
204     }
205
206     if (old_shift && !shift_status)     /* modifier released */
207     {
208         if (!key_pressed && SP->return_key_modifiers)
209             return TRUE;
210     }
211     else if (!old_shift && shift_status)    /* modifier pressed */
212         key_pressed = FALSE;
213
214     old_shift = shift_status;
215
216 #ifndef USE_KBHIT
217     regs.h.ah = check_function;
218     PDCINT(0x16, regs);
219
220     return !(regs.W.flags & 64);
221 #else
222     return kbhit();
223 #endif
224 }
225
226 static int _process_mouse_events(void)
227 {
228     int i;
229     short shift_flags = 0;
230
231     memset(&pdc_mouse_status, 0, sizeof(pdc_mouse_status));
232
233     key_pressed = TRUE;
234     old_shift = shift_status;
235     SP->key_code = TRUE;
236
237     /* Set shift modifiers */
238
239     if (shift_status & 3)
240         shift_flags |= BUTTON_SHIFT;
241
242     if (shift_status & 4)
243         shift_flags |= BUTTON_CONTROL;
244
245     if (shift_status & 8)
246         shift_flags |= BUTTON_ALT;
247
248     /* Scroll wheel support for CuteMouse */
249
250     if (mouse_scroll)
251     {
252         pdc_mouse_status.changes = mouse_scroll & 0x80 ?
253             PDC_MOUSE_WHEEL_UP : PDC_MOUSE_WHEEL_DOWN;
254
255         pdc_mouse_status.x = -1;
256         pdc_mouse_status.y = -1;
257
258         return KEY_MOUSE;
259     }
260
261     if (mouse_moved)
262     {
263         pdc_mouse_status.changes = PDC_MOUSE_MOVED;
264
265         for (i = 0; i < 3; i++)
266         {
267             if (ms_regs.h.bl & (1 << button_map[i]))
268             {
269                 pdc_mouse_status.button[i] = BUTTON_MOVED | shift_flags;
270                 pdc_mouse_status.changes |= (1 << i);
271             }
272         }
273     }
274     else    /* button event */
275     {
276         for (i = 0; i < 3; i++)
277         {
278             if (button[i].pressed)
279             {
280                 /* Check for a click -- a PRESS followed
281                    immediately by a release */
282
283                 if (!button[i].released)
284                 {
285                     if (SP->mouse_wait)
286                     {
287                         PDCREGS regs;
288
289                         napms(SP->mouse_wait);
290
291                         regs.W.ax = 6;
292                         regs.W.bx = button_map[i];
293                         PDCINT(0x33, regs);
294
295                         pdc_mouse_status.button[i] = regs.W.bx ?
296                             BUTTON_CLICKED : BUTTON_PRESSED;
297                     }
298                     else
299                         pdc_mouse_status.button[i] = BUTTON_PRESSED;
300                 }
301                 else
302                     pdc_mouse_status.button[i] = BUTTON_CLICKED;
303             }
304
305             if (button[i].pressed || button[i].released)
306             {
307                 pdc_mouse_status.button[i] |= shift_flags;
308                 pdc_mouse_status.changes |= (1 << i);
309             }
310         }
311     }
312
313     pdc_mouse_status.x = ms_regs.W.cx >> 3;
314     pdc_mouse_status.y = ms_regs.W.dx >> 3;
315
316     old_ms = ms_regs;
317
318     return KEY_MOUSE;
319 }
320
321 /* return the next available key or mouse event */
322
323 int PDC_get_key(void)
324 {
325     PDCREGS regs;
326     int key, scan;
327
328     pdc_key_modifiers = 0;
329
330     if (mouse_vis && (mouse_scroll || mouse_button || mouse_moved))
331         return _process_mouse_events();
332
333     /* Return modifiers as keys? */
334
335     if (old_shift && !shift_status)
336     {
337         key = -1;
338
339         if (old_shift & 1)
340             key = KEY_SHIFT_R;
341
342         if (old_shift & 2)
343             key = KEY_SHIFT_L;
344
345         if (shift_function == 0x12)
346         {
347             if (old_shift & 0x400)
348                 key = KEY_CONTROL_R;
349
350             if (old_shift & 0x100)
351                 key = KEY_CONTROL_L;
352
353             if (old_shift & 0x800)
354                 key = KEY_ALT_R;
355
356             if (old_shift & 0x200)
357                 key = KEY_ALT_L;
358         }
359         else
360         {
361             if (old_shift & 4)
362                 key = KEY_CONTROL_R;
363
364             if (old_shift & 8)
365                 key = KEY_ALT_R;
366         }
367
368         key_pressed = FALSE;
369         old_shift = shift_status;
370
371         SP->key_code = TRUE;
372         return key;
373     }
374
375     regs.h.ah = keyboard_function;
376     PDCINT(0x16, regs);
377     key = regs.h.al;
378     scan = regs.h.ah;
379
380     if (SP->save_key_modifiers)
381     {
382         if (shift_status & 3)
383             pdc_key_modifiers |= PDC_KEY_MODIFIER_SHIFT;
384
385         if (shift_status & 4)
386             pdc_key_modifiers |= PDC_KEY_MODIFIER_CONTROL;
387
388         if (shift_status & 8)
389             pdc_key_modifiers |= PDC_KEY_MODIFIER_ALT;
390
391         if (shift_status & 0x20)
392             pdc_key_modifiers |= PDC_KEY_MODIFIER_NUMLOCK;
393     }
394
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];
411
412     if (shift_status & 3)
413     {
414         switch (key)
415         {
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;
445         }
446     }
447
448     key_pressed = TRUE;
449     SP->key_code = ((unsigned)key >= 256);
450
451     return key;
452 }
453
454 /* discard any pending keyboard or mouse input -- this is the core
455    routine for flushinp() */
456
457 void PDC_flushinp(void)
458 {
459     PDC_LOG(("PDC_flushinp() - called\n"));
460
461     /* Force the BIOS keyboard buffer head and tail pointers to be
462        the same...  Real nasty trick... */
463
464     setdosmemword(0x41a, getdosmemword(0x41c));
465 }
466
467 int PDC_mouse_set(void)
468 {
469     PDCREGS regs;
470     unsigned long mbe = SP->_trap_mbe;
471
472     if (mbe && !mouse_avail)
473     {
474         regs.W.ax = 0;
475         PDCINT(0x33, regs);
476
477         mouse_avail = !!(regs.W.ax);
478     }
479
480     if (mbe)
481     {
482         if (mouse_avail && !mouse_vis)
483         {
484             memset(&old_ms, 0, sizeof(old_ms));
485
486             regs.W.ax = 1;
487             PDCINT(0x33, regs);
488
489             mouse_vis = TRUE;
490         }
491     }
492     else
493     {
494         if (mouse_avail && mouse_vis)
495         {
496             regs.W.ax = 2;
497             PDCINT(0x33, regs);
498
499             mouse_vis = FALSE;
500         }
501     }
502
503     return (mouse_avail || !mbe) ? OK : ERR;
504 }
505
506 int PDC_modifiers_set(void)
507 {
508     key_pressed = FALSE;
509
510     return OK;
511 }