* lisp/files.el (interpreter-mode-alist): Add rbash.
[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
e067f0c1
CY
907 RETURN_UNGCPRO (0);
908 }
4f06187f 909
e067f0c1
CY
910 /* Otherwise, record the converted selection to binary. */
911 cs = xmalloc (sizeof (struct selection_data));
912 cs->nofree = 1;
913 cs->property = property;
914 cs->wait_object = NULL;
915 cs->next = converted_selections;
916 converted_selections = cs;
917 lisp_data_to_selection_data (SELECTION_EVENT_DISPLAY (event),
918 lisp_selection,
919 &(cs->data), &(cs->type),
920 &(cs->size), &(cs->format),
921 &(cs->nofree));
922 RETURN_UNGCPRO (1);
ede4db72
RS
923}
924\f
e18e6130 925/* Handle a SelectionClear event EVENT, which indicates that some
ede4db72
RS
926 client cleared out our previously asserted selection.
927 This is called from keyboard.c when such an event is found in the queue. */
928
dd0fe424 929static void
971de7fb 930x_handle_selection_clear (struct input_event *event)
ede4db72
RS
931{
932 Display *display = SELECTION_EVENT_DISPLAY (event);
933 Atom selection = SELECTION_EVENT_SELECTION (event);
934 Time changed_owner_time = SELECTION_EVENT_TIME (event);
1b65481e 935
ede4db72
RS
936 Lisp_Object selection_symbol, local_selection_data;
937 Time local_selection_time;
5c3a351a 938 struct x_display_info *dpyinfo = x_display_info_for_display (display);
a9f737ee 939 Lisp_Object Vselection_alist;
e18e6130 940
dd0fe424
KS
941 TRACE0 ("x_handle_selection_clear");
942
a9f737ee 943 if (!dpyinfo) return;
16041401 944
d9c0d4a3 945 selection_symbol = x_atom_to_symbol (display, selection);
a9f737ee 946 local_selection_data = LOCAL_SELECTION (selection_symbol, dpyinfo);
ede4db72
RS
947
948 /* Well, we already believe that we don't own it, so that's just fine. */
949 if (NILP (local_selection_data)) return;
950
951 local_selection_time = (Time)
8e713be6 952 cons_to_long (XCAR (XCDR (XCDR (local_selection_data))));
ede4db72 953
a9f737ee
CY
954 /* We have reasserted the selection since this SelectionClear was
955 generated, so we can disregard it. */
ede4db72
RS
956 if (changed_owner_time != CurrentTime
957 && local_selection_time > changed_owner_time)
958 return;
959
a9f737ee
CY
960 /* Otherwise, really clear. Don't use Fdelq as that may QUIT;. */
961 Vselection_alist = dpyinfo->terminal->Vselection_alist;
962 if (EQ (local_selection_data, CAR (Vselection_alist)))
963 Vselection_alist = XCDR (Vselection_alist);
ede4db72
RS
964 else
965 {
966 Lisp_Object rest;
99784d63 967 for (rest = Vselection_alist; CONSP (rest); rest = XCDR (rest))
a9f737ee 968 if (EQ (local_selection_data, CAR (XCDR (rest))))
ede4db72 969 {
a9f737ee 970 XSETCDR (rest, XCDR (XCDR (rest)));
ede4db72
RS
971 break;
972 }
973 }
a9f737ee 974 dpyinfo->terminal->Vselection_alist = Vselection_alist;
ede4db72 975
a9f737ee 976 /* Run the `x-lost-selection-functions' abnormal hook. */
ede4db72 977 {
a9f737ee
CY
978 Lisp_Object args[2];
979 args[0] = Vx_lost_selection_functions;
980 args[1] = selection_symbol;
981 Frun_hook_with_args (2, args);
ede4db72 982 }
a9f737ee
CY
983
984 prepare_menu_bars ();
985 redisplay_preserve_echo_area (20);
ede4db72
RS
986}
987
dd0fe424 988void
971de7fb 989x_handle_selection_event (struct input_event *event)
dd0fe424
KS
990{
991 TRACE0 ("x_handle_selection_event");
e067f0c1 992 if (event->kind != SELECTION_REQUEST_EVENT)
dd0fe424 993 x_handle_selection_clear (event);
e067f0c1
CY
994 else if (x_queue_selection_requests)
995 x_queue_event (event);
996 else
997 x_handle_selection_request (event);
dd0fe424
KS
998}
999
1000
118bd841
RS
1001/* Clear all selections that were made from frame F.
1002 We do this when about to delete a frame. */
1003
1004void
971de7fb 1005x_clear_frame_selections (FRAME_PTR f)
118bd841
RS
1006{
1007 Lisp_Object frame;
1008 Lisp_Object rest;
a9f737ee
CY
1009 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1010 struct terminal *t = dpyinfo->terminal;
118bd841 1011
90851bbe 1012 XSETFRAME (frame, f);
118bd841 1013
0d199f9c 1014 /* Delete elements from the beginning of Vselection_alist. */
a9f737ee
CY
1015 while (CONSP (t->Vselection_alist)
1016 && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (t->Vselection_alist)))))))
0d199f9c 1017 {
a9f737ee
CY
1018 /* Run the `x-lost-selection-functions' abnormal hook. */
1019 Lisp_Object args[2];
1020 args[0] = Vx_lost_selection_functions;
1021 args[1] = Fcar (Fcar (t->Vselection_alist));
1022 Frun_hook_with_args (2, args);
0d199f9c 1023
a9f737ee 1024 t->Vselection_alist = XCDR (t->Vselection_alist);
0d199f9c
RS
1025 }
1026
1027 /* Delete elements after the beginning of Vselection_alist. */
a9f737ee
CY
1028 for (rest = t->Vselection_alist; CONSP (rest); rest = XCDR (rest))
1029 if (CONSP (XCDR (rest))
1030 && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (XCDR (rest))))))))
118bd841 1031 {
a9f737ee
CY
1032 Lisp_Object args[2];
1033 args[0] = Vx_lost_selection_functions;
1034 args[1] = XCAR (XCAR (XCDR (rest)));
1035 Frun_hook_with_args (2, args);
1036 XSETCDR (rest, XCDR (XCDR (rest)));
118bd841
RS
1037 break;
1038 }
1039}
ede4db72 1040\f
ede4db72
RS
1041/* Nonzero if any properties for DISPLAY and WINDOW
1042 are on the list of what we are waiting for. */
1043
1044static int
971de7fb 1045waiting_for_other_props_on_window (Display *display, Window window)
ede4db72
RS
1046{
1047 struct prop_location *rest = property_change_wait_list;
1048 while (rest)
1049 if (rest->display == display && rest->window == window)
1050 return 1;
1051 else
1052 rest = rest->next;
1053 return 0;
1054}
1055
1056/* Add an entry to the list of property changes we are waiting for.
1057 DISPLAY, WINDOW, PROPERTY, STATE describe what we will wait for.
1058 The return value is a number that uniquely identifies
1059 this awaited property change. */
1060
d1f21a66 1061static struct prop_location *
971de7fb 1062expect_property_change (Display *display, Window window, Atom property, int state)
ede4db72 1063{
d9c0d4a3 1064 struct prop_location *pl = (struct prop_location *) xmalloc (sizeof *pl);
2f65feb6 1065 pl->identifier = ++prop_location_identifier;
ede4db72
RS
1066 pl->display = display;
1067 pl->window = window;
1068 pl->property = property;
1069 pl->desired_state = state;
1070 pl->next = property_change_wait_list;
d1f21a66 1071 pl->arrived = 0;
ede4db72 1072 property_change_wait_list = pl;
d1f21a66 1073 return pl;
ede4db72
RS
1074}
1075
1076/* Delete an entry from the list of property changes we are waiting for.
2f65feb6 1077 IDENTIFIER is the number that uniquely identifies the entry. */
ede4db72
RS
1078
1079static void
971de7fb 1080unexpect_property_change (struct prop_location *location)
ede4db72
RS
1081{
1082 struct prop_location *prev = 0, *rest = property_change_wait_list;
1083 while (rest)
1084 {
d1f21a66 1085 if (rest == location)
ede4db72
RS
1086 {
1087 if (prev)
1088 prev->next = rest->next;
1089 else
1090 property_change_wait_list = rest->next;
4feb31b2 1091 xfree (rest);
ede4db72
RS
1092 return;
1093 }
1094 prev = rest;
1095 rest = rest->next;
1096 }
1097}
1098
2f65feb6
RS
1099/* Remove the property change expectation element for IDENTIFIER. */
1100
1101static Lisp_Object
971de7fb 1102wait_for_property_change_unwind (Lisp_Object loc)
2f65feb6 1103{
dd0fe424
KS
1104 struct prop_location *location = XSAVE_VALUE (loc)->pointer;
1105
1106 unexpect_property_change (location);
1107 if (location == property_change_reply_object)
1108 property_change_reply_object = 0;
ab552306 1109 return Qnil;
2f65feb6
RS
1110}
1111
ede4db72 1112/* Actually wait for a property change.
2f65feb6 1113 IDENTIFIER should be the value that expect_property_change returned. */
ede4db72
RS
1114
1115static void
971de7fb 1116wait_for_property_change (struct prop_location *location)
ede4db72 1117{
2f65feb6 1118 int secs, usecs;
aed13378 1119 int count = SPECPDL_INDEX ();
d1f21a66 1120
dd0fe424
KS
1121 if (property_change_reply_object)
1122 abort ();
2f65feb6
RS
1123
1124 /* Make sure to do unexpect_property_change if we quit or err. */
dd0fe424
KS
1125 record_unwind_protect (wait_for_property_change_unwind,
1126 make_save_value (location, 0));
2f65feb6 1127
f3fbd155 1128 XSETCAR (property_change_reply, Qnil);
afe1529d 1129 property_change_reply_object = location;
dd0fe424 1130
afe1529d
RS
1131 /* If the event we are waiting for arrives beyond here, it will set
1132 property_change_reply, because property_change_reply_object says so. */
d1f21a66
RS
1133 if (! location->arrived)
1134 {
d1f21a66
RS
1135 secs = x_selection_timeout / 1000;
1136 usecs = (x_selection_timeout % 1000) * 1000;
d9c0d4a3 1137 TRACE2 (" Waiting %d secs, %d usecs", secs, usecs);
d64b707c
KS
1138 wait_reading_process_output (secs, usecs, 0, 0,
1139 property_change_reply, NULL, 0);
d1f21a66 1140
8e713be6 1141 if (NILP (XCAR (property_change_reply)))
d9c0d4a3
GM
1142 {
1143 TRACE0 (" Timed out");
1144 error ("Timed out waiting for property-notify event");
1145 }
d1f21a66 1146 }
2f65feb6
RS
1147
1148 unbind_to (count, Qnil);
ede4db72
RS
1149}
1150
1151/* Called from XTread_socket in response to a PropertyNotify event. */
1152
1153void
971de7fb 1154x_handle_property_notify (XPropertyEvent *event)
ede4db72 1155{
6abdaa4a 1156 struct prop_location *rest;
d9c0d4a3 1157
6abdaa4a 1158 for (rest = property_change_wait_list; rest; rest = rest->next)
ede4db72 1159 {
dd0fe424
KS
1160 if (!rest->arrived
1161 && rest->property == event->atom
ede4db72
RS
1162 && rest->window == event->window
1163 && rest->display == event->display
1164 && rest->desired_state == event->state)
1165 {
d9c0d4a3
GM
1166 TRACE2 ("Expected %s of property %s",
1167 (event->state == PropertyDelete ? "deletion" : "change"),
1168 XGetAtomName (event->display, event->atom));
ede4db72 1169
d1f21a66
RS
1170 rest->arrived = 1;
1171
ede4db72
RS
1172 /* If this is the one wait_for_property_change is waiting for,
1173 tell it to wake up. */
d1f21a66 1174 if (rest == property_change_reply_object)
f3fbd155 1175 XSETCAR (property_change_reply, Qt);
ede4db72 1176
ede4db72
RS
1177 return;
1178 }
ede4db72 1179 }
ede4db72
RS
1180}
1181
1182
1183\f
ede4db72
RS
1184/* Variables for communication with x_handle_selection_notify. */
1185static Atom reading_which_selection;
1186static Lisp_Object reading_selection_reply;
1187static Window reading_selection_window;
1188
1189/* Do protocol to read selection-data from the server.
a9f737ee
CY
1190 Converts this to Lisp data and returns it.
1191 FRAME is the frame whose X window shall request the selection. */
ede4db72
RS
1192
1193static Lisp_Object
a9f737ee
CY
1194x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
1195 Lisp_Object time_stamp, Lisp_Object frame)
ede4db72 1196{
a9f737ee
CY
1197 struct frame *f = XFRAME (frame);
1198 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1199 Display *display = dpyinfo->display;
1200 Window requestor_window = FRAME_X_WINDOW (f);
5d0ba25b 1201 Time requestor_time = last_event_timestamp;
a9f737ee
CY
1202 Atom target_property = dpyinfo->Xatom_EMACS_TMP;
1203 Atom selection_atom = symbol_to_x_atom (dpyinfo, selection_symbol);
1204 Atom type_atom = (CONSP (target_type)
1205 ? symbol_to_x_atom (dpyinfo, XCAR (target_type))
1206 : symbol_to_x_atom (dpyinfo, target_type));
80da0190 1207 int secs, usecs;
c525d842 1208 int count = SPECPDL_INDEX ();
ede4db72 1209
a9f737ee 1210 if (!FRAME_LIVE_P (f))
428a555e
KL
1211 return Qnil;
1212
3a42401d
JD
1213 if (! NILP (time_stamp))
1214 {
1215 if (CONSP (time_stamp))
1216 requestor_time = (Time) cons_to_long (time_stamp);
1217 else if (INTEGERP (time_stamp))
1218 requestor_time = (Time) XUINT (time_stamp);
1219 else if (FLOATP (time_stamp))
ff59904a 1220 requestor_time = (Time) XFLOAT_DATA (time_stamp);
3a42401d
JD
1221 else
1222 error ("TIME_STAMP must be cons or number");
1223 }
1224
ede4db72 1225 BLOCK_INPUT;
1b65481e 1226
c525d842
CY
1227 /* The protected block contains wait_reading_process_output, which
1228 can run random lisp code (process handlers) or signal.
1229 Therefore, we put the x_uncatch_errors call in an unwind. */
1230 record_unwind_protect (x_catch_errors_unwind, Qnil);
9ba8e10d 1231 x_catch_errors (display);
1b65481e 1232
d9c0d4a3
GM
1233 TRACE2 ("Get selection %s, type %s",
1234 XGetAtomName (display, type_atom),
1235 XGetAtomName (display, target_property));
1236
ede4db72 1237 XConvertSelection (display, selection_atom, type_atom, target_property,
5d0ba25b 1238 requestor_window, requestor_time);
5c3a351a 1239 XFlush (display);
ede4db72
RS
1240
1241 /* Prepare to block until the reply has been read. */
5d0ba25b 1242 reading_selection_window = requestor_window;
ede4db72 1243 reading_which_selection = selection_atom;
f3fbd155 1244 XSETCAR (reading_selection_reply, Qnil);
55b2d45d 1245
e067f0c1
CY
1246 /* It should not be necessary to stop handling selection requests
1247 during this time. In fact, the SAVE_TARGETS mechanism requires
1248 us to handle a clipboard manager's requests before it returns
1249 SelectionNotify. */
1250#if 0
a9f737ee
CY
1251 x_start_queuing_selection_requests ();
1252 record_unwind_protect (queue_selection_requests_unwind, Qnil);
e067f0c1
CY
1253#endif
1254
ede4db72
RS
1255 UNBLOCK_INPUT;
1256
80da0190
RS
1257 /* This allows quits. Also, don't wait forever. */
1258 secs = x_selection_timeout / 1000;
1259 usecs = (x_selection_timeout % 1000) * 1000;
d9c0d4a3 1260 TRACE1 (" Start waiting %d secs for SelectionNotify", secs);
d64b707c
KS
1261 wait_reading_process_output (secs, usecs, 0, 0,
1262 reading_selection_reply, NULL, 0);
d9c0d4a3 1263 TRACE1 (" Got event = %d", !NILP (XCAR (reading_selection_reply)));
ede4db72 1264
7c6b2ea4 1265 BLOCK_INPUT;
c525d842
CY
1266 if (x_had_errors_p (display))
1267 error ("Cannot get selection");
1268 /* This calls x_uncatch_errors. */
9ba8e10d 1269 unbind_to (count, Qnil);
7c6b2ea4
RS
1270 UNBLOCK_INPUT;
1271
8e713be6 1272 if (NILP (XCAR (reading_selection_reply)))
606140dd 1273 error ("Timed out waiting for reply from selection owner");
8e713be6 1274 if (EQ (XCAR (reading_selection_reply), Qlambda))
12061f06 1275 return Qnil;
ede4db72
RS
1276
1277 /* Otherwise, the selection is waiting for us on the requested property. */
1278 return
5d0ba25b 1279 x_get_window_property_as_lisp_data (display, requestor_window,
ede4db72
RS
1280 target_property, target_type,
1281 selection_atom);
1282}
1283\f
1284/* Subroutines of x_get_window_property_as_lisp_data */
1285
4feb31b2 1286/* Use xfree, not XFree, to free the data obtained with this function. */
0158abbc 1287
ede4db72 1288static void
d5a3eaaf
AS
1289x_get_window_property (Display *display, Window window, Atom property,
1290 unsigned char **data_ret, int *bytes_ret,
1291 Atom *actual_type_ret, int *actual_format_ret,
1292 unsigned long *actual_size_ret, int delete_p)
ede4db72
RS
1293{
1294 int total_size;
1295 unsigned long bytes_remaining;
1296 int offset = 0;
1297 unsigned char *tmp_data = 0;
1298 int result;
1299 int buffer_size = SELECTION_QUANTUM (display);
1b65481e 1300
d9c0d4a3
GM
1301 if (buffer_size > MAX_SELECTION_QUANTUM)
1302 buffer_size = MAX_SELECTION_QUANTUM;
1b65481e 1303
ede4db72 1304 BLOCK_INPUT;
1b65481e 1305
ede4db72
RS
1306 /* First probe the thing to find out how big it is. */
1307 result = XGetWindowProperty (display, window, property,
137edb72 1308 0L, 0L, False, AnyPropertyType,
ede4db72
RS
1309 actual_type_ret, actual_format_ret,
1310 actual_size_ret,
1311 &bytes_remaining, &tmp_data);
ede4db72
RS
1312 if (result != Success)
1313 {
2f65feb6 1314 UNBLOCK_INPUT;
ede4db72
RS
1315 *data_ret = 0;
1316 *bytes_ret = 0;
1317 return;
1318 }
1b65481e 1319
0158abbc
RS
1320 /* This was allocated by Xlib, so use XFree. */
1321 XFree ((char *) tmp_data);
1b65481e 1322
ede4db72
RS
1323 if (*actual_type_ret == None || *actual_format_ret == 0)
1324 {
2f65feb6 1325 UNBLOCK_INPUT;
ede4db72
RS
1326 return;
1327 }
1328
1329 total_size = bytes_remaining + 1;
1330 *data_ret = (unsigned char *) xmalloc (total_size);
1b65481e 1331
2a1a4c9d 1332 /* Now read, until we've gotten it all. */
ede4db72
RS
1333 while (bytes_remaining)
1334 {
d9c0d4a3 1335#ifdef TRACE_SELECTION
c2982e87 1336 unsigned long last = bytes_remaining;
ede4db72
RS
1337#endif
1338 result
1339 = XGetWindowProperty (display, window, property,
137edb72 1340 (long)offset/4, (long)buffer_size/4,
2f65feb6 1341 False,
ede4db72
RS
1342 AnyPropertyType,
1343 actual_type_ret, actual_format_ret,
1344 actual_size_ret, &bytes_remaining, &tmp_data);
d9c0d4a3 1345
c2982e87 1346 TRACE2 ("Read %lu bytes from property %s",
d9c0d4a3
GM
1347 last - bytes_remaining,
1348 XGetAtomName (display, property));
1349
ede4db72
RS
1350 /* If this doesn't return Success at this point, it means that
1351 some clod deleted the selection while we were in the midst of
d9c0d4a3
GM
1352 reading it. Deal with that, I guess.... */
1353 if (result != Success)
1354 break;
e22cf39c
JD
1355
1356 /* The man page for XGetWindowProperty says:
1357 "If the returned format is 32, the returned data is represented
1358 as a long array and should be cast to that type to obtain the
1359 elements."
1360 This applies even if long is more than 32 bits, the X library
1361 converts from 32 bit elements received from the X server to long
72af86bd 1362 and passes the long array to us. Thus, for that case memcpy can not
e22cf39c
JD
1363 be used. We convert to a 32 bit type here, because so much code
1364 assume on that.
1365
1366 The bytes and offsets passed to XGetWindowProperty refers to the
1367 property and those are indeed in 32 bit quantities if format is 32. */
1368
2172544b 1369 if (32 < BITS_PER_LONG && *actual_format_ret == 32)
e22cf39c
JD
1370 {
1371 unsigned long i;
1372 int *idata = (int *) ((*data_ret) + offset);
1373 long *ldata = (long *) tmp_data;
1374
1375 for (i = 0; i < *actual_size_ret; ++i)
1376 {
1377 idata[i]= (int) ldata[i];
1378 offset += 4;
1379 }
1380 }
1381 else
1382 {
1383 *actual_size_ret *= *actual_format_ret / 8;
72af86bd 1384 memcpy ((*data_ret) + offset, tmp_data, *actual_size_ret);
e22cf39c
JD
1385 offset += *actual_size_ret;
1386 }
1b65481e 1387
0158abbc
RS
1388 /* This was allocated by Xlib, so use XFree. */
1389 XFree ((char *) tmp_data);
ede4db72 1390 }
2f65feb6 1391
5c3a351a 1392 XFlush (display);
ede4db72
RS
1393 UNBLOCK_INPUT;
1394 *bytes_ret = offset;
1395}
1396\f
4feb31b2 1397/* Use xfree, not XFree, to free the data obtained with this function. */
0158abbc 1398
ede4db72 1399static void
d5a3eaaf
AS
1400receive_incremental_selection (Display *display, Window window, Atom property,
1401 Lisp_Object target_type,
1402 unsigned int min_size_bytes,
1403 unsigned char **data_ret, int *size_bytes_ret,
1404 Atom *type_ret, int *format_ret,
1405 unsigned long *size_ret)
ede4db72
RS
1406{
1407 int offset = 0;
d1f21a66 1408 struct prop_location *wait_object;
ede4db72
RS
1409 *size_bytes_ret = min_size_bytes;
1410 *data_ret = (unsigned char *) xmalloc (*size_bytes_ret);
d9c0d4a3
GM
1411
1412 TRACE1 ("Read %d bytes incrementally", min_size_bytes);
2f65feb6
RS
1413
1414 /* At this point, we have read an INCR property.
1415 Delete the property to ack it.
1416 (But first, prepare to receive the next event in this handshake.)
ede4db72
RS
1417
1418 Now, we must loop, waiting for the sending window to put a value on
1419 that property, then reading the property, then deleting it to ack.
1420 We are done when the sender places a property of length 0.
1421 */
2f65feb6
RS
1422 BLOCK_INPUT;
1423 XSelectInput (display, window, STANDARD_EVENT_SET | PropertyChangeMask);
d9c0d4a3 1424 TRACE1 (" Delete property %s",
dd0fe424 1425 SDATA (SYMBOL_NAME (x_atom_to_symbol (display, property))));
2f65feb6 1426 XDeleteProperty (display, window, property);
d9c0d4a3 1427 TRACE1 (" Expect new value of property %s",
dd0fe424 1428 SDATA (SYMBOL_NAME (x_atom_to_symbol (display, property))));
d1f21a66
RS
1429 wait_object = expect_property_change (display, window, property,
1430 PropertyNewValue);
5c3a351a 1431 XFlush (display);
2f65feb6
RS
1432 UNBLOCK_INPUT;
1433
ede4db72
RS
1434 while (1)
1435 {
1436 unsigned char *tmp_data;
1437 int tmp_size_bytes;
d9c0d4a3
GM
1438
1439 TRACE0 (" Wait for property change");
d1f21a66 1440 wait_for_property_change (wait_object);
1b65481e 1441
ede4db72 1442 /* expect it again immediately, because x_get_window_property may
2a1a4c9d 1443 .. no it won't, I don't get it.
d9c0d4a3
GM
1444 .. Ok, I get it now, the Xt code that implements INCR is broken. */
1445 TRACE0 (" Get property value");
ede4db72
RS
1446 x_get_window_property (display, window, property,
1447 &tmp_data, &tmp_size_bytes,
1448 type_ret, format_ret, size_ret, 1);
1449
d9c0d4a3
GM
1450 TRACE1 (" Read increment of %d bytes", tmp_size_bytes);
1451
ede4db72
RS
1452 if (tmp_size_bytes == 0) /* we're done */
1453 {
d9c0d4a3
GM
1454 TRACE0 ("Done reading incrementally");
1455
2f65feb6
RS
1456 if (! waiting_for_other_props_on_window (display, window))
1457 XSelectInput (display, window, STANDARD_EVENT_SET);
4feb31b2 1458 /* Use xfree, not XFree, because x_get_window_property
0158abbc 1459 calls xmalloc itself. */
70fdbb46 1460 xfree (tmp_data);
ede4db72
RS
1461 break;
1462 }
2f65feb6
RS
1463
1464 BLOCK_INPUT;
d9c0d4a3
GM
1465 TRACE1 (" ACK by deleting property %s",
1466 XGetAtomName (display, property));
2f65feb6 1467 XDeleteProperty (display, window, property);
d1f21a66
RS
1468 wait_object = expect_property_change (display, window, property,
1469 PropertyNewValue);
5c3a351a 1470 XFlush (display);
2f65feb6
RS
1471 UNBLOCK_INPUT;
1472
ede4db72
RS
1473 if (*size_bytes_ret < offset + tmp_size_bytes)
1474 {
ede4db72
RS
1475 *size_bytes_ret = offset + tmp_size_bytes;
1476 *data_ret = (unsigned char *) xrealloc (*data_ret, *size_bytes_ret);
1477 }
1b65481e 1478
72af86bd 1479 memcpy ((*data_ret) + offset, tmp_data, tmp_size_bytes);
ede4db72 1480 offset += tmp_size_bytes;
1b65481e 1481
4feb31b2 1482 /* Use xfree, not XFree, because x_get_window_property
0158abbc 1483 calls xmalloc itself. */
4feb31b2 1484 xfree (tmp_data);
ede4db72
RS
1485 }
1486}
d9c0d4a3 1487
ede4db72 1488\f
e067f0c1
CY
1489/* Fetch a value from property PROPERTY of X window WINDOW on display
1490 DISPLAY. TARGET_TYPE and SELECTION_ATOM are used in error message
1491 if this fails. */
ede4db72
RS
1492
1493static Lisp_Object
d5a3eaaf
AS
1494x_get_window_property_as_lisp_data (Display *display, Window window,
1495 Atom property,
1496 Lisp_Object target_type,
1497 Atom selection_atom)
ede4db72
RS
1498{
1499 Atom actual_type;
1500 int actual_format;
1501 unsigned long actual_size;
1502 unsigned char *data = 0;
1503 int bytes = 0;
1504 Lisp_Object val;
5c3a351a 1505 struct x_display_info *dpyinfo = x_display_info_for_display (display);
ede4db72 1506
d9c0d4a3
GM
1507 TRACE0 ("Reading selection data");
1508
ede4db72
RS
1509 x_get_window_property (display, window, property, &data, &bytes,
1510 &actual_type, &actual_format, &actual_size, 1);
1511 if (! data)
1512 {
1513 int there_is_a_selection_owner;
1514 BLOCK_INPUT;
1515 there_is_a_selection_owner
1516 = XGetSelectionOwner (display, selection_atom);
1517 UNBLOCK_INPUT;
4d30ce50
KS
1518 if (there_is_a_selection_owner)
1519 signal_error ("Selection owner couldn't convert",
1520 actual_type
1521 ? list2 (target_type,
1522 x_atom_to_symbol (display, actual_type))
1523 : target_type);
1524 else
1525 signal_error ("No selection",
1526 x_atom_to_symbol (display, selection_atom));
ede4db72 1527 }
1b65481e 1528
5c3a351a 1529 if (actual_type == dpyinfo->Xatom_INCR)
ede4db72
RS
1530 {
1531 /* That wasn't really the data, just the beginning. */
1532
1533 unsigned int min_size_bytes = * ((unsigned int *) data);
1534 BLOCK_INPUT;
4feb31b2 1535 /* Use xfree, not XFree, because x_get_window_property
0158abbc 1536 calls xmalloc itself. */
4feb31b2 1537 xfree ((char *) data);
ede4db72
RS
1538 UNBLOCK_INPUT;
1539 receive_incremental_selection (display, window, property, target_type,
1540 min_size_bytes, &data, &bytes,
1541 &actual_type, &actual_format,
1542 &actual_size);
1543 }
1544
2f65feb6 1545 BLOCK_INPUT;
d9c0d4a3 1546 TRACE1 (" Delete property %s", XGetAtomName (display, property));
2f65feb6 1547 XDeleteProperty (display, window, property);
5c3a351a 1548 XFlush (display);
2f65feb6
RS
1549 UNBLOCK_INPUT;
1550
ede4db72
RS
1551 /* It's been read. Now convert it to a lisp object in some semi-rational
1552 manner. */
1553 val = selection_data_to_lisp_data (display, data, bytes,
1554 actual_type, actual_format);
1b65481e 1555
4feb31b2 1556 /* Use xfree, not XFree, because x_get_window_property
0158abbc 1557 calls xmalloc itself. */
4feb31b2 1558 xfree ((char *) data);
ede4db72
RS
1559 return val;
1560}
1561\f
1562/* These functions convert from the selection data read from the server into
1563 something that we can use from Lisp, and vice versa.
1564
1565 Type: Format: Size: Lisp Type:
1566 ----- ------- ----- -----------
1567 * 8 * String
1568 ATOM 32 1 Symbol
1569 ATOM 32 > 1 Vector of Symbols
1570 * 16 1 Integer
1571 * 16 > 1 Vector of Integers
1572 * 32 1 if <=16 bits: Integer
1573 if > 16 bits: Cons of top16, bot16
1574 * 32 > 1 Vector of the above
1575
1576 When converting a Lisp number to C, it is assumed to be of format 16 if
1577 it is an integer, and of format 32 if it is a cons of two integers.
1578
1579 When converting a vector of numbers from Lisp to C, it is assumed to be
1580 of format 16 if every element in the vector is an integer, and is assumed
1581 to be of format 32 if any element is a cons of two integers.
1582
1583 When converting an object to C, it may be of the form (SYMBOL . <data>)
1584 where SYMBOL is what we should claim that the type is. Format and
b8d6f4af
JD
1585 representation are as above.
1586
1587 Important: When format is 32, data should contain an array of int,
1588 not an array of long as the X library returns. This makes a difference
1589 when sizeof(long) != sizeof(int). */
ede4db72
RS
1590
1591
1592
1593static Lisp_Object
eec47d6b
DN
1594selection_data_to_lisp_data (Display *display, const unsigned char *data,
1595 int size, Atom type, int format)
ede4db72 1596{
5c3a351a 1597 struct x_display_info *dpyinfo = x_display_info_for_display (display);
ede4db72 1598
5c3a351a 1599 if (type == dpyinfo->Xatom_NULL)
ede4db72
RS
1600 return QNULL;
1601
1602 /* Convert any 8-bit data to a string, for compactness. */
1603 else if (format == 8)
e6c7c988 1604 {
e57ad4d8
KH
1605 Lisp_Object str, lispy_type;
1606
1607 str = make_unibyte_string ((char *) data, size);
1608 /* Indicate that this string is from foreign selection by a text
1609 property `foreign-selection' so that the caller of
1610 x-get-selection-internal (usually x-get-selection) can know
1611 that the string must be decode. */
1612 if (type == dpyinfo->Xatom_COMPOUND_TEXT)
1613 lispy_type = QCOMPOUND_TEXT;
1614 else if (type == dpyinfo->Xatom_UTF8_STRING)
1615 lispy_type = QUTF8_STRING;
e6c7c988 1616 else
e57ad4d8
KH
1617 lispy_type = QSTRING;
1618 Fput_text_property (make_number (0), make_number (size),
1619 Qforeign_selection, lispy_type, str);
e6c7c988
KH
1620 return str;
1621 }
ede4db72 1622 /* Convert a single atom to a Lisp_Symbol. Convert a set of atoms to
e067f0c1
CY
1623 a vector of symbols. */
1624 else if (type == XA_ATOM
1625 /* Treat ATOM_PAIR type similar to list of atoms. */
1626 || type == dpyinfo->Xatom_ATOM_PAIR)
ede4db72
RS
1627 {
1628 int i;
b8d6f4af
JD
1629 /* On a 64 bit machine sizeof(Atom) == sizeof(long) == 8.
1630 But the callers of these function has made sure the data for
1631 format == 32 is an array of int. Thus, use int instead
1632 of Atom. */
1633 int *idata = (int *) data;
1634
1635 if (size == sizeof (int))
1636 return x_atom_to_symbol (display, (Atom) idata[0]);
ede4db72
RS
1637 else
1638 {
b8d6f4af 1639 Lisp_Object v = Fmake_vector (make_number (size / sizeof (int)),
e607a484 1640 make_number (0));
b8d6f4af 1641 for (i = 0; i < size / sizeof (int); i++)
e607a484 1642 Faset (v, make_number (i),
b8d6f4af 1643 x_atom_to_symbol (display, (Atom) idata[i]));
ede4db72
RS
1644 return v;
1645 }
1646 }
1647
1ad08acd
RS
1648 /* Convert a single 16-bit number or a small 32-bit number to a Lisp_Int.
1649 If the number is 32 bits and won't fit in a Lisp_Int,
1650 convert it to a cons of integers, 16 bits in each half.
ede4db72 1651 */
2f51feb8
AS
1652 else if (format == 32 && size == sizeof (int))
1653 return long_to_cons (((unsigned int *) data) [0]);
ede4db72
RS
1654 else if (format == 16 && size == sizeof (short))
1655 return make_number ((int) (((unsigned short *) data) [0]));
1656
1657 /* Convert any other kind of data to a vector of numbers, represented
1658 as above (as an integer, or a cons of two 16 bit integers.)
1659 */
1660 else if (format == 16)
1661 {
1662 int i;
937a3875
RS
1663 Lisp_Object v;
1664 v = Fmake_vector (make_number (size / 2), make_number (0));
1665 for (i = 0; i < size / 2; i++)
ede4db72
RS
1666 {
1667 int j = (int) ((unsigned short *) data) [i];
e607a484 1668 Faset (v, make_number (i), make_number (j));
ede4db72
RS
1669 }
1670 return v;
1671 }
1672 else
1673 {
1674 int i;
e607a484 1675 Lisp_Object v = Fmake_vector (make_number (size / 4), make_number (0));
ede4db72
RS
1676 for (i = 0; i < size / 4; i++)
1677 {
2f51feb8 1678 unsigned int j = ((unsigned int *) data) [i];
e607a484 1679 Faset (v, make_number (i), long_to_cons (j));
ede4db72
RS
1680 }
1681 return v;
1682 }
1683}
1684
1685
4feb31b2 1686/* Use xfree, not XFree, to free the data obtained with this function. */
0158abbc 1687
ede4db72 1688static void
d5a3eaaf
AS
1689lisp_data_to_selection_data (Display *display, Lisp_Object obj,
1690 unsigned char **data_ret, Atom *type_ret,
1691 unsigned int *size_ret,
1692 int *format_ret, int *nofree_ret)
ede4db72
RS
1693{
1694 Lisp_Object type = Qnil;
5c3a351a 1695 struct x_display_info *dpyinfo = x_display_info_for_display (display);
aca39f42
RS
1696
1697 *nofree_ret = 0;
1698
8e713be6 1699 if (CONSP (obj) && SYMBOLP (XCAR (obj)))
ede4db72 1700 {
8e713be6
KR
1701 type = XCAR (obj);
1702 obj = XCDR (obj);
1703 if (CONSP (obj) && NILP (XCDR (obj)))
1704 obj = XCAR (obj);
ede4db72
RS
1705 }
1706
1707 if (EQ (obj, QNULL) || (EQ (type, QNULL)))
1708 { /* This is not the same as declining */
1709 *format_ret = 32;
1710 *size_ret = 0;
1711 *data_ret = 0;
1712 type = QNULL;
1713 }
1714 else if (STRINGP (obj))
1715 {
1bd70c6e
KH
1716 if (SCHARS (obj) < SBYTES (obj))
1717 /* OBJ is a multibyte string containing a non-ASCII char. */
4d30ce50 1718 signal_error ("Non-ASCII string must be encoded in advance", obj);
7b9ae523 1719 if (NILP (type))
5109c8dd
KH
1720 type = QSTRING;
1721 *format_ret = 8;
1722 *size_ret = SBYTES (obj);
1723 *data_ret = SDATA (obj);
1724 *nofree_ret = 1;
ede4db72
RS
1725 }
1726 else if (SYMBOLP (obj))
1727 {
1728 *format_ret = 32;
1729 *size_ret = 1;
1730 *data_ret = (unsigned char *) xmalloc (sizeof (Atom) + 1);
1731 (*data_ret) [sizeof (Atom)] = 0;
a9f737ee 1732 (*(Atom **) data_ret) [0] = symbol_to_x_atom (dpyinfo, obj);
ede4db72
RS
1733 if (NILP (type)) type = QATOM;
1734 }
7da64e5c 1735 else if (INTEGERP (obj)
ede4db72
RS
1736 && XINT (obj) < 0xFFFF
1737 && XINT (obj) > -0xFFFF)
1738 {
1739 *format_ret = 16;
1740 *size_ret = 1;
1741 *data_ret = (unsigned char *) xmalloc (sizeof (short) + 1);
1742 (*data_ret) [sizeof (short)] = 0;
1743 (*(short **) data_ret) [0] = (short) XINT (obj);
1744 if (NILP (type)) type = QINTEGER;
1745 }
a87ed99c 1746 else if (INTEGERP (obj)
8e713be6
KR
1747 || (CONSP (obj) && INTEGERP (XCAR (obj))
1748 && (INTEGERP (XCDR (obj))
1749 || (CONSP (XCDR (obj))
1750 && INTEGERP (XCAR (XCDR (obj)))))))
ede4db72
RS
1751 {
1752 *format_ret = 32;
1753 *size_ret = 1;
1754 *data_ret = (unsigned char *) xmalloc (sizeof (long) + 1);
1755 (*data_ret) [sizeof (long)] = 0;
1756 (*(unsigned long **) data_ret) [0] = cons_to_long (obj);
1757 if (NILP (type)) type = QINTEGER;
1758 }
1759 else if (VECTORP (obj))
1760 {
1761 /* Lisp_Vectors may represent a set of ATOMs;
1762 a set of 16 or 32 bit INTEGERs;
1763 or a set of ATOM_PAIRs (represented as [[A1 A2] [A3 A4] ...]
1764 */
1765 int i;
1766
1767 if (SYMBOLP (XVECTOR (obj)->contents [0]))
1768 /* This vector is an ATOM set */
1769 {
1770 if (NILP (type)) type = QATOM;
77b37c05 1771 *size_ret = ASIZE (obj);
ede4db72 1772 *format_ret = 32;
ede4db72 1773 for (i = 0; i < *size_ret; i++)
e067f0c1 1774 if (!SYMBOLP (XVECTOR (obj)->contents [i]))
4d30ce50 1775 signal_error ("All elements of selection vector must have same type", obj);
1b65481e 1776
e067f0c1
CY
1777 *data_ret = (unsigned char *) xmalloc ((*size_ret) * sizeof (Atom));
1778 for (i = 0; i < *size_ret; i++)
1779 (*(Atom **) data_ret) [i]
a9f737ee 1780 = symbol_to_x_atom (dpyinfo, XVECTOR (obj)->contents [i]);
ede4db72 1781 }
ede4db72
RS
1782 else
1783 /* This vector is an INTEGER set, or something like it */
1784 {
e22cf39c 1785 int data_size = 2;
77b37c05 1786 *size_ret = ASIZE (obj);
ede4db72
RS
1787 if (NILP (type)) type = QINTEGER;
1788 *format_ret = 16;
1789 for (i = 0; i < *size_ret; i++)
1790 if (CONSP (XVECTOR (obj)->contents [i]))
1791 *format_ret = 32;
7da64e5c 1792 else if (!INTEGERP (XVECTOR (obj)->contents [i]))
4d30ce50
KS
1793 signal_error (/* Qselection_error */
1794 "Elements of selection vector must be integers or conses of integers",
1795 obj);
ede4db72 1796
e22cf39c
JD
1797 /* Use sizeof(long) even if it is more than 32 bits. See comment
1798 in x_get_window_property and x_fill_property_data. */
6e816df5 1799
e22cf39c
JD
1800 if (*format_ret == 32) data_size = sizeof(long);
1801 *data_ret = (unsigned char *) xmalloc (*size_ret * data_size);
ede4db72
RS
1802 for (i = 0; i < *size_ret; i++)
1803 if (*format_ret == 32)
1804 (*((unsigned long **) data_ret)) [i]
1805 = cons_to_long (XVECTOR (obj)->contents [i]);
1806 else
1807 (*((unsigned short **) data_ret)) [i]
1808 = (unsigned short) cons_to_long (XVECTOR (obj)->contents [i]);
1809 }
1810 }
1811 else
4d30ce50 1812 signal_error (/* Qselection_error */ "Unrecognized selection data", obj);
ede4db72 1813
a9f737ee 1814 *type_ret = symbol_to_x_atom (dpyinfo, type);
ede4db72
RS
1815}
1816
1817static Lisp_Object
971de7fb 1818clean_local_selection_data (Lisp_Object obj)
ede4db72
RS
1819{
1820 if (CONSP (obj)
8e713be6
KR
1821 && INTEGERP (XCAR (obj))
1822 && CONSP (XCDR (obj))
1823 && INTEGERP (XCAR (XCDR (obj)))
1824 && NILP (XCDR (XCDR (obj))))
1825 obj = Fcons (XCAR (obj), XCDR (obj));
ede4db72
RS
1826
1827 if (CONSP (obj)
8e713be6
KR
1828 && INTEGERP (XCAR (obj))
1829 && INTEGERP (XCDR (obj)))
ede4db72 1830 {
8e713be6
KR
1831 if (XINT (XCAR (obj)) == 0)
1832 return XCDR (obj);
1833 if (XINT (XCAR (obj)) == -1)
1834 return make_number (- XINT (XCDR (obj)));
ede4db72
RS
1835 }
1836 if (VECTORP (obj))
1837 {
1838 int i;
77b37c05 1839 int size = ASIZE (obj);
ede4db72
RS
1840 Lisp_Object copy;
1841 if (size == 1)
1842 return clean_local_selection_data (XVECTOR (obj)->contents [0]);
e607a484 1843 copy = Fmake_vector (make_number (size), Qnil);
ede4db72
RS
1844 for (i = 0; i < size; i++)
1845 XVECTOR (copy)->contents [i]
1846 = clean_local_selection_data (XVECTOR (obj)->contents [i]);
1847 return copy;
1848 }
1849 return obj;
1850}
1851\f
1852/* Called from XTread_socket to handle SelectionNotify events.
606140dd
KH
1853 If it's the selection we are waiting for, stop waiting
1854 by setting the car of reading_selection_reply to non-nil.
1855 We store t there if the reply is successful, lambda if not. */
ede4db72
RS
1856
1857void
971de7fb 1858x_handle_selection_notify (XSelectionEvent *event)
ede4db72 1859{
5d0ba25b 1860 if (event->requestor != reading_selection_window)
ede4db72
RS
1861 return;
1862 if (event->selection != reading_which_selection)
1863 return;
1864
d9c0d4a3 1865 TRACE0 ("Received SelectionNotify");
f3fbd155
KR
1866 XSETCAR (reading_selection_reply,
1867 (event->property != 0 ? Qt : Qlambda));
ede4db72
RS
1868}
1869
1870\f
a9f737ee
CY
1871/* From a Lisp_Object, return a suitable frame for selection
1872 operations. OBJECT may be a frame, a terminal object, or nil
1873 (which stands for the selected frame--or, if that is not an X
1874 frame, the first X display on the list). If no suitable frame can
1875 be found, return NULL. */
1876
1877static struct frame *
1878frame_for_x_selection (Lisp_Object object)
1879{
fb1ac845 1880 Lisp_Object tail;
a9f737ee
CY
1881 struct frame *f;
1882
1883 if (NILP (object))
1884 {
1885 f = XFRAME (selected_frame);
1886 if (FRAME_X_P (f) && FRAME_LIVE_P (f))
1887 return f;
1888
1889 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1890 {
1891 f = XFRAME (XCAR (tail));
1892 if (FRAME_X_P (f) && FRAME_LIVE_P (f))
1893 return f;
1894 }
1895 }
1896 else if (TERMINALP (object))
1897 {
1898 struct terminal *t = get_terminal (object, 1);
1899 if (t->type == output_x_window)
1900 {
1901 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1902 {
1903 f = XFRAME (XCAR (tail));
1904 if (FRAME_LIVE_P (f) && f->terminal == t)
1905 return f;
1906 }
1907 }
1908 }
1909 else if (FRAMEP (object))
1910 {
1911 f = XFRAME (object);
1912 if (FRAME_X_P (f) && FRAME_LIVE_P (f))
1913 return f;
1914 }
1915
1916 return NULL;
1917}
1918
1919
a0d76c27 1920DEFUN ("x-own-selection-internal", Fx_own_selection_internal,
a9f737ee 1921 Sx_own_selection_internal, 2, 3, 0,
abb71cf4
CY
1922 doc: /* Assert an X selection of type SELECTION and value VALUE.
1923SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
8c1a1077
PJ
1924\(Those are literal upper-case symbol names, since that's what X expects.)
1925VALUE is typically a string, or a cons of two markers, but may be
a9f737ee
CY
1926anything that the functions on `selection-converter-alist' know about.
1927
1928FRAME should be a frame that should own the selection. If omitted or
1929nil, it defaults to the selected frame. */)
1930 (Lisp_Object selection, Lisp_Object value, Lisp_Object frame)
ede4db72 1931{
a9f737ee
CY
1932 if (NILP (frame)) frame = selected_frame;
1933 if (!FRAME_LIVE_P (XFRAME (frame)) || !FRAME_X_P (XFRAME (frame)))
1934 error ("X selection unavailable for this frame");
1935
abb71cf4
CY
1936 CHECK_SYMBOL (selection);
1937 if (NILP (value)) error ("VALUE may not be nil");
a9f737ee 1938 x_own_selection (selection, value, frame);
abb71cf4 1939 return value;
ede4db72
RS
1940}
1941
1942
1943/* Request the selection value from the owner. If we are the owner,
1944 simply return our selection value. If we are not the owner, this
1945 will block until all of the data has arrived. */
1946
a0d76c27 1947DEFUN ("x-get-selection-internal", Fx_get_selection_internal,
a9f737ee 1948 Sx_get_selection_internal, 2, 4, 0,
8c1a1077
PJ
1949 doc: /* Return text selected from some X window.
1950SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
1951\(Those are literal upper-case symbol names, since that's what X expects.)
3a42401d
JD
1952TYPE is the type of data desired, typically `STRING'.
1953TIME_STAMP is the time to use in the XConvertSelection call for foreign
a9f737ee
CY
1954selections. If omitted, defaults to the time for the last event.
1955
1956TERMINAL should be a terminal object or a frame specifying the X
1957server to query. If omitted or nil, that stands for the selected
1958frame's display, or the first available X display. */)
1959 (Lisp_Object selection_symbol, Lisp_Object target_type,
1960 Lisp_Object time_stamp, Lisp_Object terminal)
ede4db72
RS
1961{
1962 Lisp_Object val = Qnil;
1963 struct gcpro gcpro1, gcpro2;
a9f737ee 1964 struct frame *f = frame_for_x_selection (terminal);
ede4db72 1965 GCPRO2 (target_type, val); /* we store newly consed data into these */
a9f737ee 1966
b7826503 1967 CHECK_SYMBOL (selection_symbol);
a9f737ee
CY
1968 CHECK_SYMBOL (target_type);
1969 if (EQ (target_type, QMULTIPLE))
1970 error ("Retrieving MULTIPLE selections is currently unimplemented");
1971 if (!f)
1972 error ("X selection unavailable for this frame");
1973
1974 val = x_get_local_selection (selection_symbol, target_type, 1,
1975 FRAME_X_DISPLAY_INFO (f));
ede4db72 1976
a9f737ee 1977 if (NILP (val) && FRAME_LIVE_P (f))
ede4db72 1978 {
a9f737ee
CY
1979 Lisp_Object frame;
1980 XSETFRAME (frame, f);
1981 RETURN_UNGCPRO (x_get_foreign_selection (selection_symbol, target_type,
1982 time_stamp, frame));
ede4db72 1983 }
ede4db72 1984
abb71cf4 1985 if (CONSP (val) && SYMBOLP (XCAR (val)))
ede4db72 1986 {
8e713be6
KR
1987 val = XCDR (val);
1988 if (CONSP (val) && NILP (XCDR (val)))
1989 val = XCAR (val);
ede4db72 1990 }
abb71cf4 1991 RETURN_UNGCPRO (clean_local_selection_data (val));
ede4db72
RS
1992}
1993
a0d76c27 1994DEFUN ("x-disown-selection-internal", Fx_disown_selection_internal,
a9f737ee 1995 Sx_disown_selection_internal, 1, 3, 0,
8c1a1077 1996 doc: /* If we own the selection SELECTION, disown it.
a9f737ee
CY
1997Disowning it means there is no such selection.
1998
1999TERMINAL should be a terminal object or a frame specifying the X
2000server to query. If omitted or nil, that stands for the selected
2001frame's display, or the first available X display. */)
2002 (Lisp_Object selection, Lisp_Object time_object, Lisp_Object terminal)
ede4db72 2003{
ede4db72
RS
2004 Time timestamp;
2005 Atom selection_atom;
31df61d6
AS
2006 union {
2007 struct selection_input_event sie;
2008 struct input_event ie;
2009 } event;
a9f737ee 2010 struct frame *f = frame_for_x_selection (terminal);
5c3a351a 2011 struct x_display_info *dpyinfo;
ede4db72 2012
a9f737ee 2013 if (!f)
428a555e
KL
2014 return Qnil;
2015
a9f737ee 2016 dpyinfo = FRAME_X_DISPLAY_INFO (f);
b7826503 2017 CHECK_SYMBOL (selection);
ede4db72 2018
a9f737ee
CY
2019 /* Don't disown the selection when we're not the owner. */
2020 if (NILP (LOCAL_SELECTION (selection, dpyinfo)))
2021 return Qnil;
ede4db72 2022
a9f737ee 2023 selection_atom = symbol_to_x_atom (dpyinfo, selection);
ede4db72
RS
2024
2025 BLOCK_INPUT;
a9f737ee
CY
2026 timestamp = (NILP (time_object) ? last_event_timestamp
2027 : cons_to_long (time_object));
2028 XSetSelectionOwner (dpyinfo->display, selection_atom, None, timestamp);
ede4db72
RS
2029 UNBLOCK_INPUT;
2030
eb8c3be9 2031 /* It doesn't seem to be guaranteed that a SelectionClear event will be
ede4db72
RS
2032 generated for a window which owns the selection when that window sets
2033 the selection owner to None. The NCD server does, the MIT Sun4 server
2034 doesn't. So we synthesize one; this means we might get two, but
2035 that's ok, because the second one won't have any effect. */
a9f737ee 2036 SELECTION_EVENT_DISPLAY (&event.sie) = dpyinfo->display;
31df61d6
AS
2037 SELECTION_EVENT_SELECTION (&event.sie) = selection_atom;
2038 SELECTION_EVENT_TIME (&event.sie) = timestamp;
2039 x_handle_selection_clear (&event.ie);
ede4db72
RS
2040
2041 return Qt;
2042}
2043
ede4db72 2044DEFUN ("x-selection-owner-p", Fx_selection_owner_p, Sx_selection_owner_p,
a9f737ee 2045 0, 2, 0,
8c1a1077
PJ
2046 doc: /* Whether the current Emacs process owns the given X Selection.
2047The arg should be the name of the selection in question, typically one of
2048the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
2049\(Those are literal upper-case symbol names, since that's what X expects.)
2050For convenience, the symbol nil is the same as `PRIMARY',
a9f737ee
CY
2051and t is the same as `SECONDARY'.
2052
2053TERMINAL should be a terminal object or a frame specifying the X
2054server to query. If omitted or nil, that stands for the selected
2055frame's display, or the first available X display. */)
2056 (Lisp_Object selection, Lisp_Object terminal)
ede4db72 2057{
a9f737ee
CY
2058 struct frame *f = frame_for_x_selection (terminal);
2059
b7826503 2060 CHECK_SYMBOL (selection);
ede4db72
RS
2061 if (EQ (selection, Qnil)) selection = QPRIMARY;
2062 if (EQ (selection, Qt)) selection = QSECONDARY;
1b65481e 2063
a9f737ee
CY
2064 if (f && !NILP (LOCAL_SELECTION (selection, FRAME_X_DISPLAY_INFO (f))))
2065 return Qt;
2066 else
ede4db72 2067 return Qnil;
ede4db72
RS
2068}
2069
2070DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
a9f737ee
CY
2071 0, 2, 0,
2072 doc: /* Whether there is an owner for the given X selection.
2073SELECTION should be the name of the selection in question, typically
2074one of the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'. (X expects
2075these literal upper-case names.) The symbol nil is the same as
2076`PRIMARY', and t is the same as `SECONDARY'.
2077
2078TERMINAL should be a terminal object or a frame specifying the X
2079server to query. If omitted or nil, that stands for the selected
2080frame's display, or the first available X display. */)
2081 (Lisp_Object selection, Lisp_Object terminal)
ede4db72
RS
2082{
2083 Window owner;
356ba514 2084 Atom atom;
a9f737ee
CY
2085 struct frame *f = frame_for_x_selection (terminal);
2086 struct x_display_info *dpyinfo;
b8c70430 2087
b7826503 2088 CHECK_SYMBOL (selection);
356ba514
RS
2089 if (EQ (selection, Qnil)) selection = QPRIMARY;
2090 if (EQ (selection, Qt)) selection = QSECONDARY;
a9f737ee
CY
2091
2092 if (!f)
356ba514 2093 return Qnil;
a9f737ee
CY
2094
2095 dpyinfo = FRAME_X_DISPLAY_INFO (f);
2096
2097 if (!NILP (LOCAL_SELECTION (selection, dpyinfo)))
2098 return Qt;
2099
2100 atom = symbol_to_x_atom (dpyinfo, selection);
2101 if (atom == 0) return Qnil;
ede4db72 2102 BLOCK_INPUT;
a9f737ee 2103 owner = XGetSelectionOwner (dpyinfo->display, atom);
ede4db72
RS
2104 UNBLOCK_INPUT;
2105 return (owner ? Qt : Qnil);
2106}
2107
a9f737ee
CY
2108/* Send the clipboard manager a SAVE_TARGETS request with a
2109 UTF8_STRING property, as described by
2110 http://www.freedesktop.org/wiki/ClipboardManager */
2111
fb1ac845 2112static void
a9f737ee
CY
2113x_clipboard_manager_save (struct x_display_info *dpyinfo,
2114 Lisp_Object frame)
2115{
2116 struct frame *f = XFRAME (frame);
2117 Atom data = dpyinfo->Xatom_UTF8_STRING;
2118
2119 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2120 dpyinfo->Xatom_EMACS_TMP,
2121 dpyinfo->Xatom_ATOM, 32, PropModeReplace,
2122 (unsigned char *) &data, 1);
2123 x_get_foreign_selection (QCLIPBOARD_MANAGER, QSAVE_TARGETS,
2124 Qnil, frame);
2125}
2126
2127DEFUN ("x-clipboard-manager-save", Fx_clipboard_manager_save,
2128 Sx_clipboard_manager_save, 0, 1, 0,
2129 doc: /* Save the clipboard contents to the clipboard manager.
2130This function is intended to run from `delete-frame-functions' and
2131`kill-emacs-hook', to transfer clipboard data owned by Emacs to a
2132clipboard manager prior to deleting a frame or killing Emacs.
2133
2134FRAME specifies a frame owning a clipboard; do nothing if FRAME does
2135not own the clipboard, or if no clipboard manager is present. If
2136FRAME is nil, save all clipboard contents owned by Emacs. */)
2137 (Lisp_Object frame)
2138{
2139 if (FRAMEP (frame))
2140 {
2141 struct frame *f = XFRAME (frame);
2142 if (FRAME_LIVE_P (f) && FRAME_X_P (f))
2143 {
2144 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2145 Lisp_Object local_selection
2146 = LOCAL_SELECTION (QCLIPBOARD, dpyinfo);
2147
2148 if (!NILP (local_selection)
2149 && EQ (frame, XCAR (XCDR (XCDR (XCDR (local_selection)))))
2150 && XGetSelectionOwner (dpyinfo->display,
2151 dpyinfo->Xatom_CLIPBOARD_MANAGER))
2152 x_clipboard_manager_save (dpyinfo, frame);
2153 }
2154 }
2155 else if (NILP (frame))
2156 {
2157 /* Loop through all X displays, saving owned clipboards. */
2158 struct x_display_info *dpyinfo;
fb1ac845 2159 Lisp_Object local_selection, local_frame;
a9f737ee
CY
2160 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
2161 {
2162 local_selection = LOCAL_SELECTION (QCLIPBOARD, dpyinfo);
2163 if (NILP (local_selection)
2164 || !XGetSelectionOwner (dpyinfo->display,
2165 dpyinfo->Xatom_CLIPBOARD_MANAGER))
2166 continue;
2167
fb1ac845
PE
2168 local_frame = XCAR (XCDR (XCDR (XCDR (local_selection))));
2169 if (FRAME_LIVE_P (XFRAME (local_frame)))
2170 x_clipboard_manager_save (dpyinfo, local_frame);
a9f737ee
CY
2171 }
2172 }
2173
2174 return Qnil;
2175}
2176
ede4db72 2177\f
1fb3821b
JD
2178/***********************************************************************
2179 Drag and drop support
2180***********************************************************************/
2181/* Check that lisp values are of correct type for x_fill_property_data.
2182 That is, number, string or a cons with two numbers (low and high 16
44f730c8
PE
2183 bit parts of a 32 bit number). Return the number of items in DATA,
2184 or -1 if there is an error. */
1fb3821b
JD
2185
2186int
971de7fb 2187x_check_property_data (Lisp_Object data)
1fb3821b
JD
2188{
2189 Lisp_Object iter;
2190 int size = 0;
2191
44f730c8 2192 for (iter = data; CONSP (iter); iter = XCDR (iter))
1fb3821b
JD
2193 {
2194 Lisp_Object o = XCAR (iter);
2195
2196 if (! NUMBERP (o) && ! STRINGP (o) && ! CONSP (o))
44f730c8 2197 return -1;
1fb3821b
JD
2198 else if (CONSP (o) &&
2199 (! NUMBERP (XCAR (o)) || ! NUMBERP (XCDR (o))))
44f730c8
PE
2200 return -1;
2201 size++;
1fb3821b
JD
2202 }
2203
2204 return size;
2205}
2206
2207/* Convert lisp values to a C array. Values may be a number, a string
2208 which is taken as an X atom name and converted to the atom value, or
2209 a cons containing the two 16 bit parts of a 32 bit number.
2210
2211 DPY is the display use to look up X atoms.
2212 DATA is a Lisp list of values to be converted.
2213 RET is the C array that contains the converted values. It is assumed
ff59904a 2214 it is big enough to hold all values.
e22cf39c
JD
2215 FORMAT is 8, 16 or 32 and denotes char/short/long for each C value to
2216 be stored in RET. Note that long is used for 32 even if long is more
2217 than 32 bits (see man pages for XChangeProperty, XGetWindowProperty and
2218 XClientMessageEvent). */
1fb3821b
JD
2219
2220void
971de7fb 2221x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format)
1fb3821b 2222{
e22cf39c
JD
2223 long val;
2224 long *d32 = (long *) ret;
2225 short *d16 = (short *) ret;
2226 char *d08 = (char *) ret;
1fb3821b
JD
2227 Lisp_Object iter;
2228
2229 for (iter = data; CONSP (iter); iter = XCDR (iter))
2230 {
2231 Lisp_Object o = XCAR (iter);
2232
2233 if (INTEGERP (o))
e22cf39c 2234 val = (long) XFASTINT (o);
1fb3821b 2235 else if (FLOATP (o))
e22cf39c 2236 val = (long) XFLOAT_DATA (o);
1fb3821b 2237 else if (CONSP (o))
e22cf39c 2238 val = (long) cons_to_long (o);
1fb3821b
JD
2239 else if (STRINGP (o))
2240 {
2241 BLOCK_INPUT;
51b59d79 2242 val = (long) XInternAtom (dpy, SSDATA (o), False);
1fb3821b
JD
2243 UNBLOCK_INPUT;
2244 }
2245 else
2246 error ("Wrong type, must be string, number or cons");
2247
2248 if (format == 8)
e22cf39c 2249 *d08++ = (char) val;
1fb3821b 2250 else if (format == 16)
e22cf39c 2251 *d16++ = (short) val;
1fb3821b
JD
2252 else
2253 *d32++ = val;
2254 }
2255}
2256
2257/* Convert an array of C values to a Lisp list.
2258 F is the frame to be used to look up X atoms if the TYPE is XA_ATOM.
2259 DATA is a C array of values to be converted.
2260 TYPE is the type of the data. Only XA_ATOM is special, it converts
2261 each number in DATA to its corresponfing X atom as a symbol.
2262 FORMAT is 8, 16 or 32 and gives the size in bits for each C value to
2263 be stored in RET.
2264 SIZE is the number of elements in DATA.
2265
b8d6f4af
JD
2266 Important: When format is 32, data should contain an array of int,
2267 not an array of long as the X library returns. This makes a difference
2268 when sizeof(long) != sizeof(int).
2269
1fb3821b
JD
2270 Also see comment for selection_data_to_lisp_data above. */
2271
2272Lisp_Object
eec47d6b
DN
2273x_property_data_to_lisp (struct frame *f, const unsigned char *data,
2274 Atom type, int format, long unsigned int size)
1fb3821b
JD
2275{
2276 return selection_data_to_lisp_data (FRAME_X_DISPLAY (f),
2277 data, size*format/8, type, format);
2278}
2279
31f16913 2280/* Get the mouse position in frame relative coordinates. */
1fb3821b
JD
2281
2282static void
971de7fb 2283mouse_position_for_drop (FRAME_PTR f, int *x, int *y)
1fb3821b
JD
2284{
2285 Window root, dummy_window;
2286 int dummy;
2287
2288 BLOCK_INPUT;
2289
2290 XQueryPointer (FRAME_X_DISPLAY (f),
2291 DefaultRootWindow (FRAME_X_DISPLAY (f)),
2292
2293 /* The root window which contains the pointer. */
2294 &root,
2295
2296 /* Window pointer is on, not used */
2297 &dummy_window,
2298
2299 /* The position on that root window. */
2300 x, y,
2301
2302 /* x/y in dummy_window coordinates, not used. */
2303 &dummy, &dummy,
2304
2305 /* Modifier keys and pointer buttons, about which
2306 we don't care. */
2307 (unsigned int *) &dummy);
2308
2309
2310 /* Absolute to relative. */
2311 *x -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
2312 *y -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
2313
2314 UNBLOCK_INPUT;
2315}
2316
2317DEFUN ("x-get-atom-name", Fx_get_atom_name,
2318 Sx_get_atom_name, 1, 2, 0,
2319 doc: /* Return the X atom name for VALUE as a string.
2320VALUE may be a number or a cons where the car is the upper 16 bits and
2321the cdr is the lower 16 bits of a 32 bit value.
2322Use the display for FRAME or the current frame if FRAME is not given or nil.
2323
2324If the value is 0 or the atom is not known, return the empty string. */)
5842a27b 2325 (Lisp_Object value, Lisp_Object frame)
1fb3821b
JD
2326{
2327 struct frame *f = check_x_frame (frame);
2328 char *name = 0;
42ca4633 2329 char empty[] = "";
1fb3821b 2330 Lisp_Object ret = Qnil;
1fb3821b
JD
2331 Display *dpy = FRAME_X_DISPLAY (f);
2332 Atom atom;
c525d842 2333 int had_errors;
1fb3821b
JD
2334
2335 if (INTEGERP (value))
2336 atom = (Atom) XUINT (value);
2337 else if (FLOATP (value))
ff59904a 2338 atom = (Atom) XFLOAT_DATA (value);
1fb3821b
JD
2339 else if (CONSP (value))
2340 atom = (Atom) cons_to_long (value);
2341 else
2342 error ("Wrong type, value must be number or cons");
2343
2344 BLOCK_INPUT;
9ba8e10d 2345 x_catch_errors (dpy);
42ca4633 2346 name = atom ? XGetAtomName (dpy, atom) : empty;
c525d842
CY
2347 had_errors = x_had_errors_p (dpy);
2348 x_uncatch_errors ();
1fb3821b 2349
c525d842 2350 if (!had_errors)
1fb3821b
JD
2351 ret = make_string (name, strlen (name));
2352
1fb3821b 2353 if (atom && name) XFree (name);
8b3ad112 2354 if (NILP (ret)) ret = empty_unibyte_string;
1fb3821b
JD
2355
2356 UNBLOCK_INPUT;
2357
2358 return ret;
2359}
2360
9fc68699
JD
2361DEFUN ("x-register-dnd-atom", Fx_register_dnd_atom,
2362 Sx_register_dnd_atom, 1, 2, 0,
2363 doc: /* Request that dnd events are made for ClientMessages with ATOM.
2364ATOM can be a symbol or a string. The ATOM is interned on the display that
2365FRAME is on. If FRAME is nil, the selected frame is used. */)
5842a27b 2366 (Lisp_Object atom, Lisp_Object frame)
9fc68699
JD
2367{
2368 Atom x_atom;
2369 struct frame *f = check_x_frame (frame);
2370 size_t i;
2371 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2372
2373
2374 if (SYMBOLP (atom))
a9f737ee 2375 x_atom = symbol_to_x_atom (dpyinfo, atom);
9fc68699
JD
2376 else if (STRINGP (atom))
2377 {
2378 BLOCK_INPUT;
51b59d79 2379 x_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (atom), False);
9fc68699
JD
2380 UNBLOCK_INPUT;
2381 }
2382 else
2383 error ("ATOM must be a symbol or a string");
2384
db9cd97a 2385 for (i = 0; i < dpyinfo->x_dnd_atoms_length; ++i)
9fc68699
JD
2386 if (dpyinfo->x_dnd_atoms[i] == x_atom)
2387 return Qnil;
2388
db9cd97a 2389 if (dpyinfo->x_dnd_atoms_length == dpyinfo->x_dnd_atoms_size)
9fc68699
JD
2390 {
2391 dpyinfo->x_dnd_atoms_size *= 2;
2392 dpyinfo->x_dnd_atoms = xrealloc (dpyinfo->x_dnd_atoms,
2393 sizeof (*dpyinfo->x_dnd_atoms)
2394 * dpyinfo->x_dnd_atoms_size);
2395 }
2396
2397 dpyinfo->x_dnd_atoms[dpyinfo->x_dnd_atoms_length++] = x_atom;
2398 return Qnil;
2399}
2400
2401/* Convert an XClientMessageEvent to a Lisp event of type DRAG_N_DROP_EVENT. */
1fb3821b
JD
2402
2403int
971de7fb 2404x_handle_dnd_message (struct frame *f, XClientMessageEvent *event, struct x_display_info *dpyinfo, struct input_event *bufp)
1fb3821b
JD
2405{
2406 Lisp_Object vec;
2407 Lisp_Object frame;
e22cf39c
JD
2408 /* format 32 => size 5, format 16 => size 10, format 8 => size 20 */
2409 unsigned long size = 160/event->format;
1fb3821b 2410 int x, y;
31f16913
JD
2411 unsigned char *data = (unsigned char *) event->data.b;
2412 int idata[5];
9fc68699
JD
2413 size_t i;
2414
db9cd97a 2415 for (i = 0; i < dpyinfo->x_dnd_atoms_length; ++i)
9fc68699
JD
2416 if (dpyinfo->x_dnd_atoms[i] == event->message_type) break;
2417
2418 if (i == dpyinfo->x_dnd_atoms_length) return 0;
1fb3821b
JD
2419
2420 XSETFRAME (frame, f);
2421
31f16913
JD
2422 /* On a 64 bit machine, the event->data.l array members are 64 bits (long),
2423 but the x_property_data_to_lisp (or rather selection_data_to_lisp_data)
2424 function expects them to be of size int (i.e. 32). So to be able to
2425 use that function, put the data in the form it expects if format is 32. */
2426
2172544b 2427 if (32 < BITS_PER_LONG && event->format == 32)
31f16913 2428 {
31f16913
JD
2429 for (i = 0; i < 5; ++i) /* There are only 5 longs in a ClientMessage. */
2430 idata[i] = (int) event->data.l[i];
2431 data = (unsigned char *) idata;
2432 }
2433
d2f14999 2434 vec = Fmake_vector (make_number (4), Qnil);
3ae565b3
SM
2435 ASET (vec, 0, SYMBOL_NAME (x_atom_to_symbol (FRAME_X_DISPLAY (f),
2436 event->message_type)));
2437 ASET (vec, 1, frame);
2438 ASET (vec, 2, make_number (event->format));
2439 ASET (vec, 3, x_property_data_to_lisp (f,
2440 data,
2441 event->message_type,
2442 event->format,
2443 size));
1fb3821b
JD
2444
2445 mouse_position_for_drop (f, &x, &y);
2446 bufp->kind = DRAG_N_DROP_EVENT;
862c94ca 2447 bufp->frame_or_window = frame;
1fb3821b
JD
2448 bufp->timestamp = CurrentTime;
2449 bufp->x = make_number (x);
2450 bufp->y = make_number (y);
862c94ca 2451 bufp->arg = vec;
1fb3821b
JD
2452 bufp->modifiers = 0;
2453
2454 return 1;
2455}
2456
2457DEFUN ("x-send-client-message", Fx_send_client_event,
2458 Sx_send_client_message, 6, 6, 0,
2459 doc: /* Send a client message of MESSAGE-TYPE to window DEST on DISPLAY.
2460
2461For DISPLAY, specify either a frame or a display name (a string).
2462If DISPLAY is nil, that stands for the selected frame's display.
2463DEST may be a number, in which case it is a Window id. The value 0 may
2464be used to send to the root window of the DISPLAY.
2465If DEST is a cons, it is converted to a 32 bit number
2466with the high 16 bits from the car and the lower 16 bit from the cdr. That
2467number is then used as a window id.
2468If DEST is a frame the event is sent to the outer window of that frame.
69785ad0 2469A value of nil means the currently selected frame.
1fb3821b
JD
2470If DEST is the string "PointerWindow" the event is sent to the window that
2471contains the pointer. If DEST is the string "InputFocus" the event is
2472sent to the window that has the input focus.
2473FROM is the frame sending the event. Use nil for currently selected frame.
2474MESSAGE-TYPE is the name of an Atom as a string.
2475FORMAT must be one of 8, 16 or 32 and determines the size of the values in
2476bits. VALUES is a list of numbers, cons and/or strings containing the values
2477to send. If a value is a string, it is converted to an Atom and the value of
2478the Atom is sent. If a value is a cons, it is converted to a 32 bit number
2479with the high 16 bits from the car and the lower 16 bit from the cdr.
2480If more values than fits into the event is given, the excessive values
2481are ignored. */)
5842a27b 2482 (Lisp_Object display, Lisp_Object dest, Lisp_Object from, Lisp_Object message_type, Lisp_Object format, Lisp_Object values)
2d9074ba
JD
2483{
2484 struct x_display_info *dpyinfo = check_x_display_info (display);
2485
933e29ff 2486 CHECK_STRING (message_type);
2d9074ba 2487 x_send_client_event(display, dest, from,
933e29ff 2488 XInternAtom (dpyinfo->display,
42a5b22f 2489 SSDATA (message_type),
933e29ff 2490 False),
2d9074ba
JD
2491 format, values);
2492
2493 return Qnil;
2494}
2495
2496void
2497x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from, Atom message_type, Lisp_Object format, Lisp_Object values)
1fb3821b
JD
2498{
2499 struct x_display_info *dpyinfo = check_x_display_info (display);
2500 Window wdest;
2501 XEvent event;
1fb3821b 2502 struct frame *f = check_x_frame (from);
1fb3821b
JD
2503 int to_root;
2504
1fb3821b
JD
2505 CHECK_NUMBER (format);
2506 CHECK_CONS (values);
2507
2508 if (x_check_property_data (values) == -1)
2509 error ("Bad data in VALUES, must be number, cons or string");
2510
2511 event.xclient.type = ClientMessage;
2512 event.xclient.format = XFASTINT (format);
2513
2514 if (event.xclient.format != 8 && event.xclient.format != 16
2515 && event.xclient.format != 32)
2516 error ("FORMAT must be one of 8, 16 or 32");
a0ecb2ac 2517
1fb3821b
JD
2518 if (FRAMEP (dest) || NILP (dest))
2519 {
2520 struct frame *fdest = check_x_frame (dest);
2521 wdest = FRAME_OUTER_WINDOW (fdest);
2522 }
2523 else if (STRINGP (dest))
2524 {
42a5b22f 2525 if (strcmp (SSDATA (dest), "PointerWindow") == 0)
1fb3821b 2526 wdest = PointerWindow;
42a5b22f 2527 else if (strcmp (SSDATA (dest), "InputFocus") == 0)
1fb3821b
JD
2528 wdest = InputFocus;
2529 else
2530 error ("DEST as a string must be one of PointerWindow or InputFocus");
2531 }
2532 else if (INTEGERP (dest))
2533 wdest = (Window) XFASTINT (dest);
2534 else if (FLOATP (dest))
ff59904a 2535 wdest = (Window) XFLOAT_DATA (dest);
1fb3821b
JD
2536 else if (CONSP (dest))
2537 {
2538 if (! NUMBERP (XCAR (dest)) || ! NUMBERP (XCDR (dest)))
2539 error ("Both car and cdr for DEST must be numbers");
2540 else
2541 wdest = (Window) cons_to_long (dest);
2542 }
2543 else
2544 error ("DEST must be a frame, nil, string, number or cons");
2545
2546 if (wdest == 0) wdest = dpyinfo->root_window;
2547 to_root = wdest == dpyinfo->root_window;
2548
1fb3821b
JD
2549 BLOCK_INPUT;
2550
2d9074ba 2551 event.xclient.message_type = message_type;
1fb3821b
JD
2552 event.xclient.display = dpyinfo->display;
2553
2554 /* Some clients (metacity for example) expects sending window to be here
2555 when sending to the root window. */
2556 event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest;
2557
6e816df5 2558
1fb3821b
JD
2559 memset (event.xclient.data.b, 0, sizeof (event.xclient.data.b));
2560 x_fill_property_data (dpyinfo->display, values, event.xclient.data.b,
2561 event.xclient.format);
2562
2563 /* If event mask is 0 the event is sent to the client that created
2564 the destination window. But if we are sending to the root window,
2565 there is no such client. Then we set the event mask to 0xffff. The
2566 event then goes to clients selecting for events on the root window. */
9ba8e10d 2567 x_catch_errors (dpyinfo->display);
1fb3821b
JD
2568 {
2569 int propagate = to_root ? False : True;
2570 unsigned mask = to_root ? 0xffff : 0;
2571 XSendEvent (dpyinfo->display, wdest, propagate, mask, &event);
2572 XFlush (dpyinfo->display);
2573 }
4545fa20 2574 x_uncatch_errors ();
1fb3821b 2575 UNBLOCK_INPUT;
1fb3821b
JD
2576}
2577
2578\f
ede4db72 2579void
971de7fb 2580syms_of_xselect (void)
ede4db72 2581{
ede4db72
RS
2582 defsubr (&Sx_get_selection_internal);
2583 defsubr (&Sx_own_selection_internal);
2584 defsubr (&Sx_disown_selection_internal);
2585 defsubr (&Sx_selection_owner_p);
2586 defsubr (&Sx_selection_exists_p);
a9f737ee 2587 defsubr (&Sx_clipboard_manager_save);
ede4db72 2588
1fb3821b
JD
2589 defsubr (&Sx_get_atom_name);
2590 defsubr (&Sx_send_client_message);
9fc68699 2591 defsubr (&Sx_register_dnd_atom);
1fb3821b 2592
ede4db72
RS
2593 reading_selection_reply = Fcons (Qnil, Qnil);
2594 staticpro (&reading_selection_reply);
2595 reading_selection_window = 0;
2596 reading_which_selection = 0;
2597
2598 property_change_wait_list = 0;
2f65feb6 2599 prop_location_identifier = 0;
ede4db72
RS
2600 property_change_reply = Fcons (Qnil, Qnil);
2601 staticpro (&property_change_reply);
2602
e067f0c1
CY
2603 converted_selections = NULL;
2604 conversion_fail_tag = None;
2605
29208e82 2606 DEFVAR_LISP ("selection-converter-alist", Vselection_converter_alist,
8c1a1077
PJ
2607 doc: /* An alist associating X Windows selection-types with functions.
2608These functions are called to convert the selection, with three args:
2609the name of the selection (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');
2610a desired type to which the selection should be converted;
2611and the local selection value (whatever was given to `x-own-selection').
2612
2613The function should return the value to send to the X server
2614\(typically a string). A return value of nil
2615means that the conversion could not be done.
2616A return value which is the symbol `NULL'
2617means that a side-effect was executed,
2618and there is no meaningful selection value. */);
ede4db72
RS
2619 Vselection_converter_alist = Qnil;
2620
29208e82 2621 DEFVAR_LISP ("x-lost-selection-functions", Vx_lost_selection_functions,
8c1a1077
PJ
2622 doc: /* A list of functions to be called when Emacs loses an X selection.
2623\(This happens when some other X client makes its own selection
2624or when a Lisp program explicitly clears the selection.)
2625The functions are called with one argument, the selection type
2626\(a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'). */);
c917a8de 2627 Vx_lost_selection_functions = Qnil;
ede4db72 2628
29208e82 2629 DEFVAR_LISP ("x-sent-selection-functions", Vx_sent_selection_functions,
8c1a1077 2630 doc: /* A list of functions to be called when Emacs answers a selection request.
e067f0c1 2631The functions are called with three arguments:
8c1a1077
PJ
2632 - the selection name (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');
2633 - the selection-type which Emacs was asked to convert the
2634 selection into before sending (for example, `STRING' or `LENGTH');
2635 - a flag indicating success or failure for responding to the request.
2636We might have failed (and declined the request) for any number of reasons,
2637including being asked for a selection that we no longer own, or being asked
2638to convert into a type that we don't know about or that is inappropriate.
2639This hook doesn't let you change the behavior of Emacs's selection replies,
2640it merely informs you that they have happened. */);
c917a8de 2641 Vx_sent_selection_functions = Qnil;
ede4db72 2642
29208e82 2643 DEFVAR_INT ("x-selection-timeout", x_selection_timeout,
8c1a1077
PJ
2644 doc: /* Number of milliseconds to wait for a selection reply.
2645If the selection owner doesn't reply in this time, we give up.
2646A value of 0 means wait as long as necessary. This is initialized from the
2647\"*selectionTimeout\" resource. */);
ede4db72
RS
2648 x_selection_timeout = 0;
2649
9852377f 2650 /* QPRIMARY is defined in keyboard.c. */
f3d4e0a4
CY
2651 DEFSYM (QSECONDARY, "SECONDARY");
2652 DEFSYM (QSTRING, "STRING");
2653 DEFSYM (QINTEGER, "INTEGER");
2654 DEFSYM (QCLIPBOARD, "CLIPBOARD");
2655 DEFSYM (QTIMESTAMP, "TIMESTAMP");
2656 DEFSYM (QTEXT, "TEXT");
2657 DEFSYM (QCOMPOUND_TEXT, "COMPOUND_TEXT");
2658 DEFSYM (QUTF8_STRING, "UTF8_STRING");
2659 DEFSYM (QDELETE, "DELETE");
2660 DEFSYM (QMULTIPLE, "MULTIPLE");
2661 DEFSYM (QINCR, "INCR");
2662 DEFSYM (QEMACS_TMP, "_EMACS_TMP_");
2663 DEFSYM (QTARGETS, "TARGETS");
2664 DEFSYM (QATOM, "ATOM");
2665 DEFSYM (QATOM_PAIR, "ATOM_PAIR");
a9f737ee
CY
2666 DEFSYM (QCLIPBOARD_MANAGER, "CLIPBOARD_MANAGER");
2667 DEFSYM (QSAVE_TARGETS, "SAVE_TARGETS");
f3d4e0a4
CY
2668 DEFSYM (QNULL, "NULL");
2669 DEFSYM (Qcompound_text_with_extensions, "compound-text-with-extensions");
2670 DEFSYM (Qforeign_selection, "foreign-selection");
ede4db72 2671}