259 |
|
|
260 |
|
|
261 |
/*********************************************************************** |
/*********************************************************************** |
262 |
|
Conversions on Apple event objects |
263 |
|
***********************************************************************/ |
264 |
|
|
265 |
|
static Lisp_Object Qundecoded_file_name; |
266 |
|
|
267 |
|
static Lisp_Object |
268 |
|
mac_aelist_to_lisp (desc_list) |
269 |
|
AEDescList *desc_list; |
270 |
|
{ |
271 |
|
OSErr err; |
272 |
|
long count; |
273 |
|
Lisp_Object result, elem; |
274 |
|
DescType desc_type; |
275 |
|
Size size; |
276 |
|
AEKeyword keyword; |
277 |
|
AEDesc desc; |
278 |
|
|
279 |
|
err = AECountItems (desc_list, &count); |
280 |
|
if (err != noErr) |
281 |
|
return Qnil; |
282 |
|
result = Qnil; |
283 |
|
while (count > 0) |
284 |
|
{ |
285 |
|
err = AESizeOfNthItem (desc_list, count, &desc_type, &size); |
286 |
|
if (err == noErr) |
287 |
|
switch (desc_type) |
288 |
|
{ |
289 |
|
case typeAEList: |
290 |
|
case typeAERecord: |
291 |
|
case typeAppleEvent: |
292 |
|
err = AEGetNthDesc (desc_list, count, typeWildCard, |
293 |
|
&keyword, &desc); |
294 |
|
if (err != noErr) |
295 |
|
break; |
296 |
|
elem = mac_aelist_to_lisp (&desc); |
297 |
|
AEDisposeDesc (&desc); |
298 |
|
break; |
299 |
|
|
300 |
|
default: |
301 |
|
if (desc_type == typeNull) |
302 |
|
elem = Qnil; |
303 |
|
else |
304 |
|
{ |
305 |
|
elem = make_uninit_string (size); |
306 |
|
err = AEGetNthPtr (desc_list, count, typeWildCard, &keyword, |
307 |
|
&desc_type, SDATA (elem), size, &size); |
308 |
|
} |
309 |
|
if (err != noErr) |
310 |
|
break; |
311 |
|
desc_type = EndianU32_NtoB (desc_type); |
312 |
|
elem = Fcons (make_unibyte_string ((char *) &desc_type, 4), elem); |
313 |
|
break; |
314 |
|
} |
315 |
|
|
316 |
|
if (err != noErr) |
317 |
|
elem = Qnil; |
318 |
|
else if (desc_list->descriptorType != typeAEList) |
319 |
|
{ |
320 |
|
keyword = EndianU32_NtoB (keyword); |
321 |
|
elem = Fcons (make_unibyte_string ((char *) &keyword, 4), elem); |
322 |
|
} |
323 |
|
|
324 |
|
result = Fcons (elem, result); |
325 |
|
count--; |
326 |
|
} |
327 |
|
|
328 |
|
desc_type = EndianU32_NtoB (desc_list->descriptorType); |
329 |
|
return Fcons (make_unibyte_string ((char *) &desc_type, 4), result); |
330 |
|
} |
331 |
|
|
332 |
|
Lisp_Object |
333 |
|
mac_aedesc_to_lisp (desc) |
334 |
|
AEDesc *desc; |
335 |
|
{ |
336 |
|
OSErr err; |
337 |
|
DescType desc_type = desc->descriptorType; |
338 |
|
Lisp_Object result; |
339 |
|
|
340 |
|
switch (desc_type) |
341 |
|
{ |
342 |
|
case typeNull: |
343 |
|
result = Qnil; |
344 |
|
break; |
345 |
|
|
346 |
|
case typeAEList: |
347 |
|
case typeAERecord: |
348 |
|
case typeAppleEvent: |
349 |
|
return mac_aelist_to_lisp (desc); |
350 |
|
#if 0 |
351 |
|
/* The following one is much simpler, but creates and disposes |
352 |
|
of Apple event descriptors many times. */ |
353 |
|
{ |
354 |
|
long count; |
355 |
|
Lisp_Object elem; |
356 |
|
AEKeyword keyword; |
357 |
|
AEDesc desc1; |
358 |
|
|
359 |
|
err = AECountItems (desc, &count); |
360 |
|
if (err != noErr) |
361 |
|
break; |
362 |
|
result = Qnil; |
363 |
|
while (count > 0) |
364 |
|
{ |
365 |
|
err = AEGetNthDesc (desc, count, typeWildCard, &keyword, &desc1); |
366 |
|
if (err != noErr) |
367 |
|
break; |
368 |
|
elem = mac_aedesc_to_lisp (&desc1); |
369 |
|
AEDisposeDesc (&desc1); |
370 |
|
if (desc_type != typeAEList) |
371 |
|
{ |
372 |
|
keyword = EndianU32_NtoB (keyword); |
373 |
|
elem = Fcons (make_unibyte_string ((char *) &keyword, 4), elem); |
374 |
|
} |
375 |
|
result = Fcons (elem, result); |
376 |
|
count--; |
377 |
|
} |
378 |
|
} |
379 |
|
#endif |
380 |
|
break; |
381 |
|
|
382 |
|
default: |
383 |
|
#if TARGET_API_MAC_CARBON |
384 |
|
result = make_uninit_string (AEGetDescDataSize (desc)); |
385 |
|
err = AEGetDescData (desc, SDATA (result), SBYTES (result)); |
386 |
|
#else |
387 |
|
result = make_uninit_string (GetHandleSize (desc->dataHandle)); |
388 |
|
memcpy (SDATA (result), *(desc->dataHandle), SBYTES (result)); |
389 |
|
#endif |
390 |
|
break; |
391 |
|
} |
392 |
|
|
393 |
|
if (err != noErr) |
394 |
|
return Qnil; |
395 |
|
|
396 |
|
desc_type = EndianU32_NtoB (desc_type); |
397 |
|
return Fcons (make_unibyte_string ((char *) &desc_type, 4), result); |
398 |
|
} |
399 |
|
|
400 |
|
#if TARGET_API_MAC_CARBON |
401 |
|
OSErr |
402 |
|
create_apple_event_from_event_ref (event, num_params, names, |
403 |
|
types, sizes, result) |
404 |
|
EventRef event; |
405 |
|
UInt32 num_params; |
406 |
|
EventParamName *names; |
407 |
|
EventParamType *types; |
408 |
|
UInt32 *sizes; |
409 |
|
AppleEvent *result; |
410 |
|
{ |
411 |
|
OSErr err; |
412 |
|
static const ProcessSerialNumber psn = {0, kCurrentProcess}; |
413 |
|
AEAddressDesc address_desc; |
414 |
|
UInt32 i; |
415 |
|
CFStringRef string; |
416 |
|
CFDataRef data; |
417 |
|
char *buf; |
418 |
|
|
419 |
|
err = AECreateDesc (typeProcessSerialNumber, &psn, |
420 |
|
sizeof (ProcessSerialNumber), &address_desc); |
421 |
|
if (err == noErr) |
422 |
|
{ |
423 |
|
err = AECreateAppleEvent (0, 0, /* Dummy class and ID. */ |
424 |
|
&address_desc, /* NULL is not allowed |
425 |
|
on Mac OS Classic. */ |
426 |
|
kAutoGenerateReturnID, |
427 |
|
kAnyTransactionID, result); |
428 |
|
AEDisposeDesc (&address_desc); |
429 |
|
} |
430 |
|
if (err != noErr) |
431 |
|
return err; |
432 |
|
|
433 |
|
for (i = 0; i < num_params; i++) |
434 |
|
switch (types[i]) |
435 |
|
{ |
436 |
|
#ifdef MAC_OSX |
437 |
|
case typeCFStringRef: |
438 |
|
err = GetEventParameter (event, names[i], typeCFStringRef, NULL, |
439 |
|
sizeof (CFStringRef), NULL, &string); |
440 |
|
if (err != noErr) |
441 |
|
break; |
442 |
|
data = CFStringCreateExternalRepresentation (NULL, string, |
443 |
|
kCFStringEncodingUTF8, |
444 |
|
'?'); |
445 |
|
if (data == NULL) |
446 |
|
break; |
447 |
|
/* typeUTF8Text is not available on Mac OS X 10.1. */ |
448 |
|
AEPutParamPtr (result, names[i], 'utf8', |
449 |
|
CFDataGetBytePtr (data), CFDataGetLength (data)); |
450 |
|
CFRelease (data); |
451 |
|
break; |
452 |
|
#endif |
453 |
|
|
454 |
|
default: |
455 |
|
buf = xmalloc (sizes[i]); |
456 |
|
if (buf == NULL) |
457 |
|
break; |
458 |
|
err = GetEventParameter (event, names[i], types[i], NULL, |
459 |
|
sizes[i], NULL, buf); |
460 |
|
if (err == noErr) |
461 |
|
AEPutParamPtr (result, names[i], types[i], buf, sizes[i]); |
462 |
|
xfree (buf); |
463 |
|
break; |
464 |
|
} |
465 |
|
|
466 |
|
return noErr; |
467 |
|
} |
468 |
|
#endif |
469 |
|
|
470 |
|
|
471 |
|
/*********************************************************************** |
472 |
Conversion between Lisp and Core Foundation objects |
Conversion between Lisp and Core Foundation objects |
473 |
***********************************************************************/ |
***********************************************************************/ |
474 |
|
|
4097 |
} |
} |
4098 |
|
|
4099 |
|
|
4100 |
|
DEFUN ("mac-coerce-ae-data", Fmac_coerce_ae_data, Smac_coerce_ae_data, 3, 3, 0, |
4101 |
|
doc: /* Coerce Apple event data SRC-DATA of type SRC-TYPE to DST-TYPE. |
4102 |
|
Each type should be a string of length 4 or the symbol |
4103 |
|
`undecoded-file-name'. */) |
4104 |
|
(src_type, src_data, dst_type) |
4105 |
|
Lisp_Object src_type, src_data, dst_type; |
4106 |
|
{ |
4107 |
|
OSErr err; |
4108 |
|
Lisp_Object result = Qnil; |
4109 |
|
DescType src_desc_type, dst_desc_type; |
4110 |
|
AEDesc dst_desc; |
4111 |
|
#ifdef MAC_OSX |
4112 |
|
FSRef fref; |
4113 |
|
#else |
4114 |
|
FSSpec fs; |
4115 |
|
#endif |
4116 |
|
|
4117 |
|
CHECK_STRING (src_data); |
4118 |
|
if (EQ (src_type, Qundecoded_file_name)) |
4119 |
|
{ |
4120 |
|
#ifdef MAC_OSX |
4121 |
|
src_desc_type = typeFileURL; |
4122 |
|
#else |
4123 |
|
src_desc_type = typeFSS; |
4124 |
|
#endif |
4125 |
|
} |
4126 |
|
else |
4127 |
|
src_desc_type = mac_get_code_from_arg (src_type, 0); |
4128 |
|
|
4129 |
|
if (EQ (dst_type, Qundecoded_file_name)) |
4130 |
|
{ |
4131 |
|
#ifdef MAC_OSX |
4132 |
|
dst_desc_type = typeFSRef; |
4133 |
|
#else |
4134 |
|
dst_desc_type = typeFSS; |
4135 |
|
#endif |
4136 |
|
} |
4137 |
|
else |
4138 |
|
dst_desc_type = mac_get_code_from_arg (dst_type, 0); |
4139 |
|
|
4140 |
|
BLOCK_INPUT; |
4141 |
|
if (EQ (src_type, Qundecoded_file_name)) |
4142 |
|
{ |
4143 |
|
#ifdef MAC_OSX |
4144 |
|
CFStringRef str; |
4145 |
|
CFURLRef url = NULL; |
4146 |
|
CFDataRef data = NULL; |
4147 |
|
|
4148 |
|
str = cfstring_create_with_utf8_cstring (SDATA (src_data)); |
4149 |
|
if (str) |
4150 |
|
{ |
4151 |
|
url = CFURLCreateWithFileSystemPath (NULL, str, |
4152 |
|
kCFURLPOSIXPathStyle, false); |
4153 |
|
CFRelease (str); |
4154 |
|
} |
4155 |
|
if (url) |
4156 |
|
{ |
4157 |
|
data = CFURLCreateData (NULL, url, kCFStringEncodingUTF8, true); |
4158 |
|
CFRelease (url); |
4159 |
|
} |
4160 |
|
if (data) |
4161 |
|
err = AECoercePtr (src_desc_type, CFDataGetBytePtr (data), |
4162 |
|
CFDataGetLength (data), |
4163 |
|
dst_desc_type, &dst_desc); |
4164 |
|
else |
4165 |
|
err = memFullErr; |
4166 |
|
#else |
4167 |
|
err = posix_pathname_to_fsspec (SDATA (src_data), &fs); |
4168 |
|
if (err == noErr) |
4169 |
|
AECoercePtr (src_desc_type, &fs, sizeof (FSSpec), |
4170 |
|
dst_desc_type, &dst_desc); |
4171 |
|
#endif |
4172 |
|
} |
4173 |
|
else |
4174 |
|
err = AECoercePtr (src_desc_type, SDATA (src_data), SBYTES (src_data), |
4175 |
|
dst_desc_type, &dst_desc); |
4176 |
|
|
4177 |
|
if (err == noErr) |
4178 |
|
{ |
4179 |
|
if (EQ (dst_type, Qundecoded_file_name)) |
4180 |
|
{ |
4181 |
|
char file_name[MAXPATHLEN]; |
4182 |
|
|
4183 |
|
#ifdef MAC_OSX |
4184 |
|
err = AEGetDescData (&dst_desc, &fref, sizeof (FSRef)); |
4185 |
|
if (err == noErr) |
4186 |
|
err = FSRefMakePath (&fref, file_name, sizeof (file_name)); |
4187 |
|
#else |
4188 |
|
#if TARGET_API_MAC_CARBON |
4189 |
|
err = AEGetDescData (&dst_desc, &fs, sizeof (FSSpec)); |
4190 |
|
#else |
4191 |
|
memcpy (&fs, *(dst_desc.dataHandle), sizeof (FSSpec)); |
4192 |
|
#endif |
4193 |
|
if (err == noErr) |
4194 |
|
err = fsspec_to_posix_pathname (&fs, file_name, |
4195 |
|
sizeof (file_name) - 1); |
4196 |
|
#endif |
4197 |
|
if (err == noErr) |
4198 |
|
result = make_unibyte_string (file_name, strlen (file_name)); |
4199 |
|
} |
4200 |
|
else |
4201 |
|
result = Fcdr (mac_aedesc_to_lisp (&dst_desc)); |
4202 |
|
AEDisposeDesc (&dst_desc); |
4203 |
|
} |
4204 |
|
UNBLOCK_INPUT; |
4205 |
|
|
4206 |
|
return result; |
4207 |
|
} |
4208 |
|
|
4209 |
|
|
4210 |
#if TARGET_API_MAC_CARBON |
#if TARGET_API_MAC_CARBON |
4211 |
static Lisp_Object Qxml, Qmime_charset; |
static Lisp_Object Qxml, Qmime_charset; |
4212 |
static Lisp_Object QNFD, QNFKD, QNFC, QNFKC, QHFS_plus_D, QHFS_plus_C; |
static Lisp_Object QNFD, QNFKD, QNFC, QNFKC, QHFS_plus_D, QHFS_plus_C; |
4996 |
void |
void |
4997 |
syms_of_mac () |
syms_of_mac () |
4998 |
{ |
{ |
4999 |
|
Qundecoded_file_name = intern ("undecoded-file-name"); |
5000 |
|
staticpro (&Qundecoded_file_name); |
5001 |
|
|
5002 |
#if TARGET_API_MAC_CARBON |
#if TARGET_API_MAC_CARBON |
5003 |
Qstring = intern ("string"); staticpro (&Qstring); |
Qstring = intern ("string"); staticpro (&Qstring); |
5004 |
Qnumber = intern ("number"); staticpro (&Qnumber); |
Qnumber = intern ("number"); staticpro (&Qnumber); |
5022 |
QHFS_plus_C = intern ("HFS+C"); staticpro (&QHFS_plus_C); |
QHFS_plus_C = intern ("HFS+C"); staticpro (&QHFS_plus_C); |
5023 |
#endif |
#endif |
5024 |
|
|
5025 |
|
defsubr (&Smac_coerce_ae_data); |
5026 |
#if TARGET_API_MAC_CARBON |
#if TARGET_API_MAC_CARBON |
5027 |
defsubr (&Smac_get_preference); |
defsubr (&Smac_get_preference); |
5028 |
defsubr (&Smac_code_convert_string); |
defsubr (&Smac_code_convert_string); |