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 /** System Management (System) */
18 /** */
19 /**************************************************************************/
20
21 #define GX_SOURCE_CODE
22
23
24 /* Locate GUIX system data in this file. */
25
26 #define GX_SYSTEM_INIT
27
28
29 /* Include necessary system files. */
30
31 #include "gx_api.h"
32 #include "gx_system.h"
33 #include "gx_utility.h"
34 #include "gx_animation.h"
35
36 /**************************************************************************/
37 /* */
38 /* FUNCTION RELEASE */
39 /* */
40 /* _gx_system_initialize PORTABLE C */
41 /* 6.1.3 */
42 /* AUTHOR */
43 /* */
44 /* Kenneth Maxwell, Microsoft Corporation */
45 /* */
46 /* DESCRIPTION */
47 /* */
48 /* This service initializes GUIX. */
49 /* */
50 /* INPUT */
51 /* */
52 /* None */
53 /* */
54 /* OUTPUT */
55 /* */
56 /* status Completion status */
57 /* */
58 /* CALLS */
59 /* */
60 /* memset Clear various data structures */
61 /* _gx_system_error_process Process system errors */
62 /* _gx_utility_ltoa Int to ASCII conversion */
63 /* _gx_utility_string_length_check Test string length */
64 /* tx_timer_create Create ThreadX Timer */
65 /* tx_mutex_create Create system protection mutex*/
66 /* tx_queue_create Create system event queue */
67 /* tx_queue_delete Delete system event queue */
68 /* */
69 /* CALLED BY */
70 /* */
71 /* Application Code */
72 /* */
73 /* RELEASE HISTORY */
74 /* */
75 /* DATE NAME DESCRIPTION */
76 /* */
77 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
78 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
79 /* resulting in version 6.1 */
80 /* 12-31-2020 Kenneth Maxwell Modified comment(s), */
81 /* added GX_DISABLE_THREADX_ */
82 /* TIMER_SOURCE configuration, */
83 /* resulting in version 6.1.3 */
84 /* */
85 /**************************************************************************/
_gx_system_initialize(VOID)86 UINT _gx_system_initialize(VOID)
87 {
88 #ifndef TX_DISABLE_ERROR_CHECKING
89 UINT status;
90 #endif
91 UINT index;
92 UINT length;
93
94 /* Set linked list pointers to NULL. */
95
96 _gx_system_display_created_list = GX_NULL;
97 _gx_system_canvas_created_list = GX_NULL;
98 _gx_system_root_window_created_list = GX_NULL;
99 _gx_system_focus_owner = GX_NULL;
100
101 /* Clear all the created counters. */
102 _gx_system_display_created_count = 0;
103 _gx_system_canvas_created_count = 0;
104
105 /* initialize the draw context stack */
106 _gx_system_draw_context_stack_end = _gx_system_draw_context_stack;
107 _gx_system_draw_context_stack_end += GX_MAX_CONTEXT_NESTING;
108 _gx_system_current_draw_context = GX_NULL;
109
110 /* initialize gradient list */
111 _gx_system_gradient_list = GX_NULL;
112
113 /* initialize the input capture stack */
114 memset(_gx_system_input_capture_stack, 0, sizeof(GX_WIDGET *) * GX_MAX_INPUT_CAPTURE_NESTING);
115 _gx_system_capture_count = 0;
116 _gx_system_input_owner = GX_NULL;
117
118 /* initialize rich text context stack. */
119 _gx_system_rich_text_context_stack.gx_rich_text_context_stack_top = 0;
120 _gx_system_rich_text_context_stack_save.gx_rich_text_context_stack_top = 0;
121
122 /* initialize the lock count to 0 */
123 _gx_system_lock_nesting = 0;
124
125 /* no thread has GUIX locked */
126
127 _gx_system_lock_thread = GX_NULL;
128
129 /* initialize default vertical scrollbar appearance */
130 memset(&_gx_system_vertical_scrollbar_appearance, 0, sizeof(GX_SCROLLBAR_APPEARANCE));
131
132 _gx_system_vertical_scrollbar_style = GX_SCROLLBAR_VERTICAL | GX_SCROLLBAR_RELATIVE_THUMB | GX_SCROLLBAR_END_BUTTONS;
133
134 _gx_system_vertical_scrollbar_appearance.gx_scroll_width = 20;
135 _gx_system_vertical_scrollbar_appearance.gx_scroll_thumb_width = 18;
136 _gx_system_vertical_scrollbar_appearance.gx_scroll_thumb_color = GX_COLOR_ID_SCROLL_BUTTON;
137 _gx_system_vertical_scrollbar_appearance.gx_scroll_thumb_border_color = GX_COLOR_ID_SCROLL_BUTTON;
138 _gx_system_vertical_scrollbar_appearance.gx_scroll_button_color = GX_COLOR_ID_SCROLL_BUTTON;
139 _gx_system_vertical_scrollbar_appearance.gx_scroll_thumb_travel_min = 20;
140 _gx_system_vertical_scrollbar_appearance.gx_scroll_thumb_travel_max = 20;
141 _gx_system_vertical_scrollbar_appearance.gx_scroll_thumb_border_style = GX_STYLE_BORDER_THIN;
142
143 /* initialize default horizontal scrollbar appearance */
144 _gx_system_horizontal_scrollbar_appearance = _gx_system_vertical_scrollbar_appearance;
145 _gx_system_horizontal_scrollbar_style = GX_SCROLLBAR_HORIZONTAL | GX_SCROLLBAR_RELATIVE_THUMB | GX_SCROLLBAR_END_BUTTONS;
146
147 #if defined(GX_DYNAMIC_BIDI_TEXT_SUPPORT)
148 _gx_system_bidi_text_enabled = GX_FALSE;
149 #endif
150
151 #if defined(GX_THAI_GLYPH_SHAPING_SUPPORT)
152 _gx_system_text_render_style = 0;
153 #endif
154
155 /* initialize theme table information */
156 _gx_system_theme_table = GX_NULL;
157 _gx_system_theme_table_size = 0;
158 _gx_system_active_theme = 0;
159
160 /* Initialize the version string */
161 memset(_gx_system_version_string, 0, GX_VERSION_STRING_LENGTH);
162
163 /* We are allocating 16 bytes for the version string. MAJOR_VERSION and MINOR_VERSION do not exceed 3 bytes each
164 (version 999.999). Therefore the code below will not exceed the 16 byte buffer. (8 + 3 + '.' + 3 + NULL). */
165 length = sizeof("Version ") - 1;
166
167 /* Copy "Version " to version string. */
168 memcpy(_gx_system_version_string, "Version ", length); /* Use case of memcpy is verified. */
169
170 index = length;
171
172 /* Convert major version value to version string. */
173 _gx_utility_ltoa(__GUIX_MAJOR_VERSION, _gx_system_version_string + index, GX_VERSION_STRING_LENGTH - index);
174
175 /* Calculate major version string length. */
176 _gx_utility_string_length_check(_gx_system_version_string + index, &length, GX_VERSION_STRING_LENGTH - index);
177
178 index += length;
179 _gx_system_version_string[index++] = '.';
180
181 /* Convert minor version value to version string. */
182 _gx_utility_ltoa(__GUIX_MINOR_VERSION, _gx_system_version_string + index, GX_VERSION_STRING_LENGTH - index);
183
184 /* Initialize the system timers */
185
186 memset(_gx_system_timer_memory, 0, sizeof(GX_TIMER) * GX_MAX_ACTIVE_TIMERS);
187 _gx_system_free_timer_list = _gx_system_timer_memory;
188 _gx_system_active_timer_list = GX_NULL;
189
190 /* link all the timers in the timer free list */
191 for (index = 0; index < GX_MAX_ACTIVE_TIMERS - 1; index++)
192 {
193 _gx_system_timer_memory[index].gx_timer_next = &_gx_system_timer_memory[index + 1];
194 }
195
196 /* initialize pen tracking variables */
197 _gx_system_last_clock = 0;
198 _gx_system_clock_delta = 0;
199 _gx_system_last_pen_point.gx_point_x = 0;
200 _gx_system_last_pen_point.gx_point_y = 0;
201 _gx_system_pen_speed_x = 0;
202 _gx_system_pen_speed_y = 0;
203
204 /* initialize touch configuration information */
205 _gx_system_pen_configuration.gx_pen_configuration_min_drag_dist = 80;
206 _gx_system_pen_configuration.gx_pen_configuration_max_pen_speed_ticks = 10;
207
208 /* Initialize free animation pool */
209 #if (GX_ANIMATION_POOL_SIZE > 0)
210 /* link all of the animation blocks into free list */
211 for (index = 0; index < GX_ANIMATION_POOL_SIZE - 1; index++)
212 {
213 _gx_animation_create(&_gx_system_animation_pool[index]);
214 _gx_system_animation_pool[index].gx_animation_next = &_gx_system_animation_pool[index + 1];
215 }
216 _gx_system_animation_free_list = _gx_system_animation_pool;
217 #endif
218
219 /* initialize the active animation list */
220 _gx_system_animation_list = GX_NULL;
221
222 /* initialize memory allocators */
223 _gx_system_memory_allocator = GX_NULL;
224 _gx_system_memory_free = GX_NULL;
225
226 /* Initialize the viewport storage */
227
228 _gx_system_free_views = _gx_system_view_memory;
229
230 for (index = 0; index < GX_MAX_VIEWS - 1; index++)
231 {
232 _gx_system_free_views -> gx_view_next = (_gx_system_free_views + 1);
233 _gx_system_free_views = _gx_system_free_views -> gx_view_next;
234 }
235 _gx_system_free_views -> gx_view_next = GX_NULL;
236 _gx_system_free_views = _gx_system_view_memory;
237
238 /* Initialize the system error information. */
239 _gx_system_last_error = GX_SUCCESS;
240 _gx_system_error_count = 0;
241
242 _gx_system_clipboard = GX_NULL;
243 _gx_system_clipboard_size = 0;
244
245 /* Initiate system screen stack controler. */
246 memset(&_gx_system_screen_stack, 0, sizeof(GX_SCREEN_STACK_CONTROL));
247
248 /* Create the required ThreadX objects. */
249
250 #ifdef GX_THREADX_BINDING
251 /* First initialize all ThreadX objects to 0. */
252 memset(&_gx_system_event_queue, 0, sizeof(_gx_system_event_queue));
253 memset(&_gx_system_protect, 0, sizeof(_gx_system_protect));
254
255 /* Check the validity of the GX_EVENT_SIZE constant. */
256 if (GX_EVENT_SIZE < sizeof(GX_EVENT))
257 {
258
259 /* The constant GX_EVENT_SIZE is not large enough to hold a GX_EVENT type, which is a system
260 error. GX_EVENT_SIZE must be redefined and the GUIX library must be rebuilt. */
261
262 /* Call system error handler. */
263 _gx_system_error_process(GX_SYSTEM_EVENT_SIZE_MISMATCH);
264
265 /* Return error! */
266 return(GX_SYSTEM_ERROR);
267 }
268
269 #ifndef GX_DISABLE_THREADX_TIMER_SOURCE
270 memset(&_gx_system_timer, 0, sizeof(_gx_system_timer));
271
272 /* create the ThreadX timer that drives all GUIX timers */
273 tx_timer_create(&_gx_system_timer, "guix timer", _gx_system_timer_expiration, 0,
274 GX_SYSTEM_TIMER_TICKS, GX_SYSTEM_TIMER_TICKS, TX_NO_ACTIVATE);
275 #endif
276
277 #ifdef TX_DISABLE_ERROR_CHECKING
278 tx_queue_create(&_gx_system_event_queue, "GUIX System Event Queue", (GX_EVENT_SIZE / sizeof(ULONG)),
279 _gx_system_event_queue_memory, sizeof(_gx_system_event_queue_memory));
280 #else
281 /* Create the system event queue. */
282 status = tx_queue_create(&_gx_system_event_queue, "GUIX System Event Queue", (GX_EVENT_SIZE / sizeof(ULONG)),
283 _gx_system_event_queue_memory, sizeof(_gx_system_event_queue_memory));
284
285 /* Determine if the event queue creation was successful. */
286 if (status != TX_SUCCESS)
287 {
288
289 /* Queue create failed - call system error handler. */
290 _gx_system_error_process(GX_SYSTEM_QUEUE_CREATE_FAILED);
291
292 /* Return error! */
293 return(GX_SYSTEM_ERROR);
294 }
295 #endif
296
297 #ifdef TX_DISABLE_ERROR_CHECKING
298 tx_mutex_create(&_gx_system_protect, "GUIX System Protection", TX_NO_INHERIT);
299 #else
300 /* Create the system protection mutex. */
301 status = tx_mutex_create(&_gx_system_protect, "GUIX System Protection", TX_NO_INHERIT);
302
303 /* Determine if the mutex creation was successful. */
304 if (status != TX_SUCCESS)
305 {
306
307 /* Mutex create failed - call system error handler. */
308 _gx_system_error_process(GX_SYSTEM_MUTEX_CREATE_FAILED);
309
310 /* Delete the event queue. */
311 tx_queue_delete(&_gx_system_event_queue);
312
313 /* Return error! */
314 return(GX_SYSTEM_ERROR);
315 }
316 #endif
317
318 /* initialize GUIX thread here. It is started later by gx_system_start() */
319 memset(&_gx_system_thread, 0, sizeof(_gx_system_thread));
320
321 #ifdef TX_DISABLE_ERROR_CHECKING
322 tx_thread_create(&_gx_system_thread, "GUIX System Thread",
323 _gx_system_thread_entry, 0,
324 _gx_system_thread_stack, sizeof(_gx_system_thread_stack),
325 GX_SYSTEM_THREAD_PRIORITY, GX_SYSTEM_THREAD_PRIORITY,
326 GX_SYSTEM_THREAD_TIMESLICE, TX_DONT_START);
327 #else
328 status = tx_thread_create(&_gx_system_thread, "GUIX System Thread",
329 _gx_system_thread_entry, 0,
330 _gx_system_thread_stack, sizeof(_gx_system_thread_stack),
331 GX_SYSTEM_THREAD_PRIORITY, GX_SYSTEM_THREAD_PRIORITY,
332 GX_SYSTEM_THREAD_TIMESLICE, TX_DONT_START);
333
334 if (status != TX_SUCCESS)
335 {
336 /* delete other resources */
337 tx_queue_delete(&_gx_system_event_queue);
338
339 /* Delete the mutex. */
340 tx_mutex_delete(&_gx_system_protect);
341
342 /* thread create failed - call system error handler. */
343 _gx_system_error_process(GX_SYSTEM_THREAD_CREATE_FAILED);
344 return(GX_SYSTEM_ERROR);
345 }
346 #endif
347 #else
348 GX_RTOS_BINDING_INITIALIZE;
349 #endif
350
351 /* Return successful completion. */
352 return(GX_SUCCESS);
353 }
354
355