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