]> code.delx.au - gnu-emacs/blobdiff - src/macterm.c
(update_text_area): Avoid needless redraw of rightmost
[gnu-emacs] / src / macterm.c
index 5d8fb1d5f513aadc7e7e72e992455c70e2562a44..5fd416be6b85dd93df32d19f4a188016dde3e198 100644 (file)
@@ -1,6 +1,6 @@
 /* Implementation of GUI terminal on the Mac OS.
    Copyright (C) 2000, 2001, 2002, 2003, 2004,
-                 2005 Free Software Foundation, Inc.
+                 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -68,7 +68,6 @@ Boston, MA 02110-1301, USA.  */
 #include <errno.h>
 #include <setjmp.h>
 #include <sys/stat.h>
-#include <sys/param.h>
 
 #include "charset.h"
 #include "coding.h"
@@ -93,8 +92,9 @@ Boston, MA 02110-1301, USA.  */
 
 Lisp_Object Vx_toolkit_scroll_bars;
 
-/* If Non-nil, the text will be rendered using Core Graphics text rendering which may anti-alias the text.  */
-Lisp_Object Vmac_use_core_graphics;
+/* If non-zero, the text will be rendered using Core Graphics text
+   rendering which may anti-alias the text.  */
+int mac_use_core_graphics;
 
 
 /* Non-zero means that a HELP_EVENT has been generated since Emacs
@@ -105,6 +105,10 @@ static int any_help_event_p;
 /* Last window where we saw the mouse.  Used by mouse-autoselect-window.  */
 static Lisp_Object last_window;
 
+/* Non-zero means make use of UNDERLINE_POSITION font properties.
+   (Not yet supported.)  */
+int x_use_underline_position_properties;
+
 /* This is a chain of structures for all the X displays currently in
    use.  */
 
@@ -199,8 +203,7 @@ extern EMACS_INT extra_keyboard_modifiers;
 
 /* The keysyms to use for the various modifiers.  */
 
-static Lisp_Object Qalt, Qhyper, Qsuper, Qcontrol,
-  Qmeta, Qmodifier_value;
+static Lisp_Object Qalt, Qhyper, Qsuper, Qcontrol, Qmeta, Qmodifier_value;
 
 extern int inhibit_window_system;
 
@@ -255,7 +258,7 @@ static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
                                            unsigned long *));
 
 static int is_emacs_window P_ ((WindowPtr));
-
+static XCharStruct *mac_per_char_metric P_ ((XFontStruct *, XChar2b *, int));
 static void XSetFont P_ ((Display *, GC, XFontStruct *));
 
 /* Defined in macmenu.h.  */
@@ -264,14 +267,13 @@ extern void menubar_selection_callback (FRAME_PTR, int);
 #define GC_FORE_COLOR(gc)      (&(gc)->fore_color)
 #define GC_BACK_COLOR(gc)      (&(gc)->back_color)
 #define GC_FONT(gc)            ((gc)->xgcv.font)
-#define GC_CLIP_REGION(gc)     ((gc)->clip_region)
 #define FRAME_NORMAL_GC(f)     ((f)->output_data.mac->normal_gc)
 
 static RgnHandle saved_port_clip_region = NULL;
 
 static void
-mac_begin_clip (region)
-     RgnHandle region;
+mac_begin_clip (gc)
+     GC gc;
 {
   static RgnHandle new_region = NULL;
 
@@ -280,19 +282,19 @@ mac_begin_clip (region)
   if (new_region == NULL)
     new_region = NewRgn ();
 
-  if (region)
+  if (gc->n_clip_rects)
     {
       GetClip (saved_port_clip_region);
-      SectRgn (saved_port_clip_region, region, new_region);
+      SectRgn (saved_port_clip_region, gc->clip_region, new_region);
       SetClip (new_region);
     }
 }
 
 static void
-mac_end_clip (region)
-     RgnHandle region;
+mac_end_clip (gc)
+     GC gc;
 {
-  if (region)
+  if (gc->n_clip_rects)
     SetClip (saved_port_clip_region);
 }
 
@@ -320,10 +322,10 @@ mac_draw_line (f, gc, x1, y1, x2, y2)
 
   RGBForeColor (GC_FORE_COLOR (gc));
 
-  mac_begin_clip (GC_CLIP_REGION (gc));
+  mac_begin_clip (gc);
   MoveTo (x1, y1);
   LineTo (x2, y2);
-  mac_end_clip (GC_CLIP_REGION (gc));
+  mac_end_clip (gc);
 }
 
 void
@@ -364,9 +366,9 @@ mac_erase_rectangle (f, gc, x, y, width, height)
   RGBBackColor (GC_BACK_COLOR (gc));
   SetRect (&r, x, y, x + width, y + height);
 
-  mac_begin_clip (GC_CLIP_REGION (gc));
+  mac_begin_clip (gc);
   EraseRect (&r);
-  mac_end_clip (GC_CLIP_REGION (gc));
+  mac_end_clip (gc);
 
   RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
 }
@@ -429,7 +431,7 @@ mac_draw_bitmap (f, gc, x, y, width, height, bits, overlay_p)
   RGBBackColor (GC_BACK_COLOR (gc));
   SetRect (&r, x, y, x + width, y + height);
 
-  mac_begin_clip (GC_CLIP_REGION (gc));
+  mac_begin_clip (gc);
 #if TARGET_API_MAC_CARBON
   {
     CGrafPtr port;
@@ -444,7 +446,7 @@ mac_draw_bitmap (f, gc, x, y, width, height, bits, overlay_p)
   CopyBits (&bitmap, &(FRAME_MAC_WINDOW (f)->portBits), &(bitmap.bounds), &r,
            overlay_p ? srcOr : srcCopy, 0);
 #endif /* not TARGET_API_MAC_CARBON */
-  mac_end_clip (GC_CLIP_REGION (gc));
+  mac_end_clip (gc);
 
   RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
 }
@@ -576,9 +578,9 @@ mac_fill_rectangle (f, gc, x, y, width, height)
   RGBForeColor (GC_FORE_COLOR (gc));
   SetRect (&r, x, y, x + width, y + height);
 
-  mac_begin_clip (GC_CLIP_REGION (gc));
+  mac_begin_clip (gc);
   PaintRect (&r); /* using foreground color of gc */
-  mac_end_clip (GC_CLIP_REGION (gc));
+  mac_end_clip (gc);
 }
 
 
@@ -598,9 +600,9 @@ mac_draw_rectangle (f, gc, x, y, width, height)
   RGBForeColor (GC_FORE_COLOR (gc));
   SetRect (&r, x, y, x + width + 1, y + height + 1);
 
-  mac_begin_clip (GC_CLIP_REGION (gc));
+  mac_begin_clip (gc);
   FrameRect (&r); /* using foreground color of gc */
-  mac_end_clip (GC_CLIP_REGION (gc));
+  mac_end_clip (gc);
 }
 
 
@@ -623,6 +625,7 @@ atsu_get_text_layout_with_text_ptr (text, text_length, style, text_layout)
       static ATSLineLayoutOptions line_layout =
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
        kATSLineDisableAllLayoutOperations | kATSLineUseDeviceMetrics
+       | kATSLineUseQDRendering
 #else
        kATSLineIsDisplayOnly | kATSLineFractDisable
 #endif
@@ -678,27 +681,15 @@ mac_invert_rectangle (f, x, y, width, height)
 
 
 static void
-mac_draw_string_common (f, gc, x, y, buf, nchars, mode, bytes_per_char)
+mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width, bytes_per_char)
      struct frame *f;
      GC gc;
      int x, y;
      char *buf;
