/[emacs]/emacs/src/xselect.c
ViewVC logotype

Diff of /emacs/src/xselect.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.141 by jhd, Fri Nov 5 07:05:13 2004 UTC revision 1.142 by kfstorm, Fri Nov 5 11:30:31 2004 UTC
# Line 32  Boston, MA 02111-1307, USA.  */ Line 32  Boston, MA 02111-1307, USA.  */
32  #include "buffer.h"  #include "buffer.h"
33  #include "process.h"  #include "process.h"
34  #include "termhooks.h"  #include "termhooks.h"
35    #include "keyboard.h"
36    
37  #include <X11/Xproto.h>  #include <X11/Xproto.h>
38    
# Line 171  static void lisp_data_to_selection_data Line 172  static void lisp_data_to_selection_data
172  static Lisp_Object selection_data_to_lisp_data ();  static Lisp_Object selection_data_to_lisp_data ();
173  static Lisp_Object x_get_window_property_as_lisp_data ();  static Lisp_Object x_get_window_property_as_lisp_data ();
174    
175    
176    
177    /* Define a queue to save up SelectionRequest events for later handling.  */
178    
179    struct selection_event_queue
180      {
181        struct input_event event;
182        struct selection_event_queue *next;
183      };
184    
185    static struct selection_event_queue *selection_queue;
186    
187    /* Nonzero means queue up certain events--don't process them yet.  */
188    
189    static int x_queue_selection_requests;
190    
191    /* Queue up an X event *EVENT, to be processed later.  */
192    
193    static void
194    x_queue_event (event)
195         struct input_event *event;
196    {
197      struct selection_event_queue *queue_tmp;
198    
199      /* Don't queue repeated requests */
200      for (queue_tmp = selection_queue; queue_tmp; queue_tmp = queue_tmp->next)
201        {
202          if (!bcmp (&queue_tmp->event, event, sizeof (*event)))
203            {
204              TRACE1 ("IGNORE DUP SELECTION EVENT %08x", (unsigned long)queue_tmp);
205              return;
206            }
207        }
208    
209      queue_tmp
210        = (struct selection_event_queue *) xmalloc (sizeof (struct selection_event_queue));
211    
212      if (queue_tmp != NULL)
213        {
214          TRACE1 ("QUEUE SELECTION EVENT %08x", (unsigned long)queue_tmp);
215          queue_tmp->event = *event;
216          queue_tmp->next = selection_queue;
217          selection_queue = queue_tmp;
218        }
219    }
220    
221    /* Start queuing SelectionRequest events.  */
222    
223    static void
224    x_start_queuing_selection_requests ()
225    {
226      if (x_queue_selection_requests)
227        abort ();
228    
229      x_queue_selection_requests++;
230      TRACE1 ("x_start_queuing_selection_requests %d", x_queue_selection_requests);
231    }
232    
233    /* Stop queuing SelectionRequest events.  */
234    
235    static void
236    x_stop_queuing_selection_requests ()
237    {
238      TRACE1 ("x_stop_queuing_selection_requests %d", x_queue_selection_requests);
239      --x_queue_selection_requests;
240    
241      /* Take all the queued events and put them back
242         so that they get processed afresh.  */
243    
244      while (selection_queue != NULL)
245        {
246          struct selection_event_queue *queue_tmp = selection_queue;
247          TRACE1 ("RESTORE SELECTION EVENT %08x", (unsigned long)queue_tmp);
248          kbd_buffer_unget_event (&queue_tmp->event);
249          selection_queue = queue_tmp->next;
250          xfree ((char *)queue_tmp);
251        }
252    }
253    
254    
255  /* This converts a Lisp symbol to a server Atom, avoiding a server  /* This converts a Lisp symbol to a server Atom, avoiding a server
256     roundtrip whenever possible.  */     roundtrip whenever possible.  */
257    
# Line 560  static struct prop_location *property_ch Line 641  static struct prop_location *property_ch
641  static struct prop_location *property_change_wait_list;  static struct prop_location *property_change_wait_list;
642    
643  static Lisp_Object  static Lisp_Object
644  queue_selection_requests_unwind (frame)  queue_selection_requests_unwind (tem)
645       Lisp_Object frame;       Lisp_Object tem;
646  {  {
647    FRAME_PTR f = XFRAME (frame);    x_stop_queuing_selection_requests ();
   
   if (! NILP (frame))  
     x_stop_queuing_selection_requests (FRAME_X_DISPLAY (f));  
648    return Qnil;    return Qnil;
649  }  }
650    
# Line 664  x_reply_selection_request (event, format Line 742  x_reply_selection_request (event, format
742           bother trying to queue them.  */           bother trying to queue them.  */
743        if (!NILP (frame))        if (!NILP (frame))
744          {          {
745            x_start_queuing_selection_requests (display);            x_start_queuing_selection_requests ();
746    
747            record_unwind_protect (queue_selection_requests_unwind,            record_unwind_protect (queue_selection_requests_unwind,
748                                   frame);                                   Qnil);
749          }          }
750    
751        if (x_window_to_frame (dpyinfo, window)) /* #### debug */        if (x_window_to_frame (dpyinfo, window)) /* #### debug */
# Line 701  x_reply_selection_request (event, format Line 779  x_reply_selection_request (event, format
779                    XGetAtomName (display, reply.property));                    XGetAtomName (display, reply.property));
780            wait_for_property_change (wait_object);            wait_for_property_change (wait_object);
781          }          }
782          else
783            unexpect_property_change (wait_object);
784    
785        TRACE0 ("Got ACK");        TRACE0 ("Got ACK");
786        while (bytes_remaining)        while (bytes_remaining)
# Line 774  x_reply_selection_request (event, format Line 854  x_reply_selection_request (event, format
854  /* Handle a SelectionRequest event EVENT.  /* Handle a SelectionRequest event EVENT.
855     This is called from keyboard.c when such an event is found in the queue.  */     This is called from keyboard.c when such an event is found in the queue.  */
856    
857  void  static void
858  x_handle_selection_request (event)  x_handle_selection_request (event)
859       struct input_event *event;       struct input_event *event;
860  {  {
# Line 789  x_handle_selection_request (event) Line 869  x_handle_selection_request (event)
869    struct x_display_info *dpyinfo    struct x_display_info *dpyinfo
870      = x_display_info_for_display (SELECTION_EVENT_DISPLAY (event));      = x_display_info_for_display (SELECTION_EVENT_DISPLAY (event));
871    
872      TRACE0 ("x_handle_selection_request");
873    
874    local_selection_data = Qnil;    local_selection_data = Qnil;
875    target_symbol = Qnil;    target_symbol = Qnil;
876    converted_selection = Qnil;    converted_selection = Qnil;
# Line 883  x_handle_selection_request (event) Line 965  x_handle_selection_request (event)
965     client cleared out our previously asserted selection.     client cleared out our previously asserted selection.
966     This is called from keyboard.c when such an event is found in the queue.  */     This is called from keyboard.c when such an event is found in the queue.  */
967    
968  void  static void
969  x_handle_selection_clear (event)  x_handle_selection_clear (event)
970       struct input_event *event;       struct input_event *event;
971  {  {
# Line 896  x_handle_selection_clear (event) Line 978  x_handle_selection_clear (event)
978    struct x_display_info *dpyinfo = x_display_info_for_display (display);    struct x_display_info *dpyinfo = x_display_info_for_display (display);
979    struct x_display_info *t_dpyinfo;    struct x_display_info *t_dpyinfo;
980    
981      TRACE0 ("x_handle_selection_clear");
982    
983    /* If the new selection owner is also Emacs,    /* If the new selection owner is also Emacs,
984       don't clear the new selection.  */       don't clear the new selection.  */
985    BLOCK_INPUT;    BLOCK_INPUT;
# Line 964  x_handle_selection_clear (event) Line 1048  x_handle_selection_clear (event)
1048    }    }
1049  }  }
1050    
1051    void
1052    x_handle_selection_event (event)
1053         struct input_event *event;
1054    {
1055      TRACE0 ("x_handle_selection_event");
1056    
1057      if (event->kind == SELECTION_REQUEST_EVENT)
1058        {
1059          if (x_queue_selection_requests)
1060            x_queue_event (event);
1061          else
1062            x_handle_selection_request (event);
1063        }
1064      else
1065        x_handle_selection_clear (event);
1066    }
1067    
1068    
1069  /* Clear all selections that were made from frame F.  /* Clear all selections that were made from frame F.
1070     We do this when about to delete a frame.  */     We do this when about to delete a frame.  */
1071    
# Line 1094  unexpect_property_change (location) Line 1196  unexpect_property_change (location)
1196  /* Remove the property change expectation element for IDENTIFIER.  */  /* Remove the property change expectation element for IDENTIFIER.  */
1197    
1198  static Lisp_Object  static Lisp_Object
1199  wait_for_property_change_unwind (identifierval)  wait_for_property_change_unwind (loc)
1200       Lisp_Object identifierval;       Lisp_Object loc;
1201  {  {
1202    unexpect_property_change ((struct prop_location *)    struct prop_location *location = XSAVE_VALUE (loc)->pointer;
1203                              (XFASTINT (XCAR (identifierval)) << 16  
1204                               | XFASTINT (XCDR (identifierval))));    unexpect_property_change (location);
1205      if (location == property_change_reply_object)
1206        property_change_reply_object = 0;
1207    return Qnil;    return Qnil;
1208  }  }
1209    
# Line 1112  wait_for_property_change (location) Line 1216  wait_for_property_change (location)
1216  {  {
1217    int secs, usecs;    int secs, usecs;
1218    int count = SPECPDL_INDEX ();    int count = SPECPDL_INDEX ();
   Lisp_Object tem;  
1219    
1220    tem = Fcons (Qnil, Qnil);    if (property_change_reply_object)
1221    XSETCARFASTINT (tem, (EMACS_UINT)location >> 16);      abort ();
   XSETCDRFASTINT (tem, (EMACS_UINT)location & 0xffff);  
1222    
1223    /* Make sure to do unexpect_property_change if we quit or err.  */    /* Make sure to do unexpect_property_change if we quit or err.  */
1224    record_unwind_protect (wait_for_property_change_unwind, tem);    record_unwind_protect (wait_for_property_change_unwind,
1225                             make_save_value (location, 0));
1226    
1227    XSETCAR (property_change_reply, Qnil);    XSETCAR (property_change_reply, Qnil);
   
1228    property_change_reply_object = location;    property_change_reply_object = location;
1229    
1230    /* If the event we are waiting for arrives beyond here, it will set    /* If the event we are waiting for arrives beyond here, it will set
1231       property_change_reply, because property_change_reply_object says so.  */       property_change_reply, because property_change_reply_object says so.  */
1232    if (! location->arrived)    if (! location->arrived)
# Line 1154  x_handle_property_notify (event) Line 1257  x_handle_property_notify (event)
1257    
1258    while (rest)    while (rest)
1259      {      {
1260        if (rest->property == event->atom        if (!rest->arrived
1261              && rest->property == event->atom
1262            && rest->window == event->window            && rest->window == event->window
1263            && rest->display == event->display            && rest->display == event->display
1264            && rest->desired_state == event->state)            && rest->desired_state == event->state)
# Line 1170  x_handle_property_notify (event) Line 1274  x_handle_property_notify (event)
1274            if (rest == property_change_reply_object)            if (rest == property_change_reply_object)
1275              XSETCAR (property_change_reply, Qt);              XSETCAR (property_change_reply, Qt);
1276    
           if (prev)  
             prev->next = rest->next;  
           else  
             property_change_wait_list = rest->next;  
           xfree (rest);  
1277            return;            return;
1278          }          }
1279    
# Line 1300  x_get_foreign_selection (selection_symbo Line 1399  x_get_foreign_selection (selection_symbo
1399       bother trying to queue them.  */       bother trying to queue them.  */
1400    if (!NILP (frame))    if (!NILP (frame))
1401      {      {
1402        x_start_queuing_selection_requests (display);        x_start_queuing_selection_requests ();
1403    
1404        record_unwind_protect (queue_selection_requests_unwind,        record_unwind_protect (queue_selection_requests_unwind,
1405                               frame);                               Qnil);
1406      }      }
1407    UNBLOCK_INPUT;    UNBLOCK_INPUT;
1408    
# Line 1459  receive_incremental_selection (display, Line 1558  receive_incremental_selection (display,
1558    BLOCK_INPUT;    BLOCK_INPUT;
1559    XSelectInput (display, window, STANDARD_EVENT_SET | PropertyChangeMask);    XSelectInput (display, window, STANDARD_EVENT_SET | PropertyChangeMask);
1560    TRACE1 ("  Delete property %s",    TRACE1 ("  Delete property %s",
1561            SDATA (XSYMBOL (x_atom_to_symbol (display, property))->xname));            SDATA (SYMBOL_NAME (x_atom_to_symbol (display, property))));
1562    XDeleteProperty (display, window, property);    XDeleteProperty (display, window, property);
1563    TRACE1 ("  Expect new value of property %s",    TRACE1 ("  Expect new value of property %s",
1564            SDATA (XSYMBOL (x_atom_to_symbol (display, property))->xname));            SDATA (SYMBOL_NAME (x_atom_to_symbol (display, property))));
1565    wait_object = expect_property_change (display, window, property,    wait_object = expect_property_change (display, window, property,
1566                                          PropertyNewValue);                                          PropertyNewValue);
1567    XFlush (display);    XFlush (display);
# Line 1492  receive_incremental_selection (display, Line 1591  receive_incremental_selection (display,
1591    
1592            if (! waiting_for_other_props_on_window (display, window))            if (! waiting_for_other_props_on_window (display, window))
1593              XSelectInput (display, window, STANDARD_EVENT_SET);              XSelectInput (display, window, STANDARD_EVENT_SET);
           unexpect_property_change (wait_object);  
1594            /* Use xfree, not XFree, because x_get_window_property            /* Use xfree, not XFree, because x_get_window_property
1595               calls xmalloc itself.  */               calls xmalloc itself.  */
1596            if (tmp_data) xfree (tmp_data);            if (tmp_data) xfree (tmp_data);

Legend:
Removed from v.1.141  
changed lines
  Added in v.1.142

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26