]> code.delx.au - gnu-emacs/blobdiff - src/mac.c
(text_read_only): Use xsignal0, xsignal1.
[gnu-emacs] / src / mac.c
index 2b4e8dcbc642f8d1793e12db3c954102de0e2f97..4652757fab35912e4488cfaca3b5bbccf6309ca8 100644 (file)
--- a/src/mac.c
+++ b/src/mac.c
@@ -46,11 +46,9 @@ Boston, MA 02110-1301, USA.  */
 #include <Folders.h>
 #include <Resources.h>
 #include <Aliases.h>
-#include <FixMath.h>
 #include <Timer.h>
 #include <OSA.h>
 #include <AppleScript.h>
-#include <Scrap.h>
 #include <Events.h>
 #include <Processes.h>
 #include <EPPC.h>
@@ -270,9 +268,29 @@ posix_to_mac_pathname (const char *ufn, char *mfn, int mfnbuflen)
 
 static Lisp_Object Qundecoded_file_name;
 
+static struct {
+  AEKeyword keyword;
+  char *name;
+  Lisp_Object symbol;
+} ae_attr_table [] =
+  {{keyTransactionIDAttr,      "transaction-id"},
+   {keyReturnIDAttr,           "return-id"},
+   {keyEventClassAttr,         "event-class"},
+   {keyEventIDAttr,            "event-id"},
+   {keyAddressAttr,            "address"},
+   {keyOptionalKeywordAttr,    "optional-keyword"},
+   {keyTimeoutAttr,            "timeout"},
+   {keyInteractLevelAttr,      "interact-level"},
+   {keyEventSourceAttr,                "event-source"},
+   /* {keyMissedKeywordAttr,   "missed-keyword"}, */
+   {keyOriginalAddressAttr,    "original-address"},
+   {keyReplyRequestedAttr,     "reply-requested"},
+   {KEY_EMACS_SUSPENSION_ID_ATTR, "emacs-suspension-id"}
+  };
+
 static Lisp_Object
 mac_aelist_to_lisp (desc_list)
-     AEDescList *desc_list;
+     const AEDescList *desc_list;
 {
   OSErr err;
   long count;
@@ -281,22 +299,36 @@ mac_aelist_to_lisp (desc_list)
   Size size;
   AEKeyword keyword;
   AEDesc desc;
+  int attribute_p = 0;
 
   err = AECountItems (desc_list, &count);
   if (err != noErr)
     return Qnil;
   result = Qnil;
+
+ again:
   while (count > 0)
     {
-      err = AESizeOfNthItem (desc_list, count, &desc_type, &size);
+      if (attribute_p)
+       {
+         keyword = ae_attr_table[count - 1].keyword;
+         err = AESizeOfAttribute (desc_list, keyword, &desc_type, &size);
+       }
+      else
+       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 (attribute_p)
+             err = AEGetAttributeDesc (desc_list, keyword, typeWildCard,
+                                       &desc);
+           else
+             err = AEGetNthDesc (desc_list, count, typeWildCard,
+                                 &keyword, &desc);
            if (err != noErr)
              break;
            elem = mac_aelist_to_lisp (&desc);
@@ -309,8 +341,13 @@ mac_aelist_to_lisp (desc_list)
            else
              {
                elem = make_uninit_string (size);
-               err = AEGetNthPtr (desc_list, count, typeWildCard, &keyword,
-                                  &desc_type, SDATA (elem), size, &size);
+               if (attribute_p)
+                 err = AEGetAttributePtr (desc_list, keyword, typeWildCard,
+                                          &desc_type, SDATA (elem),
+                                          size, &size);
+               else
+                 err = AEGetNthPtr (desc_list, count, typeWildCard, &keyword,
+                                    &desc_type, SDATA (elem), size, &size);
              }
            if (err != noErr)
              break;
@@ -319,25 +356,42 @@ mac_aelist_to_lisp (desc_list)
            break;
        }
 
-      if (err != noErr)
-       elem = Qnil;
-      else if (desc_list->descriptorType != typeAEList)
+      if (err == noErr || desc_list->descriptorType == typeAEList)
        {
-         keyword = EndianU32_NtoB (keyword);
-         elem = Fcons (make_unibyte_string ((char *) &keyword, 4), elem);
+         if (err != noErr)
+           elem = Qnil;        /* Don't skip elements in AEList.  */
+         else if (desc_list->descriptorType != typeAEList)
+           {
+             if (attribute_p)
+               elem = Fcons (ae_attr_table[count-1].symbol, elem);
+             else
+               {
+                 keyword = EndianU32_NtoB (keyword);
+                 elem = Fcons (make_unibyte_string ((char *) &keyword, 4),
+                               elem);
+               }
+           }
+
+         result = Fcons (elem, result);
        }
 
-      result = Fcons (elem, result);
       count--;
     }
 
+  if (desc_list->descriptorType == typeAppleEvent && !attribute_p)
+    {
+      attribute_p = 1;
+      count = sizeof (ae_attr_table) / sizeof (ae_attr_table[0]);
+      goto again;
+    }
+
   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;
+     const AEDesc *desc;
 {
   OSErr err = noErr;
   DescType desc_type = desc->descriptorType;
@@ -403,6 +457,93 @@ mac_aedesc_to_lisp (desc)
   return Fcons (make_unibyte_string ((char *) &desc_type, 4), result);
 }
 
+OSErr
+mac_ae_put_lisp (desc, keyword_or_index, obj)
+     AEDescList *desc;
+     UInt32 keyword_or_index;
+     Lisp_Object obj;
+{
+  OSErr err;
+
+  if (!(desc->descriptorType == typeAppleEvent
+       || desc->descriptorType == typeAERecord
+       || desc->descriptorType == typeAEList))
+    return errAEWrongDataType;
+
+  if (CONSP (obj) && STRINGP (XCAR (obj)) && SBYTES (XCAR (obj)) == 4)
+    {
+      DescType desc_type1 = EndianU32_BtoN (*((UInt32 *) SDATA (XCAR (obj))));
+      Lisp_Object data = XCDR (obj), rest;
+      AEDesc desc1;
+
+      switch (desc_type1)
+       {
+       case typeNull:
+       case typeAppleEvent:
+         break;
+
+       case typeAEList:
+       case typeAERecord:
+         err = AECreateList (NULL, 0, desc_type1 == typeAERecord, &desc1);
+         if (err == noErr)
+           {
+             for (rest = data; CONSP (rest); rest = XCDR (rest))
+               {
+                 UInt32 keyword_or_index1 = 0;
+                 Lisp_Object elem = XCAR (rest);
+
+                 if (desc_type1 == typeAERecord)
+                   {
+                     if (CONSP (elem) && STRINGP (XCAR (elem))
+                         && SBYTES (XCAR (elem)) == 4)
+                       {
+                         keyword_or_index1 =
+                           EndianU32_BtoN (*((UInt32 *)
+                                             SDATA (XCAR (elem))));
+                         elem = XCDR (elem);
+                       }
+                     else
+                       continue;
+                   }
+
+                 err = mac_ae_put_lisp (&desc1, keyword_or_index1, elem);
+                 if (err != noErr)
+                   break;
+               }
+
+             if (err == noErr)
+               {
+                 if (desc->descriptorType == typeAEList)
+                   err = AEPutDesc (desc, keyword_or_index, &desc1);
+                 else
+                   err = AEPutParamDesc (desc, keyword_or_index, &desc1);
+               }
+
+             AEDisposeDesc (&desc1);
+           }
+         return err;
+
+       default:
+         if (!STRINGP (data))
+           break;
+         if (desc->descriptorType == typeAEList)
+           err = AEPutPtr (desc, keyword_or_index, desc_type1,
+                           SDATA (data), SBYTES (data));
+         else
+           err = AEPutParamPtr (desc, keyword_or_index, desc_type1,
+                                SDATA (data), SBYTES (data));
+         return err;
+       }
+    }
+
+  if (desc->descriptorType == typeAEList)
+    err = AEPutPtr (desc, keyword_or_index, typeNull, NULL, 0);
+  else
+    err = AEPutParamPtr (desc, keyword_or_index, typeNull, NULL, 0);
+
+  return err;
+}
+
 static pascal OSErr
 mac_coerce_file_name_ptr (type_code, data_ptr, data_size,
                          to_type, handler_refcon, result)
@@ -448,20 +589,31 @@ mac_coerce_file_name_ptr (type_code, data_ptr, data_size,
        }
       else
        err = memFullErr;
-#else
-      FSSpec fs;
-      char *buf;
 
-      buf = xmalloc (data_size + 1);
-      if (buf)
+      if (err != noErr)
        {
+         /* Just to be paranoid ...  */
+         FSRef fref;
+         char *buf;
+
+         buf = xmalloc (data_size + 1);
          memcpy (buf, data_ptr, data_size);
          buf[data_size] = '\0';
-         err = posix_pathname_to_fsspec (buf, &fs);
+         err = FSPathMakeRef (buf, &fref, NULL);
          xfree (buf);
+         if (err == noErr)
+           err = AECoercePtr (typeFSRef, &fref, sizeof (FSRef),
+                              to_type, result);
        }
-      else
-       err = memFullErr;
+#else
+      FSSpec fs;
+      char *buf;
+
+      buf = xmalloc (data_size + 1);
+      memcpy (buf, data_ptr, data_size);
+      buf[data_size] = '\0';
+      err = posix_pathname_to_fsspec (buf, &fs);
+      xfree (buf);
       if (err == noErr)
        err = AECoercePtr (typeFSS, &fs, sizeof (FSSpec), to_type, result);
 #endif
@@ -489,14 +641,11 @@ mac_coerce_file_name_ptr (type_code, data_ptr, data_size,
            {
              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);
-               }
+             err = AEGetDescData (&desc, buf, size);
+             if (err == noErr)
+               url = CFURLCreateWithBytes (NULL, buf, size,
+                                           kCFStringEncodingUTF8, NULL);
+             xfree (buf);
              AEDisposeDesc (&desc);
            }
        }
@@ -518,6 +667,34 @@ mac_coerce_file_name_ptr (type_code, data_ptr, data_size,
                              CFDataGetLength (data), result);
          CFRelease (data);
        }
+
+      if (err != noErr)
+       {
+         /* Coercion from typeAlias to typeFileURL fails on Mac OS X
+            10.2.  In such cases, try typeFSRef as a target type.  */
+         char file_name[MAXPATHLEN];
+
+         if (type_code == typeFSRef && data_size == sizeof (FSRef))
+           err = FSRefMakePath (data_ptr, file_name, sizeof (file_name));
+         else
+           {
+             AEDesc desc;
+             FSRef fref;
+
+             err = AECoercePtr (type_code, data_ptr, data_size,
+                                typeFSRef, &desc);
+             if (err == noErr)
+               {
+                 err = AEGetDescData (&desc, &fref, sizeof (FSRef));
+                 AEDisposeDesc (&desc);
+               }
+             if (err == noErr)
+               err = FSRefMakePath (&fref, file_name, sizeof (file_name));
+           }
+         if (err == noErr)
+           err = AECreateDesc (TYPE_FILE_NAME, file_name,
+                               strlen (file_name), result);
+       }
 #else
       char file_name[MAXPATHLEN];
 
@@ -537,11 +714,11 @@ mac_coerce_file_name_ptr (type_code, data_ptr, data_size,
 #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 = fsspec_to_posix_pathname (&fs, file_name,
+                                           sizeof (file_name) - 1);
        }
       if (err == noErr)
        err = AECreateDesc (TYPE_FILE_NAME, file_name,
@@ -581,21 +758,16 @@ mac_coerce_file_name_desc (from_desc, to_type, handler_refcon, result)
       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);