-     int nchars, mode, bytes_per_char;
+     int nchars, bg_width, bytes_per_char;
 {
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
-  UInt32 textFlags, savedFlags;
-  if (!NILP(Vmac_use_core_graphics)) {
-    textFlags = kQDUseCGTextRendering;
-    savedFlags = SwapQDTextFlags(textFlags);
-  }
-#endif
-
   SetPortWindowPort (FRAME_MAC_WINDOW (f));
 
-  RGBForeColor (GC_FORE_COLOR (gc));
-  if (mode != srcOr)
-    RGBBackColor (GC_BACK_COLOR (gc));
-
 #if USE_ATSUI
   if (GC_FONT (gc)->mac_style)
     {
@@ -720,91 +711,144 @@ mac_draw_string_common (f, gc, x, y, buf, nchars, mode, bytes_per_char)
                                                nchars,
                                                GC_FONT (gc)->mac_style,
                                                &text_layout);
-      if (err == noErr)
-       {
+      if (err != noErr)
+       return;
 #ifdef MAC_OSX
-         if (NILP (Vmac_use_core_graphics))
-           {
+      if (!mac_use_core_graphics)
+       {
 #endif
-             mac_begin_clip (GC_CLIP_REGION (gc));
-             MoveTo (x, y);
-             ATSUDrawText (text_layout,
-                           kATSUFromTextBeginning, kATSUToTextEnd,
-                           kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
-             mac_end_clip (GC_CLIP_REGION (gc));
-#ifdef MAC_OSX
+         mac_begin_clip (gc);
+         RGBForeColor (GC_FORE_COLOR (gc));
+         if (bg_width)
+           {
+             Rect r;
+
+             SetRect (&r, x, y - FONT_BASE (GC_FONT (gc)),
+                      x + bg_width, y + FONT_DESCENT (GC_FONT (gc)));
+             RGBBackColor (GC_BACK_COLOR (gc));
+             EraseRect (&r);
+             RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
            }
-         else
+         MoveTo (x, y);
+         ATSUDrawText (text_layout,
+                       kATSUFromTextBeginning, kATSUToTextEnd,
+                       kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
+         mac_end_clip (gc);
+#ifdef MAC_OSX
+       }
+      else
+       {
+         CGrafPtr port;
+         CGContextRef context;
+         float port_height = FRAME_PIXEL_HEIGHT (f);
+         ATSUAttributeTag tags[] = {kATSUCGContextTag};
+         ByteCount sizes[] = {sizeof (CGContextRef)};
+         ATSUAttributeValuePtr values[] = {&context};
+
+         GetPort (&port);
+         QDBeginCGContext (port, &context);
+         if (gc->n_clip_rects || bg_width)
            {
-             CGrafPtr port;
-             CGContextRef context;
-             float port_height = FRAME_PIXEL_HEIGHT (f);
-             ATSUAttributeTag tags[] = {kATSUCGContextTag};
-             ByteCount sizes[] = {sizeof (CGContextRef)};
-             ATSUAttributeValuePtr values[] = {&context};
-
-             GetPort (&port);
-             QDBeginCGContext (port, &context);
+             CGContextTranslateCTM (context, 0, port_height);
+             CGContextScaleCTM (context, 1, -1);
              if (gc->n_clip_rects)
+               CGContextClipToRects (context, gc->clip_rects,
+                                     gc->n_clip_rects);
+             if (bg_width)
                {
-                 CGContextTranslateCTM (context, 0, port_height);
-                 CGContextScaleCTM (context, 1, -1);
-                 CGContextClipToRects (context, gc->clip_rects,
-                                       gc->n_clip_rects);
-                 CGContextScaleCTM (context, 1, -1);
-                 CGContextTranslateCTM (context, 0, -port_height);
+                 CGContextSetRGBFillColor
+                   (context,
+                    RED_FROM_ULONG (gc->xgcv.background) / 255.0f,
+                    GREEN_FROM_ULONG (gc->xgcv.background) / 255.0f,
+                    BLUE_FROM_ULONG (gc->xgcv.background) / 255.0f,
+                    1.0);
+                 CGContextFillRect
+                   (context,
+                    CGRectMake (x, y - FONT_BASE (GC_FONT (gc)),
+                                bg_width, FONT_HEIGHT (GC_FONT (gc))));
                }
-             CGContextSetRGBFillColor
-               (context,
-                RED_FROM_ULONG (gc->xgcv.foreground) / 255.0,
-                GREEN_FROM_ULONG (gc->xgcv.foreground) / 255.0,
-                BLUE_FROM_ULONG (gc->xgcv.foreground) / 255.0,
-                1.0);
-             err = ATSUSetLayoutControls (text_layout,
-                                          sizeof (tags) / sizeof (tags[0]),
-                                          tags, sizes, values);
-             if (err == noErr)
-               ATSUDrawText (text_layout,
-                             kATSUFromTextBeginning, kATSUToTextEnd,
-                             Long2Fix (x), Long2Fix (port_height - y));
-             CGContextSynchronize (context);
-             QDEndCGContext (port, &context);
-#if 0
-             /* This doesn't work on Mac OS X 10.1.  */
-             ATSUClearLayoutControls (text_layout,
+             CGContextScaleCTM (context, 1, -1);
+             CGContextTranslateCTM (context, 0, -port_height);
+           }
+         CGContextSetRGBFillColor
+           (context,
+            RED_FROM_ULONG (gc->xgcv.foreground) / 255.0f,
+            GREEN_FROM_ULONG (gc->xgcv.foreground) / 255.0f,
+            BLUE_FROM_ULONG (gc->xgcv.foreground) / 255.0f,
+            1.0);
+         err = ATSUSetLayoutControls (text_layout,
                                       sizeof (tags) / sizeof (tags[0]),
-                                      tags);
+                                      tags, sizes, values);
+         if (err == noErr)
+           ATSUDrawText (text_layout,
+                         kATSUFromTextBeginning, kATSUToTextEnd,
+                         Long2Fix (x), Long2Fix (port_height - y));
+         CGContextSynchronize (context);
+         QDEndCGContext (port, &context);
+#if 0
+         /* This doesn't work on Mac OS X 10.1.  */
+         ATSUClearLayoutControls (text_layout,
+                                  sizeof (tags) / sizeof (tags[0]), tags);
 #else
-             ATSUSetLayoutControls (text_layout,
-                                    sizeof (tags) / sizeof (tags[0]),
-                                    tags, sizes, values);
-#endif
-           }
+         ATSUSetLayoutControls (text_layout,
+                                sizeof (tags) / sizeof (tags[0]),
+                                tags, sizes, values);
 #endif
        }
+#endif /* MAC_OSX */
     }
   else
+#endif /* USE_ATSUI */
     {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+      UInt32 savedFlags;
+
+      if (mac_use_core_graphics)
+       savedFlags = SwapQDTextFlags (kQDUseCGTextRendering);
 #endif
-  TextFont (GC_FONT (gc)->mac_fontnum);
-  TextSize (GC_FONT (gc)->mac_fontsize);
-  TextFace (GC_FONT (gc)->mac_fontface);
-  TextMode (mode);
+      mac_begin_clip (gc);
+      RGBForeColor (GC_FORE_COLOR (gc));
+#ifdef MAC_OS8
+      if (bg_width)
+       {
+         RGBBackColor (GC_BACK_COLOR (gc));
+         TextMode (srcCopy);
+       }
+      else
+       TextMode (srcOr);
+#else
+      /* We prefer not to use srcCopy text transfer mode on Mac OS X
+        because:
+        - Screen is double-buffered.  (In srcCopy mode, a text is
+          drawn into an offscreen graphics world first.  So
+          performance gain cannot be expected.)
+        - It lowers rendering quality.
+        - Some fonts leave garbage on cursor movement.  */
+      if (bg_width)
+       {
+         Rect r;
 
-  mac_begin_clip (GC_CLIP_REGION (gc));
-  MoveTo (x, y);
-  DrawText (buf, 0, nchars * bytes_per_char);
-  mac_end_clip (GC_CLIP_REGION (gc));
-#if USE_ATSUI
-    }
+         RGBBackColor (GC_BACK_COLOR (gc));
+         SetRect (&r, x, y - FONT_BASE (GC_FONT (gc)),
+                  x + bg_width, y + FONT_DESCENT (GC_FONT (gc)));
+         EraseRect (&r);
+       }
+      TextMode (srcOr);
 #endif
+      TextFont (GC_FONT (gc)->mac_fontnum);
+      TextSize (GC_FONT (gc)->mac_fontsize);
+      TextFace (GC_FONT (gc)->mac_fontface);
+      MoveTo (x, y);
+      DrawText (buf, 0, nchars * bytes_per_char);
+      if (bg_width)
+       RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+      mac_end_clip (gc);
 
-  if (mode != srcOr)
-    RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
-  if (!NILP(Vmac_use_core_graphics))
-    SwapQDTextFlags(savedFlags);
+      if (mac_use_core_graphics)
+       SwapQDTextFlags(savedFlags);
 #endif
+    }
 }
 
 
@@ -818,7 +862,7 @@ mac_draw_string (f, gc, x, y, buf, nchars)
      char *buf;
      int nchars;
 {
-  mac_draw_string_common (f, gc, x, y, buf, nchars, srcOr, 1);
+  mac_draw_string_common (f, gc, x, y, buf, nchars, 0, 1);
 }
 
 
@@ -832,61 +876,214 @@ mac_draw_string_16 (f, gc, x, y, buf, nchars)
      XChar2b *buf;
      int nchars;
 {
-  mac_draw_string_common (f, gc, x, y, (char *) buf, nchars, srcOr, 2);
+  mac_draw_string_common (f, gc, x, y, (char *) buf, nchars, 0, 2);
 }
 
 
 /* Mac replacement for XDrawImageString.  */
 
 static void
-mac_draw_image_string (f, gc, x, y, buf, nchars)
+mac_draw_image_string (f, gc, x, y, buf, nchars, bg_width)
      struct frame *f;
      GC gc;
      int x, y;
      char *buf;
-     int nchars;
+     int nchars, bg_width;
 {
-  mac_draw_string_common (f, gc, x, y, buf, nchars, srcCopy, 1);
+  mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width, 1);
 }
 
 
 /* Mac replacement for XDrawString16.  */
 
 static void
-mac_draw_image_string_16 (f, gc, x, y, buf, nchars)
+mac_draw_image_string_16 (f, gc, x, y, buf, nchars, bg_width)
      struct frame *f;
      GC gc;
      int x, y;
      XChar2b *buf;
-     int nchars;
+     int nchars, bg_width;
 {
-  mac_draw_string_common (f, gc, x, y, (char *) buf, nchars, srcCopy, 2);
+  mac_draw_string_common (f, gc, x, y, (char *) buf, nchars, bg_width, 2);
 }
 
 
