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