[mutter] iconcache: Fix the icon of Kerbel Space Program
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] iconcache: Fix the icon of Kerbel Space Program
- Date: Wed, 18 Feb 2015 07:45:24 +0000 (UTC)
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]