aboutsummaryrefslogtreecommitdiffstats
path: root/src/xselect.c
diff options
context:
space:
mode:
authorPo Lu2022-06-06 11:08:19 +0800
committerPo Lu2022-06-06 11:08:19 +0800
commitb90d2a6a63f1b7f73d2cb7e976148e8195fc5502 (patch)
tree965057d58b783e920711e05138ad56184ceec6c4 /src/xselect.c
parent0a36671f415bd681ddca0bad8612aca031fd407d (diff)
downloademacs-b90d2a6a63f1b7f73d2cb7e976148e8195fc5502.tar.gz
emacs-b90d2a6a63f1b7f73d2cb7e976148e8195fc5502.zip
Rework X selections to make it safe to run the debugger inside converters
* src/keyboard.c (prev_kbd_event): Delete function. (readable_events): Return 1 if x_detect_pending_selection_requests returns true. (kbd_buffer_unget_event): Also delete function, since nested selection requests are really handled correctly. (kbd_buffer_get_event): Handle events from the special X deferred selection queue as well. * src/keyboard.h: Update prototypes. * src/xselect.c (struct selection_event_queue) (selection_input_event_equal, x_queue_event) (x_start_queuing_selection_requests) (x_stop_queuing_selection_requests): Delete structs, since they are no longer required. (x_handle_selection_request, x_handle_selection_event): Allow nested selection events. * src/xterm.c (struct x_selection_request_event): New struct. (x_handle_pending_selection_requests_1) (x_handle_pending_selection_requests): Handle all events in the new selection event queue. (x_push_selection_request, x_detect_pending_selection_requests): New functions. (x_dnd_begin_drag_and_drop): Drain the selection queue here as well. (handle_one_xevent): When inside a nested event loop, just push selections to that queue. (XTread_socket): Allow reading X events if x_dnd_unwind_flag is true, even though DND is in progress. (x_delete_display): Delete pending selection events for the display that is going away. * src/xterm.h: Update prototypes.
Diffstat (limited to 'src/xselect.c')
-rw-r--r--src/xselect.c93
1 files changed, 0 insertions, 93 deletions
diff --git a/src/xselect.c b/src/xselect.c
index 5f2a0cf56de..6e693c25884 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -116,92 +116,6 @@ selection_quantum (Display *display)
116 assq_no_quit (selection_symbol, dpyinfo->terminal->Vselection_alist) 116 assq_no_quit (selection_symbol, dpyinfo->terminal->Vselection_alist)
117 117
118 118
119/* Define a queue to save up SELECTION_REQUEST_EVENT events for later
120 handling. */
121
122struct selection_event_queue
123 {
124 struct selection_input_event event;
125 struct selection_event_queue *next;
126 };
127
128static struct selection_event_queue *selection_queue;
129
130/* Nonzero means queue up SELECTION_REQUEST_EVENT events. */
131
132static int x_queue_selection_requests;
133
134/* True if the input events are duplicates. */
135
136static bool
137selection_input_event_equal (struct selection_input_event *a,
138 struct selection_input_event *b)
139{
140 return (a->kind == b->kind && a->dpyinfo == b->dpyinfo
141 && a->requestor == b->requestor && a->selection == b->selection
142 && a->target == b->target && a->property == b->property
143 && a->time == b->time);
144}
145
146/* Queue up an SELECTION_REQUEST_EVENT *EVENT, to be processed later. */
147
148static void
149x_queue_event (struct selection_input_event *event)
150{
151 struct selection_event_queue *queue_tmp;
152
153 /* Don't queue repeated requests.
154 This only happens for large requests which uses the incremental protocol. */
155 for (queue_tmp = selection_queue; queue_tmp; queue_tmp = queue_tmp->next)
156 {
157 if (selection_input_event_equal (event, &queue_tmp->event))
158 {
159 TRACE1 ("DECLINE DUP SELECTION EVENT %p", queue_tmp);
160 x_decline_selection_request (event);
161 return;
162 }
163 }
164
165 queue_tmp = xmalloc (sizeof *queue_tmp);
166 TRACE1 ("QUEUE SELECTION EVENT %p", queue_tmp);
167 queue_tmp->event = *event;
168 queue_tmp->next = selection_queue;
169 selection_queue = queue_tmp;
170}
171
172/* Start queuing SELECTION_REQUEST_EVENT events. */
173
174static void
175x_start_queuing_selection_requests (void)
176{
177 if (x_queue_selection_requests)
178 emacs_abort ();
179
180 x_queue_selection_requests++;
181 TRACE1 ("x_start_queuing_selection_requests %d", x_queue_selection_requests);
182}
183
184/* Stop queuing SELECTION_REQUEST_EVENT events. */
185
186static void
187x_stop_queuing_selection_requests (void)
188{
189 TRACE1 ("x_stop_queuing_selection_requests %d", x_queue_selection_requests);
190 --x_queue_selection_requests;
191
192 /* Take all the queued events and put them back
193 so that they get processed afresh. */
194
195 while (selection_queue != NULL)
196 {
197 struct selection_event_queue *queue_tmp = selection_queue;
198 TRACE1 ("RESTORE SELECTION EVENT %p", queue_tmp);
199 kbd_buffer_unget_event (&queue_tmp->event);
200 selection_queue = queue_tmp->next;
201 xfree (queue_tmp);
202 }
203}
204
205 119
206/* This converts a Lisp symbol to a server Atom, avoiding a server 120/* This converts a Lisp symbol to a server Atom, avoiding a server
207 roundtrip whenever possible. */ 121 roundtrip whenever possible. */
@@ -839,11 +753,6 @@ x_handle_selection_request (struct selection_input_event *event)
839 selection_request_dpyinfo = dpyinfo; 753 selection_request_dpyinfo = dpyinfo;
840 record_unwind_protect_void (x_selection_request_lisp_error); 754 record_unwind_protect_void (x_selection_request_lisp_error);
841 755
842 /* We might be able to handle nested x_handle_selection_requests,
843 but this is difficult to test, and seems unimportant. */
844 x_start_queuing_selection_requests ();
845 record_unwind_protect_void (x_stop_queuing_selection_requests);
846
847 TRACE2 ("x_handle_selection_request: selection=%s, target=%s", 756 TRACE2 ("x_handle_selection_request: selection=%s, target=%s",
848 SDATA (SYMBOL_NAME (selection_symbol)), 757 SDATA (SYMBOL_NAME (selection_symbol)),
849 SDATA (SYMBOL_NAME (target_symbol))); 758 SDATA (SYMBOL_NAME (target_symbol)));
@@ -1028,8 +937,6 @@ x_handle_selection_event (struct selection_input_event *event)
1028 TRACE0 ("x_handle_selection_event"); 937 TRACE0 ("x_handle_selection_event");
1029 if (event->kind != SELECTION_REQUEST_EVENT) 938 if (event->kind != SELECTION_REQUEST_EVENT)
1030 x_handle_selection_clear (event); 939 x_handle_selection_clear (event);
1031 else if (x_queue_selection_requests)
1032 x_queue_event (event);
1033 else 940 else
1034 x_handle_selection_request (event); 941 x_handle_selection_request (event);
1035} 942}