]> code.delx.au - gnu-emacs/blob - src/macselect.c
(BASE_PURESIZE): Increase to 1205000.
[gnu-emacs] / src / macselect.c
1 /* Selection processing for Emacs on Mac OS.
2 Copyright (C) 2005 Free Software Foundation, Inc.
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., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA. */
20
21 #include <config.h>
22
23 #include "lisp.h"
24 #include "macterm.h"
25 #include "blockinput.h"
26 #include "keymap.h"
27
28 #if !TARGET_API_MAC_CARBON
29 #include <Endian.h>
30 typedef int ScrapRef;
31 typedef ResType ScrapFlavorType;
32 #endif /* !TARGET_API_MAC_CARBON */
33
34 static OSErr get_scrap_from_symbol P_ ((Lisp_Object, int, ScrapRef *));
35 static ScrapFlavorType get_flavor_type_from_symbol P_ ((Lisp_Object));
36 static int valid_scrap_target_type_p P_ ((Lisp_Object));
37 static OSErr clear_scrap P_ ((ScrapRef *));
38 static OSErr put_scrap_string P_ ((ScrapRef, Lisp_Object, Lisp_Object));
39 static OSErr put_scrap_private_timestamp P_ ((ScrapRef, unsigned long));
40 static ScrapFlavorType scrap_has_target_type P_ ((ScrapRef, Lisp_Object));
41 static Lisp_Object get_scrap_string P_ ((ScrapRef, Lisp_Object));
42 static OSErr get_scrap_private_timestamp P_ ((ScrapRef, unsigned long *));
43 static Lisp_Object get_scrap_target_type_list P_ ((ScrapRef));
44 static void x_own_selection P_ ((Lisp_Object, Lisp_Object));
45 static Lisp_Object x_get_local_selection P_ ((Lisp_Object, Lisp_Object, int));
46 static Lisp_Object x_get_foreign_selection P_ ((Lisp_Object,
47 Lisp_Object,
48 Lisp_Object));
49 EXFUN (Fx_selection_owner_p, 1);
50 #ifdef MAC_OSX
51 static OSStatus mac_handle_service_event P_ ((EventHandlerCallRef,
52 EventRef, void *));
53 void init_service_handler P_ ((void));
54 #endif
55
56 Lisp_Object QPRIMARY, QSECONDARY, QTIMESTAMP, QTARGETS;
57
58 static Lisp_Object Vx_lost_selection_functions;
59 /* Coding system for communicating with other programs via scrap. */
60 static Lisp_Object Vselection_coding_system;
61
62 /* Coding system for the next communicating with other programs. */
63 static Lisp_Object Vnext_selection_coding_system;
64
65 static Lisp_Object Qforeign_selection;
66
67 /* The timestamp of the last input event Emacs received from the
68 window 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.
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, and the data for the flavor
81 type SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP in the corresponding scrap
82 (if exists) coincides with SELECTION-TIMESTAMP, then it can be
83 assumed that Emacs owns that selection.
84 The only (eq) parts of this list that are visible from Lisp are the
85 selection-values. */
86 static Lisp_Object Vselection_alist;
87
88 #define SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP 'Etsp'
89
90 /* This is an alist whose CARs are selection-types and whose CDRs are
91 the names of Lisp functions to call to convert the given Emacs
92 selection value to a string representing the given selection type.
93 This is for Lisp-level extension of the emacs selection
94 handling. */
95 static Lisp_Object Vselection_converter_alist;
96
97 /* A selection name (represented as a Lisp symbol) can be associated
98 with a named scrap via `mac-scrap-name' property. Likewise for a
99 selection type with a scrap flavor type via `mac-ostype'. */
100 static Lisp_Object Qmac_scrap_name, Qmac_ostype;
101
102 #ifdef MAC_OSX
103 /* Selection name for communication via Services menu. */
104 static Lisp_Object Vmac_services_selection;
105 #endif
106 \f
107 /* Get a reference to the scrap corresponding to the symbol SYM. The
108 reference is set to *SCRAP, and it becomes NULL if there's no
109 corresponding scrap. Clear the scrap if CLEAR_P is non-zero. */
110
111 static OSErr
112 get_scrap_from_symbol (sym, clear_p, scrap)
113 Lisp_Object sym;
114 int clear_p;
115 ScrapRef *scrap;
116 {
117 OSErr err = noErr;
118 Lisp_Object str = Fget (sym, Qmac_scrap_name);
119
120 if (!STRINGP (str))
121 *scrap = NULL;
122 else
123 {
124 #if TARGET_API_MAC_CARBON
125 #ifdef MAC_OSX
126 CFStringRef scrap_name = cfstring_create_with_string (str);
127 OptionBits options = (clear_p ? kScrapClearNamedScrap
128 : kScrapGetNamedScrap);
129
130 err = GetScrapByName (scrap_name, options, scrap);
131 CFRelease (scrap_name);
132 #else /* !MAC_OSX */
133 if (clear_p)
134 err = ClearCurrentScrap ();
135 if (err == noErr)
136 err = GetCurrentScrap (scrap);
137 #endif /* !MAC_OSX */
138 #else /* !TARGET_API_MAC_CARBON */
139 if (clear_p)
140 err = ZeroScrap ();
141 if (err == noErr)
142 *scrap = 1;
143 #endif /* !TARGET_API_MAC_CARBON */
144 }
145
146 return err;
147 }
148
149 /* Get a scrap flavor type from the symbol SYM. Return 0 if no
150 corresponding flavor type. */
151
152 static ScrapFlavorType
153 get_flavor_type_from_symbol (sym)
154 Lisp_Object sym;
155 {
156 Lisp_Object str = Fget (sym, Qmac_ostype);
157
158 if (STRINGP (str) && SBYTES (str) == 4)
159 return EndianU32_BtoN (*((UInt32 *) SDATA (str)));
160
161 return 0;
162 }
163
164 /* Check if the symbol SYM has a corresponding scrap flavor type. */
165
166 static int
167 valid_scrap_target_type_p (sym)
168 Lisp_Object sym;
169 {
170 return get_flavor_type_from_symbol (sym) != 0;
171 }
172
173 /* Clear the scrap whose reference is *SCRAP. */
174
175 static INLINE OSErr
176 clear_scrap (scrap)
177 ScrapRef *scrap;
178 {
179 #if TARGET_API_MAC_CARBON
180 #ifdef MAC_OSX
181 return ClearScrap (scrap);
182 #else
183 return ClearCurrentScrap ();
184 #endif
185 #else /* !TARGET_API_MAC_CARBON */
186 return ZeroScrap ();
187 #endif /* !TARGET_API_MAC_CARBON */
188 }
189
190 /* Put Lisp String STR to the scrap SCRAP. The target type is
191 specified by TYPE. */
192
193 static OSErr
194 put_scrap_string (scrap, type, str)
195 ScrapRef scrap;
196 Lisp_Object type, str;
197 {
198 ScrapFlavorType flavor_type = get_flavor_type_from_symbol (type);
199
200 if (flavor_type == 0)
201 return noTypeErr;
202
203 #if TARGET_API_MAC_CARBON
204 return PutScrapFlavor (scrap, flavor_type, kScrapFlavorMaskNone,
205 SBYTES (str), SDATA (str));
206 #else /* !TARGET_API_MAC_CARBON */
207 return PutScrap (SBYTES (str), flavor_type, SDATA (str));
208 #endif /* !TARGET_API_MAC_CARBON */
209 }
210
211 /* Put TIMESTAMP to the scrap SCRAP. The timestamp is used for
212 checking if the scrap is owned by the process. */
213
214 static INLINE OSErr
215 put_scrap_private_timestamp (scrap, timestamp)
216 ScrapRef scrap;
217 unsigned long timestamp;
218 {
219 #if TARGET_API_MAC_CARBON
220 return PutScrapFlavor (scrap, SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP,
221 kScrapFlavorMaskSenderOnly,
222 sizeof (timestamp), &timestamp);
223 #else /* !TARGET_API_MAC_CARBON */
224 return PutScrap (sizeof (timestamp), SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP,
225 &timestamp);
226 #endif /* !TARGET_API_MAC_CARBON */
227 }
228
229 /* Check if data for the target type TYPE is available in SCRAP. */
230
231 static ScrapFlavorType
232 scrap_has_target_type (scrap, type)
233 ScrapRef scrap;
234 Lisp_Object type;
235 {
236 OSErr err;
237 ScrapFlavorType flavor_type = get_flavor_type_from_symbol (type);
238
239 if (flavor_type)
240 {
241 #if TARGET_API_MAC_CARBON
242 ScrapFlavorFlags flags;
243
244 err = GetScrapFlavorFlags (scrap, flavor_type, &flags);
245 if (err != noErr)
246 flavor_type = 0;
247 #else /* !TARGET_API_MAC_CARBON */
248 SInt32 size, offset;
249
250 size = GetScrap (NULL, flavor_type, &offset);
251 if (size < 0)
252 flavor_type = 0;
253 #endif /* !TARGET_API_MAC_CARBON */
254 }
255
256 return flavor_type;
257 }
258
259 /* Get data for the target type TYPE from SCRAP and create a Lisp
260 string. Return nil if failed to get data. */
261
262 static Lisp_Object
263 get_scrap_string (scrap, type)
264 ScrapRef scrap;
265 Lisp_Object type;
266 {
267 OSErr err;
268 Lisp_Object result = Qnil;
269 ScrapFlavorType flavor_type = get_flavor_type_from_symbol (type);
270 #if TARGET_API_MAC_CARBON
271 Size size;
272
273 if (flavor_type)
274 {
275 err = GetScrapFlavorSize (scrap, flavor_type, &size);
276 if (err == noErr)
277 {
278 do
279 {
280 result = make_uninit_string (size);
281 err = GetScrapFlavorData (scrap, flavor_type,
282 &size, SDATA (result));
283 if (err != noErr)
284 result = Qnil;
285 else if (size < SBYTES (result))
286 result = make_unibyte_string (SDATA (result), size);
287 }
288 while (STRINGP (result) && size > SBYTES (result));
289 }
290 }
291 #else
292 Handle handle;
293 SInt32 size, offset;
294
295 if (flavor_type)
296 size = GetScrap (NULL, flavor_type, &offset);
297 if (size >= 0)
298 {
299 handle = NewHandle (size);
300 HLock (handle);
301 size = GetScrap (handle, flavor_type, &offset);
302 if (size >= 0)
303 result = make_unibyte_string (*handle, size);
304 DisposeHandle (handle);
305 }
306 #endif
307
308 return result;
309 }
310
311 /* Get timestamp from the scrap SCRAP and set to *TIMPSTAMP. */
312
313 static OSErr
314 get_scrap_private_timestamp (scrap, timestamp)
315 ScrapRef scrap;
316 unsigned long *timestamp;
317 {
318 OSErr err = noErr;
319 #if TARGET_API_MAC_CARBON
320 ScrapFlavorFlags flags;
321
322 err = GetScrapFlavorFlags (scrap, SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP, &flags);
323 if (err == noErr)
324 {
325 if (!(flags & kScrapFlavorMaskSenderOnly))
326 err = noTypeErr;
327 else
328 {
329 Size size = sizeof (*timestamp);
330
331 err = GetScrapFlavorData (scrap, SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP,
332 &size, timestamp);
333 if (err == noErr && size != sizeof (*timestamp))
334 err = noTypeErr;
335 }
336 }
337 #else /* !TARGET_API_MAC_CARBON */
338 Handle handle;
339 SInt32 size, offset;
340
341 size = GetScrap (NULL, SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP, &offset);
342 if (size == sizeof (*timestamp))
343 {
344 handle = NewHandle (size);
345 HLock (handle);
346 size = GetScrap (handle, SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP, &offset);
347 if (size == sizeof (*timestamp))
348 *timestamp = *((unsigned long *) *handle);
349 DisposeHandle (handle);
350 }
351 if (size != sizeof (*timestamp))
352 err = noTypeErr;
353 #endif /* !TARGET_API_MAC_CARBON */
354
355 return err;
356 }
357
358 /* Get the list of target types in SCRAP. The return value is a list
359 of target type symbols possibly followed by scrap flavor type
360 strings. */
361
362 static Lisp_Object
363 get_scrap_target_type_list (scrap)
364 ScrapRef scrap;
365 {
366 Lisp_Object result = Qnil, rest, target_type;
367 #if TARGET_API_MAC_CARBON
368 OSErr err;
369 UInt32 count, i, type;
370 ScrapFlavorInfo *flavor_info = NULL;
371 Lisp_Object strings = Qnil;
372
373 err = GetScrapFlavorCount (scrap, &count);
374 if (err == noErr)
375 flavor_info = xmalloc (sizeof (ScrapFlavorInfo) * count);
376 err = GetScrapFlavorInfoList (scrap, &count, flavor_info);
377 if (err != noErr)
378 {
379 xfree (flavor_info);
380 flavor_info = NULL;
381 }
382 if (flavor_info == NULL)
383 count = 0;
384 #endif
385 for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest))
386 {
387 ScrapFlavorType flavor_type = 0;
388
389 if (CONSP (XCAR (rest)) && SYMBOLP (target_type = XCAR (XCAR (rest)))
390 && (flavor_type = scrap_has_target_type (scrap, target_type)))
391 {
392 result = Fcons (target_type, result);
393 #if TARGET_API_MAC_CARBON
394 for (i = 0; i < count; i++)
395 if (flavor_info[i].flavorType == flavor_type)
396 {
397 flavor_info[i].flavorType = 0;
398 break;
399 }
400 #endif
401 }
402 }
403 #if TARGET_API_MAC_CARBON
404 if (flavor_info)
405 {
406 for (i = 0; i < count; i++)
407 if (flavor_info[i].flavorType)
408 {
409 type = EndianU32_NtoB (flavor_info[i].flavorType);
410 strings = Fcons (make_unibyte_string ((char *) &type, 4), strings);
411 }
412 result = nconc2 (result, strings);
413 xfree (flavor_info);
414 }
415 #endif
416
417 return result;
418 }
419 \f
420 /* Do protocol to assert ourself as a selection owner.
421 Update the Vselection_alist so that we can reply to later requests for
422 our selection. */
423
424 static void
425 x_own_selection (selection_name, selection_value)
426 Lisp_Object selection_name, selection_value;
427 {
428 OSErr err;
429 ScrapRef scrap;
430 struct gcpro gcpro1, gcpro2;
431 Lisp_Object rest, handler_fn, value, type;
432 int count;
433
434 CHECK_SYMBOL (selection_name);
435
436 GCPRO2 (selection_name, selection_value);
437
438 BLOCK_INPUT;
439
440 err = get_scrap_from_symbol (selection_name, 1, &scrap);
441 if (err == noErr && scrap)
442 {
443 /* Don't allow a quit within the converter.
444 When the user types C-g, he would be surprised
445 if by luck it came during a converter. */
446 count = SPECPDL_INDEX ();
447 specbind (Qinhibit_quit, Qt);
448
449 for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest))
450 {
451 if (!(CONSP (XCAR (rest))
452 && SYMBOLP (type = XCAR (XCAR (rest)))
453 && valid_scrap_target_type_p (type)
454 && SYMBOLP (handler_fn = XCDR (XCAR (rest)))))
455 continue;
456
457 if (!NILP (handler_fn))
458 value = call3 (handler_fn, selection_name,
459 type, selection_value);
460
461 if (STRINGP (value))
462 err = put_scrap_string (scrap, type, value);
463 else if (CONSP (value)
464 && EQ (XCAR (value), type)
465 && STRINGP (XCDR (value)))
466 err = put_scrap_string (scrap, type, XCDR (value));
467 }
468
469 unbind_to (count, Qnil);
470
471 if (err == noErr)
472 err = put_scrap_private_timestamp (scrap, last_event_timestamp);
473 }
474
475 UNBLOCK_INPUT;
476
477 UNGCPRO;
478
479 if (scrap && err != noErr)
480 error ("Can't set selection");
481
482 /* Now update the local cache */
483 {
484 Lisp_Object selection_time;
485 Lisp_Object selection_data;
486 Lisp_Object prev_value;
487
488 selection_time = long_to_cons (last_event_timestamp);
489 selection_data = Fcons (selection_name,
490 Fcons (selection_value,
491 Fcons (selection_time,
492 Fcons (selected_frame, Qnil))));
493 prev_value = assq_no_quit (selection_name, Vselection_alist);
494
495 Vselection_alist = Fcons (selection_data, Vselection_alist);
496
497 /* If we already owned the selection, remove the old selection data.
498 Perhaps we should destructively modify it instead.
499 Don't use Fdelq as that may QUIT. */
500 if (!NILP (prev_value))
501 {
502 Lisp_Object rest; /* we know it's not the CAR, so it's easy. */
503 for (rest = Vselection_alist; !NILP (rest); rest = Fcdr (rest))
504 if (EQ (prev_value, Fcar (XCDR (rest))))
505 {
506 XSETCDR (rest, Fcdr (XCDR (rest)));
507 break;
508 }
509 }
510 }
511 }
512 \f
513 /* Given a selection-name and desired type, look up our local copy of
514 the selection value and convert it to the type.
515 The value is nil or a string.
516 This function is used both for remote requests (LOCAL_REQUEST is zero)
517 and for local x-get-selection-internal (LOCAL_REQUEST is nonzero).
518
519 This calls random Lisp code, and may signal or gc. */
520
521 static Lisp_Object
522 x_get_local_selection (selection_symbol, target_type, local_request)
523 Lisp_Object selection_symbol, target_type;
524 int local_request;
525 {
526 Lisp_Object local_value;
527 Lisp_Object handler_fn, value, type, check;
528 int count;
529
530 if (NILP (Fx_selection_owner_p (selection_symbol)))
531 return Qnil;
532
533 local_value = assq_no_quit (selection_symbol, Vselection_alist);
534
535 /* TIMESTAMP is a special case 'cause that's easiest. */
536 if (EQ (target_type, QTIMESTAMP))
537 {
538 handler_fn = Qnil;
539 value = XCAR (XCDR (XCDR (local_value)));
540 }
541 #if 0
542 else if (EQ (target_type, QDELETE))
543 {
544 handler_fn = Qnil;
545 Fx_disown_selection_internal
546 (selection_symbol,
547 XCAR (XCDR (XCDR (local_value))));
548 value = QNULL;
549 }
550 #endif
551 else
552 {
553 /* Don't allow a quit within the converter.
554 When the user types C-g, he would be surprised
555 if by luck it came during a converter. */
556 count = SPECPDL_INDEX ();
557 specbind (Qinhibit_quit, Qt);
558
559 CHECK_SYMBOL (target_type);
560 handler_fn = Fcdr (Fassq (target_type, Vselection_converter_alist));
561 /* gcpro is not needed here since nothing but HANDLER_FN
562 is live, and that ought to be a symbol. */
563
564 if (!NILP (handler_fn))
565 value = call3 (handler_fn,
566 selection_symbol, (local_request ? Qnil : target_type),
567 XCAR (XCDR (local_value)));
568 else
569 value = Qnil;
570 unbind_to (count, Qnil);
571 }
572
573 /* Make sure this value is of a type that we could transmit
574 to another X client. */
575
576 check = value;
577 if (CONSP (value)
578 && SYMBOLP (XCAR (value)))
579 type = XCAR (value),
580 check = XCDR (value);
581
582 if (STRINGP (check)
583 || VECTORP (check)
584 || SYMBOLP (check)
585 || INTEGERP (check)
586 || NILP (value))
587 return value;
588 /* Check for a value that cons_to_long could handle. */
589 else if (CONSP (check)
590 && INTEGERP (XCAR (check))
591 && (INTEGERP (XCDR (check))
592 ||
593 (CONSP (XCDR (check))
594 && INTEGERP (XCAR (XCDR (check)))
595 && NILP (XCDR (XCDR (check))))))
596 return value;
597 else
598 return
599 Fsignal (Qerror,
600 Fcons (build_string ("invalid data returned by selection-conversion function"),
601 Fcons (handler_fn, Fcons (value, Qnil))));
602 }
603
604 \f
605 /* Clear all selections that were made from frame F.
606 We do this when about to delete a frame. */
607
608 void
609 x_clear_frame_selections (f)
610 FRAME_PTR f;
611 {
612 Lisp_Object frame;
613 Lisp_Object rest;
614
615 XSETFRAME (frame, f);
616
617 /* Otherwise, we're really honest and truly being told to drop it.
618 Don't use Fdelq as that may QUIT;. */
619
620 /* Delete elements from the beginning of Vselection_alist. */
621 while (!NILP (Vselection_alist)
622 && EQ (frame, Fcar (Fcdr (Fcdr (Fcdr (Fcar (Vselection_alist)))))))
623 {
624 /* Let random Lisp code notice that the selection has been stolen. */
625 Lisp_Object hooks, selection_symbol;
626
627 hooks = Vx_lost_selection_functions;
628 selection_symbol = Fcar (Fcar (Vselection_alist));
629
630 if (!EQ (hooks, Qunbound)
631 && !NILP (Fx_selection_owner_p (selection_symbol)))
632 {
633 for (; CONSP (hooks); hooks = Fcdr (hooks))
634 call1 (Fcar (hooks), selection_symbol);
635 #if 0 /* This can crash when deleting a frame
636 from x_connection_closed. Anyway, it seems unnecessary;
637 something else should cause a redisplay. */
638 redisplay_preserve_echo_area (21);
639 #endif
640 }
641
642 Vselection_alist = Fcdr (Vselection_alist);
643 }
644
645 /* Delete elements after the beginning of Vselection_alist. */
646 for (rest = Vselection_alist; !NILP (rest); rest = Fcdr (rest))
647 if (EQ (frame, Fcar (Fcdr (Fcdr (Fcdr (Fcar (XCDR (rest))))))))
648 {
649 /* Let random Lisp code notice that the selection has been stolen. */
650 Lisp_Object hooks, selection_symbol;
651
652 hooks = Vx_lost_selection_functions;
653 selection_symbol = Fcar (Fcar (XCDR (rest)));
654
655 if (!EQ (hooks, Qunbound)
656 && !NILP (Fx_selection_owner_p (selection_symbol)))
657 {
658 for (; CONSP (hooks); hooks = Fcdr (hooks))
659 call1 (Fcar (hooks), selection_symbol);
660 #if 0 /* See above */
661 redisplay_preserve_echo_area (22);
662 #endif
663 }
664 XSETCDR (rest, Fcdr (XCDR (rest)));
665 break;
666 }
667 }
668 \f
669 /* Do protocol to read selection-data from the server.
670 Converts this to Lisp data and returns it. */
671
672 static Lisp_Object
673 x_get_foreign_selection (selection_symbol, target_type, time_stamp)
674 Lisp_Object selection_symbol, target_type, time_stamp;
675 {
676 OSErr err;
677 ScrapRef scrap;
678 Lisp_Object result = Qnil;
679
680 BLOCK_INPUT;
681
682 err = get_scrap_from_symbol (selection_symbol, 0, &scrap);
683 if (err == noErr && scrap)
684 {
685 if (EQ (target_type, QTARGETS))
686 {
687 result = get_scrap_target_type_list (scrap);
688 result = Fvconcat (1, &result);
689 }
690 else
691 {
692 result = get_scrap_string (scrap, target_type);
693 if (STRINGP (result))
694 Fput_text_property (make_number (0), make_number (SBYTES (result)),
695 Qforeign_selection, target_type, result);
696 }
697 }
698
699 UNBLOCK_INPUT;
700
701 return result;
702 }
703
704
705 DEFUN ("x-own-selection-internal", Fx_own_selection_internal,
706 Sx_own_selection_internal, 2, 2, 0,
707 doc: /* Assert a selection of the given TYPE with the given VALUE.
708 TYPE is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
709 VALUE is typically a string, or a cons of two markers, but may be
710 anything that the functions on `selection-converter-alist' know about. */)
711 (selection_name, selection_value)
712 Lisp_Object selection_name, selection_value;
713 {
714 check_mac ();
715 CHECK_SYMBOL (selection_name);
716 if (NILP (selection_value)) error ("SELECTION-VALUE may not be nil");
717 x_own_selection (selection_name, selection_value);
718 return selection_value;
719 }
720
721
722 /* Request the selection value from the owner. If we are the owner,
723 simply return our selection value. If we are not the owner, this
724 will block until all of the data has arrived. */
725
726 DEFUN ("x-get-selection-internal", Fx_get_selection_internal,
727 Sx_get_selection_internal, 2, 3, 0,
728 doc: /* Return text selected from some Mac application.
729 SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
730 TYPE is the type of data desired, typically `STRING'.
731 TIME_STAMP is ignored on Mac. */)
732 (selection_symbol, target_type, time_stamp)
733 Lisp_Object selection_symbol, target_type, time_stamp;
734 {
735 Lisp_Object val = Qnil;
736 struct gcpro gcpro1, gcpro2;
737 GCPRO2 (target_type, val); /* we store newly consed data into these */
738 check_mac ();
739 CHECK_SYMBOL (selection_symbol);
740 CHECK_SYMBOL (target_type);
741
742 val = x_get_local_selection (selection_symbol, target_type, 1);
743
744 if (NILP (val))
745 {
746 val = x_get_foreign_selection (selection_symbol, target_type, time_stamp);
747 goto DONE;
748 }
749
750 if (CONSP (val)
751 && SYMBOLP (XCAR (val)))
752 {
753 val = XCDR (val);
754 if (CONSP (val) && NILP (XCDR (val)))
755 val = XCAR (val);
756 }
757 DONE:
758 UNGCPRO;
759 return val;
760 }
761
762 DEFUN ("x-disown-selection-internal", Fx_disown_selection_internal,
763 Sx_disown_selection_internal, 1, 2, 0,
764 doc: /* If we own the selection SELECTION, disown it.
765 Disowning it means there is no such selection. */)
766 (selection, time)
767 Lisp_Object selection;
768 Lisp_Object time;
769 {
770 OSErr err;
771 ScrapRef scrap;
772 Lisp_Object local_selection_data;
773
774 check_mac ();
775 CHECK_SYMBOL (selection);
776
777 if (NILP (Fx_selection_owner_p (selection)))
778 return Qnil; /* Don't disown the selection when we're not the owner. */
779
780 local_selection_data = assq_no_quit (selection, Vselection_alist);
781
782 /* Don't use Fdelq as that may QUIT;. */
783
784 if (EQ (local_selection_data, Fcar (Vselection_alist)))
785 Vselection_alist = Fcdr (Vselection_alist);
786 else
787 {
788 Lisp_Object rest;
789 for (rest = Vselection_alist; !NILP (rest); rest = Fcdr (rest))
790 if (EQ (local_selection_data, Fcar (XCDR (rest))))
791 {
792 XSETCDR (rest, Fcdr (XCDR (rest)));
793 break;
794 }
795 }
796
797 /* Let random lisp code notice that the selection has been stolen. */
798
799 {
800 Lisp_Object rest;
801 rest = Vx_lost_selection_functions;
802 if (!EQ (rest, Qunbound))
803 {
804 for (; CONSP (rest); rest = Fcdr (rest))
805 call1 (Fcar (rest), selection);
806 prepare_menu_bars ();
807 redisplay_preserve_echo_area (20);
808 }
809 }
810
811 BLOCK_INPUT;
812
813 err = get_scrap_from_symbol (selection, 0, &scrap);
814 if (err == noErr && scrap)
815 clear_scrap (&scrap);
816
817 UNBLOCK_INPUT;
818
819 return Qt;
820 }
821
822
823 DEFUN ("x-selection-owner-p", Fx_selection_owner_p, Sx_selection_owner_p,
824 0, 1, 0,
825 doc: /* Whether the current Emacs process owns the given SELECTION.
826 The arg should be the name of the selection in question, typically one of
827 the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
828 For convenience, the symbol nil is the same as `PRIMARY',
829 and t is the same as `SECONDARY'. */)
830 (selection)
831 Lisp_Object selection;
832 {
833 OSErr err;
834 ScrapRef scrap;
835 Lisp_Object result = Qnil, local_selection_data;
836
837 check_mac ();
838 CHECK_SYMBOL (selection);
839 if (EQ (selection, Qnil)) selection = QPRIMARY;
840 if (EQ (selection, Qt)) selection = QSECONDARY;
841
842 local_selection_data = assq_no_quit (selection, Vselection_alist);
843
844 if (NILP (local_selection_data))
845 return Qnil;
846
847 BLOCK_INPUT;
848
849 err = get_scrap_from_symbol (selection, 0, &scrap);
850 if (err == noErr && scrap)
851 {
852 unsigned long timestamp;
853
854 err = get_scrap_private_timestamp (scrap, &timestamp);
855 if (err == noErr
856 && (timestamp
857 == cons_to_long (XCAR (XCDR (XCDR (local_selection_data))))))
858 result = Qt;
859 }
860 else
861 result = Qt;
862
863 UNBLOCK_INPUT;
864
865 return result;
866 }
867
868 DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
869 0, 1, 0,
870 doc: /* Whether there is an owner for the given SELECTION.
871 The arg should be the name of the selection in question, typically one of
872 the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
873 For convenience, the symbol nil is the same as `PRIMARY',
874 and t is the same as `SECONDARY'. */)
875 (selection)
876 Lisp_Object selection;
877 {
878 OSErr err;
879 ScrapRef scrap;
880 Lisp_Object result = Qnil, rest;
881
882 /* It should be safe to call this before we have an Mac frame. */
883 if (! FRAME_MAC_P (SELECTED_FRAME ()))
884 return Qnil;
885
886 CHECK_SYMBOL (selection);
887 if (!NILP (Fx_selection_owner_p (selection)))
888 return Qt;
889 if (EQ (selection, Qnil)) selection = QPRIMARY;
890 if (EQ (selection, Qt)) selection = QSECONDARY;
891
892 BLOCK_INPUT;
893
894 err = get_scrap_from_symbol (selection, 0, &scrap);
895 if (err == noErr && scrap)
896 for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest))
897 {
898 if (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest)))
899 && scrap_has_target_type (scrap, XCAR (XCAR (rest))))
900 {
901 result = Qt;
902 break;
903 }
904 }
905
906 UNBLOCK_INPUT;
907
908 return result;
909 }
910
911 \f
912 int mac_ready_for_apple_events = 0;
913 static Lisp_Object Vmac_apple_event_map;
914 static Lisp_Object Qmac_apple_event_class, Qmac_apple_event_id;
915 static struct
916 {
917 AppleEvent *buf;
918 int size, count;
919 } deferred_apple_events;
920 extern Lisp_Object Qundefined;
921 extern OSErr mac_store_apple_event P_ ((Lisp_Object, Lisp_Object,
922 const AEDesc *));
923
924 struct apple_event_binding
925 {
926 UInt32 code; /* Apple event class or ID. */
927 Lisp_Object key, binding;
928 };
929
930 static void
931 find_event_binding_fun (key, binding, args, data)
932 Lisp_Object key, binding, args;
933 void *data;
934 {
935 struct apple_event_binding *event_binding =
936 (struct apple_event_binding *)data;
937 Lisp_Object code_string;
938
939 if (!SYMBOLP (key))
940 return;
941 code_string = Fget (key, args);
942 if (STRINGP (code_string) && SBYTES (code_string) == 4
943 && (EndianU32_BtoN (*((UInt32 *) SDATA (code_string)))
944 == event_binding->code))
945 {
946 event_binding->key = key;
947 event_binding->binding = binding;
948 }
949 }
950
951 static void
952 find_event_binding (keymap, event_binding, class_p)
953 Lisp_Object keymap;
954 struct apple_event_binding *event_binding;
955 int class_p;
956 {
957 if (event_binding->code == 0)
958 event_binding->binding =
959 access_keymap (keymap, event_binding->key, 0, 1, 0);
960 else
961 {
962 event_binding->binding = Qnil;
963 map_keymap (keymap, find_event_binding_fun,
964 class_p ? Qmac_apple_event_class : Qmac_apple_event_id,
965 event_binding, 0);
966 }
967 }
968
969 void
970 mac_find_apple_event_spec (class, id, class_key, id_key, binding)
971 AEEventClass class;
972 AEEventID id;
973 Lisp_Object *class_key, *id_key, *binding;
974 {
975 struct apple_event_binding event_binding;
976 Lisp_Object keymap;
977
978 *binding = Qnil;
979
980 keymap = get_keymap (Vmac_apple_event_map, 0, 0);
981 if (NILP (keymap))
982 return;
983
984 event_binding.code = class;
985 event_binding.key = *class_key;
986 event_binding.binding = Qnil;
987 find_event_binding (keymap, &event_binding, 1);
988 *class_key = event_binding.key;
989 keymap = get_keymap (event_binding.binding, 0, 0);
990 if (NILP (keymap))
991 return;
992
993 event_binding.code = id;
994 event_binding.key = *id_key;
995 event_binding.binding = Qnil;
996 find_event_binding (keymap, &event_binding, 0);
997 *id_key = event_binding.key;
998 *binding = event_binding.binding;
999 }
1000
1001 static OSErr
1002 defer_apple_events (apple_event, reply)
1003 const AppleEvent *apple_event, *reply;
1004 {
1005 OSErr err;
1006
1007 err = AESuspendTheCurrentEvent (apple_event);
1008
1009 /* Mac OS 10.3 Xcode manual says AESuspendTheCurrentEvent makes
1010 copies of the Apple event and the reply, but Mac OS 10.4 Xcode
1011 manual says it doesn't. Anyway we create copies of them and save
1012 them in `deferred_apple_events'. */
1013 if (err == noErr)
1014 {
1015 if (deferred_apple_events.buf == NULL)
1016 {
1017 deferred_apple_events.size = 16;
1018 deferred_apple_events.count = 0;
1019 deferred_apple_events.buf =
1020 xmalloc (sizeof (AppleEvent) * deferred_apple_events.size);
1021 }
1022 else if (deferred_apple_events.count == deferred_apple_events.size)
1023 {
1024 deferred_apple_events.size *= 2;
1025 deferred_apple_events.buf
1026 = xrealloc (deferred_apple_events.buf,
1027 sizeof (AppleEvent) * deferred_apple_events.size);
1028 }
1029 }
1030
1031 if (err == noErr)
1032 {
1033 int count = deferred_apple_events.count;
1034
1035 AEDuplicateDesc (apple_event, deferred_apple_events.buf + count);
1036 AEDuplicateDesc (reply, deferred_apple_events.buf + count + 1);
1037 deferred_apple_events.count += 2;
1038 }
1039
1040 return err;
1041 }
1042
1043 static pascal OSErr
1044 mac_handle_apple_event (apple_event, reply, refcon)
1045 const AppleEvent *apple_event;
1046 AppleEvent *reply;
1047 SInt32 refcon;
1048 {
1049 OSErr err;
1050 AEEventClass event_class;
1051 AEEventID event_id;
1052 Lisp_Object class_key, id_key, binding;
1053
1054 /* We can't handle an Apple event that requests a reply, but this
1055 seems to be too restrictive. */
1056 #if 0
1057 if (reply->descriptorType != typeNull)
1058 return errAEEventNotHandled;
1059 #endif
1060
1061 if (!mac_ready_for_apple_events)
1062 {
1063 err = defer_apple_events (apple_event, reply);
1064 if (err != noErr)
1065 return errAEEventNotHandled;
1066 return noErr;
1067 }
1068
1069 err = AEGetAttributePtr (apple_event, keyEventClassAttr, typeType, NULL,
1070 &event_class, sizeof (AEEventClass), NULL);
1071 if (err == noErr)
1072 err = AEGetAttributePtr (apple_event, keyEventIDAttr, typeType, NULL,
1073 &event_id, sizeof (AEEventID), NULL);
1074 if (err == noErr)
1075 {
1076 mac_find_apple_event_spec (event_class, event_id,
1077 &class_key, &id_key, &binding);
1078 if (!NILP (binding) && !EQ (binding, Qundefined))
1079 {
1080 if (INTEGERP (binding))
1081 return XINT (binding);
1082 err = mac_store_apple_event (class_key, id_key, apple_event);
1083 if (err == noErr)
1084 return noErr;
1085 }
1086 }
1087 return errAEEventNotHandled;
1088 }
1089
1090 void
1091 init_apple_event_handler ()
1092 {
1093 OSErr err;
1094 long result;
1095
1096 /* Make sure we have Apple events before starting. */
1097 err = Gestalt (gestaltAppleEventsAttr, &result);
1098 if (err != noErr)
1099 abort ();
1100
1101 if (!(result & (1 << gestaltAppleEventsPresent)))
1102 abort ();
1103
1104 err = AEInstallEventHandler (typeWildCard, typeWildCard,
1105 #if TARGET_API_MAC_CARBON
1106 NewAEEventHandlerUPP (mac_handle_apple_event),
1107 #else
1108 NewAEEventHandlerProc (mac_handle_apple_event),
1109 #endif
1110 0L, false);
1111 if (err != noErr)
1112 abort ();
1113 }
1114
1115 DEFUN ("mac-process-deferred-apple-events", Fmac_process_deferred_apple_events, Smac_process_deferred_apple_events, 0, 0, 0,
1116 doc: /* Process Apple events that are deferred at the startup time. */)
1117 ()
1118 {
1119 Lisp_Object result = Qnil;
1120 long i;
1121
1122 if (mac_ready_for_apple_events)
1123 return Qnil;
1124
1125 BLOCK_INPUT;
1126 mac_ready_for_apple_events = 1;
1127 if (deferred_apple_events.buf)
1128 {
1129 for (i = 0; i < deferred_apple_events.count; i += 2)
1130 {
1131 AEResumeTheCurrentEvent (deferred_apple_events.buf + i,
1132 deferred_apple_events.buf + i + 1,
1133 ((AEEventHandlerUPP)
1134 kAEUseStandardDispatch), 0);
1135 AEDisposeDesc (deferred_apple_events.buf + i);
1136 AEDisposeDesc (deferred_apple_events.buf + i + 1);
1137 }
1138 xfree (deferred_apple_events.buf);
1139 bzero (&deferred_apple_events, sizeof (deferred_apple_events));
1140
1141 result = Qt;
1142 }
1143 UNBLOCK_INPUT;
1144
1145 return result;
1146 }
1147
1148 \f
1149 #ifdef MAC_OSX
1150 void
1151 init_service_handler ()
1152 {
1153 EventTypeSpec specs[] = {{kEventClassService, kEventServiceGetTypes},
1154 {kEventClassService, kEventServiceCopy},
1155 {kEventClassService, kEventServicePaste},
1156 {kEventClassService, kEventServicePerform}};
1157 InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_service_event),
1158 GetEventTypeCount (specs), specs, NULL, NULL);
1159 }
1160
1161 extern OSErr mac_store_services_event P_ ((EventRef));
1162
1163 static OSStatus
1164 copy_scrap_flavor_data (from_scrap, to_scrap, flavor_type)
1165 ScrapRef from_scrap, to_scrap;
1166 ScrapFlavorType flavor_type;
1167 {
1168 OSStatus err;
1169 Size size, size_allocated;
1170 char *buf = NULL;
1171
1172 err = GetScrapFlavorSize (from_scrap, flavor_type, &size);
1173 if (err == noErr)
1174 buf = xmalloc (size);
1175 while (buf)
1176 {
1177 size_allocated = size;
1178 err = GetScrapFlavorData (from_scrap, flavor_type, &size, buf);
1179 if (err != noErr)
1180 {
1181 xfree (buf);
1182 buf = NULL;
1183 }
1184 else if (size_allocated < size)
1185 buf = xrealloc (buf, size);
1186 else
1187 break;
1188 }
1189 if (err == noErr)
1190 {
1191 if (buf == NULL)
1192 err = memFullErr;
1193 else
1194 {
1195 err = PutScrapFlavor (to_scrap, flavor_type, kScrapFlavorMaskNone,
1196 size, buf);
1197 xfree (buf);
1198 }
1199 }
1200
1201 return err;
1202 }
1203
1204 static OSStatus
1205 mac_handle_service_event (call_ref, event, data)
1206 EventHandlerCallRef call_ref;
1207 EventRef event;
1208 void *data;
1209 {
1210 OSStatus err = noErr;
1211 ScrapRef cur_scrap, specific_scrap;
1212 UInt32 event_kind = GetEventKind (event);
1213 CFMutableArrayRef copy_types, paste_types;
1214 CFStringRef type;
1215 Lisp_Object rest;
1216 ScrapFlavorType flavor_type;
1217
1218 /* Check if Vmac_services_selection is a valid selection that has a
1219 corresponding scrap. */
1220 if (!SYMBOLP (Vmac_services_selection))
1221 err = eventNotHandledErr;
1222 else
1223 err = get_scrap_from_symbol (Vmac_services_selection, 0, &cur_scrap);
1224 if (!(err == noErr && cur_scrap))
1225 return eventNotHandledErr;
1226
1227 switch (event_kind)
1228 {
1229 case kEventServiceGetTypes:
1230 /* Set paste types. */
1231 err = GetEventParameter (event, kEventParamServicePasteTypes,
1232 typeCFMutableArrayRef, NULL,
1233 sizeof (CFMutableArrayRef), NULL,
1234 &paste_types);
1235 if (err != noErr)
1236 break;
1237
1238 for (rest = Vselection_converter_alist; CONSP (rest);
1239 rest = XCDR (rest))
1240 if (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest)))
1241 && (flavor_type =
1242 get_flavor_type_from_symbol (XCAR (XCAR (rest)))))
1243 {
1244 type = CreateTypeStringWithOSType (flavor_type);
1245 if (type)
1246 {
1247 CFArrayAppendValue (paste_types, type);
1248 CFRelease (type);
1249 }
1250 }
1251
1252 /* Set copy types. */
1253 err = GetEventParameter (event, kEventParamServiceCopyTypes,
1254 typeCFMutableArrayRef, NULL,
1255 sizeof (CFMutableArrayRef), NULL,
1256 &copy_types);
1257 if (err != noErr)
1258 break;
1259
1260 if (NILP (Fx_selection_owner_p (Vmac_services_selection)))
1261 break;
1262 else
1263 goto copy_all_flavors;
1264
1265 case kEventServiceCopy:
1266 err = GetEventParameter (event, kEventParamScrapRef,
1267 typeScrapRef, NULL,
1268 sizeof (ScrapRef), NULL, &specific_scrap);
1269 if (err != noErr
1270 || NILP (Fx_selection_owner_p (Vmac_services_selection)))
1271 {
1272 err = eventNotHandledErr;
1273 break;
1274 }
1275
1276 copy_all_flavors:
1277 {
1278 UInt32 count, i;
1279 ScrapFlavorInfo *flavor_info = NULL;
1280 ScrapFlavorFlags flags;
1281
1282 err = GetScrapFlavorCount (cur_scrap, &count);
1283 if (err == noErr)
1284 flavor_info = xmalloc (sizeof (ScrapFlavorInfo) * count);
1285 err = GetScrapFlavorInfoList (cur_scrap, &count, flavor_info);
1286 if (err != noErr)
1287 {
1288 xfree (flavor_info);
1289 flavor_info = NULL;
1290 }
1291 if (flavor_info == NULL)
1292 break;
1293
1294 for (i = 0; i < count; i++)
1295 {
1296 flavor_type = flavor_info[i].flavorType;
1297 err = GetScrapFlavorFlags (cur_scrap, flavor_type, &flags);
1298 if (err == noErr && !(flags & kScrapFlavorMaskSenderOnly))
1299 {
1300 if (event_kind == kEventServiceCopy)
1301 err = copy_scrap_flavor_data (cur_scrap, specific_scrap,
1302 flavor_type);
1303 else /* event_kind == kEventServiceGetTypes */
1304 {
1305 type = CreateTypeStringWithOSType (flavor_type);
1306 if (type)
1307 {
1308 CFArrayAppendValue (copy_types, type);
1309 CFRelease (type);
1310 }
1311 }
1312 }
1313 }
1314 xfree (flavor_info);
1315 }
1316 break;
1317
1318 case kEventServicePaste:
1319 case kEventServicePerform:
1320 {
1321 int data_exists_p = 0;
1322
1323 err = GetEventParameter (event, kEventParamScrapRef, typeScrapRef,
1324 NULL, sizeof (ScrapRef), NULL,
1325 &specific_scrap);
1326 if (err == noErr)
1327 err = clear_scrap (&cur_scrap);
1328 if (err == noErr)
1329 for (rest = Vselection_converter_alist; CONSP (rest);
1330 rest = XCDR (rest))
1331 {
1332 if (! (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest)))))
1333 continue;
1334 flavor_type = get_flavor_type_from_symbol (XCAR (XCAR (rest)));
1335 if (flavor_type == 0)
1336 continue;
1337 err = copy_scrap_flavor_data (specific_scrap, cur_scrap,
1338 flavor_type);
1339 if (err == noErr)
1340 data_exists_p = 1;
1341 }
1342 if (!data_exists_p)
1343 err = eventNotHandledErr;
1344 else
1345 err = mac_store_services_event (event);
1346 }
1347 break;
1348 }
1349
1350 if (err != noErr)
1351 err = eventNotHandledErr;
1352 return err;
1353 }
1354 #endif
1355
1356
1357 void
1358 syms_of_macselect ()
1359 {
1360 defsubr (&Sx_get_selection_internal);
1361 defsubr (&Sx_own_selection_internal);
1362 defsubr (&Sx_disown_selection_internal);
1363 defsubr (&Sx_selection_owner_p);
1364 defsubr (&Sx_selection_exists_p);
1365 defsubr (&Smac_process_deferred_apple_events);
1366
1367 Vselection_alist = Qnil;
1368 staticpro (&Vselection_alist);
1369
1370 DEFVAR_LISP ("selection-converter-alist", &Vselection_converter_alist,
1371 doc: /* An alist associating selection-types with functions.
1372 These functions are called to convert the selection, with three args:
1373 the name of the selection (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');
1374 a desired type to which the selection should be converted;
1375 and the local selection value (whatever was given to `x-own-selection').
1376
1377 The function should return the value to send to the Scrap Manager
1378 \(must be a string). A return value of nil
1379 means that the conversion could not be done.
1380 A return value which is the symbol `NULL'
1381 means that a side-effect was executed,
1382 and there is no meaningful selection value. */);
1383 Vselection_converter_alist = Qnil;
1384
1385 DEFVAR_LISP ("x-lost-selection-functions", &Vx_lost_selection_functions,
1386 doc: /* A list of functions to be called when Emacs loses a selection.
1387 \(This happens when a Lisp program explicitly clears the selection.)
1388 The functions are called with one argument, the selection type
1389 \(a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'). */);
1390 Vx_lost_selection_functions = Qnil;
1391
1392 DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system,
1393 doc: /* Coding system for communicating with other programs.
1394 When sending or receiving text via cut_buffer, selection, and clipboard,
1395 the text is encoded or decoded by this coding system.
1396 The default value is determined by the system script code. */);
1397 Vselection_coding_system = Qnil;
1398
1399 DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system,
1400 doc: /* Coding system for the next communication with other programs.
1401 Usually, `selection-coding-system' is used for communicating with
1402 other programs. But, if this variable is set, it is used for the
1403 next communication only. After the communication, this variable is
1404 set to nil. */);
1405 Vnext_selection_coding_system = Qnil;
1406
1407 DEFVAR_LISP ("mac-apple-event-map", &Vmac_apple_event_map,
1408 doc: /* Keymap for Apple events handled by Emacs. */);
1409 Vmac_apple_event_map = Qnil;
1410
1411 #ifdef MAC_OSX
1412 DEFVAR_LISP ("mac-services-selection", &Vmac_services_selection,
1413 doc: /* Selection name for communication via Services menu. */);
1414 Vmac_services_selection = intern ("PRIMARY");
1415 #endif
1416
1417 QPRIMARY = intern ("PRIMARY"); staticpro (&QPRIMARY);
1418 QSECONDARY = intern ("SECONDARY"); staticpro (&QSECONDARY);
1419 QTIMESTAMP = intern ("TIMESTAMP"); staticpro (&QTIMESTAMP);
1420 QTARGETS = intern ("TARGETS"); staticpro (&QTARGETS);
1421
1422 Qforeign_selection = intern ("foreign-selection");
1423 staticpro (&Qforeign_selection);
1424
1425 Qmac_scrap_name = intern ("mac-scrap-name");
1426 staticpro (&Qmac_scrap_name);
1427
1428 Qmac_ostype = intern ("mac-ostype");
1429 staticpro (&Qmac_ostype);
1430
1431 Qmac_apple_event_class = intern ("mac-apple-event-class");
1432 staticpro (&Qmac_apple_event_class);
1433
1434 Qmac_apple_event_id = intern ("mac-apple-event-id");
1435 staticpro (&Qmac_apple_event_id);
1436 }
1437
1438 /* arch-tag: f3c91ad8-99e0-4bd6-9eef-251b2f848732
1439 (do not change this comment) */