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