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 /** Window Management (Window) */
18 /** */
19 /**************************************************************************/
20
21 #define GX_SOURCE_CODE
22
23
24 /* Include necessary system files. */
25
26 #include "gx_api.h"
27 #include "gx_system.h"
28 #include "gx_widget.h"
29 #include "gx_window.h"
30 #include "gx_utility.h"
31
32
33 /**************************************************************************/
34 /* */
35 /* FUNCTION RELEASE */
36 /* */
37 /* _gx_window_execute PORTABLE C */
38 /* 6.1 */
39 /* AUTHOR */
40 /* */
41 /* Kenneth Maxwell, Microsoft Corporation */
42 /* */
43 /* DESCRIPTION */
44 /* */
45 /* This function modally executes a window. */
46 /* */
47 /* INPUT */
48 /* */
49 /* window Window's widget control block */
50 /* return_ptr return value */
51 /* */
52 /* OUTPUT */
53 /* */
54 /* status Completion status */
55 /* */
56 /* CALLS */
57 /* */
58 /* */
59 /* CALLED BY */
60 /* */
61 /* Application Code */
62 /* GUIX Internal Code */
63 /* */
64 /* RELEASE HISTORY */
65 /* */
66 /* DATE NAME DESCRIPTION */
67 /* */
68 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
69 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
70 /* resulting in version 6.1 */
71 /* */
72 /**************************************************************************/
_gx_window_execute(GX_WINDOW * window,ULONG * return_ptr)73 UINT _gx_window_execute(GX_WINDOW *window, ULONG *return_ptr)
74 {
75 UINT status = GX_SUCCESS;
76 UINT return_code = 0;
77
78 #ifdef GX_THREADX_BINDING
79 ULONG event_memory[GX_EVENT_ULONGS];
80 #else
81 GX_EVENT event_memory;
82 #endif
83
84 GX_EVENT *event_ptr;
85 GX_WIDGET *widget;
86
87 if (window -> gx_widget_status & GX_STATUS_MODAL)
88 {
89 return GX_NO_CHANGE;
90 }
91
92 _gx_widget_status_add((GX_WIDGET *)window, GX_STATUS_MODAL);
93
94 /* Loop to process GUIX events. */
95 while (!return_code)
96 {
97 #ifdef GX_THREADX_BINDING
98 /* Pickup event from event queue. */
99 status = tx_queue_receive(&_gx_system_event_queue, &event_memory[0], TX_NO_WAIT);
100
101 /* Was there an event? */
102 if (status == TX_QUEUE_EMPTY)
103 {
104 /* No event to process, so re-draw dirty widgets */
105 _gx_system_canvas_refresh();
106
107 /* Now block this thread until an event is received. */
108 status = tx_queue_receive(&_gx_system_event_queue, &event_memory[0], TX_WAIT_FOREVER);
109 if (status == TX_SUCCESS)
110 {
111 status = GX_SUCCESS;
112 }
113 }
114 #else
115 /* here for generic RTOS binding */
116 status = GX_EVENT_POP(&event_memory, GX_FALSE);
117 if (status == GX_FAILURE)
118 {
119 _gx_system_canvas_refresh();
120 status = GX_EVENT_POP(&event_memory, GX_TRUE);
121 }
122 #endif
123
124 /* Check for a successful status. */
125 if (status == GX_SUCCESS)
126 {
127 /* Setup a pointer to the event. */
128 event_ptr = (GX_EVENT *)(&event_memory);
129
130 switch (event_ptr -> gx_event_type)
131 {
132 /* Determine if a redraw event is present. */
133 case GX_EVENT_REDRAW:
134 /* Yes, a redraw event is present, detect and process the dirty area(s). */
135 widget = (GX_WIDGET *)_gx_system_root_window_created_list;
136 while (widget)
137 {
138 _gx_system_dirty_mark(widget);
139 widget = widget -> gx_widget_next;
140 }
141 break;
142
143 case GX_EVENT_TIMER:
144 if (event_ptr -> gx_event_target == GX_NULL)
145 {
146 /* the event is from gx_system_timer_expiration */
147 _gx_system_timer_update(event_ptr -> gx_event_payload.gx_event_ulongdata);
148 }
149 else
150 {
151 return_code = _gx_system_event_dispatch(event_ptr);
152 }
153 break;
154
155 case GX_EVENT_PEN_DOWN:
156 case GX_EVENT_PEN_UP:
157 case GX_EVENT_PEN_DRAG:
158 if (_gx_system_capture_count > 0 ||
159 _gx_utility_rectangle_point_detect(&window -> gx_widget_size, event_ptr -> gx_event_payload.gx_event_pointdata))
160 {
161 return_code = _gx_system_event_dispatch(event_ptr);
162 }
163 break;
164
165 case GX_EVENT_TERMINATE:
166 _gx_system_event_send(event_ptr);
167 return_code = GX_EVENT_TERMINATE;
168 break;
169
170 case GX_EVENT_HIDE:
171 _gx_system_event_dispatch(event_ptr);
172 return_code = GX_EVENT_HIDE;
173 break;
174
175 case GX_EVENT_CLOSE:
176 _gx_system_event_dispatch(event_ptr);
177 return_code = GX_EVENT_CLOSE;
178 break;
179
180 case 0:
181 /* event has been purged */
182 break;
183
184 default:
185 /* Dispatch the event to GUIX proper window/widget. */
186 return_code = _gx_system_event_dispatch(event_ptr);
187 break;
188 }
189 }
190 else
191 {
192 /* Error receiving event - call system error handler. */
193 _gx_system_error_process(GX_SYSTEM_EVENT_RECEIVE_ERROR);
194
195 /* Return to exit the system thread. */
196
197 _gx_widget_status_remove((GX_WIDGET *)window, GX_STATUS_MODAL);
198
199 if (return_ptr)
200 {
201 *return_ptr = 0;
202 }
203 return GX_SYSTEM_EVENT_RECEIVE_ERROR;
204 }
205 }
206
207 _gx_widget_status_remove((GX_WIDGET *)window, GX_STATUS_MODAL);
208
209 if (return_ptr)
210 {
211 *return_ptr = return_code;
212 }
213
214 _gx_widget_detach((GX_WIDGET *)window);
215 return GX_SUCCESS;
216 }
217
218