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 -fcoverage-compilation-dir=/rootdir/cafe-panel -resource-dir /usr/lib/llvm-16/lib/clang/16 -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-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/cafe-panel -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-07-20-021807-56096-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,PanelBackground* background)
203{
204 panel_background_composite(background);
205}
206
207static void
208background_changed (PanelBackgroundMonitor *monitor,
209 PanelBackground *background)
210{
211 GdkPixbuf *tmp;
212
213 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)
;
214
215 tmp = background->desktop;
216
217 background->desktop = panel_background_monitor_get_region (
218 background->monitor,
219 background->region.x,
220 background->region.y,
221 background->region.width,
222 background->region.height);
223
224 if (tmp)
225 g_object_unref (tmp);
226
227 panel_background_composite (background);
228}
229
230static GdkPixbuf *
231get_desktop_pixbuf (PanelBackground *background)
232{
233 GdkPixbuf *desktop;
234
235 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)
;
236
237 if (!background->monitor) {
238 background->monitor =
239 panel_background_monitor_get_for_screen (
240 cdk_window_get_screen (background->window));
241
242 background->monitor_signal =
243 g_signal_connect (g_signal_connect_data ((background->monitor), ("changed"),
(((GCallback) (background_changed))), (background), ((void*)
0), (GConnectFlags) 0)
244 background->monitor, "changed",g_signal_connect_data ((background->monitor), ("changed"),
(((GCallback) (background_changed))), (background), ((void*)
0), (GConnectFlags) 0)
245 G_CALLBACK (background_changed), background)g_signal_connect_data ((background->monitor), ("changed"),
(((GCallback) (background_changed))), (background), ((void*)
0), (GConnectFlags) 0)
;
246 }
247 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)
248 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)
249 background)g_signal_connect_data ((cdk_window_get_screen(background->
window)), ("composited-changed"), (((GCallback) (_panel_background_transparency
))), (background), ((void*)0), (GConnectFlags) 0)
;
250
251 desktop = panel_background_monitor_get_region (
252 background->monitor,
253 background->region.x,
254 background->region.y,
255 background->region.width,
256 background->region.height);
257
258 return desktop;
259}
260
261#endif // HAVE_X11
262
263static cairo_pattern_t *
264composite_image_onto_desktop (PanelBackground *background)
265{
266 int width, height;
267 cairo_t *cr;
268 cairo_surface_t *surface;
269 cairo_pattern_t *pattern;
270
271 width = background->region.width;
272 height = background->region.height;
273
274 surface = cdk_window_create_similar_surface (background->window,
275 CAIRO_CONTENT_COLOR_ALPHA,
276 width, height);
277 if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) {
278 cairo_surface_destroy (surface);
279 return NULL((void*)0);
280 }
281
282 cr = cairo_create (surface);
283
284#ifdef HAVE_X111
285 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; }))))
) {
286 if (!background->desktop)
287 background->desktop = get_desktop_pixbuf (background);
288
289 if(!cdk_window_check_composited_wm (background->window)){
290 cairo_set_source_rgb (cr, 1, 1, 1);
291 cairo_paint (cr);
292
293 if (background->desktop) {
294 cdk_cairo_set_source_pixbuf (cr, background->desktop, 0, 0);
295 cairo_rectangle (cr, 0, 0, width, height);
296 cairo_fill (cr);
297 }
298 }
299 }
300#endif // HAVE_X11
301
302 cdk_cairo_set_source_pixbuf (cr, background->transformed_image, 0, 0);
303 pattern = cairo_get_source (cr);
304 cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
305
306 cairo_rectangle (cr, 0, 0, width, height);
307 cairo_fill (cr);
308
309 cairo_destroy (cr);
310
311 pattern = cairo_pattern_create_for_surface (surface);
312 cairo_surface_destroy (surface);
313 return pattern;
314}
315
316static cairo_pattern_t *
317composite_color_onto_desktop (PanelBackground *background)
318{
319 cairo_surface_t *surface;
320 cairo_pattern_t *pattern;
321 cairo_t *cr;
322
323 surface = cdk_window_create_similar_surface (background->window,
324 CAIRO_CONTENT_COLOR_ALPHA,
325 background->region.width,
326 background->region.height);
327 if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) {
328 cairo_surface_destroy (surface);
329 return NULL((void*)0);
330 }
331
332 cr = cairo_create (surface);
333
334#ifdef HAVE_X111
335 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; }))))
) {
336 if (!background->desktop)
337 background->desktop = get_desktop_pixbuf (background);
338
339 if(!cdk_window_check_composited_wm (background->window)){
340 if (background->desktop) {
341 cdk_cairo_set_source_pixbuf (cr, background->desktop, 0, 0);
342 cairo_paint (cr);
343 }
344 }
345 }
346#endif // HAVE_X11
347
348 cdk_cairo_set_source_rgba (cr, &background->color);
349 cairo_paint (cr);
350
351 cairo_destroy (cr);
352
353 pattern = cairo_pattern_create_for_surface (surface);
354 cairo_surface_destroy (surface);
355
356 return pattern;
357}
358
359static cairo_pattern_t *
360get_composited_pattern (PanelBackground *background)
361{
362 cairo_pattern_t *retval = NULL((void*)0);
363
364 switch (background->type) {
365 case PANEL_BACK_NONE:
366 break;
367 case PANEL_BACK_COLOR:
368 retval = composite_color_onto_desktop (background);
369 break;
370 case PANEL_BACK_IMAGE:
371 retval = composite_image_onto_desktop (background);
372 break;
373 default:
374 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "panel-background.c"
, 374, ((const char*) (__func__)), ((void*)0)); } while (0)
;
375 break;
376 }
377
378 return retval;
379}
380
381static gboolean
382panel_background_composite (PanelBackground *background)
383{
384 if (!background->transformed)
385 return FALSE(0);
386
387 free_composited_resources (background);
388
389 switch (background->type) {
390 case PANEL_BACK_NONE:
391 break;
392 case PANEL_BACK_COLOR:
393 if (background->has_alpha)
394 background->composited_pattern =
395 get_composited_pattern (background);
396 break;
397 case PANEL_BACK_IMAGE:
398 if (background->transformed_image) {
399 background->composited_pattern =
400 get_composited_pattern (background);
401 }
402 break;
403 default:
404 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "panel-background.c"
, 404, ((const char*) (__func__)), ((void*)0)); } while (0)
;
405 break;
406 }
407
408 background->composited = TRUE(!(0));
409
410
411 panel_background_prepare (background);
412
413 return TRUE(!(0));
414}
415
416static void
417free_transformed_resources (PanelBackground *background)
418{
419 free_composited_resources (background);
420
421 background->transformed = FALSE(0);
422
423 if (background->type != PANEL_BACK_IMAGE)
424 return;
425
426 if (background->transformed_image)
427 g_object_unref (background->transformed_image);
428 background->transformed_image = NULL((void*)0);
429}
430
431static GdkPixbuf *
432get_scaled_and_rotated_pixbuf (PanelBackground *background)
433{
434 GdkPixbuf *scaled;
435 GdkPixbuf *retval;
436 int orig_width, orig_height;
437 int panel_width, panel_height;
438 int width, height;
439
440 load_background_file (background);
441 if (!background->loaded_image)
442 return NULL((void*)0);
443
444 orig_width = gdk_pixbuf_get_width (background->loaded_image);
445 orig_height = gdk_pixbuf_get_height (background->loaded_image);
446
447 panel_width = background->region.width;
448 panel_height = background->region.height;
449
450 width = orig_width;
451 height = orig_height;
452
453 if (background->fit_image) {
454 switch (background->orientation) {
455 case CTK_ORIENTATION_HORIZONTAL:
456 width = orig_width * panel_height / orig_height;
457 height = panel_height;
458 break;
459 case CTK_ORIENTATION_VERTICAL:
460 if (background->rotate_image) {
461 width = orig_width * panel_width / orig_height;
462 height = panel_width;
463 } else {
464 width = panel_width;
465 height = orig_height * panel_width / orig_width;
466 }
467 break;
468 default:
469 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "panel-background.c"
, 469, ((const char*) (__func__)), ((void*)0)); } while (0)
;
470 break;
471 }
472 } else if (background->stretch_image) {
473 if (background->orientation == CTK_ORIENTATION_VERTICAL &&
474 background->rotate_image) {
475 width = panel_height;
476 height = panel_width;
477 } else {
478 width = panel_width;
479 height = panel_height;
480 }
481 } else if (background->orientation == CTK_ORIENTATION_VERTICAL &&
482 background->rotate_image) {
483 int tmp = width;
484 width = height;
485 height = tmp;
486 }
487
488 if (width == orig_width &&
489 height == orig_height) {
490 scaled = background->loaded_image;
491 g_object_ref (scaled)((__typeof__ (scaled)) (g_object_ref) (scaled));
492 } else {
493 scaled = gdk_pixbuf_scale_simple (
494 background->loaded_image,
495 width, height,
496 GDK_INTERP_BILINEAR);
497 }
498
499 if (background->rotate_image &&
500 background->orientation == CTK_ORIENTATION_VERTICAL) {
501 if (!background->has_alpha) {
502 guchar *dest;
503 guchar *src;
504 int x, y;
505 int destrowstride;
506 int srcrowstride;
507
508 retval = gdk_pixbuf_new (
509 GDK_COLORSPACE_RGB, FALSE(0), 8, height, width);
510
511 dest = gdk_pixbuf_get_pixels (retval);
512 destrowstride = gdk_pixbuf_get_rowstride (retval);
513 src = gdk_pixbuf_get_pixels (scaled);
514 srcrowstride = gdk_pixbuf_get_rowstride (scaled);
515
516 for (y = 0; y < height; y++)
517 for (x = 0; x < width; x++) {
518 guchar *dstptr = & ( dest [3*y + destrowstride * (width - x - 1)] );
519 guchar *srcptr = & ( src [y * srcrowstride + 3*x] );
520 dstptr[0] = srcptr[0];
521 dstptr[1] = srcptr[1];
522 dstptr[2] = srcptr[2];
523 }
524
525 g_object_unref (scaled);
526 } else {
527 guint32 *dest;
528 guint32 *src;
529 int x, y;
530 int destrowstride;
531 int srcrowstride;
532
533 retval = gdk_pixbuf_new (
534 GDK_COLORSPACE_RGB, TRUE(!(0)), 8, height, width);
535
536 dest = (guint32 *) gdk_pixbuf_get_pixels (retval);
537 destrowstride = gdk_pixbuf_get_rowstride (retval) / 4;
538 src = (guint32 *) gdk_pixbuf_get_pixels (scaled);
539 srcrowstride = gdk_pixbuf_get_rowstride (scaled) / 4;
540
541 for (y = 0; y < height; y++)
542 for (x = 0; x < width; x++)
543 dest [y + destrowstride * (width - x - 1)] =
544 src [y * srcrowstride + x];
545
546 g_object_unref (scaled);
547 }
548 } else
549 retval = scaled;
550
551 return retval;
552}
553
554static gboolean
555panel_background_transform (PanelBackground *background)
556{
557 if (background->region.width == -1)
558 return FALSE(0);
559
560 free_transformed_resources (background);
561
562 if (background->type == PANEL_BACK_IMAGE)
563 background->transformed_image =
564 get_scaled_and_rotated_pixbuf (background);
565
566 background->transformed = TRUE(!(0));
567
568 panel_background_composite (background);
569
570 return TRUE(!(0));
571}
572
573#ifdef HAVE_X111
574static void
575disconnect_background_monitor (PanelBackground *background)
576{
577 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)
;
578 if (background->monitor) {
579 g_signal_handler_disconnect (
580 background->monitor, background->monitor_signal);
581 background->monitor_signal = -1;
582 g_object_unref (background->monitor);
583 }
584 background->monitor = NULL((void*)0);
585
586 if (background->desktop)
587 g_object_unref (background->desktop);
588 background->desktop = NULL((void*)0);
589}
590#endif // HAVE_X11
591
592static void
593panel_background_update_has_alpha (PanelBackground *background)
594{
595 gboolean has_alpha = FALSE(0);
596
597 if (background->type == PANEL_BACK_COLOR)
598 has_alpha = (background->color.alpha < 1.);
599
600 else if (background->type == PANEL_BACK_IMAGE &&
601 background->loaded_image)
602 has_alpha = gdk_pixbuf_get_has_alpha (background->loaded_image);
603
604 background->has_alpha = has_alpha;
605
606#ifdef HAVE_X111
607 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; }))))
) {
608 if (!has_alpha)
609 disconnect_background_monitor (background);
610 }
611#endif // HAVE_X11
612}
613
614static void
615load_background_file (PanelBackground *background)
616{
617 GError *error = NULL((void*)0);
618
619 if (!g_file_test (background->image, G_FILE_TEST_IS_REGULAR))
620 return;
621
622 //FIXME add a monitor on the file so that we reload the background
623 //when it changes
624 background->loaded_image =
625 gdk_pixbuf_new_from_file (background->image, &error);
626 if (!background->loaded_image) {
627 g_assert (error != NULL)do { if (error != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "panel-background.c", 627, ((const char*) (__func__
)), "error != NULL"); } while (0)
;
628 g_warning (G_STRLOC"panel-background.c" ":" "628" ": unable to open '%s': %s",
629 background->image, error->message);
630 g_error_free (error);
631 }
632
633 panel_background_update_has_alpha (background);
634}
635
636void
637panel_background_set_type (PanelBackground *background,
638 PanelBackgroundType type)
639{
640 if (background->type == type)
641 return;
642
643 free_transformed_resources (background);
644
645 background->type = type;
646
647 panel_background_update_has_alpha (background);
648
649 panel_background_transform (background);
650}
651
652static void
653panel_background_set_opacity_no_update (PanelBackground *background,
654 guint16 opacity)
655{
656 background->color.alpha = opacity / 65535.0;
657 panel_background_update_has_alpha (background);
658}
659
660void
661panel_background_set_opacity (PanelBackground *background,
662 guint16 opacity)
663{
664 if (background->color.alpha == (opacity / 65535.0))
665 return;
666
667 free_transformed_resources (background);
668 panel_background_set_opacity_no_update (background, opacity);
669 panel_background_transform (background);
670}
671
672static void
673panel_background_set_color_no_update (PanelBackground *background,
674 const CdkRGBA *color)
675{
676 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)
;
677
678 if (cdk_rgba_equal (color, &background->color))
679 return;
680
681 background->color = *color;
682 panel_background_update_has_alpha (background);
683}
684
685void
686panel_background_set_color (PanelBackground *background,
687 const CdkRGBA *color)
688{
689 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)
;
690
691 if (cdk_rgba_equal (color, &background->color))
692 return;
693
694 free_transformed_resources (background);
695 panel_background_set_color_no_update (background, color);
696 panel_background_transform (background);
697}
698
699static void
700panel_background_set_image_no_update (PanelBackground *background,
701 const char *image)
702{
703 if (background->loaded_image)
704 g_object_unref (background->loaded_image);
705 background->loaded_image = NULL((void*)0);
706
707 if (background->image)
708 g_free (background->image);
709 background->image = NULL((void*)0);
710
711 if (image && image [0])
712 background->image = g_strdup (image)g_strdup_inline (image);
713
714 panel_background_update_has_alpha (background);
715}
716
717void
718panel_background_set_image (PanelBackground *background,
719 const char *image)
720{
721 if (!background->image && !image)
722 return;
723
724 if (background->image && image && !strcmp (background->image, image))
725 return;
726
727 free_transformed_resources (background);
728 panel_background_set_image_no_update (background, image);
729 panel_background_transform (background);
730}
731
732static void
733panel_background_set_fit_no_update (PanelBackground *background,
734 gboolean fit_image)
735{
736 background->fit_image = fit_image != FALSE(0);
737}
738
739void
740panel_background_set_fit (PanelBackground *background,
741 gboolean fit_image)
742{
743 fit_image = fit_image != FALSE(0);
744
745 if (background->fit_image == fit_image)
746 return;
747
748 free_transformed_resources (background);
749 panel_background_set_fit_no_update (background, fit_image);
750 panel_background_transform (background);
751}
752
753static void
754panel_background_set_stretch_no_update (PanelBackground *background,
755 gboolean stretch_image)
756{
757 background->stretch_image = stretch_image != FALSE(0);
758}
759
760void
761panel_background_set_stretch (PanelBackground *background,
762 gboolean stretch_image)
763{
764 stretch_image = stretch_image != FALSE(0);
765
766 if (background->stretch_image == stretch_image)
767 return;
768
769 free_transformed_resources (background);
770 panel_background_set_stretch_no_update (background, stretch_image);
771 panel_background_transform (background);
772}
773
774static void
775panel_background_set_rotate_no_update (PanelBackground *background,
776 gboolean rotate_image)
777{
778 background->rotate_image = rotate_image != FALSE(0);
779}
780
781void
782panel_background_set_rotate (PanelBackground *background,
783 gboolean rotate_image)
784{
785 rotate_image = rotate_image != FALSE(0);
786
787 if (background->rotate_image == rotate_image)
788 return;
789
790 free_transformed_resources (background);
791 panel_background_set_rotate_no_update (background, rotate_image);
792 panel_background_transform (background);
793}
794
795void
796panel_background_set (PanelBackground *background,
797 PanelBackgroundType type,
798 const CdkRGBA *color,
799 const char *image,
800 gboolean fit_image,
801 gboolean stretch_image,
802 gboolean rotate_image)
803{
804 panel_background_set_color_no_update (background, color);
805 panel_background_set_image_no_update (background, image);
806 panel_background_set_fit_no_update (background, fit_image);
807 panel_background_set_stretch_no_update (background, stretch_image);
808 panel_background_set_rotate_no_update (background, rotate_image);
809 panel_background_set_type (background, type);
810}
811
812void
813panel_background_set_default_style (PanelBackground *background,
814 CdkRGBA *color,
815 cairo_pattern_t *pattern)
816{
817 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)
;
818
819 background->default_color = *color;
820
821 if (pattern)
822 cairo_pattern_reference (pattern);
823
824 if (background->default_pattern)
825 cairo_pattern_destroy (background->default_pattern);
826
827 background->default_pattern = pattern;
828 if (background->type == PANEL_BACK_NONE)
829 panel_background_prepare (background);
830}
831
832
833void
834panel_background_realized (PanelBackground *background,
835 CdkWindow *window)
836{
837 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)
;
838
839 if (background->window)
840 return;
841
842 background->window = g_object_ref (window)((__typeof__ (window)) (g_object_ref) (window));
843
844 panel_background_prepare_css ();
845
846 panel_background_prepare (background);
847}
848
849void
850panel_background_unrealized (PanelBackground *background)
851{
852 if (background->window)
853 g_object_unref (background->window);
854 background->window = NULL((void*)0);
855}
856
857void
858panel_background_change_region (PanelBackground *background,
859 CtkOrientation orientation,
860 int x,
861 int y,
862 int width,
863 int height)
864{
865 gboolean need_to_retransform = FALSE(0);
866 gboolean need_to_reprepare = FALSE(0);
867
868 if (background->region.x == x &&
869 background->region.y == y &&
870 background->region.width == width &&
871 background->region.height == height &&
872 background->orientation == orientation)
873 return;
874
875 /* we only need to retransform anything
876 on size/orientation changes if the
877 background is an image and some
878 conditions are met */
879 if (background->type == PANEL_BACK_IMAGE) {
880 if (background->orientation != orientation &&
881 background->rotate_image) {
882 /* if orientation changes and we are rotating */
883 need_to_retransform = TRUE(!(0));
884 } else if ((background->region.width != width ||
885 background->region.height != height) &&
886 (background->fit_image ||
887 background->stretch_image)) {
888 /* or if the size changes and we are
889 stretching or fitting the image */
890 need_to_retransform = TRUE(!(0));
891 }
892 }
893
894 /* if size changed, we at least need
895 to "prepare" the background again */
896 if (background->region.width != width ||
897 background->region.height != height)
898 need_to_reprepare = TRUE(!(0));
899
900 background->region.x = x;
901 background->region.y = y;
902 background->region.width = width;
903 background->region.height = height;
904
905 background->orientation = orientation;
906
907#ifdef HAVE_X111
908 if (background->desktop)
909 g_object_unref (background->desktop);
910 background->desktop = NULL((void*)0);
911#endif // HAVE_X11
912
913 if (need_to_retransform || ! background->transformed)
914 /* only retransform the background if we have in
915 fact changed size/orientation */
916 panel_background_transform (background);
917 else if (background->has_alpha || ! background->composited)
918 /* only do compositing if we have some alpha
919 value to worry about */
920 panel_background_composite (background);
921 else if (need_to_reprepare)
922 /* at least we must prepare the background
923 if the size changed */
924 panel_background_prepare (background);
925}
926
927void
928panel_background_init (PanelBackground *background,
929 PanelBackgroundChangedNotify notify_changed,
930 gpointer user_data)
931{
932 background->type = PANEL_BACK_NONE;
933 background->notify_changed = notify_changed;
934 background->user_data = user_data;
935
936 background->color.red = 0.;
937 background->color.blue = 0.;
938 background->color.green = 0.;
939 background->color.alpha = 1.;
940
941 background->image = NULL((void*)0);
942 background->loaded_image = NULL((void*)0);
943
944 background->orientation = CTK_ORIENTATION_HORIZONTAL;
945 background->region.x = -1;
946 background->region.y = -1;
947 background->region.width = -1;
948 background->region.height = -1;
949 background->transformed_image = NULL((void*)0);
950 background->composited_pattern = NULL((void*)0);
951
952#ifdef HAVE_X111
953 background->monitor = NULL((void*)0);
954 background->desktop = NULL((void*)0);
955 background->monitor_signal = -1;
956#endif // HAVE_X11
957
958 background->window = NULL((void*)0);
959
960 background->default_pattern = NULL((void*)0);
961
962 background->default_color.red = 0.;
963 background->default_color.green = 0.;
964 background->default_color.blue = 0.;
965 background->default_color.alpha = 1.;
966
967 background->fit_image = FALSE(0);
968 background->stretch_image = FALSE(0);
969 background->rotate_image = FALSE(0);
970
971 background->has_alpha = FALSE(0);
972
973 background->transformed = FALSE(0);
974 background->composited = FALSE(0);
975}
976
977void
978panel_background_free (PanelBackground *background)
979{
980#ifdef HAVE_X111
981 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; }))))
) {
982 disconnect_background_monitor (background);
983 }
984#endif // HAVE_X11
985
986 free_transformed_resources (background);
987
988 if (background->image)
989 g_free (background->image);
990 background->image = NULL((void*)0);
991
992 if (background->loaded_image)
993 g_object_unref (background->loaded_image);
994 background->loaded_image = NULL((void*)0);
995
996#ifdef HAVE_X111
997 if (background->monitor)
998 g_object_unref (background->monitor);
999 background->monitor = NULL((void*)0);
1000#endif // HAVE_X11
1001
1002 if (background->window)
1003 g_object_unref (background->window);
1004 background->window = NULL((void*)0);
1005
1006 if (background->default_pattern)
1007 cairo_pattern_destroy (background->default_pattern);
1008 background->default_pattern = NULL((void*)0);
1009}
1010
1011char *
1012panel_background_make_string (PanelBackground *background,
1013 int x,
1014 int y)
1015{
1016 PanelBackgroundType effective_type;
1017 char *retval;
1018
1019 retval = NULL((void*)0);
1020
1021 effective_type = panel_background_effective_type (background);
1022
1023#ifdef HAVE_X111
1024 if (is_using_x11 () &&
1025 (effective_type == PANEL_BACK_IMAGE ||
1026 (effective_type == PANEL_BACK_COLOR &&
1027 background->has_alpha &&
1028 !cdk_window_check_composited_wm(background->window)))) {
1029
1030 cairo_surface_t *surface;
1031
1032 if (!background->composited_pattern)
1033 return NULL((void*)0);
1034
1035 if (cairo_pattern_get_surface (background->composited_pattern, &surface) != CAIRO_STATUS_SUCCESS)
1036 return NULL((void*)0);
1037
1038 if (cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_XLIB)
1039 return NULL((void*)0);
1040
1041 retval = g_strdup_printf ("pixmap:%d,%d,%d", (guint32)cairo_xlib_surface_get_drawable (surface), x, y);
1042 } else
1043#endif
1044 if (effective_type == PANEL_BACK_COLOR) {
1045 gchar *rgba = cdk_rgba_to_string (&background->color);
1046 retval = g_strdup_printf (
1047 "color:%s",
1048 rgba);
1049 g_free (rgba);
1050 } else
1051 retval = g_strdup ("none:")g_strdup_inline ("none:");
1052
1053 return retval;
1054}
1055
1056PanelBackgroundType
1057panel_background_get_type (PanelBackground *background)
1058{
1059 return background->type;
1060}
1061
1062const CdkRGBA *
1063panel_background_get_color (PanelBackground *background)
1064{
1065 return &(background->color);
1066}
1067
1068/* What are we actually rendering - e.g. if we're supposed to
1069 * be rendering an image, but haven't got a valid image, then
1070 * we're rendering the default ctk background.
1071 */
1072PanelBackgroundType
1073panel_background_effective_type (PanelBackground *background)
1074{
1075 PanelBackgroundType retval;
1076
1077 retval = background->type;
1078 if (background->type == PANEL_BACK_IMAGE && !background->composited_pattern)
1079 retval = PANEL_BACK_NONE;
1080
1081 return retval;
1082}