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