[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] Changes to emacs/src/xselect.c [emacs-unicode-2]
From: |
Miles Bader |
Subject: |
[Emacs-diffs] Changes to emacs/src/xselect.c [emacs-unicode-2] |
Date: |
Thu, 11 Nov 2004 22:18:58 -0500 |
Index: emacs/src/xselect.c
diff -c emacs/src/xselect.c:1.129.2.5 emacs/src/xselect.c:1.129.2.6
*** emacs/src/xselect.c:1.129.2.5 Thu Nov 4 08:55:33 2004
--- emacs/src/xselect.c Fri Nov 12 02:52:57 2004
***************
*** 24,29 ****
--- 24,37 ----
#include <config.h>
#include <stdio.h> /* termhooks.h needs this */
+
+ #ifdef HAVE_SYS_TYPES_H
+ #include <sys/types.h>
+ #endif
+ #ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+ #endif
+
#include "lisp.h"
#include "xterm.h" /* for all of the X includes */
#include "dispextern.h" /* frame.h seems to want this */
***************
*** 32,37 ****
--- 40,46 ----
#include "buffer.h"
#include "process.h"
#include "termhooks.h"
+ #include "keyboard.h"
#include <X11/Xproto.h>
***************
*** 85,94 ****
--- 94,106 ----
fprintf (stderr, "%d: " fmt "\n", getpid (), a0)
#define TRACE2(fmt, a0, a1) \
fprintf (stderr, "%d: " fmt "\n", getpid (), a0, a1)
+ #define TRACE3(fmt, a0, a1, a2) \
+ fprintf (stderr, "%d: " fmt "\n", getpid (), a0, a1, a2)
#else
#define TRACE0(fmt) (void) 0
#define TRACE1(fmt, a0) (void) 0
#define TRACE2(fmt, a0, a1) (void) 0
+ #define TRACE3(fmt, a0, a1) (void) 0
#endif
***************
*** 168,173 ****
--- 180,268 ----
static Lisp_Object selection_data_to_lisp_data ();
static Lisp_Object x_get_window_property_as_lisp_data ();
+
+
+ /* 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. */
+
+ while (selection_queue != NULL)
+ {
+ struct selection_event_queue *queue_tmp = selection_queue;
+ TRACE1 ("RESTORE SELECTION EVENT %08lx", (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. */
***************
*** 557,569 ****
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;
}
--- 652,661 ----
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;
}
***************
*** 623,628 ****
--- 715,731 ----
BLOCK_INPUT;
count = x_catch_errors (display);
+ #ifdef TRACE_SELECTION
+ {
+ static int cnt;
+ char *sel = XGetAtomName (display, reply.selection);
+ char *tgt = XGetAtomName (display, reply.target);
+ TRACE3 ("%s, target %s (%d)", sel, tgt, ++cnt);
+ if (sel) XFree (sel);
+ if (tgt) XFree (tgt);
+ }
+ #endif /* TRACE_SELECTION */
+
/* Store the data on the requested property.
If the selection is large, only store the first N bytes of it.
*/
***************
*** 650,659 ****
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 */
--- 753,762 ----
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 */
***************
*** 687,692 ****
--- 790,797 ----
XGetAtomName (display, reply.property));
wait_for_property_change (wait_object);
}
+ else
+ unexpect_property_change (wait_object);
TRACE0 ("Got ACK");
while (bytes_remaining)
***************
*** 760,766 ****
/* 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;
{
--- 865,871 ----
/* 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;
{
***************
*** 775,780 ****
--- 880,889 ----
struct x_display_info *dpyinfo
= x_display_info_for_display (SELECTION_EVENT_DISPLAY (event));
+ TRACE2 ("x_handle_selection_request, from=0x%08lx time=%lu",
+ (unsigned long) SELECTION_EVENT_REQUESTOR (event),
+ (unsigned long) SELECTION_EVENT_TIME (event));
+
local_selection_data = Qnil;
target_symbol = Qnil;
converted_selection = Qnil;
***************
*** 869,875 ****
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;
{
--- 978,984 ----
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;
{
***************
*** 882,887 ****
--- 991,998 ----
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;
***************
*** 950,955 ****
--- 1061,1084 ----
}
}
+ 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. */
***************
*** 1080,1091 ****
/* 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;
}
--- 1209,1222 ----
/* 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;
}
***************
*** 1098,1115 ****
{
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)
--- 1229,1245 ----
{
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)
***************
*** 1140,1146 ****
while (rest)
{
! if (rest->property == event->atom
&& rest->window == event->window
&& rest->display == event->display
&& rest->desired_state == event->state)
--- 1270,1277 ----
while (rest)
{
! if (!rest->arrived
! && rest->property == event->atom
&& rest->window == event->window
&& rest->display == event->display
&& rest->desired_state == event->state)
***************
*** 1156,1166 ****
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;
}
--- 1287,1292 ----
***************
*** 1286,1295 ****
bother trying to queue them. */
if (!NILP (frame))
{
! x_start_queuing_selection_requests (display);
record_unwind_protect (queue_selection_requests_unwind,
! frame);
}
UNBLOCK_INPUT;
--- 1412,1421 ----
bother trying to queue them. */
if (!NILP (frame))
{
! x_start_queuing_selection_requests ();
record_unwind_protect (queue_selection_requests_unwind,
! Qnil);
}
UNBLOCK_INPUT;
***************
*** 1445,1454 ****
BLOCK_INPUT;
XSelectInput (display, window, STANDARD_EVENT_SET | PropertyChangeMask);
TRACE1 (" Delete property %s",
! XSYMBOL (x_atom_to_symbol (display, property))->name->data);
XDeleteProperty (display, window, property);
TRACE1 (" Expect new value of property %s",
! XSYMBOL (x_atom_to_symbol (display, property))->name->data);
wait_object = expect_property_change (display, window, property,
PropertyNewValue);
XFlush (display);
--- 1571,1580 ----
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);
***************
*** 1478,1484 ****
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);
--- 1604,1609 ----