* src/xselect.c (x_convert_selection): Yet another int/Lisp_Object mixup.
[bpt/emacs.git] / src / xselect.c
CommitLineData
2408b3a1 1/* X Selection processing for Emacs.
73b0cd50 2 Copyright (C) 1993-1997, 2000-2011 Free Software Foundation, Inc.
ede4db72
RS
3
4This file is part of GNU Emacs.
5
9ec0b715 6GNU Emacs is free software: you can redistribute it and/or modify
ede4db72 7it under the terms of the GNU General Public License as published by
9ec0b715
GM
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
ede4db72
RS
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
9ec0b715 17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
ede4db72 18
c6c5df7f 19
ede4db72
RS
20/* Rewritten by jwz */
21
18160b98 22#include <config.h>
5b698285 23#include <stdio.h> /* termhooks.h needs this */
d7306fe6 24#include <setjmp.h>
678b3958
KS
25
26#ifdef HAVE_SYS_TYPES_H
27#include <sys/types.h>
28#endif
4004364e 29
678b3958 30#include <unistd.h>
678b3958 31
ede4db72
RS
32#include "lisp.h"
33#include "xterm.h" /* for all of the X includes */
7da64e5c
RS
34#include "dispextern.h" /* frame.h seems to want this */
35#include "frame.h" /* Need this to get the X window of selected_frame */
9ac0d9e0 36#include "blockinput.h"
5faa9b45 37#include "buffer.h"
dfcf069d 38#include "process.h"
1fb3821b 39#include "termhooks.h"
dd0fe424 40#include "keyboard.h"
f3d4e0a4 41#include "character.h"
1fb3821b
JD
42
43#include <X11/Xproto.h>
7da64e5c 44
d9c0d4a3 45struct prop_location;
e067f0c1 46struct selection_data;
d9c0d4a3 47
f57e2426 48static Lisp_Object x_atom_to_symbol (Display *dpy, Atom atom);
a9f737ee
CY
49static Atom symbol_to_x_atom (struct x_display_info *, Lisp_Object);
50static void x_own_selection (Lisp_Object, Lisp_Object, Lisp_Object);
51static Lisp_Object x_get_local_selection (Lisp_Object, Lisp_Object, int,
52 struct x_display_info *);
f57e2426
J
53static void x_decline_selection_request (struct input_event *);
54static Lisp_Object x_selection_request_lisp_error (Lisp_Object);
55static Lisp_Object queue_selection_requests_unwind (Lisp_Object);
f57e2426 56static Lisp_Object x_catch_errors_unwind (Lisp_Object);
e067f0c1
CY
57static void x_reply_selection_request (struct input_event *, struct x_display_info *);
58static int x_convert_selection (struct input_event *, Lisp_Object, Lisp_Object,
a9f737ee 59 Atom, int, struct x_display_info *);
f57e2426
J
60static int waiting_for_other_props_on_window (Display *, Window);
61static struct prop_location *expect_property_change (Display *, Window,
62 Atom, int);
63static void unexpect_property_change (struct prop_location *);
64static Lisp_Object wait_for_property_change_unwind (Lisp_Object);
65static void wait_for_property_change (struct prop_location *);
a9f737ee
CY
66static Lisp_Object x_get_foreign_selection (Lisp_Object, Lisp_Object,
67 Lisp_Object, Lisp_Object);
f57e2426
J
68static void x_get_window_property (Display *, Window, Atom,
69 unsigned char **, int *,
70 Atom *, int *, unsigned long *, int);
71static void receive_incremental_selection (Display *, Window, Atom,
72 Lisp_Object, unsigned,
73 unsigned char **, int *,
74 Atom *, int *, unsigned long *);
75static Lisp_Object x_get_window_property_as_lisp_data (Display *,
76 Window, Atom,
77 Lisp_Object, Atom);
eec47d6b
DN
78static Lisp_Object selection_data_to_lisp_data (Display *,
79 const unsigned char *,
f57e2426
J
80 int, Atom, int);
81static void lisp_data_to_selection_data (Display *, Lisp_Object,
82 unsigned char **, Atom *,
83 unsigned *, int *, int *);
84static Lisp_Object clean_local_selection_data (Lisp_Object);
d9c0d4a3
GM
85
86/* Printing traces to stderr. */
87
88#ifdef TRACE_SELECTION
89#define TRACE0(fmt) \
90 fprintf (stderr, "%d: " fmt "\n", getpid ())
91#define TRACE1(fmt, a0) \
92 fprintf (stderr, "%d: " fmt "\n", getpid (), a0)
93#define TRACE2(fmt, a0, a1) \
94 fprintf (stderr, "%d: " fmt "\n", getpid (), a0, a1)
9c3ad9e1
JD
95#define TRACE3(fmt, a0, a1, a2) \
96 fprintf (stderr, "%d: " fmt "\n", getpid (), a0, a1, a2)
d9c0d4a3
GM
97#else
98#define TRACE0(fmt) (void) 0
99#define TRACE1(fmt, a0) (void) 0
100#define TRACE2(fmt, a0, a1) (void) 0
101#endif
102
103
955cbe7b 104static Lisp_Object QSECONDARY, QSTRING, QINTEGER, QCLIPBOARD, QTIMESTAMP,
ede4db72 105 QTEXT, QDELETE, QMULTIPLE, QINCR, QEMACS_TMP, QTARGETS, QATOM, QNULL,
a9f737ee 106 QATOM_PAIR, QCLIPBOARD_MANAGER, QSAVE_TARGETS;
ede4db72 107
955cbe7b
PE
108static Lisp_Object QCOMPOUND_TEXT; /* This is a type of selection. */
109static Lisp_Object QUTF8_STRING; /* This is a type of selection. */
e6c7c988 110
955cbe7b 111static Lisp_Object Qcompound_text_with_extensions;
fbbe0ace 112
e57ad4d8
KH
113static Lisp_Object Qforeign_selection;
114
ede4db72
RS
115/* If this is a smaller number than the max-request-size of the display,
116 emacs will use INCR selection transfer when the selection is larger
117 than this. The max-request-size is usually around 64k, so if you want
1b65481e 118 emacs to use incremental selection transfers when the selection is
ede4db72 119 smaller than that, set this. I added this mostly for debugging the
8f4f023f 120 incremental transfer stuff, but it might improve server performance. */
ede4db72
RS
121#define MAX_SELECTION_QUANTUM 0xFFFFFF
122
c3498e64 123#define SELECTION_QUANTUM(dpy) ((XMaxRequestSize(dpy) << 2) - 100)
ede4db72 124
a9f737ee
CY
125#define LOCAL_SELECTION(selection_symbol,dpyinfo) \
126 assq_no_quit (selection_symbol, dpyinfo->terminal->Vselection_alist)
dd0fe424
KS
127
128\f
678b3958
KS
129/* Define a queue to save up SELECTION_REQUEST_EVENT events for later
130 handling. */
dd0fe424
KS
131
132struct selection_event_queue
133 {
134 struct input_event event;
135 struct selection_event_queue *next;
136 };
137
138static struct selection_event_queue *selection_queue;
139
678b3958 140/* Nonzero means queue up SELECTION_REQUEST_EVENT events. */
dd0fe424
KS
141
142static int x_queue_selection_requests;
143
678b3958 144/* Queue up an SELECTION_REQUEST_EVENT *EVENT, to be processed later. */
dd0fe424
KS
145
146static void
971de7fb 147x_queue_event (struct input_event *event)
dd0fe424
KS
148{
149 struct selection_event_queue *queue_tmp;
150
678b3958
KS
151 /* Don't queue repeated requests.
152 This only happens for large requests which uses the incremental protocol. */
dd0fe424
KS
153 for (queue_tmp = selection_queue; queue_tmp; queue_tmp = queue_tmp->next)
154 {
72af86bd 155 if (!memcmp (&queue_tmp->event, event, sizeof (*event)))
dd0fe424 156 {
6f04d126 157 TRACE1 ("DECLINE DUP SELECTION EVENT %p", queue_tmp);
678b3958 158 x_decline_selection_request (event);
dd0fe424
KS
159 return;
160 }
161 }
162
163 queue_tmp
164 = (struct selection_event_queue *) xmalloc (sizeof (struct selection_event_queue));
165
166 if (queue_tmp != NULL)
167 {
6f04d126 168 TRACE1 ("QUEUE SELECTION EVENT %p", queue_tmp);
dd0fe424
KS
169 queue_tmp->event = *event;
170 queue_tmp->next = selection_queue;
171 selection_queue = queue_tmp;
172 }
173}
174
678b3958 175/* Start queuing SELECTION_REQUEST_EVENT events. */
dd0fe424
KS
176
177static void
971de7fb 178x_start_queuing_selection_requests (void)
dd0fe424
KS
179{
180 if (x_queue_selection_requests)
181 abort ();
182
183 x_queue_selection_requests++;
184 TRACE1 ("x_start_queuing_selection_requests %d", x_queue_selection_requests);
185}
186
678b3958 187/* Stop queuing SELECTION_REQUEST_EVENT events. */
dd0fe424
KS
188
189static void
971de7fb 190x_stop_queuing_selection_requests (void)
dd0fe424
KS
191{
192 TRACE1 ("x_stop_queuing_selection_requests %d", x_queue_selection_requests);
193 --x_queue_selection_requests;
194
195 /* Take all the queued events and put them back
196 so that they get processed afresh. */
197
198 while (selection_queue != NULL)
199 {
200 struct selection_event_queue *queue_tmp = selection_queue;
6f04d126 201 TRACE1 ("RESTORE SELECTION EVENT %p", queue_tmp);
dd0fe424
KS
202 kbd_buffer_unget_event (&queue_tmp->event);
203 selection_queue = queue_tmp->next;
204 xfree ((char *)queue_tmp);
205 }
206}
207\f
208
1b65481e 209/* This converts a Lisp symbol to a server Atom, avoiding a server
ede4db72
RS
210 roundtrip whenever possible. */
211
212static Atom
a9f737ee 213symbol_to_x_atom (struct x_display_info *dpyinfo, Lisp_Object sym)
ede4db72
RS
214{
215 Atom val;
216 if (NILP (sym)) return 0;
217 if (EQ (sym, QPRIMARY)) return XA_PRIMARY;
218 if (EQ (sym, QSECONDARY)) return XA_SECONDARY;
219 if (EQ (sym, QSTRING)) return XA_STRING;
220 if (EQ (sym, QINTEGER)) return XA_INTEGER;
221 if (EQ (sym, QATOM)) return XA_ATOM;
5c3a351a
RS
222 if (EQ (sym, QCLIPBOARD)) return dpyinfo->Xatom_CLIPBOARD;
223 if (EQ (sym, QTIMESTAMP)) return dpyinfo->Xatom_TIMESTAMP;
224 if (EQ (sym, QTEXT)) return dpyinfo->Xatom_TEXT;
e6c7c988 225 if (EQ (sym, QCOMPOUND_TEXT)) return dpyinfo->Xatom_COMPOUND_TEXT;
5109c8dd 226 if (EQ (sym, QUTF8_STRING)) return dpyinfo->Xatom_UTF8_STRING;
5c3a351a
RS
227 if (EQ (sym, QDELETE)) return dpyinfo->Xatom_DELETE;
228 if (EQ (sym, QMULTIPLE)) return dpyinfo->Xatom_MULTIPLE;
229 if (EQ (sym, QINCR)) return dpyinfo->Xatom_INCR;
230 if (EQ (sym, QEMACS_TMP)) return dpyinfo->Xatom_EMACS_TMP;
231 if (EQ (sym, QTARGETS)) return dpyinfo->Xatom_TARGETS;
232 if (EQ (sym, QNULL)) return dpyinfo->Xatom_NULL;
ede4db72
RS
233 if (!SYMBOLP (sym)) abort ();
234
51b59d79 235 TRACE1 (" XInternAtom %s", SSDATA (SYMBOL_NAME (sym)));
ede4db72 236 BLOCK_INPUT;
a9f737ee 237 val = XInternAtom (dpyinfo->display, SSDATA (SYMBOL_NAME (sym)), False);
ede4db72
RS
238 UNBLOCK_INPUT;
239 return val;
240}
241
242
243/* This converts a server Atom to a Lisp symbol, avoiding server roundtrips
244 and calls to intern whenever possible. */
245
246static Lisp_Object
971de7fb 247x_atom_to_symbol (Display *dpy, Atom atom)
ede4db72 248{
d9c0d4a3 249 struct x_display_info *dpyinfo;
ede4db72
RS
250 char *str;
251 Lisp_Object val;
1b65481e 252
d9c0d4a3
GM
253 if (! atom)
254 return Qnil;
1b65481e 255
7da64e5c
RS
256 switch (atom)
257 {
258 case XA_PRIMARY:
259 return QPRIMARY;
260 case XA_SECONDARY:
261 return QSECONDARY;
262 case XA_STRING:
263 return QSTRING;
264 case XA_INTEGER:
265 return QINTEGER;
266 case XA_ATOM:
267 return QATOM;
7da64e5c
RS
268 }
269
d9c0d4a3 270 dpyinfo = x_display_info_for_display (dpy);
a9f737ee
CY
271 if (dpyinfo == NULL)
272 return Qnil;
5c3a351a 273 if (atom == dpyinfo->Xatom_CLIPBOARD)
7da64e5c 274 return QCLIPBOARD;
5c3a351a 275 if (atom == dpyinfo->Xatom_TIMESTAMP)
7da64e5c 276 return QTIMESTAMP;
5c3a351a 277 if (atom == dpyinfo->Xatom_TEXT)
7da64e5c 278 return QTEXT;
e6c7c988
KH
279 if (atom == dpyinfo->Xatom_COMPOUND_TEXT)
280 return QCOMPOUND_TEXT;
5109c8dd
KH
281 if (atom == dpyinfo->Xatom_UTF8_STRING)
282 return QUTF8_STRING;
5c3a351a 283 if (atom == dpyinfo->Xatom_DELETE)
7da64e5c 284 return QDELETE;
5c3a351a 285 if (atom == dpyinfo->Xatom_MULTIPLE)
7da64e5c 286 return QMULTIPLE;
5c3a351a 287 if (atom == dpyinfo->Xatom_INCR)
7da64e5c 288 return QINCR;
5c3a351a 289 if (atom == dpyinfo->Xatom_EMACS_TMP)
7da64e5c 290 return QEMACS_TMP;
5c3a351a 291 if (atom == dpyinfo->Xatom_TARGETS)
7da64e5c 292 return QTARGETS;
5c3a351a 293 if (atom == dpyinfo->Xatom_NULL)
7da64e5c 294 return QNULL;
ede4db72
RS
295
296 BLOCK_INPUT;
d9c0d4a3 297 str = XGetAtomName (dpy, atom);
ede4db72 298 UNBLOCK_INPUT;
d9c0d4a3 299 TRACE1 ("XGetAtomName --> %s", str);
ede4db72
RS
300 if (! str) return Qnil;
301 val = intern (str);
302 BLOCK_INPUT;
0158abbc 303 /* This was allocated by Xlib, so use XFree. */
ede4db72
RS
304 XFree (str);
305 UNBLOCK_INPUT;
306 return val;
307}
8a89415e 308\f
ede4db72 309/* Do protocol to assert ourself as a selection owner.
a9f737ee 310 FRAME shall be the owner; it must be a valid X frame.
1b65481e 311 Update the Vselection_alist so that we can reply to later requests for
ede4db72
RS
312 our selection. */
313
314static void
a9f737ee
CY
315x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value,
316 Lisp_Object frame)
ede4db72 317{
a9f737ee
CY
318 struct frame *f = XFRAME (frame);
319 Window selecting_window = FRAME_X_WINDOW (f);
320 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
321 Display *display = dpyinfo->display;
aa0daa9f 322 Time timestamp = last_event_timestamp;
a9f737ee 323 Atom selection_atom = symbol_to_x_atom (dpyinfo, selection_name);
ede4db72
RS
324
325 BLOCK_INPUT;
9ba8e10d 326 x_catch_errors (display);
aa0daa9f 327 XSetSelectionOwner (display, selection_atom, selecting_window, timestamp);
a7b24d46 328 x_check_errors (display, "Can't set selection: %s");
4545fa20 329 x_uncatch_errors ();
ede4db72
RS
330 UNBLOCK_INPUT;
331
332 /* Now update the local cache */
333 {
ede4db72
RS
334 Lisp_Object selection_data;
335 Lisp_Object prev_value;
336
16041401 337 selection_data = list4 (selection_name, selection_value,
a9f737ee
CY
338 long_to_cons (timestamp), frame);
339 prev_value = LOCAL_SELECTION (selection_name, dpyinfo);
ede4db72 340
a9f737ee
CY
341 dpyinfo->terminal->Vselection_alist
342 = Fcons (selection_data, dpyinfo->terminal->Vselection_alist);
ede4db72 343
a9f737ee
CY
344 /* If we already owned the selection, remove the old selection
345 data. Don't use Fdelq as that may QUIT. */
ede4db72
RS
346 if (!NILP (prev_value))
347 {
a9f737ee
CY
348 /* We know it's not the CAR, so it's easy. */
349 Lisp_Object rest = dpyinfo->terminal->Vselection_alist;
350 for (; CONSP (rest); rest = XCDR (rest))
8e713be6 351 if (EQ (prev_value, Fcar (XCDR (rest))))
ede4db72 352 {
a9f737ee 353 XSETCDR (rest, XCDR (XCDR (rest)));
ede4db72
RS
354 break;
355 }
356 }
357 }
358}
359\f
360/* Given a selection-name and desired type, look up our local copy of
361 the selection value and convert it to the type.
362 The value is nil or a string.
5109c8dd
KH
363 This function is used both for remote requests (LOCAL_REQUEST is zero)
364 and for local x-get-selection-internal (LOCAL_REQUEST is nonzero).
ede4db72
RS
365
366 This calls random Lisp code, and may signal or gc. */
367
368static Lisp_Object
a9f737ee
CY
369x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
370 int local_request, struct x_display_info *dpyinfo)
ede4db72
RS
371{
372 Lisp_Object local_value;
6abdaa4a 373 Lisp_Object handler_fn, value, check;
ede4db72
RS
374 int count;
375
a9f737ee 376 local_value = LOCAL_SELECTION (selection_symbol, dpyinfo);
ede4db72
RS
377
378 if (NILP (local_value)) return Qnil;
379
a9f737ee 380 /* TIMESTAMP is a special case. */
ede4db72
RS
381 if (EQ (target_type, QTIMESTAMP))
382 {
383 handler_fn = Qnil;
8e713be6 384 value = XCAR (XCDR (XCDR (local_value)));
ede4db72 385 }
ede4db72
RS
386 else
387 {
388 /* Don't allow a quit within the converter.
389 When the user types C-g, he would be surprised
390 if by luck it came during a converter. */
aed13378 391 count = SPECPDL_INDEX ();
ede4db72
RS
392 specbind (Qinhibit_quit, Qt);
393
b7826503 394 CHECK_SYMBOL (target_type);
ede4db72 395 handler_fn = Fcdr (Fassq (target_type, Vselection_converter_alist));
4f06187f
RS
396 /* gcpro is not needed here since nothing but HANDLER_FN
397 is live, and that ought to be a symbol. */
398
1eb4d468
RS
399 if (!NILP (handler_fn))
400 value = call3 (handler_fn,
5109c8dd 401 selection_symbol, (local_request ? Qnil : target_type),
8e713be6 402 XCAR (XCDR (local_value)));
1eb4d468
RS
403 else
404 value = Qnil;
ede4db72
RS
405 unbind_to (count, Qnil);
406 }
407
408 /* Make sure this value is of a type that we could transmit
409 to another X client. */
a87ed99c 410
ede4db72
RS
411 check = value;
412 if (CONSP (value)
8e713be6 413 && SYMBOLP (XCAR (value)))
8e713be6 414 check = XCDR (value);
1b65481e 415
ede4db72
RS
416 if (STRINGP (check)
417 || VECTORP (check)
418 || SYMBOLP (check)
7da64e5c 419 || INTEGERP (check)
ede4db72
RS
420 || NILP (value))
421 return value;
a87ed99c 422 /* Check for a value that cons_to_long could handle. */
ede4db72 423 else if (CONSP (check)
8e713be6
KR
424 && INTEGERP (XCAR (check))
425 && (INTEGERP (XCDR (check))
ede4db72 426 ||
8e713be6
KR
427 (CONSP (XCDR (check))
428 && INTEGERP (XCAR (XCDR (check)))
429 && NILP (XCDR (XCDR (check))))))
ede4db72 430 return value;
4d30ce50
KS
431
432 signal_error ("Invalid data returned by selection-conversion function",
433 list2 (handler_fn, value));
ede4db72
RS
434}
435\f
436/* Subroutines of x_reply_selection_request. */
437
5d0ba25b 438/* Send a SelectionNotify event to the requestor with property=None,
ede4db72
RS
439 meaning we were unable to do what they wanted. */
440
441static void
971de7fb 442x_decline_selection_request (struct input_event *event)
ede4db72 443{
65969f63
CY
444 XEvent reply_base;
445 XSelectionEvent *reply = &(reply_base.xselection);
1b65481e 446
65969f63
CY
447 reply->type = SelectionNotify;
448 reply->display = SELECTION_EVENT_DISPLAY (event);
449 reply->requestor = SELECTION_EVENT_REQUESTOR (event);
450 reply->selection = SELECTION_EVENT_SELECTION (event);
451 reply->time = SELECTION_EVENT_TIME (event);
452 reply->target = SELECTION_EVENT_TARGET (event);
453 reply->property = None;
ede4db72 454
d9c0d4a3
GM
455 /* The reason for the error may be that the receiver has
456 died in the meantime. Handle that case. */
ede4db72 457 BLOCK_INPUT;
65969f63
CY
458 x_catch_errors (reply->display);
459 XSendEvent (reply->display, reply->requestor, False, 0L, &reply_base);
460 XFlush (reply->display);
4545fa20 461 x_uncatch_errors ();
ede4db72
RS
462 UNBLOCK_INPUT;
463}
464
465/* This is the selection request currently being processed.
466 It is set to zero when the request is fully processed. */
467static struct input_event *x_selection_current_request;
468
ca29f2b8
GM
469/* Display info in x_selection_request. */
470
471static struct x_display_info *selection_request_dpyinfo;
472
e067f0c1
CY
473/* Raw selection data, for sending to a requestor window. */
474
475struct selection_data
476{
477 unsigned char *data;
478 unsigned int size;
479 int format;
480 Atom type;
481 int nofree;
482 Atom property;
483 /* This can be set to non-NULL during x_reply_selection_request, if
484 the selection is waiting for an INCR transfer to complete. Don't
485 free these; that's done by unexpect_property_change. */
486 struct prop_location *wait_object;
487 struct selection_data *next;
488};
489
490/* Linked list of the above (in support of MULTIPLE targets). */
491
492struct selection_data *converted_selections;
493
494/* "Data" to send a requestor for a failed MULTIPLE subtarget. */
495Atom conversion_fail_tag;
496
ede4db72 497/* Used as an unwind-protect clause so that, if a selection-converter signals
2a1a4c9d 498 an error, we tell the requester that we were unable to do what they wanted
ede4db72
RS
499 before we throw to top-level or go into the debugger or whatever. */
500
501static Lisp_Object
971de7fb 502x_selection_request_lisp_error (Lisp_Object ignore)
ede4db72 503{
e067f0c1
CY
504 struct selection_data *cs, *next;
505
506 for (cs = converted_selections; cs; cs = next)
507 {
508 next = cs->next;
509 if (cs->nofree == 0 && cs->data)
510 xfree (cs->data);
511 xfree (cs);
512 }
513 converted_selections = NULL;
514
ca29f2b8
GM
515 if (x_selection_current_request != 0
516 && selection_request_dpyinfo->display)
ede4db72
RS
517 x_decline_selection_request (x_selection_current_request);
518 return Qnil;
519}
c525d842
CY
520
521static Lisp_Object
971de7fb 522x_catch_errors_unwind (Lisp_Object dummy)
c525d842
CY
523{
524 BLOCK_INPUT;
525 x_uncatch_errors ();
526 UNBLOCK_INPUT;
6f10509c 527 return Qnil;
c525d842 528}
ede4db72 529\f
d1f21a66
RS
530
531/* This stuff is so that INCR selections are reentrant (that is, so we can
532 be servicing multiple INCR selection requests simultaneously.) I haven't
533 actually tested that yet. */
534
535/* Keep a list of the property changes that are awaited. */
536
537struct prop_location
538{
539 int identifier;
540 Display *display;
541 Window window;
542 Atom property;
543 int desired_state;
544 int arrived;
545 struct prop_location *next;
546};
547
971de7fb
DN
548static struct prop_location *expect_property_change (Display *display, Window window, Atom property, int state);
549static void wait_for_property_change (struct prop_location *location);
550static void unexpect_property_change (struct prop_location *location);
551static int waiting_for_other_props_on_window (Display *display, Window window);
d1f21a66
RS
552
553static int prop_location_identifier;
554
555static Lisp_Object property_change_reply;
556
557static struct prop_location *property_change_reply_object;
558
559static struct prop_location *property_change_wait_list;
55b2d45d
RS
560
561static Lisp_Object
971de7fb 562queue_selection_requests_unwind (Lisp_Object tem)
55b2d45d 563{
dd0fe424 564 x_stop_queuing_selection_requests ();
ab552306 565 return Qnil;
55b2d45d
RS
566}
567
d1f21a66 568\f
e067f0c1 569/* Send the reply to a selection request event EVENT. */
ede4db72 570
46d47e41 571#ifdef TRACE_SELECTION
ca7af97a 572static int x_reply_selection_request_cnt;
46d47e41
GM
573#endif /* TRACE_SELECTION */
574
ede4db72 575static void
e067f0c1 576x_reply_selection_request (struct input_event *event, struct x_display_info *dpyinfo)
ede4db72 577{
65969f63
CY
578 XEvent reply_base;
579 XSelectionEvent *reply = &(reply_base.xselection);
ede4db72 580 Display *display = SELECTION_EVENT_DISPLAY (event);
5d0ba25b 581 Window window = SELECTION_EVENT_REQUESTOR (event);
ede4db72 582 int bytes_remaining;
ede4db72 583 int max_bytes = SELECTION_QUANTUM (display);
9ba8e10d 584 int count = SPECPDL_INDEX ();
e067f0c1 585 struct selection_data *cs;
ede4db72
RS
586
587 if (max_bytes > MAX_SELECTION_QUANTUM)
588 max_bytes = MAX_SELECTION_QUANTUM;
589
65969f63
CY
590 reply->type = SelectionNotify;
591 reply->display = display;
592 reply->requestor = window;
593 reply->selection = SELECTION_EVENT_SELECTION (event);
594 reply->time = SELECTION_EVENT_TIME (event);
595 reply->target = SELECTION_EVENT_TARGET (event);
596 reply->property = SELECTION_EVENT_PROPERTY (event);
597 if (reply->property == None)
598 reply->property = reply->target;
ede4db72 599
afe1529d 600 BLOCK_INPUT;
c525d842
CY
601 /* The protected block contains wait_for_property_change, which can
602 run random lisp code (process handlers) or signal. Therefore, we
603 put the x_uncatch_errors call in an unwind. */
604 record_unwind_protect (x_catch_errors_unwind, Qnil);
9ba8e10d 605 x_catch_errors (display);
ede4db72 606
e067f0c1
CY
607 /* Loop over converted selections, storing them in the requested
608 properties. If data is large, only store the first N bytes
609 (section 2.7.2 of ICCCM). Note that we store the data for a
610 MULTIPLE request in the opposite order; the ICCM says only that
611 the conversion itself must be done in the same order. */
612 for (cs = converted_selections; cs; cs = cs->next)
613 {
a9f737ee
CY
614 if (cs->property == None)
615 continue;
616
617 bytes_remaining = cs->size * (cs->format / 8);
618 if (bytes_remaining <= max_bytes)
e067f0c1 619 {
a9f737ee
CY
620 /* Send all the data at once, with minimal handshaking. */
621 TRACE1 ("Sending all %d bytes", bytes_remaining);
622 XChangeProperty (display, window, cs->property,
623 cs->type, cs->format, PropModeReplace,
624 cs->data, cs->size);
625 }
626 else
627 {
628 /* Send an INCR tag to initiate incremental transfer. */
629 long value[1];
630
631 TRACE2 ("Start sending %d bytes incrementally (%s)",
632 bytes_remaining, XGetAtomName (display, cs->property));
633 cs->wait_object
634 = expect_property_change (display, window, cs->property,
635 PropertyDelete);
636
637 /* XChangeProperty expects an array of long even if long is
638 more than 32 bits. */
639 value[0] = bytes_remaining;
640 XChangeProperty (display, window, cs->property,
641 dpyinfo->Xatom_INCR, 32, PropModeReplace,
642 (unsigned char *) value, 1);
643 XSelectInput (display, window, PropertyChangeMask);
e067f0c1
CY
644 }
645 }
646
647 /* Now issue the SelectionNotify event. */
648 XSendEvent (display, window, False, 0L, &reply_base);
649 XFlush (display);
650
9c3ad9e1
JD
651#ifdef TRACE_SELECTION
652 {
65969f63
CY
653 char *sel = XGetAtomName (display, reply->selection);
654 char *tgt = XGetAtomName (display, reply->target);
e067f0c1
CY
655 TRACE3 ("Sent SelectionNotify: %s, target %s (%d)",
656 sel, tgt, ++x_reply_selection_request_cnt);
9c3ad9e1
JD
657 if (sel) XFree (sel);
658 if (tgt) XFree (tgt);
659 }
660#endif /* TRACE_SELECTION */
661
e067f0c1
CY
662 /* Finish sending the rest of each of the INCR values. This should
663 be improved; there's a chance of deadlock if more than one
664 subtarget in a MULTIPLE selection requires an INCR transfer, and
665 the requestor and Emacs loop waiting on different transfers. */
666 for (cs = converted_selections; cs; cs = cs->next)
667 if (cs->wait_object)
e22cf39c 668 {
e067f0c1
CY
669 int format_bytes = cs->format / 8;
670 int had_errors = x_had_errors_p (display);
671 UNBLOCK_INPUT;
1b65481e 672
e067f0c1 673 bytes_remaining = cs->size * format_bytes;
ede4db72 674
e067f0c1
CY
675 /* Wait for the requester to ack by deleting the property.
676 This can run Lisp code (process handlers) or signal. */
677 if (! had_errors)
678 {
679 TRACE1 ("Waiting for ACK (deletion of %s)",
680 XGetAtomName (display, cs->property));
681 wait_for_property_change (cs->wait_object);
682 }
683 else
684 unexpect_property_change (cs->wait_object);
ede4db72 685
e067f0c1
CY
686 while (bytes_remaining)
687 {
688 int i = ((bytes_remaining < max_bytes)
689 ? bytes_remaining
690 : max_bytes) / format_bytes;
691 BLOCK_INPUT;
692
693 cs->wait_object
694 = expect_property_change (display, window, cs->property,
695 PropertyDelete);
696
697 TRACE1 ("Sending increment of %d elements", i);
698 TRACE1 ("Set %s to increment data",
699 XGetAtomName (display, cs->property));
700
701 /* Append the next chunk of data to the property. */
702 XChangeProperty (display, window, cs->property,
703 cs->type, cs->format, PropModeAppend,
704 cs->data, i);
705 bytes_remaining -= i * format_bytes;
a9f737ee
CY
706 cs->data += i * ((cs->format == 32) ? sizeof (long)
707 : format_bytes);
e067f0c1
CY
708 XFlush (display);
709 had_errors = x_had_errors_p (display);
710 UNBLOCK_INPUT;
ede4db72 711
e067f0c1 712 if (had_errors) break;
afe1529d 713
e067f0c1
CY
714 /* Wait for the requester to ack this chunk by deleting
715 the property. This can run Lisp code or signal. */
716 TRACE1 ("Waiting for increment ACK (deletion of %s)",
717 XGetAtomName (display, cs->property));
718 wait_for_property_change (cs->wait_object);
719 }
1b65481e 720
e067f0c1
CY
721 /* Now write a zero-length chunk to the property to tell the
722 requester that we're done. */
723 BLOCK_INPUT;
724 if (! waiting_for_other_props_on_window (display, window))
725 XSelectInput (display, window, 0L);
726
727 TRACE1 ("Set %s to a 0-length chunk to indicate EOF",
728 XGetAtomName (display, cs->property));
729 XChangeProperty (display, window, cs->property,
730 cs->type, cs->format, PropModeReplace,
731 cs->data, 0);
732 TRACE0 ("Done sending incrementally");
733 }
afe1529d 734
ceabd272 735 /* rms, 2003-01-03: I think I have fixed this bug. */
47a6ac17
GM
736 /* The window we're communicating with may have been deleted
737 in the meantime (that's a real situation from a bug report).
738 In this case, there may be events in the event queue still
739 refering to the deleted window, and we'll get a BadWindow error
740 in XTread_socket when processing the events. I don't have
741 an idea how to fix that. gerd, 2001-01-98. */
844fc085
JD
742 /* 2004-09-10: XSync and UNBLOCK so that possible protocol errors are
743 delivered before uncatch errors. */
744 XSync (display, False);
afe1529d 745 UNBLOCK_INPUT;
0608b1a0
JD
746
747 /* GTK queues events in addition to the queue in Xlib. So we
748 UNBLOCK to enter the event loop and get possible errors delivered,
749 and then BLOCK again because x_uncatch_errors requires it. */
750 BLOCK_INPUT;
c525d842 751 /* This calls x_uncatch_errors. */
9ba8e10d 752 unbind_to (count, Qnil);
afe1529d 753 UNBLOCK_INPUT;
ede4db72
RS
754}
755\f
756/* Handle a SelectionRequest event EVENT.
757 This is called from keyboard.c when such an event is found in the queue. */
758
dd0fe424 759static void
971de7fb 760x_handle_selection_request (struct input_event *event)
ede4db72 761{
e067f0c1 762 struct gcpro gcpro1, gcpro2;
ede4db72 763 Time local_selection_time;
e067f0c1
CY
764
765 Display *display = SELECTION_EVENT_DISPLAY (event);
766 struct x_display_info *dpyinfo = x_display_info_for_display (display);
e067f0c1
CY
767 Atom selection = SELECTION_EVENT_SELECTION (event);
768 Lisp_Object selection_symbol = x_atom_to_symbol (display, selection);
769 Atom target = SELECTION_EVENT_TARGET (event);
770 Lisp_Object target_symbol = x_atom_to_symbol (display, target);
771 Atom property = SELECTION_EVENT_PROPERTY (event);
a9f737ee 772 Lisp_Object local_selection_data;
e067f0c1
CY
773 int success = 0;
774 int count = SPECPDL_INDEX ();
e067f0c1 775 GCPRO2 (local_selection_data, target_symbol);
ede4db72 776
a9f737ee
CY
777 if (!dpyinfo) goto DONE;
778
779 local_selection_data = LOCAL_SELECTION (selection_symbol, dpyinfo);
780
e067f0c1
CY
781 /* Decline if we don't own any selections. */
782 if (NILP (local_selection_data)) goto DONE;
ede4db72 783
e067f0c1
CY
784 /* Decline requests issued prior to our acquiring the selection. */
785 local_selection_time
786 = (Time) cons_to_long (XCAR (XCDR (XCDR (local_selection_data))));
ede4db72 787 if (SELECTION_EVENT_TIME (event) != CurrentTime
7da64e5c 788 && local_selection_time > SELECTION_EVENT_TIME (event))
e067f0c1 789 goto DONE;
ede4db72 790
ede4db72 791 x_selection_current_request = event;
ca29f2b8 792 selection_request_dpyinfo = dpyinfo;
ede4db72
RS
793 record_unwind_protect (x_selection_request_lisp_error, Qnil);
794
e067f0c1
CY
795 /* We might be able to handle nested x_handle_selection_requests,
796 but this is difficult to test, and seems unimportant. */
797 x_start_queuing_selection_requests ();
798 record_unwind_protect (queue_selection_requests_unwind, Qnil);
ede4db72 799
757c9275
CY
800 TRACE2 ("x_handle_selection_request: selection=%s, target=%s",
801 SDATA (SYMBOL_NAME (selection_symbol)),
802 SDATA (SYMBOL_NAME (target_symbol)));
803
ede4db72 804 if (EQ (target_symbol, QMULTIPLE))
e067f0c1
CY
805 {
806 /* For MULTIPLE targets, the event property names a list of atom
807 pairs; the first atom names a target and the second names a
808 non-None property. */
809 Window requestor = SELECTION_EVENT_REQUESTOR (event);
810 Lisp_Object multprop;
811 int j, nselections;
812
813 if (property == None) goto DONE;
a9f737ee
CY
814 multprop
815 = x_get_window_property_as_lisp_data (display, requestor, property,
816 QMULTIPLE, selection);
e067f0c1 817
757c9275 818 if (!VECTORP (multprop) || ASIZE (multprop) % 2)
e067f0c1
CY
819 goto DONE;
820
821 nselections = ASIZE (multprop) / 2;
822 /* Perform conversions. This can signal. */
823 for (j = 0; j < nselections; j++)
824 {
e067f0c1 825 Lisp_Object subtarget = AREF (multprop, 2*j);
a9f737ee 826 Atom subproperty = symbol_to_x_atom (dpyinfo,
e067f0c1
CY
827 AREF (multprop, 2*j+1));
828
829 if (subproperty != None)
830 x_convert_selection (event, selection_symbol, subtarget,
a9f737ee 831 subproperty, 1, dpyinfo);
e067f0c1
CY
832 }
833 success = 1;
834 }
835 else
836 {
837 if (property == None)
838 property = SELECTION_EVENT_TARGET (event);
839 success = x_convert_selection (event, selection_symbol,
a9f737ee
CY
840 target_symbol, property,
841 0, dpyinfo);
e067f0c1 842 }
1b65481e 843
e067f0c1 844 DONE:
1b65481e 845
e067f0c1
CY
846 if (success)
847 x_reply_selection_request (event, dpyinfo);
848 else
849 x_decline_selection_request (event);
850 x_selection_current_request = 0;
1b65481e 851
e067f0c1
CY
852 /* Run the `x-sent-selection-functions' abnormal hook. */
853 if (!NILP (Vx_sent_selection_functions)
854 && !EQ (Vx_sent_selection_functions, Qunbound))
ede4db72 855 {
e067f0c1
CY
856 Lisp_Object args[4];
857 args[0] = Vx_sent_selection_functions;
858 args[1] = selection_symbol;
859 args[2] = target_symbol;
860 args[3] = success ? Qt : Qnil;
861 Frun_hook_with_args (4, args);
862 }
866f8518 863
e067f0c1
CY
864 unbind_to (count, Qnil);
865 UNGCPRO;
866}
1b65481e 867
e067f0c1
CY
868/* Perform the requested selection conversion, and write the data to
869 the converted_selections linked list, where it can be accessed by
870 x_reply_selection_request. If FOR_MULTIPLE is non-zero, write out
871 the data even if conversion fails, using conversion_fail_tag.
ede4db72 872
e067f0c1 873 Return 0 if the selection failed to convert, 1 otherwise. */
ede4db72 874
e067f0c1 875static int
a9f737ee
CY
876x_convert_selection (struct input_event *event, Lisp_Object selection_symbol,
877 Lisp_Object target_symbol, Atom property,
878 int for_multiple, struct x_display_info *dpyinfo)
e067f0c1
CY
879{
880 struct gcpro gcpro1;
881 Lisp_Object lisp_selection;
882 struct selection_data *cs;
883 GCPRO1 (lisp_selection);
866f8518 884
e067f0c1 885 lisp_selection
a9f737ee
CY
886 = x_get_local_selection (selection_symbol, target_symbol,
887 0, dpyinfo);
ede4db72 888
e067f0c1
CY
889 /* A nil return value means we can't perform the conversion. */
890 if (NILP (lisp_selection)
891 || (CONSP (lisp_selection) && NILP (XCDR (lisp_selection))))
892 {
893 if (for_multiple)
894 {
895 cs = xmalloc (sizeof (struct selection_data));
896 cs->data = (unsigned char *) &conversion_fail_tag;
897 cs->size = 1;
898 cs->format = 32;
899 cs->type = XA_ATOM;
900 cs->nofree = 1;
901 cs->property = property;
902 cs->wait_object = NULL;
903 cs->next = converted_selections;
904 converted_selections = cs;
905 }
ede4db72 906
18480f8f
SM
907 UNGCPRO;
908 return 0;
e067f0c1 909 }
4f06187f 910
e067f0c1
CY
911 /* Otherwise, record the converted selection to binary. */
912 cs = xmalloc (sizeof (struct selection_data));
913 cs->nofree = 1;
914 cs->property = property;
915 cs->wait_object = NULL;
916 cs->next = converted_selections;
917 converted_selections = cs;
918 lisp_data_to_selection_data (SELECTION_EVENT_DISPLAY (event),
919 lisp_selection,
920 &(cs->data), &(cs->type),
921 &(cs->size), &(cs->format),
922 &(cs->nofree));
18480f8f
SM
923 UNGCPRO;
924 return 1;
ede4db72
RS
925}
926\f
e18e6130 927/* Handle a SelectionClear event EVENT, which indicates that some
ede4db72
RS
928 client cleared out our previously asserted selection.
929 This is called from keyboard.c when such an event is found in the queue. */
930
dd0fe424 931static void
971de7fb 932x_handle_selection_clear (struct input_event *event)
ede4db72
RS
933{
934 Display *display = SELECTION_EVENT_DISPLAY (event);
935 Atom selection = SELECTION_EVENT_SELECTION (event);
936 Time changed_owner_time = SELECTION_EVENT_TIME (event);
1b65481e 937
ede4db72
RS
938 Lisp_Object selection_symbol, local_selection_data;
939 Time local_selection_time;
5c3a351a 940 struct x_display_info *dpyinfo = x_display_info_for_display (display);
a9f737ee 941 Lisp_Object Vselection_alist;
e18e6130 942
dd0fe424
KS
943 TRACE0 ("x_handle_selection_clear");
944
a9f737ee 945 if (!dpyinfo) return;
16041401 946
d9c0d4a3 947 selection_symbol = x_atom_to_symbol (display, selection);
a9f737ee 948 local_selection_data = LOCAL_SELECTION (selection_symbol, dpyinfo);
ede4db72
RS
949
950 /* Well, we already believe that we don't own it, so that's just fine. */
951 if (NILP (local_selection_data)) return;
952
953 local_selection_time = (Time)
8e713be6 954 cons_to_long (XCAR (XCDR (XCDR (local_selection_data))));
ede4db72 955
a9f737ee
CY
956 /* We have reasserted the selection since this SelectionClear was
957 generated, so we can disregard it. */
ede4db72
RS
958 if (changed_owner_time != CurrentTime
959 && local_selection_time > changed_owner_time)
960 return;
961
a9f737ee
CY
962 /* Otherwise, really clear. Don't use Fdelq as that may QUIT;. */
963 Vselection_alist = dpyinfo->terminal->Vselection_alist;
964 if (EQ (local_selection_data, CAR (Vselection_alist)))
965 Vselection_alist = XCDR (Vselection_alist);
ede4db72
RS
966 else
967 {
968 Lisp_Object rest;
99784d63 969 for (rest = Vselection_alist; CONSP (rest); rest = XCDR (rest))
a9f737ee 970 if (EQ (local_selection_data, CAR (XCDR (rest))))
ede4db72 971 {
a9f737ee 972 XSETCDR (rest, XCDR (XCDR (rest)));
ede4db72
RS
973 break;
974 }
975 }
a9f737ee 976 dpyinfo->terminal->Vselection_alist = Vselection_alist;
ede4db72 977
a9f737ee 978 /* Run the `x-lost-selection-functions' abnormal hook. */
ede4db72 979 {
a9f737ee
CY
980 Lisp_Object args[2];
981 args[0] = Vx_lost_selection_functions;
982 args[1] = selection_symbol;
983 Frun_hook_with_args (2, args);
ede4db72 984 }
a9f737ee
CY
985
986 prepare_menu_bars ();
987 redisplay_preserve_echo_area (20);
ede4db72
RS
988}
989
dd0fe424 990void
971de7fb 991x_handle_selection_event (struct input_event *event)
dd0fe424
KS
992{
993 TRACE0 ("x_handle_selection_event");
e067f0c1 994 if (event->kind != SELECTION_REQUEST_EVENT)
dd0fe424 995 x_handle_selection_clear (event);
e067f0c1
CY
996 else if (x_queue_selection_requests)
997 x_queue_event (event);
998 else
999 x_handle_selection_request (event);
dd0fe424
KS
1000}
1001
1002
118bd841
RS
1003/* Clear all selections that were made from frame F.
1004 We do this when about to delete a frame. */
1005
1006void
971de7fb 1007x_clear_frame_selections (FRAME_PTR f)
118bd841
RS
1008{
1009 Lisp_Object frame;
1010 Lisp_Object rest;
a9f737ee
CY
1011 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1012 struct terminal *t = dpyinfo->terminal;
118bd841 1013
90851bbe 1014 XSETFRAME (frame, f);
118bd841 1015
0d199f9c 1016 /* Delete elements from the beginning of Vselection_alist. */
a9f737ee
CY
1017 while (CONSP (t->Vselection_alist)
1018 && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (t->Vselection_alist)))))))
0d199f9c 1019 {
a9f737ee
CY
1020 /* Run the `x-lost-selection-functions' abnormal hook. */
1021 Lisp_Object args[2];
1022 args[0] = Vx_lost_selection_functions;
1023 args[1] = Fcar (Fcar (t->Vselection_alist));
1024 Frun_hook_with_args (2, args);
0d199f9c 1025
a9f737ee 1026 t->Vselection_alist = XCDR (t->Vselection_alist);
0d199f9c
RS
1027 }
1028
1029 /* Delete elements after the beginning of Vselection_alist. */
a9f737ee
CY
1030 for (rest = t->Vselection_alist; CONSP (rest); rest = XCDR (rest))
1031 if (CONSP (XCDR (rest))
1032 && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (XCDR (rest))))))))
118bd841 1033 {
a9f737ee
CY
1034 Lisp_Object args[2];
1035 args[0] = Vx_lost_selection_functions;
1036 args[1] = XCAR (XCAR (XCDR (rest)));
1037 Frun_hook_with_args (2, args);
1038 XSETCDR (rest, XCDR (XCDR (rest)));
118bd841
RS
1039 break;
1040 }
1041}
ede4db72 1042\f
ede4db72
RS
1043/* Nonzero if any properties for DISPLAY and WINDOW
1044 are on the list of what we are waiting for. */
1045
1046static int
971de7fb 1047waiting_for_other_props_on_window (Display *display, Window window)
ede4db72
RS
1048{
1049 struct prop_location *rest = property_change_wait_list;
1050 while (rest)
1051 if (rest->display == display && rest->window == window)
1052 return 1;
1053 else
1054 rest = rest->next;
1055 return 0;
1056}
1057
1058/* Add an entry to the list of property changes we are waiting for.
1059 DISPLAY, WINDOW, PROPERTY, STATE describe what we will wait for.
1060 The return value is a number that uniquely identifies
1061 this awaited property change. */
1062
d1f21a66 1063static struct prop_location *
971de7fb 1064expect_property_change (Display *display, Window window, Atom property, int state)
ede4db72 1065{
d9c0d4a3 1066 struct prop_location *pl = (struct prop_location *) xmalloc (sizeof *pl);
2f65feb6 1067 pl->identifier = ++prop_location_identifier;
ede4db72
RS
1068 pl->display = display;
1069 pl->window = window;
1070 pl->property = property;
1071 pl->desired_state = state;
1072 pl->next = property_change_wait_list;
d1f21a66 1073 pl->arrived = 0;
ede4db72 1074 property_change_wait_list = pl;
d1f21a66 1075 return pl;
ede4db72
RS
1076}
1077
1078/* Delete an entry from the list of property changes we are waiting for.
2f65feb6 1079 IDENTIFIER is the number that uniquely identifies the entry. */
ede4db72
RS
1080
1081static void
971de7fb 1082unexpect_property_change (struct prop_location *location)
ede4db72
RS
1083{
1084 struct prop_location *prev = 0, *rest = property_change_wait_list;
1085 while (rest)
1086 {
d1f21a66 1087 if (rest == location)
ede4db72
RS
1088 {
1089 if (prev)
1090 prev->next = rest->next;
1091 else
1092 property_change_wait_list = rest->next;
4feb31b2 1093 xfree (rest);
ede4db72
RS
1094 return;
1095 }
1096 prev = rest;
1097 rest = rest->next;
1098 }
1099}
1100
2f65feb6
RS
1101/* Remove the property change expectation element for IDENTIFIER. */
1102
1103static Lisp_Object
971de7fb 1104wait_for_property_change_unwind (Lisp_Object loc)
2f65feb6 1105{
dd0fe424
KS
1106 struct prop_location *location = XSAVE_VALUE (loc)->pointer;
1107
1108 unexpect_property_change (location);
1109 if (location == property_change_reply_object)
1110 property_change_reply_object = 0;
ab552306 1111 return Qnil;
2f65feb6
RS
1112}
1113
ede4db72 1114/* Actually wait for a property change.
2f65feb6 1115 IDENTIFIER should be the value that expect_property_change returned. */
ede4db72
RS
1116
1117static void
971de7fb 1118wait_for_property_change (struct prop_location *location)
ede4db72 1119{
2f65feb6 1120 int secs, usecs;
aed13378 1121 int count = SPECPDL_INDEX ();
d1f21a66 1122
dd0fe424
KS
1123 if (property_change_reply_object)
1124 abort ();
2f65feb6
RS
1125
1126 /* Make sure to do unexpect_property_change if we quit or err. */
dd0fe424
KS
1127 record_unwind_protect (wait_for_property_change_unwind,
1128 make_save_value (location, 0));
2f65feb6 1129
f3fbd155 1130 XSETCAR (property_change_reply, Qnil);
afe1529d 1131 property_change_reply_object = location;
dd0fe424 1132
afe1529d
RS
1133 /* If the event we are waiting for arrives beyond here, it will set
1134 property_change_reply, because property_change_reply_object says so. */
d1f21a66
RS
1135 if (! location->arrived)
1136 {
d1f21a66
RS
1137 secs = x_selection_timeout / 1000;
1138 usecs = (x_selection_timeout % 1000) * 1000;
d9c0d4a3 1139 TRACE2 (" Waiting %d secs, %d usecs", secs, usecs);
d64b707c
KS
1140 wait_reading_process_output (secs, usecs, 0, 0,
1141 property_change_reply, NULL, 0);
d1f21a66 1142
8e713be6 1143 if (NILP (XCAR (property_change_reply)))
d9c0d4a3
GM
1144 {
1145 TRACE0 (" Timed out");
1146 error ("Timed out waiting for property-notify event");
1147 }
d1f21a66 1148 }
2f65feb6
RS
1149
1150 unbind_to (count, Qnil);
ede4db72
RS
1151}
1152
1153/* Called from XTread_socket in response to a PropertyNotify event. */
1154
1155void
971de7fb 1156x_handle_property_notify (XPropertyEvent *event)
ede4db72 1157{
6abdaa4a 1158 struct prop_location *rest;
d9c0d4a3 1159
6abdaa4a 1160 for (rest = property_change_wait_list; rest; rest = rest->next)
ede4db72 1161 {
dd0fe424
KS
1162 if (!rest->arrived
1163 && rest->property == event->atom
ede4db72
RS
1164 && rest->window == event->window
1165 && rest->display == event->display
1166 && rest->desired_state == event->state)
1167 {
d9c0d4a3
GM
1168 TRACE2 ("Expected %s of property %s",
1169 (event->state == PropertyDelete ? "deletion" : "change"),
1170 XGetAtomName (event->display, event->atom));
ede4db72 1171
d1f21a66
RS
1172 rest->arrived = 1;
1173
ede4db72
RS
1174 /* If this is the one wait_for_property_change is waiting for,
1175 tell it to wake up. */
d1f21a66 1176 if (rest == property_change_reply_object)
f3fbd155 1177 XSETCAR (property_change_reply, Qt);
ede4db72 1178
ede4db72
RS
1179 return;
1180 }
ede4db72 1181 }
ede4db72
RS
1182}
1183
1184
1185\f
ede4db72
RS
1186/* Variables for communication with x_handle_selection_notify. */
1187static Atom reading_which_selection;
1188static Lisp_Object reading_selection_reply;
1189static Window reading_selection_window;
1190
1191/* Do protocol to read selection-data from the server.
a9f737ee
CY
1192 Converts this to Lisp data and returns it.
1193 FRAME is the frame whose X window shall request the selection. */
ede4db72
RS
1194
1195static Lisp_Object
a9f737ee
CY
1196x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
1197 Lisp_Object time_stamp, Lisp_Object frame)
ede4db72 1198{
a9f737ee
CY
1199 struct frame *f = XFRAME (frame);
1200 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1201 Display *display = dpyinfo->display;
1202 Window requestor_window = FRAME_X_WINDOW (f);
5d0ba25b 1203 Time requestor_time = last_event_timestamp;
a9f737ee
CY
1204 Atom target_property = dpyinfo->Xatom_EMACS_TMP;
1205 Atom selection_atom = symbol_to_x_atom (dpyinfo, selection_symbol);
1206 Atom type_atom = (CONSP (target_type)
1207 ? symbol_to_x_atom (dpyinfo, XCAR (target_type))
1208 : symbol_to_x_atom (dpyinfo, target_type));
80da0190 1209 int secs, usecs;
c525d842 1210 int count = SPECPDL_INDEX ();
ede4db72 1211
a9f737ee 1212 if (!FRAME_LIVE_P (f))
428a555e
KL
1213 return Qnil;
1214
3a42401d
JD
1215 if (! NILP (time_stamp))
1216 {
1217 if (CONSP (time_stamp))
1218 requestor_time = (Time) cons_to_long (time_stamp);
1219 else if (INTEGERP (time_stamp))
1220 requestor_time = (Time) XUINT (time_stamp);
1221 else if (FLOATP (time_stamp))
ff59904a 1222 requestor_time = (Time) XFLOAT_DATA (time_stamp);
3a42401d
JD
1223 else
1224 error ("TIME_STAMP must be cons or number");
1225 }
1226
ede4db72 1227 BLOCK_INPUT;
1b65481e 1228
c525d842
CY
1229 /* The protected block contains wait_reading_process_output, which
1230 can run random lisp code (process handlers) or signal.
1231 Therefore, we put the x_uncatch_errors call in an unwind. */
1232 record_unwind_protect (x_catch_errors_unwind, Qnil);
9ba8e10d 1233 x_catch_errors (display);
1b65481e 1234
d9c0d4a3
GM
1235 TRACE2 ("Get selection %s, type %s",
1236 XGetAtomName (display, type_atom),
1237 XGetAtomName (display, target_property));
1238
ede4db72 1239 XConvertSelection (display, selection_atom, type_atom, target_property,
5d0ba25b 1240 requestor_window, requestor_time);
5c3a351a 1241 XFlush (display);
ede4db72
RS
1242
1243 /* Prepare to block until the reply has been read. */
5d0ba25b 1244 reading_selection_window = requestor_window;
ede4db72 1245 reading_which_selection = selection_atom;
f3fbd155 1246 XSETCAR (reading_selection_reply, Qnil);
55b2d45d 1247
e067f0c1
CY
1248 /* It should not be necessary to stop handling selection requests
1249 during this time. In fact, the SAVE_TARGETS mechanism requires
1250 us to handle a clipboard manager's requests before it returns
1251 SelectionNotify. */
1252#if 0
a9f737ee
CY
1253 x_start_queuing_selection_requests ();
1254 record_unwind_protect (queue_selection_requests_unwind, Qnil);
e067f0c1
CY
1255#endif
1256
ede4db72
RS
1257 UNBLOCK_INPUT;
1258
80da0190
RS
1259 /* This allows quits. Also, don't wait forever. */
1260 secs = x_selection_timeout / 1000;
1261 usecs = (x_selection_timeout % 1000) * 1000;
d9c0d4a3 1262 TRACE1 (" Start waiting %d secs for SelectionNotify", secs);
d64b707c
KS
1263 wait_reading_process_output (secs, usecs, 0, 0,
1264 reading_selection_reply, NULL, 0);
d9c0d4a3 1265 TRACE1 (" Got event = %d", !NILP (XCAR (reading_selection_reply)));
ede4db72 1266
7c6b2ea4 1267 BLOCK_INPUT;
c525d842
CY
1268 if (x_had_errors_p (display))
1269 error ("Cannot get selection");
1270 /* This calls x_uncatch_errors. */
9ba8e10d 1271 unbind_to (count, Qnil);
7c6b2ea4
RS
1272 UNBLOCK_INPUT;
1273
8e713be6 1274 if (NILP (XCAR (reading_selection_reply)))
606140dd 1275 error ("Timed out waiting for reply from selection owner");
8e713be6 1276 if (EQ (XCAR (reading_selection_reply), Qlambda))
12061f06 1277 return Qnil;
ede4db72
RS
1278
1279 /* Otherwise, the selection is waiting for us on the requested property. */
1280 return
5d0ba25b 1281 x_get_window_property_as_lisp_data (display, requestor_window,
ede4db72
RS
1282 target_property, target_type,
1283 selection_atom);
1284}
1285\f
1286/* Subroutines of x_get_window_property_as_lisp_data */
1287
4feb31b2 1288/* Use xfree, not XFree, to free the data obtained with this function. */
0158abbc 1289
ede4db72 1290static void
d5a3eaaf
AS
1291x_get_window_property (Display *display, Window window, Atom property,
1292 unsigned char **data_ret, int *bytes_ret,
1293 Atom *actual_type_ret, int *actual_format_ret,
1294 unsigned long *actual_size_ret, int delete_p)
ede4db72
RS
1295{
1296 int total_size;
1297 unsigned long bytes_remaining;
1298 int offset = 0;
1299 unsigned char *tmp_data = 0;
1300 int result;
1301 int buffer_size = SELECTION_QUANTUM (display);
1b65481e 1302
d9c0d4a3
GM
1303 if (buffer_size > MAX_SELECTION_QUANTUM)
1304 buffer_size = MAX_SELECTION_QUANTUM;
1b65481e 1305
ede4db72 1306 BLOCK_INPUT;
1b65481e 1307
ede4db72
RS
1308 /* First probe the thing to find out how big it is. */
1309 result = XGetWindowProperty (display, window, property,
137edb72 1310 0L, 0L, False, AnyPropertyType,
ede4db72
RS
1311 actual_type_ret, actual_format_ret,
1312 actual_size_ret,
1313 &bytes_remaining, &tmp_data);
ede4db72
RS
1314 if (result != Success)
1315 {
2f65feb6 1316 UNBLOCK_INPUT;
ede4db72
RS
1317 *data_ret = 0;
1318 *bytes_ret = 0;
1319 return;
1320 }
1b65481e 1321
0158abbc
RS
1322 /* This was allocated by Xlib, so use XFree. */
1323 XFree ((char *) tmp_data);
1b65481e 1324
ede4db72
RS
1325 if (*actual_type_ret == None || *actual_format_ret == 0)
1326 {
2f65feb6 1327 UNBLOCK_INPUT;
ede4db72
RS
1328 return;
1329 }
1330
1331 total_size = bytes_remaining + 1;
1332 *data_ret = (unsigned char *) xmalloc (total_size);
1b65481e 1333
2a1a4c9d 1334 /* Now read, until we've gotten it all. */
ede4db72
RS
1335 while (bytes_remaining)
1336 {
d9c0d4a3 1337#ifdef TRACE_SELECTION
c2982e87 1338 unsigned long last = bytes_remaining;
ede4db72
RS
1339#endif
1340 result
1341 = XGetWindowProperty (display, window, property,
137edb72 1342 (long)offset/4, (long)buffer_size/4,
2f65feb6 1343 False,
ede4db72
RS
1344 AnyPropertyType,
1345 actual_type_ret, actual_format_ret,
1346 actual_size_ret, &bytes_remaining, &tmp_data);
d9c0d4a3 1347
c2982e87 1348 TRACE2 ("Read %lu bytes from property %s",
d9c0d4a3
GM
1349 last - bytes_remaining,
1350 XGetAtomName (display, property));
1351
ede4db72
RS
1352 /* If this doesn't return Success at this point, it means that
1353 some clod deleted the selection while we were in the midst of
d9c0d4a3
GM
1354 reading it. Deal with that, I guess.... */
1355 if (result != Success)
1356 break;
e22cf39c
JD
1357
1358 /* The man page for XGetWindowProperty says:
1359 "If the returned format is 32, the returned data is represented
1360 as a long array and should be cast to that type to obtain the
1361 elements."
1362 This applies even if long is more than 32 bits, the X library
1363 converts from 32 bit elements received from the X server to long
72af86bd 1364 and passes the long array to us. Thus, for that case memcpy can not
e22cf39c
JD
1365 be used. We convert to a 32 bit type here, because so much code
1366 assume on that.
1367
1368 The bytes and offsets passed to XGetWindowProperty refers to the
1369 property and those are indeed in 32 bit quantities if format is 32. */
1370
2172544b 1371 if (32 < BITS_PER_LONG && *actual_format_ret == 32)
e22cf39c
JD
1372 {
1373 unsigned long i;
1374 int *idata = (int *) ((*data_ret) + offset);
1375 long *ldata = (long *) tmp_data;
1376
1377 for (i = 0; i < *actual_size_ret; ++i)
1378 {
1379 idata[i]= (int) ldata[i];
1380 offset += 4;
1381 }
1382 }
1383 else
1384 {
1385 *actual_size_ret *= *actual_format_ret / 8;
72af86bd 1386 memcpy ((*data_ret) + offset, tmp_data, *actual_size_ret);
e22cf39c
JD
1387 offset += *actual_size_ret;
1388 }
1b65481e 1389
0158abbc
RS
1390 /* This was allocated by Xlib, so use XFree. */
1391 XFree ((char *) tmp_data);
ede4db72 1392 }
2f65feb6 1393
5c3a351a 1394 XFlush (display);
ede4db72
RS
1395 UNBLOCK_INPUT;
1396 *bytes_ret = offset;
1397}
1398\f
4feb31b2 1399/* Use xfree, not XFree, to free the data obtained with this function. */
0158abbc 1400
ede4db72 1401static void
d5a3eaaf
AS
1402receive_incremental_selection (Display *display, Window window, Atom property,
1403 Lisp_Object target_type,
1404 unsigned int min_size_bytes,
1405 unsigned char **data_ret, int *size_bytes_ret,
1406 Atom *type_ret, int *format_ret,
1407 unsigned long *size_ret)
ede4db72
RS
1408{
1409 int offset = 0;
d1f21a66 1410 struct prop_location *wait_object;
ede4db72
RS
1411 *size_bytes_ret = min_size_bytes;
1412 *data_ret = (unsigned char *) xmalloc (*size_bytes_ret);
d9c0d4a3
GM
1413
1414 TRACE1 ("Read %d bytes incrementally", min_size_bytes);
2f65feb6
RS
1415
1416 /* At this point, we have read an INCR property.
1417 Delete the property to ack it.
1418 (But first, prepare to receive the next event in this handshake.)
ede4db72
RS
1419
1420 Now, we must loop, waiting for the sending window to put a value on
1421 that property, then reading the property, then deleting it to ack.
1422 We are done when the sender places a property of length 0.
1423 */
2f65feb6
RS
1424 BLOCK_INPUT;
1425 XSelectInput (display, window, STANDARD_EVENT_SET | PropertyChangeMask);
d9c0d4a3 1426 TRACE1 (" Delete property %s",
dd0fe424 1427 SDATA (SYMBOL_NAME (x_atom_to_symbol (display, property))));
2f65feb6 1428 XDeleteProperty (display, window, property);
d9c0d4a3 1429 TRACE1 (" Expect new value of property %s",
dd0fe424 1430 SDATA (SYMBOL_NAME (x_atom_to_symbol (display, property))));
d1f21a66
RS
1431 wait_object = expect_property_change (display, window, property,
1432 PropertyNewValue);
5c3a351a 1433 XFlush (display);
2f65feb6
RS
1434 UNBLOCK_INPUT;
1435
ede4db72
RS
1436 while (1)
1437 {
1438 unsigned char *tmp_data;
1439 int tmp_size_bytes;
d9c0d4a3
GM
1440
1441 TRACE0 (" Wait for property change");
d1f21a66 1442 wait_for_property_change (wait_object);
1b65481e 1443
ede4db72 1444 /* expect it again immediately, because x_get_window_property may
2a1a4c9d 1445 .. no it won't, I don't get it.
d9c0d4a3
GM
1446 .. Ok, I get it now, the Xt code that implements INCR is broken. */
1447 TRACE0 (" Get property value");
ede4db72
RS
1448 x_get_window_property (display, window, property,
1449 &tmp_data, &tmp_size_bytes,
1450 type_ret, format_ret, size_ret, 1);
1451
d9c0d4a3
GM
1452 TRACE1 (" Read increment of %d bytes", tmp_size_bytes);
1453
ede4db72
RS
1454 if (tmp_size_bytes == 0) /* we're done */
1455 {
d9c0d4a3
GM
1456 TRACE0 ("Done reading incrementally");
1457
2f65feb6
RS
1458 if (! waiting_for_other_props_on_window (display, window))
1459 XSelectInput (display, window, STANDARD_EVENT_SET);
4feb31b2 1460 /* Use xfree, not XFree, because x_get_window_property
0158abbc 1461 calls xmalloc itself. */
70fdbb46 1462 xfree (tmp_data);
ede4db72
RS
1463 break;
1464 }
2f65feb6
RS
1465
1466 BLOCK_INPUT;
d9c0d4a3
GM
1467 TRACE1 (" ACK by deleting property %s",
1468 XGetAtomName (display, property));
2f65feb6 1469 XDeleteProperty (display, window, property);
d1f21a66
RS
1470 wait_object = expect_property_change (display, window, property,
1471 PropertyNewValue);
5c3a351a 1472 XFlush (display);
2f65feb6
RS
1473 UNBLOCK_INPUT;
1474
ede4db72
RS
1475 if (*size_bytes_ret < offset + tmp_size_bytes)
1476 {
ede4db72
RS
1477 *size_bytes_ret = offset + tmp_size_bytes;
1478 *data_ret = (unsigned char *) xrealloc (*data_ret, *size_bytes_ret);
1479 }
1b65481e 1480
72af86bd 1481 memcpy ((*data_ret) + offset, tmp_data, tmp_size_bytes);
ede4db72 1482 offset += tmp_size_bytes;
1b65481e 1483
4feb31b2 1484 /* Use xfree, not XFree, because x_get_window_property
0158abbc 1485 calls xmalloc itself. */
4feb31b2 1486 xfree (tmp_data);
ede4db72
RS
1487 }
1488}
d9c0d4a3 1489
ede4db72 1490\f
e067f0c1
CY
1491/* Fetch a value from property PROPERTY of X window WINDOW on display
1492 DISPLAY. TARGET_TYPE and SELECTION_ATOM are used in error message
1493 if this fails. */
ede4db72
RS
1494
1495static Lisp_Object
d5a3eaaf
AS
1496x_get_window_property_as_lisp_data (Display *display, Window window,
1497 Atom property,
1498 Lisp_Object target_type,
1499 Atom selection_atom)
ede4db72
RS
1500{
1501 Atom actual_type;
1502 int actual_format;
1503 unsigned long actual_size;
1504 unsigned char *data = 0;
1505 int bytes = 0;
1506 Lisp_Object val;
5c3a351a 1507 struct x_display_info *dpyinfo = x_display_info_for_display (display);
ede4db72 1508
d9c0d4a3
GM
1509 TRACE0 ("Reading selection data");
1510
ede4db72
RS
1511 x_get_window_property (display, window, property, &data, &bytes,
1512 &actual_type, &actual_format, &actual_size, 1);
1513 if (! data)
1514 {
1515 int there_is_a_selection_owner;
1516 BLOCK_INPUT;
1517 there_is_a_selection_owner
1518 = XGetSelectionOwner (display, selection_atom);
1519 UNBLOCK_INPUT;
4d30ce50
KS
1520 if (there_is_a_selection_owner)
1521 signal_error ("Selection owner couldn't convert",
1522 actual_type
1523 ? list2 (target_type,
1524 x_atom_to_symbol (display, actual_type))
1525 : target_type);
1526 else
1527 signal_error ("No selection",
1528 x_atom_to_symbol (display, selection_atom));
ede4db72 1529 }
1b65481e 1530
5c3a351a 1531 if (actual_type == dpyinfo->Xatom_INCR)
ede4db72
RS
1532 {
1533 /* That wasn't really the data, just the beginning. */
1534
1535 unsigned int min_size_bytes = * ((unsigned int *) data);
1536 BLOCK_INPUT;
4feb31b2 1537 /* Use xfree, not XFree, because x_get_window_property
0158abbc 1538 calls xmalloc itself. */
4feb31b2 1539 xfree ((char *) data);
ede4db72
RS
1540 UNBLOCK_INPUT;
1541 receive_incremental_selection (display, window, property, target_type,
1542 min_size_bytes, &data, &bytes,
1543 &actual_type, &actual_format,
1544 &actual_size);
1545 }
1546
2f65feb6 1547 BLOCK_INPUT;
d9c0d4a3 1548 TRACE1 (" Delete property %s", XGetAtomName (display, property));
2f65feb6 1549 XDeleteProperty (display, window, property);
5c3a351a 1550 XFlush (display);
2f65feb6
RS
1551 UNBLOCK_INPUT;
1552
ede4db72
RS
1553 /* It's been read. Now convert it to a lisp object in some semi-rational
1554 manner. */
1555 val = selection_data_to_lisp_data (display, data, bytes,
1556 actual_type, actual_format);
1b65481e 1557
4feb31b2 1558 /* Use xfree, not XFree, because x_get_window_property
0158abbc 1559 calls xmalloc itself. */
4feb31b2 1560 xfree ((char *) data);
ede4db72
RS
1561 return val;
1562}
1563\f
1564/* These functions convert from the selection data read from the server into
1565 something that we can use from Lisp, and vice versa.
1566
1567 Type: Format: Size: Lisp Type:
1568 ----- ------- ----- -----------
1569 * 8 * String
1570 ATOM 32 1 Symbol
1571 ATOM 32 > 1 Vector of Symbols
1572 * 16 1 Integer
1573 * 16 > 1 Vector of Integers
1574 * 32 1 if <=16 bits: Integer
1575 if > 16 bits: Cons of top16, bot16
1576 * 32 > 1 Vector of the above
1577
1578 When converting a Lisp number to C, it is assumed to be of format 16 if
1579 it is an integer, and of format 32 if it is a cons of two integers.
1580
1581 When converting a vector of numbers from Lisp to C, it is assumed to be
1582 of format 16 if every element in the vector is an integer, and is assumed
1583 to be of format 32 if any element is a cons of two integers.
1584
1585 When converting an object to C, it may be of the form (SYMBOL . <data>)
1586 where SYMBOL is what we should claim that the type is. Format and
b8d6f4af
JD
1587 representation are as above.
1588
1589 Important: When format is 32, data should contain an array of int,
1590 not an array of long as the X library returns. This makes a difference
1591 when sizeof(long) != sizeof(int). */
ede4db72
RS
1592
1593
1594
1595static Lisp_Object
eec47d6b
DN
1596selection_data_to_lisp_data (Display *display, const unsigned char *data,
1597 int size, Atom type, int format)
ede4db72 1598{
5c3a351a 1599 struct x_display_info *dpyinfo = x_display_info_for_display (display);
ede4db72 1600
5c3a351a 1601 if (type == dpyinfo->Xatom_NULL)
ede4db72
RS
1602 return QNULL;
1603
1604 /* Convert any 8-bit data to a string, for compactness. */
1605 else if (format == 8)
e6c7c988 1606 {
e57ad4d8
KH
1607 Lisp_Object str, lispy_type;
1608
1609 str = make_unibyte_string ((char *) data, size);
1610 /* Indicate that this string is from foreign selection by a text
1611 property `foreign-selection' so that the caller of
1612 x-get-selection-internal (usually x-get-selection) can know
1613 that the string must be decode. */
1614 if (type == dpyinfo->Xatom_COMPOUND_TEXT)
1615 lispy_type = QCOMPOUND_TEXT;
1616 else if (type == dpyinfo->Xatom_UTF8_STRING)
1617 lispy_type = QUTF8_STRING;
e6c7c988 1618 else
e57ad4d8
KH
1619 lispy_type = QSTRING;
1620 Fput_text_property (make_number (0), make_number (size),
1621 Qforeign_selection, lispy_type, str);
e6c7c988
KH
1622 return str;
1623 }
ede4db72 1624 /* Convert a single atom to a Lisp_Symbol. Convert a set of atoms to
e067f0c1
CY
1625 a vector of symbols. */
1626 else if (type == XA_ATOM
1627 /* Treat ATOM_PAIR type similar to list of atoms. */
1628 || type == dpyinfo->Xatom_ATOM_PAIR)
ede4db72
RS
1629 {
1630 int i;
b8d6f4af
JD
1631 /* On a 64 bit machine sizeof(Atom) == sizeof(long) == 8.
1632 But the callers of these function has made sure the data for
1633 format == 32 is an array of int. Thus, use int instead
1634 of Atom. */
1635 int *idata = (int *) data;
1636
1637 if (size == sizeof (int))
1638 return x_atom_to_symbol (display, (Atom) idata[0]);
ede4db72
RS
1639 else
1640 {
b8d6f4af 1641 Lisp_Object v = Fmake_vector (make_number (size / sizeof (int)),
e607a484 1642 make_number (0));
b8d6f4af 1643 for (i = 0; i < size / sizeof (int); i++)
e607a484 1644 Faset (v, make_number (i),
b8d6f4af 1645 x_atom_to_symbol (display, (Atom) idata[i]));
ede4db72
RS
1646 return v;
1647 }
1648 }
1649
1ad08acd
RS
1650 /* Convert a single 16-bit number or a small 32-bit number to a Lisp_Int.
1651 If the number is 32 bits and won't fit in a Lisp_Int,
1652 convert it to a cons of integers, 16 bits in each half.
ede4db72 1653 */
2f51feb8
AS
1654 else if (format == 32 && size == sizeof (int))
1655 return long_to_cons (((unsigned int *) data) [0]);
ede4db72
RS
1656 else if (format == 16 && size == sizeof (short))
1657 return make_number ((int) (((unsigned short *) data) [0]));
1658
1659 /* Convert any other kind of data to a vector of numbers, represented
1660 as above (as an integer, or a cons of two 16 bit integers.)
1661 */
1662 else if (format == 16)
1663 {
1664 int i;
937a3875
RS
1665 Lisp_Object v;
1666 v = Fmake_vector (make_number (size / 2), make_number (0));
1667 for (i = 0; i < size / 2; i++)
ede4db72
RS
1668 {
1669 int j = (int) ((unsigned short *) data) [i];
e607a484 1670 Faset (v, make_number (i), make_number (j));
ede4db72
RS
1671 }
1672 return v;
1673 }
1674 else
1675 {
1676 int i;
e607a484 1677 Lisp_Object v = Fmake_vector (make_number (size / 4), make_number (0));
ede4db72
RS
1678 for (i = 0; i < size / 4; i++)
1679 {
2f51feb8 1680 unsigned int j = ((unsigned int *) data) [i];
e607a484 1681 Faset (v, make_number (i), long_to_cons (j));
ede4db72
RS
1682 }
1683 return v;
1684 }
1685}
1686
1687
4feb31b2 1688/* Use xfree, not XFree, to free the data obtained with this function. */
0158abbc 1689
ede4db72 1690static void
d5a3eaaf
AS
1691lisp_data_to_selection_data (Display *display, Lisp_Object obj,
1692 unsigned char **data_ret, Atom *type_ret,
1693 unsigned int *size_ret,
1694 int *format_ret, int *nofree_ret)
ede4db72
RS
1695{
1696 Lisp_Object type = Qnil;
5c3a351a 1697 struct x_display_info *dpyinfo = x_display_info_for_display (display);
aca39f42
RS
1698
1699 *nofree_ret = 0;
1700
8e713be6 1701 if (CONSP (obj) && SYMBOLP (XCAR (obj)))
ede4db72 1702 {
8e713be6
KR
1703 type = XCAR (obj);
1704 obj = XCDR (obj);
1705 if (CONSP (obj) && NILP (XCDR (obj)))
1706 obj = XCAR (obj);
ede4db72
RS
1707 }
1708
1709 if (EQ (obj, QNULL) || (EQ (type, QNULL)))
1710 { /* This is not the same as declining */
1711 *format_ret = 32;
1712 *size_ret = 0;
1713 *data_ret = 0;
1714 type = QNULL;
1715 }
1716 else if (STRINGP (obj))
1717 {
1bd70c6e
KH
1718 if (SCHARS (obj) < SBYTES (obj))
1719 /* OBJ is a multibyte string containing a non-ASCII char. */
4d30ce50 1720 signal_error ("Non-ASCII string must be encoded in advance", obj);
7b9ae523 1721 if (NILP (type))
5109c8dd
KH
1722 type = QSTRING;
1723 *format_ret = 8;
1724 *size_ret = SBYTES (obj);
1725 *data_ret = SDATA (obj);
1726 *nofree_ret = 1;
ede4db72
RS
1727 }
1728 else if (SYMBOLP (obj))
1729 {
1730 *format_ret = 32;
1731 *size_ret = 1;
1732 *data_ret = (unsigned char *) xmalloc (sizeof (Atom) + 1);
1733 (*data_ret) [sizeof (Atom)] = 0;
a9f737ee 1734 (*(Atom **) data_ret) [0] = symbol_to_x_atom (dpyinfo, obj);
ede4db72
RS
1735 if (NILP (type)) type = QATOM;
1736 }
7da64e5c 1737 else if (INTEGERP (obj)
ede4db72
RS
1738 && XINT (obj) < 0xFFFF
1739 && XINT (obj) > -0xFFFF)
1740 {
1741 *format_ret = 16;
1742 *size_ret = 1;
1743 *data_ret = (unsigned char *) xmalloc (sizeof (short) + 1);
1744 (*data_ret) [sizeof (short)] = 0;
1745 (*(short **) data_ret) [0] = (short) XINT (obj);
1746 if (NILP (type)) type = QINTEGER;
1747 }
a87ed99c 1748 else if (INTEGERP (obj)
8e713be6
KR
1749 || (CONSP (obj) && INTEGERP (XCAR (obj))
1750 && (INTEGERP (XCDR (obj))
1751 || (CONSP (XCDR (obj))
1752 && INTEGERP (XCAR (XCDR (obj)))))))
ede4db72
RS
1753 {
1754 *format_ret = 32;
1755 *size_ret = 1;
1756 *data_ret = (unsigned char *) xmalloc (sizeof (long) + 1);
1757 (*data_ret) [sizeof (long)] = 0;
1758 (*(unsigned long **) data_ret) [0] = cons_to_long (obj);
1759 if (NILP (type)) type = QINTEGER;
1760 }
1761 else if (VECTORP (obj))
1762 {
1763 /* Lisp_Vectors may represent a set of ATOMs;
1764 a set of 16 or 32 bit INTEGERs;
1765 or a set of ATOM_PAIRs (represented as [[A1 A2] [A3 A4] ...]
1766 */
1767 int i;
1768
1769 if (SYMBOLP (XVECTOR (obj)->contents [0]))
1770 /* This vector is an ATOM set */
1771 {
1772 if (NILP (type)) type = QATOM;
77b37c05 1773 *size_ret = ASIZE (obj);
ede4db72 1774 *format_ret = 32;
ede4db72 1775 for (i = 0; i < *size_ret; i++)
e067f0c1 1776 if (!SYMBOLP (XVECTOR (obj)->contents [i]))
4d30ce50 1777 signal_error ("All elements of selection vector must have same type", obj);
1b65481e 1778
e067f0c1
CY
1779 *data_ret = (unsigned char *) xmalloc ((*size_ret) * sizeof (Atom));
1780 for (i = 0; i < *size_ret; i++)
1781 (*(Atom **) data_ret) [i]
a9f737ee 1782 = symbol_to_x_atom (dpyinfo, XVECTOR (obj)->contents [i]);
ede4db72 1783 }
ede4db72
RS
1784 else
1785 /* This vector is an INTEGER set, or something like it */
1786 {
e22cf39c 1787 int data_size = 2;
77b37c05 1788 *size_ret = ASIZE (obj);
ede4db72
RS
1789 if (NILP (type)) type = QINTEGER;
1790 *format_ret = 16;
1791 for (i = 0; i < *size_ret; i++)
1792 if (CONSP (XVECTOR (obj)->contents [i]))
1793 *format_ret = 32;
7da64e5c 1794 else if (!INTEGERP (XVECTOR (obj)->contents [i]))
4d30ce50
KS
1795 signal_error (/* Qselection_error */
1796 "Elements of selection vector must be integers or conses of integers",
1797 obj);
ede4db72 1798
e22cf39c
JD
1799 /* Use sizeof(long) even if it is more than 32 bits. See comment
1800 in x_get_window_property and x_fill_property_data. */
6e816df5 1801
e22cf39c
JD
1802 if (*format_ret == 32) data_size = sizeof(long);
1803 *data_ret = (unsigned char *) xmalloc (*size_ret * data_size);
ede4db72
RS
1804 for (i = 0; i < *size_ret; i++)
1805 if (*format_ret == 32)
1806 (*((unsigned long **) data_ret)) [i]
1807 = cons_to_long (XVECTOR (obj)->contents [i]);
1808 else
1809 (*((unsigned short **) data_ret)) [i]
1810 = (unsigned short) cons_to_long (XVECTOR (obj)->contents [i]);
1811 }
1812 }
1813 else
4d30ce50 1814 signal_error (/* Qselection_error */ "Unrecognized selection data", obj);
ede4db72 1815
a9f737ee 1816 *type_ret = symbol_to_x_atom (dpyinfo, type);
ede4db72
RS
1817}
1818
1819static Lisp_Object
971de7fb 1820clean_local_selection_data (Lisp_Object obj)
ede4db72
RS
1821{
1822 if (CONSP (obj)
8e713be6
KR
1823 && INTEGERP (XCAR (obj))
1824 && CONSP (XCDR (obj))
1825 && INTEGERP (XCAR (XCDR (obj)))
1826 && NILP (XCDR (XCDR (obj))))
1827 obj = Fcons (XCAR (obj), XCDR (obj));
ede4db72
RS
1828
1829 if (CONSP (obj)
8e713be6
KR
1830 && INTEGERP (XCAR (obj))
1831 && INTEGERP (XCDR (obj)))
ede4db72 1832 {
8e713be6
KR
1833 if (XINT (XCAR (obj)) == 0)
1834 return XCDR (obj);
1835 if (XINT (XCAR (obj)) == -1)
1836 return make_number (- XINT (XCDR (obj)));
ede4db72
RS
1837 }
1838 if (VECTORP (obj))
1839 {
1840 int i;
77b37c05 1841 int size = ASIZE (obj);
ede4db72
RS
1842 Lisp_Object copy;
1843 if (size == 1)
1844 return clean_local_selection_data (XVECTOR (obj)->contents [0]);
e607a484 1845 copy = Fmake_vector (make_number (size), Qnil);
ede4db72
RS
1846 for (i = 0; i < size; i++)
1847 XVECTOR (copy)->contents [i]
1848 = clean_local_selection_data (XVECTOR (obj)->contents [i]);
1849 return copy;
1850 }
1851 return obj;
1852}
1853\f
1854/* Called from XTread_socket to handle SelectionNotify events.
606140dd
KH
1855 If it's the selection we are waiting for, stop waiting
1856 by setting the car of reading_selection_reply to non-nil.
1857 We store t there if the reply is successful, lambda if not. */
ede4db72
RS
1858
1859void
971de7fb 1860x_handle_selection_notify (XSelectionEvent *event)
ede4db72 1861{
5d0ba25b 1862 if (event->requestor != reading_selection_window)
ede4db72
RS
1863 return;
1864 if (event->selection != reading_which_selection)
1865 return;
1866
d9c0d4a3 1867 TRACE0 ("Received SelectionNotify");
f3fbd155
KR
1868 XSETCAR (reading_selection_reply,
1869 (event->property != 0 ? Qt : Qlambda));
ede4db72
RS
1870}
1871
1872\f
a9f737ee
CY
1873/* From a Lisp_Object, return a suitable frame for selection
1874 operations. OBJECT may be a frame, a terminal object, or nil
1875 (which stands for the selected frame--or, if that is not an X
1876 frame, the first X display on the list). If no suitable frame can
1877 be found, return NULL. */
1878
1879static struct frame *
1880frame_for_x_selection (Lisp_Object object)
1881{
fb1ac845 1882 Lisp_Object tail;
a9f737ee
CY
1883 struct frame *f;
1884
1885 if (NILP (object))
1886 {
1887 f = XFRAME (selected_frame);
1888 if (FRAME_X_P (f) && FRAME_LIVE_P (f))
1889 return f;
1890
1891 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1892 {
1893 f = XFRAME (XCAR (tail));
1894 if (FRAME_X_P (f) && FRAME_LIVE_P (f))
1895 return f;
1896 }
1897 }
1898 else if (TERMINALP (object))
1899 {
1900 struct terminal *t = get_terminal (object, 1);
1901 if (t->type == output_x_window)
1902 {
1903 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1904 {
1905 f = XFRAME (XCAR (tail));
1906 if (FRAME_LIVE_P (f) && f->terminal == t)
1907 return f;
1908 }
1909 }
1910 }
1911 else if (FRAMEP (object))
1912 {
1913 f = XFRAME (object);
1914 if (FRAME_X_P (f) && FRAME_LIVE_P (f))
1915 return f;
1916 }
1917
1918 return NULL;
1919}
1920
1921
a0d76c27 1922DEFUN ("x-own-selection-internal", Fx_own_selection_internal,
a9f737ee 1923 Sx_own_selection_internal, 2, 3, 0,
abb71cf4
CY
1924 doc: /* Assert an X selection of type SELECTION and value VALUE.
1925SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
8c1a1077
PJ
1926\(Those are literal upper-case symbol names, since that's what X expects.)
1927VALUE is typically a string, or a cons of two markers, but may be
a9f737ee
CY
1928anything that the functions on `selection-converter-alist' know about.
1929
1930FRAME should be a frame that should own the selection. If omitted or
1931nil, it defaults to the selected frame. */)
1932 (Lisp_Object selection, Lisp_Object value, Lisp_Object frame)
ede4db72 1933{
a9f737ee
CY
1934 if (NILP (frame)) frame = selected_frame;
1935 if (!FRAME_LIVE_P (XFRAME (frame)) || !FRAME_X_P (XFRAME (frame)))
1936 error ("X selection unavailable for this frame");
1937
abb71cf4
CY
1938 CHECK_SYMBOL (selection);
1939 if (NILP (value)) error ("VALUE may not be nil");
a9f737ee 1940 x_own_selection (selection, value, frame);
abb71cf4 1941 return value;
ede4db72
RS
1942}
1943
1944
1945/* Request the selection value from the owner. If we are the owner,
1946 simply return our selection value. If we are not the owner, this
1947 will block until all of the data has arrived. */
1948
a0d76c27 1949DEFUN ("x-get-selection-internal", Fx_get_selection_internal,
a9f737ee 1950 Sx_get_selection_internal, 2, 4, 0,
8c1a1077
PJ
1951 doc: /* Return text selected from some X window.
1952SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
1953\(Those are literal upper-case symbol names, since that's what X expects.)
3a42401d
JD
1954TYPE is the type of data desired, typically `STRING'.
1955TIME_STAMP is the time to use in the XConvertSelection call for foreign
a9f737ee
CY
1956selections. If omitted, defaults to the time for the last event.
1957
1958TERMINAL should be a terminal object or a frame specifying the X
1959server to query. If omitted or nil, that stands for the selected
1960frame's display, or the first available X display. */)
1961 (Lisp_Object selection_symbol, Lisp_Object target_type,
1962 Lisp_Object time_stamp, Lisp_Object terminal)
ede4db72
RS
1963{
1964 Lisp_Object val = Qnil;
1965 struct gcpro gcpro1, gcpro2;
a9f737ee 1966 struct frame *f = frame_for_x_selection (terminal);
ede4db72 1967 GCPRO2 (target_type, val); /* we store newly consed data into these */
a9f737ee 1968
b7826503 1969 CHECK_SYMBOL (selection_symbol);
a9f737ee
CY
1970 CHECK_SYMBOL (target_type);
1971 if (EQ (target_type, QMULTIPLE))
1972 error ("Retrieving MULTIPLE selections is currently unimplemented");
1973 if (!f)
1974 error ("X selection unavailable for this frame");
1975
1976 val = x_get_local_selection (selection_symbol, target_type, 1,
1977 FRAME_X_DISPLAY_INFO (f));
ede4db72 1978
a9f737ee 1979 if (NILP (val) && FRAME_LIVE_P (f))
ede4db72 1980 {
a9f737ee
CY
1981 Lisp_Object frame;
1982 XSETFRAME (frame, f);
1983 RETURN_UNGCPRO (x_get_foreign_selection (selection_symbol, target_type,
1984 time_stamp, frame));
ede4db72 1985 }
ede4db72 1986
abb71cf4 1987 if (CONSP (val) && SYMBOLP (XCAR (val)))
ede4db72 1988 {
8e713be6
KR
1989 val = XCDR (val);
1990 if (CONSP (val) && NILP (XCDR (val)))
1991 val = XCAR (val);
ede4db72 1992 }
abb71cf4 1993 RETURN_UNGCPRO (clean_local_selection_data (val));
ede4db72
RS
1994}
1995
a0d76c27 1996DEFUN ("x-disown-selection-internal", Fx_disown_selection_internal,
a9f737ee 1997 Sx_disown_selection_internal, 1, 3, 0,
8c1a1077 1998 doc: /* If we own the selection SELECTION, disown it.
a9f737ee
CY
1999Disowning it means there is no such selection.
2000
2001TERMINAL should be a terminal object or a frame specifying the X
2002server to query. If omitted or nil, that stands for the selected
2003frame's display, or the first available X display. */)
2004 (Lisp_Object selection, Lisp_Object time_object, Lisp_Object terminal)
ede4db72 2005{
ede4db72
RS
2006 Time timestamp;
2007 Atom selection_atom;
31df61d6
AS
2008 union {
2009 struct selection_input_event sie;
2010 struct input_event ie;
2011 } event;
a9f737ee 2012 struct frame *f = frame_for_x_selection (terminal);
5c3a351a 2013 struct x_display_info *dpyinfo;
ede4db72 2014
a9f737ee 2015 if (!f)
428a555e
KL
2016 return Qnil;
2017
a9f737ee 2018 dpyinfo = FRAME_X_DISPLAY_INFO (f);
b7826503 2019 CHECK_SYMBOL (selection);
ede4db72 2020
a9f737ee
CY
2021 /* Don't disown the selection when we're not the owner. */
2022 if (NILP (LOCAL_SELECTION (selection, dpyinfo)))
2023 return Qnil;
ede4db72 2024
a9f737ee 2025 selection_atom = symbol_to_x_atom (dpyinfo, selection);
ede4db72
RS
2026
2027 BLOCK_INPUT;
a9f737ee
CY
2028 timestamp = (NILP (time_object) ? last_event_timestamp
2029 : cons_to_long (time_object));
2030 XSetSelectionOwner (dpyinfo->display, selection_atom, None, timestamp);
ede4db72
RS
2031 UNBLOCK_INPUT;
2032
eb8c3be9 2033 /* It doesn't seem to be guaranteed that a SelectionClear event will be
ede4db72
RS
2034 generated for a window which owns the selection when that window sets
2035 the selection owner to None. The NCD server does, the MIT Sun4 server
2036 doesn't. So we synthesize one; this means we might get two, but
2037 that's ok, because the second one won't have any effect. */
a9f737ee 2038 SELECTION_EVENT_DISPLAY (&event.sie) = dpyinfo->display;
31df61d6
AS
2039 SELECTION_EVENT_SELECTION (&event.sie) = selection_atom;
2040 SELECTION_EVENT_TIME (&event.sie) = timestamp;
2041 x_handle_selection_clear (&event.ie);
ede4db72
RS
2042
2043 return Qt;
2044}
2045
ede4db72 2046DEFUN ("x-selection-owner-p", Fx_selection_owner_p, Sx_selection_owner_p,
a9f737ee 2047 0, 2, 0,
8c1a1077
PJ
2048 doc: /* Whether the current Emacs process owns the given X Selection.
2049The arg should be the name of the selection in question, typically one of
2050the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
2051\(Those are literal upper-case symbol names, since that's what X expects.)
2052For convenience, the symbol nil is the same as `PRIMARY',
a9f737ee
CY
2053and t is the same as `SECONDARY'.
2054
2055TERMINAL should be a terminal object or a frame specifying the X
2056server to query. If omitted or nil, that stands for the selected
2057frame's display, or the first available X display. */)
2058 (Lisp_Object selection, Lisp_Object terminal)
ede4db72 2059{
a9f737ee
CY
2060 struct frame *f = frame_for_x_selection (terminal);
2061
b7826503 2062 CHECK_SYMBOL (selection);
ede4db72
RS
2063 if (EQ (selection, Qnil)) selection = QPRIMARY;
2064 if (EQ (selection, Qt)) selection = QSECONDARY;
1b65481e 2065
a9f737ee
CY
2066 if (f && !NILP (LOCAL_SELECTION (selection, FRAME_X_DISPLAY_INFO (f))))
2067 return Qt;
2068 else
ede4db72 2069 return Qnil;
ede4db72
RS
2070}
2071
2072DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
a9f737ee
CY
2073 0, 2, 0,
2074 doc: /* Whether there is an owner for the given X selection.
2075SELECTION should be the name of the selection in question, typically
2076one of the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'. (X expects
2077these literal upper-case names.) The symbol nil is the same as
2078`PRIMARY', and t is the same as `SECONDARY'.
2079
2080TERMINAL should be a terminal object or a frame specifying the X
2081server to query. If omitted or nil, that stands for the selected
2082frame's display, or the first available X display. */)
2083 (Lisp_Object selection, Lisp_Object terminal)
ede4db72
RS
2084{
2085 Window owner;
356ba514 2086 Atom atom;
a9f737ee
CY
2087 struct frame *f = frame_for_x_selection (terminal);
2088 struct x_display_info *dpyinfo;
b8c70430 2089
b7826503 2090 CHECK_SYMBOL (selection);
356ba514
RS
2091 if (EQ (selection, Qnil)) selection = QPRIMARY;
2092 if (EQ (selection, Qt)) selection = QSECONDARY;
a9f737ee
CY
2093
2094 if (!f)
356ba514 2095 return Qnil;
a9f737ee
CY
2096
2097 dpyinfo = FRAME_X_DISPLAY_INFO (f);
2098
2099 if (!NILP (LOCAL_SELECTION (selection, dpyinfo)))
2100 return Qt;
2101
2102 atom = symbol_to_x_atom (dpyinfo, selection);
2103 if (atom == 0) return Qnil;
ede4db72 2104 BLOCK_INPUT;
a9f737ee 2105 owner = XGetSelectionOwner (dpyinfo->display, atom);
ede4db72
RS
2106 UNBLOCK_INPUT;
2107 return (owner ? Qt : Qnil);
2108}
2109
a9f737ee
CY
2110/* Send the clipboard manager a SAVE_TARGETS request with a
2111 UTF8_STRING property, as described by
2112 http://www.freedesktop.org/wiki/ClipboardManager */
2113
fb1ac845 2114static void
a9f737ee
CY
2115x_clipboard_manager_save (struct x_display_info *dpyinfo,
2116 Lisp_Object frame)
2117{
2118 struct frame *f = XFRAME (frame);
2119 Atom data = dpyinfo->Xatom_UTF8_STRING;
2120
2121 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2122 dpyinfo->Xatom_EMACS_TMP,
2123 dpyinfo->Xatom_ATOM, 32, PropModeReplace,
2124 (unsigned char *) &data, 1);
2125 x_get_foreign_selection (QCLIPBOARD_MANAGER, QSAVE_TARGETS,
2126 Qnil, frame);
2127}
2128
2129DEFUN ("x-clipboard-manager-save", Fx_clipboard_manager_save,
2130 Sx_clipboard_manager_save, 0, 1, 0,
2131 doc: /* Save the clipboard contents to the clipboard manager.
2132This function is intended to run from `delete-frame-functions' and
2133`kill-emacs-hook', to transfer clipboard data owned by Emacs to a
2134clipboard manager prior to deleting a frame or killing Emacs.
2135
2136FRAME specifies a frame owning a clipboard; do nothing if FRAME does
2137not own the clipboard, or if no clipboard manager is present. If
2138FRAME is nil, save all clipboard contents owned by Emacs. */)
2139 (Lisp_Object frame)
2140{
2141 if (FRAMEP (frame))
2142 {
2143 struct frame *f = XFRAME (frame);
2144 if (FRAME_LIVE_P (f) && FRAME_X_P (f))
2145 {
2146 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2147 Lisp_Object local_selection
2148 = LOCAL_SELECTION (QCLIPBOARD, dpyinfo);
2149
2150 if (!NILP (local_selection)
2151 && EQ (frame, XCAR (XCDR (XCDR (XCDR (local_selection)))))
2152 && XGetSelectionOwner (dpyinfo->display,
2153 dpyinfo->Xatom_CLIPBOARD_MANAGER))
2154 x_clipboard_manager_save (dpyinfo, frame);
2155 }
2156 }
2157 else if (NILP (frame))
2158 {
2159 /* Loop through all X displays, saving owned clipboards. */
2160 struct x_display_info *dpyinfo;
fb1ac845 2161 Lisp_Object local_selection, local_frame;
a9f737ee
CY
2162 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
2163 {
2164 local_selection = LOCAL_SELECTION (QCLIPBOARD, dpyinfo);
2165 if (NILP (local_selection)
2166 || !XGetSelectionOwner (dpyinfo->display,
2167 dpyinfo->Xatom_CLIPBOARD_MANAGER))
2168 continue;
2169
fb1ac845
PE
2170 local_frame = XCAR (XCDR (XCDR (XCDR (local_selection))));
2171 if (FRAME_LIVE_P (XFRAME (local_frame)))
2172 x_clipboard_manager_save (dpyinfo, local_frame);
a9f737ee
CY
2173 }
2174 }
2175
2176 return Qnil;
2177}
2178
ede4db72 2179\f
1fb3821b
JD
2180/***********************************************************************
2181 Drag and drop support
2182***********************************************************************/
2183/* Check that lisp values are of correct type for x_fill_property_data.
2184 That is, number, string or a cons with two numbers (low and high 16
44f730c8
PE
2185 bit parts of a 32 bit number). Return the number of items in DATA,
2186 or -1 if there is an error. */
1fb3821b
JD
2187
2188int
971de7fb 2189x_check_property_data (Lisp_Object data)
1fb3821b
JD
2190{
2191 Lisp_Object iter;
2192 int size = 0;
2193
44f730c8 2194 for (iter = data; CONSP (iter); iter = XCDR (iter))
1fb3821b
JD
2195 {
2196 Lisp_Object o = XCAR (iter);
2197
2198 if (! NUMBERP (o) && ! STRINGP (o) && ! CONSP (o))
44f730c8 2199 return -1;
1fb3821b
JD
2200 else if (CONSP (o) &&
2201 (! NUMBERP (XCAR (o)) || ! NUMBERP (XCDR (o))))
44f730c8
PE
2202 return -1;
2203 size++;
1fb3821b
JD
2204 }
2205
2206 return size;
2207}
2208
2209/* Convert lisp values to a C array. Values may be a number, a string
2210 which is taken as an X atom name and converted to the atom value, or
2211 a cons containing the two 16 bit parts of a 32 bit number.
2212
2213 DPY is the display use to look up X atoms.
2214 DATA is a Lisp list of values to be converted.
2215 RET is the C array that contains the converted values. It is assumed
ff59904a 2216 it is big enough to hold all values.
e22cf39c
JD
2217 FORMAT is 8, 16 or 32 and denotes char/short/long for each C value to
2218 be stored in RET. Note that long is used for 32 even if long is more
2219 than 32 bits (see man pages for XChangeProperty, XGetWindowProperty and
2220 XClientMessageEvent). */
1fb3821b
JD
2221
2222void
971de7fb 2223x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format)
1fb3821b 2224{
e22cf39c
JD
2225 long val;
2226 long *d32 = (long *) ret;
2227 short *d16 = (short *) ret;
2228 char *d08 = (char *) ret;
1fb3821b
JD
2229 Lisp_Object iter;
2230
2231 for (iter = data; CONSP (iter); iter = XCDR (iter))
2232 {
2233 Lisp_Object o = XCAR (iter);
2234
2235 if (INTEGERP (o))
e22cf39c 2236 val = (long) XFASTINT (o);
1fb3821b 2237 else if (FLOATP (o))
e22cf39c 2238 val = (long) XFLOAT_DATA (o);
1fb3821b 2239 else if (CONSP (o))
e22cf39c 2240 val = (long) cons_to_long (o);
1fb3821b
JD
2241 else if (STRINGP (o))
2242 {
2243 BLOCK_INPUT;
51b59d79 2244 val = (long) XInternAtom (dpy, SSDATA (o), False);
1fb3821b
JD
2245 UNBLOCK_INPUT;
2246 }
2247 else
2248 error ("Wrong type, must be string, number or cons");
2249
2250 if (format == 8)
e22cf39c 2251 *d08++ = (char) val;
1fb3821b 2252 else if (format == 16)
e22cf39c 2253 *d16++ = (short) val;
1fb3821b
JD
2254 else
2255 *d32++ = val;
2256 }
2257}
2258
2259/* Convert an array of C values to a Lisp list.
2260 F is the frame to be used to look up X atoms if the TYPE is XA_ATOM.
2261 DATA is a C array of values to be converted.
2262 TYPE is the type of the data. Only XA_ATOM is special, it converts
2263 each number in DATA to its corresponfing X atom as a symbol.
2264 FORMAT is 8, 16 or 32 and gives the size in bits for each C value to
2265 be stored in RET.
2266 SIZE is the number of elements in DATA.
2267
b8d6f4af
JD
2268 Important: When format is 32, data should contain an array of int,
2269 not an array of long as the X library returns. This makes a difference
2270 when sizeof(long) != sizeof(int).
2271
1fb3821b
JD
2272 Also see comment for selection_data_to_lisp_data above. */
2273
2274Lisp_Object
eec47d6b
DN
2275x_property_data_to_lisp (struct frame *f, const unsigned char *data,
2276 Atom type, int format, long unsigned int size)
1fb3821b
JD
2277{
2278 return selection_data_to_lisp_data (FRAME_X_DISPLAY (f),
2279 data, size*format/8, type, format);
2280}
2281
31f16913 2282/* Get the mouse position in frame relative coordinates. */
1fb3821b
JD
2283
2284static void
971de7fb 2285mouse_position_for_drop (FRAME_PTR f, int *x, int *y)
1fb3821b
JD
2286{
2287 Window root, dummy_window;
2288 int dummy;
2289
2290 BLOCK_INPUT;
2291
2292 XQueryPointer (FRAME_X_DISPLAY (f),
2293 DefaultRootWindow (FRAME_X_DISPLAY (f)),
2294
2295 /* The root window which contains the pointer. */
2296 &root,
2297
2298 /* Window pointer is on, not used */
2299 &dummy_window,
2300
2301 /* The position on that root window. */
2302 x, y,
2303
2304 /* x/y in dummy_window coordinates, not used. */
2305 &dummy, &dummy,
2306
2307 /* Modifier keys and pointer buttons, about which
2308 we don't care. */
2309 (unsigned int *) &dummy);
2310
2311
2312 /* Absolute to relative. */
2313 *x -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
2314 *y -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
2315
2316 UNBLOCK_INPUT;
2317}
2318
2319DEFUN ("x-get-atom-name", Fx_get_atom_name,
2320 Sx_get_atom_name, 1, 2, 0,
2321 doc: /* Return the X atom name for VALUE as a string.
2322VALUE may be a number or a cons where the car is the upper 16 bits and
2323the cdr is the lower 16 bits of a 32 bit value.
2324Use the display for FRAME or the current frame if FRAME is not given or nil.
2325
2326If the value is 0 or the atom is not known, return the empty string. */)
5842a27b 2327 (Lisp_Object value, Lisp_Object frame)
1fb3821b
JD
2328{
2329 struct frame *f = check_x_frame (frame);
2330 char *name = 0;
42ca4633 2331 char empty[] = "";
1fb3821b 2332 Lisp_Object ret = Qnil;
1fb3821b
JD
2333 Display *dpy = FRAME_X_DISPLAY (f);
2334 Atom atom;
c525d842 2335 int had_errors;
1fb3821b
JD
2336
2337 if (INTEGERP (value))
2338 atom = (Atom) XUINT (value);
2339 else if (FLOATP (value))
ff59904a 2340 atom = (Atom) XFLOAT_DATA (value);
1fb3821b
JD
2341 else if (CONSP (value))
2342 atom = (Atom) cons_to_long (value);
2343 else
2344 error ("Wrong type, value must be number or cons");
2345
2346 BLOCK_INPUT;
9ba8e10d 2347 x_catch_errors (dpy);
42ca4633 2348 name = atom ? XGetAtomName (dpy, atom) : empty;
c525d842
CY
2349 had_errors = x_had_errors_p (dpy);
2350 x_uncatch_errors ();
1fb3821b 2351
c525d842 2352 if (!had_errors)
1fb3821b
JD
2353 ret = make_string (name, strlen (name));
2354
1fb3821b 2355 if (atom && name) XFree (name);
8b3ad112 2356 if (NILP (ret)) ret = empty_unibyte_string;
1fb3821b
JD
2357
2358 UNBLOCK_INPUT;
2359
2360 return ret;
2361}
2362
9fc68699
JD
2363DEFUN ("x-register-dnd-atom", Fx_register_dnd_atom,
2364 Sx_register_dnd_atom, 1, 2, 0,
2365 doc: /* Request that dnd events are made for ClientMessages with ATOM.
2366ATOM can be a symbol or a string. The ATOM is interned on the display that
2367FRAME is on. If FRAME is nil, the selected frame is used. */)
5842a27b 2368 (Lisp_Object atom, Lisp_Object frame)
9fc68699
JD
2369{
2370 Atom x_atom;
2371 struct frame *f = check_x_frame (frame);
2372 size_t i;
2373 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2374
2375
2376 if (SYMBOLP (atom))
a9f737ee 2377 x_atom = symbol_to_x_atom (dpyinfo, atom);
9fc68699
JD
2378 else if (STRINGP (atom))
2379 {
2380 BLOCK_INPUT;
51b59d79 2381 x_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (atom), False);
9fc68699
JD
2382 UNBLOCK_INPUT;
2383 }
2384 else
2385 error ("ATOM must be a symbol or a string");
2386
db9cd97a 2387 for (i = 0; i < dpyinfo->x_dnd_atoms_length; ++i)
9fc68699
JD
2388 if (dpyinfo->x_dnd_atoms[i] == x_atom)
2389 return Qnil;
2390
db9cd97a 2391 if (dpyinfo->x_dnd_atoms_length == dpyinfo->x_dnd_atoms_size)
9fc68699
JD
2392 {
2393 dpyinfo->x_dnd_atoms_size *= 2;
2394 dpyinfo->x_dnd_atoms = xrealloc (dpyinfo->x_dnd_atoms,
2395 sizeof (*dpyinfo->x_dnd_atoms)
2396 * dpyinfo->x_dnd_atoms_size);
2397 }
2398
2399 dpyinfo->x_dnd_atoms[dpyinfo->x_dnd_atoms_length++] = x_atom;
2400 return Qnil;
2401}
2402
2403/* Convert an XClientMessageEvent to a Lisp event of type DRAG_N_DROP_EVENT. */
1fb3821b
JD
2404
2405int
971de7fb 2406x_handle_dnd_message (struct frame *f, XClientMessageEvent *event, struct x_display_info *dpyinfo, struct input_event *bufp)
1fb3821b
JD
2407{
2408 Lisp_Object vec;
2409 Lisp_Object frame;
e22cf39c
JD
2410 /* format 32 => size 5, format 16 => size 10, format 8 => size 20 */
2411 unsigned long size = 160/event->format;
1fb3821b 2412 int x, y;
31f16913
JD
2413 unsigned char *data = (unsigned char *) event->data.b;
2414 int idata[5];
9fc68699
JD
2415 size_t i;
2416
db9cd97a 2417 for (i = 0; i < dpyinfo->x_dnd_atoms_length; ++i)
9fc68699
JD
2418 if (dpyinfo->x_dnd_atoms[i] == event->message_type) break;
2419
2420 if (i == dpyinfo->x_dnd_atoms_length) return 0;
1fb3821b
JD
2421
2422 XSETFRAME (frame, f);
2423
31f16913
JD
2424 /* On a 64 bit machine, the event->data.l array members are 64 bits (long),
2425 but the x_property_data_to_lisp (or rather selection_data_to_lisp_data)
2426 function expects them to be of size int (i.e. 32). So to be able to
2427 use that function, put the data in the form it expects if format is 32. */
2428
2172544b 2429 if (32 < BITS_PER_LONG && event->format == 32)
31f16913 2430 {
31f16913
JD
2431 for (i = 0; i < 5; ++i) /* There are only 5 longs in a ClientMessage. */
2432 idata[i] = (int) event->data.l[i];
2433 data = (unsigned char *) idata;
2434 }
2435
d2f14999 2436 vec = Fmake_vector (make_number (4), Qnil);
3ae565b3
SM
2437 ASET (vec, 0, SYMBOL_NAME (x_atom_to_symbol (FRAME_X_DISPLAY (f),
2438 event->message_type)));
2439 ASET (vec, 1, frame);
2440 ASET (vec, 2, make_number (event->format));
2441 ASET (vec, 3, x_property_data_to_lisp (f,
2442 data,
2443 event->message_type,
2444 event->format,
2445 size));
1fb3821b
JD
2446
2447 mouse_position_for_drop (f, &x, &y);
2448 bufp->kind = DRAG_N_DROP_EVENT;
862c94ca 2449 bufp->frame_or_window = frame;
1fb3821b
JD
2450 bufp->timestamp = CurrentTime;
2451 bufp->x = make_number (x);
2452 bufp->y = make_number (y);
862c94ca 2453 bufp->arg = vec;
1fb3821b
JD
2454 bufp->modifiers = 0;
2455
2456 return 1;
2457}
2458
2459DEFUN ("x-send-client-message", Fx_send_client_event,
2460 Sx_send_client_message, 6, 6, 0,
2461 doc: /* Send a client message of MESSAGE-TYPE to window DEST on DISPLAY.
2462
2463For DISPLAY, specify either a frame or a display name (a string).
2464If DISPLAY is nil, that stands for the selected frame's display.
2465DEST may be a number, in which case it is a Window id. The value 0 may
2466be used to send to the root window of the DISPLAY.
2467If DEST is a cons, it is converted to a 32 bit number
2468with the high 16 bits from the car and the lower 16 bit from the cdr. That
2469number is then used as a window id.
2470If DEST is a frame the event is sent to the outer window of that frame.
69785ad0 2471A value of nil means the currently selected frame.
1fb3821b
JD
2472If DEST is the string "PointerWindow" the event is sent to the window that
2473contains the pointer. If DEST is the string "InputFocus" the event is
2474sent to the window that has the input focus.
2475FROM is the frame sending the event. Use nil for currently selected frame.
2476MESSAGE-TYPE is the name of an Atom as a string.
2477FORMAT must be one of 8, 16 or 32 and determines the size of the values in
2478bits. VALUES is a list of numbers, cons and/or strings containing the values
2479to send. If a value is a string, it is converted to an Atom and the value of
2480the Atom is sent. If a value is a cons, it is converted to a 32 bit number
2481with the high 16 bits from the car and the lower 16 bit from the cdr.
2482If more values than fits into the event is given, the excessive values
2483are ignored. */)
5842a27b 2484 (Lisp_Object display, Lisp_Object dest, Lisp_Object from, Lisp_Object message_type, Lisp_Object format, Lisp_Object values)
2d9074ba
JD
2485{
2486 struct x_display_info *dpyinfo = check_x_display_info (display);
2487
933e29ff 2488 CHECK_STRING (message_type);
2d9074ba 2489 x_send_client_event(display, dest, from,
933e29ff 2490 XInternAtom (dpyinfo->display,
42a5b22f 2491 SSDATA (message_type),
933e29ff 2492 False),
2d9074ba
JD
2493 format, values);
2494
2495 return Qnil;
2496}
2497
2498void
2499x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from, Atom message_type, Lisp_Object format, Lisp_Object values)
1fb3821b
JD
2500{
2501 struct x_display_info *dpyinfo = check_x_display_info (display);
2502 Window wdest;
2503 XEvent event;
1fb3821b 2504 struct frame *f = check_x_frame (from);
1fb3821b
JD
2505 int to_root;
2506
1fb3821b
JD
2507 CHECK_NUMBER (format);
2508 CHECK_CONS (values);
2509
2510 if (x_check_property_data (values) == -1)
2511 error ("Bad data in VALUES, must be number, cons or string");
2512
2513 event.xclient.type = ClientMessage;
2514 event.xclient.format = XFASTINT (format);
2515
2516 if (event.xclient.format != 8 && event.xclient.format != 16
2517 && event.xclient.format != 32)
2518 error ("FORMAT must be one of 8, 16 or 32");
a0ecb2ac 2519
1fb3821b
JD
2520 if (FRAMEP (dest) || NILP (dest))
2521 {
2522 struct frame *fdest = check_x_frame (dest);
2523 wdest = FRAME_OUTER_WINDOW (fdest);
2524 }
2525 else if (STRINGP (dest))
2526 {
42a5b22f 2527 if (strcmp (SSDATA (dest), "PointerWindow") == 0)
1fb3821b 2528 wdest = PointerWindow;
42a5b22f 2529 else if (strcmp (SSDATA (dest), "InputFocus") == 0)
1fb3821b
JD
2530 wdest = InputFocus;
2531 else
2532 error ("DEST as a string must be one of PointerWindow or InputFocus");
2533 }
2534 else if (INTEGERP (dest))
2535 wdest = (Window) XFASTINT (dest);
2536 else if (FLOATP (dest))
ff59904a 2537 wdest = (Window) XFLOAT_DATA (dest);
1fb3821b
JD
2538 else if (CONSP (dest))
2539 {
2540 if (! NUMBERP (XCAR (dest)) || ! NUMBERP (XCDR (dest)))
2541 error ("Both car and cdr for DEST must be numbers");
2542 else
2543 wdest = (Window) cons_to_long (dest);
2544 }
2545 else
2546 error ("DEST must be a frame, nil, string, number or cons");
2547
2548 if (wdest == 0) wdest = dpyinfo->root_window;
2549 to_root = wdest == dpyinfo->root_window;
2550
1fb3821b
JD
2551 BLOCK_INPUT;
2552
2d9074ba 2553 event.xclient.message_type = message_type;
1fb3821b
JD
2554 event.xclient.display = dpyinfo->display;
2555
2556 /* Some clients (metacity for example) expects sending window to be here
2557 when sending to the root window. */
2558 event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest;
2559
6e816df5 2560
1fb3821b
JD
2561 memset (event.xclient.data.b, 0, sizeof (event.xclient.data.b));
2562 x_fill_property_data (dpyinfo->display, values, event.xclient.data.b,
2563 event.xclient.format);
2564
2565 /* If event mask is 0 the event is sent to the client that created
2566 the destination window. But if we are sending to the root window,
2567 there is no such client. Then we set the event mask to 0xffff. The
2568 event then goes to clients selecting for events on the root window. */
9ba8e10d 2569 x_catch_errors (dpyinfo->display);
1fb3821b
JD
2570 {
2571 int propagate = to_root ? False : True;
2572 unsigned mask = to_root ? 0xffff : 0;
2573 XSendEvent (dpyinfo->display, wdest, propagate, mask, &event);
2574 XFlush (dpyinfo->display);
2575 }
4545fa20 2576 x_uncatch_errors ();
1fb3821b 2577 UNBLOCK_INPUT;
1fb3821b
JD
2578}
2579
2580\f
ede4db72 2581void
971de7fb 2582syms_of_xselect (void)
ede4db72 2583{
ede4db72
RS
2584 defsubr (&Sx_get_selection_internal);
2585 defsubr (&Sx_own_selection_internal);
2586 defsubr (&Sx_disown_selection_internal);
2587 defsubr (&Sx_selection_owner_p);
2588 defsubr (&Sx_selection_exists_p);
a9f737ee 2589 defsubr (&Sx_clipboard_manager_save);
ede4db72 2590
1fb3821b
JD
2591 defsubr (&Sx_get_atom_name);
2592 defsubr (&Sx_send_client_message);
9fc68699 2593 defsubr (&Sx_register_dnd_atom);
1fb3821b 2594
ede4db72
RS
2595 reading_selection_reply = Fcons (Qnil, Qnil);
2596 staticpro (&reading_selection_reply);
2597 reading_selection_window = 0;
2598 reading_which_selection = 0;
2599
2600 property_change_wait_list = 0;
2f65feb6 2601 prop_location_identifier = 0;
ede4db72
RS
2602 property_change_reply = Fcons (Qnil, Qnil);
2603 staticpro (&property_change_reply);
2604
e067f0c1
CY
2605 converted_selections = NULL;
2606 conversion_fail_tag = None;
2607
29208e82 2608 DEFVAR_LISP ("selection-converter-alist", Vselection_converter_alist,
8c1a1077
PJ
2609 doc: /* An alist associating X Windows selection-types with functions.
2610These functions are called to convert the selection, with three args:
2611the name of the selection (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');
2612a desired type to which the selection should be converted;
2613and the local selection value (whatever was given to `x-own-selection').
2614
2615The function should return the value to send to the X server
2616\(typically a string). A return value of nil
2617means that the conversion could not be done.
2618A return value which is the symbol `NULL'
2619means that a side-effect was executed,
2620and there is no meaningful selection value. */);
ede4db72
RS
2621 Vselection_converter_alist = Qnil;
2622
29208e82 2623 DEFVAR_LISP ("x-lost-selection-functions", Vx_lost_selection_functions,
8c1a1077
PJ
2624 doc: /* A list of functions to be called when Emacs loses an X selection.
2625\(This happens when some other X client makes its own selection
2626or when a Lisp program explicitly clears the selection.)
2627The functions are called with one argument, the selection type
2628\(a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'). */);
c917a8de 2629 Vx_lost_selection_functions = Qnil;
ede4db72 2630
29208e82 2631 DEFVAR_LISP ("x-sent-selection-functions", Vx_sent_selection_functions,
8c1a1077 2632 doc: /* A list of functions to be called when Emacs answers a selection request.
e067f0c1 2633The functions are called with three arguments:
8c1a1077
PJ
2634 - the selection name (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');
2635 - the selection-type which Emacs was asked to convert the
2636 selection into before sending (for example, `STRING' or `LENGTH');
2637 - a flag indicating success or failure for responding to the request.
2638We might have failed (and declined the request) for any number of reasons,
2639including being asked for a selection that we no longer own, or being asked
2640to convert into a type that we don't know about or that is inappropriate.
2641This hook doesn't let you change the behavior of Emacs's selection replies,
2642it merely informs you that they have happened. */);
c917a8de 2643 Vx_sent_selection_functions = Qnil;
ede4db72 2644
29208e82 2645 DEFVAR_INT ("x-selection-timeout", x_selection_timeout,
8c1a1077
PJ
2646 doc: /* Number of milliseconds to wait for a selection reply.
2647If the selection owner doesn't reply in this time, we give up.
2648A value of 0 means wait as long as necessary. This is initialized from the
2649\"*selectionTimeout\" resource. */);
ede4db72
RS
2650 x_selection_timeout = 0;
2651
9852377f 2652 /* QPRIMARY is defined in keyboard.c. */
f3d4e0a4
CY
2653 DEFSYM (QSECONDARY, "SECONDARY");
2654 DEFSYM (QSTRING, "STRING");
2655 DEFSYM (QINTEGER, "INTEGER");
2656 DEFSYM (QCLIPBOARD, "CLIPBOARD");
2657 DEFSYM (QTIMESTAMP, "TIMESTAMP");
2658 DEFSYM (QTEXT, "TEXT");
2659 DEFSYM (QCOMPOUND_TEXT, "COMPOUND_TEXT");
2660 DEFSYM (QUTF8_STRING, "UTF8_STRING");
2661 DEFSYM (QDELETE, "DELETE");
2662 DEFSYM (QMULTIPLE, "MULTIPLE");
2663 DEFSYM (QINCR, "INCR");
2664 DEFSYM (QEMACS_TMP, "_EMACS_TMP_");
2665 DEFSYM (QTARGETS, "TARGETS");
2666 DEFSYM (QATOM, "ATOM");
2667 DEFSYM (QATOM_PAIR, "ATOM_PAIR");
a9f737ee
CY
2668 DEFSYM (QCLIPBOARD_MANAGER, "CLIPBOARD_MANAGER");
2669 DEFSYM (QSAVE_TARGETS, "SAVE_TARGETS");
f3d4e0a4
CY
2670 DEFSYM (QNULL, "NULL");
2671 DEFSYM (Qcompound_text_with_extensions, "compound-text-with-extensions");
2672 DEFSYM (Qforeign_selection, "foreign-selection");
ede4db72 2673}