+/* Mac replacement for XQueryTextExtents, but takes a character.  If
+   STYLE is NULL, measurement is done by QuickDraw Text routines for
+   the font of the current graphics port.  If CG_GLYPH is not NULL,
+   *CG_GLYPH is set to the glyph ID or 0 if it cannot be obtained.  */
+
+static OSErr
+mac_query_char_extents (style, c,
+                       font_ascent_return, font_descent_return,
+                       overall_return, cg_glyph)
+#if USE_ATSUI
+     ATSUStyle style;
+#else
+     void *style;
+#endif
+     int c;
+     int *font_ascent_return, *font_descent_return;
+     XCharStruct *overall_return;
 #if USE_CG_TEXT_DRAWING
-static XCharStruct *x_per_char_metric P_ ((XFontStruct *, XChar2b *));
+     CGGlyph *cg_glyph;
+#else
+     void *cg_glyph;
+#endif
+{
+  OSErr err = noErr;
+  int width;
+  Rect char_bounds;
+
+#if USE_ATSUI
+  if (style)
+    {
+      ATSUTextLayout text_layout;
+      UniChar ch = c;
+
+      err = atsu_get_text_layout_with_text_ptr (&ch, 1, style, &text_layout);
+      if (err == noErr)
+       {
+         ATSTrapezoid glyph_bounds;
+
+         err = ATSUGetGlyphBounds (text_layout, 0, 0,
+                                   kATSUFromTextBeginning, kATSUToTextEnd,
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+                                   kATSUseFractionalOrigins,
+#else
+                                   kATSUseDeviceOrigins,
+#endif
+                                   1, &glyph_bounds, NULL);
+         if (err == noErr)
+           {
+             xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x
+                      == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x);
+
+             width = Fix2Long (glyph_bounds.upperRight.x
+                               - glyph_bounds.upperLeft.x);
+             if (font_ascent_return)
+               *font_ascent_return = -Fix2Long (glyph_bounds.upperLeft.y);
+             if (font_descent_return)
+               *font_descent_return = Fix2Long (glyph_bounds.lowerLeft.y);
+           }
+       }
+      if (err == noErr && overall_return)
+       {
+         err = ATSUMeasureTextImage (text_layout,
+                                     kATSUFromTextBeginning, kATSUToTextEnd,
+                                     0, 0, &char_bounds);
+         if (err == noErr)
+           STORE_XCHARSTRUCT (*overall_return, width, char_bounds);
+#if USE_CG_TEXT_DRAWING
+         if (err == noErr && cg_glyph)
+           {
+             OSErr err1;
+             ATSUGlyphInfoArray glyph_info_array;
+             ByteCount count = sizeof (ATSUGlyphInfoArray);
+
+             err1 = ATSUMatchFontsToText (text_layout, kATSUFromTextBeginning,
+                                          kATSUToTextEnd, NULL, NULL, NULL);
+             if (err1 == noErr)
+               err1 = ATSUGetGlyphInfo (text_layout, kATSUFromTextBeginning,
+                                        kATSUToTextEnd, &count,
+                                        &glyph_info_array);
+             if (err1 == noErr)
+               {
+                 xassert (glyph_info_array.glyphs[0].glyphID);
+                 *cg_glyph = glyph_info_array.glyphs[0].glyphID;
+               }
+             else
+               *cg_glyph = 0;
+           }
+#endif
+       }
+    }
+  else
+#endif
+    {
+      if (font_ascent_return || font_descent_return)
+       {
+         FontInfo font_info;
+
+         GetFontInfo (&font_info);
+         if (font_ascent_return)
+           *font_ascent_return = font_info.ascent;
+         if (font_descent_return)
+           *font_descent_return = font_info.descent;
+       }
+      if (overall_return)
+       {
+         char ch = c;
+
+         width = CharWidth (ch);
+         QDTextBounds (1, &ch, &char_bounds);
+         STORE_XCHARSTRUCT (*overall_return, width, char_bounds);
+       }
+    }
+
+  return err;
+}
+
+
+/* Mac replacement for XTextExtents16.  Only sets horizontal metrics.  */
+
+static int
+mac_text_extents_16 (font_struct, string, nchars, overall_return)
+     XFontStruct *font_struct;
+     XChar2b *string;
+     int nchars;
+     XCharStruct *overall_return;
+{
+  int i;
+  short width = 0, lbearing = 0, rbearing = 0;
+  XCharStruct *pcm;
+
+  for (i = 0; i < nchars; i++)
+    {
+      pcm = mac_per_char_metric (font_struct, string, 0);
+      if (pcm == NULL)
+       width += FONT_WIDTH (font_struct);
+      else
+       {
+         lbearing = min (lbearing, width + pcm->lbearing);
+         rbearing = max (rbearing, width + pcm->rbearing);
+         width += pcm->width;
+       }
+      string++;
+    }
 
+  overall_return->lbearing = lbearing;
+  overall_return->rbearing = rbearing;
+  overall_return->width = width;
+
+  /* What's the meaning of the return value of XTextExtents16?  */
+}
+
+
+#if USE_CG_TEXT_DRAWING
 static int cg_text_anti_aliasing_threshold = 8;
 
 static void
 init_cg_text_anti_aliasing_threshold ()
 {
-  Lisp_Object val =
-    Fmac_get_preference (build_string ("AppleAntiAliasingThreshold"),
-                        Qnil, Qnil, Qnil);
+  int threshold;
+  Boolean valid_p;
 
-  if (INTEGERP (val))
-    cg_text_anti_aliasing_threshold = XINT (val);
+  threshold =
+    CFPreferencesGetAppIntegerValue (CFSTR ("AppleAntiAliasingThreshold"),
+                                    kCFPreferencesCurrentApplication,
+                                    &valid_p);
+  if (valid_p)
+    cg_text_anti_aliasing_threshold = threshold;
 }
 
 static int
-mac_draw_string_cg (f, gc, x, y, buf, nchars)
+mac_draw_image_string_cg (f, gc, x, y, buf, nchars, bg_width)
      struct frame *f;
      GC gc;
      int x, y;
      XChar2b *buf;
-     int nchars;
+     int nchars, bg_width;
 {
   CGrafPtr port;
   float port_height, gx, gy;
@@ -895,7 +1092,7 @@ mac_draw_string_cg (f, gc, x, y, buf, nchars)
   CGGlyph *glyphs;
   CGSize *advances;
 
-  if (NILP (Vmac_use_core_graphics) || GC_FONT (gc)->cg_font == NULL)
+  if (!mac_use_core_graphics || GC_FONT (gc)->cg_font == NULL)
     return 0;
 
   port = GetWindowPort (FRAME_MAC_WINDOW (f));
@@ -903,28 +1100,46 @@ mac_draw_string_cg (f, gc, x, y, buf, nchars)
   gx = x;
   gy = port_height - y;
   glyphs = (CGGlyph *)buf;
-  advances = xmalloc (sizeof (CGSize) * nchars);
+  advances = alloca (sizeof (CGSize) * nchars);
+  if (advances == NULL)
+    return 0;
   for (i = 0; i < nchars; i++)
     {
-      advances[i].width = x_per_char_metric (GC_FONT (gc), buf)->width;
+      XCharStruct *pcm = mac_per_char_metric (GC_FONT (gc), buf, 0);
+
+      advances[i].width = pcm->width;
       advances[i].height = 0;
       glyphs[i] = GC_FONT (gc)->cg_glyphs[buf->byte2];
       buf++;
     }
 
   QDBeginCGContext (port, &context);
-  if (gc->n_clip_rects)
+  if (gc->n_clip_rects || bg_width)
     {
       CGContextTranslateCTM (context, 0, port_height);
       CGContextScaleCTM (context, 1, -1);
-      CGContextClipToRects (context, gc->clip_rects, gc->n_clip_rects);
+      if (gc->n_clip_rects)
+       CGContextClipToRects (context, gc->clip_rects, gc->n_clip_rects);
+      if (bg_width)
+       {
+         CGContextSetRGBFillColor
+           (context,
+            RED_FROM_ULONG (gc->xgcv.background) / 255.0f,
+            GREEN_FROM_ULONG (gc->xgcv.background) / 255.0f,
+            BLUE_FROM_ULONG (gc->xgcv.background) / 255.0f,
+            1.0);
+         CGContextFillRect
+           (context,
+            CGRectMake (gx, y - FONT_BASE (GC_FONT (gc)),
+                        bg_width, FONT_HEIGHT (GC_FONT (gc))));
+       }
       CGContextScaleCTM (context, 1, -1);
       CGContextTranslateCTM (context, 0, -port_height);
     }
   CGContextSetRGBFillColor (context,
-                           RED_FROM_ULONG (gc->xgcv.foreground) / 255.0,
-                           GREEN_FROM_ULONG (gc->xgcv.foreground) / 255.0,
-                           BLUE_FROM_ULONG (gc->xgcv.foreground) / 255.0,
+                           RED_FROM_ULONG (gc->xgcv.foreground) / 255.0f,
+                           GREEN_FROM_ULONG (gc->xgcv.foreground) / 255.0f,
+                           BLUE_FROM_ULONG (gc->xgcv.foreground) / 255.0f,
                            1.0);
   CGContextSetFont (context, GC_FONT (gc)->cg_font);
   CGContextSetFontSize (context, GC_FONT (gc)->mac_fontsize);
@@ -943,8 +1158,6 @@ mac_draw_string_cg (f, gc, x, y, buf, nchars)
   CGContextSynchronize (context);
   QDEndCGContext (port, &context);
 
-  xfree (advances);
-
   return 1;
 }
 #endif
@@ -971,7 +1184,7 @@ mac_copy_area (src, f, gc, src_x, src_y, width, height, dest_x, dest_y)
   ForeColor (blackColor);
   BackColor (whiteColor);
 
