(x_create_tip_frame): Apply 2006-03-11 change for xfns.c.
[bpt/emacs.git] / src / macterm.c
index 9051196..649bfb4 100644 (file)
@@ -267,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;
 
@@ -283,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);
 }
 
@@ -323,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
@@ -367,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)));
 }
@@ -432,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;
@@ -447,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)));
 }
@@ -579,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);
 }
 
 
@@ -599,11 +598,11 @@ mac_draw_rectangle (f, gc, x, y, width, height)
   SetPortWindowPort (FRAME_MAC_WINDOW (f));
 
   RGBForeColor (GC_FORE_COLOR (gc));
-  SetRect (&r, x, y, x + width + 1, y + height + 1);
+  SetRect (&r, x, y, x + width, y + height);
 
-  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);
 }
 
 
@@ -682,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 (mac_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)
     {
@@ -724,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 (!mac_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 (mac_use_core_graphics)
-    SwapQDTextFlags(savedFlags);
+      if (mac_use_core_graphics)
+       SwapQDTextFlags(savedFlags);
 #endif
+    }
 }
 
 
@@ -822,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);
 }
 
 
@@ -836,35 +876,35 @@ 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);
 }
 
 
@@ -1026,21 +1066,24 @@ 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;
@@ -1057,7 +1100,9 @@ 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++)
     {
       XCharStruct *pcm = mac_per_char_metric (GC_FONT (gc), buf, 0);
@@ -1069,18 +1114,32 @@ mac_draw_string_cg (f, gc, x, y, buf, nchars)
     }
 
   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);
@@ -1099,8 +1158,6 @@ mac_draw_string_cg (f, gc, x, y, buf, nchars)
   CGContextSynchronize (context);
   QDEndCGContext (port, &context);
 
-  xfree (advances);
-
   return 1;
 }
 #endif
@@ -1127,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
   {
@@ -1145,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)));
 }
@@ -1171,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
@@ -1191,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)));
 }
@@ -1229,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 */
@@ -1367,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 ();
@@ -1395,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;
@@ -1416,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;
 }
 
 
@@ -2319,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
@@ -2358,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,
@@ -2380,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.  */
@@ -2398,7 +2436,7 @@ x_draw_glyph_string_foreground (s)
        {
          struct glyph *g = s->first_glyph + i;
          mac_draw_rectangle (s->f, s->gc, x, s->y,
-                             g->pixel_width - 1, s->height - 1);
+                             g->pixel_width, s->height);
          x += g->pixel_width;
        }
     }
@@ -2419,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
@@ -2427,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);
     }
 }
 
@@ -2489,7 +2515,7 @@ x_draw_composite_glyph_string_foreground (s)
     {
       if (s->gidx == 0)
        mac_draw_rectangle (s->f, s->gc, x, s->y,
-                           s->width - 1, s->height - 1);
+                           s->width, s->height);
     }
   else
     {
@@ -3042,15 +3068,15 @@ x_draw_image_foreground (s)
              int r = s->img->relief;
              if (r < 0) r = -r;
              mac_draw_rectangle (s->f, s->gc, x - r, y - r,
-                                 s->slice.width + r*2 - 1,
-                                 s->slice.height + r*2 - 1);
+                                 s->slice.width + r*2,
+                                 s->slice.height + r*2);
            }
        }
     }
   else
     /* Draw a rectangle if image could not be loaded.  */
     mac_draw_rectangle (s->f, s->gc, x, y,
-                       s->slice.width - 1, s->slice.height - 1);
+                       s->slice.width, s->slice.height);
 }
 
 
@@ -4239,8 +4265,8 @@ static OSStatus set_scroll_bar_timer P_ ((EventTimerInterval));
 static int control_part_code_to_scroll_bar_part P_ ((ControlPartCode));
 static void construct_scroll_bar_click P_ ((struct scroll_bar *, int,
                                            struct input_event *));
-static OSErr get_control_part_bounds P_ ((ControlHandle, ControlPartCode,
-                                         Rect *));
+static OSStatus get_control_part_bounds P_ ((ControlHandle, ControlPartCode,
+                                            Rect *));
 static void x_scroll_bar_handle_press P_ ((struct scroll_bar *,
                                           ControlPartCode,
                                           struct input_event *));
@@ -4361,7 +4387,7 @@ construct_scroll_bar_click (bar, part, bufp)
   bufp->modifiers = 0;
 }
 
-static OSErr
+static OSStatus
 get_control_part_bounds (ch, part_code, rect)
      ControlHandle ch;
      ControlPartCode part_code;
@@ -4503,10 +4529,12 @@ 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;
 
