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