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 /** Window Management (Window) */
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_widget.h"
29 #include "gx_window.h"
30 #include "gx_utility.h"
31
32
33 /**************************************************************************/
34 /* */
35 /* FUNCTION RELEASE */
36 /* */
37 /* _gx_window_event_process PORTABLE C */
38 /* 6.1 */
39 /* AUTHOR */
40 /* */
41 /* Kenneth Maxwell, Microsoft Corporation */
42 /* */
43 /* DESCRIPTION */
44 /* */
45 /* This function processes events for the specified window. */
46 /* */
47 /* INPUT */
48 /* */
49 /* window Window's widget control block */
50 /* event_ptr Incoming event to process */
51 /* */
52 /* OUTPUT */
53 /* */
54 /* status Completion status */
55 /* */
56 /* CALLS */
57 /* */
58 /* _gx_widget_shift Shift a widget */
59 /* _gx_window_view_update_detect Detect changes to the window */
60 /* viewport */
61 /* _gx_widget_event_process Call widget event processing */
62 /* _gx_window_cilent_scroll Scroll window client area */
63 /* _gx_widget_front_move Move window to front */
64 /* */
65 /* CALLED BY */
66 /* */
67 /* Application Code */
68 /* GUIX Internal Code */
69 /* */
70 /* RELEASE HISTORY */
71 /* */
72 /* DATE NAME DESCRIPTION */
73 /* */
74 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
75 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
76 /* resulting in version 6.1 */
77 /* */
78 /**************************************************************************/
_gx_window_event_process(GX_WINDOW * window,GX_EVENT * event_ptr)79 UINT _gx_window_event_process(GX_WINDOW *window, GX_EVENT *event_ptr)
80 {
81
82 UINT status;
83 GX_WIDGET *widget;
84 GX_WIDGET *parent;
85 GX_VALUE xShift;
86 GX_VALUE yShift;
87
88 status = GX_SUCCESS;
89 widget = (GX_WIDGET *)window;
90
91 /* Process relative to the type of event. */
92 switch (event_ptr -> gx_event_type)
93 {
94 case GX_EVENT_PEN_DOWN:
95 /* if this window is moveable, go into move mode */
96 if (window -> gx_widget_status & GX_STATUS_MOVABLE)
97 {
98 window -> gx_window_move_mode = GX_TRUE;
99 window -> gx_window_move_start = event_ptr -> gx_event_payload.gx_event_pointdata;
100 /* Return successful status. */
101 return(GX_SUCCESS);
102 }
103 else
104 {
105 status = _gx_widget_event_process(widget, event_ptr);
106 }
107 break;
108
109 case GX_EVENT_PEN_DRAG:
110 if (window -> gx_window_move_mode)
111 {
112 xShift = (GX_VALUE)(event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_x -
113 window -> gx_window_move_start.gx_point_x);
114 yShift = (GX_VALUE)(event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_y -
115 window -> gx_window_move_start.gx_point_y);
116
117 window -> gx_window_move_start = event_ptr -> gx_event_payload.gx_event_pointdata;
118
119 _gx_widget_shift(widget, xShift, yShift, GX_TRUE);
120 }
121 else
122 {
123 status = _gx_widget_event_process(widget, event_ptr);
124 }
125 return(status);
126
127 case GX_EVENT_PEN_UP:
128 if (window -> gx_window_move_mode)
129 {
130 window -> gx_window_move_mode = GX_FALSE;
131 }
132 else
133 {
134 status = _gx_widget_event_process(widget, event_ptr);
135 }
136 break;
137
138 case GX_EVENT_FOCUS_GAINED:
139 /* first do default handling */
140
141 if (widget -> gx_widget_status & GX_STATUS_ACCEPTS_FOCUS)
142 {
143 _gx_widget_event_process(widget, event_ptr);
144
145 /* If this window owns focus, try to assign focus to client child */
146 if (_gx_system_focus_owner == GX_NULL ||
147 _gx_system_focus_owner == widget)
148 {
149 _gx_widget_child_focus_assign(widget);
150 }
151
152 /* Now move window to front. */
153 if (window -> gx_widget_type != GX_TYPE_ROOT_WINDOW)
154 {
155 if (_gx_widget_front_move(widget, GX_NULL) != GX_NO_CHANGE)
156 {
157 /* if I am a top-level window and I moved in front, then
158 the viewport lists need to be updated.
159 */
160 _gx_window_view_update_detect(window);
161 }
162 }
163 }
164 break;
165
166 case GX_EVENT_HIDE:
167 /* do the default handling */
168 status = _gx_widget_event_process(widget, event_ptr);
169
170 /* if this window is child of root, viewports must be updated */
171 _gx_window_view_update_detect(window);
172 break;
173
174 case GX_EVENT_CLOSE:
175 _gx_widget_detach(widget);
176 return GX_EVENT_CLOSE;
177
178 case GX_EVENT_SHOW:
179 /* do the default handling */
180 status = _gx_widget_event_process(widget, event_ptr);
181
182 _gx_widget_nav_order_initialize(widget);
183
184 /* if this window is child of root, viewports must be updated */
185 _gx_window_view_update_detect(window);
186
187 /* if this window is in front, claim focus */
188 if (widget -> gx_widget_type != GX_TYPE_ROOT_WINDOW &&
189 !(widget -> gx_widget_status & GX_STATUS_HAS_FOCUS))
190 {
191 parent = widget;
192 while (parent && widget -> gx_widget_next == GX_NULL)
193 {
194 parent = widget -> gx_widget_parent;
195
196 if (parent)
197 {
198 if (parent -> gx_widget_type == GX_TYPE_ROOT_WINDOW)
199 {
200 _gx_system_focus_claim((GX_WIDGET *)window);
201 break;
202 }
203 widget = parent;
204 parent = widget -> gx_widget_parent;
205 }
206 }
207 }
208
209 break;
210
211 case GX_EVENT_VERTICAL_SCROLL:
212 _gx_window_scroll(window, 0, (GX_VALUE)(event_ptr -> gx_event_payload.gx_event_intdata[1] - event_ptr -> gx_event_payload.gx_event_intdata[0]));
213 break;
214
215 case GX_EVENT_HORIZONTAL_SCROLL:
216 _gx_window_scroll(window, (GX_VALUE)(event_ptr -> gx_event_payload.gx_event_intdata[1] - event_ptr -> gx_event_payload.gx_event_intdata[0]), 0);
217 break;
218
219 default:
220
221 /* Call the widget default processing. */
222 status = _gx_widget_event_process(widget, event_ptr);
223 }
224 /* Return widget event processing status. */
225 return(status);
226 }
227
228