diff options
| author | Po Lu | 2022-04-14 09:30:09 +0800 |
|---|---|---|
| committer | Po Lu | 2022-04-14 09:31:02 +0800 |
| commit | 63c28d389d04e7212939e190266fd758d20550a2 (patch) | |
| tree | 0a81bb17432f78bad809fc9b09cb17ac93bdfe1c /src | |
| parent | 2ea3e7b246bc9b40f1c321c39106a07ae4a4690f (diff) | |
| download | emacs-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.c | 93 |
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) | |||
| 3339 | static void | 3339 | static void |
| 3340 | x_dnd_send_position (struct frame *f, Window target, int supported, | 3340 | x_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; |