File: | cafe-panel/panel-background.c |
Warning: | line 119, column 4 Value stored to 'height' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * panel-background.c: panel background rendering |
3 | * |
4 | * Copyright (C) 2002, 2003 Sun Microsystems, Inc. |
5 | * |
6 | * This program is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU General Public License as |
8 | * published by the Free Software Foundation; either version 2 of the |
9 | * License, or (at your option) any later version. |
10 | * |
11 | * This program is distributed in the hope that it will be useful, but |
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU General Public License |
17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA |
19 | * 02110-1301, USA. |
20 | * |
21 | * Authors: |
22 | * Mark McLoughlin <mark@skynet.ie> |
23 | */ |
24 | |
25 | #include <config.h> |
26 | |
27 | #include "panel-background.h" |
28 | |
29 | #include <string.h> |
30 | #include <cdk/cdk.h> |
31 | #include <ctk/ctk.h> |
32 | #include <cairo.h> |
33 | |
34 | #ifdef HAVE_X111 |
35 | #include <xstuff.h> |
36 | #include <cairo-xlib.h> |
37 | #endif |
38 | |
39 | #include "panel-util.h" |
40 | |
41 | |
42 | static gboolean panel_background_composite (PanelBackground *background); |
43 | static void load_background_file (PanelBackground *background); |
44 | |
45 | |
46 | static void |
47 | set_pixbuf_background (PanelBackground *background) |
48 | { |
49 | g_assert (background->composited_pattern != NULL)do { if (background->composited_pattern != ((void*)0)) ; else g_assertion_message_expr (((gchar*) 0), "panel-background.c" , 49, ((const char*) (__func__)), "background->composited_pattern != NULL" ); } while (0); |
50 | |
51 | cdk_window_set_background_pattern (background->window, background->composited_pattern); |
52 | } |
53 | |
54 | void panel_background_apply_css (PanelBackground *background, CtkWidget *widget) |
55 | { |
56 | CtkStyleContext *context; |
57 | PanelBackgroundType effective_type; |
58 | |
59 | context = ctk_widget_get_style_context (widget); |
60 | effective_type = panel_background_effective_type (background); |
61 | |
62 | switch (effective_type) { |
63 | case PANEL_BACK_NONE: |
64 | ctk_style_context_remove_class (context, "cafe-custom-panel-background"); |
65 | break; |
66 | case PANEL_BACK_COLOR: |
67 | case PANEL_BACK_IMAGE: |
68 | ctk_style_context_add_class (context, "cafe-custom-panel-background"); |
69 | break; |
70 | default: |
71 | g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "panel-background.c" , 71, ((const char*) (__func__)), ((void*)0)); } while (0); |
72 | break; |
73 | } |
74 | } |
75 | |
76 | static void |
77 | panel_background_prepare_css () |
78 | { |
79 | CtkCssProvider *provider; |
80 | |
81 | provider = ctk_css_provider_new (); |
82 | ctk_css_provider_load_from_data (provider, |
83 | ".cafe-custom-panel-background{\n" |
84 | " background-color: rgba (0, 0, 0, 0);\n" |
85 | " background-image: none;\n" |
86 | "}", |
87 | -1, NULL((void*)0)); |
88 | ctk_style_context_add_provider_for_screen (cdk_screen_get_default (), |
89 | CTK_STYLE_PROVIDER (provider)((((CtkStyleProvider*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((provider)), ((ctk_style_provider_get_type ( ))))))), |
90 | CTK_STYLE_PROVIDER_PRIORITY_APPLICATION600); |
91 | g_object_unref (provider); |
92 | } |
93 | |
94 | static gboolean |
95 | panel_background_prepare (PanelBackground *background) |
96 | { |
97 | PanelBackgroundType effective_type; |
98 | CtkWidget *widget = NULL((void*)0); |
99 | |
100 | if (!background->transformed) |
101 | return FALSE(0); |
102 | |
103 | effective_type = panel_background_effective_type (background); |
104 | |
105 | switch (effective_type) { |
106 | case PANEL_BACK_NONE: |
107 | if (background->default_pattern) { |
108 | /* the theme background-image pattern must be scaled by |
109 | * the width & height of the panel so that when the |
110 | * backing region is cleared |
111 | * (cdk_window_clear_backing_region), the correctly |
112 | * scaled pattern is used */ |
113 | cairo_matrix_t m; |
114 | cairo_surface_t *surface; |
115 | double width, height; |
116 | |
117 | surface = NULL((void*)0); |
118 | width = 1.0; |
119 | height = 1.0; |
Value stored to 'height' is never read | |
120 | cairo_pattern_get_surface(background->default_pattern, &surface); |
121 | /* catch invalid images (e.g. -ctk-gradient) before scaling and rendering */ |
122 | if (surface != NULL((void*)0) ){ |
123 | cairo_surface_reference(surface); |
124 | width = cairo_image_surface_get_width (surface); |
125 | height = cairo_image_surface_get_height (surface); |
126 | cairo_matrix_init_translate (&m, 0, 0); |
127 | cairo_matrix_scale (&m, |
128 | width / background->region.width, |
129 | height / background->region.height); |
130 | cairo_pattern_set_matrix (background->default_pattern, &m); |
131 | |
132 | cdk_window_set_background_pattern (background->window, |
133 | background->default_pattern); |
134 | } |
135 | else { |
136 | g_warning ("%s", "unsupported value of 'background-image' in CTK+ theme (such as '-ctk-gradient')"); |
137 | /* use any background color that has been set if image is invalid */ |
138 | cdk_window_set_background_rgba ( |
139 | background->window, &background->default_color); |
140 | } |
141 | cairo_surface_destroy(surface); |
142 | } else |
143 | cdk_window_set_background_rgba ( |
144 | background->window, &background->default_color); |
145 | break; |
146 | |
147 | case PANEL_BACK_COLOR: |
148 | #ifdef HAVE_X111 |
149 | if (CDK_IS_X11_DISPLAY (cdk_display_get_default ())(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (cdk_display_get_default ())); GType __t = ((cdk_x11_display_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; })))) && |
150 | background->has_alpha && |
151 | !cdk_window_check_composited_wm(background->window)) |
152 | set_pixbuf_background (background); |
153 | else |
154 | #endif // HAVE_X11 |
155 | { // Not using X11, or pixbuf background not needed |
156 | cdk_window_set_background_rgba (background->window, |
157 | &background->color); |
158 | } |
159 | break; |
160 | |
161 | case PANEL_BACK_IMAGE: |
162 | set_pixbuf_background (background); |
163 | break; |
164 | |
165 | default: |
166 | g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "panel-background.c" , 166, ((const char*) (__func__)), ((void*)0)); } while (0); |
167 | break; |
168 | } |
169 | |
170 | /* Panel applets may use the panel's background pixmap to |
171 | * decide how to draw themselves. Therefore, we need to |
172 | * make sure that all drawing has been completed before |
173 | * the applet looks at the pixmap. */ |
174 | cdk_display_sync (cdk_window_get_display (background->window)); |
175 | |
176 | cdk_window_get_user_data (CDK_WINDOW (background->window)((((CdkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((background->window)), ((cdk_window_get_type ())))))), |
177 | (gpointer) &widget); |
178 | |
179 | if (CTK_IS_WIDGET (widget)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (widget)); GType __t = ((ctk_widget_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; }))))) { |
180 | panel_background_apply_css (background, ctk_widget_get_toplevel(widget)); |
181 | ctk_widget_set_app_paintable(widget,TRUE(!(0))); |
182 | ctk_widget_queue_draw (widget); |
183 | } |
184 | |
185 | background->notify_changed (background, background->user_data); |
186 | |
187 | return TRUE(!(0)); |
188 | } |
189 | |
190 | static void |
191 | free_composited_resources (PanelBackground *background) |
192 | { |
193 | background->composited = FALSE(0); |
194 | |
195 | if (background->composited_pattern) |
196 | cairo_pattern_destroy (background->composited_pattern); |
197 | background->composited_pattern = NULL((void*)0); |
198 | } |
199 | |
200 | #ifdef HAVE_X111 |
201 | |
202 | static void _panel_background_transparency (CdkScreen *screen G_GNUC_UNUSED__attribute__ ((__unused__)), |
203 | PanelBackground *background) |
204 | { |
205 | panel_background_composite(background); |
206 | } |
207 | |
208 | static void |
209 | background_changed (PanelBackgroundMonitor *monitor G_GNUC_UNUSED__attribute__ ((__unused__)), |
210 | PanelBackground *background) |
211 | { |
212 | GdkPixbuf *tmp; |
213 | |
214 | g_return_if_fail (CDK_IS_X11_DISPLAY (cdk_display_get_default ()))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((cdk_display_get_default ())); GType __t = ((cdk_x11_display_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 (((gchar*) 0 ), ((const char*) (__func__)), "CDK_IS_X11_DISPLAY (cdk_display_get_default ())" ); return; } } while (0); |
215 | |
216 | tmp = background->desktop; |
217 | |
218 | background->desktop = panel_background_monitor_get_region ( |
219 | background->monitor, |
220 | background->region.x, |
221 | background->region.y, |
222 | background->region.width, |
223 | background->region.height); |
224 | |
225 | if (tmp) |
226 | g_object_unref (tmp); |
227 | |
228 | panel_background_composite (background); |
229 | } |
230 | |
231 | static GdkPixbuf * |
232 | get_desktop_pixbuf (PanelBackground *background) |
233 | { |
234 | GdkPixbuf *desktop; |
235 | |
236 | g_return_val_if_fail (CDK_IS_X11_DISPLAY (cdk_display_get_default ()), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((cdk_display_get_default ())); GType __t = ((cdk_x11_display_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 (((gchar*) 0 ), ((const char*) (__func__)), "CDK_IS_X11_DISPLAY (cdk_display_get_default ())" ); return (((void*)0)); } } while (0); |
237 | |
238 | if (!background->monitor) { |
239 | background->monitor = |
240 | panel_background_monitor_get_for_screen ( |
241 | cdk_window_get_screen (background->window)); |
242 | |
243 | background->monitor_signal = |
244 | g_signal_connect (g_signal_connect_data ((background->monitor), ("changed"), (((GCallback) (background_changed))), (background), ((void*) 0), (GConnectFlags) 0) |
245 | background->monitor, "changed",g_signal_connect_data ((background->monitor), ("changed"), (((GCallback) (background_changed))), (background), ((void*) 0), (GConnectFlags) 0) |
246 | G_CALLBACK (background_changed), background)g_signal_connect_data ((background->monitor), ("changed"), (((GCallback) (background_changed))), (background), ((void*) 0), (GConnectFlags) 0); |
247 | } |
248 | g_signal_connect(cdk_window_get_screen(background->window), "composited-changed",g_signal_connect_data ((cdk_window_get_screen(background-> window)), ("composited-changed"), (((GCallback) (_panel_background_transparency ))), (background), ((void*)0), (GConnectFlags) 0) |
249 | G_CALLBACK(_panel_background_transparency),g_signal_connect_data ((cdk_window_get_screen(background-> window)), ("composited-changed"), (((GCallback) (_panel_background_transparency ))), (background), ((void*)0), (GConnectFlags) 0) |
250 | background)g_signal_connect_data ((cdk_window_get_screen(background-> window)), ("composited-changed"), (((GCallback) (_panel_background_transparency ))), (background), ((void*)0), (GConnectFlags) 0); |
251 | |
252 | desktop = panel_background_monitor_get_region ( |
253 | background->monitor, |
254 | background->region.x, |
255 | background->region.y, |
256 | background->region.width, |
257 | background->region.height); |
258 | |
259 | return desktop; |
260 | } |
261 | |
262 | #endif // HAVE_X11 |
263 | |
264 | static cairo_pattern_t * |
265 | composite_image_onto_desktop (PanelBackground *background) |
266 | { |
267 | int width, height; |
268 | cairo_t *cr; |
269 | cairo_surface_t *surface; |
270 | cairo_pattern_t *pattern; |
271 | |
272 | width = background->region.width; |
273 | height = background->region.height; |
274 | |
275 | surface = cdk_window_create_similar_surface (background->window, |
276 | CAIRO_CONTENT_COLOR_ALPHA, |
277 | width, height); |
278 | if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) { |
279 | cairo_surface_destroy (surface); |
280 | return NULL((void*)0); |
281 | } |
282 | |
283 | cr = cairo_create (surface); |
284 | |
285 | #ifdef HAVE_X111 |
286 | if (CDK_IS_X11_DISPLAY (cdk_display_get_default ())(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (cdk_display_get_default ())); GType __t = ((cdk_x11_display_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; }))))) { |
287 | if (!background->desktop) |
288 | background->desktop = get_desktop_pixbuf (background); |
289 | |
290 | if(!cdk_window_check_composited_wm (background->window)){ |
291 | cairo_set_source_rgb (cr, 1, 1, 1); |
292 | cairo_paint (cr); |
293 | |
294 | if (background->desktop) { |
295 | cdk_cairo_set_source_pixbuf (cr, background->desktop, 0, 0); |
296 | cairo_rectangle (cr, 0, 0, width, height); |
297 | cairo_fill (cr); |
298 | } |
299 | } |
300 | } |
301 | #endif // HAVE_X11 |
302 | |
303 | cdk_cairo_set_source_pixbuf (cr, background->transformed_image, 0, 0); |
304 | pattern = cairo_get_source (cr); |
305 | cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); |
306 | |
307 | cairo_rectangle (cr, 0, 0, width, height); |
308 | cairo_fill (cr); |
309 | |
310 | cairo_destroy (cr); |
311 | |
312 | pattern = cairo_pattern_create_for_surface (surface); |
313 | cairo_surface_destroy (surface); |
314 | return pattern; |
315 | } |
316 | |
317 | static cairo_pattern_t * |
318 | composite_color_onto_desktop (PanelBackground *background) |
319 | { |
320 | cairo_surface_t *surface; |
321 | cairo_pattern_t *pattern; |
322 | cairo_t *cr; |
323 | |
324 | surface = cdk_window_create_similar_surface (background->window, |
325 | CAIRO_CONTENT_COLOR_ALPHA, |
326 | background->region.width, |
327 | background->region.height); |
328 | if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) { |
329 | cairo_surface_destroy (surface); |
330 | return NULL((void*)0); |
331 | } |
332 | |
333 | cr = cairo_create (surface); |
334 | |
335 | #ifdef HAVE_X111 |
336 | if (CDK_IS_X11_DISPLAY (cdk_display_get_default ())(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (cdk_display_get_default ())); GType __t = ((cdk_x11_display_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; }))))) { |
337 | if (!background->desktop) |
338 | background->desktop = get_desktop_pixbuf (background); |
339 | |
340 | if(!cdk_window_check_composited_wm (background->window)){ |
341 | if (background->desktop) { |
342 | cdk_cairo_set_source_pixbuf (cr, background->desktop, 0, 0); |
343 | cairo_paint (cr); |
344 | } |
345 | } |
346 | } |
347 | #endif // HAVE_X11 |
348 | |
349 | cdk_cairo_set_source_rgba (cr, &background->color); |
350 | cairo_paint (cr); |
351 | |
352 | cairo_destroy (cr); |
353 | |
354 | pattern = cairo_pattern_create_for_surface (surface); |
355 | cairo_surface_destroy (surface); |
356 | |
357 | return pattern; |
358 | } |
359 | |
360 | static cairo_pattern_t * |
361 | get_composited_pattern (PanelBackground *background) |
362 | { |
363 | cairo_pattern_t *retval = NULL((void*)0); |
364 | |
365 | switch (background->type) { |
366 | case PANEL_BACK_NONE: |
367 | break; |
368 | case PANEL_BACK_COLOR: |
369 | retval = composite_color_onto_desktop (background); |
370 | break; |
371 | case PANEL_BACK_IMAGE: |
372 | retval = composite_image_onto_desktop (background); |
373 | break; |
374 | default: |
375 | g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "panel-background.c" , 375, ((const char*) (__func__)), ((void*)0)); } while (0); |
376 | break; |
377 | } |
378 | |
379 | return retval; |
380 | } |
381 | |
382 | static gboolean |
383 | panel_background_composite (PanelBackground *background) |
384 | { |
385 | if (!background->transformed) |
386 | return FALSE(0); |
387 | |
388 | free_composited_resources (background); |
389 | |
390 | switch (background->type) { |
391 | case PANEL_BACK_NONE: |
392 | break; |
393 | case PANEL_BACK_COLOR: |
394 | if (background->has_alpha) |
395 | background->composited_pattern = |
396 | get_composited_pattern (background); |
397 | break; |
398 | case PANEL_BACK_IMAGE: |
399 | if (background->transformed_image) { |
400 | background->composited_pattern = |
401 | get_composited_pattern (background); |
402 | } |
403 | break; |
404 | default: |
405 | g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "panel-background.c" , 405, ((const char*) (__func__)), ((void*)0)); } while (0); |
406 | break; |
407 | } |
408 | |
409 | background->composited = TRUE(!(0)); |
410 | |
411 | |
412 | panel_background_prepare (background); |
413 | |
414 | return TRUE(!(0)); |
415 | } |
416 | |
417 | static void |
418 | free_transformed_resources (PanelBackground *background) |
419 | { |
420 | free_composited_resources (background); |
421 | |
422 | background->transformed = FALSE(0); |
423 | |
424 | if (background->type != PANEL_BACK_IMAGE) |
425 | return; |
426 | |
427 | if (background->transformed_image) |
428 | g_object_unref (background->transformed_image); |
429 | background->transformed_image = NULL((void*)0); |
430 | } |
431 | |
432 | static GdkPixbuf * |
433 | get_scaled_and_rotated_pixbuf (PanelBackground *background) |
434 | { |
435 | GdkPixbuf *scaled; |
436 | GdkPixbuf *retval; |
437 | int orig_width, orig_height; |
438 | int panel_width, panel_height; |
439 | int width, height; |
440 | |
441 | load_background_file (background); |
442 | if (!background->loaded_image) |
443 | return NULL((void*)0); |
444 | |
445 | orig_width = gdk_pixbuf_get_width (background->loaded_image); |
446 | orig_height = gdk_pixbuf_get_height (background->loaded_image); |
447 | |
448 | panel_width = background->region.width; |
449 | panel_height = background->region.height; |
450 | |
451 | width = orig_width; |
452 | height = orig_height; |
453 | |
454 | if (background->fit_image) { |
455 | switch (background->orientation) { |
456 | case CTK_ORIENTATION_HORIZONTAL: |
457 | width = orig_width * panel_height / orig_height; |
458 | height = panel_height; |
459 | break; |
460 | case CTK_ORIENTATION_VERTICAL: |
461 | if (background->rotate_image) { |
462 | width = orig_width * panel_width / orig_height; |
463 | height = panel_width; |
464 | } else { |
465 | width = panel_width; |
466 | height = orig_height * panel_width / orig_width; |
467 | } |
468 | break; |
469 | default: |
470 | g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "panel-background.c" , 470, ((const char*) (__func__)), ((void*)0)); } while (0); |
471 | break; |
472 | } |
473 | } else if (background->stretch_image) { |
474 | if (background->orientation == CTK_ORIENTATION_VERTICAL && |
475 | background->rotate_image) { |
476 | width = panel_height; |
477 | height = panel_width; |
478 | } else { |
479 | width = panel_width; |
480 | height = panel_height; |
481 | } |
482 | } else if (background->orientation == CTK_ORIENTATION_VERTICAL && |
483 | background->rotate_image) { |
484 | int tmp = width; |
485 | width = height; |
486 | height = tmp; |
487 | } |
488 | |
489 | if (width == orig_width && |
490 | height == orig_height) { |
491 | scaled = background->loaded_image; |
492 | g_object_ref (scaled)((__typeof__ (scaled)) (g_object_ref) (scaled)); |
493 | } else { |
494 | scaled = gdk_pixbuf_scale_simple ( |
495 | background->loaded_image, |
496 | width, height, |
497 | GDK_INTERP_BILINEAR); |
498 | } |
499 | |
500 | if (background->rotate_image && |
501 | background->orientation == CTK_ORIENTATION_VERTICAL) { |
502 | if (!background->has_alpha) { |
503 | guchar *dest; |
504 | guchar *src; |
505 | int x, y; |
506 | int destrowstride; |
507 | int srcrowstride; |
508 | |
509 | retval = gdk_pixbuf_new ( |
510 | GDK_COLORSPACE_RGB, FALSE(0), 8, height, width); |
511 | |
512 | dest = gdk_pixbuf_get_pixels (retval); |
513 | destrowstride = gdk_pixbuf_get_rowstride (retval); |
514 | src = gdk_pixbuf_get_pixels (scaled); |
515 | srcrowstride = gdk_pixbuf_get_rowstride (scaled); |
516 | |
517 | for (y = 0; y < height; y++) |
518 | for (x = 0; x < width; x++) { |
519 | guchar *dstptr = & ( dest [3*y + destrowstride * (width - x - 1)] ); |
520 | guchar *srcptr = & ( src [y * srcrowstride + 3*x] ); |
521 | dstptr[0] = srcptr[0]; |
522 | dstptr[1] = srcptr[1]; |
523 | dstptr[2] = srcptr[2]; |
524 | } |
525 | |
526 | g_object_unref (scaled); |
527 | } else { |
528 | guint32 *dest; |
529 | guint32 *src; |
530 | int x, y; |
531 | int destrowstride; |
532 | int srcrowstride; |
533 | |
534 | retval = gdk_pixbuf_new ( |
535 | GDK_COLORSPACE_RGB, TRUE(!(0)), 8, height, width); |
536 | |
537 | dest = (guint32 *) gdk_pixbuf_get_pixels (retval); |
538 | destrowstride = gdk_pixbuf_get_rowstride (retval) / 4; |
539 | src = (guint32 *) gdk_pixbuf_get_pixels (scaled); |
540 | srcrowstride = gdk_pixbuf_get_rowstride (scaled) / 4; |
541 | |
542 | for (y = 0; y < height; y++) |
543 | for (x = 0; x < width; x++) |
544 | dest [y + destrowstride * (width - x - 1)] = |
545 | src [y * srcrowstride + x]; |
546 | |
547 | g_object_unref (scaled); |
548 | } |
549 | } else |
550 | retval = scaled; |
551 | |
552 | return retval; |
553 | } |
554 | |
555 | static gboolean |
556 | panel_background_transform (PanelBackground *background) |
557 | { |
558 | if (background->region.width == -1) |
559 | return FALSE(0); |
560 | |
561 | free_transformed_resources (background); |
562 | |
563 | if (background->type == PANEL_BACK_IMAGE) |
564 | background->transformed_image = |
565 | get_scaled_and_rotated_pixbuf (background); |
566 | |
567 | background->transformed = TRUE(!(0)); |
568 | |
569 | panel_background_composite (background); |
570 | |
571 | return TRUE(!(0)); |
572 | } |
573 | |
574 | #ifdef HAVE_X111 |
575 | static void |
576 | disconnect_background_monitor (PanelBackground *background) |
577 | { |
578 | g_return_if_fail (CDK_IS_X11_DISPLAY (cdk_display_get_default ()))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((cdk_display_get_default ())); GType __t = ((cdk_x11_display_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 (((gchar*) 0 ), ((const char*) (__func__)), "CDK_IS_X11_DISPLAY (cdk_display_get_default ())" ); return; } } while (0); |
579 | if (background->monitor) { |
580 | g_signal_handler_disconnect ( |
581 | background->monitor, background->monitor_signal); |
582 | background->monitor_signal = -1; |
583 | g_object_unref (background->monitor); |
584 | } |
585 | background->monitor = NULL((void*)0); |
586 | |
587 | if (background->desktop) |
588 | g_object_unref (background->desktop); |
589 | background->desktop = NULL((void*)0); |
590 | } |
591 | #endif // HAVE_X11 |
592 | |
593 | static void |
594 | panel_background_update_has_alpha (PanelBackground *background) |
595 | { |
596 | gboolean has_alpha = FALSE(0); |
597 | |
598 | if (background->type == PANEL_BACK_COLOR) |
599 | has_alpha = (background->color.alpha < 1.); |
600 | |
601 | else if (background->type == PANEL_BACK_IMAGE && |
602 | background->loaded_image) |
603 | has_alpha = gdk_pixbuf_get_has_alpha (background->loaded_image); |
604 | |
605 | background->has_alpha = has_alpha; |
606 | |
607 | #ifdef HAVE_X111 |
608 | if (CDK_IS_X11_DISPLAY (cdk_display_get_default ())(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (cdk_display_get_default ())); GType __t = ((cdk_x11_display_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; }))))) { |
609 | if (!has_alpha) |
610 | disconnect_background_monitor (background); |
611 | } |
612 | #endif // HAVE_X11 |
613 | } |
614 | |
615 | static void |
616 | load_background_file (PanelBackground *background) |
617 | { |
618 | GError *error = NULL((void*)0); |
619 | |
620 | if (!g_file_test (background->image, G_FILE_TEST_IS_REGULAR)) |
621 | return; |
622 | |
623 | //FIXME add a monitor on the file so that we reload the background |
624 | //when it changes |
625 | background->loaded_image = |
626 | gdk_pixbuf_new_from_file (background->image, &error); |
627 | if (!background->loaded_image) { |
628 | g_assert (error != NULL)do { if (error != ((void*)0)) ; else g_assertion_message_expr (((gchar*) 0), "panel-background.c", 628, ((const char*) (__func__ )), "error != NULL"); } while (0); |
629 | g_warning (G_STRLOC"panel-background.c" ":" "629" ": unable to open '%s': %s", |
630 | background->image, error->message); |
631 | g_error_free (error); |
632 | } |
633 | |
634 | panel_background_update_has_alpha (background); |
635 | } |
636 | |
637 | void |
638 | panel_background_set_type (PanelBackground *background, |
639 | PanelBackgroundType type) |
640 | { |
641 | if (background->type == type) |
642 | return; |
643 | |
644 | free_transformed_resources (background); |
645 | |
646 | background->type = type; |
647 | |
648 | panel_background_update_has_alpha (background); |
649 | |
650 | panel_background_transform (background); |
651 | } |
652 | |
653 | static void |
654 | panel_background_set_opacity_no_update (PanelBackground *background, |
655 | guint16 opacity) |
656 | { |
657 | background->color.alpha = opacity / 65535.0; |
658 | panel_background_update_has_alpha (background); |
659 | } |
660 | |
661 | void |
662 | panel_background_set_opacity (PanelBackground *background, |
663 | guint16 opacity) |
664 | { |
665 | if (background->color.alpha == (opacity / 65535.0)) |
666 | return; |
667 | |
668 | free_transformed_resources (background); |
669 | panel_background_set_opacity_no_update (background, opacity); |
670 | panel_background_transform (background); |
671 | } |
672 | |
673 | static void |
674 | panel_background_set_color_no_update (PanelBackground *background, |
675 | const CdkRGBA *color) |
676 | { |
677 | g_return_if_fail (color != NULL)do { if ((color != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "color != NULL"); return; } } while (0); |
678 | |
679 | if (cdk_rgba_equal (color, &background->color)) |
680 | return; |
681 | |
682 | background->color = *color; |
683 | panel_background_update_has_alpha (background); |
684 | } |
685 | |
686 | void |
687 | panel_background_set_color (PanelBackground *background, |
688 | const CdkRGBA *color) |
689 | { |
690 | g_return_if_fail (color != NULL)do { if ((color != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "color != NULL"); return; } } while (0); |
691 | |
692 | if (cdk_rgba_equal (color, &background->color)) |
693 | return; |
694 | |
695 | free_transformed_resources (background); |
696 | panel_background_set_color_no_update (background, color); |
697 | panel_background_transform (background); |
698 | } |
699 | |
700 | static void |
701 | panel_background_set_image_no_update (PanelBackground *background, |
702 | const char *image) |
703 | { |
704 | if (background->loaded_image) |
705 | g_object_unref (background->loaded_image); |
706 | background->loaded_image = NULL((void*)0); |
707 | |
708 | if (background->image) |
709 | g_free (background->image); |
710 | background->image = NULL((void*)0); |
711 | |
712 | if (image && image [0]) |
713 | background->image = g_strdup (image)g_strdup_inline (image); |
714 | |
715 | panel_background_update_has_alpha (background); |
716 | } |
717 | |
718 | void |
719 | panel_background_set_image (PanelBackground *background, |
720 | const char *image) |
721 | { |
722 | if (!background->image && !image) |
723 | return; |
724 | |
725 | if (background->image && image && !strcmp (background->image, image)) |
726 | return; |
727 | |
728 | free_transformed_resources (background); |
729 | panel_background_set_image_no_update (background, image); |
730 | panel_background_transform (background); |
731 | } |
732 | |
733 | static void |
734 | panel_background_set_fit_no_update (PanelBackground *background, |
735 | gboolean fit_image) |
736 | { |
737 | background->fit_image = fit_image != FALSE(0); |
738 | } |
739 | |
740 | void |
741 | panel_background_set_fit (PanelBackground *background, |
742 | gboolean fit_image) |
743 | { |
744 | fit_image = fit_image != FALSE(0); |
745 | |
746 | if (background->fit_image == fit_image) |
747 | return; |
748 | |
749 | free_transformed_resources (background); |
750 | panel_background_set_fit_no_update (background, fit_image); |
751 | panel_background_transform (background); |
752 | } |
753 | |
754 | static void |
755 | panel_background_set_stretch_no_update (PanelBackground *background, |
756 | gboolean stretch_image) |
757 | { |
758 | background->stretch_image = stretch_image != FALSE(0); |
759 | } |
760 | |
761 | void |
762 | panel_background_set_stretch (PanelBackground *background, |
763 | gboolean stretch_image) |
764 | { |
765 | stretch_image = stretch_image != FALSE(0); |
766 | |
767 | if (background->stretch_image == stretch_image) |
768 | return; |
769 | |
770 | free_transformed_resources (background); |
771 | panel_background_set_stretch_no_update (background, stretch_image); |
772 | panel_background_transform (background); |
773 | } |
774 | |
775 | static void |
776 | panel_background_set_rotate_no_update (PanelBackground *background, |
777 | gboolean rotate_image) |
778 | { |
779 | background->rotate_image = rotate_image != FALSE(0); |
780 | } |
781 | |
782 | void |
783 | panel_background_set_rotate (PanelBackground *background, |
784 | gboolean rotate_image) |
785 | { |
786 | rotate_image = rotate_image != FALSE(0); |
787 | |
788 | if (background->rotate_image == rotate_image) |
789 | return; |
790 | |
791 | free_transformed_resources (background); |
792 | panel_background_set_rotate_no_update (background, rotate_image); |
793 | panel_background_transform (background); |
794 | } |
795 | |
796 | void |
797 | panel_background_set (PanelBackground *background, |
798 | PanelBackgroundType type, |
799 | const CdkRGBA *color, |
800 | const char *image, |
801 | gboolean fit_image, |
802 | gboolean stretch_image, |
803 | gboolean rotate_image) |
804 | { |
805 | panel_background_set_color_no_update (background, color); |
806 | panel_background_set_image_no_update (background, image); |
807 | panel_background_set_fit_no_update (background, fit_image); |
808 | panel_background_set_stretch_no_update (background, stretch_image); |
809 | panel_background_set_rotate_no_update (background, rotate_image); |
810 | panel_background_set_type (background, type); |
811 | } |
812 | |
813 | void |
814 | panel_background_set_default_style (PanelBackground *background, |
815 | CdkRGBA *color, |
816 | cairo_pattern_t *pattern) |
817 | { |
818 | g_return_if_fail (color != NULL)do { if ((color != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "color != NULL"); return; } } while (0); |
819 | |
820 | background->default_color = *color; |
821 | |
822 | if (pattern) |
823 | cairo_pattern_reference (pattern); |
824 | |
825 | if (background->default_pattern) |
826 | cairo_pattern_destroy (background->default_pattern); |
827 | |
828 | background->default_pattern = pattern; |
829 | if (background->type == PANEL_BACK_NONE) |
830 | panel_background_prepare (background); |
831 | } |
832 | |
833 | |
834 | void |
835 | panel_background_realized (PanelBackground *background, |
836 | CdkWindow *window) |
837 | { |
838 | g_return_if_fail (window != NULL)do { if ((window != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "window != NULL") ; return; } } while (0); |
839 | |
840 | if (background->window) |
841 | return; |
842 | |
843 | background->window = g_object_ref (window)((__typeof__ (window)) (g_object_ref) (window)); |
844 | |
845 | panel_background_prepare_css (); |
846 | |
847 | panel_background_prepare (background); |
848 | } |
849 | |
850 | void |
851 | panel_background_unrealized (PanelBackground *background) |
852 | { |
853 | if (background->window) |
854 | g_object_unref (background->window); |
855 | background->window = NULL((void*)0); |
856 | } |
857 | |
858 | void |
859 | panel_background_change_region (PanelBackground *background, |
860 | CtkOrientation orientation, |
861 | int x, |
862 | int y, |
863 | int width, |
864 | int height) |
865 | { |
866 | gboolean need_to_retransform = FALSE(0); |
867 | gboolean need_to_reprepare = FALSE(0); |
868 | |
869 | if (background->region.x == x && |
870 | background->region.y == y && |
871 | background->region.width == width && |
872 | background->region.height == height && |
873 | background->orientation == orientation) |
874 | return; |
875 | |
876 | /* we only need to retransform anything |
877 | on size/orientation changes if the |
878 | background is an image and some |
879 | conditions are met */ |
880 | if (background->type == PANEL_BACK_IMAGE) { |
881 | if (background->orientation != orientation && |
882 | background->rotate_image) { |
883 | /* if orientation changes and we are rotating */ |
884 | need_to_retransform = TRUE(!(0)); |
885 | } else if ((background->region.width != width || |
886 | background->region.height != height) && |
887 | (background->fit_image || |
888 | background->stretch_image)) { |
889 | /* or if the size changes and we are |
890 | stretching or fitting the image */ |
891 | need_to_retransform = TRUE(!(0)); |
892 | } |
893 | } |
894 | |
895 | /* if size changed, we at least need |
896 | to "prepare" the background again */ |
897 | if (background->region.width != width || |
898 | background->region.height != height) |
899 | need_to_reprepare = TRUE(!(0)); |
900 | |
901 | background->region.x = x; |
902 | background->region.y = y; |
903 | background->region.width = width; |
904 | background->region.height = height; |
905 | |
906 | background->orientation = orientation; |
907 | |
908 | #ifdef HAVE_X111 |
909 | if (background->desktop) |
910 | g_object_unref (background->desktop); |
911 | background->desktop = NULL((void*)0); |
912 | #endif // HAVE_X11 |
913 | |
914 | if (need_to_retransform || ! background->transformed) |
915 | /* only retransform the background if we have in |
916 | fact changed size/orientation */ |
917 | panel_background_transform (background); |
918 | else if (background->has_alpha || ! background->composited) |
919 | /* only do compositing if we have some alpha |
920 | value to worry about */ |
921 | panel_background_composite (background); |
922 | else if (need_to_reprepare) |
923 | /* at least we must prepare the background |
924 | if the size changed */ |
925 | panel_background_prepare (background); |
926 | } |
927 | |
928 | void |
929 | panel_background_init (PanelBackground *background, |
930 | PanelBackgroundChangedNotify notify_changed, |
931 | gpointer user_data) |
932 | { |
933 | background->type = PANEL_BACK_NONE; |
934 | background->notify_changed = notify_changed; |
935 | background->user_data = user_data; |
936 | |
937 | background->color.red = 0.; |
938 | background->color.blue = 0.; |
939 | background->color.green = 0.; |
940 | background->color.alpha = 1.; |
941 | |
942 | background->image = NULL((void*)0); |
943 | background->loaded_image = NULL((void*)0); |
944 | |
945 | background->orientation = CTK_ORIENTATION_HORIZONTAL; |
946 | background->region.x = -1; |
947 | background->region.y = -1; |
948 | background->region.width = -1; |
949 | background->region.height = -1; |
950 | background->transformed_image = NULL((void*)0); |
951 | background->composited_pattern = NULL((void*)0); |
952 | |
953 | #ifdef HAVE_X111 |
954 | background->monitor = NULL((void*)0); |
955 | background->desktop = NULL((void*)0); |
956 | background->monitor_signal = -1; |
957 | #endif // HAVE_X11 |
958 | |
959 | background->window = NULL((void*)0); |
960 | |
961 | background->default_pattern = NULL((void*)0); |
962 | |
963 | background->default_color.red = 0.; |
964 | background->default_color.green = 0.; |
965 | background->default_color.blue = 0.; |
966 | background->default_color.alpha = 1.; |
967 | |
968 | background->fit_image = FALSE(0); |
969 | background->stretch_image = FALSE(0); |
970 | background->rotate_image = FALSE(0); |
971 | |
972 | background->has_alpha = FALSE(0); |
973 | |
974 | background->transformed = FALSE(0); |
975 | background->composited = FALSE(0); |
976 | } |
977 | |
978 | void |
979 | panel_background_free (PanelBackground *background) |
980 | { |
981 | #ifdef HAVE_X111 |
982 | if (CDK_IS_X11_DISPLAY (cdk_display_get_default ())(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (cdk_display_get_default ())); GType __t = ((cdk_x11_display_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; }))))) { |
983 | disconnect_background_monitor (background); |
984 | } |
985 | #endif // HAVE_X11 |
986 | |
987 | free_transformed_resources (background); |
988 | |
989 | if (background->image) |
990 | g_free (background->image); |
991 | background->image = NULL((void*)0); |
992 | |
993 | if (background->loaded_image) |
994 | g_object_unref (background->loaded_image); |
995 | background->loaded_image = NULL((void*)0); |
996 | |
997 | #ifdef HAVE_X111 |
998 | if (background->monitor) |
999 | g_object_unref (background->monitor); |
1000 | background->monitor = NULL((void*)0); |
1001 | #endif // HAVE_X11 |
1002 | |
1003 | if (background->window) |
1004 | g_object_unref (background->window); |
1005 | background->window = NULL((void*)0); |
1006 | |
1007 | if (background->default_pattern) |
1008 | cairo_pattern_destroy (background->default_pattern); |
1009 | background->default_pattern = NULL((void*)0); |
1010 | } |
1011 | |
1012 | char * |
1013 | panel_background_make_string (PanelBackground *background, |
1014 | int x, |
1015 | int y) |
1016 | { |
1017 | PanelBackgroundType effective_type; |
1018 | char *retval; |
1019 | |
1020 | retval = NULL((void*)0); |
1021 | |
1022 | effective_type = panel_background_effective_type (background); |
1023 | |
1024 | #ifdef HAVE_X111 |
1025 | if (is_using_x11 () && |
1026 | (effective_type == PANEL_BACK_IMAGE || |
1027 | (effective_type == PANEL_BACK_COLOR && |
1028 | background->has_alpha && |
1029 | !cdk_window_check_composited_wm(background->window)))) { |
1030 | |
1031 | cairo_surface_t *surface; |
1032 | |
1033 | if (!background->composited_pattern) |
1034 | return NULL((void*)0); |
1035 | |
1036 | if (cairo_pattern_get_surface (background->composited_pattern, &surface) != CAIRO_STATUS_SUCCESS) |
1037 | return NULL((void*)0); |
1038 | |
1039 | if (cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_XLIB) |
1040 | return NULL((void*)0); |
1041 | |
1042 | retval = g_strdup_printf ("pixmap:%d,%d,%d", (guint32)cairo_xlib_surface_get_drawable (surface), x, y); |
1043 | } else |
1044 | #endif |
1045 | if (effective_type == PANEL_BACK_COLOR) { |
1046 | gchar *rgba = cdk_rgba_to_string (&background->color); |
1047 | retval = g_strdup_printf ( |
1048 | "color:%s", |
1049 | rgba); |
1050 | g_free (rgba); |
1051 | } else |
1052 | retval = g_strdup ("none:")g_strdup_inline ("none:"); |
1053 | |
1054 | return retval; |
1055 | } |
1056 | |
1057 | PanelBackgroundType |
1058 | panel_background_get_type (PanelBackground *background) |
1059 | { |
1060 | return background->type; |
1061 | } |
1062 | |
1063 | const CdkRGBA * |
1064 | panel_background_get_color (PanelBackground *background) |
1065 | { |
1066 | return &(background->color); |
1067 | } |
1068 | |
1069 | /* What are we actually rendering - e.g. if we're supposed to |
1070 | * be rendering an image, but haven't got a valid image, then |
1071 | * we're rendering the default ctk background. |
1072 | */ |
1073 | PanelBackgroundType |
1074 | panel_background_effective_type (PanelBackground *background) |
1075 | { |
1076 | PanelBackgroundType retval; |
1077 | |
1078 | retval = background->type; |
1079 | if (background->type == PANEL_BACK_IMAGE && !background->composited_pattern) |
1080 | retval = PANEL_BACK_NONE; |
1081 | |
1082 | return retval; |
1083 | } |