]> code.delx.au - gnu-emacs/blobdiff - src/macfns.c
* macfns.c (Fx_file_dialog): Save As dialog includes only the
[gnu-emacs] / src / macfns.c
index fbade05ea17e865996844267cc75372accd8eb6e..33da9091575de86582ea18ab2ced68aff2b5bfa7 100644 (file)
@@ -55,6 +55,7 @@ static unsigned char gray_bits[] = {
 #include <ctype.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/param.h>
 
 #include <stdlib.h>
 #include <string.h>
@@ -158,9 +159,7 @@ Lisp_Object Qshift;
 
 extern Lisp_Object Vwindow_system_version;
 
-extern int mac_initialized;
-
-
+#if 0 /* Use xstricmp instead.  */
 /* compare two strings ignoring case */
 
 static int
@@ -171,13 +170,14 @@ stricmp (const char *s, const char *t)
       return 0;
   return tolower (*s) - tolower (*t);
 }
+#endif
 
 /* compare two strings up to n characters, ignoring case */
 
 static int
 strnicmp (const char *s, const char *t, unsigned int n)
 {
-  for ( ; n-- > 0 && tolower (*s) == tolower (*t); s++, t++)
+  for ( ; n > 0 && tolower (*s) == tolower (*t); n--, s++, t++)
     if (*s == '\0')
       return 0;
   return n == 0 ? 0 : tolower (*s) - tolower (*t);
@@ -190,7 +190,7 @@ void
 check_mac ()
 {
   if (! mac_in_use)
-    error ("Mac OS not in use or not initialized");
+    error ("Mac native windows not in use or not initialized");
 }
 
 /* Nonzero if we can use mouse menus.
@@ -228,33 +228,28 @@ struct mac_display_info *
 check_x_display_info (frame)
      Lisp_Object frame;
 {
-  if (!mac_initialized)
-    {
-      mac_initialize ();
-      mac_initialized = 1;
-    }
+  struct mac_display_info *dpyinfo = NULL;
 
   if (NILP (frame))
     {
       struct frame *sf = XFRAME (selected_frame);
 
       if (FRAME_MAC_P (sf) && FRAME_LIVE_P (sf))
-       return FRAME_MAC_DISPLAY_INFO (sf);
+       dpyinfo = FRAME_MAC_DISPLAY_INFO (sf);
+      else if (x_display_list != 0)
+       dpyinfo = x_display_list;
       else
-       return &one_mac_display_info;
+       error ("Mac native windows are not in use or not initialized");
     }
   else if (STRINGP (frame))
-    return x_display_info_for_name (frame);
+    dpyinfo = x_display_info_for_name (frame);
   else
     {
-      FRAME_PTR f;
-
-      CHECK_LIVE_FRAME (frame);
-      f = XFRAME (frame);
-      if (! FRAME_MAC_P (f))
-       error ("non-mac frame used");
-      return FRAME_MAC_DISPLAY_INFO (f);
+      FRAME_PTR f = check_x_frame (frame);
+      dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
     }
+
+  return dpyinfo;
 }
 \f
 /* Return the Emacs frame-object corresponding to a mac window.
@@ -312,6 +307,9 @@ static Lisp_Object x_default_scroll_bar_color_parameter P_ ((struct frame *,
                                                             Lisp_Object,
                                                             char *, char *,
                                                             int));
+
+extern void mac_get_window_bounds P_ ((struct frame *, Rect *, Rect *));
+
 /* Store the screen positions of frame F into XPTR and YPTR.
    These are the positions of the containing window manager window,
    not Emacs's own window.  */
@@ -321,31 +319,15 @@ x_real_positions (f, xptr, yptr)
      FRAME_PTR f;
      int *xptr, *yptr;
 {
-  Point pt;
-  GrafPtr oldport;
+  Rect inner, outer;
 
-#ifdef TARGET_API_MAC_CARBON
-  {
-    Rect r;
+  mac_get_window_bounds (f, &inner, &outer);
 
-    GetWindowPortBounds (f->output_data.mac->mWP, &r);
-    SetPt (&pt, r.left, r.top);
-  }
-#else /* not TARGET_API_MAC_CARBON */
-  SetPt (&pt,
-        f->output_data.mac->mWP->portRect.left,
-        f->output_data.mac->mWP->portRect.top);
-#endif /* not TARGET_API_MAC_CARBON */
-  GetPort (&oldport);
-  LocalToGlobal (&pt);
-  SetPort (oldport);
-
-  /* MAC has no frame pixel diff.  */
-  f->x_pixels_diff = 0;
-  f->y_pixels_diff = 0;
-
-  *xptr = pt.h;
-  *yptr = pt.v;
+  f->x_pixels_diff = inner.left - outer.left;
+  f->y_pixels_diff = inner.top - outer.top;
+
+  *xptr = outer.left;
+  *yptr = outer.top;
 }
 
 \f
@@ -1122,7 +1104,7 @@ mac_color_map_lookup (colorname)
   BLOCK_INPUT;
 
   for (i = 0; i < sizeof (mac_color_map) / sizeof (mac_color_map[0]); i++)
-    if (stricmp (colorname, mac_color_map[i].name) == 0)
+    if (xstricmp (colorname, mac_color_map[i].name) == 0)
       {
         ret = make_number (mac_color_map[i].color);
         break;
@@ -1403,6 +1385,7 @@ x_set_foreground_color (f, arg, oldval)
      struct frame *f;
      Lisp_Object arg, oldval;
 {
+  struct mac_output *mac = f->output_data.mac;
   unsigned long fg, old_fg;
 
   fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
@@ -1411,10 +1394,28 @@ x_set_foreground_color (f, arg, oldval)
 
   if (FRAME_MAC_WINDOW (f) != 0)
     {
+      Display *dpy = FRAME_MAC_DISPLAY (f);
+
+      BLOCK_INPUT;
+      XSetForeground (dpy, mac->normal_gc, fg);
+      XSetBackground (dpy, mac->reverse_gc, fg);
+
+      if (mac->cursor_pixel == old_fg)
+       {
+         unload_color (f, mac->cursor_pixel);
+         mac->cursor_pixel = fg;
+         XSetBackground (dpy, mac->cursor_gc, mac->cursor_pixel);
+       }
+
+      UNBLOCK_INPUT;
+
       update_face_from_frame_parameter (f, Qforeground_color, arg);
+
       if (FRAME_VISIBLE_P (f))
         redraw_frame (f);
     }
+
+  unload_color (f, old_fg);
 }
 
 void
@@ -1422,11 +1423,24 @@ x_set_background_color (f, arg, oldval)
      struct frame *f;
      Lisp_Object arg, oldval;
 {
-  FRAME_BACKGROUND_PIXEL (f)
-    = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
+  struct mac_output *mac = f->output_data.mac;
+  unsigned long bg;
+
+  bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
+  unload_color (f, FRAME_BACKGROUND_PIXEL (f));
+  FRAME_BACKGROUND_PIXEL (f) = bg;
 
   if (FRAME_MAC_WINDOW (f) != 0)
     {
+      Display *dpy = FRAME_MAC_DISPLAY (f);
+
+      BLOCK_INPUT;
+      XSetBackground (dpy, mac->normal_gc, bg);
+      XSetForeground (dpy, mac->reverse_gc, bg);
+      XSetWindowBackground (dpy, FRAME_MAC_WINDOW (f), bg);
+      XSetForeground (dpy, mac->cursor_gc, bg);
+
+      UNBLOCK_INPUT;
       update_face_from_frame_parameter (f, Qbackground_color, arg);
 
       if (FRAME_VISIBLE_P (f))
@@ -1934,8 +1948,8 @@ x_set_name (f, name, explicit)
   if (FRAME_MAC_WINDOW (f))
     {
       if (STRING_MULTIBYTE (name))
-#if 0 /* MAC_TODO: encoding title string */
-       name = ENCODE_SYSTEM (name);
+#if TARGET_API_MAC_CARBON
+       name = ENCODE_UTF_8 (name);
 #else
         return;
 #endif
@@ -1943,6 +1957,13 @@ x_set_name (f, name, explicit)
       BLOCK_INPUT;
 
       {
+#if TARGET_API_MAC_CARBON
+       CFStringRef windowTitle =
+         cfstring_create_with_utf8_cstring (SDATA (name));
+
+       SetWindowTitleWithCFString (FRAME_MAC_WINDOW (f), windowTitle);
+       CFRelease (windowTitle);
+#else
        Str255 windowTitle;
        if (strlen (SDATA (name)) < 255)
          {
@@ -1950,6 +1971,7 @@ x_set_name (f, name, explicit)
            c2pstr (windowTitle);
            SetWTitle (FRAME_MAC_WINDOW (f), windowTitle);
          }
+#endif
       }
 
       UNBLOCK_INPUT;
@@ -2008,8 +2030,8 @@ x_set_title (f, name, old_name)
   if (FRAME_MAC_WINDOW (f))
     {
       if (STRING_MULTIBYTE (name))
-#if 0 /* MAC_TODO: encoding title string */
-       name = ENCODE_SYSTEM (name);
+#if TARGET_API_MAC_CARBON
+       name = ENCODE_UTF_8 (name);
 #else
         return;
 #endif
@@ -2017,6 +2039,13 @@ x_set_title (f, name, old_name)
       BLOCK_INPUT;
 
       {
+#if TARGET_API_MAC_CARBON
+       CFStringRef windowTitle =
+         cfstring_create_with_utf8_cstring (SDATA (name));
+
+       SetWindowTitleWithCFString (FRAME_MAC_WINDOW (f), windowTitle);
+       CFRelease (windowTitle);
+#else
        Str255 windowTitle;
        if (strlen (SDATA (name)) < 255)
          {
@@ -2024,6 +2053,7 @@ x_set_title (f, name, old_name)
            c2pstr (windowTitle);
            SetWTitle (FRAME_MAC_WINDOW (f), windowTitle);
          }
+#endif
       }
 
       UNBLOCK_INPUT;
@@ -2056,13 +2086,49 @@ x_set_scroll_bar_default_width (f)
 \f
 /* Subroutines of creating a frame.  */
 
+static char *
+mac_get_rdb_resource (rdb, resource)
+     char *rdb;
+     char *resource;
+{
+  char *value = rdb;
+  int len = strlen (resource);
+
+  while (*value)
+    {
+      if ((strncmp (value, resource, len) == 0) && (value[len] == ':'))
+        return xstrdup (&value[len + 1]);
+
+      value = strchr (value, '\0') + 1;
+    }
+
+  return NULL;
+}
+
+/* Retrieve the string resource specified by NAME with CLASS from
+   database RDB. */
+
 char *
 x_get_string_resource (rdb, name, class)
      XrmDatabase rdb;
      char *name, *class;
 {
-  /* MAC_TODO: implement resource strings */
+  if (rdb)
+    {
+      char *resource;
+
+      if (resource = mac_get_rdb_resource (rdb, name))
+        return resource;
+      if (resource = mac_get_rdb_resource (rdb, class))
+        return resource;
+    }
+
+  /* MAC_TODO: implement resource strings.  (Maybe Property Lists?)  */
+#if 0
+  return mac_get_string_resource (name, class);
+#else
   return (char *)0;
+#endif
 }
 
 /* Return the value of parameter PARAM.
@@ -2226,36 +2292,46 @@ XParseGeometry (string, x, y, width, height)
 }
 
 \f
-#if 0 /* MAC_TODO */
 /* Create and set up the Mac window for frame F.  */
 
+extern OSErr install_window_handler (WindowPtr);
+
 static void
-mac_window (f, window_prompting, minibuffer_only)
+mac_window (f)
      struct frame *f;
-     long window_prompting;
-     int minibuffer_only;
 {
   Rect r;
 
   BLOCK_INPUT;
 
-  /* Use the resource name as the top-level window name
-     for looking up resources.  Make a non-Lisp copy
-     for the window manager, so GC relocation won't bother it.
-
-     Elsewhere we specify the window name for the window manager.  */
-
-  {
-    char *str = (char *) SDATA (Vx_resource_name);
-    f->namebuf = (char *) xmalloc (strlen (str) + 1);
-    strcpy (f->namebuf, str);
-  }
-
   SetRect (&r, f->left_pos, f->top_pos,
            f->left_pos + FRAME_PIXEL_WIDTH (f),
            f->top_pos + FRAME_PIXEL_HEIGHT (f));
+#if TARGET_API_MAC_CARBON
+  CreateNewWindow (kDocumentWindowClass,
+                  kWindowStandardDocumentAttributes
+                  /* | kWindowToolbarButtonAttribute */,
+                  &r, &FRAME_MAC_WINDOW (f));
+  if (FRAME_MAC_WINDOW (f))
+    {
+      SetWRefCon (FRAME_MAC_WINDOW (f), (long) f->output_data.mac);
+      if (install_window_handler (FRAME_MAC_WINDOW (f)) != noErr)
+       {
+         DisposeWindow (FRAME_MAC_WINDOW (f));
+         FRAME_MAC_WINDOW (f) = NULL;
+       }
+    }
+#else
   FRAME_MAC_WINDOW (f)
-    = NewCWindow (NULL, &r, "\p", 1, zoomDocProc, (WindowPtr) -1, 1, (long) f->output_data.mac);
+    = NewCWindow (NULL, &r, "\p", false, zoomDocProc,
+                 (WindowPtr) -1, 1, (long) f->output_data.mac);
+#endif
+  /* so that update events can find this mac_output struct */
+  f->output_data.mac->mFP = f;  /* point back to emacs frame */
+
+  if (FRAME_MAC_WINDOW (f))
+    XSetWindowBackground (FRAME_MAC_DISPLAY(f), FRAME_MAC_WINDOW (f),
+                         FRAME_BACKGROUND_PIXEL (f));
 
   validate_x_resource_name ();
 
@@ -2273,17 +2349,11 @@ mac_window (f, window_prompting, minibuffer_only)
     x_set_name (f, name, explicit);
   }
 
-  ShowWindow (FRAME_MAC_WINDOW (f));
-
   UNBLOCK_INPUT;
 
-  if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
-    initialize_frame_menubar (f);
-
   if (FRAME_MAC_WINDOW (f) == 0)
     error ("Unable to create window");
 }
-#endif /* MAC_TODO */
 
 /* Handle the icon stuff for this window.  Perhaps later we might
    want an x_set_icon_position which can be called interactively as
@@ -2700,6 +2770,8 @@ This function is an internal primitive--use `make-frame' instead.  */)
                       "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL);
   x_default_parameter (f, parms, Qtitle, Qnil,
                       "title", "Title", RES_TYPE_STRING);
+  x_default_parameter (f, parms, Qfullscreen, Qnil,
+                       "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
 
   f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
 
@@ -2725,8 +2797,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
   tem = mac_get_arg (parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
   f->no_split = minibuffer_only || EQ (tem, Qt);
 
-  /* mac_window (f, window_prompting, minibuffer_only); */
-  make_mac_frame (f);
+  mac_window (f);
 
   x_icon (f, parms);
   x_make_gc (f);
@@ -2760,14 +2831,12 @@ This function is an internal primitive--use `make-frame' instead.  */)
   FRAME_LINES (f) = 0;
   change_frame_size (f, height, width, 1, 0, 0);
 
-#if 0 /* MAC_TODO: when we have window manager hints */
   /* Tell the server what size and position, etc, we want, and how
      badly we want them.  This should be done after we have the menu
      bar so that its size can be taken into account.  */
   BLOCK_INPUT;
   x_wm_set_size_hint (f, window_prompting, 0);
   UNBLOCK_INPUT;
-#endif
 
   /* Make the window appear on the frame and enable display, unless
      the caller says not to.  However, with explicit parent, Emacs
@@ -2981,17 +3050,20 @@ If omitted or nil, that stands for the selected frame's display.  */)
   (display)
      Lisp_Object display;
 {
-  int mac_major_version, mac_minor_version;
+  int mac_major_version;
   SInt32 response;
 
   if (Gestalt (gestaltSystemVersion, &response) != noErr)
     error ("Cannot get Mac OS version");
 
-  mac_major_version = (response >> 8) & 0xf;
-  mac_minor_version = (response >> 4) & 0xf;
+  mac_major_version = (response >> 8) & 0xff;
+  /* convert BCD to int */
+  mac_major_version -= (mac_major_version >> 4) * 6;
 
   return Fcons (make_number (mac_major_version),
-               Fcons (make_number (mac_minor_version), Qnil));
+               Fcons (make_number ((response >> 4) & 0xf),
+                      Fcons (make_number (response & 0xf),
+                             Qnil)));
 }
 
 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
@@ -3138,6 +3210,9 @@ x_display_info_for_name (name)
 
   CHECK_STRING (name);
 
+  if (! EQ (Vwindow_system, intern ("mac")))
+    error ("Not using Mac native windows");
+
   for (dpyinfo = &one_mac_display_info, names = x_display_name_list;
        dpyinfo;
        dpyinfo = dpyinfo->next, names = XCDR (names))
@@ -3165,7 +3240,6 @@ x_display_info_for_name (name)
   return dpyinfo;
 }
 
-#if 0 /* MAC_TODO: implement network support */
 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
        1, 3, 0,
        doc: /* Open a connection to a server.
@@ -3184,7 +3258,7 @@ terminate Emacs if we can't open the connection.  */)
     CHECK_STRING (xrm_string);
 
   if (! EQ (Vwindow_system, intern ("mac")))
-    error ("Not using Mac OS");
+    error ("Not using Mac native windows");
 
   if (! NILP (xrm_string))
     xrm_option = (unsigned char *) SDATA (xrm_string);
@@ -3232,11 +3306,9 @@ If DISPLAY is nil, that stands for the selected frame's display.  */)
   for (i = 0; i < dpyinfo->n_fonts; i++)
     if (dpyinfo->font_table[i].name)
       {
-        if (dpyinfo->font_table[i].name != dpyinfo->font_table[i].full_name)
-          xfree (dpyinfo->font_table[i].full_name);
-        xfree (dpyinfo->font_table[i].name);
-        x_unload_font (dpyinfo, dpyinfo->font_table[i].font);
+        mac_unload_font (dpyinfo, dpyinfo->font_table[i].font);
       }
+
   x_destroy_all_bitmaps (dpyinfo);
 
   x_delete_display (dpyinfo);
@@ -3244,7 +3316,6 @@ If DISPLAY is nil, that stands for the selected frame's display.  */)
 
   return Qnil;
 }
-#endif /* 0 */
 
 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
        doc: /* Return the list of display names that Emacs has connections to.  */)
@@ -3807,18 +3878,25 @@ x_create_tip_frame (dpyinfo, parms, text)
 
     BLOCK_INPUT;
     SetRect (&r, 0, 0, 1, 1);
+#if TARGET_API_MAC_CARBON
     if (CreateNewWindow (kHelpWindowClass,
 #ifdef MAC_OS_X_VERSION_10_2
                         kWindowIgnoreClicksAttribute |
 #endif
+                        kWindowNoUpdatesAttribute |
                         kWindowNoActivatesAttribute,
                         &r, &tip_window) == noErr)
+#else
+    if (tip_window = NewCWindow (NULL, &r, "\p", false, plainDBox,
+                                NULL, false, 0L))
+#endif
       {
        FRAME_MAC_WINDOW (f) = tip_window;
+       XSetWindowBackground (FRAME_MAC_DISPLAY(f), tip_window,
+                             FRAME_BACKGROUND_PIXEL (f));
        SetWRefCon (tip_window, (long) f->output_data.mac);
        /* so that update events can find this mac_output struct */
        f->output_data.mac->mFP = f;
-       ShowWindow (tip_window);
       }
     UNBLOCK_INPUT;
   }
@@ -4134,6 +4212,7 @@ Text larger than the specified size is clipped.  */)
   BLOCK_INPUT;
   MoveWindow (FRAME_MAC_WINDOW (f), root_x, root_y, false);
   SizeWindow (FRAME_MAC_WINDOW (f), width, height, true);
+  ShowWindow (FRAME_MAC_WINDOW (f));
   BringToFront (FRAME_MAC_WINDOW (f));
   UNBLOCK_INPUT;
 
@@ -4192,11 +4271,14 @@ Value is t if tooltip was open, nil otherwise.  */)
 
 
 \f
-#ifdef TARGET_API_MAC_CARBON
+#if TARGET_API_MAC_CARBON
 /***********************************************************************
                        File selection dialog
  ***********************************************************************/
 
+static pascal void mac_nav_event_callback P_ ((NavEventCallbackMessage,
+                                              NavCBRecPtr, void *));
+
 /**
    There is a relatively standard way to do this using applescript to run
    a (choose file) method.  However, this doesn't do "the right thing"
@@ -4208,22 +4290,24 @@ Value is t if tooltip was open, nil otherwise.  */)
 
 extern Lisp_Object Qfile_name_history;
 
-DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0,
+DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
        doc: /* Read file name, prompting with PROMPT in directory DIR.
 Use a file selection dialog.
 Select DEFAULT-FILENAME in the dialog's file selection box, if
-specified.  Ensure that file exists if MUSTMATCH is non-nil.  */)
-  (prompt, dir, default_filename, mustmatch)
-     Lisp_Object prompt, dir, default_filename, mustmatch;
+specified.  Ensure that file exists if MUSTMATCH is non-nil.
+If ONLY-DIR-P is non-nil, the user can only select directories.  */)
+  (prompt, dir, default_filename, mustmatch, only_dir_p)
+     Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
 {
   struct frame *f = SELECTED_FRAME ();
   Lisp_Object file = Qnil;
   int count = SPECPDL_INDEX ();
-  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
-  char filename[1001];
+  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
+  char filename[MAXPATHLEN];
   int default_filter_index = 1; /* 1: All Files, 2: Directories only  */
+  static NavEventUPP mac_nav_event_callbackUPP = NULL;
 
-  GCPRO5 (prompt, dir, default_filename, mustmatch, file);
+  GCPRO6 (prompt, dir, default_filename, mustmatch, file, only_dir_p);
   CHECK_STRING (prompt);
   CHECK_STRING (dir);
 
@@ -4237,8 +4321,9 @@ specified.  Ensure that file exists if MUSTMATCH is non-nil.  */)
     NavDialogRef dialogRef;
     NavTypeListHandle fileTypes = NULL;
     NavUserAction userAction;
-    CFStringRef message=NULL, client=NULL, saveName = NULL;
+    CFStringRef message=NULL, saveName = NULL;
     
+    BLOCK_INPUT;
     /* No need for a callback function because we are modal */
     NavGetDefaultDialogCreationOptions(&options);
     options.modality = kWindowModalityAppModal;
@@ -4248,51 +4333,49 @@ specified.  Ensure that file exists if MUSTMATCH is non-nil.  */)
     options.optionFlags |= kNavSelectAllReadableItem;
     if (!NILP(prompt))
       {
-       message = CFStringCreateWithCStringNoCopy(NULL, SDATA(prompt),
-                                                 kCFStringEncodingUTF8, 
-                                                 kCFAllocatorNull);
+       message =
+         cfstring_create_with_utf8_cstring (SDATA (ENCODE_UTF_8 (prompt)));
        options.message = message;
       }
     /* Don't set the application, let it use default.
-    client = CFStringCreateWithCStringNoCopy(NULL, "Emacs", 
-                                            kCFStringEncodingMacRoman, NULL);
-    options.clientName = client;
+    options.clientName = CFSTR ("Emacs");
     */
 
-    /* Do Dired hack copied from w32fns.c */ 
-    if (!NILP(prompt) && strncmp (SDATA(prompt), "Dired", 5) == 0)
-      status = NavCreateChooseFolderDialog(&options, NULL, NULL, NULL,
-                                          &dialogRef);
+    if (mac_nav_event_callbackUPP == NULL)
+      mac_nav_event_callbackUPP = NewNavEventUPP (mac_nav_event_callback);
+
+    if (!NILP (only_dir_p))
+      status = NavCreateChooseFolderDialog(&options, mac_nav_event_callbackUPP,
+                                          NULL, NULL, &dialogRef);
     else if (NILP (mustmatch)) 
       { 
        /* This is a save dialog */
+       options.optionFlags |= kNavDontConfirmReplacement;
+       options.actionButtonLabel = CFSTR ("Ok");
+       options.windowTitle = CFSTR ("Enter name");
+
        if (!NILP(default_filename))
          {
-           saveName = CFStringCreateWithCString(NULL, SDATA(default_filename),
-                                                kCFStringEncodingUTF8);
+           Lisp_Object utf8 = ENCODE_UTF_8 (default_filename);
+           char *begPtr = SDATA(utf8);
+           char *filePtr = begPtr + SBYTES(utf8);
+           while (filePtr != begPtr && !IS_DIRECTORY_SEP(filePtr[-1]))
+             filePtr--;
+           saveName = cfstring_create_with_utf8_cstring (filePtr);
            options.saveFileName = saveName;
            options.optionFlags |= kNavSelectDefaultLocation;
          }
-       /* MAC_TODO: Find a better way to determine if this is a save
-          or load dialog than comparing dir with default_filename */
-       if (EQ(dir, default_filename)) 
-         {
-           status = NavCreateChooseFileDialog(&options, fileTypes,
-                                              NULL, NULL, NULL, NULL, 
-                                              &dialogRef);
-         }
-       else {
          status = NavCreatePutFileDialog(&options, 
                                          'TEXT', kNavGenericSignature,
-                                         NULL, NULL, &dialogRef);
+                                         mac_nav_event_callbackUPP, NULL,
+                                         &dialogRef);
        }
-      }
     else
       {
        /* This is an open dialog*/
        status = NavCreateChooseFileDialog(&options, fileTypes,
-                                          NULL, NULL, NULL, NULL, 
-                                          &dialogRef);
+                                          mac_nav_event_callbackUPP, NULL,
+                                          NULL, NULL, &dialogRef);
       }
     
     /* Set the default location and continue*/
@@ -4300,22 +4383,19 @@ specified.  Ensure that file exists if MUSTMATCH is non-nil.  */)
       if (!NILP(dir)) {
        FSRef defLoc;
        AEDesc defLocAed;
-       status = FSPathMakeRef(SDATA(dir), &defLoc, NULL);
+       status = FSPathMakeRef(SDATA(ENCODE_FILE(dir)), &defLoc, NULL);
        if (status == noErr) 
          {
            AECreateDesc(typeFSRef, &defLoc, sizeof(FSRef), &defLocAed);
            NavCustomControl(dialogRef, kNavCtlSetLocation, (void*) &defLocAed);
+           AEDisposeDesc(&defLocAed);
          }
-       AEDisposeDesc(&defLocAed);
       }
 
-      BLOCK_INPUT;
       status = NavDialogRun(dialogRef);
-      UNBLOCK_INPUT;
     }
 
     if (saveName) CFRelease(saveName);
-    if (client) CFRelease(client);
     if (message) CFRelease(message);
 
     if (status == noErr) {
@@ -4324,9 +4404,7 @@ specified.  Ensure that file exists if MUSTMATCH is non-nil.  */)
        {
        case kNavUserActionNone:
        case kNavUserActionCancel:
-         NavDialogDispose(dialogRef);
-         Fsignal (Qquit, Qnil);  /* Treat cancel like C-g */
-         return;
+         break;                /* Treat cancel like C-g */
        case kNavUserActionOpen:
        case kNavUserActionChoose:
        case kNavUserActionSaveAs:
@@ -4337,7 +4415,7 @@ specified.  Ensure that file exists if MUSTMATCH is non-nil.  */)
            status = NavDialogGetReply(dialogRef, &reply);
            AECoerceDesc(&reply.selection, typeFSRef, &aed);
            AEGetDescData(&aed, (void *) &fsRef, sizeof (FSRef));
-           FSRefMakePath(&fsRef, (UInt8 *) filename, 1000);
+           FSRefMakePath(&fsRef, (UInt8 *) filename, sizeof (filename));
            AEDisposeDesc(&aed);
            if (reply.saveFileName)
              {
@@ -4346,9 +4424,11 @@ specified.  Ensure that file exists if MUSTMATCH is non-nil.  */)
                if (len && filename[len-1] != '/')
                  filename[len++] = '/';
                CFStringGetCString(reply.saveFileName, filename+len, 
-                                  1000-len, kCFStringEncodingUTF8);
+                                  sizeof (filename) - len,
+                                  kCFStringEncodingUTF8);
              }
-           file = DECODE_FILE(build_string (filename));
+           file = DECODE_FILE (make_unibyte_string (filename,
+                                                    strlen (filename)));
            NavDisposeReply(&reply);
          }
          break;
@@ -4361,6 +4441,7 @@ specified.  Ensure that file exists if MUSTMATCH is non-nil.  */)
                               dir, mustmatch, dir, Qfile_name_history,
                               default_filename, Qnil);
     }
+    UNBLOCK_INPUT;
   }
 
   UNGCPRO;
@@ -4373,6 +4454,15 @@ specified.  Ensure that file exists if MUSTMATCH is non-nil.  */)
 }
 
 
+/* Need to register some event callback function for enabling drag and
+   drop in Navigation Service dialogs.  */
+static pascal void
+mac_nav_event_callback (selector, parms, data)
+     NavEventCallbackMessage selector;
+     NavCBRecPtr parms;
+     void *data ;
+{
+}
 #endif
 \f
 /***********************************************************************
@@ -4409,17 +4499,22 @@ frame_parm_handler mac_frame_parm_handlers[] =
   0, /* MAC_TODO: x_set_scroll_bar_background, */
   x_set_screen_gamma,
   x_set_line_spacing,
-  0, /* MAC_TODO: x_set_fringe_width, */
-  0, /* MAC_TODO: x_set_fringe_width, */
+  x_set_fringe_width,
+  x_set_fringe_width,
   0, /* x_set_wait_for_wm, */
-  0, /* MAC_TODO: x_set_fullscreen, */
+  x_set_fullscreen,
 };
 
 void
 syms_of_macfns ()
 {
-  /* Certainly running on Mac.  */
+#ifdef MAC_OSX
+  /* This is zero if not using Mac native windows.  */
+  mac_in_use = 0;
+#else
+  /* Certainly running on Mac native windows.  */
   mac_in_use = 1;
+#endif
 
   /* The section below is built by the lisp expression at the top of the file,
      just above where these variables are declared.  */
@@ -4543,10 +4638,8 @@ Chinese, Japanese, and Korean.  */);
   defsubr (&Sx_display_backing_store);
   defsubr (&Sx_display_save_under);
   defsubr (&Sx_create_frame);
-#if 0 /* MAC_TODO: implement network support */
   defsubr (&Sx_open_connection);
   defsubr (&Sx_close_connection);
-#endif
   defsubr (&Sx_display_list);
   defsubr (&Sx_synchronize);