aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-04-14 09:30:09 +0800
committerPo Lu2022-04-14 09:31:02 +0800
commit63c28d389d04e7212939e190266fd758d20550a2 (patch)
tree0a81bb17432f78bad809fc9b09cb17ac93bdfe1c /src
parent2ea3e7b246bc9b40f1c321c39106a07ae4a4690f (diff)
downloademacs-63c28d389d04e7212939e190266fd758d20550a2.tar.gz
emacs-63c28d389d04e7212939e190266fd758d20550a2.zip
Add support for Xdnd features introduced after version 5
* src/xterm.c (x_dnd_send_position, x_dnd_update_state) (handle_one_xevent): Add support for sending button and keyboard state during DND.
Diffstat (limited to 'src')
-rw-r--r--src/xterm.c93
1 files changed, 83 insertions, 10 deletions
diff --git a/src/xterm.c b/src/xterm.c
index db9266f10bc..aad772c4236 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -3339,7 +3339,8 @@ x_dnd_send_enter (struct frame *f, Window target, int supported)
3339static void 3339static void
3340x_dnd_send_position (struct frame *f, Window target, int supported, 3340x_dnd_send_position (struct frame *f, Window target, int supported,
3341 unsigned short root_x, unsigned short root_y, 3341 unsigned short root_x, unsigned short root_y,
3342 Time timestamp, Atom action) 3342 Time timestamp, Atom action, int button,
3343 unsigned state)
3343{ 3344{
3344 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); 3345 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
3345 XEvent msg; 3346 XEvent msg;
@@ -3380,6 +3381,20 @@ x_dnd_send_position (struct frame *f, Window target, int supported,
3380 msg.xclient.window = target; 3381 msg.xclient.window = target;
3381 msg.xclient.data.l[0] = FRAME_X_WINDOW (f); 3382 msg.xclient.data.l[0] = FRAME_X_WINDOW (f);
3382 msg.xclient.data.l[1] = 0; 3383 msg.xclient.data.l[1] = 0;
3384
3385 if (supported >= 5)
3386 {
3387 if (button >= 4 && button <= 8)
3388 {
3389 msg.xclient.data.l[1] |= (1 << 9);
3390 msg.xclient.data.l[1] |= (button - 4) << 7;
3391 }
3392
3393 msg.xclient.data.l[1] |= state & 0x3f;
3394 }
3395 else if (button)
3396 return;
3397
3383 msg.xclient.data.l[2] = (root_x << 16) | root_y; 3398 msg.xclient.data.l[2] = (root_x << 16) | root_y;
3384 msg.xclient.data.l[3] = 0; 3399 msg.xclient.data.l[3] = 0;
3385 msg.xclient.data.l[4] = 0; 3400 msg.xclient.data.l[4] = 0;
@@ -13467,7 +13482,7 @@ x_dnd_update_state (struct x_display_info *dpyinfo, Time timestamp)
13467 x_dnd_last_protocol_version, 13482 x_dnd_last_protocol_version,
13468 root_x, root_y, 13483 root_x, root_y,
13469 x_dnd_selection_timestamp, 13484 x_dnd_selection_timestamp,
13470 x_dnd_wanted_action); 13485 x_dnd_wanted_action, 0, 0);
13471 else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None) 13486 else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None)
13472 { 13487 {
13473 if (!x_dnd_motif_setup_p) 13488 if (!x_dnd_motif_setup_p)
@@ -15244,7 +15259,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
15244 event->xmotion.x_root, 15259 event->xmotion.x_root,
15245 event->xmotion.y_root, 15260 event->xmotion.y_root,
15246 x_dnd_selection_timestamp, 15261 x_dnd_selection_timestamp,
15247 x_dnd_wanted_action); 15262 x_dnd_wanted_action, 0,
15263 event->xmotion.state);
15248 else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None) 15264 else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None)
15249 { 15265 {
15250 if (!x_dnd_motif_setup_p) 15266 if (!x_dnd_motif_setup_p)
@@ -15688,6 +15704,23 @@ handle_one_xevent (struct x_display_info *dpyinfo,
15688 if (x_dnd_in_progress 15704 if (x_dnd_in_progress
15689 && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) 15705 && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
15690 { 15706 {
15707 if (event->xbutton.type == ButtonPress
15708 && x_dnd_last_seen_window != None
15709 && x_dnd_last_protocol_version != -1)
15710 {
15711 x_dnd_send_position (x_dnd_frame,
15712 x_dnd_last_seen_window,
15713 x_dnd_last_protocol_version,
15714 event->xbutton.x_root,
15715 event->xbutton.y_root,
15716 x_dnd_selection_timestamp,
15717 x_dnd_wanted_action,
15718 event->xbutton.button,
15719 event->xbutton.state);
15720
15721 goto OTHER;
15722 }
15723
15691 for (int i = 1; i < 8; ++i) 15724 for (int i = 1; i < 8; ++i)
15692 { 15725 {
15693 if (i != event->xbutton.button 15726 if (i != event->xbutton.button
@@ -16351,6 +16384,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
16351 xm_top_level_leave_message lmsg; 16384 xm_top_level_leave_message lmsg;
16352 xm_top_level_enter_message emsg; 16385 xm_top_level_enter_message emsg;
16353 xm_drag_motion_message dmsg; 16386 xm_drag_motion_message dmsg;
16387 int dnd_state;
16354 16388
16355 source = xi_device_from_id (dpyinfo, xev->sourceid); 16389 source = xi_device_from_id (dpyinfo, xev->sourceid);
16356 16390
@@ -16769,11 +16803,26 @@ handle_one_xevent (struct x_display_info *dpyinfo,
16769 } 16803 }
16770 16804
16771 if (x_dnd_last_protocol_version != -1 && target != None) 16805 if (x_dnd_last_protocol_version != -1 && target != None)
16772 x_dnd_send_position (x_dnd_frame, target, 16806 {
16773 x_dnd_last_protocol_version, 16807 dnd_state = xev->mods.effective;
16774 xev->root_x, xev->root_y, 16808
16775 x_dnd_selection_timestamp, 16809 if (xev->buttons.mask_len)
16776 x_dnd_wanted_action); 16810 {
16811 if (XIMaskIsSet (xev->buttons.mask, 1))
16812 dnd_state |= Button1Mask;
16813 if (XIMaskIsSet (xev->buttons.mask, 2))
16814 dnd_state |= Button2Mask;
16815 if (XIMaskIsSet (xev->buttons.mask, 3))
16816 dnd_state |= Button3Mask;
16817 }
16818
16819 x_dnd_send_position (x_dnd_frame, target,
16820 x_dnd_last_protocol_version,
16821 xev->root_x, xev->root_y,
16822 x_dnd_selection_timestamp,
16823 x_dnd_wanted_action, 0,
16824 dnd_state);
16825 }
16777 else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None) 16826 else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None)
16778 { 16827 {
16779 if (!x_dnd_motif_setup_p) 16828 if (!x_dnd_motif_setup_p)
@@ -16900,18 +16949,42 @@ handle_one_xevent (struct x_display_info *dpyinfo,
16900 /* A fake XButtonEvent for x_construct_mouse_click. */ 16949 /* A fake XButtonEvent for x_construct_mouse_click. */
16901 XButtonEvent bv; 16950 XButtonEvent bv;
16902 bool dnd_grab = false; 16951 bool dnd_grab = false;
16952 int dnd_state;
16903 16953
16904 if (x_dnd_in_progress 16954 if (x_dnd_in_progress
16905 && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) 16955 && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
16906 { 16956 {
16957 if (xev->evtype == XI_ButtonPress
16958 && x_dnd_last_seen_window != None
16959 && x_dnd_last_protocol_version != -1)
16960 {
16961 dnd_state = xev->mods.effective;
16962
16963 if (xev->buttons.mask_len)
16964 {
16965 if (XIMaskIsSet (xev->buttons.mask, 1))
16966 dnd_state |= Button1Mask;
16967 if (XIMaskIsSet (xev->buttons.mask, 2))
16968 dnd_state |= Button2Mask;
16969 if (XIMaskIsSet (xev->buttons.mask, 3))
16970 dnd_state |= Button3Mask;
16971 }
16972
16973 x_dnd_send_position (x_dnd_frame, x_dnd_last_seen_window,
16974 x_dnd_last_protocol_version, xev->root_x,
16975 xev->root_y, x_dnd_selection_timestamp,
16976 x_dnd_wanted_action, xev->detail, dnd_state);
16977
16978 goto XI_OTHER;
16979 }
16980
16907 for (int i = 0; i < xev->buttons.mask_len * 8; ++i) 16981 for (int i = 0; i < xev->buttons.mask_len * 8; ++i)
16908 { 16982 {
16909 if (i != xev->detail && XIMaskIsSet (xev->buttons.mask, i)) 16983 if (i != xev->detail && XIMaskIsSet (xev->buttons.mask, i))
16910 dnd_grab = true; 16984 dnd_grab = true;
16911 } 16985 }
16912 16986
16913 if (!dnd_grab 16987 if (!dnd_grab && xev->evtype == XI_ButtonRelease)
16914 && xev->evtype == XI_ButtonRelease)
16915 { 16988 {
16916 x_dnd_end_window = x_dnd_last_seen_window; 16989 x_dnd_end_window = x_dnd_last_seen_window;
16917 x_dnd_in_progress = false; 16990 x_dnd_in_progress = false;