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