File: | capplets/common/theme-thumbnail.c |
Warning: | line 934, column 3 This statement is never executed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | |
23 | typedef 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 | |
37 | static 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 | |
48 | enum { |
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 | |
59 | typedef 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 | |
69 | typedef struct { |
70 | gchar* thumbnail_type; |
71 | gpointer theme_info; |
72 | ThemeThumbnailFunc func; |
73 | gpointer user_data; |
74 | GDestroyNotify destroy; |
75 | } ThemeQueueItem; |
76 | |
77 | static GList* theme_queue = NULL((void*)0); |
78 | |
79 | static int pipe_to_factory_fd[2]; |
80 | static 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 | |
93 | static 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 | |
125 | static GdkPixbuf * |
126 | create_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 | |
168 | static GdkPixbuf * |
169 | create_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 | |
283 | static GdkPixbuf * |
284 | create_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 | |
353 | static GdkPixbuf * |
354 | create_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 | |
424 | static GdkPixbuf * |
425 | create_icon_theme_pixbuf (ThemeThumbnailData *theme_thumbnail_data) |
426 | { |
427 | return create_folder_icon ((char *) theme_thumbnail_data->icon_theme_name->data); |
428 | } |
429 | |
430 | |
431 | static void |
432 | handle_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 | |
550 | static gboolean |
551 | message_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 | |
641 | static void |
642 | generate_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 | |
676 | static gboolean |
677 | message_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 | |
767 | static void |
768 | send_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 | |
834 | static GdkPixbuf * |
835 | read_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 | |
880 | eof: |
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 | |
889 | static GdkPixbuf * |
890 | generate_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 | |
910 | GdkPixbuf * |
911 | generate_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 | |
921 | GdkPixbuf * |
922 | generate_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 | |
937 | GdkPixbuf * |
938 | generate_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 | |
948 | GdkPixbuf * |
949 | generate_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 | |
959 | static 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 | |
1009 | void |
1010 | generate_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 | |
1026 | void 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 | |
1035 | void |
1036 | generate_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 | |
1052 | void |
1053 | generate_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 | |
1069 | void |
1070 | theme_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 | } |