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