Commit 31b6888a authored by YAMAMOTO Mitsuharu's avatar YAMAMOTO Mitsuharu
Browse files

(Qundecoded_file_name): New variable.

(syms_of_mac): Initialize it.
(mac_aelist_to_lisp, mac_aedesc_to_lisp): New functions.
[TARGET_API_MAC_CARBON] (create_apple_event_from_event_ref): New
function.
(Fmac_coerce_ae_data): New defun.
(syms_of_mac): Defsubr it.
parent f66c49cc
......@@ -257,6 +257,216 @@ posix_to_mac_pathname (const char *ufn, char *mfn, int mfnbuflen)
return 1;
}
/***********************************************************************
Conversions on Apple event objects
***********************************************************************/
static Lisp_Object Qundecoded_file_name;
static Lisp_Object
mac_aelist_to_lisp (desc_list)
AEDescList *desc_list;
{
OSErr err;
long count;
Lisp_Object result, elem;
DescType desc_type;
Size size;
AEKeyword keyword;
AEDesc desc;
err = AECountItems (desc_list, &count);
if (err != noErr)
return Qnil;
result = Qnil;
while (count > 0)
{
err = AESizeOfNthItem (desc_list, count, &desc_type, &size);
if (err == noErr)
switch (desc_type)
{
case typeAEList:
case typeAERecord:
case typeAppleEvent:
err = AEGetNthDesc (desc_list, count, typeWildCard,
&keyword, &desc);
if (err != noErr)
break;
elem = mac_aelist_to_lisp (&desc);
AEDisposeDesc (&desc);
break;
default:
if (desc_type == typeNull)
elem = Qnil;
else
{
elem = make_uninit_string (size);
err = AEGetNthPtr (desc_list, count, typeWildCard, &keyword,
&desc_type, SDATA (elem), size, &size);
}
if (err != noErr)
break;
desc_type = EndianU32_NtoB (desc_type);
elem = Fcons (make_unibyte_string ((char *) &desc_type, 4), elem);
break;
}
if (err != noErr)
elem = Qnil;
else if (desc_list->descriptorType != typeAEList)
{
keyword = EndianU32_NtoB (keyword);
elem = Fcons (make_unibyte_string ((char *) &keyword, 4), elem);
}
result = Fcons (elem, result);
count--;
}
desc_type = EndianU32_NtoB (desc_list->descriptorType);
return Fcons (make_unibyte_string ((char *) &desc_type, 4), result);
}
Lisp_Object
mac_aedesc_to_lisp (desc)
AEDesc *desc;
{
OSErr err;
DescType desc_type = desc->descriptorType;
Lisp_Object result;
switch (desc_type)
{
case typeNull:
result = Qnil;
break;
case typeAEList:
case typeAERecord:
case typeAppleEvent:
return mac_aelist_to_lisp (desc);
#if 0
/* The following one is much simpler, but creates and disposes
of Apple event descriptors many times. */
{
long count;
Lisp_Object elem;
AEKeyword keyword;
AEDesc desc1;
err = AECountItems (desc, &count);
if (err != noErr)
break;
result = Qnil;
while (count > 0)
{
err = AEGetNthDesc (desc, count, typeWildCard, &keyword, &desc1);
if (err != noErr)
break;
elem = mac_aedesc_to_lisp (&desc1);
AEDisposeDesc (&desc1);
if (desc_type != typeAEList)
{
keyword = EndianU32_NtoB (keyword);
elem = Fcons (make_unibyte_string ((char *) &keyword, 4), elem);
}
result = Fcons (elem, result);
count--;
}
}
#endif
break;
default:
#if TARGET_API_MAC_CARBON
result = make_uninit_string (AEGetDescDataSize (desc));
err = AEGetDescData (desc, SDATA (result), SBYTES (result));
#else
result = make_uninit_string (GetHandleSize (desc->dataHandle));
memcpy (SDATA (result), *(desc->dataHandle), SBYTES (result));
#endif
break;
}
if (err != noErr)
return Qnil;
desc_type = EndianU32_NtoB (desc_type);
return Fcons (make_unibyte_string ((char *) &desc_type, 4), result);
}
#if TARGET_API_MAC_CARBON
OSErr
create_apple_event_from_event_ref (event, num_params, names,
types, sizes, result)
EventRef event;
UInt32 num_params;
EventParamName *names;
EventParamType *types;
UInt32 *sizes;
AppleEvent *result;
{
OSErr err;
static const ProcessSerialNumber psn = {0, kCurrentProcess};
AEAddressDesc address_desc;
UInt32 i;
CFStringRef string;
CFDataRef data;
char *buf;
err = AECreateDesc (typeProcessSerialNumber, &psn,
sizeof (ProcessSerialNumber), &address_desc);
if (err == noErr)
{
err = AECreateAppleEvent (0, 0, /* Dummy class and ID. */
&address_desc, /* NULL is not allowed
on Mac OS Classic. */
kAutoGenerateReturnID,
kAnyTransactionID, result);
AEDisposeDesc (&address_desc);
}
if (err != noErr)
return err;
for (i = 0; i < num_params; i++)
switch (types[i])
{
#ifdef MAC_OSX
case typeCFStringRef:
err = GetEventParameter (event, names[i], typeCFStringRef, NULL,
sizeof (CFStringRef), NULL, &string);
if (err != noErr)
break;
data = CFStringCreateExternalRepresentation (NULL, string,
kCFStringEncodingUTF8,
'?');
if (data == NULL)
break;
/* typeUTF8Text is not available on Mac OS X 10.1. */
AEPutParamPtr (result, names[i], 'utf8',
CFDataGetBytePtr (data), CFDataGetLength (data));
CFRelease (data);
break;
#endif
default:
buf = xmalloc (sizes[i]);
if (buf == NULL)
break;
err = GetEventParameter (event, names[i], types[i], NULL,
sizes[i], NULL, buf);
if (err == noErr)
AEPutParamPtr (result, names[i], types[i], buf, sizes[i]);
xfree (buf);
break;
}
return noErr;
}
#endif
/***********************************************************************
Conversion between Lisp and Core Foundation objects
......@@ -3887,6 +4097,116 @@ DEFUN ("posix-file-name-to-mac", Fposix_file_name_to_mac,
}
DEFUN ("mac-coerce-ae-data", Fmac_coerce_ae_data, Smac_coerce_ae_data, 3, 3, 0,
doc: /* Coerce Apple event data SRC-DATA of type SRC-TYPE to DST-TYPE.
Each type should be a string of length 4 or the symbol
`undecoded-file-name'. */)
(src_type, src_data, dst_type)
Lisp_Object src_type, src_data, dst_type;
{
OSErr err;
Lisp_Object result = Qnil;
DescType src_desc_type, dst_desc_type;
AEDesc dst_desc;
#ifdef MAC_OSX
FSRef fref;
#else
FSSpec fs;
#endif
CHECK_STRING (src_data);
if (EQ (src_type, Qundecoded_file_name))
{
#ifdef MAC_OSX
src_desc_type = typeFileURL;
#else
src_desc_type = typeFSS;
#endif
}
else
src_desc_type = mac_get_code_from_arg (src_type, 0);
if (EQ (dst_type, Qundecoded_file_name))
{
#ifdef MAC_OSX
dst_desc_type = typeFSRef;
#else
dst_desc_type = typeFSS;
#endif
}
else
dst_desc_type = mac_get_code_from_arg (dst_type, 0);
BLOCK_INPUT;
if (EQ (src_type, Qundecoded_file_name))
{
#ifdef MAC_OSX
CFStringRef str;
CFURLRef url = NULL;
CFDataRef data = NULL;
str = cfstring_create_with_utf8_cstring (SDATA (src_data));
if (str)
{
url = CFURLCreateWithFileSystemPath (NULL, str,
kCFURLPOSIXPathStyle, false);
CFRelease (str);
}
if (url)
{
data = CFURLCreateData (NULL, url, kCFStringEncodingUTF8, true);
CFRelease (url);
}
if (data)
err = AECoercePtr (src_desc_type, CFDataGetBytePtr (data),
CFDataGetLength (data),
dst_desc_type, &dst_desc);
else
err = memFullErr;
#else
err = posix_pathname_to_fsspec (SDATA (src_data), &fs);
if (err == noErr)
AECoercePtr (src_desc_type, &fs, sizeof (FSSpec),
dst_desc_type, &dst_desc);
#endif
}
else
err = AECoercePtr (src_desc_type, SDATA (src_data), SBYTES (src_data),
dst_desc_type, &dst_desc);
if (err == noErr)
{
if (EQ (dst_type, Qundecoded_file_name))
{
char file_name[MAXPATHLEN];
#ifdef MAC_OSX
err = AEGetDescData (&dst_desc, &fref, sizeof (FSRef));
if (err == noErr)
err = FSRefMakePath (&fref, file_name, sizeof (file_name));
#else
#if TARGET_API_MAC_CARBON
err = AEGetDescData (&dst_desc, &fs, sizeof (FSSpec));
#else
memcpy (&fs, *(dst_desc.dataHandle), sizeof (FSSpec));
#endif
if (err == noErr)
err = fsspec_to_posix_pathname (&fs, file_name,
sizeof (file_name) - 1);
#endif
if (err == noErr)
result = make_unibyte_string (file_name, strlen (file_name));
}
else
result = Fcdr (mac_aedesc_to_lisp (&dst_desc));
AEDisposeDesc (&dst_desc);
}
UNBLOCK_INPUT;
return result;
}
#if TARGET_API_MAC_CARBON
static Lisp_Object Qxml, Qmime_charset;
static Lisp_Object QNFD, QNFKD, QNFC, QNFKC, QHFS_plus_D, QHFS_plus_C;
......@@ -4676,6 +4996,9 @@ init_mac_osx_environment ()
void
syms_of_mac ()
{
Qundecoded_file_name = intern ("undecoded-file-name");
staticpro (&Qundecoded_file_name);
#if TARGET_API_MAC_CARBON
Qstring = intern ("string"); staticpro (&Qstring);
Qnumber = intern ("number"); staticpro (&Qnumber);
......@@ -4699,6 +5022,7 @@ syms_of_mac ()
QHFS_plus_C = intern ("HFS+C"); staticpro (&QHFS_plus_C);
#endif
defsubr (&Smac_coerce_ae_data);
#if TARGET_API_MAC_CARBON
defsubr (&Smac_get_preference);
defsubr (&Smac_code_convert_string);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment