This source file includes following definitions.
- selection_quantum
- symbol_to_x_atom
- x_atom_to_symbol
- x_own_selection
- x_get_local_selection
- x_decline_selection_request
- set_property_change_object
- x_push_current_selection_request
- x_pop_current_selection_request
- x_selection_request_lisp_error
- c_size_for_format
- x_size_for_format
- selection_data_for_offset
- selection_data_size
- transfer_selecting_event
- x_cancel_selection_transfer
- x_selection_transfer_timeout
- x_start_selection_transfer
- x_continue_selection_transfer
- x_remove_selection_transfers
- x_handle_selection_error
- x_reply_selection_request
- x_handle_selection_request
- x_convert_selection
- x_handle_selection_clear
- x_handle_selection_event
- x_should_preserve_selection
- x_clear_frame_selections
- waiting_for_other_props_on_window
- expect_property_change
- unexpect_property_change
- wait_for_property_change_unwind
- wait_for_property_change
- x_handle_property_notify
- x_display_selection_waiting_message
- x_cancel_atimer
- x_get_foreign_selection
- x_get_window_property
- receive_incremental_selection
- x_free_selection_data
- x_get_window_property_as_lisp_data
- selection_data_to_lisp_data
- cons_to_x_long
- lisp_data_to_selection_data
- clean_local_selection_data
- x_handle_selection_notify
- frame_for_x_selection
- x_clipboard_manager_save
- x_clipboard_manager_error_1
- x_clipboard_manager_error_2
- x_clipboard_manager_save_frame
- x_clipboard_manager_save_all
- x_check_property_data
- x_fill_property_data
- x_property_data_to_lisp
- x_handle_dnd_message
- x_send_client_event
- x_timestamp_for_selection
- syms_of_xselect
- syms_of_xselect_for_pdumper
- mark_xselect
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <config.h>
22 #include <limits.h>
23
24 #ifdef HAVE_SYS_TYPES_H
25 #include <sys/types.h>
26 #endif
27
28 #include <unistd.h>
29
30 #include "lisp.h"
31 #include "xterm.h"
32 #include "frame.h"
33 #include "blockinput.h"
34 #include "sysstdio.h"
35 #include "termhooks.h"
36 #include "keyboard.h"
37 #include "pdumper.h"
38 #include "atimer.h"
39
40 #include <X11/Xproto.h>
41
42 struct prop_location;
43 struct selection_data;
44
45 static void x_decline_selection_request (struct selection_input_event *);
46 static bool x_convert_selection (Lisp_Object, Lisp_Object, Atom,
47 struct x_display_info *, bool);
48 static bool waiting_for_other_props_on_window (Display *, Window);
49 static struct prop_location *expect_property_change (Display *, Window,
50 Atom, int);
51 static void unexpect_property_change (struct prop_location *);
52 static void wait_for_property_change (struct prop_location *);
53 static Lisp_Object x_get_window_property_as_lisp_data (struct x_display_info *,
54 Window, Atom,
55 Lisp_Object, Atom, bool);
56 static Lisp_Object selection_data_to_lisp_data (struct x_display_info *,
57 const unsigned char *,
58 ptrdiff_t, Atom, int);
59 static void lisp_data_to_selection_data (struct x_display_info *, Lisp_Object,
60 struct selection_data *);
61 static void x_send_client_event (Lisp_Object, Lisp_Object, Lisp_Object,
62 Atom, Lisp_Object, Lisp_Object);
63
64
65
66 #ifdef TRACE_SELECTION
67 #define TRACE0(fmt) \
68 fprintf (stderr, "%"PRIdMAX": " fmt "\n", (intmax_t) getpid ())
69 #define TRACE1(fmt, a0) \
70 fprintf (stderr, "%"PRIdMAX": " fmt "\n", (intmax_t) getpid (), a0)
71 #define TRACE2(fmt, a0, a1) \
72 fprintf (stderr, "%"PRIdMAX": " fmt "\n", (intmax_t) getpid (), a0, a1)
73 #define TRACE3(fmt, a0, a1, a2) \
74 fprintf (stderr, "%"PRIdMAX": " fmt "\n", (intmax_t) getpid (), a0, a1, a2)
75 #else
76 #define TRACE0(fmt) (void) 0
77 #define TRACE1(fmt, a0) (void) 0
78 #define TRACE2(fmt, a0, a1) (void) 0
79 #define TRACE3(fmt, a0, a1, a2) (void) 0
80 #endif
81
82
83
84 #define X_LONG_SIZE 4
85
86
87
88
89
90
91
92
93
94
95
96
97
98 #define MAX_SELECTION_QUANTUM \
99 ((int) min (0xFFFFFF, (min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX) - 1) \
100 / max (X_LONG_SIZE, sizeof (long)))))
101
102 static int
103 selection_quantum (Display *display)
104 {
105 long mrs;
106
107 mrs = XExtendedMaxRequestSize (display);
108
109 if (!mrs)
110 mrs = XMaxRequestSize (display);
111
112 return (mrs < MAX_SELECTION_QUANTUM / X_LONG_SIZE + 25
113 ? (mrs - 25) * X_LONG_SIZE
114 : MAX_SELECTION_QUANTUM);
115 }
116
117 #define LOCAL_SELECTION(selection_symbol, dpyinfo) \
118 assq_no_quit (selection_symbol, dpyinfo->terminal->Vselection_alist)
119
120
121
122
123
124
125 Atom
126 symbol_to_x_atom (struct x_display_info *dpyinfo, Lisp_Object sym)
127 {
128 Atom val;
129 if (NILP (sym))
130 return 0;
131 if (EQ (sym, QPRIMARY))
132 return XA_PRIMARY;
133 if (EQ (sym, QSECONDARY))
134 return XA_SECONDARY;
135 if (EQ (sym, QSTRING))
136 return XA_STRING;
137 if (EQ (sym, QINTEGER))
138 return XA_INTEGER;
139 if (EQ (sym, QATOM))
140 return XA_ATOM;
141 if (EQ (sym, QCLIPBOARD))
142 return dpyinfo->Xatom_CLIPBOARD;
143 if (EQ (sym, QTIMESTAMP))
144 return dpyinfo->Xatom_TIMESTAMP;
145 if (EQ (sym, QTEXT))
146 return dpyinfo->Xatom_TEXT;
147 if (EQ (sym, QCOMPOUND_TEXT))
148 return dpyinfo->Xatom_COMPOUND_TEXT;
149 if (EQ (sym, QUTF8_STRING))
150 return dpyinfo->Xatom_UTF8_STRING;
151 if (EQ (sym, QDELETE))
152 return dpyinfo->Xatom_DELETE;
153 if (EQ (sym, QMULTIPLE))
154 return dpyinfo->Xatom_MULTIPLE;
155 if (EQ (sym, QINCR))
156 return dpyinfo->Xatom_INCR;
157 if (EQ (sym, Q_EMACS_TMP_))
158 return dpyinfo->Xatom_EMACS_TMP;
159 if (EQ (sym, QTARGETS))
160 return dpyinfo->Xatom_TARGETS;
161 if (EQ (sym, QNULL))
162 return dpyinfo->Xatom_NULL;
163 if (EQ (sym, QXdndSelection))
164 return dpyinfo->Xatom_XdndSelection;
165 if (EQ (sym, QXmTRANSFER_SUCCESS))
166 return dpyinfo->Xatom_XmTRANSFER_SUCCESS;
167 if (EQ (sym, QXmTRANSFER_FAILURE))
168 return dpyinfo->Xatom_XmTRANSFER_FAILURE;
169 if (EQ (sym, QXdndDirectSave0))
170 return dpyinfo->Xatom_XdndDirectSave0;
171 if (EQ (sym, Qtext_plain))
172 return dpyinfo->Xatom_text_plain;
173 if (EQ (sym, QXdndActionDirectSave))
174 return dpyinfo->Xatom_XdndActionDirectSave;
175
176 if (!SYMBOLP (sym))
177 emacs_abort ();
178
179 TRACE1 (" XInternAtom %s", SSDATA (SYMBOL_NAME (sym)));
180 block_input ();
181 val = x_intern_cached_atom (dpyinfo, SSDATA (SYMBOL_NAME (sym)), false);
182 unblock_input ();
183 return val;
184 }
185
186
187
188
189
190 Lisp_Object
191 x_atom_to_symbol (struct x_display_info *dpyinfo, Atom atom)
192 {
193 char *str;
194 Lisp_Object val;
195
196 if (! atom)
197 return Qnil;
198
199 switch (atom)
200 {
201 case XA_PRIMARY:
202 return QPRIMARY;
203 case XA_SECONDARY:
204 return QSECONDARY;
205 case XA_STRING:
206 return QSTRING;
207 case XA_INTEGER:
208 return QINTEGER;
209 case XA_ATOM:
210 return QATOM;
211 }
212
213 if (dpyinfo == NULL)
214 return Qnil;
215 if (atom == dpyinfo->Xatom_CLIPBOARD)
216 return QCLIPBOARD;
217 if (atom == dpyinfo->Xatom_TIMESTAMP)
218 return QTIMESTAMP;
219 if (atom == dpyinfo->Xatom_TEXT)
220 return QTEXT;
221 if (atom == dpyinfo->Xatom_COMPOUND_TEXT)
222 return QCOMPOUND_TEXT;
223 if (atom == dpyinfo->Xatom_UTF8_STRING)
224 return QUTF8_STRING;
225 if (atom == dpyinfo->Xatom_DELETE)
226 return QDELETE;
227 if (atom == dpyinfo->Xatom_MULTIPLE)
228 return QMULTIPLE;
229 if (atom == dpyinfo->Xatom_INCR)
230 return QINCR;
231 if (atom == dpyinfo->Xatom_EMACS_TMP)
232 return Q_EMACS_TMP_;
233 if (atom == dpyinfo->Xatom_TARGETS)
234 return QTARGETS;
235 if (atom == dpyinfo->Xatom_NULL)
236 return QNULL;
237 if (atom == dpyinfo->Xatom_XdndSelection)
238 return QXdndSelection;
239 if (atom == dpyinfo->Xatom_XmTRANSFER_SUCCESS)
240 return QXmTRANSFER_SUCCESS;
241 if (atom == dpyinfo->Xatom_XmTRANSFER_FAILURE)
242 return QXmTRANSFER_FAILURE;
243 if (atom == dpyinfo->Xatom_XdndDirectSave0)
244 return QXdndDirectSave0;
245 if (atom == dpyinfo->Xatom_text_plain)
246 return Qtext_plain;
247 if (atom == dpyinfo->Xatom_XdndActionDirectSave)
248 return QXdndActionDirectSave;
249
250 x_catch_errors (dpyinfo->display);
251 str = x_get_atom_name (dpyinfo, atom, NULL);
252 x_uncatch_errors ();
253
254 TRACE0 ("XGetAtomName --> NULL");
255 if (!str)
256 return Qnil;
257 TRACE1 ("XGetAtomName --> %s", str);
258
259 val = intern (str);
260 xfree (str);
261 return val;
262 }
263
264
265
266
267
268
269
270
271
272
273 void
274 x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value,
275 Lisp_Object frame, Lisp_Object dnd_data, Time timestamp)
276 {
277 struct frame *f = XFRAME (frame);
278 Window selecting_window = FRAME_X_WINDOW (f);
279 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
280 Display *display = dpyinfo->display;
281 Atom selection_atom = symbol_to_x_atom (dpyinfo, selection_name);
282
283 if (!timestamp)
284 timestamp = dpyinfo->last_user_time;
285
286 block_input ();
287 XSetSelectionOwner (display, selection_atom, selecting_window,
288 timestamp);
289 unblock_input ();
290
291
292 {
293 Lisp_Object selection_data;
294 Lisp_Object prev_value;
295
296 selection_data = list5 (selection_name, selection_value,
297 INT_TO_INTEGER (timestamp), frame,
298 dnd_data);
299 prev_value = LOCAL_SELECTION (selection_name, dpyinfo);
300
301 tset_selection_alist
302 (dpyinfo->terminal,
303 Fcons (selection_data, dpyinfo->terminal->Vselection_alist));
304
305
306
307 if (!NILP (prev_value))
308 {
309
310 Lisp_Object rest = dpyinfo->terminal->Vselection_alist;
311 for (; CONSP (rest); rest = XCDR (rest))
312 if (EQ (prev_value, CAR (XCDR (rest))))
313 {
314 XSETCDR (rest, XCDR (XCDR (rest)));
315 break;
316 }
317 }
318 }
319 }
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336 static Lisp_Object
337 x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
338 bool local_request, struct x_display_info *dpyinfo,
339 Lisp_Object local_value, bool need_alternate)
340 {
341 Lisp_Object tem;
342 Lisp_Object handler_fn, value, check;
343 bool may_quit;
344 specpdl_ref count;
345
346 may_quit = false;
347
348 if (NILP (local_value))
349 local_value = LOCAL_SELECTION (selection_symbol, dpyinfo);
350 else
351 may_quit = true;
352
353 if (NILP (local_value))
354 return Qnil;
355
356
357 if (EQ (target_type, QTIMESTAMP))
358 {
359 handler_fn = Qnil;
360 value = XCAR (XCDR (XCDR (local_value)));
361 }
362 else
363 {
364
365
366
367 count = SPECPDL_INDEX ();
368
369 if (!may_quit)
370 specbind (Qinhibit_quit, Qt);
371
372 CHECK_SYMBOL (target_type);
373 handler_fn = CDR (Fassq (target_type, Vselection_converter_alist));
374
375 if (CONSP (handler_fn))
376 handler_fn = XCDR (handler_fn);
377
378 if (!need_alternate)
379 tem = XCAR (XCDR (local_value));
380 else
381 tem = XCAR (XCDR (XCDR (XCDR (XCDR (local_value)))));
382
383 if (STRINGP (tem))
384 {
385 local_value = Fget_text_property (make_fixnum (0),
386 target_type, tem);
387
388 if (!NILP (local_value))
389 tem = local_value;
390 }
391
392 if (!NILP (handler_fn))
393 value = call3 (handler_fn, selection_symbol,
394 ((local_request
395 && NILP (Vx_treat_local_requests_remotely))
396 ? Qnil
397 : target_type),
398 tem);
399 else
400 value = Qnil;
401 value = unbind_to (count, value);
402 }
403
404
405
406
407 check = value;
408 if (CONSP (value)
409 && SYMBOLP (XCAR (value)))
410 check = XCDR (value);
411
412 if (STRINGP (check)
413 || VECTORP (check)
414 || SYMBOLP (check)
415 || INTEGERP (check)
416 || NILP (value))
417 return value;
418
419 else if (CONSP (check)
420 && INTEGERP (XCAR (check))
421 && (INTEGERP (XCDR (check))
422 ||
423 (CONSP (XCDR (check))
424 && INTEGERP (XCAR (XCDR (check)))
425 && NILP (XCDR (XCDR (check))))))
426 return value;
427
428 signal_error ("Invalid data returned by selection-conversion function",
429 list2 (handler_fn, value));
430 }
431
432
433
434
435
436
437 static void
438 x_decline_selection_request (struct selection_input_event *event)
439 {
440 XEvent reply_base;
441 XSelectionEvent *reply;
442 Display *dpy;
443 struct x_display_info *dpyinfo;
444
445 reply = &(reply_base.xselection);
446 dpy = SELECTION_EVENT_DISPLAY (event);
447 dpyinfo = x_display_info_for_display (dpy);
448
449 if (!dpyinfo)
450 return;
451
452 reply->type = SelectionNotify;
453 reply->display = dpy;
454 reply->requestor = SELECTION_EVENT_REQUESTOR (event);
455 reply->selection = SELECTION_EVENT_SELECTION (event);
456 reply->time = SELECTION_EVENT_TIME (event);
457 reply->target = SELECTION_EVENT_TARGET (event);
458 reply->property = None;
459
460
461
462 block_input ();
463 x_ignore_errors_for_next_request (dpyinfo, 0);
464 XSendEvent (dpyinfo->display, reply->requestor,
465 False, 0, &reply_base);
466 x_stop_ignoring_errors (dpyinfo);
467
468 XFlush (dpyinfo->display);
469 unblock_input ();
470 }
471
472
473
474 struct selection_data
475 {
476
477 unsigned char *data;
478
479
480
481
482 Lisp_Object string;
483
484
485
486 ptrdiff_t size;
487
488
489 int format;
490
491
492 Atom type;
493
494
495 Atom property;
496
497
498
499 struct selection_data *next;
500 };
501
502
503
504
505 struct transfer
506 {
507
508 Window requestor;
509
510
511
512 size_t offset, items_per_request;
513
514
515 struct x_display_info *dpyinfo;
516
517
518 struct selection_data data;
519
520
521 struct transfer *next, *last;
522
523
524 struct atimer *timeout;
525
526
527 unsigned int serial;
528
529
530 int flags;
531 };
532
533 #define SELECTED_EVENTS 1
534
535 struct x_selection_request
536 {
537
538 struct x_selection_request *last;
539
540
541 struct x_display_info *dpyinfo;
542
543
544 struct selection_input_event *request;
545
546
547 struct selection_data *converted_selections;
548
549
550 unsigned int serial;
551
552
553 bool converted;
554 };
555
556
557
558
559 struct x_selection_request *selection_request_stack;
560
561
562
563
564 struct transfer outstanding_transfers;
565
566
567
568 static unsigned int selection_serial;
569
570
571
572 struct prop_location
573 {
574 int identifier;
575 Display *display;
576 Window window;
577 Atom property;
578 int desired_state;
579 bool arrived;
580 struct prop_location *next;
581 };
582
583 static int prop_location_identifier;
584
585 static Lisp_Object property_change_reply;
586
587 static struct prop_location *property_change_reply_object;
588
589 static struct prop_location *property_change_wait_list;
590
591 static void
592 set_property_change_object (struct prop_location *location)
593 {
594
595
596 if (! input_blocked_p ())
597 emacs_abort ();
598
599 XSETCAR (property_change_reply, Qnil);
600 property_change_reply_object = location;
601 }
602
603
604
605 static void
606 x_push_current_selection_request (struct selection_input_event *se,
607 struct x_display_info *dpyinfo)
608 {
609 struct x_selection_request *frame;
610
611 frame = xmalloc (sizeof *frame);
612 frame->converted = false;
613 frame->last = selection_request_stack;
614 frame->request = se;
615 frame->dpyinfo = dpyinfo;
616 frame->converted_selections = NULL;
617
618 selection_request_stack = frame;
619 }
620
621 static void
622 x_pop_current_selection_request (void)
623 {
624 struct x_selection_request *tem;
625
626 tem = selection_request_stack;
627 selection_request_stack = selection_request_stack->last;
628
629 xfree (tem);
630 }
631
632
633
634
635
636 static void
637 x_selection_request_lisp_error (void)
638 {
639 struct selection_data *cs, *next;
640 struct x_selection_request *frame;
641
642 frame = selection_request_stack;
643
644 for (cs = frame->converted_selections; cs; cs = next)
645 {
646 next = cs->next;
647 if (cs->data)
648 xfree (cs->data);
649 xfree (cs);
650 }
651 frame->converted_selections = NULL;
652
653 if (!frame->converted && frame->dpyinfo->display)
654 x_decline_selection_request (frame->request);
655 }
656
657
658
659 static size_t
660 c_size_for_format (int format)
661 {
662 switch (format)
663 {
664 case 8:
665 return sizeof (char);
666
667 case 16:
668 return sizeof (short);
669
670 case 32:
671 return sizeof (long);
672 }
673
674 emacs_abort ();
675 }
676
677 static size_t
678 x_size_for_format (int format)
679 {
680 switch (format)
681 {
682 case 8:
683 return 1;
684
685 case 16:
686 return 2;
687
688 case 32:
689 return 4;
690 }
691
692 emacs_abort ();
693 }
694
695
696
697
698
699
700 static unsigned char *
701 selection_data_for_offset (struct selection_data *data,
702 long offset, size_t *remaining)
703 {
704 unsigned char *base;
705 size_t size;
706
707 if (!NILP (data->string))
708 {
709 base = SDATA (data->string);
710 size = SBYTES (data->string);
711 }
712 else
713 {
714 base = data->data;
715 size = data->size;
716 }
717
718 if (offset >= size)
719 {
720 *remaining = 0;
721 return NULL;
722 }
723
724 base += (offset * c_size_for_format (data->format));
725 *remaining = size - offset;
726 return base;
727 }
728
729
730
731
732
733 static size_t
734 selection_data_size (struct selection_data *data)
735 {
736 size_t scratch;
737
738 if (!NILP (data->string))
739 return SBYTES (data->string);
740
741 switch (data->format)
742 {
743 case 8:
744 return (size_t) data->size;
745
746 case 16:
747 if (ckd_mul (&scratch, data->size, 2))
748 return SIZE_MAX;
749
750 return scratch;
751
752 case 32:
753 if (ckd_mul (&scratch, data->size, 4))
754 return SIZE_MAX;
755
756 return scratch;
757 }
758
759
760 emacs_abort ();
761 }
762
763
764
765
766 static bool
767 transfer_selecting_event (struct x_display_info *dpyinfo,
768 Window requestor)
769 {
770 struct transfer *next;
771
772 next = outstanding_transfers.next;
773 for (; next != &outstanding_transfers; next = next->next)
774 {
775 if (next->requestor == requestor
776 && next->dpyinfo == dpyinfo)
777 return true;
778 }
779
780 return false;
781 }
782
783
784
785
786 static void
787 x_cancel_selection_transfer (struct transfer *transfer)
788 {
789 xfree (transfer->data.data);
790
791 if (transfer->next)
792 {
793 transfer->next->last = transfer->last;
794 transfer->last->next = transfer->next;
795 }
796
797 if (transfer->flags & SELECTED_EVENTS
798 && !transfer_selecting_event (transfer->dpyinfo,
799 transfer->requestor)
800
801 && transfer->dpyinfo->display)
802 {
803
804
805 block_input ();
806 x_ignore_errors_for_next_request (transfer->dpyinfo, 0);
807 XSelectInput (transfer->dpyinfo->display,
808 transfer->requestor, NoEventMask);
809 x_stop_ignoring_errors (transfer->dpyinfo);
810 unblock_input ();
811 }
812
813 cancel_atimer (transfer->timeout);
814 xfree (transfer);
815 }
816
817 static void
818 x_selection_transfer_timeout (struct atimer *atimer)
819 {
820 struct transfer *transfer;
821
822 transfer = atimer->client_data;
823 x_cancel_selection_transfer (transfer);
824 }
825
826
827
828
829
830
831 static void
832 x_start_selection_transfer (struct x_display_info *dpyinfo, Window requestor,
833 struct selection_data *data)
834 {
835 struct transfer *transfer;
836 intmax_t timeout;
837 intmax_t secs;
838 int nsecs;
839 size_t remaining, max_size;
840 unsigned char *xdata;
841 unsigned long data_size;
842
843 timeout = max (0, x_selection_timeout);
844 secs = timeout / 1000;
845 nsecs = (timeout % 1000) * 1000000;
846
847 transfer = xzalloc (sizeof *transfer);
848 transfer->requestor = requestor;
849 transfer->dpyinfo = dpyinfo;
850
851 transfer->timeout = start_atimer (ATIMER_RELATIVE,
852 make_timespec (secs, nsecs),
853 x_selection_transfer_timeout,
854 transfer);
855
856
857
858
859
860 transfer->data = *data;
861 data->data = NULL;
862
863
864
865
866 data->string = Qnil;
867
868
869
870
871
872
873 max_size = selection_quantum (dpyinfo->display);
874
875 TRACE3 (" x_start_selection_transfer: transferring to 0x%lx. "
876 "transfer consists of %zu bytes, quantum being %zu",
877 requestor, selection_data_size (&transfer->data),
878 max_size);
879
880 if (selection_data_size (&transfer->data) > max_size)
881 {
882
883
884
885 transfer->items_per_request
886 = (max_size / x_size_for_format (transfer->data.format));
887 TRACE1 (" x_start_selection_transfer: starting incremental"
888 " selection transfer, with %zu items per request",
889 transfer->items_per_request);
890
891
892
893 transfer->next = outstanding_transfers.next;
894 transfer->last = &outstanding_transfers;
895 transfer->next->last = transfer;
896 transfer->last->next = transfer;
897
898
899
900
901 transfer->serial = (++selection_serial
902 ? selection_serial
903 : ++selection_serial);
904
905
906
907
908 data_size = selection_data_size (&transfer->data);
909
910
911
912 transfer->flags |= SELECTED_EVENTS;
913
914 x_ignore_errors_for_next_request (dpyinfo, transfer->serial);
915 XChangeProperty (dpyinfo->display, requestor,
916 transfer->data.property,
917 dpyinfo->Xatom_INCR, 32, PropModeReplace,
918 (unsigned char *) &data_size, 1);
919
920
921
922
923
924
925
926 XSelectInput (dpyinfo->display, requestor, PropertyChangeMask);
927 x_stop_ignoring_errors (dpyinfo);
928 }
929 else
930 {
931
932 xdata = selection_data_for_offset (&transfer->data,
933 0, &remaining);
934 eassert (remaining <= INT_MAX);
935
936 TRACE1 (" x_start_selection_transfer: writing"
937 " %zu elements directly to requestor window",
938 remaining);
939
940 x_ignore_errors_for_next_request (dpyinfo, 0);
941 XChangeProperty (dpyinfo->display, requestor,
942 transfer->data.property,
943 transfer->data.type,
944 transfer->data.format,
945 PropModeReplace, xdata, remaining);
946 x_stop_ignoring_errors (dpyinfo);
947
948
949 x_cancel_selection_transfer (transfer);
950 }
951 }
952
953
954
955
956
957 static void
958 x_continue_selection_transfer (struct transfer *transfer)
959 {
960 size_t remaining;
961 unsigned char *xdata;
962
963 xdata = selection_data_for_offset (&transfer->data,
964 transfer->offset,
965 &remaining);
966 remaining = min (remaining, transfer->items_per_request);
967
968 if (!remaining)
969 {
970
971
972 TRACE0 (" x_continue_selection_transfer: writing 0 items to"
973 " indicate EOF");
974 x_ignore_errors_for_next_request (transfer->dpyinfo, 0);
975 XChangeProperty (transfer->dpyinfo->display,
976 transfer->requestor,
977 transfer->data.property,
978 transfer->data.type,
979 transfer->data.format,
980 PropModeReplace,
981 NULL, 0);
982 x_stop_ignoring_errors (transfer->dpyinfo);
983 TRACE0 (" x_continue_selection_transfer: done sending incrementally");
984
985 x_cancel_selection_transfer (transfer);
986 }
987 else
988 {
989 TRACE2 (" x_continue_selection_transfer: writing %zu items"
990 "; current offset is %zu", remaining, transfer->offset);
991 eassert (remaining <= INT_MAX);
992
993 transfer->offset += remaining;
994
995 x_ignore_errors_for_next_request (transfer->dpyinfo,
996 transfer->serial);
997 XChangeProperty (transfer->dpyinfo->display,
998 transfer->requestor,
999 transfer->data.property,
1000 transfer->data.type,
1001 transfer->data.format,
1002 PropModeReplace, xdata,
1003 remaining);
1004 x_stop_ignoring_errors (transfer->dpyinfo);
1005 }
1006 }
1007
1008 void
1009 x_remove_selection_transfers (struct x_display_info *dpyinfo)
1010 {
1011 struct transfer *next, *last;
1012
1013 next = outstanding_transfers.next;
1014 while (next != &outstanding_transfers)
1015 {
1016 last = next;
1017 next = next->next;
1018
1019 if (last->dpyinfo == dpyinfo)
1020 x_cancel_selection_transfer (last);
1021 }
1022 }
1023
1024
1025
1026
1027
1028 void
1029 x_handle_selection_error (unsigned int serial, XErrorEvent *error)
1030 {
1031 struct transfer *next, *last;
1032
1033 if (error->error_code != BadWindow)
1034
1035
1036
1037
1038 return;
1039
1040 next = outstanding_transfers.next;
1041 while (next != &outstanding_transfers)
1042 {
1043 last = next;
1044 next = next->next;
1045
1046 if (last->serial == serial)
1047 {
1048
1049
1050
1051
1052 last->flags &= ~SELECTED_EVENTS;
1053 x_cancel_selection_transfer (last);
1054 }
1055 }
1056 }
1057
1058
1059
1060 static void
1061 x_reply_selection_request (struct selection_input_event *event,
1062 struct x_display_info *dpyinfo)
1063 {
1064 XEvent message;
1065 struct selection_data *cs;
1066 struct x_selection_request *frame;
1067
1068 block_input ();
1069 frame = selection_request_stack;
1070
1071 message.xselection.type = SelectionNotify;
1072 message.xselection.display = dpyinfo->display;
1073 message.xselection.requestor = SELECTION_EVENT_REQUESTOR (event);
1074 message.xselection.selection = SELECTION_EVENT_SELECTION (event);
1075 message.xselection.time = SELECTION_EVENT_TIME (event);
1076 message.xselection.target = SELECTION_EVENT_TARGET (event);
1077 message.xselection.property = SELECTION_EVENT_PROPERTY (event);
1078
1079 if (message.xselection.property == None)
1080 message.xselection.property = message.xselection.target;
1081
1082
1083
1084 for (cs = frame->converted_selections; cs; cs = cs->next)
1085 x_start_selection_transfer (dpyinfo,
1086 SELECTION_EVENT_REQUESTOR (event),
1087 cs);
1088
1089
1090
1091
1092 x_ignore_errors_for_next_request (dpyinfo, 0);
1093 XSendEvent (dpyinfo->display, SELECTION_EVENT_REQUESTOR (event),
1094 False, NoEventMask, &message);
1095 x_stop_ignoring_errors (dpyinfo);
1096 unblock_input ();
1097 }
1098
1099
1100
1101
1102 static void
1103 x_handle_selection_request (struct selection_input_event *event)
1104 {
1105 Time local_selection_time;
1106 struct x_display_info *dpyinfo = SELECTION_EVENT_DPYINFO (event);
1107 Atom selection = SELECTION_EVENT_SELECTION (event);
1108 Lisp_Object selection_symbol = x_atom_to_symbol (dpyinfo, selection);
1109 Atom target = SELECTION_EVENT_TARGET (event);
1110 Lisp_Object target_symbol = x_atom_to_symbol (dpyinfo, target);
1111 Atom property = SELECTION_EVENT_PROPERTY (event);
1112 Lisp_Object local_selection_data;
1113 bool success = false;
1114 specpdl_ref count = SPECPDL_INDEX ();
1115 bool pushed, use_alternate;
1116 Lisp_Object alias, tem;
1117
1118 alias = Vx_selection_alias_alist;
1119
1120 FOR_EACH_TAIL_SAFE (alias)
1121 {
1122 tem = Qnil;
1123
1124 if (CONSP (alias))
1125 tem = XCAR (alias);
1126
1127 if (CONSP (tem)
1128 && EQ (XCAR (tem), selection_symbol)
1129 && SYMBOLP (XCDR (tem)))
1130 {
1131 selection_symbol = XCDR (tem);
1132 break;
1133 }
1134 }
1135
1136 pushed = false;
1137
1138 if (!dpyinfo)
1139 goto REALLY_DONE;
1140
1141 local_selection_data = LOCAL_SELECTION (selection_symbol, dpyinfo);
1142
1143
1144 if (NILP (local_selection_data)) goto DONE;
1145
1146
1147 CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))),
1148 Time, local_selection_time);
1149 if (SELECTION_EVENT_TIME (event) != CurrentTime
1150 && local_selection_time > SELECTION_EVENT_TIME (event))
1151 goto DONE;
1152
1153 use_alternate = false;
1154
1155
1156
1157 if (dpyinfo->pending_dnd_time
1158 && ((SELECTION_EVENT_TIME (event)
1159 == dpyinfo->pending_dnd_time + 1)
1160 || (SELECTION_EVENT_TIME (event)
1161 == dpyinfo->pending_dnd_time + 2)))
1162 use_alternate = true;
1163
1164 block_input ();
1165 pushed = true;
1166 x_push_current_selection_request (event, dpyinfo);
1167 record_unwind_protect_void (x_pop_current_selection_request);
1168 record_unwind_protect_void (x_selection_request_lisp_error);
1169 unblock_input ();
1170
1171 TRACE2 ("x_handle_selection_request: selection=%s, target=%s",
1172 SDATA (SYMBOL_NAME (selection_symbol)),
1173 SDATA (SYMBOL_NAME (target_symbol)));
1174
1175 if (EQ (target_symbol, QMULTIPLE))
1176 {
1177
1178
1179
1180 Window requestor = SELECTION_EVENT_REQUESTOR (event);
1181 Lisp_Object multprop;
1182 ptrdiff_t j, nselections;
1183 struct selection_data cs;
1184
1185 if (property == None)
1186 goto DONE;
1187
1188 multprop
1189 = x_get_window_property_as_lisp_data (dpyinfo, requestor, property,
1190 QMULTIPLE, selection, true);
1191
1192 if (!VECTORP (multprop) || ASIZE (multprop) % 2)
1193 goto DONE;
1194
1195 nselections = ASIZE (multprop) / 2;
1196
1197 for (j = 0; j < nselections; j++)
1198 {
1199 Lisp_Object subtarget = AREF (multprop, 2 * j);
1200 Atom subproperty = symbol_to_x_atom (dpyinfo,
1201 AREF (multprop, 2*j+1));
1202 bool subsuccess = false;
1203
1204 if (subproperty != None)
1205 subsuccess = x_convert_selection (selection_symbol, subtarget,
1206 subproperty, dpyinfo,
1207 use_alternate);
1208 if (!subsuccess)
1209 ASET (multprop, 2 * j + 1, Qnil);
1210 }
1211
1212
1213 lisp_data_to_selection_data (dpyinfo, multprop, &cs);
1214
1215
1216
1217
1218 if (cs.type == XA_ATOM)
1219 cs.type = dpyinfo->Xatom_ATOM_PAIR;
1220
1221 XChangeProperty (dpyinfo->display, requestor, property,
1222 cs.type, cs.format, PropModeReplace,
1223 cs.data, cs.size);
1224 success = true;
1225
1226 xfree (cs.data);
1227 }
1228 else
1229 {
1230 if (property == None)
1231 property = SELECTION_EVENT_TARGET (event);
1232
1233 success = x_convert_selection (selection_symbol,
1234 target_symbol, property,
1235 dpyinfo, use_alternate);
1236 }
1237
1238 DONE:
1239
1240 if (success)
1241 x_reply_selection_request (event, dpyinfo);
1242 else
1243 x_decline_selection_request (event);
1244
1245 if (pushed)
1246 selection_request_stack->converted = true;
1247
1248
1249 if (!NILP (Vx_sent_selection_functions)
1250 && !BASE_EQ (Vx_sent_selection_functions, Qunbound))
1251 CALLN (Frun_hook_with_args, Qx_sent_selection_functions,
1252 selection_symbol, target_symbol, success ? Qt : Qnil);
1253
1254
1255 REALLY_DONE:
1256
1257 unbind_to (count, Qnil);
1258 return;
1259 }
1260
1261
1262
1263
1264
1265
1266
1267 static bool
1268 x_convert_selection (Lisp_Object selection_symbol, Lisp_Object target_symbol,
1269 Atom property, struct x_display_info *dpyinfo,
1270 bool use_alternate)
1271 {
1272 Lisp_Object lisp_selection;
1273 struct selection_data *cs;
1274 struct x_selection_request *frame;
1275
1276 lisp_selection
1277 = x_get_local_selection (selection_symbol, target_symbol,
1278 false, dpyinfo, Qnil, use_alternate);
1279
1280 frame = selection_request_stack;
1281
1282
1283 if (NILP (lisp_selection)
1284 || (CONSP (lisp_selection) && NILP (XCDR (lisp_selection))))
1285 return false;
1286
1287
1288 cs = xmalloc (sizeof *cs);
1289 cs->data = NULL;
1290 cs->string = Qnil;
1291 cs->property = property;
1292 cs->next = frame->converted_selections;
1293 frame->converted_selections = cs;
1294
1295 lisp_data_to_selection_data (dpyinfo, lisp_selection, cs);
1296 return true;
1297 }
1298
1299
1300
1301
1302
1303 static void
1304 x_handle_selection_clear (struct selection_input_event *event)
1305 {
1306 Atom selection = SELECTION_EVENT_SELECTION (event);
1307 Time changed_owner_time = SELECTION_EVENT_TIME (event);
1308
1309 Lisp_Object selection_symbol, local_selection_data;
1310 Time local_selection_time;
1311 struct x_display_info *dpyinfo = SELECTION_EVENT_DPYINFO (event);
1312 Lisp_Object Vselection_alist;
1313
1314 TRACE0 ("x_handle_selection_clear");
1315
1316 if (!dpyinfo) return;
1317
1318 selection_symbol = x_atom_to_symbol (dpyinfo, selection);
1319 local_selection_data = LOCAL_SELECTION (selection_symbol, dpyinfo);
1320
1321
1322 if (NILP (local_selection_data)) return;
1323
1324 CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))),
1325 Time, local_selection_time);
1326
1327
1328
1329 if (changed_owner_time != CurrentTime
1330 && local_selection_time > changed_owner_time)
1331 return;
1332
1333
1334 Vselection_alist = dpyinfo->terminal->Vselection_alist;
1335 if (EQ (local_selection_data, CAR (Vselection_alist)))
1336 Vselection_alist = XCDR (Vselection_alist);
1337 else
1338 {
1339 Lisp_Object rest;
1340 for (rest = Vselection_alist; CONSP (rest); rest = XCDR (rest))
1341 if (EQ (local_selection_data, CAR (XCDR (rest))))
1342 {
1343 XSETCDR (rest, XCDR (XCDR (rest)));
1344 break;
1345 }
1346 }
1347 tset_selection_alist (dpyinfo->terminal, Vselection_alist);
1348
1349
1350 CALLN (Frun_hook_with_args, Qx_lost_selection_functions, selection_symbol);
1351
1352
1353
1354 if (x_dnd_in_progress
1355 && EQ (selection_symbol, QXdndSelection))
1356 error ("Lost ownership of XdndSelection");
1357
1358 redisplay_preserve_echo_area (20);
1359 }
1360
1361 void
1362 x_handle_selection_event (struct selection_input_event *event)
1363 {
1364 TRACE0 ("x_handle_selection_event");
1365 if (event->kind != SELECTION_REQUEST_EVENT)
1366 x_handle_selection_clear (event);
1367 else
1368 x_handle_selection_request (event);
1369 }
1370
1371 static bool
1372 x_should_preserve_selection (Lisp_Object selection)
1373 {
1374 Lisp_Object tem;
1375
1376 tem = Vx_auto_preserve_selections;
1377
1378 if (CONSP (Vx_auto_preserve_selections))
1379 {
1380 FOR_EACH_TAIL_SAFE (tem)
1381 {
1382 if (EQ (XCAR (tem), selection))
1383 return true;
1384 }
1385
1386 return false;
1387 }
1388
1389 return !NILP (tem);
1390 }
1391
1392
1393
1394
1395 void
1396 x_clear_frame_selections (struct frame *f)
1397 {
1398 Lisp_Object frame, rest, lost, selection;
1399 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
1400 struct terminal *t = dpyinfo->terminal;
1401
1402 XSETFRAME (frame, f);
1403 lost = Qnil;
1404
1405
1406 while (CONSP (t->Vselection_alist)
1407 && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (t->Vselection_alist)))))))
1408 {
1409 selection = CAR (CAR (t->Vselection_alist));
1410
1411 if (!x_should_preserve_selection (selection))
1412
1413 CALLN (Frun_hook_with_args, Qx_lost_selection_functions,
1414 selection);
1415 else
1416 lost = Fcons (CAR (t->Vselection_alist), lost);
1417
1418 tset_selection_alist (t, XCDR (t->Vselection_alist));
1419 }
1420
1421
1422 for (rest = t->Vselection_alist; CONSP (rest); rest = XCDR (rest))
1423 if (CONSP (XCDR (rest))
1424 && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (XCDR (rest))))))))
1425 {
1426 selection = XCAR (XCAR (XCDR (rest)));
1427
1428 if (!x_should_preserve_selection (selection))
1429 CALLN (Frun_hook_with_args, Qx_lost_selection_functions,
1430 selection);
1431 else
1432 lost = Fcons (XCAR (XCDR (rest)), lost);
1433
1434 XSETCDR (rest, XCDR (XCDR (rest)));
1435 break;
1436 }
1437
1438 if (!NILP (lost))
1439 x_preserve_selections (dpyinfo, lost, frame);
1440 }
1441
1442
1443
1444
1445 static bool
1446 waiting_for_other_props_on_window (Display *display, Window window)
1447 {
1448 for (struct prop_location *p = property_change_wait_list; p; p = p->next)
1449 if (p->display == display && p->window == window)
1450 return true;
1451 return false;
1452 }
1453
1454
1455
1456
1457
1458
1459 static struct prop_location *
1460 expect_property_change (Display *display, Window window,
1461 Atom property, int state)
1462 {
1463 struct prop_location *pl = xmalloc (sizeof *pl);
1464 pl->identifier = ++prop_location_identifier;
1465 pl->display = display;
1466 pl->window = window;
1467 pl->property = property;
1468 pl->desired_state = state;
1469 pl->next = property_change_wait_list;
1470 pl->arrived = false;
1471 property_change_wait_list = pl;
1472 return pl;
1473 }
1474
1475
1476
1477
1478 static void
1479 unexpect_property_change (struct prop_location *location)
1480 {
1481 struct prop_location *prop, **pprev = &property_change_wait_list;
1482
1483 for (prop = property_change_wait_list; prop; prop = *pprev)
1484 {
1485 if (prop == location)
1486 {
1487 *pprev = prop->next;
1488 xfree (prop);
1489 break;
1490 }
1491 else
1492 pprev = &prop->next;
1493 }
1494 }
1495
1496
1497
1498 static void
1499 wait_for_property_change_unwind (void *loc)
1500 {
1501 struct prop_location *location = loc;
1502
1503 unexpect_property_change (location);
1504 if (location == property_change_reply_object)
1505 property_change_reply_object = 0;
1506 }
1507
1508
1509
1510
1511 static void
1512 wait_for_property_change (struct prop_location *location)
1513 {
1514 specpdl_ref count = SPECPDL_INDEX ();
1515
1516
1517 record_unwind_protect_ptr (wait_for_property_change_unwind, location);
1518
1519
1520
1521
1522
1523
1524 if (! location->arrived)
1525 {
1526 intmax_t timeout = max (0, x_selection_timeout);
1527 intmax_t secs = timeout / 1000;
1528 int nsecs = (timeout % 1000) * 1000000;
1529 TRACE2 (" Waiting %"PRIdMAX" secs, %d nsecs", secs, nsecs);
1530
1531 if (!input_blocked_p ())
1532 wait_reading_process_output (secs, nsecs, 0, false,
1533 property_change_reply, NULL, 0);
1534 else
1535 x_wait_for_cell_change (property_change_reply,
1536 make_timespec (secs, nsecs));
1537
1538 if (NILP (XCAR (property_change_reply)))
1539 {
1540 TRACE0 (" Timed out");
1541 error ("Timed out waiting for property-notify event");
1542 }
1543 }
1544
1545 unbind_to (count, Qnil);
1546 }
1547
1548
1549
1550 void
1551 x_handle_property_notify (const XPropertyEvent *event)
1552 {
1553 struct prop_location *rest;
1554 struct transfer *next;
1555 #ifdef TRACE_SELECTION
1556 char *name;
1557 #endif
1558
1559 for (rest = property_change_wait_list; rest; rest = rest->next)
1560 {
1561 if (!rest->arrived
1562 && rest->property == event->atom
1563 && rest->window == event->window
1564 && rest->display == event->display
1565 && rest->desired_state == event->state)
1566 {
1567 #ifdef TRACE_SELECTION
1568 name = XGetAtomName (event->display, event->atom);
1569
1570 TRACE2 ("Expected %s of property %s",
1571 (event->state == PropertyDelete ? "deletion" : "change"),
1572 name ? name : "unknown");
1573
1574 if (name)
1575 XFree (name);
1576 #endif
1577
1578 rest->arrived = true;
1579
1580
1581
1582 if (rest == property_change_reply_object)
1583 XSETCAR (property_change_reply, Qt);
1584
1585 return;
1586 }
1587 }
1588
1589
1590
1591 next = outstanding_transfers.next;
1592 while (next != &outstanding_transfers)
1593 {
1594 if (next->dpyinfo->display == event->display
1595 && next->requestor == event->window
1596 && next->data.property == event->atom
1597 && event->state == PropertyDelete)
1598 {
1599 TRACE1 ("Expected PropertyDelete event arrived from the"
1600 " requestor window %lx", next->requestor);
1601
1602 x_continue_selection_transfer (next);
1603 return;
1604 }
1605
1606 next = next->next;
1607 }
1608 }
1609
1610 static void
1611 x_display_selection_waiting_message (struct atimer *timer)
1612 {
1613 Lisp_Object val;
1614
1615 val = build_string ("Waiting for reply from selection owner...");
1616 message3_nolog (val);
1617 }
1618
1619 static void
1620 x_cancel_atimer (void *atimer)
1621 {
1622 cancel_atimer (atimer);
1623 }
1624
1625
1626
1627 static Atom reading_which_selection;
1628 static Lisp_Object reading_selection_reply;
1629 static Window reading_selection_window;
1630
1631
1632
1633
1634
1635 static Lisp_Object
1636 x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
1637 Lisp_Object time_stamp, Lisp_Object frame)
1638 {
1639 struct frame *f = XFRAME (frame);
1640 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
1641 Display *display = dpyinfo->display;
1642 Window requestor_window = FRAME_X_WINDOW (f);
1643 Time requestor_time = dpyinfo->last_user_time;
1644 Atom target_property = dpyinfo->Xatom_EMACS_TMP;
1645 Atom selection_atom = symbol_to_x_atom (dpyinfo, selection_symbol);
1646 Atom type_atom = (CONSP (target_type)
1647 ? symbol_to_x_atom (dpyinfo, XCAR (target_type))
1648 : symbol_to_x_atom (dpyinfo, target_type));
1649 struct atimer *delayed_message;
1650 struct timespec message_interval;
1651 specpdl_ref count;
1652
1653 count = SPECPDL_INDEX ();
1654
1655 if (!FRAME_LIVE_P (f))
1656 return unbind_to (count, Qnil);
1657
1658 if (! NILP (time_stamp))
1659 CONS_TO_INTEGER (time_stamp, Time, requestor_time);
1660
1661 block_input ();
1662 TRACE2 ("Get selection %s, type %s",
1663 XGetAtomName (display, type_atom),
1664 XGetAtomName (display, target_property));
1665
1666 x_catch_errors (display);
1667 XConvertSelection (display, selection_atom, type_atom, target_property,
1668 requestor_window, requestor_time);
1669 x_check_errors (display, "Can't convert selection: %s");
1670 x_uncatch_errors_after_check ();
1671
1672
1673 reading_selection_window = requestor_window;
1674 reading_which_selection = selection_atom;
1675 XSETCAR (reading_selection_reply, Qnil);
1676
1677
1678
1679
1680
1681 #if false
1682 x_start_queuing_selection_requests ();
1683 record_unwind_protect_void (x_stop_queuing_selection_requests);
1684 #endif
1685
1686 unblock_input ();
1687
1688 message_interval = make_timespec (1, 0);
1689 delayed_message = start_atimer (ATIMER_RELATIVE, message_interval,
1690 x_display_selection_waiting_message,
1691 NULL);
1692 record_unwind_protect_ptr (x_cancel_atimer, delayed_message);
1693
1694
1695 intmax_t timeout = max (0, x_selection_timeout);
1696 intmax_t secs = timeout / 1000;
1697 int nsecs = (timeout % 1000) * 1000000;
1698 TRACE1 (" Start waiting %"PRIdMAX" secs for SelectionNotify.", secs);
1699
1700 if (input_blocked_p ())
1701 TRACE0 (" Input is blocked.");
1702 else
1703 TRACE1 (" Waiting for %d nsecs in addition.", nsecs);
1704
1705
1706
1707
1708
1709
1710 if (!input_blocked_p ())
1711 wait_reading_process_output (secs, nsecs, 0, false,
1712 reading_selection_reply, NULL, 0);
1713 else
1714 x_wait_for_cell_change (reading_selection_reply,
1715 make_timespec (secs, nsecs));
1716 TRACE1 (" Got event = %s", (!NILP (XCAR (reading_selection_reply))
1717 ? (SYMBOLP (XCAR (reading_selection_reply))
1718 ? SSDATA (SYMBOL_NAME (XCAR (reading_selection_reply)))
1719 : "YES")
1720 : "NO"));
1721
1722 if (NILP (XCAR (reading_selection_reply)))
1723 error ("Timed out waiting for reply from selection owner");
1724 if (EQ (XCAR (reading_selection_reply), Qlambda))
1725 return unbind_to (count, Qnil);
1726
1727
1728 return unbind_to (count,
1729 x_get_window_property_as_lisp_data (dpyinfo,
1730 requestor_window,
1731 target_property,
1732 target_type,
1733 selection_atom,
1734 false));
1735 }
1736
1737
1738
1739
1740
1741 static void
1742 x_get_window_property (Display *display, Window window, Atom property,
1743 unsigned char **data_ret, ptrdiff_t *bytes_ret,
1744 Atom *actual_type_ret, int *actual_format_ret,
1745 unsigned long *actual_size_ret)
1746 {
1747 ptrdiff_t total_size;
1748 unsigned long bytes_remaining;
1749 ptrdiff_t offset = 0;
1750 unsigned char *data = 0;
1751 unsigned char *tmp_data = 0;
1752 int result;
1753 int buffer_size = selection_quantum (display);
1754
1755
1756 ptrdiff_t x_long_size = X_LONG_SIZE;
1757
1758
1759
1760
1761 ptrdiff_t total_size_max
1762 = ((min (PTRDIFF_MAX, SIZE_MAX) - 1) / x_long_size < LONG_MAX
1763 ? min (PTRDIFF_MAX, SIZE_MAX) - 1
1764 : LONG_MAX * x_long_size);
1765
1766 block_input ();
1767
1768
1769 result = XGetWindowProperty (display, window, property,
1770 0, 0, False, AnyPropertyType,
1771 actual_type_ret, actual_format_ret,
1772 actual_size_ret,
1773 &bytes_remaining, &tmp_data);
1774 if (result != Success)
1775 goto done;
1776
1777
1778 XFree (tmp_data);
1779
1780 if (*actual_type_ret == None || *actual_format_ret == 0)
1781 goto done;
1782
1783 if (total_size_max < bytes_remaining)
1784 goto size_overflow;
1785 total_size = bytes_remaining;
1786 data = xmalloc (total_size + 1);
1787
1788
1789 while (bytes_remaining)
1790 {
1791 ptrdiff_t bytes_gotten;
1792 int bytes_per_item;
1793 result
1794 = XGetWindowProperty (display, window, property,
1795 offset / X_LONG_SIZE,
1796 buffer_size / X_LONG_SIZE,
1797 False,
1798 AnyPropertyType,
1799 actual_type_ret, actual_format_ret,
1800 actual_size_ret, &bytes_remaining, &tmp_data);
1801
1802
1803
1804
1805 if (result != Success)
1806 break;
1807
1808 bytes_per_item = *actual_format_ret >> 3;
1809 eassert (*actual_size_ret <= buffer_size / bytes_per_item);
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824 bytes_gotten = *actual_size_ret;
1825 bytes_gotten *= bytes_per_item;
1826
1827 TRACE2 ("Read %"pD"d bytes from property %s",
1828 bytes_gotten, XGetAtomName (display, property));
1829
1830 if (total_size - offset < bytes_gotten)
1831 {
1832 unsigned char *data1;
1833 ptrdiff_t remaining_lim = total_size_max - offset - bytes_gotten;
1834 if (remaining_lim < 0 || remaining_lim < bytes_remaining)
1835 goto size_overflow;
1836 total_size = offset + bytes_gotten + bytes_remaining;
1837 data1 = xrealloc (data, total_size + 1);
1838 data = data1;
1839 }
1840
1841 if (LONG_WIDTH > 32 && *actual_format_ret == 32)
1842 {
1843 unsigned long i;
1844 int *idata = (int *) (data + offset);
1845 long *ldata = (long *) tmp_data;
1846
1847 for (i = 0; i < *actual_size_ret; ++i)
1848 idata[i] = ldata[i];
1849 }
1850 else
1851 memcpy (data + offset, tmp_data, bytes_gotten);
1852
1853 offset += bytes_gotten;
1854
1855
1856 XFree (tmp_data);
1857 }
1858
1859 XFlush (display);
1860 data[offset] = '\0';
1861
1862 done:
1863 unblock_input ();
1864 *data_ret = data;
1865 *bytes_ret = offset;
1866 return;
1867
1868 size_overflow:
1869 if (data)
1870 xfree (data);
1871 unblock_input ();
1872 memory_full (SIZE_MAX);
1873 }
1874
1875
1876
1877 static void
1878 receive_incremental_selection (struct x_display_info *dpyinfo,
1879 Window window, Atom property,
1880 Lisp_Object target_type,
1881 unsigned int min_size_bytes,
1882 unsigned char **data_ret,
1883 ptrdiff_t *size_bytes_ret,
1884 Atom *type_ret, int *format_ret,
1885 unsigned long *size_ret,
1886 ptrdiff_t *real_bytes_ret)
1887 {
1888 ptrdiff_t offset = 0;
1889 struct prop_location *wait_object;
1890 Display *display = dpyinfo->display;
1891
1892 if (min (PTRDIFF_MAX, SIZE_MAX) < min_size_bytes)
1893 memory_full (SIZE_MAX);
1894 *data_ret = xmalloc (min_size_bytes);
1895 *size_bytes_ret = min_size_bytes;
1896
1897 TRACE1 ("Read %u bytes incrementally", min_size_bytes);
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907 block_input ();
1908 XSelectInput (display, window, STANDARD_EVENT_SET | PropertyChangeMask);
1909 TRACE1 (" Delete property %s",
1910 SDATA (SYMBOL_NAME (x_atom_to_symbol (dpyinfo, property))));
1911 XDeleteProperty (display, window, property);
1912 TRACE1 (" Expect new value of property %s",
1913 SDATA (SYMBOL_NAME (x_atom_to_symbol (dpyinfo, property))));
1914 wait_object = expect_property_change (display, window, property,
1915 PropertyNewValue);
1916 XFlush (display);
1917
1918 set_property_change_object (wait_object);
1919 unblock_input ();
1920
1921 while (true)
1922 {
1923 unsigned char *tmp_data;
1924 ptrdiff_t tmp_size_bytes;
1925
1926 TRACE0 (" Wait for property change");
1927 wait_for_property_change (wait_object);
1928
1929
1930
1931
1932 TRACE0 (" Get property value");
1933 x_get_window_property (display, window, property,
1934 &tmp_data, &tmp_size_bytes,
1935 type_ret, format_ret, size_ret);
1936
1937 TRACE1 (" Read increment of %"pD"d bytes", tmp_size_bytes);
1938
1939 if (tmp_size_bytes == 0)
1940 {
1941 TRACE1 ("Done reading incrementally; total bytes: %"pD"d",
1942 *size_bytes_ret);
1943
1944 if (! waiting_for_other_props_on_window (display, window))
1945 XSelectInput (display, window, STANDARD_EVENT_SET);
1946
1947
1948 xfree (tmp_data);
1949 break;
1950 }
1951
1952 block_input ();
1953 TRACE1 (" ACK by deleting property %s",
1954 XGetAtomName (display, property));
1955 XDeleteProperty (display, window, property);
1956 wait_object = expect_property_change (display, window, property,
1957 PropertyNewValue);
1958
1959
1960 set_property_change_object (wait_object);
1961 XFlush (display);
1962 unblock_input ();
1963
1964 if (*size_bytes_ret - offset < tmp_size_bytes)
1965 *data_ret = xpalloc (*data_ret, size_bytes_ret,
1966 tmp_size_bytes - (*size_bytes_ret - offset),
1967 -1, 1);
1968
1969 memcpy ((*data_ret) + offset, tmp_data, tmp_size_bytes);
1970 offset += tmp_size_bytes;
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983 *real_bytes_ret += tmp_size_bytes;
1984
1985
1986
1987 xfree (tmp_data);
1988 }
1989 }
1990
1991
1992
1993
1994
1995
1996 static void
1997 x_free_selection_data (void *data)
1998 {
1999 unsigned char **ptr;
2000
2001 ptr = data;
2002 xfree (*ptr);
2003 }
2004
2005
2006
2007
2008
2009 static Lisp_Object
2010 x_get_window_property_as_lisp_data (struct x_display_info *dpyinfo,
2011 Window window, Atom property,
2012 Lisp_Object target_type,
2013 Atom selection_atom,
2014 bool for_multiple)
2015 {
2016 Atom actual_type;
2017 int actual_format;
2018 unsigned long actual_size;
2019 unsigned char *data = 0;
2020 ptrdiff_t bytes = 0, array_bytes;
2021 Lisp_Object val;
2022 Display *display = dpyinfo->display;
2023 specpdl_ref count;
2024
2025
2026
2027 array_bytes = 0;
2028
2029 TRACE0 ("Reading selection data");
2030
2031 x_get_window_property (display, window, property, &data, &bytes,
2032 &actual_type, &actual_format, &actual_size);
2033 if (! data)
2034 {
2035 if (for_multiple)
2036 return Qnil;
2037 block_input ();
2038 bool there_is_a_selection_owner
2039 = XGetSelectionOwner (display, selection_atom) != 0;
2040 unblock_input ();
2041 if (there_is_a_selection_owner)
2042 {
2043 AUTO_STRING (format, "Selection owner couldn't convert: %s");
2044 CALLN (Fmessage, format,
2045 actual_type
2046 ? list2 (target_type,
2047 x_atom_to_symbol (dpyinfo, actual_type))
2048 : target_type);
2049 return Qnil;
2050 }
2051 else
2052 {
2053 AUTO_STRING (format, "No selection: %s");
2054 CALLN (Fmessage, format, x_atom_to_symbol (dpyinfo, selection_atom));
2055 return Qnil;
2056 }
2057 }
2058
2059
2060
2061
2062
2063 count = SPECPDL_INDEX ();
2064 record_unwind_protect_ptr (x_free_selection_data, &data);
2065
2066 if (!for_multiple && actual_type == dpyinfo->Xatom_INCR)
2067 {
2068
2069
2070 unsigned int min_size_bytes = * ((unsigned int *) data);
2071 block_input ();
2072
2073
2074 xfree (data);
2075
2076
2077 data = NULL;
2078 unblock_input ();
2079
2080
2081
2082
2083 bytes = 0;
2084 receive_incremental_selection (dpyinfo, window, property, target_type,
2085 min_size_bytes, &data, &array_bytes,
2086 &actual_type, &actual_format,
2087 &actual_size, &bytes);
2088 }
2089
2090 if (!for_multiple)
2091 {
2092 block_input ();
2093 TRACE1 (" Delete property %s", XGetAtomName (display, property));
2094 XDeleteProperty (display, window, property);
2095 XFlush (display);
2096 unblock_input ();
2097 }
2098
2099
2100
2101 val = selection_data_to_lisp_data (dpyinfo, data, bytes,
2102 actual_type, actual_format);
2103
2104
2105 return unbind_to (count, val);
2106 }
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131 static Lisp_Object
2132 selection_data_to_lisp_data (struct x_display_info *dpyinfo,
2133 const unsigned char *data,
2134 ptrdiff_t size, Atom type, int format)
2135 {
2136 if (type == dpyinfo->Xatom_NULL)
2137 return QNULL;
2138
2139
2140 else if (format == 8)
2141 {
2142 Lisp_Object str, lispy_type;
2143
2144 str = make_unibyte_string ((char *) data, size);
2145
2146
2147
2148
2149 if (type == dpyinfo->Xatom_COMPOUND_TEXT)
2150 lispy_type = QCOMPOUND_TEXT;
2151 else if (type == dpyinfo->Xatom_UTF8_STRING)
2152 lispy_type = QUTF8_STRING;
2153 else
2154 lispy_type = QSTRING;
2155 Fput_text_property (make_fixnum (0), make_fixnum (size),
2156 Qforeign_selection, lispy_type, str);
2157 return str;
2158 }
2159
2160
2161 else if (type == XA_ATOM
2162
2163 || type == dpyinfo->Xatom_ATOM_PAIR)
2164 {
2165 ptrdiff_t i;
2166
2167
2168
2169
2170 int *idata = (int *) data;
2171
2172 if (size == sizeof (int))
2173 return x_atom_to_symbol (dpyinfo, (Atom) idata[0]);
2174 else
2175 {
2176 Lisp_Object v = make_nil_vector (size / sizeof (int));
2177
2178 for (i = 0; i < size / sizeof (int); i++)
2179 ASET (v, i, x_atom_to_symbol (dpyinfo, (Atom) idata[i]));
2180 return v;
2181 }
2182 }
2183
2184
2185
2186
2187
2188
2189
2190
2191 else if (format == 32 && size == sizeof (int))
2192 {
2193 if (type == XA_INTEGER)
2194 return INT_TO_INTEGER (((int *) data) [0]);
2195 else
2196 return INT_TO_INTEGER (((unsigned int *) data) [0]);
2197 }
2198 else if (format == 16 && size == sizeof (short))
2199 {
2200 if (type == XA_INTEGER)
2201 return make_fixnum (((short *) data) [0]);
2202 else
2203 return make_fixnum (((unsigned short *) data) [0]);
2204 }
2205
2206
2207
2208
2209 else if (format == 16)
2210 {
2211 ptrdiff_t i;
2212 Lisp_Object v = make_uninit_vector (size / 2);
2213
2214 if (type == XA_INTEGER)
2215 {
2216 for (i = 0; i < size / 2; i++)
2217 {
2218 short j = ((short *) data) [i];
2219 ASET (v, i, make_fixnum (j));
2220 }
2221 }
2222 else
2223 {
2224 for (i = 0; i < size / 2; i++)
2225 {
2226 unsigned short j = ((unsigned short *) data) [i];
2227 ASET (v, i, make_fixnum (j));
2228 }
2229 }
2230 return v;
2231 }
2232 else
2233 {
2234 ptrdiff_t i;
2235 Lisp_Object v = make_nil_vector (size / X_LONG_SIZE);
2236
2237 if (type == XA_INTEGER)
2238 {
2239 for (i = 0; i < size / X_LONG_SIZE; i++)
2240 {
2241 int j = ((int *) data) [i];
2242 ASET (v, i, INT_TO_INTEGER (j));
2243 }
2244 }
2245 else
2246 {
2247 for (i = 0; i < size / X_LONG_SIZE; i++)
2248 {
2249 unsigned int j = ((unsigned int *) data) [i];
2250 ASET (v, i, INT_TO_INTEGER (j));
2251 }
2252 }
2253 return v;
2254 }
2255 }
2256
2257
2258
2259
2260
2261
2262
2263 static unsigned long
2264 cons_to_x_long (Lisp_Object obj)
2265 {
2266 if (X_ULONG_MAX <= INTMAX_MAX
2267 || NILP (Fnatnump (CONSP (obj) ? XCAR (obj) : obj)))
2268 return cons_to_signed (obj, X_LONG_MIN, min (X_ULONG_MAX, INTMAX_MAX));
2269 else
2270 return cons_to_unsigned (obj, X_ULONG_MAX);
2271 }
2272
2273
2274
2275 static void
2276 lisp_data_to_selection_data (struct x_display_info *dpyinfo,
2277 Lisp_Object obj, struct selection_data *cs)
2278 {
2279 Lisp_Object type;
2280 char **name_buffer;
2281
2282 USE_SAFE_ALLOCA;
2283
2284 type = Qnil;
2285
2286 eassert (cs != NULL);
2287
2288 if (CONSP (obj) && SYMBOLP (XCAR (obj)))
2289 {
2290 type = XCAR (obj);
2291 obj = XCDR (obj);
2292 if (CONSP (obj) && NILP (XCDR (obj)))
2293 obj = XCAR (obj);
2294 }
2295
2296
2297
2298 if (EQ (obj, QNULL) || (EQ (type, QNULL)))
2299 {
2300 cs->format = 32;
2301 cs->size = 0;
2302 cs->data = NULL;
2303 type = QNULL;
2304 }
2305 else if (STRINGP (obj))
2306 {
2307 if (SCHARS (obj) < SBYTES (obj))
2308
2309 signal_error ("Non-ASCII string must be encoded in advance", obj);
2310
2311 if (NILP (type))
2312 type = QSTRING;
2313
2314 cs->format = 8;
2315 cs->size = -1;
2316 cs->data = NULL;
2317 cs->string = obj;
2318 }
2319 else if (SYMBOLP (obj))
2320 {
2321 void *data = xmalloc (sizeof (Atom) + 1);
2322 Atom *x_atom_ptr = data;
2323 cs->data = data;
2324 cs->format = 32;
2325 cs->size = 1;
2326 cs->data[sizeof (Atom)] = 0;
2327 *x_atom_ptr = symbol_to_x_atom (dpyinfo, obj);
2328 if (NILP (type)) type = QATOM;
2329 }
2330 else if (RANGED_FIXNUMP (X_SHRT_MIN, obj, X_SHRT_MAX))
2331 {
2332 void *data = xmalloc (sizeof (short) + 1);
2333 short *short_ptr = data;
2334 cs->data = data;
2335 cs->format = 16;
2336 cs->size = 1;
2337 cs->data[sizeof (short)] = 0;
2338 *short_ptr = XFIXNUM (obj);
2339 if (NILP (type)) type = QINTEGER;
2340 }
2341 else if (INTEGERP (obj)
2342 || (CONSP (obj) && INTEGERP (XCAR (obj))
2343 && (FIXNUMP (XCDR (obj))
2344 || (CONSP (XCDR (obj))
2345 && FIXNUMP (XCAR (XCDR (obj)))))))
2346 {
2347 void *data = xmalloc (sizeof (unsigned long) + 1);
2348 unsigned long *x_long_ptr = data;
2349 cs->data = data;
2350 cs->format = 32;
2351 cs->size = 1;
2352 cs->data[sizeof (unsigned long)] = 0;
2353 *x_long_ptr = cons_to_x_long (obj);
2354 if (NILP (type)) type = QINTEGER;
2355 }
2356 else if (VECTORP (obj))
2357 {
2358
2359
2360
2361
2362 ptrdiff_t i;
2363 ptrdiff_t size = ASIZE (obj);
2364
2365 if (!size)
2366 {
2367
2368
2369
2370 cs->data = NULL;
2371 cs->format = 32;
2372 cs->size = 0;
2373 type = QINTEGER;
2374 }
2375 else if (SYMBOLP (AREF (obj, 0)))
2376
2377 {
2378 void *data;
2379 Atom *x_atoms;
2380 if (NILP (type)) type = QATOM;
2381 for (i = 0; i < size; i++)
2382 if (!SYMBOLP (AREF (obj, i)))
2383 signal_error ("All elements of selection vector must have same type", obj);
2384
2385 cs->data = data = xnmalloc (size, sizeof *x_atoms);
2386 x_atoms = data;
2387 cs->format = 32;
2388 cs->size = size;
2389
2390 if (size == 1)
2391 x_atoms[0] = symbol_to_x_atom (dpyinfo, AREF (obj, i));
2392 else
2393 {
2394 SAFE_NALLOCA (name_buffer, sizeof *x_atoms, size);
2395
2396 for (i = 0; i < size; i++)
2397 name_buffer[i] = SSDATA (SYMBOL_NAME (AREF (obj, i)));
2398
2399 x_intern_atoms (dpyinfo, name_buffer, size,
2400 x_atoms);
2401 }
2402 }
2403 else
2404
2405 {
2406 int format = 16;
2407 int data_size = sizeof (short);
2408 void *data;
2409 unsigned long *x_atoms;
2410 short *shorts;
2411 if (NILP (type)) type = QINTEGER;
2412 for (i = 0; i < size; i++)
2413 {
2414 if (! RANGED_FIXNUMP (X_SHRT_MIN, AREF (obj, i),
2415 X_SHRT_MAX))
2416 {
2417
2418
2419
2420 data_size = sizeof (long);
2421 format = 32;
2422 break;
2423 }
2424 }
2425 cs->data = data = xnmalloc (size, data_size);
2426 x_atoms = data;
2427 shorts = data;
2428 cs->format = format;
2429 cs->size = size;
2430 for (i = 0; i < size; i++)
2431 {
2432 if (format == 32)
2433 x_atoms[i] = cons_to_x_long (AREF (obj, i));
2434 else
2435 shorts[i] = XFIXNUM (AREF (obj, i));
2436 }
2437 }
2438 }
2439 else
2440 signal_error ( "Unrecognized selection data", obj);
2441
2442 cs->type = symbol_to_x_atom (dpyinfo, type);
2443
2444 SAFE_FREE ();
2445 }
2446
2447 static Lisp_Object
2448 clean_local_selection_data (Lisp_Object obj)
2449 {
2450 if (CONSP (obj)
2451 && INTEGERP (XCAR (obj))
2452 && CONSP (XCDR (obj))
2453 && FIXNUMP (XCAR (XCDR (obj)))
2454 && NILP (XCDR (XCDR (obj))))
2455 obj = Fcons (XCAR (obj), XCDR (obj));
2456
2457 if (CONSP (obj)
2458 && INTEGERP (XCAR (obj))
2459 && FIXNUMP (XCDR (obj)))
2460 {
2461 if (BASE_EQ (XCAR (obj), make_fixnum (0)))
2462 return XCDR (obj);
2463 if (BASE_EQ (XCAR (obj), make_fixnum (-1)))
2464 return make_fixnum (- XFIXNUM (XCDR (obj)));
2465 }
2466 if (VECTORP (obj))
2467 {
2468 ptrdiff_t i;
2469 ptrdiff_t size = ASIZE (obj);
2470 Lisp_Object copy;
2471 if (size == 1)
2472 return clean_local_selection_data (AREF (obj, 0));
2473 copy = make_nil_vector (size);
2474 for (i = 0; i < size; i++)
2475 ASET (copy, i, clean_local_selection_data (AREF (obj, i)));
2476 return copy;
2477 }
2478 return obj;
2479 }
2480
2481
2482
2483
2484
2485
2486 void
2487 x_handle_selection_notify (const XSelectionEvent *event)
2488 {
2489 if (event->requestor != reading_selection_window)
2490 return;
2491 if (event->selection != reading_which_selection)
2492 return;
2493
2494 TRACE1 ("Received SelectionNotify: %d", (int) event->property);
2495 XSETCAR (reading_selection_reply,
2496 (event->property != 0 ? Qt : Qlambda));
2497 }
2498
2499
2500
2501
2502
2503
2504
2505
2506 static struct frame *
2507 frame_for_x_selection (Lisp_Object object)
2508 {
2509 Lisp_Object tail, frame;
2510 struct frame *f;
2511
2512 if (NILP (object))
2513 {
2514 f = XFRAME (selected_frame);
2515 if (FRAME_X_P (f) && FRAME_LIVE_P (f))
2516 return f;
2517
2518 FOR_EACH_FRAME (tail, frame)
2519 {
2520 f = XFRAME (frame);
2521 if (FRAME_X_P (f) && FRAME_LIVE_P (f))
2522 return f;
2523 }
2524 }
2525 else if (TERMINALP (object))
2526 {
2527 struct terminal *t = decode_live_terminal (object);
2528
2529 if (t->type == output_x_window)
2530 FOR_EACH_FRAME (tail, frame)
2531 {
2532 f = XFRAME (frame);
2533 if (FRAME_LIVE_P (f) && f->terminal == t)
2534 return f;
2535 }
2536 }
2537 else if (FRAMEP (object))
2538 {
2539 f = XFRAME (object);
2540 if (FRAME_X_P (f) && FRAME_LIVE_P (f))
2541 return f;
2542 }
2543
2544 return NULL;
2545 }
2546
2547
2548 DEFUN ("x-own-selection-internal", Fx_own_selection_internal,
2549 Sx_own_selection_internal, 2, 3, 0,
2550 doc:
2551
2552
2553
2554
2555
2556
2557
2558
2559 )
2560 (Lisp_Object selection, Lisp_Object value, Lisp_Object frame)
2561 {
2562 if (NILP (frame)) frame = selected_frame;
2563 if (!FRAME_LIVE_P (XFRAME (frame)) || !FRAME_X_P (XFRAME (frame)))
2564 error ("X selection unavailable for this frame");
2565
2566 CHECK_SYMBOL (selection);
2567 if (NILP (value)) error ("VALUE may not be nil");
2568 x_own_selection (selection, value, frame, Qnil, 0);
2569 return value;
2570 }
2571
2572
2573
2574
2575
2576
2577 DEFUN ("x-get-selection-internal", Fx_get_selection_internal,
2578 Sx_get_selection_internal, 2, 4, 0,
2579 doc:
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591 )
2592 (Lisp_Object selection_symbol, Lisp_Object target_type,
2593 Lisp_Object time_stamp, Lisp_Object terminal)
2594 {
2595 Lisp_Object val = Qnil;
2596 Lisp_Object maybe_alias;
2597 struct frame *f = frame_for_x_selection (terminal);
2598
2599 CHECK_SYMBOL (selection_symbol);
2600 CHECK_SYMBOL (target_type);
2601
2602 if (EQ (target_type, QMULTIPLE))
2603 error ("Retrieving MULTIPLE selections is currently unimplemented");
2604 if (!f)
2605 error ("X selection unavailable for this frame");
2606
2607
2608
2609 maybe_alias = Fassq (selection_symbol, Vx_selection_alias_alist);
2610
2611 if (!NILP (maybe_alias))
2612 {
2613 selection_symbol = XCDR (maybe_alias);
2614 CHECK_SYMBOL (selection_symbol);
2615 }
2616
2617 val = x_get_local_selection (selection_symbol, target_type, true,
2618 FRAME_DISPLAY_INFO (f), Qnil, false);
2619
2620 if (NILP (val) && FRAME_LIVE_P (f))
2621 {
2622 Lisp_Object frame;
2623 XSETFRAME (frame, f);
2624 return x_get_foreign_selection (selection_symbol, target_type,
2625 time_stamp, frame);
2626 }
2627
2628 if (CONSP (val) && SYMBOLP (XCAR (val)))
2629 {
2630 val = XCDR (val);
2631 if (CONSP (val) && NILP (XCDR (val)))
2632 val = XCAR (val);
2633 }
2634 return clean_local_selection_data (val);
2635 }
2636
2637 DEFUN ("x-disown-selection-internal", Fx_disown_selection_internal,
2638 Sx_disown_selection_internal, 1, 3, 0,
2639 doc:
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650 )
2651 (Lisp_Object selection, Lisp_Object time_object, Lisp_Object terminal)
2652 {
2653 Time timestamp;
2654 Atom selection_atom;
2655 struct selection_input_event event;
2656 struct frame *f = frame_for_x_selection (terminal);
2657 struct x_display_info *dpyinfo;
2658
2659 if (!f)
2660 return Qnil;
2661
2662 dpyinfo = FRAME_DISPLAY_INFO (f);
2663 CHECK_SYMBOL (selection);
2664
2665
2666 if (NILP (LOCAL_SELECTION (selection, dpyinfo)))
2667 return Qnil;
2668
2669 selection_atom = symbol_to_x_atom (dpyinfo, selection);
2670
2671 block_input ();
2672 if (NILP (time_object))
2673 timestamp = dpyinfo->last_user_time;
2674 else
2675 CONS_TO_INTEGER (time_object, Time, timestamp);
2676 XSetSelectionOwner (dpyinfo->display, selection_atom, None, timestamp);
2677 unblock_input ();
2678
2679
2680
2681
2682
2683
2684 SELECTION_EVENT_DPYINFO (&event) = dpyinfo;
2685 SELECTION_EVENT_SELECTION (&event) = selection_atom;
2686 SELECTION_EVENT_TIME (&event) = timestamp;
2687 x_handle_selection_clear (&event);
2688
2689 return Qt;
2690 }
2691
2692 DEFUN ("x-selection-owner-p", Fx_selection_owner_p, Sx_selection_owner_p,
2693 0, 2, 0,
2694 doc:
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705 )
2706 (Lisp_Object selection, Lisp_Object terminal)
2707 {
2708 struct frame *f = frame_for_x_selection (terminal);
2709
2710 CHECK_SYMBOL (selection);
2711 if (NILP (selection)) selection = QPRIMARY;
2712 if (EQ (selection, Qt)) selection = QSECONDARY;
2713
2714 if (f && !NILP (LOCAL_SELECTION (selection, FRAME_DISPLAY_INFO (f))))
2715 return Qt;
2716 else
2717 return Qnil;
2718 }
2719
2720 DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
2721 0, 2, 0,
2722 doc:
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732 )
2733 (Lisp_Object selection, Lisp_Object terminal)
2734 {
2735 Window owner;
2736 Atom atom;
2737 #ifdef HAVE_XFIXES
2738 Window temp_owner;
2739 #endif
2740 struct frame *f = frame_for_x_selection (terminal);
2741 struct x_display_info *dpyinfo;
2742
2743 CHECK_SYMBOL (selection);
2744
2745 if (NILP (selection))
2746 selection = QPRIMARY;
2747
2748 if (EQ (selection, Qt))
2749 selection = QSECONDARY;
2750
2751 if (!f)
2752 return Qnil;
2753
2754 dpyinfo = FRAME_DISPLAY_INFO (f);
2755
2756 if (!NILP (LOCAL_SELECTION (selection, dpyinfo)))
2757 return Qt;
2758
2759 atom = symbol_to_x_atom (dpyinfo, selection);
2760
2761 if (!atom)
2762 return Qnil;
2763
2764 #ifdef HAVE_XFIXES
2765
2766 temp_owner = x_find_selection_owner (dpyinfo, atom);
2767
2768 if (temp_owner != X_INVALID_WINDOW)
2769 return (temp_owner != None ? Qt : Qnil);
2770 #endif
2771
2772 block_input ();
2773 owner = XGetSelectionOwner (dpyinfo->display, atom);
2774 unblock_input ();
2775
2776 return (owner ? Qt : Qnil);
2777 }
2778
2779 DEFUN ("x-get-local-selection", Fx_get_local_selection, Sx_get_local_selection,
2780 0, 2, 0,
2781 doc:
2782
2783
2784
2785
2786
2787
2788
2789 )
2790 (Lisp_Object value, Lisp_Object target)
2791 {
2792 Time time;
2793 Lisp_Object name, timestamp, frame, result;
2794
2795 CHECK_SYMBOL (target);
2796
2797
2798 Lisp_Object v = value; CHECK_CONS (v);
2799 name = XCAR (v); v = XCDR (v); CHECK_CONS (v);
2800 v = XCDR (v); CHECK_CONS (v);
2801 timestamp = XCAR (v); v = XCDR (v); CHECK_CONS (v);
2802 frame = XCAR (v);
2803
2804 CHECK_SYMBOL (name);
2805 CONS_TO_INTEGER (timestamp, Time, time);
2806 check_window_system (decode_live_frame (frame));
2807
2808 result = x_get_local_selection (name, target, true,
2809 NULL, value, false);
2810
2811 if (CONSP (result) && SYMBOLP (XCAR (result)))
2812 {
2813 result = XCDR (result);
2814
2815 if (CONSP (result) && NILP (XCDR (result)))
2816 result = XCAR (result);
2817 }
2818
2819 return clean_local_selection_data (result);
2820 }
2821
2822
2823
2824
2825
2826 static Lisp_Object
2827 x_clipboard_manager_save (Lisp_Object frame)
2828 {
2829 struct frame *f = XFRAME (frame);
2830 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2831 Atom data = dpyinfo->Xatom_UTF8_STRING;
2832
2833 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2834 dpyinfo->Xatom_EMACS_TMP,
2835 dpyinfo->Xatom_ATOM, 32, PropModeReplace,
2836 (unsigned char *) &data, 1);
2837 x_get_foreign_selection (QCLIPBOARD_MANAGER, QSAVE_TARGETS,
2838 Qnil, frame);
2839 return Qt;
2840 }
2841
2842
2843
2844 static Lisp_Object
2845 x_clipboard_manager_error_1 (Lisp_Object err)
2846 {
2847 AUTO_STRING (format, "X clipboard manager error: %s\n\
2848 If the problem persists, set `%s' to nil.");
2849 AUTO_STRING (varname, "x-select-enable-clipboard-manager");
2850 CALLN (Fmessage, format, CAR (CDR (err)), varname);
2851 return Qnil;
2852 }
2853
2854
2855
2856 static Lisp_Object
2857 x_clipboard_manager_error_2 (Lisp_Object err)
2858 {
2859 fputs (("Error saving to X clipboard manager.\n"
2860 "If the problem persists,"
2861 " set 'x-select-enable-clipboard-manager' to nil.\n"),
2862 stderr);
2863 return Qnil;
2864 }
2865
2866
2867
2868
2869
2870 void
2871 x_clipboard_manager_save_frame (Lisp_Object frame)
2872 {
2873 struct frame *f;
2874
2875 if (!NILP (Vx_select_enable_clipboard_manager)
2876 && FRAMEP (frame)
2877 && (f = XFRAME (frame), FRAME_X_P (f))
2878 && FRAME_LIVE_P (f))
2879 {
2880 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2881 Lisp_Object local_selection
2882 = LOCAL_SELECTION (QCLIPBOARD, dpyinfo);
2883
2884 if (!NILP (local_selection)
2885 && EQ (frame, XCAR (XCDR (XCDR (XCDR (local_selection)))))
2886 && XGetSelectionOwner (dpyinfo->display,
2887 dpyinfo->Xatom_CLIPBOARD_MANAGER))
2888 internal_condition_case_1 (x_clipboard_manager_save, frame, Qt,
2889 x_clipboard_manager_error_1);
2890 }
2891 }
2892
2893
2894
2895
2896
2897 void
2898 x_clipboard_manager_save_all (void)
2899 {
2900
2901 struct x_display_info *dpyinfo;
2902 Lisp_Object local_selection, local_frame;
2903
2904 if (NILP (Vx_select_enable_clipboard_manager))
2905 return;
2906
2907 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
2908 {
2909 local_selection = LOCAL_SELECTION (QCLIPBOARD, dpyinfo);
2910 if (NILP (local_selection)
2911 || !XGetSelectionOwner (dpyinfo->display,
2912 dpyinfo->Xatom_CLIPBOARD_MANAGER))
2913 continue;
2914
2915 local_frame = XCAR (XCDR (XCDR (XCDR (local_selection))));
2916 if (FRAME_LIVE_P (XFRAME (local_frame)))
2917 {
2918 message ("Saving clipboard to X clipboard manager...");
2919 internal_condition_case_1 (x_clipboard_manager_save, local_frame,
2920 Qt, x_clipboard_manager_error_2);
2921 }
2922 }
2923 }
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934 int
2935 x_check_property_data (Lisp_Object data)
2936 {
2937 Lisp_Object iter;
2938 int size = 0;
2939
2940 for (iter = data; CONSP (iter); iter = XCDR (iter))
2941 {
2942 Lisp_Object o = XCAR (iter);
2943
2944 if (! NUMBERP (o) && ! STRINGP (o) && ! CONSP (o))
2945 return -1;
2946 else if (CONSP (o) &&
2947 (! NUMBERP (XCAR (o)) || ! NUMBERP (XCDR (o))))
2948 return -1;
2949 if (size == INT_MAX)
2950 return -1;
2951 size++;
2952 }
2953
2954 return size;
2955 }
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971 void
2972 x_fill_property_data (struct x_display_info *dpyinfo, Lisp_Object data,
2973 void *ret, int nelements_max, int format)
2974 {
2975 unsigned long val;
2976 unsigned long *d32 = (unsigned long *) ret;
2977 unsigned short *d16 = (unsigned short *) ret;
2978 unsigned char *d08 = (unsigned char *) ret;
2979 int nelements;
2980 Lisp_Object iter;
2981
2982 for (iter = data, nelements = 0;
2983 CONSP (iter) && nelements < nelements_max;
2984 iter = XCDR (iter), nelements++)
2985 {
2986 Lisp_Object o = XCAR (iter);
2987
2988 if (NUMBERP (o) || CONSP (o))
2989 {
2990 if (CONSP (o)
2991 && RANGED_FIXNUMP (X_LONG_MIN >> 16, XCAR (o), X_LONG_MAX >> 16)
2992 && RANGED_FIXNUMP (- (1 << 15), XCDR (o), -1))
2993 {
2994
2995
2996
2997
2998 unsigned long v1 = XFIXNUM (XCAR (o)) & 0xffff;
2999 unsigned long v2 = XFIXNUM (XCDR (o)) & 0xffff;
3000 val = (v1 << 16) | v2;
3001 }
3002 else
3003 val = cons_to_x_long (o);
3004 }
3005 else if (STRINGP (o))
3006 {
3007 block_input ();
3008 val = x_intern_cached_atom (dpyinfo, SSDATA (o), false);
3009 unblock_input ();
3010 }
3011 else
3012 error ("Wrong type, must be string, number or cons");
3013
3014 if (format == 8)
3015 {
3016 if ((1 << 8) < val && val <= X_ULONG_MAX - (1 << 7))
3017 error ("Out of `char' range");
3018 *d08++ = val;
3019 }
3020 else if (format == 16)
3021 {
3022 if ((1 << 16) < val && val <= X_ULONG_MAX - (1 << 15))
3023 error ("Out of `short' range");
3024 *d16++ = val;
3025 }
3026 else
3027 *d32++ = val;
3028 }
3029 }
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046 Lisp_Object
3047 x_property_data_to_lisp (struct frame *f, const unsigned char *data,
3048 Atom type, int format, unsigned long size)
3049 {
3050 ptrdiff_t format_bytes = format >> 3;
3051 ptrdiff_t data_bytes;
3052 if (ckd_mul (&data_bytes, size, format_bytes))
3053 memory_full (SIZE_MAX);
3054 return selection_data_to_lisp_data (FRAME_DISPLAY_INFO (f), data,
3055 data_bytes, type, format);
3056 }
3057
3058 DEFUN ("x-get-atom-name", Fx_get_atom_name,
3059 Sx_get_atom_name, 1, 2, 0,
3060 doc:
3061
3062
3063
3064
3065 )
3066 (Lisp_Object value, Lisp_Object frame)
3067 {
3068 struct frame *f = decode_window_system_frame (frame);
3069 Display *dpy = FRAME_X_DISPLAY (f);
3070 struct x_display_info *dpyinfo;
3071 Atom atom;
3072 bool had_errors_p, need_sync;
3073 char *name;
3074 Lisp_Object ret;
3075
3076 dpyinfo = FRAME_DISPLAY_INFO (f);
3077 CONS_TO_INTEGER (value, Atom, atom);
3078
3079 x_catch_errors (dpy);
3080 name = x_get_atom_name (dpyinfo, atom, &need_sync);
3081 had_errors_p = need_sync && x_had_errors_p (dpy);
3082 x_uncatch_errors_after_check ();
3083
3084 ret = empty_unibyte_string;
3085
3086 if (name)
3087 {
3088 if (!had_errors_p)
3089 ret = build_string (name);
3090 xfree (name);
3091 }
3092
3093 return ret;
3094 }
3095
3096 DEFUN ("x-register-dnd-atom", Fx_register_dnd_atom,
3097 Sx_register_dnd_atom, 1, 2, 0,
3098 doc:
3099
3100 )
3101 (Lisp_Object atom, Lisp_Object frame)
3102 {
3103 Atom x_atom;
3104 struct frame *f = decode_window_system_frame (frame);
3105 ptrdiff_t i;
3106 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
3107
3108 if (SYMBOLP (atom))
3109 x_atom = symbol_to_x_atom (dpyinfo, atom);
3110 else if (STRINGP (atom))
3111 {
3112 block_input ();
3113 x_atom = x_intern_cached_atom (dpyinfo, SSDATA (atom),
3114 false);
3115 unblock_input ();
3116 }
3117 else
3118 error ("ATOM must be a symbol or a string");
3119
3120 for (i = 0; i < dpyinfo->x_dnd_atoms_length; ++i)
3121 if (dpyinfo->x_dnd_atoms[i] == x_atom)
3122 return Qnil;
3123
3124 if (dpyinfo->x_dnd_atoms_length == dpyinfo->x_dnd_atoms_size)
3125 dpyinfo->x_dnd_atoms =
3126 xpalloc (dpyinfo->x_dnd_atoms, &dpyinfo->x_dnd_atoms_size,
3127 1, -1, sizeof *dpyinfo->x_dnd_atoms);
3128
3129 dpyinfo->x_dnd_atoms[dpyinfo->x_dnd_atoms_length++] = x_atom;
3130 return Qnil;
3131 }
3132
3133
3134
3135 bool
3136 x_handle_dnd_message (struct frame *f, const XClientMessageEvent *event,
3137 struct x_display_info *dpyinfo, struct input_event *bufp,
3138 bool root_window_coords, int root_x, int root_y)
3139 {
3140 Lisp_Object vec;
3141 Lisp_Object frame;
3142
3143 unsigned long size = 160/event->format;
3144 int x, y;
3145 unsigned char *data = (unsigned char *) event->data.b;
3146 int idata[5];
3147 ptrdiff_t i;
3148
3149 for (i = 0; i < dpyinfo->x_dnd_atoms_length; ++i)
3150 if (dpyinfo->x_dnd_atoms[i] == event->message_type) break;
3151
3152 if (i == dpyinfo->x_dnd_atoms_length) return false;
3153
3154 XSETFRAME (frame, f);
3155
3156
3157
3158
3159
3160
3161 if (LONG_WIDTH > 32 && event->format == 32)
3162 {
3163 for (i = 0; i < 5; ++i)
3164 idata[i] = event->data.l[i];
3165 data = (unsigned char *) idata;
3166 }
3167
3168 vec = make_nil_vector (4);
3169 ASET (vec, 0, SYMBOL_NAME (x_atom_to_symbol (FRAME_DISPLAY_INFO (f),
3170 event->message_type)));
3171 ASET (vec, 1, frame);
3172 ASET (vec, 2, make_fixnum (event->format));
3173 ASET (vec, 3, x_property_data_to_lisp (f,
3174 data,
3175 event->message_type,
3176 event->format,
3177 size));
3178
3179 if (!root_window_coords)
3180 x_relative_mouse_position (f, &x, &y);
3181 else
3182 x_translate_coordinates (f, root_x, root_y, &x, &y);
3183
3184 bufp->kind = DRAG_N_DROP_EVENT;
3185 bufp->frame_or_window = frame;
3186 bufp->timestamp = CurrentTime;
3187 bufp->x = make_fixnum (x);
3188 bufp->y = make_fixnum (y);
3189 bufp->arg = vec;
3190 bufp->modifiers = 0;
3191
3192 return true;
3193 }
3194
3195 DEFUN ("x-send-client-message", Fx_send_client_message,
3196 Sx_send_client_message, 6, 6, 0,
3197 doc:
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223 )
3224 (Lisp_Object display, Lisp_Object dest, Lisp_Object from,
3225 Lisp_Object message_type, Lisp_Object format, Lisp_Object values)
3226 {
3227 struct x_display_info *dpyinfo = check_x_display_info (display);
3228
3229 CHECK_STRING (message_type);
3230 x_send_client_event (display, dest, from,
3231 XInternAtom (dpyinfo->display,
3232 SSDATA (message_type),
3233 False),
3234 format, values);
3235
3236 return Qnil;
3237 }
3238
3239 static void
3240 x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from,
3241 Atom message_type, Lisp_Object format, Lisp_Object values)
3242 {
3243 struct x_display_info *dpyinfo = check_x_display_info (display);
3244 Window wdest;
3245 XEvent event;
3246 struct frame *f = decode_window_system_frame (from);
3247 bool to_root;
3248
3249 CHECK_FIXNUM (format);
3250 CHECK_CONS (values);
3251
3252 if (x_check_property_data (values) == -1)
3253 error ("Bad data in VALUES, must be number, cons or string");
3254
3255 if (XFIXNUM (format) != 8 && XFIXNUM (format) != 16 && XFIXNUM (format) != 32)
3256 error ("FORMAT must be one of 8, 16 or 32");
3257
3258 event.xclient.type = ClientMessage;
3259 event.xclient.format = XFIXNUM (format);
3260
3261 if (FRAMEP (dest) || NILP (dest))
3262 {
3263 struct frame *fdest = decode_window_system_frame (dest);
3264 wdest = FRAME_OUTER_WINDOW (fdest);
3265 }
3266 else if (STRINGP (dest))
3267 {
3268 if (strcmp (SSDATA (dest), "PointerWindow") == 0)
3269 wdest = PointerWindow;
3270 else if (strcmp (SSDATA (dest), "InputFocus") == 0)
3271 wdest = InputFocus;
3272 else
3273 error ("DEST as a string must be one of PointerWindow or InputFocus");
3274 }
3275 else if (NUMBERP (dest) || CONSP (dest))
3276 CONS_TO_INTEGER (dest, Window, wdest);
3277 else
3278 error ("DEST must be a frame, nil, string, number or cons");
3279
3280 if (wdest == 0) wdest = dpyinfo->root_window;
3281 to_root = wdest == dpyinfo->root_window;
3282
3283 block_input ();
3284
3285 event.xclient.send_event = True;
3286 event.xclient.serial = 0;
3287 event.xclient.message_type = message_type;
3288 event.xclient.display = dpyinfo->display;
3289
3290
3291
3292 event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest;
3293
3294 memset (event.xclient.data.l, 0, sizeof (event.xclient.data.l));
3295
3296 x_fill_property_data (dpyinfo, values, event.xclient.data.b,
3297 5 * 32 / event.xclient.format,
3298 event.xclient.format);
3299
3300
3301
3302
3303
3304 x_catch_errors_for_lisp (dpyinfo);
3305 {
3306 bool propagate = !to_root;
3307 long mask = to_root ? 0xffffff : 0;
3308
3309 XSendEvent (dpyinfo->display, wdest, propagate, mask, &event);
3310 XFlush (dpyinfo->display);
3311 }
3312 x_check_errors_for_lisp (dpyinfo, "Failed to send client event: %s");
3313 x_uncatch_errors_for_lisp (dpyinfo);
3314 unblock_input ();
3315 }
3316
3317
3318
3319
3320
3321
3322 Lisp_Object
3323 x_timestamp_for_selection (struct x_display_info *dpyinfo,
3324 Lisp_Object selection)
3325 {
3326 Lisp_Object value, local_value;
3327
3328 local_value = LOCAL_SELECTION (selection, dpyinfo);
3329
3330 if (NILP (local_value))
3331 return Qnil;
3332
3333 value = XCAR (XCDR (XCDR (local_value)));
3334
3335 return value;
3336 }
3337
3338 static void syms_of_xselect_for_pdumper (void);
3339
3340 void
3341 syms_of_xselect (void)
3342 {
3343 defsubr (&Sx_get_selection_internal);
3344 defsubr (&Sx_own_selection_internal);
3345 defsubr (&Sx_disown_selection_internal);
3346 defsubr (&Sx_selection_owner_p);
3347 defsubr (&Sx_selection_exists_p);
3348
3349 defsubr (&Sx_get_atom_name);
3350 defsubr (&Sx_send_client_message);
3351 defsubr (&Sx_register_dnd_atom);
3352 defsubr (&Sx_get_local_selection);
3353
3354 reading_selection_reply = Fcons (Qnil, Qnil);
3355 staticpro (&reading_selection_reply);
3356 staticpro (&property_change_reply);
3357
3358 outstanding_transfers.next = &outstanding_transfers;
3359 outstanding_transfers.last = &outstanding_transfers;
3360
3361 DEFVAR_LISP ("selection-converter-alist", Vselection_converter_alist,
3362 doc:
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381 );
3382 Vselection_converter_alist = Qnil;
3383
3384 DEFVAR_LISP ("x-lost-selection-functions", Vx_lost_selection_functions,
3385 doc:
3386
3387
3388
3389 );
3390 Vx_lost_selection_functions = Qnil;
3391
3392 DEFVAR_LISP ("x-sent-selection-functions", Vx_sent_selection_functions,
3393 doc:
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403 );
3404 Vx_sent_selection_functions = Qnil;
3405
3406 DEFVAR_LISP ("x-select-enable-clipboard-manager",
3407 Vx_select_enable_clipboard_manager,
3408 doc:
3409
3410
3411 );
3412 Vx_select_enable_clipboard_manager = Qt;
3413
3414 DEFVAR_INT ("x-selection-timeout", x_selection_timeout,
3415 doc:
3416
3417
3418 );
3419 x_selection_timeout = 0;
3420
3421 DEFVAR_LISP ("x-treat-local-requests-remotely", Vx_treat_local_requests_remotely,
3422 doc:
3423
3424
3425
3426 );
3427 Vx_treat_local_requests_remotely = Qnil;
3428
3429 DEFVAR_LISP ("x-selection-alias-alist", Vx_selection_alias_alist,
3430 doc:
3431
3432
3433
3434
3435 );
3436 Vx_selection_alias_alist = Qnil;
3437
3438
3439 DEFSYM (QSECONDARY, "SECONDARY");
3440 DEFSYM (QSTRING, "STRING");
3441 DEFSYM (QINTEGER, "INTEGER");
3442 DEFSYM (QCLIPBOARD, "CLIPBOARD");
3443 DEFSYM (QTIMESTAMP, "TIMESTAMP");
3444 DEFSYM (QTEXT, "TEXT");
3445
3446
3447 DEFSYM (QCOMPOUND_TEXT, "COMPOUND_TEXT");
3448 DEFSYM (QUTF8_STRING, "UTF8_STRING");
3449
3450 DEFSYM (QDELETE, "DELETE");
3451 DEFSYM (QMULTIPLE, "MULTIPLE");
3452 DEFSYM (QINCR, "INCR");
3453 DEFSYM (Q_EMACS_TMP_, "_EMACS_TMP_");
3454 DEFSYM (QTARGETS, "TARGETS");
3455 DEFSYM (QATOM, "ATOM");
3456 DEFSYM (QCLIPBOARD_MANAGER, "CLIPBOARD_MANAGER");
3457 DEFSYM (QSAVE_TARGETS, "SAVE_TARGETS");
3458 DEFSYM (QNULL, "NULL");
3459 DEFSYM (QXdndDirectSave0, "XdndDirectSave0");
3460 DEFSYM (QXdndActionDirectSave, "XdndActionDirectSave");
3461 DEFSYM (Qtext_plain, "text/plain");
3462 DEFSYM (Qforeign_selection, "foreign-selection");
3463 DEFSYM (Qx_lost_selection_functions, "x-lost-selection-functions");
3464 DEFSYM (Qx_sent_selection_functions, "x-sent-selection-functions");
3465
3466 DEFSYM (QXmTRANSFER_SUCCESS, "XmTRANSFER_SUCCESS");
3467 DEFSYM (QXmTRANSFER_FAILURE, "XmTRANSFER_FAILURE");
3468
3469 pdumper_do_now_and_after_load (syms_of_xselect_for_pdumper);
3470 }
3471
3472 static void
3473 syms_of_xselect_for_pdumper (void)
3474 {
3475 outstanding_transfers.next = &outstanding_transfers;
3476 outstanding_transfers.last = &outstanding_transfers;
3477
3478 reading_selection_window = 0;
3479 reading_which_selection = 0;
3480 property_change_wait_list = 0;
3481 prop_location_identifier = 0;
3482 property_change_reply = Fcons (Qnil, Qnil);
3483 }
3484
3485 void
3486 mark_xselect (void)
3487 {
3488 struct transfer *next;
3489 struct x_selection_request *frame;
3490 struct selection_data *cs;
3491
3492
3493
3494
3495
3496 next = outstanding_transfers.next;
3497
3498 if (!next)
3499
3500 return;
3501
3502 while (next != &outstanding_transfers)
3503 {
3504 mark_object (next->data.string);
3505 next = next->next;
3506 }
3507
3508 frame = selection_request_stack;
3509 for (; frame; frame = frame->last)
3510 {
3511 for (cs = frame->converted_selections; cs; cs = cs->next)
3512 mark_object (cs->string);
3513 }
3514 }