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