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