+/* Define a queue to save up SELECTION_REQUEST_EVENT events for later
+ handling. */
+
+struct selection_event_queue
+ {
+ struct input_event event;
+ struct selection_event_queue *next;
+ };
+
+static struct selection_event_queue *selection_queue;
+
+/* Nonzero means queue up SELECTION_REQUEST_EVENT events. */
+
+static int x_queue_selection_requests;
+
+/* Queue up an SELECTION_REQUEST_EVENT *EVENT, to be processed later. */
+
+static void
+x_queue_event (event)
+ struct input_event *event;
+{
+ struct selection_event_queue *queue_tmp;
+
+ /* Don't queue repeated requests.
+ This only happens for large requests which uses the incremental protocol. */
+ for (queue_tmp = selection_queue; queue_tmp; queue_tmp = queue_tmp->next)
+ {
+ if (!bcmp (&queue_tmp->event, event, sizeof (*event)))
+ {
+ TRACE1 ("DECLINE DUP SELECTION EVENT %08lx", (unsigned long)queue_tmp);
+ x_decline_selection_request (event);
+ return;
+ }
+ }
+
+ queue_tmp
+ = (struct selection_event_queue *) xmalloc (sizeof (struct selection_event_queue));
+
+ if (queue_tmp != NULL)
+ {
+ TRACE1 ("QUEUE SELECTION EVENT %08lx", (unsigned long)queue_tmp);
+ queue_tmp->event = *event;
+ queue_tmp->next = selection_queue;
+ selection_queue = queue_tmp;
+ }
+}
+
+/* Start queuing SELECTION_REQUEST_EVENT events. */
+
+static void
+x_start_queuing_selection_requests ()
+{
+ if (x_queue_selection_requests)
+ abort ();
+
+ x_queue_selection_requests++;
+ TRACE1 ("x_start_queuing_selection_requests %d", x_queue_selection_requests);
+}
+
+/* Stop queuing SELECTION_REQUEST_EVENT events. */
+
+static void
+x_stop_queuing_selection_requests ()
+{
+ TRACE1 ("x_stop_queuing_selection_requests %d", x_queue_selection_requests);
+ --x_queue_selection_requests;
+
+ /* Take all the queued events and put them back
+ so that they get processed afresh. */