emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] Changes to emacs/src/xselect.c [lexbind]


From: Miles Bader
Subject: [Emacs-diffs] Changes to emacs/src/xselect.c [lexbind]
Date: Thu, 11 Nov 2004 23:43:15 -0500

Index: emacs/src/xselect.c
diff -c emacs/src/xselect.c:1.119.2.9 emacs/src/xselect.c:1.119.2.10
*** emacs/src/xselect.c:1.119.2.9       Fri Oct 29 02:05:11 2004
--- emacs/src/xselect.c Fri Nov 12 04:21:16 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 ----




reply via email to

[Prev in Thread] Current Thread [Next in Thread]