GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_system_dirty_partial_add.c Lines: 58 58 100.0 %
Date: 2024-12-05 08:52:37 Branches: 38 38 100.0 %

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_utility.h"
29
30
31
/**************************************************************************/
32
/*                                                                        */
33
/*  FUNCTION                                               RELEASE        */
34
/*                                                                        */
35
/*    _gx_system_dirty_partial_add                        PORTABLE C      */
36
/*                                                           6.1          */
37
/*  AUTHOR                                                                */
38
/*                                                                        */
39
/*    Kenneth Maxwell, Microsoft Corporation                              */
40
/*                                                                        */
41
/*  DESCRIPTION                                                           */
42
/*                                                                        */
43
/*    This service marks the partial area of this widget as dirty.        */
44
/*                                                                        */
45
/*  INPUT                                                                 */
46
/*                                                                        */
47
/*    widget                                Pointer to widget control     */
48
/*                                            block                       */
49
/*    dirty_area                            Dirty area of widget to add   */
50
/*                                                                        */
51
/*  OUTPUT                                                                */
52
/*                                                                        */
53
/*    status                                Completion status             */
54
/*                                                                        */
55
/*  CALLS                                                                 */
56
/*                                                                        */
57
/*    GX_ENTER_CRITICAL                     Enter critical section        */
58
/*    _gx_utility_rectangle_overlap_detect  Detect overlapping rectangles */
59
/*    _gx_utility_rectangle_combine         Combine two rectangles        */
60
/*    GX_EXIT_CRITICAL                      Exit critical section         */
61
/*                                                                        */
62
/*  CALLED BY                                                             */
63
/*                                                                        */
64
/*    Application Code                                                    */
65
/*    GUIX Internal Code                                                  */
66
/*                                                                        */
67
/*  RELEASE HISTORY                                                       */
68
/*                                                                        */
69
/*    DATE              NAME                      DESCRIPTION             */
70
/*                                                                        */
71
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
72
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
73
/*                                            resulting in version 6.1    */
74
/*                                                                        */
75
/**************************************************************************/
76
6380
VOID _gx_system_dirty_entry_shift(GX_WIDGET *widget, INT xShift, INT yShift)
77
{
78
UINT            index;
79
GX_DIRTY_AREA  *dirty_entry;
80
GX_WIDGET      *test;
81
GX_WINDOW_ROOT *root;
82
GX_CANVAS      *canvas;
83
84
6380
    if (!widget)
85
    {
86
1
        return;
87
    }
88
6379
    if ((widget -> gx_widget_status & (GX_STATUS_VISIBLE | GX_STATUS_DIRTY)) != (GX_STATUS_VISIBLE | GX_STATUS_DIRTY))
89
    {
90
19
        return;
91
    }
92
93
    /* lock access before linked list update */
94
6360
    GX_ENTER_CRITICAL
95
96
    /* walk up to find root window */
97
6360
    test = widget;
98
99
25448
    while (test -> gx_widget_parent)
100
    {
101
19088
        test = test -> gx_widget_parent;
102
    }
103
104
6360
    if (test -> gx_widget_type != GX_TYPE_ROOT_WINDOW)
105
    {
106
1
        GX_EXIT_CRITICAL
107
1
        return;
108
    }
109
110
6359
    root = (GX_WINDOW_ROOT *)test;
111
112
    /* pick up pointer to canvas */
113
6359
    canvas = root -> gx_window_root_canvas;
114
115
    /* Setup pointer to dirty list.  */
116
117
6359
    dirty_entry = canvas -> gx_canvas_dirty_list;
118
119
    /* Find existing entrie(s)  */
120
27693
    for (index = 0; index < canvas -> gx_canvas_dirty_count; index++)
121
    {
122
21334
        if (dirty_entry -> gx_dirty_area_widget == widget)
123
        {
124
731
            _gx_utility_rectangle_shift(&dirty_entry -> gx_dirty_area_rectangle, (GX_VALUE)xShift, (GX_VALUE)yShift);
125
        }
126
127
        /* Move to next dirty entry.  */
128
21334
        dirty_entry++;
129
    }
130
6359
    GX_EXIT_CRITICAL
131
}
132
133
#ifndef GUIX_STUDIO
134
365689
UINT  _gx_system_dirty_partial_add(GX_WIDGET *widget, GX_RECTANGLE *dirty_area)
135
{
136
137
UINT            index;
138
GX_DIRTY_AREA  *dirty_entry;
139
GX_WIDGET      *test;
140
GX_WINDOW_ROOT *root;
141
GX_CANVAS      *canvas;
142
143
365689
    if (!widget)
144
    {
145
1
        return GX_PTR_ERROR;
146
    }
147
365688
    if (!(widget -> gx_widget_status & GX_STATUS_VISIBLE))
148
    {
149
52347
        return GX_PTR_ERROR;
150
    }
151
152
    /* lock access before linked list update */
153
313341
    GX_ENTER_CRITICAL
154
155
    /* if a widget is transparent, we actually need to mark it's
156
       first non-transparent parent as being dirty
157
     */
158
159
421512
    while(widget -> gx_widget_parent)
160
    {
161
338057
        if (widget -> gx_widget_status & GX_STATUS_TRANSPARENT)
162
        {
163
108171
            widget = widget -> gx_widget_parent;
164
        }
165
        else
166
        {
167
229886
            break;
168
        }
169
    }
170
171
    /* walk up to find root window */
172
313341
    test = widget;
173
174
657555
    while (test -> gx_widget_parent)
175
    {
176
344214
        test = test -> gx_widget_parent;
177
    }
178
179
313341
    if (test -> gx_widget_type != GX_TYPE_ROOT_WINDOW)
180
    {
181
3
        GX_EXIT_CRITICAL
182
3
        return GX_PTR_ERROR;
183
    }
184
185
313338
    root = (GX_WINDOW_ROOT *)test;
186
187
    /* pick up pointer to canvas */
188
313338
    canvas = root -> gx_window_root_canvas;
189
190
    /* if we are running low on dirty-area records, only allow
191
       marking the root as dirty
192
     */
193
313338
    if (canvas -> gx_canvas_dirty_count >= GX_MAX_DIRTY_AREAS - 1)
194
    {
195
2911
        widget = (GX_WIDGET *)root;
196
    }
197
198
    /* Setup pointer to dirty list.  */
199
200
313338
    dirty_entry = canvas -> gx_canvas_dirty_list;
201
202
    /* Check to see if widget already has an entry.  */
203
313338
    if (widget -> gx_widget_status & GX_STATUS_DIRTY)
204
    {
205
227370
        for (index = 0; index < canvas -> gx_canvas_dirty_count; index++)
206
        {
207
            /* Is the same widget is present. */
208
151726
            if (dirty_entry -> gx_dirty_area_widget == widget)
209
            {
210
                /* if rectangles overlap or if we are running low on dirty area,
211
                   records, combine them rather than adding another entry
212
                 */
213

99402
                if (canvas -> gx_canvas_dirty_count >= GX_MAX_DIRTY_AREAS - 1 ||
214
49648
                    _gx_utility_rectangle_overlap_detect(&dirty_entry -> gx_dirty_area_rectangle,
215
                                                         dirty_area, GX_NULL))
216
                {
217
                    /* Combine the dirty rectangles.  */
218
27801
                    _gx_utility_rectangle_combine(&dirty_entry -> gx_dirty_area_rectangle, dirty_area);
219
220
                    /* Return success.  */
221
27801
                    GX_EXIT_CRITICAL
222
27801
                    return(GX_SUCCESS);
223
                }
224
            }
225
226
            /* Move to next dirty entry.  */
227
123925
            dirty_entry++;
228
        }
229
    }
230
231
    /* If we get here, we didn't find an entry for this caller. Add a new entry.  */
232
233
    /* Are there more dirty entries?  */
234
285537
    if (canvas -> gx_canvas_dirty_count < GX_MAX_DIRTY_AREAS)
235
    {
236
        /* Yes, more dirty entries, add this one!  */
237
284137
        dirty_entry = &canvas -> gx_canvas_dirty_list[canvas -> gx_canvas_dirty_count];
238
284137
        canvas -> gx_canvas_dirty_count++;
239
284137
        dirty_entry -> gx_dirty_area_widget =    widget;
240
284137
        dirty_entry -> gx_dirty_area_rectangle = *dirty_area;
241
284137
        widget -> gx_widget_status |= GX_STATUS_DIRTY;
242
    }
243
244
    /* end of critical section */
245
285537
    GX_EXIT_CRITICAL
246
247
    /* Return success. */
248
285537
    return(GX_SUCCESS);
249
}
250
251
#endif
252