GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_system_event_dispatch.c Lines: 39 39 100.0 %
Date: 2024-12-05 08:52:37 Branches: 22 24 91.7 %

Line Branch Exec Source
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
/**************************************************************************/
80
74628
UINT  _gx_system_event_dispatch(GX_EVENT *in_event)
81
{
82
83
74628
GX_WIDGET      *target = GX_NULL;
84
74628
GX_WINDOW_ROOT *root_window = GX_NULL;
85
GX_EVENT        out_event;
86
GX_POINT        pen_pos;
87
74628
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
74628
    if (in_event -> gx_event_type == 0)
94
    {
95
1
        return 0;
96
    }
97
98
    /* copy the event to dispatch */
99
74627
    out_event = *in_event;
100
101
    /* is this event targetted to a particular widget? */
102
74627
    if (out_event.gx_event_target)
103
    {
104
35424
        target = out_event.gx_event_target;
105
35424
        return_code = target -> gx_widget_event_process_function(target,  &out_event);
106
    }
107
    else
108
    {
109
39203
        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
23116
        case GX_EVENT_PEN_DOWN:
132
        case GX_EVENT_PEN_UP:
133
        case GX_EVENT_PEN_DRAG:
134
135
            /* get absolute click position */
136
23116
            pen_pos = out_event.gx_event_payload.gx_event_pointdata;
137
138
23116
            if (_gx_system_capture_count > 0)
139
            {
140
                /* Get the widget that owns the system input.  */
141
6384
                target = *_gx_system_input_capture_stack;
142
143
6384
                if (target)
144
                {
145
146
                    /* Find the root window of the widget that owns the system input. */
147
6384
                    root_window = (GX_WINDOW_ROOT *)target -> gx_widget_parent;
148

18048
                    while (root_window && root_window -> gx_widget_parent)
149
                    {
150
11664
                        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
16732
                root_window = _gx_system_top_root_find(&out_event);
158
            }
159
160
23116
            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
23115
                pen_pos.gx_point_x =
175
23115
                    (GX_VALUE)(pen_pos.gx_point_x - root_window -> gx_window_root_canvas -> gx_canvas_display_offset_x);
176
23115
                pen_pos.gx_point_y =
177
23115
                    (GX_VALUE)(pen_pos.gx_point_y - root_window -> gx_window_root_canvas -> gx_canvas_display_offset_y);
178
179
23115
                if (!target)
180
                {
181
                    /* find the child of this root under the click position */
182
16731
                    target = _gx_system_top_widget_find((GX_WIDGET *)root_window, pen_pos, GX_STATUS_SELECTABLE);
183
                }
184
            }
185
186
            /* Was a widget found?  */
187
23116
            if (target)
188
            {
189
15742
                out_event.gx_event_payload.gx_event_pointdata = pen_pos;
190
15742
                out_event.gx_event_target = target;
191
192
15742
                if (out_event.gx_event_type == GX_EVENT_PEN_DOWN)
193
                {
194
7752
                    _gx_system_focus_claim(target);
195
                }
196
197
                /* Yes, a widget was found, call it's event notification function.  */
198
15742
                return_code = target -> gx_widget_event_process_function(target, &out_event);
199
            }
200
23116
            break;
201
202
16087
        default:
203
16087
            if (_gx_system_focus_owner)
204
            {
205
16086
                return_code = _gx_system_focus_owner -> gx_widget_event_process_function(
206
                        _gx_system_focus_owner, &out_event);
207
            }
208
16087
            break;
209
        }
210
    }
211
74626
    return return_code;
212
}
213