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