libpayload: remove trailing whitespace and run dos2unix
[coreboot.git] / payloads / libpayload / curses / PDCurses-3.4 / win32 / pdckbd.c
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 }