Bug Summary

File:ctk/ctkcssnode.c
Warning:line 187, column 1
Potential memory leak

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ctkcssnode.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/ctk -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -D G_LOG_DOMAIN="Ctk" -D G_LOG_USE_STRUCTURED=1 -D CTK_VERSION="3.25.5" -D CTK_BINARY_VERSION="3.0.0" -D CTK_COMPILATION -D CTK_PRINT_BACKEND_ENABLE_UNSUPPORTED -D CTK_LIBDIR="/usr/lib" -D CTK_LOCALEDIR="/usr/share/locale" -D CTK_DATADIR="/usr/share" -D CTK_DATA_PREFIX="/usr" -D CTK_SYSCONFDIR="/usr/etc" -D CTK_HOST="x86_64-pc-linux-gnu" -D CTK_PRINT_BACKENDS="file,cups" -D X11_DATA_PREFIX="/usr" -D ISO_CODES_PREFIX="" -I .. -I ../ctk -I .. -I ../cdk -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -D G_ENABLE_DEBUG -D G_ENABLE_CONSISTENCY_CHECKS -D GLIB_MIN_REQUIRED_VERSION=GLIB_VERSION_2_66 -D GLIB_MAX_ALLOWED_VERSION=GLIB_VERSION_2_66 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/atk-1.0 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/gio-unix-2.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/pango-1.0 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/ctk -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-09-19-172241-43638-1 -x c ctkcssnode.c
1/* CTK - The GIMP Toolkit
2 * Copyright (C) 2014 Benjamin Otte <otte@gnome.org>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "config.h"
19
20#include "ctkcssnodeprivate.h"
21
22#include "ctkcssanimatedstyleprivate.h"
23#include "ctkcsssectionprivate.h"
24#include "ctkcssstylepropertyprivate.h"
25#include "ctkintl.h"
26#include "ctkmarshalers.h"
27#include "ctksettingsprivate.h"
28#include "ctktypebuiltins.h"
29
30/*
31 * CSS nodes are the backbone of the CtkStyleContext implementation and
32 * replace the role that CtkWidgetPath played in the past. A CSS node has
33 * an element name and a state, and can have an id and style classes, which
34 * is what is needed to determine the matching CSS selectors. CSS nodes have
35 * a 'visible' property, which makes it possible to temporarily 'hide' them
36 * from CSS matching - e.g. an invisible node will not affect :nth-child
37 * matching and so forth.
38 *
39 * The API to manage states, names, ids and classes of CSS nodes is:
40 * - ctk_css_node_get/set_state. States are represented as CtkStateFlags
41 * - ctk_css_node_get/set_name. Names are represented as interned strings
42 * - ctk_css_node_get/set_id. Ids are represented as interned strings
43 * - ctk_css_node_add/remove/has_class and ctk_css_node_list_classes. Style
44 * classes are represented as quarks.
45 *
46 * CSS nodes are organized in a dom-like tree, and there is API to navigate
47 * and manipulate this tree:
48 * - ctk_css_node_set_parent
49 * - ctk_css_node_insert_before/after
50 * - ctk_css_node_get_parent
51 * - ctk_css_node_get_first/last_child
52 * - ctk_css_node_get_previous/next_sibling
53 * Note that parents keep a reference on their children in this tree.
54 *
55 * Every widget has one or more CSS nodes - the first one gets created
56 * automatically by CtkStyleContext. To set the name of the main node,
57 * call ctk_widget_class_set_css_name() in class_init(). Widget implementations
58 * can and should add subnodes as suitable.
59 *
60 * Best practice is:
61 * - For permanent subnodes, create them in init(), and keep a pointer
62 * to the node (you don't have to keep a reference, cleanup will be
63 * automatic by means of the parent node getting cleaned up by the
64 * style context).
65 * - For transient nodes, create/destroy them when the conditions that
66 * warrant their existence change.
67 * - Keep the state of all your nodes up-to-date. This probably requires
68 * a ::state-flags-changed (and possibly ::direction-changed) handler,
69 * as well as code to update the state in other places. Note that CTK+
70 * does this automatically for the widget's main CSS node.
71 * - The sibling ordering in the CSS node tree is supposed to correspond
72 * to the visible order of content: top-to-bottom and left-to-right.
73 * Reorder your nodes to maintain this correlation. In particular for
74 * horizontally layed out widgets, this will require listening to
75 * ::direction-changed.
76 * - The draw function should just use ctk_style_context_save_to_node() to
77 * 'switch' to the right node, not make any other changes to the style
78 * context.
79 *
80 * A noteworthy difference between ctk_style_context_save() and
81 * ctk_style_context_save_to_node() is that the former inherits all the
82 * style classes from the main CSS node, which often leads to unintended
83 * inheritance.
84 */
85
86/* When these change we do a full restyling. Otherwise we try to figure out
87 * if we need to change things. */
88#define CTK_CSS_RADICAL_CHANGE((1ULL << 2) | (1ULL << 1) | (1ULL << 0) | (
1ULL << 32) | (1ULL << 33))
(CTK_CSS_CHANGE_ID(1ULL << 2) | CTK_CSS_CHANGE_NAME(1ULL << 1) | CTK_CSS_CHANGE_CLASS(1ULL << 0) | CTK_CSS_CHANGE_SOURCE(1ULL << 32) | CTK_CSS_CHANGE_PARENT_STYLE(1ULL << 33))
89
90G_DEFINE_TYPE (CtkCssNode, ctk_css_node, G_TYPE_OBJECT)static void ctk_css_node_init (CtkCssNode *self); static void
ctk_css_node_class_init (CtkCssNodeClass *klass); static GType
ctk_css_node_get_type_once (void); static gpointer ctk_css_node_parent_class
= ((void*)0); static gint CtkCssNode_private_offset; static void
ctk_css_node_class_intern_init (gpointer klass) { ctk_css_node_parent_class
= g_type_class_peek_parent (klass); if (CtkCssNode_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CtkCssNode_private_offset
); ctk_css_node_class_init ((CtkCssNodeClass*) klass); } __attribute__
((__unused__)) static inline gpointer ctk_css_node_get_instance_private
(CtkCssNode *self) { return (((gpointer) ((guint8*) (self) +
(glong) (CtkCssNode_private_offset)))); } GType ctk_css_node_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_css_node_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_css_node_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
(GType) ((20) << (2))), g_intern_static_string ("CtkCssNode"
), sizeof (CtkCssNodeClass), (GClassInitFunc)(void (*)(void))
ctk_css_node_class_intern_init, sizeof (CtkCssNode), (GInstanceInitFunc
)(void (*)(void)) ctk_css_node_init, (GTypeFlags) 0); { {{};}
} return g_define_type_id; }
91
92enum {
93 NODE_ADDED,
94 NODE_REMOVED,
95 STYLE_CHANGED,
96 LAST_SIGNAL
97};
98
99enum {
100 PROP_0,
101 PROP_CLASSES,
102 PROP_ID,
103 PROP_NAME,
104 PROP_STATE,
105 PROP_VISIBLE,
106 PROP_WIDGET_TYPE,
107 NUM_PROPERTIES
108};
109
110struct _CtkCssNodeStyleChange {
111 CtkCssStyle *old_style;
112 CtkCssStyle *new_style;
113};
114
115static guint cssnode_signals[LAST_SIGNAL] = { 0 };
116static GParamSpec *cssnode_properties[NUM_PROPERTIES];
117
118static CtkStyleProviderPrivate *
119ctk_css_node_get_style_provider_or_null (CtkCssNode *cssnode)
120{
121 return CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class
))))
->get_style_provider (cssnode);
122}
123
124static void
125ctk_css_node_set_invalid (CtkCssNode *node,
126 gboolean invalid)
127{
128 if (node->invalid == invalid)
129 return;
130
131 node->invalid = invalid;
132
133 if (node->visible)
134 {
135 if (node->parent)
136 {
137 if (invalid)
138 ctk_css_node_set_invalid (node->parent, TRUE(!(0)));
139 }
140 else
141 {
142 if (invalid)
143 CTK_CSS_NODE_GET_CLASS (node)((((CtkCssNodeClass*) (((GTypeInstance*) ((node)))->g_class
))))
->queue_validate (node);
144 else
145 CTK_CSS_NODE_GET_CLASS (node)((((CtkCssNodeClass*) (((GTypeInstance*) ((node)))->g_class
))))
->dequeue_validate (node);
146 }
147 }
148}
149
150static void
151ctk_css_node_get_property (GObject *object,
152 guint property_id,
153 GValue *value,
154 GParamSpec *pspec)
155{
156 CtkCssNode *cssnode = CTK_CSS_NODE (object)((((CtkCssNode*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (object), ((ctk_css_node_get_type ()))))))
;
157
158 switch (property_id)
1
Control jumps to 'case PROP_CLASSES:' at line 160
159 {
160 case PROP_CLASSES:
161 g_value_take_boxed (value, ctk_css_node_get_classes (cssnode));
2
Calling 'ctk_css_node_get_classes'
6
Returned allocated memory
162 break;
7
Execution continues on line 155
163
164 case PROP_ID:
165 g_value_set_string (value, ctk_css_node_get_id (cssnode));
166 break;
167
168 case PROP_NAME:
169 g_value_set_string (value, ctk_css_node_get_name (cssnode));
170 break;
171
172 case PROP_STATE:
173 g_value_set_flags (value, ctk_css_node_get_state (cssnode));
174 break;
175
176 case PROP_VISIBLE:
177 g_value_set_boolean (value, ctk_css_node_get_visible (cssnode));
178 break;
179
180 case PROP_WIDGET_TYPE:
181 g_value_set_gtype (value, ctk_css_node_get_widget_type (cssnode));
182 break;
183
184 default:
185 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((property_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "ctkcssnode.c", 185, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
186 }
187}
8
Potential memory leak
188
189static void
190ctk_css_node_set_property (GObject *object,
191 guint property_id,
192 const GValue *value,
193 GParamSpec *pspec)
194{
195 CtkCssNode *cssnode = CTK_CSS_NODE (object)((((CtkCssNode*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (object), ((ctk_css_node_get_type ()))))))
;
196
197 switch (property_id)
198 {
199 case PROP_CLASSES:
200 ctk_css_node_set_classes (cssnode, g_value_get_boxed (value));
201 break;
202
203 case PROP_ID:
204 ctk_css_node_set_id (cssnode, g_value_get_string (value));
205 break;
206
207 case PROP_NAME:
208 ctk_css_node_set_name (cssnode, g_value_get_string (value));
209 break;
210
211 case PROP_STATE:
212 ctk_css_node_set_state (cssnode, g_value_get_flags (value));
213 break;
214
215 case PROP_VISIBLE:
216 ctk_css_node_set_visible (cssnode, g_value_get_boolean (value));
217 break;
218
219 case PROP_WIDGET_TYPE:
220 ctk_css_node_set_widget_type (cssnode, g_value_get_gtype (value));
221 break;
222
223 default:
224 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((property_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "ctkcssnode.c", 224, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
225 }
226}
227
228static void
229ctk_css_node_dispose (GObject *object)
230{
231 CtkCssNode *cssnode = CTK_CSS_NODE (object)((((CtkCssNode*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (object), ((ctk_css_node_get_type ()))))))
;
232
233 while (cssnode->first_child)
234 {
235 ctk_css_node_set_parent (cssnode->first_child, NULL((void*)0));
236 }
237
238 ctk_css_node_set_invalid (cssnode, FALSE(0));
239
240 g_clear_pointer (&cssnode->cache, ctk_css_node_style_cache_unref)do { _Static_assert (sizeof *(&cssnode->cache) == sizeof
(gpointer), "Expression evaluates to false"); __typeof__ ((&
cssnode->cache)) _pp = (&cssnode->cache); __typeof__
(*(&cssnode->cache)) _ptr = *_pp; *_pp = ((void*)0); if
(_ptr) (ctk_css_node_style_cache_unref) (_ptr); } while (0)
;
241
242 G_OBJECT_CLASS (ctk_css_node_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_css_node_parent_class)), (((GType) ((20) << (2
))))))))
->dispose (object);
243}
244
245static void
246ctk_css_node_finalize (GObject *object)
247{
248 CtkCssNode *cssnode = CTK_CSS_NODE (object)((((CtkCssNode*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (object), ((ctk_css_node_get_type ()))))))
;
249
250 if (cssnode->style)
251 g_object_unref (cssnode->style);
252 ctk_css_node_declaration_unref (cssnode->decl);
253
254 G_OBJECT_CLASS (ctk_css_node_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_css_node_parent_class)), (((GType) ((20) << (2
))))))))
->finalize (object);
255}
256
257static gboolean
258ctk_css_node_is_first_child (CtkCssNode *node)
259{
260 CtkCssNode *iter;
261
262 for (iter = node->previous_sibling;
263 iter != NULL((void*)0);
264 iter = iter->previous_sibling)
265 {
266 if (iter->visible)
267 return FALSE(0);
268 }
269 return TRUE(!(0));
270}
271
272static gboolean
273ctk_css_node_is_last_child (CtkCssNode *node)
274{
275 CtkCssNode *iter;
276
277 for (iter = node->next_sibling;
278 iter != NULL((void*)0);
279 iter = iter->next_sibling)
280 {
281 if (iter->visible)
282 return FALSE(0);
283 }
284 return TRUE(!(0));
285}
286
287static gboolean
288may_use_global_parent_cache (CtkCssNode *node)
289{
290 CtkStyleProviderPrivate *provider;
291 CtkCssNode *parent;
292
293 parent = ctk_css_node_get_parent (node);
294 if (parent == NULL((void*)0))
295 return FALSE(0);
296
297 provider = ctk_css_node_get_style_provider_or_null (node);
298 if (provider != NULL((void*)0) && provider != ctk_css_node_get_style_provider (parent))
299 return FALSE(0);
300
301 return TRUE(!(0));
302}
303
304static CtkCssStyle *
305lookup_in_global_parent_cache (CtkCssNode *node,
306 const CtkCssNodeDeclaration *decl)
307{
308 CtkCssNode *parent;
309
310 parent = node->parent;
311
312 if (parent == NULL((void*)0) ||
313 !may_use_global_parent_cache (node))
314 return NULL((void*)0);
315
316 if (parent->cache == NULL((void*)0))
317 return NULL((void*)0);
318
319 g_assert (node->cache == NULL)do { if (node->cache == ((void*)0)) ; else g_assertion_message_expr
("Ctk", "ctkcssnode.c", 319, ((const char*) (__func__)), "node->cache == NULL"
); } while (0)
;
320 node->cache = ctk_css_node_style_cache_lookup (parent->cache,
321 decl,
322 ctk_css_node_is_first_child (node),
323 ctk_css_node_is_last_child (node));
324 if (node->cache == NULL((void*)0))
325 return NULL((void*)0);
326
327 return ctk_css_node_style_cache_get_style (node->cache);
328}
329
330static void
331store_in_global_parent_cache (CtkCssNode *node,
332 const CtkCssNodeDeclaration *decl,
333 CtkCssStyle *style)
334{
335 CtkCssNode *parent;
336
337 g_assert (CTK_IS_CSS_STATIC_STYLE (style))do { if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) (style); GType __t = ((ctk_css_static_style_get_type ()));
gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
))))) ; else g_assertion_message_expr ("Ctk", "ctkcssnode.c",
337, ((const char*) (__func__)), "CTK_IS_CSS_STATIC_STYLE (style)"
); } while (0)
;
338
339 parent = node->parent;
340
341 if (parent == NULL((void*)0) ||
342 !may_use_global_parent_cache (node))
343 return;
344
345 if (parent->cache == NULL((void*)0))
346 parent->cache = ctk_css_node_style_cache_new (parent->style);
347
348 node->cache = ctk_css_node_style_cache_insert (parent->cache,
349 (CtkCssNodeDeclaration *) decl,
350 ctk_css_node_is_first_child (node),
351 ctk_css_node_is_last_child (node),
352 style);
353}
354
355static CtkCssStyle *
356ctk_css_node_create_style (CtkCssNode *cssnode)
357{
358 const CtkCssNodeDeclaration *decl;
359 CtkCssMatcher matcher;
360 CtkCssStyle *parent;
361 CtkCssStyle *style;
362
363 decl = ctk_css_node_get_declaration (cssnode);
364 parent = cssnode->parent ? cssnode->parent->style : NULL((void*)0);
365
366 style = lookup_in_global_parent_cache (cssnode, decl);
367 if (style)
368 return g_object_ref (style)((__typeof__ (style)) (g_object_ref) (style));
369
370 if (ctk_css_node_init_matcher (cssnode, &matcher))
371 style = ctk_css_static_style_new_compute (ctk_css_node_get_style_provider (cssnode),
372 &matcher,
373 parent);
374 else
375 style = ctk_css_static_style_new_compute (ctk_css_node_get_style_provider (cssnode),
376 NULL((void*)0),
377 parent);
378
379 store_in_global_parent_cache (cssnode, decl, style);
380
381 return style;
382}
383
384static gboolean
385should_create_transitions (CtkCssChange change)
386{
387 return (change & CTK_CSS_CHANGE_ANIMATIONS(1ULL << 35)) == 0;
388}
389
390static gboolean
391ctk_css_style_needs_recreation (CtkCssStyle *style,
392 CtkCssChange change)
393{
394 /* Try to avoid invalidating if we can */
395 if (change & CTK_CSS_RADICAL_CHANGE((1ULL << 2) | (1ULL << 1) | (1ULL << 0) | (
1ULL << 32) | (1ULL << 33))
)
396 return TRUE(!(0));
397
398 if (CTK_IS_CSS_ANIMATED_STYLE (style)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
style); GType __t = ((ctk_css_animated_style_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
399 style = CTK_CSS_ANIMATED_STYLE (style)((((CtkCssAnimatedStyle*) (void *) g_type_check_instance_cast
((GTypeInstance*) (style), ((ctk_css_animated_style_get_type
()))))))
->style;
400
401 if (ctk_css_static_style_get_change (CTK_CSS_STATIC_STYLE (style)((((CtkCssStaticStyle*) (void *) g_type_check_instance_cast (
(GTypeInstance*) (style), ((ctk_css_static_style_get_type ())
)))))
) & change)
402 return TRUE(!(0));
403 else
404 return FALSE(0);
405}
406
407static CtkCssStyle *
408ctk_css_node_real_update_style (CtkCssNode *cssnode,
409 CtkCssChange change,
410 gint64 timestamp,
411 CtkCssStyle *style)
412{
413 CtkCssStyle *static_style, *new_static_style, *new_style;
414
415 if (CTK_IS_CSS_ANIMATED_STYLE (style)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
style); GType __t = ((ctk_css_animated_style_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
416 {
417 static_style = CTK_CSS_ANIMATED_STYLE (style)((((CtkCssAnimatedStyle*) (void *) g_type_check_instance_cast
((GTypeInstance*) (style), ((ctk_css_animated_style_get_type
()))))))
->style;
418 }
419 else
420 {
421 static_style = style;
422 }
423
424 if (ctk_css_style_needs_recreation (static_style, change))
425 new_static_style = ctk_css_node_create_style (cssnode);
426 else
427 new_static_style = g_object_ref (static_style)((__typeof__ (static_style)) (g_object_ref) (static_style));
428
429 if (new_static_style != static_style || (change & CTK_CSS_CHANGE_ANIMATIONS(1ULL << 35)))
430 {
431 CtkCssNode *parent = ctk_css_node_get_parent (cssnode);
432 new_style = ctk_css_animated_style_new (new_static_style,
433 parent ? ctk_css_node_get_style (parent) : NULL((void*)0),
434 timestamp,
435 ctk_css_node_get_style_provider (cssnode),
436 should_create_transitions (change) ? style : NULL((void*)0));
437
438 /* Clear the cache again, the static style we looked up above
439 * may have populated it. */
440 g_clear_pointer (&cssnode->cache, ctk_css_node_style_cache_unref)do { _Static_assert (sizeof *(&cssnode->cache) == sizeof
(gpointer), "Expression evaluates to false"); __typeof__ ((&
cssnode->cache)) _pp = (&cssnode->cache); __typeof__
(*(&cssnode->cache)) _ptr = *_pp; *_pp = ((void*)0); if
(_ptr) (ctk_css_node_style_cache_unref) (_ptr); } while (0)
;
441 }
442 else if (static_style != style && (change & CTK_CSS_CHANGE_TIMESTAMP(1ULL << 34)))
443 {
444 new_style = ctk_css_animated_style_new_advance (CTK_CSS_ANIMATED_STYLE (style)((((CtkCssAnimatedStyle*) (void *) g_type_check_instance_cast
((GTypeInstance*) (style), ((ctk_css_animated_style_get_type
()))))))
,
445 static_style,
446 timestamp);
447 }
448 else
449 {
450 new_style = g_object_ref (style)((__typeof__ (style)) (g_object_ref) (style));
451 }
452
453 if (!ctk_css_style_is_static (new_style))
454 ctk_css_node_set_invalid (cssnode, TRUE(!(0)));
455
456 g_object_unref (new_static_style);
457
458 return new_style;
459}
460
461static void
462ctk_css_node_real_invalidate (CtkCssNode *node G_GNUC_UNUSED__attribute__ ((__unused__)))
463{
464}
465
466static void
467ctk_css_node_real_queue_validate (CtkCssNode *node G_GNUC_UNUSED__attribute__ ((__unused__)))
468{
469}
470
471static void
472ctk_css_node_real_dequeue_validate (CtkCssNode *node G_GNUC_UNUSED__attribute__ ((__unused__)))
473{
474}
475
476static void
477ctk_css_node_real_validate (CtkCssNode *node G_GNUC_UNUSED__attribute__ ((__unused__)))
478{
479}
480
481gboolean
482ctk_css_node_real_init_matcher (CtkCssNode *cssnode,
483 CtkCssMatcher *matcher)
484{
485 _ctk_css_matcher_node_init (matcher, cssnode);
486
487 return TRUE(!(0));
488}
489
490static CtkWidgetPath *
491ctk_css_node_real_create_widget_path (CtkCssNode *cssnode G_GNUC_UNUSED__attribute__ ((__unused__)))
492{
493 return ctk_widget_path_new ();
494}
495
496static const CtkWidgetPath *
497ctk_css_node_real_get_widget_path (CtkCssNode *cssnode G_GNUC_UNUSED__attribute__ ((__unused__)))
498{
499 return NULL((void*)0);
500}
501
502static CtkStyleProviderPrivate *
503ctk_css_node_real_get_style_provider (CtkCssNode *cssnode G_GNUC_UNUSED__attribute__ ((__unused__)))
504{
505 return NULL((void*)0);
506}
507
508static CdkFrameClock *
509ctk_css_node_real_get_frame_clock (CtkCssNode *cssnode G_GNUC_UNUSED__attribute__ ((__unused__)))
510{
511 return NULL((void*)0);
512}
513
514static void
515ctk_css_node_real_node_removed (CtkCssNode *parent G_GNUC_UNUSED__attribute__ ((__unused__)),
516 CtkCssNode *node,
517 CtkCssNode *previous G_GNUC_UNUSED__attribute__ ((__unused__)))
518{
519 if (node->previous_sibling)
520 node->previous_sibling->next_sibling = node->next_sibling;
521 else
522 node->parent->first_child = node->next_sibling;
523
524 if (node->next_sibling)
525 node->next_sibling->previous_sibling = node->previous_sibling;
526 else
527 node->parent->last_child = node->previous_sibling;
528
529 node->previous_sibling = NULL((void*)0);
530 node->next_sibling = NULL((void*)0);
531 node->parent = NULL((void*)0);
532}
533
534static void
535ctk_css_node_real_node_added (CtkCssNode *parent,
536 CtkCssNode *node,
537 CtkCssNode *new_previous)
538{
539 if (new_previous)
540 {
541 node->previous_sibling = new_previous;
542 node->next_sibling = new_previous->next_sibling;
543 new_previous->next_sibling = node;
544 }
545 else
546 {
547 node->next_sibling = parent->first_child;
548 parent->first_child = node;
549 }
550
551 if (node->next_sibling)
552 node->next_sibling->previous_sibling = node;
553 else
554 parent->last_child = node;
555
556 node->parent = parent;
557}
558
559static void
560ctk_css_node_real_style_changed (CtkCssNode *cssnode,
561 CtkCssStyleChange *change)
562{
563 g_set_object (&cssnode->style, ctk_css_style_change_get_new_style (change))(__extension__ ({ _Static_assert (sizeof *(&cssnode->style
) == sizeof (ctk_css_style_change_get_new_style (change)), "Expression evaluates to false"
); union { char *in; GObject **out; } _object_ptr; _object_ptr
.in = (char *) (&cssnode->style); (void) (0 ? *(&cssnode
->style) = (ctk_css_style_change_get_new_style (change)), (
0) : (0)); (g_set_object) (_object_ptr.out, (GObject *) ctk_css_style_change_get_new_style
(change)); }))
;
564}
565
566static void
567ctk_css_node_class_init (CtkCssNodeClass *klass)
568{
569 GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
570
571 object_class->get_property = ctk_css_node_get_property;
572 object_class->set_property = ctk_css_node_set_property;
573 object_class->dispose = ctk_css_node_dispose;
574 object_class->finalize = ctk_css_node_finalize;
575
576 klass->update_style = ctk_css_node_real_update_style;
577 klass->invalidate = ctk_css_node_real_invalidate;
578 klass->validate = ctk_css_node_real_validate;
579 klass->queue_validate = ctk_css_node_real_queue_validate;
580 klass->dequeue_validate = ctk_css_node_real_dequeue_validate;
581 klass->init_matcher = ctk_css_node_real_init_matcher;
582 klass->create_widget_path = ctk_css_node_real_create_widget_path;
583 klass->get_widget_path = ctk_css_node_real_get_widget_path;
584 klass->get_style_provider = ctk_css_node_real_get_style_provider;
585 klass->get_frame_clock = ctk_css_node_real_get_frame_clock;
586
587 klass->node_added = ctk_css_node_real_node_added;
588 klass->node_removed = ctk_css_node_real_node_removed;
589 klass->style_changed = ctk_css_node_real_style_changed;
590
591 cssnode_signals[NODE_ADDED] =
592 g_signal_new (I_("node-added")g_intern_static_string ("node-added"),
593 G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type),
594 G_SIGNAL_RUN_LAST,
595 G_STRUCT_OFFSET (CtkCssNodeClass, node_added)((glong) __builtin_offsetof(CtkCssNodeClass, node_added)),
596 NULL((void*)0), NULL((void*)0),
597 _ctk_marshal_VOID__OBJECT_OBJECT,
598 G_TYPE_NONE((GType) ((1) << (2))), 2,
599 CTK_TYPE_CSS_NODE(ctk_css_node_get_type ()), CTK_TYPE_CSS_NODE(ctk_css_node_get_type ()));
600 g_signal_set_va_marshaller (cssnode_signals[NODE_ADDED],
601 G_TYPE_FROM_CLASS (klass)(((GTypeClass*) (klass))->g_type),
602 _ctk_marshal_VOID__OBJECT_OBJECTv);
603
604 cssnode_signals[NODE_REMOVED] =
605 g_signal_new (I_("node-removed")g_intern_static_string ("node-removed"),
606 G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type),
607 G_SIGNAL_RUN_LAST,
608 G_STRUCT_OFFSET (CtkCssNodeClass, node_removed)((glong) __builtin_offsetof(CtkCssNodeClass, node_removed)),
609 NULL((void*)0), NULL((void*)0),
610 _ctk_marshal_VOID__OBJECT_OBJECT,
611 G_TYPE_NONE((GType) ((1) << (2))), 2,
612 CTK_TYPE_CSS_NODE(ctk_css_node_get_type ()), CTK_TYPE_CSS_NODE(ctk_css_node_get_type ()));
613 g_signal_set_va_marshaller (cssnode_signals[NODE_REMOVED],
614 G_TYPE_FROM_CLASS (klass)(((GTypeClass*) (klass))->g_type),
615 _ctk_marshal_VOID__OBJECT_OBJECTv);
616
617 cssnode_signals[STYLE_CHANGED] =
618 g_signal_new (I_("style-changed")g_intern_static_string ("style-changed"),
619 G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type),
620 G_SIGNAL_RUN_LAST,
621 G_STRUCT_OFFSET (CtkCssNodeClass, style_changed)((glong) __builtin_offsetof(CtkCssNodeClass, style_changed)),
622 NULL((void*)0), NULL((void*)0),
623 NULL((void*)0),
624 G_TYPE_NONE((GType) ((1) << (2))), 1,
625 G_TYPE_POINTER((GType) ((17) << (2))));
626
627 cssnode_properties[PROP_CLASSES] =
628 g_param_spec_boxed ("classes", P_("Style Classes")g_dgettext("ctk30" "-properties","Style Classes"), P_("List of classes")g_dgettext("ctk30" "-properties","List of classes"),
629 G_TYPE_STRV(g_strv_get_type ()),
630 G_PARAM_READWRITE
631 | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
)
);
632 cssnode_properties[PROP_ID] =
633 g_param_spec_string ("id", P_("ID")g_dgettext("ctk30" "-properties","ID"), P_("Unique ID")g_dgettext("ctk30" "-properties","Unique ID"),
634 NULL((void*)0),
635 G_PARAM_READWRITE
636 | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
)
);
637 cssnode_properties[PROP_NAME] =
638 g_param_spec_string ("name", P_("Name")g_dgettext("ctk30" "-properties","Name"), "Name identifying the type of node",
639 NULL((void*)0),
640 G_PARAM_READWRITE
641 | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
)
);
642 cssnode_properties[PROP_STATE] =
643 g_param_spec_flags ("state", P_("State")g_dgettext("ctk30" "-properties","State"), P_("State flags")g_dgettext("ctk30" "-properties","State flags"),
644 CTK_TYPE_STATE_FLAGS(ctk_state_flags_get_type ()),
645 0,
646 G_PARAM_READWRITE
647 | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
)
);
648 cssnode_properties[PROP_VISIBLE] =
649 g_param_spec_boolean ("visible", P_("Visible")g_dgettext("ctk30" "-properties","Visible"), P_("If other nodes can see this node")g_dgettext("ctk30" "-properties","If other nodes can see this node"
)
,
650 TRUE(!(0)),
651 G_PARAM_READWRITE
652 | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
)
);
653 cssnode_properties[PROP_WIDGET_TYPE] =
654 g_param_spec_gtype ("widget-type", P_("Widget type")g_dgettext("ctk30" "-properties","Widget type"), P_("GType of the widget")g_dgettext("ctk30" "-properties","GType of the widget"),
655 G_TYPE_NONE((GType) ((1) << (2))),
656 G_PARAM_READWRITE
657 | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
)
);
658
659 g_object_class_install_properties (object_class, NUM_PROPERTIES, cssnode_properties);
660}
661
662static void
663ctk_css_node_init (CtkCssNode *cssnode)
664{
665 cssnode->decl = ctk_css_node_declaration_new ();
666
667 cssnode->style = g_object_ref (ctk_css_static_style_get_default ())((__typeof__ (ctk_css_static_style_get_default ())) (g_object_ref
) (ctk_css_static_style_get_default ()))
;
668
669 cssnode->visible = TRUE(!(0));
670}
671
672/**
673 * ctk_css_node_new:
674 *
675 * Creates a new CSS node.
676 *
677 * Returns: (transfer full): the new CSS node
678 */
679CtkCssNode *
680ctk_css_node_new (void)
681{
682 return g_object_new (CTK_TYPE_CSS_NODE(ctk_css_node_get_type ()), NULL((void*)0));
683}
684
685static CdkFrameClock *
686ctk_css_node_get_frame_clock_or_null (CtkCssNode *cssnode)
687{
688 while (cssnode->parent)
689 cssnode = cssnode->parent;
690
691 return CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class
))))
->get_frame_clock (cssnode);
692}
693
694static gint64
695ctk_css_node_get_timestamp (CtkCssNode *cssnode)
696{
697 CdkFrameClock *frameclock;
698
699 frameclock = ctk_css_node_get_frame_clock_or_null (cssnode);
700 if (frameclock == NULL((void*)0))
701 return 0;
702
703 return cdk_frame_clock_get_frame_time (frameclock);
704}
705
706static void
707ctk_css_node_parent_was_unset (CtkCssNode *node)
708{
709 if (node->visible && node->invalid)
710 CTK_CSS_NODE_GET_CLASS (node)((((CtkCssNodeClass*) (((GTypeInstance*) ((node)))->g_class
))))
->queue_validate (node);
711}
712
713static void
714ctk_css_node_parent_will_be_set (CtkCssNode *node)
715{
716 if (node->visible && node->invalid)
717 CTK_CSS_NODE_GET_CLASS (node)((((CtkCssNodeClass*) (((GTypeInstance*) ((node)))->g_class
))))
->dequeue_validate (node);
718}
719
720static void
721ctk_css_node_invalidate_style (CtkCssNode *cssnode)
722{
723 if (cssnode->style_is_invalid)
724 return;
725
726 cssnode->style_is_invalid = TRUE(!(0));
727 ctk_css_node_set_invalid (cssnode, TRUE(!(0)));
728
729 if (cssnode->first_child)
730 ctk_css_node_invalidate_style (cssnode->first_child);
731
732 if (cssnode->next_sibling)
733 ctk_css_node_invalidate_style (cssnode->next_sibling);
734}
735
736static void
737ctk_css_node_reposition (CtkCssNode *node,
738 CtkCssNode *new_parent,
739 CtkCssNode *previous)
740{
741 CtkCssNode *old_parent;
742
743 g_assert (! (new_parent == NULL && previous != NULL))do { if (! (new_parent == ((void*)0) && previous != (
(void*)0))) ; else g_assertion_message_expr ("Ctk", "ctkcssnode.c"
, 743, ((const char*) (__func__)), "! (new_parent == NULL && previous != NULL)"
); } while (0)
;
744
745 old_parent = node->parent;
746 /* Take a reference here so the whole function has a reference */
747 g_object_ref (node)((__typeof__ (node)) (g_object_ref) (node));
748
749 if (node->visible)
750 {
751 if (node->next_sibling)
752 ctk_css_node_invalidate (node->next_sibling,
753 CTK_CSS_CHANGE_ANY_SIBLING((1ULL << 8) | (1ULL << 9) | (1ULL << 10) |
((1ULL << 11) | (1ULL << 12) | (1ULL << 13
) | (1ULL << 14)) | (1ULL << 15))
754 | CTK_CSS_CHANGE_NTH_CHILD(1ULL << 5)
755 | (node->previous_sibling ? 0 : CTK_CSS_CHANGE_FIRST_CHILD(1ULL << 3)));
756 else if (node->previous_sibling)
757 ctk_css_node_invalidate (node->previous_sibling, CTK_CSS_CHANGE_LAST_CHILD(1ULL << 4));
758 }
759
760 if (old_parent != NULL((void*)0))
761 {
762 g_signal_emit (old_parent, cssnode_signals[NODE_REMOVED], 0, node, node->previous_sibling);
763 if (old_parent->first_child && node->visible)
764 ctk_css_node_invalidate (old_parent->first_child, CTK_CSS_CHANGE_NTH_LAST_CHILD(1ULL << 6));
765 }
766
767 if (old_parent != new_parent)
768 {
769 if (old_parent == NULL((void*)0))
770 {
771 ctk_css_node_parent_will_be_set (node);
772 }
773 else
774 {
775 g_object_unref (node);
776 }
777
778 if (ctk_css_node_get_style_provider_or_null (node) == NULL((void*)0))
779 ctk_css_node_invalidate_style_provider (node);
780 ctk_css_node_invalidate (node, CTK_CSS_CHANGE_TIMESTAMP(1ULL << 34) | CTK_CSS_CHANGE_ANIMATIONS(1ULL << 35));
781
782 if (new_parent)
783 {
784 g_object_ref (node)((__typeof__ (node)) (g_object_ref) (node));
785
786 if (node->pending_changes)
787 new_parent->needs_propagation = TRUE(!(0));
788 if (node->invalid && node->visible)
789 ctk_css_node_set_invalid (new_parent, TRUE(!(0)));
790 }
791 else
792 {
793 ctk_css_node_parent_was_unset (node);
794 }
795 }
796
797 if (new_parent)
798 {
799 g_signal_emit (new_parent, cssnode_signals[NODE_ADDED], 0, node, previous);
800 if (node->visible)
801 ctk_css_node_invalidate (new_parent->first_child, CTK_CSS_CHANGE_NTH_LAST_CHILD(1ULL << 6));
802 }
803
804 if (node->visible)
805 {
806 if (node->next_sibling)
807 {
808 if (node->previous_sibling == NULL((void*)0))
809 ctk_css_node_invalidate (node->next_sibling, CTK_CSS_CHANGE_FIRST_CHILD(1ULL << 3));
810 else
811 ctk_css_node_invalidate_style (node->next_sibling);
812 }
813 else if (node->previous_sibling)
814 {
815 ctk_css_node_invalidate (node->previous_sibling, CTK_CSS_CHANGE_LAST_CHILD(1ULL << 4));
816 }
817 }
818 else
819 {
820 if (node->next_sibling)
821 ctk_css_node_invalidate_style (node->next_sibling);
822 }
823
824 ctk_css_node_invalidate (node, CTK_CSS_CHANGE_ANY_PARENT((1ULL << 16) | (1ULL << 24) | (1ULL << 17)
| (1ULL << 26) | (1ULL << 18) | (1ULL << 25
) | ((1ULL << 19) | (1ULL << 20) | (1ULL <<
21) | (1ULL << 22)) | ((1ULL << 27) | (1ULL <<
28) | (1ULL << 29) | (1ULL << 30)) | (1ULL <<
23) | (1ULL << 31))
825 | CTK_CSS_CHANGE_ANY_SIBLING((1ULL << 8) | (1ULL << 9) | (1ULL << 10) |
((1ULL << 11) | (1ULL << 12) | (1ULL << 13
) | (1ULL << 14)) | (1ULL << 15))
826 | CTK_CSS_CHANGE_NTH_CHILD(1ULL << 5)
827 | (node->previous_sibling ? 0 : CTK_CSS_CHANGE_FIRST_CHILD(1ULL << 3))
828 | (node->next_sibling ? 0 : CTK_CSS_CHANGE_LAST_CHILD(1ULL << 4)));
829
830 g_object_unref (node);
831}
832
833void
834ctk_css_node_set_parent (CtkCssNode *node,
835 CtkCssNode *parent)
836{
837 if (node->parent == parent)
838 return;
839
840 ctk_css_node_reposition (node, parent, parent ? parent->last_child : NULL((void*)0));
841}
842
843/* If previous_sibling is NULL, insert at the beginning */
844void
845ctk_css_node_insert_after (CtkCssNode *parent,
846 CtkCssNode *cssnode,
847 CtkCssNode *previous_sibling)
848{
849 g_return_if_fail (previous_sibling == NULL || previous_sibling->parent == parent)do { if ((previous_sibling == ((void*)0) || previous_sibling->
parent == parent)) { } else { g_return_if_fail_warning ("Ctk"
, ((const char*) (__func__)), "previous_sibling == NULL || previous_sibling->parent == parent"
); return; } } while (0)
;
850 g_return_if_fail (cssnode != previous_sibling)do { if ((cssnode != previous_sibling)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "cssnode != previous_sibling"
); return; } } while (0)
;
851
852 if (cssnode->previous_sibling == previous_sibling &&
853 cssnode->parent == parent)
854 return;
855
856 ctk_css_node_reposition (cssnode,
857 parent,
858 previous_sibling);
859}
860
861/* If next_sibling is NULL, insert at the end */
862void
863ctk_css_node_insert_before (CtkCssNode *parent,
864 CtkCssNode *cssnode,
865 CtkCssNode *next_sibling)
866{
867 g_return_if_fail (next_sibling == NULL || next_sibling->parent == parent)do { if ((next_sibling == ((void*)0) || next_sibling->parent
== parent)) { } else { g_return_if_fail_warning ("Ctk", ((const
char*) (__func__)), "next_sibling == NULL || next_sibling->parent == parent"
); return; } } while (0)
;
868 g_return_if_fail (cssnode != next_sibling)do { if ((cssnode != next_sibling)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "cssnode != next_sibling"
); return; } } while (0)
;
869
870 if (cssnode->next_sibling == next_sibling &&
871 cssnode->parent == parent)
872 return;
873
874 ctk_css_node_reposition (cssnode,
875 parent,
876 next_sibling ? next_sibling->previous_sibling : parent->last_child);
877}
878
879void
880ctk_css_node_reverse_children (CtkCssNode *cssnode)
881{
882 CtkCssNode *end;
883
884 end = cssnode->last_child;
885 while (cssnode->first_child != end)
886 {
887 ctk_css_node_reposition (cssnode->first_child,
888 cssnode,
889 end);
890 }
891
892}
893
894CtkCssNode *
895ctk_css_node_get_parent (CtkCssNode *cssnode)
896{
897 return cssnode->parent;
898}
899
900CtkCssNode *
901ctk_css_node_get_first_child (CtkCssNode *cssnode)
902{
903 return cssnode->first_child;
904}
905
906CtkCssNode *
907ctk_css_node_get_last_child (CtkCssNode *cssnode)
908{
909 return cssnode->last_child;
910}
911
912CtkCssNode *
913ctk_css_node_get_previous_sibling (CtkCssNode *cssnode)
914{
915 return cssnode->previous_sibling;
916}
917
918CtkCssNode *
919ctk_css_node_get_next_sibling (CtkCssNode *cssnode)
920{
921 return cssnode->next_sibling;
922}
923
924static gboolean
925ctk_css_node_set_style (CtkCssNode *cssnode,
926 CtkCssStyle *style)
927{
928 CtkCssStyleChange change;
929 gboolean style_changed;
930
931 if (cssnode->style == style)
932 return FALSE(0);
933
934 ctk_css_style_change_init (&change, cssnode->style, style);
935
936 style_changed = ctk_css_style_change_has_change (&change);
937 if (style_changed)
938 {
939 g_signal_emit (cssnode, cssnode_signals[STYLE_CHANGED], 0, &change);
940 }
941 else if (cssnode->style != style &&
942 (CTK_IS_CSS_ANIMATED_STYLE (cssnode->style)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
cssnode->style); GType __t = ((ctk_css_animated_style_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))
|| CTK_IS_CSS_ANIMATED_STYLE (style)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
style); GType __t = ((ctk_css_animated_style_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
))
943 {
944 /* This is when animations are starting/stopping but they didn't change any CSS this frame */
945 g_set_object (&cssnode->style, style)(__extension__ ({ _Static_assert (sizeof *(&cssnode->style
) == sizeof (style), "Expression evaluates to false"); union {
char *in; GObject **out; } _object_ptr; _object_ptr.in = (char
*) (&cssnode->style); (void) (0 ? *(&cssnode->
style) = (style), (0) : (0)); (g_set_object) (_object_ptr.out
, (GObject *) style); }))
;
946 }
947
948 ctk_css_style_change_finish (&change);
949
950 return style_changed;
951}
952
953static void
954ctk_css_node_propagate_pending_changes (CtkCssNode *cssnode,
955 gboolean style_changed)
956{
957 CtkCssChange change, child_change;
958 CtkCssNode *child;
959
960 change = _ctk_css_change_for_child (cssnode->pending_changes);
961 if (style_changed)
962 change |= CTK_CSS_CHANGE_PARENT_STYLE(1ULL << 33);
963
964 if (!cssnode->needs_propagation && change == 0)
965 return;
966
967 for (child = ctk_css_node_get_first_child (cssnode);
968 child;
969 child = ctk_css_node_get_next_sibling (child))
970 {
971 child_change = child->pending_changes;
972 ctk_css_node_invalidate (child, change);
973 if (child->visible)
974 change |= _ctk_css_change_for_sibling (child_change);
975 }
976
977 cssnode->needs_propagation = FALSE(0);
978}
979
980static gboolean
981ctk_css_node_needs_new_style (CtkCssNode *cssnode)
982{
983 return cssnode->style_is_invalid || cssnode->needs_propagation;
984}
985
986static void
987ctk_css_node_ensure_style (CtkCssNode *cssnode,
988 gint64 current_time)
989{
990 gboolean style_changed;
991
992 if (!ctk_css_node_needs_new_style (cssnode))
993 return;
994
995 if (cssnode->parent)
996 ctk_css_node_ensure_style (cssnode->parent, current_time);
997
998 if (cssnode->style_is_invalid)
999 {
1000 CtkCssStyle *new_style;
1001
1002 if (cssnode->previous_sibling)
1003 ctk_css_node_ensure_style (cssnode->previous_sibling, current_time);
1004
1005 g_clear_pointer (&cssnode->cache, ctk_css_node_style_cache_unref)do { _Static_assert (sizeof *(&cssnode->cache) == sizeof
(gpointer), "Expression evaluates to false"); __typeof__ ((&
cssnode->cache)) _pp = (&cssnode->cache); __typeof__
(*(&cssnode->cache)) _ptr = *_pp; *_pp = ((void*)0); if
(_ptr) (ctk_css_node_style_cache_unref) (_ptr); } while (0)
;
1006
1007 new_style = CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class
))))
->update_style (cssnode,
1008 cssnode->pending_changes,
1009 current_time,
1010 cssnode->style);
1011
1012 style_changed = ctk_css_node_set_style (cssnode, new_style);
1013 g_object_unref (new_style);
1014 }
1015 else
1016 {
1017 style_changed = FALSE(0);
1018 }
1019
1020 ctk_css_node_propagate_pending_changes (cssnode, style_changed);
1021
1022 cssnode->pending_changes = 0;
1023 cssnode->style_is_invalid = FALSE(0);
1024}
1025
1026CtkCssStyle *
1027ctk_css_node_get_style (CtkCssNode *cssnode)
1028{
1029 if (ctk_css_node_needs_new_style (cssnode))
1030 {
1031 gint64 timestamp = ctk_css_node_get_timestamp (cssnode);
1032
1033 ctk_css_node_ensure_style (cssnode, timestamp);
1034 }
1035
1036 return cssnode->style;
1037}
1038
1039void
1040ctk_css_node_set_visible (CtkCssNode *cssnode,
1041 gboolean visible)
1042{
1043 CtkCssNode *iter;
1044
1045 if (cssnode->visible == visible)
1046 return;
1047
1048 cssnode->visible = visible;
1049 g_object_notify_by_pspec (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((cssnode)), (((GType) ((20) << (2))))))))
, cssnode_properties[PROP_VISIBLE]);
1050
1051 if (cssnode->invalid)
1052 {
1053 if (cssnode->visible)
1054 {
1055 if (cssnode->parent)
1056 ctk_css_node_set_invalid (cssnode->parent, TRUE(!(0)));
1057 else
1058 CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class
))))
->queue_validate (cssnode);
1059 }
1060 else
1061 {
1062 if (cssnode->parent == NULL((void*)0))
1063 CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class
))))
->dequeue_validate (cssnode);
1064 }
1065 }
1066
1067 if (cssnode->next_sibling)
1068 {
1069 ctk_css_node_invalidate (cssnode->next_sibling, CTK_CSS_CHANGE_ANY_SIBLING((1ULL << 8) | (1ULL << 9) | (1ULL << 10) |
((1ULL << 11) | (1ULL << 12) | (1ULL << 13
) | (1ULL << 14)) | (1ULL << 15))
| CTK_CSS_CHANGE_NTH_CHILD(1ULL << 5));
1070 if (ctk_css_node_is_first_child (cssnode))
1071 {
1072 for (iter = cssnode->next_sibling;
1073 iter != NULL((void*)0);
1074 iter = iter->next_sibling)
1075 {
1076 ctk_css_node_invalidate (iter, CTK_CSS_CHANGE_FIRST_CHILD(1ULL << 3));
1077 if (iter->visible)
1078 break;
1079 }
1080 }
1081 }
1082
1083 if (cssnode->previous_sibling)
1084 {
1085 if (ctk_css_node_is_last_child (cssnode))
1086 {
1087 for (iter = cssnode->previous_sibling;
1088 iter != NULL((void*)0);
1089 iter = iter->previous_sibling)
1090 {
1091 ctk_css_node_invalidate (iter, CTK_CSS_CHANGE_LAST_CHILD(1ULL << 4));
1092 if (iter->visible)
1093 break;
1094 }
1095 }
1096 ctk_css_node_invalidate (cssnode->parent->first_child, CTK_CSS_CHANGE_NTH_LAST_CHILD(1ULL << 6));
1097 }
1098}
1099
1100gboolean
1101ctk_css_node_get_visible (CtkCssNode *cssnode)
1102{
1103 return cssnode->visible;
1104}
1105
1106void
1107ctk_css_node_set_name (CtkCssNode *cssnode,
1108 /*interned*/ const char *name)
1109{
1110 if (ctk_css_node_declaration_set_name (&cssnode->decl, name))
1111 {
1112 ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_NAME(1ULL << 1));
1113 g_object_notify_by_pspec (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((cssnode)), (((GType) ((20) << (2))))))))
, cssnode_properties[PROP_NAME]);
1114 }
1115}
1116
1117/* interned */ const char *
1118ctk_css_node_get_name (CtkCssNode *cssnode)
1119{
1120 return ctk_css_node_declaration_get_name (cssnode->decl);
1121}
1122
1123void
1124ctk_css_node_set_widget_type (CtkCssNode *cssnode,
1125 GType widget_type)
1126{
1127 if (ctk_css_node_declaration_set_type (&cssnode->decl, widget_type))
1128 {
1129 ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_NAME(1ULL << 1));
1130 g_object_notify_by_pspec (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((cssnode)), (((GType) ((20) << (2))))))))
, cssnode_properties[PROP_WIDGET_TYPE]);
1131 }
1132}
1133
1134GType
1135ctk_css_node_get_widget_type (CtkCssNode *cssnode)
1136{
1137 return ctk_css_node_declaration_get_type (cssnode->decl);
1138}
1139
1140void
1141ctk_css_node_set_id (CtkCssNode *cssnode,
1142 /* interned */ const char *id)
1143{
1144 if (ctk_css_node_declaration_set_id (&cssnode->decl, id))
1145 {
1146 ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_ID(1ULL << 2));
1147 g_object_notify_by_pspec (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((cssnode)), (((GType) ((20) << (2))))))))
, cssnode_properties[PROP_ID]);
1148 }
1149}
1150
1151/* interned */ const char *
1152ctk_css_node_get_id (CtkCssNode *cssnode)
1153{
1154 return ctk_css_node_declaration_get_id (cssnode->decl);
1155}
1156
1157void
1158ctk_css_node_set_state (CtkCssNode *cssnode,
1159 CtkStateFlags state_flags)
1160{
1161 if (ctk_css_node_declaration_set_state (&cssnode->decl, state_flags))
1162 {
1163 ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_STATE(1ULL << 7));
1164 g_object_notify_by_pspec (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((cssnode)), (((GType) ((20) << (2))))))))
, cssnode_properties[PROP_STATE]);
1165 }
1166}
1167
1168CtkStateFlags
1169ctk_css_node_get_state (CtkCssNode *cssnode)
1170{
1171 return ctk_css_node_declaration_get_state (cssnode->decl);
1172}
1173
1174void
1175ctk_css_node_set_junction_sides (CtkCssNode *cssnode,
1176 CtkJunctionSides junction_sides)
1177{
1178 ctk_css_node_declaration_set_junction_sides (&cssnode->decl, junction_sides);
1179}
1180
1181CtkJunctionSides
1182ctk_css_node_get_junction_sides (CtkCssNode *cssnode)
1183{
1184 return ctk_css_node_declaration_get_junction_sides (cssnode->decl);
1185}
1186
1187static void
1188ctk_css_node_clear_classes (CtkCssNode *cssnode)
1189{
1190 if (ctk_css_node_declaration_clear_classes (&cssnode->decl))
1191 {
1192 ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_CLASS(1ULL << 0));
1193 g_object_notify_by_pspec (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((cssnode)), (((GType) ((20) << (2))))))))
, cssnode_properties[PROP_CLASSES]);
1194 }
1195}
1196
1197void
1198ctk_css_node_set_classes (CtkCssNode *cssnode,
1199 const char **classes)
1200{
1201 guint i;
1202
1203 g_object_freeze_notify (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((cssnode)), (((GType) ((20) << (2))))))))
);
1204
1205 ctk_css_node_clear_classes (cssnode);
1206
1207 if (classes)
1208 {
1209 for (i = 0; classes[i] != NULL((void*)0); i++)
1210 {
1211 ctk_css_node_add_class (cssnode, g_quark_from_string (classes[i]));
1212 }
1213 }
1214
1215 g_object_thaw_notify (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((cssnode)), (((GType) ((20) << (2))))))))
);
1216}
1217
1218char **
1219ctk_css_node_get_classes (CtkCssNode *cssnode)
1220{
1221 const GQuark *classes;
1222 char **result;
1223 guint n_classes, i, j;
1224
1225 classes = ctk_css_node_declaration_get_classes (cssnode->decl, &n_classes);
1226 result = g_new (char *, n_classes + 1)((char * *) g_malloc_n ((n_classes + 1), sizeof (char *)));
3
Memory is allocated
1227
1228 for (i = n_classes, j = 0; i-- > 0; ++j)
4
Assuming the condition is false
5
Loop condition is false. Execution continues on line 1233
1229 {
1230 result[j] = g_strdup (g_quark_to_string (classes[i]))g_strdup_inline (g_quark_to_string (classes[i]));
1231 }
1232
1233 result[n_classes] = NULL((void*)0);
1234 return result;
1235}
1236
1237void
1238ctk_css_node_add_class (CtkCssNode *cssnode,
1239 GQuark style_class)
1240{
1241 if (ctk_css_node_declaration_add_class (&cssnode->decl, style_class))
1242 {
1243 ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_CLASS(1ULL << 0));
1244 g_object_notify_by_pspec (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((cssnode)), (((GType) ((20) << (2))))))))
, cssnode_properties[PROP_CLASSES]);
1245 }
1246}
1247
1248void
1249ctk_css_node_remove_class (CtkCssNode *cssnode,
1250 GQuark style_class)
1251{
1252 if (ctk_css_node_declaration_remove_class (&cssnode->decl, style_class))
1253 {
1254 ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_CLASS(1ULL << 0));
1255 g_object_notify_by_pspec (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((cssnode)), (((GType) ((20) << (2))))))))
, cssnode_properties[PROP_CLASSES]);
1256 }
1257}
1258
1259gboolean
1260ctk_css_node_has_class (CtkCssNode *cssnode,
1261 GQuark style_class)
1262{
1263 return ctk_css_node_declaration_has_class (cssnode->decl, style_class);
1264}
1265
1266const GQuark *
1267ctk_css_node_list_classes (CtkCssNode *cssnode,
1268 guint *n_classes)
1269{
1270 return ctk_css_node_declaration_get_classes (cssnode->decl, n_classes);
1271}
1272
1273void
1274ctk_css_node_add_region (CtkCssNode *cssnode,
1275 GQuark region,
1276 CtkRegionFlags flags)
1277{
1278 ctk_css_node_declaration_add_region (&cssnode->decl, region, flags);
1279}
1280
1281void
1282ctk_css_node_remove_region (CtkCssNode *cssnode,
1283 GQuark region)
1284{
1285 ctk_css_node_declaration_remove_region (&cssnode->decl, region);
1286}
1287
1288gboolean
1289ctk_css_node_has_region (CtkCssNode *cssnode,
1290 GQuark region,
1291 CtkRegionFlags *out_flags)
1292{
1293 return ctk_css_node_declaration_has_region (cssnode->decl, region, out_flags);
1294}
1295
1296GList *
1297ctk_css_node_list_regions (CtkCssNode *cssnode)
1298{
1299 return ctk_css_node_declaration_list_regions (cssnode->decl);
1300}
1301
1302
1303const CtkCssNodeDeclaration *
1304ctk_css_node_get_declaration (CtkCssNode *cssnode)
1305{
1306 return cssnode->decl;
1307}
1308
1309void
1310ctk_css_node_invalidate_style_provider (CtkCssNode *cssnode)
1311{
1312 CtkCssNode *child;
1313
1314 ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_SOURCE(1ULL << 32));
1315
1316 for (child = cssnode->first_child;
1317 child;
1318 child = child->next_sibling)
1319 {
1320 if (ctk_css_node_get_style_provider_or_null (child) == NULL((void*)0))
1321 ctk_css_node_invalidate_style_provider (child);
1322 }
1323}
1324
1325static void
1326ctk_css_node_invalidate_timestamp (CtkCssNode *cssnode)
1327{
1328 CtkCssNode *child;
1329
1330 if (!cssnode->invalid)
1331 return;
1332
1333 if (!ctk_css_style_is_static (cssnode->style))
1334 ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_TIMESTAMP(1ULL << 34));
1335
1336 for (child = cssnode->first_child; child; child = child->next_sibling)
1337 {
1338 ctk_css_node_invalidate_timestamp (child);
1339 }
1340}
1341
1342void
1343ctk_css_node_invalidate_frame_clock (CtkCssNode *cssnode,
1344 gboolean just_timestamp)
1345{
1346 /* frame clock is handled by the top level */
1347 if (cssnode->parent)
1348 return;
1349
1350 ctk_css_node_invalidate_timestamp (cssnode);
1351
1352 if (!just_timestamp)
1353 ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_ANIMATIONS(1ULL << 35));
1354}
1355
1356void
1357ctk_css_node_invalidate (CtkCssNode *cssnode,
1358 CtkCssChange change)
1359{
1360 if (!cssnode->invalid)
1361 change &= ~CTK_CSS_CHANGE_TIMESTAMP(1ULL << 34);
1362
1363 if (change == 0)
1364 return;
1365
1366 cssnode->pending_changes |= change;
1367
1368 CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class
))))
->invalidate (cssnode);
1369
1370 if (cssnode->parent)
1371 cssnode->parent->needs_propagation = TRUE(!(0));
1372 ctk_css_node_invalidate_style (cssnode);
1373}
1374
1375void
1376ctk_css_node_validate_internal (CtkCssNode *cssnode,
1377 gint64 timestamp)
1378{
1379 CtkCssNode *child;
1380
1381 if (!cssnode->invalid)
1382 return;
1383
1384 ctk_css_node_ensure_style (cssnode, timestamp);
1385
1386 /* need to set to FALSE then to TRUE here to make it chain up */
1387 ctk_css_node_set_invalid (cssnode, FALSE(0));
1388 if (!ctk_css_style_is_static (cssnode->style))
1389 ctk_css_node_set_invalid (cssnode, TRUE(!(0)));
1390
1391 CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class
))))
->validate (cssnode);
1392
1393 for (child = ctk_css_node_get_first_child (cssnode);
1394 child;
1395 child = ctk_css_node_get_next_sibling (child))
1396 {
1397 if (child->visible)
1398 ctk_css_node_validate_internal (child, timestamp);
1399 }
1400}
1401
1402void
1403ctk_css_node_validate (CtkCssNode *cssnode)
1404{
1405 gint64 timestamp;
1406
1407 timestamp = ctk_css_node_get_timestamp (cssnode);
1408
1409 ctk_css_node_validate_internal (cssnode, timestamp);
1410}
1411
1412gboolean
1413ctk_css_node_init_matcher (CtkCssNode *cssnode,
1414 CtkCssMatcher *matcher)
1415{
1416 return CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class
))))
->init_matcher (cssnode, matcher);
1417}
1418
1419CtkWidgetPath *
1420ctk_css_node_create_widget_path (CtkCssNode *cssnode)
1421{
1422 return CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class
))))
->create_widget_path (cssnode);
1423}
1424
1425const CtkWidgetPath *
1426ctk_css_node_get_widget_path (CtkCssNode *cssnode)
1427{
1428 return CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class
))))
->get_widget_path (cssnode);
1429}
1430
1431CtkStyleProviderPrivate *
1432ctk_css_node_get_style_provider (CtkCssNode *cssnode)
1433{
1434 CtkStyleProviderPrivate *result;
1435 CtkSettings *settings;
1436
1437 result = ctk_css_node_get_style_provider_or_null (cssnode);
1438 if (result)
1439 return result;
1440
1441 if (cssnode->parent)
1442 return ctk_css_node_get_style_provider (cssnode->parent);
1443
1444 settings = ctk_settings_get_default ();
1445 if (!settings)
1446 return NULL((void*)0);
1447
1448 return CTK_STYLE_PROVIDER_PRIVATE (_ctk_settings_get_style_cascade (settings, 1))((((CtkStyleProviderPrivate*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((_ctk_settings_get_style_cascade (settings
, 1))), ((_ctk_style_provider_private_get_type ()))))))
;
1449}
1450
1451void
1452ctk_css_node_print (CtkCssNode *cssnode,
1453 CtkStyleContextPrintFlags flags,
1454 GString *string,
1455 guint indent)
1456{
1457 gboolean need_newline = FALSE(0);
1458
1459 g_string_append_printf (string, "%*s", indent, "");
1460
1461 if (!cssnode->visible)
1462 g_string_append_c (string, '[')g_string_append_c_inline (string, '[');
1463
1464 ctk_css_node_declaration_print (cssnode->decl, string);
1465
1466 if (!cssnode->visible)
1467 g_string_append_c (string, ']')g_string_append_c_inline (string, ']');
1468
1469 g_string_append_c (string, '\n')g_string_append_c_inline (string, '\n');
1470
1471 if (flags & CTK_STYLE_CONTEXT_PRINT_SHOW_STYLE)
1472 need_newline = ctk_css_style_print (ctk_css_node_get_style (cssnode), string, indent + 2, TRUE(!(0)));
1473
1474 if (flags & CTK_STYLE_CONTEXT_PRINT_RECURSE)
1475 {
1476 CtkCssNode *node;
1477
1478 if (need_newline && ctk_css_node_get_first_child (cssnode))
1479 g_string_append_c (string, '\n')g_string_append_c_inline (string, '\n');
1480
1481 for (node = ctk_css_node_get_first_child (cssnode); node; node = ctk_css_node_get_next_sibling (node))
1482 ctk_css_node_print (node, flags, string, indent + 2);
1483 }
1484}