1 /********************************************************************/
2 /*                                                                  */
3 /*  gkb_win.c     Keyboard and mouse access for windows.            */
4 /*  Copyright (C) 1989 - 2013, 2015, 2016, 2018  Thomas Mertes      */
5 /*  Copyright (C) 2020, 2021  Thomas Mertes                         */
6 /*                                                                  */
7 /*  This file is part of the Seed7 Runtime Library.                 */
8 /*                                                                  */
9 /*  The Seed7 Runtime Library is free software; you can             */
10 /*  redistribute it and/or modify it under the terms of the GNU     */
11 /*  Lesser General Public License as published by the Free Software */
12 /*  Foundation; either version 2.1 of the License, or (at your      */
13 /*  option) any later version.                                      */
14 /*                                                                  */
15 /*  The Seed7 Runtime Library is distributed in the hope that it    */
16 /*  will be useful, but WITHOUT ANY WARRANTY; without even the      */
17 /*  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR */
18 /*  PURPOSE.  See the GNU Lesser General Public License for more    */
19 /*  details.                                                        */
20 /*                                                                  */
21 /*  You should have received a copy of the GNU Lesser General       */
22 /*  Public License along with this program; if not, write to the    */
23 /*  Free Software Foundation, Inc., 51 Franklin Street,             */
24 /*  Fifth Floor, Boston, MA  02110-1301, USA.                       */
25 /*                                                                  */
26 /*  Module: Seed7 Runtime Library                                   */
27 /*  File: seed7/src/gkb_x11.c                                       */
28 /*  Changes: 2005 - 2007, 2013  Thomas Mertes                       */
29 /*  Content: Keyboard and mouse access for windows.                 */
30 /*                                                                  */
31 /********************************************************************/
32 
33 #define LOG_FUNCTIONS 0
34 #define VERBOSE_EXCEPTIONS 0
35 
36 #include "version.h"
37 
38 #include "stdlib.h"
39 #include "stdio.h"
40 #include "windows.h"
41 #if WINDOWSX_H_PRESENT
42 #include "windowsx.h"
43 #else
44 #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
45 #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
46 #endif
47 
48 #include "common.h"
49 #include "data_rtl.h"
50 #include "hsh_rtl.h"
51 #include "rtl_err.h"
52 #include "kbd_drv.h"
53 
54 
55 #define TRACE_EVENTS 0
56 #if TRACE_EVENTS
57 #define traceEvent(traceStatements) traceStatements
58 #else
59 #define traceEvent(traceStatements)
60 #endif
61 
62 static intType button_x = 0;
63 static intType button_y = 0;
64 static HWND button_window = 0;
65 static rtlHashType window_hash = NULL;
66 static WPARAM resizeMode = 0;
67 static int resizeLeft;
68 static int resizeTop;
69 static int resizeStartWidth;
70 static int resizeStartHeight;
71 static int resizeWidthDelta;
72 static int resizeHeightDelta;
73 static boolType mouseMoveProcessed = FALSE;
74 
75 static const charType map_1252_to_unicode[] = {
76 /* 128 */ 0x20AC,    '?', 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
77 /* 136 */ 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152,    '?', 0x017D,    '?',
78 /* 144 */    '?', 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
79 /* 152 */ 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153,    '?', 0x017E, 0x0178};
80 
81 extern int getCloseAction (winType actual_window);
82 extern void setResizeReturnsKey (winType resizeWindow, boolType active);
83 extern boolType getResizeReturnsKey (winType resizeWindow);
84 extern void drwSetCloseAction (winType actual_window, intType closeAction);
85 
86 
87 #ifdef DMC_GKB_WIN_DEFINES
88 #define WM_MOUSEWHEEL                   0x020A
89 #endif
90 
91 #ifndef WM_XBUTTONDOWN
92 #define WM_XBUTTONDOWN 0x020B
93 #endif
94 
95 #if defined(_WIN64)
96 typedef int64Type intPtrType;
97 #else
98 typedef int32Type intPtrType;
99 #endif
100 
101 
102 
find_window(HWND sys_window)103 winType find_window (HWND sys_window)
104 
105   {
106     winType window;
107 
108   /* find_window */
109     if (window_hash == NULL) {
110       window = NULL;
111     } else {
112       window = (winType) (memSizeType)
113           hshIdxDefault0(window_hash,
114                          (genericType) (memSizeType) sys_window,
115                          (intType) ((memSizeType) sys_window) >> 6,
116                          (compareType) &genericCmp);
117     } /* if */
118     logFunction(printf("find_window(" FMT_X_MEM ") --> " FMT_X_MEM "\n",
119                        (memSizeType) sys_window, (memSizeType) window););
120     return window;
121   } /* find_window */
122 
123 
124 
enter_window(winType curr_window,HWND sys_window)125 void enter_window (winType curr_window, HWND sys_window)
126 
127   { /* enter_window */
128     /* printf("enter_window(%lx, %lx)\n", (unsigned long) curr_window, (unsigned long) sys_window); */
129     if (window_hash == NULL) {
130       window_hash = hshEmpty();
131     } /* if */
132     (void) hshIdxEnterDefault(window_hash,
133                               (genericType) (memSizeType) sys_window,
134                               (genericType) (memSizeType) curr_window,
135                               (intType) ((memSizeType) sys_window) >> 6);
136   } /* enter_window */
137 
138 
139 
remove_window(HWND sys_window)140 void remove_window (HWND sys_window)
141 
142   { /* remove_window */
143     /* printf("remove_window(%lx)\n", (unsigned long) sys_window); */
144     hshExcl(window_hash,
145             (genericType) (memSizeType) sys_window,
146             (intType) ((memSizeType) sys_window) >> 6,
147             (compareType) &genericCmp,
148             (destrFuncType) &genericDestr,
149             (destrFuncType) &genericDestr);
150   } /* remove_window */
151 
152 
153 
resizeBottomAndRight(MSG * msg)154 static void resizeBottomAndRight (MSG *msg)
155 
156   {
157     POINT point;
158     RECT rect;
159 
160   /* resizeBottomAndRight */
161     resizeMode = msg->wParam;
162     point.x = GET_X_LPARAM(msg->lParam);
163     point.y = GET_Y_LPARAM(msg->lParam);
164     ScreenToClient(msg->hwnd, &point);
165     SetCapture(msg->hwnd);
166     GetWindowRect(msg->hwnd, &rect);
167     resizeStartWidth = (int) (rect.right - rect.left);
168     resizeStartHeight = (int) (rect.bottom - rect.top);
169     GetClientRect(msg->hwnd, &rect);
170     resizeWidthDelta = resizeStartWidth - (int) (rect.right - rect.left);
171     resizeHeightDelta = resizeStartHeight - (int) (rect.bottom - rect.top);
172     resizeWidthDelta -= point.x - rect.right;
173     resizeHeightDelta -= point.y - rect.bottom;
174     BringWindowToTop(msg->hwnd);
175   } /* resizeBottomAndRight */
176 
177 
178 
resizeTopAndLeft(MSG * msg)179 static void resizeTopAndLeft (MSG *msg)
180 
181   {
182     POINT point;
183     RECT rect;
184 
185   /* resizeTopAndLeft */
186     resizeMode = msg->wParam;
187     point.x = GET_X_LPARAM(msg->lParam);
188     point.y = GET_Y_LPARAM(msg->lParam);
189     ScreenToClient(msg->hwnd, &point);
190     SetCapture(msg->hwnd);
191     GetWindowRect(msg->hwnd, &rect);
192     resizeLeft = rect.left;
193     resizeTop = rect.top;
194     resizeStartWidth = (int) (rect.right - rect.left);
195     resizeStartHeight = (int) (rect.bottom - rect.top);
196     GetClientRect(msg->hwnd, &rect);
197     resizeWidthDelta = point.x - rect.left;
198     resizeHeightDelta = point.y - rect.top;
199     BringWindowToTop(msg->hwnd);
200   } /* resizeTopAndLeft */
201 
202 
203 
startMoveWindow(MSG * msg)204 static void startMoveWindow (MSG *msg)
205 
206   {
207     POINT point;
208     RECT rect;
209 
210   /* startMoveWindow */
211     resizeMode = msg->wParam;
212     point.x = GET_X_LPARAM(msg->lParam);
213     point.y = GET_Y_LPARAM(msg->lParam);
214     ScreenToClient(msg->hwnd, &point);
215     SetCapture(msg->hwnd);
216     GetWindowRect(msg->hwnd, &rect);
217     resizeLeft = rect.left;
218     resizeTop = rect.top;
219     GetClientRect(msg->hwnd, &rect);
220     resizeWidthDelta = point.x - rect.left;
221     resizeHeightDelta = point.y - rect.top;
222     BringWindowToTop(msg->hwnd);
223   } /* startMoveWindow */
224 
225 
226 
systemSizeCommand(MSG * msg)227 static void systemSizeCommand (MSG *msg)
228 
229   {
230     RECT windowRect;
231     RECT clientRect;
232     POINT clientBottomRight;
233 
234   /* systemSizeCommand */
235     GetWindowRect(msg->hwnd, &windowRect);
236     GetClientRect(msg->hwnd, &clientRect);
237     clientBottomRight.x = clientRect.right;
238     clientBottomRight.y = clientRect.bottom;
239     ClientToScreen(msg->hwnd, &clientBottomRight);
240     SetCursorPos(clientBottomRight.x + (windowRect.right - clientBottomRight.x) / 2,
241                  clientBottomRight.y + (windowRect.bottom - clientBottomRight.y) / 2);
242   } /* systemSizeCommand */
243 
244 
245 
systemMoveCommand(MSG * msg)246 static void systemMoveCommand (MSG *msg)
247 
248   {
249     RECT windowRect;
250     RECT clientRect;
251     POINT clientTopLeft;
252 
253   /* systemMoveCommand */
254     GetWindowRect(msg->hwnd, &windowRect);
255     GetClientRect(msg->hwnd, &clientRect);
256     clientTopLeft.x = clientRect.left;
257     clientTopLeft.y = clientRect.top;
258     ClientToScreen(msg->hwnd, &clientTopLeft);
259     SetCursorPos(windowRect.left + (windowRect.right - windowRect.left) / 2,
260                  windowRect.top + (clientTopLeft.y - windowRect.top) / 2);
261   } /* systemMoveCommand */
262 
263 
264 
processMouseMove(MSG * msg)265 static void processMouseMove (MSG *msg)
266 
267   { /* processMouseMove */
268     switch (resizeMode) {
269       case HTBOTTOMRIGHT:
270         SetWindowPos(msg->hwnd, 0, 0, 0,
271             GET_X_LPARAM(msg->lParam) + resizeWidthDelta,
272             GET_Y_LPARAM(msg->lParam) + resizeHeightDelta,
273             /* SWP_NOSENDCHANGING | */ SWP_NOZORDER | SWP_NOMOVE);
274         break;
275       case HTRIGHT:
276         SetWindowPos(msg->hwnd, 0, 0, 0,
277             GET_X_LPARAM(msg->lParam) + resizeWidthDelta,
278             resizeStartHeight,
279             /* SWP_NOSENDCHANGING | */ SWP_NOZORDER | SWP_NOMOVE);
280         break;
281       case HTBOTTOM:
282         SetWindowPos(msg->hwnd, 0, 0, 0,
283             resizeStartWidth,
284             GET_Y_LPARAM(msg->lParam) + resizeHeightDelta,
285             /* SWP_NOSENDCHANGING | */ SWP_NOZORDER | SWP_NOMOVE);
286         break;
287       case HTTOPLEFT:
288         if ((int) resizeStartWidth - GET_X_LPARAM(msg->lParam) + resizeWidthDelta >= GetSystemMetrics(SM_CXMINTRACK) &&
289             (int) resizeStartHeight - GET_Y_LPARAM(msg->lParam) + resizeHeightDelta >= GetSystemMetrics(SM_CYMINTRACK)) {
290           SetWindowPos(msg->hwnd, 0,
291               resizeLeft + GET_X_LPARAM(msg->lParam) - resizeWidthDelta,
292               resizeTop + GET_Y_LPARAM(msg->lParam) - resizeHeightDelta,
293               resizeStartWidth - GET_X_LPARAM(msg->lParam) + resizeWidthDelta,
294               resizeStartHeight - GET_Y_LPARAM(msg->lParam) + resizeHeightDelta,
295               SWP_NOSENDCHANGING | SWP_NOZORDER);
296           resizeLeft += GET_X_LPARAM(msg->lParam) - resizeWidthDelta;
297           resizeTop += GET_Y_LPARAM(msg->lParam) - resizeHeightDelta;
298           resizeStartWidth -= GET_X_LPARAM(msg->lParam) - resizeWidthDelta;
299           resizeStartHeight -= GET_Y_LPARAM(msg->lParam) - resizeHeightDelta;
300         } else if ((int) resizeStartWidth - GET_X_LPARAM(msg->lParam) + resizeWidthDelta >= GetSystemMetrics(SM_CXMINTRACK) &&
301             (int) resizeStartHeight >= GetSystemMetrics(SM_CYMINTRACK)) {
302           SetWindowPos(msg->hwnd, 0,
303               resizeLeft + GET_X_LPARAM(msg->lParam) - resizeWidthDelta,
304               resizeTop + resizeStartHeight - GetSystemMetrics(SM_CYMINTRACK),
305               resizeStartWidth - GET_X_LPARAM(msg->lParam) + resizeWidthDelta,
306               GetSystemMetrics(SM_CYMINTRACK),
307               SWP_NOSENDCHANGING | SWP_NOZORDER);
308           resizeLeft += GET_X_LPARAM(msg->lParam) - resizeWidthDelta;
309           resizeTop += resizeStartHeight - GetSystemMetrics(SM_CYMINTRACK);
310           resizeStartWidth -= GET_X_LPARAM(msg->lParam) - resizeWidthDelta;
311           resizeStartHeight = GetSystemMetrics(SM_CYMINTRACK);
312         } else if ((int) resizeStartWidth >= GetSystemMetrics(SM_CXMINTRACK) &&
313             (int) resizeStartHeight - GET_Y_LPARAM(msg->lParam) + resizeHeightDelta >= GetSystemMetrics(SM_CYMINTRACK)) {
314           SetWindowPos(msg->hwnd, 0,
315               resizeLeft + resizeStartWidth - GetSystemMetrics(SM_CXMINTRACK),
316               resizeTop + GET_Y_LPARAM(msg->lParam) - resizeHeightDelta,
317               GetSystemMetrics(SM_CXMINTRACK),
318               resizeStartHeight - GET_Y_LPARAM(msg->lParam) + resizeHeightDelta,
319               SWP_NOSENDCHANGING | SWP_NOZORDER);
320           resizeLeft += resizeStartWidth - GetSystemMetrics(SM_CXMINTRACK);;
321           resizeTop += GET_Y_LPARAM(msg->lParam) - resizeHeightDelta;
322           resizeStartWidth = GetSystemMetrics(SM_CXMINTRACK);
323           resizeStartHeight -= GET_Y_LPARAM(msg->lParam) - resizeHeightDelta;
324         } else if ((int) resizeStartWidth >= GetSystemMetrics(SM_CXMINTRACK) &&
325             (int) resizeStartHeight >= GetSystemMetrics(SM_CYMINTRACK)) {
326           SetWindowPos(msg->hwnd, 0,
327               resizeLeft + resizeStartWidth - GetSystemMetrics(SM_CXMINTRACK),
328               resizeTop + resizeStartHeight - GetSystemMetrics(SM_CYMINTRACK),
329               GetSystemMetrics(SM_CXMINTRACK),
330               GetSystemMetrics(SM_CYMINTRACK),
331               SWP_NOSENDCHANGING | SWP_NOZORDER);
332           resizeLeft += resizeStartWidth - GetSystemMetrics(SM_CXMINTRACK);
333           resizeTop += resizeStartHeight - GetSystemMetrics(SM_CYMINTRACK);
334           resizeStartWidth = GetSystemMetrics(SM_CXMINTRACK);
335           resizeStartHeight = GetSystemMetrics(SM_CYMINTRACK);
336         } /* if */
337         break;
338       case HTLEFT:
339         if ((int) resizeStartWidth - GET_X_LPARAM(msg->lParam) + resizeWidthDelta >= GetSystemMetrics(SM_CXMINTRACK)) {
340           SetWindowPos(msg->hwnd, 0,
341               resizeLeft + GET_X_LPARAM(msg->lParam) - resizeWidthDelta,
342               resizeTop,
343               resizeStartWidth - GET_X_LPARAM(msg->lParam) + resizeWidthDelta,
344               resizeStartHeight,
345               SWP_NOSENDCHANGING | SWP_NOZORDER);
346           resizeLeft += GET_X_LPARAM(msg->lParam) - resizeWidthDelta;
347           resizeStartWidth -= GET_X_LPARAM(msg->lParam) - resizeWidthDelta;
348         } else if ((int) resizeStartWidth >= GetSystemMetrics(SM_CXMINTRACK)) {
349           SetWindowPos(msg->hwnd, 0,
350               resizeLeft + resizeStartWidth - GetSystemMetrics(SM_CXMINTRACK),
351               resizeTop,
352               GetSystemMetrics(SM_CXMINTRACK),
353               resizeStartHeight,
354               SWP_NOSENDCHANGING | SWP_NOZORDER);
355           resizeLeft += resizeStartWidth - GetSystemMetrics(SM_CXMINTRACK);
356           resizeStartWidth = GetSystemMetrics(SM_CXMINTRACK);
357         } /* if */
358         break;
359       case HTTOP:
360         if ((int) resizeStartHeight - GET_Y_LPARAM(msg->lParam) + resizeHeightDelta >= GetSystemMetrics(SM_CYMINTRACK)) {
361           SetWindowPos(msg->hwnd, 0,
362               resizeLeft,
363               resizeTop + GET_Y_LPARAM(msg->lParam) - resizeHeightDelta,
364               resizeStartWidth,
365               resizeStartHeight - GET_Y_LPARAM(msg->lParam) + resizeHeightDelta,
366               SWP_NOSENDCHANGING | SWP_NOZORDER);
367           resizeTop += GET_Y_LPARAM(msg->lParam) - resizeHeightDelta;
368           resizeStartHeight -= GET_Y_LPARAM(msg->lParam) - resizeHeightDelta;
369         } else if ((int) resizeStartHeight >= GetSystemMetrics(SM_CYMINTRACK)) {
370           SetWindowPos(msg->hwnd, 0,
371               resizeLeft,
372               resizeTop + resizeStartHeight - GetSystemMetrics(SM_CYMINTRACK),
373               resizeStartWidth,
374               GetSystemMetrics(SM_CYMINTRACK),
375               SWP_NOSENDCHANGING | SWP_NOZORDER);
376           resizeTop += resizeStartHeight - GetSystemMetrics(SM_CYMINTRACK);
377           resizeStartHeight = GetSystemMetrics(SM_CYMINTRACK);
378         } /* if */
379         break;
380       case HTTOPRIGHT:
381         if ((int) resizeStartHeight - GET_Y_LPARAM(msg->lParam) + resizeHeightDelta >= GetSystemMetrics(SM_CYMINTRACK)) {
382           SetWindowPos(msg->hwnd, 0,
383               resizeLeft,
384               resizeTop + GET_Y_LPARAM(msg->lParam) - resizeHeightDelta,
385               resizeStartWidth + GET_X_LPARAM(msg->lParam) - resizeWidthDelta,
386               resizeStartHeight - GET_Y_LPARAM(msg->lParam) + resizeHeightDelta,
387               /* SWP_NOSENDCHANGING | */ SWP_NOZORDER);
388           resizeTop += GET_Y_LPARAM(msg->lParam) - resizeHeightDelta;
389           resizeStartHeight -= GET_Y_LPARAM(msg->lParam) - resizeHeightDelta;
390         } else if ((int) resizeStartHeight >= GetSystemMetrics(SM_CYMINTRACK)) {
391           SetWindowPos(msg->hwnd, 0,
392               resizeLeft,
393               resizeTop + resizeStartHeight - GetSystemMetrics(SM_CYMINTRACK),
394               resizeStartWidth + GET_X_LPARAM(msg->lParam) - resizeWidthDelta,
395               GetSystemMetrics(SM_CYMINTRACK),
396               /* SWP_NOSENDCHANGING | */ SWP_NOZORDER);
397           resizeTop += resizeStartHeight - GetSystemMetrics(SM_CYMINTRACK);
398           resizeStartHeight = GetSystemMetrics(SM_CYMINTRACK);
399         } /* if */
400         break;
401       case HTBOTTOMLEFT:
402         if ((int) resizeStartWidth - GET_X_LPARAM(msg->lParam) + resizeWidthDelta >= GetSystemMetrics(SM_CXMINTRACK)) {
403           SetWindowPos(msg->hwnd, 0,
404               resizeLeft + GET_X_LPARAM(msg->lParam) - resizeWidthDelta,
405               resizeTop,
406               resizeStartWidth - GET_X_LPARAM(msg->lParam) + resizeWidthDelta,
407               resizeStartHeight + GET_Y_LPARAM(msg->lParam) - resizeHeightDelta,
408               /* SWP_NOSENDCHANGING | */ SWP_NOZORDER);
409           resizeLeft += GET_X_LPARAM(msg->lParam) - resizeWidthDelta;
410           resizeStartWidth -= GET_X_LPARAM(msg->lParam) - resizeWidthDelta;
411         } else if ((int) resizeStartWidth >= GetSystemMetrics(SM_CXMINTRACK)) {
412           SetWindowPos(msg->hwnd, 0,
413               resizeLeft + resizeStartWidth - GetSystemMetrics(SM_CXMINTRACK),
414               resizeTop,
415               GetSystemMetrics(SM_CXMINTRACK),
416               resizeStartHeight + GET_Y_LPARAM(msg->lParam) - resizeHeightDelta,
417               /* SWP_NOSENDCHANGING | */ SWP_NOZORDER);
418           resizeLeft += resizeStartWidth - GetSystemMetrics(SM_CXMINTRACK);
419           resizeStartWidth = GetSystemMetrics(SM_CXMINTRACK);
420         } /* if */
421         break;
422       case HTCAPTION:
423         SetWindowPos(msg->hwnd, 0,
424             resizeLeft + GET_X_LPARAM(msg->lParam) - resizeWidthDelta,
425             resizeTop + GET_Y_LPARAM(msg->lParam) - resizeHeightDelta,
426             0, 0,
427             SWP_NOSENDCHANGING | SWP_NOZORDER | SWP_NOSIZE);
428           resizeLeft += GET_X_LPARAM(msg->lParam) - resizeWidthDelta;
429           resizeTop += GET_Y_LPARAM(msg->lParam) - resizeHeightDelta;
430         break;
431     } /* switch */
432   } /* processMouseMove */
433 
434 
435 
gkbGetc(void)436 charType gkbGetc (void)
437 
438   {
439     BOOL bRet;
440     MSG msg;
441     charType result = K_NONE;
442 
443   /* gkbGetc */
444     logFunction(printf("gkbGetc\n"););
445     /* printf("before GetMessage\n"); */
446     bRet = GetMessage(&msg, NULL, 0, 0);
447     /* printf("after GetMessage\n"); */
448     while (result == K_NONE && bRet != 0) {
449       if (bRet == -1) {
450         logError(printf("GetMessage(&msg, NULL, 0, 0)=-1\n"););
451       } else {
452         /* printf("gkbGetc message=%d %lu, %d, %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
453         switch (msg.message) {
454           case WM_KEYDOWN:
455             traceEvent(printf("WM_KEYDOWN hwnd=" FMT_U_MEM ", wParam=" FMT_U64
456                               ", lParam=" FMT_X64 ", SHIFT=%hx, CONTROL=%hx, MENU=%hx\n",
457                               (memSizeType) msg.hwnd, (uint64Type) msg.wParam,
458                               (uint64Type) msg.lParam, GetKeyState(VK_SHIFT),
459                               GetKeyState(VK_CONTROL), GetKeyState(VK_MENU)););
460             if (GetKeyState(VK_SHIFT) & 0x8000) {
461               /* printf("VK_SHIFT\n"); */
462               switch (msg.wParam) {
463                 case VK_RETURN:   result = K_SFT_NL;         break;
464                 case VK_BACK:     result = K_SFT_BS;         break;
465                 case VK_TAB:      result = K_BACKTAB;        break;
466                 case VK_ESCAPE:   result = K_SFT_ESC;        break;
467                 case VK_F1:       result = K_SFT_F1;         break;
468                 case VK_F2:       result = K_SFT_F2;         break;
469                 case VK_F3:       result = K_SFT_F3;         break;
470                 case VK_F4:       result = K_SFT_F4;         break;
471                 case VK_F5:       result = K_SFT_F5;         break;
472                 case VK_F6:       result = K_SFT_F6;         break;
473                 case VK_F7:       result = K_SFT_F7;         break;
474                 case VK_F8:       result = K_SFT_F8;         break;
475                 case VK_F9:       result = K_SFT_F9;         break;
476                 case VK_F10:      result = K_SFT_F10;        break;
477                 case VK_F11:      result = K_SFT_F11;        break;
478                 case VK_F12:      result = K_SFT_F12;        break;
479                 case VK_LEFT:     result = K_SFT_LEFT;       break;
480                 case VK_RIGHT:    result = K_SFT_RIGHT;      break;
481                 case VK_UP:       result = K_SFT_UP;         break;
482                 case VK_DOWN:     result = K_SFT_DOWN;       break;
483                 case VK_HOME:     result = K_SFT_HOME;       break;
484                 case VK_END:      result = K_SFT_END;        break;
485                 case VK_PRIOR:    result = K_SFT_PGUP;       break;
486                 case VK_NEXT:     result = K_SFT_PGDN;       break;
487                 case VK_CLEAR:    result = K_SFT_PAD_CENTER; break;
488                 case VK_INSERT:   result = K_SFT_INS;        break;
489                 case VK_DELETE:   result = K_SFT_DEL;        break;
490                 case VK_APPS:     result = K_SFT_MENU;       break;
491                 case VK_PRINT:    result = K_SFT_PRINT;      break;
492                 case VK_PAUSE:    result = K_SFT_PAUSE;      break;
493                 case VK_SHIFT:
494                 case VK_CONTROL:
495                 case VK_MENU:
496                 case VK_CAPITAL:
497                 case VK_NUMLOCK:
498                 case VK_SCROLL:   result = K_NONE;           break;
499                 default:          result = K_UNDEF;          break;
500               } /* switch */
501             } else if (((GetKeyState(VK_CONTROL)  & 0x8000) != 0 &&
502                         (GetKeyState(VK_RMENU)    & 0x8000) == 0) ||
503                         (GetKeyState(VK_RCONTROL) & 0x8000) != 0) {
504               /* This condition is complicated because Alt Gr is     */
505               /* encoded as if left-control + right-alt are pressed. */
506               /* This situation is filtered out with this condition. */
507               /* printf("VK_CONTROL\n"); */
508               switch (msg.wParam) {
509                 case VK_RETURN:   result = K_CTL_NL;         break;
510                 case VK_BACK:     result = K_CTL_BS;         break;
511                 case VK_TAB:      result = K_CTL_TAB;        break;
512                 case VK_ESCAPE:   result = K_CTL_ESC;        break;
513                 case VK_F1:       result = K_CTL_F1;         break;
514                 case VK_F2:       result = K_CTL_F2;         break;
515                 case VK_F3:       result = K_CTL_F3;         break;
516                 case VK_F4:       result = K_CTL_F4;         break;
517                 case VK_F5:       result = K_CTL_F5;         break;
518                 case VK_F6:       result = K_CTL_F6;         break;
519                 case VK_F7:       result = K_CTL_F7;         break;
520                 case VK_F8:       result = K_CTL_F8;         break;
521                 case VK_F9:       result = K_CTL_F9;         break;
522                 case VK_F10:      result = K_CTL_F10;        break;
523                 case VK_F11:      result = K_CTL_F11;        break;
524                 case VK_F12:      result = K_CTL_F12;        break;
525                 case '0':         result = K_CTL_0;          break;
526                 case '1':         result = K_CTL_1;          break;
527                 case '2':         result = K_CTL_2;          break;
528                 case '3':         result = K_CTL_3;          break;
529                 case '4':         result = K_CTL_4;          break;
530                 case '5':         result = K_CTL_5;          break;
531                 case '6':         result = K_CTL_6;          break;
532                 case '7':         result = K_CTL_7;          break;
533                 case '8':         result = K_CTL_8;          break;
534                 case '9':         result = K_CTL_9;          break;
535                 case VK_NUMPAD0:  result = K_CTL_INS;        break;
536                 case VK_NUMPAD1:  result = K_CTL_END;        break;
537                 case VK_NUMPAD2:  result = K_CTL_DOWN;       break;
538                 case VK_NUMPAD3:  result = K_CTL_PGDN;       break;
539                 case VK_NUMPAD4:  result = K_CTL_LEFT;       break;
540                 case VK_NUMPAD5:  result = K_CTL_PAD_CENTER; break;
541                 case VK_NUMPAD6:  result = K_CTL_RIGHT;      break;
542                 case VK_NUMPAD7:  result = K_CTL_HOME;       break;
543                 case VK_NUMPAD8:  result = K_CTL_UP;         break;
544                 case VK_NUMPAD9:  result = K_CTL_PGUP;       break;
545                 case VK_DECIMAL:  result = K_CTL_DEL;        break;
546                 case VK_LEFT:     result = K_CTL_LEFT;       break;
547                 case VK_RIGHT:    result = K_CTL_RIGHT;      break;
548                 case VK_UP:       result = K_CTL_UP;         break;
549                 case VK_DOWN:     result = K_CTL_DOWN;       break;
550                 case VK_HOME:     result = K_CTL_HOME;       break;
551                 case VK_END:      result = K_CTL_END;        break;
552                 case VK_PRIOR:    result = K_CTL_PGUP;       break;
553                 case VK_NEXT:     result = K_CTL_PGDN;       break;
554                 case VK_CLEAR:    result = K_CTL_PAD_CENTER; break;
555                 case VK_INSERT:   result = K_CTL_INS;        break;
556                 case VK_DELETE:   result = K_CTL_DEL;        break;
557                 case VK_APPS:     result = K_CTL_MENU;       break;
558                 case VK_PRINT:    result = K_CTL_PRINT;      break;
559                 case VK_PAUSE:    result = K_CTL_PAUSE;      break;
560                 case VK_SHIFT:
561                 case VK_CONTROL:
562                 case VK_MENU:
563                 case VK_CAPITAL:
564                 case VK_NUMLOCK:
565                 case VK_SCROLL:   result = K_NONE;           break;
566                 default:          result = K_UNDEF;          break;
567               } /* switch */
568             } else if (GetKeyState(VK_MENU) & 0x8000) {
569               /* This condition is true for the Alt key and the Alt Gr key. */
570               /* printf("VK_MENU\n"); */
571               switch (msg.wParam) {
572                 case VK_RETURN:   result = K_ALT_NL;         break;
573                 case VK_BACK:     result = K_ALT_BS;         break;
574                 case VK_TAB:      result = K_ALT_TAB;        break;
575                 case VK_ESCAPE:   result = K_ALT_ESC;        break;
576                 case VK_F1:       result = K_ALT_F1;         break;
577                 case VK_F2:       result = K_ALT_F2;         break;
578                 case VK_F3:       result = K_ALT_F3;         break;
579                 case VK_F4:       result = K_ALT_F4;         break;
580                 case VK_F5:       result = K_ALT_F5;         break;
581                 case VK_F6:       result = K_ALT_F6;         break;
582                 case VK_F7:       result = K_ALT_F7;         break;
583                 case VK_F8:       result = K_ALT_F8;         break;
584                 case VK_F9:       result = K_ALT_F9;         break;
585                 case VK_F10:      result = K_ALT_F10;        break;
586                 case VK_F11:      result = K_ALT_F11;        break;
587                 case VK_F12:      result = K_ALT_F12;        break;
588                 case VK_NUMPAD0:  result = K_ALT_INS;        break;
589                 case VK_NUMPAD1:  result = K_ALT_END;        break;
590                 case VK_NUMPAD2:  result = K_ALT_DOWN;       break;
591                 case VK_NUMPAD3:  result = K_ALT_PGDN;       break;
592                 case VK_NUMPAD4:  result = K_ALT_LEFT;       break;
593                 case VK_NUMPAD5:  result = K_ALT_PAD_CENTER; break;
594                 case VK_NUMPAD6:  result = K_ALT_RIGHT;      break;
595                 case VK_NUMPAD7:  result = K_ALT_HOME;       break;
596                 case VK_NUMPAD8:  result = K_ALT_UP;         break;
597                 case VK_NUMPAD9:  result = K_ALT_PGUP;       break;
598                 case VK_DECIMAL:  result = K_ALT_DEL;        break;
599                 case VK_LEFT:     result = K_ALT_LEFT;       break;
600                 case VK_RIGHT:    result = K_ALT_RIGHT;      break;
601                 case VK_UP:       result = K_ALT_UP;         break;
602                 case VK_DOWN:     result = K_ALT_DOWN;       break;
603                 case VK_HOME:     result = K_ALT_HOME;       break;
604                 case VK_END:      result = K_ALT_END;        break;
605                 case VK_PRIOR:    result = K_ALT_PGUP;       break;
606                 case VK_NEXT:     result = K_ALT_PGDN;       break;
607                 case VK_CLEAR:    result = K_ALT_PAD_CENTER; break;
608                 case VK_INSERT:   result = K_ALT_INS;        break;
609                 case VK_DELETE:   result = K_ALT_DEL;        break;
610                 case VK_APPS:     result = K_ALT_MENU;       break;
611                 case VK_PRINT:    result = K_ALT_PRINT;      break;
612                 case VK_PAUSE:    result = K_ALT_PAUSE;      break;
613                 case VK_SHIFT:
614                 case VK_CONTROL:
615                 case VK_MENU:
616                 case VK_CAPITAL:
617                 case VK_NUMLOCK:
618                 case VK_SCROLL:   result = K_NONE;           break;
619                 default:          result = K_UNDEF;          break;
620               } /* switch */
621             } else if ((GetKeyState(VK_NUMLOCK) & 0x0001) != 0) {
622               /* printf("VK_NUMLOCK\n"); */
623               if (msg.lParam & 0x1000000) {
624                 /* The key is a cursor key but not from the numeric keypad. */
625                 switch (msg.wParam) {
626                   case VK_RETURN:   result = K_NL;         break;
627                   case VK_BACK:     result = K_BS;         break;
628                   case VK_TAB:      result = K_TAB;        break;
629                   case VK_ESCAPE:   result = K_ESC;        break;
630                   case VK_LEFT:     result = K_LEFT;       break;
631                   case VK_RIGHT:    result = K_RIGHT;      break;
632                   case VK_UP:       result = K_UP;         break;
633                   case VK_DOWN:     result = K_DOWN;       break;
634                   case VK_HOME:     result = K_HOME;       break;
635                   case VK_END:      result = K_END;        break;
636                   case VK_PRIOR:    result = K_PGUP;       break;
637                   case VK_NEXT:     result = K_PGDN;       break;
638                   case VK_CLEAR:    result = K_PAD_CENTER; break;
639                   case VK_INSERT:   result = K_INS;        break;
640                   case VK_DELETE:   result = K_DEL;        break;
641                   case VK_APPS:     result = K_MENU;       break;
642                   case VK_PRINT:    result = K_PRINT;      break;
643                   case VK_PAUSE:    result = K_PAUSE;      break;
644                   case VK_SHIFT:
645                   case VK_CONTROL:
646                   case VK_MENU:
647                   case VK_CAPITAL:
648                   case VK_NUMLOCK:
649                   case VK_SCROLL:   result = K_NONE;       break;
650                   default:          result = K_UNDEF;      break;
651                 } /* switch */
652               } else {
653                 switch (msg.wParam) {
654                   case VK_RETURN:   result = K_NL;             break;
655                   case VK_BACK:     result = K_BS;             break;
656                   case VK_TAB:      result = K_TAB;            break;
657                   case VK_ESCAPE:   result = K_ESC;            break;
658                   case VK_F1:       result = K_F1;             break;
659                   case VK_F2:       result = K_F2;             break;
660                   case VK_F3:       result = K_F3;             break;
661                   case VK_F4:       result = K_F4;             break;
662                   case VK_F5:       result = K_F5;             break;
663                   case VK_F6:       result = K_F6;             break;
664                   case VK_F7:       result = K_F7;             break;
665                   case VK_F8:       result = K_F8;             break;
666                   case VK_F9:       result = K_F9;             break;
667                   case VK_F10:      result = K_F10;            break;
668                   case VK_F11:      result = K_F11;            break;
669                   case VK_F12:      result = K_F12;            break;
670                   case VK_LEFT:     result = K_SFT_LEFT;       break;
671                   case VK_RIGHT:    result = K_SFT_RIGHT;      break;
672                   case VK_UP:       result = K_SFT_UP;         break;
673                   case VK_DOWN:     result = K_SFT_DOWN;       break;
674                   case VK_HOME:     result = K_SFT_HOME;       break;
675                   case VK_END:      result = K_SFT_END;        break;
676                   case VK_PRIOR:    result = K_SFT_PGUP;       break;
677                   case VK_NEXT:     result = K_SFT_PGDN;       break;
678                   case VK_CLEAR:    result = K_SFT_PAD_CENTER; break;
679                   case VK_INSERT:   result = K_SFT_INS;        break;
680                   case VK_DELETE:   result = K_SFT_DEL;        break;
681                   case VK_APPS:     result = K_MENU;           break;
682                   case VK_PRINT:    result = K_PRINT;          break;
683                   case VK_PAUSE:    result = K_PAUSE;          break;
684                   case VK_SHIFT:
685                   case VK_CONTROL:
686                   case VK_MENU:
687                   case VK_CAPITAL:
688                   case VK_NUMLOCK:
689                   case VK_SCROLL:   result = K_NONE;           break;
690                   default:          result = K_UNDEF;          break;
691                 } /* switch */
692               } /* if */
693             } else {
694               /* printf("no key state\n"); */
695               switch (msg.wParam) {
696                 case VK_RETURN:   result = K_NL;         break;
697                 case VK_ESCAPE:   result = K_ESC;        break;
698                 case VK_F1:       result = K_F1;         break;
699                 case VK_F2:       result = K_F2;         break;
700                 case VK_F3:       result = K_F3;         break;
701                 case VK_F4:       result = K_F4;         break;
702                 case VK_F5:       result = K_F5;         break;
703                 case VK_F6:       result = K_F6;         break;
704                 case VK_F7:       result = K_F7;         break;
705                 case VK_F8:       result = K_F8;         break;
706                 case VK_F9:       result = K_F9;         break;
707                 case VK_F10:      result = K_F10;        break;
708                 case VK_F11:      result = K_F11;        break;
709                 case VK_F12:      result = K_F12;        break;
710                 case VK_LEFT:     result = K_LEFT;       break;
711                 case VK_RIGHT:    result = K_RIGHT;      break;
712                 case VK_UP:       result = K_UP;         break;
713                 case VK_DOWN:     result = K_DOWN;       break;
714                 case VK_HOME:     result = K_HOME;       break;
715                 case VK_END:      result = K_END;        break;
716                 case VK_PRIOR:    result = K_PGUP;       break;
717                 case VK_NEXT:     result = K_PGDN;       break;
718                 case VK_CLEAR:    result = K_PAD_CENTER; break;
719                 case VK_INSERT:   result = K_INS;        break;
720                 case VK_DELETE:   result = K_DEL;        break;
721                 case VK_APPS:     result = K_MENU;       break;
722                 case VK_PRINT:    result = K_PRINT;      break;
723                 case VK_PAUSE:    result = K_PAUSE;      break;
724                 case VK_SHIFT:
725                 case VK_CONTROL:
726                 case VK_MENU:
727                 case VK_CAPITAL:
728                 case VK_NUMLOCK:
729                 case VK_SCROLL:   result = K_NONE;       break;
730                 default:          result = K_UNDEF;      break;
731               } /* switch */
732             } /* if */
733             if (result == K_UNDEF) {
734               /* printf("TranslateMessage(%d) %lu, %d %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
735               TranslateMessage(&msg);
736               /* printf("translated message=%d %lu, %d %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
737               if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
738                 /* printf("PeekMessage(%d) %lu, %d %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
739                 if (msg.message == WM_CHAR) {
740                   result = K_NONE;
741                 } /* if */
742               } else {
743                 /* printf("PeekMessage --> empty\n"); */
744               } /* if */
745             } /* if */
746             break;
747           case WM_LBUTTONDOWN:
748             traceEvent(printf("WM_LBUTTONDOWN hwnd=" FMT_U_MEM
749                               ", wParam=" FMT_U64 ", lParam=" FMT_X64 "\n",
750                               (memSizeType) msg.hwnd, (uint64Type) msg.wParam,
751                               (uint64Type) msg.lParam););
752             button_x = LOWORD(msg.lParam);
753             button_y = HIWORD(msg.lParam);
754             button_window = msg.hwnd;
755             if (GetKeyState(VK_MENU) & 0x8000) {
756               result = K_ALT_MOUSE1;
757             } else if (msg.wParam & 0x04) {
758               result = K_SFT_MOUSE1;
759             } else if (msg.wParam & 0x08) {
760               result = K_CTL_MOUSE1;
761             } else {
762               result = K_MOUSE1;
763             } /* if */
764             break;
765           case WM_MBUTTONDOWN:
766             traceEvent(printf("WM_MBUTTONDOWN hwnd=" FMT_U_MEM
767                               ", wParam=" FMT_U64 ", lParam=" FMT_X64 "\n",
768                               (memSizeType) msg.hwnd, (uint64Type) msg.wParam,
769                               (uint64Type) msg.lParam););
770             button_x = LOWORD(msg.lParam);
771             button_y = HIWORD(msg.lParam);
772             button_window = msg.hwnd;
773             if (GetKeyState(VK_MENU) & 0x8000) {
774               result = K_ALT_MOUSE2;
775             } else if (msg.wParam & 0x04) {
776               result = K_SFT_MOUSE2;
777             } else if (msg.wParam & 0x08) {
778               result = K_CTL_MOUSE2;
779             } else {
780               result = K_MOUSE2;
781             } /* if */
782             break;
783           case WM_RBUTTONDOWN:
784             traceEvent(printf("WM_RBUTTONDOWN hwnd=" FMT_U_MEM
785                               ", wParam=" FMT_U64 ", lParam=" FMT_X64 "\n",
786                               (memSizeType) msg.hwnd, (uint64Type) msg.wParam,
787                               (uint64Type) msg.lParam););
788             button_x = LOWORD(msg.lParam);
789             button_y = HIWORD(msg.lParam);
790             button_window = msg.hwnd;
791             if (GetKeyState(VK_MENU) & 0x8000) {
792               result = K_ALT_MOUSE3;
793             } else if (msg.wParam & 0x04) {
794               result = K_SFT_MOUSE3;
795             } else if (msg.wParam & 0x08) {
796               result = K_CTL_MOUSE3;
797             } else {
798               result = K_MOUSE3;
799             } /* if */
800             break;
801           case WM_MOUSEWHEEL:
802             traceEvent(printf("WM_MOUSEWHEEL hwnd=" FMT_U_MEM
803                               ", wParam=" FMT_U64 ", lParam=" FMT_X64 "\n",
804                               (memSizeType) msg.hwnd, (uint64Type) msg.wParam,
805                               (uint64Type) msg.lParam););
806             button_x = LOWORD(msg.lParam);
807             button_y = HIWORD(msg.lParam);
808             button_window = msg.hwnd;
809             if ((intPtrType) msg.wParam > 0) {
810               if (GetKeyState(VK_MENU) & 0x8000) {
811                 result = K_ALT_MOUSE4;
812               } else if (msg.wParam & 0x04) {
813                 result = K_SFT_MOUSE4;
814               } else if (msg.wParam & 0x08) {
815                 result = K_CTL_MOUSE4;
816               } else {
817                 result = K_MOUSE4;
818               } /* if */
819             } else {
820               if (GetKeyState(VK_MENU) & 0x8000) {
821                 result = K_ALT_MOUSE5;
822               } else if (msg.wParam & 0x04) {
823                 result = K_SFT_MOUSE5;
824               } else if (msg.wParam & 0x08) {
825                 result = K_CTL_MOUSE5;
826               } else {
827                 result = K_MOUSE5;
828               } /* if */
829             } /* if */
830             break;
831           case WM_XBUTTONDOWN:
832             traceEvent(printf("WM_XBUTTONDOWN hwnd=" FMT_U_MEM
833                               ", wParam=" FMT_U64 ", lParam=" FMT_X64 "\n",
834                               (memSizeType) msg.hwnd, (uint64Type) msg.wParam,
835                               (uint64Type) msg.lParam););
836             button_x = LOWORD(msg.lParam);
837             button_y = HIWORD(msg.lParam);
838             button_window = msg.hwnd;
839             if ((msg.wParam & 0xffff0) == 0x20040) {
840               if (GetKeyState(VK_MENU) & 0x8000) {
841                 result = K_ALT_MOUSE_FWD;
842               } else if (msg.wParam & 0x04) {
843                 result = K_SFT_MOUSE_FWD;
844               } else if (msg.wParam & 0x08) {
845                 result = K_CTL_MOUSE_FWD;
846               } else {
847                 result = K_MOUSE_FWD;
848               } /* if */
849             } else if ((msg.wParam & 0xffff0) == 0x10020) {
850               if (GetKeyState(VK_MENU) & 0x8000) {
851                 result = K_ALT_MOUSE_BACK;
852               } else if (msg.wParam & 0x04) {
853                 result = K_SFT_MOUSE_BACK;
854               } else if (msg.wParam & 0x08) {
855                 result = K_CTL_MOUSE_BACK;
856               } else {
857                 result = K_MOUSE_BACK;
858               } /* if */
859             } else {
860               result = K_UNDEF;
861             } /* if */
862             break;
863           case WM_SYSKEYDOWN:
864             traceEvent(printf("WM_SYSKEYDOWN hwnd=" FMT_U_MEM
865                               ", wParam=" FMT_U64 ", lParam=" FMT_X64 ", "
866                               "SHIFT=%hx, CONTROL=%hx, MENU=%hx\n",
867                               (memSizeType) msg.hwnd, (uint64Type) msg.wParam,
868                               (uint64Type) msg.lParam, GetKeyState(VK_SHIFT),
869                               GetKeyState(VK_CONTROL), GetKeyState(VK_MENU)););
870             if (msg.lParam & 0x1000000) {
871               /* The key is a cursor key but not from the numeric keypad. */
872               switch (msg.wParam) {
873                 case VK_RETURN:   result = K_ALT_NL;         break;
874                 case VK_BACK:     result = K_ALT_BS;         break;
875                 case VK_TAB:      result = K_ALT_TAB;        break;
876                 case VK_ESCAPE:   result = K_ALT_ESC;        break;
877                 case VK_LEFT:     result = K_ALT_LEFT;       break;
878                 case VK_RIGHT:    result = K_ALT_RIGHT;      break;
879                 case VK_UP:       result = K_ALT_UP;         break;
880                 case VK_DOWN:     result = K_ALT_DOWN;       break;
881                 case VK_HOME:     result = K_ALT_HOME;       break;
882                 case VK_END:      result = K_ALT_END;        break;
883                 case VK_PRIOR:    result = K_ALT_PGUP;       break;
884                 case VK_NEXT:     result = K_ALT_PGDN;       break;
885                 case VK_CLEAR:    result = K_ALT_PAD_CENTER; break;
886                 case VK_INSERT:   result = K_ALT_INS;        break;
887                 case VK_DELETE:   result = K_ALT_DEL;        break;
888                 case VK_APPS:     result = K_ALT_MENU;       break;
889                 case VK_PRINT:    result = K_ALT_PRINT;      break;
890                 case VK_PAUSE:    result = K_ALT_PAUSE;      break;
891                 case VK_SHIFT:
892                 case VK_CONTROL:
893                 case VK_MENU:
894                 case VK_CAPITAL:
895                 case VK_NUMLOCK:
896                 case VK_SCROLL:   result = K_NONE;        break;
897                 default:
898                   /* printf("WM_SYSKEYDOWN %lu, %d %x\n", msg.hwnd, msg.wParam, msg.lParam); */
899                   result = K_UNDEF;
900                   break;
901               } /* switch */
902             } else {
903               switch (msg.wParam) {
904                 case 'A':         result = K_ALT_A;          break;
905                 case 'B':         result = K_ALT_B;          break;
906                 case 'C':         result = K_ALT_C;          break;
907                 case 'D':         result = K_ALT_D;          break;
908                 case 'E':         result = K_ALT_E;          break;
909                 case 'F':         result = K_ALT_F;          break;
910                 case 'G':         result = K_ALT_G;          break;
911                 case 'H':         result = K_ALT_H;          break;
912                 case 'I':         result = K_ALT_I;          break;
913                 case 'J':         result = K_ALT_J;          break;
914                 case 'K':         result = K_ALT_K;          break;
915                 case 'L':         result = K_ALT_L;          break;
916                 case 'M':         result = K_ALT_M;          break;
917                 case 'N':         result = K_ALT_N;          break;
918                 case 'O':         result = K_ALT_O;          break;
919                 case 'P':         result = K_ALT_P;          break;
920                 case 'Q':         result = K_ALT_Q;          break;
921                 case 'R':         result = K_ALT_R;          break;
922                 case 'S':         result = K_ALT_S;          break;
923                 case 'T':         result = K_ALT_T;          break;
924                 case 'U':         result = K_ALT_U;          break;
925                 case 'V':         result = K_ALT_V;          break;
926                 case 'W':         result = K_ALT_W;          break;
927                 case 'X':         result = K_ALT_X;          break;
928                 case 'Y':         result = K_ALT_Y;          break;
929                 case 'Z':         result = K_ALT_Z;          break;
930                 case '0':         result = K_ALT_0;          break;
931                 case '1':         result = K_ALT_1;          break;
932                 case '2':         result = K_ALT_2;          break;
933                 case '3':         result = K_ALT_3;          break;
934                 case '4':         result = K_ALT_4;          break;
935                 case '5':         result = K_ALT_5;          break;
936                 case '6':         result = K_ALT_6;          break;
937                 case '7':         result = K_ALT_7;          break;
938                 case '8':         result = K_ALT_8;          break;
939                 case '9':         result = K_ALT_9;          break;
940                 case VK_RETURN:   result = K_ALT_NL;         break;
941                 case VK_BACK:     result = K_ALT_BS;         break;
942                 case VK_TAB:      result = K_ALT_TAB;        break;
943                 case VK_ESCAPE:   result = K_ALT_ESC;        break;
944                 case VK_NUMPAD0:  result = K_ALT_INS;        break;
945                 case VK_NUMPAD1:  result = K_ALT_END;        break;
946                 case VK_NUMPAD2:  result = K_ALT_DOWN;       break;
947                 case VK_NUMPAD3:  result = K_ALT_PGDN;       break;
948                 case VK_NUMPAD4:  result = K_ALT_LEFT;       break;
949                 case VK_NUMPAD5:  result = K_ALT_PAD_CENTER; break;
950                 case VK_NUMPAD6:  result = K_ALT_RIGHT;      break;
951                 case VK_NUMPAD7:  result = K_ALT_HOME;       break;
952                 case VK_NUMPAD8:  result = K_ALT_UP;         break;
953                 case VK_NUMPAD9:  result = K_ALT_PGUP;       break;
954                 case VK_DECIMAL:  result = K_ALT_DEL;        break;
955                 case VK_LEFT:     result = K_ALT_LEFT;       break;
956                 case VK_RIGHT:    result = K_ALT_RIGHT;      break;
957                 case VK_UP:       result = K_ALT_UP;         break;
958                 case VK_DOWN:     result = K_ALT_DOWN;       break;
959                 case VK_HOME:     result = K_ALT_HOME;       break;
960                 case VK_END:      result = K_ALT_END;        break;
961                 case VK_PRIOR:    result = K_ALT_PGUP;       break;
962                 case VK_NEXT:     result = K_ALT_PGDN;       break;
963                 case VK_CLEAR:    result = K_ALT_PAD_CENTER; break;
964                 case VK_INSERT:   result = K_ALT_INS;        break;
965                 case VK_DELETE:   result = K_ALT_DEL;        break;
966                 case VK_APPS:     result = K_ALT_MENU;       break;
967                 case VK_PRINT:    result = K_ALT_PRINT;      break;
968                 case VK_PAUSE:    result = K_ALT_PAUSE;      break;
969                 case VK_F1:       result = K_ALT_F1;         break;
970                 case VK_F2:       result = K_ALT_F2;         break;
971                 case VK_F3:       result = K_ALT_F3;         break;
972                 case VK_F4:       result = K_ALT_F4;         break;
973                 case VK_F5:       result = K_ALT_F5;         break;
974                 case VK_F6:       result = K_ALT_F6;         break;
975                 case VK_F7:       result = K_ALT_F7;         break;
976                 case VK_F8:       result = K_ALT_F8;         break;
977                 case VK_F9:       result = K_ALT_F9;         break;
978                 case VK_F10:
979                   if (msg.lParam & 0x20000000) {
980                     result = K_ALT_F10;
981                   } else if (GetKeyState(VK_SHIFT) & 0x8000) {
982                     result = K_SFT_F10;
983                   } else if (GetKeyState(VK_CONTROL) & 0x8000) {
984                     result = K_CTL_F10;
985                   } else {
986                     result = K_F10;
987                   } /* if */
988                   break;
989                 case VK_F11:      result = K_ALT_F11;        break;
990                 case VK_F12:      result = K_ALT_F12;        break;
991                 case VK_SHIFT:
992                 case VK_CONTROL:
993                 case VK_MENU:
994                 case VK_CAPITAL:
995                 case VK_NUMLOCK:
996                 case VK_SCROLL:   result = K_NONE;           break;
997                 default:
998                   /* printf("WM_SYSKEYDOWN %lu, %d %x\n", msg.hwnd, msg.wParam, msg.lParam); */
999                   result = K_UNDEF;
1000                   break;
1001               } /* switch */
1002             } /* if */
1003             break;
1004           case WM_NCLBUTTONDOWN:
1005             traceEvent(printf("WM_NCLBUTTONDOWN hwnd=" FMT_U_MEM
1006                               ", wParam=" FMT_U64 ", lParam=" FMT_X64 ", "
1007                               "SHIFT=%hx, CONTROL=%hx, MENU=%hx\n",
1008                               (memSizeType) msg.hwnd, (uint64Type) msg.wParam,
1009                               (uint64Type) msg.lParam, GetKeyState(VK_SHIFT),
1010                               GetKeyState(VK_CONTROL), GetKeyState(VK_MENU)););
1011             if (msg.wParam == HTCLOSE && IsWindow(msg.hwnd)) {
1012               /* printf("HTCLOSE\n"); */
1013               switch (getCloseAction(find_window(msg.hwnd))) {
1014                 case CLOSE_BUTTON_CLOSES_PROGRAM:
1015                   exit(0);
1016                   break;
1017                 case CLOSE_BUTTON_RETURNS_KEY:
1018                   result = K_CLOSE;
1019                   button_window = msg.hwnd;
1020                   break;
1021                 case CLOSE_BUTTON_RAISES_EXCEPTION:
1022                   raise_error(CLOSE_ERROR);
1023                   result = K_CLOSE;
1024                   break;
1025               } /* switch */
1026             } else if (msg.wParam == HTBOTTOMRIGHT || msg.wParam == HTRIGHT || msg.wParam == HTBOTTOM) {
1027               resizeBottomAndRight(&msg);
1028             } else if (msg.wParam == HTTOPLEFT || msg.wParam == HTLEFT || msg.wParam == HTTOP ||
1029                 msg.wParam == HTTOPRIGHT || msg.wParam == HTBOTTOMLEFT) {
1030               resizeTopAndLeft(&msg);
1031             } else if (msg.wParam == HTCAPTION) {
1032               startMoveWindow(&msg);
1033             } else {
1034               TranslateMessage(&msg);
1035               DispatchMessage(&msg);
1036             } /* if */
1037             break;
1038           case WM_SYSCOMMAND:
1039             traceEvent(printf("WM_SYSCOMMAND hwnd=" FMT_U_MEM
1040                               ", wParam=" FMT_U64 ", lParam=" FMT_X64 ", "
1041                               "SHIFT=%hx, CONTROL=%hx, MENU=%hx\n",
1042                               (memSizeType) msg.hwnd, (uint64Type) msg.wParam,
1043                               (uint64Type) msg.lParam, GetKeyState(VK_SHIFT),
1044                               GetKeyState(VK_CONTROL), GetKeyState(VK_MENU)););
1045             if (msg.wParam == SC_CLOSE && IsWindow(msg.hwnd)) {
1046               /* printf("SC_CLOSE\n"); */
1047               switch (getCloseAction(find_window(msg.hwnd))) {
1048                 case CLOSE_BUTTON_CLOSES_PROGRAM:
1049                   exit(0);
1050                   break;
1051                 case CLOSE_BUTTON_RETURNS_KEY:
1052                   result = K_CLOSE;
1053                   button_window = msg.hwnd;
1054                   break;
1055                 case CLOSE_BUTTON_RAISES_EXCEPTION:
1056                   raise_error(CLOSE_ERROR);
1057                   result = K_CLOSE;
1058                   break;
1059               } /* switch */
1060             } else if (msg.wParam == SC_SIZE) {
1061               /* printf("SC_SIZE\n"); */
1062               systemSizeCommand(&msg);
1063             } else if (msg.wParam == SC_MOVE) {
1064               /* printf("SC_MOVE\n"); */
1065               systemMoveCommand(&msg);
1066             } else {
1067               TranslateMessage(&msg);
1068               DispatchMessage(&msg);
1069             } /* if */
1070             break;
1071           case WM_MOUSEMOVE:
1072             traceEvent(printf("WM_MOUSEMOVE hwnd=" FMT_U_MEM
1073                               ", wParam=" FMT_U64 ", lParam=" FMT_X64 ", "
1074                               "SHIFT=%hx, CONTROL=%hx, MENU=%hx\n",
1075                               (memSizeType) msg.hwnd, (uint64Type) msg.wParam,
1076                               (uint64Type) msg.lParam, GetKeyState(VK_SHIFT),
1077                               GetKeyState(VK_CONTROL), GetKeyState(VK_MENU)););
1078             if (resizeMode != 0) {
1079               if (mouseMoveProcessed) {
1080                 if (resizeMode != HTCAPTION) {
1081                   result = K_RESIZE;
1082                   button_window = msg.hwnd;
1083                 } /* if */
1084               } else {
1085                 processMouseMove(&msg);
1086                 if (resizeMode != HTCAPTION &&
1087                     getResizeReturnsKey(find_window(msg.hwnd))) {
1088                   result = K_RESIZE;
1089                   button_window = msg.hwnd;
1090                 } /* if */
1091               } /* if */
1092               mouseMoveProcessed = FALSE;
1093             } else {
1094               TranslateMessage(&msg);
1095               DispatchMessage(&msg);
1096             } /* if */
1097             break;
1098           case WM_LBUTTONUP:
1099             /* printf("WM_LBUTTONUP\n"); */
1100             if (resizeMode != 0) {
1101               /* printf("resizeMode: %d\n", (int) resizeMode); */
1102               ReleaseCapture();
1103               resizeMode = 0;
1104             } else {
1105               TranslateMessage(&msg);
1106               DispatchMessage(&msg);
1107             } /* if */
1108             break;
1109           case WM_CHAR:
1110             traceEvent(printf("WM_CHAR hwnd=" FMT_U_MEM
1111                               ", wParam=" FMT_U64 ", lParam=" FMT_X64 "\n",
1112                               (memSizeType) msg.hwnd, (uint64Type) msg.wParam,
1113                               (uint64Type) msg.lParam););
1114             result = (charType) msg.wParam;
1115             if (result >= 128 && result <= 159) {
1116               result = map_1252_to_unicode[result - 128];
1117             } /* if */
1118             break;
1119           case WM_USER:
1120             traceEvent(printf("WM_USER hwnd=" FMT_U_MEM
1121                               ", wParam=" FMT_U64 ", lParam=" FMT_X64 "\n",
1122                               (memSizeType) msg.hwnd, (uint64Type) msg.wParam,
1123                               (uint64Type) msg.lParam););
1124             result = K_RESIZE;
1125             button_window = msg.hwnd;
1126             break;
1127           default:
1128             /* printf("A message=%d %lu, %d, %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
1129             traceEvent(printf("message=%d, hwnd=" FMT_U_MEM
1130                               ", wParam=" FMT_U64 ", lParam=" FMT_X64 "\n",
1131                               msg.message, (memSizeType) msg.hwnd, (uint64Type) msg.wParam,
1132                               (uint64Type) msg.lParam););
1133             /* E.g.: WM_NCMOUSELEAVE */
1134             TranslateMessage(&msg);
1135             /* printf("translated message=%d %lu, %d %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
1136             DispatchMessage(&msg);
1137             break;
1138         } /* switch */
1139       } /* if */
1140       if (result == K_NONE) {
1141         /* printf("before GetMessage\n"); */
1142         bRet = GetMessage(&msg, NULL, 0, 0);
1143         /* printf("after GetMessage\n"); */
1144       } /* if */
1145     } /* while */
1146     logFunction(printf("gkbGetc --> %d\n", result););
1147     return result;
1148   } /* gkbGetc */
1149 
1150 
1151 
gkbKeyPressed(void)1152 boolType gkbKeyPressed (void)
1153 
1154   {
1155     BOOL msg_present;
1156     BOOL bRet;
1157     MSG msg;
1158     boolType result;
1159 
1160   /* gkbKeyPressed */
1161     logFunction(printf("gkbKeyPressed\n"););
1162     result = FALSE;
1163     msg_present = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
1164     while (msg_present) {
1165       /* printf("gkbKeyPressed message=%d %lu, %d, %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
1166       switch (msg.message) {
1167         case WM_KEYDOWN:
1168         case WM_SYSKEYDOWN:
1169           if (msg.wParam == VK_SHIFT   || msg.wParam == VK_CONTROL ||
1170               msg.wParam == VK_MENU    || msg.wParam == VK_CAPITAL ||
1171               msg.wParam == VK_NUMLOCK || msg.wParam == VK_SCROLL) {
1172             bRet = GetMessage(&msg, NULL, 0, 0);
1173             if (bRet == 0) {
1174               logError(printf("GetMessage(&msg, NULL, 0, 0)=0\n"););
1175             } else if (bRet == -1) {
1176               logError(printf("GetMessage(&msg, NULL, 0, 0)=-1\n"););
1177             } else {
1178               /* printf("message=%d %lu, %d, %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
1179               TranslateMessage(&msg);
1180               /* printf("translated message=%d %lu, %d %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
1181               DispatchMessage(&msg);
1182             } /* if */
1183             msg_present = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
1184           } else {
1185             msg_present = 0;
1186             result = TRUE;
1187           } /* if */
1188           break;
1189         case WM_LBUTTONDOWN:
1190         case WM_MBUTTONDOWN:
1191         case WM_RBUTTONDOWN:
1192         case WM_MOUSEWHEEL:
1193         case WM_XBUTTONDOWN:
1194           /* printf("gkbKeyPressed --> TRUE for message %d\n", msg.message); */
1195           msg_present = 0;
1196           result = TRUE;
1197           break;
1198         case WM_NCLBUTTONDOWN:
1199           traceEvent(printf("gkbKeyPressed WM_NCLBUTTONDOWN hwnd=" FMT_U_MEM
1200                             ", wParam=" FMT_U64 ", lParam=" FMT_X64 "\n",
1201                             (memSizeType) msg.hwnd, (uint64Type) msg.wParam,
1202                             (uint64Type) msg.lParam););
1203           if (msg.wParam == HTCLOSE && IsWindow(msg.hwnd)) {
1204             /* printf("HTCLOSE\n"); */
1205             if (getCloseAction(find_window(msg.hwnd)) == CLOSE_BUTTON_CLOSES_PROGRAM) {
1206               exit(0);
1207             } else {
1208               msg_present = 0;
1209               result = TRUE;
1210             } /* if */
1211           } else if (msg.wParam == HTBOTTOMRIGHT || msg.wParam == HTRIGHT || msg.wParam == HTBOTTOM) {
1212             resizeBottomAndRight(&msg);
1213             bRet = GetMessage(&msg, NULL, 0, 0);
1214             if (bRet == 0 || bRet == -1) {
1215               logError(printf("GetMessage(&msg, NULL, 0, 0)=%d\n", (int) bRet););
1216             } /* if */
1217             msg_present = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
1218           } else if (msg.wParam == HTTOPLEFT || msg.wParam == HTLEFT || msg.wParam == HTTOP ||
1219               msg.wParam == HTTOPRIGHT || msg.wParam == HTBOTTOMLEFT) {
1220             resizeTopAndLeft(&msg);
1221             bRet = GetMessage(&msg, NULL, 0, 0);
1222             if (bRet == 0 || bRet == -1) {
1223               logError(printf("GetMessage(&msg, NULL, 0, 0)=%d\n", (int) bRet););
1224             } /* if */
1225             msg_present = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
1226           } else if (msg.wParam == HTCAPTION) {
1227             startMoveWindow(&msg);
1228             bRet = GetMessage(&msg, NULL, 0, 0);
1229             if (bRet == 0 || bRet == -1) {
1230               logError(printf("GetMessage(&msg, NULL, 0, 0)=%d\n", (int) bRet););
1231             } /* if */
1232             msg_present = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
1233           } else {
1234             bRet = GetMessage(&msg, NULL, 0, 0);
1235             if (bRet == 0 || bRet == -1) {
1236               logError(printf("GetMessage(&msg, NULL, 0, 0)=%d\n", (int) bRet););
1237             } else {
1238               /* printf("x message=%d %lu, %d, %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
1239               TranslateMessage(&msg);
1240               /* printf("x translated message=%d %lu, %d %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
1241               DispatchMessage(&msg);
1242               /* printf("x dispatched message=%d %lu, %d %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
1243             } /* if */
1244             msg_present = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
1245           } /* if */
1246           break;
1247         case WM_SYSCOMMAND:
1248           traceEvent(printf("gkbKeyPressed WM_SYSCOMMAND hwnd=" FMT_U_MEM
1249                              ", wParam=" FMT_U64 ", lParam=" FMT_X64 "\n",
1250                             (memSizeType) msg.hwnd, (uint64Type) msg.wParam,
1251                             (uint64Type) msg.lParam););
1252           if (msg.wParam == SC_CLOSE && IsWindow(msg.hwnd)) {
1253             /* printf("SC_CLOSE\n"); */
1254             msg_present = 0;
1255             result = TRUE;
1256           } else if (msg.wParam == SC_SIZE) {
1257             /* printf("SC_SIZE\n"); */
1258             systemSizeCommand(&msg);
1259             bRet = GetMessage(&msg, NULL, 0, 0);
1260             if (bRet == 0 || bRet == -1) {
1261               logError(printf("GetMessage(&msg, NULL, 0, 0)=%d\n", (int) bRet););
1262             } /* if */
1263             msg_present = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
1264           } else if (msg.wParam == SC_MOVE) {
1265             /* printf("SC_MOVE\n"); */
1266             systemMoveCommand(&msg);
1267             bRet = GetMessage(&msg, NULL, 0, 0);
1268             if (bRet == 0 || bRet == -1) {
1269               logError(printf("GetMessage(&msg, NULL, 0, 0)=%d\n", (int) bRet););
1270             } /* if */
1271             msg_present = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
1272           } else {
1273             bRet = GetMessage(&msg, NULL, 0, 0);
1274             if (bRet == 0 || bRet == -1) {
1275               logError(printf("GetMessage(&msg, NULL, 0, 0)=%d\n", (int) bRet););
1276             } else {
1277               TranslateMessage(&msg);
1278               DispatchMessage(&msg);
1279             } /* if */
1280             msg_present = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
1281           } /* if */
1282           break;
1283         case WM_MOUSEMOVE:
1284           /* printf("gkbKeyPressed WM_MOUSEMOVE\n"); */
1285           if (resizeMode != 0) {
1286             processMouseMove(&msg);
1287             if (resizeMode != HTCAPTION &&
1288                 getResizeReturnsKey(find_window(msg.hwnd))) {
1289               mouseMoveProcessed = TRUE;
1290               msg_present = 0;
1291               result = TRUE;
1292             } else {
1293               bRet = GetMessage(&msg, NULL, 0, 0);
1294               if (bRet == 0 || bRet == -1) {
1295                 logError(printf("GetMessage(&msg, NULL, 0, 0)=%d\n", (int) bRet););
1296               } /* if */
1297               msg_present = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
1298             } /* if */
1299           } else {
1300             bRet = GetMessage(&msg, NULL, 0, 0);
1301             if (bRet == 0 || bRet == -1) {
1302               logError(printf("GetMessage(&msg, NULL, 0, 0)=%d\n", (int) bRet););
1303             } else {
1304               /* printf("x message=%d %lu, %d, %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
1305               TranslateMessage(&msg);
1306               /* printf("x translated message=%d %lu, %d %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
1307               DispatchMessage(&msg);
1308               /* printf("x dispatched message=%d %lu, %d %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
1309             } /* if */
1310             msg_present = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
1311           } /* if */
1312           break;
1313         case WM_LBUTTONUP:
1314           traceEvent(printf("gkbKeyPressed WM_LBUTTONUP hwnd=" FMT_U_MEM
1315                              ", wParam=" FMT_U64 ", lParam=" FMT_X64 "\n",
1316                             (memSizeType) msg.hwnd, (uint64Type) msg.wParam,
1317                             (uint64Type) msg.lParam););
1318           if (resizeMode != 0) {
1319             /* printf("resizeMode: %d\n", (int) resizeMode); */
1320             ReleaseCapture();
1321             resizeMode = 0;
1322             msg_present = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
1323           } else {
1324             bRet = GetMessage(&msg, NULL, 0, 0);
1325             if (bRet == 0 || bRet == -1) {
1326               logError(printf("GetMessage(&msg, NULL, 0, 0)=%d\n", (int) bRet););
1327             } else {
1328               /* printf("y message=%d %lu, %d, %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
1329               TranslateMessage(&msg);
1330               /* printf("y translated message=%d %lu, %d %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
1331               DispatchMessage(&msg);
1332               /* printf("y dispatched message=%d %lu, %d %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
1333             } /* if */
1334             msg_present = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
1335           } /* if */
1336           break;
1337         case WM_SYSKEYUP:
1338           traceEvent(printf("gkbKeyPressed WM_SYSKEYUP hwnd=" FMT_U_MEM
1339                             ", wParam=" FMT_U64 ", lParam=" FMT_X64 "\n",
1340                             (memSizeType) msg.hwnd, (uint64Type) msg.wParam,
1341                             (uint64Type) msg.lParam););
1342           bRet = GetMessage(&msg, NULL, 0, 0);
1343           if (bRet == 0) {
1344             logError(printf("y GetMessage(&msg, NULL, 0, 0)=0\n"););
1345           } else if (bRet == -1) {
1346             logError(printf("y GetMessage(&msg, NULL, 0, 0)=-1\n"););
1347           } /* if */
1348           msg_present = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
1349           break;
1350         case WM_USER:
1351           traceEvent(printf("gkbKeyPressed WM_USER hwnd=" FMT_U_MEM
1352                             ", wParam=" FMT_U64 ", lParam=" FMT_X64 "\n",
1353                             (memSizeType) msg.hwnd, (uint64Type) msg.wParam,
1354                             (uint64Type) msg.lParam););
1355           msg_present = 0;
1356           result = TRUE;
1357           break;
1358         default:
1359           bRet = GetMessage(&msg, NULL, 0, 0);
1360           if (bRet == 0) {
1361             logError(printf("GetMessage(&msg, NULL, 0, 0)=0\n"););
1362           } else if (bRet == -1) {
1363             logError(printf("GetMessage(&msg, NULL, 0, 0)=-1\n"););
1364           } else {
1365             /* printf("B message=%d %lu, %d, %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
1366             TranslateMessage(&msg);
1367             /* printf("translated message=%d %lu, %d %x\n", msg.message, msg.hwnd, msg.wParam, msg.lParam); */
1368             DispatchMessage(&msg);
1369             /* printf("after DispatchMessage\n"); */
1370           } /* if */
1371           msg_present = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
1372           break;
1373       } /* switch */
1374     } /* while */
1375     logFunction(printf("gkbKeyPressed --> %d\n", result););
1376     return result;
1377   } /* gkbKeyPressed */
1378 
1379 
1380 
gkbButtonPressed(charType button)1381 boolType gkbButtonPressed (charType button)
1382 
1383   {
1384     int vkey1 = 0;
1385     int vkey2 = 0;
1386     int not_vkey = 0;
1387     int state_vkey = 0;
1388     boolType okay = TRUE;
1389     boolType result;
1390 
1391   /* gkbButtonPressed */
1392     gkbKeyPressed();
1393     switch (button) {
1394       case K_CTL_A: case K_ALT_A: case 'A': case 'a': vkey1 = 'A'; break;
1395       case K_CTL_B: case K_ALT_B: case 'B': case 'b': vkey1 = 'B'; break;
1396       case K_CTL_C: case K_ALT_C: case 'C': case 'c': vkey1 = 'C'; break;
1397       case K_CTL_D: case K_ALT_D: case 'D': case 'd': vkey1 = 'D'; break;
1398       case K_CTL_E: case K_ALT_E: case 'E': case 'e': vkey1 = 'E'; break;
1399       case K_CTL_F: case K_ALT_F: case 'F': case 'f': vkey1 = 'F'; break;
1400       case K_CTL_G: case K_ALT_G: case 'G': case 'g': vkey1 = 'G'; break;
1401       /* K_CTL_H */ case K_ALT_H: case 'H': case 'h': vkey1 = 'H'; break;
1402       /* K_CTL_I */ case K_ALT_I: case 'I': case 'i': vkey1 = 'I'; break;
1403       /* K_CTL_J */ case K_ALT_J: case 'J': case 'j': vkey1 = 'J'; break;
1404       case K_CTL_K: case K_ALT_K: case 'K': case 'k': vkey1 = 'K'; break;
1405       case K_CTL_L: case K_ALT_L: case 'L': case 'l': vkey1 = 'L'; break;
1406       case K_CTL_M: case K_ALT_M: case 'M': case 'm': vkey1 = 'M'; break;
1407       case K_CTL_N: case K_ALT_N: case 'N': case 'n': vkey1 = 'N'; break;
1408       case K_CTL_O: case K_ALT_O: case 'O': case 'o': vkey1 = 'O'; break;
1409       case K_CTL_P: case K_ALT_P: case 'P': case 'p': vkey1 = 'P'; break;
1410       case K_CTL_Q: case K_ALT_Q: case 'Q': case 'q': vkey1 = 'Q'; break;
1411       case K_CTL_R: case K_ALT_R: case 'R': case 'r': vkey1 = 'R'; break;
1412       case K_CTL_S: case K_ALT_S: case 'S': case 's': vkey1 = 'S'; break;
1413       case K_CTL_T: case K_ALT_T: case 'T': case 't': vkey1 = 'T'; break;
1414       case K_CTL_U: case K_ALT_U: case 'U': case 'u': vkey1 = 'U'; break;
1415       case K_CTL_V: case K_ALT_V: case 'V': case 'v': vkey1 = 'V'; break;
1416       case K_CTL_W: case K_ALT_W: case 'W': case 'w': vkey1 = 'W'; break;
1417       case K_CTL_X: case K_ALT_X: case 'X': case 'x': vkey1 = 'X'; break;
1418       case K_CTL_Y: case K_ALT_Y: case 'Y': case 'y': vkey1 = 'Y'; break;
1419       case K_CTL_Z: case K_ALT_Z: case 'Z': case 'z': vkey1 = 'Z'; break;
1420 
1421       case K_CTL_0: case K_ALT_0: vkey1 = '0'; break;
1422       case K_CTL_1: case K_ALT_1: vkey1 = '1'; break;
1423       case K_CTL_2: case K_ALT_2: vkey1 = '2'; break;
1424       case K_CTL_3: case K_ALT_3: vkey1 = '3'; break;
1425       case K_CTL_4: case K_ALT_4: vkey1 = '4'; break;
1426       case K_CTL_5: case K_ALT_5: vkey1 = '5'; break;
1427       case K_CTL_6: case K_ALT_6: vkey1 = '6'; break;
1428       case K_CTL_7: case K_ALT_7: vkey1 = '7'; break;
1429       case K_CTL_8: case K_ALT_8: vkey1 = '8'; break;
1430       case K_CTL_9: case K_ALT_9: vkey1 = '9'; break;
1431 
1432       case '0': vkey1 = '0';
1433                 if ((GetKeyState(VK_NUMLOCK) & 0x0001) != 0 &&
1434                     (GetKeyState(VK_CONTROL) & 0x8000) == 0 &&
1435                     (GetKeyState(VK_MENU) & 0x8000) == 0) {
1436                   vkey2 = VK_NUMPAD0;
1437                 } break;
1438       case '1': vkey1 = '1';
1439                 if ((GetKeyState(VK_NUMLOCK) & 0x0001) != 0 &&
1440                     (GetKeyState(VK_CONTROL) & 0x8000) == 0 &&
1441                     (GetKeyState(VK_MENU) & 0x8000) == 0) {
1442                   vkey2 = VK_NUMPAD1;
1443                 } break;
1444       case '2': vkey1 = '2';
1445                 if ((GetKeyState(VK_NUMLOCK) & 0x0001) != 0 &&
1446                     (GetKeyState(VK_CONTROL) & 0x8000) == 0 &&
1447                     (GetKeyState(VK_MENU) & 0x8000) == 0) {
1448                   vkey2 = VK_NUMPAD2;
1449                 } break;
1450       case '3': vkey1 = '3';
1451                 if ((GetKeyState(VK_NUMLOCK) & 0x0001) != 0 &&
1452                     (GetKeyState(VK_CONTROL) & 0x8000) == 0 &&
1453                     (GetKeyState(VK_MENU) & 0x8000) == 0) {
1454                   vkey2 = VK_NUMPAD3;
1455                 } break;
1456       case '4': vkey1 = '4';
1457                 if ((GetKeyState(VK_NUMLOCK) & 0x0001) != 0 &&
1458                     (GetKeyState(VK_CONTROL) & 0x8000) == 0 &&
1459                     (GetKeyState(VK_MENU) & 0x8000) == 0) {
1460                   vkey2 = VK_NUMPAD4;
1461                 } break;
1462       case '5': vkey1 = '5';
1463                 if ((GetKeyState(VK_NUMLOCK) & 0x0001) != 0 &&
1464                     (GetKeyState(VK_CONTROL) & 0x8000) == 0 &&
1465                     (GetKeyState(VK_MENU) & 0x8000) == 0) {
1466                   vkey2 = VK_NUMPAD5;
1467                 } break;
1468       case '6': vkey1 = '6';
1469                 if ((GetKeyState(VK_NUMLOCK) & 0x0001) != 0 &&
1470                     (GetKeyState(VK_CONTROL) & 0x8000) == 0 &&
1471                     (GetKeyState(VK_MENU) & 0x8000) == 0) {
1472                   vkey2 = VK_NUMPAD6;
1473                 } break;
1474       case '7': vkey1 = '7';
1475                 if ((GetKeyState(VK_NUMLOCK) & 0x0001) != 0 &&
1476                     (GetKeyState(VK_CONTROL) & 0x8000) == 0 &&
1477                     (GetKeyState(VK_MENU) & 0x8000) == 0) {
1478                   vkey2 = VK_NUMPAD7;
1479                 } break;
1480       case '8': vkey1 = '8';
1481                 if ((GetKeyState(VK_NUMLOCK) & 0x0001) != 0 &&
1482                     (GetKeyState(VK_CONTROL) & 0x8000) == 0 &&
1483                     (GetKeyState(VK_MENU) & 0x8000) == 0) {
1484                   vkey2 = VK_NUMPAD8;
1485                 } break;
1486       case '9': vkey1 = '9';
1487                 if ((GetKeyState(VK_NUMLOCK) & 0x0001) != 0 &&
1488                     (GetKeyState(VK_CONTROL) & 0x8000) == 0 &&
1489                     (GetKeyState(VK_MENU) & 0x8000) == 0) {
1490                   vkey2 = VK_NUMPAD9;
1491                 } break;
1492 
1493       case K_F1:  case K_SFT_F1:  case K_CTL_F1:  case K_ALT_F1:  vkey1 = VK_F1;  break;
1494       case K_F2:  case K_SFT_F2:  case K_CTL_F2:  case K_ALT_F2:  vkey1 = VK_F2;  break;
1495       case K_F3:  case K_SFT_F3:  case K_CTL_F3:  case K_ALT_F3:  vkey1 = VK_F3;  break;
1496       case K_F4:  case K_SFT_F4:  case K_CTL_F4:  case K_ALT_F4:  vkey1 = VK_F4;  break;
1497       case K_F5:  case K_SFT_F5:  case K_CTL_F5:  case K_ALT_F5:  vkey1 = VK_F5;  break;
1498       case K_F6:  case K_SFT_F6:  case K_CTL_F6:  case K_ALT_F6:  vkey1 = VK_F6;  break;
1499       case K_F7:  case K_SFT_F7:  case K_CTL_F7:  case K_ALT_F7:  vkey1 = VK_F7;  break;
1500       case K_F8:  case K_SFT_F8:  case K_CTL_F8:  case K_ALT_F8:  vkey1 = VK_F8;  break;
1501       case K_F9:  case K_SFT_F9:  case K_CTL_F9:  case K_ALT_F9:  vkey1 = VK_F9;  break;
1502       case K_F10: case K_SFT_F10: case K_CTL_F10: case K_ALT_F10: vkey1 = VK_F10; break;
1503       case K_F11: case K_SFT_F11: case K_CTL_F11: case K_ALT_F11: vkey1 = VK_F11; break;
1504       case K_F12: case K_SFT_F12: case K_CTL_F12: case K_ALT_F12: vkey1 = VK_F12; break;
1505 
1506       case K_LEFT:  case K_SFT_LEFT:  case K_CTL_LEFT:  case K_ALT_LEFT:
1507         vkey1 = VK_LEFT;
1508         if ((GetKeyState(VK_CONTROL) & 0x8000) != 0 ||
1509             (GetKeyState(VK_MENU) & 0x8000) != 0) {
1510           vkey2 = VK_NUMPAD4;
1511         } /* if */
1512         break;
1513       case K_RIGHT: case K_SFT_RIGHT: case K_CTL_RIGHT: case K_ALT_RIGHT:
1514         vkey1 = VK_RIGHT;
1515         if ((GetKeyState(VK_CONTROL) & 0x8000) != 0 ||
1516             (GetKeyState(VK_MENU) & 0x8000) != 0) {
1517           vkey2 = VK_NUMPAD6;
1518         } /* if */
1519         break;
1520       case K_UP:    case K_SFT_UP:    case K_CTL_UP:    case K_ALT_UP:
1521         vkey1 = VK_UP;
1522         if ((GetKeyState(VK_CONTROL) & 0x8000) != 0 ||
1523             (GetKeyState(VK_MENU) & 0x8000) != 0) {
1524           vkey2 = VK_NUMPAD8;
1525         } /* if */
1526         break;
1527       case K_DOWN:  case K_SFT_DOWN:  case K_CTL_DOWN:  case K_ALT_DOWN:
1528         vkey1 = VK_DOWN;
1529         if ((GetKeyState(VK_CONTROL) & 0x8000) != 0 ||
1530             (GetKeyState(VK_MENU) & 0x8000) != 0) {
1531           vkey2 = VK_NUMPAD2;
1532         } /* if */
1533         break;
1534       case K_HOME:  case K_SFT_HOME:  case K_CTL_HOME:  case K_ALT_HOME:
1535         vkey1 = VK_HOME;
1536         if ((GetKeyState(VK_CONTROL) & 0x8000) != 0 ||
1537             (GetKeyState(VK_MENU) & 0x8000) != 0) {
1538           vkey2 = VK_NUMPAD7;
1539         } /* if */
1540         break;
1541       case K_END:   case K_SFT_END:   case K_CTL_END:   case K_ALT_END:
1542         vkey1 = VK_END;
1543         if ((GetKeyState(VK_CONTROL) & 0x8000) != 0 ||
1544             (GetKeyState(VK_MENU) & 0x8000) != 0) {
1545           vkey2 = VK_NUMPAD1;
1546         } /* if */
1547         break;
1548       case K_PGUP:  case K_SFT_PGUP:  case K_CTL_PGUP:  case K_ALT_PGUP:
1549         vkey1 = VK_PRIOR;
1550         if ((GetKeyState(VK_CONTROL) & 0x8000) != 0 ||
1551             (GetKeyState(VK_MENU) & 0x8000) != 0) {
1552           vkey2 = VK_NUMPAD9;
1553         } /* if */
1554         break;
1555       case K_PGDN:  case K_SFT_PGDN:  case K_CTL_PGDN:  case K_ALT_PGDN:
1556         vkey1 = VK_NEXT;
1557         if ((GetKeyState(VK_CONTROL) & 0x8000) != 0 ||
1558             (GetKeyState(VK_MENU) & 0x8000) != 0) {
1559           vkey2 = VK_NUMPAD3;
1560         } /* if */
1561         break;
1562       case K_INS:   case K_SFT_INS:   case K_CTL_INS:   case K_ALT_INS:
1563         vkey1 = VK_INSERT;
1564         if ((GetKeyState(VK_CONTROL) & 0x8000) != 0 ||
1565             (GetKeyState(VK_MENU) & 0x8000) != 0) {
1566           vkey2 = VK_NUMPAD0;
1567         } /* if */
1568         break;
1569       case K_DEL:   case K_SFT_DEL:   case K_CTL_DEL:   case K_ALT_DEL:
1570         vkey1 = VK_DELETE;
1571         if ((GetKeyState(VK_CONTROL) & 0x8000) != 0 ||
1572             (GetKeyState(VK_MENU) & 0x8000) != 0) {
1573           vkey2 = VK_DECIMAL;
1574         } /* if */
1575         break;
1576       case K_PAD_CENTER:     case K_SFT_PAD_CENTER:
1577       case K_CTL_PAD_CENTER: case K_ALT_PAD_CENTER:
1578         vkey1 = VK_CLEAR;
1579         if ((GetKeyState(VK_CONTROL) & 0x8000) != 0 ||
1580             (GetKeyState(VK_MENU) & 0x8000) != 0) {
1581           vkey2 = VK_NUMPAD5;
1582         } /* if */
1583         break;
1584 
1585       case K_NL:
1586         vkey1 = VK_RETURN;
1587         if ((GetKeyState(VK_CONTROL) & 0x8000) != 0) {
1588           vkey2 = 'J';
1589         } break;
1590       case K_SFT_NL:  case K_CTL_NL:  case K_ALT_NL:
1591         vkey1 = VK_RETURN; break;
1592       case K_BS:
1593         vkey1 = VK_BACK;
1594         if ((GetKeyState(VK_CONTROL) & 0x8000) != 0) {
1595           vkey2 = 'H';
1596         } break;
1597       case K_SFT_BS:  case K_CTL_BS:  case K_ALT_BS:
1598         vkey1 = VK_BACK;   break;
1599       case K_TAB:
1600         vkey1 = VK_TAB;
1601         if ((GetKeyState(VK_CONTROL) & 0x8000) != 0) {
1602           vkey2 = 'I';
1603         } break;
1604       case K_BACKTAB: case K_CTL_TAB: case K_ALT_TAB:
1605         vkey1 = VK_TAB;    break;
1606       case K_ESC: case K_SFT_ESC: case K_CTL_ESC: case K_ALT_ESC:
1607         vkey1 = VK_ESCAPE; break;
1608 
1609       case K_MENU:   case K_SFT_MENU:   case K_CTL_MENU:   case K_ALT_MENU:
1610         vkey1 = VK_APPS;   break;
1611       case K_PRINT:  case K_SFT_PRINT:  case K_CTL_PRINT:  case K_ALT_PRINT:
1612         vkey1 = VK_PRINT;  break;
1613       case K_PAUSE:  case K_SFT_PAUSE:  case K_CTL_PAUSE:  case K_ALT_PAUSE:
1614         vkey1 = VK_PAUSE;  break;
1615 
1616       case ' ': vkey1 = VK_SPACE;    break;
1617       case '*': vkey1 = VK_MULTIPLY; break;
1618       case '+': vkey1 = VK_ADD;      break;
1619       case '-': vkey1 = VK_SUBTRACT; break;
1620       case '/': vkey1 = VK_DIVIDE;   break;
1621 
1622       case K_MOUSE1: case K_SFT_MOUSE1: case K_CTL_MOUSE1: case K_ALT_MOUSE1:
1623         if (resizeMode == 0) {
1624           vkey1 = VK_LBUTTON;
1625         } /* if */
1626         break;
1627       case K_MOUSE2: case K_SFT_MOUSE2: case K_CTL_MOUSE2: case K_ALT_MOUSE2: vkey1 = VK_MBUTTON; break;
1628       case K_MOUSE3: case K_SFT_MOUSE3: case K_CTL_MOUSE3: case K_ALT_MOUSE3: vkey1 = VK_RBUTTON; break;
1629 
1630       case K_MOUSE_FWD:      case K_SFT_MOUSE_FWD:
1631       case K_CTL_MOUSE_FWD:  case K_ALT_MOUSE_FWD:  vkey1 = VK_XBUTTON2; break;
1632       case K_MOUSE_BACK:     case K_SFT_MOUSE_BACK:
1633       case K_CTL_MOUSE_BACK: case K_ALT_MOUSE_BACK: vkey1 = VK_XBUTTON1; break;
1634 
1635       case K_SHIFT:          vkey1 = VK_SHIFT;    break;
1636       case K_LEFT_SHIFT:     vkey1 = VK_LSHIFT;   break;
1637       case K_RIGHT_SHIFT:    vkey1 = VK_RSHIFT;   break;
1638       case K_CONTROL:        vkey1 = VK_CONTROL;  not_vkey = VK_RMENU; vkey2 = VK_RCONTROL; break;
1639       case K_LEFT_CONTROL:   vkey1 = VK_LCONTROL; not_vkey = VK_RMENU; break;
1640       case K_RIGHT_CONTROL:  vkey1 = VK_RCONTROL; break;
1641       case K_ALT:            vkey1 = VK_MENU;     break;
1642       case K_LEFT_ALT:       vkey1 = VK_LMENU;    break;
1643       case K_RIGHT_ALT:      vkey1 = VK_RMENU;    break;
1644       case K_SHIFT_LOCK:     vkey1      = VK_CAPITAL; break;
1645       case K_SHIFT_LOCK_ON:  state_vkey = VK_CAPITAL; break;
1646       case K_NUM_LOCK:       vkey1      = VK_NUMLOCK; break;
1647       case K_NUM_LOCK_ON:    state_vkey = VK_NUMLOCK; break;
1648       case K_SCROLL_LOCK:    vkey1      = VK_SCROLL;  break;
1649       case K_SCROLL_LOCK_ON: state_vkey = VK_SCROLL;  break;
1650 
1651       default: result = FALSE; okay = FALSE; break;
1652     } /* switch */
1653 
1654     if (okay) {
1655       if (vkey1 != 0) {
1656         result = (GetKeyState(vkey1) & 0x8000) != 0;
1657         if (result && not_vkey != 0) {
1658           result = (GetKeyState(not_vkey) & 0x8000) == 0;
1659         } /* if */
1660         if (!result && vkey2 != 0) {
1661           result = (GetKeyState(vkey2) & 0x8000) != 0;
1662         } /* if */
1663       } else {
1664         result = (GetKeyState(state_vkey) & 0x0001) != 0;
1665       } /* if */
1666     } /* if */
1667     return result;
1668   } /* gkbButtonPressed */
1669 
1670 
1671 
gkbRawGetc(void)1672 charType gkbRawGetc (void)
1673 
1674   { /* gkbRawGetc */
1675     return gkbGetc();
1676   } /* gkbRawGetc */
1677 
1678 
1679 
gkbSelectInput(winType aWindow,charType aKey,boolType active)1680 void gkbSelectInput (winType aWindow, charType aKey, boolType active)
1681 
1682   { /* gkbSelectInput */
1683     if (aKey == K_RESIZE) {
1684       setResizeReturnsKey(aWindow, active);
1685     } else if (aKey == K_CLOSE) {
1686       if (active) {
1687         drwSetCloseAction(aWindow, CLOSE_BUTTON_RETURNS_KEY);
1688       } else {
1689         drwSetCloseAction(aWindow, CLOSE_BUTTON_CLOSES_PROGRAM);
1690       } /* if */
1691     } else {
1692       raise_error(RANGE_ERROR);
1693     } /* if */
1694   } /* gkbSelectInput */
1695 
1696 
1697 
gkbButtonXpos(void)1698 intType gkbButtonXpos (void)
1699 
1700   { /* gkbButtonXpos */
1701     return button_x;
1702   } /* gkbButtonXpos */
1703 
1704 
1705 
gkbButtonYpos(void)1706 intType gkbButtonYpos (void)
1707 
1708   { /* gkbButtonYpos */
1709     return button_y;
1710   } /* gkbButtonYpos */
1711 
1712 
1713 
gkbWindow(void)1714 winType gkbWindow (void)
1715 
1716   {
1717     winType result;
1718 
1719   /* gkbWindow */
1720     logFunction(printf("gkbWindow\n"););
1721     result = find_window(button_window);
1722     if (result != NULL) {
1723       result->usage_count++;
1724     } /* if */
1725     logFunction(printf("gkbWindow -> " FMT_U_MEM "\n", (memSizeType) result););
1726     return result;
1727   } /* gkbWindow */
1728 
1729 
1730 
drwFlush(void)1731 void drwFlush (void)
1732 
1733   { /* drwFlush */
1734     logFunction(printf("drwFlush\n"););
1735     gkbKeyPressed();
1736     logFunction(printf("drwFlush -->\n"););
1737   } /* drwFlush */
1738