Adjusted for the change of MAX_CHARSET.
[bpt/emacs.git] / src / xselect.c
CommitLineData
2408b3a1 1/* X Selection processing for Emacs.
002bbc0e 2 Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation.
ede4db72
RS
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
3b7ad313
EN
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
ede4db72 20
c6c5df7f 21
ede4db72
RS
22/* Rewritten by jwz */
23
18160b98 24#include <config.h>
ede4db72
RS
25#include "lisp.h"
26#include "xterm.h" /* for all of the X includes */
7da64e5c
RS
27#include "dispextern.h" /* frame.h seems to want this */
28#include "frame.h" /* Need this to get the X window of selected_frame */
9ac0d9e0 29#include "blockinput.h"
e6c7c988
KH
30#include "charset.h"
31#include "coding.h"
7da64e5c 32
ede4db72
RS
33#define CUT_BUFFER_SUPPORT
34
ede4db72
RS
35Lisp_Object QPRIMARY, QSECONDARY, QSTRING, QINTEGER, QCLIPBOARD, QTIMESTAMP,
36 QTEXT, QDELETE, QMULTIPLE, QINCR, QEMACS_TMP, QTARGETS, QATOM, QNULL,
37 QATOM_PAIR;
38
e6c7c988
KH
39Lisp_Object QCOMPOUND_TEXT; /* This is a type of selection. */
40
ede4db72
RS
41#ifdef CUT_BUFFER_SUPPORT
42Lisp_Object QCUT_BUFFER0, QCUT_BUFFER1, QCUT_BUFFER2, QCUT_BUFFER3,
43 QCUT_BUFFER4, QCUT_BUFFER5, QCUT_BUFFER6, QCUT_BUFFER7;
44#endif
45
8f4f023f
RS
46static Lisp_Object Vx_lost_selection_hooks;
47static Lisp_Object Vx_sent_selection_hooks;
ede4db72
RS
48
49/* If this is a smaller number than the max-request-size of the display,
50 emacs will use INCR selection transfer when the selection is larger
51 than this. The max-request-size is usually around 64k, so if you want
52 emacs to use incremental selection transfers when the selection is
53 smaller than that, set this. I added this mostly for debugging the
8f4f023f 54 incremental transfer stuff, but it might improve server performance. */
ede4db72
RS
55#define MAX_SELECTION_QUANTUM 0xFFFFFF
56
c3498e64
JB
57#ifdef HAVE_X11R4
58#define SELECTION_QUANTUM(dpy) ((XMaxRequestSize(dpy) << 2) - 100)
59#else
60#define SELECTION_QUANTUM(dpy) (((dpy)->max_request_size << 2) - 100)
61#endif
ede4db72 62
7da64e5c 63/* The timestamp of the last input event Emacs received from the X server. */
29674445
KH
64/* Defined in keyboard.c. */
65extern unsigned long last_event_timestamp;
ede4db72
RS
66
67/* This is an association list whose elements are of the form
118bd841
RS
68 ( SELECTION-NAME SELECTION-VALUE SELECTION-TIMESTAMP FRAME)
69 SELECTION-NAME is a lisp symbol, whose name is the name of an X Atom.
70 SELECTION-VALUE is the value that emacs owns for that selection.
ede4db72 71 It may be any kind of Lisp object.
118bd841 72 SELECTION-TIMESTAMP is the time at which emacs began owning this selection,
ede4db72 73 as a cons of two 16-bit numbers (making a 32 bit time.)
118bd841
RS
74 FRAME is the frame for which we made the selection.
75 If there is an entry in this alist, then it can be assumed that Emacs owns
ede4db72
RS
76 that selection.
77 The only (eq) parts of this list that are visible from Lisp are the
8f4f023f
RS
78 selection-values. */
79static Lisp_Object Vselection_alist;
ede4db72
RS
80
81/* This is an alist whose CARs are selection-types (whose names are the same
82 as the names of X Atoms) and whose CDRs are the names of Lisp functions to
83 call to convert the given Emacs selection value to a string representing
84 the given selection type. This is for Lisp-level extension of the emacs
8f4f023f
RS
85 selection handling. */
86static Lisp_Object Vselection_converter_alist;
ede4db72
RS
87
88/* If the selection owner takes too long to reply to a selection request,
8f4f023f
RS
89 we give up on it. This is in milliseconds (0 = no timeout.) */
90static int x_selection_timeout;
ede4db72
RS
91\f
92/* Utility functions */
93
94static void lisp_data_to_selection_data ();
95static Lisp_Object selection_data_to_lisp_data ();
96static Lisp_Object x_get_window_property_as_lisp_data ();
97
ede4db72
RS
98/* This converts a Lisp symbol to a server Atom, avoiding a server
99 roundtrip whenever possible. */
100
101static Atom
5c3a351a
RS
102symbol_to_x_atom (dpyinfo, display, sym)
103 struct x_display_info *dpyinfo;
ede4db72
RS
104 Display *display;
105 Lisp_Object sym;
106{
107 Atom val;
108 if (NILP (sym)) return 0;
109 if (EQ (sym, QPRIMARY)) return XA_PRIMARY;
110 if (EQ (sym, QSECONDARY)) return XA_SECONDARY;
111 if (EQ (sym, QSTRING)) return XA_STRING;
112 if (EQ (sym, QINTEGER)) return XA_INTEGER;
113 if (EQ (sym, QATOM)) return XA_ATOM;
5c3a351a
RS
114 if (EQ (sym, QCLIPBOARD)) return dpyinfo->Xatom_CLIPBOARD;
115 if (EQ (sym, QTIMESTAMP)) return dpyinfo->Xatom_TIMESTAMP;
116 if (EQ (sym, QTEXT)) return dpyinfo->Xatom_TEXT;
e6c7c988 117 if (EQ (sym, QCOMPOUND_TEXT)) return dpyinfo->Xatom_COMPOUND_TEXT;
5c3a351a
RS
118 if (EQ (sym, QDELETE)) return dpyinfo->Xatom_DELETE;
119 if (EQ (sym, QMULTIPLE)) return dpyinfo->Xatom_MULTIPLE;
120 if (EQ (sym, QINCR)) return dpyinfo->Xatom_INCR;
121 if (EQ (sym, QEMACS_TMP)) return dpyinfo->Xatom_EMACS_TMP;
122 if (EQ (sym, QTARGETS)) return dpyinfo->Xatom_TARGETS;
123 if (EQ (sym, QNULL)) return dpyinfo->Xatom_NULL;
ede4db72
RS
124#ifdef CUT_BUFFER_SUPPORT
125 if (EQ (sym, QCUT_BUFFER0)) return XA_CUT_BUFFER0;
126 if (EQ (sym, QCUT_BUFFER1)) return XA_CUT_BUFFER1;
127 if (EQ (sym, QCUT_BUFFER2)) return XA_CUT_BUFFER2;
128 if (EQ (sym, QCUT_BUFFER3)) return XA_CUT_BUFFER3;
129 if (EQ (sym, QCUT_BUFFER4)) return XA_CUT_BUFFER4;
130 if (EQ (sym, QCUT_BUFFER5)) return XA_CUT_BUFFER5;
131 if (EQ (sym, QCUT_BUFFER6)) return XA_CUT_BUFFER6;
132 if (EQ (sym, QCUT_BUFFER7)) return XA_CUT_BUFFER7;
133#endif
134 if (!SYMBOLP (sym)) abort ();
135
136#if 0
137 fprintf (stderr, " XInternAtom %s\n", (char *) XSYMBOL (sym)->name->data);
138#endif
139 BLOCK_INPUT;
140 val = XInternAtom (display, (char *) XSYMBOL (sym)->name->data, False);
141 UNBLOCK_INPUT;
142 return val;
143}
144
145
146/* This converts a server Atom to a Lisp symbol, avoiding server roundtrips
147 and calls to intern whenever possible. */
148
149static Lisp_Object
5c3a351a
RS
150x_atom_to_symbol (dpyinfo, display, atom)
151 struct x_display_info *dpyinfo;
ede4db72
RS
152 Display *display;
153 Atom atom;
154{
155 char *str;
156 Lisp_Object val;
157 if (! atom) return Qnil;
7da64e5c
RS
158 switch (atom)
159 {
160 case XA_PRIMARY:
161 return QPRIMARY;
162 case XA_SECONDARY:
163 return QSECONDARY;
164 case XA_STRING:
165 return QSTRING;
166 case XA_INTEGER:
167 return QINTEGER;
168 case XA_ATOM:
169 return QATOM;
ede4db72 170#ifdef CUT_BUFFER_SUPPORT
7da64e5c
RS
171 case XA_CUT_BUFFER0:
172 return QCUT_BUFFER0;
173 case XA_CUT_BUFFER1:
174 return QCUT_BUFFER1;
175 case XA_CUT_BUFFER2:
176 return QCUT_BUFFER2;
177 case XA_CUT_BUFFER3:
178 return QCUT_BUFFER3;
179 case XA_CUT_BUFFER4:
180 return QCUT_BUFFER4;
181 case XA_CUT_BUFFER5:
182 return QCUT_BUFFER5;
183 case XA_CUT_BUFFER6:
184 return QCUT_BUFFER6;
185 case XA_CUT_BUFFER7:
186 return QCUT_BUFFER7;
ede4db72 187#endif
7da64e5c
RS
188 }
189
5c3a351a 190 if (atom == dpyinfo->Xatom_CLIPBOARD)
7da64e5c 191 return QCLIPBOARD;
5c3a351a 192 if (atom == dpyinfo->Xatom_TIMESTAMP)
7da64e5c 193 return QTIMESTAMP;
5c3a351a 194 if (atom == dpyinfo->Xatom_TEXT)
7da64e5c 195 return QTEXT;
e6c7c988
KH
196 if (atom == dpyinfo->Xatom_COMPOUND_TEXT)
197 return QCOMPOUND_TEXT;
5c3a351a 198 if (atom == dpyinfo->Xatom_DELETE)
7da64e5c 199 return QDELETE;
5c3a351a 200 if (atom == dpyinfo->Xatom_MULTIPLE)
7da64e5c 201 return QMULTIPLE;
5c3a351a 202 if (atom == dpyinfo->Xatom_INCR)
7da64e5c 203 return QINCR;
5c3a351a 204 if (atom == dpyinfo->Xatom_EMACS_TMP)
7da64e5c 205 return QEMACS_TMP;
5c3a351a 206 if (atom == dpyinfo->Xatom_TARGETS)
7da64e5c 207 return QTARGETS;
5c3a351a 208 if (atom == dpyinfo->Xatom_NULL)
7da64e5c 209 return QNULL;
ede4db72
RS
210
211 BLOCK_INPUT;
212 str = XGetAtomName (display, atom);
213 UNBLOCK_INPUT;
214#if 0
215 fprintf (stderr, " XGetAtomName --> %s\n", str);
216#endif
217 if (! str) return Qnil;
218 val = intern (str);
219 BLOCK_INPUT;
0158abbc 220 /* This was allocated by Xlib, so use XFree. */
ede4db72
RS
221 XFree (str);
222 UNBLOCK_INPUT;
223 return val;
224}
8a89415e 225\f
ede4db72
RS
226/* Do protocol to assert ourself as a selection owner.
227 Update the Vselection_alist so that we can reply to later requests for
228 our selection. */
229
230static void
231x_own_selection (selection_name, selection_value)
232 Lisp_Object selection_name, selection_value;
233{
ede4db72 234 Window selecting_window = FRAME_X_WINDOW (selected_frame);
3834c318 235 Display *display = FRAME_X_DISPLAY (selected_frame);
7da64e5c 236 Time time = last_event_timestamp;
ede4db72 237 Atom selection_atom;
5c3a351a 238 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (selected_frame);
ede4db72
RS
239
240 CHECK_SYMBOL (selection_name, 0);
5c3a351a 241 selection_atom = symbol_to_x_atom (dpyinfo, display, selection_name);
ede4db72
RS
242
243 BLOCK_INPUT;
a7b24d46 244 x_catch_errors (display);
ede4db72 245 XSetSelectionOwner (display, selection_atom, selecting_window, time);
a7b24d46
RS
246 x_check_errors (display, "Can't set selection: %s");
247 x_uncatch_errors (display);
ede4db72
RS
248 UNBLOCK_INPUT;
249
250 /* Now update the local cache */
251 {
252 Lisp_Object selection_time;
253 Lisp_Object selection_data;
254 Lisp_Object prev_value;
255
256 selection_time = long_to_cons ((unsigned long) time);
257 selection_data = Fcons (selection_name,
258 Fcons (selection_value,
118bd841
RS
259 Fcons (selection_time,
260 Fcons (Fselected_frame (), Qnil))));
ede4db72
RS
261 prev_value = assq_no_quit (selection_name, Vselection_alist);
262
263 Vselection_alist = Fcons (selection_data, Vselection_alist);
264
265 /* If we already owned the selection, remove the old selection data.
266 Perhaps we should destructively modify it instead.
267 Don't use Fdelq as that may QUIT. */
268 if (!NILP (prev_value))
269 {
270 Lisp_Object rest; /* we know it's not the CAR, so it's easy. */
271 for (rest = Vselection_alist; !NILP (rest); rest = Fcdr (rest))
272 if (EQ (prev_value, Fcar (XCONS (rest)->cdr)))
273 {
274 XCONS (rest)->cdr = Fcdr (XCONS (rest)->cdr);
275 break;
276 }
277 }
278 }
279}
280\f
281/* Given a selection-name and desired type, look up our local copy of
282 the selection value and convert it to the type.
283 The value is nil or a string.
284 This function is used both for remote requests
7da64e5c 285 and for local x-get-selection-internal.
ede4db72
RS
286
287 This calls random Lisp code, and may signal or gc. */
288
289static Lisp_Object
290x_get_local_selection (selection_symbol, target_type)
291 Lisp_Object selection_symbol, target_type;
292{
293 Lisp_Object local_value;
294 Lisp_Object handler_fn, value, type, check;
295 int count;
296
297 local_value = assq_no_quit (selection_symbol, Vselection_alist);
298
299 if (NILP (local_value)) return Qnil;
300
301 /* TIMESTAMP and MULTIPLE are special cases 'cause that's easiest. */
302 if (EQ (target_type, QTIMESTAMP))
303 {
304 handler_fn = Qnil;
305 value = XCONS (XCONS (XCONS (local_value)->cdr)->cdr)->car;
306 }
307#if 0
308 else if (EQ (target_type, QDELETE))
309 {
310 handler_fn = Qnil;
311 Fx_disown_selection_internal
312 (selection_symbol,
313 XCONS (XCONS (XCONS (local_value)->cdr)->cdr)->car);
314 value = QNULL;
315 }
316#endif
317
318#if 0 /* #### MULTIPLE doesn't work yet */
319 else if (CONSP (target_type)
320 && XCONS (target_type)->car == QMULTIPLE)
321 {
9d2d1dd8
KH
322 Lisp_Object pairs;
323 int size;
ede4db72 324 int i;
9d2d1dd8
KH
325 pairs = XCONS (target_type)->cdr;
326 size = XVECTOR (pairs)->size;
ede4db72
RS
327 /* If the target is MULTIPLE, then target_type looks like
328 (MULTIPLE . [[SELECTION1 TARGET1] [SELECTION2 TARGET2] ... ])
329 We modify the second element of each pair in the vector and
330 return it as [[SELECTION1 <value1>] [SELECTION2 <value2>] ... ]
331 */
332 for (i = 0; i < size; i++)
333 {
9d2d1dd8
KH
334 Lisp_Object pair;
335 pair = XVECTOR (pairs)->contents [i];
ede4db72
RS
336 XVECTOR (pair)->contents [1]
337 = x_get_local_selection (XVECTOR (pair)->contents [0],
338 XVECTOR (pair)->contents [1]);
339 }
340 return pairs;
341 }
342#endif
343 else
344 {
345 /* Don't allow a quit within the converter.
346 When the user types C-g, he would be surprised
347 if by luck it came during a converter. */
348 count = specpdl_ptr - specpdl;
349 specbind (Qinhibit_quit, Qt);
350
351 CHECK_SYMBOL (target_type, 0);
352 handler_fn = Fcdr (Fassq (target_type, Vselection_converter_alist));
1eb4d468
RS
353 if (!NILP (handler_fn))
354 value = call3 (handler_fn,
355 selection_symbol, target_type,
356 XCONS (XCONS (local_value)->cdr)->car);
357 else
358 value = Qnil;
ede4db72
RS
359 unbind_to (count, Qnil);
360 }
361
362 /* Make sure this value is of a type that we could transmit
363 to another X client. */
a87ed99c 364
ede4db72
RS
365 check = value;
366 if (CONSP (value)
367 && SYMBOLP (XCONS (value)->car))
368 type = XCONS (value)->car,
369 check = XCONS (value)->cdr;
370
371 if (STRINGP (check)
372 || VECTORP (check)
373 || SYMBOLP (check)
7da64e5c 374 || INTEGERP (check)
ede4db72
RS
375 || NILP (value))
376 return value;
a87ed99c 377 /* Check for a value that cons_to_long could handle. */
ede4db72 378 else if (CONSP (check)
7da64e5c
RS
379 && INTEGERP (XCONS (check)->car)
380 && (INTEGERP (XCONS (check)->cdr)
ede4db72
RS
381 ||
382 (CONSP (XCONS (check)->cdr)
7da64e5c 383 && INTEGERP (XCONS (XCONS (check)->cdr)->car)
ede4db72
RS
384 && NILP (XCONS (XCONS (check)->cdr)->cdr))))
385 return value;
386 else
387 return
388 Fsignal (Qerror,
a87ed99c 389 Fcons (build_string ("invalid data returned by selection-conversion function"),
ede4db72
RS
390 Fcons (handler_fn, Fcons (value, Qnil))));
391}
392\f
393/* Subroutines of x_reply_selection_request. */
394
5d0ba25b 395/* Send a SelectionNotify event to the requestor with property=None,
ede4db72
RS
396 meaning we were unable to do what they wanted. */
397
398static void
399x_decline_selection_request (event)
400 struct input_event *event;
401{
402 XSelectionEvent reply;
403 reply.type = SelectionNotify;
404 reply.display = SELECTION_EVENT_DISPLAY (event);
5d0ba25b 405 reply.requestor = SELECTION_EVENT_REQUESTOR (event);
ede4db72
RS
406 reply.selection = SELECTION_EVENT_SELECTION (event);
407 reply.time = SELECTION_EVENT_TIME (event);
408 reply.target = SELECTION_EVENT_TARGET (event);
409 reply.property = None;
410
411 BLOCK_INPUT;
5d0ba25b 412 XSendEvent (reply.display, reply.requestor, False, 0L,
7ffb2841 413 (XEvent *) &reply);
5c3a351a 414 XFlush (reply.display);
ede4db72
RS
415 UNBLOCK_INPUT;
416}
417
418/* This is the selection request currently being processed.
419 It is set to zero when the request is fully processed. */
420static struct input_event *x_selection_current_request;
421
422/* Used as an unwind-protect clause so that, if a selection-converter signals
2a1a4c9d 423 an error, we tell the requester that we were unable to do what they wanted
ede4db72
RS
424 before we throw to top-level or go into the debugger or whatever. */
425
426static Lisp_Object
427x_selection_request_lisp_error (ignore)
428 Lisp_Object ignore;
429{
430 if (x_selection_current_request != 0)
431 x_decline_selection_request (x_selection_current_request);
432 return Qnil;
433}
434\f
d1f21a66
RS
435
436/* This stuff is so that INCR selections are reentrant (that is, so we can
437 be servicing multiple INCR selection requests simultaneously.) I haven't
438 actually tested that yet. */
439
440/* Keep a list of the property changes that are awaited. */
441
442struct prop_location
443{
444 int identifier;
445 Display *display;
446 Window window;
447 Atom property;
448 int desired_state;
449 int arrived;
450 struct prop_location *next;
451};
452
453static struct prop_location *expect_property_change ();
454static void wait_for_property_change ();
455static void unexpect_property_change ();
456static int waiting_for_other_props_on_window ();
457
458static int prop_location_identifier;
459
460static Lisp_Object property_change_reply;
461
462static struct prop_location *property_change_reply_object;
463
464static struct prop_location *property_change_wait_list;
55b2d45d
RS
465
466static Lisp_Object
467queue_selection_requests_unwind (frame)
468 Lisp_Object frame;
469{
470 FRAME_PTR f = XFRAME (frame);
471
472 if (! NILP (frame))
473 x_stop_queuing_selection_requests (FRAME_X_DISPLAY (f));
ab552306 474 return Qnil;
55b2d45d
RS
475}
476
477/* Return some frame whose display info is DPYINFO.
478 Return nil if there is none. */
479
480static Lisp_Object
481some_frame_on_display (dpyinfo)
482 struct x_display_info *dpyinfo;
483{
484 Lisp_Object list, frame;
485
486 FOR_EACH_FRAME (list, frame)
487 {
488 if (FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
489 return frame;
490 }
491
492 return Qnil;
493}
d1f21a66 494\f
ede4db72
RS
495/* Send the reply to a selection request event EVENT.
496 TYPE is the type of selection data requested.
497 DATA and SIZE describe the data to send, already converted.
498 FORMAT is the unit-size (in bits) of the data to be transmitted. */
499
500static void
501x_reply_selection_request (event, format, data, size, type)
502 struct input_event *event;
503 int format, size;
504 unsigned char *data;
505 Atom type;
506{
507 XSelectionEvent reply;
508 Display *display = SELECTION_EVENT_DISPLAY (event);
5d0ba25b 509 Window window = SELECTION_EVENT_REQUESTOR (event);
ede4db72
RS
510 int bytes_remaining;
511 int format_bytes = format/8;
512 int max_bytes = SELECTION_QUANTUM (display);
5c3a351a 513 struct x_display_info *dpyinfo = x_display_info_for_display (display);
ede4db72
RS
514
515 if (max_bytes > MAX_SELECTION_QUANTUM)
516 max_bytes = MAX_SELECTION_QUANTUM;
517
518 reply.type = SelectionNotify;
519 reply.display = display;
5d0ba25b 520 reply.requestor = window;
ede4db72
RS
521 reply.selection = SELECTION_EVENT_SELECTION (event);
522 reply.time = SELECTION_EVENT_TIME (event);
523 reply.target = SELECTION_EVENT_TARGET (event);
524 reply.property = SELECTION_EVENT_PROPERTY (event);
525 if (reply.property == None)
526 reply.property = reply.target;
527
528 /* #### XChangeProperty can generate BadAlloc, and we must handle it! */
afe1529d
RS
529 BLOCK_INPUT;
530 x_catch_errors (display);
ede4db72 531
ede4db72
RS
532 /* Store the data on the requested property.
533 If the selection is large, only store the first N bytes of it.
534 */
535 bytes_remaining = size * format_bytes;
536 if (bytes_remaining <= max_bytes)
537 {
538 /* Send all the data at once, with minimal handshaking. */
539#if 0
540 fprintf (stderr,"\nStoring all %d\n", bytes_remaining);
541#endif
542 XChangeProperty (display, window, reply.property, type, format,
543 PropModeReplace, data, size);
544 /* At this point, the selection was successfully stored; ack it. */
2f65feb6 545 XSendEvent (display, window, False, 0L, (XEvent *) &reply);
ede4db72
RS
546 }
547 else
548 {
549 /* Send an INCR selection. */
d1f21a66 550 struct prop_location *wait_object;
afe1529d 551 int had_errors;
55b2d45d
RS
552 int count = specpdl_ptr - specpdl;
553 Lisp_Object frame;
ede4db72 554
55b2d45d
RS
555 frame = some_frame_on_display (dpyinfo);
556
557 /* If the display no longer has frames, we can't expect
558 to get many more selection requests from it, so don't
559 bother trying to queue them. */
560 if (!NILP (frame))
561 {
562 x_start_queuing_selection_requests (display);
563
564 record_unwind_protect (queue_selection_requests_unwind,
565 frame);
566 }
2f65feb6 567
19126e11 568 if (x_window_to_frame (dpyinfo, window)) /* #### debug */
606140dd 569 error ("Attempt to transfer an INCR to ourself!");
ede4db72
RS
570#if 0
571 fprintf (stderr, "\nINCR %d\n", bytes_remaining);
572#endif
d1f21a66
RS
573 wait_object = expect_property_change (display, window, reply.property,
574 PropertyDelete);
ede4db72 575
5c3a351a 576 XChangeProperty (display, window, reply.property, dpyinfo->Xatom_INCR,
55b2d45d
RS
577 32, PropModeReplace,
578 (unsigned char *) &bytes_remaining, 1);
ede4db72
RS
579 XSelectInput (display, window, PropertyChangeMask);
580 /* Tell 'em the INCR data is there... */
55b2d45d 581 XSendEvent (display, window, False, 0L, (XEvent *) &reply);
5c3a351a 582 XFlush (display);
afe1529d
RS
583
584 had_errors = x_had_errors_p (display);
2f65feb6 585 UNBLOCK_INPUT;
ede4db72 586
2a1a4c9d 587 /* First, wait for the requester to ack by deleting the property.
ede4db72 588 This can run random lisp code (process handlers) or signal. */
afe1529d
RS
589 if (! had_errors)
590 wait_for_property_change (wait_object);
ede4db72
RS
591
592 while (bytes_remaining)
593 {
594 int i = ((bytes_remaining < max_bytes)
595 ? bytes_remaining
596 : max_bytes);
2f65feb6
RS
597
598 BLOCK_INPUT;
599
d1f21a66
RS
600 wait_object
601 = expect_property_change (display, window, reply.property,
602 PropertyDelete);
ede4db72
RS
603#if 0
604 fprintf (stderr," INCR adding %d\n", i);
605#endif
606 /* Append the next chunk of data to the property. */
607 XChangeProperty (display, window, reply.property, type, format,
608 PropModeAppend, data, i / format_bytes);
609 bytes_remaining -= i;
610 data += i;
5c3a351a 611 XFlush (display);
afe1529d 612 had_errors = x_had_errors_p (display);
2f65feb6 613 UNBLOCK_INPUT;
ede4db72 614
afe1529d
RS
615 if (had_errors)
616 break;
617
2a1a4c9d 618 /* Now wait for the requester to ack this chunk by deleting the
ede4db72
RS
619 property. This can run random lisp code or signal.
620 */
d1f21a66 621 wait_for_property_change (wait_object);
ede4db72 622 }
2a1a4c9d 623 /* Now write a zero-length chunk to the property to tell the requester
ede4db72
RS
624 that we're done. */
625#if 0
626 fprintf (stderr," INCR done\n");
627#endif
2f65feb6 628 BLOCK_INPUT;
ede4db72
RS
629 if (! waiting_for_other_props_on_window (display, window))
630 XSelectInput (display, window, 0L);
631
632 XChangeProperty (display, window, reply.property, type, format,
633 PropModeReplace, data, 0);
55b2d45d
RS
634
635 unbind_to (count, Qnil);
ede4db72 636 }
afe1529d
RS
637
638 XFlush (display);
639 x_uncatch_errors (display);
640 UNBLOCK_INPUT;
ede4db72
RS
641}
642\f
643/* Handle a SelectionRequest event EVENT.
644 This is called from keyboard.c when such an event is found in the queue. */
645
646void
647x_handle_selection_request (event)
648 struct input_event *event;
649{
650 struct gcpro gcpro1, gcpro2, gcpro3;
9d2d1dd8 651 Lisp_Object local_selection_data;
ede4db72 652 Lisp_Object selection_symbol;
9d2d1dd8
KH
653 Lisp_Object target_symbol;
654 Lisp_Object converted_selection;
ede4db72 655 Time local_selection_time;
9d2d1dd8 656 Lisp_Object successful_p;
ede4db72 657 int count;
5c3a351a
RS
658 struct x_display_info *dpyinfo
659 = x_display_info_for_display (SELECTION_EVENT_DISPLAY (event));
ede4db72 660
9d2d1dd8
KH
661 local_selection_data = Qnil;
662 target_symbol = Qnil;
663 converted_selection = Qnil;
664 successful_p = Qnil;
665
ede4db72
RS
666 GCPRO3 (local_selection_data, converted_selection, target_symbol);
667
5c3a351a
RS
668 selection_symbol = x_atom_to_symbol (dpyinfo,
669 SELECTION_EVENT_DISPLAY (event),
ede4db72
RS
670 SELECTION_EVENT_SELECTION (event));
671
672 local_selection_data = assq_no_quit (selection_symbol, Vselection_alist);
ede4db72
RS
673
674 if (NILP (local_selection_data))
675 {
676 /* Someone asked for the selection, but we don't have it any more.
677 */
678 x_decline_selection_request (event);
679 goto DONE;
680 }
681
682 local_selection_time = (Time)
683 cons_to_long (XCONS (XCONS (XCONS (local_selection_data)->cdr)->cdr)->car);
684
685 if (SELECTION_EVENT_TIME (event) != CurrentTime
7da64e5c 686 && local_selection_time > SELECTION_EVENT_TIME (event))
ede4db72
RS
687 {
688 /* Someone asked for the selection, and we have one, but not the one
689 they're looking for.
690 */
691 x_decline_selection_request (event);
692 goto DONE;
693 }
694
695 count = specpdl_ptr - specpdl;
696 x_selection_current_request = event;
697 record_unwind_protect (x_selection_request_lisp_error, Qnil);
698
5c3a351a 699 target_symbol = x_atom_to_symbol (dpyinfo, SELECTION_EVENT_DISPLAY (event),
ede4db72
RS
700 SELECTION_EVENT_TARGET (event));
701
702#if 0 /* #### MULTIPLE doesn't work yet */
703 if (EQ (target_symbol, QMULTIPLE))
704 target_symbol = fetch_multiple_target (event);
705#endif
706
707 /* Convert lisp objects back into binary data */
708
709 converted_selection
710 = x_get_local_selection (selection_symbol, target_symbol);
711
712 if (! NILP (converted_selection))
713 {
714 unsigned char *data;
715 unsigned int size;
716 int format;
717 Atom type;
aca39f42
RS
718 int nofree;
719
2f65feb6
RS
720 lisp_data_to_selection_data (SELECTION_EVENT_DISPLAY (event),
721 converted_selection,
aca39f42 722 &data, &type, &size, &format, &nofree);
ede4db72
RS
723
724 x_reply_selection_request (event, format, data, size, type);
725 successful_p = Qt;
726
727 /* Indicate we have successfully processed this event. */
7da64e5c 728 x_selection_current_request = 0;
ede4db72 729
002bbc0e 730 /* Use free, not XFree, because lisp_data_to_selection_data
0158abbc 731 calls xmalloc itself. */
aca39f42 732 if (!nofree)
002bbc0e 733 free (data);
ede4db72
RS
734 }
735 unbind_to (count, Qnil);
736
737 DONE:
738
739 UNGCPRO;
740
741 /* Let random lisp code notice that the selection has been asked for. */
742 {
9d2d1dd8
KH
743 Lisp_Object rest;
744 rest = Vx_sent_selection_hooks;
ede4db72
RS
745 if (!EQ (rest, Qunbound))
746 for (; CONSP (rest); rest = Fcdr (rest))
747 call3 (Fcar (rest), selection_symbol, target_symbol, successful_p);
748 }
749}
750\f
751/* Handle a SelectionClear event EVENT, which indicates that some other
752 client cleared out our previously asserted selection.
753 This is called from keyboard.c when such an event is found in the queue. */
754
755void
756x_handle_selection_clear (event)
757 struct input_event *event;
758{
759 Display *display = SELECTION_EVENT_DISPLAY (event);
760 Atom selection = SELECTION_EVENT_SELECTION (event);
761 Time changed_owner_time = SELECTION_EVENT_TIME (event);
762
763 Lisp_Object selection_symbol, local_selection_data;
764 Time local_selection_time;
5c3a351a 765 struct x_display_info *dpyinfo = x_display_info_for_display (display);
ede4db72 766
5c3a351a 767 selection_symbol = x_atom_to_symbol (dpyinfo, display, selection);
ede4db72
RS
768
769 local_selection_data = assq_no_quit (selection_symbol, Vselection_alist);
770
771 /* Well, we already believe that we don't own it, so that's just fine. */
772 if (NILP (local_selection_data)) return;
773
774 local_selection_time = (Time)
775 cons_to_long (XCONS (XCONS (XCONS (local_selection_data)->cdr)->cdr)->car);
776
777 /* This SelectionClear is for a selection that we no longer own, so we can
778 disregard it. (That is, we have reasserted the selection since this
779 request was generated.) */
780
781 if (changed_owner_time != CurrentTime
782 && local_selection_time > changed_owner_time)
783 return;
784
785 /* Otherwise, we're really honest and truly being told to drop it.
786 Don't use Fdelq as that may QUIT;. */
787
788 if (EQ (local_selection_data, Fcar (Vselection_alist)))
789 Vselection_alist = Fcdr (Vselection_alist);
790 else
791 {
792 Lisp_Object rest;
793 for (rest = Vselection_alist; !NILP (rest); rest = Fcdr (rest))
794 if (EQ (local_selection_data, Fcar (XCONS (rest)->cdr)))
795 {
796 XCONS (rest)->cdr = Fcdr (XCONS (rest)->cdr);
797 break;
798 }
799 }
800
801 /* Let random lisp code notice that the selection has been stolen. */
802
803 {
d1f21a66
RS
804 Lisp_Object rest;
805 rest = Vx_lost_selection_hooks;
ede4db72 806 if (!EQ (rest, Qunbound))
d1f21a66
RS
807 {
808 for (; CONSP (rest); rest = Fcdr (rest))
809 call1 (Fcar (rest), selection_symbol);
7c6b2ea4 810 prepare_menu_bars ();
d1f21a66
RS
811 redisplay_preserve_echo_area ();
812 }
ede4db72
RS
813 }
814}
815
118bd841
RS
816/* Clear all selections that were made from frame F.
817 We do this when about to delete a frame. */
818
819void
820x_clear_frame_selections (f)
821 FRAME_PTR f;
822{
823 Lisp_Object frame;
824 Lisp_Object rest;
825
90851bbe 826 XSETFRAME (frame, f);
118bd841
RS
827
828 /* Otherwise, we're really honest and truly being told to drop it.
829 Don't use Fdelq as that may QUIT;. */
830
0d199f9c
RS
831 /* Delete elements from the beginning of Vselection_alist. */
832 while (!NILP (Vselection_alist)
833 && EQ (frame, Fcar (Fcdr (Fcdr (Fcdr (Fcar (Vselection_alist)))))))
834 {
835 /* Let random Lisp code notice that the selection has been stolen. */
836 Lisp_Object hooks, selection_symbol;
837
838 hooks = Vx_lost_selection_hooks;
839 selection_symbol = Fcar (Fcar (Vselection_alist));
840
841 if (!EQ (hooks, Qunbound))
842 {
843 for (; CONSP (hooks); hooks = Fcdr (hooks))
844 call1 (Fcar (hooks), selection_symbol);
996b804d
MB
845#if 0 /* This can crash when deleting a frame
846 from x_connection_closed. Anyway, it seems unnecessary;
847 something else should cause a redisplay. */
0d199f9c 848 redisplay_preserve_echo_area ();
996b804d 849#endif
0d199f9c
RS
850 }
851
852 Vselection_alist = Fcdr (Vselection_alist);
853 }
854
855 /* Delete elements after the beginning of Vselection_alist. */
118bd841
RS
856 for (rest = Vselection_alist; !NILP (rest); rest = Fcdr (rest))
857 if (EQ (frame, Fcar (Fcdr (Fcdr (Fcdr (Fcar (XCONS (rest)->cdr)))))))
858 {
859 /* Let random Lisp code notice that the selection has been stolen. */
860 Lisp_Object hooks, selection_symbol;
861
862 hooks = Vx_lost_selection_hooks;
0d199f9c 863 selection_symbol = Fcar (Fcar (XCONS (rest)->cdr));
118bd841
RS
864
865 if (!EQ (hooks, Qunbound))
866 {
867 for (; CONSP (hooks); hooks = Fcdr (hooks))
868 call1 (Fcar (hooks), selection_symbol);
996b804d 869#if 0 /* See above */
118bd841 870 redisplay_preserve_echo_area ();
996b804d 871#endif
118bd841
RS
872 }
873 XCONS (rest)->cdr = Fcdr (XCONS (rest)->cdr);
874 break;
875 }
876}
ede4db72 877\f
ede4db72
RS
878/* Nonzero if any properties for DISPLAY and WINDOW
879 are on the list of what we are waiting for. */
880
881static int
882waiting_for_other_props_on_window (display, window)
883 Display *display;
884 Window window;
885{
886 struct prop_location *rest = property_change_wait_list;
887 while (rest)
888 if (rest->display == display && rest->window == window)
889 return 1;
890 else
891 rest = rest->next;
892 return 0;
893}
894
895/* Add an entry to the list of property changes we are waiting for.
896 DISPLAY, WINDOW, PROPERTY, STATE describe what we will wait for.
897 The return value is a number that uniquely identifies
898 this awaited property change. */
899
d1f21a66 900static struct prop_location *
ede4db72
RS
901expect_property_change (display, window, property, state)
902 Display *display;
903 Window window;
904 Lisp_Object property;
905 int state;
906{
907 struct prop_location *pl
908 = (struct prop_location *) xmalloc (sizeof (struct prop_location));
2f65feb6 909 pl->identifier = ++prop_location_identifier;
ede4db72
RS
910 pl->display = display;
911 pl->window = window;
912 pl->property = property;
913 pl->desired_state = state;
914 pl->next = property_change_wait_list;
d1f21a66 915 pl->arrived = 0;
ede4db72 916 property_change_wait_list = pl;
d1f21a66 917 return pl;
ede4db72
RS
918}
919
920/* Delete an entry from the list of property changes we are waiting for.
2f65feb6 921 IDENTIFIER is the number that uniquely identifies the entry. */
ede4db72
RS
922
923static void
d1f21a66
RS
924unexpect_property_change (location)
925 struct prop_location *location;
ede4db72
RS
926{
927 struct prop_location *prev = 0, *rest = property_change_wait_list;
928 while (rest)
929 {
d1f21a66 930 if (rest == location)
ede4db72
RS
931 {
932 if (prev)
933 prev->next = rest->next;
934 else
935 property_change_wait_list = rest->next;
002bbc0e 936 free (rest);
ede4db72
RS
937 return;
938 }
939 prev = rest;
940 rest = rest->next;
941 }
942}
943
2f65feb6
RS
944/* Remove the property change expectation element for IDENTIFIER. */
945
946static Lisp_Object
947wait_for_property_change_unwind (identifierval)
948 Lisp_Object identifierval;
949{
c4898489
KH
950 unexpect_property_change ((struct prop_location *)
951 (XFASTINT (XCONS (identifierval)->car) << 16
952 | XFASTINT (XCONS (identifierval)->cdr)));
ab552306 953 return Qnil;
2f65feb6
RS
954}
955
ede4db72 956/* Actually wait for a property change.
2f65feb6 957 IDENTIFIER should be the value that expect_property_change returned. */
ede4db72
RS
958
959static void
d1f21a66
RS
960wait_for_property_change (location)
961 struct prop_location *location;
ede4db72 962{
2f65feb6
RS
963 int secs, usecs;
964 int count = specpdl_ptr - specpdl;
d1f21a66
RS
965 Lisp_Object tem;
966
c4898489
KH
967 tem = Fcons (Qnil, Qnil);
968 XSETFASTINT (XCONS (tem)->car, (EMACS_UINT)location >> 16);
969 XSETFASTINT (XCONS (tem)->cdr, (EMACS_UINT)location & 0xffff);
2f65feb6
RS
970
971 /* Make sure to do unexpect_property_change if we quit or err. */
d1f21a66 972 record_unwind_protect (wait_for_property_change_unwind, tem);
2f65feb6 973
ede4db72 974 XCONS (property_change_reply)->car = Qnil;
2f65feb6 975
afe1529d
RS
976 property_change_reply_object = location;
977 /* If the event we are waiting for arrives beyond here, it will set
978 property_change_reply, because property_change_reply_object says so. */
d1f21a66
RS
979 if (! location->arrived)
980 {
d1f21a66
RS
981 secs = x_selection_timeout / 1000;
982 usecs = (x_selection_timeout % 1000) * 1000;
983 wait_reading_process_input (secs, usecs, property_change_reply, 0);
984
985 if (NILP (XCONS (property_change_reply)->car))
606140dd 986 error ("Timed out waiting for property-notify event");
d1f21a66 987 }
2f65feb6
RS
988
989 unbind_to (count, Qnil);
ede4db72
RS
990}
991
992/* Called from XTread_socket in response to a PropertyNotify event. */
993
994void
995x_handle_property_notify (event)
996 XPropertyEvent *event;
997{
998 struct prop_location *prev = 0, *rest = property_change_wait_list;
999 while (rest)
1000 {
1001 if (rest->property == event->atom
1002 && rest->window == event->window
1003 && rest->display == event->display
1004 && rest->desired_state == event->state)
1005 {
1006#if 0
1007 fprintf (stderr, "Saw expected prop-%s on %s\n",
1008 (event->state == PropertyDelete ? "delete" : "change"),
5c3a351a 1009 (char *) XSYMBOL (x_atom_to_symbol (dpyinfo, event->display,
ede4db72
RS
1010 event->atom))
1011 ->name->data);
1012#endif
1013
d1f21a66
RS
1014 rest->arrived = 1;
1015
ede4db72
RS
1016 /* If this is the one wait_for_property_change is waiting for,
1017 tell it to wake up. */
d1f21a66 1018 if (rest == property_change_reply_object)
ede4db72
RS
1019 XCONS (property_change_reply)->car = Qt;
1020
1021 if (prev)
1022 prev->next = rest->next;
1023 else
1024 property_change_wait_list = rest->next;
002bbc0e 1025 free (rest);
ede4db72
RS
1026 return;
1027 }
1028 prev = rest;
1029 rest = rest->next;
1030 }
1031#if 0
1032 fprintf (stderr, "Saw UNexpected prop-%s on %s\n",
1033 (event->state == PropertyDelete ? "delete" : "change"),
5c3a351a
RS
1034 (char *) XSYMBOL (x_atom_to_symbol (dpyinfo,
1035 event->display, event->atom))
ede4db72
RS
1036 ->name->data);
1037#endif
1038}
1039
1040
1041\f
1042#if 0 /* #### MULTIPLE doesn't work yet */
1043
1044static Lisp_Object
1045fetch_multiple_target (event)
1046 XSelectionRequestEvent *event;
1047{
1048 Display *display = event->display;
5d0ba25b 1049 Window window = event->requestor;
ede4db72
RS
1050 Atom target = event->target;
1051 Atom selection_atom = event->selection;
1052 int result;
1053
1054 return
1055 Fcons (QMULTIPLE,
1056 x_get_window_property_as_lisp_data (display, window, target,
1057 QMULTIPLE, selection_atom));
1058}
1059
1060static Lisp_Object
1061copy_multiple_data (obj)
1062 Lisp_Object obj;
1063{
1064 Lisp_Object vec;
1065 int i;
1066 int size;
1067 if (CONSP (obj))
1068 return Fcons (XCONS (obj)->car, copy_multiple_data (XCONS (obj)->cdr));
1069
1070 CHECK_VECTOR (obj, 0);
1071 vec = Fmake_vector (size = XVECTOR (obj)->size, Qnil);
1072 for (i = 0; i < size; i++)
1073 {
1074 Lisp_Object vec2 = XVECTOR (obj)->contents [i];
1075 CHECK_VECTOR (vec2, 0);
1076 if (XVECTOR (vec2)->size != 2)
1077 /* ??? Confusing error message */
1078 Fsignal (Qerror, Fcons (build_string ("vectors must be of length 2"),
1079 Fcons (vec2, Qnil)));
1080 XVECTOR (vec)->contents [i] = Fmake_vector (2, Qnil);
1081 XVECTOR (XVECTOR (vec)->contents [i])->contents [0]
1082 = XVECTOR (vec2)->contents [0];
1083 XVECTOR (XVECTOR (vec)->contents [i])->contents [1]
1084 = XVECTOR (vec2)->contents [1];
1085 }
1086 return vec;
1087}
1088
1089#endif
1090
1091\f
1092/* Variables for communication with x_handle_selection_notify. */
1093static Atom reading_which_selection;
1094static Lisp_Object reading_selection_reply;
1095static Window reading_selection_window;
1096
1097/* Do protocol to read selection-data from the server.
1098 Converts this to Lisp data and returns it. */
1099
1100static Lisp_Object
1101x_get_foreign_selection (selection_symbol, target_type)
1102 Lisp_Object selection_symbol, target_type;
1103{
5d0ba25b 1104 Window requestor_window = FRAME_X_WINDOW (selected_frame);
3834c318 1105 Display *display = FRAME_X_DISPLAY (selected_frame);
5c3a351a 1106 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (selected_frame);
5d0ba25b 1107 Time requestor_time = last_event_timestamp;
5c3a351a
RS
1108 Atom target_property = dpyinfo->Xatom_EMACS_TMP;
1109 Atom selection_atom = symbol_to_x_atom (dpyinfo, display, selection_symbol);
ede4db72 1110 Atom type_atom;
80da0190 1111 int secs, usecs;
55b2d45d
RS
1112 int count = specpdl_ptr - specpdl;
1113 Lisp_Object frame;
ede4db72
RS
1114
1115 if (CONSP (target_type))
5c3a351a 1116 type_atom = symbol_to_x_atom (dpyinfo, display, XCONS (target_type)->car);
ede4db72 1117 else
5c3a351a 1118 type_atom = symbol_to_x_atom (dpyinfo, display, target_type);
ede4db72
RS
1119
1120 BLOCK_INPUT;
a7b24d46 1121 x_catch_errors (display);
ede4db72 1122 XConvertSelection (display, selection_atom, type_atom, target_property,
5d0ba25b 1123 requestor_window, requestor_time);
5c3a351a 1124 XFlush (display);
ede4db72
RS
1125
1126 /* Prepare to block until the reply has been read. */
5d0ba25b 1127 reading_selection_window = requestor_window;
ede4db72
RS
1128 reading_which_selection = selection_atom;
1129 XCONS (reading_selection_reply)->car = Qnil;
55b2d45d
RS
1130
1131 frame = some_frame_on_display (dpyinfo);
1132
1133 /* If the display no longer has frames, we can't expect
1134 to get many more selection requests from it, so don't
1135 bother trying to queue them. */
1136 if (!NILP (frame))
1137 {
1138 x_start_queuing_selection_requests (display);
1139
1140 record_unwind_protect (queue_selection_requests_unwind,
1141 frame);
1142 }
ede4db72
RS
1143 UNBLOCK_INPUT;
1144
80da0190
RS
1145 /* This allows quits. Also, don't wait forever. */
1146 secs = x_selection_timeout / 1000;
1147 usecs = (x_selection_timeout % 1000) * 1000;
1148 wait_reading_process_input (secs, usecs, reading_selection_reply, 0);
ede4db72 1149
7c6b2ea4 1150 BLOCK_INPUT;
a7b24d46
RS
1151 x_check_errors (display, "Cannot get selection: %s");
1152 x_uncatch_errors (display);
55b2d45d 1153 unbind_to (count, Qnil);
7c6b2ea4
RS
1154 UNBLOCK_INPUT;
1155
ede4db72 1156 if (NILP (XCONS (reading_selection_reply)->car))
606140dd
KH
1157 error ("Timed out waiting for reply from selection owner");
1158 if (EQ (XCONS (reading_selection_reply)->car, Qlambda))
1159 error ("No `%s' selection", XSYMBOL (selection_symbol)->name->data);
ede4db72
RS
1160
1161 /* Otherwise, the selection is waiting for us on the requested property. */
1162 return
5d0ba25b 1163 x_get_window_property_as_lisp_data (display, requestor_window,
ede4db72
RS
1164 target_property, target_type,
1165 selection_atom);
1166}
1167\f
1168/* Subroutines of x_get_window_property_as_lisp_data */
1169
002bbc0e 1170/* Use free, not XFree, to free the data obtained with this function. */
0158abbc 1171
ede4db72
RS
1172static void
1173x_get_window_property (display, window, property, data_ret, bytes_ret,
1174 actual_type_ret, actual_format_ret, actual_size_ret,
1175 delete_p)
1176 Display *display;
1177 Window window;
1178 Atom property;
1179 unsigned char **data_ret;
1180 int *bytes_ret;
1181 Atom *actual_type_ret;
1182 int *actual_format_ret;
1183 unsigned long *actual_size_ret;
1184 int delete_p;
1185{
1186 int total_size;
1187 unsigned long bytes_remaining;
1188 int offset = 0;
1189 unsigned char *tmp_data = 0;
1190 int result;
1191 int buffer_size = SELECTION_QUANTUM (display);
1192 if (buffer_size > MAX_SELECTION_QUANTUM) buffer_size = MAX_SELECTION_QUANTUM;
1193
1194 BLOCK_INPUT;
1195 /* First probe the thing to find out how big it is. */
1196 result = XGetWindowProperty (display, window, property,
137edb72 1197 0L, 0L, False, AnyPropertyType,
ede4db72
RS
1198 actual_type_ret, actual_format_ret,
1199 actual_size_ret,
1200 &bytes_remaining, &tmp_data);
ede4db72
RS
1201 if (result != Success)
1202 {
2f65feb6 1203 UNBLOCK_INPUT;
ede4db72
RS
1204 *data_ret = 0;
1205 *bytes_ret = 0;
1206 return;
1207 }
0158abbc
RS
1208 /* This was allocated by Xlib, so use XFree. */
1209 XFree ((char *) tmp_data);
ede4db72
RS
1210
1211 if (*actual_type_ret == None || *actual_format_ret == 0)
1212 {
2f65feb6 1213 UNBLOCK_INPUT;
ede4db72
RS
1214 return;
1215 }
1216
1217 total_size = bytes_remaining + 1;
1218 *data_ret = (unsigned char *) xmalloc (total_size);
1219
2a1a4c9d 1220 /* Now read, until we've gotten it all. */
ede4db72
RS
1221 while (bytes_remaining)
1222 {
1223#if 0
1224 int last = bytes_remaining;
1225#endif
1226 result
1227 = XGetWindowProperty (display, window, property,
137edb72 1228 (long)offset/4, (long)buffer_size/4,
2f65feb6 1229 False,
ede4db72
RS
1230 AnyPropertyType,
1231 actual_type_ret, actual_format_ret,
1232 actual_size_ret, &bytes_remaining, &tmp_data);
1233#if 0
1234 fprintf (stderr, "<< read %d\n", last-bytes_remaining);
1235#endif
1236 /* If this doesn't return Success at this point, it means that
1237 some clod deleted the selection while we were in the midst of
1238 reading it. Deal with that, I guess....
1239 */
1240 if (result != Success) break;
1241 *actual_size_ret *= *actual_format_ret / 8;
1242 bcopy (tmp_data, (*data_ret) + offset, *actual_size_ret);
1243 offset += *actual_size_ret;
0158abbc
RS
1244 /* This was allocated by Xlib, so use XFree. */
1245 XFree ((char *) tmp_data);
ede4db72 1246 }
2f65feb6 1247
5c3a351a 1248 XFlush (display);
ede4db72
RS
1249 UNBLOCK_INPUT;
1250 *bytes_ret = offset;
1251}
1252\f
002bbc0e 1253/* Use free, not XFree, to free the data obtained with this function. */
0158abbc 1254
ede4db72
RS
1255static void
1256receive_incremental_selection (display, window, property, target_type,
1257 min_size_bytes, data_ret, size_bytes_ret,
1258 type_ret, format_ret, size_ret)
1259 Display *display;
1260 Window window;
1261 Atom property;
1262 Lisp_Object target_type; /* for error messages only */
1263 unsigned int min_size_bytes;
1264 unsigned char **data_ret;
1265 int *size_bytes_ret;
1266 Atom *type_ret;
1267 unsigned long *size_ret;
1268 int *format_ret;
1269{
1270 int offset = 0;
d1f21a66 1271 struct prop_location *wait_object;
ede4db72
RS
1272 *size_bytes_ret = min_size_bytes;
1273 *data_ret = (unsigned char *) xmalloc (*size_bytes_ret);
1274#if 0
1275 fprintf (stderr, "\nread INCR %d\n", min_size_bytes);
1276#endif
2f65feb6
RS
1277
1278 /* At this point, we have read an INCR property.
1279 Delete the property to ack it.
1280 (But first, prepare to receive the next event in this handshake.)
ede4db72
RS
1281
1282 Now, we must loop, waiting for the sending window to put a value on
1283 that property, then reading the property, then deleting it to ack.
1284 We are done when the sender places a property of length 0.
1285 */
2f65feb6
RS
1286 BLOCK_INPUT;
1287 XSelectInput (display, window, STANDARD_EVENT_SET | PropertyChangeMask);
1288 XDeleteProperty (display, window, property);
d1f21a66
RS
1289 wait_object = expect_property_change (display, window, property,
1290 PropertyNewValue);
5c3a351a 1291 XFlush (display);
2f65feb6
RS
1292 UNBLOCK_INPUT;
1293
ede4db72
RS
1294 while (1)
1295 {
1296 unsigned char *tmp_data;
1297 int tmp_size_bytes;
d1f21a66 1298 wait_for_property_change (wait_object);
ede4db72 1299 /* expect it again immediately, because x_get_window_property may
2a1a4c9d 1300 .. no it won't, I don't get it.
ede4db72
RS
1301 .. Ok, I get it now, the Xt code that implements INCR is broken.
1302 */
ede4db72
RS
1303 x_get_window_property (display, window, property,
1304 &tmp_data, &tmp_size_bytes,
1305 type_ret, format_ret, size_ret, 1);
1306
1307 if (tmp_size_bytes == 0) /* we're done */
1308 {
1309#if 0
1310 fprintf (stderr, " read INCR done\n");
1311#endif
2f65feb6
RS
1312 if (! waiting_for_other_props_on_window (display, window))
1313 XSelectInput (display, window, STANDARD_EVENT_SET);
d1f21a66 1314 unexpect_property_change (wait_object);
002bbc0e 1315 /* Use free, not XFree, because x_get_window_property
0158abbc 1316 calls xmalloc itself. */
002bbc0e 1317 if (tmp_data) free (tmp_data);
ede4db72
RS
1318 break;
1319 }
2f65feb6
RS
1320
1321 BLOCK_INPUT;
1322 XDeleteProperty (display, window, property);
d1f21a66
RS
1323 wait_object = expect_property_change (display, window, property,
1324 PropertyNewValue);
5c3a351a 1325 XFlush (display);
2f65feb6
RS
1326 UNBLOCK_INPUT;
1327
ede4db72
RS
1328#if 0
1329 fprintf (stderr, " read INCR %d\n", tmp_size_bytes);
1330#endif
1331 if (*size_bytes_ret < offset + tmp_size_bytes)
1332 {
1333#if 0
1334 fprintf (stderr, " read INCR realloc %d -> %d\n",
1335 *size_bytes_ret, offset + tmp_size_bytes);
1336#endif
1337 *size_bytes_ret = offset + tmp_size_bytes;
1338 *data_ret = (unsigned char *) xrealloc (*data_ret, *size_bytes_ret);
1339 }
018cfa07 1340 bcopy (tmp_data, (*data_ret) + offset, tmp_size_bytes);
ede4db72 1341 offset += tmp_size_bytes;
002bbc0e 1342 /* Use free, not XFree, because x_get_window_property
0158abbc 1343 calls xmalloc itself. */
002bbc0e 1344 free (tmp_data);
ede4db72
RS
1345 }
1346}
1347\f
1348/* Once a requested selection is "ready" (we got a SelectionNotify event),
1349 fetch value from property PROPERTY of X window WINDOW on display DISPLAY.
1350 TARGET_TYPE and SELECTION_ATOM are used in error message if this fails. */
1351
1352static Lisp_Object
1353x_get_window_property_as_lisp_data (display, window, property, target_type,
1354 selection_atom)
1355 Display *display;
1356 Window window;
1357 Atom property;
1358 Lisp_Object target_type; /* for error messages only */
1359 Atom selection_atom; /* for error messages only */
1360{
1361 Atom actual_type;
1362 int actual_format;
1363 unsigned long actual_size;
1364 unsigned char *data = 0;
1365 int bytes = 0;
1366 Lisp_Object val;
5c3a351a 1367 struct x_display_info *dpyinfo = x_display_info_for_display (display);
ede4db72
RS
1368
1369 x_get_window_property (display, window, property, &data, &bytes,
1370 &actual_type, &actual_format, &actual_size, 1);
1371 if (! data)
1372 {
1373 int there_is_a_selection_owner;
1374 BLOCK_INPUT;
1375 there_is_a_selection_owner
1376 = XGetSelectionOwner (display, selection_atom);
1377 UNBLOCK_INPUT;
1378 while (1) /* Note debugger can no longer return, so this is obsolete */
1379 Fsignal (Qerror,
1380 there_is_a_selection_owner ?
1381 Fcons (build_string ("selection owner couldn't convert"),
1382 actual_type
1383 ? Fcons (target_type,
5c3a351a
RS
1384 Fcons (x_atom_to_symbol (dpyinfo, display,
1385 actual_type),
ede4db72
RS
1386 Qnil))
1387 : Fcons (target_type, Qnil))
1388 : Fcons (build_string ("no selection"),
5c3a351a
RS
1389 Fcons (x_atom_to_symbol (dpyinfo, display,
1390 selection_atom),
ede4db72
RS
1391 Qnil)));
1392 }
1393
5c3a351a 1394 if (actual_type == dpyinfo->Xatom_INCR)
ede4db72
RS
1395 {
1396 /* That wasn't really the data, just the beginning. */
1397
1398 unsigned int min_size_bytes = * ((unsigned int *) data);
1399 BLOCK_INPUT;
002bbc0e 1400 /* Use free, not XFree, because x_get_window_property
0158abbc 1401 calls xmalloc itself. */
002bbc0e 1402 free ((char *) data);
ede4db72
RS
1403 UNBLOCK_INPUT;
1404 receive_incremental_selection (display, window, property, target_type,
1405 min_size_bytes, &data, &bytes,
1406 &actual_type, &actual_format,
1407 &actual_size);
1408 }
1409
2f65feb6
RS
1410 BLOCK_INPUT;
1411 XDeleteProperty (display, window, property);
5c3a351a 1412 XFlush (display);
2f65feb6
RS
1413 UNBLOCK_INPUT;
1414
ede4db72
RS
1415 /* It's been read. Now convert it to a lisp object in some semi-rational
1416 manner. */
1417 val = selection_data_to_lisp_data (display, data, bytes,
1418 actual_type, actual_format);
1419
002bbc0e 1420 /* Use free, not XFree, because x_get_window_property
0158abbc 1421 calls xmalloc itself. */
002bbc0e 1422 free ((char *) data);
ede4db72
RS
1423 return val;
1424}
1425\f
1426/* These functions convert from the selection data read from the server into
1427 something that we can use from Lisp, and vice versa.
1428
1429 Type: Format: Size: Lisp Type:
1430 ----- ------- ----- -----------
1431 * 8 * String
1432 ATOM 32 1 Symbol
1433 ATOM 32 > 1 Vector of Symbols
1434 * 16 1 Integer
1435 * 16 > 1 Vector of Integers
1436 * 32 1 if <=16 bits: Integer
1437 if > 16 bits: Cons of top16, bot16
1438 * 32 > 1 Vector of the above
1439
1440 When converting a Lisp number to C, it is assumed to be of format 16 if
1441 it is an integer, and of format 32 if it is a cons of two integers.
1442
1443 When converting a vector of numbers from Lisp to C, it is assumed to be
1444 of format 16 if every element in the vector is an integer, and is assumed
1445 to be of format 32 if any element is a cons of two integers.
1446
1447 When converting an object to C, it may be of the form (SYMBOL . <data>)
1448 where SYMBOL is what we should claim that the type is. Format and
1449 representation are as above. */
1450
1451
1452
1453static Lisp_Object
1454selection_data_to_lisp_data (display, data, size, type, format)
1455 Display *display;
1456 unsigned char *data;
1457 Atom type;
1458 int size, format;
1459{
5c3a351a 1460 struct x_display_info *dpyinfo = x_display_info_for_display (display);
ede4db72 1461
5c3a351a 1462 if (type == dpyinfo->Xatom_NULL)
ede4db72
RS
1463 return QNULL;
1464
1465 /* Convert any 8-bit data to a string, for compactness. */
1466 else if (format == 8)
e6c7c988
KH
1467 {
1468 Lisp_Object str;
ede4db72 1469
e6c7c988
KH
1470 if (type != dpyinfo->Xatom_TEXT && type != dpyinfo->Xatom_COMPOUND_TEXT)
1471 str = make_string ((char *) data, size);
1472 else
1473 {
1474 /* If TYPE is `TEXT' or `COMPOUND_TEXT', we should decode
1475 DATA to Emacs internal format because DATA may be
1476 encoded in compound text format. */
1477 int bufsize, dummy;
1478 unsigned char *buf;
1479 struct coding_system coding;
90da0ee6 1480 Lisp_Object sym = intern ("iso-8859-1");
e6c7c988
KH
1481
1482 setup_coding_system (Fcheck_coding_system (sym), &coding);
1483 coding.last_block = 1;
1484 bufsize = decoding_buffer_size (&coding, size);
1485 buf = (unsigned char *) xmalloc (bufsize);
1486 size = decode_coding (&coding, data, buf, size, bufsize, &dummy);
1487 str = make_string ((char *) buf, size);
1488 xfree (buf);
1489 }
1490 return str;
1491 }
ede4db72
RS
1492 /* Convert a single atom to a Lisp_Symbol. Convert a set of atoms to
1493 a vector of symbols.
1494 */
1495 else if (type == XA_ATOM)
1496 {
1497 int i;
1498 if (size == sizeof (Atom))
5c3a351a 1499 return x_atom_to_symbol (dpyinfo, display, *((Atom *) data));
ede4db72
RS
1500 else
1501 {
1502 Lisp_Object v = Fmake_vector (size / sizeof (Atom), 0);
1503 for (i = 0; i < size / sizeof (Atom); i++)
5c3a351a
RS
1504 Faset (v, i, x_atom_to_symbol (dpyinfo, display,
1505 ((Atom *) data) [i]));
ede4db72
RS
1506 return v;
1507 }
1508 }
1509
1510 /* Convert a single 16 or small 32 bit number to a Lisp_Int.
1511 If the number is > 16 bits, convert it to a cons of integers,
1512 16 bits in each half.
1513 */
1514 else if (format == 32 && size == sizeof (long))
1515 return long_to_cons (((unsigned long *) data) [0]);
1516 else if (format == 16 && size == sizeof (short))
1517 return make_number ((int) (((unsigned short *) data) [0]));
1518
1519 /* Convert any other kind of data to a vector of numbers, represented
1520 as above (as an integer, or a cons of two 16 bit integers.)
1521 */
1522 else if (format == 16)
1523 {
1524 int i;
1525 Lisp_Object v = Fmake_vector (size / 4, 0);
1526 for (i = 0; i < size / 4; i++)
1527 {
1528 int j = (int) ((unsigned short *) data) [i];
1529 Faset (v, i, make_number (j));
1530 }
1531 return v;
1532 }
1533 else
1534 {
1535 int i;
1536 Lisp_Object v = Fmake_vector (size / 4, 0);
1537 for (i = 0; i < size / 4; i++)
1538 {
1539 unsigned long j = ((unsigned long *) data) [i];
1540 Faset (v, i, long_to_cons (j));
1541 }
1542 return v;
1543 }
1544}
1545
1546
002bbc0e 1547/* Use free, not XFree, to free the data obtained with this function. */
0158abbc 1548
ede4db72
RS
1549static void
1550lisp_data_to_selection_data (display, obj,
aca39f42
RS
1551 data_ret, type_ret, size_ret,
1552 format_ret, nofree_ret)
ede4db72
RS
1553 Display *display;
1554 Lisp_Object obj;
1555 unsigned char **data_ret;
1556 Atom *type_ret;
1557 unsigned int *size_ret;
1558 int *format_ret;
aca39f42 1559 int *nofree_ret;
ede4db72
RS
1560{
1561 Lisp_Object type = Qnil;
5c3a351a 1562 struct x_display_info *dpyinfo = x_display_info_for_display (display);
aca39f42
RS
1563
1564 *nofree_ret = 0;
1565
ede4db72
RS
1566 if (CONSP (obj) && SYMBOLP (XCONS (obj)->car))
1567 {
1568 type = XCONS (obj)->car;
1569 obj = XCONS (obj)->cdr;
1570 if (CONSP (obj) && NILP (XCONS (obj)->cdr))
1571 obj = XCONS (obj)->car;
1572 }
1573
1574 if (EQ (obj, QNULL) || (EQ (type, QNULL)))
1575 { /* This is not the same as declining */
1576 *format_ret = 32;
1577 *size_ret = 0;
1578 *data_ret = 0;
1579 type = QNULL;
1580 }
1581 else if (STRINGP (obj))
1582 {
e6c7c988
KH
1583 /* Since we are now handling multilingual text, we must consider
1584 sending back compound text. */
467e7675 1585 char charsets[MAX_CHARSET + 1];
e6c7c988
KH
1586 int num;
1587
ede4db72
RS
1588 *format_ret = 8;
1589 *size_ret = XSTRING (obj)->size;
aca39f42 1590 *data_ret = XSTRING (obj)->data;
467e7675 1591 bzero (charsets, MAX_CHARSET + 1);
e6c7c988
KH
1592 num = ((*size_ret <= 1) /* Check the possibility of short cut. */
1593 ? 0
1594 : find_charset_in_str (*data_ret, *size_ret, charsets));
1595
1596 if (!num || (num == 1 && charsets[CHARSET_ASCII]))
1597 {
1598 /* No multibyte character in OBJ. We need not encode it. */
1599 *nofree_ret = 1;
1600 if (NILP (type)) type = QSTRING;
1601 }
1602 else
1603 {
1604 /* We must encode contents of OBJ to compound text format.
1605 The format is compatible with what the target `STRING'
1606 expects if OBJ contains only ASCII and Latin-1
1607 characters. */
1608 int bufsize, dummy;
1609 unsigned char *buf;
1610 struct coding_system coding;
90da0ee6 1611 Lisp_Object sym = intern ("iso-8859-1");
e6c7c988
KH
1612
1613 setup_coding_system (Fcheck_coding_system (sym), &coding);
1614 coding.last_block = 1;
1615 bufsize = encoding_buffer_size (&coding, *size_ret);
1616 buf = (unsigned char *) xmalloc (bufsize);
1617 *size_ret = encode_coding (&coding, *data_ret, buf,
1618 *size_ret, bufsize, &dummy);
1619 *data_ret = buf;
1620 if (charsets[charset_latin_iso8859_1]
1621 && (num == 1 || (num == 2 && charsets[CHARSET_ASCII])))
1622 {
1623 /* Ok, we can return it as `STRING'. */
1624 if (NILP (type)) type = QSTRING;
1625 }
1626 else
1627 {
1628 /* We must return it as `COMPOUND_TEXT'. */
1629 if (NILP (type)) type = QCOMPOUND_TEXT;
1630 }
1631 }
ede4db72
RS
1632 }
1633 else if (SYMBOLP (obj))
1634 {
1635 *format_ret = 32;
1636 *size_ret = 1;
1637 *data_ret = (unsigned char *) xmalloc (sizeof (Atom) + 1);
1638 (*data_ret) [sizeof (Atom)] = 0;
5c3a351a 1639 (*(Atom **) data_ret) [0] = symbol_to_x_atom (dpyinfo, display, obj);
ede4db72
RS
1640 if (NILP (type)) type = QATOM;
1641 }
7da64e5c 1642 else if (INTEGERP (obj)
ede4db72
RS
1643 && XINT (obj) < 0xFFFF
1644 && XINT (obj) > -0xFFFF)
1645 {
1646 *format_ret = 16;
1647 *size_ret = 1;
1648 *data_ret = (unsigned char *) xmalloc (sizeof (short) + 1);
1649 (*data_ret) [sizeof (short)] = 0;
1650 (*(short **) data_ret) [0] = (short) XINT (obj);
1651 if (NILP (type)) type = QINTEGER;
1652 }
a87ed99c
RS
1653 else if (INTEGERP (obj)
1654 || (CONSP (obj) && INTEGERP (XCONS (obj)->car)
1655 && (INTEGERP (XCONS (obj)->cdr)
1656 || (CONSP (XCONS (obj)->cdr)
1657 && INTEGERP (XCONS (XCONS (obj)->cdr)->car)))))
ede4db72
RS
1658 {
1659 *format_ret = 32;
1660 *size_ret = 1;
1661 *data_ret = (unsigned char *) xmalloc (sizeof (long) + 1);
1662 (*data_ret) [sizeof (long)] = 0;
1663 (*(unsigned long **) data_ret) [0] = cons_to_long (obj);
1664 if (NILP (type)) type = QINTEGER;
1665 }
1666 else if (VECTORP (obj))
1667 {
1668 /* Lisp_Vectors may represent a set of ATOMs;
1669 a set of 16 or 32 bit INTEGERs;
1670 or a set of ATOM_PAIRs (represented as [[A1 A2] [A3 A4] ...]
1671 */
1672 int i;
1673
1674 if (SYMBOLP (XVECTOR (obj)->contents [0]))
1675 /* This vector is an ATOM set */
1676 {
1677 if (NILP (type)) type = QATOM;
1678 *size_ret = XVECTOR (obj)->size;
1679 *format_ret = 32;
1680 *data_ret = (unsigned char *) xmalloc ((*size_ret) * sizeof (Atom));
1681 for (i = 0; i < *size_ret; i++)
1682 if (SYMBOLP (XVECTOR (obj)->contents [i]))
1683 (*(Atom **) data_ret) [i]
5c3a351a 1684 = symbol_to_x_atom (dpyinfo, display, XVECTOR (obj)->contents [i]);
ede4db72
RS
1685 else
1686 Fsignal (Qerror, /* Qselection_error */
1687 Fcons (build_string
1688 ("all elements of selection vector must have same type"),
1689 Fcons (obj, Qnil)));
1690 }
1691#if 0 /* #### MULTIPLE doesn't work yet */
1692 else if (VECTORP (XVECTOR (obj)->contents [0]))
1693 /* This vector is an ATOM_PAIR set */
1694 {
1695 if (NILP (type)) type = QATOM_PAIR;
1696 *size_ret = XVECTOR (obj)->size;
1697 *format_ret = 32;
1698 *data_ret = (unsigned char *)
1699 xmalloc ((*size_ret) * sizeof (Atom) * 2);
1700 for (i = 0; i < *size_ret; i++)
1701 if (VECTORP (XVECTOR (obj)->contents [i]))
1702 {
1703 Lisp_Object pair = XVECTOR (obj)->contents [i];
1704 if (XVECTOR (pair)->size != 2)
1705 Fsignal (Qerror,
1706 Fcons (build_string
1707 ("elements of the vector must be vectors of exactly two elements"),
1708 Fcons (pair, Qnil)));
1709
1710 (*(Atom **) data_ret) [i * 2]
5c3a351a
RS
1711 = symbol_to_x_atom (dpyinfo, display,
1712 XVECTOR (pair)->contents [0]);
ede4db72 1713 (*(Atom **) data_ret) [(i * 2) + 1]
5c3a351a
RS
1714 = symbol_to_x_atom (dpyinfo, display,
1715 XVECTOR (pair)->contents [1]);
ede4db72
RS
1716 }
1717 else
1718 Fsignal (Qerror,
1719 Fcons (build_string
1720 ("all elements of the vector must be of the same type"),
1721 Fcons (obj, Qnil)));
1722
1723 }
1724#endif
1725 else
1726 /* This vector is an INTEGER set, or something like it */
1727 {
1728 *size_ret = XVECTOR (obj)->size;
1729 if (NILP (type)) type = QINTEGER;
1730 *format_ret = 16;
1731 for (i = 0; i < *size_ret; i++)
1732 if (CONSP (XVECTOR (obj)->contents [i]))
1733 *format_ret = 32;
7da64e5c 1734 else if (!INTEGERP (XVECTOR (obj)->contents [i]))
ede4db72
RS
1735 Fsignal (Qerror, /* Qselection_error */
1736 Fcons (build_string
1737 ("elements of selection vector must be integers or conses of integers"),
1738 Fcons (obj, Qnil)));
1739
1740 *data_ret = (unsigned char *) xmalloc (*size_ret * (*format_ret/8));
1741 for (i = 0; i < *size_ret; i++)
1742 if (*format_ret == 32)
1743 (*((unsigned long **) data_ret)) [i]
1744 = cons_to_long (XVECTOR (obj)->contents [i]);
1745 else
1746 (*((unsigned short **) data_ret)) [i]
1747 = (unsigned short) cons_to_long (XVECTOR (obj)->contents [i]);
1748 }
1749 }
1750 else
1751 Fsignal (Qerror, /* Qselection_error */
1752 Fcons (build_string ("unrecognised selection data"),
1753 Fcons (obj, Qnil)));
1754
5c3a351a 1755 *type_ret = symbol_to_x_atom (dpyinfo, display, type);
ede4db72
RS
1756}
1757
1758static Lisp_Object
1759clean_local_selection_data (obj)
1760 Lisp_Object obj;
1761{
1762 if (CONSP (obj)
7da64e5c 1763 && INTEGERP (XCONS (obj)->car)
ede4db72 1764 && CONSP (XCONS (obj)->cdr)
7da64e5c 1765 && INTEGERP (XCONS (XCONS (obj)->cdr)->car)
ede4db72
RS
1766 && NILP (XCONS (XCONS (obj)->cdr)->cdr))
1767 obj = Fcons (XCONS (obj)->car, XCONS (obj)->cdr);
1768
1769 if (CONSP (obj)
7da64e5c
RS
1770 && INTEGERP (XCONS (obj)->car)
1771 && INTEGERP (XCONS (obj)->cdr))
ede4db72
RS
1772 {
1773 if (XINT (XCONS (obj)->car) == 0)
1774 return XCONS (obj)->cdr;
1775 if (XINT (XCONS (obj)->car) == -1)
1776 return make_number (- XINT (XCONS (obj)->cdr));
1777 }
1778 if (VECTORP (obj))
1779 {
1780 int i;
1781 int size = XVECTOR (obj)->size;
1782 Lisp_Object copy;
1783 if (size == 1)
1784 return clean_local_selection_data (XVECTOR (obj)->contents [0]);
1785 copy = Fmake_vector (size, Qnil);
1786 for (i = 0; i < size; i++)
1787 XVECTOR (copy)->contents [i]
1788 = clean_local_selection_data (XVECTOR (obj)->contents [i]);
1789 return copy;
1790 }
1791 return obj;
1792}
1793\f
1794/* Called from XTread_socket to handle SelectionNotify events.
606140dd
KH
1795 If it's the selection we are waiting for, stop waiting
1796 by setting the car of reading_selection_reply to non-nil.
1797 We store t there if the reply is successful, lambda if not. */
ede4db72
RS
1798
1799void
1800x_handle_selection_notify (event)
1801 XSelectionEvent *event;
1802{
5d0ba25b 1803 if (event->requestor != reading_selection_window)
ede4db72
RS
1804 return;
1805 if (event->selection != reading_which_selection)
1806 return;
1807
606140dd
KH
1808 XCONS (reading_selection_reply)->car
1809 = (event->property != 0 ? Qt : Qlambda);
ede4db72
RS
1810}
1811
1812\f
a0d76c27
EN
1813DEFUN ("x-own-selection-internal", Fx_own_selection_internal,
1814 Sx_own_selection_internal, 2, 2, 0,
ede4db72
RS
1815 "Assert an X selection of the given TYPE with the given VALUE.\n\
1816TYPE is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
1817\(Those are literal upper-case symbol names, since that's what X expects.)\n\
1818VALUE is typically a string, or a cons of two markers, but may be\n\
a87ed99c 1819anything that the functions on `selection-converter-alist' know about.")
ede4db72
RS
1820 (selection_name, selection_value)
1821 Lisp_Object selection_name, selection_value;
1822{
703e0710 1823 check_x ();
ede4db72 1824 CHECK_SYMBOL (selection_name, 0);
606140dd 1825 if (NILP (selection_value)) error ("selection-value may not be nil");
ede4db72
RS
1826 x_own_selection (selection_name, selection_value);
1827 return selection_value;
1828}
1829
1830
1831/* Request the selection value from the owner. If we are the owner,
1832 simply return our selection value. If we are not the owner, this
1833 will block until all of the data has arrived. */
1834
a0d76c27
EN
1835DEFUN ("x-get-selection-internal", Fx_get_selection_internal,
1836 Sx_get_selection_internal, 2, 2, 0,
ede4db72
RS
1837 "Return text selected from some X window.\n\
1838SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
1839\(Those are literal upper-case symbol names, since that's what X expects.)\n\
a87ed99c 1840TYPE is the type of data desired, typically `STRING'.")
ede4db72
RS
1841 (selection_symbol, target_type)
1842 Lisp_Object selection_symbol, target_type;
1843{
1844 Lisp_Object val = Qnil;
1845 struct gcpro gcpro1, gcpro2;
1846 GCPRO2 (target_type, val); /* we store newly consed data into these */
703e0710 1847 check_x ();
ede4db72
RS
1848 CHECK_SYMBOL (selection_symbol, 0);
1849
1850#if 0 /* #### MULTIPLE doesn't work yet */
1851 if (CONSP (target_type)
1852 && XCONS (target_type)->car == QMULTIPLE)
1853 {
1854 CHECK_VECTOR (XCONS (target_type)->cdr, 0);
1855 /* So we don't destructively modify this... */
1856 target_type = copy_multiple_data (target_type);
1857 }
1858 else
1859#endif
1860 CHECK_SYMBOL (target_type, 0);
1861
1862 val = x_get_local_selection (selection_symbol, target_type);
1863
1864 if (NILP (val))
1865 {
1866 val = x_get_foreign_selection (selection_symbol, target_type);
1867 goto DONE;
1868 }
1869
1870 if (CONSP (val)
1871 && SYMBOLP (XCONS (val)->car))
1872 {
1873 val = XCONS (val)->cdr;
1874 if (CONSP (val) && NILP (XCONS (val)->cdr))
1875 val = XCONS (val)->car;
1876 }
1877 val = clean_local_selection_data (val);
1878 DONE:
1879 UNGCPRO;
1880 return val;
1881}
1882
a0d76c27
EN
1883DEFUN ("x-disown-selection-internal", Fx_disown_selection_internal,
1884 Sx_disown_selection_internal, 1, 2, 0,
a87ed99c
RS
1885 "If we own the selection SELECTION, disown it.\n\
1886Disowning it means there is no such selection.")
ede4db72
RS
1887 (selection, time)
1888 Lisp_Object selection;
1889 Lisp_Object time;
1890{
ede4db72
RS
1891 Time timestamp;
1892 Atom selection_atom;
1893 XSelectionClearEvent event;
3834c318 1894 Display *display;
5c3a351a 1895 struct x_display_info *dpyinfo;
ede4db72 1896
703e0710 1897 check_x ();
3834c318 1898 display = FRAME_X_DISPLAY (selected_frame);
5c3a351a 1899 dpyinfo = FRAME_X_DISPLAY_INFO (selected_frame);
ede4db72
RS
1900 CHECK_SYMBOL (selection, 0);
1901 if (NILP (time))
7da64e5c 1902 timestamp = last_event_timestamp;
ede4db72
RS
1903 else
1904 timestamp = cons_to_long (time);
1905
1906 if (NILP (assq_no_quit (selection, Vselection_alist)))
1907 return Qnil; /* Don't disown the selection when we're not the owner. */
1908
5c3a351a 1909 selection_atom = symbol_to_x_atom (dpyinfo, display, selection);
ede4db72
RS
1910
1911 BLOCK_INPUT;
1912 XSetSelectionOwner (display, selection_atom, None, timestamp);
1913 UNBLOCK_INPUT;
1914
eb8c3be9 1915 /* It doesn't seem to be guaranteed that a SelectionClear event will be
ede4db72
RS
1916 generated for a window which owns the selection when that window sets
1917 the selection owner to None. The NCD server does, the MIT Sun4 server
1918 doesn't. So we synthesize one; this means we might get two, but
1919 that's ok, because the second one won't have any effect. */
8d47f8c4
RS
1920 SELECTION_EVENT_DISPLAY (&event) = display;
1921 SELECTION_EVENT_SELECTION (&event) = selection_atom;
1922 SELECTION_EVENT_TIME (&event) = timestamp;
ede4db72
RS
1923 x_handle_selection_clear (&event);
1924
1925 return Qt;
1926}
1927
a87ed99c
RS
1928/* Get rid of all the selections in buffer BUFFER.
1929 This is used when we kill a buffer. */
1930
1931void
1932x_disown_buffer_selections (buffer)
1933 Lisp_Object buffer;
1934{
1935 Lisp_Object tail;
1936 struct buffer *buf = XBUFFER (buffer);
1937
1938 for (tail = Vselection_alist; CONSP (tail); tail = XCONS (tail)->cdr)
1939 {
1940 Lisp_Object elt, value;
1941 elt = XCONS (tail)->car;
1942 value = XCONS (elt)->cdr;
1943 if (CONSP (value) && MARKERP (XCONS (value)->car)
1944 && XMARKER (XCONS (value)->car)->buffer == buf)
1945 Fx_disown_selection_internal (XCONS (elt)->car, Qnil);
1946 }
1947}
ede4db72
RS
1948
1949DEFUN ("x-selection-owner-p", Fx_selection_owner_p, Sx_selection_owner_p,
1950 0, 1, 0,
a87ed99c 1951 "Whether the current Emacs process owns the given X Selection.\n\
ede4db72
RS
1952The arg should be the name of the selection in question, typically one of\n\
1953the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
1954\(Those are literal upper-case symbol names, since that's what X expects.)\n\
1955For convenience, the symbol nil is the same as `PRIMARY',\n\
1956and t is the same as `SECONDARY'.)")
1957 (selection)
1958 Lisp_Object selection;
1959{
703e0710 1960 check_x ();
ede4db72
RS
1961 CHECK_SYMBOL (selection, 0);
1962 if (EQ (selection, Qnil)) selection = QPRIMARY;
1963 if (EQ (selection, Qt)) selection = QSECONDARY;
1964
1965 if (NILP (Fassq (selection, Vselection_alist)))
1966 return Qnil;
1967 return Qt;
1968}
1969
1970DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
1971 0, 1, 0,
1972 "Whether there is an owner for the given X Selection.\n\
1973The arg should be the name of the selection in question, typically one of\n\
1974the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
1975\(Those are literal upper-case symbol names, since that's what X expects.)\n\
1976For convenience, the symbol nil is the same as `PRIMARY',\n\
1977and t is the same as `SECONDARY'.)")
1978 (selection)
1979 Lisp_Object selection;
1980{
1981 Window owner;
356ba514 1982 Atom atom;
3834c318
RS
1983 Display *dpy;
1984
b8c70430 1985 /* It should be safe to call this before we have an X frame. */
c6423dc1 1986 if (! FRAME_X_P (selected_frame))
b8c70430
RS
1987 return Qnil;
1988
3834c318 1989 dpy = FRAME_X_DISPLAY (selected_frame);
ede4db72
RS
1990 CHECK_SYMBOL (selection, 0);
1991 if (!NILP (Fx_selection_owner_p (selection)))
1992 return Qt;
356ba514
RS
1993 if (EQ (selection, Qnil)) selection = QPRIMARY;
1994 if (EQ (selection, Qt)) selection = QSECONDARY;
5c3a351a
RS
1995 atom = symbol_to_x_atom (FRAME_X_DISPLAY_INFO (selected_frame),
1996 dpy, selection);
356ba514
RS
1997 if (atom == 0)
1998 return Qnil;
ede4db72 1999 BLOCK_INPUT;
356ba514 2000 owner = XGetSelectionOwner (dpy, atom);
ede4db72
RS
2001 UNBLOCK_INPUT;
2002 return (owner ? Qt : Qnil);
2003}
2004
2005\f
2006#ifdef CUT_BUFFER_SUPPORT
2007
ede4db72
RS
2008/* Ensure that all 8 cut buffers exist. ICCCM says we gotta... */
2009static void
2010initialize_cut_buffers (display, window)
2011 Display *display;
2012 Window window;
2013{
2014 unsigned char *data = (unsigned char *) "";
2015 BLOCK_INPUT;
2016#define FROB(atom) XChangeProperty (display, window, atom, XA_STRING, 8, \
2017 PropModeAppend, data, 0)
2018 FROB (XA_CUT_BUFFER0);
2019 FROB (XA_CUT_BUFFER1);
2020 FROB (XA_CUT_BUFFER2);
2021 FROB (XA_CUT_BUFFER3);
2022 FROB (XA_CUT_BUFFER4);
2023 FROB (XA_CUT_BUFFER5);
2024 FROB (XA_CUT_BUFFER6);
2025 FROB (XA_CUT_BUFFER7);
2026#undef FROB
2027 UNBLOCK_INPUT;
ede4db72
RS
2028}
2029
2030
a87ed99c 2031#define CHECK_CUT_BUFFER(symbol,n) \
ede4db72
RS
2032 { CHECK_SYMBOL ((symbol), (n)); \
2033 if (!EQ((symbol), QCUT_BUFFER0) && !EQ((symbol), QCUT_BUFFER1) \
2034 && !EQ((symbol), QCUT_BUFFER2) && !EQ((symbol), QCUT_BUFFER3) \
2035 && !EQ((symbol), QCUT_BUFFER4) && !EQ((symbol), QCUT_BUFFER5) \
2036 && !EQ((symbol), QCUT_BUFFER6) && !EQ((symbol), QCUT_BUFFER7)) \
2037 Fsignal (Qerror, \
a87ed99c 2038 Fcons (build_string ("doesn't name a cut buffer"), \
ede4db72
RS
2039 Fcons ((symbol), Qnil))); \
2040 }
2041
a87ed99c
RS
2042DEFUN ("x-get-cut-buffer-internal", Fx_get_cut_buffer_internal,
2043 Sx_get_cut_buffer_internal, 1, 1, 0,
2044 "Returns the value of the named cut buffer (typically CUT_BUFFER0).")
ede4db72
RS
2045 (buffer)
2046 Lisp_Object buffer;
2047{
3834c318 2048 Window window;
ede4db72
RS
2049 Atom buffer_atom;
2050 unsigned char *data;
2051 int bytes;
2052 Atom type;
2053 int format;
2054 unsigned long size;
2055 Lisp_Object ret;
3834c318 2056 Display *display;
5c3a351a 2057 struct x_display_info *dpyinfo;
ede4db72 2058
703e0710 2059 check_x ();
3834c318 2060 display = FRAME_X_DISPLAY (selected_frame);
5c3a351a 2061 dpyinfo = FRAME_X_DISPLAY_INFO (selected_frame);
3834c318 2062 window = RootWindow (display, 0); /* Cut buffers are on screen 0 */
a87ed99c 2063 CHECK_CUT_BUFFER (buffer, 0);
5c3a351a 2064 buffer_atom = symbol_to_x_atom (dpyinfo, display, buffer);
ede4db72
RS
2065
2066 x_get_window_property (display, window, buffer_atom, &data, &bytes,
2067 &type, &format, &size, 0);
2068 if (!data) return Qnil;
2069
2070 if (format != 8 || type != XA_STRING)
2071 Fsignal (Qerror,
2072 Fcons (build_string ("cut buffer doesn't contain 8-bit data"),
5c3a351a 2073 Fcons (x_atom_to_symbol (dpyinfo, display, type),
ede4db72
RS
2074 Fcons (make_number (format), Qnil))));
2075
2076 ret = (bytes ? make_string ((char *) data, bytes) : Qnil);
002bbc0e 2077 /* Use free, not XFree, because x_get_window_property
0158abbc 2078 calls xmalloc itself. */
002bbc0e 2079 free (data);
ede4db72
RS
2080 return ret;
2081}
2082
2083
a87ed99c
RS
2084DEFUN ("x-store-cut-buffer-internal", Fx_store_cut_buffer_internal,
2085 Sx_store_cut_buffer_internal, 2, 2, 0,
2086 "Sets the value of the named cut buffer (typically CUT_BUFFER0).")
ede4db72
RS
2087 (buffer, string)
2088 Lisp_Object buffer, string;
2089{
3834c318 2090 Window window;
ede4db72
RS
2091 Atom buffer_atom;
2092 unsigned char *data;
2093 int bytes;
2094 int bytes_remaining;
3834c318
RS
2095 int max_bytes;
2096 Display *display;
ede4db72 2097
703e0710 2098 check_x ();
3834c318
RS
2099 display = FRAME_X_DISPLAY (selected_frame);
2100 window = RootWindow (display, 0); /* Cut buffers are on screen 0 */
2101
2102 max_bytes = SELECTION_QUANTUM (display);
2103 if (max_bytes > MAX_SELECTION_QUANTUM)
2104 max_bytes = MAX_SELECTION_QUANTUM;
2105
a87ed99c 2106 CHECK_CUT_BUFFER (buffer, 0);
ede4db72 2107 CHECK_STRING (string, 0);
5c3a351a
RS
2108 buffer_atom = symbol_to_x_atom (FRAME_X_DISPLAY_INFO (selected_frame),
2109 display, buffer);
ede4db72
RS
2110 data = (unsigned char *) XSTRING (string)->data;
2111 bytes = XSTRING (string)->size;
2112 bytes_remaining = bytes;
2113
04649dbc
KH
2114 if (! FRAME_X_DISPLAY_INFO (selected_frame)->cut_buffers_initialized)
2115 {
2116 initialize_cut_buffers (display, window);
2117 FRAME_X_DISPLAY_INFO (selected_frame)->cut_buffers_initialized = 1;
2118 }
ede4db72
RS
2119
2120 BLOCK_INPUT;
10608c8c
RS
2121
2122 /* Don't mess up with an empty value. */
2123 if (!bytes_remaining)
2124 XChangeProperty (display, window, buffer_atom, XA_STRING, 8,
2125 PropModeReplace, data, 0);
2126
ede4db72
RS
2127 while (bytes_remaining)
2128 {
2129 int chunk = (bytes_remaining < max_bytes
2130 ? bytes_remaining : max_bytes);
2131 XChangeProperty (display, window, buffer_atom, XA_STRING, 8,
2132 (bytes_remaining == bytes
2133 ? PropModeReplace
2134 : PropModeAppend),
2135 data, chunk);
2136 data += chunk;
2137 bytes_remaining -= chunk;
2138 }
2139 UNBLOCK_INPUT;
2140 return string;
2141}
2142
2143
a87ed99c
RS
2144DEFUN ("x-rotate-cut-buffers-internal", Fx_rotate_cut_buffers_internal,
2145 Sx_rotate_cut_buffers_internal, 1, 1, 0,
2146 "Rotate the values of the cut buffers by the given number of steps;\n\
ede4db72
RS
2147positive means move values forward, negative means backward.")
2148 (n)
2149 Lisp_Object n;
2150{
3834c318
RS
2151 Window window;
2152 Atom props[8];
2153 Display *display;
ede4db72 2154
703e0710 2155 check_x ();
3834c318
RS
2156 display = FRAME_X_DISPLAY (selected_frame);
2157 window = RootWindow (display, 0); /* Cut buffers are on screen 0 */
7da64e5c 2158 CHECK_NUMBER (n, 0);
3834c318
RS
2159 if (XINT (n) == 0)
2160 return n;
04649dbc
KH
2161 if (! FRAME_X_DISPLAY_INFO (selected_frame)->cut_buffers_initialized)
2162 {
2163 initialize_cut_buffers (display, window);
2164 FRAME_X_DISPLAY_INFO (selected_frame)->cut_buffers_initialized = 1;
2165 }
3834c318 2166
ede4db72
RS
2167 props[0] = XA_CUT_BUFFER0;
2168 props[1] = XA_CUT_BUFFER1;
2169 props[2] = XA_CUT_BUFFER2;
2170 props[3] = XA_CUT_BUFFER3;
2171 props[4] = XA_CUT_BUFFER4;
2172 props[5] = XA_CUT_BUFFER5;
2173 props[6] = XA_CUT_BUFFER6;
2174 props[7] = XA_CUT_BUFFER7;
2175 BLOCK_INPUT;
2176 XRotateWindowProperties (display, window, props, 8, XINT (n));
2177 UNBLOCK_INPUT;
2178 return n;
2179}
2180
2181#endif
2182\f
ede4db72
RS
2183void
2184syms_of_xselect ()
2185{
ede4db72
RS
2186 defsubr (&Sx_get_selection_internal);
2187 defsubr (&Sx_own_selection_internal);
2188 defsubr (&Sx_disown_selection_internal);
2189 defsubr (&Sx_selection_owner_p);
2190 defsubr (&Sx_selection_exists_p);
2191
2192#ifdef CUT_BUFFER_SUPPORT
a87ed99c
RS
2193 defsubr (&Sx_get_cut_buffer_internal);
2194 defsubr (&Sx_store_cut_buffer_internal);
2195 defsubr (&Sx_rotate_cut_buffers_internal);
ede4db72
RS
2196#endif
2197
2198 reading_selection_reply = Fcons (Qnil, Qnil);
2199 staticpro (&reading_selection_reply);
2200 reading_selection_window = 0;
2201 reading_which_selection = 0;
2202
2203 property_change_wait_list = 0;
2f65feb6 2204 prop_location_identifier = 0;
ede4db72
RS
2205 property_change_reply = Fcons (Qnil, Qnil);
2206 staticpro (&property_change_reply);
2207
2208 Vselection_alist = Qnil;
2209 staticpro (&Vselection_alist);
2210
2211 DEFVAR_LISP ("selection-converter-alist", &Vselection_converter_alist,
2212 "An alist associating X Windows selection-types with functions.\n\
2213These functions are called to convert the selection, with three args:\n\
2214the name of the selection (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');\n\
2215a desired type to which the selection should be converted;\n\
2216and the local selection value (whatever was given to `x-own-selection').\n\
2217\n\
2218The function should return the value to send to the X server\n\
2219\(typically a string). A return value of nil\n\
2220means that the conversion could not be done.\n\
2221A return value which is the symbol `NULL'\n\
2222means that a side-effect was executed,\n\
2223and there is no meaningful selection value.");
2224 Vselection_converter_alist = Qnil;
2225
2226 DEFVAR_LISP ("x-lost-selection-hooks", &Vx_lost_selection_hooks,
2227 "A list of functions to be called when Emacs loses an X selection.\n\
2228\(This happens when some other X client makes its own selection\n\
2229or when a Lisp program explicitly clears the selection.)\n\
2230The functions are called with one argument, the selection type\n\
d31b6237 2231\(a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD').");
ede4db72
RS
2232 Vx_lost_selection_hooks = Qnil;
2233
2234 DEFVAR_LISP ("x-sent-selection-hooks", &Vx_sent_selection_hooks,
2235 "A list of functions to be called when Emacs answers a selection request.\n\
2236The functions are called with four arguments:\n\
2237 - the selection name (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');\n\
2238 - the selection-type which Emacs was asked to convert the\n\
2239 selection into before sending (for example, `STRING' or `LENGTH');\n\
2240 - a flag indicating success or failure for responding to the request.\n\
2241We might have failed (and declined the request) for any number of reasons,\n\
2242including being asked for a selection that we no longer own, or being asked\n\
2243to convert into a type that we don't know about or that is inappropriate.\n\
2244This hook doesn't let you change the behavior of Emacs's selection replies,\n\
2245it merely informs you that they have happened.");
2246 Vx_sent_selection_hooks = Qnil;
2247
2248 DEFVAR_INT ("x-selection-timeout", &x_selection_timeout,
80da0190 2249 "Number of milliseconds to wait for a selection reply.\n\
2a1a4c9d 2250If the selection owner doesn't reply in this time, we give up.\n\
ede4db72 2251A value of 0 means wait as long as necessary. This is initialized from the\n\
80da0190 2252\"*selectionTimeout\" resource.");
ede4db72
RS
2253 x_selection_timeout = 0;
2254
2255 QPRIMARY = intern ("PRIMARY"); staticpro (&QPRIMARY);
2256 QSECONDARY = intern ("SECONDARY"); staticpro (&QSECONDARY);
2257 QSTRING = intern ("STRING"); staticpro (&QSTRING);
2258 QINTEGER = intern ("INTEGER"); staticpro (&QINTEGER);
2259 QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD);
2260 QTIMESTAMP = intern ("TIMESTAMP"); staticpro (&QTIMESTAMP);
2261 QTEXT = intern ("TEXT"); staticpro (&QTEXT);
e6c7c988 2262 QCOMPOUND_TEXT = intern ("COMPOUND_TEXT"); staticpro (&QCOMPOUND_TEXT);
ede4db72
RS
2263 QTIMESTAMP = intern ("TIMESTAMP"); staticpro (&QTIMESTAMP);
2264 QDELETE = intern ("DELETE"); staticpro (&QDELETE);
2265 QMULTIPLE = intern ("MULTIPLE"); staticpro (&QMULTIPLE);
2266 QINCR = intern ("INCR"); staticpro (&QINCR);
2267 QEMACS_TMP = intern ("_EMACS_TMP_"); staticpro (&QEMACS_TMP);
2268 QTARGETS = intern ("TARGETS"); staticpro (&QTARGETS);
2269 QATOM = intern ("ATOM"); staticpro (&QATOM);
2270 QATOM_PAIR = intern ("ATOM_PAIR"); staticpro (&QATOM_PAIR);
2271 QNULL = intern ("NULL"); staticpro (&QNULL);
2272
2273#ifdef CUT_BUFFER_SUPPORT
2274 QCUT_BUFFER0 = intern ("CUT_BUFFER0"); staticpro (&QCUT_BUFFER0);
2275 QCUT_BUFFER1 = intern ("CUT_BUFFER1"); staticpro (&QCUT_BUFFER1);
2276 QCUT_BUFFER2 = intern ("CUT_BUFFER2"); staticpro (&QCUT_BUFFER2);
2277 QCUT_BUFFER3 = intern ("CUT_BUFFER3"); staticpro (&QCUT_BUFFER3);
2278 QCUT_BUFFER4 = intern ("CUT_BUFFER4"); staticpro (&QCUT_BUFFER4);
2279 QCUT_BUFFER5 = intern ("CUT_BUFFER5"); staticpro (&QCUT_BUFFER5);
2280 QCUT_BUFFER6 = intern ("CUT_BUFFER6"); staticpro (&QCUT_BUFFER6);
2281 QCUT_BUFFER7 = intern ("CUT_BUFFER7"); staticpro (&QCUT_BUFFER7);
2282#endif
2283
2284}