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