]> code.delx.au - gnu-emacs/blobdiff - src/mac.c
(Fgarbage_collect): Update call to truncate_undo_list.
[gnu-emacs] / src / mac.c
index 439f900db5b4694b88765e6f3aee83566679f2bf..53e56cfb54176766d7d3a6f98e341d4a82107272 100644 (file)
--- a/src/mac.c
+++ b/src/mac.c
@@ -24,14 +24,17 @@ Boston, MA 02111-1307, USA.  */
 
 #include <stdio.h>
 #include <errno.h>
+#include <time.h>
 #include <utime.h>
 #include <dirent.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <string.h>
 #include <pwd.h>
+#include <grp.h>
 #include <sys/param.h>
 #include <stdlib.h>
+#include <fcntl.h>
 #if __MWERKS__
 #include <unistd.h>
 #endif
@@ -44,6 +47,8 @@ Boston, MA 02111-1307, USA.  */
 #undef realloc
 #undef init_process
 #include <Carbon/Carbon.h>
+#undef mktime
+#define mktime emacs_mktime
 #undef free
 #define free unexec_free
 #undef malloc
@@ -70,6 +75,7 @@ Boston, MA 02111-1307, USA.  */
 #include "process.h"
 #include "sysselect.h"
 #include "systime.h"
+#include "blockinput.h"
 
 Lisp_Object QCLIPBOARD;
 
@@ -256,6 +262,22 @@ posix_to_mac_pathname (const char *ufn, char *mfn, int mfnbuflen)
   return 1;
 }
 
+#if TARGET_API_MAC_CARBON
+CFStringRef
+cfstring_create_with_utf8_cstring (c_str)
+     const char *c_str;
+{
+  CFStringRef str;
+
+  str = CFStringCreateWithCString (NULL, c_str, kCFStringEncodingUTF8);
+  if (str == NULL)
+    /* Failed to interpret as UTF 8.  Fall back on Mac Roman.  */
+    str = CFStringCreateWithCString (NULL, c_str, kCFStringEncodingMacRoman);
+
+  return str;
+}
+#endif
+
 #ifndef MAC_OSX
 
 /* The following functions with "sys_" prefix are stubs to Unix
@@ -1163,6 +1185,13 @@ static struct passwd my_passwd =
   my_passwd_dir,
 };
 
+static struct group my_group =
+{
+  /* There are no groups on the mac, so we just return "root" as the
+     group name.  */
+  "root",
+};
+
 
 /* Initialized by main () in macterm.c to pathname of emacs directory.  */
 
@@ -1257,6 +1286,13 @@ getpwuid (uid_t uid)
 }
 
 
+struct group *
+getgrgid (gid_t gid)
+{
+  return &my_group;
+}
+
+
 struct passwd *
 getpwnam (const char *name)
 {
@@ -2531,7 +2567,9 @@ component.  */)
 
   CHECK_STRING (script);
 
+  BLOCK_INPUT;
   status = do_applescript (SDATA (script), &result);
