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