aboutsummaryrefslogtreecommitdiffstats
path: root/src/macselect.c
diff options
context:
space:
mode:
authorYAMAMOTO Mitsuharu2008-04-06 01:58:39 +0000
committerYAMAMOTO Mitsuharu2008-04-06 01:58:39 +0000
commit5d6c5138509b0bba003bf93d0b6fe9bcc77195af (patch)
tree8d99072b56cdcd59228128a69028948a58e9e225 /src/macselect.c
parent5aa4098ee2f374fadf0bab8a4382b19a4da4cad6 (diff)
downloademacs-5d6c5138509b0bba003bf93d0b6fe9bcc77195af.tar.gz
emacs-5d6c5138509b0bba003bf93d0b6fe9bcc77195af.zip
[!TARGET_API_MAC_CARBON]: Don't include Scrap.h.
(Selection): Move typedef to macgui.h. (Vselection_converter_alist, Qmac_scrap_name, Qmac_ostype) (Vmac_apple_event_map, Qmac_apple_event_class, Qmac_apple_event_id): Make variables non-static. (Vmac_dnd_known_types) [TARGET_API_MAC_CARBON]: Likewise. (mac_handle_apple_event, cleanup_all_suspended_apple_events): Make functions non-static. (Vmac_service_selection) [MAC_OSX]: Likewise. (mac_get_selection_from_symbol, get_flavor_type_from_symbol) (mac_valid_selection_target_p, mac_clear_selection) (mac_get_selection_ownership_info, mac_valid_selection_value_p) (mac_put_selection_value, mac_selection_has_target_p) (mac_get_selection_value, mac_get_selection_target_list) (init_apple_event_handler, install_drag_handler, remove_drag_handler): Move functions to mactoolbox.c. (mac_do_track_drag, mac_do_receive_drag) [TARGET_API_MAC_CARBON]: Likewise. (copy_scrap_flavor_data, mac_handle_service_event) (install_service_handler) [MAC_OSX]: Likewise. (syms_of_macselect) <Vmac_dnd_known_types>: Use mac_dnd_default_known_types.
Diffstat (limited to 'src/macselect.c')
-rw-r--r--src/macselect.c770
1 files changed, 13 insertions, 757 deletions
diff --git a/src/macselect.c b/src/macselect.c
index 56efd496945..df7e98c0d67 100644
--- a/src/macselect.c
+++ b/src/macselect.c
@@ -25,38 +25,15 @@ Boston, MA 02110-1301, USA. */
25#include "blockinput.h" 25#include "blockinput.h"
26#include "keymap.h" 26#include "keymap.h"
27 27
28#if TARGET_API_MAC_CARBON 28#if !TARGET_API_MAC_CARBON
29typedef ScrapRef Selection;
30#else /* !TARGET_API_MAC_CARBON */
31#include <Scrap.h>
32#include <Endian.h> 29#include <Endian.h>
33typedef int Selection; 30#endif
34#endif /* !TARGET_API_MAC_CARBON */ 31
35
36static OSStatus mac_get_selection_from_symbol P_ ((Lisp_Object, int,
37 Selection *));
38static ScrapFlavorType get_flavor_type_from_symbol P_ ((Lisp_Object,
39 Selection));
40static int mac_valid_selection_target_p P_ ((Lisp_Object));
41static OSStatus mac_clear_selection P_ ((Selection *));
42static Lisp_Object mac_get_selection_ownership_info P_ ((Selection));
43static int mac_valid_selection_value_p P_ ((Lisp_Object, Lisp_Object));
44static OSStatus mac_put_selection_value P_ ((Selection, Lisp_Object,
45 Lisp_Object));
46static int mac_selection_has_target_p P_ ((Selection, Lisp_Object));
47static Lisp_Object mac_get_selection_value P_ ((Selection, Lisp_Object));
48static Lisp_Object mac_get_selection_target_list P_ ((Selection));
49static void x_own_selection P_ ((Lisp_Object, Lisp_Object)); 32static void x_own_selection P_ ((Lisp_Object, Lisp_Object));
50static Lisp_Object x_get_local_selection P_ ((Lisp_Object, Lisp_Object, int)); 33static Lisp_Object x_get_local_selection P_ ((Lisp_Object, Lisp_Object, int));
51static Lisp_Object x_get_foreign_selection P_ ((Lisp_Object, 34static Lisp_Object x_get_foreign_selection P_ ((Lisp_Object,
52 Lisp_Object, 35 Lisp_Object,
53 Lisp_Object)); 36 Lisp_Object));
54EXFUN (Fx_selection_owner_p, 1);
55#ifdef MAC_OSX
56static OSStatus mac_handle_service_event P_ ((EventHandlerCallRef,
57 EventRef, void *));
58void init_service_handler P_ ((void));
59#endif
60 37
61Lisp_Object QPRIMARY, QSECONDARY, QTIMESTAMP, QTARGETS; 38Lisp_Object QPRIMARY, QSECONDARY, QTIMESTAMP, QTARGETS;
62 39
@@ -98,302 +75,13 @@ static Lisp_Object Vselection_alist;
98 selection value to a string representing the given selection type. 75 selection value to a string representing the given selection type.
99 This is for Lisp-level extension of the emacs selection 76 This is for Lisp-level extension of the emacs selection
100 handling. */ 77 handling. */
101static Lisp_Object Vselection_converter_alist; 78Lisp_Object Vselection_converter_alist;
102 79
103/* A selection name (represented as a Lisp symbol) can be associated 80/* A selection name (represented as a Lisp symbol) can be associated
104 with a named scrap via `mac-scrap-name' property. Likewise for a 81 with a named scrap via `mac-scrap-name' property. Likewise for a
105 selection type with a scrap flavor type via `mac-ostype'. */ 82 selection type with a scrap flavor type via `mac-ostype'. */
106static Lisp_Object Qmac_scrap_name, Qmac_ostype; 83Lisp_Object Qmac_scrap_name, Qmac_ostype;
107
108#ifdef MAC_OSX
109/* Selection name for communication via Services menu. */
110static Lisp_Object Vmac_service_selection;
111#endif
112
113/* Get a reference to the selection corresponding to the symbol SYM.
114 The reference is set to *SEL, and it becomes NULL if there's no
115 corresponding selection. Clear the selection if CLEAR_P is
116 non-zero. */
117
118static OSStatus
119mac_get_selection_from_symbol (sym, clear_p, sel)
120 Lisp_Object sym;
121 int clear_p;
122 Selection *sel;
123{
124 OSStatus err = noErr;
125 Lisp_Object str = Fget (sym, Qmac_scrap_name);
126
127 if (!STRINGP (str))
128 *sel = NULL;
129 else
130 {
131#if TARGET_API_MAC_CARBON
132#ifdef MAC_OSX
133 CFStringRef scrap_name = cfstring_create_with_string (str);
134 OptionBits options = (clear_p ? kScrapClearNamedScrap
135 : kScrapGetNamedScrap);
136
137 err = GetScrapByName (scrap_name, options, sel);
138 CFRelease (scrap_name);
139#else /* !MAC_OSX */
140 if (clear_p)
141 err = ClearCurrentScrap ();
142 if (err == noErr)
143 err = GetCurrentScrap (sel);
144#endif /* !MAC_OSX */
145#else /* !TARGET_API_MAC_CARBON */
146 if (clear_p)
147 err = ZeroScrap ();
148 if (err == noErr)
149 *sel = 1;
150#endif /* !TARGET_API_MAC_CARBON */
151 }
152
153 return err;
154}
155
156/* Get a scrap flavor type from the symbol SYM. Return 0 if no
157 corresponding flavor type. If SEL is non-zero, the return value is
158 non-zero only when the SEL has the flavor type. */
159
160static ScrapFlavorType
161get_flavor_type_from_symbol (sym, sel)
162 Lisp_Object sym;
163 Selection sel;
164{
165 Lisp_Object str = Fget (sym, Qmac_ostype);
166 ScrapFlavorType flavor_type;
167
168 if (STRINGP (str) && SBYTES (str) == 4)
169 flavor_type = EndianU32_BtoN (*((UInt32 *) SDATA (str)));
170 else
171 flavor_type = 0;
172
173 if (flavor_type && sel)
174 {
175#if TARGET_API_MAC_CARBON
176 OSStatus err;
177 ScrapFlavorFlags flags;
178
179 err = GetScrapFlavorFlags (sel, flavor_type, &flags);
180 if (err != noErr)
181 flavor_type = 0;
182#else /* !TARGET_API_MAC_CARBON */
183 SInt32 size, offset;
184
185 size = GetScrap (NULL, flavor_type, &offset);
186 if (size < 0)
187 flavor_type = 0;
188#endif /* !TARGET_API_MAC_CARBON */
189 }
190
191 return flavor_type;
192}
193
194/* Check if the symbol SYM has a corresponding selection target type. */
195
196static int
197mac_valid_selection_target_p (sym)
198 Lisp_Object sym;
199{
200 return get_flavor_type_from_symbol (sym, 0) != 0;
201}
202
203/* Clear the selection whose reference is *SEL. */
204
205static OSStatus
206mac_clear_selection (sel)
207 Selection *sel;
208{
209#if TARGET_API_MAC_CARBON
210#ifdef MAC_OSX
211 return ClearScrap (sel);
212#else
213 OSStatus err;
214
215 err = ClearCurrentScrap ();
216 if (err == noErr)
217 err = GetCurrentScrap (sel);
218 return err;
219#endif
220#else /* !TARGET_API_MAC_CARBON */
221 return ZeroScrap ();
222#endif /* !TARGET_API_MAC_CARBON */
223}
224
225/* Get ownership information for SEL. Emacs can detect a change of
226 the ownership by comparing saved and current values of the
227 ownership information. */
228
229static Lisp_Object
230mac_get_selection_ownership_info (sel)
231 Selection sel;
232{
233#if TARGET_API_MAC_CARBON
234 return long_to_cons ((unsigned long) sel);
235#else /* !TARGET_API_MAC_CARBON */
236 ScrapStuffPtr scrap_info = InfoScrap ();
237
238 return make_number (scrap_info->scrapCount);
239#endif /* !TARGET_API_MAC_CARBON */
240}
241
242/* Return non-zero if VALUE is a valid selection value for TARGET. */
243
244static int
245mac_valid_selection_value_p (value, target)
246 Lisp_Object value, target;
247{
248 return STRINGP (value);
249}
250
251/* Put Lisp Object VALUE to the selection SEL. The target type is
252 specified by TARGET. */
253
254static OSStatus
255mac_put_selection_value (sel, target, value)
256 Selection sel;
257 Lisp_Object target, value;
258{
259 ScrapFlavorType flavor_type = get_flavor_type_from_symbol (target, 0);
260
261 if (flavor_type == 0 || !STRINGP (value))
262 return noTypeErr;
263
264#if TARGET_API_MAC_CARBON
265 return PutScrapFlavor (sel, flavor_type, kScrapFlavorMaskNone,
266 SBYTES (value), SDATA (value));
267#else /* !TARGET_API_MAC_CARBON */
268 return PutScrap (SBYTES (value), flavor_type, SDATA (value));
269#endif /* !TARGET_API_MAC_CARBON */
270}
271 84
272/* Check if data for the target type TARGET is available in SEL. */
273
274static int
275mac_selection_has_target_p (sel, target)
276 Selection sel;
277 Lisp_Object target;
278{
279 return get_flavor_type_from_symbol (target, sel) != 0;
280}
281
282/* Get data for the target type TARGET from SEL and create a Lisp
283 string. Return nil if failed to get data. */
284
285static Lisp_Object
286mac_get_selection_value (sel, target)
287 Selection sel;
288 Lisp_Object target;
289{
290 OSStatus err;
291 Lisp_Object result = Qnil;
292 ScrapFlavorType flavor_type = get_flavor_type_from_symbol (target, sel);
293#if TARGET_API_MAC_CARBON
294 Size size;
295
296 if (flavor_type)
297 {
298 err = GetScrapFlavorSize (sel, flavor_type, &size);
299 if (err == noErr)
300 {
301 do
302 {
303 result = make_uninit_string (size);
304 err = GetScrapFlavorData (sel, flavor_type,
305 &size, SDATA (result));
306 if (err != noErr)
307 result = Qnil;
308 else if (size < SBYTES (result))
309 result = make_unibyte_string (SDATA (result), size);
310 }
311 while (STRINGP (result) && size > SBYTES (result));
312 }
313 }
314#else
315 Handle handle;
316 SInt32 size, offset;
317
318 if (flavor_type)
319 size = GetScrap (NULL, flavor_type, &offset);
320 if (size >= 0)
321 {
322 handle = NewHandle (size);
323 HLock (handle);
324 size = GetScrap (handle, flavor_type, &offset);
325 if (size >= 0)
326 result = make_unibyte_string (*handle, size);
327 DisposeHandle (handle);
328 }
329#endif
330
331 return result;
332}
333
334/* Get the list of target types in SEL. The return value is a list of
335 target type symbols possibly followed by scrap flavor type
336 strings. */
337
338static Lisp_Object
339mac_get_selection_target_list (sel)
340 Selection sel;
341{
342 Lisp_Object result = Qnil, rest, target;
343#if TARGET_API_MAC_CARBON
344 OSStatus err;
345 UInt32 count, i, type;
346 ScrapFlavorInfo *flavor_info = NULL;
347 Lisp_Object strings = Qnil;
348
349 err = GetScrapFlavorCount (sel, &count);
350 if (err == noErr)
351 flavor_info = xmalloc (sizeof (ScrapFlavorInfo) * count);
352 err = GetScrapFlavorInfoList (sel, &count, flavor_info);
353 if (err != noErr)
354 {
355 xfree (flavor_info);
356 flavor_info = NULL;
357 }
358 if (flavor_info == NULL)
359 count = 0;
360#endif
361 for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest))
362 {
363 ScrapFlavorType flavor_type = 0;
364
365 if (CONSP (XCAR (rest))
366 && (target = XCAR (XCAR (rest)),
367 SYMBOLP (target))
368 && (flavor_type = get_flavor_type_from_symbol (target, sel)))
369 {
370 result = Fcons (target, result);
371#if TARGET_API_MAC_CARBON
372 for (i = 0; i < count; i++)
373 if (flavor_info[i].flavorType == flavor_type)
374 {
375 flavor_info[i].flavorType = 0;
376 break;
377 }
378#endif
379 }
380 }
381#if TARGET_API_MAC_CARBON
382 if (flavor_info)
383 {
384 for (i = 0; i < count; i++)
385 if (flavor_info[i].flavorType)
386 {
387 type = EndianU32_NtoB (flavor_info[i].flavorType);
388 strings = Fcons (make_unibyte_string ((char *) &type, 4), strings);
389 }
390 result = nconc2 (result, strings);
391 xfree (flavor_info);
392 }
393#endif
394
395 return result;
396}
397 85
398/* Do protocol to assert ourself as a selection owner. 86/* Do protocol to assert ourself as a selection owner.
399 Update the Vselection_alist so that we can reply to later requests for 87 Update the Vselection_alist so that we can reply to later requests for
@@ -892,8 +580,8 @@ and t is the same as `SECONDARY'. */)
892 Apple event support 580 Apple event support
893***********************************************************************/ 581***********************************************************************/
894int mac_ready_for_apple_events = 0; 582int mac_ready_for_apple_events = 0;
895static Lisp_Object Vmac_apple_event_map; 583Lisp_Object Vmac_apple_event_map;
896static Lisp_Object Qmac_apple_event_class, Qmac_apple_event_id; 584Lisp_Object Qmac_apple_event_class, Qmac_apple_event_id;
897static Lisp_Object Qemacs_suspension_id; 585static Lisp_Object Qemacs_suspension_id;
898extern Lisp_Object Qundefined; 586extern Lisp_Object Qundefined;
899extern void mac_store_apple_event P_ ((Lisp_Object, Lisp_Object, 587extern void mac_store_apple_event P_ ((Lisp_Object, Lisp_Object,
@@ -1095,7 +783,7 @@ mac_handle_apple_event_1 (class, id, apple_event, reply)
1095 return err; 783 return err;
1096} 784}
1097 785
1098static pascal OSErr 786pascal OSErr
1099mac_handle_apple_event (apple_event, reply, refcon) 787mac_handle_apple_event (apple_event, reply, refcon)
1100 const AppleEvent *apple_event; 788 const AppleEvent *apple_event;
1101 AppleEvent *reply; 789 AppleEvent *reply;
@@ -1173,40 +861,13 @@ cleanup_suspended_apple_events (head, all_p)
1173 return nresumed; 861 return nresumed;
1174} 862}
1175 863
1176static void 864void
1177cleanup_all_suspended_apple_events () 865cleanup_all_suspended_apple_events ()
1178{ 866{
1179 cleanup_suspended_apple_events (&deferred_apple_events, 1); 867 cleanup_suspended_apple_events (&deferred_apple_events, 1);
1180 cleanup_suspended_apple_events (&suspended_apple_events, 1); 868 cleanup_suspended_apple_events (&suspended_apple_events, 1);
1181} 869}
1182 870
1183void
1184init_apple_event_handler ()
1185{
1186 OSErr err;
1187 long result;
1188
1189 /* Make sure we have Apple events before starting. */
1190 err = Gestalt (gestaltAppleEventsAttr, &result);
1191 if (err != noErr)
1192 abort ();
1193
1194 if (!(result & (1 << gestaltAppleEventsPresent)))
1195 abort ();
1196
1197 err = AEInstallEventHandler (typeWildCard, typeWildCard,
1198#if TARGET_API_MAC_CARBON
1199 NewAEEventHandlerUPP (mac_handle_apple_event),
1200#else
1201 NewAEEventHandlerProc (mac_handle_apple_event),
1202#endif
1203 0L, false);
1204 if (err != noErr)
1205 abort ();
1206
1207 atexit (cleanup_all_suspended_apple_events);
1208}
1209
1210static UInt32 871static UInt32
1211get_suspension_id (apple_event) 872get_suspension_id (apple_event)
1212 Lisp_Object apple_event; 873 Lisp_Object apple_event;
@@ -1399,419 +1060,18 @@ nil, which means the event is already resumed or expired. */)
1399 Drag and drop support 1060 Drag and drop support
1400***********************************************************************/ 1061***********************************************************************/
1401#if TARGET_API_MAC_CARBON 1062#if TARGET_API_MAC_CARBON
1402static Lisp_Object Vmac_dnd_known_types; 1063Lisp_Object Vmac_dnd_known_types;
1403static pascal OSErr mac_do_track_drag P_ ((DragTrackingMessage, WindowRef,
1404 void *, DragRef));
1405static pascal OSErr mac_do_receive_drag P_ ((WindowRef, void *, DragRef));
1406static DragTrackingHandlerUPP mac_do_track_dragUPP = NULL;
1407static DragReceiveHandlerUPP mac_do_receive_dragUPP = NULL;
1408
1409extern void mac_store_drag_event P_ ((WindowRef, Point, SInt16,
1410 const AEDesc *));
1411
1412static pascal OSErr
1413mac_do_track_drag (message, window, refcon, drag)
1414 DragTrackingMessage message;
1415 WindowRef window;
1416 void *refcon;
1417 DragRef drag;
1418{
1419 OSErr err = noErr;
1420 static int can_accept;
1421 UInt16 num_items, index;
1422
1423 if (GetFrontWindowOfClass (kMovableModalWindowClass, false))
1424 return dragNotAcceptedErr;
1425
1426 switch (message)
1427 {
1428 case kDragTrackingEnterHandler:
1429 err = CountDragItems (drag, &num_items);
1430 if (err != noErr)
1431 break;
1432 can_accept = 0;
1433 for (index = 1; index <= num_items; index++)
1434 {
1435 ItemReference item;
1436 FlavorFlags flags;
1437 Lisp_Object rest;
1438
1439 err = GetDragItemReferenceNumber (drag, index, &item);
1440 if (err != noErr)
1441 continue;
1442 for (rest = Vmac_dnd_known_types; CONSP (rest); rest = XCDR (rest))
1443 {
1444 Lisp_Object str;
1445 FlavorType type;
1446
1447 str = XCAR (rest);
1448 if (!(STRINGP (str) && SBYTES (str) == 4))
1449 continue;
1450 type = EndianU32_BtoN (*((UInt32 *) SDATA (str)));
1451
1452 err = GetFlavorFlags (drag, item, type, &flags);
1453 if (err == noErr)
1454 {
1455 can_accept = 1;
1456 break;
1457 }
1458 }
1459 }
1460 break;
1461
1462 case kDragTrackingEnterWindow:
1463 if (can_accept)
1464 {
1465 RgnHandle hilite_rgn = NewRgn ();
1466
1467 if (hilite_rgn)
1468 {
1469 Rect r;
1470
1471 GetWindowPortBounds (window, &r);
1472 OffsetRect (&r, -r.left, -r.top);
1473 RectRgn (hilite_rgn, &r);
1474 ShowDragHilite (drag, hilite_rgn, true);
1475 DisposeRgn (hilite_rgn);
1476 }
1477 SetThemeCursor (kThemeCopyArrowCursor);
1478 }
1479 break;
1480
1481 case kDragTrackingInWindow:
1482 break;
1483
1484 case kDragTrackingLeaveWindow:
1485 if (can_accept)
1486 {
1487 HideDragHilite (drag);
1488 SetThemeCursor (kThemeArrowCursor);
1489 }
1490 break;
1491
1492 case kDragTrackingLeaveHandler:
1493 break;
1494 }
1495
1496 if (err != noErr)
1497 return dragNotAcceptedErr;
1498 return noErr;
1499}
1500
1501static pascal OSErr
1502mac_do_receive_drag (window, refcon, drag)
1503 WindowRef window;
1504 void *refcon;
1505 DragRef drag;
1506{
1507 OSErr err;
1508 int num_types, i;
1509 Lisp_Object rest, str;
1510 FlavorType *types;
1511 AppleEvent apple_event;
1512 Point mouse_pos;
1513 SInt16 modifiers;
1514
1515 if (GetFrontWindowOfClass (kMovableModalWindowClass, false))
1516 return dragNotAcceptedErr;
1517
1518 num_types = 0;
1519 for (rest = Vmac_dnd_known_types; CONSP (rest); rest = XCDR (rest))
1520 {
1521 str = XCAR (rest);
1522 if (STRINGP (str) && SBYTES (str) == 4)
1523 num_types++;
1524 }
1525
1526 types = xmalloc (sizeof (FlavorType) * num_types);
1527 i = 0;
1528 for (rest = Vmac_dnd_known_types; CONSP (rest); rest = XCDR (rest))
1529 {
1530 str = XCAR (rest);
1531 if (STRINGP (str) && SBYTES (str) == 4)
1532 types[i++] = EndianU32_BtoN (*((UInt32 *) SDATA (str)));
1533 }
1534
1535 err = create_apple_event_from_drag_ref (drag, num_types, types,
1536 &apple_event);
1537 xfree (types);
1538
1539 if (err == noErr)
1540 err = GetDragMouse (drag, &mouse_pos, NULL);
1541 if (err == noErr)
1542 {
1543 GlobalToLocal (&mouse_pos);
1544 err = GetDragModifiers (drag, NULL, NULL, &modifiers);
1545 }
1546 if (err == noErr)
1547 {
1548 UInt32 key_modifiers = modifiers;
1549
1550 err = AEPutParamPtr (&apple_event, kEventParamKeyModifiers,
1551 typeUInt32, &key_modifiers, sizeof (UInt32));
1552 }
1553
1554 if (err == noErr)
1555 {
1556 mac_store_drag_event (window, mouse_pos, 0, &apple_event);
1557 AEDisposeDesc (&apple_event);
1558 mac_wakeup_from_rne ();
1559 return noErr;
1560 }
1561 else
1562 return dragNotAcceptedErr;
1563}
1564#endif /* TARGET_API_MAC_CARBON */ 1064#endif /* TARGET_API_MAC_CARBON */
1565 1065
1566OSErr
1567install_drag_handler (window)
1568 WindowRef window;
1569{
1570 OSErr err = noErr;
1571
1572#if TARGET_API_MAC_CARBON
1573 if (mac_do_track_dragUPP == NULL)
1574 mac_do_track_dragUPP = NewDragTrackingHandlerUPP (mac_do_track_drag);
1575 if (mac_do_receive_dragUPP == NULL)
1576 mac_do_receive_dragUPP = NewDragReceiveHandlerUPP (mac_do_receive_drag);
1577
1578 err = InstallTrackingHandler (mac_do_track_dragUPP, window, NULL);
1579 if (err == noErr)
1580 err = InstallReceiveHandler (mac_do_receive_dragUPP, window, NULL);
1581#endif
1582
1583 return err;
1584}
1585
1586void
1587remove_drag_handler (window)
1588 WindowRef window;
1589{
1590#if TARGET_API_MAC_CARBON
1591 if (mac_do_track_dragUPP)
1592 RemoveTrackingHandler (mac_do_track_dragUPP, window);
1593 if (mac_do_receive_dragUPP)
1594 RemoveReceiveHandler (mac_do_receive_dragUPP, window);
1595#endif
1596}
1597
1598 1066
1599/*********************************************************************** 1067/***********************************************************************
1600 Services menu support 1068 Services menu support
1601***********************************************************************/ 1069***********************************************************************/
1602#ifdef MAC_OSX 1070#ifdef MAC_OSX
1603OSStatus 1071/* Selection name for communication via Services menu. */
1604install_service_handler () 1072Lisp_Object Vmac_service_selection;
1605{
1606 static const EventTypeSpec specs[] =
1607 {{kEventClassService, kEventServiceGetTypes},
1608 {kEventClassService, kEventServiceCopy},
1609 {kEventClassService, kEventServicePaste},
1610 {kEventClassService, kEventServicePerform}};
1611
1612 return InstallApplicationEventHandler (NewEventHandlerUPP
1613 (mac_handle_service_event),
1614 GetEventTypeCount (specs),
1615 specs, NULL, NULL);
1616}
1617
1618extern OSStatus mac_store_service_event P_ ((EventRef));
1619
1620static OSStatus
1621copy_scrap_flavor_data (from_scrap, to_scrap, flavor_type)
1622 ScrapRef from_scrap, to_scrap;
1623 ScrapFlavorType flavor_type;
1624{
1625 OSStatus err;
1626 Size size, size_allocated;
1627 char *buf = NULL;
1628
1629 err = GetScrapFlavorSize (from_scrap, flavor_type, &size);
1630 if (err == noErr)
1631 buf = xmalloc (size);
1632 while (buf)
1633 {
1634 size_allocated = size;
1635 err = GetScrapFlavorData (from_scrap, flavor_type, &size, buf);
1636 if (err != noErr)
1637 {
1638 xfree (buf);
1639 buf = NULL;
1640 }
1641 else if (size_allocated < size)
1642 buf = xrealloc (buf, size);
1643 else
1644 break;
1645 }
1646 if (err == noErr)
1647 {
1648 if (buf == NULL)
1649 err = memFullErr;
1650 else
1651 {
1652 err = PutScrapFlavor (to_scrap, flavor_type, kScrapFlavorMaskNone,
1653 size, buf);
1654 xfree (buf);
1655 }
1656 }
1657
1658 return err;
1659}
1660
1661static OSStatus
1662mac_handle_service_event (call_ref, event, data)
1663 EventHandlerCallRef call_ref;
1664 EventRef event;
1665 void *data;
1666{
1667 OSStatus err = noErr;
1668 ScrapRef cur_scrap, specific_scrap;
1669 UInt32 event_kind = GetEventKind (event);
1670 CFMutableArrayRef copy_types, paste_types;
1671 CFStringRef type;
1672 Lisp_Object rest;
1673 ScrapFlavorType flavor_type;
1674
1675 /* Check if Vmac_service_selection is a valid selection that has a
1676 corresponding scrap. */
1677 if (!SYMBOLP (Vmac_service_selection))
1678 err = eventNotHandledErr;
1679 else
1680 err = mac_get_selection_from_symbol (Vmac_service_selection, 0, &cur_scrap);
1681 if (!(err == noErr && cur_scrap))
1682 return eventNotHandledErr;
1683
1684 switch (event_kind)
1685 {
1686 case kEventServiceGetTypes:
1687 /* Set paste types. */
1688 err = GetEventParameter (event, kEventParamServicePasteTypes,
1689 typeCFMutableArrayRef, NULL,
1690 sizeof (CFMutableArrayRef), NULL,
1691 &paste_types);
1692 if (err != noErr)
1693 break;
1694
1695 for (rest = Vselection_converter_alist; CONSP (rest);
1696 rest = XCDR (rest))
1697 if (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest)))
1698 && (flavor_type =
1699 get_flavor_type_from_symbol (XCAR (XCAR (rest)), 0)))
1700 {
1701 type = CreateTypeStringWithOSType (flavor_type);
1702 if (type)
1703 {
1704 CFArrayAppendValue (paste_types, type);
1705 CFRelease (type);
1706 }
1707 }
1708
1709 /* Set copy types. */
1710 err = GetEventParameter (event, kEventParamServiceCopyTypes,
1711 typeCFMutableArrayRef, NULL,
1712 sizeof (CFMutableArrayRef), NULL,
1713 &copy_types);
1714 if (err != noErr)
1715 break;
1716
1717 if (NILP (Fx_selection_owner_p (Vmac_service_selection)))
1718 break;
1719 else
1720 goto copy_all_flavors;
1721
1722 case kEventServiceCopy:
1723 err = GetEventParameter (event, kEventParamScrapRef,
1724 typeScrapRef, NULL,
1725 sizeof (ScrapRef), NULL, &specific_scrap);
1726 if (err != noErr
1727 || NILP (Fx_selection_owner_p (Vmac_service_selection)))
1728 {
1729 err = eventNotHandledErr;
1730 break;
1731 }
1732
1733 copy_all_flavors:
1734 {
1735 UInt32 count, i;
1736 ScrapFlavorInfo *flavor_info = NULL;
1737 ScrapFlavorFlags flags;
1738
1739 err = GetScrapFlavorCount (cur_scrap, &count);
1740 if (err == noErr)
1741 flavor_info = xmalloc (sizeof (ScrapFlavorInfo) * count);
1742 err = GetScrapFlavorInfoList (cur_scrap, &count, flavor_info);
1743 if (err != noErr)
1744 {
1745 xfree (flavor_info);
1746 flavor_info = NULL;
1747 }
1748 if (flavor_info == NULL)
1749 break;
1750
1751 for (i = 0; i < count; i++)
1752 {
1753 flavor_type = flavor_info[i].flavorType;
1754 err = GetScrapFlavorFlags (cur_scrap, flavor_type, &flags);
1755 if (err == noErr && !(flags & kScrapFlavorMaskSenderOnly))
1756 {
1757 if (event_kind == kEventServiceCopy)
1758 err = copy_scrap_flavor_data (cur_scrap, specific_scrap,
1759 flavor_type);
1760 else /* event_kind == kEventServiceGetTypes */
1761 {
1762 type = CreateTypeStringWithOSType (flavor_type);
1763 if (type)
1764 {
1765 CFArrayAppendValue (copy_types, type);
1766 CFRelease (type);
1767 }
1768 }
1769 }
1770 }
1771 xfree (flavor_info);
1772 }
1773 break;
1774
1775 case kEventServicePaste:
1776 case kEventServicePerform:
1777 {
1778 int data_exists_p = 0;
1779
1780 err = GetEventParameter (event, kEventParamScrapRef, typeScrapRef,
1781 NULL, sizeof (ScrapRef), NULL,
1782 &specific_scrap);
1783 if (err == noErr)
1784 err = mac_clear_selection (&cur_scrap);
1785 if (err == noErr)
1786 for (rest = Vselection_converter_alist; CONSP (rest);
1787 rest = XCDR (rest))
1788 {
1789 if (! (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest)))))
1790 continue;
1791 flavor_type = get_flavor_type_from_symbol (XCAR (XCAR (rest)),
1792 specific_scrap);
1793 if (flavor_type == 0)
1794 continue;
1795 err = copy_scrap_flavor_data (specific_scrap, cur_scrap,
1796 flavor_type);
1797 if (err == noErr)
1798 data_exists_p = 1;
1799 }
1800 if (!data_exists_p)
1801 err = eventNotHandledErr;
1802 else
1803 err = mac_store_service_event (event);
1804 }
1805 break;
1806 }
1807
1808 if (err != noErr)
1809 err = eventNotHandledErr;
1810 return err;
1811}
1812#endif 1073#endif
1813 1074
1814
1815void 1075void
1816syms_of_macselect () 1076syms_of_macselect ()
1817{ 1077{
@@ -1870,11 +1130,7 @@ set to nil. */);
1870 DEFVAR_LISP ("mac-dnd-known-types", &Vmac_dnd_known_types, 1130 DEFVAR_LISP ("mac-dnd-known-types", &Vmac_dnd_known_types,
1871 doc: /* The types accepted by default for dropped data. 1131 doc: /* The types accepted by default for dropped data.
1872The types are chosen in the order they appear in the list. */); 1132The types are chosen in the order they appear in the list. */);
1873 Vmac_dnd_known_types = list4 (build_string ("hfs "), build_string ("utxt"), 1133 Vmac_dnd_known_types = mac_dnd_default_known_types ();
1874 build_string ("TEXT"), build_string ("TIFF"));
1875#ifdef MAC_OSX
1876 Vmac_dnd_known_types = Fcons (build_string ("furl"), Vmac_dnd_known_types);
1877#endif
1878#endif 1134#endif
1879 1135
1880#ifdef MAC_OSX 1136#ifdef MAC_OSX