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)