comparison src/xselect.c @ 57952:a6f82b95d10b

* xselect.c (struct selection_event_queue, selection_queue) (x_queue_selection_requests, x_queue_event) (x_start_queuing_selection_requests) (x_stop_queuing_selection_requests): Add new queue for selection input events to replace previous XEvent queue in xterm.c. (queue_selection_requests_unwind): Adapt to new queue. (x_reply_selection_request): Adapt to new queue. Unexpect wait_object in case of x errors (memory leak). (x_handle_selection_request, x_handle_selection_clear): Make static. (x_handle_selection_event): New function. May queue selection events. (wait_for_property_change_unwind): Use save_value instead of cons. Clear property_change_reply_object. (wait_for_property_change): Abort if already waiting. Use save_value instead of cons for unwind data. (x_handle_property_notify): Skip events already arrived, but don't free them, as "arrived" field is checked by wait_for_property_change, and it will be freed by unwind or explicit unexpect_property_change. (x_get_foreign_selection): Add to new queue. (receive_incremental_selection): Don't unexpect wait_object when done as it has already been freed by previous wait_for_property_change.
author Kim F. Storm <storm@cua.dk>
date Fri, 05 Nov 2004 11:30:31 +0000
parents 481911368712
children b32fa5b7492d 7a0245dd1848
comparison
equal deleted inserted replaced
57951:fbbae2d9a2f4 57952:a6f82b95d10b
30 #include "frame.h" /* Need this to get the X window of selected_frame */ 30 #include "frame.h" /* Need this to get the X window of selected_frame */
31 #include "blockinput.h" 31 #include "blockinput.h"
32 #include "buffer.h" 32 #include "buffer.h"
33 #include "process.h" 33 #include "process.h"
34 #include "termhooks.h" 34 #include "termhooks.h"
35 #include "keyboard.h"
35 36
36 #include <X11/Xproto.h> 37 #include <X11/Xproto.h>
37 38
38 struct prop_location; 39 struct prop_location;
39 40
169 170
170 static void lisp_data_to_selection_data (); 171 static void lisp_data_to_selection_data ();
171 static Lisp_Object selection_data_to_lisp_data (); 172 static Lisp_Object selection_data_to_lisp_data ();
172 static Lisp_Object x_get_window_property_as_lisp_data (); 173 static Lisp_Object x_get_window_property_as_lisp_data ();
173 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
174 /* This converts a Lisp symbol to a server Atom, avoiding a server 255 /* This converts a Lisp symbol to a server Atom, avoiding a server
175 roundtrip whenever possible. */ 256 roundtrip whenever possible. */
176 257
177 static Atom 258 static Atom
178 symbol_to_x_atom (dpyinfo, display, sym) 259 symbol_to_x_atom (dpyinfo, display, sym)
558 static struct prop_location *property_change_reply_object; 639 static struct prop_location *property_change_reply_object;
559 640
560 static struct prop_location *property_change_wait_list; 641 static struct prop_location *property_change_wait_list;
561 642
562 static Lisp_Object 643 static Lisp_Object
563 queue_selection_requests_unwind (frame) 644 queue_selection_requests_unwind (tem)
564 Lisp_Object frame; 645 Lisp_Object tem;
565 { 646 {
566 FRAME_PTR f = XFRAME (frame); 647 x_stop_queuing_selection_requests ();
567
568 if (! NILP (frame))
569 x_stop_queuing_selection_requests (FRAME_X_DISPLAY (f));
570 return Qnil; 648 return Qnil;
571 } 649 }
572 650
573 /* Return some frame whose display info is DPYINFO. 651 /* Return some frame whose display info is DPYINFO.
574 Return nil if there is none. */ 652 Return nil if there is none. */
662 /* If the display no longer has frames, we can't expect 740 /* If the display no longer has frames, we can't expect
663 to get many more selection requests from it, so don't 741 to get many more selection requests from it, so don't
664 bother trying to queue them. */ 742 bother trying to queue them. */
665 if (!NILP (frame)) 743 if (!NILP (frame))
666 { 744 {
667 x_start_queuing_selection_requests (display); 745 x_start_queuing_selection_requests ();
668 746
669 record_unwind_protect (queue_selection_requests_unwind, 747 record_unwind_protect (queue_selection_requests_unwind,
670 frame); 748 Qnil);
671 } 749 }
672 750
673 if (x_window_to_frame (dpyinfo, window)) /* #### debug */ 751 if (x_window_to_frame (dpyinfo, window)) /* #### debug */
674 error ("Attempt to transfer an INCR to ourself!"); 752 error ("Attempt to transfer an INCR to ourself!");
675 753
699 { 777 {
700 TRACE1 ("Waiting for ACK (deletion of %s)", 778 TRACE1 ("Waiting for ACK (deletion of %s)",
701 XGetAtomName (display, reply.property)); 779 XGetAtomName (display, reply.property));
702 wait_for_property_change (wait_object); 780 wait_for_property_change (wait_object);
703 } 781 }
782 else
783 unexpect_property_change (wait_object);
704 784
705 TRACE0 ("Got ACK"); 785 TRACE0 ("Got ACK");
706 while (bytes_remaining) 786 while (bytes_remaining)
707 { 787 {
708 int i = ((bytes_remaining < max_bytes) 788 int i = ((bytes_remaining < max_bytes)
772 } 852 }
773 853
774 /* Handle a SelectionRequest event EVENT. 854 /* Handle a SelectionRequest event EVENT.
775 This is called from keyboard.c when such an event is found in the queue. */ 855 This is called from keyboard.c when such an event is found in the queue. */
776 856
777 void 857 static void
778 x_handle_selection_request (event) 858 x_handle_selection_request (event)
779 struct input_event *event; 859 struct input_event *event;
780 { 860 {
781 struct gcpro gcpro1, gcpro2, gcpro3; 861 struct gcpro gcpro1, gcpro2, gcpro3;
782 Lisp_Object local_selection_data; 862 Lisp_Object local_selection_data;
787 Lisp_Object successful_p; 867 Lisp_Object successful_p;
788 int count; 868 int count;
789 struct x_display_info *dpyinfo 869 struct x_display_info *dpyinfo
790 = x_display_info_for_display (SELECTION_EVENT_DISPLAY (event)); 870 = x_display_info_for_display (SELECTION_EVENT_DISPLAY (event));
791 871
872 TRACE0 ("x_handle_selection_request");
873
792 local_selection_data = Qnil; 874 local_selection_data = Qnil;
793 target_symbol = Qnil; 875 target_symbol = Qnil;
794 converted_selection = Qnil; 876 converted_selection = Qnil;
795 successful_p = Qnil; 877 successful_p = Qnil;
796 878
881 963
882 /* Handle a SelectionClear event EVENT, which indicates that some 964 /* Handle a SelectionClear event EVENT, which indicates that some
883 client cleared out our previously asserted selection. 965 client cleared out our previously asserted selection.
884 This is called from keyboard.c when such an event is found in the queue. */ 966 This is called from keyboard.c when such an event is found in the queue. */
885 967
886 void 968 static void
887 x_handle_selection_clear (event) 969 x_handle_selection_clear (event)
888 struct input_event *event; 970 struct input_event *event;
889 { 971 {
890 Display *display = SELECTION_EVENT_DISPLAY (event); 972 Display *display = SELECTION_EVENT_DISPLAY (event);
891 Atom selection = SELECTION_EVENT_SELECTION (event); 973 Atom selection = SELECTION_EVENT_SELECTION (event);
893 975
894 Lisp_Object selection_symbol, local_selection_data; 976 Lisp_Object selection_symbol, local_selection_data;
895 Time local_selection_time; 977 Time local_selection_time;
896 struct x_display_info *dpyinfo = x_display_info_for_display (display); 978 struct x_display_info *dpyinfo = x_display_info_for_display (display);
897 struct x_display_info *t_dpyinfo; 979 struct x_display_info *t_dpyinfo;
980
981 TRACE0 ("x_handle_selection_clear");
898 982
899 /* If the new selection owner is also Emacs, 983 /* If the new selection owner is also Emacs,
900 don't clear the new selection. */ 984 don't clear the new selection. */
901 BLOCK_INPUT; 985 BLOCK_INPUT;
902 /* Check each display on the same terminal, 986 /* Check each display on the same terminal,
962 redisplay_preserve_echo_area (20); 1046 redisplay_preserve_echo_area (20);
963 } 1047 }
964 } 1048 }
965 } 1049 }
966 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
967 /* Clear all selections that were made from frame F. 1069 /* Clear all selections that were made from frame F.
968 We do this when about to delete a frame. */ 1070 We do this when about to delete a frame. */
969 1071
970 void 1072 void
971 x_clear_frame_selections (f) 1073 x_clear_frame_selections (f)
1092 } 1194 }
1093 1195
1094 /* Remove the property change expectation element for IDENTIFIER. */ 1196 /* Remove the property change expectation element for IDENTIFIER. */
1095 1197
1096 static Lisp_Object 1198 static Lisp_Object
1097 wait_for_property_change_unwind (identifierval) 1199 wait_for_property_change_unwind (loc)
1098 Lisp_Object identifierval; 1200 Lisp_Object loc;
1099 { 1201 {
1100 unexpect_property_change ((struct prop_location *) 1202 struct prop_location *location = XSAVE_VALUE (loc)->pointer;
1101 (XFASTINT (XCAR (identifierval)) << 16 1203
1102 | XFASTINT (XCDR (identifierval)))); 1204 unexpect_property_change (location);
1205 if (location == property_change_reply_object)
1206 property_change_reply_object = 0;
1103 return Qnil; 1207 return Qnil;
1104 } 1208 }
1105 1209
1106 /* Actually wait for a property change. 1210 /* Actually wait for a property change.
1107 IDENTIFIER should be the value that expect_property_change returned. */ 1211 IDENTIFIER should be the value that expect_property_change returned. */
1110 wait_for_property_change (location) 1214 wait_for_property_change (location)
1111 struct prop_location *location; 1215 struct prop_location *location;
1112 { 1216 {
1113 int secs, usecs; 1217 int secs, usecs;
1114 int count = SPECPDL_INDEX (); 1218 int count = SPECPDL_INDEX ();
1115 Lisp_Object tem; 1219
1116 1220 if (property_change_reply_object)
1117 tem = Fcons (Qnil, Qnil); 1221 abort ();
1118 XSETCARFASTINT (tem, (EMACS_UINT)location >> 16);
1119 XSETCDRFASTINT (tem, (EMACS_UINT)location & 0xffff);
1120 1222
1121 /* Make sure to do unexpect_property_change if we quit or err. */ 1223 /* Make sure to do unexpect_property_change if we quit or err. */
1122 record_unwind_protect (wait_for_property_change_unwind, tem); 1224 record_unwind_protect (wait_for_property_change_unwind,
1225 make_save_value (location, 0));
1123 1226
1124 XSETCAR (property_change_reply, Qnil); 1227 XSETCAR (property_change_reply, Qnil);
1125
1126 property_change_reply_object = location; 1228 property_change_reply_object = location;
1229
1127 /* If the event we are waiting for arrives beyond here, it will set 1230 /* If the event we are waiting for arrives beyond here, it will set
1128 property_change_reply, because property_change_reply_object says so. */ 1231 property_change_reply, because property_change_reply_object says so. */
1129 if (! location->arrived) 1232 if (! location->arrived)
1130 { 1233 {
1131 secs = x_selection_timeout / 1000; 1234 secs = x_selection_timeout / 1000;
1152 { 1255 {
1153 struct prop_location *prev = 0, *rest = property_change_wait_list; 1256 struct prop_location *prev = 0, *rest = property_change_wait_list;
1154 1257
1155 while (rest) 1258 while (rest)
1156 { 1259 {
1157 if (rest->property == event->atom 1260 if (!rest->arrived
1261 && rest->property == event->atom
1158 && rest->window == event->window 1262 && rest->window == event->window
1159 && rest->display == event->display 1263 && rest->display == event->display
1160 && rest->desired_state == event->state) 1264 && rest->desired_state == event->state)
1161 { 1265 {
1162 TRACE2 ("Expected %s of property %s", 1266 TRACE2 ("Expected %s of property %s",
1168 /* If this is the one wait_for_property_change is waiting for, 1272 /* If this is the one wait_for_property_change is waiting for,
1169 tell it to wake up. */ 1273 tell it to wake up. */
1170 if (rest == property_change_reply_object) 1274 if (rest == property_change_reply_object)
1171 XSETCAR (property_change_reply, Qt); 1275 XSETCAR (property_change_reply, Qt);
1172 1276
1173 if (prev)
1174 prev->next = rest->next;
1175 else
1176 property_change_wait_list = rest->next;
1177 xfree (rest);
1178 return; 1277 return;
1179 } 1278 }
1180 1279
1181 prev = rest; 1280 prev = rest;
1182 rest = rest->next; 1281 rest = rest->next;
1298 /* If the display no longer has frames, we can't expect 1397 /* If the display no longer has frames, we can't expect
1299 to get many more selection requests from it, so don't 1398 to get many more selection requests from it, so don't
1300 bother trying to queue them. */ 1399 bother trying to queue them. */
1301 if (!NILP (frame)) 1400 if (!NILP (frame))
1302 { 1401 {
1303 x_start_queuing_selection_requests (display); 1402 x_start_queuing_selection_requests ();
1304 1403
1305 record_unwind_protect (queue_selection_requests_unwind, 1404 record_unwind_protect (queue_selection_requests_unwind,
1306 frame); 1405 Qnil);
1307 } 1406 }
1308 UNBLOCK_INPUT; 1407 UNBLOCK_INPUT;
1309 1408
1310 /* This allows quits. Also, don't wait forever. */ 1409 /* This allows quits. Also, don't wait forever. */
1311 secs = x_selection_timeout / 1000; 1410 secs = x_selection_timeout / 1000;
1457 We are done when the sender places a property of length 0. 1556 We are done when the sender places a property of length 0.
1458 */ 1557 */
1459 BLOCK_INPUT; 1558 BLOCK_INPUT;
1460 XSelectInput (display, window, STANDARD_EVENT_SET | PropertyChangeMask); 1559 XSelectInput (display, window, STANDARD_EVENT_SET | PropertyChangeMask);
1461 TRACE1 (" Delete property %s", 1560 TRACE1 (" Delete property %s",
1462 SDATA (XSYMBOL (x_atom_to_symbol (display, property))->xname)); 1561 SDATA (SYMBOL_NAME (x_atom_to_symbol (display, property))));
1463 XDeleteProperty (display, window, property); 1562 XDeleteProperty (display, window, property);
1464 TRACE1 (" Expect new value of property %s", 1563 TRACE1 (" Expect new value of property %s",
1465 SDATA (XSYMBOL (x_atom_to_symbol (display, property))->xname)); 1564 SDATA (SYMBOL_NAME (x_atom_to_symbol (display, property))));
1466 wait_object = expect_property_change (display, window, property, 1565 wait_object = expect_property_change (display, window, property,
1467 PropertyNewValue); 1566 PropertyNewValue);
1468 XFlush (display); 1567 XFlush (display);
1469 UNBLOCK_INPUT; 1568 UNBLOCK_INPUT;
1470 1569
1490 { 1589 {
1491 TRACE0 ("Done reading incrementally"); 1590 TRACE0 ("Done reading incrementally");
1492 1591
1493 if (! waiting_for_other_props_on_window (display, window)) 1592 if (! waiting_for_other_props_on_window (display, window))
1494 XSelectInput (display, window, STANDARD_EVENT_SET); 1593 XSelectInput (display, window, STANDARD_EVENT_SET);
1495 unexpect_property_change (wait_object);
1496 /* Use xfree, not XFree, because x_get_window_property 1594 /* Use xfree, not XFree, because x_get_window_property
1497 calls xmalloc itself. */ 1595 calls xmalloc itself. */
1498 if (tmp_data) xfree (tmp_data); 1596 if (tmp_data) xfree (tmp_data);
1499 break; 1597 break;
1500 } 1598 }