[mutter] iconcache: Fix the icon of Kerbel Space Program



commit 9b903e93e3cd0601b436c55b7cea1fbecf29895f
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Tue Feb 17 23:37:01 2015 -0800

    iconcache: Fix the icon of Kerbel Space Program
    
    Kerbel Space Program, and perhaps some other SDL-based programs, use
    a really dumb way of specifying icons, which is totally
    non-standards-compliant.
    
    The ICCCM specifies that the icon_pixmap field of WM_HINTS should be a
    1-bit-deep Pixmap, but we've seen applications set it to a pixmap of the
    root depth as well, so we support that.
    
    Kerbel Space Program seems to use it with a 32-bit depth Pixmap,
    signifying ARGB32 (which it is), along with a 1-bit icon_mask, which
    crashes us.
    
    Keep in mind that Pixmaps, by definition, have no Visual attached, so
    we simply have to make a guess at the correct visual based on the
    depth. Do that by assuming that a depth-32 visual always means ARGB32,
    which is a pretty safe bet.

 src/x11/iconcache.c |   42 ++++++++++++++++++++++++++----------------
 1 files changed, 26 insertions(+), 16 deletions(-)
---
diff --git a/src/x11/iconcache.c b/src/x11/iconcache.c
index 71b7417..4747295 100644
--- a/src/x11/iconcache.c
+++ b/src/x11/iconcache.c
@@ -27,8 +27,10 @@
 
 #include <cairo.h>
 #include <cairo-xlib.h>
+#include <cairo-xlib-xrender.h>
 
 #include <X11/Xatom.h>
+#include <X11/extensions/Xrender.h>
 
 static gboolean
 find_largest_sizes (gulong *data,
@@ -284,34 +286,42 @@ get_pixmap_geometry (MetaDisplay *display,
     *d = depth;
 }
 
+static int
+standard_pict_format_for_depth (int depth)
+{
+  switch (depth)
+    {
+    case 1:
+      return PictStandardA1;
+    case 24:
+      return PictStandardRGB24;
+    case 32:
+      return PictStandardARGB32;
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+static XRenderPictFormat *
+pict_format_for_depth (Display *xdisplay, int depth)
+{
+  return XRenderFindStandardFormat (xdisplay, standard_pict_format_for_depth (depth));
+}
+
 static cairo_surface_t *
 surface_from_pixmap (Display *xdisplay, Pixmap xpixmap,
                      int width, int height)
 {
-  cairo_surface_t *surface;
   Window root_return;
   int x_ret, y_ret;
   unsigned int w_ret, h_ret, bw_ret, depth_ret;
-  XWindowAttributes attrs;
 
   if (!XGetGeometry (xdisplay, xpixmap, &root_return,
                      &x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret))
     return NULL;
 
-  if (depth_ret == 1)
-    {
-      surface = cairo_xlib_surface_create_for_bitmap (xdisplay, xpixmap, DefaultScreenOfDisplay (xdisplay),
-                                                      w_ret, h_ret);
-    }
-  else
-    {
-      if (!XGetWindowAttributes (xdisplay, root_return, &attrs))
-        return NULL;
-
-      surface = cairo_xlib_surface_create (xdisplay, xpixmap, attrs.visual, w_ret, h_ret);
-    }
-
-  return surface;
+  return cairo_xlib_surface_create_with_xrender_format (xdisplay, xpixmap, DefaultScreenOfDisplay (xdisplay),
+                                                        pict_format_for_depth (xdisplay, depth_ret), w_ret, 
h_ret);
 }
 
 static gboolean


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