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 /* Include necessary system files. */
26
27 #include "gx_api.h"
28 #include "gx_system.h"
29 #include "gx_display.h"
30
31 /**************************************************************************/
32 /* */
33 /* FUNCTION RELEASE */
34 /* */
35 /* _gx_system_event_dispatch PORTABLE C */
36 /* 6.2.1 */
37 /* AUTHOR */
38 /* */
39 /* Kenneth Maxwell, Microsoft Corporation */
40 /* */
41 /* DESCRIPTION */
42 /* */
43 /* This function dispatches new system events to the appropriate */
44 /* widget(s). */
45 /* */
46 /* INPUT */
47 /* */
48 /* in_event New event */
49 /* */
50 /* OUTPUT */
51 /* */
52 /* None */
53 /* */
54 /* CALLS */
55 /* */
56 /* _gx_system_top_root_find Find the root widget */
57 /* _gx_system_top_widget_find Find top widget */
58 /* _gx_system_focus_claim Mark the widget to receive */
59 /* GUIX input focus */
60 /* [gx_widget_event_process_function] Widget's event processing */
61 /* */
62 /* CALLED BY */
63 /* */
64 /* GUIX Internal Code */
65 /* */
66 /* RELEASE HISTORY */
67 /* */
68 /* DATE NAME DESCRIPTION */
69 /* */
70 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
71 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
72 /* resulting in version 6.1 */
73 /* 04-25-2022 Ting Zhu Modified comment(s), */
74 /* improved logic, */
75 /* resulting in version 6.1.11 */
76 /* 03-08-2023 Ting Zhu Modified comment(s), fixed */
77 /* a gcc warning, */
78 /* resulting in version 6.2.1 */
79 /* */
80 /**************************************************************************/
_gx_system_event_dispatch(GX_EVENT * in_event)81 UINT _gx_system_event_dispatch(GX_EVENT *in_event)
82 {
83
84 GX_WIDGET *target = GX_NULL;
85 GX_WINDOW_ROOT *root_window = GX_NULL;
86 GX_EVENT out_event;
87 GX_POINT pen_pos;
88 UINT return_code = 0;
89
90 #if defined(GX_MOUSE_SUPPORT)
91 GX_DISPLAY *display;
92 #endif
93 /* check for NULL event. This happens when an event is purged */
94 if (in_event -> gx_event_type == 0)
95 {
96 return 0;
97 }
98
99 /* copy the event to dispatch */
100 out_event = *in_event;
101
102 /* is this event targetted to a particular widget? */
103 if (out_event.gx_event_target)
104 {
105 target = out_event.gx_event_target;
106 return_code = target -> gx_widget_event_process_function(target, &out_event);
107 }
108 else
109 {
110 switch (out_event.gx_event_type)
111 {
112 #if defined(GX_MOUSE_SUPPORT)
113 case GX_EVENT_PEN_MOVE:
114 /* Find the top root window under this click position */
115 pen_pos = out_event.gx_event_payload.gx_event_pointdata;
116 root_window = _gx_system_top_root_find(&out_event);
117
118 if (root_window)
119 {
120 /* mouse cursor coordinates are display relative, not canvas relative,
121 so set cursor position before canvas offset is applied
122 */
123 display = root_window -> gx_window_root_canvas -> gx_canvas_display;
124 if (display -> gx_display_mouse_position_set)
125 {
126 display -> gx_display_mouse_position_set(display, &pen_pos);
127 }
128 }
129 break;
130 #endif
131
132 case GX_EVENT_PEN_DOWN:
133 case GX_EVENT_PEN_UP:
134 case GX_EVENT_PEN_DRAG:
135
136 /* get absolute click position */
137 pen_pos = out_event.gx_event_payload.gx_event_pointdata;
138
139 if (_gx_system_capture_count > 0)
140 {
141 /* Get the widget that owns the system input. */
142 target = *_gx_system_input_capture_stack;
143
144 if (target)
145 {
146
147 /* Find the root window of the widget that owns the system input. */
148 root_window = (GX_WINDOW_ROOT *)target -> gx_widget_parent;
149 while (root_window && root_window -> gx_widget_parent)
150 {
151 root_window = (GX_WINDOW_ROOT *)root_window -> gx_widget_parent;
152 }
153 }
154 }
155 else
156 {
157 /* Find the top root window under this click position */
158 root_window = _gx_system_top_root_find(&out_event);
159 }
160
161 if (root_window)
162 {
163 #if defined(GX_MOUSE_SUPPORT)
164 /* mouse cursor coordinates are display relative, not canvas relative,
165 so set cursor position before canvas offset is applied
166 */
167 display = root_window -> gx_window_root_canvas -> gx_canvas_display;
168 if (display -> gx_display_mouse_position_set)
169 {
170 display -> gx_display_mouse_position_set(display, &pen_pos);
171 }
172 #endif
173
174 /* adjust the pen position by the canvas offset */
175 pen_pos.gx_point_x =
176 (GX_VALUE)(pen_pos.gx_point_x - root_window -> gx_window_root_canvas -> gx_canvas_display_offset_x);
177 pen_pos.gx_point_y =
178 (GX_VALUE)(pen_pos.gx_point_y - root_window -> gx_window_root_canvas -> gx_canvas_display_offset_y);
179
180 if (!target)
181 {
182 /* find the child of this root under the click position */
183 target = _gx_system_top_widget_find((GX_WIDGET *)root_window, pen_pos, GX_STATUS_SELECTABLE);
184 }
185 }
186
187 /* Was a widget found? */
188 if (target)
189 {
190 out_event.gx_event_payload.gx_event_pointdata = pen_pos;
191 out_event.gx_event_target = target;
192
193 if (out_event.gx_event_type == GX_EVENT_PEN_DOWN)
194 {
195 _gx_system_focus_claim(target);
196 }
197
198 /* Yes, a widget was found, call it's event notification function. */
199 return_code = target -> gx_widget_event_process_function(target, &out_event);
200 }
201 break;
202
203 default:
204 if (_gx_system_focus_owner)
205 {
206 return_code = _gx_system_focus_owner -> gx_widget_event_process_function(
207 _gx_system_focus_owner, &out_event);
208 }
209 break;
210 }
211 }
212 return return_code;
213 }
214
215