diff options
| author | Po Lu | 2022-03-26 17:10:42 +0800 |
|---|---|---|
| committer | Po Lu | 2022-03-26 17:14:38 +0800 |
| commit | a4d45f1efd669bae3ea21a0c2cf0e3302a8379f2 (patch) | |
| tree | 09a5940b057da63f332bb1f1549e9f821d31f13b /src | |
| parent | 4525b4911834a95850e70c48de4c71de44af53de (diff) | |
| download | emacs-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.c | 122 |
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; | |||
| 658 | bool use_xim = false; /* configure --without-xim */ | 662 | bool 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 |