-  mac_begin_clip (GC_CLIP_REGION (gc));
+  mac_begin_clip (gc);
   LockPixels (GetGWorldPixMap (src));
 #if TARGET_API_MAC_CARBON
   {
@@ -989,7 +1202,7 @@ mac_copy_area (src, f, gc, src_x, src_y, width, height, dest_x, dest_y)
            &src_r, &dest_r, srcCopy, 0);
 #endif /* not TARGET_API_MAC_CARBON */
   UnlockPixels (GetGWorldPixMap (src));
-  mac_end_clip (GC_CLIP_REGION (gc));
+  mac_end_clip (gc);
 
   RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
 }
@@ -1015,7 +1228,7 @@ mac_copy_area_with_mask (src, mask, f, gc, src_x, src_y,
   ForeColor (blackColor);
   BackColor (whiteColor);
 
-  mac_begin_clip (GC_CLIP_REGION (gc));
+  mac_begin_clip (gc);
   LockPixels (GetGWorldPixMap (src));
   LockPixels (GetGWorldPixMap (mask));
 #if TARGET_API_MAC_CARBON
@@ -1035,7 +1248,7 @@ mac_copy_area_with_mask (src, mask, f, gc, src_x, src_y,
 #endif /* not TARGET_API_MAC_CARBON */
   UnlockPixels (GetGWorldPixMap (mask));
   UnlockPixels (GetGWorldPixMap (src));
-  mac_end_clip (GC_CLIP_REGION (gc));
+  mac_end_clip (gc);
 
   RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
 }
@@ -1073,9 +1286,9 @@ mac_scroll_area (f, gc, src_x, src_y, width, height, dest_x, dest_y)
      color mapping in CopyBits.  Otherwise, it will be slow.  */
   ForeColor (blackColor);
   BackColor (whiteColor);
-  mac_begin_clip (GC_CLIP_REGION (gc));
+  mac_begin_clip (gc);
   CopyBits (&(w->portBits), &(w->portBits), &src_r, &dest_r, srcCopy, 0);
-  mac_end_clip (GC_CLIP_REGION (gc));
+  mac_end_clip (gc);
 
   RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
 #endif /* not TARGET_API_MAC_CARBON */
@@ -1211,17 +1424,10 @@ mac_set_clip_rectangles (display, gc, rectangles, n)
 {
   int i;
 
-  if (n < 0 || n > MAX_CLIP_RECTS)
-    abort ();
-  if (n == 0)
-    {
-      if (gc->clip_region)
-       {
-         DisposeRgn (gc->clip_region);
-         gc->clip_region = NULL;
-       }
-    }
-  else
+  xassert (n >= 0 && n <= MAX_CLIP_RECTS);
+
+  gc->n_clip_rects = n;
+  if (n > 0)
     {
       if (gc->clip_region == NULL)
        gc->clip_region = NewRgn ();
@@ -1239,8 +1445,6 @@ mac_set_clip_rectangles (display, gc, rectangles, n)
        }
     }
 #if defined (MAC_OSX) && USE_ATSUI
-  gc->n_clip_rects = n;
-
   for (i = 0; i < n; i++)
     {
       Rect *rect = rectangles + i;
@@ -1260,7 +1464,7 @@ mac_reset_clip_rectangles (display, gc)
      Display *display;
      GC gc;
 {
-  mac_set_clip_rectangles (display, gc, NULL, 0);
+  gc->n_clip_rects = 0;
 }
 
 
@@ -1720,63 +1924,32 @@ x_per_char_metric (font, char2b)
 #if USE_ATSUI
   if (font->mac_style)
     {
-      if (char2b->byte1 >= font->min_byte1
-         && char2b->byte1 <= font->max_byte1
-         && char2b->byte2 >= font->min_char_or_byte2
-         && char2b->byte2 <= font->max_char_or_byte2)
+      XCharStructRow **row = font->bounds.rows + char2b->byte1;
+
+      if (*row == NULL)
        {
-         pcm = (font->per_char
-                + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1)
-                   * (char2b->byte1 - font->min_byte1))
-                + (char2b->byte2 - font->min_char_or_byte2));
+         *row = xmalloc (sizeof (XCharStructRow));
+         if (*row)
+           bzero (*row, sizeof (XCharStructRow));
        }
-
-      if (pcm && !pcm->valid_p)
+      if (*row)
        {
-         OSErr err;
-         ATSUTextLayout text_layout;
-         UniChar c;
-         int char_width;
-         ATSTrapezoid glyph_bounds;
-         Rect char_bounds;
-
-         c = (char2b->byte1 << 8) + char2b->byte2;
-         BLOCK_INPUT;
-         err = atsu_get_text_layout_with_text_ptr (&c, 1,
-                                                   font->mac_style,
-                                                   &text_layout);
-         if (err == noErr)
-           err = ATSUMeasureTextImage (text_layout,
-                                       kATSUFromTextBeginning, kATSUToTextEnd,
-                                       0, 0, &char_bounds);
-
-         if (err == noErr)
-           err = ATSUGetGlyphBounds (text_layout, 0, 0,
-                                     kATSUFromTextBeginning, kATSUToTextEnd,
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
-                                     kATSUseFractionalOrigins,
-#else
-                                     kATSUseDeviceOrigins,
-#endif
-                                     1, &glyph_bounds, NULL);
-         UNBLOCK_INPUT;
-         if (err != noErr)
-           pcm = NULL;
-         else
+         pcm = (*row)->per_char + char2b->byte2;
+         if (!XCHARSTRUCTROW_CHAR_VALID_P (*row, char2b->byte2))
            {
-             xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x
-                      == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x);
-
-             char_width = Fix2Long (glyph_bounds.upperRight.x
-                                    - glyph_bounds.upperLeft.x);
-             STORE_XCHARSTRUCT (*pcm, char_width, char_bounds);
+             BLOCK_INPUT;
+             mac_query_char_extents (font->mac_style,
+                                     (char2b->byte1 << 8) + char2b->byte2,
+                                     NULL, NULL, pcm, NULL);
+             UNBLOCK_INPUT;
+             XCHARSTRUCTROW_SET_CHAR_VALID (*row, char2b->byte2);
            }
        }
     }
   else
     {
 #endif
-  if (font->per_char != NULL)
+  if (font->bounds.per_char != NULL)
     {
       if (font->min_byte1 == 0 && font->max_byte1 == 0)
        {
@@ -1789,7 +1962,8 @@ x_per_char_metric (font, char2b)
          if (char2b->byte1 == 0
              && char2b->byte2 >= font->min_char_or_byte2
              && char2b->byte2 <= font->max_char_or_byte2)
-           pcm = font->per_char + char2b->byte2 - font->min_char_or_byte2;
+           pcm = font->bounds.per_char
+             + (char2b->byte2 - font->min_char_or_byte2);
        }
       else
        {
@@ -1811,7 +1985,7 @@ x_per_char_metric (font, char2b)
              && char2b->byte2 >= font->min_char_or_byte2
              && char2b->byte2 <= font->max_char_or_byte2)
            {
-             pcm = (font->per_char
+             pcm = (font->bounds.per_char
                     + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1)
                        * (char2b->byte1 - font->min_byte1))
                     + (char2b->byte2 - font->min_char_or_byte2));
@@ -2153,67 +2327,32 @@ mac_compute_glyph_string_overhangs (s)
 {
   if (s->cmp == NULL
       && s->first_glyph->type == CHAR_GLYPH)
-    {
-      Rect r;
-      MacFontStruct *font = s->font;
-
+    if (!s->two_byte_p
 #if USE_ATSUI
-      if (font->mac_style)
-       {
-         OSErr err;
-         ATSUTextLayout text_layout;
-         UniChar *buf;
-         int i;
+       || s->font->mac_style
+#endif
+       )
+      {
+       XCharStruct cs;
 
-         SetRect (&r, 0, 0, 0, 0);
-         buf = xmalloc (sizeof (UniChar) * s->nchars);
-         if (buf)
-           {
-             for (i = 0; i < s->nchars; i++)
-               buf[i] = (s->char2b[i].byte1 << 8) + s->char2b[i].byte2;
+       mac_text_extents_16 (s->font, s->char2b, s->nchars, &cs);
+       s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0;
+       s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0;
+      }
+    else
+      {
+       Rect r;
+       MacFontStruct *font = s->font;
 
-             err = atsu_get_text_layout_with_text_ptr (buf, s->nchars,
-                                                       font->mac_style,
-                                                       &text_layout);
-             if (err == noErr)
-               err = ATSUMeasureTextImage (text_layout,
-                                           kATSUFromTextBeginning,
-                                           kATSUToTextEnd,
-                                           0, 0, &r);
-             xfree (buf);
-           }
-       }
-      else
-       {
-#endif
-      TextFont (font->mac_fontnum);
-      TextSize (font->mac_fontsize);
-      TextFace (font->mac_fontface);
+       TextFont (font->mac_fontnum);
+       TextSize (font->mac_fontsize);
+       TextFace (font->mac_fontface);
 
-      if (s->two_byte_p)
        QDTextBounds (s->nchars * 2, (char *)s->char2b, &r);
-      else
-       {
-         int i;
-         char *buf = xmalloc (s->nchars);
 
-         if (buf == NULL)
-           SetRect (&r, 0, 0, 0, 0);
-         else
-           {
-             for (i = 0; i < s->nchars; ++i)
-               buf[i] = s->char2b[i].byte2;
-             QDTextBounds (s->nchars, buf, &r);
-             xfree (buf);
-           }
-       }
-#if USE_ATSUI
-        }
-#endif
-
-      s->right_overhang = r.right > s->width ? r.right - s->width : 0;
-      s->left_overhang = r.left < 0 ? -r.left : 0;
-    }
+       s->right_overhang = r.right > s->width ? r.right - s->width : 0;
+       s->left_overhang = r.left < 0 ? -r.left : 0;
+      }
 }
 
 
@@ -2228,14 +2367,6 @@ x_clear_glyph_string_rect (s, x, y, w, h)
 }
 
 
-/* We prefer not to use XDrawImageString (srcCopy text transfer mode)
-   on Mac OS X because:
-   - Screen is double-buffered.  (In srcCopy mode, a text is drawn
-     into an offscreen graphics world first.  So performance gain
-     cannot be expected.)
-   - It lowers rendering quality.
-   - Some fonts leave garbage on cursor movement.  */
-
 /* Draw the background of glyph_string S.  If S->background_filled_p
    is non-zero don't draw it.  FORCE_P non-zero means draw the
    background even if it wouldn't be drawn normally.  This is used
@@ -2267,12 +2398,10 @@ x_draw_glyph_string_background (s, force_p)
        }
       else
 #endif
-#if defined (MAC_OS8) && !USE_ATSUI
         if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
               || s->font_not_found_p
               || s->extends_to_end_of_line_p
               || force_p)
-#endif
        {
          x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
                                     s->background_width,
@@ -2289,7 +2418,7 @@ static void
 x_draw_glyph_string_foreground (s)
      struct glyph_string *s;
 {
-  int i, x;
+  int i, x, bg_width;
 
   /* If first glyph of S has a left box line, start drawing the text
      of S to the right of that box line.  */
@@ -2328,7 +2457,6 @@ x_draw_glyph_string_foreground (s)
        for (i = 0; i < s->nchars; ++i)
          char1b[i] = s->char2b[i].byte2;
 
-#if defined (MAC_OS8) && !USE_ATSUI
       /* Draw text with XDrawString if background has already been
         filled.  Otherwise, use XDrawImageString.  (Note that
         XDrawImageString is usually faster than XDrawString.)  Always
@@ -2336,38 +2464,27 @@ x_draw_glyph_string_foreground (s)
         no chance that characters under a box cursor are invisible.  */
       if (s->for_overlaps
          || (s->background_filled_p && s->hl != DRAW_CURSOR))
-#endif
-       {
-         /* Draw characters with 16-bit or 8-bit functions.  */
-         if (s->two_byte_p
+       bg_width = 0;           /* Corresponds to XDrawString.  */
+      else
+       bg_width = s->background_width; /* Corresponds to XDrawImageString.  */
+
+      if (s->two_byte_p
 #if USE_ATSUI
-             || GC_FONT (s->gc)->mac_style
+         || GC_FONT (s->gc)->mac_style
 #endif
-             )
+         )
 #if USE_CG_TEXT_DRAWING
-           if (!s->two_byte_p
-               && mac_draw_string_cg (s->f, s->gc, x, s->ybase - boff,
-                                      s->char2b, s->nchars))
-             ;
-           else
+       if (!s->two_byte_p
+           && mac_draw_image_string_cg (s->f, s->gc, x, s->ybase - boff,
+                                        s->char2b, s->nchars, bg_width))
+         ;
+       else
 #endif
-           mac_draw_string_16 (s->f, s->gc, x, s->ybase - boff,
-                               s->char2b, s->nchars);
-         else
-           mac_draw_string (s->f, s->gc, x, s->ybase - boff,
-                            char1b, s->nchars);
-       }
-#if defined (MAC_OS8) && !USE_ATSUI
+         mac_draw_image_string_16 (s->f, s->gc, x, s->ybase - boff,
+                                   s->char2b, s->nchars, bg_width);
       else
-       {
-         if (s->two_byte_p)
-           mac_draw_image_string_16 (s->f, s->gc, x, s->ybase - boff,
-                                     s->char2b, s->nchars);
-         else
-           mac_draw_image_string (s->f, s->gc, x, s->ybase - boff,
-                                  char1b, s->nchars);
-       }
-#endif
+       mac_draw_image_string (s->f, s->gc, x, s->ybase - boff,
+                              char1b, s->nchars, bg_width);
     }
 }
 
