1 /* Public Domain Curses */
3 #if defined(__EMX__) || defined(__WATCOMC__) || defined(__IBMC__) || \
11 RCSID("$Id: pdckbd.c,v 1.89 2008/07/14 04:24:51 wmcbrine Exp $")
13 /*man-start**************************************************************
18 unsigned long PDC_get_input_fd(void);
21 PDC_get_input_fd() returns the file descriptor that PDCurses
22 reads its input from. It can be used for select().
24 Portability X/Open BSD SYS V
25 PDC_get_input_fd - - -
27 **man-end****************************************************************/
31 static int tahead
= -1;
33 static KBDINFO kbdinfo
; /* default keyboard mode */
34 static HMOU mouse_handle
= 0;
35 static MOUSE_STATUS old_mouse_status
;
36 static USHORT old_shift
= 0;
37 static bool key_pressed
= FALSE
;
38 static int mouse_events
= 0;
41 /************************************************************************
42 * Table for key code translation of function keys in keypad mode *
43 * These values are for strict IBM keyboard compatibles only *
44 ************************************************************************/
46 static short key_table
[] =
51 -1, -1, ALT_BKSP
, KEY_BTAB
,
52 ALT_Q
, ALT_W
, ALT_E
, ALT_R
,
53 ALT_T
, ALT_Y
, ALT_U
, ALT_I
,
54 ALT_O
, ALT_P
, ALT_LBRACKET
, ALT_RBRACKET
,
55 ALT_ENTER
, -1, ALT_A
, ALT_S
,
56 ALT_D
, ALT_F
, ALT_G
, ALT_H
,
57 ALT_J
, ALT_K
, ALT_L
, ALT_SEMICOLON
,
58 ALT_FQUOTE
, ALT_BQUOTE
, -1, ALT_BSLASH
,
59 ALT_Z
, ALT_X
, ALT_C
, ALT_V
,
60 ALT_B
, ALT_N
, ALT_M
, ALT_COMMA
,
61 ALT_STOP
, ALT_FSLASH
, -1, ALT_PADSTAR
,
63 KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5),
64 KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9),
65 KEY_F(10), -1, -1, KEY_HOME
,
66 KEY_UP
, KEY_PPAGE
, ALT_PADMINUS
, KEY_LEFT
,
67 KEY_B2
, KEY_RIGHT
, ALT_PADPLUS
, KEY_END
,
68 KEY_DOWN
, KEY_NPAGE
, KEY_IC
, KEY_DC
,
69 KEY_F(13), KEY_F(14), KEY_F(15), KEY_F(16),
70 KEY_F(17), KEY_F(18), KEY_F(19), KEY_F(20),
71 KEY_F(21), KEY_F(22), KEY_F(25), KEY_F(26),
72 KEY_F(27), KEY_F(28), KEY_F(29), KEY_F(30),
73 KEY_F(31), KEY_F(32), KEY_F(33), KEY_F(34),
74 KEY_F(37), KEY_F(38), KEY_F(39), KEY_F(40),
75 KEY_F(41), KEY_F(42), KEY_F(43), KEY_F(44),
76 KEY_F(45), KEY_F(46), -1, CTL_LEFT
,
77 CTL_RIGHT
, CTL_END
, CTL_PGDN
, CTL_HOME
,
78 ALT_1
, ALT_2
, ALT_3
, ALT_4
,
79 ALT_5
, ALT_6
, ALT_7
, ALT_8
,
80 ALT_9
, ALT_0
, ALT_MINUS
, ALT_EQUAL
,
81 CTL_PGUP
, KEY_F(11), KEY_F(12), KEY_F(23),
82 KEY_F(24), KEY_F(35), KEY_F(36), KEY_F(47),
83 KEY_F(48), CTL_UP
, CTL_PADMINUS
, CTL_PADCENTER
,
84 CTL_PADPLUS
, CTL_DOWN
, CTL_INS
, CTL_DEL
,
85 CTL_TAB
, CTL_PADSLASH
, CTL_PADSTAR
, ALT_HOME
,
86 ALT_UP
, ALT_PGUP
, -1, ALT_LEFT
,
87 -1, ALT_RIGHT
, -1, ALT_END
,
88 ALT_DOWN
, ALT_PGDN
, ALT_INS
, ALT_DEL
,
89 ALT_PADSLASH
, ALT_TAB
, ALT_PADENTER
, -1
92 unsigned long pdc_key_modifiers
= 0L;
94 unsigned long PDC_get_input_fd(void)
96 PDC_LOG(("PDC_get_input_fd() - called\n"));
98 return (unsigned long)fileno(stdin
);
103 void PDC_get_keyboard_info(void)
105 kbdinfo
.cb
= sizeof(kbdinfo
);
106 KbdGetStatus(&kbdinfo
, 0);
109 void PDC_set_keyboard_default(void)
111 KbdSetStatus(&kbdinfo
, 0);
114 #endif /* ifndef EMXVIDEO */
116 void PDC_set_keyboard_binary(bool on
)
118 PDC_LOG(("PDC_set_keyboard_binary() - called\n"));
123 kbdinfo
.fsMask
&= ~(KEYBOARD_ASCII_MODE
);
124 kbdinfo
.fsMask
|= KEYBOARD_BINARY_MODE
;
128 kbdinfo
.fsMask
&= ~(KEYBOARD_BINARY_MODE
);
129 kbdinfo
.fsMask
|= KEYBOARD_ASCII_MODE
;
132 KbdSetStatus(&kbdinfo
, 0);
136 signal(SIGBREAK
, on
? SIG_IGN
: SIG_DFL
);
140 /* check if a key or mouse event is waiting */
142 bool PDC_check_key(void)
144 #if !defined(_MSC_VER) && !defined(EMXVIDEO)
145 KBDKEYINFO keyInfo
= {0};
149 if (tahead
== -1) /* Nothing typed yet */
151 tahead
= _read_kbd(0, 0, 0);
153 /* Read additional */
156 tahead
= _read_kbd(0, 1, 0) << 8;
159 return (tahead
!= -1);
163 KbdGetStatus(&kbdinfo
, 0);
169 MouGetNumQueEl(&queue
, mouse_handle
);
170 mouse_events
= queue
.cEvents
;
176 if (old_shift
&& !kbdinfo
.fsState
) /* modifier released */
178 if (!key_pressed
&& SP
->return_key_modifiers
)
181 else if (!old_shift
&& kbdinfo
.fsState
) /* modifier pressed */
184 old_shift
= kbdinfo
.fsState
;
186 KbdPeek(&keyInfo
, 0); /* peek at keyboard */
187 return (keyInfo
.fbStatus
!= 0);
196 static int _process_mouse_events(void)
199 static const USHORT button_mask
[] = {6, 96, 24},
200 move_mask
[] = {2, 32, 8},
201 press_mask
[] = {4, 64, 16};
203 short shift_flags
= 0;
206 MouReadEventQue(&event
, &count
, mouse_handle
);
209 for (i
= 0; i
< 3; i
++)
211 pdc_mouse_status
.button
[i
] =
212 ((event
.fs
& move_mask
[i
]) ? BUTTON_MOVED
: 0) |
213 ((event
.fs
& press_mask
[i
]) ? BUTTON_PRESSED
: 0);
215 /* PRESS events are sometimes mistakenly reported as MOVE
216 events. A MOVE should always follow a PRESS, so treat a MOVE
217 immediately after a RELEASE as a PRESS. */
219 if ((pdc_mouse_status
.button
[i
] == BUTTON_MOVED
) &&
220 (old_mouse_status
.button
[i
] == BUTTON_RELEASED
))
222 pdc_mouse_status
.button
[i
] = BUTTON_PRESSED
;
225 if (pdc_mouse_status
.button
[i
] == BUTTON_PRESSED
&& SP
->mouse_wait
)
227 /* Check for a click -- a PRESS followed immediately by a
234 napms(SP
->mouse_wait
);
236 MouGetNumQueEl(&queue
, mouse_handle
);
237 mouse_events
= queue
.cEvents
;
242 MouReadEventQue(&event
, &count
, mouse_handle
);
244 if (!(event
.fs
& button_mask
[i
]))
245 pdc_mouse_status
.button
[i
] = BUTTON_CLICKED
;
250 pdc_mouse_status
.x
= event
.col
;
251 pdc_mouse_status
.y
= event
.row
;
253 pdc_mouse_status
.changes
= 0;
255 for (i
= 0; i
< 3; i
++)
257 if (old_mouse_status
.button
[i
] != pdc_mouse_status
.button
[i
])
258 pdc_mouse_status
.changes
|= (1 << i
);
260 if (pdc_mouse_status
.button
[i
] == BUTTON_MOVED
)
262 /* Discard non-moved "moves" */
264 if (pdc_mouse_status
.x
== old_mouse_status
.x
&&
265 pdc_mouse_status
.y
== old_mouse_status
.y
)
268 /* Motion events always flag the button as changed */
270 pdc_mouse_status
.changes
|= (1 << i
);
271 pdc_mouse_status
.changes
|= PDC_MOUSE_MOVED
;
276 old_mouse_status
= pdc_mouse_status
;
278 /* Treat click events as release events for comparison purposes */
280 for (i
= 0; i
< 3; i
++)
282 if (old_mouse_status
.button
[i
] == BUTTON_CLICKED
)
283 old_mouse_status
.button
[i
] = BUTTON_RELEASED
;
286 /* Check for SHIFT/CONTROL/ALT */
288 if (kbdinfo
.fsState
& KBDSTF_ALT
)
289 shift_flags
|= BUTTON_ALT
;
291 if (kbdinfo
.fsState
& KBDSTF_CONTROL
)
292 shift_flags
|= BUTTON_CONTROL
;
294 if (kbdinfo
.fsState
& (KBDSTF_LEFTSHIFT
|KBDSTF_RIGHTSHIFT
))
295 shift_flags
|= BUTTON_SHIFT
;
299 for (i
= 0; i
< 3; i
++)
301 if (pdc_mouse_status
.changes
& (1 << i
))
302 pdc_mouse_status
.button
[i
] |= shift_flags
;
306 old_shift
= kbdinfo
.fsState
;
315 /* return the next available key or mouse event */
317 int PDC_get_key(void)
321 KBDKEYINFO keyInfo
= {0};
327 tahead
= _read_kbd(0, 1, 0);
329 /* Read additional */
332 tahead
= _read_kbd(0, 1, 0) << 8;
337 pdc_key_modifiers
= 0L;
341 pdc_key_modifiers
= 0L;
343 if (mouse_handle
&& mouse_events
)
344 return _process_mouse_events();
346 if (old_shift
&& !kbdinfo
.fsState
)
350 if (old_shift
& KBDSTF_LEFTALT
)
354 else if (old_shift
& KBDSTF_RIGHTALT
)
358 else if (old_shift
& KBDSTF_LEFTCONTROL
)
362 else if (old_shift
& KBDSTF_RIGHTCONTROL
)
366 else if (old_shift
& KBDSTF_LEFTSHIFT
)
370 else if (old_shift
& KBDSTF_RIGHTSHIFT
)
376 old_shift
= kbdinfo
.fsState
;
382 KbdCharIn(&keyInfo
, IO_WAIT
, 0); /* get a character */
384 key
= keyInfo
.chChar
;
385 scan
= keyInfo
.chScan
;
387 if (SP
->save_key_modifiers
)
389 if (keyInfo
.fsState
& KBDSTF_ALT
)
390 pdc_key_modifiers
|= PDC_KEY_MODIFIER_ALT
;
392 if (keyInfo
.fsState
& KBDSTF_CONTROL
)
393 pdc_key_modifiers
|= PDC_KEY_MODIFIER_CONTROL
;
395 if (keyInfo
.fsState
& KBDSTF_NUMLOCK_ON
)
396 pdc_key_modifiers
|= PDC_KEY_MODIFIER_NUMLOCK
;
398 if (keyInfo
.fsState
& (KBDSTF_LEFTSHIFT
|KBDSTF_RIGHTSHIFT
))
399 pdc_key_modifiers
|= PDC_KEY_MODIFIER_SHIFT
;
402 if (scan
== 0x1c && key
== 0x0a) /* ^Enter */
404 else if (scan
== 0xe0 && key
== 0x0d) /* PadEnter */
406 else if (scan
== 0xe0 && key
== 0x0a) /* ^PadEnter */
408 else if (scan
== 0x37 && key
== 0x2a) /* Star */
410 else if (scan
== 0x4a && key
== 0x2d) /* Minus */
412 else if (scan
== 0x4e && key
== 0x2b) /* Plus */
414 else if (scan
== 0xe0 && key
== 0x2f) /* Slash */
416 else if (key
== 0x00 || (key
== 0xe0 && scan
> 53 && scan
!= 86))
417 key
= (scan
> 0xa7) ? -1 : key_table
[scan
];
419 if (keyInfo
.fsState
& (KBDSTF_LEFTSHIFT
|KBDSTF_RIGHTSHIFT
))
423 case KEY_HOME
: /* Shift Home */
426 case KEY_UP
: /* Shift Up */
429 case KEY_PPAGE
: /* Shift PgUp */
432 case KEY_LEFT
: /* Shift Left */
435 case KEY_RIGHT
: /* Shift Right */
438 case KEY_END
: /* Shift End */
441 case KEY_DOWN
: /* Shift Down */
444 case KEY_NPAGE
: /* Shift PgDn */
447 case KEY_IC
: /* Shift Ins */
450 case KEY_DC
: /* Shift Del */
456 SP
->key_code
= ((unsigned)key
>= 256);
461 /* discard any pending keyboard or mouse input -- this is the core
462 routine for flushinp() */
464 void PDC_flushinp(void)
466 PDC_LOG(("PDC_flushinp() - called\n"));
469 tcflush(0, TCIFLUSH
);
472 MouFlushQue(mouse_handle
);
478 int PDC_mouse_set(void)
482 unsigned long mbe
= SP
->_trap_mbe
;
484 if (mbe
&& !mouse_handle
)
486 memset(&old_mouse_status
, 0, sizeof(MOUSE_STATUS
));
487 MouOpen(NULL
, &mouse_handle
);
489 MouDrawPtr(mouse_handle
);
491 else if (!mbe
&& mouse_handle
)
493 MouClose(mouse_handle
);
497 if (mbe
&& mouse_handle
)
499 USHORT mask
= ((mbe
& (BUTTON1_PRESSED
| BUTTON1_CLICKED
|
500 BUTTON1_MOVED
)) ? 6 : 0) |
502 ((mbe
& (BUTTON3_PRESSED
| BUTTON3_CLICKED
|
503 BUTTON3_MOVED
)) ? 24 : 0) |
505 ((mbe
& (BUTTON2_PRESSED
| BUTTON2_CLICKED
|
506 BUTTON2_MOVED
)) ? 96 : 0);
508 MouSetEventMask(&mask
, mouse_handle
);
514 int PDC_modifiers_set(void)