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