@@ -4412,8 +4529,7 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
      int portion, position, whole;
 {
   ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
-
-  int value, viewsize, maximum;
+  int value, viewsize, maximum, visible_p;
 
   if (whole == 0 || XINT (bar->track_height) == 0)
     value = 0, viewsize = 1, maximum = 0;
@@ -4426,11 +4542,17 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
 
   BLOCK_INPUT;
 
+  /* Temporarily hide the scroll bar to avoid multiple redraws.  */
+  visible_p = IsControlVisible (ch);
+  SetControlVisibility (ch, false, false);
+
   SetControl32BitMinimum (ch, 0);
   SetControl32BitMaximum (ch, maximum);
   SetControl32BitValue (ch, value);
   SetControlViewSize (ch, viewsize);
 
+  SetControlVisibility (ch, visible_p, true);
+
   UNBLOCK_INPUT;
 }
 
@@ -5208,7 +5330,10 @@ mac_define_frame_cursor (f, cursor)
      struct frame *f;
      Cursor cursor;
 {
-  SetThemeCursor (cursor);
+  struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+
+  if (dpyinfo->x_focus_frame == f)
+    SetThemeCursor (cursor);
 }
 
 
@@ -5746,7 +5871,7 @@ x_raise_frame (f)
   if (f->async_visible)
     {
       BLOCK_INPUT;
-      SelectWindow (FRAME_MAC_WINDOW (f));
+      BringToFront (FRAME_MAC_WINDOW (f));
       UNBLOCK_INPUT;
     }
 }
@@ -5760,7 +5885,7 @@ x_lower_frame (f)
   if (f->async_visible)
     {
       BLOCK_INPUT;
-      SendBehind (FRAME_MAC_WINDOW (f), nil);
+      SendBehind (FRAME_MAC_WINDOW (f), NULL);
       UNBLOCK_INPUT;
     }
 }
@@ -5873,7 +5998,6 @@ x_make_frame_visible (f)
 
       f->output_data.mac->asked_for_visible = 1;
 
-      SelectWindow (FRAME_MAC_WINDOW (f));
       CollapseWindow (FRAME_MAC_WINDOW (f), false);
       ShowWindow (FRAME_MAC_WINDOW (f));
     }
@@ -7371,7 +7495,7 @@ is_fully_specified_xlfd (char *p)
 static MacFontStruct *
 XLoadQueryFont (Display *dpy, char *fontname)
 {
-  int i, size, char_width;
+  int size;
   char *name;
   Str255 family;
   Str31 charset;
@@ -7388,6 +7512,7 @@ XLoadQueryFont (Display *dpy, char *fontname)
   short scriptcode;
 #endif
   MacFontStruct *font;
+  XCharStruct *space_bounds = NULL, *pcm;
 
   if (is_fully_specified_xlfd (fontname))
     name = fontname;
@@ -7416,8 +7541,10 @@ XLoadQueryFont (Display *dpy, char *fontname)
       static Boolean bold_p, italic_p;
       ATSUAttributeValuePtr values[] = {&font_id, &size_fixed,
                                        &bold_p, &italic_p};
-      ATSUFontFeatureType types[] = {kAllTypographicFeaturesType};
-      ATSUFontFeatureSelector selectors[] = {kAllTypeFeaturesOffSelector};
+      ATSUFontFeatureType types[] = {kAllTypographicFeaturesType,
+                                    kDiacriticsType};
+      ATSUFontFeatureSelector selectors[] = {kAllTypeFeaturesOffSelector,
+                                            kDecomposeDiacriticsSelector};
       Lisp_Object font_id_cons;
 
       font_id_cons = Fgethash (make_unibyte_string (family, strlen (family)),
@@ -7484,19 +7611,27 @@ XLoadQueryFont (Display *dpy, char *fontname)
   if (font->mac_style)
     {
       OSErr err;
-      ATSUTextLayout text_layout;
-      UniChar c = 0x20;
-      Rect char_bounds, min_bounds, max_bounds;
-      int min_width, max_width;
-      ATSTrapezoid glyph_bounds;
+      UniChar c;
+
+      font->min_byte1 = 0;
+      font->max_byte1 = 0xff;
+      font->min_char_or_byte2 = 0;
+      font->max_char_or_byte2 = 0xff;
 
-      font->per_char = xmalloc (sizeof (XCharStruct) * 0x10000);
-      if (font->per_char == NULL)
+      font->bounds.rows = xmalloc (sizeof (XCharStructRow *) * 0x100);
+      if (font->bounds.rows == NULL)
+       {
+         mac_unload_font (&one_mac_display_info, font);
+         return NULL;
+       }
+      bzero (font->bounds.rows, sizeof (XCharStructRow *) * 0x100);
+      font->bounds.rows[0] = xmalloc (sizeof (XCharStructRow));
+      if (font->bounds.rows[0] == NULL)
        {
          mac_unload_font (&one_mac_display_info, font);
          return NULL;
        }
-      bzero (font->per_char, sizeof (XCharStruct) * 0x10000);
+      bzero (font->bounds.rows[0], sizeof (XCharStructRow));
 
 #if USE_CG_TEXT_DRAWING
       {
@@ -7521,108 +7656,58 @@ XLoadQueryFont (Display *dpy, char *fontname)
       if (font->cg_glyphs)
        bzero (font->cg_glyphs, sizeof (CGGlyph) * 0x100);
 #endif
-
-      err = atsu_get_text_layout_with_text_ptr (&c, 1,
-                                               font->mac_style,
-                                               &text_layout);
+      space_bounds = font->bounds.rows[0]->per_char + 0x20;
+      err = mac_query_char_extents (font->mac_style, 0x20,
+                                   &font->ascent, &font->descent,
+                                   space_bounds,
+#if USE_CG_TEXT_DRAWING
+                                   (font->cg_glyphs ? font->cg_glyphs + 0x20
+                                    : NULL)
+#else
+                                   NULL
+#endif
+                                   );
       if (err != noErr)
        {
          mac_unload_font (&one_mac_display_info, font);
          return NULL;
        }
+      XCHARSTRUCTROW_SET_CHAR_VALID (font->bounds.rows[0], 0x20);
 
-      for (c = 0x20; c <= 0xff; c++)
+      pcm = font->bounds.rows[0]->per_char;
+      for (c = 0x21; c <= 0xff; c++)
        {
          if (c == 0xad)
            /* Soft hyphen is not supported in ATSUI.  */
            continue;
          else if (c == 0x7f)
            {
-             STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds);
-             STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
              c = 0x9f;
              continue;
            }
 
-         err = ATSUClearLayoutCache (text_layout, kATSUFromTextBeginning);
-         if (err == noErr)
-           err = ATSUMeasureTextImage (text_layout,
-                                       kATSUFromTextBeginning, kATSUToTextEnd,
-                                       0, 0, &char_bounds);
-         if (err == noErr)
-           err = ATSUGetGlyphBounds (text_layout, 0, 0,
-                                     kATSUFromTextBeginning, kATSUToTextEnd,
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
-                                     kATSUseFractionalOrigins,
+         mac_query_char_extents (font->mac_style, c, NULL, NULL, pcm + c,
+#if USE_CG_TEXT_DRAWING
+                                 (font->cg_glyphs ? font->cg_glyphs + c
+                                  : NULL)
 #else
-                                     kATSUseDeviceOrigins,
+                                   NULL
 #endif
-                                     1, &glyph_bounds, NULL);
-         if (err == noErr)
-           {
-             xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x
-                      == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x);
+                                 );
+         XCHARSTRUCTROW_SET_CHAR_VALID (font->bounds.rows[0], c);
 
-             char_width = Fix2Long (glyph_bounds.upperRight.x
-                                    - glyph_bounds.upperLeft.x);
-             STORE_XCHARSTRUCT (font->per_char[c],
-                                char_width, char_bounds);
-             if (c == 0x20)
-               {
-                 min_width = max_width = char_width;
-                 min_bounds = max_bounds = char_bounds;
-                 font->ascent = -Fix2Long (glyph_bounds.upperLeft.y);
-                 font->descent = Fix2Long (glyph_bounds.lowerLeft.y);
-               }
-             else
-               {
-                 if (char_width > 0)
-                   {
-                     min_width = min (min_width, char_width);
-                     max_width = max (max_width, char_width);
-                   }
-                 if (!EmptyRect (&char_bounds))
-                   {
-                     SetRect (&min_bounds,
-                              max (min_bounds.left, char_bounds.left),
-                              max (min_bounds.top, char_bounds.top),
-                              min (min_bounds.right, char_bounds.right),
-                              min (min_bounds.bottom, char_bounds.bottom));
-                     UnionRect (&max_bounds, &char_bounds, &max_bounds);
-                   }
-               }
-           }
 #if USE_CG_TEXT_DRAWING
-         if (err == noErr && char_width > 0 && font->cg_font)
+         if (font->cg_glyphs && font->cg_glyphs[c] == 0)
            {
-             ATSUGlyphInfoArray glyph_info_array;
-             ByteCount count = sizeof (ATSUGlyphInfoArray);
-
-             err = ATSUMatchFontsToText (text_layout, kATSUFromTextBeginning,
-                                         kATSUToTextEnd, NULL, NULL, NULL);
-             if (err == noErr)
-               err = ATSUGetGlyphInfo (text_layout, kATSUFromTextBeginning,
-                                       kATSUToTextEnd, &count,
-                                       &glyph_info_array);
-             if (err == noErr)
-               font->cg_glyphs[c] = glyph_info_array.glyphs[0].glyphID;
-             else
-               {
-                 /* Don't use CG text drawing if font substitution
-                    occurs in ASCII or Latin-1 characters.  */
-                 CGFontRelease (font->cg_font);
-                 font->cg_font = NULL;
-                 xfree (font->cg_glyphs);
-                 font->cg_glyphs = NULL;
-               }
+             /* Don't use CG text drawing if font substitution occurs in
+                ASCII or Latin-1 characters.  */
+             CGFontRelease (font->cg_font);
+             font->cg_font = NULL;
+             xfree (font->cg_glyphs);
+             font->cg_glyphs = NULL;
            }
 #endif
        }
-
-      font->min_byte1 = 0;
-      font->max_byte1 = 0xff;
-      font->min_char_or_byte2 = 0;
-      font->max_char_or_byte2 = 0xff;
     }
   else
 #endif
@@ -7661,6 +7746,8 @@ XLoadQueryFont (Display *dpy, char *fontname)
 
       if (is_two_byte_font)
        {
+         int char_width;
+
          font->min_byte1 = 0xa1;
          font->max_byte1 = 0xfe;
          font->min_char_or_byte2 = 0xa1;
@@ -7689,21 +7776,8 @@ XLoadQueryFont (Display *dpy, char *fontname)
              char_width = StringWidth("\p\xa1\xa1");
              break;
            }
-       }
-      else
-       {
-         font->min_byte1 = font->max_byte1 = 0;
-         font->min_char_or_byte2 = 0x20;
-         font->max_char_or_byte2 = 0xff;
 
-         /* Do this instead of use the_fontinfo.widMax, which
-            incorrectly returns 15 for 12-point Monaco! */
-         char_width = CharWidth ('m');
-       }
-
-      if (is_two_byte_font)
-       {
-         font->per_char = NULL;
+         font->bounds.per_char = NULL;
 
          if (fontface & italic)
            font->max_bounds.rbearing = char_width + 1;
@@ -7718,54 +7792,28 @@ XLoadQueryFont (Display *dpy, char *fontname)
        }
       else
        {
-         int c, min_width, max_width;
-         Rect char_bounds, min_bounds, max_bounds;
-         char ch;
-
-         font->per_char = xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
-         bzero (font->per_char, sizeof (XCharStruct) * (0xff - 0x20 + 1));
+         int c;
 
-         min_width = max_width = char_width;
-         SetRect (&min_bounds, -32767, -32767, 32767, 32767);
-         SetRect (&max_bounds, 0, 0, 0, 0);
-         for (c = 0x20; c <= 0xff; c++)
-           {
-             if (c == 0x7f)
-               {
-                 STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds);
-                 STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
-                 continue;
-               }
+         font->min_byte1 = font->max_byte1 = 0;
+         font->min_char_or_byte2 = 0x20;
+         font->max_char_or_byte2 = 0xff;
 
-             ch = c;
-             char_width = CharWidth (ch);
-             QDTextBounds (1, &ch, &char_bounds);
-             STORE_XCHARSTRUCT (font->per_char[c - 0x20],
-                                char_width, char_bounds);
-             /* Some Japanese fonts (in SJIS encoding) return 0 as
-                the character width of 0x7f.  */
-             if (char_width > 0)
-               {
-                 min_width = min (min_width, char_width);
-                 max_width = max (max_width, char_width);
-               }
-             if (!EmptyRect (&char_bounds))
-               {
-                 SetRect (&min_bounds,
-                          max (min_bounds.left, char_bounds.left),
-                          max (min_bounds.top, char_bounds.top),
-                          min (min_bounds.right, char_bounds.right),
-                          min (min_bounds.bottom, char_bounds.bottom));
-                 UnionRect (&max_bounds, &char_bounds, &max_bounds);
-               }
-           }
-         if (min_width == max_width
-             && max_bounds.left >= 0 && max_bounds.right <= max_width)
+         font->bounds.per_char =
+           xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
+         if (font->bounds.per_char == NULL)
            {
-             /* Fixed width and no overhangs.  */
-             xfree (font->per_char);
-             font->per_char = NULL;
+             mac_unload_font (&one_mac_display_info, font);
+             return NULL;
            }
+         bzero (font->bounds.per_char,
+                sizeof (XCharStruct) * (0xff - 0x20 + 1));
+
+         space_bounds = font->bounds.per_char;
+         mac_query_char_extents (NULL, 0x20, &font->ascent, &font->descent,
+                                 space_bounds, NULL);
+
+         for (c = 0x21, pcm = space_bounds + 1; c <= 0xff; c++, pcm++)
+           mac_query_char_extents (NULL, c, NULL, NULL, pcm, NULL);
        }
 
       /* Restore previous font number, size and face.  */
@@ -7774,12 +7822,56 @@ XLoadQueryFont (Display *dpy, char *fontname)
       TextFace (old_fontface);
     }
 
