mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 19:42:05 +00:00
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.
This commit is contained in:
parent
7966f00a18
commit
9b903e93e3
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user