### Use the Nonrectangular Window Shape extension if available.
HAVE_XSHAPE=no
+HAVE_XCB_SHAPE=no
if test "${HAVE_X11}" = "yes"; then
AC_CHECK_HEADER(X11/extensions/shape.h,
[AC_CHECK_LIB(Xext, XShapeQueryVersion, HAVE_XSHAPE=yes)],
])
if test $HAVE_XSHAPE = yes; then
XSHAPE_LIBS=-lXext
+ AC_CHECK_HEADER(xcb/shape.h,
+ [AC_CHECK_LIB(xcb-shape, xcb_shape_combine, HAVE_XCB_SHAPE=yes)], [],
+ [#include <xcb/shape.h>])
+
+ if test $HAVE_XCB_SHAPE = yes && test "$XCB_LIBS" != ""; then
+ XSHAPE_LIBS="$XSHAPE_LIBS -lxcb-shape"
+ AC_DEFINE(HAVE_XCB_SHAPE, 1, [Define to 1 if XCB supports the Nonrectangular Window Shape extension.])
+ fi
fi
if test $HAVE_XSHAPE = yes; then
AC_DEFINE(HAVE_XSHAPE, 1, [Define to 1 if you have the Nonrectangular Window Shape extension.])
#include <X11/extensions/shape.h>
#endif
+#ifdef HAVE_XCB_SHAPE
+#include <xcb/shape.h>
+#endif
+
/* Load sys/types.h if not already loaded.
In some systems loading it twice is suicidal. */
#ifndef makedev
bool use_xim = false; /* configure --without-xim */
#endif
+#if XCB_SHAPE_MAJOR_VERSION > 1 \
+ || (XCB_SHAPE_MAJOR_VERSION == 1 && \
+ XCB_SHAPE_MINOR_VERSION >= 1)
+#define HAVE_XCB_SHAPE_INPUT_RECTS
+#endif
+
#ifdef USE_GTK
/* GTK can't tolerate a call to `handle_interrupt' inside an event
signal handler, but we have to store input events inside the
xcb_get_geometry_reply_t *geometry_reply;
xcb_generic_error_t *error;
#endif
+
+#ifdef HAVE_XCB_SHAPE
+ xcb_shape_get_rectangles_cookie_t *bounding_rect_cookies;
+ xcb_shape_get_rectangles_reply_t *bounding_rect_reply;
+ xcb_rectangle_iterator_t bounding_rect_iterator;
+#endif
+
+#ifdef HAVE_XCB_SHAPE_INPUT_RECTS
+ xcb_shape_get_rectangles_cookie_t *input_rect_cookies;
+ xcb_shape_get_rectangles_reply_t *input_rect_reply;
+ xcb_rectangle_iterator_t input_rect_iterator;
+#endif
+
struct x_client_list_window *tem;
-#ifdef HAVE_XSHAPE
+#if defined HAVE_XSHAPE && !defined HAVE_XCB_SHAPE_INPUT_RECTS
int count, ordering;
XRectangle *rects;
#endif
= alloca (sizeof *get_property_cookies * nitems);
get_geometry_cookies
= alloca (sizeof *get_geometry_cookies * nitems);
+ bounding_rect_cookies
+ = alloca (sizeof *bounding_rect_cookies * nitems);
+
+#ifdef HAVE_XCB_SHAPE_INPUT_RECTS
+ input_rect_cookies
+ = alloca (sizeof *input_rect_cookies * nitems);
+#endif
for (i = 0; i < nitems; ++i)
{
0, 2);
get_geometry_cookies[i]
= xcb_get_geometry (dpyinfo->xcb_connection, (xcb_window_t) toplevels[i]);
+
+#ifdef HAVE_XCB_SHAPE
+ bounding_rect_cookies[i]
+ = xcb_shape_get_rectangles (dpyinfo->xcb_connection,
+ (xcb_window_t) toplevels[i],
+ XCB_SHAPE_SK_BOUNDING);
+#endif
+
+#ifdef HAVE_XCB_SHAPE_INPUT_RECTS
+ if (dpyinfo->xshape_major > 1
+ || (dpyinfo->xshape_major == 1
+ && dpyinfo->xshape_minor >= 1))
+ input_rect_cookies[i]
+ = xcb_shape_get_rectangles (dpyinfo->xcb_connection,
+ (xcb_window_t) toplevels[i],
+ XCB_SHAPE_SK_INPUT);
+#endif
}
#endif
ShapeNotifyMask);
x_uncatch_errors ();
+#ifndef HAVE_XCB_SHAPE
x_catch_errors (dpyinfo->display);
rects = XShapeGetRectangles (dpyinfo->display,
toplevels[i],
XFree (rects);
}
+#else
+ bounding_rect_reply = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
+ bounding_rect_cookies[i],
+ &error);
+ if (bounding_rect_reply)
+ {
+ bounding_rect_iterator
+ = xcb_shape_get_rectangles_rectangles_iterator (bounding_rect_reply);
+ tem->n_bounding_rects = bounding_rect_iterator.rem + 1;
+ tem->bounding_rects = xmalloc (tem->n_bounding_rects
+ * sizeof *tem->bounding_rects);
+ tem->n_bounding_rects = 0;
+
+ for (; bounding_rect_iterator.rem; xcb_rectangle_next (&bounding_rect_iterator))
+ {
+ tem->bounding_rects[tem->n_bounding_rects].x
+ = bounding_rect_iterator.data->x;
+ tem->bounding_rects[tem->n_bounding_rects].y
+ = bounding_rect_iterator.data->y;
+ tem->bounding_rects[tem->n_bounding_rects].width
+ = bounding_rect_iterator.data->width;
+ tem->bounding_rects[tem->n_bounding_rects].height
+ = bounding_rect_iterator.data->height;
+
+ tem->n_bounding_rects++;
+ }
+
+ free (bounding_rect_reply);
+ }
+ else
+ free (error);
+#endif
+
+#ifdef HAVE_XCB_SHAPE_INPUT_RECTS
+ if (dpyinfo->xshape_major > 1
+ || (dpyinfo->xshape_major == 1
+ && dpyinfo->xshape_minor >= 1))
+ {
+ input_rect_reply = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
+ input_rect_cookies[i],
+ &error);
+
+ if (input_rect_reply)
+ {
+ input_rect_iterator
+ = xcb_shape_get_rectangles_rectangles_iterator (input_rect_reply);
+ tem->n_input_rects = input_rect_iterator.rem + 1;
+ tem->input_rects = xmalloc (tem->n_input_rects
+ * sizeof *tem->input_rects);
+ tem->n_input_rects = 0;
+
+ for (; input_rect_iterator.rem; xcb_rectangle_next (&input_rect_iterator))
+ {
+ tem->input_rects[tem->n_input_rects].x
+ = input_rect_iterator.data->x;
+ tem->input_rects[tem->n_input_rects].y
+ = input_rect_iterator.data->y;
+ tem->input_rects[tem->n_input_rects].width
+ = input_rect_iterator.data->width;
+ tem->input_rects[tem->n_input_rects].height
+ = input_rect_iterator.data->height;
+
+ tem->n_input_rects++;
+ }
+
+ free (input_rect_reply);
+ }
+ else
+ free (error);
+ }
+#else
#ifdef ShapeInput
if (dpyinfo->xshape_major > 1
|| (dpyinfo->xshape_major == 1
XFree (rects);
}
}
+#endif
#endif
}