Mercurial > emacs
comparison src/macselect.c @ 80454:98811b17d3b9
[!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.
author | YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> |
---|---|
date | Sun, 06 Apr 2008 01:58:39 +0000 |
parents | 1d3df1b9547b |
children | aee651d7cdc7 3af508d0bd74 |
comparison
equal
deleted
inserted
replaced
80453:07666d9ede23 | 80454:98811b17d3b9 |
---|---|
23 #include "lisp.h" | 23 #include "lisp.h" |
24 #include "macterm.h" | 24 #include "macterm.h" |
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 |
29 typedef ScrapRef Selection; | |
30 #else /* !TARGET_API_MAC_CARBON */ | |
31 #include <Scrap.h> | |
32 #include <Endian.h> | 29 #include <Endian.h> |
33 typedef int Selection; | 30 #endif |
34 #endif /* !TARGET_API_MAC_CARBON */ | 31 |
35 | |
36 static OSStatus mac_get_selection_from_symbol P_ ((Lisp_Object, int, | |
37 Selection *)); | |
38 static ScrapFlavorType get_flavor_type_from_symbol P_ ((Lisp_Object, | |
39 Selection)); | |
40 static int mac_valid_selection_target_p P_ ((Lisp_Object)); | |
41 static OSStatus mac_clear_selection P_ ((Selection *)); | |
42 static Lisp_Object mac_get_selection_ownership_info P_ ((Selection)); | |
43 static int mac_valid_selection_value_p P_ ((Lisp_Object, Lisp_Object)); | |
44 static OSStatus mac_put_selection_value P_ ((Selection, Lisp_Object, | |
45 Lisp_Object)); | |
46 static int mac_selection_has_target_p P_ ((Selection, Lisp_Object)); | |
47 static Lisp_Object mac_get_selection_value P_ ((Selection, Lisp_Object)); | |
48 static Lisp_Object mac_get_selection_target_list P_ ((Selection)); | |
49 static void x_own_selection P_ ((Lisp_Object, Lisp_Object)); | 32 static void x_own_selection P_ ((Lisp_Object, Lisp_Object)); |
50 static Lisp_Object x_get_local_selection P_ ((Lisp_Object, Lisp_Object, int)); | 33 static Lisp_Object x_get_local_selection P_ ((Lisp_Object, Lisp_Object, int)); |
51 static Lisp_Object x_get_foreign_selection P_ ((Lisp_Object, | 34 static Lisp_Object x_get_foreign_selection P_ ((Lisp_Object, |
52 Lisp_Object, | 35 Lisp_Object, |
53 Lisp_Object)); | 36 Lisp_Object)); |
54 EXFUN (Fx_selection_owner_p, 1); | |
55 #ifdef MAC_OSX | |
56 static OSStatus mac_handle_service_event P_ ((EventHandlerCallRef, | |
57 EventRef, void *)); | |
58 void init_service_handler P_ ((void)); | |
59 #endif | |
60 | 37 |
61 Lisp_Object QPRIMARY, QSECONDARY, QTIMESTAMP, QTARGETS; | 38 Lisp_Object QPRIMARY, QSECONDARY, QTIMESTAMP, QTARGETS; |
62 | 39 |
63 static Lisp_Object Vx_lost_selection_functions; | 40 static Lisp_Object Vx_lost_selection_functions; |
64 /* Coding system for communicating with other programs via selections. */ | 41 /* Coding system for communicating with other programs via selections. */ |
96 /* This is an alist whose CARs are selection-types and whose CDRs are | 73 /* This is an alist whose CARs are selection-types and whose CDRs are |
97 the names of Lisp functions to call to convert the given Emacs | 74 the names of Lisp functions to call to convert the given Emacs |
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. */ |
101 static Lisp_Object Vselection_converter_alist; | 78 Lisp_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'. */ |
106 static Lisp_Object Qmac_scrap_name, Qmac_ostype; | 83 Lisp_Object Qmac_scrap_name, Qmac_ostype; |
107 | 84 |
108 #ifdef MAC_OSX | |
109 /* Selection name for communication via Services menu. */ | |
110 static 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 | |
118 static OSStatus | |
119 mac_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 | |
160 static ScrapFlavorType | |
161 get_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 | |
196 static int | |
197 mac_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 | |
205 static OSStatus | |
206 mac_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 | |
229 static Lisp_Object | |
230 mac_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 | |
244 static int | |
245 mac_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 | |
254 static OSStatus | |
255 mac_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 | |
272 /* Check if data for the target type TARGET is available in SEL. */ | |
273 | |
274 static int | |
275 mac_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 | |
285 static Lisp_Object | |
286 mac_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 | |
338 static Lisp_Object | |
339 mac_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 |
400 our selection. */ | 88 our selection. */ |
401 | 89 |
890 | 578 |
891 /*********************************************************************** | 579 /*********************************************************************** |
892 Apple event support | 580 Apple event support |
893 ***********************************************************************/ | 581 ***********************************************************************/ |
894 int mac_ready_for_apple_events = 0; | 582 int mac_ready_for_apple_events = 0; |
895 static Lisp_Object Vmac_apple_event_map; | 583 Lisp_Object Vmac_apple_event_map; |
896 static Lisp_Object Qmac_apple_event_class, Qmac_apple_event_id; | 584 Lisp_Object Qmac_apple_event_class, Qmac_apple_event_id; |
897 static Lisp_Object Qemacs_suspension_id; | 585 static Lisp_Object Qemacs_suspension_id; |
898 extern Lisp_Object Qundefined; | 586 extern Lisp_Object Qundefined; |
899 extern void mac_store_apple_event P_ ((Lisp_Object, Lisp_Object, | 587 extern void mac_store_apple_event P_ ((Lisp_Object, Lisp_Object, |
900 const AEDesc *)); | 588 const AEDesc *)); |
901 | 589 |
1093 } | 781 } |
1094 | 782 |
1095 return err; | 783 return err; |
1096 } | 784 } |
1097 | 785 |
1098 static pascal OSErr | 786 pascal OSErr |
1099 mac_handle_apple_event (apple_event, reply, refcon) | 787 mac_handle_apple_event (apple_event, reply, refcon) |
1100 const AppleEvent *apple_event; | 788 const AppleEvent *apple_event; |
1101 AppleEvent *reply; | 789 AppleEvent *reply; |
1102 SInt32 refcon; | 790 SInt32 refcon; |
1103 { | 791 { |
1171 *head = p; | 859 *head = p; |
1172 | 860 |
1173 return nresumed; | 861 return nresumed; |
1174 } | 862 } |
1175 | 863 |
1176 static void | 864 void |
1177 cleanup_all_suspended_apple_events () | 865 cleanup_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 } | |
1182 | |
1183 void | |
1184 init_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 } | 869 } |
1209 | 870 |
1210 static UInt32 | 871 static UInt32 |
1211 get_suspension_id (apple_event) | 872 get_suspension_id (apple_event) |
1212 Lisp_Object apple_event; | 873 Lisp_Object apple_event; |
1397 | 1058 |
1398 /*********************************************************************** | 1059 /*********************************************************************** |
1399 Drag and drop support | 1060 Drag and drop support |
1400 ***********************************************************************/ | 1061 ***********************************************************************/ |
1401 #if TARGET_API_MAC_CARBON | 1062 #if TARGET_API_MAC_CARBON |
1402 static Lisp_Object Vmac_dnd_known_types; | 1063 Lisp_Object Vmac_dnd_known_types; |
1403 static pascal OSErr mac_do_track_drag P_ ((DragTrackingMessage, WindowRef, | |
1404 void *, DragRef)); | |
1405 static pascal OSErr mac_do_receive_drag P_ ((WindowRef, void *, DragRef)); | |
1406 static DragTrackingHandlerUPP mac_do_track_dragUPP = NULL; | |
1407 static DragReceiveHandlerUPP mac_do_receive_dragUPP = NULL; | |
1408 | |
1409 extern void mac_store_drag_event P_ ((WindowRef, Point, SInt16, | |
1410 const AEDesc *)); | |
1411 | |
1412 static pascal OSErr | |
1413 mac_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 | |
1501 static pascal OSErr | |
1502 mac_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 | |
1566 OSErr | |
1567 install_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 | |
1586 void | |
1587 remove_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 | 1065 |
1598 | 1066 |
1599 /*********************************************************************** | 1067 /*********************************************************************** |
1600 Services menu support | 1068 Services menu support |
1601 ***********************************************************************/ | 1069 ***********************************************************************/ |
1602 #ifdef MAC_OSX | 1070 #ifdef MAC_OSX |
1603 OSStatus | 1071 /* Selection name for communication via Services menu. */ |
1604 install_service_handler () | 1072 Lisp_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 | |
1618 extern OSStatus mac_store_service_event P_ ((EventRef)); | |
1619 | |
1620 static OSStatus | |
1621 copy_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 | |
1661 static OSStatus | |
1662 mac_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 ©_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 | |
1814 | 1074 |
1815 void | 1075 void |
1816 syms_of_macselect () | 1076 syms_of_macselect () |
1817 { | 1077 { |
1818 defsubr (&Sx_get_selection_internal); | 1078 defsubr (&Sx_get_selection_internal); |
1868 | 1128 |
1869 #if TARGET_API_MAC_CARBON | 1129 #if TARGET_API_MAC_CARBON |
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. |
1872 The types are chosen in the order they appear in the list. */); | 1132 The 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 |
1881 DEFVAR_LISP ("mac-service-selection", &Vmac_service_selection, | 1137 DEFVAR_LISP ("mac-service-selection", &Vmac_service_selection, |
1882 doc: /* Selection name for communication via Services menu. */); | 1138 doc: /* Selection name for communication via Services menu. */); |