-  if (whole == 0 || XINT (bar->track_height) == 0)
+  if (XINT (bar->track_height) == 0)
+    return;
+
+  if (whole == 0)
     value = 0, viewsize = 1, maximum = 0;
   else
     {
@@ -4517,10 +4545,19 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
 
   BLOCK_INPUT;
 
-  SetControl32BitMinimum (ch, 0);
-  SetControl32BitMaximum (ch, maximum);
-  SetControl32BitValue (ch, value);
-  SetControlViewSize (ch, viewsize);
+  if (GetControlViewSize (ch) != viewsize
+      || GetControl32BitValue (ch) != value
+      || GetControl32BitMaximum (ch) != maximum)
+    {
+      /* Temporarily hide the scroll bar to avoid multiple redraws.  */
+      SetControlVisibility (ch, false, false);
+
+      SetControl32BitMaximum (ch, maximum);
+      SetControl32BitValue (ch, value);
+      SetControlViewSize (ch, viewsize);
+
+      SetControlVisibility (ch, true, true);
+    }
 
   UNBLOCK_INPUT;
 }
@@ -4557,7 +4594,12 @@ x_scroll_bar_create (w, top, left, width, height, disp_top, disp_height)
   r.bottom = disp_top + disp_height;
 
 #if TARGET_API_MAC_CARBON
-  ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p", width < disp_height,
+  ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p",
+#if USE_TOOLKIT_SCROLL_BARS
+                  false,
+#else
+                  width < disp_height,
+#endif
                   0, 0, 0, kControlScrollBarProc, (long) bar);
 #else
   ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p", width < disp_height,
@@ -4727,6 +4769,7 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
   /* Adjustments according to Inside Macintosh to make it look nice */
   disp_top = top;
   disp_height = height;
+#ifdef MAC_OS8
   if (disp_top == 0)
     {
       disp_top = -1;
@@ -4740,6 +4783,7 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
 
   if (sb_left + sb_width == FRAME_PIXEL_WIDTH (f))
     sb_left++;
+#endif
 
   /* Does the scroll bar exist yet?  */
   if (NILP (w->vertical_scroll_bar))
@@ -4775,8 +4819,10 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
           MoveControl (ch, sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM, disp_top);
           SizeControl (ch, sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
                       disp_height);
+#ifndef USE_TOOLKIT_SCROLL_BARS
          if (sb_width < disp_height)
            ShowControl (ch);
+#endif
 
           /* Remember new settings.  */
           XSETINT (bar->left, sb_left);
@@ -4794,30 +4840,41 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
 
 #ifdef USE_TOOLKIT_SCROLL_BARS
   if (NILP (bar->track_top))
-    {
-      ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
-      Rect r0, r1;
+    if (sb_width >= disp_height)
+      {
+       XSETINT (bar->track_top, 0);
+       XSETINT (bar->track_height, 0);
+      }
+    else
+      {
+       ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
+       Rect r0, r1;
 
-      BLOCK_INPUT;
+       BLOCK_INPUT;
 
-      SetControl32BitMinimum (ch, 0);
-      SetControl32BitMaximum (ch, 1);
-      SetControlViewSize (ch, 1);
+       SetControl32BitMinimum (ch, 0);
+       SetControl32BitMaximum (ch, 1);
+       SetControlViewSize (ch, 1);
 
-      /* Move the scroll bar thumb to the top.  */
-      SetControl32BitValue (ch, 0);
-      get_control_part_bounds (ch, kControlIndicatorPart, &r0);
+       /* Move the scroll bar thumb to the top.  */
+       SetControl32BitValue (ch, 0);
+       get_control_part_bounds (ch, kControlIndicatorPart, &r0);
 
-      /* Move the scroll bar thumb to the bottom.  */
-      SetControl32BitValue (ch, 1);
-      get_control_part_bounds (ch, kControlIndicatorPart, &r1);
+       /* Move the scroll bar thumb to the bottom.  */
+       SetControl32BitValue (ch, 1);
+       get_control_part_bounds (ch, kControlIndicatorPart, &r1);
 
-      UnionRect (&r0, &r1, &r0);
-      XSETINT (bar->track_top, r0.top);
-      XSETINT (bar->track_height, r0.bottom - r0.top);
+       UnionRect (&r0, &r1, &r0);
+       XSETINT (bar->track_top, r0.top);
+       XSETINT (bar->track_height, r0.bottom - r0.top);
 
-      UNBLOCK_INPUT;
-    }
+       /* Don't show the scroll bar if its height is not enough to
+          display the scroll bar thumb.  */
+       if (r0.bottom - r0.top > 0)
+         ShowControl (ch);
+
+       UNBLOCK_INPUT;
+      }
 
   x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
 #else /* not USE_TOOLKIT_SCROLL_BARS */
@@ -5188,7 +5245,7 @@ x_draw_hollow_cursor (w, row)
   /* Compute frame-relative coordinates for phys cursor.  */
   x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
   y = get_phys_cursor_geometry (w, row, cursor_glyph, &h);
-  wd = w->phys_cursor_width;
+  wd = w->phys_cursor_width + 1;
 
   /* The foreground of cursor_gc is typically the same as the normal
      background color, which can cause the cursor box to be invisible.  */
@@ -5299,7 +5356,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);
 }
 
 
@@ -5837,7 +5897,7 @@ x_raise_frame (f)
   if (f->async_visible)
     {
       BLOCK_INPUT;
-      SelectWindow (FRAME_MAC_WINDOW (f));
+      BringToFront (FRAME_MAC_WINDOW (f));
       UNBLOCK_INPUT;
     }
 }
@@ -5851,7 +5911,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;
     }
 }
@@ -5964,7 +6024,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));
     }
@@ -7832,9 +7891,13 @@ XLoadQueryFont (Display *dpy, char *fontname)
 #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
 
@@ -8346,6 +8409,7 @@ mac_get_mouse_btn (EventRef ref)
    XTread_socket loop).  */
 static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec)
 {
+  OSStatus err;
   Boolean result = ConvertEventRefToEventRecord (eventRef, eventRec);
 
   if (result)
@@ -8379,13 +8443,19 @@ static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec)
            unsigned char char_codes;
            UInt32 key_code;
 
-           eventRec->what = keyDown;
-           GetEventParameter (eventRef, kEventParamKeyMacCharCodes, typeChar,
-                              NULL, sizeof (char), NULL, &char_codes);
-           GetEventParameter (eventRef, kEventParamKeyCode, typeUInt32,
-                              NULL, sizeof (UInt32), NULL, &key_code);
-           eventRec->message = char_codes | ((key_code & 0xff) << 8);
-           result = 1;
+           err = GetEventParameter (eventRef, kEventParamKeyMacCharCodes,
+                                    typeChar, NULL, sizeof (char),
+                                    NULL, &char_codes);
+           if (err == noErr)
+             err = GetEventParameter (eventRef, kEventParamKeyCode,
+                                      typeUInt32, NULL, sizeof (UInt32),
+                                      NULL, &key_code);
+           if (err == noErr)
+             {
+               eventRec->what = keyDown;
+               eventRec->message = char_codes | ((key_code & 0xff) << 8);
+               result = 1;
+             }
          }
          break;
 
