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