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