Bug Summary

File:capplets/common/theme-thumbnail.c
Warning:line 934, column 3
This statement is never executed

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 theme-thumbnail.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/capplets/common -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I ../.. -D CAFECC_DATA_DIR="/usr/local/share/cafe-control-center" -D CAFELOCALEDIR="/usr/local/share/locale" -D CTK_ENGINE_DIR="/usr/lib/x86_64-linux-gnu/ctk-3.0/3.0.0/theming-engines" -D G_LOG_DOMAIN="capplet-common" -D INSTALL_PREFIX="/usr/local" -I ../.. -I ../../libwindow-settings -D PIXMAP_DIR="/usr/local/share/cafe-control-center/pixmaps" -I /usr/include/ctk-3.0 -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/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/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -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/libxml2 -I /usr/include/cafe-desktop-2.0 -I /usr/include/startup-notification-1.0 -I /usr/include/dconf -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/cafe-desktop-2.0 -I /usr/include/ctk-3.0 -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/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/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -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/startup-notification-1.0 -I /usr/include/dconf -I /usr/include/croma-1 -I /usr/include/ctk-3.0 -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/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/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -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/cafe-settings-daemon -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/dconf -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -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/13/../../../../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/capplets/common -ferror-limit 19 -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/2023-10-26-092734-110513-1 -x c theme-thumbnail.c
1#include <config.h>
2#include <unistd.h>
3#include <string.h>
4#include <croma-private/util.h>
5#include <croma-private/theme.h>
6#include <croma-private/theme-parser.h>
7#include <croma-private/preview-widget.h>
8#include <signal.h>
9#include <errno(*__errno_location ()).h>
10#include <math.h>
11
12/* We have to #undef this as croma #defines these. */
13#undef _
14#undef N_
15
16#include <glib.h>
17
18#include "theme-thumbnail.h"
19#include "ctkrc-utils.h"
20#include "capplet-util.h"
21
22
23typedef struct {
24 gboolean set;
25 gint thumbnail_width;
26 gint thumbnail_height;
27 GByteArray* data;
28 gchar* theme_name;
29 ThemeThumbnailFunc func;
30 gpointer user_data;
31 GDestroyNotify destroy;
32 GIOChannel* channel;
33 guint watch_id;
34} ThemeThumbnailAsyncData;
35
36
37static ThemeThumbnailAsyncData async_data;
38
39/* Protocol */
40
41/* Our protocol is pretty simple. The parent process will write several strings
42 * (separated by a '\000'). They are the widget theme, the wm theme, the icon
43 * theme, etc. Then, it will wait for the child to write back the data. The
44 * parent expects ICON_SIZE_WIDTH * ICON_SIZE_HEIGHT * 4 bytes of information.
45 * After that, the child is ready for the next theme to render.
46 */
47
48enum {
49 READY_FOR_THEME,
50 READING_TYPE,
51 READING_CONTROL_THEME_NAME,
52 READING_CTK_COLOR_SCHEME,
53 READING_WM_THEME_NAME,
54 READING_ICON_THEME_NAME,
55 READING_APPLICATION_FONT,
56 WRITING_PIXBUF_DATA
57};
58
59typedef struct {
60 gint status;
61 GByteArray* type;
62 GByteArray* control_theme_name;
63 GByteArray* ctk_color_scheme;
64 GByteArray* wm_theme_name;
65 GByteArray* icon_theme_name;
66 GByteArray* application_font;
67} ThemeThumbnailData;
68
69typedef struct {
70 gchar* thumbnail_type;
71 gpointer theme_info;
72 ThemeThumbnailFunc func;
73 gpointer user_data;
74 GDestroyNotify destroy;
75} ThemeQueueItem;
76
77static GList* theme_queue = NULL((void*)0);
78
79static int pipe_to_factory_fd[2];
80static int pipe_from_factory_fd[2];
81
82#define THUMBNAIL_TYPE_META"meta" "meta"
83#define THUMBNAIL_TYPE_CTK"ctk" "ctk"
84#define THUMBNAIL_TYPE_CROMA"croma" "croma"
85#define THUMBNAIL_TYPE_ICON"icon" "icon"
86
87#define META_THUMBNAIL_SIZE128 128
88#define CTK_THUMBNAIL_SIZE96 96
89#define CROMA_THUMBNAIL_WIDTH120 120
90#define CROMA_THUMBNAIL_HEIGHT60 60
91
92
93static void pixbuf_apply_mask_region(GdkPixbuf* pixbuf, cairo_region_t* region)
94{
95 gint nchannels, rowstride, w, h;
96 guchar *pixels, *p;
97
98 g_return_if_fail (pixbuf)do { if ((pixbuf)) { } else { g_return_if_fail_warning ("capplet-common"
, ((const char*) (__func__)), "pixbuf"); return; } } while (0
)
;
99 g_return_if_fail (region)do { if ((region)) { } else { g_return_if_fail_warning ("capplet-common"
, ((const char*) (__func__)), "region"); return; } } while (0
)
;
100
101 nchannels = gdk_pixbuf_get_n_channels (pixbuf);
102 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
103 pixels = gdk_pixbuf_get_pixels (pixbuf);
104
105
106 /* we need an alpha channel ... */
107 if (!gdk_pixbuf_get_has_alpha (pixbuf) || nchannels != 4)
108 return;
109
110 for (w = 0; w < gdk_pixbuf_get_width (pixbuf); ++w)
111 for (h = 0; h < gdk_pixbuf_get_height (pixbuf); ++h)
112 {
113 if (!cairo_region_contains_point (region, w, h))
114 {
115 p = pixels + h * rowstride + w * nchannels;
116 if (G_BYTE_ORDER1234 == G_BIG_ENDIAN4321)
117 p[0] = 0x0;
118 else
119 p[3] = 0x0;
120 }
121 }
122
123}
124
125static GdkPixbuf *
126create_folder_icon (char *icon_theme_name)
127{
128 CtkIconTheme *icon_theme;
129 GdkPixbuf *folder_icon = NULL((void*)0);
130 CtkIconInfo *folder_icon_info;
131 gchar *example_icon_name;
132 const gchar *icon_names[5];
133 gint i;
134
135 icon_theme = ctk_icon_theme_new ();
136 ctk_icon_theme_set_custom_theme (icon_theme, icon_theme_name);
137
138 i = 0;
139 /* Get the Example icon name in the theme if specified */
140 example_icon_name = ctk_icon_theme_get_example_icon_name (icon_theme);
141 if (example_icon_name != NULL((void*)0))
142 icon_names[i++] = example_icon_name;
143 icon_names[i++] = "x-directory-normal";
144 icon_names[i++] = "cafe-fs-directory";
145 icon_names[i++] = "folder";
146 icon_names[i++] = NULL((void*)0);
147
148 folder_icon_info = ctk_icon_theme_choose_icon (icon_theme, icon_names, 48, CTK_ICON_LOOKUP_FORCE_SIZE);
149 if (folder_icon_info != NULL((void*)0))
150 {
151 folder_icon = ctk_icon_info_load_icon (folder_icon_info, NULL((void*)0));
152 g_object_unref (folder_icon_info);
153 }
154
155 if (folder_icon == NULL((void*)0))
156 {
157 folder_icon = ctk_icon_theme_load_icon (icon_theme,
158 "image-missing",
159 48, 0, NULL((void*)0));
160 }
161
162 g_object_unref (icon_theme);
163 g_free (example_icon_name);
164
165 return folder_icon;
166}
167
168static GdkPixbuf *
169create_meta_theme_pixbuf (ThemeThumbnailData *theme_thumbnail_data)
170{
171 CtkWidget *window;
172 CtkWidget *preview;
173 CtkWidget *vbox;
174 CtkWidget *box;
175 CtkWidget *image_button;
176 CtkWidget *checkbox;
177 CtkWidget *radio;
178
179 CtkRequisition requisition;
180 CtkAllocation allocation;
181 CtkAllocation vbox_allocation;
182 MetaFrameFlags flags;
183 MetaTheme *theme;
184 GdkPixbuf *pixbuf, *icon;
185 int icon_width, icon_height;
186 cairo_region_t *region;
187
188 g_object_set (ctk_settings_get_default (),
189 "ctk-theme-name", (char *) theme_thumbnail_data->control_theme_name->data,
190 "ctk-font-name", (char *) theme_thumbnail_data->application_font->data,
191 "ctk-icon-theme-name", (char *) theme_thumbnail_data->icon_theme_name->data,
192 "ctk-color-scheme", (char *) theme_thumbnail_data->ctk_color_scheme->data,
193 NULL((void*)0));
194
195 theme = meta_theme_load ((char *) theme_thumbnail_data->wm_theme_name->data, NULL((void*)0));
196 if (theme == NULL((void*)0))
197 return NULL((void*)0);
198
199 /* Represent the icon theme */
200 icon = create_folder_icon ((char *) theme_thumbnail_data->icon_theme_name->data);
201 icon_width = gdk_pixbuf_get_width (icon);
202 icon_height = gdk_pixbuf_get_height (icon);
203
204 /* Create a fake window */
205 flags = META_FRAME_ALLOWS_DELETE |
206 META_FRAME_ALLOWS_MENU |
207 META_FRAME_ALLOWS_MINIMIZE |
208 META_FRAME_ALLOWS_MAXIMIZE |
209 META_FRAME_ALLOWS_VERTICAL_RESIZE |
210 META_FRAME_ALLOWS_HORIZONTAL_RESIZE |
211 META_FRAME_HAS_FOCUS |
212 META_FRAME_ALLOWS_SHADE |
213 META_FRAME_ALLOWS_MOVE;
214
215 window = ctk_offscreen_window_new ();
216 preview = meta_preview_new ();
217 ctk_container_add (CTK_CONTAINER (window)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_container_get_type ()))))))
, preview);
218 ctk_widget_show_all (window);
219
220 vbox = ctk_box_new (CTK_ORIENTATION_VERTICAL, 6);
221 ctk_container_set_border_width (CTK_CONTAINER (vbox)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((vbox)), ((ctk_container_get_type ()))))))
, 6);
222 ctk_container_add (CTK_CONTAINER (preview)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), ((ctk_container_get_type ()))))))
, vbox);
223
224 image_button = ctk_button_new_with_mnemonic (_("_Open")gettext ("_Open"));
225 ctk_button_set_image (CTK_BUTTON (image_button)((((CtkButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((image_button)), ((ctk_button_get_type ()))))))
, ctk_image_new_from_icon_name ("document-open", CTK_ICON_SIZE_BUTTON));
226
227 ctk_widget_set_halign (image_button, CTK_ALIGN_START);
228 ctk_widget_set_valign (image_button, CTK_ALIGN_START);
229 ctk_widget_show (image_button);
230 ctk_box_pack_start (CTK_BOX (vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((vbox)), ((ctk_box_get_type ()))))))
, image_button, FALSE(0), FALSE(0), 0);
231 box = ctk_box_new (CTK_ORIENTATION_HORIZONTAL, 0);
232 ctk_box_pack_start (CTK_BOX (vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((vbox)), ((ctk_box_get_type ()))))))
, box, FALSE(0), FALSE(0), 0);
233 checkbox = ctk_check_button_new ();
234 ctk_toggle_button_set_active (CTK_TOGGLE_BUTTON (checkbox)((((CtkToggleButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((checkbox)), ((ctk_toggle_button_get_type ()))))))
, TRUE(!(0)));
235 ctk_box_pack_start (CTK_BOX (box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((box)), ((ctk_box_get_type ()))))))
, checkbox, FALSE(0), FALSE(0), 0);
236 radio = ctk_radio_button_new (NULL((void*)0));
237 ctk_box_pack_start (CTK_BOX (box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((box)), ((ctk_box_get_type ()))))))
, radio, FALSE(0), FALSE(0), 0);
238
239 ctk_widget_show_all (preview);
240
241 meta_preview_set_frame_flags (META_PREVIEW (preview)((((MetaPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), ((meta_preview_get_type ()))))))
, flags);
242 meta_preview_set_theme (META_PREVIEW (preview)((((MetaPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), ((meta_preview_get_type ()))))))
, theme);
243 meta_preview_set_title (META_PREVIEW (preview)((((MetaPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), ((meta_preview_get_type ()))))))
, "");
244
245 ctk_window_set_default_size (CTK_WINDOW (window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_window_get_type ()))))))
, META_THUMBNAIL_SIZE128, META_THUMBNAIL_SIZE128);
246
247 ctk_widget_get_preferred_size (window, &requisition, NULL((void*)0));
248 allocation.x = 0;
249 allocation.y = 0;
250 allocation.width = META_THUMBNAIL_SIZE128;
251 allocation.height = META_THUMBNAIL_SIZE128;
252 ctk_widget_size_allocate (window, &allocation);
253 ctk_widget_get_preferred_size (window, &requisition, NULL((void*)0));
254
255 ctk_widget_queue_draw (window);
256 while (ctk_events_pending ())
257 ctk_main_iteration ();
258
259 pixbuf = ctk_offscreen_window_get_pixbuf (CTK_OFFSCREEN_WINDOW (window)((((CtkOffscreenWindow*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((window)), ((ctk_offscreen_window_get_type (
)))))))
);
260
261 ctk_widget_get_allocation (vbox, &vbox_allocation);
262
263 /* Add the icon theme to the pixbuf */
264 gdk_pixbuf_composite (icon, pixbuf,
265 vbox_allocation.x + vbox_allocation.width - icon_width - 5,
266 vbox_allocation.y + vbox_allocation.height - icon_height - 5,
267 icon_width, icon_height,
268 vbox_allocation.x + vbox_allocation.width - icon_width - 5,
269 vbox_allocation.y + vbox_allocation.height - icon_height - 5,
270 1.0, 1.0, GDK_INTERP_BILINEAR, 255);
271 region = meta_preview_get_clip_region (META_PREVIEW (preview)((((MetaPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), ((meta_preview_get_type ()))))))
,
272 META_THUMBNAIL_SIZE128, META_THUMBNAIL_SIZE128);
273 pixbuf_apply_mask_region (pixbuf, region);
274 cairo_region_destroy (region);
275
276 g_object_unref (icon);
277 ctk_widget_destroy (window);
278 meta_theme_free (theme);
279
280 return pixbuf;
281}
282
283static GdkPixbuf *
284create_ctk_theme_pixbuf (ThemeThumbnailData *theme_thumbnail_data)
285{
286 CtkSettings *settings;
287 CtkWidget *window, *vbox, *box, *image_button, *checkbox, *radio;
288 CtkRequisition requisition;
289 CtkAllocation allocation;
290 GdkPixbuf *pixbuf, *retval;
291 gint width, height;
292
293 settings = ctk_settings_get_default ();
294 g_object_set (settings, "ctk-theme-name", (char *) theme_thumbnail_data->control_theme_name->data,
295 "ctk-color-scheme", (char *) theme_thumbnail_data->ctk_color_scheme->data,
296 NULL((void*)0));
297
298 window = ctk_offscreen_window_new ();
299
300 vbox = ctk_box_new (CTK_ORIENTATION_VERTICAL, 0);
301 ctk_container_add (CTK_CONTAINER (window)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_container_get_type ()))))))
, vbox);
302 box = ctk_box_new (CTK_ORIENTATION_HORIZONTAL, 6);
303 ctk_container_set_border_width (CTK_CONTAINER (box)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((box)), ((ctk_container_get_type ()))))))
, 6);
304 ctk_box_pack_start (CTK_BOX (vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((vbox)), ((ctk_box_get_type ()))))))
, box, FALSE(0), FALSE(0), 0);
305
306 image_button = ctk_button_new_with_mnemonic (_("_Open")gettext ("_Open"));
307 ctk_button_set_image (CTK_BUTTON (image_button)((((CtkButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((image_button)), ((ctk_button_get_type ()))))))
, ctk_image_new_from_icon_name ("document-open", CTK_ICON_SIZE_BUTTON));
308
309 ctk_box_pack_start (CTK_BOX (box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((box)), ((ctk_box_get_type ()))))))
, image_button, FALSE(0), FALSE(0), 0);
310 checkbox = ctk_check_button_new ();
311 ctk_toggle_button_set_active (CTK_TOGGLE_BUTTON (checkbox)((((CtkToggleButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((checkbox)), ((ctk_toggle_button_get_type ()))))))
, TRUE(!(0)));
312 ctk_box_pack_start (CTK_BOX (box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((box)), ((ctk_box_get_type ()))))))
, checkbox, FALSE(0), FALSE(0), 0);
313 radio = ctk_radio_button_new_from_widget (NULL((void*)0));
314 ctk_box_pack_start (CTK_BOX (box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((box)), ((ctk_box_get_type ()))))))
, radio, FALSE(0), FALSE(0), 0);
315
316 ctk_widget_show_all (window);
317 ctk_widget_show_all (vbox);
318 ctk_widget_realize (image_button);
319 ctk_widget_realize (ctk_bin_get_child (CTK_BIN (image_button)((((CtkBin*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((image_button)), ((ctk_bin_get_type ()))))))
));
320 ctk_widget_realize (checkbox);
321 ctk_widget_realize (radio);
322 ctk_widget_map (image_button);
323 ctk_widget_map (ctk_bin_get_child (CTK_BIN (image_button)((((CtkBin*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((image_button)), ((ctk_bin_get_type ()))))))
));
324 ctk_widget_map (checkbox);
325 ctk_widget_map (radio);
326
327 ctk_widget_get_preferred_size (window, &requisition, NULL((void*)0));
328 allocation.x = 0;
329 allocation.y = 0;
330 allocation.width = requisition.width;
331 allocation.height = requisition.height;
332 ctk_widget_size_allocate (window, &allocation);
333 ctk_widget_get_preferred_size (window, &requisition, NULL((void*)0));
334
335 ctk_window_get_size (CTK_WINDOW (window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_window_get_type ()))))))
, &width, &height);
336
337 ctk_widget_queue_draw (window);
338 while (ctk_events_pending ())
339 ctk_main_iteration ();
340
341 pixbuf = ctk_offscreen_window_get_pixbuf (CTK_OFFSCREEN_WINDOW (window)((((CtkOffscreenWindow*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((window)), ((ctk_offscreen_window_get_type (
)))))))
);
342
343 retval = gdk_pixbuf_scale_simple (pixbuf,
344 CTK_THUMBNAIL_SIZE96,
345 (int) CTK_THUMBNAIL_SIZE96 * (((double) height) / ((double) width)),
346 GDK_INTERP_BILINEAR);
347 g_object_unref (pixbuf);
348 ctk_widget_destroy (window);
349
350 return retval;
351}
352
353static GdkPixbuf *
354create_croma_theme_pixbuf (ThemeThumbnailData *theme_thumbnail_data)
355{
356 CtkWidget *window, *preview, *dummy;
357 MetaFrameFlags flags;
358 MetaTheme *theme;
359 CtkRequisition requisition;
360 CtkAllocation allocation;
361 GdkPixbuf *pixbuf, *retval;
362 cairo_region_t *region;
363
364 theme = meta_theme_load ((char *) theme_thumbnail_data->wm_theme_name->data, NULL((void*)0));
365 if (theme == NULL((void*)0))
366 return NULL((void*)0);
367
368 flags = META_FRAME_ALLOWS_DELETE |
369 META_FRAME_ALLOWS_MENU |
370 META_FRAME_ALLOWS_MINIMIZE |
371 META_FRAME_ALLOWS_MAXIMIZE |
372 META_FRAME_ALLOWS_VERTICAL_RESIZE |
373 META_FRAME_ALLOWS_HORIZONTAL_RESIZE |
374 META_FRAME_HAS_FOCUS |
375 META_FRAME_ALLOWS_SHADE |
376 META_FRAME_ALLOWS_MOVE;
377
378 window = ctk_offscreen_window_new ();
379 ctk_window_set_default_size (CTK_WINDOW (window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_window_get_type ()))))))
, (int) CROMA_THUMBNAIL_WIDTH120 * 1.2, (int) CROMA_THUMBNAIL_HEIGHT60 * 1.2);
380
381 preview = meta_preview_new ();
382 meta_preview_set_frame_flags (META_PREVIEW (preview)((((MetaPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), ((meta_preview_get_type ()))))))
, flags);
383 meta_preview_set_theme (META_PREVIEW (preview)((((MetaPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), ((meta_preview_get_type ()))))))
, theme);
384 meta_preview_set_title (META_PREVIEW (preview)((((MetaPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), ((meta_preview_get_type ()))))))
, "");
385 ctk_container_add (CTK_CONTAINER (window)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_container_get_type ()))))))
, preview);
386
387 dummy = ctk_label_new ("");
388 ctk_container_add (CTK_CONTAINER (preview)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), ((ctk_container_get_type ()))))))
, dummy);
389
390 ctk_widget_show_all (window);
391
392 ctk_widget_get_preferred_size (window, &requisition, NULL((void*)0));
393 allocation.x = 0;
394 allocation.y = 0;
395 allocation.width = (int) CROMA_THUMBNAIL_WIDTH120 * 1.2;
396 allocation.height = (int) CROMA_THUMBNAIL_HEIGHT60 * 1.2;
397 ctk_widget_size_allocate (window, &allocation);
398 ctk_widget_get_preferred_size (window, &requisition, NULL((void*)0));
399
400 ctk_widget_queue_draw (window);
401 while (ctk_events_pending ())
402 ctk_main_iteration ();
403
404 pixbuf = ctk_offscreen_window_get_pixbuf (CTK_OFFSCREEN_WINDOW (window)((((CtkOffscreenWindow*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((window)), ((ctk_offscreen_window_get_type (
)))))))
);
405
406 region = meta_preview_get_clip_region (META_PREVIEW (preview)((((MetaPreview*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), ((meta_preview_get_type ()))))))
,
407 CROMA_THUMBNAIL_WIDTH120 * 1.2, CROMA_THUMBNAIL_HEIGHT60 * 1.2);
408 pixbuf_apply_mask_region (pixbuf, region);
409 cairo_region_destroy (region);
410
411
412 retval = gdk_pixbuf_scale_simple (pixbuf,
413 CROMA_THUMBNAIL_WIDTH120,
414 CROMA_THUMBNAIL_HEIGHT60,
415 GDK_INTERP_BILINEAR);
416 g_object_unref (pixbuf);
417
418 ctk_widget_destroy (window);
419 meta_theme_free (theme);
420
421 return retval;
422}
423
424static GdkPixbuf *
425create_icon_theme_pixbuf (ThemeThumbnailData *theme_thumbnail_data)
426{
427 return create_folder_icon ((char *) theme_thumbnail_data->icon_theme_name->data);
428}
429
430
431static void
432handle_bytes (const guint8 *buffer,
433 gint bytes_read,
434 ThemeThumbnailData *theme_thumbnail_data)
435{
436 const guint8 *ptr;
437 ptr = buffer;
438
439 while (bytes_read > 0)
440 {
441 guint8 *nil;
442
443 switch (theme_thumbnail_data->status)
444 {
445 case READY_FOR_THEME:
446 theme_thumbnail_data->status = READING_TYPE;
447 /* fall through */
448 case READING_TYPE:
449 nil = memchr (ptr, '\000', bytes_read);
450 if (nil == NULL((void*)0))
451 {
452 g_byte_array_append (theme_thumbnail_data->type, ptr, bytes_read);
453 bytes_read = 0;
454 }
455 else
456 {
457 g_byte_array_append (theme_thumbnail_data->type, ptr, nil - ptr + 1);
458 bytes_read -= (nil - ptr + 1);
459 ptr = nil + 1;
460 theme_thumbnail_data->status = READING_CONTROL_THEME_NAME;
461 }
462 break;
463
464 case READING_CONTROL_THEME_NAME:
465 nil = memchr (ptr, '\000', bytes_read);
466 if (nil == NULL((void*)0))
467 {
468 g_byte_array_append (theme_thumbnail_data->control_theme_name, ptr, bytes_read);
469 bytes_read = 0;
470 }
471 else
472 {
473 g_byte_array_append (theme_thumbnail_data->control_theme_name, ptr, nil - ptr + 1);
474 bytes_read -= (nil - ptr + 1);
475 ptr = nil + 1;
476 theme_thumbnail_data->status = READING_CTK_COLOR_SCHEME;
477 }
478 break;
479
480 case READING_CTK_COLOR_SCHEME:
481 nil = memchr (ptr, '\000', bytes_read);
482 if (nil == NULL((void*)0))
483 {
484 g_byte_array_append (theme_thumbnail_data->ctk_color_scheme, ptr, bytes_read);
485 bytes_read = 0;
486 }
487 else
488 {
489 g_byte_array_append (theme_thumbnail_data->ctk_color_scheme, ptr, nil - ptr + 1);
490 bytes_read -= (nil - ptr + 1);
491 ptr = nil + 1;
492 theme_thumbnail_data->status = READING_WM_THEME_NAME;
493 }
494 break;
495
496 case READING_WM_THEME_NAME:
497 nil = memchr (ptr, '\000', bytes_read);
498 if (nil == NULL((void*)0))
499 {
500 g_byte_array_append (theme_thumbnail_data->wm_theme_name, ptr, bytes_read);
501 bytes_read = 0;
502 }
503 else
504 {
505 g_byte_array_append (theme_thumbnail_data->wm_theme_name, ptr, nil - ptr + 1);
506 bytes_read -= (nil - ptr + 1);
507 ptr = nil + 1;
508 theme_thumbnail_data->status = READING_ICON_THEME_NAME;
509 }
510 break;
511
512 case READING_ICON_THEME_NAME:
513 nil = memchr (ptr, '\000', bytes_read);
514 if (nil == NULL((void*)0))
515 {
516 g_byte_array_append (theme_thumbnail_data->icon_theme_name, ptr, bytes_read);
517 bytes_read = 0;
518 }
519 else
520 {
521 g_byte_array_append (theme_thumbnail_data->icon_theme_name, ptr, nil - ptr + 1);
522 bytes_read -= (nil - ptr + 1);
523 ptr = nil + 1;
524 theme_thumbnail_data->status = READING_APPLICATION_FONT;
525 }
526 break;
527
528 case READING_APPLICATION_FONT:
529 nil = memchr (ptr, '\000', bytes_read);
530 if (nil == NULL((void*)0))
531 {
532 g_byte_array_append (theme_thumbnail_data->application_font, ptr, bytes_read);
533 bytes_read = 0;
534 }
535 else
536 {
537 g_byte_array_append (theme_thumbnail_data->application_font, ptr, nil - ptr + 1);
538 bytes_read -= (nil - ptr + 1);
539 ptr = nil + 1;
540 theme_thumbnail_data->status = WRITING_PIXBUF_DATA;
541 }
542 break;
543
544 default:
545 g_assert_not_reached ()do { g_assertion_message_expr ("capplet-common", "theme-thumbnail.c"
, 545, ((const char*) (__func__)), ((void*)0)); } while (0)
;
546 }
547 }
548}
549
550static gboolean
551message_from_capplet (GIOChannel *source,
552 GIOCondition condition,
553 gpointer data)
554{
555 gchar buffer[1024];
556 GIOStatus status;
557 gsize bytes_read;
558 ThemeThumbnailData *theme_thumbnail_data;
559
560 theme_thumbnail_data = (ThemeThumbnailData *) data;
561 status = g_io_channel_read_chars (source,
562 buffer,
563 1024,
564 &bytes_read,
565 NULL((void*)0));
566
567 switch (status)
568 {
569 case G_IO_STATUS_NORMAL:
570 handle_bytes ((guint8 *) buffer, bytes_read, theme_thumbnail_data);
571
572 if (theme_thumbnail_data->status == WRITING_PIXBUF_DATA)
573 {
574 GdkPixbuf *pixbuf = NULL((void*)0);
575 gint i, rowstride;
576 guchar *pixels;
577 gint width, height;
578 const gchar *type = (const gchar *) theme_thumbnail_data->type->data;
579
580 if (!strcmp (type, THUMBNAIL_TYPE_META"meta"))
581 pixbuf = create_meta_theme_pixbuf (theme_thumbnail_data);
582 else if (!strcmp (type, THUMBNAIL_TYPE_CTK"ctk"))
583 pixbuf = create_ctk_theme_pixbuf (theme_thumbnail_data);
584 else if (!strcmp (type, THUMBNAIL_TYPE_CROMA"croma"))
585 pixbuf = create_croma_theme_pixbuf (theme_thumbnail_data);
586 else if (!strcmp (type, THUMBNAIL_TYPE_ICON"icon"))
587 pixbuf = create_icon_theme_pixbuf (theme_thumbnail_data);
588 else
589 g_assert_not_reached ()do { g_assertion_message_expr ("capplet-common", "theme-thumbnail.c"
, 589, ((const char*) (__func__)), ((void*)0)); } while (0)
;
590
591 if (pixbuf == NULL((void*)0)) {
592 width = height = rowstride = 0;
593 pixels = NULL((void*)0);
594 } else {
595 width = gdk_pixbuf_get_width (pixbuf);
596 height = gdk_pixbuf_get_height (pixbuf);
597 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
598 pixels = gdk_pixbuf_get_pixels (pixbuf);
599 }
600
601 /* Write the pixbuf's size */
602
603 if (write (pipe_from_factory_fd[1], &width, sizeof (width)) == -1)
604 perror ("write error");
605
606 if (write (pipe_from_factory_fd[1], &height, sizeof (height)) == -1)
607 perror ("write error");
608
609 for (i = 0; i < height; i++)
610 {
611 if (write (pipe_from_factory_fd[1], pixels + rowstride * i, width * gdk_pixbuf_get_n_channels (pixbuf)) == -1)
612 perror ("write error");
613 }
614
615 if (pixbuf)
616 g_object_unref (pixbuf);
617 g_byte_array_set_size (theme_thumbnail_data->type, 0);
618 g_byte_array_set_size (theme_thumbnail_data->control_theme_name, 0);
619 g_byte_array_set_size (theme_thumbnail_data->ctk_color_scheme, 0);
620 g_byte_array_set_size (theme_thumbnail_data->wm_theme_name, 0);
621 g_byte_array_set_size (theme_thumbnail_data->icon_theme_name, 0);
622 g_byte_array_set_size (theme_thumbnail_data->application_font, 0);
623 theme_thumbnail_data->status = READY_FOR_THEME;
624 }
625 return TRUE(!(0));
626
627 case G_IO_STATUS_AGAIN:
628 return TRUE(!(0));
629
630 case G_IO_STATUS_EOF:
631 case G_IO_STATUS_ERROR:
632 _exit (0);
633
634 default:
635 g_assert_not_reached ()do { g_assertion_message_expr ("capplet-common", "theme-thumbnail.c"
, 635, ((const char*) (__func__)), ((void*)0)); } while (0)
;
636 }
637
638 return TRUE(!(0));
639}
640
641static void
642generate_next_in_queue (void)
643{
644 ThemeQueueItem *item;
645
646 if (theme_queue == NULL((void*)0))
647 return;
648
649 item = theme_queue->data;
650 theme_queue = g_list_delete_link (theme_queue, g_list_first (theme_queue));
651
652 if (!strcmp (item->thumbnail_type, THUMBNAIL_TYPE_META"meta"))
653 generate_meta_theme_thumbnail_async ((CafeThemeMetaInfo *) item->theme_info,
654 item->func,
655 item->user_data,
656 item->destroy);
657 else if (!strcmp (item->thumbnail_type, THUMBNAIL_TYPE_CTK"ctk"))
658 generate_ctk_theme_thumbnail_async ((CafeThemeInfo *) item->theme_info,
659 item->func,
660 item->user_data,
661 item->destroy);
662 else if (!strcmp (item->thumbnail_type, THUMBNAIL_TYPE_CROMA"croma"))
663 generate_croma_theme_thumbnail_async ((CafeThemeInfo *) item->theme_info,
664 item->func,
665 item->user_data,
666 item->destroy);
667 else if (!strcmp (item->thumbnail_type, THUMBNAIL_TYPE_ICON"icon"))
668 generate_icon_theme_thumbnail_async ((CafeThemeIconInfo *) item->theme_info,
669 item->func,
670 item->user_data,
671 item->destroy);
672
673 g_free (item);
674}
675
676static gboolean
677message_from_child (GIOChannel *source,
678 GIOCondition condition,
679 gpointer data)
680{
681 gchar buffer[1024];
682 GIOStatus status;
683 gsize bytes_read;
684
685 if (async_data.set == FALSE(0))
686 return TRUE(!(0));
687
688 if (condition == G_IO_HUP)
689 return FALSE(0);
690
691 status = g_io_channel_read_chars (source,
692 buffer,
693 1024,
694 &bytes_read,
695 NULL((void*)0));
696 switch (status)
697 {
698 case G_IO_STATUS_NORMAL:
699 g_byte_array_append (async_data.data, (guchar *) buffer, bytes_read);
700
701 if (async_data.thumbnail_width == -1 && async_data.data->len >= 2 * sizeof (gint))
702 {
703 async_data.thumbnail_width = *((gint *) async_data.data->data);
704 async_data.thumbnail_height = *(((gint *) async_data.data->data) + 1);
705 g_byte_array_remove_range (async_data.data, 0, 2 * sizeof (gint));
706 }
707
708 if (async_data.thumbnail_width >= 0 && async_data.data->len == async_data.thumbnail_width * async_data.thumbnail_height * 4)
709 {
710 GdkPixbuf *pixbuf = NULL((void*)0);
711
712 if (async_data.thumbnail_width > 0) {
713 gchar *pixels;
714 gint i, rowstride;
715
716 pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE(!(0)), 8, async_data.thumbnail_width, async_data.thumbnail_height);
717 pixels = (gchar *) gdk_pixbuf_get_pixels (pixbuf);
718 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
719
720 for (i = 0; i < async_data.thumbnail_height; ++i)
721 memcpy (pixels + rowstride * i, async_data.data->data + 4 * async_data.thumbnail_width * i, async_data.thumbnail_width * 4);
722 }
723
724 /* callback function needs to ref the pixbuf if it wants to keep it */
725 (* async_data.func) (pixbuf, async_data.theme_name, async_data.user_data);
726
727 if (async_data.destroy)
728 (* async_data.destroy) (async_data.user_data);
729
730 if (pixbuf)
731 g_object_unref (pixbuf);
732
733 /* Clean up async_data */
734 g_free (async_data.theme_name);
735 g_source_remove (async_data.watch_id);
736 g_io_channel_unref (async_data.channel);
737
738 /* reset async_data */
739 async_data.thumbnail_width = -1;
740 async_data.thumbnail_height = -1;
741 async_data.theme_name = NULL((void*)0);
742 async_data.channel = NULL((void*)0);
743 async_data.func = NULL((void*)0);
744 async_data.user_data = NULL((void*)0);
745 async_data.destroy = NULL((void*)0);
746 async_data.set = FALSE(0);
747 g_byte_array_set_size (async_data.data, 0);
748
749 generate_next_in_queue ();
750 }
751 return TRUE(!(0));
752
753 case G_IO_STATUS_AGAIN:
754 return TRUE(!(0));
755
756 case G_IO_STATUS_EOF:
757 case G_IO_STATUS_ERROR:
758 return FALSE(0);
759
760 default:
761 g_assert_not_reached ()do { g_assertion_message_expr ("capplet-common", "theme-thumbnail.c"
, 761, ((const char*) (__func__)), ((void*)0)); } while (0)
;
762 }
763
764 return TRUE(!(0));
765}
766
767static void
768send_thumbnail_request (gchar *thumbnail_type,
769 gchar *ctk_theme_name,
770 gchar *ctk_color_scheme,
771 gchar *croma_theme_name,
772 gchar *icon_theme_name,
773 gchar *application_font)
774{
775 if (write (pipe_to_factory_fd[1], thumbnail_type, strlen (thumbnail_type) + 1) == -1)
776 perror ("write error");
777
778 if (ctk_theme_name)
779 {
780 if (write (pipe_to_factory_fd[1], ctk_theme_name, strlen (ctk_theme_name) + 1) == -1)
781 perror ("write error");
782 }
783 else
784 {
785 if (write (pipe_to_factory_fd[1], "", 1) == -1)
786 perror ("write error");
787 }
788
789 if (ctk_color_scheme)
790 {
791 if (write (pipe_to_factory_fd[1], ctk_color_scheme, strlen (ctk_color_scheme) + 1) == -1)
792 perror ("write error");
793 }
794 else
795 {
796 if (write (pipe_to_factory_fd[1], "", 1) == -1)
797 perror ("write error");
798 }
799
800 if (croma_theme_name)
801 {
802 if (write (pipe_to_factory_fd[1], croma_theme_name, strlen (croma_theme_name) + 1) == -1)
803 perror ("write error");
804 }
805 else
806 {
807 if (write (pipe_to_factory_fd[1], "", 1) == -1)
808 perror ("write error");
809 }
810
811 if (icon_theme_name)
812 {
813 if (write (pipe_to_factory_fd[1], icon_theme_name, strlen (icon_theme_name) + 1) == -1)
814 perror ("write error");
815 }
816 else
817 {
818 if (write (pipe_to_factory_fd[1], "", 1) == -1)
819 perror ("write error");
820 }
821
822 if (application_font)
823 {
824 if (write (pipe_to_factory_fd[1], application_font, strlen (application_font) + 1) == -1)
825 perror ("write error");
826 }
827 else
828 {
829 if (write (pipe_to_factory_fd[1], "Sans 10", strlen ("Sans 10") + 1) == -1)
830 perror ("write error");
831 }
832}
833
834static GdkPixbuf *
835read_pixbuf (void)
836{
837 gint bytes_read, i, j = 0;
838 gint size[2];
839 GdkPixbuf *pixbuf;
840 gint rowstride;
841 guchar *pixels;
842
843 do
844 {
845 bytes_read = read (pipe_from_factory_fd[0], ((guint8*) size) + j, 2 * sizeof (gint));
846 if (bytes_read == 0)
847 goto eof;
848 j += bytes_read;
849 }
850 while (j < 2 * sizeof (gint));
851
852 if (size[0] <= 0 || size[1] <= 0)
853 return NULL((void*)0);
854
855 pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE(!(0)), 8, size[0], size[1]);
856 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
857 pixels = gdk_pixbuf_get_pixels (pixbuf);
858
859 for (i = 0; i < size[1]; i++)
860 {
861 j = 0;
862
863 do
864 {
865 bytes_read = read (pipe_from_factory_fd[0], pixels + rowstride * i + j, size[0] * gdk_pixbuf_get_n_channels (pixbuf) - j);
866
867 if (bytes_read > 0)
868 j += bytes_read;
869 else if (bytes_read == 0)
870 {
871 g_object_unref (pixbuf);
872 goto eof;
873 }
874 }
875 while (j < size[0] * gdk_pixbuf_get_n_channels (pixbuf));
876 }
877
878 return pixbuf;
879
880eof:
881 g_warning ("Received EOF while reading thumbnail");
882 close (pipe_to_factory_fd[1]);
883 pipe_to_factory_fd[1] = 0;
884 close (pipe_from_factory_fd[0]);
885 pipe_from_factory_fd[0] = 0;
886 return NULL((void*)0);
887}
888
889static GdkPixbuf *
890generate_theme_thumbnail (gchar *thumbnail_type,
891 gchar *ctk_theme_name,
892 gchar *ctk_color_scheme,
893 gchar *croma_theme_name,
894 gchar *icon_theme_name,
895 gchar *application_font)
896{
897 if (async_data.set || !pipe_to_factory_fd[1] || !pipe_from_factory_fd[0])
898 return NULL((void*)0);
899
900 send_thumbnail_request (thumbnail_type,
901 ctk_theme_name,
902 ctk_color_scheme,
903 croma_theme_name,
904 icon_theme_name,
905 application_font);
906
907 return read_pixbuf ();
908}
909
910GdkPixbuf *
911generate_meta_theme_thumbnail (CafeThemeMetaInfo *theme_info)
912{
913 return generate_theme_thumbnail (THUMBNAIL_TYPE_META"meta",
914 theme_info->ctk_theme_name,
915 theme_info->ctk_color_scheme,
916 theme_info->croma_theme_name,
917 theme_info->icon_theme_name,
918 theme_info->application_font);
919}
920
921GdkPixbuf *
922generate_ctk_theme_thumbnail (CafeThemeInfo *theme_info)
923{
924 gchar *scheme;
925
926 scheme = ctkrc_get_color_scheme_for_theme (theme_info->name);
927
928 return generate_theme_thumbnail (THUMBNAIL_TYPE_CTK"ctk",
929 theme_info->name,
930 scheme,
931 NULL((void*)0),
932 NULL((void*)0),
933 NULL((void*)0));
934 g_free (scheme);
This statement is never executed
935}
936
937GdkPixbuf *
938generate_croma_theme_thumbnail (CafeThemeInfo *theme_info)
939{
940 return generate_theme_thumbnail (THUMBNAIL_TYPE_CROMA"croma",
941 NULL((void*)0),
942 NULL((void*)0),
943 theme_info->name,
944 NULL((void*)0),
945 NULL((void*)0));
946}
947
948GdkPixbuf *
949generate_icon_theme_thumbnail (CafeThemeIconInfo *theme_info)
950{
951 return generate_theme_thumbnail (THUMBNAIL_TYPE_ICON"icon",
952 NULL((void*)0),
953 NULL((void*)0),
954 NULL((void*)0),
955 theme_info->name,
956 NULL((void*)0));
957}
958
959static void generate_theme_thumbnail_async(gpointer theme_info, gchar* theme_name, gchar* thumbnail_type, gchar* ctk_theme_name, gchar* ctk_color_scheme, gchar* croma_theme_name, gchar* icon_theme_name, gchar* application_font, ThemeThumbnailFunc func, gpointer user_data, GDestroyNotify destroy)
960{
961 if (async_data.set)
962 {
963 ThemeQueueItem* item = g_new0 (ThemeQueueItem, 1)((ThemeQueueItem *) g_malloc0_n ((1), sizeof (ThemeQueueItem)
))
;
964
965 item->thumbnail_type = thumbnail_type;
966 item->theme_info = theme_info;
967 item->func = func;
968 item->user_data = user_data;
969 item->destroy = destroy;
970
971 theme_queue = g_list_append(theme_queue, item);
972
973 return;
974 }
975
976 if (!pipe_to_factory_fd[1] || !pipe_from_factory_fd[0])
977 {
978 (*func)(NULL((void*)0), theme_name, user_data);
979
980 if (destroy)
981 {
982 (*destroy)(user_data);
983 }
984
985 return;
986 }
987
988 if (async_data.channel == NULL((void*)0))
989 {
990 async_data.channel = g_io_channel_unix_new(pipe_from_factory_fd[0]);
991
992 g_io_channel_set_flags(async_data.channel, g_io_channel_get_flags (async_data.channel) | G_IO_FLAG_NONBLOCK, NULL((void*)0));
993 g_io_channel_set_encoding(async_data.channel, NULL((void*)0), NULL((void*)0));
994
995 async_data.watch_id = g_io_add_watch(async_data.channel, G_IO_IN | G_IO_HUP, message_from_child, NULL((void*)0));
996 }
997
998 async_data.set = TRUE(!(0));
999 async_data.thumbnail_width = -1;
1000 async_data.thumbnail_height = -1;
1001 async_data.theme_name = g_strdup(theme_name)g_strdup_inline (theme_name);
1002 async_data.func = func;
1003 async_data.user_data = user_data;
1004 async_data.destroy = destroy;
1005
1006 send_thumbnail_request(thumbnail_type, ctk_theme_name, ctk_color_scheme, croma_theme_name, icon_theme_name, application_font);
1007}
1008
1009void
1010generate_meta_theme_thumbnail_async (CafeThemeMetaInfo *theme_info,
1011 ThemeThumbnailFunc func,
1012 gpointer user_data,
1013 GDestroyNotify destroy)
1014{
1015 generate_theme_thumbnail_async (theme_info,
1016 theme_info->name,
1017 THUMBNAIL_TYPE_META"meta",
1018 theme_info->ctk_theme_name,
1019 theme_info->ctk_color_scheme,
1020 theme_info->croma_theme_name,
1021 theme_info->icon_theme_name,
1022 theme_info->application_font,
1023 func, user_data, destroy);
1024}
1025
1026void generate_ctk_theme_thumbnail_async (CafeThemeInfo* theme_info, ThemeThumbnailFunc func, gpointer user_data, GDestroyNotify destroy)
1027{
1028 gchar* scheme = ctkrc_get_color_scheme_for_theme(theme_info->name);
1029
1030 generate_theme_thumbnail_async(theme_info, theme_info->name, THUMBNAIL_TYPE_CTK"ctk", theme_info->name, scheme, NULL((void*)0), NULL((void*)0), NULL((void*)0), func, user_data, destroy);
1031
1032 g_free(scheme);
1033}
1034
1035void
1036generate_croma_theme_thumbnail_async (CafeThemeInfo *theme_info,
1037 ThemeThumbnailFunc func,
1038 gpointer user_data,
1039 GDestroyNotify destroy)
1040{
1041 generate_theme_thumbnail_async (theme_info,
1042 theme_info->name,
1043 THUMBNAIL_TYPE_CROMA"croma",
1044 NULL((void*)0),
1045 NULL((void*)0),
1046 theme_info->name,
1047 NULL((void*)0),
1048 NULL((void*)0),
1049 func, user_data, destroy);
1050}
1051
1052void
1053generate_icon_theme_thumbnail_async (CafeThemeIconInfo *theme_info,
1054 ThemeThumbnailFunc func,
1055 gpointer user_data,
1056 GDestroyNotify destroy)
1057{
1058 generate_theme_thumbnail_async (theme_info,
1059 theme_info->name,
1060 THUMBNAIL_TYPE_ICON"icon",
1061 NULL((void*)0),
1062 NULL((void*)0),
1063 NULL((void*)0),
1064 theme_info->name,
1065 NULL((void*)0),
1066 func, user_data, destroy);
1067}
1068
1069void
1070theme_thumbnail_factory_init (int argc, char *argv[])
1071{
1072 gint child_pid;
1073
1074 if (pipe (pipe_to_factory_fd) == -1)
1075 perror ("pipe error");
1076
1077 if (pipe (pipe_from_factory_fd) == -1)
1078 perror ("pipe error");
1079
1080 child_pid = fork ();
1081 if (child_pid == 0)
1082 {
1083 ThemeThumbnailData data;
1084 GIOChannel *channel;
1085
1086 /* Child */
1087 ctk_init (&argc, &argv);
1088
1089 close (pipe_to_factory_fd[1]);
1090 pipe_to_factory_fd[1] = 0;
1091 close (pipe_from_factory_fd[0]);
1092 pipe_from_factory_fd[0] = 0;
1093
1094 data.status = READY_FOR_THEME;
1095 data.type = g_byte_array_new ();
1096 data.control_theme_name = g_byte_array_new ();
1097 data.ctk_color_scheme = g_byte_array_new ();
1098 data.wm_theme_name = g_byte_array_new ();
1099 data.icon_theme_name = g_byte_array_new ();
1100 data.application_font = g_byte_array_new ();
1101
1102 channel = g_io_channel_unix_new (pipe_to_factory_fd[0]);
1103 g_io_channel_set_flags (channel, g_io_channel_get_flags (channel) |
1104 G_IO_FLAG_NONBLOCK, NULL((void*)0));
1105 g_io_channel_set_encoding (channel, NULL((void*)0), NULL((void*)0));
1106 g_io_add_watch (channel, G_IO_IN | G_IO_HUP, message_from_capplet, &data);
1107 g_io_channel_unref (channel);
1108
1109 ctk_main ();
1110 _exit (0);
1111 }
1112
1113 g_assert (child_pid > 0)do { if (child_pid > 0) ; else g_assertion_message_expr ("capplet-common"
, "theme-thumbnail.c", 1113, ((const char*) (__func__)), "child_pid > 0"
); } while (0)
;
1114
1115 /* Parent */
1116 close (pipe_to_factory_fd[0]);
1117 close (pipe_from_factory_fd[1]);
1118
1119 async_data.set = FALSE(0);
1120 async_data.theme_name = NULL((void*)0);
1121 async_data.data = g_byte_array_new ();
1122}