[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] Changes to emacs/src/xselect.c
From: |
Kim F . Storm |
Subject: |
[Emacs-diffs] Changes to emacs/src/xselect.c |
Date: |
Fri, 05 Nov 2004 06:39:19 -0500 |
Index: emacs/src/xselect.c
diff -c emacs/src/xselect.c:1.141 emacs/src/xselect.c:1.142
*** emacs/src/xselect.c:1.141 Fri Nov 5 07:05:13 2004
--- emacs/src/xselect.c Fri Nov 5 11:30:31 2004
***************
*** 32,37 ****
--- 32,38 ----
#include "buffer.h"
#include "process.h"
#include "termhooks.h"
+ #include "keyboard.h"
#include <X11/Xproto.h>
***************
*** 171,176 ****
--- 172,257 ----
static Lisp_Object selection_data_to_lisp_data ();
static Lisp_Object x_get_window_property_as_lisp_data ();
+
+
+ /* Define a queue to save up SelectionRequest 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 certain events--don't process them yet. */
+
+ static int x_queue_selection_requests;
+
+ /* Queue up an X 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 */
+ for (queue_tmp = selection_queue; queue_tmp; queue_tmp = queue_tmp->next)
+ {
+ if (!bcmp (&queue_tmp->event, event, sizeof (*event)))
+ {
+ TRACE1 ("IGNORE DUP SELECTION EVENT %08x", (unsigned long)queue_tmp);
+ return;
+ }
+ }
+
+ queue_tmp
+ = (struct selection_event_queue *) xmalloc (sizeof (struct
selection_event_queue));
+
+ if (queue_tmp != NULL)
+ {
+ TRACE1 ("QUEUE SELECTION EVENT %08x", (unsigned long)queue_tmp);
+ queue_tmp->event = *event;
+ queue_tmp->next = selection_queue;
+ selection_queue = queue_tmp;
+ }
+ }
+
+ /* Start queuing SelectionRequest 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 SelectionRequest 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. */
+
+ while (selection_queue != NULL)
+ {
+ struct selection_event_queue *queue_tmp = selection_queue;
+ TRACE1 ("RESTORE SELECTION EVENT %08x", (unsigned long)queue_tmp);
+ kbd_buffer_unget_event (&queue_tmp->event);
+ selection_queue = queue_tmp->next;
+ xfree ((char *)queue_tmp);
+ }
+ }
+
+
/* This converts a Lisp symbol to a server Atom, avoiding a server
roundtrip whenever possible. */
***************
*** 560,572 ****
static struct prop_location *property_change_wait_list;
static Lisp_Object
! queue_selection_requests_unwind (frame)
! Lisp_Object frame;
{
! FRAME_PTR f = XFRAME (frame);
!
! if (! NILP (frame))
! x_stop_queuing_selection_requests (FRAME_X_DISPLAY (f));
return Qnil;
}
--- 641,650 ----
static struct prop_location *property_change_wait_list;
static Lisp_Object
! queue_selection_requests_unwind (tem)
! Lisp_Object tem;
{
! x_stop_queuing_selection_requests ();
return Qnil;
}
***************
*** 664,673 ****
bother trying to queue them. */
if (!NILP (frame))
{
! x_start_queuing_selection_requests (display);
record_unwind_protect (queue_selection_requests_unwind,
! frame);
}
if (x_window_to_frame (dpyinfo, window)) /* #### debug */
--- 742,751 ----
bother trying to queue them. */
if (!NILP (frame))
{
! x_start_queuing_selection_requests ();
record_unwind_protect (queue_selection_requests_unwind,
! Qnil);
}
if (x_window_to_frame (dpyinfo, window)) /* #### debug */
***************
*** 701,706 ****
--- 779,786 ----
XGetAtomName (display, reply.property));
wait_for_property_change (wait_object);
}
+ else
+ unexpect_property_change (wait_object);
TRACE0 ("Got ACK");
while (bytes_remaining)
***************
*** 774,780 ****
/* Handle a SelectionRequest event EVENT.
This is called from keyboard.c when such an event is found in the queue.
*/
! void
x_handle_selection_request (event)
struct input_event *event;
{
--- 854,860 ----
/* Handle a SelectionRequest event EVENT.
This is called from keyboard.c when such an event is found in the queue.
*/
! static void
x_handle_selection_request (event)
struct input_event *event;
{
***************
*** 789,794 ****
--- 869,876 ----
struct x_display_info *dpyinfo
= x_display_info_for_display (SELECTION_EVENT_DISPLAY (event));
+ TRACE0 ("x_handle_selection_request");
+
local_selection_data = Qnil;
target_symbol = Qnil;
converted_selection = Qnil;
***************
*** 883,889 ****
client cleared out our previously asserted selection.
This is called from keyboard.c when such an event is found in the queue.
*/
! void
x_handle_selection_clear (event)
struct input_event *event;
{
--- 965,971 ----
client cleared out our previously asserted selection.
This is called from keyboard.c when such an event is found in the queue.
*/
! static void
x_handle_selection_clear (event)
struct input_event *event;
{
***************
*** 896,901 ****
--- 978,985 ----
struct x_display_info *dpyinfo = x_display_info_for_display (display);
struct x_display_info *t_dpyinfo;
+ TRACE0 ("x_handle_selection_clear");
+
/* If the new selection owner is also Emacs,
don't clear the new selection. */
BLOCK_INPUT;
***************
*** 964,969 ****
--- 1048,1071 ----
}
}
+ void
+ x_handle_selection_event (event)
+ struct input_event *event;
+ {
+ TRACE0 ("x_handle_selection_event");
+
+ if (event->kind == SELECTION_REQUEST_EVENT)
+ {
+ if (x_queue_selection_requests)
+ x_queue_event (event);
+ else
+ x_handle_selection_request (event);
+ }
+ else
+ x_handle_selection_clear (event);
+ }
+
+
/* Clear all selections that were made from frame F.
We do this when about to delete a frame. */
***************
*** 1094,1105 ****
/* Remove the property change expectation element for IDENTIFIER. */
static Lisp_Object
! wait_for_property_change_unwind (identifierval)
! Lisp_Object identifierval;
{
! unexpect_property_change ((struct prop_location *)
! (XFASTINT (XCAR (identifierval)) << 16
! | XFASTINT (XCDR (identifierval))));
return Qnil;
}
--- 1196,1209 ----
/* Remove the property change expectation element for IDENTIFIER. */
static Lisp_Object
! wait_for_property_change_unwind (loc)
! Lisp_Object loc;
{
! struct prop_location *location = XSAVE_VALUE (loc)->pointer;
!
! unexpect_property_change (location);
! if (location == property_change_reply_object)
! property_change_reply_object = 0;
return Qnil;
}
***************
*** 1112,1129 ****
{
int secs, usecs;
int count = SPECPDL_INDEX ();
- Lisp_Object tem;
! tem = Fcons (Qnil, Qnil);
! XSETCARFASTINT (tem, (EMACS_UINT)location >> 16);
! XSETCDRFASTINT (tem, (EMACS_UINT)location & 0xffff);
/* Make sure to do unexpect_property_change if we quit or err. */
! record_unwind_protect (wait_for_property_change_unwind, tem);
XSETCAR (property_change_reply, Qnil);
-
property_change_reply_object = location;
/* If the event we are waiting for arrives beyond here, it will set
property_change_reply, because property_change_reply_object says so. */
if (! location->arrived)
--- 1216,1232 ----
{
int secs, usecs;
int count = SPECPDL_INDEX ();
! if (property_change_reply_object)
! abort ();
/* Make sure to do unexpect_property_change if we quit or err. */
! record_unwind_protect (wait_for_property_change_unwind,
! make_save_value (location, 0));
XSETCAR (property_change_reply, Qnil);
property_change_reply_object = location;
+
/* If the event we are waiting for arrives beyond here, it will set
property_change_reply, because property_change_reply_object says so. */
if (! location->arrived)
***************
*** 1154,1160 ****
while (rest)
{
! if (rest->property == event->atom
&& rest->window == event->window
&& rest->display == event->display
&& rest->desired_state == event->state)
--- 1257,1264 ----
while (rest)
{
! if (!rest->arrived
! && rest->property == event->atom
&& rest->window == event->window
&& rest->display == event->display
&& rest->desired_state == event->state)
***************
*** 1170,1180 ****
if (rest == property_change_reply_object)
XSETCAR (property_change_reply, Qt);
- if (prev)
- prev->next = rest->next;
- else
- property_change_wait_list = rest->next;
- xfree (rest);
return;
}
--- 1274,1279 ----
***************
*** 1300,1309 ****
bother trying to queue them. */
if (!NILP (frame))
{
! x_start_queuing_selection_requests (display);
record_unwind_protect (queue_selection_requests_unwind,
! frame);
}
UNBLOCK_INPUT;
--- 1399,1408 ----
bother trying to queue them. */
if (!NILP (frame))
{
! x_start_queuing_selection_requests ();
record_unwind_protect (queue_selection_requests_unwind,
! Qnil);
}
UNBLOCK_INPUT;
***************
*** 1459,1468 ****
BLOCK_INPUT;
XSelectInput (display, window, STANDARD_EVENT_SET | PropertyChangeMask);
TRACE1 (" Delete property %s",
! SDATA (XSYMBOL (x_atom_to_symbol (display, property))->xname));
XDeleteProperty (display, window, property);
TRACE1 (" Expect new value of property %s",
! SDATA (XSYMBOL (x_atom_to_symbol (display, property))->xname));
wait_object = expect_property_change (display, window, property,
PropertyNewValue);
XFlush (display);
--- 1558,1567 ----
BLOCK_INPUT;
XSelectInput (display, window, STANDARD_EVENT_SET | PropertyChangeMask);
TRACE1 (" Delete property %s",
! SDATA (SYMBOL_NAME (x_atom_to_symbol (display, property))));
XDeleteProperty (display, window, property);
TRACE1 (" Expect new value of property %s",
! SDATA (SYMBOL_NAME (x_atom_to_symbol (display, property))));
wait_object = expect_property_change (display, window, property,
PropertyNewValue);
XFlush (display);
***************
*** 1492,1498 ****
if (! waiting_for_other_props_on_window (display, window))
XSelectInput (display, window, STANDARD_EVENT_SET);
- unexpect_property_change (wait_object);
/* Use xfree, not XFree, because x_get_window_property
calls xmalloc itself. */
if (tmp_data) xfree (tmp_data);
--- 1591,1596 ----