(update_frame_tool_bar): Use -1 as index
[bpt/emacs.git] / src / macfns.c
index 2df3b4e..34f8094 100644 (file)
@@ -1,12 +1,12 @@
 /* Graphical user interface functions for Mac OS.
    Copyright (C) 2000, 2001, 2002, 2003, 2004,
-                 2005, 2006 Free Software Foundation, Inc.
+                 2005, 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -218,9 +218,6 @@ void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
-
-extern void mac_get_window_bounds P_ ((struct frame *, Rect *, Rect *));
-
 \f
 
 /* Store the screen positions of frame F into XPTR and YPTR.
@@ -1685,6 +1682,25 @@ x_set_tool_bar_lines (f, value, oldval)
   /* Make sure we redisplay all windows in this frame.  */
   ++windows_or_buffers_changed;
 
+#if USE_MAC_TOOLBAR
+  FRAME_TOOL_BAR_LINES (f) = 0;
+  if (nlines)
+    {
+      FRAME_EXTERNAL_TOOL_BAR (f) = 1;
+      if (FRAME_MAC_P (f) && !IsWindowToolbarVisible (FRAME_MAC_WINDOW (f)))
+       /* Make sure next redisplay shows the tool bar.  */
+       XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
+    }
+  else
+    {
+      if (FRAME_EXTERNAL_TOOL_BAR (f))
+        free_frame_tool_bar (f);
+      FRAME_EXTERNAL_TOOL_BAR (f) = 0;
+    }
+
+  return;
+#endif
+
   delta = nlines - FRAME_TOOL_BAR_LINES (f);
 
   /* Don't resize the tool-bar to more than we have room for.  */
@@ -1909,24 +1925,6 @@ x_set_scroll_bar_default_width (f)
 #endif /* not MAC_OSX */
 }
 
-void
-mac_set_scroll_bar_width (f, arg, oldval)
-     struct frame *f;
-     Lisp_Object arg, oldval;
-{
-#ifdef MAC_OSX
-  if (INTEGERP (arg) && XINT (arg) > 0)
-    {
-      if (XINT (arg) < (MAC_AQUA_SMALL_VERTICAL_SCROLL_BAR_WIDTH
-                       + MAC_AQUA_VERTICAL_SCROLL_BAR_WIDTH) / 2)
-       XSETINT (arg, MAC_AQUA_SMALL_VERTICAL_SCROLL_BAR_WIDTH);
-      else
-       XSETINT (arg, MAC_AQUA_VERTICAL_SCROLL_BAR_WIDTH);
-    }
-#endif
-  x_set_scroll_bar_width (f, arg, oldval);
-}
-
 static void
 mac_set_font (f, arg, oldval)
      struct frame *f;
@@ -1969,9 +1967,9 @@ mac_update_proxy_icon (f)
     {
       AEDesc desc;
 #ifdef MAC_OSX
-      FSRef fref;
+      FSRef fref, fref_proxy;
 #else
-      FSSpec fss;
+      FSSpec fss, fss_proxy;
 #endif
       Boolean changed;
       Lisp_Object encoded_file_name = ENCODE_FILE (file_name);
@@ -1997,10 +1995,19 @@ mac_update_proxy_icon (f)
        {
          if (alias)
            {
+             /* (FS)ResolveAlias never sets `changed' to true if
+                `alias' is minimal.  */
 #ifdef MAC_OSX
-             err = FSUpdateAlias (NULL, &fref, alias, &changed);
+             err = FSResolveAlias (NULL, alias, &fref_proxy, &changed);
+             if (err == noErr)
+               err = FSCompareFSRefs (&fref, &fref_proxy);
 #else
-             err = UpdateAlias (NULL, &fss, alias, &changed);
+             err = ResolveAlias (NULL, alias, &fss_proxy, &changed);
+             if (err == noErr)
+               err = !(fss.vRefNum == fss_proxy.vRefNum
+                       && fss.parID == fss_proxy.parID
+                       && EqualString (fss.name, fss_proxy.name,
+                                       false, true));
 #endif
            }
          if (err != noErr || alias == NULL)
@@ -2051,11 +2058,11 @@ mac_update_title_bar (f, save_match_data)
         confusing.  */
       || (!MINI_WINDOW_P (w)
          && (modified_p != !NILP (w->last_had_star))))
-    SetWindowModified (FRAME_MAC_WINDOW (f),
-                      !MINI_WINDOW_P (w) && modified_p);
-
-  if (windows_or_buffers_changed)
-    mac_update_proxy_icon (f);
+    {
+      SetWindowModified (FRAME_MAC_WINDOW (f),
+                        !MINI_WINDOW_P (w) && modified_p);
+      mac_update_proxy_icon (f);
+    }
 #endif
 }
 
@@ -2272,11 +2279,11 @@ mac_window (f)
          FRAME_MAC_WINDOW (f) = NULL;
        }
     }
-#else
+#else  /* !TARGET_API_MAC_CARBON */
   FRAME_MAC_WINDOW (f)
     = NewCWindow (NULL, &r, "\p", false, zoomDocProc,
-                 (WindowPtr) -1, 1, (long) f->output_data.mac);
-#endif
+                 (WindowRef) -1, 1, (long) f->output_data.mac);
+#endif  /* !TARGET_API_MAC_CARBON */
   /* so that update events can find this mac_output struct */
   f->output_data.mac->mFP = f;  /* point back to emacs frame */
 
@@ -2296,6 +2303,16 @@ mac_window (f)
     XSetWindowBackground (FRAME_MAC_DISPLAY(f), FRAME_MAC_WINDOW (f),
                          FRAME_BACKGROUND_PIXEL (f));
 
+#if USE_MAC_TOOLBAR
+  /* At the moment, the size of the tool bar is not yet known.  We
+     record the gravity value of the newly created window and use it
+     to adjust the position of the window (especially for a negative
+     specification of its vertical position) when the tool bar is
+     first redisplayed.  */
+  if (FRAME_EXTERNAL_TOOL_BAR (f))
+    f->output_data.mac->toolbar_win_gravity = f->win_gravity;
+#endif
+
   validate_x_resource_name ();
 
   /* x_set_name normally ignores requests to set the name if the
@@ -2854,9 +2871,31 @@ FRAME nil means use the selected frame.  */)
      (frame)
      Lisp_Object frame;
 {
+  OSErr err;
+  ProcessSerialNumber front_psn;
+  static const ProcessSerialNumber current_psn = {0, kCurrentProcess};
+  Boolean front_p;
   struct frame *f = check_x_frame (frame);
 
   BLOCK_INPUT;
+  /* Move the current process to the foreground if it is not.  Don't
+     call SetFrontProcess if the current process is already running in
+     the foreground so as not to change the z-order of windows.  */
+  err = GetFrontProcess (&front_psn);
+  if (err == noErr)
+    err = SameProcess (&front_psn, &current_psn, &front_p);
+  if (err == noErr)
+    if (!front_p)
+      {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+       if (FrontNonFloatingWindow () == FRAME_MAC_WINDOW (f))
+         SetFrontProcessWithOptions (&current_psn,
+                                     kSetFrontProcessFrontWindowOnly);
+       else
+#endif
+         SetFrontProcess (&current_psn);
+      }
+
 #ifdef MAC_OSX
   ActivateWindow (ActiveNonFloatingWindow (), false);
   ActivateWindow (FRAME_MAC_WINDOW (f), true);
@@ -3021,7 +3060,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
      (display)
      Lisp_Object display;
 {
-  return build_string ("Apple Computers");
+  return build_string ("Apple Inc.");
 }
 
 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
@@ -3092,8 +3131,8 @@ If omitted or nil, that stands for the selected frame's display.  */)
      Lisp_Object display;
 {
   struct mac_display_info *dpyinfo = check_x_display_info (display);
+  float mm_per_pixel;
 
-  /* Only of the main display.  */
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
   if (CGDisplayScreenSize != NULL)
@@ -3103,20 +3142,21 @@ If omitted or nil, that stands for the selected frame's display.  */)
 
       BLOCK_INPUT;
       size = CGDisplayScreenSize (kCGDirectMainDisplay);
+      mm_per_pixel = size.height / CGDisplayPixelsHigh (kCGDirectMainDisplay);
       UNBLOCK_INPUT;
-
-      return make_number ((int) (size.height + .5f));
     }
 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
-  else
+  else                         /* CGDisplayScreenSize == NULL */
 #endif
 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030  */
 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
     {
       /* This is an approximation.  */
-      return make_number ((int) (dpyinfo->height * 25.4 / dpyinfo->resy));
+      mm_per_pixel = 25.4f / dpyinfo->resy;
     }
 #endif
+
+  return make_number ((int) (dpyinfo->height * mm_per_pixel + 0.5f));
 }
 
 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
@@ -3128,8 +3168,8 @@ If omitted or nil, that stands for the selected frame's display.  */)
      Lisp_Object display;
 {
   struct mac_display_info *dpyinfo = check_x_display_info (display);
+  float mm_per_pixel;
 
-  /* Only of the main display.  */
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
   if (CGDisplayScreenSize != NULL)
@@ -3139,20 +3179,21 @@ If omitted or nil, that stands for the selected frame's display.  */)
 
       BLOCK_INPUT;
       size = CGDisplayScreenSize (kCGDirectMainDisplay);
+      mm_per_pixel = size.width / CGDisplayPixelsWide (kCGDirectMainDisplay);
       UNBLOCK_INPUT;
-
-      return make_number ((int) (size.width + .5f));
     }
 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
-  else
+  else                         /* CGDisplayScreenSize == NULL */
 #endif
 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030  */
 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
     {
       /* This is an approximation.  */
-      return make_number ((int) (dpyinfo->width * 25.4 / dpyinfo->resx));
+      mm_per_pixel = 25.4f / dpyinfo->resx;
     }
 #endif
