diff options
| author | Po Lu | 2022-03-31 21:28:09 +0800 |
|---|---|---|
| committer | Po Lu | 2022-03-31 21:28:22 +0800 |
| commit | 1bd14387027d5fa93ccbc38b6e4ce715c916bbc6 (patch) | |
| tree | fb163c90382571255117bb9b6c829f3546b3a71f /src | |
| parent | af0ea35ea00725d2700a5215b56b725dc0d88d0d (diff) | |
| download | emacs-1bd14387027d5fa93ccbc38b6e4ce715c916bbc6.tar.gz emacs-1bd14387027d5fa93ccbc38b6e4ce715c916bbc6.zip | |
Implement missing parts of the Motif drag and drop protocol
* src/xterm.c (xm_drop_start_reply): New structure.
(xm_get_drag_window): Don't grab the server since this leads to
weird freezes when creating the drag window.
(xm_read_drop_start_reply): New function.
(x_dnd_begin_drag_and_drop): Set Motif finish flag to 0.
(handle_one_xevent): When starting a motif drop, set the finish
flag to 1. When the receiver replies to our drop message, set
the finish flag to 2 if the drop was accepted, and only clear
the waiting for finish flag when a selection request for
XmTRANSFER_SUCCESS or XmTRANSFER_FAILURE arrives.
(x_term_init): New atoms.
* src/xterm.h (struct x_display_info): New atoms.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xterm.c | 169 | ||||
| -rw-r--r-- | src/xterm.h | 2 |
2 files changed, 148 insertions, 23 deletions
diff --git a/src/xterm.c b/src/xterm.c index 81b84c8609c..2f53bb469b3 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -807,6 +807,13 @@ static int x_filter_event (struct x_display_info *, XEvent *); | |||
| 807 | 807 | ||
| 808 | static bool x_dnd_in_progress; | 808 | static bool x_dnd_in_progress; |
| 809 | static bool x_dnd_waiting_for_finish; | 809 | static bool x_dnd_waiting_for_finish; |
| 810 | /* 0 means nothing has happened. 1 means an XmDROP_START message was | ||
| 811 | sent to the target, but no response has yet been received. 2 means | ||
| 812 | a response to our XmDROP_START message was received and the target | ||
| 813 | accepted the drop, so Emacs should start waiting for the drop | ||
| 814 | target to convert one of the special selections XmTRANSFER_SUCCESS | ||
| 815 | or XmTRANSFER_FAILURE. */ | ||
| 816 | static int x_dnd_waiting_for_motif_finish; | ||
| 810 | static Window x_dnd_pending_finish_target; | 817 | static Window x_dnd_pending_finish_target; |
| 811 | static int x_dnd_waiting_for_finish_proto; | 818 | static int x_dnd_waiting_for_finish_proto; |
| 812 | static bool x_dnd_allow_current_frame; | 819 | static bool x_dnd_allow_current_frame; |
| @@ -920,6 +927,16 @@ typedef struct xm_drop_start_message | |||
| 920 | /* CARD32 */ uint32_t source_window; | 927 | /* CARD32 */ uint32_t source_window; |
| 921 | } xm_drop_start_message; | 928 | } xm_drop_start_message; |
| 922 | 929 | ||
| 930 | typedef struct xm_drop_start_reply | ||
| 931 | { | ||
| 932 | /* BYTE */ uint8_t reason; | ||
| 933 | /* BYTE */ uint8_t byte_order; | ||
| 934 | |||
| 935 | /* CARD16 */ uint16_t side_effects; | ||
| 936 | /* CARD16 */ uint16_t better_x; | ||
| 937 | /* CARD16 */ uint16_t better_y; | ||
| 938 | } xm_drop_start_reply; | ||
| 939 | |||
| 923 | typedef struct xm_drag_initiator_info | 940 | typedef struct xm_drag_initiator_info |
| 924 | { | 941 | { |
| 925 | /* BYTE */ uint8_t byteorder; | 942 | /* BYTE */ uint8_t byteorder; |
| @@ -942,33 +959,38 @@ typedef struct xm_drag_receiver_info | |||
| 942 | } xm_drag_receiver_info; | 959 | } xm_drag_receiver_info; |
| 943 | 960 | ||
| 944 | #define XM_DRAG_SIDE_EFFECT(op, site, ops, act) \ | 961 | #define XM_DRAG_SIDE_EFFECT(op, site, ops, act) \ |
| 945 | ((op) | ((site) << 4) | ((ops) << 8) | ((act) << 16)) | 962 | ((op) | ((site) << 4) | ((ops) << 8) | ((act) << 12)) |
| 946 | 963 | ||
| 947 | /* Some of the macros below are temporarily unused. */ | 964 | /* Some of the macros below are temporarily unused. */ |
| 948 | 965 | ||
| 949 | /* #define XM_DRAG_SIDE_EFFECT_OPERATION(effect) ((effect) & 0xf) */ | 966 | #define XM_DRAG_SIDE_EFFECT_OPERATION(effect) ((effect) & 0xf) |
| 950 | /* #define XM_DRAG_SIDE_EFFECT_SITE_STATUS(effect) (((effect) & 0xf0) >> 4) */ | 967 | #define XM_DRAG_SIDE_EFFECT_SITE_STATUS(effect) (((effect) & 0xf0) >> 4) |
| 951 | /* #define XM_DRAG_SIDE_EFFECT_OPERATIONS(effect) (((effect) & 0xf00) >> 8) */ | 968 | /* #define XM_DRAG_SIDE_EFFECT_OPERATIONS(effect) (((effect) & 0xf00) >> 8) */ |
| 952 | /* #define XM_DRAG_SIDE_EFFECT_DROP_ACTION(effect) (((effect) & 0xf000) >> 16) */ | 969 | #define XM_DRAG_SIDE_EFFECT_DROP_ACTION(effect) (((effect) & 0xf000) >> 12) |
| 953 | 970 | ||
| 954 | #define XM_DRAG_NOOP 0 | 971 | #define XM_DRAG_NOOP 0 |
| 955 | #define XM_DRAG_MOVE (1L << 0) | 972 | #define XM_DRAG_MOVE (1L << 0) |
| 956 | #define XM_DRAG_COPY (1L << 1) | 973 | #define XM_DRAG_COPY (1L << 1) |
| 957 | #define XM_DRAG_LINK (1L << 2) | 974 | #define XM_DRAG_LINK (1L << 2) |
| 958 | 975 | ||
| 959 | #define XM_DROP_ACTION_DROP 0 | 976 | #define XM_DROP_ACTION_DROP 0 |
| 960 | #define XM_DROP_SITE_VALID 1 | 977 | /* #define XM_DROP_ACTION_DROP_HELP 1 */ |
| 978 | #define XM_DROP_ACTION_DROP_CANCEL 2 | ||
| 961 | 979 | ||
| 962 | #define XM_DRAG_REASON(originator, code) ((code) | ((originator) << 7)) | 980 | #define XM_DRAG_REASON(originator, code) ((code) | ((originator) << 7)) |
| 963 | /* #define XM_DRAG_REASON_ORIGINATOR(reason) (((reason) & 0x80) ? 1 : 0) */ | 981 | #define XM_DRAG_REASON_ORIGINATOR(reason) (((reason) & 0x80) ? 1 : 0) |
| 964 | /* #define XM_DRAG_REASON_CODE(reason) ((reason) & 0x7f) */ | 982 | #define XM_DRAG_REASON_CODE(reason) ((reason) & 0x7f) |
| 965 | 983 | ||
| 966 | #define XM_DRAG_REASON_DROP_START 5 | 984 | #define XM_DRAG_REASON_DROP_START 5 |
| 967 | #define XM_DRAG_ORIGINATOR_INITIATOR 0 | 985 | #define XM_DRAG_ORIGINATOR_INITIATOR 0 |
| 968 | /* #define XM_DRAG_ORIGINATOR_RECEIVER 1 */ | 986 | #define XM_DRAG_ORIGINATOR_RECEIVER 1 |
| 969 | 987 | ||
| 970 | #define XM_DRAG_STYLE_NONE 0 | 988 | #define XM_DRAG_STYLE_NONE 0 |
| 971 | 989 | ||
| 990 | #define XM_DROP_SITE_VALID 3 | ||
| 991 | /* #define XM_DROP_SITE_INVALID 2 */ | ||
| 992 | /* #define XM_DROP_SITE_NONE 1 */ | ||
| 993 | |||
| 972 | static uint8_t | 994 | static uint8_t |
| 973 | xm_side_effect_from_action (struct x_display_info *dpyinfo, Atom action) | 995 | xm_side_effect_from_action (struct x_display_info *dpyinfo, Atom action) |
| 974 | { | 996 | { |
| @@ -1150,7 +1172,6 @@ xm_get_drag_window (struct x_display_info *dpyinfo) | |||
| 1150 | Display *temp_display; | 1172 | Display *temp_display; |
| 1151 | 1173 | ||
| 1152 | drag_window = None; | 1174 | drag_window = None; |
| 1153 | XGrabServer (dpyinfo->display); | ||
| 1154 | rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window, | 1175 | rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window, |
| 1155 | dpyinfo->Xatom_MOTIF_DRAG_WINDOW, | 1176 | dpyinfo->Xatom_MOTIF_DRAG_WINDOW, |
| 1156 | 0, 1, False, XA_WINDOW, &actual_type, | 1177 | 0, 1, False, XA_WINDOW, &actual_type, |
| @@ -1177,8 +1198,6 @@ xm_get_drag_window (struct x_display_info *dpyinfo) | |||
| 1177 | XFree (tmp_data); | 1198 | XFree (tmp_data); |
| 1178 | } | 1199 | } |
| 1179 | 1200 | ||
| 1180 | XUngrabServer (dpyinfo->display); | ||
| 1181 | |||
| 1182 | if (drag_window == None) | 1201 | if (drag_window == None) |
| 1183 | { | 1202 | { |
| 1184 | unrequest_sigio (); | 1203 | unrequest_sigio (); |
| @@ -1189,8 +1208,6 @@ xm_get_drag_window (struct x_display_info *dpyinfo) | |||
| 1189 | return None; | 1208 | return None; |
| 1190 | 1209 | ||
| 1191 | XSetCloseDownMode (temp_display, RetainPermanent); | 1210 | XSetCloseDownMode (temp_display, RetainPermanent); |
| 1192 | |||
| 1193 | XGrabServer (temp_display); | ||
| 1194 | attrs.override_redirect = True; | 1211 | attrs.override_redirect = True; |
| 1195 | drag_window = XCreateWindow (temp_display, DefaultRootWindow (temp_display), | 1212 | drag_window = XCreateWindow (temp_display, DefaultRootWindow (temp_display), |
| 1196 | -1, -1, 1, 1, 0, CopyFromParent, InputOnly, | 1213 | -1, -1, 1, 1, 0, CopyFromParent, InputOnly, |
| @@ -1200,7 +1217,6 @@ xm_get_drag_window (struct x_display_info *dpyinfo) | |||
| 1200 | "_MOTIF_DRAG_WINDOW", False), | 1217 | "_MOTIF_DRAG_WINDOW", False), |
| 1201 | XA_WINDOW, 32, PropModeReplace, | 1218 | XA_WINDOW, 32, PropModeReplace, |
| 1202 | (unsigned char *) &drag_window, 1); | 1219 | (unsigned char *) &drag_window, 1); |
| 1203 | XUngrabServer (temp_display); | ||
| 1204 | XCloseDisplay (temp_display); | 1220 | XCloseDisplay (temp_display); |
| 1205 | 1221 | ||
| 1206 | /* Make sure the drag window created is actually valid for the | 1222 | /* Make sure the drag window created is actually valid for the |
| @@ -1397,6 +1413,37 @@ xm_send_drop_message (struct x_display_info *dpyinfo, Window source, | |||
| 1397 | } | 1413 | } |
| 1398 | 1414 | ||
| 1399 | static int | 1415 | static int |
| 1416 | xm_read_drop_start_reply (XEvent *msg, xm_drop_start_reply *reply) | ||
| 1417 | { | ||
| 1418 | uint8_t *data; | ||
| 1419 | |||
| 1420 | data = (uint8_t *) &msg->xclient.data.b[0]; | ||
| 1421 | |||
| 1422 | if ((XM_DRAG_REASON_ORIGINATOR (data[0]) | ||
| 1423 | != XM_DRAG_ORIGINATOR_RECEIVER) | ||
| 1424 | || (XM_DRAG_REASON_CODE (data[0]) | ||
| 1425 | != XM_DRAG_REASON_DROP_START)) | ||
| 1426 | return 1; | ||
| 1427 | |||
| 1428 | reply->reason = *(data++); | ||
| 1429 | reply->byte_order = *(data++); | ||
| 1430 | reply->side_effects = *(uint16_t *) data; | ||
| 1431 | reply->better_x = *(uint16_t *) (data + 2); | ||
| 1432 | reply->better_y = *(uint16_t *) (data + 4); | ||
| 1433 | |||
| 1434 | if (reply->byte_order != XM_TARGETS_TABLE_CUR) | ||
| 1435 | { | ||
| 1436 | SWAPCARD16 (reply->side_effects); | ||
| 1437 | SWAPCARD16 (reply->better_x); | ||
| 1438 | SWAPCARD16 (reply->better_y); | ||
| 1439 | } | ||
| 1440 | |||
| 1441 | reply->byte_order = XM_TARGETS_TABLE_CUR; | ||
| 1442 | |||
| 1443 | return 0; | ||
| 1444 | } | ||
| 1445 | |||
| 1446 | static int | ||
| 1400 | xm_read_drag_receiver_info (struct x_display_info *dpyinfo, | 1447 | xm_read_drag_receiver_info (struct x_display_info *dpyinfo, |
| 1401 | Window wdesc, xm_drag_receiver_info *rec) | 1448 | Window wdesc, xm_drag_receiver_info *rec) |
| 1402 | { | 1449 | { |
| @@ -8475,6 +8522,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 8475 | x_dnd_wanted_action = xaction; | 8522 | x_dnd_wanted_action = xaction; |
| 8476 | x_dnd_return_frame = 0; | 8523 | x_dnd_return_frame = 0; |
| 8477 | x_dnd_waiting_for_finish = false; | 8524 | x_dnd_waiting_for_finish = false; |
| 8525 | x_dnd_waiting_for_motif_finish = 0; | ||
| 8478 | x_dnd_end_window = None; | 8526 | x_dnd_end_window = None; |
| 8479 | x_dnd_use_toplevels | 8527 | x_dnd_use_toplevels |
| 8480 | = x_wm_supports (f, FRAME_DISPLAY_INFO (f)->Xatom_net_client_list_stacking); | 8528 | = x_wm_supports (f, FRAME_DISPLAY_INFO (f)->Xatom_net_client_list_stacking); |
| @@ -12384,7 +12432,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 12384 | } | 12432 | } |
| 12385 | 12433 | ||
| 12386 | if (event->xclient.message_type == dpyinfo->Xatom_XdndFinished | 12434 | if (event->xclient.message_type == dpyinfo->Xatom_XdndFinished |
| 12387 | && x_dnd_waiting_for_finish | 12435 | && (x_dnd_waiting_for_finish && !x_dnd_waiting_for_motif_finish) |
| 12388 | && event->xclient.data.l[0] == x_dnd_pending_finish_target) | 12436 | && event->xclient.data.l[0] == x_dnd_pending_finish_target) |
| 12389 | { | 12437 | { |
| 12390 | x_dnd_waiting_for_finish = false; | 12438 | x_dnd_waiting_for_finish = false; |
| @@ -12397,6 +12445,59 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 12397 | x_dnd_action = None; | 12445 | x_dnd_action = None; |
| 12398 | } | 12446 | } |
| 12399 | 12447 | ||
| 12448 | if ((event->xclient.message_type | ||
| 12449 | == dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE) | ||
| 12450 | /* FIXME: There should probably be a check that the event | ||
| 12451 | comes from the same display where the drop event was | ||
| 12452 | sent, but there's no way to get that information here | ||
| 12453 | safely. */ | ||
| 12454 | && x_dnd_waiting_for_finish | ||
| 12455 | && x_dnd_waiting_for_motif_finish == 1) | ||
| 12456 | { | ||
| 12457 | xm_drop_start_reply reply; | ||
| 12458 | uint16_t operation, status, action; | ||
| 12459 | |||
| 12460 | if (!xm_read_drop_start_reply (event, &reply)) | ||
| 12461 | { | ||
| 12462 | operation = XM_DRAG_SIDE_EFFECT_OPERATION (reply.side_effects); | ||
| 12463 | status = XM_DRAG_SIDE_EFFECT_SITE_STATUS (reply.side_effects); | ||
| 12464 | action = XM_DRAG_SIDE_EFFECT_DROP_ACTION (reply.side_effects); | ||
| 12465 | |||
| 12466 | if (operation != XM_DRAG_MOVE | ||
| 12467 | && operation != XM_DRAG_COPY | ||
| 12468 | && operation != XM_DRAG_LINK) | ||
| 12469 | { | ||
| 12470 | x_dnd_waiting_for_finish = false; | ||
| 12471 | goto OTHER; | ||
| 12472 | } | ||
| 12473 | |||
| 12474 | if (status != XM_DROP_SITE_VALID | ||
| 12475 | || action == XM_DROP_ACTION_DROP_CANCEL) | ||
| 12476 | { | ||
| 12477 | x_dnd_waiting_for_finish = false; | ||
| 12478 | goto OTHER; | ||
| 12479 | } | ||
| 12480 | |||
| 12481 | switch (operation) | ||
| 12482 | { | ||
| 12483 | case XM_DRAG_MOVE: | ||
| 12484 | x_dnd_action = dpyinfo->Xatom_XdndActionMove; | ||
| 12485 | break; | ||
| 12486 | |||
| 12487 | case XM_DRAG_COPY: | ||
| 12488 | x_dnd_action = dpyinfo->Xatom_XdndActionCopy; | ||
| 12489 | break; | ||
| 12490 | |||
| 12491 | case XM_DRAG_LINK: | ||
| 12492 | x_dnd_action = dpyinfo->Xatom_XdndActionLink; | ||
| 12493 | break; | ||
| 12494 | } | ||
| 12495 | |||
| 12496 | x_dnd_waiting_for_motif_finish = 2; | ||
| 12497 | goto OTHER; | ||
| 12498 | } | ||
| 12499 | } | ||
| 12500 | |||
| 12400 | if (event->xclient.message_type == dpyinfo->Xatom_wm_protocols | 12501 | if (event->xclient.message_type == dpyinfo->Xatom_wm_protocols |
| 12401 | && event->xclient.format == 32) | 12502 | && event->xclient.format == 32) |
| 12402 | { | 12503 | { |
| @@ -12703,6 +12804,13 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 12703 | *hold_quit = inev.ie; | 12804 | *hold_quit = inev.ie; |
| 12704 | EVENT_INIT (inev.ie); | 12805 | EVENT_INIT (inev.ie); |
| 12705 | } | 12806 | } |
| 12807 | |||
| 12808 | if (x_dnd_waiting_for_finish | ||
| 12809 | && x_dnd_waiting_for_motif_finish == 2 | ||
| 12810 | && eventp->selection == dpyinfo->Xatom_XdndSelection | ||
| 12811 | && (eventp->target == dpyinfo->Xatom_XmTRANSFER_SUCCESS | ||
| 12812 | || eventp->target == dpyinfo->Xatom_XmTRANSFER_FAILURE)) | ||
| 12813 | x_dnd_waiting_for_finish = false; | ||
| 12706 | } | 12814 | } |
| 12707 | break; | 12815 | break; |
| 12708 | 12816 | ||
| @@ -14197,7 +14305,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 14197 | 14305 | ||
| 14198 | xm_write_drag_initiator_info (dpyinfo->display, | 14306 | xm_write_drag_initiator_info (dpyinfo->display, |
| 14199 | FRAME_X_WINDOW (x_dnd_frame), | 14307 | FRAME_X_WINDOW (x_dnd_frame), |
| 14200 | dpyinfo->Xatom_MOTIF_DRAG_INITIATOR_INFO, | 14308 | dpyinfo->Xatom_XdndSelection, |
| 14201 | dpyinfo->Xatom_MOTIF_DRAG_INITIATOR_INFO, | 14309 | dpyinfo->Xatom_MOTIF_DRAG_INITIATOR_INFO, |
| 14202 | &drag_initiator_info); | 14310 | &drag_initiator_info); |
| 14203 | 14311 | ||
| @@ -14207,18 +14315,19 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 14207 | dmsg.side_effects | 14315 | dmsg.side_effects |
| 14208 | = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo, | 14316 | = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo, |
| 14209 | x_dnd_wanted_action), | 14317 | x_dnd_wanted_action), |
| 14210 | XM_DROP_SITE_VALID, | 14318 | XM_DROP_SITE_VALID, XM_DRAG_NOOP, |
| 14211 | xm_side_effect_from_action (dpyinfo, | ||
| 14212 | x_dnd_wanted_action), | ||
| 14213 | XM_DROP_ACTION_DROP); | 14319 | XM_DROP_ACTION_DROP); |
| 14214 | dmsg.timestamp = event->xbutton.time; | 14320 | dmsg.timestamp = event->xbutton.time; |
| 14215 | dmsg.x = event->xbutton.x_root; | 14321 | dmsg.x = event->xbutton.x_root; |
| 14216 | dmsg.y = event->xbutton.y_root; | 14322 | dmsg.y = event->xbutton.y_root; |
| 14217 | dmsg.index_atom = dpyinfo->Xatom_MOTIF_DRAG_INITIATOR_INFO; | 14323 | dmsg.index_atom = dpyinfo->Xatom_XdndSelection; |
| 14218 | dmsg.source_window = FRAME_X_WINDOW (x_dnd_frame); | 14324 | dmsg.source_window = FRAME_X_WINDOW (x_dnd_frame); |
| 14219 | 14325 | ||
| 14220 | xm_send_drop_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame), | 14326 | xm_send_drop_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame), |
| 14221 | x_dnd_last_seen_window, &dmsg); | 14327 | x_dnd_last_seen_window, &dmsg); |
| 14328 | |||
| 14329 | x_dnd_waiting_for_finish = true; | ||
| 14330 | x_dnd_waiting_for_motif_finish = 1; | ||
| 14222 | } | 14331 | } |
| 14223 | } | 14332 | } |
| 14224 | } | 14333 | } |
| @@ -15248,7 +15357,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 15248 | 15357 | ||
| 15249 | xm_write_drag_initiator_info (dpyinfo->display, | 15358 | xm_write_drag_initiator_info (dpyinfo->display, |
| 15250 | FRAME_X_WINDOW (x_dnd_frame), | 15359 | FRAME_X_WINDOW (x_dnd_frame), |
| 15251 | dpyinfo->Xatom_MOTIF_DRAG_INITIATOR_INFO, | 15360 | dpyinfo->Xatom_XdndSelection, |
| 15252 | dpyinfo->Xatom_MOTIF_DRAG_INITIATOR_INFO, | 15361 | dpyinfo->Xatom_MOTIF_DRAG_INITIATOR_INFO, |
| 15253 | &drag_initiator_info); | 15362 | &drag_initiator_info); |
| 15254 | 15363 | ||
| @@ -15265,11 +15374,23 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 15265 | dmsg.timestamp = xev->time; | 15374 | dmsg.timestamp = xev->time; |
| 15266 | dmsg.x = lrint (xev->root_x); | 15375 | dmsg.x = lrint (xev->root_x); |
| 15267 | dmsg.y = lrint (xev->root_y); | 15376 | dmsg.y = lrint (xev->root_y); |
| 15268 | dmsg.index_atom = dpyinfo->Xatom_MOTIF_DRAG_INITIATOR_INFO; | 15377 | /* This atom technically has to be |
| 15378 | unique to each drag-and-drop | ||
| 15379 | operation, but that isn't easy to | ||
| 15380 | accomplish, since we cannot | ||
| 15381 | randomly move data around between | ||
| 15382 | selections. Let's hope no two | ||
| 15383 | instances of Emacs try to drag | ||
| 15384 | into the same window at the same | ||
| 15385 | time. */ | ||
| 15386 | dmsg.index_atom = dpyinfo->Xatom_XdndSelection; | ||
| 15269 | dmsg.source_window = FRAME_X_WINDOW (x_dnd_frame); | 15387 | dmsg.source_window = FRAME_X_WINDOW (x_dnd_frame); |
| 15270 | 15388 | ||
| 15271 | xm_send_drop_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame), | 15389 | xm_send_drop_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame), |
| 15272 | x_dnd_last_seen_window, &dmsg); | 15390 | x_dnd_last_seen_window, &dmsg); |
| 15391 | |||
| 15392 | x_dnd_waiting_for_finish = true; | ||
| 15393 | x_dnd_waiting_for_motif_finish = 1; | ||
| 15273 | } | 15394 | } |
| 15274 | } | 15395 | } |
| 15275 | } | 15396 | } |
| @@ -21140,6 +21261,8 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 21140 | Xatom_MOTIF_DRAG_INITIATOR_INFO) | 21261 | Xatom_MOTIF_DRAG_INITIATOR_INFO) |
| 21141 | ATOM_REFS_INIT ("_MOTIF_DRAG_RECEIVER_INFO", | 21262 | ATOM_REFS_INIT ("_MOTIF_DRAG_RECEIVER_INFO", |
| 21142 | Xatom_MOTIF_DRAG_RECEIVER_INFO) | 21263 | Xatom_MOTIF_DRAG_RECEIVER_INFO) |
| 21264 | ATOM_REFS_INIT ("XmTRANSFER_SUCCESS", Xatom_XmTRANSFER_SUCCESS) | ||
| 21265 | ATOM_REFS_INIT ("XmTRANSFER_FAILURE", Xatom_XmTRANSFER_FAILURE) | ||
| 21143 | }; | 21266 | }; |
| 21144 | 21267 | ||
| 21145 | int i; | 21268 | int i; |
diff --git a/src/xterm.h b/src/xterm.h index eb9e25d3cdd..062b34b35ce 100644 --- a/src/xterm.h +++ b/src/xterm.h | |||
| @@ -437,6 +437,8 @@ struct x_display_info | |||
| 437 | Xatom_MOTIF_DRAG_TARGETS, Xatom_MOTIF_DRAG_AND_DROP_MESSAGE, | 437 | Xatom_MOTIF_DRAG_TARGETS, Xatom_MOTIF_DRAG_AND_DROP_MESSAGE, |
| 438 | Xatom_MOTIF_DRAG_INITIATOR_INFO, Xatom_MOTIF_DRAG_RECEIVER_INFO; | 438 | Xatom_MOTIF_DRAG_INITIATOR_INFO, Xatom_MOTIF_DRAG_RECEIVER_INFO; |
| 439 | 439 | ||
| 440 | Atom Xatom_XmTRANSFER_SUCCESS, Xatom_XmTRANSFER_FAILURE; | ||
| 441 | |||
| 440 | /* The frame (if any) which has the X window that has keyboard focus. | 442 | /* The frame (if any) which has the X window that has keyboard focus. |
| 441 | Zero if none. This is examined by Ffocus_frame in xfns.c. Note | 443 | Zero if none. This is examined by Ffocus_frame in xfns.c. Note |
| 442 | that a mere EnterNotify event can set this; if you need to know the | 444 | that a mere EnterNotify event can set this; if you need to know the |