pdcurses/pdckbd.c

changeset 97
2d43f05b284c
equal deleted inserted replaced
96:5314ebdcb38d 97:2d43f05b284c
1 /* Public Domain Curses */
2
3 #include "pdcwin.h"
4
5 RCSID("$Id: pdckbd.c,v 1.115 2008/07/20 20:12:04 wmcbrine Exp $")
6
7 /*man-start**************************************************************
8
9 Name: pdckbd
10
11 Synopsis:
12 unsigned long PDC_get_input_fd(void);
13
14 Description:
15 PDC_get_input_fd() returns the file descriptor that PDCurses
16 reads its input from. It can be used for select().
17
18 Portability X/Open BSD SYS V
19 PDC_get_input_fd - - -
20
21 **man-end****************************************************************/
22
23 unsigned long pdc_key_modifiers = 0L;
24
25 /* These variables are used to store information about the next
26 Input Event. */
27
28 static INPUT_RECORD save_ip;
29 static MOUSE_STATUS old_mouse_status;
30 static DWORD event_count = 0;
31 static SHORT left_key;
32 static int key_count = 0;
33 static int save_press = 0;
34
35 #define KEV save_ip.Event.KeyEvent
36 #define MEV save_ip.Event.MouseEvent
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 typedef struct
44 {
45 unsigned short normal;
46 unsigned short shift;
47 unsigned short control;
48 unsigned short alt;
49 unsigned short extended;
50 } KPTAB;
51
52 static KPTAB kptab[] =
53 {
54 {0, 0, 0, 0, 0 }, /* 0 */
55 {0, 0, 0, 0, 0 }, /* 1 VK_LBUTTON */
56 {0, 0, 0, 0, 0 }, /* 2 VK_RBUTTON */
57 {0, 0, 0, 0, 0 }, /* 3 VK_CANCEL */
58 {0, 0, 0, 0, 0 }, /* 4 VK_MBUTTON */
59 {0, 0, 0, 0, 0 }, /* 5 */
60 {0, 0, 0, 0, 0 }, /* 6 */
61 {0, 0, 0, 0, 0 }, /* 7 */
62 {0x08, 0x08, 0x7F, ALT_BKSP, 0 }, /* 8 VK_BACK */
63 {0x09, KEY_BTAB, CTL_TAB, ALT_TAB, 999 }, /* 9 VK_TAB */
64 {0, 0, 0, 0, 0 }, /* 10 */
65 {0, 0, 0, 0, 0 }, /* 11 */
66 {KEY_B2, 0x35, CTL_PAD5, ALT_PAD5, 0 }, /* 12 VK_CLEAR */
67 {0x0D, 0x0D, CTL_ENTER, ALT_ENTER, 1 }, /* 13 VK_RETURN */
68 {0, 0, 0, 0, 0 }, /* 14 */
69 {0, 0, 0, 0, 0 }, /* 15 */
70 {0, 0, 0, 0, 0 }, /* 16 VK_SHIFT HANDLED SEPARATELY */
71 {0, 0, 0, 0, 0 }, /* 17 VK_CONTROL HANDLED SEPARATELY */
72 {0, 0, 0, 0, 0 }, /* 18 VK_MENU HANDLED SEPARATELY */
73 {0, 0, 0, 0, 0 }, /* 19 VK_PAUSE */
74 {0, 0, 0, 0, 0 }, /* 20 VK_CAPITAL HANDLED SEPARATELY */
75 {0, 0, 0, 0, 0 }, /* 21 VK_HANGUL */
76 {0, 0, 0, 0, 0 }, /* 22 */
77 {0, 0, 0, 0, 0 }, /* 23 VK_JUNJA */
78 {0, 0, 0, 0, 0 }, /* 24 VK_FINAL */
79 {0, 0, 0, 0, 0 }, /* 25 VK_HANJA */
80 {0, 0, 0, 0, 0 }, /* 26 */
81 {0x1B, 0x1B, 0x1B, ALT_ESC, 0 }, /* 27 VK_ESCAPE */
82 {0, 0, 0, 0, 0 }, /* 28 VK_CONVERT */
83 {0, 0, 0, 0, 0 }, /* 29 VK_NONCONVERT */
84 {0, 0, 0, 0, 0 }, /* 30 VK_ACCEPT */
85 {0, 0, 0, 0, 0 }, /* 31 VK_MODECHANGE */
86 {0x20, 0x20, 0x20, 0x20, 0 }, /* 32 VK_SPACE */
87 {KEY_A3, 0x39, CTL_PAD9, ALT_PAD9, 3 }, /* 33 VK_PRIOR */
88 {KEY_C3, 0x33, CTL_PAD3, ALT_PAD3, 4 }, /* 34 VK_NEXT */
89 {KEY_C1, 0x31, CTL_PAD1, ALT_PAD1, 5 }, /* 35 VK_END */
90 {KEY_A1, 0x37, CTL_PAD7, ALT_PAD7, 6 }, /* 36 VK_HOME */
91 {KEY_B1, 0x34, CTL_PAD4, ALT_PAD4, 7 }, /* 37 VK_LEFT */
92 {KEY_A2, 0x38, CTL_PAD8, ALT_PAD8, 8 }, /* 38 VK_UP */
93 {KEY_B3, 0x36, CTL_PAD6, ALT_PAD6, 9 }, /* 39 VK_RIGHT */
94 {KEY_C2, 0x32, CTL_PAD2, ALT_PAD2, 10 }, /* 40 VK_DOWN */
95 {0, 0, 0, 0, 0 }, /* 41 VK_SELECT */
96 {0, 0, 0, 0, 0 }, /* 42 VK_PRINT */
97 {0, 0, 0, 0, 0 }, /* 43 VK_EXECUTE */
98 {0, 0, 0, 0, 0 }, /* 44 VK_SNAPSHOT*/
99 {PAD0, 0x30, CTL_PAD0, ALT_PAD0, 11 }, /* 45 VK_INSERT */
100 {PADSTOP, 0x2E, CTL_PADSTOP, ALT_PADSTOP,12 }, /* 46 VK_DELETE */
101 {0, 0, 0, 0, 0 }, /* 47 VK_HELP */
102 {0x30, 0x29, 0, ALT_0, 0 }, /* 48 */
103 {0x31, 0x21, 0, ALT_1, 0 }, /* 49 */
104 {0x32, 0x40, 0, ALT_2, 0 }, /* 50 */
105 {0x33, 0x23, 0, ALT_3, 0 }, /* 51 */
106 {0x34, 0x24, 0, ALT_4, 0 }, /* 52 */
107 {0x35, 0x25, 0, ALT_5, 0 }, /* 53 */
108 {0x36, 0x5E, 0, ALT_6, 0 }, /* 54 */
109 {0x37, 0x26, 0, ALT_7, 0 }, /* 55 */
110 {0x38, 0x2A, 0, ALT_8, 0 }, /* 56 */
111 {0x39, 0x28, 0, ALT_9, 0 }, /* 57 */
112 {0, 0, 0, 0, 0 }, /* 58 */
113 {0, 0, 0, 0, 0 }, /* 59 */
114 {0, 0, 0, 0, 0 }, /* 60 */
115 {0, 0, 0, 0, 0 }, /* 61 */
116 {0, 0, 0, 0, 0 }, /* 62 */
117 {0, 0, 0, 0, 0 }, /* 63 */
118 {0, 0, 0, 0, 0 }, /* 64 */
119 {0x61, 0x41, 0x01, ALT_A, 0 }, /* 65 */
120 {0x62, 0x42, 0x02, ALT_B, 0 }, /* 66 */
121 {0x63, 0x43, 0x03, ALT_C, 0 }, /* 67 */
122 {0x64, 0x44, 0x04, ALT_D, 0 }, /* 68 */
123 {0x65, 0x45, 0x05, ALT_E, 0 }, /* 69 */
124 {0x66, 0x46, 0x06, ALT_F, 0 }, /* 70 */
125 {0x67, 0x47, 0x07, ALT_G, 0 }, /* 71 */
126 {0x68, 0x48, 0x08, ALT_H, 0 }, /* 72 */
127 {0x69, 0x49, 0x09, ALT_I, 0 }, /* 73 */
128 {0x6A, 0x4A, 0x0A, ALT_J, 0 }, /* 74 */
129 {0x6B, 0x4B, 0x0B, ALT_K, 0 }, /* 75 */
130 {0x6C, 0x4C, 0x0C, ALT_L, 0 }, /* 76 */
131 {0x6D, 0x4D, 0x0D, ALT_M, 0 }, /* 77 */
132 {0x6E, 0x4E, 0x0E, ALT_N, 0 }, /* 78 */
133 {0x6F, 0x4F, 0x0F, ALT_O, 0 }, /* 79 */
134 {0x70, 0x50, 0x10, ALT_P, 0 }, /* 80 */
135 {0x71, 0x51, 0x11, ALT_Q, 0 }, /* 81 */
136 {0x72, 0x52, 0x12, ALT_R, 0 }, /* 82 */
137 {0x73, 0x53, 0x13, ALT_S, 0 }, /* 83 */
138 {0x74, 0x54, 0x14, ALT_T, 0 }, /* 84 */
139 {0x75, 0x55, 0x15, ALT_U, 0 }, /* 85 */
140 {0x76, 0x56, 0x16, ALT_V, 0 }, /* 86 */
141 {0x77, 0x57, 0x17, ALT_W, 0 }, /* 87 */
142 {0x78, 0x58, 0x18, ALT_X, 0 }, /* 88 */
143 {0x79, 0x59, 0x19, ALT_Y, 0 }, /* 89 */
144 {0x7A, 0x5A, 0x1A, ALT_Z, 0 }, /* 90 */
145 {0, 0, 0, 0, 0 }, /* 91 VK_LWIN */
146 {0, 0, 0, 0, 0 }, /* 92 VK_RWIN */
147 {0, 0, 0, 0, 0 }, /* 93 VK_APPS */
148 {0, 0, 0, 0, 0 }, /* 94 */
149 {0, 0, 0, 0, 0 }, /* 95 */
150 {0x30, 0, CTL_PAD0, ALT_PAD0, 0 }, /* 96 VK_NUMPAD0 */
151 {0x31, 0, CTL_PAD1, ALT_PAD1, 0 }, /* 97 VK_NUMPAD1 */
152 {0x32, 0, CTL_PAD2, ALT_PAD2, 0 }, /* 98 VK_NUMPAD2 */
153 {0x33, 0, CTL_PAD3, ALT_PAD3, 0 }, /* 99 VK_NUMPAD3 */
154 {0x34, 0, CTL_PAD4, ALT_PAD4, 0 }, /* 100 VK_NUMPAD4 */
155 {0x35, 0, CTL_PAD5, ALT_PAD5, 0 }, /* 101 VK_NUMPAD5 */
156 {0x36, 0, CTL_PAD6, ALT_PAD6, 0 }, /* 102 VK_NUMPAD6 */
157 {0x37, 0, CTL_PAD7, ALT_PAD7, 0 }, /* 103 VK_NUMPAD7 */
158 {0x38, 0, CTL_PAD8, ALT_PAD8, 0 }, /* 104 VK_NUMPAD8 */
159 {0x39, 0, CTL_PAD9, ALT_PAD9, 0 }, /* 105 VK_NUMPAD9 */
160 {PADSTAR, SHF_PADSTAR,CTL_PADSTAR, ALT_PADSTAR,999 }, /* 106 VK_MULTIPLY*/
161 {PADPLUS, SHF_PADPLUS,CTL_PADPLUS, ALT_PADPLUS,999 }, /* 107 VK_ADD */
162 {0, 0, 0, 0, 0 }, /* 108 VK_SEPARATOR */
163 {PADMINUS, SHF_PADMINUS,CTL_PADMINUS,ALT_PADMINUS,999}, /* 109 VK_SUBTRACT*/
164 {0x2E, 0, CTL_PADSTOP, ALT_PADSTOP,0 }, /* 110 VK_DECIMAL */
165 {PADSLASH, SHF_PADSLASH,CTL_PADSLASH,ALT_PADSLASH,2 }, /* 111 VK_DIVIDE */
166 {KEY_F(1), KEY_F(13), KEY_F(25), KEY_F(37), 0 }, /* 112 VK_F1 */
167 {KEY_F(2), KEY_F(14), KEY_F(26), KEY_F(38), 0 }, /* 113 VK_F2 */
168 {KEY_F(3), KEY_F(15), KEY_F(27), KEY_F(39), 0 }, /* 114 VK_F3 */
169 {KEY_F(4), KEY_F(16), KEY_F(28), KEY_F(40), 0 }, /* 115 VK_F4 */
170 {KEY_F(5), KEY_F(17), KEY_F(29), KEY_F(41), 0 }, /* 116 VK_F5 */
171 {KEY_F(6), KEY_F(18), KEY_F(30), KEY_F(42), 0 }, /* 117 VK_F6 */
172 {KEY_F(7), KEY_F(19), KEY_F(31), KEY_F(43), 0 }, /* 118 VK_F7 */
173 {KEY_F(8), KEY_F(20), KEY_F(32), KEY_F(44), 0 }, /* 119 VK_F8 */
174 {KEY_F(9), KEY_F(21), KEY_F(33), KEY_F(45), 0 }, /* 120 VK_F9 */
175 {KEY_F(10), KEY_F(22), KEY_F(34), KEY_F(46), 0 }, /* 121 VK_F10 */
176 {KEY_F(11), KEY_F(23), KEY_F(35), KEY_F(47), 0 }, /* 122 VK_F11 */
177 {KEY_F(12), KEY_F(24), KEY_F(36), KEY_F(48), 0 }, /* 123 VK_F12 */
178
179 /* 124 through 218 */
180
181 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
182 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
183 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
184 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
185 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
186 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
187 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
188 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
189 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
190 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
191 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
192 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
193 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
194 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
195 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
196 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
197 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
198 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
199 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
200 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
201 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
202 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
203 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
204 {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
205
206 {0x5B, 0x7B, 0x1B, ALT_LBRACKET,0 }, /* 219 */
207 {0x5C, 0x7C, 0x1C, ALT_BSLASH, 0 }, /* 220 */
208 {0x5D, 0x7D, 0x1D, ALT_RBRACKET,0 }, /* 221 */
209 {0, 0, 0x27, ALT_FQUOTE, 0 }, /* 222 */
210 {0, 0, 0, 0, 0 }, /* 223 */
211 {0, 0, 0, 0, 0 }, /* 224 */
212 {0, 0, 0, 0, 0 } /* 225 */
213 };
214
215 static KPTAB ext_kptab[] =
216 {
217 {0, 0, 0, 0, }, /* MUST BE EMPTY */
218 {PADENTER, SHF_PADENTER, CTL_PADENTER, ALT_PADENTER}, /* 13 */
219 {PADSLASH, SHF_PADSLASH, CTL_PADSLASH, ALT_PADSLASH}, /* 111 */
220 {KEY_PPAGE, KEY_SPREVIOUS, CTL_PGUP, ALT_PGUP }, /* 33 */
221 {KEY_NPAGE, KEY_SNEXT, CTL_PGDN, ALT_PGDN }, /* 34 */
222 {KEY_END, KEY_SEND, CTL_END, ALT_END }, /* 35 */
223 {KEY_HOME, KEY_SHOME, CTL_HOME, ALT_HOME }, /* 36 */
224 {KEY_LEFT, KEY_SLEFT, CTL_LEFT, ALT_LEFT }, /* 37 */
225 {KEY_UP, KEY_SUP, CTL_UP, ALT_UP }, /* 38 */
226 {KEY_RIGHT, KEY_SRIGHT, CTL_RIGHT, ALT_RIGHT }, /* 39 */
227 {KEY_DOWN, KEY_SDOWN, CTL_DOWN, ALT_DOWN }, /* 40 */
228 {KEY_IC, KEY_SIC, CTL_INS, ALT_INS }, /* 45 */
229 {KEY_DC, KEY_SDC, CTL_DEL, ALT_DEL }, /* 46 */
230 {PADSLASH, SHF_PADSLASH, CTL_PADSLASH, ALT_PADSLASH}, /* 191 */
231 };
232
233 /* End of kptab[] */
234
235 unsigned long PDC_get_input_fd(void)
236 {
237 PDC_LOG(("PDC_get_input_fd() - called\n"));
238
239 return 0L;
240 }
241
242 void PDC_set_keyboard_binary(bool on)
243 {
244 PDC_LOG(("PDC_set_keyboard_binary() - called\n"));
245 }
246
247 /* check if a key or mouse event is waiting */
248
249 bool PDC_check_key(void)
250 {
251 if (key_count > 0)
252 return TRUE;
253
254 GetNumberOfConsoleInputEvents(pdc_con_in, &event_count);
255
256 return (event_count != 0);
257 }
258
259 /* _get_key_count returns 0 if save_ip doesn't contain an event which
260 should be passed back to the user. This function filters "useless"
261 events.
262
263 The function returns the number of keys waiting. This may be > 1
264 if the repetition of real keys pressed so far are > 1.
265
266 Returns 0 on NUMLOCK, CAPSLOCK, SCROLLLOCK.
267
268 Returns 1 for SHIFT, ALT, CTRL only if no other key has been pressed
269 in between, and SP->return_key_modifiers is set; these are returned
270 on keyup.
271
272 Normal keys are returned on keydown only. The number of repetitions
273 are returned. Dead keys (diacritics) are omitted. See below for a
274 description.
275 */
276
277 static int _get_key_count(void)
278 {
279 int num_keys = 0, vk;
280
281 PDC_LOG(("_get_key_count() - called\n"));
282
283 vk = KEV.wVirtualKeyCode;
284
285 if (KEV.bKeyDown)
286 {
287 /* key down */
288
289 save_press = 0;
290
291 if (vk == VK_CAPITAL || vk == VK_NUMLOCK || vk == VK_SCROLL)
292 {
293 /* throw away these modifiers */
294 }
295 else if (vk == VK_SHIFT || vk == VK_CONTROL || vk == VK_MENU)
296 {
297 /* These keys are returned on keyup only. */
298
299 save_press = vk;
300 switch (vk)
301 {
302 case VK_SHIFT:
303 left_key = GetKeyState(VK_LSHIFT);
304 break;
305 case VK_CONTROL:
306 left_key = GetKeyState(VK_LCONTROL);
307 break;
308 case VK_MENU:
309 left_key = GetKeyState(VK_LMENU);
310 }
311 }
312 else
313 {
314 /* Check for diacritics. These are dead keys. Some locales
315 have modified characters like umlaut-a, which is an "a"
316 with two dots on it. In some locales you have to press a
317 special key (the dead key) immediately followed by the
318 "a" to get a composed umlaut-a. The special key may have
319 a normal meaning with different modifiers. */
320
321 if (KEV.uChar.UnicodeChar || !(MapVirtualKey(vk, 2) & 0x80000000))
322 num_keys = KEV.wRepeatCount;
323 }
324 }
325 else
326 {
327 /* key up */
328
329 /* Only modifier keys or the results of ALT-numpad entry are
330 returned on keyup */
331
332 if ((vk == VK_MENU && KEV.uChar.UnicodeChar) ||
333 ((vk == VK_SHIFT || vk == VK_CONTROL || vk == VK_MENU) &&
334 vk == save_press))
335 {
336 save_press = 0;
337 num_keys = 1;
338 }
339 }
340
341 PDC_LOG(("_get_key_count() - returning: num_keys %d\n", num_keys));
342
343 return num_keys;
344 }
345
346 /* _process_key_event returns -1 if the key in save_ip should be
347 ignored. Otherwise it returns the keycode which should be returned
348 by PDC_get_key(). save_ip must be a key event.
349
350 CTRL-ALT support has been disabled, when is it emitted plainly? */
351
352 static int _process_key_event(void)
353 {
354 int key = (unsigned short)KEV.uChar.UnicodeChar;
355 WORD vk = KEV.wVirtualKeyCode;
356 DWORD state = KEV.dwControlKeyState;
357
358 int idx;
359 BOOL enhanced;
360
361 SP->key_code = TRUE;
362
363 /* Save the key modifiers if required. Do this first to allow to
364 detect e.g. a pressed CTRL key after a hit of NUMLOCK. */
365
366 if (SP->save_key_modifiers)
367 {
368 if (state & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED))
369 pdc_key_modifiers |= PDC_KEY_MODIFIER_ALT;
370
371 if (state & SHIFT_PRESSED)
372 pdc_key_modifiers |= PDC_KEY_MODIFIER_SHIFT;
373
374 if (state & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED))
375 pdc_key_modifiers |= PDC_KEY_MODIFIER_CONTROL;
376
377 if (state & NUMLOCK_ON)
378 pdc_key_modifiers |= PDC_KEY_MODIFIER_NUMLOCK;
379 }
380
381 /* Handle modifier keys hit by themselves */
382
383 switch (vk)
384 {
385 case VK_SHIFT: /* shift */
386 if (!SP->return_key_modifiers)
387 return -1;
388
389 return (left_key & 0x8000) ? KEY_SHIFT_L : KEY_SHIFT_R;
390
391 case VK_CONTROL: /* control */
392 if (!SP->return_key_modifiers)
393 return -1;
394
395 return (left_key & 0x8000) ? KEY_CONTROL_L : KEY_CONTROL_R;
396
397 case VK_MENU: /* alt */
398 if (!key)
399 {
400 if (!SP->return_key_modifiers)
401 return -1;
402
403 return (left_key & 0x8000) ? KEY_ALT_L : KEY_ALT_R;
404 }
405 }
406
407 /* The system may emit Ascii or Unicode characters depending on
408 whether ReadConsoleInputA or ReadConsoleInputW is used.
409
410 Normally, if key != 0 then the system did the translation
411 successfully. But this is not true for LEFT_ALT (different to
412 RIGHT_ALT). In case of LEFT_ALT we can get key != 0. So
413 check for this first. */
414
415 if (key && ( !(state & LEFT_ALT_PRESSED) ||
416 (state & RIGHT_ALT_PRESSED) ))
417 {
418 /* This code should catch all keys returning a printable
419 character. Characters above 0x7F should be returned as
420 positive codes. But if'ndef NUMKEYPAD we have to return
421 extended keycodes for keypad codes. */
422
423 #ifndef NUMKEYPAD
424 if (kptab[vk].extended == 0)
425 #endif
426 {
427 SP->key_code = FALSE;
428 return key;
429 }
430 }
431
432 /* This case happens if a functional key has been entered. */
433
434 if ((state & ENHANCED_KEY) && (kptab[vk].extended != 999))
435 {
436 enhanced = TRUE;
437 idx = kptab[vk].extended;
438 }
439 else
440 {
441 enhanced = FALSE;
442 idx = vk;
443 }
444
445 if (state & SHIFT_PRESSED)
446 key = enhanced ? ext_kptab[idx].shift : kptab[idx].shift;
447
448 else if (state & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED))
449 key = enhanced ? ext_kptab[idx].control : kptab[idx].control;
450
451 else if (state & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED))
452 key = enhanced ? ext_kptab[idx].alt : kptab[idx].alt;
453
454 else
455 key = enhanced ? ext_kptab[idx].normal : kptab[idx].normal;
456
457 if (key < KEY_CODE_YES)
458 SP->key_code = FALSE;
459
460 return key;
461 }
462
463 static int _process_mouse_event(void)
464 {
465 static const DWORD button_mask[] = {1, 4, 2};
466 short action, shift_flags = 0;
467 int i;
468
469 save_press = 0;
470 SP->key_code = TRUE;
471
472 memset(&pdc_mouse_status, 0, sizeof(MOUSE_STATUS));
473
474 /* Handle scroll wheel */
475
476 if (MEV.dwEventFlags == 4)
477 {
478 pdc_mouse_status.changes = (MEV.dwButtonState & 0xFF000000) ?
479 PDC_MOUSE_WHEEL_DOWN : PDC_MOUSE_WHEEL_UP;
480
481 pdc_mouse_status.x = -1;
482 pdc_mouse_status.y = -1;
483
484 memset(&old_mouse_status, 0, sizeof(old_mouse_status));
485
486 return KEY_MOUSE;
487 }
488
489 action = (MEV.dwEventFlags == 2) ? BUTTON_DOUBLE_CLICKED :
490 ((MEV.dwEventFlags == 1) ? BUTTON_MOVED : BUTTON_PRESSED);
491
492 for (i = 0; i < 3; i++)
493 pdc_mouse_status.button[i] =
494 (MEV.dwButtonState & button_mask[i]) ? action : 0;
495
496 if (action == BUTTON_PRESSED && MEV.dwButtonState & 7 && SP->mouse_wait)
497 {
498 /* Check for a click -- a PRESS followed immediately by a release */
499
500 if (!event_count)
501 {
502 napms(SP->mouse_wait);
503
504 GetNumberOfConsoleInputEvents(pdc_con_in, &event_count);
505 }
506
507 if (event_count)
508 {
509 INPUT_RECORD ip;
510 DWORD count;
511 bool have_click = FALSE;
512
513 PeekConsoleInput(pdc_con_in, &ip, 1, &count);
514
515 for (i = 0; i < 3; i++)
516 {
517 if (pdc_mouse_status.button[i] == BUTTON_PRESSED &&
518 !(ip.Event.MouseEvent.dwButtonState & button_mask[i]))
519 {
520 pdc_mouse_status.button[i] = BUTTON_CLICKED;
521 have_click = TRUE;
522 }
523 }
524
525 /* If a click was found, throw out the event */
526
527 if (have_click)
528 ReadConsoleInput(pdc_con_in, &ip, 1, &count);
529 }
530 }
531
532 pdc_mouse_status.x = MEV.dwMousePosition.X;
533 pdc_mouse_status.y = MEV.dwMousePosition.Y;
534
535 pdc_mouse_status.changes = 0;
536
537 for (i = 0; i < 3; i++)
538 {
539 if (old_mouse_status.button[i] != pdc_mouse_status.button[i])
540 pdc_mouse_status.changes |= (1 << i);
541
542 if (pdc_mouse_status.button[i] == BUTTON_MOVED)
543 {
544 /* Discard non-moved "moves" */
545
546 if (pdc_mouse_status.x == old_mouse_status.x &&
547 pdc_mouse_status.y == old_mouse_status.y)
548 return -1;
549
550 /* Motion events always flag the button as changed */
551
552 pdc_mouse_status.changes |= (1 << i);
553 pdc_mouse_status.changes |= PDC_MOUSE_MOVED;
554 break;
555 }
556 }
557
558 old_mouse_status = pdc_mouse_status;
559
560 /* Treat click events as release events for comparison purposes */
561
562 for (i = 0; i < 3; i++)
563 {
564 if (old_mouse_status.button[i] == BUTTON_CLICKED ||
565 old_mouse_status.button[i] == BUTTON_DOUBLE_CLICKED)
566 old_mouse_status.button[i] = BUTTON_RELEASED;
567 }
568
569 /* Check for SHIFT/CONTROL/ALT */
570
571 if (MEV.dwControlKeyState & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED))
572 shift_flags |= BUTTON_ALT;
573
574 if (MEV.dwControlKeyState & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED))
575 shift_flags |= BUTTON_CONTROL;
576
577 if (MEV.dwControlKeyState & SHIFT_PRESSED)
578 shift_flags |= BUTTON_SHIFT;
579
580 if (shift_flags)
581 {
582 for (i = 0; i < 3; i++)
583 {
584 if (pdc_mouse_status.changes & (1 << i))
585 pdc_mouse_status.button[i] |= shift_flags;
586 }
587 }
588
589 return KEY_MOUSE;
590 }
591
592 /* return the next available key or mouse event */
593
594 int PDC_get_key(void)
595 {
596 pdc_key_modifiers = 0L;
597
598 if (!key_count)
599 {
600 DWORD count;
601
602 ReadConsoleInput(pdc_con_in, &save_ip, 1, &count);
603 event_count--;
604
605 if (save_ip.EventType == MOUSE_EVENT)
606 key_count = 1;
607 else if (save_ip.EventType == KEY_EVENT)
608 key_count = _get_key_count();
609 }
610
611 if (key_count)
612 {
613 key_count--;
614
615 switch (save_ip.EventType)
616 {
617 case KEY_EVENT:
618 return _process_key_event();
619
620 case MOUSE_EVENT:
621 return _process_mouse_event();
622 }
623 }
624
625 return -1;
626 }
627
628 /* discard any pending keyboard or mouse input -- this is the core
629 routine for flushinp() */
630
631 void PDC_flushinp(void)
632 {
633 PDC_LOG(("PDC_flushinp() - called\n"));
634
635 FlushConsoleInputBuffer(pdc_con_in);
636 }
637
638 int PDC_mouse_set(void)
639 {
640 /* If turning on mouse input: Set ENABLE_MOUSE_INPUT, and clear
641 all other flags, including the extended flags;
642 If turning off the mouse: Set QuickEdit Mode to the status it
643 had on startup, and clear all other flags */
644
645 SetConsoleMode(pdc_con_in, SP->_trap_mbe ?
646 (ENABLE_MOUSE_INPUT|0x0080) : (pdc_quick_edit|0x0080));
647
648 memset(&old_mouse_status, 0, sizeof(old_mouse_status));
649
650 return OK;
651 }
652
653 int PDC_modifiers_set(void)
654 {
655 return OK;
656 }

mercurial