summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-09-17 16:48:17 +0100
committerMarco Trevisan (Treviño) <mail@3v1n0.net>2014-09-17 18:51:57 +0200
commit5f88636284154e76611012c8a7c7495b9d917bd7 (patch)
tree3c5cc56f0cf1eee0894670e05375ae4ec36af381
parent20b1bfbe7b96c5d5a7508bc0f6180775df6ddb3c (diff)
downloadlibwnck-5f88636284154e76611012c8a7c7495b9d917bd7.tar.gz
xutils: Support non-standard depths for icon pixmaps
Currently the presumption is that applications assign a Pixmap for their icon image using the default visual for the screen, or as an A1 bitmap for the icon mask. At least SDL doesn't conform to this rule and always uses 32-bit ARGB Pixmaps. This cases the XCopyArea used by Cairo to grab the image surface from the Pixmap to fail as the source Pixmap and the cairo surface are of different depths and triggers a BadMatch - killing libwnck and its client gnome-shell/gala et al. So as a fallback, if the depth does not match the visual of the root window, we presume that it is in a standard XRenderPictFormat and create a cairo surface of the appropriate depth - instead of crashing, we may just get a weirdly coloured icon. Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=736817 Cc: Marco Trevisan (Treviño) <mail@3v1n0.net> Cc: Benjamin Otte <otte@redhat.com>
-rw-r--r--libwnck/xutils.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/libwnck/xutils.c b/libwnck/xutils.c
index 8222b19..53f3083 100644
--- a/libwnck/xutils.c
+++ b/libwnck/xutils.c
@@ -24,6 +24,9 @@
#include <string.h>
#include <stdio.h>
#include <cairo-xlib.h>
+#if CAIRO_HAS_XLIB_XRENDER_SURFACE
+#include <cairo-xlib-xrender.h>
+#endif
#include "screen.h"
#include "window.h"
#include "private.h"
@@ -1706,10 +1709,34 @@ _wnck_cairo_surface_get_from_pixmap (Screen *screen,
if (!XGetWindowAttributes (display, root_return, &attrs))
goto TRAP_POP;
- surface = cairo_xlib_surface_create (display,
- xpixmap,
- attrs.visual,
- w_ret, h_ret);
+ if (depth_ret == attrs.depth)
+ {
+ surface = cairo_xlib_surface_create (display,
+ xpixmap,
+ attrs.visual,
+ w_ret, h_ret);
+ }
+ else
+ {
+#if CAIRO_HAS_XLIB_XRENDER_SURFACE
+ int std;
+
+ switch (depth_ret) {
+ case 1: std = PictStandardA1; break;
+ case 4: std = PictStandardA4; break;
+ case 8: std = PictStandardA8; break;
+ case 24: std = PictStandardRGB24; break;
+ case 32: std = PictStandardARGB32; break;
+ default: goto TRAP_POP;
+ }
+
+ surface = cairo_xlib_surface_create_with_xrender_format (display,
+ xpixmap,
+ attrs.screen,
+ XRenderFindStandardFormat (display, std),
+ w_ret, h_ret);
+#endif
+ }
}
TRAP_POP: