/* Unix emulation routines for GNU Emacs on the Mac OS.
Copyright (C) 2000, 2001, 2002, 2003, 2004,
- 2005 Free Software Foundation, Inc.
+ 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Emacs.
/* The single script context used for all script executions. */
static OSAID as_script_context;
+static OSErr posix_pathname_to_fsspec P_ ((const char *, FSSpec *));
+static OSErr fsspec_to_posix_pathname P_ ((const FSSpec *, char *, int));
/* When converting from Mac to Unix pathnames, /'s in folder names are
converted to :'s. This function, used in copying folder names,
}
\f
+/***********************************************************************
+ 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 = noErr;
+ 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);
+}
+
+static pascal OSErr
+mac_coerce_file_name_ptr (type_code, data_ptr, data_size,
+ to_type, handler_refcon, result)
+ DescType type_code;
+ const void *data_ptr;
+ Size data_size;
+ DescType to_type;
+ long handler_refcon;
+ AEDesc *result;
+{
+ OSErr err;
+
+ if (type_code == typeNull)
+ err = errAECoercionFail;
+ else if (type_code == to_type || to_type == typeWildCard)
+ err = AECreateDesc (TYPE_FILE_NAME, data_ptr, data_size, result);
+ else if (type_code == TYPE_FILE_NAME)
+ /* Coercion from undecoded file name. */
+ {
+#ifdef MAC_OSX
+ CFStringRef str;
+ CFURLRef url = NULL;
+ CFDataRef data = NULL;
+
+ str = CFStringCreateWithBytes (NULL, data_ptr, data_size,
+ kCFStringEncodingUTF8, false);
+ if (str)
+ {
+ url = CFURLCreateWithFileSystemPath (NULL, str,
+ kCFURLPOSIXPathStyle, false);
+ CFRelease (str);
+ }
+ if (url)
+ {
+ data = CFURLCreateData (NULL, url, kCFStringEncodingUTF8, true);
+ CFRelease (url);
+ }
+ if (data)
+ {
+ err = AECoercePtr (typeFileURL, CFDataGetBytePtr (data),
+ CFDataGetLength (data), to_type, result);
+ CFRelease (data);
+ }
+ else
+ err = memFullErr;
+#else
+ FSSpec fs;
+ char *buf;
+
+ buf = xmalloc (data_size + 1);
+ if (buf)
+ {
+ memcpy (buf, data_ptr, data_size);
+ buf[data_size] = '\0';
+ err = posix_pathname_to_fsspec (buf, &fs);
+ xfree (buf);
+ }
+ else
+ err = memFullErr;
+ if (err == noErr)
+ err = AECoercePtr (typeFSS, &fs, sizeof (FSSpec), to_type, result);
+#endif
+ }
+ else if (to_type == TYPE_FILE_NAME)
+ /* Coercion to undecoded file name. */
+ {
+#ifdef MAC_OSX
+ CFURLRef url = NULL;
+ CFStringRef str = NULL;
+ CFDataRef data = NULL;
+
+ if (type_code == typeFileURL)
+ url = CFURLCreateWithBytes (NULL, data_ptr, data_size,
+ kCFStringEncodingUTF8, NULL);
+ else
+ {
+ AEDesc desc;
+ Size size;
+ char *buf;
+
+ err = AECoercePtr (type_code, data_ptr, data_size,
+ typeFileURL, &desc);
+ if (err == noErr)
+ {
+ size = AEGetDescDataSize (&desc);
+ buf = xmalloc (size);
+ if (buf)
+ {
+ err = AEGetDescData (&desc, buf, size);
+ if (err == noErr)
+ url = CFURLCreateWithBytes (NULL, buf, size,
+ kCFStringEncodingUTF8, NULL);
+ xfree (buf);
+ }
+ AEDisposeDesc (&desc);
+ }
+ }
+ if (url)
+ {
+ str = CFURLCopyFileSystemPath (url, kCFURLPOSIXPathStyle);
+ CFRelease (url);
+ }
+ if (str)
+ {
+ data = CFStringCreateExternalRepresentation (NULL, str,
+ kCFStringEncodingUTF8,
+ '\0');
+ CFRelease (str);
+ }
+ if (data)
+ {
+ err = AECreateDesc (TYPE_FILE_NAME, CFDataGetBytePtr (data),
+ CFDataGetLength (data), result);
+ CFRelease (data);
+ }
+#else
+ char file_name[MAXPATHLEN];
+
+ if (type_code == typeFSS && data_size == sizeof (FSSpec))
+ err = fsspec_to_posix_pathname (data_ptr, file_name,
+ sizeof (file_name) - 1);
+ else
+ {
+ AEDesc desc;
+ FSSpec fs;
+
+ err = AECoercePtr (type_code, data_ptr, data_size, typeFSS, &desc);
+ if (err == noErr)
+ {
+#if TARGET_API_MAC_CARBON
+ err = AEGetDescData (&desc, &fs, sizeof (FSSpec));
+#else
+ fs = *(FSSpec *)(*(desc.dataHandle));
+#endif
+ if (err == noErr)
+ err = fsspec_to_posix_pathname (&fs, file_name,
+ sizeof (file_name) - 1);
+ AEDisposeDesc (&desc);
+ }
+ }
+ if (err == noErr)
+ err = AECreateDesc (TYPE_FILE_NAME, file_name,
+ strlen (file_name), result);
+#endif
+ }
+ else
+ abort ();
+
+ if (err != noErr)
+ return errAECoercionFail;
+ return noErr;
+}
+
+static pascal OSErr
+mac_coerce_file_name_desc (from_desc, to_type, handler_refcon, result)
+ const AEDesc *from_desc;
+ DescType to_type;
+ long handler_refcon;
+ AEDesc *result;
+{
+ OSErr err = noErr;
+ DescType from_type = from_desc->descriptorType;
+
+ if (from_type == typeNull)
+ err = errAECoercionFail;
+ else if (from_type == to_type || to_type == typeWildCard)
+ err = AEDuplicateDesc (from_desc, result);
+ else
+ {
+ char *data_ptr;
+ Size data_size;
+
+#if TARGET_API_MAC_CARBON
+ data_size = AEGetDescDataSize (from_desc);
+#else
+ data_size = GetHandleSize (from_desc->dataHandle);
+#endif
+ data_ptr = xmalloc (data_size);
+ if (data_ptr)
+ {
+#if TARGET_API_MAC_CARBON
+ err = AEGetDescData (from_desc, data_ptr, data_size);
+#else
+ memcpy (data_ptr, *(from_desc->dataHandle), data_size);
+#endif
+ if (err == noErr)
+ err = mac_coerce_file_name_ptr (from_type, data_ptr,
+ data_size, to_type,
+ handler_refcon, result);
+ xfree (data_ptr);
+ }
+ else
+ err = memFullErr;
+ }
+
+ if (err != noErr)
+ return errAECoercionFail;
+ return noErr;
+}
+
+OSErr
+init_coercion_handler ()
+{
+ OSErr err;
+
+ static AECoercePtrUPP coerce_file_name_ptrUPP = NULL;
+ static AECoerceDescUPP coerce_file_name_descUPP = NULL;
+
+ if (coerce_file_name_ptrUPP == NULL)
+ {
+ coerce_file_name_ptrUPP = NewAECoercePtrUPP (mac_coerce_file_name_ptr);
+ coerce_file_name_descUPP = NewAECoerceDescUPP (mac_coerce_file_name_desc);
+ }
+
+ err = AEInstallCoercionHandler (TYPE_FILE_NAME, typeWildCard,
+ (AECoercionHandlerUPP)
+ coerce_file_name_ptrUPP, 0, false, false);
+ if (err == noErr)
+ err = AEInstallCoercionHandler (typeWildCard, TYPE_FILE_NAME,
+ (AECoercionHandlerUPP)
+ coerce_file_name_ptrUPP, 0, false, false);
+ if (err == noErr)
+ err = AEInstallCoercionHandler (TYPE_FILE_NAME, typeWildCard,
+ coerce_file_name_descUPP, 0, true, false);
+ if (err == noErr)
+ err = AEInstallCoercionHandler (typeWildCard, TYPE_FILE_NAME,
+ coerce_file_name_descUPP, 0, true, false);
+ return err;
+}
+
+#if TARGET_API_MAC_CARBON
+OSErr
+create_apple_event_from_event_ref (event, num_params, names, types, result)
+ EventRef event;
+ UInt32 num_params;
+ EventParamName *names;
+ EventParamType *types;
+ AppleEvent *result;
+{
+ OSErr err;
+ static const ProcessSerialNumber psn = {0, kCurrentProcess};
+ AEAddressDesc address_desc;
+ UInt32 i, size;
+ 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:
+ err = GetEventParameter (event, names[i], types[i], NULL,
+ 0, &size, NULL);
+ if (err != noErr)
+ break;
+ buf = xmalloc (size);
+ if (buf == NULL)
+ break;
+ err = GetEventParameter (event, names[i], types[i], NULL,
+ size, NULL, buf);
+ if (err == noErr)
+ AEPutParamPtr (result, names[i], types[i], buf, size);
+ xfree (buf);
+ break;
+ }
+
+ return noErr;
+}
+#endif
+
+\f
/***********************************************************************
Conversion between Lisp and Core Foundation objects
***********************************************************************/
#if TARGET_API_MAC_CARBON
static Lisp_Object Qstring, Qnumber, Qboolean, Qdate, Qdata;
static Lisp_Object Qarray, Qdictionary;
-#define DECODE_UTF_8(str) code_convert_string_norecord (str, Qutf_8, 0)
struct cfdict_context
{
}
-/* From CFString to a lisp string. Never returns a unibyte string
- (even if it only contains ASCII characters).
- This may cause GC during code conversion. */
+/* From CFString to a lisp string. Returns a unibyte string
+ containing a UTF-8 byte sequence. */
Lisp_Object
-cfstring_to_lisp (string)
+cfstring_to_lisp_nodecode (string)
CFStringRef string;
{
Lisp_Object result = Qnil;
}
}
+ return result;
+}
+
+
+/* From CFString to a lisp string. Never returns a unibyte string
+ (even if it only contains ASCII characters).
+ This may cause GC during code conversion. */
+
+Lisp_Object
+cfstring_to_lisp (string)
+ CFStringRef string;
+{
+ Lisp_Object result = cfstring_to_lisp_nodecode (string);
+
if (!NILP (result))
{
- result = DECODE_UTF_8 (result);
+ result = code_convert_string_norecord (result, Qutf_8, 0);
/* This may be superfluous. Just to make sure that the result
is a multibyte string. */
result = string_to_multibyte (result);
implemented as a hash table that maps a pair (SRC-NODE-ID .
EDGE-LABEL) to DEST-NODE-ID. It also holds a maximum node id used
in the table as a value for HASHKEY_MAX_NID. A value associated to
- a node is recorded as a value for the node id. */
+ a node is recorded as a value for the node id.
+
+ A database also has a cache for past queries as a value for
+ HASHKEY_QUERY_CACHE. It is another hash table that maps
+ "NAME-STRING\0CLASS-STRING" to the result of the query. */
#define HASHKEY_MAX_NID (make_number (0))
+#define HASHKEY_QUERY_CACHE (make_number (-1))
static XrmDatabase
xrm_create_database ()
make_float (DEFAULT_REHASH_THRESHOLD),
Qnil, Qnil, Qnil);
Fputhash (HASHKEY_MAX_NID, make_number (0), database);
+ Fputhash (HASHKEY_QUERY_CACHE, Qnil, database);
return database;
}
Fputhash (node_id, value, database);
Fputhash (HASHKEY_MAX_NID, make_number (max_nid), database);
+ Fputhash (HASHKEY_QUERY_CACHE, Qnil, database);
}
/* Merge multiple resource entries specified by DATA into a resource
XrmDatabase database;
char *name, *class;
{
- Lisp_Object quark_name, quark_class, tmp;
- int nn, nc;
+ Lisp_Object key, query_cache, quark_name, quark_class, tmp;
+ int i, nn, nc;
+ struct Lisp_Hash_Table *h;
+ unsigned hash_code;
+
+ nn = strlen (name);
+ nc = strlen (class);
+ key = make_uninit_string (nn + nc + 1);
+ strcpy (SDATA (key), name);
+ strncpy (SDATA (key) + nn + 1, class, nc);
+
+ query_cache = Fgethash (HASHKEY_QUERY_CACHE, database, Qnil);
+ if (NILP (query_cache))
+ {
+ query_cache = make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE),
+ make_float (DEFAULT_REHASH_SIZE),
+ make_float (DEFAULT_REHASH_THRESHOLD),
+ Qnil, Qnil, Qnil);
+ Fputhash (HASHKEY_QUERY_CACHE, query_cache, database);
+ }
+ h = XHASH_TABLE (query_cache);
+ i = hash_lookup (h, key, &hash_code);
+ if (i >= 0)
+ return HASH_VALUE (h, i);
quark_name = parse_resource_name (&name);
if (*name != '\0')
if (nn != nc)
return Qnil;
else
- return xrm_q_get_resource (database, quark_name, quark_class);
+ {
+ tmp = xrm_q_get_resource (database, quark_name, quark_class);
+ hash_put (h, key, tmp, hash_code);
+ return tmp;
+ }
}
#if TARGET_API_MAC_CARBON
CFSetGetValues (key_set, (const void **)keys);
for (index = 0; index < count; index++)
{
- res_name = SDATA (cfstring_to_lisp (keys[index]));
+ res_name = SDATA (cfstring_to_lisp_nodecode (keys[index]));
quarks = parse_resource_name (&res_name);
if (!(NILP (quarks) || *res_name))
{
}
-OSErr
+static OSErr
posix_pathname_to_fsspec (ufn, fs)
const char *ufn;
FSSpec *fs;
}
}
-OSErr
+static OSErr
fsspec_to_posix_pathname (fs, ufn, ufnbuflen)
const FSSpec *fs;
char *ufn;
wildcard filename expansion. Since we don't really have a shell on
the Mac, this case is detected and the starting of the shell is
by-passed. We really need to add code here to do filename
- expansion to support such functionality. */
+ expansion to support such functionality.
+
+ We can't use this strategy in Carbon because the High Level Event
+ APIs are not available. */
int
run_mac_command (argv, workdir, infn, outfn, errfn)
/* Compile and execute the AppleScript SCRIPT and return the error
status as function value. A zero is returned if compilation and
- execution is successful, in which case RESULT returns a pointer to
- a string containing the resulting script value. Otherwise, the Mac
- error code is returned and RESULT returns a pointer to an error
- string. In both cases the caller should deallocate the storage
- used by the string pointed to by RESULT if it is non-NULL. For
- documentation on the MacOS scripting architecture, see Inside
- Macintosh - Interapplication Communications: Scripting Components. */
+ execution is successful, in which case *RESULT is set to a Lisp
+ string containing the resulting script value. Otherwise, the Mac
+ error code is returned and *RESULT is set to an error Lisp string.
+ For documentation on the MacOS scripting architecture, see Inside
+ Macintosh - Interapplication Communications: Scripting
+ Components. */
static long
-do_applescript (char *script, char **result)
+do_applescript (script, result)
+ Lisp_Object script, *result;
{
- AEDesc script_desc, result_desc, error_desc;
+ AEDesc script_desc, result_desc, error_desc, *desc = NULL;
OSErr error;
OSAError osaerror;
- long length;
- *result = 0;
+ *result = Qnil;
if (!as_scripting_component)
initialize_applescript();
- error = AECreateDesc (typeChar, script, strlen(script), &script_desc);
+ error = AECreateDesc (typeChar, SDATA (script), SBYTES (script),
+ &script_desc);
if (error)
return error;
osaerror = OSADoScript (as_scripting_component, &script_desc, kOSANullScript,
typeChar, kOSAModeNull, &result_desc);
- if (osaerror == errOSAScriptError)
- {
- /* error executing AppleScript: retrieve error message */
- if (!OSAScriptError (as_scripting_component, kOSAErrorMessage, typeChar,
- &error_desc))
- {
-#if TARGET_API_MAC_CARBON
- length = AEGetDescDataSize (&error_desc);
- *result = (char *) xmalloc (length + 1);
- if (*result)
- {
- AEGetDescData (&error_desc, *result, length);
- *(*result + length) = '\0';
- }
-#else /* not TARGET_API_MAC_CARBON */
- HLock (error_desc.dataHandle);
- length = GetHandleSize(error_desc.dataHandle);
- *result = (char *) xmalloc (length + 1);
- if (*result)
- {
- memcpy (*result, *(error_desc.dataHandle), length);
- *(*result + length) = '\0';
- }
- HUnlock (error_desc.dataHandle);
-#endif /* not TARGET_API_MAC_CARBON */
- AEDisposeDesc (&error_desc);
- }
- }
- else if (osaerror == noErr) /* success: retrieve resulting script value */
+ if (osaerror == noErr)
+ /* success: retrieve resulting script value */
+ desc = &result_desc;
+ else if (osaerror == errOSAScriptError)
+ /* error executing AppleScript: retrieve error message */
+ if (!OSAScriptError (as_scripting_component, kOSAErrorMessage, typeChar,
+ &error_desc))
+ desc = &error_desc;
+
+ if (desc)
{
#if TARGET_API_MAC_CARBON
- length = AEGetDescDataSize (&result_desc);
- *result = (char *) xmalloc (length + 1);
- if (*result)
- {
- AEGetDescData (&result_desc, *result, length);
- *(*result + length) = '\0';
- }
+ *result = make_uninit_string (AEGetDescDataSize (desc));
+ AEGetDescData (desc, SDATA (*result), SBYTES (*result));
#else /* not TARGET_API_MAC_CARBON */
- HLock (result_desc.dataHandle);
- length = GetHandleSize(result_desc.dataHandle);
- *result = (char *) xmalloc (length + 1);
- if (*result)
- {
- memcpy (*result, *(result_desc.dataHandle), length);
- *(*result + length) = '\0';
- }
- HUnlock (result_desc.dataHandle);
+ *result = make_uninit_string (GetHandleSize (desc->dataHandle));
+ memcpy (SDATA (*result), *(desc->dataHandle), SBYTES (*result));
#endif /* not TARGET_API_MAC_CARBON */
- AEDisposeDesc (&result_desc);
+ AEDisposeDesc (desc);
}
AEDisposeDesc (&script_desc);
(script)
Lisp_Object script;
{
- char *result, *temp;
- Lisp_Object lisp_result;
+ Lisp_Object result;
long status;
CHECK_STRING (script);
BLOCK_INPUT;
- status = do_applescript (SDATA (script), &result);
+ status = do_applescript (script, &result);
UNBLOCK_INPUT;
- if (status)
- {
- if (!result)
- error ("AppleScript error %d", status);
- else
- {
- /* Unfortunately only OSADoScript in do_applescript knows how
- how large the resulting script value or error message is
- going to be and therefore as caller memory must be
- deallocated here. It is necessary to free the error
- message before calling error to avoid a memory leak. */
- temp = (char *) alloca (strlen (result) + 1);
- strcpy (temp, result);
- xfree (result);
- error (temp);
- }
- }
+ if (status == 0)
+ return result;
+ else if (!STRINGP (result))
+ error ("AppleScript error %d", status);
else
- {
- lisp_result = build_string (result);
- xfree (result);
- return lisp_result;
- }
+ error ("%s", SDATA (result));
}
}
+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))
+ src_desc_type = TYPE_FILE_NAME;
+ else
+ src_desc_type = mac_get_code_from_arg (src_type, 0);
+
+ if (EQ (dst_type, Qundecoded_file_name))
+ dst_desc_type = TYPE_FILE_NAME;
+ else
+ dst_desc_type = mac_get_code_from_arg (dst_type, 0);
+
+ BLOCK_INPUT;
+ err = AECoercePtr (src_desc_type, SDATA (src_data), SBYTES (src_data),
+ dst_desc_type, &dst_desc);
+ if (err == noErr)
+ {
+ 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;
return 0;
}
+#if USE_CG_DRAWING
+ mac_prepare_for_quickdraw (NULL);
+#endif
/* Avoid initial overhead of RunLoop setup for the case that
some input is already available. */
EMACS_SET_SECS_USECS (select_timeout, 0, 0);
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);
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);