mirror of
https://github.com/brl/mutter.git
synced 2025-01-11 20:22:23 +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.h>
|
||||||
#include <cairo-xlib.h>
|
#include <cairo-xlib.h>
|
||||||
|
#include <cairo-xlib-xrender.h>
|
||||||
|
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/extensions/Xrender.h>
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
find_largest_sizes (gulong *data,
|
find_largest_sizes (gulong *data,
|
||||||
@ -284,34 +286,42 @@ get_pixmap_geometry (MetaDisplay *display,
|
|||||||
*d = depth;
|
*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 *
|
static cairo_surface_t *
|
||||||
surface_from_pixmap (Display *xdisplay, Pixmap xpixmap,
|
surface_from_pixmap (Display *xdisplay, Pixmap xpixmap,
|
||||||
int width, int height)
|
int width, int height)
|
||||||
{
|
{
|
||||||
cairo_surface_t *surface;
|
|
||||||
Window root_return;
|
Window root_return;
|
||||||
int x_ret, y_ret;
|
int x_ret, y_ret;
|
||||||
unsigned int w_ret, h_ret, bw_ret, depth_ret;
|
unsigned int w_ret, h_ret, bw_ret, depth_ret;
|
||||||
XWindowAttributes attrs;
|
|
||||||
|
|
||||||
if (!XGetGeometry (xdisplay, xpixmap, &root_return,
|
if (!XGetGeometry (xdisplay, xpixmap, &root_return,
|
||||||
&x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret))
|
&x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (depth_ret == 1)
|
return cairo_xlib_surface_create_with_xrender_format (xdisplay, xpixmap, DefaultScreenOfDisplay (xdisplay),
|
||||||
{
|
pict_format_for_depth (xdisplay, depth_ret), w_ret, h_ret);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
Loading…
Reference in New Issue
Block a user