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