Fix -Wimplicit warnings.
[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 Vclipboard_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 str = make_unibyte_string ((char *) data, size);
1498 else
1499 {
1500 int bufsize;
1501 unsigned char *buf;
1502 struct coding_system coding;
1503
1504 setup_coding_system
1505 (Fcheck_coding_system(Vclipboard_coding_system), &coding);
1506 coding.mode |= CODING_MODE_LAST_BLOCK;
1507 bufsize = decoding_buffer_size (&coding, size);
1508 buf = (unsigned char *) xmalloc (bufsize);
1509 decode_coding (&coding, data, buf, size, bufsize);
1510 size = (coding.fake_multibyte
1511 ? multibyte_chars_in_text (buf, coding.produced)
1512 : coding.produced_char);
1513 str = make_string_from_bytes ((char *) buf, size, coding.produced);
1514 xfree (buf);
1515 }
1516 return str;
1517 }
1518 /* Convert a single atom to a Lisp_Symbol. Convert a set of atoms to
1519 a vector of symbols.
1520 */
1521 else if (type == XA_ATOM)
1522 {
1523 int i;
1524 if (size == sizeof (Atom))
1525 return x_atom_to_symbol (dpyinfo, display, *((Atom *) data));
1526 else
1527 {
1528 Lisp_Object v = Fmake_vector (make_number (size / sizeof (Atom)),
1529 make_number (0));
1530 for (i = 0; i < size / sizeof (Atom); i++)
1531 Faset (v, make_number (i),
1532 x_atom_to_symbol (dpyinfo, display, ((Atom *) data) [i]));
1533 return v;
1534 }
1535 }
1536
1537 /* Convert a single 16 or small 32 bit number to a Lisp_Int.
1538 If the number is > 16 bits, convert it to a cons of integers,
1539 16 bits in each half.
1540 */
1541 else if (format == 32 && size == sizeof (long))
1542 return long_to_cons (((unsigned long *) data) [0]);
1543 else if (format == 16 && size == sizeof (short))
1544 return make_number ((int) (((unsigned short *) data) [0]));
1545
1546 /* Convert any other kind of data to a vector of numbers, represented
1547 as above (as an integer, or a cons of two 16 bit integers.)
1548 */
1549 else if (format == 16)
1550 {
1551 int i;
1552 Lisp_Object v;
1553 v = Fmake_vector (make_number (size / 2), make_number (0));
1554 for (i = 0; i < size / 2; i++)
1555 {
1556 int j = (int) ((unsigned short *) data) [i];
1557 Faset (v, make_number (i), make_number (j));
1558 }
1559 return v;
1560 }
1561 else
1562 {
1563 int i;
1564 Lisp_Object v = Fmake_vector (make_number (size / 4), make_number (0));
1565 for (i = 0; i < size / 4; i++)
1566 {
1567 unsigned long j = ((unsigned long *) data) [i];
1568 Faset (v, make_number (i), long_to_cons (j));
1569 }
1570 return v;
1571 }
1572 }
1573
1574
1575 /* Use xfree, not XFree, to free the data obtained with this function. */
1576
1577 static void
1578 lisp_data_to_selection_data (display, obj,
1579 data_ret, type_ret, size_ret,
1580 format_ret, nofree_ret)
1581 Display *display;
1582 Lisp_Object obj;
1583 unsigned char **data_ret;
1584 Atom *type_ret;
1585 unsigned int *size_ret;
1586 int *format_ret;
1587 int *nofree_ret;
1588 {
1589 Lisp_Object type = Qnil;
1590 struct x_display_info *dpyinfo = x_display_info_for_display (display);
1591
1592 *nofree_ret = 0;
1593
1594 if (CONSP (obj) && SYMBOLP (XCONS (obj)->car))
1595 {
1596 type = XCONS (obj)->car;
1597 obj = XCONS (obj)->cdr;
1598 if (CONSP (obj) && NILP (XCONS (obj)->cdr))
1599 obj = XCONS (obj)->car;
1600 }
1601
1602 if (EQ (obj, QNULL) || (EQ (type, QNULL)))
1603 { /* This is not the same as declining */
1604 *format_ret = 32;
1605 *size_ret = 0;
1606 *data_ret = 0;
1607 type = QNULL;
1608 }
1609 else if (STRINGP (obj))
1610 {
1611 /* Since we are now handling multilingual text, we must consider
1612 sending back compound text. */
1613 int charsets[MAX_CHARSET + 1];
1614 int num;
1615
1616 *format_ret = 8;
1617 *size_ret = STRING_BYTES (XSTRING (obj));
1618 *data_ret = XSTRING (obj)->data;
1619 bzero (charsets, (MAX_CHARSET + 1) * sizeof (int));
1620 num = ((*size_ret <= 1 /* Check the possibility of short cut. */
1621 || NILP (buffer_defaults.enable_multibyte_characters))
1622 ? 0
1623 : find_charset_in_str (*data_ret, *size_ret, charsets, Qnil));
1624
1625 if (!num || (num == 1 && charsets[CHARSET_ASCII]))
1626 {
1627 /* No multibyte character in OBJ. We need not encode it. */
1628 *nofree_ret = 1;
1629 if (NILP (type)) type = QSTRING;
1630 }
1631 else
1632 {
1633 /* We must encode contents of OBJ to compound text format.
1634 The format is compatible with what the target `STRING'
1635 expects if OBJ contains only ASCII and Latin-1
1636 characters. */
1637 int bufsize;
1638 unsigned char *buf;
1639 struct coding_system coding;
1640
1641 setup_coding_system
1642 (Fcheck_coding_system (Vclipboard_coding_system), &coding);
1643 coding.mode |= CODING_MODE_LAST_BLOCK;
1644 bufsize = encoding_buffer_size (&coding, *size_ret);
1645 buf = (unsigned char *) xmalloc (bufsize);
1646 encode_coding (&coding, *data_ret, buf, *size_ret, bufsize);
1647 *size_ret = coding.produced;
1648 *data_ret = buf;
1649 if (charsets[charset_latin_iso8859_1]
1650 && (num == 1 || (num == 2 && charsets[CHARSET_ASCII])))
1651 {
1652 /* Ok, we can return it as `STRING'. */
1653 if (NILP (type)) type = QSTRING;
1654 }
1655 else
1656 {
1657 /* We must return it as `COMPOUND_TEXT'. */
1658 if (NILP (type)) type = QCOMPOUND_TEXT;
1659 }
1660 }
1661 }
1662 else if (SYMBOLP (obj))
1663 {
1664 *format_ret = 32;
1665 *size_ret = 1;
1666 *data_ret = (unsigned char *) xmalloc (sizeof (Atom) + 1);
1667 (*data_ret) [sizeof (Atom)] = 0;
1668 (*(Atom **) data_ret) [0] = symbol_to_x_atom (dpyinfo, display, obj);
1669 if (NILP (type)) type = QATOM;
1670 }
1671 else if (INTEGERP (obj)
1672 && XINT (obj) < 0xFFFF
1673 && XINT (obj) > -0xFFFF)
1674 {
1675 *format_ret = 16;
1676 *size_ret = 1;
1677 *data_ret = (unsigned char *) xmalloc (sizeof (short) + 1);
1678 (*data_ret) [sizeof (short)] = 0;
1679 (*(short **) data_ret) [0] = (short) XINT (obj);
1680 if (NILP (type)) type = QINTEGER;
1681 }
1682 else if (INTEGERP (obj)
1683 || (CONSP (obj) && INTEGERP (XCONS (obj)->car)
1684 && (INTEGERP (XCONS (obj)->cdr)
1685 || (CONSP (XCONS (obj)->cdr)
1686 && INTEGERP (XCONS (XCONS (obj)->cdr)->car)))))
1687 {
1688 *format_ret = 32;
1689 *size_ret = 1;
1690 *data_ret = (unsigned char *) xmalloc (sizeof (long) + 1);
1691 (*data_ret) [sizeof (long)] = 0;
1692 (*(unsigned long **) data_ret) [0] = cons_to_long (obj);
1693 if (NILP (type)) type = QINTEGER;
1694 }
1695 else if (VECTORP (obj))
1696 {
1697 /* Lisp_Vectors may represent a set of ATOMs;
1698 a set of 16 or 32 bit INTEGERs;
1699 or a set of ATOM_PAIRs (represented as [[A1 A2] [A3 A4] ...]
1700 */
1701 int i;
1702
1703 if (SYMBOLP (XVECTOR (obj)->contents [0]))
1704 /* This vector is an ATOM set */
1705 {
1706 if (NILP (type)) type = QATOM;
1707 *size_ret = XVECTOR (obj)->size;
1708 *format_ret = 32;
1709 *data_ret = (unsigned char *) xmalloc ((*size_ret) * sizeof (Atom));
1710 for (i = 0; i < *size_ret; i++)
1711 if (SYMBOLP (XVECTOR (obj)->contents [i]))
1712 (*(Atom **) data_ret) [i]
1713 = symbol_to_x_atom (dpyinfo, display, XVECTOR (obj)->contents [i]);
1714 else
1715 Fsignal (Qerror, /* Qselection_error */
1716 Fcons (build_string
1717 ("all elements of selection vector must have same type"),
1718 Fcons (obj, Qnil)));
1719 }
1720 #if 0 /* #### MULTIPLE doesn't work yet */
1721 else if (VECTORP (XVECTOR (obj)->contents [0]))
1722 /* This vector is an ATOM_PAIR set */
1723 {
1724 if (NILP (type)) type = QATOM_PAIR;
1725 *size_ret = XVECTOR (obj)->size;
1726 *format_ret = 32;
1727 *data_ret = (unsigned char *)
1728 xmalloc ((*size_ret) * sizeof (Atom) * 2);
1729 for (i = 0; i < *size_ret; i++)
1730 if (VECTORP (XVECTOR (obj)->contents [i]))
1731 {
1732 Lisp_Object pair = XVECTOR (obj)->contents [i];
1733 if (XVECTOR (pair)->size != 2)
1734 Fsignal (Qerror,
1735 Fcons (build_string
1736 ("elements of the vector must be vectors of exactly two elements"),
1737 Fcons (pair, Qnil)));
1738
1739 (*(Atom **) data_ret) [i * 2]
1740 = symbol_to_x_atom (dpyinfo, display,
1741 XVECTOR (pair)->contents [0]);
1742 (*(Atom **) data_ret) [(i * 2) + 1]
1743 = symbol_to_x_atom (dpyinfo, display,
1744 XVECTOR (pair)->contents [1]);
1745 }
1746 else
1747 Fsignal (Qerror,
1748 Fcons (build_string
1749 ("all elements of the vector must be of the same type"),
1750 Fcons (obj, Qnil)));
1751
1752 }
1753 #endif
1754 else
1755 /* This vector is an INTEGER set, or something like it */
1756 {
1757 *size_ret = XVECTOR (obj)->size;
1758 if (NILP (type)) type = QINTEGER;
1759 *format_ret = 16;
1760 for (i = 0; i < *size_ret; i++)
1761 if (CONSP (XVECTOR (obj)->contents [i]))
1762 *format_ret = 32;
1763 else if (!INTEGERP (XVECTOR (obj)->contents [i]))
1764 Fsignal (Qerror, /* Qselection_error */
1765 Fcons (build_string
1766 ("elements of selection vector must be integers or conses of integers"),
1767 Fcons (obj, Qnil)));
1768
1769 *data_ret = (unsigned char *) xmalloc (*size_ret * (*format_ret/8));
1770 for (i = 0; i < *size_ret; i++)
1771 if (*format_ret == 32)
1772 (*((unsigned long **) data_ret)) [i]
1773 = cons_to_long (XVECTOR (obj)->contents [i]);
1774 else
1775 (*((unsigned short **) data_ret)) [i]
1776 = (unsigned short) cons_to_long (XVECTOR (obj)->contents [i]);
1777 }
1778 }
1779 else
1780 Fsignal (Qerror, /* Qselection_error */
1781 Fcons (build_string ("unrecognised selection data"),
1782 Fcons (obj, Qnil)));
1783
1784 *type_ret = symbol_to_x_atom (dpyinfo, display, type);
1785 }
1786
1787 static Lisp_Object
1788 clean_local_selection_data (obj)
1789 Lisp_Object obj;
1790 {
1791 if (CONSP (obj)
1792 && INTEGERP (XCONS (obj)->car)
1793 && CONSP (XCONS (obj)->cdr)
1794 && INTEGERP (XCONS (XCONS (obj)->cdr)->car)
1795 && NILP (XCONS (XCONS (obj)->cdr)->cdr))
1796 obj = Fcons (XCONS (obj)->car, XCONS (obj)->cdr);
1797
1798 if (CONSP (obj)
1799 && INTEGERP (XCONS (obj)->car)
1800 && INTEGERP (XCONS (obj)->cdr))
1801 {
1802 if (XINT (XCONS (obj)->car) == 0)
1803 return XCONS (obj)->cdr;
1804 if (XINT (XCONS (obj)->car) == -1)
1805 return make_number (- XINT (XCONS (obj)->cdr));
1806 }
1807 if (VECTORP (obj))
1808 {
1809 int i;
1810 int size = XVECTOR (obj)->size;
1811 Lisp_Object copy;
1812 if (size == 1)
1813 return clean_local_selection_data (XVECTOR (obj)->contents [0]);
1814 copy = Fmake_vector (make_number (size), Qnil);
1815 for (i = 0; i < size; i++)
1816 XVECTOR (copy)->contents [i]
1817 = clean_local_selection_data (XVECTOR (obj)->contents [i]);
1818 return copy;
1819 }
1820 return obj;
1821 }
1822 \f
1823 /* Called from XTread_socket to handle SelectionNotify events.
1824 If it's the selection we are waiting for, stop waiting
1825 by setting the car of reading_selection_reply to non-nil.
1826 We store t there if the reply is successful, lambda if not. */
1827
1828 void
1829 x_handle_selection_notify (event)
1830 XSelectionEvent *event;
1831 {
1832 if (event->requestor != reading_selection_window)
1833 return;
1834 if (event->selection != reading_which_selection)
1835 return;
1836
1837 XCONS (reading_selection_reply)->car
1838 = (event->property != 0 ? Qt : Qlambda);
1839 }
1840
1841 \f
1842 DEFUN ("x-own-selection-internal", Fx_own_selection_internal,
1843 Sx_own_selection_internal, 2, 2, 0,
1844 "Assert an X selection of the given TYPE with the given VALUE.\n\
1845 TYPE is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
1846 \(Those are literal upper-case symbol names, since that's what X expects.)\n\
1847 VALUE is typically a string, or a cons of two markers, but may be\n\
1848 anything that the functions on `selection-converter-alist' know about.")
1849 (selection_name, selection_value)
1850 Lisp_Object selection_name, selection_value;
1851 {
1852 check_x ();
1853 CHECK_SYMBOL (selection_name, 0);
1854 if (NILP (selection_value)) error ("selection-value may not be nil");
1855 x_own_selection (selection_name, selection_value);
1856 return selection_value;
1857 }
1858
1859
1860 /* Request the selection value from the owner. If we are the owner,
1861 simply return our selection value. If we are not the owner, this
1862 will block until all of the data has arrived. */
1863
1864 DEFUN ("x-get-selection-internal", Fx_get_selection_internal,
1865 Sx_get_selection_internal, 2, 2, 0,
1866 "Return text selected from some X window.\n\
1867 SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
1868 \(Those are literal upper-case symbol names, since that's what X expects.)\n\
1869 TYPE is the type of data desired, typically `STRING'.")
1870 (selection_symbol, target_type)
1871 Lisp_Object selection_symbol, target_type;
1872 {
1873 Lisp_Object val = Qnil;
1874 struct gcpro gcpro1, gcpro2;
1875 GCPRO2 (target_type, val); /* we store newly consed data into these */
1876 check_x ();
1877 CHECK_SYMBOL (selection_symbol, 0);
1878
1879 #if 0 /* #### MULTIPLE doesn't work yet */
1880 if (CONSP (target_type)
1881 && XCONS (target_type)->car == QMULTIPLE)
1882 {
1883 CHECK_VECTOR (XCONS (target_type)->cdr, 0);
1884 /* So we don't destructively modify this... */
1885 target_type = copy_multiple_data (target_type);
1886 }
1887 else
1888 #endif
1889 CHECK_SYMBOL (target_type, 0);
1890
1891 val = x_get_local_selection (selection_symbol, target_type);
1892
1893 if (NILP (val))
1894 {
1895 val = x_get_foreign_selection (selection_symbol, target_type);
1896 goto DONE;
1897 }
1898
1899 if (CONSP (val)
1900 && SYMBOLP (XCONS (val)->car))
1901 {
1902 val = XCONS (val)->cdr;
1903 if (CONSP (val) && NILP (XCONS (val)->cdr))
1904 val = XCONS (val)->car;
1905 }
1906 val = clean_local_selection_data (val);
1907 DONE:
1908 UNGCPRO;
1909 return val;
1910 }
1911
1912 DEFUN ("x-disown-selection-internal", Fx_disown_selection_internal,
1913 Sx_disown_selection_internal, 1, 2, 0,
1914 "If we own the selection SELECTION, disown it.\n\
1915 Disowning it means there is no such selection.")
1916 (selection, time)
1917 Lisp_Object selection;
1918 Lisp_Object time;
1919 {
1920 Time timestamp;
1921 Atom selection_atom;
1922 struct selection_input_event event;
1923 Display *display;
1924 struct x_display_info *dpyinfo;
1925
1926 check_x ();
1927 display = FRAME_X_DISPLAY (selected_frame);
1928 dpyinfo = FRAME_X_DISPLAY_INFO (selected_frame);
1929 CHECK_SYMBOL (selection, 0);
1930 if (NILP (time))
1931 timestamp = last_event_timestamp;
1932 else
1933 timestamp = cons_to_long (time);
1934
1935 if (NILP (assq_no_quit (selection, Vselection_alist)))
1936 return Qnil; /* Don't disown the selection when we're not the owner. */
1937
1938 selection_atom = symbol_to_x_atom (dpyinfo, display, selection);
1939
1940 BLOCK_INPUT;
1941 XSetSelectionOwner (display, selection_atom, None, timestamp);
1942 UNBLOCK_INPUT;
1943
1944 /* It doesn't seem to be guaranteed that a SelectionClear event will be
1945 generated for a window which owns the selection when that window sets
1946 the selection owner to None. The NCD server does, the MIT Sun4 server
1947 doesn't. So we synthesize one; this means we might get two, but
1948 that's ok, because the second one won't have any effect. */
1949 SELECTION_EVENT_DISPLAY (&event) = display;
1950 SELECTION_EVENT_SELECTION (&event) = selection_atom;
1951 SELECTION_EVENT_TIME (&event) = timestamp;
1952 x_handle_selection_clear ((struct input_event *) &event);
1953
1954 return Qt;
1955 }
1956
1957 /* Get rid of all the selections in buffer BUFFER.
1958 This is used when we kill a buffer. */
1959
1960 void
1961 x_disown_buffer_selections (buffer)
1962 Lisp_Object buffer;
1963 {
1964 Lisp_Object tail;
1965 struct buffer *buf = XBUFFER (buffer);
1966
1967 for (tail = Vselection_alist; CONSP (tail); tail = XCONS (tail)->cdr)
1968 {
1969 Lisp_Object elt, value;
1970 elt = XCONS (tail)->car;
1971 value = XCONS (elt)->cdr;
1972 if (CONSP (value) && MARKERP (XCONS (value)->car)
1973 && XMARKER (XCONS (value)->car)->buffer == buf)
1974 Fx_disown_selection_internal (XCONS (elt)->car, Qnil);
1975 }
1976 }
1977
1978 DEFUN ("x-selection-owner-p", Fx_selection_owner_p, Sx_selection_owner_p,
1979 0, 1, 0,
1980 "Whether the current Emacs process owns the given X Selection.\n\
1981 The arg should be the name of the selection in question, typically one of\n\
1982 the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
1983 \(Those are literal upper-case symbol names, since that's what X expects.)\n\
1984 For convenience, the symbol nil is the same as `PRIMARY',\n\
1985 and t is the same as `SECONDARY'.)")
1986 (selection)
1987 Lisp_Object selection;
1988 {
1989 check_x ();
1990 CHECK_SYMBOL (selection, 0);
1991 if (EQ (selection, Qnil)) selection = QPRIMARY;
1992 if (EQ (selection, Qt)) selection = QSECONDARY;
1993
1994 if (NILP (Fassq (selection, Vselection_alist)))
1995 return Qnil;
1996 return Qt;
1997 }
1998
1999 DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
2000 0, 1, 0,
2001 "Whether there is an owner for the given X Selection.\n\
2002 The arg should be the name of the selection in question, typically one of\n\
2003 the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
2004 \(Those are literal upper-case symbol names, since that's what X expects.)\n\
2005 For convenience, the symbol nil is the same as `PRIMARY',\n\
2006 and t is the same as `SECONDARY'.)")
2007 (selection)
2008 Lisp_Object selection;
2009 {
2010 Window owner;
2011 Atom atom;
2012 Display *dpy;
2013
2014 /* It should be safe to call this before we have an X frame. */
2015 if (! FRAME_X_P (selected_frame))
2016 return Qnil;
2017
2018 dpy = FRAME_X_DISPLAY (selected_frame);
2019 CHECK_SYMBOL (selection, 0);
2020 if (!NILP (Fx_selection_owner_p (selection)))
2021 return Qt;
2022 if (EQ (selection, Qnil)) selection = QPRIMARY;
2023 if (EQ (selection, Qt)) selection = QSECONDARY;
2024 atom = symbol_to_x_atom (FRAME_X_DISPLAY_INFO (selected_frame),
2025 dpy, selection);
2026 if (atom == 0)
2027 return Qnil;
2028 BLOCK_INPUT;
2029 owner = XGetSelectionOwner (dpy, atom);
2030 UNBLOCK_INPUT;
2031 return (owner ? Qt : Qnil);
2032 }
2033
2034 \f
2035 #ifdef CUT_BUFFER_SUPPORT
2036
2037 /* Ensure that all 8 cut buffers exist. ICCCM says we gotta... */
2038 static void
2039 initialize_cut_buffers (display, window)
2040 Display *display;
2041 Window window;
2042 {
2043 unsigned char *data = (unsigned char *) "";
2044 BLOCK_INPUT;
2045 #define FROB(atom) XChangeProperty (display, window, atom, XA_STRING, 8, \
2046 PropModeAppend, data, 0)
2047 FROB (XA_CUT_BUFFER0);
2048 FROB (XA_CUT_BUFFER1);
2049 FROB (XA_CUT_BUFFER2);
2050 FROB (XA_CUT_BUFFER3);
2051 FROB (XA_CUT_BUFFER4);
2052 FROB (XA_CUT_BUFFER5);
2053 FROB (XA_CUT_BUFFER6);
2054 FROB (XA_CUT_BUFFER7);
2055 #undef FROB
2056 UNBLOCK_INPUT;
2057 }
2058
2059
2060 #define CHECK_CUT_BUFFER(symbol,n) \
2061 { CHECK_SYMBOL ((symbol), (n)); \
2062 if (!EQ((symbol), QCUT_BUFFER0) && !EQ((symbol), QCUT_BUFFER1) \
2063 && !EQ((symbol), QCUT_BUFFER2) && !EQ((symbol), QCUT_BUFFER3) \
2064 && !EQ((symbol), QCUT_BUFFER4) && !EQ((symbol), QCUT_BUFFER5) \
2065 && !EQ((symbol), QCUT_BUFFER6) && !EQ((symbol), QCUT_BUFFER7)) \
2066 Fsignal (Qerror, \
2067 Fcons (build_string ("doesn't name a cut buffer"), \
2068 Fcons ((symbol), Qnil))); \
2069 }
2070
2071 DEFUN ("x-get-cut-buffer-internal", Fx_get_cut_buffer_internal,
2072 Sx_get_cut_buffer_internal, 1, 1, 0,
2073 "Returns the value of the named cut buffer (typically CUT_BUFFER0).")
2074 (buffer)
2075 Lisp_Object buffer;
2076 {
2077 Window window;
2078 Atom buffer_atom;
2079 unsigned char *data;
2080 int bytes;
2081 Atom type;
2082 int format;
2083 unsigned long size;
2084 Lisp_Object ret;
2085 Display *display;
2086 struct x_display_info *dpyinfo;
2087
2088 check_x ();
2089 display = FRAME_X_DISPLAY (selected_frame);
2090 dpyinfo = FRAME_X_DISPLAY_INFO (selected_frame);
2091 window = RootWindow (display, 0); /* Cut buffers are on screen 0 */
2092 CHECK_CUT_BUFFER (buffer, 0);
2093 buffer_atom = symbol_to_x_atom (dpyinfo, display, buffer);
2094
2095 x_get_window_property (display, window, buffer_atom, &data, &bytes,
2096 &type, &format, &size, 0);
2097 if (!data) return Qnil;
2098
2099 if (format != 8 || type != XA_STRING)
2100 Fsignal (Qerror,
2101 Fcons (build_string ("cut buffer doesn't contain 8-bit data"),
2102 Fcons (x_atom_to_symbol (dpyinfo, display, type),
2103 Fcons (make_number (format), Qnil))));
2104
2105 ret = (bytes ? make_string ((char *) data, bytes) : Qnil);
2106 /* Use xfree, not XFree, because x_get_window_property
2107 calls xmalloc itself. */
2108 xfree (data);
2109 return ret;
2110 }
2111
2112
2113 DEFUN ("x-store-cut-buffer-internal", Fx_store_cut_buffer_internal,
2114 Sx_store_cut_buffer_internal, 2, 2, 0,
2115 "Sets the value of the named cut buffer (typically CUT_BUFFER0).")
2116 (buffer, string)
2117 Lisp_Object buffer, string;
2118 {
2119 Window window;
2120 Atom buffer_atom;
2121 unsigned char *data;
2122 int bytes;
2123 int bytes_remaining;
2124 int max_bytes;
2125 Display *display;
2126
2127 check_x ();
2128 display = FRAME_X_DISPLAY (selected_frame);
2129 window = RootWindow (display, 0); /* Cut buffers are on screen 0 */
2130
2131 max_bytes = SELECTION_QUANTUM (display);
2132 if (max_bytes > MAX_SELECTION_QUANTUM)
2133 max_bytes = MAX_SELECTION_QUANTUM;
2134
2135 CHECK_CUT_BUFFER (buffer, 0);
2136 CHECK_STRING (string, 0);
2137 buffer_atom = symbol_to_x_atom (FRAME_X_DISPLAY_INFO (selected_frame),
2138 display, buffer);
2139 data = (unsigned char *) XSTRING (string)->data;
2140 bytes = STRING_BYTES (XSTRING (string));
2141 bytes_remaining = bytes;
2142
2143 if (! FRAME_X_DISPLAY_INFO (selected_frame)->cut_buffers_initialized)
2144 {
2145 initialize_cut_buffers (display, window);
2146 FRAME_X_DISPLAY_INFO (selected_frame)->cut_buffers_initialized = 1;
2147 }
2148
2149 BLOCK_INPUT;
2150
2151 /* Don't mess up with an empty value. */
2152 if (!bytes_remaining)
2153 XChangeProperty (display, window, buffer_atom, XA_STRING, 8,
2154 PropModeReplace, data, 0);
2155
2156 while (bytes_remaining)
2157 {
2158 int chunk = (bytes_remaining < max_bytes
2159 ? bytes_remaining : max_bytes);
2160 XChangeProperty (display, window, buffer_atom, XA_STRING, 8,
2161 (bytes_remaining == bytes
2162 ? PropModeReplace
2163 : PropModeAppend),
2164 data, chunk);
2165 data += chunk;
2166 bytes_remaining -= chunk;
2167 }
2168 UNBLOCK_INPUT;
2169 return string;
2170 }
2171
2172
2173 DEFUN ("x-rotate-cut-buffers-internal", Fx_rotate_cut_buffers_internal,
2174 Sx_rotate_cut_buffers_internal, 1, 1, 0,
2175 "Rotate the values of the cut buffers by the given number of step.\n\
2176 Positive means shift the values forward, negative means backward.")
2177 (n)
2178 Lisp_Object n;
2179 {
2180 Window window;
2181 Atom props[8];
2182 Display *display;
2183
2184 check_x ();
2185 display = FRAME_X_DISPLAY (selected_frame);
2186 window = RootWindow (display, 0); /* Cut buffers are on screen 0 */
2187 CHECK_NUMBER (n, 0);
2188 if (XINT (n) == 0)
2189 return n;
2190 if (! FRAME_X_DISPLAY_INFO (selected_frame)->cut_buffers_initialized)
2191 {
2192 initialize_cut_buffers (display, window);
2193 FRAME_X_DISPLAY_INFO (selected_frame)->cut_buffers_initialized = 1;
2194 }
2195
2196 props[0] = XA_CUT_BUFFER0;
2197 props[1] = XA_CUT_BUFFER1;
2198 props[2] = XA_CUT_BUFFER2;
2199 props[3] = XA_CUT_BUFFER3;
2200 props[4] = XA_CUT_BUFFER4;
2201 props[5] = XA_CUT_BUFFER5;
2202 props[6] = XA_CUT_BUFFER6;
2203 props[7] = XA_CUT_BUFFER7;
2204 BLOCK_INPUT;
2205 XRotateWindowProperties (display, window, props, 8, XINT (n));
2206 UNBLOCK_INPUT;
2207 return n;
2208 }
2209
2210 #endif
2211 \f
2212 void
2213 syms_of_xselect ()
2214 {
2215 defsubr (&Sx_get_selection_internal);
2216 defsubr (&Sx_own_selection_internal);
2217 defsubr (&Sx_disown_selection_internal);
2218 defsubr (&Sx_selection_owner_p);
2219 defsubr (&Sx_selection_exists_p);
2220
2221 #ifdef CUT_BUFFER_SUPPORT
2222 defsubr (&Sx_get_cut_buffer_internal);
2223 defsubr (&Sx_store_cut_buffer_internal);
2224 defsubr (&Sx_rotate_cut_buffers_internal);
2225 #endif
2226
2227 reading_selection_reply = Fcons (Qnil, Qnil);
2228 staticpro (&reading_selection_reply);
2229 reading_selection_window = 0;
2230 reading_which_selection = 0;
2231
2232 property_change_wait_list = 0;
2233 prop_location_identifier = 0;
2234 property_change_reply = Fcons (Qnil, Qnil);
2235 staticpro (&property_change_reply);
2236
2237 Vselection_alist = Qnil;
2238 staticpro (&Vselection_alist);
2239
2240 DEFVAR_LISP ("selection-converter-alist", &Vselection_converter_alist,
2241 "An alist associating X Windows selection-types with functions.\n\
2242 These functions are called to convert the selection, with three args:\n\
2243 the name of the selection (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');\n\
2244 a desired type to which the selection should be converted;\n\
2245 and the local selection value (whatever was given to `x-own-selection').\n\
2246 \n\
2247 The function should return the value to send to the X server\n\
2248 \(typically a string). A return value of nil\n\
2249 means that the conversion could not be done.\n\
2250 A return value which is the symbol `NULL'\n\
2251 means that a side-effect was executed,\n\
2252 and there is no meaningful selection value.");
2253 Vselection_converter_alist = Qnil;
2254
2255 DEFVAR_LISP ("x-lost-selection-hooks", &Vx_lost_selection_hooks,
2256 "A list of functions to be called when Emacs loses an X selection.\n\
2257 \(This happens when some other X client makes its own selection\n\
2258 or when a Lisp program explicitly clears the selection.)\n\
2259 The functions are called with one argument, the selection type\n\
2260 \(a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD').");
2261 Vx_lost_selection_hooks = Qnil;
2262
2263 DEFVAR_LISP ("x-sent-selection-hooks", &Vx_sent_selection_hooks,
2264 "A list of functions to be called when Emacs answers a selection request.\n\
2265 The functions are called with four arguments:\n\
2266 - the selection name (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');\n\
2267 - the selection-type which Emacs was asked to convert the\n\
2268 selection into before sending (for example, `STRING' or `LENGTH');\n\
2269 - a flag indicating success or failure for responding to the request.\n\
2270 We might have failed (and declined the request) for any number of reasons,\n\
2271 including being asked for a selection that we no longer own, or being asked\n\
2272 to convert into a type that we don't know about or that is inappropriate.\n\
2273 This hook doesn't let you change the behavior of Emacs's selection replies,\n\
2274 it merely informs you that they have happened.");
2275 Vx_sent_selection_hooks = Qnil;
2276
2277 DEFVAR_LISP ("clipboard-coding-system", &Vclipboard_coding_system,
2278 "Coding system for communicating with other X clients.\n\
2279 When sending or receiving text via cut_buffer, selection, and clipboard,\n\
2280 the text is encoded or decoded by this coding system.\n\
2281 A default value is `compound-text'");
2282 Vclipboard_coding_system=intern ("compound-text");
2283 staticpro(&Vclipboard_coding_system);
2284
2285 DEFVAR_INT ("x-selection-timeout", &x_selection_timeout,
2286 "Number of milliseconds to wait for a selection reply.\n\
2287 If the selection owner doesn't reply in this time, we give up.\n\
2288 A value of 0 means wait as long as necessary. This is initialized from the\n\
2289 \"*selectionTimeout\" resource.");
2290 x_selection_timeout = 0;
2291
2292 QPRIMARY = intern ("PRIMARY"); staticpro (&QPRIMARY);
2293 QSECONDARY = intern ("SECONDARY"); staticpro (&QSECONDARY);
2294 QSTRING = intern ("STRING"); staticpro (&QSTRING);
2295 QINTEGER = intern ("INTEGER"); staticpro (&QINTEGER);
2296 QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD);
2297 QTIMESTAMP = intern ("TIMESTAMP"); staticpro (&QTIMESTAMP);
2298 QTEXT = intern ("TEXT"); staticpro (&QTEXT);
2299 QCOMPOUND_TEXT = intern ("COMPOUND_TEXT"); staticpro (&QCOMPOUND_TEXT);
2300 QTIMESTAMP = intern ("TIMESTAMP"); staticpro (&QTIMESTAMP);
2301 QDELETE = intern ("DELETE"); staticpro (&QDELETE);
2302 QMULTIPLE = intern ("MULTIPLE"); staticpro (&QMULTIPLE);
2303 QINCR = intern ("INCR"); staticpro (&QINCR);
2304 QEMACS_TMP = intern ("_EMACS_TMP_"); staticpro (&QEMACS_TMP);
2305 QTARGETS = intern ("TARGETS"); staticpro (&QTARGETS);
2306 QATOM = intern ("ATOM"); staticpro (&QATOM);
2307 QATOM_PAIR = intern ("ATOM_PAIR"); staticpro (&QATOM_PAIR);
2308 QNULL = intern ("NULL"); staticpro (&QNULL);
2309
2310 #ifdef CUT_BUFFER_SUPPORT
2311 QCUT_BUFFER0 = intern ("CUT_BUFFER0"); staticpro (&QCUT_BUFFER0);
2312 QCUT_BUFFER1 = intern ("CUT_BUFFER1"); staticpro (&QCUT_BUFFER1);
2313 QCUT_BUFFER2 = intern ("CUT_BUFFER2"); staticpro (&QCUT_BUFFER2);
2314 QCUT_BUFFER3 = intern ("CUT_BUFFER3"); staticpro (&QCUT_BUFFER3);
2315 QCUT_BUFFER4 = intern ("CUT_BUFFER4"); staticpro (&QCUT_BUFFER4);
2316 QCUT_BUFFER5 = intern ("CUT_BUFFER5"); staticpro (&QCUT_BUFFER5);
2317 QCUT_BUFFER6 = intern ("CUT_BUFFER6"); staticpro (&QCUT_BUFFER6);
2318 QCUT_BUFFER7 = intern ("CUT_BUFFER7"); staticpro (&QCUT_BUFFER7);
2319 #endif
2320
2321 }