+
+  return make_number ((int) (dpyinfo->width * mm_per_pixel + 0.5f));
 }
 
 DEFUN ("x-display-backing-store", Fx_display_backing_store,
@@ -4061,8 +4102,12 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
       Point mouse_pos;
 
       BLOCK_INPUT;
+#if TARGET_API_MAC_CARBON
+      GetGlobalMouse (&mouse_pos);
+#else
       GetMouse (&mouse_pos);
       LocalToGlobal (&mouse_pos);
+#endif
       *root_x = mouse_pos.h;
       *root_y = mouse_pos.v;
       UNBLOCK_INPUT;
@@ -4102,6 +4147,8 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
        doc: /* Show STRING in a "tooltip" window on frame FRAME.
 A tooltip window is a small window displaying a string.
 
+This is an internal function; Lisp code should call `tooltip-show'.
+
 FRAME nil or omitted means use the selected frame.
 
 PARMS is an optional list of frame parameters which can be used to
@@ -4504,7 +4551,7 @@ If ONLY-DIR-P is non-nil, the user can only select directories.  */)
                      filename[len++] = '/';
                    CFStringGetCString(reply.saveFileName, filename+len,
                                       sizeof (filename) - len,
-#if MAC_OSX
+#ifdef MAC_OSX
                                       kCFStringEncodingUTF8
 #else
                                       CFStringGetSystemEncoding ()
@@ -4566,22 +4613,22 @@ DEFUN ("mac-clear-font-name-table", Fmac_clear_font_name_table,
 }
 
 #if USE_MAC_FONT_PANEL
-DEFUN ("mac-set-font-panel-visibility", Fmac_set_font_panel_visibility,
-       Smac_set_font_panel_visibility, 1, 1, 0,
-  doc: /* Make the font panel visible if and only if VISIBLE is non-nil.
+DEFUN ("mac-set-font-panel-visible-p", Fmac_set_font_panel_visible_p,
+       Smac_set_font_panel_visible_p, 1, 1, 0,
+  doc: /* Make the font panel visible if and only if FLAG is non-nil.
 This is for internal use only.  Use `mac-font-panel-mode' instead.  */)
-     (visible)
-     Lisp_Object visible;
+     (flag)
+     Lisp_Object flag;
 {
   OSStatus err = noErr;
 
   check_mac ();
 
   BLOCK_INPUT;
-  if (NILP (visible) != !mac_font_panel_visible_p ())
+  if (NILP (flag) != !mac_font_panel_visible_p ())
     {
       err = mac_show_hide_font_panel ();
-      if (err == noErr && !NILP (visible))
+      if (err == noErr && !NILP (flag))
        {
          Lisp_Object focus_frame = x_get_focus_frame (SELECTED_FRAME ());
          struct frame *f = (NILP (focus_frame) ? SELECTED_FRAME ()
@@ -4597,6 +4644,30 @@ This is for internal use only.  Use `mac-font-panel-mode' instead.  */)
   return Qnil;
 }
 #endif
+
+#if USE_ATSUI
+extern Lisp_Object mac_atsu_font_face_attributes P_ ((ATSUFontID));
+
+DEFUN ("mac-atsu-font-face-attributes", Fmac_atsu_font_face_attributes,
+       Smac_atsu_font_face_attributes, 1, 1, 0,
+  doc: /* Return plist of face attributes and values for ATSU font ID.
+ID is specified by either an integer or a float.  */)
+     (id)
+     Lisp_Object id;
+{
+  ATSUFontID font_id;
+  Lisp_Object result;
+
+  check_mac ();
+  CHECK_NUMBER_OR_FLOAT(id);
+  font_id = NUMBERP (id) ? XINT (id) : (ATSUFontID) XFLOAT (id);
+  BLOCK_INPUT;
+  result = mac_atsu_font_face_attributes (font_id);
+  UNBLOCK_INPUT;
+  return result;
+}
+#endif
+
 \f
 /***********************************************************************
                            Initialization
@@ -4622,7 +4693,7 @@ frame_parm_handler mac_frame_parm_handlers[] =
   x_set_menu_bar_lines,
   x_set_mouse_color,
   x_explicitly_set_name,
-  mac_set_scroll_bar_width,
+  x_set_scroll_bar_width,
   x_set_title,
   x_set_unsplittable,
   x_set_vertical_scroll_bars,
@@ -4827,7 +4898,10 @@ Chinese, Japanese, and Korean.  */);
 #endif
   defsubr (&Smac_clear_font_name_table);
 #if USE_MAC_FONT_PANEL
-  defsubr (&Smac_set_font_panel_visibility);
+  defsubr (&Smac_set_font_panel_visible_p);
+#endif
+#if USE_ATSUI
+  defsubr (&Smac_atsu_font_face_attributes);
 #endif
 }