+  UNBLOCK_INPUT;
   if (status)
     {
       if (!result)
@@ -2601,26 +2639,23 @@ DEFUN ("mac-paste-function", Fmac_paste_function, Smac_paste_function, 0, 0, 0,
      ()
 {
 #if TARGET_API_MAC_CARBON
+  OSStatus err;
   ScrapRef scrap;
   ScrapFlavorFlags sff;
   Size s;
   int i;
   char *data;
 
-  if (GetCurrentScrap (&scrap) != noErr)
-    return Qnil;
-
-  if (GetScrapFlavorFlags (scrap, kScrapFlavorTypeText, &sff) != noErr)
-    return Qnil;
-
-  if (GetScrapFlavorSize (scrap, kScrapFlavorTypeText, &s) != noErr)
-    return Qnil;
-
-  if ((data = (char*) alloca (s)) == NULL)
-    return Qnil;
-
-  if (GetScrapFlavorData (scrap, kScrapFlavorTypeText, &s, data) != noErr
-      || s == 0)
+  BLOCK_INPUT;
+  err = GetCurrentScrap (&scrap);
+  if (err == noErr)
+    err = GetScrapFlavorFlags (scrap, kScrapFlavorTypeText, &sff);
+  if (err == noErr)
+    err = GetScrapFlavorSize (scrap, kScrapFlavorTypeText, &s);
+  if (err == noErr && (data = (char*) alloca (s)))
+    err = GetScrapFlavorData (scrap, kScrapFlavorTypeText, &s, data);
+  UNBLOCK_INPUT;
+  if (err != noErr || s == 0)
     return Qnil;
 
   /* Emacs expects clipboard contents have Unix-style eol's */
@@ -2685,13 +2720,22 @@ DEFUN ("mac-cut-function", Fmac_cut_function, Smac_cut_function, 1, 2, 0,
 #if TARGET_API_MAC_CARBON
   {
     ScrapRef scrap;
+
+    BLOCK_INPUT;
     ClearCurrentScrap ();
     if (GetCurrentScrap (&scrap) != noErr)
-      error ("cannot get current scrap");
+      {
+       UNBLOCK_INPUT;
+       error ("cannot get current scrap");
+      }
 
     if (PutScrapFlavor (scrap, kScrapFlavorTypeText, kScrapFlavorMaskNone, len,
                        buf) != noErr)
-      error ("cannot put to scrap");
+      {
+       UNBLOCK_INPUT;
+       error ("cannot put to scrap");
+      }
+    UNBLOCK_INPUT;
   }
 #else /* not TARGET_API_MAC_CARBON */
   ZeroScrap ();
@@ -2726,9 +2770,11 @@ and t is the same as `SECONDARY'.  */)
       ScrapRef scrap;
       ScrapFlavorFlags sff;
 
+      BLOCK_INPUT;
       if (GetCurrentScrap (&scrap) == noErr)
         if (GetScrapFlavorFlags (scrap, kScrapFlavorTypeText, &sff) == noErr)
           val = Qt;
+      UNBLOCK_INPUT;
 #else /* not TARGET_API_MAC_CARBON */
       Handle my_handle;
       long rc, scrap_offset;
@@ -2760,69 +2806,100 @@ extern int noninteractive;
    the system call SELECT corrects this discrepancy.  */
 int
 sys_select (n, rfds, wfds, efds, timeout)
-  int n;
-  SELECT_TYPE *rfds;
-  SELECT_TYPE *wfds;
-  SELECT_TYPE *efds;
-  struct timeval *timeout;
+     int n;
+     SELECT_TYPE *rfds;
+     SELECT_TYPE *wfds;
+     SELECT_TYPE *efds;
+     struct timeval *timeout;
 {
-  if (!inhibit_window_system && rfds && FD_ISSET (0, rfds))
-    return 1;
-  else if (inhibit_window_system || noninteractive)
-    return select(n, rfds, wfds, efds, timeout);
-  else
+  OSErr err;
+  EMACS_TIME end_time, now, remaining_time;
+  if (inhibit_window_system || noninteractive
+      || rfds == NULL || !FD_ISSET (0, rfds))
+    return select (n, rfds, wfds, efds, timeout);
+  
+  if (wfds == NULL && efds == NULL)
+    {
+      int i;
+
+      for (i = 1; i < n; i++)
+       if (FD_ISSET (i, rfds))
+         break;
+      if (i == n)
+       {
+         EventTimeout timeout_sec =
+           (timeout
+            ? (EMACS_SECS (*timeout) * kEventDurationSecond
+               + EMACS_USECS (*timeout) * kEventDurationMicrosecond)
+            : kEventDurationForever);
+
+         BLOCK_INPUT;
+         err = ReceiveNextEvent (0, NULL, timeout_sec,
+                                 kEventLeaveInQueue, NULL);
+         UNBLOCK_INPUT;
+         if (err == noErr)
+           {
+             FD_ZERO (rfds);
+             FD_SET (0, rfds);
+             return 1;
+           }
+         else
+           return 0;
+       }
+    }
+
+  if (timeout)
+    {
+      remaining_time = *timeout;
+      EMACS_GET_TIME (now);
+      EMACS_ADD_TIME (end_time, now, remaining_time);
+    }
+  FD_CLR (0, rfds);
+  do
     {
-      EMACS_TIME end_time, now;
-      
-      EMACS_GET_TIME (end_time);
+      EMACS_TIME select_timeout;
+      SELECT_TYPE orfds = *rfds;
+      int r;
+
+      EMACS_SET_SECS_USECS (select_timeout, 0, 20000);
+
+      if (timeout && EMACS_TIME_LT (remaining_time, select_timeout))
+       select_timeout = remaining_time;
+
+      r = select (n, &orfds, wfds, efds, &select_timeout);
+      BLOCK_INPUT;
+      err = ReceiveNextEvent (0, NULL, kEventDurationNoWait,
+                             kEventLeaveInQueue, NULL);
+      UNBLOCK_INPUT;
+      if (r > 0)
+       {
+         *rfds = orfds;
+         if (err == noErr)
+           {
+             FD_SET (0, rfds);
+             r++;
+           }
+         return r;
+       }
+      else if (err == noErr)
+       {
+         FD_ZERO (rfds);
+         FD_SET (0, rfds);
+         return 1;
+       }
+
       if (timeout)
-       EMACS_ADD_TIME (end_time, end_time, *timeout);
-      
-      do
        {
-         int r;
-         EMACS_TIME one_second;
-         
-         EMACS_SET_SECS (one_second, 1);
-         EMACS_SET_USECS (one_second, 0);
-         
-         if ((r = select (n, rfds, wfds, efds, &one_second)) > 0)
-           return r;
-         
-         mac_check_for_quit_char();
-         
          EMACS_GET_TIME (now);
-         EMACS_SUB_TIME (now, end_time, now);
+         EMACS_SUB_TIME (remaining_time, end_time, now);
        }
-      while (!timeout || !EMACS_TIME_NEG_P (now));
-      
-      return 0;
     }
-}
+  while (!timeout || EMACS_TIME_LT (now, end_time));
 
-#undef read
-int sys_read (fds, buf, nbyte)
-     int fds;
-     char *buf;
-     unsigned int nbyte;
-{
-  SELECT_TYPE rfds;
-  EMACS_TIME one_second;
-  int r;
-
-  /* Use select to block on IO while still checking for quit_char */
-  if (!inhibit_window_system && !noninteractive)
-    {
-      FD_ZERO (&rfds);
-      FD_SET (fds, &rfds);
-      if (sys_select (fds+1, &rfds, 0, 0, NULL) < 0)
-       return -1;
-    }
-      
-  return read (fds, buf, nbyte);
+  return 0;
 }
 
-
 /* Set up environment variables so that Emacs can correctly find its
    support files when packaged as an application bundle.  Directories
    placed in /usr/local/share/emacs/<emacs-version>/, /usr/local/bin,
@@ -2914,12 +2991,12 @@ init_mac_osx_environment ()
       q[0] = '\0';
 
       strcpy (p, app_bundle_pathname);
-      strcat (p, "/Contents/MacOS/bin");
+      strcat (p, "/Contents/MacOS/libexec");
       if (stat (p, &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR)
        strcat (q, p);
 
       strcpy (p, app_bundle_pathname);
-      strcat (p, "/Contents/MacOS/libexec");
+      strcat (p, "/Contents/MacOS/bin");
       if (stat (p, &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR)
        {
          if (q[0] != '\0')
@@ -2971,3 +3048,6 @@ syms_of_mac ()
   defsubr (&Smac_file_name_to_posix);
   defsubr (&Sposix_file_name_to_mac);
 }
+
+/* arch-tag: 29d30c1f-0c6b-4f88-8a6d-0558d7f9dbff
+   (do not change this comment) */