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