+  if (space_bounds)
+    {
+      int c;
+
+      font->min_bounds = font->max_bounds = *space_bounds;
+      for (c = 0x21, pcm = space_bounds + 1; c <= 0x7f; c++, pcm++)
+       if (pcm->width > 0)
+         {
+           font->min_bounds.lbearing = min (font->min_bounds.lbearing,
+                                            pcm->lbearing);
+           font->min_bounds.rbearing = min (font->min_bounds.rbearing,
+                                            pcm->rbearing);
+           font->min_bounds.width    = min (font->min_bounds.width,
+                                            pcm->width);
+           font->min_bounds.ascent   = min (font->min_bounds.ascent,
+                                            pcm->ascent);
+
+           font->max_bounds.lbearing = max (font->max_bounds.lbearing,
+                                            pcm->lbearing);
+           font->max_bounds.rbearing = max (font->max_bounds.rbearing,
+                                            pcm->rbearing);
+           font->max_bounds.width    = max (font->max_bounds.width,
+                                            pcm->width);
+           font->max_bounds.ascent   = max (font->max_bounds.ascent,
+                                            pcm->ascent);
+         }
+      if (
+#if USE_ATSUI
+         font->mac_style == NULL &&
+#endif
+         font->max_bounds.width == font->min_bounds.width
+         && font->min_bounds.lbearing >= 0
+         && font->max_bounds.rbearing <= font->max_bounds.width)
+       {
+         /* Fixed width and no overhangs.  */
+         xfree (font->bounds.per_char);
+         font->bounds.per_char = NULL;
+       }
+    }
+
 #if !defined (MAC_OS8) || USE_ATSUI
   /* AppKit and WebKit do some adjustment to the heights of Courier,
      Helvetica, and Times.  This only works on the environments where
-     the XDrawImageString counterpart is never used.  */
-  if (strcmp (family, "courier") == 0 || strcmp (family, "helvetica") == 0
-      || strcmp (family, "times") == 0)
+     srcCopy text transfer mode is never used.  */
+  if (
+#ifdef MAC_OS8                 /* implies USE_ATSUI */
+      font->mac_style &&
+#endif
+      (strcmp (family, "courier") == 0 || strcmp (family, "helvetica") == 0
+       || strcmp (family, "times") == 0))
     font->ascent += (font->ascent + font->descent) * .15 + 0.5;
 #endif
 
@@ -7793,17 +7885,26 @@ mac_unload_font (dpyinfo, font)
      XFontStruct *font;
 {
   xfree (font->full_name);
-  if (font->per_char)
-    xfree (font->per_char);
 #if USE_ATSUI
   if (font->mac_style)
-    ATSUDisposeStyle (font->mac_style);
+    {
+      int i;
+
+      for (i = font->min_byte1; i <= font->max_byte1; i++)
+       if (font->bounds.rows[i])
+         xfree (font->bounds.rows[i]);
+      xfree (font->bounds.rows);
+      ATSUDisposeStyle (font->mac_style);
+    }
+  else
+#endif
+    if (font->bounds.per_char)
+      xfree (font->bounds.per_char);
 #if USE_CG_TEXT_DRAWING
   if (font->cg_font)
     CGFontRelease (font->cg_font);
   if (font->cg_glyphs)
     xfree (font->cg_glyphs);
-#endif
 #endif
   xfree (font);
 }
@@ -8109,17 +8210,17 @@ Lisp_Object Vmac_function_modifier;
 Lisp_Object Vmac_emulate_three_button_mouse;
 
 #if USE_CARBON_EVENTS
-/* True if the mouse wheel button (i.e. button 4) should map to
+/* Non-zero if the mouse wheel button (i.e. button 4) should map to
    mouse-2, instead of mouse-3.  */
-Lisp_Object Vmac_wheel_button_is_mouse_2;
+int mac_wheel_button_is_mouse_2;
 
-/* If Non-nil, the Mac "Command" key is passed on to the Mac Toolbox
+/* If non-zero, the Mac "Command" key is passed on to the Mac Toolbox
    for processing before Emacs sees it.  */
-Lisp_Object Vmac_pass_command_to_system;
+int mac_pass_command_to_system;
 
-/* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox
+/* If non-zero, the Mac "Control" key is passed on to the Mac Toolbox
    for processing before Emacs sees it.  */
-Lisp_Object Vmac_pass_control_to_system;
+int mac_pass_control_to_system;
 #endif
 
 /* Points to the variable `inev' in the function XTread_socket.  It is
@@ -8139,6 +8240,7 @@ extern void init_apple_event_handler P_ ((void));
 extern void mac_find_apple_event_spec P_ ((AEEventClass, AEEventID,
                                           Lisp_Object *, Lisp_Object *,
                                           Lisp_Object *));
+extern OSErr init_coercion_handler P_ ((void));
 
 #if TARGET_API_MAC_CARBON
 /* Drag and Drop */
@@ -8176,8 +8278,6 @@ mac_to_emacs_modifiers (EventModifiers mods)
   if (mods & shiftKey)
     result |= shift_modifier;
 
-
-
   /* Deactivated to simplify configuration:
      if Vmac_option_modifier is non-NIL, we fully process the Option
      key. Otherwise, we only process it if an additional Ctrl or Command
@@ -8265,10 +8365,10 @@ mac_get_mouse_btn (EventRef ref)
        return mac_get_emulated_btn(mods);
       }
     case kEventMouseButtonSecondary:
-      return NILP (Vmac_wheel_button_is_mouse_2) ? 1 : 2;
+      return mac_wheel_button_is_mouse_2 ? 2 : 1;
     case kEventMouseButtonTertiary:
     case 4:  /* 4 is the number for the mouse wheel button */
-      return NILP (Vmac_wheel_button_is_mouse_2) ? 2 : 1;
+      return mac_wheel_button_is_mouse_2 ? 1 : 2;
     default:
       return 0;
     }
@@ -8779,10 +8879,8 @@ mac_handle_command_event (next_handler, event, data)
                                         kEventParamKeyModifiers};
        static EventParamType types[] = {typeHICommand,
                                         typeUInt32};
-       static UInt32 sizes[] = {sizeof (HICommand),
-                                sizeof (UInt32)};
        err = create_apple_event_from_event_ref (event, 2, names, types,
-                                                sizes, &apple_event);
+                                                &apple_event);
        if (err == noErr)
          {
            err = mac_store_apple_event (class_key, id_key, &apple_event);
@@ -8966,8 +9064,8 @@ mac_store_services_event (event)
     {
     case kEventServicePaste:
       id_key = Qpaste;
-      err = create_apple_event_from_event_ref (event, 0, NULL,
-                                              NULL, NULL, &apple_event);
+      err = create_apple_event_from_event_ref (event, 0, NULL, NULL,
+                                              &apple_event);
       break;
 
     case kEventServicePerform:
@@ -8976,12 +9074,10 @@ mac_store_services_event (event)
                                         kEventParamServiceUserData};
        static EventParamType types[] = {typeCFStringRef,
                                         typeCFStringRef};
-       static UInt32 sizes[] = {sizeof (CFStringRef),
-                                sizeof (CFStringRef)};
 
        id_key = Qperform;
        err = create_apple_event_from_event_ref (event, 2, names, types,
-                                                sizes, &apple_event);
+                                                &apple_event);
       }
       break;
 
@@ -9151,25 +9247,25 @@ mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
       result = GetFlavorFlags (theDrag, theItem, flavorTypeHFS, &theFlags);
       if (result == noErr)
        {
-#ifdef MAC_OSX
-         FSRef fref;
-#endif
-         char unix_path_name[MAXPATHLEN];
+         OSErr err;
+         AEDesc desc;
 
-         GetFlavorData (theDrag, theItem, flavorTypeHFS, &data, &size, 0L);
-#ifdef MAC_OSX
-         /* Use Carbon routines, otherwise it converts the file name
-            to /Macintosh HD/..., which is not correct. */
-         FSpMakeFSRef (&data.fileSpec, &fref);
-         if (! FSRefMakePath (&fref, unix_path_name, sizeof (unix_path_name)));
-#else
-         if (fsspec_to_posix_pathname (&data.fileSpec, unix_path_name,
-                                       sizeof (unix_path_name) - 1) == noErr)
-#endif
-           /* x-dnd functions expect undecoded filenames.  */
-            file_list = Fcons (make_unibyte_string (unix_path_name,
-                                                   strlen (unix_path_name)),
-                              file_list);
+         err = GetFlavorData (theDrag, theItem, flavorTypeHFS,
+                              &data, &size, 0L);
+         if (err == noErr)
+           err = AECoercePtr (typeFSS, &data.fileSpec, sizeof (FSSpec),
+                              TYPE_FILE_NAME, &desc);
+         if (err == noErr)
+           {
+             Lisp_Object file;
+
+             /* x-dnd functions expect undecoded filenames.  */
+             file = make_uninit_string (AEGetDescDataSize (&desc));
+             err = AEGetDescData (&desc, SDATA (file), SBYTES (file));
+             if (err == noErr)
+               file_list = Fcons (file, file_list);
+             AEDisposeDesc (&desc);
+           }
        }
     }
   /* If there are items in the list, construct an event and post it to
@@ -9191,8 +9287,8 @@ mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
       XSETINT (event.x, mouse.h);
       XSETINT (event.y, mouse.v);
       XSETFRAME (frame, f);
-      event.frame_or_window = Fcons (frame, file_list);
-      event.arg = Qnil;
+      event.frame_or_window = frame;
+      event.arg = file_list;
       /* Post to the interrupt queue */
       kbd_buffer_store_event (&event);
       /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */
