1 /* Public Domain Curses */
3 /* MS C doesn't return flags from int86() */
14 RCSID("$Id: pdckbd.c,v 1.87 2008/07/13 16:08:17 wmcbrine Exp $")
16 /*man-start**************************************************************
21 unsigned long PDC_get_input_fd(void);
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****************************************************************/
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[] =
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,
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"));
116 setmode(fileno(stdin), on ? O_BINARY : O_TEXT);
117 signal(SIGINT, on ? SIG_IGN : SIG_DFL);
121 /* check if a key or mouse event is waiting */
123 bool PDC_check_key(void)
127 if (shift_function == 0xff)
131 /* get shift status for all keyboards */
137 /* get shift status for enhanced keyboards */
142 if (scan == regs.h.al && getdosmembyte(0x496) == 0x10)
144 keyboard_function = 0x10;
145 check_function = 0x11;
146 shift_function = 0x12;
150 keyboard_function = 0;
156 regs.h.ah = shift_function;
159 shift_status = regs.W.ax;
166 PDCINT(0x33, ms_regs);
168 mouse_button = FALSE;
170 for (i = 0; i < 3; i++)
173 regs.W.bx = button_map[i];
175 button[i].released = regs.W.bx;
178 ms_regs.W.cx = regs.W.cx;
179 ms_regs.W.dx = regs.W.dx;
184 regs.W.bx = button_map[i];
186 button[i].pressed = regs.W.bx;
189 ms_regs.W.cx = regs.W.cx;
190 ms_regs.W.dx = regs.W.dx;
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)
206 if (old_shift && !shift_status) /* modifier released */
208 if (!key_pressed && SP->return_key_modifiers)
211 else if (!old_shift && shift_status) /* modifier pressed */
214 old_shift = shift_status;
217 regs.h.ah = check_function;
220 return !(regs.W.flags & 64);
226 static int _process_mouse_events(void)
229 short shift_flags = 0;
231 memset(&pdc_mouse_status, 0, sizeof(pdc_mouse_status));
234 old_shift = shift_status;
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 */
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;
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)
289 napms(SP->mouse_wait);
292 regs.W.bx = button_map[i];
295 pdc_mouse_status.button[i] = regs.W.bx ?
296 BUTTON_CLICKED : BUTTON_PRESSED;
299 pdc_mouse_status.button[i] = BUTTON_PRESSED;
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;
321 /* return the next available key or mouse event */
323 int PDC_get_key(void)
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)
345 if (shift_function == 0x12)
347 if (old_shift & 0x400)
350 if (old_shift & 0x100)
353 if (old_shift & 0x800)
356 if (old_shift & 0x200)
369 old_shift = shift_status;
375 regs.h.ah = keyboard_function;
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 */
397 else if (scan == 0xe0 && key == 0x0d) /* PadEnter */
399 else if (scan == 0xe0 && key == 0x0a) /* ^PadEnter */
401 else if (scan == 0x37 && key == 0x2a) /* Star */
403 else if (scan == 0x4a && key == 0x2d) /* Minus */
405 else if (scan == 0x4e && key == 0x2b) /* Plus */
407 else if (scan == 0xe0 && key == 0x2f) /* Slash */
409 else if (key == 0x00 || (key == 0xe0 && scan > 53 && scan != 86))
410 key = (scan > 0xa7) ? -1 : key_table[scan];
412 if (shift_status & 3)
416 case KEY_HOME: /* Shift Home */
419 case KEY_UP: /* Shift Up */
422 case KEY_PPAGE: /* Shift PgUp */
425 case KEY_LEFT: /* Shift Left */
428 case KEY_RIGHT: /* Shift Right */
431 case KEY_END: /* Shift End */
434 case KEY_DOWN: /* Shift Down */
437 case KEY_NPAGE: /* Shift PgDn */
440 case KEY_IC: /* Shift Ins */
443 case KEY_DC: /* Shift Del */
449 SP->key_code = ((unsigned)key >= 256);
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)
470 unsigned long mbe = SP->_trap_mbe;
472 if (mbe && !mouse_avail)
477 mouse_avail = !!(regs.W.ax);
482 if (mouse_avail && !mouse_vis)
484 memset(&old_ms, 0, sizeof(old_ms));
494 if (mouse_avail && mouse_vis)
503 return (mouse_avail || !mbe) ? OK : ERR;
506 int PDC_modifiers_set(void)