aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-03-26 17:10:42 +0800
committerPo Lu2022-03-26 17:14:38 +0800
commita4d45f1efd669bae3ea21a0c2cf0e3302a8379f2 (patch)
tree09a5940b057da63f332bb1f1549e9f821d31f13b /src
parent4525b4911834a95850e70c48de4c71de44af53de (diff)
downloademacs-a4d45f1efd669bae3ea21a0c2cf0e3302a8379f2.tar.gz
emacs-a4d45f1efd669bae3ea21a0c2cf0e3302a8379f2.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/xterm.c122
1 files changed, 121 insertions, 1 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 7edec2cd401..e448c177c0a 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -550,6 +550,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
550#include <X11/extensions/shape.h> 550#include <X11/extensions/shape.h>
551#endif 551#endif
552 552
553#ifdef HAVE_XCB_SHAPE
554#include <xcb/shape.h>
555#endif
556
553/* Load sys/types.h if not already loaded. 557/* Load sys/types.h if not already loaded.
554 In some systems loading it twice is suicidal. */ 558 In some systems loading it twice is suicidal. */
555#ifndef makedev 559#ifndef makedev
@@ -658,6 +662,12 @@ bool use_xim = true;
658bool use_xim = false; /* configure --without-xim */ 662bool use_xim = false; /* configure --without-xim */
659#endif 663#endif
660 664
665#if XCB_SHAPE_MAJOR_VERSION > 1 \
666 || (XCB_SHAPE_MAJOR_VERSION == 1 && \
667 XCB_SHAPE_MINOR_VERSION >= 1)
668#define HAVE_XCB_SHAPE_INPUT_RECTS
669#endif
670
661#ifdef USE_GTK 671#ifdef USE_GTK
662/* GTK can't tolerate a call to `handle_interrupt' inside an event 672/* GTK can't tolerate a call to `handle_interrupt' inside an event
663 signal handler, but we have to store input events inside the 673 signal handler, but we have to store input events inside the
@@ -912,8 +922,21 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
912 xcb_get_geometry_reply_t *geometry_reply; 922 xcb_get_geometry_reply_t *geometry_reply;
913 xcb_generic_error_t *error; 923 xcb_generic_error_t *error;
914#endif 924#endif
925
926#ifdef HAVE_XCB_SHAPE
927 xcb_shape_get_rectangles_cookie_t *bounding_rect_cookies;
928 xcb_shape_get_rectangles_reply_t *bounding_rect_reply;
929 xcb_rectangle_iterator_t bounding_rect_iterator;
930#endif
931
932#ifdef HAVE_XCB_SHAPE_INPUT_RECTS
933 xcb_shape_get_rectangles_cookie_t *input_rect_cookies;
934 xcb_shape_get_rectangles_reply_t *input_rect_reply;
935 xcb_rectangle_iterator_t input_rect_iterator;
936#endif
937
915 struct x_client_list_window *tem; 938 struct x_client_list_window *tem;
916#ifdef HAVE_XSHAPE 939#if defined HAVE_XSHAPE && !defined HAVE_XCB_SHAPE_INPUT_RECTS
917 int count, ordering; 940 int count, ordering;
918 XRectangle *rects; 941 XRectangle *rects;
919#endif 942#endif
@@ -943,6 +966,13 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
943 = alloca (sizeof *get_property_cookies * nitems); 966 = alloca (sizeof *get_property_cookies * nitems);
944 get_geometry_cookies 967 get_geometry_cookies
945 = alloca (sizeof *get_geometry_cookies * nitems); 968 = alloca (sizeof *get_geometry_cookies * nitems);
969 bounding_rect_cookies
970 = alloca (sizeof *bounding_rect_cookies * nitems);
971
972#ifdef HAVE_XCB_SHAPE_INPUT_RECTS
973 input_rect_cookies
974 = alloca (sizeof *input_rect_cookies * nitems);
975#endif
946 976
947 for (i = 0; i < nitems; ++i) 977 for (i = 0; i < nitems; ++i)
948 { 978 {
@@ -960,6 +990,23 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
960 0, 2); 990 0, 2);
961 get_geometry_cookies[i] 991 get_geometry_cookies[i]
962 = xcb_get_geometry (dpyinfo->xcb_connection, (xcb_window_t) toplevels[i]); 992 = xcb_get_geometry (dpyinfo->xcb_connection, (xcb_window_t) toplevels[i]);
993
994#ifdef HAVE_XCB_SHAPE
995 bounding_rect_cookies[i]
996 = xcb_shape_get_rectangles (dpyinfo->xcb_connection,
997 (xcb_window_t) toplevels[i],
998 XCB_SHAPE_SK_BOUNDING);
999#endif
1000
1001#ifdef HAVE_XCB_SHAPE_INPUT_RECTS
1002 if (dpyinfo->xshape_major > 1
1003 || (dpyinfo->xshape_major == 1
1004 && dpyinfo->xshape_minor >= 1))
1005 input_rect_cookies[i]
1006 = xcb_shape_get_rectangles (dpyinfo->xcb_connection,
1007 (xcb_window_t) toplevels[i],
1008 XCB_SHAPE_SK_INPUT);
1009#endif
963 } 1010 }
964#endif 1011#endif
965 1012
@@ -1094,6 +1141,7 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
1094 ShapeNotifyMask); 1141 ShapeNotifyMask);
1095 x_uncatch_errors (); 1142 x_uncatch_errors ();
1096 1143
1144#ifndef HAVE_XCB_SHAPE
1097 x_catch_errors (dpyinfo->display); 1145 x_catch_errors (dpyinfo->display);
1098 rects = XShapeGetRectangles (dpyinfo->display, 1146 rects = XShapeGetRectangles (dpyinfo->display,
1099 toplevels[i], 1147 toplevels[i],
@@ -1114,7 +1162,78 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
1114 1162
1115 XFree (rects); 1163 XFree (rects);
1116 } 1164 }
1165#else
1166 bounding_rect_reply = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
1167 bounding_rect_cookies[i],
1168 &error);
1117 1169
1170 if (bounding_rect_reply)
1171 {
1172 bounding_rect_iterator
1173 = xcb_shape_get_rectangles_rectangles_iterator (bounding_rect_reply);
1174 tem->n_bounding_rects = bounding_rect_iterator.rem + 1;
1175 tem->bounding_rects = xmalloc (tem->n_bounding_rects
1176 * sizeof *tem->bounding_rects);
1177 tem->n_bounding_rects = 0;
1178
1179 for (; bounding_rect_iterator.rem; xcb_rectangle_next (&bounding_rect_iterator))
1180 {
1181 tem->bounding_rects[tem->n_bounding_rects].x
1182 = bounding_rect_iterator.data->x;
1183 tem->bounding_rects[tem->n_bounding_rects].y
1184 = bounding_rect_iterator.data->y;
1185 tem->bounding_rects[tem->n_bounding_rects].width
1186 = bounding_rect_iterator.data->width;
1187 tem->bounding_rects[tem->n_bounding_rects].height
1188 = bounding_rect_iterator.data->height;
1189
1190 tem->n_bounding_rects++;
1191 }
1192
1193 free (bounding_rect_reply);
1194 }
1195 else
1196 free (error);
1197#endif
1198
1199#ifdef HAVE_XCB_SHAPE_INPUT_RECTS
1200 if (dpyinfo->xshape_major > 1
1201 || (dpyinfo->xshape_major == 1
1202 && dpyinfo->xshape_minor >= 1))
1203 {
1204 input_rect_reply = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
1205 input_rect_cookies[i],
1206 &error);
1207
1208 if (input_rect_reply)
1209 {
1210 input_rect_iterator
1211 = xcb_shape_get_rectangles_rectangles_iterator (input_rect_reply);
1212 tem->n_input_rects = input_rect_iterator.rem + 1;
1213 tem->input_rects = xmalloc (tem->n_input_rects
1214 * sizeof *tem->input_rects);
1215 tem->n_input_rects = 0;
1216
1217 for (; input_rect_iterator.rem; xcb_rectangle_next (&input_rect_iterator))
1218 {
1219 tem->input_rects[tem->n_input_rects].x
1220 = input_rect_iterator.data->x;
1221 tem->input_rects[tem->n_input_rects].y
1222 = input_rect_iterator.data->y;
1223 tem->input_rects[tem->n_input_rects].width
1224 = input_rect_iterator.data->width;
1225 tem->input_rects[tem->n_input_rects].height
1226 = input_rect_iterator.data->height;
1227
1228 tem->n_input_rects++;
1229 }
1230
1231 free (input_rect_reply);
1232 }
1233 else
1234 free (error);
1235 }
1236#else
1118#ifdef ShapeInput 1237#ifdef ShapeInput
1119 if (dpyinfo->xshape_major > 1 1238 if (dpyinfo->xshape_major > 1
1120 || (dpyinfo->xshape_major == 1 1239 || (dpyinfo->xshape_major == 1
@@ -1141,6 +1260,7 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
1141 } 1260 }
1142 } 1261 }
1143#endif 1262#endif
1263#endif
1144 } 1264 }
1145 1265
1146 /* Handle the common case where the input shape equals the 1266 /* Handle the common case where the input shape equals the