@@ -9261,6 +9357,8 @@ main (void)
 
   init_environ ();
 
+  init_coercion_handler ();
+
   initialize_applescript ();
 
   init_apple_event_handler ();
@@ -9411,10 +9509,12 @@ convert_fn_keycode (EventRef eventRef, int keyCode, int *newCode)
 static int
 backtranslate_modified_keycode(int mods, int keycode, int def)
 {
-  if  (mods &
-       (controlKey |
-       (NILP (Vmac_option_modifier) ? 0 : optionKey) |
-       cmdKey))
+  EventModifiers mapped_modifiers =
+    (NILP (Vmac_control_modifier) ? 0 : controlKey)
+    | (NILP (Vmac_option_modifier) ? 0 : optionKey)
+    | (NILP (Vmac_command_modifier) ? 0 : cmdKey);
+
+  if (mods & mapped_modifiers)
     {
       /* This code comes from Keyboard Resource,
         Appendix C of IM - Text.  This is necessary
@@ -9429,14 +9529,15 @@ backtranslate_modified_keycode(int mods, int keycode, int def)
         to preserve key combinations translated by the OS
         such as Alt-3.
       */
-      /* mask off option and command */
-      int new_modifiers = mods & 0xe600;
+      /* Mask off modifier keys that are mapped to some Emacs
+        modifiers.  */
+      int new_modifiers = mods & ~mapped_modifiers;
       /* set high byte of keycode to modifier high byte*/
       int new_keycode = keycode | new_modifiers;
       Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
       unsigned long some_state = 0;
       return (int) KeyTranslate (kchr_ptr, new_keycode,
-                          &some_state) & 0xff;
+                                &some_state) & 0xff;
       /* TO DO: Recognize two separate resulting characters, "for
         example, when the user presses Option-E followed by N, you
         can map this through the KeyTranslate function using the
@@ -9517,6 +9618,8 @@ XTread_socket (sd, expected, hold_quit)
   /* So people can tell when we have read the available input.  */
   input_signal_count++;
 
+  ++handling_signal;
+
 #if USE_CARBON_EVENTS
   toolbox_dispatcher = GetEventDispatcherTarget ();
 
@@ -9990,9 +10093,9 @@ XTread_socket (sd, expected, hold_quit)
               will pass back noErr, otherwise it will pass back
               "eventNotHandledErr" and we can process it
               normally.  */
-           if ((!NILP (Vmac_pass_command_to_system)
+           if ((mac_pass_command_to_system
                 || !(er.modifiers & cmdKey))
-               && (!NILP (Vmac_pass_control_to_system)
+               && (mac_pass_control_to_system
                    || !(er.modifiers & controlKey))
                && (NILP (Vmac_option_modifier)
                    || !(er.modifiers & optionKey)))
@@ -10061,12 +10164,10 @@ XTread_socket (sd, expected, hold_quit)
                }
              else
                {
-
                  inev.code =
                    backtranslate_modified_keycode(er.modifiers, keycode,
                                                   er.message & charCodeMask);
                  inev.kind = ASCII_KEYSTROKE_EVENT;
-
                }
          }
 
@@ -10159,6 +10260,7 @@ XTread_socket (sd, expected, hold_quit)
   }
 #endif
 
+  --handling_signal;
   UNBLOCK_INPUT;
   return count;
 }
@@ -10648,6 +10750,8 @@ mac_initialize ()
 #endif /* USE_CARBON_EVENTS */
 
 #ifdef MAC_OSX
+  init_coercion_handler ();
+
   init_apple_event_handler ();
 
   if (!inhibit_window_system)
@@ -10710,6 +10814,18 @@ syms_of_macterm ()
   atsu_font_id_hash = Qnil;
 #endif
 
+  /* We don't yet support this, but defining this here avoids whining
+     from cus-start.el and other places, like "M-x set-variable".  */
+  DEFVAR_BOOL ("x-use-underline-position-properties",
+              &x_use_underline_position_properties,
+     doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
+nil means ignore them.  If you encounter fonts with bogus
+UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
+to 4.1, set this to nil.
+
+NOTE: Not supported on Mac yet.  */);
+  x_use_underline_position_properties = 0;
+
   DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
               doc: /* If not nil, Emacs uses toolkit scroll bars.  */);
 #ifdef USE_TOOLKIT_SCROLL_BARS
@@ -10724,35 +10840,35 @@ syms_of_macterm ()
 /* Variables to configure modifier key assignment.  */
 
   DEFVAR_LISP ("mac-control-modifier", &Vmac_control_modifier,
-    doc: /* Modifier key assumed when the Mac control key is pressed.
-The value can be `alt', `control', `hyper', or `super' for the
+    doc: /* *Modifier key assumed when the Mac control key is pressed.
+The value can be `control', `meta', `alt', `hyper', or `super' for the
 respective modifier.  The default is `control'.  */);
   Vmac_control_modifier = Qcontrol;
 
   DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier,
-    doc: /* Modifier key assumed when the Mac alt/option key is pressed.
-The value can be `alt', `control', `hyper', or `super' for the
+    doc: /* *Modifier key assumed when the Mac alt/option key is pressed.
+The value can be `control', `meta', `alt', `hyper', or `super' for the
 respective modifier.  If the value is nil then the key will act as the
 normal Mac control modifier, and the option key can be used to compose
 characters depending on the chosen Mac keyboard setting.  */);
   Vmac_option_modifier = Qnil;
 
   DEFVAR_LISP ("mac-command-modifier", &Vmac_command_modifier,
-    doc: /* Modifier key assumed when the Mac command key is pressed.
-The value can be `alt', `control', `hyper', or `super' for the
+    doc: /* *Modifier key assumed when the Mac command key is pressed.
+The value can be `control', `meta', `alt', `hyper', or `super' for the
 respective modifier.  The default is `meta'.  */);
   Vmac_command_modifier = Qmeta;
 
   DEFVAR_LISP ("mac-function-modifier", &Vmac_function_modifier,
-    doc: /* Modifier key assumed when the Mac function key is pressed.
-The value can be `alt', `control', `hyper', or `super' for the
+    doc: /* *Modifier key assumed when the Mac function key is pressed.
+The value can be `control', `meta', `alt', `hyper', or `super' for the
 respective modifier.  Note that remapping the function key may lead to
 unexpected results for some keys on non-US/GB keyboards.  */);
   Vmac_function_modifier = Qnil;
 
   DEFVAR_LISP ("mac-emulate-three-button-mouse",
               &Vmac_emulate_three_button_mouse,
-    doc: /* Specify a way of three button mouse emulation.
+    doc: /* *Specify a way of three button mouse emulation.
 The value can be nil, t, or the symbol `reverse'.
 nil means that no emulation should be done and the modifiers should be
 placed on the mouse-1 event.
@@ -10764,27 +10880,27 @@ mouse-3 and the command-key will register for mouse-2.  */);
   Vmac_emulate_three_button_mouse = Qnil;
 
 #if USE_CARBON_EVENTS
-  DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2,
-   doc: /* Non-nil if the wheel button is mouse-2 and the right click mouse-3.
+  DEFVAR_BOOL ("mac-wheel-button-is-mouse-2", &mac_wheel_button_is_mouse_2,
+   doc: /* *Non-nil if the wheel button is mouse-2 and the right click mouse-3.
 Otherwise, the right click will be treated as mouse-2 and the wheel
 button will be mouse-3.  */);
-  Vmac_wheel_button_is_mouse_2 = Qt;
+  mac_wheel_button_is_mouse_2 = 1;
 
-  DEFVAR_LISP ("mac-pass-command-to-system", &Vmac_pass_command_to_system,
-   doc: /* Non-nil if command key presses are passed on to the Mac Toolbox.  */);
-  Vmac_pass_command_to_system = Qt;
+  DEFVAR_BOOL ("mac-pass-command-to-system", &mac_pass_command_to_system,
+   doc: /* *Non-nil if command key presses are passed on to the Mac Toolbox.  */);
+  mac_pass_command_to_system = 1;
 
-  DEFVAR_LISP ("mac-pass-control-to-system", &Vmac_pass_control_to_system,
-   doc: /* Non-nil if control key presses are passed on to the Mac Toolbox.  */);
-  Vmac_pass_control_to_system = Qt;
+  DEFVAR_BOOL ("mac-pass-control-to-system", &mac_pass_control_to_system,
+   doc: /* *Non-nil if control key presses are passed on to the Mac Toolbox.  */);
+  mac_pass_control_to_system = 1;
 
 #endif
 
-  DEFVAR_LISP ("mac-allow-anti-aliasing", &Vmac_use_core_graphics,
-   doc: /* If non-nil, allow anti-aliasing.
+  DEFVAR_BOOL ("mac-allow-anti-aliasing", &mac_use_core_graphics,
+   doc: /* *If non-nil, allow anti-aliasing.
 The text will be rendered using Core Graphics text rendering which
 may anti-alias the text.  */);
-  Vmac_use_core_graphics = Qnil;
+  mac_use_core_graphics = 0;
 
   /* Register an entry for `mac-roman' so that it can be used when
      creating the terminal frame on Mac OS 9 before loading