[libwnck] xutils: Support non-standard depths for icon pixmaps



commit 5f88636284154e76611012c8a7c7495b9d917bd7
Author: Chris Wilson <chris chris-wilson co uk>
Date:   Wed Sep 17 16:48:17 2014 +0100

    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>

 libwnck/xutils.c |   35 +++++++++++++++++++++++++++++++----
 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:


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]