xwindow: Add support for input shape from SHAPE 1.1
Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
2d736bf3b5
commit
64e05c236f
10
awesome.c
10
awesome.c
|
@ -661,6 +661,16 @@ main(int argc, char **argv)
|
||||||
/* check for shape extension */
|
/* check for shape extension */
|
||||||
query = xcb_get_extension_data(globalconf.connection, &xcb_shape_id);
|
query = xcb_get_extension_data(globalconf.connection, &xcb_shape_id);
|
||||||
globalconf.have_shape = query && query->present;
|
globalconf.have_shape = query && query->present;
|
||||||
|
if (globalconf.have_shape)
|
||||||
|
{
|
||||||
|
xcb_shape_query_version_reply_t *reply =
|
||||||
|
xcb_shape_query_version_reply(globalconf.connection,
|
||||||
|
xcb_shape_query_version_unchecked(globalconf.connection),
|
||||||
|
NULL);
|
||||||
|
globalconf.have_input_shape = reply && (reply->major_version > 1 ||
|
||||||
|
(reply->major_version == 1 && reply->minor_version >= 1));
|
||||||
|
p_delete(&reply);
|
||||||
|
}
|
||||||
|
|
||||||
event_init();
|
event_init();
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,8 @@ typedef struct
|
||||||
bool have_xtest;
|
bool have_xtest;
|
||||||
/** Check for SHAPE extension */
|
/** Check for SHAPE extension */
|
||||||
bool have_shape;
|
bool have_shape;
|
||||||
|
/** Check for SHAPE extension with input shape support */
|
||||||
|
bool have_input_shape;
|
||||||
/** Check for XKB extension */
|
/** Check for XKB extension */
|
||||||
bool have_xkb;
|
bool have_xkb;
|
||||||
uint8_t event_base_shape;
|
uint8_t event_base_shape;
|
||||||
|
|
91
xwindow.c
91
xwindow.c
|
@ -265,44 +265,70 @@ xwindow_get_shape(xcb_window_t win, enum xcb_shape_sk_t kind)
|
||||||
{
|
{
|
||||||
if (!globalconf.have_shape)
|
if (!globalconf.have_shape)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (kind == XCB_SHAPE_SK_INPUT && !globalconf.have_input_shape)
|
||||||
xcb_shape_query_extents_cookie_t ecookie = xcb_shape_query_extents(globalconf.connection, win);
|
return NULL;
|
||||||
xcb_shape_get_rectangles_cookie_t rcookie = xcb_shape_get_rectangles(globalconf.connection, win, kind);
|
|
||||||
xcb_shape_query_extents_reply_t *extents = xcb_shape_query_extents_reply(globalconf.connection, ecookie, NULL);
|
|
||||||
xcb_shape_get_rectangles_reply_t *rects_reply = xcb_shape_get_rectangles_reply(globalconf.connection, rcookie, NULL);
|
|
||||||
|
|
||||||
if (!extents || !rects_reply)
|
|
||||||
{
|
|
||||||
free(extents);
|
|
||||||
free(rects_reply);
|
|
||||||
/* Create a cairo surface in an error state */
|
|
||||||
return cairo_image_surface_create(CAIRO_FORMAT_INVALID, -1, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int16_t x, y;
|
int16_t x, y;
|
||||||
uint16_t width, height;
|
uint16_t width, height;
|
||||||
bool shaped;
|
xcb_shape_get_rectangles_cookie_t rcookie = xcb_shape_get_rectangles(globalconf.connection, win, kind);
|
||||||
if (kind == XCB_SHAPE_SK_BOUNDING)
|
if (kind == XCB_SHAPE_SK_INPUT)
|
||||||
{
|
{
|
||||||
x = extents->bounding_shape_extents_x;
|
/* We cannot query the size/existence of an input shape... */
|
||||||
y = extents->bounding_shape_extents_y;
|
xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(globalconf.connection,
|
||||||
width = extents->bounding_shape_extents_width;
|
xcb_get_geometry(globalconf.connection, win), NULL);
|
||||||
height = extents->bounding_shape_extents_height;
|
if (!geom)
|
||||||
shaped = extents->bounding_shaped;
|
{
|
||||||
} else {
|
xcb_discard_reply(globalconf.connection, rcookie.sequence);
|
||||||
assert(kind == XCB_SHAPE_SK_CLIP);
|
/* Create a cairo surface in an error state */
|
||||||
x = extents->clip_shape_extents_x;
|
return cairo_image_surface_create(CAIRO_FORMAT_INVALID, -1, -1);
|
||||||
y = extents->clip_shape_extents_y;
|
}
|
||||||
width = extents->clip_shape_extents_width;
|
x = 0;
|
||||||
height = extents->clip_shape_extents_height;
|
y = 0;
|
||||||
shaped = extents->clip_shaped;
|
width = geom->width;
|
||||||
|
height = geom->height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xcb_shape_query_extents_cookie_t ecookie = xcb_shape_query_extents(globalconf.connection, win);
|
||||||
|
xcb_shape_query_extents_reply_t *extents = xcb_shape_query_extents_reply(globalconf.connection, ecookie, NULL);
|
||||||
|
bool shaped;
|
||||||
|
|
||||||
|
if (!extents)
|
||||||
|
{
|
||||||
|
xcb_discard_reply(globalconf.connection, rcookie.sequence);
|
||||||
|
/* Create a cairo surface in an error state */
|
||||||
|
return cairo_image_surface_create(CAIRO_FORMAT_INVALID, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kind == XCB_SHAPE_SK_BOUNDING)
|
||||||
|
{
|
||||||
|
x = extents->bounding_shape_extents_x;
|
||||||
|
y = extents->bounding_shape_extents_y;
|
||||||
|
width = extents->bounding_shape_extents_width;
|
||||||
|
height = extents->bounding_shape_extents_height;
|
||||||
|
shaped = extents->bounding_shaped;
|
||||||
|
} else {
|
||||||
|
assert(kind == XCB_SHAPE_SK_CLIP);
|
||||||
|
x = extents->clip_shape_extents_x;
|
||||||
|
y = extents->clip_shape_extents_y;
|
||||||
|
width = extents->clip_shape_extents_width;
|
||||||
|
height = extents->clip_shape_extents_height;
|
||||||
|
shaped = extents->clip_shaped;
|
||||||
|
}
|
||||||
|
p_delete(&extents);
|
||||||
|
|
||||||
|
if (!shaped)
|
||||||
|
{
|
||||||
|
xcb_discard_reply(globalconf.connection, rcookie.sequence);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shaped)
|
xcb_shape_get_rectangles_reply_t *rects_reply = xcb_shape_get_rectangles_reply(globalconf.connection, rcookie, NULL);
|
||||||
|
if (!rects_reply)
|
||||||
{
|
{
|
||||||
free(extents);
|
/* Create a cairo surface in an error state */
|
||||||
free(rects_reply);
|
return cairo_image_surface_create(CAIRO_FORMAT_INVALID, -1, -1);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_A1, width, height);
|
cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_A1, width, height);
|
||||||
|
@ -318,7 +344,6 @@ xwindow_get_shape(xcb_window_t win, enum xcb_shape_sk_t kind)
|
||||||
cairo_fill(cr);
|
cairo_fill(cr);
|
||||||
|
|
||||||
cairo_destroy(cr);
|
cairo_destroy(cr);
|
||||||
free(extents);
|
|
||||||
free(rects_reply);
|
free(rects_reply);
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
@ -356,6 +381,8 @@ xwindow_set_shape(xcb_window_t win, int width, int height, enum xcb_shape_sk_t k
|
||||||
{
|
{
|
||||||
if (!globalconf.have_shape)
|
if (!globalconf.have_shape)
|
||||||
return;
|
return;
|
||||||
|
if (kind == XCB_SHAPE_SK_INPUT && !globalconf.have_input_shape)
|
||||||
|
return;
|
||||||
|
|
||||||
xcb_pixmap_t pixmap = XCB_NONE;
|
xcb_pixmap_t pixmap = XCB_NONE;
|
||||||
if (surf)
|
if (surf)
|
||||||
|
|
Loading…
Reference in New Issue