]> code.delx.au - gnu-emacs/blobdiff - src/mac.c
* xmenu.c (popup_get_selection): Pop down on C-g.
[gnu-emacs] / src / mac.c
index ce2e424249323d28bcae2a1b02b52340b408fd7f..53e56cfb54176766d7d3a6f98e341d4a82107272 100644 (file)
--- a/src/mac.c
+++ b/src/mac.c
@@ -24,12 +24,14 @@ 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>
@@ -45,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
@@ -71,6 +75,7 @@ Boston, MA 02111-1307, USA.  */
 #include "process.h"
 #include "sysselect.h"
 #include "systime.h"
+#include "blockinput.h"
 
 Lisp_Object QCLIPBOARD;
 
@@ -257,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
@@ -1164,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.  */
 
@@ -1258,6 +1286,13 @@ getpwuid (uid_t uid)
 }
 
 
+struct group *
+getgrgid (gid_t gid)
+{
+  return &my_group;
+}
+
+
 struct passwd *
 getpwnam (const char *name)
 {
@@ -2532,7 +2567,9 @@ component.  */)
 
   CHECK_STRING (script);
 
+  BLOCK_INPUT;
   status = do_applescript (SDATA (script), &result);
+  UNBLOCK_INPUT;
   if (status)
     {
       if (!result)
@@ -2602,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 */
@@ -2686,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 ();
@@ -2727,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;
@@ -2761,85 +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 ||
-          (timeout && (EMACS_SECS(*timeout)==0) &&
-           (EMACS_USECS(*timeout)==0)))
-    return select(n, rfds, wfds, efds, timeout);
-  else
-    {
-      EMACS_TIME end_time, now;
-
-      EMACS_GET_TIME (end_time);
-      if (timeout)
-       EMACS_ADD_TIME (end_time, end_time, *timeout);
-
-      do
-       {
-         int r;
-         EMACS_TIME one_second;
-         SELECT_TYPE orfds;
-
-         FD_ZERO (&orfds);
-         if (rfds)
+  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)
            {
-             orfds = *rfds;
+             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 select_timeout;
+      SELECT_TYPE orfds = *rfds;
+      int r;
 
-         EMACS_SET_SECS (one_second, 1);
-         EMACS_SET_USECS (one_second, 0);
+      EMACS_SET_SECS_USECS (select_timeout, 0, 20000);
 
-         if (timeout && EMACS_TIME_LT(*timeout, one_second))
-           one_second = *timeout;
+      if (timeout && EMACS_TIME_LT (remaining_time, select_timeout))
+       select_timeout = remaining_time;
 
-         if ((r = select (n, &orfds, wfds, efds, &one_second)) > 0)
+      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)
            {
-             *rfds = orfds;
-             return r;
+             FD_SET (0, rfds);
+             r++;
            }
+         return r;
+       }
+      else if (err == noErr)
+       {
+         FD_ZERO (rfds);
+         FD_SET (0, rfds);
+         return 1;
+       }
 
-         mac_check_for_quit_char();
-
+      if (timeout)
+       {
          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;
-    }
-}
-
-#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 &&
-      ! (fcntl(fds, F_GETFL, 0) & O_NONBLOCK))
-    {
-      FD_ZERO (&rfds);
-      FD_SET (fds, &rfds);
-      if (sys_select (fds+1, &rfds, 0, 0, NULL) < 0)
-       return -1;
     }
+  while (!timeout || EMACS_TIME_LT (now, end_time));
 
-  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,
@@ -2988,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) */