1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** GUIX Component                                                        */
16 /**                                                                       */
17 /**   Win32 Display Management (Display)                                  */
18 /**                                                                       */
19 /**************************************************************************/
20 #ifdef WIN32
21 #pragma comment(lib, "winmm.lib")
22 #include "tx_api.h"
23 #include "gx_api.h"
24 #include "gx_system.h"
25 #include "gx_display.h"
26 #include "windows.h"
27 #include "gx_win32_display_driver.h"
28 
29 #define GX_KEY_NUMPAD0          0x0030
30 #define GX_KEY_NUMPAD1          0x0031
31 #define GX_KEY_NUMPAD2          0x0032
32 #define GX_KEY_NUMPAD3          0x0033
33 #define GX_KEY_NUMPAD4          0x0034
34 #define GX_KEY_NUMPAD5          0x0035
35 #define GX_KEY_NUMPAD6          0x0036
36 #define GX_KEY_NUMPAD7          0x0037
37 #define GX_KEY_NUMPAD8          0x0038
38 #define GX_KEY_NUMPAD9          0x0039
39 #define GX_KEY_MULTIPLY         0x002a
40 #define GX_KEY_ADD              0x002b
41 #define GX_KEY_SUBTRACT         0x002d
42 #define GX_KEY_DECIMAL          0x002e
43 #define GX_KEY_DIVIDE           0x002f
44 #define GX_KEY_OEM_1            0x003b
45 #define GX_KEY_SHIFT_OEM_1      0x003a
46 #define GX_KEY_OEM_PLUS         0x003d
47 #define GX_KEY_SHIFT_OEM_PLUS   0x002b
48 #define GX_KEY_OEM_COMMA        0x002c
49 #define GX_KEY_SHIFT_OEM_COMMA  0x003c
50 #define GX_KEY_OEM_MINUS        0x002d
51 #define GX_KEY_SHIFT_OEM_MINUS  0x005f
52 #define GX_KEY_OEM_PERIOD       0x002e
53 #define GX_KEY_SHIFT_OME_PERIOD 0x003e
54 #define GX_KEY_OEM_2            0x002f
55 #define GX_KEY_SHIFT_OEM_2      0x003f
56 #define GX_KEY_OEM_3            0x0027
57 #define GX_KEY_SHIFT_OEM_3      0x007e
58 #define GX_KEY_OEM_4            0x005b
59 #define GX_KEY_SHIFT_OEM_4      0x007b
60 #define GX_KEY_OEM_5            0x005c
61 #define GX_KEY_SHIFT_OEM_5      0x007c
62 #define GX_KEY_OEM_6            0x005d
63 #define GX_KEY_SHIFT_OEM_6      0x007d
64 #define GX_KEY_OEM_7            0x0060
65 #define GX_KEY_SHIFT_OEM_7      0x0022
66 #define GX_KEY_NUM1             0x0031
67 #define GX_KEY_SHIFT_NUM1       0x0021
68 #define GX_KEY_NUM2             0x0032
69 #define GX_KEY_SHIFT_NUM2       0x0040
70 #define GX_KEY_NUM3             0x0033
71 #define GX_KEY_SHIFT_NUM3       0x0023
72 #define GX_KEY_NUM4             0x0034
73 #define GX_KEY_SHIFT_NUM4       0x0024
74 #define GX_KEY_NUM5             0x0035
75 #define GX_KEY_SHIFT_NUM5       0x0025
76 #define GX_KEY_NUM6             0x0036
77 #define GX_KEY_SHIFT_NUM6       0x005e
78 #define GX_KEY_NUM7             0x0037
79 #define GX_KEY_SHIFT_NUM7       0x0026
80 #define GX_KEY_NUM8             0x0038
81 #define GX_KEY_SHIFT_NUM8       0x002a
82 #define GX_KEY_NUM9             0x0039
83 #define GX_KEY_SHIFT_NUM9       0x0028
84 #define GX_KEY_NUM0             0x0030
85 #define GX_KEY_SHIFT_NUM0       0x0029
86 #define GX_KEY_A                0x0061
87 #define GX_KEY_B                0x0062
88 #define GX_KEY_C                0x0063
89 #define GX_KEY_D                0x0064
90 #define GX_KEY_E                0x0065
91 #define GX_KEY_F                0x0066
92 #define GX_KEY_G                0x0067
93 #define GX_KEY_H                0x0068
94 #define GX_KEY_I                0x0069
95 #define GX_KEY_J                0x006a
96 #define GX_KEY_K                0x006b
97 #define GX_KEY_L                0x006c
98 #define GX_KEY_M                0x006d
99 #define GX_KEY_N                0x006e
100 #define GX_KEY_O                0x006f
101 #define GX_KEY_P                0x0070
102 #define GX_KEY_Q                0x0071
103 #define GX_KEY_R                0x0072
104 #define GX_KEY_S                0x0073
105 #define GX_KEY_T                0x0074
106 #define GX_KEY_U                0x0075
107 #define GX_KEY_V                0x0076
108 #define GX_KEY_W                0x0077
109 #define GX_KEY_X                0x0078
110 #define GX_KEY_Y                0x0079
111 #define GX_KEY_Z                0x007a
112 
113 #define GX_WIN32_TIMER_ID 1
114 
115 typedef struct
116 {
117     USHORT win32_key;
118     USHORT guix_normal_key;
119     USHORT guix_shift_key;
120 } KEY_MAP_ENTRY;
121 
122 typedef struct
123 {
124     USHORT win32_key;
125     USHORT shift_event_type;
126     USHORT ctrl_event_type;
127 } KEY_EVENT_ENTRY;
128 
129 static KEY_MAP_ENTRY         win32_key_table[] = {
130 
131     {VK_BACK, GX_KEY_BACKSPACE, GX_KEY_BACKSPACE},
132     {VK_RETURN, GX_KEY_SELECT, GX_KEY_SELECT},
133     {VK_SHIFT, GX_KEY_SHIFT, GX_KEY_SHIFT},
134     {VK_CONTROL, GX_KEY_CONTROL, GX_KEY_CONTROL},
135     {VK_CAPITAL, GX_KEY_CAPS_LOCK, GX_KEY_CAPS_LOCK},
136     {VK_PRIOR, GX_KEY_PAGE_UP, GX_KEY_PAGE_UP},
137     {VK_NEXT, GX_KEY_PAGE_DOWN, GX_KEY_PAGE_DOWN},
138     {VK_END, GX_KEY_END, GX_KEY_END},
139     {VK_HOME, GX_KEY_HOME, GX_KEY_HOME},
140     {VK_LEFT, GX_KEY_LEFT_ARROW, GX_KEY_LEFT_ARROW},
141     {VK_UP, GX_KEY_UP_ARROW, GX_KEY_UP_ARROW},
142     {VK_RIGHT, GX_KEY_RIGHT_ARROW, GX_KEY_RIGHT_ARROW},
143     {VK_DOWN, GX_KEY_DOWN_ARROW, GX_KEY_DOWN_ARROW},
144     {VK_DELETE, GX_KEY_DELETE, GX_KEY_DELETE},
145     {VK_NUMLOCK, GX_KEY_NUMLOCK, GX_KEY_NUMLOCK},
146     {VK_SEPARATOR, GX_KEY_SEPARATOR, GX_KEY_SEPARATOR},
147     {VK_TAB, GX_KEY_NEXT, GX_KEY_PREVIOUS},
148     {VK_SPACE, GX_KEY_SPACE, GX_KEY_SPACE},
149     {VK_NUMPAD0, GX_KEY_NUMPAD0, GX_KEY_NUMPAD0},
150     {VK_NUMPAD1, GX_KEY_NUMPAD1, GX_KEY_NUMPAD1},
151     {VK_NUMPAD2, GX_KEY_NUMPAD2, GX_KEY_NUMPAD2},
152     {VK_NUMPAD3, GX_KEY_NUMPAD3, GX_KEY_NUMPAD3},
153     {VK_NUMPAD4, GX_KEY_NUMPAD4, GX_KEY_NUMPAD4},
154     {VK_NUMPAD5, GX_KEY_NUMPAD5, GX_KEY_NUMPAD5},
155     {VK_NUMPAD6, GX_KEY_NUMPAD6, GX_KEY_NUMPAD6},
156     {VK_NUMPAD7, GX_KEY_NUMPAD7, GX_KEY_NUMPAD7},
157     {VK_NUMPAD8, GX_KEY_NUMPAD8, GX_KEY_NUMPAD8},
158     {VK_NUMPAD9, GX_KEY_NUMPAD9, GX_KEY_NUMPAD9},
159     {VK_MULTIPLY, GX_KEY_MULTIPLY, GX_KEY_MULTIPLY},
160     {VK_ADD, GX_KEY_ADD, GX_KEY_ADD},
161     {VK_SUBTRACT, GX_KEY_SUBTRACT, GX_KEY_SUBTRACT},
162     {VK_DECIMAL, GX_KEY_DECIMAL, GX_KEY_DECIMAL},
163     {VK_DIVIDE, GX_KEY_DIVIDE, GX_KEY_DIVIDE},
164     {VK_OEM_PLUS, GX_KEY_OEM_PLUS, GX_KEY_SHIFT_OEM_PLUS},
165     {VK_OEM_COMMA, GX_KEY_OEM_COMMA, GX_KEY_SHIFT_OEM_COMMA},
166     {VK_OEM_MINUS, GX_KEY_OEM_MINUS, GX_KEY_SHIFT_OEM_MINUS},
167     {VK_OEM_PERIOD, GX_KEY_OEM_PERIOD, GX_KEY_SHIFT_OME_PERIOD},
168     {VK_OEM_1, GX_KEY_OEM_1, GX_KEY_SHIFT_OEM_1},
169     {VK_OEM_2, GX_KEY_OEM_2, GX_KEY_SHIFT_OEM_2},
170     {VK_OEM_3, GX_KEY_OEM_3, GX_KEY_SHIFT_OEM_3},
171     {VK_OEM_4, GX_KEY_OEM_4, GX_KEY_SHIFT_OEM_4},
172     {VK_OEM_5, GX_KEY_OEM_5, GX_KEY_SHIFT_OEM_5},
173     {VK_OEM_6, GX_KEY_OEM_6, GX_KEY_SHIFT_OEM_6},
174     {VK_OEM_7, GX_KEY_OEM_7, GX_KEY_SHIFT_OEM_7},
175     {0x31, GX_KEY_NUM1, GX_KEY_SHIFT_NUM1},
176     {0x32, GX_KEY_NUM2, GX_KEY_SHIFT_NUM2},
177     {0x33, GX_KEY_NUM3, GX_KEY_SHIFT_NUM3},
178     {0x34, GX_KEY_NUM4, GX_KEY_SHIFT_NUM4},
179     {0x35, GX_KEY_NUM5, GX_KEY_SHIFT_NUM5},
180     {0x36, GX_KEY_NUM6, GX_KEY_SHIFT_NUM6},
181     {0x37, GX_KEY_NUM7, GX_KEY_SHIFT_NUM7},
182     {0x38, GX_KEY_NUM8, GX_KEY_SHIFT_NUM8},
183     {0x39, GX_KEY_NUM9, GX_KEY_SHIFT_NUM9},
184     {0x30, GX_KEY_NUM0, GX_KEY_SHIFT_NUM0},
185     {0x41, GX_KEY_A, GX_KEY_A - 0x20},
186     {0x42, GX_KEY_B, GX_KEY_B - 0x20},
187     {0x43, GX_KEY_C, GX_KEY_C - 0x20},
188     {0x44, GX_KEY_D, GX_KEY_D - 0x20},
189     {0x45, GX_KEY_E, GX_KEY_E - 0x20},
190     {0x46, GX_KEY_F, GX_KEY_F - 0x20},
191     {0x47, GX_KEY_G, GX_KEY_G - 0x20},
192     {0x48, GX_KEY_H, GX_KEY_H - 0x20},
193     {0x49, GX_KEY_I, GX_KEY_I - 0x20},
194     {0x4a, GX_KEY_J, GX_KEY_J - 0x20},
195     {0x4b, GX_KEY_K, GX_KEY_K - 0x20},
196     {0x4c, GX_KEY_L, GX_KEY_L - 0x20},
197     {0x4d, GX_KEY_M, GX_KEY_M - 0x20},
198     {0x4e, GX_KEY_N, GX_KEY_N - 0x20},
199     {0x4f, GX_KEY_O, GX_KEY_O - 0x20},
200     {0x50, GX_KEY_P, GX_KEY_P - 0x20},
201     {0x51, GX_KEY_Q, GX_KEY_Q - 0x20},
202     {0x52, GX_KEY_R, GX_KEY_R - 0x20},
203     {0x53, GX_KEY_S, GX_KEY_S - 0x20},
204     {0x54, GX_KEY_T, GX_KEY_T - 0x20},
205     {0x55, GX_KEY_U, GX_KEY_U - 0x20},
206     {0x56, GX_KEY_V, GX_KEY_V - 0x20},
207     {0x57, GX_KEY_W, GX_KEY_W - 0x20},
208     {0x58, GX_KEY_X, GX_KEY_X - 0x20},
209     {0x59, GX_KEY_Y, GX_KEY_Y - 0x20},
210     {0x5a, GX_KEY_Z, GX_KEY_Z - 0x20},
211     {0, 0, 0}
212 };
213 
214 static KEY_EVENT_ENTRY       win32_key_events[] = {
215     {VK_END,   GX_EVENT_MARK_END, 0},
216     {VK_HOME,  GX_EVENT_MARK_HOME, 0},
217     {VK_LEFT,  GX_EVENT_MARK_PREVIOUS, 0},
218     {VK_UP,    GX_EVENT_MARK_UP, 0},
219     {VK_RIGHT, GX_EVENT_MARK_NEXT, 0},
220     {VK_DOWN,  GX_EVENT_MARK_DOWN,  0},
221     {'c',      0,  GX_EVENT_COPY},
222     {'C',      0,  GX_EVENT_COPY},
223     {'x',      0,  GX_EVENT_CUT},
224     {'X',      0,  GX_EVENT_CUT},
225     {'v',      0,  GX_EVENT_PASTE},
226     {'V',      0,  GX_EVENT_PASTE},
227     {0, 0, 0}
228 };
229 
230 static UINT                  caps_flag = 0;
231 static UINT                  shift_flag = 0;
232 static UINT                  numlock_flag = 0;
233 static UINT                  ctrl_flag = 0;
234 static char                  icon_path[MAX_PATH];
235 
236 BOOL                         win32_graphics_data_initialized = FALSE;
237 GX_WIN32_DISPLAY_DRIVER_DATA win32_instance_data[GX_MAX_WIN32_DISPLAYS];
238 UINT                         win32_timer_id = 0;
239 extern int                   gx_main(int, char **);
240 
241 #ifdef GX_THREADX_BINDING
242 extern ULONG                 _tx_thread_system_state;
243 #endif
244 
245 /**************************************************************************/
246 /*                                                                        */
247 /*  FUNCTION                                               RELEASE        */
248 /*                                                                        */
249 /*    gx_win32_timer_expiration                          PORTABLE C       */
250 /*                                                           6.1.10       */
251 /*  AUTHOR                                                                */
252 /*                                                                        */
253 /*    Ting Zhu, Microsoft Corporation                                     */
254 /*                                                                        */
255 /*  DESCRIPTION                                                           */
256 /*                                                                        */
257 /*    This is the callback function for the win32 multi-media timer that  */
258 /*    is called once upon the expiration of a timer event.                */
259 /*                                                                        */
260 /*  INPUT                                                                 */
261 /*                                                                        */
262 /*    wTimerID                              Identifier of the timer event */
263 /*    msg                                   Reserved                      */
264 /*    dwUser                                User instance data            */
265 /*    dw1                                   Reserved                      */
266 /*    dw2                                   Reserved                      */
267 /*                                                                        */
268 /*  OUTPUT                                                                */
269 /*                                                                        */
270 /*    None                                                                */
271 /*                                                                        */
272 /*  CALLS                                                                 */
273 /*                                                                        */
274 /*    None                                                                */
275 /*                                                                        */
276 /*  CALLED BY                                                             */
277 /*                                                                        */
278 /*    None                                                                */
279 /*                                                                        */
280 /*  RELEASE HISTORY                                                       */
281 /*                                                                        */
282 /*    DATE              NAME                      DESCRIPTION             */
283 /*                                                                        */
284 /*  01-31-2022     Ting Zhu                 Initial Version 6.1.10        */
285 /*                                                                        */
286 /**************************************************************************/
gx_win32_timer_expiration(UINT wTimerID,UINT msg,DWORD dwUser,DWORD dw1,DWORD dw2)287 static void CALLBACK gx_win32_timer_expiration(UINT wTimerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2)
288 {
289     GX_WIN32_DISPLAY_DRIVER_DATA *instance = (GX_WIN32_DISPLAY_DRIVER_DATA *)dwUser;
290 
291     SendMessage(instance->win32_driver_winhandle, WM_TIMER, 0, 0);
292 }
293 
294 /**************************************************************************/
295 /*                                                                        */
296 /*  FUNCTION                                               RELEASE        */
297 /*                                                                        */
298 /*    gx_win32_start_multimedia_timer                    PORTABLE C       */
299 /*                                                           6.1.10       */
300 /*  AUTHOR                                                                */
301 /*                                                                        */
302 /*    Ting Zhu, Microsoft Corporation                                     */
303 /*                                                                        */
304 /*  DESCRIPTION                                                           */
305 /*                                                                        */
306 /*    This function starts a periodic multi-media timer event.            */
307 /*                                                                        */
308 /*  INPUT                                                                 */
309 /*                                                                        */
310 /*    instance                              Pointer to win32 display      */
311 /*                                            driver data                 */
312 /*                                                                        */
313 /*  OUTPUT                                                                */
314 /*                                                                        */
315 /*    None                                                                */
316 /*                                                                        */
317 /*  CALLS                                                                 */
318 /*                                                                        */
319 /*    timeGetDevCaps                                                      */
320 /*    timeBeginPeriod                                                     */
321 /*    timeSetEvent                                                        */
322 /*                                                                        */
323 /*  CALLED BY                                                             */
324 /*                                                                        */
325 /*    gx_win32_driver_thread_initialize                                   */
326 /*                                                                        */
327 /*  RELEASE HISTORY                                                       */
328 /*                                                                        */
329 /*    DATE              NAME                      DESCRIPTION             */
330 /*                                                                        */
331 /*  01-31-2022     Ting Zhu                 Initial Version 6.1.10        */
332 /*                                                                        */
333 /**************************************************************************/
gx_win32_start_multimedia_timer(GX_WIN32_DISPLAY_DRIVER_DATA * instance)334 static void gx_win32_start_multimedia_timer(GX_WIN32_DISPLAY_DRIVER_DATA *instance)
335 {
336     TIMECAPS tc;
337     UINT     wTimerRes;
338 
339     /* Queries the timer device to determine its resolution.  */
340     if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR)
341     {
342         /* Error; application can't continue. */
343     }
344 
345     wTimerRes = min(max(tc.wPeriodMin, GX_SYSTEM_TIMER_MS), tc.wPeriodMax);
346 
347     /* Start a specified timer event. The timer runs in its own thread.
348        It calls the specified callback function when the event is activated.  */
349     win32_timer_id = timeSetEvent(GX_SYSTEM_TIMER_MS, wTimerRes, gx_win32_timer_expiration, (DWORD)instance, TIME_PERIODIC);
350 }
351 
352 /**************************************************************************/
353 /*                                                                        */
354 /*  FUNCTION                                               RELEASE        */
355 /*                                                                        */
356 /*    gx_win32_stop_multimedia_timer                     PORTABLE C       */
357 /*                                                           6.1.10       */
358 /*  AUTHOR                                                                */
359 /*                                                                        */
360 /*    Ting Zhu, Microsoft Corporation                                     */
361 /*                                                                        */
362 /*  DESCRIPTION                                                           */
363 /*                                                                        */
364 /*    This function stops a multi-media timer event.                      */
365 /*                                                                        */
366 /*  INPUT                                                                 */
367 /*                                                                        */
368 /*    None                                                                */
369 /*                                                                        */
370 /*  OUTPUT                                                                */
371 /*                                                                        */
372 /*    None                                                                */
373 /*                                                                        */
374 /*  CALLS                                                                 */
375 /*                                                                        */
376 /*    None                                                                */
377 /*                                                                        */
378 /*  CALLED BY                                                             */
379 /*                                                                        */
380 /*    gx_win32_input_driver                                               */
381 /*                                                                        */
382 /*  RELEASE HISTORY                                                       */
383 /*                                                                        */
384 /*    DATE              NAME                      DESCRIPTION             */
385 /*                                                                        */
386 /*  01-31-2022     Ting Zhu                 Initial Version 6.1.10        */
387 /*                                                                        */
388 /**************************************************************************/
gx_win32_stop_multimedia_timer()389 static void gx_win32_stop_multimedia_timer()
390 {
391     if (win32_timer_id)
392     {
393         /* Cancel a specified timer event.  */
394         timeKillEvent(win32_timer_id);
395 
396         win32_timer_id = 0;
397     }
398 }
399 
400 /**************************************************************************/
401 /*                                                                        */
402 /*  FUNCTION                                               RELEASE        */
403 /*                                                                        */
404 /*    gx_win32_map_key_to_guix_event                     PORTABLE C       */
405 /*                                                           6.1.3        */
406 /*  AUTHOR                                                                */
407 /*                                                                        */
408 /*    Kenneth Maxwell, Microsoft Corporation                              */
409 /*                                                                        */
410 /*  DESCRIPTION                                                           */
411 /*                                                                        */
412 /*    This function maps certain input key combinations to guix event     */
413 /*    type.                                                               */
414 /*                                                                        */
415 /*  INPUT                                                                 */
416 /*                                                                        */
417 /*    wParam                                Win32 key type                */
418 /*    shift                                 Shift key status              */
419 /*    ctrl                                  Ctrl key status               */
420 /*                                                                        */
421 /*  OUTPUT                                                                */
422 /*                                                                        */
423 /*    ULONG                                 GUIX event type               */
424 /*                                                                        */
425 /*  CALLS                                                                 */
426 /*                                                                        */
427 /*    None                                                                */
428 /*                                                                        */
429 /*  CALLED BY                                                             */
430 /*                                                                        */
431 /*    gx_win32_event_process                                              */
432 /*                                                                        */
433 /*  RELEASE HISTORY                                                       */
434 /*                                                                        */
435 /*    DATE              NAME                      DESCRIPTION             */
436 /*                                                                        */
437 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
438 /*                                                                        */
439 /**************************************************************************/
gx_win32_map_key_to_guix_event(USHORT wParam,int shift,int ctrl)440 static ULONG gx_win32_map_key_to_guix_event(USHORT wParam, int shift, int ctrl)
441 {
442 KEY_EVENT_ENTRY *pEntry;
443 
444     if (!shift && !ctrl)
445     {
446         return 0;
447     }
448 
449     pEntry = win32_key_events;
450 
451     while (pEntry -> win32_key)
452     {
453         if (wParam == pEntry -> win32_key)
454         {
455             if (shift && pEntry -> shift_event_type)
456             {
457                 return pEntry -> shift_event_type;
458             }
459             if (ctrl && pEntry -> ctrl_event_type)
460             {
461                 return pEntry -> ctrl_event_type;
462             }
463         }
464         pEntry++;
465     }
466     return 0;
467 }
468 
469 /**************************************************************************/
470 /*                                                                        */
471 /*  FUNCTION                                               RELEASE        */
472 /*                                                                        */
473 /*    gx_win32_map_key_to_guix_key                       PORTABLE C       */
474 /*                                                           6.1.3        */
475 /*  AUTHOR                                                                */
476 /*                                                                        */
477 /*    Kenneth Maxwell, Microsoft Corporation                              */
478 /*                                                                        */
479 /*  DESCRIPTION                                                           */
480 /*                                                                        */
481 /*    This function map windows key value to guix system key value.       */
482 /*                                                                        */
483 /*  INPUT                                                                 */
484 /*                                                                        */
485 /*    wParam                                Win32 key value               */
486 /*                                                                        */
487 /*  OUTPUT                                                                */
488 /*                                                                        */
489 /*    USHORT                                GUIX key value                */
490 /*                                                                        */
491 /*  CALLS                                                                 */
492 /*                                                                        */
493 /*    None                                                                */
494 /*                                                                        */
495 /*  CALLED BY                                                             */
496 /*                                                                        */
497 /*    gx_win32_event_process                                              */
498 /*                                                                        */
499 /*  RELEASE HISTORY                                                       */
500 /*                                                                        */
501 /*    DATE              NAME                      DESCRIPTION             */
502 /*                                                                        */
503 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
504 /*                                                                        */
505 /**************************************************************************/
gx_win32_map_key_to_guix_key(USHORT wParam)506 static USHORT gx_win32_map_key_to_guix_key(USHORT wParam)
507 {
508 KEY_MAP_ENTRY *pEntry = win32_key_table;
509 
510     while (pEntry -> win32_key)
511     {
512         if (wParam == pEntry -> win32_key)
513         {
514             if (wParam >= 0x41 && wParam <= 0x5a)
515             {
516                 if ((caps_flag && shift_flag) || ((!caps_flag) && (!shift_flag)))
517                 {
518                     return pEntry -> guix_normal_key;
519                 }
520                 else
521                 {
522                     return pEntry -> guix_shift_key;
523                 }
524             }
525             else if (shift_flag)
526             {
527                 return pEntry -> guix_shift_key;
528             }
529             else
530             {
531                 return pEntry -> guix_normal_key;
532             }
533         }
534         pEntry++;
535     }
536     return wParam;
537 }
538 
539 /**************************************************************************/
540 /*                                                                        */
541 /*  FUNCTION                                               RELEASE        */
542 /*                                                                        */
543 /*    gx_win32_get_icon_path                              PORTABLE C      */
544 /*                                                           6.1.3        */
545 /*  AUTHOR                                                                */
546 /*                                                                        */
547 /*    Kenneth Maxwell, Microsoft Corporation                              */
548 /*                                                                        */
549 /*  DESCRIPTION                                                           */
550 /*                                                                        */
551 /*    This function gets guix logo file path.                             */
552 /*                                                                        */
553 /*  INPUT                                                                 */
554 /*                                                                        */
555 /*    None                                                                */
556 /*                                                                        */
557 /*  OUTPUT                                                                */
558 /*                                                                        */
559 /*    None                                                                */
560 /*                                                                        */
561 /*  CALLS                                                                 */
562 /*                                                                        */
563 /*    RegOpenKeyExA                                                       */
564 /*    RegQueryValueEx                                                     */
565 /*    RegCloseKey                                                         */
566 /*    strcat_s                                                            */
567 /*                                                                        */
568 /*  CALLED BY                                                             */
569 /*                                                                        */
570 /*    gx_win32_window_create                                              */
571 /*                                                                        */
572 /*  RELEASE HISTORY                                                       */
573 /*                                                                        */
574 /*    DATE              NAME                      DESCRIPTION             */
575 /*                                                                        */
576 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
577 /*                                                                        */
578 /**************************************************************************/
gx_win32_get_icon_path()579 static void gx_win32_get_icon_path()
580 {
581 HKEY  key;
582 DWORD type, size;
583 LONG  status;
584 
585     icon_path[0] = 0;
586 
587     status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Eclipse Foundation\\GUIX\\InstallDir", 0, READ_CONTROL | KEY_QUERY_VALUE, &key);
588 
589     if (key)
590     {
591         size = MAX_PATH;
592         RegQueryValueEx(key, NULL, 0, &type, (BYTE *)icon_path, &size);
593         RegCloseKey(key);
594 
595         if (icon_path[0])
596         {
597             strcat_s(icon_path, MAX_PATH, "\\");
598         }
599     }
600     strcat_s(icon_path, MAX_PATH, "graphics\\system_png\\guix_1616icon.ico");
601 }
602 
603 /**************************************************************************/
604 /*                                                                        */
605 /*  FUNCTION                                               RELEASE        */
606 /*                                                                        */
607 /*    gx_win32_event_to_guix                             PORTABLE C       */
608 /*                                                           6.1.10       */
609 /*  AUTHOR                                                                */
610 /*                                                                        */
611 /*    Ting Zhu, Microsoft Corporation                                     */
612 /*                                                                        */
613 /*  DESCRIPTION                                                           */
614 /*                                                                        */
615 /*    This function sends event to GUIX system.                           */
616 /*                                                                        */
617 /*  INPUT                                                                 */
618 /*                                                                        */
619 /*    type                                  GUIX event type               */
620 /*                                                                        */
621 /*  OUTPUT                                                                */
622 /*                                                                        */
623 /*    None                                                                */
624 /*                                                                        */
625 /*  CALLS                                                                 */
626 /*                                                                        */
627 /*    _tx_thread_context_save                                             */
628 /*    _tx_thread_context_restore                                          */
629 /*    gx_system_event_send                                                */
630 /*                                                                        */
631 /*  CALLED BY                                                             */
632 /*                                                                        */
633 /*    gx_win32_message_to_guix                                            */
634 /*    gx_win32_event_process                                              */
635 /*                                                                        */
636 /*  RELEASE HISTORY                                                       */
637 /*                                                                        */
638 /*    DATE              NAME                      DESCRIPTION             */
639 /*                                                                        */
640 /*  01-31-2022     Ting Zhu                 Initial Version 6.1.10        */
641 /*                                                                        */
642 /**************************************************************************/
gx_win32_event_to_guix(GX_EVENT * event_ptr)643 void gx_win32_event_to_guix(GX_EVENT *event_ptr)
644 {
645 #ifdef GX_THREADX_BINDING
646     _tx_thread_context_save();
647 #endif
648 
649     gx_system_event_send(event_ptr);
650 
651 #ifdef GX_THREADX_BINDING
652     _tx_thread_context_restore();
653 #endif
654 }
655 
656 /**************************************************************************/
657 /*                                                                        */
658 /*  FUNCTION                                               RELEASE        */
659 /*                                                                        */
660 /*    gx_win32_message_to_guix                           PORTABLE C       */
661 /*                                                           6.1.10       */
662 /*  AUTHOR                                                                */
663 /*                                                                        */
664 /*    Kenneth Maxwell, Microsoft Corporation                              */
665 /*                                                                        */
666 /*  DESCRIPTION                                                           */
667 /*                                                                        */
668 /*    This function sends message to guix system.                         */
669 /*                                                                        */
670 /*  INPUT                                                                 */
671 /*                                                                        */
672 /*    type                                  GUIX event type               */
673 /*                                                                        */
674 /*  OUTPUT                                                                */
675 /*                                                                        */
676 /*    None                                                                */
677 /*                                                                        */
678 /*  CALLS                                                                 */
679 /*                                                                        */
680 /*    gx_system_event_send                  Send message to guix system   */
681 /*                                                                        */
682 /*  CALLED BY                                                             */
683 /*                                                                        */
684 /*    gx_win32_driver_thread_entry                                        */
685 /*    gx_win32_input_driver                                               */
686 /*    gx_win32_event_process                                              */
687 /*                                                                        */
688 /*  RELEASE HISTORY                                                       */
689 /*                                                                        */
690 /*    DATE              NAME                      DESCRIPTION             */
691 /*                                                                        */
692 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
693 /*  01-31-2022     Ting Zhu                 Modified comment(s), modified */
694 /*                                            GUIX event send logic,      */
695 /*                                            resulting in version 6.1.10 */
696 /*                                                                        */
697 /**************************************************************************/
gx_win32_message_to_guix(USHORT event_type)698 void gx_win32_message_to_guix(USHORT event_type)
699 {
700 GX_EVENT myevent;
701 
702     memset(&myevent, 0, sizeof(GX_EVENT));
703 
704     myevent.gx_event_target = GX_NULL;
705     myevent.gx_event_sender = 0;
706     myevent.gx_event_type = event_type;
707 
708     gx_win32_event_to_guix(&myevent);
709 }
710 
711 /**************************************************************************/
712 /*                                                                        */
713 /*  FUNCTION                                               RELEASE        */
714 /*                                                                        */
715 /*    gx_win32_get_free_data_instance                     PORTABLE C      */
716 /*                                                           6.1.3        */
717 /*  AUTHOR                                                                */
718 /*                                                                        */
719 /*    Kenneth Maxwell, Microsoft Corporation                              */
720 /*                                                                        */
721 /*  DESCRIPTION                                                           */
722 /*                                                                        */
723 /*    This function get win32 instance data pointer.                      */
724 /*                                                                        */
725 /*  INPUT                                                                 */
726 /*                                                                        */
727 /*    None                                                                */
728 /*                                                                        */
729 /*  OUTPUT                                                                */
730 /*                                                                        */
731 /*    GX_WIN32_DISPLAY_DRIVER_DATA *        Return instance data pointer  */
732 /*                                                                        */
733 /*  CALLS                                                                 */
734 /*                                                                        */
735 /*    memset                                                              */
736 /*                                                                        */
737 /*  CALLED BY                                                             */
738 /*                                                                        */
739 /*    Win32 display driver set up functions.                              */
740 /*                                                                        */
741 /*  RELEASE HISTORY                                                       */
742 /*                                                                        */
743 /*    DATE              NAME                      DESCRIPTION             */
744 /*                                                                        */
745 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
746 /*                                                                        */
747 /**************************************************************************/
gx_win32_get_free_data_instance(void)748 GX_WIN32_DISPLAY_DRIVER_DATA *gx_win32_get_free_data_instance(void)
749 {
750 int                           index;
751 GX_WIN32_DISPLAY_DRIVER_DATA *data = win32_instance_data;
752 
753     if (!win32_graphics_data_initialized)
754     {
755         memset(win32_instance_data, 0, sizeof(GX_WIN32_DISPLAY_DRIVER_DATA) * GX_MAX_WIN32_DISPLAYS);
756         win32_graphics_data_initialized = GX_TRUE;
757     }
758 
759     /* Search for an unused data instance. */
760     for (index = 0; index < GX_MAX_WIN32_DISPLAYS; index++)
761     {
762         if (data -> win32_driver_type == 0)
763         {
764             /* Cleanup the driver instance. */
765             memset(data, 0, sizeof(GX_WIN32_DISPLAY_DRIVER_DATA));
766             return data;
767         }
768         data++;
769     }
770     return GX_NULL;
771 }
772 
773 /**************************************************************************/
774 /*                                                                        */
775 /*  FUNCTION                                               RELEASE        */
776 /*                                                                        */
777 /*    gx_win32_get_data_instance_by_win_handle            PORTABLE C      */
778 /*                                                           6.1.3        */
779 /*  AUTHOR                                                                */
780 /*                                                                        */
781 /*    Kenneth Maxwell, Microsoft Corporation                              */
782 /*                                                                        */
783 /*  DESCRIPTION                                                           */
784 /*                                                                        */
785 /*    This function gets win32 instance data pointer by win32 handle.     */
786 /*                                                                        */
787 /*  INPUT                                                                 */
788 /*                                                                        */
789 /*    winHandle                               Win32 handle                */
790 /*                                                                        */
791 /*  OUTPUT                                                                */
792 /*                                                                        */
793 /*    GX_WIN32_DISPLAY_DRIVER_DATA *          Return instance data pointer*/
794 /*                                                                        */
795 /*  CALLS                                                                 */
796 /*                                                                        */
797 /*    None                                                                */
798 /*                                                                        */
799 /*  CALLED BY                                                             */
800 /*                                                                        */
801 /*    gx_win32_event_process                                              */
802 /*                                                                        */
803 /*  RELEASE HISTORY                                                       */
804 /*                                                                        */
805 /*    DATE              NAME                      DESCRIPTION             */
806 /*                                                                        */
807 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
808 /*                                                                        */
809 /**************************************************************************/
gx_win32_get_data_instance_by_win_handle(HWND winHandle)810 GX_WIN32_DISPLAY_DRIVER_DATA *gx_win32_get_data_instance_by_win_handle(HWND winHandle)
811 {
812 int index;
813 
814     if (!win32_graphics_data_initialized)
815     {
816         return(NULL);
817     }
818 
819     for (index = 0; index < GX_MAX_WIN32_DISPLAYS; index++)
820     {
821         if (win32_instance_data[index].win32_driver_type == 0)
822         {
823             continue;
824         }
825 
826         if (win32_instance_data[index].win32_driver_winhandle == winHandle)
827         {
828             return(&win32_instance_data[index]);
829         }
830     }
831 
832     return(0);
833 }
834 
835 /**************************************************************************/
836 /*                                                                        */
837 /*  FUNCTION                                               RELEASE        */
838 /*                                                                        */
839 /*    gx_win32_rotate_canvas_to_bmp_32bpp                PORTABLE C       */
840 /*                                                           6.1.4        */
841 /*  AUTHOR                                                                */
842 /*                                                                        */
843 /*    Kenneth Maxwell, Microsoft Corporation                              */
844 /*                                                                        */
845 /*  DESCRIPTION                                                           */
846 /*                                                                        */
847 /*    This function prepare canvas memory at which do draw operation.     */
848 /*                                                                        */
849 /*  INPUT                                                                 */
850 /*                                                                        */
851 /*    winHandle                               Win32 handle                */
852 /*                                                                        */
853 /*  OUTPUT                                                                */
854 /*                                                                        */
855 /*    None                                                                */
856 /*                                                                        */
857 /*  CALLS                                                                 */
858 /*                                                                        */
859 /*    None                                                                */
860 /*                                                                        */
861 /*  CALLED BY                                                             */
862 /*                                                                        */
863 /*    win32_canvas_memory_prepare                                         */
864 /*                                                                        */
865 /*  RELEASE HISTORY                                                       */
866 /*                                                                        */
867 /*    DATE              NAME                      DESCRIPTION             */
868 /*                                                                        */
869 /*  02-02-2021     Kenneth Maxwell          Initial Version 6.1.4         */
870 /*                                                                        */
871 /**************************************************************************/
gx_win32_rotate_canvas_to_bmp_32bpp(GX_CANVAS * canvas)872 static void gx_win32_rotate_canvas_to_bmp_32bpp(GX_CANVAS *canvas)
873 {
874 /* First pass, just copy the entire canvas, ignoring the dirty
875    rectangle. Come back and apply dirty rectangle to improve
876    efficiency.  */
877 
878 ULONG *pReadStart;
879 ULONG *pWriteStart;
880 ULONG *pRead;
881 ULONG *pWrite;
882 INT    copy_width;
883 INT    copy_height;
884 INT    row;
885 INT    column;
886 INT    write_sign;
887 
888     /* Copy left-to-right from source canvas
889        and top-to-bottom in destination bitmap (90 degree rotation)
890        and bottom-to-top in destination bitmap (270 degree rotation).  */
891 
892     pReadStart = (ULONG *)canvas -> gx_canvas_memory;
893     pWriteStart = (ULONG *)canvas -> gx_canvas_padded_memory;
894     copy_width = canvas -> gx_canvas_y_resolution;
895     copy_height = canvas -> gx_canvas_x_resolution;
896 
897     if (canvas -> gx_canvas_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
898     {
899         pWriteStart += copy_height - 1;
900         write_sign = -1;
901     }
902     else
903     {
904         /* Here for 270 degree rotation.  */
905         pWriteStart += (copy_width - 1) * copy_height;
906         write_sign = 1;
907     }
908 
909     for (row = 0; row < copy_height; row++)
910     {
911         pRead = pReadStart;
912         pWrite = pWriteStart;
913 
914         for (column = 0; column < copy_width; column++)
915         {
916             *pWrite = *pRead++;
917             pWrite -= copy_height * write_sign;
918         }
919         pReadStart += copy_width;
920         pWriteStart += write_sign;
921     }
922 }
923 
924 /**************************************************************************/
925 /*                                                                        */
926 /*  FUNCTION                                               RELEASE        */
927 /*                                                                        */
928 /*    gx_win32_rotate_canvas_to_bmp_16bpp                PORTABLE C       */
929 /*                                                           6.1.3        */
930 /*  AUTHOR                                                                */
931 /*                                                                        */
932 /*    Kenneth Maxwell, Microsoft Corporation                              */
933 /*                                                                        */
934 /*  DESCRIPTION                                                           */
935 /*                                                                        */
936 /*    This function prepare canvas memory at which do draw operation.     */
937 /*                                                                        */
938 /*  INPUT                                                                 */
939 /*                                                                        */
940 /*    winHandle                               Win32 handle                */
941 /*                                                                        */
942 /*  OUTPUT                                                                */
943 /*                                                                        */
944 /*    None                                                                */
945 /*                                                                        */
946 /*  CALLS                                                                 */
947 /*                                                                        */
948 /*    None                                                                */
949 /*                                                                        */
950 /*  CALLED BY                                                             */
951 /*                                                                        */
952 /*    win32_canvas_memory_prepare                                         */
953 /*                                                                        */
954 /*  RELEASE HISTORY                                                       */
955 /*                                                                        */
956 /*    DATE              NAME                      DESCRIPTION             */
957 /*                                                                        */
958 /*  12-31-2020     Kenneth Maxwell          Initial version 6.1.3         */
959 /*                                                                        */
960 /**************************************************************************/
gx_win32_rotate_canvas_to_bmp_16bpp(GX_CANVAS * canvas)961 static void gx_win32_rotate_canvas_to_bmp_16bpp(GX_CANVAS *canvas)
962 {
963 /* first pass, just copy the entire canvas, ignoring the dirty
964    rectangle. Come back and apply dirty rectangle to improve
965    efficiency.
966  */
967 
968 USHORT *pReadStart;
969 USHORT *pWriteStart;
970 USHORT *pRead;
971 USHORT *pWrite;
972 INT     copy_width;
973 INT     copy_height;
974 INT     row;
975 INT     column;
976 INT     write_sign;
977 INT     write_stride;
978 
979     /* copy left-to-right from source canvas
980        and top-to-bottom in destination bitmap (90 degree rotation)
981        and bottom-to-top in destination bitmap (270 degree rotation)
982      */
983 
984     pReadStart = (USHORT *)canvas -> gx_canvas_memory;
985     pWriteStart = (USHORT *)canvas -> gx_canvas_padded_memory;
986     copy_width = canvas -> gx_canvas_y_resolution;
987     copy_height = canvas -> gx_canvas_x_resolution;
988 
989     write_stride = (copy_height + 3) & 0xfffc;
990 
991     if (canvas -> gx_canvas_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
992     {
993         pWriteStart += copy_height - 1;
994         write_sign = -1;
995     }
996     else
997     {
998         /* Here for 270 degree rotation. */
999         pWriteStart += (copy_width - 1) * write_stride;
1000         write_sign = 1;
1001     }
1002 
1003     for (row = 0; row < copy_height; row++)
1004     {
1005         pRead = pReadStart;
1006         pWrite = pWriteStart;
1007 
1008         for (column = 0; column < copy_width; column++)
1009         {
1010             *pWrite = *pRead++;
1011             pWrite -= write_stride * write_sign;
1012         }
1013         pReadStart += copy_width;
1014         pWriteStart += write_sign;
1015     }
1016 }
1017 
1018 
1019 /**************************************************************************/
1020 /*                                                                        */
1021 /*  FUNCTION                                               RELEASE        */
1022 /*                                                                        */
1023 /*    gx_win32_rotate_canvas_to_bmp_8bpp                 PORTABLE C       */
1024 /*                                                           6.1.4        */
1025 /*  AUTHOR                                                                */
1026 /*                                                                        */
1027 /*    Kenneth Maxwell, Microsoft Corporation                              */
1028 /*                                                                        */
1029 /*  DESCRIPTION                                                           */
1030 /*                                                                        */
1031 /*    This function prepare canvas memory at which do draw operation.     */
1032 /*                                                                        */
1033 /*  INPUT                                                                 */
1034 /*                                                                        */
1035 /*    winHandle                               Win32 handle                */
1036 /*                                                                        */
1037 /*  OUTPUT                                                                */
1038 /*                                                                        */
1039 /*    None                                                                */
1040 /*                                                                        */
1041 /*  CALLS                                                                 */
1042 /*                                                                        */
1043 /*    None                                                                */
1044 /*                                                                        */
1045 /*  CALLED BY                                                             */
1046 /*                                                                        */
1047 /*    win32_canvas_memory_prepare                                         */
1048 /*                                                                        */
1049 /*  RELEASE HISTORY                                                       */
1050 /*                                                                        */
1051 /*    DATE              NAME                      DESCRIPTION             */
1052 /*                                                                        */
1053 /*  02-02-2021     Kenneth Maxwell          Initial Version 6.1.4         */
1054 /*                                                                        */
1055 /**************************************************************************/
gx_win32_rotate_canvas_to_bmp_8bpp(GX_CANVAS * canvas)1056 static void gx_win32_rotate_canvas_to_bmp_8bpp(GX_CANVAS *canvas)
1057 {
1058 /* first pass, just copy the entire canvas, ignoring the dirty
1059    rectangle. Come back and apply dirty rectangle to improve
1060    efficiency.
1061  */
1062 
1063 GX_UBYTE *pReadStart;
1064 GX_UBYTE *pWriteStart;
1065 GX_UBYTE *pRead;
1066 GX_UBYTE *pWrite;
1067 INT       copy_width;
1068 INT       copy_height;
1069 INT       row;
1070 INT       column;
1071 INT       write_sign;
1072 INT       write_stride;
1073 
1074     /* copy left-to-right from source canvas
1075        and top-to-bottom in destination bitmap (90 degree rotation)
1076        and bottom-to-top in destination bitmap (270 degree rotation)
1077      */
1078 
1079     pReadStart = (GX_UBYTE *)canvas -> gx_canvas_memory;
1080     pWriteStart = (GX_UBYTE *)canvas -> gx_canvas_padded_memory;
1081     copy_width = canvas -> gx_canvas_y_resolution;
1082     copy_height = canvas -> gx_canvas_x_resolution;
1083 
1084     write_stride = (copy_height + 1) & 0xfffc;
1085 
1086     if (canvas -> gx_canvas_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
1087     {
1088         pWriteStart += copy_height - 1;
1089         write_sign = -1;
1090     }
1091     else
1092     {
1093         /* Here for 270 degree rotation. */
1094         pWriteStart += (copy_width - 1) * write_stride;
1095         write_sign = 1;
1096     }
1097 
1098     for (row = 0; row < copy_height; row++)
1099     {
1100         pRead = pReadStart;
1101         pWrite = pWriteStart;
1102 
1103         for (column = 0; column < copy_width; column++)
1104         {
1105             *pWrite = *pRead++;
1106             pWrite -= write_stride * write_sign;
1107         }
1108         pReadStart += copy_width;
1109         pWriteStart += write_sign;
1110     }
1111 }
1112 
1113 /**************************************************************************/
1114 /*                                                                        */
1115 /*  FUNCTION                                               RELEASE        */
1116 /*                                                                        */
1117 /*    _win32_canvas_memory_prepare                       PORTABLE C       */
1118 /*                                                           6.1.5        */
1119 /*  AUTHOR                                                                */
1120 /*                                                                        */
1121 /*    Kenneth Maxwell, Microsoft Corporation                              */
1122 /*                                                                        */
1123 /*  DESCRIPTION                                                           */
1124 /*                                                                        */
1125 /*    This function prepare canvas memory at which do draw operation.     */
1126 /*                                                                        */
1127 /*  INPUT                                                                 */
1128 /*                                                                        */
1129 /*    winHandle                               Win32 handle                */
1130 /*                                                                        */
1131 /*  OUTPUT                                                                */
1132 /*                                                                        */
1133 /*    None                                                                */
1134 /*                                                                        */
1135 /*  CALLS                                                                 */
1136 /*                                                                        */
1137 /*    None                                                                */
1138 /*                                                                        */
1139 /*  CALLED BY                                                             */
1140 /*                                                                        */
1141 /*    gx_win32_display_buffer_toggle                                      */
1142 /*                                                                        */
1143 /*  RELEASE HISTORY                                                       */
1144 /*                                                                        */
1145 /*    DATE              NAME                      DESCRIPTION             */
1146 /*                                                                        */
1147 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
1148 /*  02-02-2021     Kenneth Maxwell          Modified comment(s),          */
1149 /*                                            added 8bpp and 32bpp canvas */
1150 /*                                            rotate logic,               */
1151 /*                                            resulting in version 6.1.4  */
1152 /*  03-02-2021     Ting Zhu                 Modified comment(s), added    */
1153 /*                                            flip rotation support,      */
1154 /*                                            resulting in version 6.1.5  */
1155 /*                                                                        */
1156 /**************************************************************************/
_win32_canvas_memory_prepare(GX_CANVAS * canvas,GX_RECTANGLE * dirty)1157 VOID *_win32_canvas_memory_prepare(GX_CANVAS *canvas, GX_RECTANGLE *dirty)
1158 {
1159 VOID       *memptr = (VOID *)canvas -> gx_canvas_memory;
1160 INT         source_stride_bytes;
1161 INT         dest_stride_bytes;
1162 INT         copy_bytes;
1163 UCHAR      *read_start;
1164 UCHAR      *write_start;
1165 GX_DISPLAY *display;
1166 GX_VALUE    dirty_width;
1167 INT         row;
1168 
1169     display = canvas -> gx_canvas_display;
1170     if (!display)
1171     {
1172         return memptr;
1173     }
1174 
1175     if (canvas -> gx_canvas_padded_memory)
1176     {
1177         if ((display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_NONE) ||
1178             (display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_FLIP))
1179         {
1180             /* we had to create padded canvas memory, so copy dirty portion from GUIX canvas memory
1181                to properly aligned buffer created just for Win32 compatibility */
1182 
1183             /* calculate where to copy from */
1184             read_start = (UCHAR *)canvas -> gx_canvas_memory;
1185             source_stride_bytes = canvas -> gx_canvas_display -> gx_display_driver_row_pitch_get(canvas -> gx_canvas_x_resolution);
1186             read_start += dirty -> gx_rectangle_top * source_stride_bytes;
1187 
1188             /* calculate where to copy to */
1189             write_start = (UCHAR *)canvas -> gx_canvas_padded_memory;
1190             dest_stride_bytes = (source_stride_bytes + 3) & 0xfffc;
1191             write_start += dirty -> gx_rectangle_top * dest_stride_bytes;
1192 
1193             dirty_width = canvas -> gx_canvas_x_resolution;
1194             copy_bytes = canvas -> gx_canvas_display -> gx_display_driver_row_pitch_get(dirty_width);
1195 
1196             /* copy the dirty rows from source to dest */
1197 
1198             for (row = dirty -> gx_rectangle_top; row <= dirty -> gx_rectangle_bottom; row++)
1199             {
1200                 memcpy(write_start, read_start, copy_bytes); /* Use case of memcpy is verified. */
1201                 read_start += source_stride_bytes;
1202                 write_start += dest_stride_bytes;
1203             }
1204             memptr = (VOID *)canvas -> gx_canvas_padded_memory;
1205         }
1206         else
1207         {
1208             switch (display -> gx_display_color_format)
1209             {
1210             case GX_COLOR_FORMAT_24XRGB:
1211             case GX_COLOR_FORMAT_32ARGB:
1212                 gx_win32_rotate_canvas_to_bmp_32bpp(canvas);
1213                 memptr = canvas -> gx_canvas_padded_memory;
1214                 break;
1215 
1216             case GX_COLOR_FORMAT_565RGB:
1217                 gx_win32_rotate_canvas_to_bmp_16bpp(canvas);
1218                 memptr = canvas -> gx_canvas_padded_memory;
1219                 break;
1220 
1221             case GX_COLOR_FORMAT_8BIT_PALETTE:
1222                 gx_win32_rotate_canvas_to_bmp_8bpp(canvas);
1223                 memptr = canvas -> gx_canvas_padded_memory;
1224                 break;
1225 
1226             default:
1227                 return canvas -> gx_canvas_memory;
1228             }
1229         }
1230     }
1231     return memptr;
1232 }
1233 
1234 /**************************************************************************/
1235 /*                                                                        */
1236 /*  FUNCTION                                               RELEASE        */
1237 /*                                                                        */
1238 /*    gx_win32_display_buffer_toggle                     PORTABLE C       */
1239 /*                                                           6.1.4        */
1240 /*  AUTHOR                                                                */
1241 /*                                                                        */
1242 /*    Kenneth Maxwell, Microsoft Corporation                              */
1243 /*                                                                        */
1244 /*  DESCRIPTION                                                           */
1245 /*                                                                        */
1246 /*    This function toggles frame buffer for guix canvas.                 */
1247 /*                                                                        */
1248 /*  INPUT                                                                 */
1249 /*                                                                        */
1250 /*    canvas                                Canvas control block pointer  */
1251 /*    dirty                                 dirty area need to toggle     */
1252 /*                                                                        */
1253 /*  OUTPUT                                                                */
1254 /*                                                                        */
1255 /*    None                                                                */
1256 /*                                                                        */
1257 /*  CALLS                                                                 */
1258 /*                                                                        */
1259 /*    gx_utility_rectangle_define           Define a rectangle            */
1260 /*    gx_utility_rectangle_overlap_detect   Detect overlap area of two rec*/
1261 /*    gx_utility_rectangle_shift            Shift a rectangle             */
1262 /*    StretchDIBits                                                       */
1263 /*    SetMapMode                                                          */
1264 /*    ReleaseDC                                                           */
1265 /*                                                                        */
1266 /*  CALLED BY                                                             */
1267 /*                                                                        */
1268 /*    None                                                                */
1269 /*                                                                        */
1270 /*  RELEASE HISTORY                                                       */
1271 /*                                                                        */
1272 /*    DATE              NAME                      DESCRIPTION             */
1273 /*                                                                        */
1274 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
1275 /*  02-02-2021     Kenneth Maxwell          Modified comment(s),          */
1276 /*                                            fixed logic,                */
1277 /*                                            resulting in version 6.1.4  */
1278 /*                                                                        */
1279 /**************************************************************************/
gx_win32_display_buffer_toggle(GX_CANVAS * canvas,GX_RECTANGLE * dirty)1280 VOID gx_win32_display_buffer_toggle(GX_CANVAS *canvas, GX_RECTANGLE *dirty)
1281 {
1282 INT                           Top;
1283 INT                           Left;
1284 INT                           Height;
1285 INT                           Width;
1286 GX_RECTANGLE                  Limit;
1287 GX_RECTANGLE                  Copy;
1288 HDC                           win_device;
1289 GX_WIN32_DISPLAY_DRIVER_DATA *driver_instance;
1290 VOID                         *memptr;
1291 
1292     /* driver_ready is flag indicating the current state of the driver.
1293        driver_ready == 0:  Driver is not ready.
1294        driver_ready == 1:  Driver becomes ready.  This is the first time GUIX refreshes the display.
1295        driver_ready == 2: Normal operational mode */
1296     driver_instance = (GX_WIN32_DISPLAY_DRIVER_DATA *)(canvas -> gx_canvas_display -> gx_display_driver_data);
1297 
1298     if (driver_instance -> win32_driver_ready == 0)
1299     {
1300         /* If the windows driver is not ready, do not update the bitmap. */
1301         return;
1302     }
1303 
1304     gx_utility_rectangle_define(&Limit, 0, 0,
1305                                 canvas -> gx_canvas_x_resolution - 1,
1306                                 canvas -> gx_canvas_y_resolution - 1);
1307 
1308     if (gx_utility_rectangle_overlap_detect(&Limit, dirty, &Copy))
1309     {
1310         memptr = _win32_canvas_memory_prepare(canvas, &Copy);
1311 
1312         INT xsrc;
1313         INT ysrc;
1314 
1315         win_device = GetDC(driver_instance->win32_driver_winhandle);
1316         SetMapMode(win_device, MM_TEXT);
1317 
1318 #ifdef GX_ENABLE_CANVAS_PARTIAL_FRAME_BUFFER
1319         xsrc = Copy.gx_rectangle_left - canvas->gx_canvas_memory_offset_x;
1320         ysrc = Copy.gx_rectangle_top - canvas->gx_canvas_memory_offset_y;
1321 
1322         driver_instance->win32_driver_bmpinfo.gx_bmp_header.biWidth = canvas->gx_canvas_memory_width;
1323         driver_instance->win32_driver_bmpinfo.gx_bmp_header.biHeight = canvas->gx_canvas_memory_height;
1324 #else
1325         xsrc = Copy.gx_rectangle_left;
1326         ysrc = Copy.gx_rectangle_top;
1327 
1328         driver_instance->win32_driver_bmpinfo.gx_bmp_header.biWidth = canvas->gx_canvas_x_resolution;
1329         driver_instance->win32_driver_bmpinfo.gx_bmp_header.biHeight = canvas->gx_canvas_y_resolution;
1330 #endif
1331 
1332         gx_utility_rectangle_shift(&Copy, canvas->gx_canvas_display_offset_x, canvas->gx_canvas_display_offset_y);
1333 
1334         Top = Copy.gx_rectangle_top;
1335         Left = Copy.gx_rectangle_left;
1336         Width = Copy.gx_rectangle_right - Copy.gx_rectangle_left + 1;
1337         Height = Copy.gx_rectangle_bottom - Copy.gx_rectangle_top + 1;
1338 
1339         StretchDIBits(win_device, Left, Top, Width, Height,
1340                       xsrc,
1341                       ysrc + Height + 1,
1342                       Width, -Height, memptr,
1343                       (BITMAPINFO *)&(driver_instance -> win32_driver_bmpinfo),
1344                       DIB_RGB_COLORS,
1345                       SRCCOPY);
1346 
1347         ReleaseDC(driver_instance -> win32_driver_winhandle, win_device);
1348     }
1349 }
1350 
1351 /**************************************************************************/
1352 /*                                                                        */
1353 /*  FUNCTION                                               RELEASE        */
1354 /*                                                                        */
1355 /*    gx_win32_window_create                             PORTABLE C       */
1356 /*                                                           6.1.10       */
1357 /*  AUTHOR                                                                */
1358 /*                                                                        */
1359 /*    Kenneth Maxwell, Microsoft Corporation                              */
1360 /*                                                                        */
1361 /*  DESCRIPTION                                                           */
1362 /*                                                                        */
1363 /*    This function create a win32 window                                 */
1364 /*                                                                        */
1365 /*  INPUT                                                                 */
1366 /*                                                                        */
1367 /*    gx_driver_ptr                         Pointer to driver data        */
1368 /*    event_process                         Win32 even process callback   */
1369 /*    xpos                                  Initial position in x-axis    */
1370 /*    ypos                                  Initial position in y-axis    */
1371 /*                                                                        */
1372 /*  OUTPUT                                                                */
1373 /*                                                                        */
1374 /*    HWND                                  Win32 handle                  */
1375 /*                                                                        */
1376 /*  CALLS                                                                 */
1377 /*                                                                        */
1378 /*    GetSystemMetrics                                                    */
1379 /*    CreateWindow                                                        */
1380 /*                                                                        */
1381 /*  CALLED BY                                                             */
1382 /*                                                                        */
1383 /*    gx_win32_driver_thread_entry                                        */
1384 /*                                                                        */
1385 /*  RELEASE HISTORY                                                       */
1386 /*                                                                        */
1387 /*    DATE              NAME                      DESCRIPTION             */
1388 /*                                                                        */
1389 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
1390 /*  01-31-2022     Ting Zhu                 Modified comment(s),          */
1391 /*                                            corrected window size,      */
1392 /*                                            resulting in version 6.1.10 */
1393 /*                                                                        */
1394 /**************************************************************************/
gx_win32_window_create(GX_WIN32_DISPLAY_DRIVER_DATA * gx_driver_ptr,WNDPROC event_process,INT xpos,INT ypos)1395 HWND gx_win32_window_create(GX_WIN32_DISPLAY_DRIVER_DATA *gx_driver_ptr, WNDPROC event_process, INT xpos, INT ypos)
1396 {
1397 HINSTANCE Instance = GetModuleHandle(NULL);
1398 RECT      TargetSize;
1399 DWORD     WinStyle;
1400 HWND      win32_hwnd = 0;
1401 DWORD     err;
1402 WNDCLASS  wndclass;
1403 
1404     wndclass.style = CS_HREDRAW | CS_VREDRAW;
1405     wndclass.lpfnWndProc = event_process;
1406     wndclass.cbClsExtra = 0;
1407     wndclass.cbWndExtra = 0;
1408     wndclass.hInstance = Instance;
1409 
1410     gx_win32_get_icon_path();
1411     wndclass.hIcon = (HICON)LoadImage(NULL, icon_path, IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
1412     err = GetLastError();
1413     wndclass.hCursor = NULL;
1414     wndclass.hbrBackground = (HBRUSH)(GetStockObject(WHITE_BRUSH));
1415     wndclass.lpszMenuName = NULL;
1416     wndclass.lpszClassName = TEXT("GUIX");
1417 
1418     RegisterClass(&wndclass);
1419 
1420     TargetSize.left = 0;
1421     TargetSize.top = 0;
1422     TargetSize.right = gx_driver_ptr -> win32_driver_bmpinfo.gx_bmp_header.biWidth - 1;
1423     TargetSize.bottom = gx_driver_ptr -> win32_driver_bmpinfo.gx_bmp_header.biHeight - 1;
1424 
1425     WinStyle = WS_CAPTION | WS_SIZEBOX | WS_VISIBLE | WS_MINIMIZEBOX |
1426         WS_MAXIMIZEBOX | WS_SYSMENU;
1427 
1428 
1429     /* This function adjusts the size of the Windows window so that the client
1430        size is the size of the display, taking into account borders
1431        and titles and such. We want our window client are to be exactly
1432        the simulatedd display size. */
1433     AdjustWindowRect(&TargetSize, WinStyle, FALSE);
1434     win32_hwnd = CreateWindow(TEXT("GUIX"), TEXT("GUIX"),
1435                               WinStyle, xpos, ypos,
1436                               TargetSize.right - TargetSize.left + 1,
1437                               TargetSize.bottom - TargetSize.top + 1, NULL, NULL,
1438                               Instance, NULL);
1439 
1440     SetCursor(LoadCursor(NULL, IDC_ARROW));
1441 
1442     return win32_hwnd;
1443 }
1444 
1445 /**************************************************************************/
1446 /*                                                                        */
1447 /*  FUNCTION                                               RELEASE        */
1448 /*                                                                        */
1449 /*    WndProc                                            PORTABLE C       */
1450 /*                                                           6.1.11       */
1451 /*  AUTHOR                                                                */
1452 /*                                                                        */
1453 /*    Kenneth Maxwell, Microsoft Corporation                              */
1454 /*                                                                        */
1455 /*  DESCRIPTION                                                           */
1456 /*                                                                        */
1457 /*    This function handlea windows message.                              */
1458 /*                                                                        */
1459 /*  INPUT                                                                 */
1460 /*                                                                        */
1461 /*    hwnd                                  Win32 handle                  */
1462 /*    message                               Message type                  */
1463 /*    wParam                                Message data                  */
1464 /*    lParam                                Message data                  */
1465 /*                                                                        */
1466 /*  OUTPUT                                                                */
1467 /*                                                                        */
1468 /*    LRESULT                                                             */
1469 /*                                                                        */
1470 /*  CALLS                                                                 */
1471 /*                                                                        */
1472 /*    gx_system_event_send                  Send message to guix system   */
1473 /*                                                                        */
1474 /*  CALLED BY                                                             */
1475 /*                                                                        */
1476 /*    gx_win32_window_create                                              */
1477 /*                                                                        */
1478 /*  RELEASE HISTORY                                                       */
1479 /*                                                                        */
1480 /*    DATE              NAME                      DESCRIPTION             */
1481 /*                                                                        */
1482 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
1483 /*  01-31-2022     Ting Zhu                 Modified comment(s), modified */
1484 /*                                            GUIX event send logic,      */
1485 /*                                            resulting in version 6.1.10 */
1486 /*  04-25-2022     Ting Zhu                 Modified comment(s), improved */
1487 /*                                            timer event send logic,     */
1488 /*                                            resulting in version 6.1.11 */
1489 /*                                                                        */
1490 /**************************************************************************/
gx_win32_event_process(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)1491 LRESULT CALLBACK gx_win32_event_process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
1492 {
1493 GX_EVENT                      NewEvent;
1494 PAINTSTRUCT                   ps;
1495 INT                           WinX;
1496 INT                           WinY;
1497 GX_WIN32_DISPLAY_DRIVER_DATA *driver_data = 0;
1498 SHORT                         s_ch[4];
1499 SHORT                         wide_char;
1500 ULONG                         event_type;
1501 GX_BOOL                       check_key_event;
1502 
1503     driver_data = gx_win32_get_data_instance_by_win_handle(hwnd);
1504     NewEvent.gx_event_sender = 0;
1505     NewEvent.gx_event_target = GX_NULL;
1506 
1507     switch (message)
1508     {
1509     case WM_TIMER:
1510         NewEvent.gx_event_type = GX_EVENT_TIMER;
1511         NewEvent.gx_event_payload.gx_event_ulongdata = 1;
1512 
1513 #ifdef GX_THREADX_BINDING
1514         _tx_thread_context_save();
1515 #endif
1516 
1517         gx_system_event_fold(&NewEvent);
1518 
1519 #ifdef GX_THREADX_BINDING
1520         _tx_thread_context_restore();
1521 #endif
1522         return 0;
1523 
1524     case WM_PAINT:
1525         BeginPaint(hwnd, &ps);
1526         gx_win32_message_to_guix(GX_EVENT_REDRAW);
1527         /* now queue a message to wake up GUIX */
1528         EndPaint(hwnd, &ps);
1529 
1530         return 0;
1531 
1532 
1533     case WM_LBUTTONDOWN:
1534         SetCapture(hwnd);
1535         WinX = LOWORD(lParam);
1536         WinY = HIWORD(lParam);
1537 
1538         NewEvent.gx_event_type = GX_EVENT_PEN_DOWN;
1539         NewEvent.gx_event_payload.gx_event_pointdata.gx_point_x = WinX;
1540         NewEvent.gx_event_payload.gx_event_pointdata.gx_point_y = WinY;
1541         NewEvent.gx_event_display_handle = (ULONG)driver_data;
1542         gx_win32_event_to_guix(&NewEvent);
1543         return 0;
1544 
1545     case WM_LBUTTONUP:
1546         ReleaseCapture();
1547         WinX = LOWORD(lParam);
1548         WinY = HIWORD(lParam);
1549 
1550         NewEvent.gx_event_type = GX_EVENT_PEN_UP;
1551         NewEvent.gx_event_payload.gx_event_pointdata.gx_point_x = WinX;
1552         NewEvent.gx_event_payload.gx_event_pointdata.gx_point_y = WinY;
1553         NewEvent.gx_event_display_handle = (ULONG)driver_data;
1554         gx_win32_event_to_guix(&NewEvent);
1555         return 0;
1556 
1557     case WM_KEYDOWN:
1558         event_type = 0;
1559         check_key_event = GX_TRUE;
1560 
1561         if (wParam != VK_PROCESSKEY)
1562         {
1563             switch (wParam)
1564             {
1565             case VK_CAPITAL:
1566                 caps_flag ^= (GX_TRUE);
1567                 break;
1568 
1569             case VK_SHIFT:
1570                 shift_flag = GX_TRUE;
1571                 check_key_event = GX_FALSE;
1572                 break;
1573 
1574             case VK_CONTROL:
1575                 ctrl_flag = GX_TRUE;
1576                 check_key_event = GX_FALSE;
1577                 break;
1578 
1579             default:
1580                 break;
1581             }
1582 
1583             if (shift_flag || ctrl_flag && check_key_event)
1584             {
1585                 event_type = gx_win32_map_key_to_guix_event(wParam, shift_flag, ctrl_flag);
1586             }
1587 
1588             if (event_type)
1589             {
1590                 NewEvent.gx_event_type = event_type;
1591             }
1592             else
1593             {
1594                 NewEvent.gx_event_type = GX_EVENT_KEY_DOWN;
1595                 NewEvent.gx_event_payload.gx_event_ushortdata[0] = gx_win32_map_key_to_guix_key(wParam);
1596             }
1597             gx_win32_event_to_guix(&NewEvent);
1598         }
1599         break;
1600 
1601     case WM_KEYUP:
1602         switch (wParam)
1603         {
1604         case VK_SHIFT:
1605             shift_flag = GX_FALSE;
1606             break;
1607 
1608         case VK_CONTROL:
1609             ctrl_flag = GX_FALSE;
1610             break;
1611 
1612         default:
1613             break;
1614         }
1615 
1616         NewEvent.gx_event_type = GX_EVENT_KEY_UP;
1617         NewEvent.gx_event_payload.gx_event_ushortdata[0] = gx_win32_map_key_to_guix_key(wParam);
1618         gx_win32_event_to_guix(&NewEvent);
1619         break;
1620 
1621     case WM_IME_CHAR:
1622         NewEvent.gx_event_type = GX_EVENT_KEY_DOWN;
1623 
1624         /* big-endian and little endian convert. */
1625         wide_char = ((wParam & 0xFF) << 8) + ((wParam & 0xFF00) >> 8);
1626 
1627         /* Convert multi-byte to unicode. */
1628         MultiByteToWideChar(CP_ACP, 0, (LPCSTR)&wide_char, 8, (LPWSTR)s_ch, 3);
1629 
1630         NewEvent.gx_event_payload.gx_event_ushortdata[0]  = s_ch[0];
1631         gx_win32_event_to_guix(&NewEvent);
1632         break;
1633 
1634     case WM_MOUSEMOVE:
1635         if (wParam & MK_LBUTTON)
1636         {
1637             WinX = LOWORD(lParam);
1638             WinY = HIWORD(lParam);
1639 
1640             NewEvent.gx_event_type = GX_EVENT_PEN_DRAG;
1641             NewEvent.gx_event_payload.gx_event_pointdata.gx_point_x = WinX;
1642             NewEvent.gx_event_payload.gx_event_pointdata.gx_point_y = WinY;
1643             NewEvent.gx_event_display_handle = (ULONG)driver_data;
1644             gx_win32_event_to_guix(&NewEvent);
1645         }
1646         return 0;
1647 
1648     case WM_SETCURSOR:
1649         return FALSE;
1650 
1651     case WM_DESTROY:
1652         PostQuitMessage(0);
1653         return 0;
1654     }
1655     return DefWindowProc(hwnd, message, wParam, lParam);
1656 }
1657 
1658 /**************************************************************************/
1659 /*                                                                        */
1660 /*  FUNCTION                                               RELEASE        */
1661 /*                                                                        */
1662 /*    gx_win32_input_driver                              PORTABLE C       */
1663 /*                                                           6.1.10       */
1664 /*  AUTHOR                                                                */
1665 /*                                                                        */
1666 /*    Kenneth Maxwell, Microsoft Corporation                              */
1667 /*                                                                        */
1668 /*  DESCRIPTION                                                           */
1669 /*                                                                        */
1670 /*    This function handle windows message and send it to guix system     */
1671 /*                                                                        */
1672 /*  INPUT                                                                 */
1673 /*                                                                        */
1674 /*    None                                                                */
1675 /*                                                                        */
1676 /*  OUTPUT                                                                */
1677 /*                                                                        */
1678 /*    None                                                                */
1679 /*                                                                        */
1680 /*  CALLS                                                                 */
1681 /*                                                                        */
1682 /*    gx_win32_message_to_guix                                            */
1683 /*    GetMessage                                                          */
1684 /*    DispatchMessage                                                     */
1685 /*                                                                        */
1686 /*  CALLED BY                                                             */
1687 /*                                                                        */
1688 /*    gx_win32_driver_thread_entry                                        */
1689 /*                                                                        */
1690 /*  RELEASE HISTORY                                                       */
1691 /*                                                                        */
1692 /*    DATE              NAME                      DESCRIPTION             */
1693 /*                                                                        */
1694 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
1695 /*  01-31-2022     Ting Zhu                 Modified comment(s), added    */
1696 /*                                            timer stop and thread       */
1697 /*                                            handle close logic,         */
1698 /*                                            resulting in version 6.1.10 */
1699 /*                                                                        */
1700 /**************************************************************************/
gx_win32_input_driver(GX_WIN32_DISPLAY_DRIVER_DATA * instance)1701 void gx_win32_input_driver(GX_WIN32_DISPLAY_DRIVER_DATA *instance)
1702 {
1703 int status;
1704 MSG msg;
1705 int exit_code = 0;
1706 
1707     while ((status = GetMessage(&msg, NULL, 0, 0)) != 0)
1708     {
1709         if ((msg.hwnd == NULL && msg.message == WM_USER) ||
1710             (status == -1))
1711         {
1712             /* Exit thread. */
1713             exit_code = -1;
1714             break;
1715         }
1716 
1717         TranslateMessage(&msg);
1718         DispatchMessage(&msg);
1719     }
1720 
1721     /* Stop multi-media timer.  */
1722     gx_win32_stop_multimedia_timer();
1723 
1724     /* Send an event to wake up the GUIX thread.  */
1725     gx_win32_message_to_guix(GX_EVENT_TERMINATE);
1726 
1727     if ((instance->win32_driver_thread_handle != INVALID_HANDLE_VALUE) &&
1728         instance->win32_driver_thread_handle)
1729     {
1730         CloseHandle(instance->win32_driver_thread_handle);
1731     }
1732 
1733     GX_WIN32_EVENT_THREAD_EXIT(exit_code);
1734 }
1735 
1736 /**************************************************************************/
1737 /*                                                                        */
1738 /*  FUNCTION                                               RELEASE        */
1739 /*                                                                        */
1740 /*    gx_win32_driver_thread_entry                       PORTABLE C       */
1741 /*                                                           6.1.7        */
1742 /*  AUTHOR                                                                */
1743 /*                                                                        */
1744 /*    Kenneth Maxwell, Microsoft Corporation                              */
1745 /*                                                                        */
1746 /*  DESCRIPTION                                                           */
1747 /*                                                                        */
1748 /*    This function creates window for guix and start guix thread in      */
1749 /*    window.                                                             */
1750 /*                                                                        */
1751 /*  INPUT                                                                 */
1752 /*                                                                        */
1753 /*    thread_input                          Pointer to win32 display      */
1754 /*                                            driver data                 */
1755 /*                                                                        */
1756 /*  OUTPUT                                                                */
1757 /*                                                                        */
1758 /*    DWORD                                                               */
1759 /*                                                                        */
1760 /*  CALLS                                                                 */
1761 /*                                                                        */
1762 /*    gx_win32_window_create                Create Win32 window           */
1763 /*    gx_win32_driver_thread_initialize     Initialize thread             */
1764 /*                                                                        */
1765 /*  CALLED BY                                                             */
1766 /*                                                                        */
1767 /*    win32 guix setup functions                                          */
1768 /*                                                                        */
1769 /*  RELEASE HISTORY                                                       */
1770 /*                                                                        */
1771 /*    DATE              NAME                      DESCRIPTION             */
1772 /*                                                                        */
1773 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
1774 /*  06-02-2021     Ting Zhu                 Modified comment(s),          */
1775 /*                                            reorganized code,           */
1776 /*                                            resulting in version 6.1.7  */
1777 /*                                                                        */
1778 /**************************************************************************/
gx_win32_driver_thread_entry(ULONG thread_input)1779 void gx_win32_driver_thread_entry(ULONG thread_input)
1780 {
1781 /* create a MS Windows window to serve as our physical display
1782    This HAS to be done in the context of the win32 thread,
1783    otherwise we don't get messages from MS Windows. Would prefer
1784    to do this as part of the win32_graphics_driver function,
1785    but that runs in the context of the GUIX thread so we can't do
1786    it there. */
1787 GX_WIN32_DISPLAY_DRIVER_DATA *instance = (GX_WIN32_DISPLAY_DRIVER_DATA *)thread_input;
1788 
1789     /* Create a win32 window for display. */
1790     instance -> win32_driver_winhandle = gx_win32_window_create(instance, gx_win32_event_process, 20, 20);
1791 
1792     gx_win32_driver_thread_initialize(instance);
1793 }
1794 
1795 /**************************************************************************/
1796 /*                                                                        */
1797 /*  FUNCTION                                               RELEASE        */
1798 /*                                                                        */
1799 /*    gx_win32_driver_thread_initialize                  PORTABLE C       */
1800 /*                                                           6.2.0        */
1801 /*  AUTHOR                                                                */
1802 /*                                                                        */
1803 /*    Ting Zhu, Microsoft Corporation                                     */
1804 /*                                                                        */
1805 /*  DESCRIPTION                                                           */
1806 /*                                                                        */
1807 /*    This function initializes thread.                                   */
1808 /*                                                                        */
1809 /*  INPUT                                                                 */
1810 /*                                                                        */
1811 /*    instance                              Pointer to win32 display      */
1812 /*                                            driver data                 */
1813 /*                                                                        */
1814 /*  OUTPUT                                                                */
1815 /*                                                                        */
1816 /*    DWORD                                                               */
1817 /*                                                                        */
1818 /*  CALLS                                                                 */
1819 /*                                                                        */
1820 /*    ShowWindow                            Active the specified window   */
1821 /*    UpdateWindow                          Update the client area of the */
1822 /*                                            specified window            */
1823 /*    gx_win32_message_to_guix              Send message to guix          */
1824 /*    SetTimer                              Set a timer                   */
1825 /*    gx_win32_input_driver                 Handle Win32 messages         */
1826 /*                                                                        */
1827 /*  CALLED BY                                                             */
1828 /*                                                                        */
1829 /*    win32 thread entry                                                  */
1830 /*                                                                        */
1831 /*  RELEASE HISTORY                                                       */
1832 /*                                                                        */
1833 /*    DATE              NAME                      DESCRIPTION             */
1834 /*                                                                        */
1835 /*  06-02-2021     Ting Zhu                 Initial Version 6.1.7         */
1836 /*  01-31-2022     Ting Zhu                 Modified comment(s), modified */
1837 /*                                            to use multi-media timer,   */
1838 /*                                            resulting in version 6.1.10 */
1839 /*  10-31-2022     Ting Zhu                 Modified comment(s), added    */
1840 /*                                            ThreadX system state check, */
1841 /*                                            resulting in version 6.2.0  */
1842 /*                                                                        */
1843 /**************************************************************************/
gx_win32_driver_thread_initialize(GX_WIN32_DISPLAY_DRIVER_DATA * instance)1844 void gx_win32_driver_thread_initialize(GX_WIN32_DISPLAY_DRIVER_DATA *instance)
1845 {
1846     /* Show window. */
1847     ShowWindow(instance->win32_driver_winhandle, SW_SHOW);
1848     UpdateWindow(instance->win32_driver_winhandle);
1849 
1850     /* Mark the driver as ready. */
1851     instance->win32_driver_ready = 1;
1852 
1853 #ifdef GX_THREADX_BINDING
1854     while (_tx_thread_system_state != 0)
1855     {
1856         /* ThreadX is not ready. */
1857         Sleep(1);
1858     }
1859 #endif
1860 
1861     /* Driver is ready, force a redraw. */
1862     gx_win32_message_to_guix(GX_EVENT_REDRAW);
1863 
1864     /* Create a multi-media timer. */
1865     gx_win32_start_multimedia_timer(instance);
1866 
1867     /* Handle win32 messages. */
1868     gx_win32_input_driver(instance);
1869 }
1870 
1871 /**************************************************************************/
1872 /*                                                                        */
1873 /*  FUNCTION                                               RELEASE        */
1874 /*                                                                        */
1875 /*    WinMain                                            PORTABLE C       */
1876 /*                                                           6.1.3        */
1877 /*  AUTHOR                                                                */
1878 /*                                                                        */
1879 /*    Kenneth Maxwell, Microsoft Corporation                              */
1880 /*                                                                        */
1881 /*  DESCRIPTION                                                           */
1882 /*                                                                        */
1883 /*    This function is win32 main function.                               */
1884 /*                                                                        */
1885 /*  INPUT                                                                 */
1886 /*                                                                        */
1887 /*    None                                                                */
1888 /*                                                                        */
1889 /*  OUTPUT                                                                */
1890 /*                                                                        */
1891 /*    int                                   Application exit status       */
1892 /*                                                                        */
1893 /*  CALLS                                                                 */
1894 /*                                                                        */
1895 /*    gx_main                               Application entry             */
1896 /*                                                                        */
1897 /*  CALLED BY                                                             */
1898 /*                                                                        */
1899 /*    None                                                                */
1900 /*                                                                        */
1901 /*  RELEASE HISTORY                                                       */
1902 /*                                                                        */
1903 /*    DATE              NAME                      DESCRIPTION             */
1904 /*                                                                        */
1905 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
1906 /*                                                                        */
1907 /**************************************************************************/
WinMain(HINSTANCE Instance,HINSTANCE PrevInstance,LPSTR pCmd,int CmdShow)1908 int WINAPI WinMain(HINSTANCE Instance, HINSTANCE PrevInstance,
1909                    LPSTR pCmd, int CmdShow)
1910 {
1911     return(gx_main(0, (char **)GX_NULL));
1912 }
1913 #endif /* WIN32 */
1914 
1915