Bug Summary

File:cafe-panel/panel-background.c
Warning:line 119, column 4
Value stored to 'height' is never read

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 panel-background.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 -pic-is-pie -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 -fdebug-compilation-dir=/rootdir/cafe-panel -fcoverage-compilation-dir=/rootdir/cafe-panel -resource-dir /usr/lib/llvm-19/lib/clang/19 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/libpng16 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/ctk-3.0 -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-desktop-2.0 -I /usr/include/startup-notification-1.0 -I /usr/include/dconf -I /usr/include/cafe-menus -I /usr/include/dconf -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/libmount -I /usr/include/blkid -I . -I . -I ../cafe-panel -I ../cafe-panel/libpanel-util -D CAFELOCALEDIR="/usr/share/locale" -D PANELDATADIR="/usr/share/cafe-panel" -D PANEL_MODULES_DIR="/usr/lib/cafe-panel/modules" -D CAFEMENU_I_KNOW_THIS_IS_UNSTABLE -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -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.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/2025-04-06-095046-54450-1 -x c panel-background.c
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
42static gboolean panel_background_composite (PanelBackground *background);
43static void load_background_file (PanelBackground *background);
44
45
46static void
47set_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
54void 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
76static void
77panel_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
94static gboolean
95panel_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
190static void
191free_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
202static void _panel_background_transparency (CdkScreen *screen G_GNUC_UNUSED__attribute__ ((__unused__)),
203 PanelBackground *background)
204{
205 panel_background_composite(background);
206}
207
208static void
209background_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
231static GdkPixbuf *
232get_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
264static cairo_pattern_t *
265composite_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
317static cairo_pattern_t *
318composite_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
360static cairo_pattern_t *
361get_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
382static gboolean
383panel_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
417static void
418free_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
432static GdkPixbuf *
433get_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
555static gboolean
556panel_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
575static void
576disconnect_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
593static void
594panel_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
615static void
616load_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
637void
638panel_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
653static void
654panel_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
661void
662panel_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
673static void
674panel_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
686void
687panel_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
700static void
701panel_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
718void
719panel_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
733static void
734panel_background_set_fit_no_update (PanelBackground *background,
735 gboolean fit_image)
736{
737 background->fit_image = fit_image != FALSE(0);
738}
739
740void
741panel_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
754static void
755panel_background_set_stretch_no_update (PanelBackground *background,
756 gboolean stretch_image)
757{
758 background->stretch_image = stretch_image != FALSE(0);
759}
760
761void
762panel_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
775static void
776panel_background_set_rotate_no_update (PanelBackground *background,
777 gboolean rotate_image)
778{
779 background->rotate_image = rotate_image != FALSE(0);
780}
781
782void
783panel_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
796void
797panel_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
813void
814panel_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
834void
835panel_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
850void
851panel_background_unrealized (PanelBackground *background)
852{
853 if (background->window)
854 g_object_unref (background->window);
855 background->window = NULL((void*)0);
856}
857
858void
859panel_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
928void
929panel_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
978void
979panel_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
1012char *
1013panel_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
1057PanelBackgroundType
1058panel_background_get_type (PanelBackground *background)
1059{
1060 return background->type;
1061}
1062
1063const CdkRGBA *
1064panel_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 */
1073PanelBackgroundType
1074panel_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}