Also fetch shapes via XCB for drag and drop
* configure.ac: Also look for xcb-shape. * src/xterm.c (HAVE_XCB_SHAPE_INPUT_RECTS): New define. (x_dnd_compute_toplevels): Use XCB for input shapes if possible.
This commit is contained in:
parent
4525b49118
commit
a4d45f1efd
2 changed files with 130 additions and 1 deletions
|
@ -4540,6 +4540,7 @@ AC_SUBST(XDBE_LIBS)
|
|||
|
||||
### 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)],
|
||||
|
@ -4548,6 +4549,14 @@ if test "${HAVE_X11}" = "yes"; then
|
|||
])
|
||||
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.])
|
||||
|
|
122
src/xterm.c
122
src/xterm.c
|
@ -550,6 +550,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#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
|
||||
|
@ -658,6 +662,12 @@ bool use_xim = true;
|
|||
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
|
||||
|
@ -912,8 +922,21 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
|
|||
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
|
||||
|
@ -943,6 +966,13 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
|
|||
= 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)
|
||||
{
|
||||
|
@ -960,6 +990,23 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
|
|||
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
|
||||
|
||||
|
@ -1094,6 +1141,7 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
|
|||
ShapeNotifyMask);
|
||||
x_uncatch_errors ();
|
||||
|
||||
#ifndef HAVE_XCB_SHAPE
|
||||
x_catch_errors (dpyinfo->display);
|
||||
rects = XShapeGetRectangles (dpyinfo->display,
|
||||
toplevels[i],
|
||||
|
@ -1114,7 +1162,78 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
|
|||
|
||||
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
|
||||
|
@ -1140,6 +1259,7 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
|
|||
XFree (rects);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue