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