+      err = AEGetDescData (from_desc, data_ptr, data_size);
 #else
-         memcpy (data_ptr, *(from_desc->dataHandle), data_size);
+      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)
+       err = mac_coerce_file_name_ptr (from_type, data_ptr,
+                                       data_size, to_type,
+                                       handler_refcon, result);
+      xfree (data_ptr);
     }
 
   if (err != noErr)
@@ -634,33 +806,46 @@ init_coercion_handler ()
 }
 
 #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;
+static OSErr
+create_apple_event (class, id, result)
+     AEEventClass class;
+     AEEventID id;
      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.   */
+      err = AECreateAppleEvent (class, id,
                                &address_desc, /* NULL is not allowed
                                                  on Mac OS Classic. */
                                kAutoGenerateReturnID,
                                kAnyTransactionID, result);
       AEDisposeDesc (&address_desc);
     }
+
+  return err;
+}
+
+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;
+  UInt32 i, size;
+  CFStringRef string;
+  CFDataRef data;
+  char *buf = NULL;
+
+  err = create_apple_event (0, 0, result); /* Dummy class and ID.  */
   if (err != noErr)
     return err;
 
@@ -678,8 +863,7 @@ create_apple_event_from_event_ref (event, num_params, names, types, result)
                                                     '?');
        if (data == NULL)
          break;
-       /* typeUTF8Text is not available on Mac OS X 10.1.  */
-       AEPutParamPtr (result, names[i], 'utf8',
+       AEPutParamPtr (result, names[i], typeUTF8Text,
                       CFDataGetBytePtr (data), CFDataGetLength (data));
        CFRelease (data);
        break;
@@ -690,21 +874,88 @@ create_apple_event_from_event_ref (event, num_params, names, types, result)
                                 0, &size, NULL);
        if (err != noErr)
          break;
-       buf = xmalloc (size);
-       if (buf == NULL)
-         break;
+       buf = xrealloc (buf, size);
        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;
       }
+  if (buf)
+    xfree (buf);
 
   return noErr;
 }
-#endif
 
+OSErr
+create_apple_event_from_drag_ref (drag, num_types, types, result)
+     DragRef drag;
+     UInt32 num_types;
+     FlavorType *types;
+     AppleEvent *result;
+{
+  OSErr err;
+  UInt16 num_items;
+  AppleEvent items;
+  long index;
+  char *buf = NULL;
+
+  err = CountDragItems (drag, &num_items);
+  if (err != noErr)
+    return err;
+  err = AECreateList (NULL, 0, false, &items);
+  if (err != noErr)
+    return err;
+
+  for (index = 1; index <= num_items; index++)
+    {
+      ItemReference item;
+      DescType desc_type = typeNull;
+      Size size;
+
+      err = GetDragItemReferenceNumber (drag, index, &item);
+      if (err == noErr)
+       {
+         int i;
+
+         for (i = 0; i < num_types; i++)
+           {
+             err = GetFlavorDataSize (drag, item, types[i], &size);
+             if (err == noErr)
+               {
+                 buf = xrealloc (buf, size);
+                 err = GetFlavorData (drag, item, types[i], buf, &size, 0);
+               }
+             if (err == noErr)
+               {
+                 desc_type = types[i];
+                 break;
+               }
+           }
+       }
+      err = AEPutPtr (&items, index, desc_type,
+                     desc_type != typeNull ? buf : NULL,
+                     desc_type != typeNull ? size : 0);
+      if (err != noErr)
+       break;
+    }
+  if (buf)
+    xfree (buf);
+
+  if (err == noErr)
+    {
+      err = create_apple_event (0, 0, result); /* Dummy class and ID.  */
+      if (err == noErr)
+       err = AEPutParamDesc (result, keyDirectObject, &items);
+      if (err != noErr)
+       AEDisposeDesc (result);
+    }
+
+  AEDisposeDesc (&items);
+
+  return err;
+}
+#endif /* TARGET_API_MAC_CARBON */
 \f
 /***********************************************************************
         Conversion between Lisp and Core Foundation objects
@@ -1596,8 +1847,6 @@ xrm_get_preference_database (application)
 
   count = CFSetGetCount (key_set);
   keys = xmalloc (sizeof (CFStringRef) * count);
-  if (keys == NULL)
-    goto out;
   CFSetGetValues (key_set, (const void **)keys);
   for (index = 0; index < count; index++)
     {
@@ -4376,8 +4625,7 @@ otherwise.  */)
       CHECK_CONS (key);
       for (tmp = key; CONSP (tmp); tmp = XCDR (tmp))
        CHECK_STRING_CAR (tmp);
