Bug Summary

File:ctk/ctkiconfactory.c
Warning:line 2559, column 47
Use of memory after it is freed

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 ctkiconfactory.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-172131-43638-1 -x c ctkiconfactory.c
1/* CTK - The GIMP Toolkit
2 * Copyright (C) 2000 Red Hat, Inc.
3 * 2008 Johan Dahlin
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/*
19 * Modified by the CTK+ Team and others 1997-2000. See the AUTHORS
20 * file for a list of people on the CTK+ Team. See the ChangeLog
21 * files for a list of changes. These files are distributed with
22 * CTK+ at ftp://ftp.ctk.org/pub/ctk/.
23 */
24
25#include "config.h"
26
27#include <stdlib.h>
28#include <errno(*__errno_location ()).h>
29#include <string.h>
30
31#include "ctkcssenumvalueprivate.h"
32#include "ctkcssiconthemevalueprivate.h"
33#include "ctkiconfactory.h"
34#include "ctkiconcache.h"
35#include "ctkdebug.h"
36#include "ctkicontheme.h"
37#include "ctksettingsprivate.h"
38#include "ctkstock.h"
39#include "ctkwidget.h"
40#include "ctkintl.h"
41#include "ctkbuildable.h"
42#include "ctkbuilderprivate.h"
43#include "ctktypebuiltins.h"
44#include "ctkstyle.h"
45#include "ctkstylecontextprivate.h"
46#include "ctkrender.h"
47#include "ctkrenderprivate.h"
48
49/**
50 * SECTION:ctkiconfactory
51 * @Short_description: Manipulating stock icons
52 * @Title: Themeable Stock Images
53 *
54 * An icon factory manages a collection of #CtkIconSet; a #CtkIconSet manages a
55 * set of variants of a particular icon (i.e. a #CtkIconSet contains variants for
56 * different sizes and widget states). Icons in an icon factory are named by a
57 * stock ID, which is a simple string identifying the icon. Each #CtkStyle has a
58 * list of #CtkIconFactory derived from the current theme; those icon factories
59 * are consulted first when searching for an icon. If the theme doesn’t set a
60 * particular icon, CTK+ looks for the icon in a list of default icon factories,
61 * maintained by ctk_icon_factory_add_default() and
62 * ctk_icon_factory_remove_default(). Applications with icons should add a default
63 * icon factory with their icons, which will allow themes to override the icons
64 * for the application.
65 *
66 * To display an icon, always use ctk_style_lookup_icon_set() on the widget that
67 * will display the icon, or the convenience function
68 * ctk_widget_render_icon(). These functions take the theme into account when
69 * looking up the icon to use for a given stock ID.
70 *
71 * # CtkIconFactory as CtkBuildable # {#CtkIconFactory-BUILDER-UI}
72 *
73 * CtkIconFactory supports a custom <sources> element, which can contain
74 * multiple <source> elements. The following attributes are allowed:
75 *
76 * - stock-id
77 *
78 * The stock id of the source, a string. This attribute is
79 * mandatory
80 *
81 * - filename
82 *
83 * The filename of the source, a string. This attribute is
84 * optional
85 *
86 * - icon-name
87 *
88 * The icon name for the source, a string. This attribute is
89 * optional.
90 *
91 * - size
92 *
93 * Size of the icon, a #CtkIconSize enum value. This attribute is
94 * optional.
95 *
96 * - direction
97 *
98 * Direction of the source, a #CtkTextDirection enum value. This
99 * attribute is optional.
100 *
101 * - state
102 *
103 * State of the source, a #CtkStateType enum value. This
104 * attribute is optional.
105 *
106 *
107 * ## A #CtkIconFactory UI definition fragment. ##
108 *
109 * |[
110 * <object class="CtkIconFactory" id="iconfactory1">
111 * <sources>
112 * <source stock-id="apple-red" filename="apple-red.png"/>
113 * </sources>
114 * </object>
115 * <object class="CtkWindow" id="window1">
116 * <child>
117 * <object class="CtkButton" id="apple_button">
118 * <property name="label">apple-red</property>
119 * <property name="use-stock">True</property>
120 * </object>
121 * </child>
122 * </object>
123 * ]|
124 */
125
126
127static GSList *all_icon_factories = NULL((void*)0);
128
129struct _CtkIconFactoryPrivate
130{
131 GHashTable *icons;
132};
133
134typedef enum {
135 CTK_ICON_SOURCE_EMPTY,
136 CTK_ICON_SOURCE_ICON_NAME,
137 CTK_ICON_SOURCE_STATIC_ICON_NAME,
138 CTK_ICON_SOURCE_FILENAME,
139 CTK_ICON_SOURCE_PIXBUF
140} CtkIconSourceType;
141
142struct _CtkIconSource
143{
144 CtkIconSourceType type;
145
146 union {
147 gchar *icon_name;
148 gchar *filename;
149 GdkPixbuf *pixbuf;
150 } source;
151
152 GdkPixbuf *filename_pixbuf;
153
154 CtkTextDirection direction;
155 CtkStateType state;
156 CtkIconSize size;
157
158 /* If TRUE, then the parameter is wildcarded, and the above
159 * fields should be ignored. If FALSE, the parameter is
160 * specified, and the above fields should be valid.
161 */
162 guint any_direction : 1;
163 guint any_state : 1;
164 guint any_size : 1;
165};
166
167
168static void
169ctk_icon_factory_buildable_init (CtkBuildableIface *iface);
170
171static gboolean ctk_icon_factory_buildable_custom_tag_start (CtkBuildable *buildable,
172 CtkBuilder *builder,
173 GObject *child,
174 const gchar *tagname,
175 GMarkupParser *parser,
176 gpointer *data);
177static void ctk_icon_factory_buildable_custom_tag_end (CtkBuildable *buildable,
178 CtkBuilder *builder,
179 GObject *child,
180 const gchar *tagname,
181 gpointer *user_data);
182static void ctk_icon_factory_finalize (GObject *object);
183static void get_default_icons (CtkIconFactory *icon_factory);
184static void icon_source_clear (CtkIconSource *source);
185
186static CtkIconSize icon_size_register_intern (const gchar *name,
187 gint width,
188 gint height);
189
190#define CTK_ICON_SOURCE_INIT(any_direction, any_state, any_size){ CTK_ICON_SOURCE_EMPTY, { ((void*)0) }, ((void*)0), 0, 0, 0,
any_direction, any_state, any_size }
\
191 { CTK_ICON_SOURCE_EMPTY, { NULL((void*)0) }, NULL((void*)0), \
192 0, 0, 0, \
193 any_direction, any_state, any_size }
194
195G_DEFINE_TYPE_WITH_CODE (CtkIconFactory, ctk_icon_factory, G_TYPE_OBJECT,static void ctk_icon_factory_init (CtkIconFactory *self); static
void ctk_icon_factory_class_init (CtkIconFactoryClass *klass
); static GType ctk_icon_factory_get_type_once (void); static
gpointer ctk_icon_factory_parent_class = ((void*)0); static gint
CtkIconFactory_private_offset; static void ctk_icon_factory_class_intern_init
(gpointer klass) { ctk_icon_factory_parent_class = g_type_class_peek_parent
(klass); if (CtkIconFactory_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CtkIconFactory_private_offset); ctk_icon_factory_class_init
((CtkIconFactoryClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer ctk_icon_factory_get_instance_private
(CtkIconFactory *self) { return (((gpointer) ((guint8*) (self
) + (glong) (CtkIconFactory_private_offset)))); } GType ctk_icon_factory_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_icon_factory_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_icon_factory_get_type_once (
void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("CtkIconFactory"
), sizeof (CtkIconFactoryClass), (GClassInitFunc)(void (*)(void
)) ctk_icon_factory_class_intern_init, sizeof (CtkIconFactory
), (GInstanceInitFunc)(void (*)(void)) ctk_icon_factory_init,
(GTypeFlags) 0); { {{ CtkIconFactory_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkIconFactoryPrivate)); } { const
GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) ctk_icon_factory_buildable_init, ((void*)0)
, ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (ctk_buildable_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
196 G_ADD_PRIVATE (CtkIconFactory)static void ctk_icon_factory_init (CtkIconFactory *self); static
void ctk_icon_factory_class_init (CtkIconFactoryClass *klass
); static GType ctk_icon_factory_get_type_once (void); static
gpointer ctk_icon_factory_parent_class = ((void*)0); static gint
CtkIconFactory_private_offset; static void ctk_icon_factory_class_intern_init
(gpointer klass) { ctk_icon_factory_parent_class = g_type_class_peek_parent
(klass); if (CtkIconFactory_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CtkIconFactory_private_offset); ctk_icon_factory_class_init
((CtkIconFactoryClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer ctk_icon_factory_get_instance_private
(CtkIconFactory *self) { return (((gpointer) ((guint8*) (self
) + (glong) (CtkIconFactory_private_offset)))); } GType ctk_icon_factory_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_icon_factory_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_icon_factory_get_type_once (
void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("CtkIconFactory"
), sizeof (CtkIconFactoryClass), (GClassInitFunc)(void (*)(void
)) ctk_icon_factory_class_intern_init, sizeof (CtkIconFactory
), (GInstanceInitFunc)(void (*)(void)) ctk_icon_factory_init,
(GTypeFlags) 0); { {{ CtkIconFactory_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkIconFactoryPrivate)); } { const
GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) ctk_icon_factory_buildable_init, ((void*)0)
, ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (ctk_buildable_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
197 G_IMPLEMENT_INTERFACE (CTK_TYPE_BUILDABLE,static void ctk_icon_factory_init (CtkIconFactory *self); static
void ctk_icon_factory_class_init (CtkIconFactoryClass *klass
); static GType ctk_icon_factory_get_type_once (void); static
gpointer ctk_icon_factory_parent_class = ((void*)0); static gint
CtkIconFactory_private_offset; static void ctk_icon_factory_class_intern_init
(gpointer klass) { ctk_icon_factory_parent_class = g_type_class_peek_parent
(klass); if (CtkIconFactory_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CtkIconFactory_private_offset); ctk_icon_factory_class_init
((CtkIconFactoryClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer ctk_icon_factory_get_instance_private
(CtkIconFactory *self) { return (((gpointer) ((guint8*) (self
) + (glong) (CtkIconFactory_private_offset)))); } GType ctk_icon_factory_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_icon_factory_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_icon_factory_get_type_once (
void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("CtkIconFactory"
), sizeof (CtkIconFactoryClass), (GClassInitFunc)(void (*)(void
)) ctk_icon_factory_class_intern_init, sizeof (CtkIconFactory
), (GInstanceInitFunc)(void (*)(void)) ctk_icon_factory_init,
(GTypeFlags) 0); { {{ CtkIconFactory_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkIconFactoryPrivate)); } { const
GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) ctk_icon_factory_buildable_init, ((void*)0)
, ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (ctk_buildable_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
198 ctk_icon_factory_buildable_init))static void ctk_icon_factory_init (CtkIconFactory *self); static
void ctk_icon_factory_class_init (CtkIconFactoryClass *klass
); static GType ctk_icon_factory_get_type_once (void); static
gpointer ctk_icon_factory_parent_class = ((void*)0); static gint
CtkIconFactory_private_offset; static void ctk_icon_factory_class_intern_init
(gpointer klass) { ctk_icon_factory_parent_class = g_type_class_peek_parent
(klass); if (CtkIconFactory_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CtkIconFactory_private_offset); ctk_icon_factory_class_init
((CtkIconFactoryClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer ctk_icon_factory_get_instance_private
(CtkIconFactory *self) { return (((gpointer) ((guint8*) (self
) + (glong) (CtkIconFactory_private_offset)))); } GType ctk_icon_factory_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_icon_factory_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_icon_factory_get_type_once (
void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("CtkIconFactory"
), sizeof (CtkIconFactoryClass), (GClassInitFunc)(void (*)(void
)) ctk_icon_factory_class_intern_init, sizeof (CtkIconFactory
), (GInstanceInitFunc)(void (*)(void)) ctk_icon_factory_init,
(GTypeFlags) 0); { {{ CtkIconFactory_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkIconFactoryPrivate)); } { const
GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) ctk_icon_factory_buildable_init, ((void*)0)
, ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (ctk_buildable_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
199
200static void
201ctk_icon_factory_init (CtkIconFactory *factory)
202{
203 CtkIconFactoryPrivate *priv;
204
205 factory->priv = ctk_icon_factory_get_instance_private (factory);
206 priv = factory->priv;
207
208 priv->icons = g_hash_table_new (g_str_hash, g_str_equal);
209 all_icon_factories = g_slist_prepend (all_icon_factories, factory);
210}
211
212static void
213ctk_icon_factory_class_init (CtkIconFactoryClass *klass)
214{
215 GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
216
217 object_class->finalize = ctk_icon_factory_finalize;
218}
219
220static void
221ctk_icon_factory_buildable_init (CtkBuildableIface *iface)
222{
223 iface->custom_tag_start = ctk_icon_factory_buildable_custom_tag_start;
224 iface->custom_tag_end = ctk_icon_factory_buildable_custom_tag_end;
225}
226
227static void
228free_icon_set (gpointer key,
229 gpointer value,
230 gpointer data G_GNUC_UNUSED__attribute__ ((__unused__)))
231{
232 g_free (key);
233 ctk_icon_set_unref (value);
234}
235
236static void
237ctk_icon_factory_finalize (GObject *object)
238{
239 CtkIconFactory *factory = CTK_ICON_FACTORY (object)((((CtkIconFactory*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_icon_factory_get_type ()))))))
;
240 CtkIconFactoryPrivate *priv = factory->priv;
241
242 all_icon_factories = g_slist_remove (all_icon_factories, factory);
243
244 g_hash_table_foreach (priv->icons, free_icon_set, NULL((void*)0));
245
246 g_hash_table_destroy (priv->icons);
247
248 G_OBJECT_CLASS (ctk_icon_factory_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_icon_factory_parent_class)), (((GType) ((20) <<
(2))))))))
->finalize (object);
249}
250
251/**
252 * ctk_icon_factory_new:
253 *
254 * Creates a new #CtkIconFactory. An icon factory manages a collection
255 * of #CtkIconSets; a #CtkIconSet manages a set of variants of a
256 * particular icon (i.e. a #CtkIconSet contains variants for different
257 * sizes and widget states). Icons in an icon factory are named by a
258 * stock ID, which is a simple string identifying the icon. Each
259 * #CtkStyle has a list of #CtkIconFactorys derived from the current
260 * theme; those icon factories are consulted first when searching for
261 * an icon. If the theme doesn’t set a particular icon, CTK+ looks for
262 * the icon in a list of default icon factories, maintained by
263 * ctk_icon_factory_add_default() and
264 * ctk_icon_factory_remove_default(). Applications with icons should
265 * add a default icon factory with their icons, which will allow
266 * themes to override the icons for the application.
267 *
268 * Returns: a new #CtkIconFactory
269 */
270CtkIconFactory*
271ctk_icon_factory_new (void)
272{
273 return g_object_new (CTK_TYPE_ICON_FACTORY(ctk_icon_factory_get_type ()), NULL((void*)0));
274}
275
276/**
277 * ctk_icon_factory_add:
278 * @factory: a #CtkIconFactory
279 * @stock_id: icon name
280 * @icon_set: icon set
281 *
282 * Adds the given @icon_set to the icon factory, under the name
283 * @stock_id. @stock_id should be namespaced for your application,
284 * e.g. “myapp-whatever-icon”. Normally applications create a
285 * #CtkIconFactory, then add it to the list of default factories with
286 * ctk_icon_factory_add_default(). Then they pass the @stock_id to
287 * widgets such as #CtkImage to display the icon. Themes can provide
288 * an icon with the same name (such as "myapp-whatever-icon") to
289 * override your application’s default icons. If an icon already
290 * existed in @factory for @stock_id, it is unreferenced and replaced
291 * with the new @icon_set.
292 */
293void
294ctk_icon_factory_add (CtkIconFactory *factory,
295 const gchar *stock_id,
296 CtkIconSet *icon_set)
297{
298 CtkIconFactoryPrivate *priv = factory->priv;
299 gpointer old_key = NULL((void*)0);
300 gpointer old_value = NULL((void*)0);
301
302 g_return_if_fail (CTK_IS_ICON_FACTORY (factory))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((factory)); GType __t = ((ctk_icon_factory_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_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_ICON_FACTORY (factory)"); return; } }
while (0)
;
303 g_return_if_fail (stock_id != NULL)do { if ((stock_id != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "stock_id != NULL"); return
; } } while (0)
;
304 g_return_if_fail (icon_set != NULL)do { if ((icon_set != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "icon_set != NULL"); return
; } } while (0)
;
305
306 g_hash_table_lookup_extended (priv->icons, stock_id,
307 &old_key, &old_value);
308
309 if (old_value == icon_set)
310 return;
311
312 ctk_icon_set_ref (icon_set);
313
314 /* GHashTable key memory management is so fantastically broken. */
315 if (old_key)
316 g_hash_table_insert (priv->icons, old_key, icon_set);
317 else
318 g_hash_table_insert (priv->icons, g_strdup (stock_id)g_strdup_inline (stock_id), icon_set);
319
320 if (old_value)
321 ctk_icon_set_unref (old_value);
322}
323
324/**
325 * ctk_icon_factory_lookup:
326 * @factory: a #CtkIconFactory
327 * @stock_id: an icon name
328 *
329 * Looks up @stock_id in the icon factory, returning an icon set
330 * if found, otherwise %NULL. For display to the user, you should
331 * use ctk_style_lookup_icon_set() on the #CtkStyle for the
332 * widget that will display the icon, instead of using this
333 * function directly, so that themes are taken into account.
334 *
335 * Returns: (transfer none): icon set of @stock_id.
336 */
337CtkIconSet *
338ctk_icon_factory_lookup (CtkIconFactory *factory,
339 const gchar *stock_id)
340{
341 CtkIconFactoryPrivate *priv;
342
343 g_return_val_if_fail (CTK_IS_ICON_FACTORY (factory), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((factory)); GType __t = ((ctk_icon_factory_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_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_ICON_FACTORY (factory)"); return (((void
*)0)); } } while (0)
;
344 g_return_val_if_fail (stock_id != NULL, NULL)do { if ((stock_id != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "stock_id != NULL"); return
(((void*)0)); } } while (0)
;
345
346 priv = factory->priv;
347
348 return g_hash_table_lookup (priv->icons, stock_id);
349}
350
351static GSList *default_factories = NULL((void*)0);
352
353/**
354 * ctk_icon_factory_add_default:
355 * @factory: a #CtkIconFactory
356 *
357 * Adds an icon factory to the list of icon factories searched by
358 * ctk_style_lookup_icon_set(). This means that, for example,
359 * ctk_image_new_from_stock() will be able to find icons in @factory.
360 * There will normally be an icon factory added for each library or
361 * application that comes with icons. The default icon factories
362 * can be overridden by themes.
363 */
364void
365ctk_icon_factory_add_default (CtkIconFactory *factory)
366{
367 g_return_if_fail (CTK_IS_ICON_FACTORY (factory))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((factory)); GType __t = ((ctk_icon_factory_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_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_ICON_FACTORY (factory)"); return; } }
while (0)
;
368
369 g_object_ref (factory)((__typeof__ (factory)) (g_object_ref) (factory));
370
371 default_factories = g_slist_prepend (default_factories, factory);
372}
373
374/**
375 * ctk_icon_factory_remove_default:
376 * @factory: a #CtkIconFactory previously added with ctk_icon_factory_add_default()
377 *
378 * Removes an icon factory from the list of default icon
379 * factories. Not normally used; you might use it for a library that
380 * can be unloaded or shut down.
381 */
382void
383ctk_icon_factory_remove_default (CtkIconFactory *factory)
384{
385 g_return_if_fail (CTK_IS_ICON_FACTORY (factory))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((factory)); GType __t = ((ctk_icon_factory_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_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_ICON_FACTORY (factory)"); return; } }
while (0)
;
386
387 default_factories = g_slist_remove (default_factories, factory);
388
389 g_object_unref (factory);
390}
391
392static CtkIconFactory *
393_ctk_icon_factory_get_default_icons (void)
394{
395 static CtkIconFactory *default_icons = NULL((void*)0);
396 CtkIconFactory *icons = NULL((void*)0);
397 CdkScreen *screen = cdk_screen_get_default ();
398
399 if (screen)
400 icons = g_object_get_data (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), (((GType) ((20) << (2))))))))
, "ctk-default-icons");
401
402 if (icons == NULL((void*)0))
403 {
404 if (default_icons == NULL((void*)0))
405 {
406 default_icons = ctk_icon_factory_new ();
407 get_default_icons (default_icons);
408 }
409 if (screen)
410 g_object_set_data_full (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), (((GType) ((20) << (2))))))))
,
411 I_("ctk-default-icons")g_intern_static_string ("ctk-default-icons"),
412 default_icons,
413 g_object_unref);
414 icons = default_icons;
415 }
416
417 return icons;
418}
419
420/**
421 * ctk_icon_factory_lookup_default:
422 * @stock_id: an icon name
423 *
424 * Looks for an icon in the list of default icon factories. For
425 * display to the user, you should use ctk_style_lookup_icon_set() on
426 * the #CtkStyle for the widget that will display the icon, instead of
427 * using this function directly, so that themes are taken into
428 * account.
429 *
430 * Returns: (transfer none): a #CtkIconSet, or %NULL
431 */
432CtkIconSet *
433ctk_icon_factory_lookup_default (const gchar *stock_id)
434{
435 GSList *tmp_list;
436 CtkIconFactory *default_icons;
437
438 g_return_val_if_fail (stock_id != NULL, NULL)do { if ((stock_id != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "stock_id != NULL"); return
(((void*)0)); } } while (0)
;
439
440 tmp_list = default_factories;
441 while (tmp_list != NULL((void*)0))
442 {
443 CtkIconSet *icon_set =
444 ctk_icon_factory_lookup (CTK_ICON_FACTORY (tmp_list->data)((((CtkIconFactory*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((tmp_list->data)), ((ctk_icon_factory_get_type ())))))
)
,
445 stock_id);
446
447 if (icon_set)
448 return icon_set;
449
450 tmp_list = tmp_list->next;
451 }
452
453 default_icons = _ctk_icon_factory_get_default_icons ();
454 if (default_icons)
455 return ctk_icon_factory_lookup (default_icons, stock_id);
456 else
457 return NULL((void*)0);
458}
459
460static void
461register_stock_icon (CtkIconFactory *factory,
462 const gchar *stock_id,
463 const gchar *icon_name)
464{
465 CtkIconSet *set = ctk_icon_set_new ();
466 CtkIconSource source = CTK_ICON_SOURCE_INIT (TRUE, TRUE, TRUE){ CTK_ICON_SOURCE_EMPTY, { ((void*)0) }, ((void*)0), 0, 0, 0,
(!(0)), (!(0)), (!(0)) }
;
467
468 source.type = CTK_ICON_SOURCE_STATIC_ICON_NAME;
469 source.source.icon_name = (gchar *)icon_name;
470 source.direction = CTK_TEXT_DIR_NONE;
471 ctk_icon_set_add_source (set, &source);
472
473 ctk_icon_factory_add (factory, stock_id, set);
474 ctk_icon_set_unref (set);
475}
476
477static void
478register_bidi_stock_icon (CtkIconFactory *factory,
479 const gchar *stock_id,
480 const gchar *icon_name)
481{
482 CtkIconSet *set = ctk_icon_set_new ();
483 CtkIconSource source = CTK_ICON_SOURCE_INIT (FALSE, TRUE, TRUE){ CTK_ICON_SOURCE_EMPTY, { ((void*)0) }, ((void*)0), 0, 0, 0,
(0), (!(0)), (!(0)) }
;
484
485 source.type = CTK_ICON_SOURCE_STATIC_ICON_NAME;
486 source.source.icon_name = (gchar *)icon_name;
487 source.direction = CTK_TEXT_DIR_LTR;
488 ctk_icon_set_add_source (set, &source);
489
490 source.type = CTK_ICON_SOURCE_STATIC_ICON_NAME;
491 source.source.icon_name = (gchar *)icon_name;
492 source.direction = CTK_TEXT_DIR_RTL;
493 ctk_icon_set_add_source (set, &source);
494
495 ctk_icon_factory_add (factory, stock_id, set);
496 ctk_icon_set_unref (set);
497}
498
499static void
500get_default_icons (CtkIconFactory *factory)
501{
502 /* KEEP IN SYNC with ctkstock.c */
503
504 register_stock_icon (factory, CTK_STOCK_DIALOG_AUTHENTICATION((CtkStock)"ctk-dialog-authentication"), "dialog-password");
505 register_stock_icon (factory, CTK_STOCK_DIALOG_ERROR((CtkStock)"ctk-dialog-error"), "dialog-error");
506 register_stock_icon (factory, CTK_STOCK_DIALOG_INFO((CtkStock)"ctk-dialog-info"), "dialog-information");
507 register_stock_icon (factory, CTK_STOCK_DIALOG_QUESTION((CtkStock)"ctk-dialog-question"), "dialog-question");
508 register_stock_icon (factory, CTK_STOCK_DIALOG_WARNING((CtkStock)"ctk-dialog-warning"), "dialog-warning");
509 register_stock_icon (factory, CTK_STOCK_DND((CtkStock)"ctk-dnd"), CTK_STOCK_DND((CtkStock)"ctk-dnd"));
510 register_stock_icon (factory, CTK_STOCK_DND_MULTIPLE((CtkStock)"ctk-dnd-multiple"), CTK_STOCK_DND_MULTIPLE((CtkStock)"ctk-dnd-multiple"));
511 register_stock_icon (factory, CTK_STOCK_APPLY((CtkStock)"ctk-apply"), CTK_STOCK_APPLY((CtkStock)"ctk-apply"));
512 register_stock_icon (factory, CTK_STOCK_CANCEL((CtkStock)"ctk-cancel"), CTK_STOCK_CANCEL((CtkStock)"ctk-cancel"));
513 register_stock_icon (factory, CTK_STOCK_NO((CtkStock)"ctk-no"), CTK_STOCK_NO((CtkStock)"ctk-no"));
514 register_stock_icon (factory, CTK_STOCK_OK((CtkStock)"ctk-ok"), CTK_STOCK_OK((CtkStock)"ctk-ok"));
515 register_stock_icon (factory, CTK_STOCK_YES((CtkStock)"ctk-yes"), CTK_STOCK_YES((CtkStock)"ctk-yes"));
516 register_stock_icon (factory, CTK_STOCK_CLOSE((CtkStock)"ctk-close"), "window-close");
517 register_stock_icon (factory, CTK_STOCK_ADD((CtkStock)"ctk-add"), "list-add");
518 register_stock_icon (factory, CTK_STOCK_JUSTIFY_CENTER((CtkStock)"ctk-justify-center"), "format-justify-center");
519 register_stock_icon (factory, CTK_STOCK_JUSTIFY_FILL((CtkStock)"ctk-justify-fill"), "format-justify-fill");
520 register_stock_icon (factory, CTK_STOCK_JUSTIFY_LEFT((CtkStock)"ctk-justify-left"), "format-justify-left");
521 register_stock_icon (factory, CTK_STOCK_JUSTIFY_RIGHT((CtkStock)"ctk-justify-right"), "format-justify-right");
522 register_stock_icon (factory, CTK_STOCK_GOTO_BOTTOM((CtkStock)"ctk-goto-bottom"), "go-bottom");
523 register_stock_icon (factory, CTK_STOCK_CDROM((CtkStock)"ctk-cdrom"), "media-optical");
524 register_stock_icon (factory, CTK_STOCK_CONVERT((CtkStock)"ctk-convert"), CTK_STOCK_CONVERT((CtkStock)"ctk-convert"));
525 register_stock_icon (factory, CTK_STOCK_COPY((CtkStock)"ctk-copy"), "edit-copy");
526 register_stock_icon (factory, CTK_STOCK_CUT((CtkStock)"ctk-cut"), "edit-cut");
527 register_stock_icon (factory, CTK_STOCK_GO_DOWN((CtkStock)"ctk-go-down"), "go-down");
528 register_stock_icon (factory, CTK_STOCK_EXECUTE((CtkStock)"ctk-execute"), "system-run");
529 register_stock_icon (factory, CTK_STOCK_QUIT((CtkStock)"ctk-quit"), "application-exit");
530 register_bidi_stock_icon (factory, CTK_STOCK_GOTO_FIRST((CtkStock)"ctk-goto-first"), "go-first");
531 register_stock_icon (factory, CTK_STOCK_SELECT_FONT((CtkStock)"ctk-select-font"), CTK_STOCK_SELECT_FONT((CtkStock)"ctk-select-font"));
532 register_stock_icon (factory, CTK_STOCK_FULLSCREEN((CtkStock)"ctk-fullscreen"), "view-fullscreen");
533 register_stock_icon (factory, CTK_STOCK_LEAVE_FULLSCREEN((CtkStock)"ctk-leave-fullscreen"), "view-restore");
534 register_stock_icon (factory, CTK_STOCK_HARDDISK((CtkStock)"ctk-harddisk"), "drive-harddisk");
535 register_stock_icon (factory, CTK_STOCK_HELP((CtkStock)"ctk-help"), "help-contents");
536 register_stock_icon (factory, CTK_STOCK_HOME((CtkStock)"ctk-home"), "go-home");
537 register_stock_icon (factory, CTK_STOCK_INFO((CtkStock)"ctk-info"), "dialog-information");
538 register_bidi_stock_icon (factory, CTK_STOCK_JUMP_TO((CtkStock)"ctk-jump-to"), "go-jump");
539 register_bidi_stock_icon (factory, CTK_STOCK_GOTO_LAST((CtkStock)"ctk-goto-last"), "go-last");
540 register_bidi_stock_icon (factory, CTK_STOCK_GO_BACK((CtkStock)"ctk-go-back"), "go-previous");
541 register_stock_icon (factory, CTK_STOCK_MISSING_IMAGE((CtkStock)"ctk-missing-image"), "image-missing");
542 register_stock_icon (factory, CTK_STOCK_NETWORK((CtkStock)"ctk-network"), "network-idle");
543 register_stock_icon (factory, CTK_STOCK_NEW((CtkStock)"ctk-new"), "document-new");
544 register_stock_icon (factory, CTK_STOCK_OPEN((CtkStock)"ctk-open"), "document-open");
545 register_stock_icon (factory, CTK_STOCK_ORIENTATION_PORTRAIT((CtkStock)"ctk-orientation-portrait"), CTK_STOCK_ORIENTATION_PORTRAIT((CtkStock)"ctk-orientation-portrait"));
546 register_stock_icon (factory, CTK_STOCK_ORIENTATION_LANDSCAPE((CtkStock)"ctk-orientation-landscape"), CTK_STOCK_ORIENTATION_LANDSCAPE((CtkStock)"ctk-orientation-landscape"));
547 register_stock_icon (factory, CTK_STOCK_ORIENTATION_REVERSE_PORTRAIT((CtkStock)"ctk-orientation-reverse-portrait"), CTK_STOCK_ORIENTATION_REVERSE_PORTRAIT((CtkStock)"ctk-orientation-reverse-portrait"));
548 register_stock_icon (factory, CTK_STOCK_ORIENTATION_REVERSE_LANDSCAPE((CtkStock)"ctk-orientation-reverse-landscape"), CTK_STOCK_ORIENTATION_REVERSE_LANDSCAPE((CtkStock)"ctk-orientation-reverse-landscape"));
549 register_stock_icon (factory, CTK_STOCK_PAGE_SETUP((CtkStock)"ctk-page-setup"), CTK_STOCK_PAGE_SETUP((CtkStock)"ctk-page-setup"));
550 register_stock_icon (factory, CTK_STOCK_PASTE((CtkStock)"ctk-paste"), "edit-paste");
551 register_stock_icon (factory, CTK_STOCK_PREFERENCES((CtkStock)"ctk-preferences"), CTK_STOCK_PREFERENCES((CtkStock)"ctk-preferences"));
552 register_stock_icon (factory, CTK_STOCK_PRINT((CtkStock)"ctk-print"), "document-print");
553 register_stock_icon (factory, CTK_STOCK_PRINT_ERROR((CtkStock)"ctk-print-error"), "printer-error");
554 register_stock_icon (factory, CTK_STOCK_PRINT_PAUSED((CtkStock)"ctk-print-paused"), "printer-paused");
555 register_stock_icon (factory, CTK_STOCK_PRINT_PREVIEW((CtkStock)"ctk-print-preview"), "document-print-preview");
556 register_stock_icon (factory, CTK_STOCK_PRINT_REPORT((CtkStock)"ctk-print-report"), "printer-info");
557 register_stock_icon (factory, CTK_STOCK_PRINT_WARNING((CtkStock)"ctk-print-warning"), "printer-warning");
558 register_stock_icon (factory, CTK_STOCK_PROPERTIES((CtkStock)"ctk-properties"), "document-properties");
559 register_bidi_stock_icon (factory, CTK_STOCK_REDO((CtkStock)"ctk-redo"), "edit-redo");
560 register_stock_icon (factory, CTK_STOCK_REMOVE((CtkStock)"ctk-remove"), "list-remove");
561 register_stock_icon (factory, CTK_STOCK_REFRESH((CtkStock)"ctk-refresh"), "view-refresh");
562 register_bidi_stock_icon (factory, CTK_STOCK_REVERT_TO_SAVED((CtkStock)"ctk-revert-to-saved"), "document-revert");
563 register_bidi_stock_icon (factory, CTK_STOCK_GO_FORWARD((CtkStock)"ctk-go-forward"), "go-next");
564 register_stock_icon (factory, CTK_STOCK_SAVE((CtkStock)"ctk-save"), "document-save");
565 register_stock_icon (factory, CTK_STOCK_FLOPPY((CtkStock)"ctk-floppy"), "media-floppy");
566 register_stock_icon (factory, CTK_STOCK_SAVE_AS((CtkStock)"ctk-save-as"), "document-save-as");
567 register_stock_icon (factory, CTK_STOCK_FIND((CtkStock)"ctk-find"), "edit-find");
568 register_stock_icon (factory, CTK_STOCK_FIND_AND_REPLACE((CtkStock)"ctk-find-and-replace"), "edit-find-replace");
569 register_stock_icon (factory, CTK_STOCK_SORT_DESCENDING((CtkStock)"ctk-sort-descending"), "view-sort-descending");
570 register_stock_icon (factory, CTK_STOCK_SORT_ASCENDING((CtkStock)"ctk-sort-ascending"), "view-sort-ascending");
571 register_stock_icon (factory, CTK_STOCK_SPELL_CHECK((CtkStock)"ctk-spell-check"), "tools-check-spelling");
572 register_stock_icon (factory, CTK_STOCK_STOP((CtkStock)"ctk-stop"), "process-stop");
573 register_stock_icon (factory, CTK_STOCK_BOLD((CtkStock)"ctk-bold"), "format-text-bold");
574 register_stock_icon (factory, CTK_STOCK_ITALIC((CtkStock)"ctk-italic"), "format-text-italic");
575 register_stock_icon (factory, CTK_STOCK_STRIKETHROUGH((CtkStock)"ctk-strikethrough"), "format-text-strikethrough");
576 register_stock_icon (factory, CTK_STOCK_UNDERLINE((CtkStock)"ctk-underline"), "format-text-underline");
577 register_bidi_stock_icon (factory, CTK_STOCK_INDENT((CtkStock)"ctk-indent"), "format-indent-more");
578 register_bidi_stock_icon (factory, CTK_STOCK_UNINDENT((CtkStock)"ctk-unindent"), "format-indent-less");
579 register_stock_icon (factory, CTK_STOCK_GOTO_TOP((CtkStock)"ctk-goto-top"), "go-top");
580 register_stock_icon (factory, CTK_STOCK_DELETE((CtkStock)"ctk-delete"), "edit-delete");
581 register_bidi_stock_icon (factory, CTK_STOCK_UNDELETE((CtkStock)"ctk-undelete"), CTK_STOCK_UNDELETE((CtkStock)"ctk-undelete"));
582 register_bidi_stock_icon (factory, CTK_STOCK_UNDO((CtkStock)"ctk-undo"), "edit-undo");
583 register_stock_icon (factory, CTK_STOCK_GO_UP((CtkStock)"ctk-go-up"), "go-up");
584 register_stock_icon (factory, CTK_STOCK_FILE((CtkStock)"ctk-file"), "text-x-generic");
585 register_stock_icon (factory, CTK_STOCK_DIRECTORY((CtkStock)"ctk-directory"), "folder");
586 register_stock_icon (factory, CTK_STOCK_ABOUT((CtkStock)"ctk-about"), "help-about");
587 register_stock_icon (factory, CTK_STOCK_CONNECT((CtkStock)"ctk-connect"), CTK_STOCK_CONNECT((CtkStock)"ctk-connect"));
588 register_stock_icon (factory, CTK_STOCK_DISCONNECT((CtkStock)"ctk-disconnect"), CTK_STOCK_DISCONNECT((CtkStock)"ctk-disconnect"));
589 register_stock_icon (factory, CTK_STOCK_EDIT((CtkStock)"ctk-edit"), CTK_STOCK_EDIT((CtkStock)"ctk-edit"));
590 register_stock_icon (factory, CTK_STOCK_CAPS_LOCK_WARNING((CtkStock)"ctk-caps-lock-warning"), CTK_STOCK_CAPS_LOCK_WARNING((CtkStock)"ctk-caps-lock-warning"));
591 register_bidi_stock_icon (factory, CTK_STOCK_MEDIA_FORWARD((CtkStock)"ctk-media-forward"), "media-seek-forward");
592 register_bidi_stock_icon (factory, CTK_STOCK_MEDIA_NEXT((CtkStock)"ctk-media-next"), "media-skip-forward");
593 register_stock_icon (factory, CTK_STOCK_MEDIA_PAUSE((CtkStock)"ctk-media-pause"), "media-playback-pause");
594 register_bidi_stock_icon (factory, CTK_STOCK_MEDIA_PLAY((CtkStock)"ctk-media-play"), "media-playback-start");
595 register_bidi_stock_icon (factory, CTK_STOCK_MEDIA_PREVIOUS((CtkStock)"ctk-media-previous"), "media-skip-backward");
596 register_stock_icon (factory, CTK_STOCK_MEDIA_RECORD((CtkStock)"ctk-media-record"), "media-record");
597 register_bidi_stock_icon (factory, CTK_STOCK_MEDIA_REWIND((CtkStock)"ctk-media-rewind"), "media-seek-backward");
598 register_stock_icon (factory, CTK_STOCK_MEDIA_STOP((CtkStock)"ctk-media-stop"), "media-playback-stop");
599 register_stock_icon (factory, CTK_STOCK_INDEX((CtkStock)"ctk-index"), CTK_STOCK_INDEX((CtkStock)"ctk-index"));
600 register_stock_icon (factory, CTK_STOCK_ZOOM_100((CtkStock)"ctk-zoom-100"), "zoom-original");
601 register_stock_icon (factory, CTK_STOCK_ZOOM_IN((CtkStock)"ctk-zoom-in"), "zoom-in");
602 register_stock_icon (factory, CTK_STOCK_ZOOM_OUT((CtkStock)"ctk-zoom-out"), "zoom-out");
603 register_stock_icon (factory, CTK_STOCK_ZOOM_FIT((CtkStock)"ctk-zoom-fit"), "zoom-fit-best");
604 register_stock_icon (factory, CTK_STOCK_SELECT_ALL((CtkStock)"ctk-select-all"), "edit-select-all");
605 register_bidi_stock_icon (factory, CTK_STOCK_CLEAR((CtkStock)"ctk-clear"), "edit-clear");
606 register_stock_icon (factory, CTK_STOCK_SELECT_COLOR((CtkStock)"ctk-select-color"), CTK_STOCK_SELECT_COLOR((CtkStock)"ctk-select-color"));
607 register_stock_icon (factory, CTK_STOCK_COLOR_PICKER((CtkStock)"ctk-color-picker"), CTK_STOCK_COLOR_PICKER((CtkStock)"ctk-color-picker"));
608}
609
610/************************************************************
611 * Icon size handling *
612 ************************************************************/
613
614typedef struct _IconSize IconSize;
615
616struct _IconSize
617{
618 gint size;
619 gchar *name;
620
621 gint width;
622 gint height;
623};
624
625typedef struct _IconAlias IconAlias;
626
627struct _IconAlias
628{
629 gchar *name;
630 gint target;
631};
632
633static GHashTable *icon_aliases = NULL((void*)0);
634static IconSize *icon_sizes = NULL((void*)0);
635static gint icon_sizes_allocated = 0;
636static gint icon_sizes_used = 0;
637
638static void
639init_icon_sizes (void)
640{
641 if (icon_sizes == NULL((void*)0))
642 {
643#define NUM_BUILTIN_SIZES 7
644 gint i;
645
646 icon_aliases = g_hash_table_new (g_str_hash, g_str_equal);
647
648 icon_sizes = g_new (IconSize, NUM_BUILTIN_SIZES)((IconSize *) g_malloc_n ((NUM_BUILTIN_SIZES), sizeof (IconSize
)))
;
649 icon_sizes_allocated = NUM_BUILTIN_SIZES;
650 icon_sizes_used = NUM_BUILTIN_SIZES;
651
652 icon_sizes[CTK_ICON_SIZE_INVALID].size = 0;
653 icon_sizes[CTK_ICON_SIZE_INVALID].name = NULL((void*)0);
654 icon_sizes[CTK_ICON_SIZE_INVALID].width = 0;
655 icon_sizes[CTK_ICON_SIZE_INVALID].height = 0;
656
657 /* the name strings aren't copied since we don't ever remove
658 * icon sizes, so we don't need to know whether they're static.
659 * Even if we did I suppose removing the builtin sizes would be
660 * disallowed.
661 */
662
663 icon_sizes[CTK_ICON_SIZE_MENU].size = CTK_ICON_SIZE_MENU;
664 icon_sizes[CTK_ICON_SIZE_MENU].name = "ctk-menu";
665 icon_sizes[CTK_ICON_SIZE_MENU].width = 16;
666 icon_sizes[CTK_ICON_SIZE_MENU].height = 16;
667
668 icon_sizes[CTK_ICON_SIZE_BUTTON].size = CTK_ICON_SIZE_BUTTON;
669 icon_sizes[CTK_ICON_SIZE_BUTTON].name = "ctk-button";
670 icon_sizes[CTK_ICON_SIZE_BUTTON].width = 16;
671 icon_sizes[CTK_ICON_SIZE_BUTTON].height = 16;
672
673 icon_sizes[CTK_ICON_SIZE_SMALL_TOOLBAR].size = CTK_ICON_SIZE_SMALL_TOOLBAR;
674 icon_sizes[CTK_ICON_SIZE_SMALL_TOOLBAR].name = "ctk-small-toolbar";
675 icon_sizes[CTK_ICON_SIZE_SMALL_TOOLBAR].width = 16;
676 icon_sizes[CTK_ICON_SIZE_SMALL_TOOLBAR].height = 16;
677
678 icon_sizes[CTK_ICON_SIZE_LARGE_TOOLBAR].size = CTK_ICON_SIZE_LARGE_TOOLBAR;
679 icon_sizes[CTK_ICON_SIZE_LARGE_TOOLBAR].name = "ctk-large-toolbar";
680 icon_sizes[CTK_ICON_SIZE_LARGE_TOOLBAR].width = 24;
681 icon_sizes[CTK_ICON_SIZE_LARGE_TOOLBAR].height = 24;
682
683 icon_sizes[CTK_ICON_SIZE_DND].size = CTK_ICON_SIZE_DND;
684 icon_sizes[CTK_ICON_SIZE_DND].name = "ctk-dnd";
685 icon_sizes[CTK_ICON_SIZE_DND].width = 32;
686 icon_sizes[CTK_ICON_SIZE_DND].height = 32;
687
688 icon_sizes[CTK_ICON_SIZE_DIALOG].size = CTK_ICON_SIZE_DIALOG;
689 icon_sizes[CTK_ICON_SIZE_DIALOG].name = "ctk-dialog";
690 icon_sizes[CTK_ICON_SIZE_DIALOG].width = 48;
691 icon_sizes[CTK_ICON_SIZE_DIALOG].height = 48;
692
693 g_assert ((CTK_ICON_SIZE_DIALOG + 1) == NUM_BUILTIN_SIZES)do { if ((CTK_ICON_SIZE_DIALOG + 1) == NUM_BUILTIN_SIZES) ; else
g_assertion_message_expr ("Ctk", "ctkiconfactory.c", 693, ((
const char*) (__func__)), "(CTK_ICON_SIZE_DIALOG + 1) == NUM_BUILTIN_SIZES"
); } while (0)
;
694
695 /* Alias everything to itself. */
696 i = 1; /* skip invalid size */
697 while (i < NUM_BUILTIN_SIZES)
698 {
699 ctk_icon_size_register_alias (icon_sizes[i].name, icon_sizes[i].size);
700
701 ++i;
702 }
703
704#undef NUM_BUILTIN_SIZES
705 }
706}
707
708static gboolean
709icon_size_lookup_intern (CtkIconSize size,
710 gint *widthp,
711 gint *heightp)
712{
713 init_icon_sizes ();
714
715 if (size == (CtkIconSize)-1)
716 return FALSE(0);
717
718 if (size >= icon_sizes_used)
719 return FALSE(0);
720
721 if (size == CTK_ICON_SIZE_INVALID)
722 return FALSE(0);
723
724 if (widthp)
725 *widthp = icon_sizes[size].width;
726
727 if (heightp)
728 *heightp = icon_sizes[size].height;
729
730 return TRUE(!(0));
731}
732
733/**
734 * ctk_icon_size_lookup_for_settings:
735 * @settings: a #CtkSettings object, used to determine
736 * which set of user preferences to used.
737 * @size: (type int): an icon size (#CtkIconSize)
738 * @width: (out) (allow-none): location to store icon width
739 * @height: (out) (allow-none): location to store icon height
740 *
741 * Obtains the pixel size of a semantic icon size, possibly
742 * modified by user preferences for a particular
743 * #CtkSettings. Normally @size would be
744 * #CTK_ICON_SIZE_MENU, #CTK_ICON_SIZE_BUTTON, etc. This function
745 * isn’t normally needed, ctk_widget_render_icon_pixbuf() is the usual
746 * way to get an icon for rendering, then just look at the size of
747 * the rendered pixbuf. The rendered pixbuf may not even correspond to
748 * the width/height returned by ctk_icon_size_lookup(), because themes
749 * are free to render the pixbuf however they like, including changing
750 * the usual size.
751 *
752 * Returns: %TRUE if @size was a valid size
753 *
754 * Since: 2.2
755 */
756gboolean
757ctk_icon_size_lookup_for_settings (CtkSettings *settings,
758 CtkIconSize size,
759 gint *width,
760 gint *height)
761{
762 g_return_val_if_fail (CTK_IS_SETTINGS (settings), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((settings)); GType __t = ((ctk_settings_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_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_SETTINGS (settings)"); return ((0)); } } while (0
)
;
763
764 return icon_size_lookup_intern (size, width, height);
765}
766
767/**
768 * ctk_icon_size_lookup:
769 * @size: (type int): an icon size (#CtkIconSize)
770 * @width: (out) (allow-none): location to store icon width
771 * @height: (out) (allow-none): location to store icon height
772 *
773 * Obtains the pixel size of a semantic icon size @size:
774 * #CTK_ICON_SIZE_MENU, #CTK_ICON_SIZE_BUTTON, etc. This function
775 * isn’t normally needed, ctk_icon_theme_load_icon() is the usual
776 * way to get an icon for rendering, then just look at the size of
777 * the rendered pixbuf. The rendered pixbuf may not even correspond to
778 * the width/height returned by ctk_icon_size_lookup(), because themes
779 * are free to render the pixbuf however they like, including changing
780 * the usual size.
781 *
782 * Returns: %TRUE if @size was a valid size
783 */
784gboolean
785ctk_icon_size_lookup (CtkIconSize size,
786 gint *widthp,
787 gint *heightp)
788{
789 CTK_NOTE (MULTIHEAD,do { if ((ctk_get_debug_flags () & CTK_DEBUG_MULTIHEAD)) {
g_warning ("ctk_icon_size_lookup ()) is not multihead safe")
; }; } while (0)
790 g_warning ("ctk_icon_size_lookup ()) is not multihead safe"))do { if ((ctk_get_debug_flags () & CTK_DEBUG_MULTIHEAD)) {
g_warning ("ctk_icon_size_lookup ()) is not multihead safe")
; }; } while (0)
;
791
792 return icon_size_lookup_intern (size, widthp, heightp);
793}
794
795static CtkIconSize
796icon_size_register_intern (const gchar *name,
797 gint width,
798 gint height)
799{
800 IconAlias *old_alias;
801 CtkIconSize size;
802
803 init_icon_sizes ();
804
805 old_alias = g_hash_table_lookup (icon_aliases, name);
806 if (old_alias && icon_sizes[old_alias->target].width > 0)
807 {
808 g_warning ("Icon size name '%s' already exists", name);
809 return CTK_ICON_SIZE_INVALID;
810 }
811
812 if (old_alias)
813 {
814 size = old_alias->target;
815 }
816 else
817 {
818 if (icon_sizes_used == icon_sizes_allocated)
819 {
820 icon_sizes_allocated *= 2;
821 icon_sizes = g_renew (IconSize, icon_sizes, icon_sizes_allocated)((IconSize *) g_realloc_n (icon_sizes, (icon_sizes_allocated)
, sizeof (IconSize)))
;
822 }
823
824 size = icon_sizes_used++;
825
826 /* alias to self. */
827 ctk_icon_size_register_alias (name, size);
828
829 icon_sizes[size].size = size;
830 icon_sizes[size].name = g_strdup (name)g_strdup_inline (name);
831 }
832
833 icon_sizes[size].width = width;
834 icon_sizes[size].height = height;
835
836 return size;
837}
838
839/**
840 * ctk_icon_size_register:
841 * @name: name of the icon size
842 * @width: the icon width
843 * @height: the icon height
844 *
845 * Registers a new icon size, along the same lines as #CTK_ICON_SIZE_MENU,
846 * etc. Returns the integer value for the size.
847 *
848 * Returns: (type int): integer value representing the size (#CtkIconSize)
849 */
850CtkIconSize
851ctk_icon_size_register (const gchar *name,
852 gint width,
853 gint height)
854{
855 g_return_val_if_fail (name != NULL, 0)do { if ((name != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "name != NULL"); return (
0); } } while (0)
;
856 g_return_val_if_fail (width > 0, 0)do { if ((width > 0)) { } else { g_return_if_fail_warning (
"Ctk", ((const char*) (__func__)), "width > 0"); return (0
); } } while (0)
;
857 g_return_val_if_fail (height > 0, 0)do { if ((height > 0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "height > 0"); return
(0); } } while (0)
;
858
859 return icon_size_register_intern (name, width, height);
860}
861
862/**
863 * ctk_icon_size_register_alias:
864 * @alias: an alias for @target
865 * @target: (type int): an existing icon size (#CtkIconSize)
866 *
867 * Registers @alias as another name for @target.
868 * So calling ctk_icon_size_from_name() with @alias as argument
869 * will return @target.
870 */
871void
872ctk_icon_size_register_alias (const gchar *alias,
873 CtkIconSize target)
874{
875 IconAlias *ia;
876
877 g_return_if_fail (alias != NULL)do { if ((alias != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "alias != NULL"); return
; } } while (0)
;
878
879 init_icon_sizes ();
880
881 if (!icon_size_lookup_intern (target, NULL((void*)0), NULL((void*)0)))
882 g_warning ("ctk_icon_size_register_alias: Icon size %u does not exist", target);
883
884 ia = g_hash_table_lookup (icon_aliases, alias);
885 if (ia)
886 {
887 if (icon_sizes[ia->target].width > 0)
888 {
889 g_warning ("ctk_icon_size_register_alias: Icon size name '%s' already exists", alias);
890 return;
891 }
892
893 ia->target = target;
894 }
895
896 if (!ia)
897 {
898 ia = g_new (IconAlias, 1)((IconAlias *) g_malloc_n ((1), sizeof (IconAlias)));
899 ia->name = g_strdup (alias)g_strdup_inline (alias);
900 ia->target = target;
901
902 g_hash_table_insert (icon_aliases, ia->name, ia);
903 }
904}
905
906/**
907 * ctk_icon_size_from_name:
908 * @name: the name to look up.
909 *
910 * Looks up the icon size associated with @name.
911 *
912 * Returns: (type int): the icon size (#CtkIconSize)
913 */
914CtkIconSize
915ctk_icon_size_from_name (const gchar *name)
916{
917 IconAlias *ia;
918
919 init_icon_sizes ();
920
921 ia = g_hash_table_lookup (icon_aliases, name);
922
923 if (ia && icon_sizes[ia->target].width > 0)
924 return ia->target;
925 else
926 return CTK_ICON_SIZE_INVALID;
927}
928
929/**
930 * ctk_icon_size_get_name:
931 * @size: (type int): a #CtkIconSize.
932 *
933 * Gets the canonical name of the given icon size. The returned string
934 * is statically allocated and should not be freed.
935 *
936 * Returns: the name of the given icon size.
937 */
938const gchar*
939ctk_icon_size_get_name (CtkIconSize size)
940{
941 if (size >= icon_sizes_used)
942 return NULL((void*)0);
943 else
944 return icon_sizes[size].name;
945}
946
947/************************************************************/
948
949/* Icon Set */
950
951struct _CtkIconSet
952{
953 guint ref_count;
954
955 GSList *sources;
956};
957
958/**
959 * ctk_icon_set_new:
960 *
961 * Creates a new #CtkIconSet. A #CtkIconSet represents a single icon
962 * in various sizes and widget states. It can provide a #GdkPixbuf
963 * for a given size and state on request, and automatically caches
964 * some of the rendered #GdkPixbuf objects.
965 *
966 * Normally you would use ctk_widget_render_icon_pixbuf() instead of
967 * using #CtkIconSet directly. The one case where you’d use
968 * #CtkIconSet is to create application-specific icon sets to place in
969 * a #CtkIconFactory.
970 *
971 * Returns: a new #CtkIconSet
972 */
973CtkIconSet*
974ctk_icon_set_new (void)
975{
976 CtkIconSet *icon_set;
977
978 icon_set = g_new (CtkIconSet, 1)((CtkIconSet *) g_malloc_n ((1), sizeof (CtkIconSet)));
6
Memory is allocated
979
980 icon_set->ref_count = 1;
981 icon_set->sources = NULL((void*)0);
982
983 return icon_set;
984}
985
986/**
987 * ctk_icon_set_new_from_pixbuf:
988 * @pixbuf: a #GdkPixbuf
989 *
990 * Creates a new #CtkIconSet with @pixbuf as the default/fallback
991 * source image. If you don’t add any additional #CtkIconSource to the
992 * icon set, all variants of the icon will be created from @pixbuf,
993 * using scaling, pixelation, etc. as required to adjust the icon size
994 * or make the icon look insensitive/prelighted.
995 *
996 * Returns: a new #CtkIconSet
997 */
998CtkIconSet *
999ctk_icon_set_new_from_pixbuf (GdkPixbuf *pixbuf)
1000{
1001 CtkIconSet *set;
1002
1003 CtkIconSource source = CTK_ICON_SOURCE_INIT (TRUE, TRUE, TRUE){ CTK_ICON_SOURCE_EMPTY, { ((void*)0) }, ((void*)0), 0, 0, 0,
(!(0)), (!(0)), (!(0)) }
;
1004
1005 g_return_val_if_fail (pixbuf != NULL, NULL)do { if ((pixbuf != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "pixbuf != NULL"); return
(((void*)0)); } } while (0)
;
1006
1007 set = ctk_icon_set_new ();
1008
1009 ctk_icon_source_set_pixbuf (&source, pixbuf);
1010 ctk_icon_set_add_source (set, &source);
1011 ctk_icon_source_set_pixbuf (&source, NULL((void*)0));
1012
1013 return set;
1014}
1015
1016
1017/**
1018 * ctk_icon_set_ref:
1019 * @icon_set: a #CtkIconSet.
1020 *
1021 * Increments the reference count on @icon_set.
1022 *
1023 * Returns: @icon_set.
1024 */
1025CtkIconSet*
1026ctk_icon_set_ref (CtkIconSet *icon_set)
1027{
1028 g_return_val_if_fail (icon_set != NULL, NULL)do { if ((icon_set != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "icon_set != NULL"); return
(((void*)0)); } } while (0)
;
1029 g_return_val_if_fail (icon_set->ref_count > 0, NULL)do { if ((icon_set->ref_count > 0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "icon_set->ref_count > 0"
); return (((void*)0)); } } while (0)
;
1030
1031 icon_set->ref_count += 1;
1032
1033 return icon_set;
1034}
1035
1036/**
1037 * ctk_icon_set_unref:
1038 * @icon_set: a #CtkIconSet
1039 *
1040 * Decrements the reference count on @icon_set, and frees memory
1041 * if the reference count reaches 0.
1042 */
1043void
1044ctk_icon_set_unref (CtkIconSet *icon_set)
1045{
1046 g_return_if_fail (icon_set != NULL)do { if ((icon_set != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "icon_set != NULL"); return
; } } while (0)
;
9
Taking true branch
10
Loop condition is false. Exiting loop
1047 g_return_if_fail (icon_set->ref_count > 0)do { if ((icon_set->ref_count > 0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "icon_set->ref_count > 0"
); return; } } while (0)
;
11
Assuming field 'ref_count' is > 0
12
Taking true branch
13
Loop condition is false. Exiting loop
1048
1049 icon_set->ref_count -= 1;
1050
1051 if (icon_set->ref_count == 0)
14
Assuming field 'ref_count' is equal to 0
15
Taking true branch
1052 {
1053 GSList *tmp_list = icon_set->sources;
1054 while (tmp_list != NULL((void*)0))
16
Assuming 'tmp_list' is equal to NULL
17
Loop condition is false. Execution continues on line 1060
1055 {
1056 ctk_icon_source_free (tmp_list->data);
1057
1058 tmp_list = tmp_list->next;
1059 }
1060 g_slist_free (icon_set->sources);
1061
1062 g_free (icon_set);
18
Memory is released
1063 }
1064}
1065
1066G_DEFINE_BOXED_TYPE (CtkIconSet, ctk_icon_set,static GType ctk_icon_set_get_type_once (void); GType ctk_icon_set_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_icon_set_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_icon_set_get_type_once (void
) { GType (* _g_register_boxed) (const gchar *, union { CtkIconSet
* (*do_copy_type) (CtkIconSet *); CtkIconSet * (*do_const_copy_type
) (const CtkIconSet *); GBoxedCopyFunc do_copy_boxed; } __attribute__
((__transparent_union__)), union { void (* do_free_type) (CtkIconSet
*); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__
)) ) = g_boxed_type_register_static; GType g_define_type_id =
_g_register_boxed (g_intern_static_string ("CtkIconSet"), ctk_icon_set_ref
, ctk_icon_set_unref); { {{};} } return g_define_type_id; }
1067 ctk_icon_set_ref,static GType ctk_icon_set_get_type_once (void); GType ctk_icon_set_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_icon_set_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_icon_set_get_type_once (void
) { GType (* _g_register_boxed) (const gchar *, union { CtkIconSet
* (*do_copy_type) (CtkIconSet *); CtkIconSet * (*do_const_copy_type
) (const CtkIconSet *); GBoxedCopyFunc do_copy_boxed; } __attribute__
((__transparent_union__)), union { void (* do_free_type) (CtkIconSet
*); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__
)) ) = g_boxed_type_register_static; GType g_define_type_id =
_g_register_boxed (g_intern_static_string ("CtkIconSet"), ctk_icon_set_ref
, ctk_icon_set_unref); { {{};} } return g_define_type_id; }
1068 ctk_icon_set_unref)static GType ctk_icon_set_get_type_once (void); GType ctk_icon_set_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_icon_set_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_icon_set_get_type_once (void
) { GType (* _g_register_boxed) (const gchar *, union { CtkIconSet
* (*do_copy_type) (CtkIconSet *); CtkIconSet * (*do_const_copy_type
) (const CtkIconSet *); GBoxedCopyFunc do_copy_boxed; } __attribute__
((__transparent_union__)), union { void (* do_free_type) (CtkIconSet
*); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__
)) ) = g_boxed_type_register_static; GType g_define_type_id =
_g_register_boxed (g_intern_static_string ("CtkIconSet"), ctk_icon_set_ref
, ctk_icon_set_unref); { {{};} } return g_define_type_id; }
1069
1070/**
1071 * ctk_icon_set_copy:
1072 * @icon_set: a #CtkIconSet
1073 *
1074 * Copies @icon_set by value.
1075 *
1076 * Returns: a new #CtkIconSet identical to the first.
1077 **/
1078CtkIconSet*
1079ctk_icon_set_copy (CtkIconSet *icon_set)
1080{
1081 CtkIconSet *copy;
1082 GSList *tmp_list;
1083
1084 copy = ctk_icon_set_new ();
1085
1086 tmp_list = icon_set->sources;
1087 while (tmp_list != NULL((void*)0))
1088 {
1089 copy->sources = g_slist_prepend (copy->sources,
1090 ctk_icon_source_copy (tmp_list->data));
1091
1092 tmp_list = tmp_list->next;
1093 }
1094
1095 copy->sources = g_slist_reverse (copy->sources);
1096
1097 return copy;
1098}
1099
1100static gboolean
1101sizes_equivalent (CtkIconSize lhs,
1102 CtkIconSize rhs)
1103{
1104 /* We used to consider sizes equivalent if they were
1105 * the same pixel size, but we don't have the CtkSettings
1106 * here, so we can't do that. Plus, it's not clear that
1107 * it is right... it was just a workaround for the fact
1108 * that we register icons by logical size, not pixel size.
1109 */
1110#if 1
1111 return lhs == rhs;
1112#else
1113
1114 gint r_w, r_h, l_w, l_h;
1115
1116 icon_size_lookup_intern (rhs, &r_w, &r_h);
1117 icon_size_lookup_intern (lhs, &l_w, &l_h);
1118
1119 return r_w == l_w && r_h == l_h;
1120#endif
1121}
1122
1123static CtkIconSource *
1124find_best_matching_source (CtkIconSet *icon_set,
1125 CtkTextDirection direction,
1126 CtkStateType state,
1127 CtkIconSize size,
1128 GSList *failed)
1129{
1130 CtkIconSource *source;
1131 GSList *tmp_list;
1132
1133 /* We need to find the best icon source. Direction matters more
1134 * than state, state matters more than size. icon_set->sources
1135 * is sorted according to wildness, so if we take the first
1136 * match we find it will be the least-wild match (if there are
1137 * multiple matches for a given "wildness" then the RC file contained
1138 * dumb stuff, and we end up with an arbitrary matching source)
1139 */
1140
1141 source = NULL((void*)0);
1142 tmp_list = icon_set->sources;
1143 while (tmp_list != NULL((void*)0))
1144 {
1145 CtkIconSource *s = tmp_list->data;
1146
1147 if ((s->any_direction || (s->direction == direction)) &&
1148 (s->any_state || (s->state == state)) &&
1149 (s->any_size || size == (CtkIconSize)-1 || (sizes_equivalent (size, s->size))))
1150 {
1151 if (!g_slist_find (failed, s))
1152 {
1153 source = s;
1154 break;
1155 }
1156 }
1157
1158 tmp_list = tmp_list->next;
1159 }
1160
1161 return source;
1162}
1163
1164static gboolean
1165ensure_filename_pixbuf (CtkIconSet *icon_set,
1166 CtkIconSource *source)
1167{
1168 if (source->filename_pixbuf == NULL((void*)0))
1169 {
1170 GError *error = NULL((void*)0);
1171
1172 source->filename_pixbuf = gdk_pixbuf_new_from_file (source->source.filename, &error);
1173
1174 if (source->filename_pixbuf == NULL((void*)0))
1175 {
1176 /* Remove this icon source so we don't keep trying to
1177 * load it.
1178 */
1179 g_warning ("Error loading icon: %s", error->message);
1180 g_error_free (error);
1181
1182 icon_set->sources = g_slist_remove (icon_set->sources, source);
1183
1184 ctk_icon_source_free (source);
1185
1186 return FALSE(0);
1187 }
1188 }
1189
1190 return TRUE(!(0));
1191}
1192
1193static GdkPixbuf *
1194render_icon_name_pixbuf (CtkIconSource *icon_source,
1195 CtkCssStyle *style,
1196 CtkIconSize size,
1197 gint scale)
1198{
1199 GdkPixbuf *pixbuf;
1200 GdkPixbuf *tmp_pixbuf;
1201 CtkIconTheme *icon_theme;
1202 gint width, height, pixel_size;
1203 gint *sizes, *s, dist;
1204 GError *error = NULL((void*)0);
1205
1206 icon_theme = ctk_css_icon_theme_value_get_icon_theme
1207 (ctk_css_style_get_value (style, CTK_CSS_PROPERTY_ICON_THEME));
1208
1209 if (!ctk_icon_size_lookup (size, &width, &height))
1210 {
1211 if (size == (CtkIconSize)-1)
1212 {
1213 /* Find an available size close to 48 */
1214 sizes = ctk_icon_theme_get_icon_sizes (icon_theme, icon_source->source.icon_name);
1215 dist = 1000;
1216 width = height = 48;
1217 for (s = sizes; *s; s++)
1218 {
1219 if (*s == -1)
1220 {
1221 width = height = 48;
1222 break;
1223 }
1224 if (*s < 48)
1225 {
1226 if (48 - *s < dist)
1227 {
1228 width = height = *s;
1229 dist = 48 - *s;
1230 }
1231 }
1232 else
1233 {
1234 if (*s - 48 < dist)
1235 {
1236 width = height = *s;
1237 dist = *s - 48;
1238 }
1239 }
1240 }
1241
1242 g_free (sizes);
1243 }
1244 else
1245 {
1246 g_warning ("Invalid icon size %u\n", size);
1247 width = height = 24;
1248 }
1249 }
1250
1251 pixel_size = MIN (width, height)(((width) < (height)) ? (width) : (height));
1252
1253 if (icon_source->direction != CTK_TEXT_DIR_NONE)
1254 {
1255 gchar *suffix[3] = { NULL((void*)0), "-ltr", "-rtl" };
1256 gchar *names[3];
1257 CtkIconInfo *info;
1258
1259 names[0] = g_strconcat (icon_source->source.icon_name, suffix[icon_source->direction], NULL((void*)0));
1260 names[1] = icon_source->source.icon_name;
1261 names[2] = NULL((void*)0);
1262
1263 info = ctk_icon_theme_choose_icon_for_scale (icon_theme,
1264 (const char **) names,
1265 pixel_size, scale,
1266 CTK_ICON_LOOKUP_USE_BUILTIN);
1267 g_free (names[0]);
1268 if (info)
1269 {
1270 tmp_pixbuf = ctk_icon_info_load_icon (info, &error);
1271 g_object_unref (info);
1272 }
1273 else
1274 tmp_pixbuf = NULL((void*)0);
1275 }
1276 else
1277 {
1278 tmp_pixbuf = ctk_icon_theme_load_icon_for_scale (icon_theme,
1279 icon_source->source.icon_name,
1280 pixel_size, scale, 0,
1281 &error);
1282 }
1283
1284 if (!tmp_pixbuf)
1285 {
1286 g_warning ("Error loading theme icon '%s' for stock: %s",
1287 icon_source->source.icon_name, error ? error->message : "");
1288 if (error)
1289 g_error_free (error);
1290 return NULL((void*)0);
1291 }
1292
1293 pixbuf = ctk_render_icon_pixbuf_unpacked (tmp_pixbuf,
1294 -1,
1295 ctk_icon_source_get_state_wildcarded (icon_source)
1296 ? _ctk_css_icon_effect_value_get (ctk_css_style_get_value (style, CTK_CSS_PROPERTY_ICON_EFFECT))
1297 : CTK_CSS_ICON_EFFECT_NONE);
1298
1299 if (!pixbuf)
1300 g_warning ("Failed to render icon");
1301
1302 g_object_unref (tmp_pixbuf);
1303
1304 return pixbuf;
1305}
1306
1307static GdkPixbuf *
1308find_and_render_icon_source (CtkIconSet *icon_set,
1309 CtkCssStyle *style,
1310 CtkTextDirection direction,
1311 CtkStateType state,
1312 CtkIconSize size,
1313 gint scale)
1314{
1315 GSList *failed = NULL((void*)0);
1316 GdkPixbuf *pixbuf = NULL((void*)0);
1317
1318 /* We treat failure in two different ways:
1319 *
1320 * A) If loading a source that specifies a filename fails,
1321 * we treat that as permanent, and remove the source
1322 * from the CtkIconSet. (in ensure_filename_pixbuf ()
1323 * B) If loading a themed icon fails, or scaling an icon
1324 * fails, we treat that as transient and will try
1325 * again next time the icon falls out of the cache
1326 * and we need to recreate it.
1327 */
1328 while (pixbuf == NULL((void*)0))
1329 {
1330 CtkIconSource *source = find_best_matching_source (icon_set, direction, state, size, failed);
1331
1332 if (source == NULL((void*)0))
1333 break;
1334
1335 switch (source->type)
1336 {
1337 case CTK_ICON_SOURCE_FILENAME:
1338 if (!ensure_filename_pixbuf (icon_set, source))
1339 break;
1340 /* Fall through */
1341 case CTK_ICON_SOURCE_PIXBUF:
1342 pixbuf = ctk_render_icon_pixbuf_unpacked (ctk_icon_source_get_pixbuf (source),
1343 ctk_icon_source_get_size_wildcarded (source) ? size : -1,
1344 ctk_icon_source_get_state_wildcarded (source)
1345 ? _ctk_css_icon_effect_value_get (
1346 ctk_css_style_get_value (style, CTK_CSS_PROPERTY_ICON_EFFECT))
1347 : CTK_CSS_ICON_EFFECT_NONE);
1348 if (!pixbuf)
1349 {
1350 g_warning ("Failed to render icon");
1351 failed = g_slist_prepend (failed, source);
1352 }
1353
1354 if (scale != 1)
1355 {
1356 GdkPixbuf *tmp = pixbuf;
1357 pixbuf = gdk_pixbuf_scale_simple (pixbuf,
1358 gdk_pixbuf_get_width (pixbuf) * scale,
1359 gdk_pixbuf_get_height (pixbuf) * scale,
1360 GDK_INTERP_BILINEAR);
1361 g_object_unref (tmp);
1362 }
1363 break;
1364 case CTK_ICON_SOURCE_ICON_NAME:
1365 case CTK_ICON_SOURCE_STATIC_ICON_NAME:
1366 pixbuf = render_icon_name_pixbuf (source, style,
1367 size, scale);
1368 if (!pixbuf)
1369 failed = g_slist_prepend (failed, source);
1370 break;
1371 case CTK_ICON_SOURCE_EMPTY:
1372 g_assert_not_reached ()do { g_assertion_message_expr ("Ctk", "ctkiconfactory.c", 1372
, ((const char*) (__func__)), ((void*)0)); } while (0)
;
1373 }
1374 }
1375
1376 g_slist_free (failed);
1377
1378 return pixbuf;
1379}
1380
1381static GdkPixbuf*
1382render_fallback_image (CtkCssStyle *style,
1383 CtkTextDirection direction G_GNUC_UNUSED__attribute__ ((__unused__)),
1384 CtkStateType state G_GNUC_UNUSED__attribute__ ((__unused__)),
1385 CtkIconSize size)
1386{
1387 /* This icon can be used for any direction/state/size */
1388 static CtkIconSource fallback_source = CTK_ICON_SOURCE_INIT (TRUE, TRUE, TRUE){ CTK_ICON_SOURCE_EMPTY, { ((void*)0) }, ((void*)0), 0, 0, 0,
(!(0)), (!(0)), (!(0)) }
;
1389
1390 if (fallback_source.type == CTK_ICON_SOURCE_EMPTY)
1391 {
1392 fallback_source.type = CTK_ICON_SOURCE_STATIC_ICON_NAME;
1393 fallback_source.source.icon_name = (gchar *)"image-missing";
1394 fallback_source.direction = CTK_TEXT_DIR_NONE;
1395 }
1396
1397 return render_icon_name_pixbuf (&fallback_source, style, size, 1);
1398}
1399
1400GdkPixbuf*
1401ctk_icon_set_render_icon_pixbuf_for_scale (CtkIconSet *icon_set,
1402 CtkCssStyle *style,
1403 CtkTextDirection direction,
1404 CtkIconSize size,
1405 gint scale)
1406{
1407 GdkPixbuf *icon = NULL((void*)0);
1408 CtkStateType state;
1409 CtkCssIconEffect effect;
1410
1411 g_return_val_if_fail (icon_set != NULL, NULL)do { if ((icon_set != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "icon_set != NULL"); return
(((void*)0)); } } while (0)
;
1412 g_return_val_if_fail (CTK_IS_CSS_STYLE (style), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) (style); GType __t = ((ctk_css_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_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_CSS_STYLE (style)"); return (((void*)0)); } } while
(0)
;
1413
1414 effect = _ctk_css_icon_effect_value_get
1415 (ctk_css_style_get_value (style, CTK_CSS_PROPERTY_ICON_EFFECT));
1416
1417 switch (effect)
1418 {
1419 default:
1420 g_assert_not_reached ()do { g_assertion_message_expr ("Ctk", "ctkiconfactory.c", 1420
, ((const char*) (__func__)), ((void*)0)); } while (0)
;
1421 case CTK_CSS_ICON_EFFECT_NONE:
1422 state = CTK_STATE_NORMAL;
1423 break;
1424 case CTK_CSS_ICON_EFFECT_HIGHLIGHT:
1425 state = CTK_STATE_PRELIGHT;
1426 break;
1427 case CTK_CSS_ICON_EFFECT_DIM:
1428 state = CTK_STATE_PRELIGHT;
1429 break;
1430 }
1431
1432 if (icon_set->sources)
1433 icon = find_and_render_icon_source (icon_set, style, direction, state,
1434 size, scale);
1435
1436 if (icon == NULL((void*)0))
1437 icon = render_fallback_image (style, direction, state, size);
1438
1439 return icon;
1440}
1441
1442/**
1443 * ctk_icon_set_render_icon_pixbuf:
1444 * @icon_set: a #CtkIconSet
1445 * @context: a #CtkStyleContext
1446 * @size: (type int): icon size (#CtkIconSize). A size of `(CtkIconSize)-1`
1447 * means render at the size of the source and don’t scale.
1448 *
1449 * Renders an icon using ctk_render_icon_pixbuf(). In most cases,
1450 * ctk_widget_render_icon_pixbuf() is better, since it automatically provides
1451 * most of the arguments from the current widget settings. This
1452 * function never returns %NULL; if the icon can’t be rendered
1453 * (perhaps because an image file fails to load), a default "missing
1454 * image" icon will be returned instead.
1455 *
1456 * Returns: (transfer full): a #GdkPixbuf to be displayed
1457 *
1458 * Since: 3.0
1459 */
1460GdkPixbuf *
1461ctk_icon_set_render_icon_pixbuf (CtkIconSet *icon_set,
1462 CtkStyleContext *context,
1463 CtkIconSize size)
1464{
1465 g_return_val_if_fail (icon_set != NULL, NULL)do { if ((icon_set != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "icon_set != NULL"); return
(((void*)0)); } } while (0)
;
1466 g_return_val_if_fail (CTK_IS_STYLE_CONTEXT (context), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((context)); GType __t = ((ctk_style_context_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_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_STYLE_CONTEXT (context)"); return (((
void*)0)); } } while (0)
;
1467
1468 return ctk_icon_set_render_icon_pixbuf_for_scale (icon_set,
1469 ctk_style_context_lookup_style (context),
1470 ctk_style_context_get_direction (context),
1471 size,
1472 1);
1473}
1474
1475/**
1476 * ctk_icon_set_render_icon_surface:
1477 * @icon_set: a #CtkIconSet
1478 * @context: a #CtkStyleContext
1479 * @size: (type int): icon size (#CtkIconSize). A size of `(CtkIconSize)-1`
1480 * means render at the size of the source and don’t scale.
1481 * @scale: the window scale to render for
1482 * @for_window: (allow-none): #CdkWindow to optimize drawing for, or %NULL
1483 *
1484 * Renders an icon using ctk_render_icon_pixbuf() and converts it to a
1485 * cairo surface.
1486 *
1487 * This function never returns %NULL; if the icon can’t be rendered
1488 * (perhaps because an image file fails to load), a default "missing
1489 * image" icon will be returned instead.
1490 *
1491 * Returns: (transfer full): a #cairo_surface_t to be displayed
1492 *
1493 * Since: 3.10
1494 */
1495cairo_surface_t *
1496ctk_icon_set_render_icon_surface (CtkIconSet *icon_set,
1497 CtkStyleContext *context,
1498 CtkIconSize size,
1499 gint scale,
1500 CdkWindow *for_window)
1501{
1502 GdkPixbuf *pixbuf;
1503 cairo_surface_t *surface;
1504
1505 pixbuf = ctk_icon_set_render_icon_pixbuf_for_scale (icon_set,
1506 ctk_style_context_lookup_style (context),
1507 ctk_style_context_get_direction (context),
1508 size,
1509 scale);
1510
1511 surface = cdk_cairo_surface_create_from_pixbuf (pixbuf, scale, for_window);
1512 g_object_unref (pixbuf);
1513
1514 return surface;
1515}
1516
1517/**
1518 * ctk_icon_set_render_icon:
1519 * @icon_set: a #CtkIconSet
1520 * @style: (allow-none): a #CtkStyle associated with @widget, or %NULL
1521 * @direction: text direction
1522 * @state: widget state
1523 * @size: (type int): icon size (#CtkIconSize). A size of `(CtkIconSize)-1`
1524 * means render at the size of the source and don’t scale.
1525 * @widget: (allow-none): widget that will display the icon, or %NULL.
1526 * The only use that is typically made of this
1527 * is to determine the appropriate #CdkScreen.
1528 * @detail: (allow-none): detail to pass to the theme engine, or %NULL.
1529 * Note that passing a detail of anything but %NULL
1530 * will disable caching.
1531 *
1532 * Renders an icon using ctk_style_render_icon(). In most cases,
1533 * ctk_widget_render_icon() is better, since it automatically provides
1534 * most of the arguments from the current widget settings. This
1535 * function never returns %NULL; if the icon can’t be rendered
1536 * (perhaps because an image file fails to load), a default "missing
1537 * image" icon will be returned instead.
1538 *
1539 * Returns: (transfer full): a #GdkPixbuf to be displayed
1540 */
1541GdkPixbuf*
1542ctk_icon_set_render_icon (CtkIconSet *icon_set,
1543 CtkStyle *style,
1544 CtkTextDirection direction,
1545 CtkStateType state,
1546 CtkIconSize size,
1547 CtkWidget *widget,
1548 const char *detail G_GNUC_UNUSED__attribute__ ((__unused__)))
1549{
1550 GdkPixbuf *icon;
1551 CtkStyleContext *context = NULL((void*)0);
1552 CtkStateFlags flags = 0;
1553
1554 g_return_val_if_fail (icon_set != NULL, NULL)do { if ((icon_set != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "icon_set != NULL"); return
(((void*)0)); } } while (0)
;
1555
1556
1557 g_return_val_if_fail (style == NULL || CTK_IS_STYLE (style), NULL)do { if ((style == ((void*)0) || (((__extension__ ({ GTypeInstance
*__inst = (GTypeInstance*) ((style)); GType __t = ((ctk_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_return_if_fail_warning ("Ctk", ((const
char*) (__func__)), "style == NULL || CTK_IS_STYLE (style)")
; return (((void*)0)); } } while (0)
;
1558
1559 if (style && ctk_style_has_context (style))
1560 {
1561 g_object_get (style, "context", &context, NULL((void*)0));
1562 /* g_object_get returns a refed object */
1563 if (context)
1564 g_object_unref (context);
1565 }
1566 else if (widget)
1567 {
1568 context = ctk_widget_get_style_context (widget);
1569 }
1570
1571 if (!context)
1572 return render_fallback_image (ctk_style_context_lookup_style (context), direction, state, size);
1573
1574 ctk_style_context_save (context);
1575
1576 switch (state)
1577 {
1578 case CTK_STATE_PRELIGHT:
1579 flags |= CTK_STATE_FLAG_PRELIGHT;
1580 break;
1581 case CTK_STATE_INSENSITIVE:
1582 flags |= CTK_STATE_FLAG_INSENSITIVE;
1583 break;
1584 default:
1585 break;
1586 }
1587
1588 ctk_style_context_set_state (context, flags);
1589 ctk_style_context_set_direction (context, direction);
1590
1591 icon = ctk_icon_set_render_icon_pixbuf (icon_set, context, size);
1592
1593 ctk_style_context_restore (context);
1594
1595 return icon;
1596}
1597
1598/* Order sources by their "wildness", so that "wilder" sources are
1599 * greater than “specific” sources; for determining ordering,
1600 * direction beats state beats size.
1601 */
1602
1603static int
1604icon_source_compare (gconstpointer ap, gconstpointer bp)
1605{
1606 const CtkIconSource *a = ap;
1607 const CtkIconSource *b = bp;
1608
1609 if (!a->any_direction && b->any_direction)
1610 return -1;
1611 else if (a->any_direction && !b->any_direction)
1612 return 1;
1613 else if (!a->any_state && b->any_state)
1614 return -1;
1615 else if (a->any_state && !b->any_state)
1616 return 1;
1617 else if (!a->any_size && b->any_size)
1618 return -1;
1619 else if (a->any_size && !b->any_size)
1620 return 1;
1621 else
1622 return 0;
1623}
1624
1625/**
1626 * ctk_icon_set_add_source:
1627 * @icon_set: a #CtkIconSet
1628 * @source: a #CtkIconSource
1629 *
1630 * Icon sets have a list of #CtkIconSource, which they use as base
1631 * icons for rendering icons in different states and sizes. Icons are
1632 * scaled, made to look insensitive, etc. in
1633 * ctk_icon_set_render_icon(), but #CtkIconSet needs base images to
1634 * work with. The base images and when to use them are described by
1635 * a #CtkIconSource.
1636 *
1637 * This function copies @source, so you can reuse the same source immediately
1638 * without affecting the icon set.
1639 *
1640 * An example of when you’d use this function: a web browser’s "Back
1641 * to Previous Page" icon might point in a different direction in
1642 * Hebrew and in English; it might look different when insensitive;
1643 * and it might change size depending on toolbar mode (small/large
1644 * icons). So a single icon set would contain all those variants of
1645 * the icon, and you might add a separate source for each one.
1646 *
1647 * You should nearly always add a “default” icon source with all
1648 * fields wildcarded, which will be used as a fallback if no more
1649 * specific source matches. #CtkIconSet always prefers more specific
1650 * icon sources to more generic icon sources. The order in which you
1651 * add the sources to the icon set does not matter.
1652 *
1653 * ctk_icon_set_new_from_pixbuf() creates a new icon set with a
1654 * default icon source based on the given pixbuf.
1655 */
1656void
1657ctk_icon_set_add_source (CtkIconSet *icon_set,
1658 const CtkIconSource *source)
1659{
1660 g_return_if_fail (icon_set != NULL)do { if ((icon_set != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "icon_set != NULL"); return
; } } while (0)
;
1661 g_return_if_fail (source != NULL)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
; } } while (0)
;
1662
1663 if (source->type == CTK_ICON_SOURCE_EMPTY)
1664 {
1665 g_warning ("Useless empty CtkIconSource");
1666 return;
1667 }
1668
1669 icon_set->sources = g_slist_insert_sorted (icon_set->sources,
1670 ctk_icon_source_copy (source),
1671 icon_source_compare);
1672}
1673
1674/**
1675 * ctk_icon_set_get_sizes:
1676 * @icon_set: a #CtkIconSet
1677 * @sizes: (array length=n_sizes) (out) (type int): return location
1678 * for array of sizes (#CtkIconSize)
1679 * @n_sizes: location to store number of elements in returned array
1680 *
1681 * Obtains a list of icon sizes this icon set can render. The returned
1682 * array must be freed with g_free().
1683 */
1684void
1685ctk_icon_set_get_sizes (CtkIconSet *icon_set,
1686 CtkIconSize **sizes,
1687 gint *n_sizes)
1688{
1689 GSList *tmp_list;
1690 gboolean all_sizes = FALSE(0);
1691 GSList *specifics = NULL((void*)0);
1692
1693 g_return_if_fail (icon_set != NULL)do { if ((icon_set != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "icon_set != NULL"); return
; } } while (0)
;
1694 g_return_if_fail (sizes != NULL)do { if ((sizes != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "sizes != NULL"); return
; } } while (0)
;
1695 g_return_if_fail (n_sizes != NULL)do { if ((n_sizes != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "n_sizes != NULL"); return
; } } while (0)
;
1696
1697 tmp_list = icon_set->sources;
1698 while (tmp_list != NULL((void*)0))
1699 {
1700 CtkIconSource *source;
1701
1702 source = tmp_list->data;
1703
1704 if (source->any_size)
1705 {
1706 all_sizes = TRUE(!(0));
1707 break;
1708 }
1709 else
1710 specifics = g_slist_prepend (specifics, GINT_TO_POINTER (source->size)((gpointer) (glong) (source->size)));
1711
1712 tmp_list = tmp_list->next;
1713 }
1714
1715 if (all_sizes)
1716 {
1717 /* Need to find out what sizes exist */
1718 gint i;
1719
1720 init_icon_sizes ();
1721
1722 *sizes = g_new (CtkIconSize, icon_sizes_used)((CtkIconSize *) g_malloc_n ((icon_sizes_used), sizeof (CtkIconSize
)))
;
1723 *n_sizes = icon_sizes_used - 1;
1724
1725 i = 1;
1726 while (i < icon_sizes_used)
1727 {
1728 (*sizes)[i - 1] = icon_sizes[i].size;
1729 ++i;
1730 }
1731 }
1732 else
1733 {
1734 gint i;
1735
1736 *n_sizes = g_slist_length (specifics);
1737 *sizes = g_new (CtkIconSize, *n_sizes)((CtkIconSize *) g_malloc_n ((*n_sizes), sizeof (CtkIconSize)
))
;
1738
1739 i = 0;
1740 tmp_list = specifics;
1741 while (tmp_list != NULL((void*)0))
1742 {
1743 (*sizes)[i] = GPOINTER_TO_INT (tmp_list->data)((gint) (glong) (tmp_list->data));
1744
1745 ++i;
1746 tmp_list = tmp_list->next;
1747 }
1748 }
1749
1750 g_slist_free (specifics);
1751}
1752
1753
1754/**
1755 * ctk_icon_source_new:
1756 *
1757 * Creates a new #CtkIconSource. A #CtkIconSource contains a #GdkPixbuf (or
1758 * image filename) that serves as the base image for one or more of the
1759 * icons in a #CtkIconSet, along with a specification for which icons in the
1760 * icon set will be based on that pixbuf or image file. An icon set contains
1761 * a set of icons that represent “the same” logical concept in different states,
1762 * different global text directions, and different sizes.
1763 *
1764 * So for example a web browser’s “Back to Previous Page” icon might
1765 * point in a different direction in Hebrew and in English; it might
1766 * look different when insensitive; and it might change size depending
1767 * on toolbar mode (small/large icons). So a single icon set would
1768 * contain all those variants of the icon. #CtkIconSet contains a list
1769 * of #CtkIconSource from which it can derive specific icon variants in
1770 * the set.
1771 *
1772 * In the simplest case, #CtkIconSet contains one source pixbuf from
1773 * which it derives all variants. The convenience function
1774 * ctk_icon_set_new_from_pixbuf() handles this case; if you only have
1775 * one source pixbuf, just use that function.
1776 *
1777 * If you want to use a different base pixbuf for different icon
1778 * variants, you create multiple icon sources, mark which variants
1779 * they’ll be used to create, and add them to the icon set with
1780 * ctk_icon_set_add_source().
1781 *
1782 * By default, the icon source has all parameters wildcarded. That is,
1783 * the icon source will be used as the base icon for any desired text
1784 * direction, widget state, or icon size.
1785 *
1786 * Returns: a new #CtkIconSource
1787 */
1788CtkIconSource*
1789ctk_icon_source_new (void)
1790{
1791 CtkIconSource *src;
1792
1793 src = g_new0 (CtkIconSource, 1)((CtkIconSource *) g_malloc0_n ((1), sizeof (CtkIconSource)));
1794
1795 src->direction = CTK_TEXT_DIR_NONE;
1796 src->size = CTK_ICON_SIZE_INVALID;
1797 src->state = CTK_STATE_NORMAL;
1798
1799 src->any_direction = TRUE(!(0));
1800 src->any_state = TRUE(!(0));
1801 src->any_size = TRUE(!(0));
1802
1803 return src;
1804}
1805
1806/**
1807 * ctk_icon_source_copy:
1808 * @source: a #CtkIconSource
1809 *
1810 * Creates a copy of @source; mostly useful for language bindings.
1811 *
1812 * Returns: a new #CtkIconSource
1813 */
1814CtkIconSource*
1815ctk_icon_source_copy (const CtkIconSource *source)
1816{
1817 CtkIconSource *copy;
1818
1819 g_return_val_if_fail (source != NULL, NULL)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
(((void*)0)); } } while (0)
;
1820
1821 copy = g_new (CtkIconSource, 1)((CtkIconSource *) g_malloc_n ((1), sizeof (CtkIconSource)));
1822
1823 *copy = *source;
1824
1825 switch (copy->type)
1826 {
1827 case CTK_ICON_SOURCE_EMPTY:
1828 case CTK_ICON_SOURCE_STATIC_ICON_NAME:
1829 break;
1830 case CTK_ICON_SOURCE_ICON_NAME:
1831 copy->source.icon_name = g_strdup (copy->source.icon_name)g_strdup_inline (copy->source.icon_name);
1832 break;
1833 case CTK_ICON_SOURCE_FILENAME:
1834 copy->source.filename = g_strdup (copy->source.filename)g_strdup_inline (copy->source.filename);
1835 if (copy->filename_pixbuf)
1836 g_object_ref (copy->filename_pixbuf)((__typeof__ (copy->filename_pixbuf)) (g_object_ref) (copy
->filename_pixbuf))
;
1837 break;
1838 case CTK_ICON_SOURCE_PIXBUF:
1839 g_object_ref (copy->source.pixbuf)((__typeof__ (copy->source.pixbuf)) (g_object_ref) (copy->
source.pixbuf))
;
1840 break;
1841 default:
1842 g_assert_not_reached()do { g_assertion_message_expr ("Ctk", "ctkiconfactory.c", 1842
, ((const char*) (__func__)), ((void*)0)); } while (0)
;
1843 }
1844
1845 return copy;
1846}
1847
1848/**
1849 * ctk_icon_source_free:
1850 * @source: a #CtkIconSource
1851 *
1852 * Frees a dynamically-allocated icon source, along with its
1853 * filename, size, and pixbuf fields if those are not %NULL.
1854 */
1855void
1856ctk_icon_source_free (CtkIconSource *source)
1857{
1858 g_return_if_fail (source != NULL)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
; } } while (0)
;
1859
1860 icon_source_clear (source);
1861 g_free (source);
1862}
1863
1864G_DEFINE_BOXED_TYPE (CtkIconSource, ctk_icon_source,static GType ctk_icon_source_get_type_once (void); GType ctk_icon_source_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_icon_source_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_icon_source_get_type_once (void
) { GType (* _g_register_boxed) (const gchar *, union { CtkIconSource
* (*do_copy_type) (CtkIconSource *); CtkIconSource * (*do_const_copy_type
) (const CtkIconSource *); GBoxedCopyFunc do_copy_boxed; } __attribute__
((__transparent_union__)), union { void (* do_free_type) (CtkIconSource
*); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__
)) ) = g_boxed_type_register_static; GType g_define_type_id =
_g_register_boxed (g_intern_static_string ("CtkIconSource"),
ctk_icon_source_copy, ctk_icon_source_free); { {{};} } return
g_define_type_id; }
1865 ctk_icon_source_copy,static GType ctk_icon_source_get_type_once (void); GType ctk_icon_source_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_icon_source_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_icon_source_get_type_once (void
) { GType (* _g_register_boxed) (const gchar *, union { CtkIconSource
* (*do_copy_type) (CtkIconSource *); CtkIconSource * (*do_const_copy_type
) (const CtkIconSource *); GBoxedCopyFunc do_copy_boxed; } __attribute__
((__transparent_union__)), union { void (* do_free_type) (CtkIconSource
*); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__
)) ) = g_boxed_type_register_static; GType g_define_type_id =
_g_register_boxed (g_intern_static_string ("CtkIconSource"),
ctk_icon_source_copy, ctk_icon_source_free); { {{};} } return
g_define_type_id; }
1866 ctk_icon_source_free)static GType ctk_icon_source_get_type_once (void); GType ctk_icon_source_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_icon_source_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_icon_source_get_type_once (void
) { GType (* _g_register_boxed) (const gchar *, union { CtkIconSource
* (*do_copy_type) (CtkIconSource *); CtkIconSource * (*do_const_copy_type
) (const CtkIconSource *); GBoxedCopyFunc do_copy_boxed; } __attribute__
((__transparent_union__)), union { void (* do_free_type) (CtkIconSource
*); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__
)) ) = g_boxed_type_register_static; GType g_define_type_id =
_g_register_boxed (g_intern_static_string ("CtkIconSource"),
ctk_icon_source_copy, ctk_icon_source_free); { {{};} } return
g_define_type_id; }
1867
1868static void
1869icon_source_clear (CtkIconSource *source)
1870{
1871 switch (source->type)
1872 {
1873 case CTK_ICON_SOURCE_EMPTY:
1874 break;
1875 case CTK_ICON_SOURCE_ICON_NAME:
1876 g_free (source->source.icon_name);
1877 /* fall thru */
1878 case CTK_ICON_SOURCE_STATIC_ICON_NAME:
1879 source->source.icon_name = NULL((void*)0);
1880 break;
1881 case CTK_ICON_SOURCE_FILENAME:
1882 g_free (source->source.filename);
1883 source->source.filename = NULL((void*)0);
1884 if (source->filename_pixbuf)
1885 g_object_unref (source->filename_pixbuf);
1886 source->filename_pixbuf = NULL((void*)0);
1887 break;
1888 case CTK_ICON_SOURCE_PIXBUF:
1889 g_object_unref (source->source.pixbuf);
1890 source->source.pixbuf = NULL((void*)0);
1891 break;
1892 default:
1893 g_assert_not_reached()do { g_assertion_message_expr ("Ctk", "ctkiconfactory.c", 1893
, ((const char*) (__func__)), ((void*)0)); } while (0)
;
1894 }
1895
1896 source->type = CTK_ICON_SOURCE_EMPTY;
1897}
1898
1899/**
1900 * ctk_icon_source_set_filename:
1901 * @source: a #CtkIconSource
1902 * @filename: (type filename): image file to use
1903 *
1904 * Sets the name of an image file to use as a base image when creating
1905 * icon variants for #CtkIconSet. The filename must be absolute.
1906 */
1907void
1908ctk_icon_source_set_filename (CtkIconSource *source,
1909 const gchar *filename)
1910{
1911 g_return_if_fail (source != NULL)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
; } } while (0)
;
1912 g_return_if_fail (filename == NULL || g_path_is_absolute (filename))do { if ((filename == ((void*)0) || g_path_is_absolute (filename
))) { } else { g_return_if_fail_warning ("Ctk", ((const char*
) (__func__)), "filename == NULL || g_path_is_absolute (filename)"
); return; } } while (0)
;
1913
1914 if (source->type == CTK_ICON_SOURCE_FILENAME &&
1915 source->source.filename == filename)
1916 return;
1917
1918 icon_source_clear (source);
1919
1920 if (filename != NULL((void*)0))
1921 {
1922 source->type = CTK_ICON_SOURCE_FILENAME;
1923 source->source.filename = g_strdup (filename)g_strdup_inline (filename);
1924 }
1925}
1926
1927/**
1928 * ctk_icon_source_set_icon_name:
1929 * @source: a #CtkIconSource
1930 * @icon_name: (allow-none): name of icon to use
1931 *
1932 * Sets the name of an icon to look up in the current icon theme
1933 * to use as a base image when creating icon variants for #CtkIconSet.
1934 */
1935void
1936ctk_icon_source_set_icon_name (CtkIconSource *source,
1937 const gchar *icon_name)
1938{
1939 g_return_if_fail (source != NULL)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
; } } while (0)
;
1940
1941 if (source->type == CTK_ICON_SOURCE_ICON_NAME &&
1942 source->source.icon_name == icon_name)
1943 return;
1944
1945 icon_source_clear (source);
1946
1947 if (icon_name != NULL((void*)0))
1948 {
1949 source->type = CTK_ICON_SOURCE_ICON_NAME;
1950 source->source.icon_name = g_strdup (icon_name)g_strdup_inline (icon_name);
1951 }
1952}
1953
1954/**
1955 * ctk_icon_source_set_pixbuf:
1956 * @source: a #CtkIconSource
1957 * @pixbuf: pixbuf to use as a source
1958 *
1959 * Sets a pixbuf to use as a base image when creating icon variants
1960 * for #CtkIconSet.
1961 */
1962void
1963ctk_icon_source_set_pixbuf (CtkIconSource *source,
1964 GdkPixbuf *pixbuf)
1965{
1966 g_return_if_fail (source != NULL)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
; } } while (0)
;
1967 g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf))do { if ((pixbuf == ((void*)0) || (((__extension__ ({ GTypeInstance
*__inst = (GTypeInstance*) ((pixbuf)); GType __t = ((gdk_pixbuf_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_return_if_fail_warning ("Ctk", ((const
char*) (__func__)), "pixbuf == NULL || GDK_IS_PIXBUF (pixbuf)"
); return; } } while (0)
;
1968
1969 if (source->type == CTK_ICON_SOURCE_PIXBUF &&
1970 source->source.pixbuf == pixbuf)
1971 return;
1972
1973 icon_source_clear (source);
1974
1975 if (pixbuf != NULL((void*)0))
1976 {
1977 source->type = CTK_ICON_SOURCE_PIXBUF;
1978 source->source.pixbuf = g_object_ref (pixbuf)((__typeof__ (pixbuf)) (g_object_ref) (pixbuf));
1979 }
1980}
1981
1982/**
1983 * ctk_icon_source_get_filename:
1984 * @source: a #CtkIconSource
1985 *
1986 * Retrieves the source filename, or %NULL if none is set. The
1987 * filename is not a copy, and should not be modified or expected to
1988 * persist beyond the lifetime of the icon source.
1989 *
1990 * Returns: (type filename): image filename. This string must not
1991 * be modified or freed.
1992 */
1993const gchar*
1994ctk_icon_source_get_filename (const CtkIconSource *source)
1995{
1996 g_return_val_if_fail (source != NULL, NULL)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
(((void*)0)); } } while (0)
;
1997
1998 if (source->type == CTK_ICON_SOURCE_FILENAME)
1999 return source->source.filename;
2000 else
2001 return NULL((void*)0);
2002}
2003
2004/**
2005 * ctk_icon_source_get_icon_name:
2006 * @source: a #CtkIconSource
2007 *
2008 * Retrieves the source icon name, or %NULL if none is set. The
2009 * icon_name is not a copy, and should not be modified or expected to
2010 * persist beyond the lifetime of the icon source.
2011 *
2012 * Returns: icon name. This string must not be modified or freed.
2013 */
2014const gchar*
2015ctk_icon_source_get_icon_name (const CtkIconSource *source)
2016{
2017 g_return_val_if_fail (source != NULL, NULL)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
(((void*)0)); } } while (0)
;
2018
2019 if (source->type == CTK_ICON_SOURCE_ICON_NAME ||
2020 source->type == CTK_ICON_SOURCE_STATIC_ICON_NAME)
2021 return source->source.icon_name;
2022 else
2023 return NULL((void*)0);
2024}
2025
2026/**
2027 * ctk_icon_source_get_pixbuf:
2028 * @source: a #CtkIconSource
2029 *
2030 * Retrieves the source pixbuf, or %NULL if none is set.
2031 * In addition, if a filename source is in use, this
2032 * function in some cases will return the pixbuf from
2033 * loaded from the filename. This is, for example, true
2034 * for the CtkIconSource passed to the #CtkStyle render_icon()
2035 * virtual function. The reference count on the pixbuf is
2036 * not incremented.
2037 *
2038 * Returns: (transfer none): source pixbuf
2039 */
2040GdkPixbuf*
2041ctk_icon_source_get_pixbuf (const CtkIconSource *source)
2042{
2043 g_return_val_if_fail (source != NULL, NULL)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
(((void*)0)); } } while (0)
;
2044
2045 if (source->type == CTK_ICON_SOURCE_PIXBUF)
2046 return source->source.pixbuf;
2047 else if (source->type == CTK_ICON_SOURCE_FILENAME)
2048 return source->filename_pixbuf;
2049 else
2050 return NULL((void*)0);
2051}
2052
2053/**
2054 * ctk_icon_source_set_direction_wildcarded:
2055 * @source: a #CtkIconSource
2056 * @setting: %TRUE to wildcard the text direction
2057 *
2058 * If the text direction is wildcarded, this source can be used
2059 * as the base image for an icon in any #CtkTextDirection.
2060 * If the text direction is not wildcarded, then the
2061 * text direction the icon source applies to should be set
2062 * with ctk_icon_source_set_direction(), and the icon source
2063 * will only be used with that text direction.
2064 *
2065 * #CtkIconSet prefers non-wildcarded sources (exact matches) over
2066 * wildcarded sources, and will use an exact match when possible.
2067 */
2068void
2069ctk_icon_source_set_direction_wildcarded (CtkIconSource *source,
2070 gboolean setting)
2071{
2072 g_return_if_fail (source != NULL)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
; } } while (0)
;
2073
2074 source->any_direction = setting != FALSE(0);
2075}
2076
2077/**
2078 * ctk_icon_source_set_state_wildcarded:
2079 * @source: a #CtkIconSource
2080 * @setting: %TRUE to wildcard the widget state
2081 *
2082 * If the widget state is wildcarded, this source can be used as the
2083 * base image for an icon in any #CtkStateType. If the widget state
2084 * is not wildcarded, then the state the source applies to should be
2085 * set with ctk_icon_source_set_state() and the icon source will
2086 * only be used with that specific state.
2087 *
2088 * #CtkIconSet prefers non-wildcarded sources (exact matches) over
2089 * wildcarded sources, and will use an exact match when possible.
2090 *
2091 * #CtkIconSet will normally transform wildcarded source images to
2092 * produce an appropriate icon for a given state, for example
2093 * lightening an image on prelight, but will not modify source images
2094 * that match exactly.
2095 */
2096void
2097ctk_icon_source_set_state_wildcarded (CtkIconSource *source,
2098 gboolean setting)
2099{
2100 g_return_if_fail (source != NULL)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
; } } while (0)
;
2101
2102 source->any_state = setting != FALSE(0);
2103}
2104
2105
2106/**
2107 * ctk_icon_source_set_size_wildcarded:
2108 * @source: a #CtkIconSource
2109 * @setting: %TRUE to wildcard the widget state
2110 *
2111 * If the icon size is wildcarded, this source can be used as the base
2112 * image for an icon of any size. If the size is not wildcarded, then
2113 * the size the source applies to should be set with
2114 * ctk_icon_source_set_size() and the icon source will only be used
2115 * with that specific size.
2116 *
2117 * #CtkIconSet prefers non-wildcarded sources (exact matches) over
2118 * wildcarded sources, and will use an exact match when possible.
2119 *
2120 * #CtkIconSet will normally scale wildcarded source images to produce
2121 * an appropriate icon at a given size, but will not change the size
2122 * of source images that match exactly.
2123 */
2124void
2125ctk_icon_source_set_size_wildcarded (CtkIconSource *source,
2126 gboolean setting)
2127{
2128 g_return_if_fail (source != NULL)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
; } } while (0)
;
2129
2130 source->any_size = setting != FALSE(0);
2131}
2132
2133/**
2134 * ctk_icon_source_get_size_wildcarded:
2135 * @source: a #CtkIconSource
2136 *
2137 * Gets the value set by ctk_icon_source_set_size_wildcarded().
2138 *
2139 * Returns: %TRUE if this icon source is a base for any icon size variant
2140 */
2141gboolean
2142ctk_icon_source_get_size_wildcarded (const CtkIconSource *source)
2143{
2144 g_return_val_if_fail (source != NULL, TRUE)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
((!(0))); } } while (0)
;
2145
2146 return source->any_size;
2147}
2148
2149/**
2150 * ctk_icon_source_get_state_wildcarded:
2151 * @source: a #CtkIconSource
2152 *
2153 * Gets the value set by ctk_icon_source_set_state_wildcarded().
2154 *
2155 * Returns: %TRUE if this icon source is a base for any widget state variant
2156 */
2157gboolean
2158ctk_icon_source_get_state_wildcarded (const CtkIconSource *source)
2159{
2160 g_return_val_if_fail (source != NULL, TRUE)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
((!(0))); } } while (0)
;
2161
2162 return source->any_state;
2163}
2164
2165/**
2166 * ctk_icon_source_get_direction_wildcarded:
2167 * @source: a #CtkIconSource
2168 *
2169 * Gets the value set by ctk_icon_source_set_direction_wildcarded().
2170 *
2171 * Returns: %TRUE if this icon source is a base for any text direction variant
2172 */
2173gboolean
2174ctk_icon_source_get_direction_wildcarded (const CtkIconSource *source)
2175{
2176 g_return_val_if_fail (source != NULL, TRUE)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
((!(0))); } } while (0)
;
2177
2178 return source->any_direction;
2179}
2180
2181/**
2182 * ctk_icon_source_set_direction:
2183 * @source: a #CtkIconSource
2184 * @direction: text direction this source applies to
2185 *
2186 * Sets the text direction this icon source is intended to be used
2187 * with.
2188 *
2189 * Setting the text direction on an icon source makes no difference
2190 * if the text direction is wildcarded. Therefore, you should usually
2191 * call ctk_icon_source_set_direction_wildcarded() to un-wildcard it
2192 * in addition to calling this function.
2193 */
2194void
2195ctk_icon_source_set_direction (CtkIconSource *source,
2196 CtkTextDirection direction)
2197{
2198 g_return_if_fail (source != NULL)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
; } } while (0)
;
2199
2200 source->direction = direction;
2201}
2202
2203/**
2204 * ctk_icon_source_set_state:
2205 * @source: a #CtkIconSource
2206 * @state: widget state this source applies to
2207 *
2208 * Sets the widget state this icon source is intended to be used
2209 * with.
2210 *
2211 * Setting the widget state on an icon source makes no difference
2212 * if the state is wildcarded. Therefore, you should usually
2213 * call ctk_icon_source_set_state_wildcarded() to un-wildcard it
2214 * in addition to calling this function.
2215 */
2216void
2217ctk_icon_source_set_state (CtkIconSource *source,
2218 CtkStateType state)
2219{
2220 g_return_if_fail (source != NULL)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
; } } while (0)
;
2221
2222 source->state = state;
2223}
2224
2225/**
2226 * ctk_icon_source_set_size:
2227 * @source: a #CtkIconSource
2228 * @size: (type int): icon size (#CtkIconSize) this source applies to
2229 *
2230 * Sets the icon size this icon source is intended to be used
2231 * with.
2232 *
2233 * Setting the icon size on an icon source makes no difference
2234 * if the size is wildcarded. Therefore, you should usually
2235 * call ctk_icon_source_set_size_wildcarded() to un-wildcard it
2236 * in addition to calling this function.
2237 */
2238void
2239ctk_icon_source_set_size (CtkIconSource *source,
2240 CtkIconSize size)
2241{
2242 g_return_if_fail (source != NULL)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
; } } while (0)
;
2243
2244 source->size = size;
2245}
2246
2247/**
2248 * ctk_icon_source_get_direction:
2249 * @source: a #CtkIconSource
2250 *
2251 * Obtains the text direction this icon source applies to. The return
2252 * value is only useful/meaningful if the text direction is not
2253 * wildcarded.
2254 *
2255 * Returns: text direction this source matches
2256 */
2257CtkTextDirection
2258ctk_icon_source_get_direction (const CtkIconSource *source)
2259{
2260 g_return_val_if_fail (source != NULL, 0)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
(0); } } while (0)
;
2261
2262 return source->direction;
2263}
2264
2265/**
2266 * ctk_icon_source_get_state:
2267 * @source: a #CtkIconSource
2268 *
2269 * Obtains the widget state this icon source applies to. The return
2270 * value is only useful/meaningful if the widget state is not
2271 * wildcarded.
2272 *
2273 * Returns: widget state this source matches
2274 */
2275CtkStateType
2276ctk_icon_source_get_state (const CtkIconSource *source)
2277{
2278 g_return_val_if_fail (source != NULL, 0)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
(0); } } while (0)
;
2279
2280 return source->state;
2281}
2282
2283/**
2284 * ctk_icon_source_get_size:
2285 * @source: a #CtkIconSource
2286 *
2287 * Obtains the icon size this source applies to. The return value
2288 * is only useful/meaningful if the icon size is not wildcarded.
2289 *
2290 * Returns: (type int): icon size (#CtkIconSize) this source matches.
2291 */
2292CtkIconSize
2293ctk_icon_source_get_size (const CtkIconSource *source)
2294{
2295 g_return_val_if_fail (source != NULL, 0)do { if ((source != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "source != NULL"); return
(0); } } while (0)
;
2296
2297 return source->size;
2298}
2299
2300/**
2301 * _ctk_icon_factory_list_ids:
2302 *
2303 * Gets all known IDs stored in an existing icon factory.
2304 * The strings in the returned list aren’t copied.
2305 * The list itself should be freed.
2306 *
2307 * Returns: List of ids in icon factories
2308 */
2309GList*
2310_ctk_icon_factory_list_ids (void)
2311{
2312 GSList *tmp_list;
2313 GList *ids;
2314
2315 ids = NULL((void*)0);
2316
2317 _ctk_icon_factory_get_default_icons ();
2318
2319 tmp_list = all_icon_factories;
2320 while (tmp_list != NULL((void*)0))
2321 {
2322 GList *these_ids;
2323 CtkIconFactory *factory = CTK_ICON_FACTORY (tmp_list->data)((((CtkIconFactory*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((tmp_list->data)), ((ctk_icon_factory_get_type ())))))
)
;
2324 CtkIconFactoryPrivate *priv = factory->priv;
2325
2326 these_ids = g_hash_table_get_keys (priv->icons);
2327
2328 ids = g_list_concat (ids, these_ids);
2329
2330 tmp_list = tmp_list->next;
2331 }
2332
2333 return ids;
2334}
2335
2336typedef struct {
2337 GSList *sources;
2338 gboolean in_source;
2339
2340} IconFactoryParserData;
2341
2342typedef struct {
2343 gchar *stock_id;
2344 gchar *filename;
2345 gchar *icon_name;
2346 CtkTextDirection direction;
2347 CtkIconSize size;
2348 CtkStateType state;
2349} IconSourceParserData;
2350
2351static void
2352icon_source_start_element (GMarkupParseContext *context,
2353 const gchar *element_name,
2354 const gchar **names,
2355 const gchar **values,
2356 gpointer user_data,
2357 GError **error)
2358{
2359 gint i;
2360 gchar *stock_id = NULL((void*)0);
2361 gchar *filename = NULL((void*)0);
2362 gchar *icon_name = NULL((void*)0);
2363 gint size = -1;
2364 gint direction = -1;
2365 gint state = -1;
2366 IconFactoryParserData *parser_data;
2367 IconSourceParserData *source_data;
2368 gchar *error_msg;
2369 GQuark error_domain;
2370
2371 parser_data = (IconFactoryParserData*)user_data;
2372
2373 if (!parser_data->in_source)
2374 {
2375 if (strcmp (element_name, "sources") != 0)
2376 {
2377 error_msg = g_strdup_printf ("Unexpected element %s, expected <sources>", element_name);
2378 error_domain = CTK_BUILDER_ERROR_INVALID_TAG;
2379 goto error;
2380 }
2381 parser_data->in_source = TRUE(!(0));
2382 return;
2383 }
2384 else
2385 {
2386 if (strcmp (element_name, "source") != 0)
2387 {
2388 error_msg = g_strdup_printf ("Unexpected element %s, expected <source>", element_name);
2389 error_domain = CTK_BUILDER_ERROR_INVALID_TAG;
2390 goto error;
2391 }
2392 }
2393
2394 for (i = 0; names[i]; i++)
2395 {
2396 if (strcmp (names[i], "stock-id") == 0)
2397 stock_id = g_strdup (values[i])g_strdup_inline (values[i]);
2398 else if (strcmp (names[i], "filename") == 0)
2399 filename = g_strdup (values[i])g_strdup_inline (values[i]);
2400 else if (strcmp (names[i], "icon-name") == 0)
2401 icon_name = g_strdup (values[i])g_strdup_inline (values[i]);
2402 else if (strcmp (names[i], "size") == 0)
2403 {
2404 if (!_ctk_builder_enum_from_string (CTK_TYPE_ICON_SIZE(ctk_icon_size_get_type ()),
2405 values[i],
2406 &size,
2407 error))
2408 return;
2409 }
2410 else if (strcmp (names[i], "direction") == 0)
2411 {
2412 if (!_ctk_builder_enum_from_string (CTK_TYPE_TEXT_DIRECTION(ctk_text_direction_get_type ()),
2413 values[i],
2414 &direction,
2415 error))
2416 return;
2417 }
2418 else if (strcmp (names[i], "state") == 0)
2419 {
2420 if (!_ctk_builder_enum_from_string (CTK_TYPE_STATE_TYPE(ctk_state_type_get_type ()),
2421 values[i],
2422 &state,
2423 error))
2424 return;
2425 }
2426 else
2427 {
2428 error_msg = g_strdup_printf ("'%s' is not a valid attribute of <%s>",
2429 names[i], "source");
2430 error_domain = CTK_BUILDER_ERROR_INVALID_ATTRIBUTE;
2431 goto error;
2432 }
2433 }
2434
2435 if (!stock_id)
2436 {
2437 error_msg = g_strdup_printf ("<source> requires a stock_id");
2438 error_domain = CTK_BUILDER_ERROR_MISSING_ATTRIBUTE;
2439 goto error;
2440 }
2441
2442 source_data = g_slice_new (IconSourceParserData)((IconSourceParserData*) g_slice_alloc (sizeof (IconSourceParserData
)))
;
2443 source_data->stock_id = stock_id;
2444 source_data->filename = filename;
2445 source_data->icon_name = icon_name;
2446 source_data->size = size;
2447 source_data->direction = direction;
2448 source_data->state = state;
2449
2450 parser_data->sources = g_slist_prepend (parser_data->sources, source_data);
2451 return;
2452
2453 error:
2454 {
2455 gchar *tmp;
2456 gint line_number, char_number;
2457
2458 g_markup_parse_context_get_position (context, &line_number, &char_number);
2459
2460 tmp = g_strdup_printf ("%s:%d:%d %s", "input",
2461 line_number, char_number, error_msg);
2462 g_set_error_literal (error, CTK_BUILDER_ERROR(ctk_builder_error_quark ()), error_domain, tmp);
2463 g_free (tmp);
2464 g_free (stock_id);
2465 g_free (filename);
2466 g_free (icon_name);
2467 return;
2468 }
2469}
2470
2471static const GMarkupParser icon_source_parser =
2472 {
2473 .start_element = icon_source_start_element,
2474 };
2475
2476static gboolean
2477ctk_icon_factory_buildable_custom_tag_start (CtkBuildable *buildable,
2478 CtkBuilder *builder G_GNUC_UNUSED__attribute__ ((__unused__)),
2479 GObject *child G_GNUC_UNUSED__attribute__ ((__unused__)),
2480 const gchar *tagname,
2481 GMarkupParser *parser,
2482 gpointer *data)
2483{
2484 g_assert (buildable)do { if (buildable) ; else g_assertion_message_expr ("Ctk", "ctkiconfactory.c"
, 2484, ((const char*) (__func__)), "buildable"); } while (0)
;
2485
2486 if (strcmp (tagname, "sources") == 0)
2487 {
2488 IconFactoryParserData *parser_data;
2489
2490 parser_data = g_slice_new0 (IconFactoryParserData)((IconFactoryParserData*) g_slice_alloc0 (sizeof (IconFactoryParserData
)))
;
2491 *parser = icon_source_parser;
2492 *data = parser_data;
2493 return TRUE(!(0));
2494 }
2495 return FALSE(0);
2496}
2497
2498static void
2499ctk_icon_factory_buildable_custom_tag_end (CtkBuildable *buildable,
2500 CtkBuilder *builder,
2501 GObject *child G_GNUC_UNUSED__attribute__ ((__unused__)),
2502 const gchar *tagname,
2503 gpointer *user_data)
2504{
2505 CtkIconFactory *icon_factory;
2506
2507 icon_factory = CTK_ICON_FACTORY (buildable)((((CtkIconFactory*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), ((ctk_icon_factory_get_type ()))))))
;
2508
2509 if (strcmp (tagname, "sources") == 0)
1
Taking true branch
2510 {
2511 IconFactoryParserData *parser_data;
2512 CtkIconSource *icon_source;
2513 CtkIconSet *icon_set;
2514 GSList *l;
2515
2516 parser_data = (IconFactoryParserData*)user_data;
2517
2518 for (l = parser_data->sources; l; l = l->next)
2
Loop condition is true. Entering loop body
2519 {
2520 IconSourceParserData *source_data = l->data;
2521
2522 icon_set = ctk_icon_factory_lookup (icon_factory, source_data->stock_id);
2523 if (!icon_set)
3
Assuming 'icon_set' is null
4
Taking true branch
2524 {
2525 icon_set = ctk_icon_set_new ();
5
Calling 'ctk_icon_set_new'
7
Returned allocated memory
2526 ctk_icon_factory_add (icon_factory, source_data->stock_id, icon_set);
2527 ctk_icon_set_unref (icon_set);
8
Calling 'ctk_icon_set_unref'
19
Returning; memory was released via 1st parameter
2528 }
2529
2530 icon_source = ctk_icon_source_new ();
2531
2532 if (source_data->filename)
20
Assuming field 'filename' is null
21
Taking false branch
2533 {
2534 gchar *filename;
2535 filename = _ctk_builder_get_absolute_filename (builder, source_data->filename);
2536 ctk_icon_source_set_filename (icon_source, filename);
2537 g_free (filename);
2538 }
2539 if (source_data->icon_name)
22
Assuming field 'icon_name' is non-null
23
Taking true branch
2540 ctk_icon_source_set_icon_name (icon_source, source_data->icon_name);
2541 if ((gint)source_data->size != -1)
24
Assuming the condition is false
25
Taking false branch
2542 {
2543 ctk_icon_source_set_size (icon_source, source_data->size);
2544 ctk_icon_source_set_size_wildcarded (icon_source, FALSE(0));
2545 }
2546 if ((gint)source_data->direction != -1)
26
Assuming the condition is false
27
Taking false branch
2547 {
2548 ctk_icon_source_set_direction (icon_source, source_data->direction);
2549 ctk_icon_source_set_direction_wildcarded (icon_source, FALSE(0));
2550 }
2551 if ((gint)source_data->state != -1)
28
Assuming the condition is false
29
Taking false branch
2552 {
2553 ctk_icon_source_set_state (icon_source, source_data->state);
2554 ctk_icon_source_set_state_wildcarded (icon_source, FALSE(0));
2555 }
2556
2557 /* Inline source_add() to avoid creating a copy */
2558 g_assert (icon_source->type != CTK_ICON_SOURCE_EMPTY)do { if (icon_source->type != CTK_ICON_SOURCE_EMPTY) ; else
g_assertion_message_expr ("Ctk", "ctkiconfactory.c", 2558, (
(const char*) (__func__)), "icon_source->type != CTK_ICON_SOURCE_EMPTY"
); } while (0)
;
30
Taking true branch
31
Loop condition is false. Exiting loop
2559 icon_set->sources = g_slist_insert_sorted (icon_set->sources,
32
Use of memory after it is freed
2560 icon_source,
2561 icon_source_compare);
2562
2563 g_free (source_data->stock_id);
2564 g_free (source_data->filename);
2565 g_free (source_data->icon_name);
2566 g_slice_free (IconSourceParserData, source_data)do { if (1) g_slice_free1 (sizeof (IconSourceParserData), (source_data
)); else (void) ((IconSourceParserData*) 0 == (source_data));
} while (0)
;
2567 }
2568 g_slist_free (parser_data->sources);
2569 g_slice_free (IconFactoryParserData, parser_data)do { if (1) g_slice_free1 (sizeof (IconFactoryParserData), (parser_data
)); else (void) ((IconFactoryParserData*) 0 == (parser_data))
; } while (0)
;
2570
2571 /* TODO: Add an attribute/tag to prevent this.
2572 * Usually it's the right thing to do though.
2573 */
2574 ctk_icon_factory_add_default (icon_factory);
2575 }
2576}