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