-      if (!NILP (tmp))
-       wrong_type_argument (Qlistp, key);
+      CHECK_LIST_END (tmp, key);
     }
   if (!NILP (application))
     CHECK_STRING (application);
@@ -4547,27 +4795,21 @@ cfstring_create_normalized (str, symbol)
       if (in_text == NULL)
        {
          buffer = xmalloc (sizeof (UniChar) * length);
-         if (buffer)
-           {
-             CFStringGetCharacters (str, CFRangeMake (0, length), buffer);
-             in_text = buffer;
-           }
+         CFStringGetCharacters (str, CFRangeMake (0, length), buffer);
+         in_text = buffer;
        }
 
       if (in_text)
-       err = CreateUnicodeToTextInfo(&map, &uni);
+       err = CreateUnicodeToTextInfo (&map, &uni);
       while (err == noErr)
        {
          out_buf = xmalloc (out_size);
-         if (out_buf == NULL)
-           err = mFulErr;
-         else
-           err = ConvertFromUnicodeToText (uni, length * sizeof (UniChar),
-                                           in_text,
-                                           kUnicodeDefaultDirectionMask,
-                                           0, NULL, NULL, NULL,
-                                           out_size, &out_read, &out_len,
-                                           out_buf);
+         err = ConvertFromUnicodeToText (uni, length * sizeof (UniChar),
+                                         in_text,
+                                         kUnicodeDefaultDirectionMask,
+                                         0, NULL, NULL, NULL,
+                                         out_size, &out_read, &out_len,
+                                         out_buf);
          if (err == noErr && out_read < length * sizeof (UniChar))
            {
              xfree (out_buf);
@@ -4665,16 +4907,6 @@ On successful conversion, return the result string, else return nil.  */)
 #endif /* TARGET_API_MAC_CARBON */
 
 
-DEFUN ("mac-clear-font-name-table", Fmac_clear_font_name_table, Smac_clear_font_name_table, 0, 0, 0,
-       doc: /* Clear the font name table.  */)
-     ()
-{
-  check_mac ();
-  mac_clear_font_name_table ();
-  return Qnil;
-}
-
-
 static Lisp_Object
 mac_get_system_locale ()
 {
@@ -5141,12 +5373,21 @@ syms_of_mac ()
   QHFS_plus_C = intern ("HFS+C");      staticpro (&QHFS_plus_C);
 #endif
 
+  {
+    int i;
+
+    for (i = 0; i < sizeof (ae_attr_table) / sizeof (ae_attr_table[0]); i++)
+      {
+       ae_attr_table[i].symbol = intern (ae_attr_table[i].name);
+       staticpro (&ae_attr_table[i].symbol);
+      }
+  }
+
   defsubr (&Smac_coerce_ae_data);
 #if TARGET_API_MAC_CARBON
   defsubr (&Smac_get_preference);
   defsubr (&Smac_code_convert_string);
 #endif
-  defsubr (&Smac_clear_font_name_table);
 
   defsubr (&Smac_set_file_creator);
   defsubr (&Smac_set_file_type);