@@ -8401,7 +8471,7 @@ static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec)
   if (result)
     {
       /* Need where and when.  */
-      UInt32 mods;
+      UInt32 mods = 0;
 
       GetEventParameter (eventRef, kEventParamMouseLocation, typeQDPoint,
                         NULL, sizeof (Point), NULL, &eventRec->where);
@@ -8811,8 +8881,7 @@ mac_handle_command_event (next_handler, event, data)
      EventRef event;
      void *data;
 {
-  OSStatus result;
-  OSErr err;
+  OSStatus result, err;
   HICommand command;
   Lisp_Object class_key, id_key, binding;
 
@@ -8820,10 +8889,10 @@ mac_handle_command_event (next_handler, event, data)
   if (result != eventNotHandledErr)
     return result;
 
-  GetEventParameter (event, kEventParamDirectObject, typeHICommand, NULL,
-                    sizeof (HICommand), NULL, &command);
+  err = GetEventParameter (event, kEventParamDirectObject, typeHICommand,
+                          NULL, sizeof (HICommand), NULL, &command);
 
-  if (command.commandID == 0)
+  if (err != noErr || command.commandID == 0)
     return eventNotHandledErr;
 
   /* A HICommand event is mapped to an Apple event whose event class
@@ -8877,12 +8946,14 @@ mac_handle_window_event (next_handler, event, data)
      void *data;
 {
   WindowPtr wp;
-  OSStatus result;
+  OSStatus result, err;
   UInt32 attributes;
   XSizeHints *size_hints;
 
-  GetEventParameter (event, kEventParamDirectObject, typeWindowRef,
-                    NULL, sizeof (WindowPtr), NULL, &wp);
+  err = GetEventParameter (event, kEventParamDirectObject, typeWindowRef,
+                          NULL, sizeof (WindowPtr), NULL, &wp);
+  if (err != noErr)
+    return eventNotHandledErr;
 
   switch (GetEventKind (event))
     {
@@ -8899,8 +8970,11 @@ mac_handle_window_event (next_handler, event, data)
       if (result != eventNotHandledErr)
        return result;
 
-      GetEventParameter (event, kEventParamAttributes, typeUInt32,
-                        NULL, sizeof (UInt32), NULL, &attributes);
+      err = GetEventParameter (event, kEventParamAttributes, typeUInt32,
+                              NULL, sizeof (UInt32), NULL, &attributes);
+      if (err != noErr)
+       break;
+
       size_hints = FRAME_SIZE_HINTS (mac_window_to_frame (wp));
       if ((attributes & kWindowBoundsChangeUserResize)
          && ((size_hints->flags & (PResizeInc | PBaseSize | PMinSize))
@@ -8909,9 +8983,12 @@ mac_handle_window_event (next_handler, event, data)
          Rect bounds;
          int width, height;
 
-         GetEventParameter (event, kEventParamCurrentBounds,
-                            typeQDRectangle,
-                            NULL, sizeof (Rect), NULL, &bounds);
+         err = GetEventParameter (event, kEventParamCurrentBounds,
+                                  typeQDRectangle, NULL, sizeof (Rect),
+                                  NULL, &bounds);
+         if (err != noErr)
+           break;
+
          width = bounds.right - bounds.left;
          height = bounds.bottom - bounds.top;
 
@@ -8960,7 +9037,7 @@ mac_handle_mouse_event (next_handler, event, data)
      EventRef event;
      void *data;
 {
-  OSStatus result;
+  OSStatus result, err;
 
   switch (GetEventKind (event))
     {
@@ -8976,22 +9053,31 @@ mac_handle_mouse_event (next_handler, event, data)
        if (result != eventNotHandledErr || read_socket_inev == NULL)
          return result;
 
-       GetEventParameter (event, kEventParamWindowRef, typeWindowRef,
-                          NULL, sizeof (WindowRef), NULL, &wp);
+       err = GetEventParameter (event, kEventParamWindowRef, typeWindowRef,
+                                NULL, sizeof (WindowRef), NULL, &wp);
+       if (err != noErr)
+         break;
+
        f = mac_window_to_frame (wp);
        if (f != mac_focus_frame (&one_mac_display_info))
          break;
 
-       GetEventParameter (event, kEventParamMouseWheelAxis,
-                          typeMouseWheelAxis, NULL,
-                          sizeof (EventMouseWheelAxis), NULL, &axis);
-       if (axis != kEventMouseWheelAxisY)
+       err = GetEventParameter (event, kEventParamMouseWheelAxis,
+                                typeMouseWheelAxis, NULL,
+                                sizeof (EventMouseWheelAxis), NULL, &axis);
+       if (err != noErr || axis != kEventMouseWheelAxisY)
          break;
 
-       GetEventParameter (event, kEventParamMouseWheelDelta, typeSInt32,
-                          NULL, sizeof (SInt32), NULL, &delta);
-       GetEventParameter (event, kEventParamMouseLocation, typeQDPoint,
-                          NULL, sizeof (Point), NULL, &point);
+       err = GetEventParameter (event, kEventParamMouseWheelDelta,
+                                typeSInt32, NULL, sizeof (SInt32),
+                                NULL, &delta);
+       if (err != noErr)
+         break;
+       err = GetEventParameter (event, kEventParamMouseLocation,
+                                typeQDPoint, NULL, sizeof (Point),
+                                NULL, &point);
+       if (err != noErr)
+         break;
        read_socket_inev->kind = WHEEL_EVENT;
        read_socket_inev->code = 0;
        read_socket_inev->modifiers =
@@ -9453,13 +9539,13 @@ convert_fn_keycode (EventRef eventRef, int keyCode, int *newCode)
   Fn modifier. That's why we need the table.
 
   */
-
+  OSStatus err;
   UInt32 mods = 0;
   if (!NILP(Vmac_function_modifier))
     {
-      GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, NULL,
-                        sizeof (UInt32), NULL, &mods);
-      if (mods & kEventKeyModifierFnMask)
+      err = GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32,
+                              NULL, sizeof (UInt32), NULL, &mods);
+      if (err != noErr && mods & kEventKeyModifierFnMask)
        {  *newCode = fn_keycode_to_xkeysym_table [keyCode & 0x7f];
 
          return (*newCode != 0);
@@ -9581,6 +9667,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 ();
 
@@ -10221,6 +10309,7 @@ XTread_socket (sd, expected, hold_quit)
   }
 #endif
 
+  --handling_signal;
   UNBLOCK_INPUT;
   return count;
 }