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