]> code.delx.au - gnu-emacs/blobdiff - src/macterm.c
Merge from emacs--devo--0
[gnu-emacs] / src / macterm.c
index 6f9e6273cb7d0b0acbe59f9fe886e7688ed0c5f7..5643372845b5c976515161544dbd8d199c4123d2 100644 (file)
@@ -1,12 +1,12 @@
 /* Implementation of GUI terminal on the Mac OS.
    Copyright (C) 2000, 2001, 2002, 2003, 2004,
-                 2005, 2006 Free Software Foundation, Inc.
+                 2005, 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -35,12 +35,7 @@ Boston, MA 02110-1301, USA.  */
 #include <alloca.h>
 #endif
 
-#if TARGET_API_MAC_CARBON
-/* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to
-   obtain events from the event queue.  If set to 0, WaitNextEvent is
-   used instead.  */
-#define USE_CARBON_EVENTS 1
-#else /* not TARGET_API_MAC_CARBON */
+#if !TARGET_API_MAC_CARBON
 #include <Quickdraw.h>
 #include <ToolUtils.h>
 #include <Sound.h>
@@ -52,6 +47,7 @@ Boston, MA 02110-1301, USA.  */
 #include <LowMem.h>
 #include <Controls.h>
 #include <Windows.h>
+#include <Displays.h>
 #if defined (__MRC__) || (__MSL__ >= 0x6000)
 #include <ControlDefinitions.h>
 #endif
@@ -230,21 +226,22 @@ void x_raise_frame P_ ((struct frame *));
 void x_set_window_size P_ ((struct frame *, int, int, int));
 void x_wm_set_window_state P_ ((struct frame *, int));
 void x_wm_set_icon_pixmap P_ ((struct frame *, int));
-void mac_initialize P_ ((void));
+static void mac_initialize P_ ((void));
 static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
 static int x_compute_min_glyph_bounds P_ ((struct frame *));
 static void x_update_end P_ ((struct frame *));
 static void XTframe_up_to_date P_ ((struct frame *));
-static void XTset_terminal_modes P_ ((void));
-static void XTreset_terminal_modes P_ ((void));
-static void x_clear_frame P_ ((void));
+static void XTset_terminal_modes P_ ((struct terminal *));
+static void XTreset_terminal_modes P_ ((struct terminal *));
+static void x_clear_frame P_ ((struct frame *));
 static void frame_highlight P_ ((struct frame *));
 static void frame_unhighlight P_ ((struct frame *));
 static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
 static void mac_focus_changed P_ ((int, struct mac_display_info *,
                                   struct frame *, struct input_event *));
 static void x_detect_focus_change P_ ((struct mac_display_info *,
-                                      EventRecord *, struct input_event *));
+                                      const EventRecord *,
+                                      struct input_event *));
 static void XTframe_rehighlight P_ ((struct frame *));
 static void x_frame_rehighlight P_ ((struct x_display_info *));
 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
@@ -261,24 +258,73 @@ static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
                                            Lisp_Object *, Lisp_Object *,
                                            unsigned long *));
 
-static int is_emacs_window P_ ((WindowPtr));
+static int is_emacs_window P_ ((WindowRef));
 static XCharStruct *mac_per_char_metric P_ ((XFontStruct *, XChar2b *, int));
 static void XSetFont P_ ((Display *, GC, XFontStruct *));
+static struct terminal *mac_create_terminal P_ ((struct mac_display_info *dpyinfo));
+
 
 #define GC_FORE_COLOR(gc)      (&(gc)->fore_color)
 #define GC_BACK_COLOR(gc)      (&(gc)->back_color)
 #define GC_FONT(gc)            ((gc)->xgcv.font)
 #define FRAME_NORMAL_GC(f)     ((f)->output_data.mac->normal_gc)
-#define CG_SET_FILL_COLOR(context, color)                      \
+
+#define CG_SET_FILL_COLOR(context, color)                              \
   CGContextSetRGBFillColor (context,                                   \
                            RED_FROM_ULONG (color) / 255.0f,            \
                            GREEN_FROM_ULONG (color) / 255.0f,          \
                            BLUE_FROM_ULONG (color) / 255.0f, 1.0f)
-#define CG_SET_STROKE_COLOR(context, color)            \
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+#define CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+  do {                                                                \
+    if (CGColorGetTypeID != NULL)                                     \
+      CGContextSetFillColorWithColor (context, cg_color);             \
+    else                                                              \
+      CG_SET_FILL_COLOR (context, color);                             \
+  } while (0)
+#else
+#define CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+  CGContextSetFillColorWithColor (context, cg_color)
+#endif
+#else
+#define CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+  CG_SET_FILL_COLOR (context, color)
+#endif
+#define CG_SET_FILL_COLOR_WITH_GC_FOREGROUND(context, gc)              \
+  CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR (context, (gc)->xgcv.foreground,        \
+                                       (gc)->cg_fore_color)
+#define CG_SET_FILL_COLOR_WITH_GC_BACKGROUND(context, gc)              \
+  CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR (context, (gc)->xgcv.background,        \
+                                       (gc)->cg_back_color)
+
+
+#define CG_SET_STROKE_COLOR(context, color)                            \
   CGContextSetRGBStrokeColor (context,                                 \
                              RED_FROM_ULONG (color) / 255.0f,          \
                              GREEN_FROM_ULONG (color) / 255.0f,        \
                              BLUE_FROM_ULONG (color) / 255.0f, 1.0f)
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+#define CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+  do {                                                                \
+    if (CGColorGetTypeID != NULL)                                     \
+      CGContextSetStrokeColorWithColor (context, cg_color);           \
+    else                                                              \
+      CG_SET_STROKE_COLOR (context, color);                           \
+  } while (0)
+#else
+#define CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+  CGContextSetStrokeColorWithColor (context, cg_color)
+#endif
+#else
+#define CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+  CG_SET_STROKE_COLOR (context, color)
+#endif
+#define CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND(context, gc) \
+  CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR (context, (gc)->xgcv.foreground, \
+                                         (gc)->cg_fore_color)
+
 #if USE_CG_DRAWING
 #define FRAME_CG_CONTEXT(f)    ((f)->output_data.mac->cg_context)
 
@@ -287,6 +333,29 @@ static void XSetFont P_ ((Display *, GC, XFontStruct *));
 static int max_fringe_bmp = 0;
 static CGImageRef *fringe_bmp = 0;
 
+static CGColorSpaceRef mac_cg_color_space_rgb;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+static CGColorRef mac_cg_color_black;
+#endif
+
+static void
+init_cg_color ()
+{
+  mac_cg_color_space_rgb = CGColorSpaceCreateDeviceRGB ();
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+  /* Don't check the availability of CGColorCreate; this symbol is
+     defined even in Mac OS X 10.1.  */
+  if (CGColorGetTypeID != NULL)
+#endif
+    {
+      float rgba[] = {0.0f, 0.0f, 0.0f, 1.0f};
+
+      mac_cg_color_black = CGColorCreate (mac_cg_color_space_rgb, rgba);
+    }
+#endif
+}
+
 static CGContextRef
 mac_begin_cg_clip (f, gc)
      struct frame *f;
@@ -344,7 +413,8 @@ mac_prepare_for_quickdraw (f)
 static RgnHandle saved_port_clip_region = NULL;
 
 static void
-mac_begin_clip (gc)
+mac_begin_clip (f, gc)
+     struct frame *f;
      GC gc;
 {
   static RgnHandle new_region = NULL;
@@ -354,6 +424,11 @@ mac_begin_clip (gc)
   if (new_region == NULL)
     new_region = NewRgn ();
 
+#if USE_CG_DRAWING
+  mac_prepare_for_quickdraw (f);
+#endif
+  SetPortWindowPort (FRAME_MAC_WINDOW (f));
+
   if (gc->n_clip_rects)
     {
       GetClip (saved_port_clip_region);
@@ -373,15 +448,6 @@ mac_end_clip (gc)
 
 /* X display function emulation */
 
-void
-XFreePixmap (display, pixmap)
-     Display *display;         /* not used */
-     Pixmap pixmap;
-{
-  DisposeGWorld (pixmap);
-}
-
-
 /* Mac version of XDrawLine.  */
 
 static void
@@ -400,7 +466,7 @@ mac_draw_line (f, gc, x1, y1, x2, y2)
     gy1 += 0.5f, gy2 += 0.5f;
 
   context = mac_begin_cg_clip (f, gc);
-  CG_SET_STROKE_COLOR (context, gc->xgcv.foreground);
+  CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND (context, gc);
   CGContextBeginPath (context);
   CGContextMoveToPoint (context, gx1, gy1);
   CGContextAddLineToPoint (context, gx2, gy2);
@@ -423,19 +489,18 @@ mac_draw_line (f, gc, x1, y1, x2, y2)
        x2--;
     }
 
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
+  mac_begin_clip (f, gc);
   RGBForeColor (GC_FORE_COLOR (gc));
-
-  mac_begin_clip (gc);
   MoveTo (x1, y1);
   LineTo (x2, y2);
   mac_end_clip (gc);
 #endif
 }
 
+/* Mac version of XDrawLine (to Pixmap).  */
+
 void
-mac_draw_line_to_pixmap (display, p, gc, x1, y1, x2, y2)
+XDrawLine (display, p, gc, x1, y1, x2, y2)
      Display *display;
      Pixmap p;
      GC gc;
@@ -481,25 +546,25 @@ mac_erase_rectangle (f, gc, x, y, width, height)
      unsigned int width, height;
 {
 #if USE_CG_DRAWING
-  CGContextRef context;
+    {
+      CGContextRef context;
 
-  context = mac_begin_cg_clip (f, gc);
-  CG_SET_FILL_COLOR (context, gc->xgcv.background);
-  CGContextFillRect (context, CGRectMake (x, y, width, height));
-  mac_end_cg_clip (f);
+      context = mac_begin_cg_clip (f, gc);
+      CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
+      CGContextFillRect (context, CGRectMake (x, y, width, height));
+      mac_end_cg_clip (f);
+    }
 #else
-  Rect r;
-
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
-  RGBBackColor (GC_BACK_COLOR (gc));
-  SetRect (&r, x, y, x + width, y + height);
-
-  mac_begin_clip (gc);
-  EraseRect (&r);
-  mac_end_clip (gc);
+    {
+      Rect r;
 
-  RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+      mac_begin_clip (f, gc);
+      RGBBackColor (GC_BACK_COLOR (gc));
+      SetRect (&r, x, y, x + width, y + height);
+      EraseRect (&r);
+      RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+      mac_end_clip (gc);
+    }
 #endif
 }
 
@@ -522,15 +587,17 @@ mac_clear_window (f)
      struct frame *f;
 {
 #if USE_CG_DRAWING
-  CGContextRef context;
-  GC gc = FRAME_NORMAL_GC (f);
-
-  context = mac_begin_cg_clip (f, NULL);
-  CG_SET_FILL_COLOR (context, gc->xgcv.background);
-  CGContextFillRect (context, CGRectMake (0, 0, FRAME_PIXEL_WIDTH (f),
-                                         FRAME_PIXEL_HEIGHT (f)));
-  mac_end_cg_clip (f);
-#else
+  {
+    CGContextRef context;
+    GC gc = FRAME_NORMAL_GC (f);
+
+    context = mac_begin_cg_clip (f, NULL);
+    CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
+    CGContextFillRect (context, CGRectMake (0, 0, FRAME_PIXEL_WIDTH (f),
+                                           FRAME_PIXEL_HEIGHT (f)));
+    mac_end_cg_clip (f);
+  }
+#else  /* !USE_CG_DRAWING */
   SetPortWindowPort (FRAME_MAC_WINDOW (f));
 
   RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
@@ -569,14 +636,14 @@ mac_draw_cg_image (image, f, gc, src_x, src_y, width, height,
   context = mac_begin_cg_clip (f, gc);
   if (!overlay_p)
     {
-      CG_SET_FILL_COLOR (context, gc->xgcv.background);
+      CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
       CGContextFillRect (context, dest_rect);
     }
   CGContextClipToRect (context, dest_rect);
   CGContextScaleCTM (context, 1, -1);
   CGContextTranslateCTM (context, 0, -port_height);
   if (CGImageIsMask (image))
-    CG_SET_FILL_COLOR (context, gc->xgcv.foreground);
+    CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
   CGContextDrawImage (context,
                      CGRectMake (dest_x - src_x,
                                  port_height - (dest_y - src_y
@@ -604,13 +671,10 @@ mac_draw_bitmap (f, gc, x, y, width, height, bits, overlay_p)
   bitmap.baseAddr = (char *)bits;
   SetRect (&(bitmap.bounds), 0, 0, width, height);
 
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
+  mac_begin_clip (f, gc);
   RGBForeColor (GC_FORE_COLOR (gc));
   RGBBackColor (GC_BACK_COLOR (gc));
   SetRect (&r, x, y, x + width, y + height);
-
-  mac_begin_clip (gc);
 #if TARGET_API_MAC_CARBON
   {
     CGrafPtr port;
@@ -625,9 +689,8 @@ 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);
-
   RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+  mac_end_clip (gc);
 }
 #endif /* !USE_CG_DRAWING */
 
@@ -640,7 +703,7 @@ mac_create_bitmap_from_bitmap_data (bitmap, bits, w, h)
      char *bits;
      int w, h;
 {
-  static unsigned char swap_nibble[16]
+  static const unsigned char swap_nibble[16]
     = { 0x0, 0x8, 0x4, 0xc,    /* 0000 1000 0100 1100 */
        0x2, 0xa, 0x6, 0xe,    /* 0010 1010 0110 1110 */
        0x1, 0x9, 0x5, 0xd,    /* 0001 1001 0101 1101 */
@@ -660,7 +723,7 @@ mac_create_bitmap_from_bitmap_data (bitmap, bits, w, h)
          /* Bitswap XBM bytes to match how Mac does things.  */
          unsigned char c = *bits++;
          *p++ = (unsigned char)((swap_nibble[c & 0xf] << 4)
-                                | (swap_nibble[(c>>4) & 0xf]));;
+                                | (swap_nibble[(c>>4) & 0xf]));
        }
     }
 
@@ -678,8 +741,8 @@ mac_free_bitmap (bitmap)
 
 Pixmap
 XCreatePixmap (display, w, width, height, depth)
-     Display *display;         /* not used */
-     WindowPtr w;
+     Display *display;
+     WindowRef w;
      unsigned int width, height;
      unsigned int depth;
 {
@@ -707,8 +770,8 @@ XCreatePixmap (display, w, width, height, depth)
 
 Pixmap
 XCreatePixmapFromBitmapData (display, w, data, width, height, fg, bg, depth)
-     Display *display;         /* not used */
-     WindowPtr w;
+     Display *display;
+     WindowRef w;
      char *data;
      unsigned int width, height;
      unsigned long fg, bg;
@@ -718,7 +781,7 @@ XCreatePixmapFromBitmapData (display, w, data, width, height, fg, bg, depth)
   BitMap bitmap;
   CGrafPtr old_port;
   GDHandle old_gdh;
-  static GC gc = NULL;         /* not reentrant */
+  static GC gc = NULL;
 
   if (gc == NULL)
     gc = XCreateGC (display, w, 0, NULL);
@@ -750,6 +813,15 @@ XCreatePixmapFromBitmapData (display, w, data, width, height, fg, bg, depth)
 }
 
 
+void
+XFreePixmap (display, pixmap)
+     Display *display;
+     Pixmap pixmap;
+{
+  DisposeGWorld (pixmap);
+}
+
+
 /* Mac replacement for XFillRectangle.  */
 
 static void
@@ -763,18 +835,15 @@ mac_fill_rectangle (f, gc, x, y, width, height)
   CGContextRef context;
 
   context = mac_begin_cg_clip (f, gc);
-  CG_SET_FILL_COLOR (context, gc->xgcv.foreground);
+  CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
   CGContextFillRect (context, CGRectMake (x, y, width, height));
   mac_end_cg_clip (f);
 #else
   Rect r;
 
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
+  mac_begin_clip (f, gc);
   RGBForeColor (GC_FORE_COLOR (gc));
   SetRect (&r, x, y, x + width, y + height);
-
-  mac_begin_clip (gc);
   PaintRect (&r); /* using foreground color of gc */
   mac_end_clip (gc);
 #endif
@@ -794,25 +863,41 @@ mac_draw_rectangle (f, gc, x, y, width, height)
   CGContextRef context;
 
   context = mac_begin_cg_clip (f, gc);
-  CG_SET_STROKE_COLOR (context, gc->xgcv.foreground);
+  CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND (context, gc);
   CGContextStrokeRect (context,
                       CGRectMake (x + 0.5f, y + 0.5f, width, height));
   mac_end_cg_clip (f);
 #else
   Rect r;
 
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
+  mac_begin_clip (f, gc);
   RGBForeColor (GC_FORE_COLOR (gc));
   SetRect (&r, x, y, x + width + 1, y + height + 1);
-
-  mac_begin_clip (gc);
   FrameRect (&r); /* using foreground color of gc */
   mac_end_clip (gc);
 #endif
 }
 
 
+static void
+mac_invert_rectangle (f, x, y, width, height)
+     struct frame *f;
+     int x, y;
+     unsigned int width, height;
+{
+  Rect r;
+
+#if USE_CG_DRAWING
+  mac_prepare_for_quickdraw (f);
+#endif
+  SetPortWindowPort (FRAME_MAC_WINDOW (f));
+
+  SetRect (&r, x, y, x + width, y + height);
+
+  InvertRect (&r);
+}
+
+
 #if USE_ATSUI
 static OSStatus
 atsu_get_text_layout_with_text_ptr (text, text_length, style, text_layout)
@@ -822,13 +907,13 @@ atsu_get_text_layout_with_text_ptr (text, text_length, style, text_layout)
      ATSUTextLayout *text_layout;
 {
   OSStatus err;
-  static ATSUTextLayout saved_text_layout = NULL; /* not reentrant */
+  static ATSUTextLayout saved_text_layout = NULL;
 
   if (saved_text_layout == NULL)
     {
-      UniCharCount lengths[] = {kATSUToTextEnd};
-      ATSUAttributeTag tags[] = {kATSULineLayoutOptionsTag};
-      ByteCount sizes[] = {sizeof (ATSLineLayoutOptions)};
+      static const UniCharCount lengths[] = {kATSUToTextEnd};
+      static const ATSUAttributeTag tags[] = {kATSULineLayoutOptionsTag};
+      static const ByteCount sizes[] = {sizeof (ATSLineLayoutOptions)};
       static ATSLineLayoutOptions line_layout =
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
        kATSLineDisableAllLayoutOperations | kATSLineUseDeviceMetrics
@@ -837,7 +922,7 @@ atsu_get_text_layout_with_text_ptr (text, text_length, style, text_layout)
        kATSLineIsDisplayOnly | kATSLineFractDisable
 #endif
        ;
-      ATSUAttributeValuePtr values[] = {&line_layout};
+      static const ATSUAttributeValuePtr values[] = {&line_layout};
 
       err = ATSUCreateTextLayoutWithTextPtr (text,
                                             kATSUFromTextBeginning,
@@ -849,7 +934,6 @@ atsu_get_text_layout_with_text_ptr (text, text_length, style, text_layout)
        err = ATSUSetLayoutControls (saved_text_layout,
                                     sizeof (tags) / sizeof (tags[0]),
                                     tags, sizes, values);
-      /* XXX: Should we do this? */
       if (err == noErr)
        err = ATSUSetTransientFontMatching (saved_text_layout, true);
     }
@@ -868,260 +952,254 @@ atsu_get_text_layout_with_text_ptr (text, text_length, style, text_layout)
     *text_layout = saved_text_layout;
   return err;
 }
-#endif
-
-
-static void
-mac_invert_rectangle (f, x, y, width, height)
-     struct frame *f;
-     int x, y;
-     unsigned int width, height;
-{
-  Rect r;
-
-#if USE_CG_DRAWING
-  mac_prepare_for_quickdraw (f);
-#endif
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
-  SetRect (&r, x, y, x + width, y + height);
-
-  InvertRect (&r);
-}
 
 
 static void
-mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width, bytes_per_char)
+mac_draw_image_string_atsui (f, gc, x, y, buf, nchars, bg_width,
+                            overstrike_p, bytes_per_char)
      struct frame *f;
      GC gc;
      int x, y;
      char *buf;
-     int nchars, bg_width, bytes_per_char;
+     int nchars, bg_width, overstrike_p, bytes_per_char;
 {
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
-#if USE_ATSUI
-  if (GC_FONT (gc)->mac_style)
-    {
-      OSStatus err;
-      ATSUTextLayout text_layout;
+  OSStatus err;
+  ATSUTextLayout text_layout;
 
-      xassert (bytes_per_char == 2);
+  xassert (bytes_per_char == 2);
 
 #ifndef WORDS_BIG_ENDIAN
-      {
-       int i;
-       UniChar *text = (UniChar *)buf;
+  {
+    int i;
+    UniChar *text = (UniChar *)buf;
 
-       for (i = 0; i < nchars; i++)
-         text[i] = EndianU16_BtoN (text[i]);
-      }
+    for (i = 0; i < nchars; i++)
+      text[i] = EndianU16_BtoN (text[i]);
+  }
 #endif
-      err = atsu_get_text_layout_with_text_ptr ((ConstUniCharArrayPtr)buf,
-                                               nchars,
-                                               GC_FONT (gc)->mac_style,
-                                               &text_layout);
-      if (err != noErr)
-       return;
+  err = atsu_get_text_layout_with_text_ptr ((ConstUniCharArrayPtr)buf,
+                                           nchars,
+                                           GC_FONT (gc)->mac_style,
+                                           &text_layout);
+  if (err != noErr)
+    return;
 #ifdef MAC_OSX
-      if (!mac_use_core_graphics)
-       {
-#endif
-#if USE_CG_DRAWING
-         mac_prepare_for_quickdraw (f);
+  if (!mac_use_core_graphics)
+    {
 #endif
-         mac_begin_clip (gc);
-         RGBForeColor (GC_FORE_COLOR (gc));
-         if (bg_width)
-           {
-             Rect r;
+      mac_begin_clip (f, 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)));
-           }
-         MoveTo (x, y);
+         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)));
+       }
+      MoveTo (x, y);
+      ATSUDrawText (text_layout,
+                   kATSUFromTextBeginning, kATSUToTextEnd,
+                   kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
+      if (overstrike_p)
+       {
+         MoveTo (x + 1, 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};
+      mac_end_clip (gc);
+#ifdef MAC_OSX
+    }
+  else
+    {
+      static CGContextRef context;
+      float port_height = FRAME_PIXEL_HEIGHT (f);
+      static const ATSUAttributeTag tags[] = {kATSUCGContextTag};
+      static const ByteCount sizes[] = {sizeof (CGContextRef)};
+      static const ATSUAttributeValuePtr values[] = {&context};
 
 #if USE_CG_DRAWING
-         context = mac_begin_cg_clip (f, gc);
+      context = mac_begin_cg_clip (f, gc);
 #else
-         GetPort (&port);
-         QDBeginCGContext (port, &context);
-         if (gc->n_clip_rects || bg_width)
-           {
-             CGContextTranslateCTM (context, 0, port_height);
-             CGContextScaleCTM (context, 1, -1);
-             if (gc->n_clip_rects)
-               CGContextClipToRects (context, gc->clip_rects,
-                                     gc->n_clip_rects);
+      CGrafPtr port;
+
+      GetPort (&port);
+      QDBeginCGContext (port, &context);
+      if (gc->n_clip_rects || bg_width)
+       {
+         CGContextTranslateCTM (context, 0, port_height);
+         CGContextScaleCTM (context, 1, -1);
+         if (gc->n_clip_rects)
+           CGContextClipToRects (context, gc->clip_rects,
+                                 gc->n_clip_rects);
 #endif
-             if (bg_width)
-               {
-                 CG_SET_FILL_COLOR (context, gc->xgcv.background);
-                 CGContextFillRect
-                   (context,
-                    CGRectMake (x, y - FONT_BASE (GC_FONT (gc)),
-                                bg_width, FONT_HEIGHT (GC_FONT (gc))));
-               }
-             CGContextScaleCTM (context, 1, -1);
-             CGContextTranslateCTM (context, 0, -port_height);
-#if !USE_CG_DRAWING
+         if (bg_width)
+           {
+             CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
+             CGContextFillRect (context,
+                                CGRectMake (x, y - FONT_BASE (GC_FONT (gc)),
+                                            bg_width,
+                                            FONT_HEIGHT (GC_FONT (gc))));
            }
+         CGContextScaleCTM (context, 1, -1);
+         CGContextTranslateCTM (context, 0, -port_height);
+#if !USE_CG_DRAWING
+       }
 #endif
-         CG_SET_FILL_COLOR (context, gc->xgcv.foreground);
-         err = ATSUSetLayoutControls (text_layout,
-                                      sizeof (tags) / sizeof (tags[0]),
-                                      tags, sizes, values);
-         if (err == noErr)
+      CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
+      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));
+         if (overstrike_p)
            ATSUDrawText (text_layout,
                          kATSUFromTextBeginning, kATSUToTextEnd,
-                         Long2Fix (x), Long2Fix (port_height - y));
+                         Long2Fix (x + 1), Long2Fix (port_height - y));
+       }
 #if USE_CG_DRAWING
-         mac_end_cg_clip (f);
-         context = NULL;
+      mac_end_cg_clip (f);
+      context = NULL;
 #else
-         CGContextSynchronize (context);
-         QDEndCGContext (port, &context);
+      CGContextSynchronize (context);
+      QDEndCGContext (port, &context);
 #endif
 #if 0
-         /* This doesn't work on Mac OS X 10.1.  */
-         ATSUClearLayoutControls (text_layout,
-                                  sizeof (tags) / sizeof (tags[0]), tags);
+      /* 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);
+      ATSUSetLayoutControls (text_layout,
+                            sizeof (tags) / sizeof (tags[0]),
+                            tags, sizes, values);
 #endif
-       }
-#endif /* MAC_OSX */
     }
-  else
+#endif /* MAC_OSX */
+}
 #endif /* USE_ATSUI */
-    {
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
-      UInt32 savedFlags;
 
-      if (mac_use_core_graphics)
-       savedFlags = SwapQDTextFlags (kQDUseCGTextRendering);
+
+static void
+mac_draw_image_string_qd (f, gc, x, y, buf, nchars, bg_width,
+                         overstrike_p, bytes_per_char)
+     struct frame *f;
+     GC gc;
+     int x, y;
+     char *buf;
+     int nchars, bg_width, overstrike_p, bytes_per_char;
+{
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+  UInt32 savedFlags;
 #endif
-#if USE_CG_DRAWING
-      mac_prepare_for_quickdraw (f);
+
+  mac_begin_clip (f, gc);
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+  if (mac_use_core_graphics)
+    savedFlags = SwapQDTextFlags (kQDUseCGTextRendering);
 #endif
-      mac_begin_clip (gc);
-      RGBForeColor (GC_FORE_COLOR (gc));
+  RGBForeColor (GC_FORE_COLOR (gc));
 #ifdef MAC_OS8
-      if (bg_width)
-       {
-         RGBBackColor (GC_BACK_COLOR (gc));
-         TextMode (srcCopy);
-       }
-      else
-       TextMode (srcOr);
+  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;
+  /* 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;
 
-         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);
+      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);
+  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 (overstrike_p)
+    {
+      TextMode (srcOr);
+      MoveTo (x + 1, y);
       DrawText (buf, 0, nchars * bytes_per_char);
-      if (bg_width)
-       RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
-      mac_end_clip (gc);
+    }
+  if (bg_width)
+    RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+  mac_end_clip (gc);
 
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
-      if (mac_use_core_graphics)
-       SwapQDTextFlags(savedFlags);
+  if (mac_use_core_graphics)
+    SwapQDTextFlags(savedFlags);
 #endif
-    }
 }
 
 
-/* Mac replacement for XDrawString.  */
-
-static void
-mac_draw_string (f, gc, x, y, buf, nchars)
+static INLINE void
+mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width,
+                       overstrike_p, bytes_per_char)
      struct frame *f;
      GC gc;
      int x, y;
      char *buf;
-     int nchars;
+     int nchars, bg_width, overstrike_p, bytes_per_char;
 {
-  mac_draw_string_common (f, gc, x, y, buf, nchars, 0, 1);
+#if USE_ATSUI
+  if (GC_FONT (gc)->mac_style)
+    mac_draw_image_string_atsui (f, gc, x, y, buf, nchars, bg_width,
+                                overstrike_p, bytes_per_char);
+  else
+#endif /* USE_ATSUI */
+    mac_draw_image_string_qd (f, gc, x, y, buf, nchars, bg_width,
+                             overstrike_p, bytes_per_char);
 }
 
 
-/* Mac replacement for XDrawString16. */
+/* Mac replacement for XDrawImageString.  */
 
 static void
-mac_draw_string_16 (f, gc, x, y, buf, nchars)
-     struct frame *f;
-     GC gc;
-     int x, y;
-     XChar2b *buf;
-     int nchars;
-{
-  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, bg_width)
+mac_draw_image_string (f, gc, x, y, buf, nchars, bg_width, overstrike_p)
      struct frame *f;
      GC gc;
      int x, y;
      char *buf;
-     int nchars, bg_width;
+     int nchars, bg_width, overstrike_p;
 {
-  mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width, 1);
+  mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width,
+                         overstrike_p, 1);
 }
 
 
-/* Mac replacement for XDrawString16.  */
+/* Mac replacement for XDrawImageString16.  */
 
 static void
-mac_draw_image_string_16 (f, gc, x, y, buf, nchars, bg_width)
+mac_draw_image_string_16 (f, gc, x, y, buf, nchars, bg_width, overstrike_p)
      struct frame *f;
      GC gc;
      int x, y;
      XChar2b *buf;
-     int nchars, bg_width;
+     int nchars, bg_width, overstrike_p;
 {
-  mac_draw_string_common (f, gc, x, y, (char *) buf, nchars, bg_width, 2);
+  mac_draw_string_common (f, gc, x, y, (char *) buf, nchars, bg_width,
+                         overstrike_p, 2);
 }
 
 
@@ -1159,7 +1237,8 @@ mac_query_char_extents (style, c,
       UniChar ch = c;
 
       err = atsu_get_text_layout_with_text_ptr (&ch, 1, style, &text_layout);
-      if (err == noErr)
+      if (err == noErr
+         && (font_ascent_return || font_descent_return || overall_return))
        {
          ATSTrapezoid glyph_bounds;
 
@@ -1204,7 +1283,12 @@ mac_query_char_extents (style, c,
                err1 = ATSUGetGlyphInfo (text_layout, kATSUFromTextBeginning,
                                         kATSUToTextEnd, &count,
                                         &glyph_info_array);
-             if (err1 == noErr)
+             if (err1 == noErr
+                 /* Make sure that we don't have to make layout
+                    adjustments.  */
+                 && glyph_info_array.glyphs[0].deltaY == 0.0f
+                 && glyph_info_array.glyphs[0].idealX == 0.0f
+                 && glyph_info_array.glyphs[0].screenX == 0)
                {
                  xassert (glyph_info_array.glyphs[0].glyphID);
                  *cg_glyph = glyph_info_array.glyphs[0].glyphID;
@@ -1295,14 +1379,13 @@ init_cg_text_anti_aliasing_threshold ()
 }
 
 static int
-mac_draw_image_string_cg (f, gc, x, y, buf, nchars, bg_width)
+mac_draw_image_string_cg (f, gc, x, y, buf, nchars, bg_width, overstrike_p)
      struct frame *f;
      GC gc;
      int x, y;
      XChar2b *buf;
-     int nchars, bg_width;
+     int nchars, bg_width, overstrike_p;
 {
-  CGrafPtr port;
   float port_height, gx, gy;
   int i;
   CGContextRef context;
@@ -1312,7 +1395,6 @@ mac_draw_image_string_cg (f, gc, x, y, buf, nchars, bg_width)
   if (!mac_use_core_graphics || GC_FONT (gc)->cg_font == NULL)
     return 0;
 
-  port = GetWindowPort (FRAME_MAC_WINDOW (f));
   port_height = FRAME_PIXEL_HEIGHT (f);
   gx = x;
   gy = port_height - y;
@@ -1333,7 +1415,7 @@ mac_draw_image_string_cg (f, gc, x, y, buf, nchars, bg_width)
 #if USE_CG_DRAWING
   context = mac_begin_cg_clip (f, gc);
 #else
-  QDBeginCGContext (port, &context);
+  QDBeginCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)), &context);
   if (gc->n_clip_rects || bg_width)
     {
       CGContextTranslateCTM (context, 0, port_height);
@@ -1343,7 +1425,7 @@ mac_draw_image_string_cg (f, gc, x, y, buf, nchars, bg_width)
 #endif
       if (bg_width)
        {
-         CG_SET_FILL_COLOR (context, gc->xgcv.background);
+         CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
          CGContextFillRect
            (context,
             CGRectMake (gx, y - FONT_BASE (GC_FONT (gc)),
@@ -1354,26 +1436,44 @@ mac_draw_image_string_cg (f, gc, x, y, buf, nchars, bg_width)
 #if !USE_CG_DRAWING
     }
 #endif
-  CG_SET_FILL_COLOR (context, gc->xgcv.foreground);
+  CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
   CGContextSetFont (context, GC_FONT (gc)->cg_font);
   CGContextSetFontSize (context, GC_FONT (gc)->mac_fontsize);
   if (GC_FONT (gc)->mac_fontsize <= cg_text_anti_aliasing_threshold)
     CGContextSetShouldAntialias (context, false);
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-  CGContextSetTextPosition (context, gx, gy);
-  CGContextShowGlyphsWithAdvances (context, glyphs, advances, nchars);
-#else
-  for (i = 0; i < nchars; i++)
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+  if (CGContextShowGlyphsWithAdvances != NULL)
+#endif
     {
-      CGContextShowGlyphsAtPoint (context, gx, gy, glyphs + i, 1);
-      gx += advances[i].width;
+      CGContextSetTextPosition (context, gx, gy);
+      CGContextShowGlyphsWithAdvances (context, glyphs, advances, nchars);
+      if (overstrike_p)
+       {
+         CGContextSetTextPosition (context, gx + 1.0f, gy);
+         CGContextShowGlyphsWithAdvances (context, glyphs, advances, nchars);
+       }
+    }
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+  else                  /* CGContextShowGlyphsWithAdvances == NULL */
+#endif
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030  */
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+    {
+      for (i = 0; i < nchars; i++)
+       {
+         CGContextShowGlyphsAtPoint (context, gx, gy, glyphs + i, 1);
+         if (overstrike_p)
+           CGContextShowGlyphsAtPoint (context, gx + 1.0f, gy, glyphs + i, 1);
+         gx += advances[i].width;
+       }
     }
 #endif
 #if USE_CG_DRAWING
   mac_end_cg_clip (f);
 #else
   CGContextSynchronize (context);
-  QDEndCGContext (port, &context);
+  QDEndCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)), &context);
 #endif
 
   return 1;
@@ -1395,7 +1495,7 @@ mac_copy_area (src, f, gc, src_x, src_y, width, height, dest_x, dest_y)
 {
   Rect src_r, dest_r;
 
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
+  mac_begin_clip (f, gc);
 
   SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
   SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
@@ -1403,7 +1503,6 @@ mac_copy_area (src, f, gc, src_x, src_y, width, height, dest_x, dest_y)
   ForeColor (blackColor);
   BackColor (whiteColor);
 
-  mac_begin_clip (gc);
   LockPixels (GetGWorldPixMap (src));
 #if TARGET_API_MAC_CARBON
   {
@@ -1421,9 +1520,10 @@ 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);
 
   RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+
+  mac_end_clip (gc);
 }
 
 
@@ -1439,7 +1539,7 @@ mac_copy_area_with_mask (src, mask, f, gc, src_x, src_y,
 {
   Rect src_r, dest_r;
 
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
+  mac_begin_clip (f, gc);
 
   SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
   SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
@@ -1447,7 +1547,6 @@ mac_copy_area_with_mask (src, mask, f, gc, src_x, src_y,
   ForeColor (blackColor);
   BackColor (whiteColor);
 
-  mac_begin_clip (gc);
   LockPixels (GetGWorldPixMap (src));
   LockPixels (GetGWorldPixMap (mask));
 #if TARGET_API_MAC_CARBON
@@ -1467,9 +1566,10 @@ 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);
 
   RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+
+  mac_end_clip (gc);
 }
 #endif /* !USE_CG_DRAWING */
 
@@ -1498,9 +1598,9 @@ mac_scroll_area (f, gc, src_x, src_y, width, height, dest_x, dest_y)
   DisposeRgn (dummy);
 #else /* not TARGET_API_MAC_CARBON */
   Rect src_r, dest_r;
-  WindowPtr w = FRAME_MAC_WINDOW (f);
+  WindowRef w = FRAME_MAC_WINDOW (f);
 
-  SetPort (w);
+  mac_begin_clip (f, gc);
 
   SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
   SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
@@ -1509,11 +1609,11 @@ 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);
   CopyBits (&(w->portBits), &(w->portBits), &src_r, &dest_r, srcCopy, 0);
-  mac_end_clip (gc);
 
   RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+
+  mac_end_clip (gc);
 #endif /* not TARGET_API_MAC_CARBON */
 }
 
@@ -1539,15 +1639,25 @@ XChangeGC (display, gc, mask, xgcv)
 /* Mac replacement for XCreateGC.  */
 
 GC
-XCreateGC (display, window, mask, xgcv)
+XCreateGC (display, d, mask, xgcv)
      Display *display;
-     Window window;
+     void *d;
      unsigned long mask;
      XGCValues *xgcv;
 {
   GC gc = xmalloc (sizeof (*gc));
 
   bzero (gc, sizeof (*gc));
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+  if (CGColorGetTypeID != NULL)
+#endif
+    {
+      gc->cg_fore_color = gc->cg_back_color = mac_cg_color_black;
+      CGColorRetain (gc->cg_fore_color);
+      CGColorRetain (gc->cg_back_color);
+    }
+#endif
   XChangeGC (display, gc, mask, xgcv);
 
   return gc;
@@ -1563,6 +1673,15 @@ XFreeGC (display, gc)
 {
   if (gc->clip_region)
     DisposeRgn (gc->clip_region);
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+  if (CGColorGetTypeID != NULL)
+#endif
+    {
+      CGColorRelease (gc->cg_fore_color);
+      CGColorRelease (gc->cg_back_color);
+    }
+#endif
   xfree (gc);
 }
 
@@ -1599,6 +1718,29 @@ XSetForeground (display, gc, color)
       gc->fore_color.red = RED16_FROM_ULONG (color);
       gc->fore_color.green = GREEN16_FROM_ULONG (color);
       gc->fore_color.blue = BLUE16_FROM_ULONG (color);
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+      if (CGColorGetTypeID != NULL)
+#endif
+       {
+         CGColorRelease (gc->cg_fore_color);
+         if (color == 0)
+           {
+             gc->cg_fore_color = mac_cg_color_black;
+             CGColorRetain (gc->cg_fore_color);
+           }
+         else
+           {
+             float rgba[4];
+
+             rgba[0] = gc->fore_color.red / 65535.0f;
+             rgba[1] = gc->fore_color.green / 65535.0f;
+             rgba[2] = gc->fore_color.blue / 65535.0f;
+             rgba[3] = 1.0f;
+             gc->cg_fore_color = CGColorCreate (mac_cg_color_space_rgb, rgba);
+           }
+       }
+#endif
     }
 }
 
@@ -1617,6 +1759,29 @@ XSetBackground (display, gc, color)
       gc->back_color.red = RED16_FROM_ULONG (color);
       gc->back_color.green = GREEN16_FROM_ULONG (color);
       gc->back_color.blue = BLUE16_FROM_ULONG (color);
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+      if (CGColorGetTypeID != NULL)
+#endif
+       {
+         CGColorRelease (gc->cg_back_color);
+         if (color == 0)
+           {
+             gc->cg_back_color = mac_cg_color_black;
+             CGColorRetain (gc->cg_back_color);
+           }
+         else
+           {
+             float rgba[4];
+
+             rgba[0] = gc->back_color.red / 65535.0f;
+             rgba[1] = gc->back_color.green / 65535.0f;
+             rgba[2] = gc->back_color.blue / 65535.0f;
+             rgba[3] = 1.0f;
+             gc->cg_back_color = CGColorCreate (mac_cg_color_space_rgb, rgba);
+           }
+       }
+#endif
     }
 }
 
@@ -1693,7 +1858,7 @@ mac_reset_clip_rectangles (display, gc)
 void
 XSetWindowBackground (display, w, color)
      Display *display;
-     WindowPtr w;
+     WindowRef w;
      unsigned long color;
 {
 #if !TARGET_API_MAC_CARBON
@@ -1760,18 +1925,16 @@ x_flush (f)
 
 #define XFlush(DISPLAY)        (void) 0
 
-\f
-/* Return the struct mac_display_info corresponding to DPY.  There's
-   only one.  */
-
-struct mac_display_info *
-mac_display_info_for_display (dpy)
-     Display *dpy;
+#if USE_CG_DRAWING
+static void
+mac_flush_display_optional (f)
+     struct frame *f;
 {
-  return &one_mac_display_info;
+  BLOCK_INPUT;
+  mac_prepare_for_quickdraw (f);
+  UNBLOCK_INPUT;
 }
-
-
+#endif
 \f
 /***********************************************************************
                    Starting and ending an update
@@ -2033,6 +2196,81 @@ x_draw_fringe_bitmap (w, row, p)
   Display *display = FRAME_MAC_DISPLAY (f);
   struct face *face = p->face;
   int rowY;
+  int overlay_p = p->overlay_p;
+
+#ifdef MAC_OSX
+  if (!overlay_p)
+    {
+      int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny;
+
+#if 0  /* MAC_TODO: stipple */
+      /* In case the same realized face is used for fringes and
+        for something displayed in the text (e.g. face `region' on
+        mono-displays, the fill style may have been changed to
+        FillSolid in x_draw_glyph_string_background.  */
+      if (face->stipple)
+       XSetFillStyle (FRAME_X_DISPLAY (f), face->gc, FillOpaqueStippled);
+      else
+       XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->background);
+#endif
+
+      /* If the fringe is adjacent to the left (right) scroll bar of a
+        leftmost (rightmost, respectively) window, then extend its
+        background to the gap between the fringe and the bar.  */
+      if ((WINDOW_LEFTMOST_P (w)
+          && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
+         || (WINDOW_RIGHTMOST_P (w)
+             && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
+       {
+         int sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
+
+         if (sb_width > 0)
+           {
+             int left = WINDOW_SCROLL_BAR_AREA_X (w);
+             int width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
+                          * FRAME_COLUMN_WIDTH (f));
+
+             if (bx < 0
+                 && (left + width == p->x
+                     || p->x + p->wd == left))
+               {
+                 /* Bitmap fills the fringe and we need background
+                    extension.  */
+                 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
+
+                 bx = p->x;
+                 nx = p->wd;
+                 by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
+                                                       row->y));
+                 ny = row->visible_height;
+               }
+
+             if (bx >= 0)
+               {
+                 if (left + width == bx)
+                   {
+                     bx = left + sb_width;
+                     nx += width - sb_width;
+                   }
+                 else if (bx + nx == left)
+                   nx += width - sb_width;
+               }
+           }
+       }
+
+      if (bx >= 0)
+       {
+         mac_erase_rectangle (f, face->gc, bx, by, nx, ny);
+         /* The fringe background has already been filled.  */
+         overlay_p = 1;
+       }
+
+#if 0  /* MAC_TODO: stipple */
+      if (!face->stipple)
+       XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->foreground);
+#endif
+    }
+#endif /* MAC_OSX */
 
   /* Must clip because of partially visible lines.  */
   rowY = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
@@ -2051,6 +2289,7 @@ x_draw_fringe_bitmap (w, row, p)
   else
     x_clip_to_row (w, row, -1, face->gc);
 
+#ifndef MAC_OSX
   if (p->bx >= 0 && !p->overlay_p)
     {
 #if 0  /* MAC_TODO: stipple */
@@ -2071,6 +2310,7 @@ x_draw_fringe_bitmap (w, row, p)
        XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->foreground);
 #endif
     }
+#endif /* !MAC_OSX */
 
   if (p->which
 #if USE_CG_DRAWING
@@ -2088,10 +2328,10 @@ x_draw_fringe_bitmap (w, row, p)
                       : face->foreground));
 #if USE_CG_DRAWING
       mac_draw_cg_image (fringe_bmp[p->which], f, face->gc, 0, p->dh,
-                        p->wd, p->h, p->x, p->y, p->overlay_p);
+                        p->wd, p->h, p->x, p->y, overlay_p);
 #else
       mac_draw_bitmap (f, face->gc, p->x, p->y,
-                      p->wd, p->h, p->bits + p->dh, p->overlay_p);
+                      p->wd, p->h, p->bits + p->dh, overlay_p);
 #endif
       XSetForeground (display, face->gc, gcv.foreground);
     }
@@ -2151,7 +2391,7 @@ mac_destroy_fringe_bitmap (which)
    rarely happens).  */
 
 static void
-XTset_terminal_modes ()
+XTset_terminal_modes (struct terminal *t)
 {
 }
 
@@ -2159,7 +2399,7 @@ XTset_terminal_modes ()
    the windows go away, and suspending requires no action.  */
 
 static void
-XTreset_terminal_modes ()
+XTreset_terminal_modes (struct terminal *t)
 {
 }
 
@@ -2190,7 +2430,7 @@ pcm_init (pcm, count)
 
 static enum pcm_status
 pcm_get_status (pcm)
-     XCharStruct *pcm;
+     const XCharStruct *pcm;
 {
   int height = pcm->ascent + pcm->descent;
 
@@ -2634,6 +2874,11 @@ mac_compute_glyph_string_overhangs (s)
       Rect r;
       MacFontStruct *font = s->font;
 
+#if USE_CG_DRAWING
+      mac_prepare_for_quickdraw (s->f);
+#endif
+      SetPortWindowPort (FRAME_MAC_WINDOW (s->f));
+
       TextFont (font->mac_fontnum);
       TextSize (font->mac_fontsize);
       TextFace (font->mac_fontface);
@@ -2766,15 +3011,18 @@ x_draw_glyph_string_foreground (s)
 #if USE_CG_TEXT_DRAWING
        if (!s->two_byte_p
            && mac_draw_image_string_cg (s->f, s->gc, x, s->ybase - boff,
-                                        s->char2b, s->nchars, bg_width))
+                                        s->char2b, s->nchars, bg_width,
+                                        s->face->overstrike))
          ;
        else
 #endif
          mac_draw_image_string_16 (s->f, s->gc, x, s->ybase - boff,
-                                   s->char2b, s->nchars, bg_width);
+                                   s->char2b, s->nchars, bg_width,
+                                   s->face->overstrike);
       else
        mac_draw_image_string (s->f, s->gc, x, s->ybase - boff,
-                              char1b, s->nchars, bg_width);
+                              char1b, s->nchars, bg_width,
+                              s->face->overstrike);
     }
 }
 
@@ -2810,10 +3058,10 @@ x_draw_composite_glyph_string_foreground (s)
   else
     {
       for (i = 0; i < s->nchars; i++, ++s->gidx)
-       mac_draw_string_16 (s->f, s->gc,
-                           x + s->cmp->offsets[s->gidx * 2],
-                           s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
-                           s->char2b + i, 1);
+       mac_draw_image_string_16 (s->f, s->gc,
+                                 x + s->cmp->offsets[s->gidx * 2],
+                                 s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
+                                 s->char2b + i, 1, 0, s->face->overstrike);
     }
 }
 
@@ -3794,15 +4042,8 @@ x_delete_glyphs (n)
    frame.  Otherwise clear the selected frame.  */
 
 static void
-x_clear_frame ()
+x_clear_frame (struct frame *f)
 {
-  struct frame *f;
-
-  if (updating_frame)
-    f = updating_frame;
-  else
-    f = SELECTED_FRAME ();
-
   /* Clearing the frame will erase any cursor, so mark them all as no
      longer visible.  */
   mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
@@ -4205,12 +4446,12 @@ mac_focus_changed (type, dpyinfo, frame, bufp)
 static void
 x_detect_focus_change (dpyinfo, event, bufp)
      struct mac_display_info *dpyinfo;
-     EventRecord *event;
+     const EventRecord *event;
      struct input_event *bufp;
 {
   struct frame *frame;
 
-  frame = mac_window_to_frame ((WindowPtr) event->message);
+  frame = mac_window_to_frame ((WindowRef) event->message);
   if (! frame)
     return;
 
@@ -4322,25 +4563,24 @@ note_mouse_movement (frame, pos)
   last_mouse_motion_position = *pos;
   XSETFRAME (last_mouse_motion_frame, frame);
 
+  if (frame == dpyinfo->mouse_face_mouse_frame
 #if TARGET_API_MAC_CARBON
-  if (!PtInRect (*pos, GetWindowPortBounds (FRAME_MAC_WINDOW (frame), &r)))
+      && !PtInRect (*pos, GetWindowPortBounds (FRAME_MAC_WINDOW (frame), &r))
 #else
-  if (!PtInRect (*pos, &FRAME_MAC_WINDOW (frame)->portRect))
+      && !PtInRect (*pos, &FRAME_MAC_WINDOW (frame)->portRect)
 #endif
+      )
     {
-      if (frame == dpyinfo->mouse_face_mouse_frame)
-       /* This case corresponds to LeaveNotify in X11.  */
-       {
-         /* If we move outside the frame, then we're certainly no
-            longer on any text in the frame.  */
-         clear_mouse_face (dpyinfo);
-         dpyinfo->mouse_face_mouse_frame = 0;
-         if (!dpyinfo->grabbed)
-           rif->define_frame_cursor (frame,
-                                     frame->output_data.mac->nontext_cursor);
-       }
-      return 1;
+      /* This case corresponds to LeaveNotify in X11.  If we move
+        outside the frame, then we're certainly no longer on any text
+        in the frame.  */
+      clear_mouse_face (dpyinfo);
+      dpyinfo->mouse_face_mouse_frame = 0;
+      if (!dpyinfo->grabbed)
+       FRAME_RIF (frame)->define_frame_cursor (frame,
+                                 frame->output_data.mac->nontext_cursor);
     }
+
   /* Has the mouse moved off the glyph it was on at the last sighting?  */
   if (frame != last_mouse_glyph_frame
       || !PtInRect (*pos, &last_mouse_glyph))
@@ -4451,8 +4691,14 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
             the frame are divided into.  */
          Point mouse_pos;
 
+#if TARGET_API_MAC_CARBON
+         GetGlobalMouse (&mouse_pos);
+         mouse_pos.h -= f1->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f1);
+         mouse_pos.v -= f1->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f1);
+#else
          SetPortWindowPort (FRAME_MAC_WINDOW (f1));
          GetMouse (&mouse_pos);
+#endif
          remember_mouse_glyph (f1, mouse_pos.h, mouse_pos.v,
                                &last_mouse_glyph);
          last_mouse_glyph_frame = f1;
@@ -4482,14 +4728,14 @@ 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 OSStatus get_control_part_bounds P_ ((ControlHandle, ControlPartCode,
+static OSStatus get_control_part_bounds P_ ((ControlRef, ControlPartCode,
                                             Rect *));
 static void x_scroll_bar_handle_press P_ ((struct scroll_bar *,
-                                          ControlPartCode,
+                                          ControlPartCode, Point,
                                           struct input_event *));
 static void x_scroll_bar_handle_release P_ ((struct scroll_bar *,
                                             struct input_event *));
-static void x_scroll_bar_handle_drag P_ ((WindowPtr, struct scroll_bar *,
+static void x_scroll_bar_handle_drag P_ ((WindowRef, struct scroll_bar *,
                                          Point, struct input_event *));
 static void x_set_toolkit_scroll_bar_thumb P_ ((struct scroll_bar *,
                                                int, int, int));
@@ -4582,7 +4828,7 @@ construct_scroll_bar_click (bar, part, bufp)
 
 static OSStatus
 get_control_part_bounds (ch, part_code, rect)
-     ControlHandle ch;
+     ControlRef ch;
      ControlPartCode part_code;
      Rect *rect;
 {
@@ -4598,9 +4844,10 @@ get_control_part_bounds (ch, part_code, rect)
 }
 
 static void
-x_scroll_bar_handle_press (bar, part_code, bufp)
+x_scroll_bar_handle_press (bar, part_code, mouse_pos, bufp)
      struct scroll_bar *bar;
      ControlPartCode part_code;
+     Point mouse_pos;
      struct input_event *bufp;
 {
   int part = control_part_code_to_scroll_bar_part (part_code);
@@ -4611,12 +4858,20 @@ x_scroll_bar_handle_press (bar, part_code, bufp)
   if (part != scroll_bar_handle)
     {
       construct_scroll_bar_click (bar, part, bufp);
-      HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar), part_code);
+      HiliteControl (SCROLL_BAR_CONTROL_REF (bar), part_code);
       set_scroll_bar_timer (SCROLL_BAR_FIRST_DELAY);
+      bar->dragging = Qnil;
+    }
+  else
+    {
+      Rect r;
+
+      get_control_part_bounds (SCROLL_BAR_CONTROL_REF (bar),
+                              kControlIndicatorPart, &r);
+      XSETINT (bar->dragging, - (mouse_pos.v - r.top) - 1);
     }
 
   last_scroll_bar_part = part;
-  bar->dragging = Qnil;
   tracked_scroll_bar = bar;
 }
 
@@ -4626,10 +4881,10 @@ x_scroll_bar_handle_release (bar, bufp)
      struct input_event *bufp;
 {
   if (last_scroll_bar_part != scroll_bar_handle
-      || !GC_NILP (bar->dragging))
+      || (INTEGERP (bar->dragging) && XINT (bar->dragging) >= 0))
     construct_scroll_bar_click (bar, scroll_bar_end_scroll, bufp);
 
-  HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar), 0);
+  HiliteControl (SCROLL_BAR_CONTROL_REF (bar), 0);
   set_scroll_bar_timer (kEventDurationForever);
 
   last_scroll_bar_part = -1;
@@ -4639,28 +4894,26 @@ x_scroll_bar_handle_release (bar, bufp)
 
 static void
 x_scroll_bar_handle_drag (win, bar, mouse_pos, bufp)
-     WindowPtr win;
+     WindowRef win;
      struct scroll_bar *bar;
      Point mouse_pos;
      struct input_event *bufp;
 {
-  ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
+  ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
 
   if (last_scroll_bar_part == scroll_bar_handle)
     {
       int top, top_range;
       Rect r;
 
-      get_control_part_bounds (SCROLL_BAR_CONTROL_HANDLE (bar),
+      get_control_part_bounds (SCROLL_BAR_CONTROL_REF (bar),
                               kControlIndicatorPart, &r);
 
-      if (GC_NILP (bar->dragging))
-       XSETINT (bar->dragging, mouse_pos.v - r.top);
+      if (INTEGERP (bar->dragging) && XINT (bar->dragging) < 0)
+       XSETINT (bar->dragging, - (XINT (bar->dragging) + 1));
 
       top = mouse_pos.v - XINT (bar->dragging) - XINT (bar->track_top);
-      top_range = (XINT (bar->track_height) - (r.bottom - r.top)) *
-       (1.0 + (float) GetControlViewSize (ch) / GetControl32BitMaximum (ch))
-       + .5;
+      top_range = XINT (bar->track_height) - XINT (bar->min_handle);
 
       if (top < 0)
        top = 0;
@@ -4701,13 +4954,13 @@ x_scroll_bar_handle_drag (win, bar, mouse_pos, bufp)
        }
 
       if (unhilite_p)
-       HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar), 0);
+       HiliteControl (SCROLL_BAR_CONTROL_REF (bar), 0);
       else if (part != last_scroll_bar_part
               || scroll_bar_timer_event_posted_p)
        {
          construct_scroll_bar_click (bar, part, bufp);
          last_scroll_bar_part = part;
-         HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar), part_code);
+         HiliteControl (SCROLL_BAR_CONTROL_REF (bar), part_code);
          set_scroll_bar_timer (SCROLL_BAR_CONTINUOUS_DELAY);
        }
     }
@@ -4721,19 +4974,22 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
      struct scroll_bar *bar;
      int portion, position, whole;
 {
-  ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
+  ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
   int value, viewsize, maximum;
 
   if (XINT (bar->track_height) == 0)
     return;
 
-  if (whole == 0)
+  if (whole <= portion)
     value = 0, viewsize = 1, maximum = 0;
   else
     {
-      value = position;
-      viewsize = portion;
-      maximum = max (0, whole - portion);
+      float scale;
+
+      maximum = XINT (bar->track_height) - XINT (bar->min_handle);
+      scale = (float) maximum / (whole - portion);
+      value = position * scale + 0.5f;
+      viewsize = (int) (portion * scale + 0.5f) + XINT (bar->min_handle);
     }
 
   BLOCK_INPUT;
@@ -4777,7 +5033,7 @@ x_scroll_bar_create (w, top, left, width, height, disp_top, disp_height)
   struct scroll_bar *bar
     = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
   Rect r;
-  ControlHandle ch;
+  ControlRef ch;
 
   BLOCK_INPUT;
 
@@ -4791,7 +5047,7 @@ x_scroll_bar_create (w, top, left, width, height, disp_top, disp_height)
 #endif
 #if TARGET_API_MAC_CARBON
   ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p",
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
                   false,
 #else
                   width < disp_height,
@@ -4801,7 +5057,7 @@ x_scroll_bar_create (w, top, left, width, height, disp_top, disp_height)
   ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p", width < disp_height,
                   0, 0, 0, scrollBarProc, (long) bar);
 #endif
-  SET_SCROLL_BAR_CONTROL_HANDLE (bar, ch);
+  SET_SCROLL_BAR_CONTROL_REF (bar, ch);
 
   XSETWINDOW (bar->window, w);
   XSETINT (bar->top, top);
@@ -4811,9 +5067,13 @@ x_scroll_bar_create (w, top, left, width, height, disp_top, disp_height)
   XSETINT (bar->start, 0);
   XSETINT (bar->end, 0);
   bar->dragging = Qnil;
+#ifdef MAC_OSX
+  bar->fringe_extended_p = Qnil;
+#endif
 #ifdef USE_TOOLKIT_SCROLL_BARS
   bar->track_top = Qnil;
   bar->track_height = Qnil;
+  bar->min_handle = Qnil;
 #endif
 
   /* Add bar to its frame's list of scroll bars.  */
@@ -4850,7 +5110,7 @@ x_scroll_bar_set_handle (bar, start, end, rebuild)
      int rebuild;
 {
   int dragging = ! NILP (bar->dragging);
-  ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
+  ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
   FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
   int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
   int length = end - start;
@@ -4919,7 +5179,7 @@ x_scroll_bar_remove (bar)
   mac_prepare_for_quickdraw (f);
 #endif
   /* Destroy the Mac scroll bar control  */
-  DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar));
+  DisposeControl (SCROLL_BAR_CONTROL_REF (bar));
 
   /* Disassociate this scroll bar from its window.  */
   XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
@@ -4942,6 +5202,9 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
   struct scroll_bar *bar;
   int top, height, left, sb_left, width, sb_width, disp_top, disp_height;
   int window_y, window_height;
+#ifdef MAC_OSX
+  int fringe_extended_p;
+#endif
 
   /* Get window dimensions.  */
   window_box (w, -1, 0, &window_y, 0, &window_height);
@@ -4961,9 +5224,9 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
 
   /* Compute the left edge of the scroll bar.  */
   if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
-    sb_left = left;
+    sb_left = left + (WINDOW_RIGHTMOST_P (w) ? width - sb_width : 0);
   else
-    sb_left = left + width - sb_width;
+    sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width);
 
   /* Adjustments according to Inside Macintosh to make it look nice */
   disp_top = top;
@@ -4984,11 +5247,29 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
     sb_left++;
 #endif
 
+#ifdef MAC_OSX
+  if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
+    fringe_extended_p = (WINDOW_LEFTMOST_P (w)
+                        && WINDOW_LEFT_FRINGE_WIDTH (w)
+                        && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+                            || WINDOW_LEFT_MARGIN_COLS (w) == 0));
+  else
+    fringe_extended_p = (WINDOW_RIGHTMOST_P (w)
+                        && WINDOW_RIGHT_FRINGE_WIDTH (w)
+                        && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+                            || WINDOW_RIGHT_MARGIN_COLS (w) == 0));
+#endif
+
   /* Does the scroll bar exist yet?  */
   if (NILP (w->vertical_scroll_bar))
     {
       BLOCK_INPUT;
-      mac_clear_area (f, left, top, width, height);
+#ifdef MAC_OSX
+      if (fringe_extended_p)
+       mac_clear_area (f, sb_left, top, sb_width, height);
+      else
+#endif
+       mac_clear_area (f, left, top, width, height);
       UNBLOCK_INPUT;
       bar = x_scroll_bar_create (w, top, sb_left, sb_width, height, disp_top,
                                 disp_height);
@@ -4997,10 +5278,10 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
   else
     {
       /* It may just need to be moved and resized.  */
-      ControlHandle ch;
+      ControlRef ch;
 
       bar = XSCROLL_BAR (w->vertical_scroll_bar);
-      ch = SCROLL_BAR_CONTROL_HANDLE (bar);
+      ch = SCROLL_BAR_CONTROL_REF (bar);
 
       BLOCK_INPUT;
 
@@ -5008,11 +5289,20 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
       if (!(XINT (bar->left) == sb_left
            && XINT (bar->top) == top
            && XINT (bar->width) == sb_width
-           && XINT (bar->height) == height))
+           && XINT (bar->height) == height
+#ifdef MAC_OSX
+           && !NILP (bar->fringe_extended_p) == fringe_extended_p
+#endif
+           ))
        {
          /* Since toolkit scroll bars are smaller than the space reserved
             for them on the frame, we have to clear "under" them.  */
-         mac_clear_area (f, left, top, width, height);
+#ifdef MAC_OSX
+         if (fringe_extended_p)
+           mac_clear_area (f, sb_left, top, sb_width, height);
+         else
+#endif
+           mac_clear_area (f, left, top, width, height);
 
 #if USE_CG_DRAWING
          mac_prepare_for_quickdraw (f);
@@ -5034,29 +5324,39 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
 #ifdef USE_TOOLKIT_SCROLL_BARS
          bar->track_top = Qnil;
          bar->track_height = Qnil;
+         bar->min_handle = Qnil;
 #endif
         }
 
       UNBLOCK_INPUT;
     }
 
+#ifdef MAC_OSX
+  bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil;
+#endif
+
 #ifdef USE_TOOLKIT_SCROLL_BARS
   if (NILP (bar->track_top))
     {
-      if (sb_width >= disp_height)
+      if (sb_width >= disp_height
+#ifdef MAC_OSX
+         || sb_width < MAC_AQUA_SMALL_VERTICAL_SCROLL_BAR_WIDTH
+#endif
+         )
        {
          XSETINT (bar->track_top, 0);
          XSETINT (bar->track_height, 0);
+         XSETINT (bar->min_handle, 0);
        }
       else
        {
-         ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
+         ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
          Rect r0, r1;
 
          BLOCK_INPUT;
 
          SetControl32BitMinimum (ch, 0);
-         SetControl32BitMaximum (ch, 1);
+         SetControl32BitMaximum (ch, 1 << 30);
          SetControlViewSize (ch, 1);
 
          /* Move the scroll bar thumb to the top.  */
@@ -5064,12 +5364,13 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
          get_control_part_bounds (ch, kControlIndicatorPart, &r0);
 
          /* Move the scroll bar thumb to the bottom.  */
-         SetControl32BitValue (ch, 1);
+         SetControl32BitValue (ch, 1 << 30);
          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);
+         XSETINT (bar->min_handle, r1.bottom - r1.top);
 
          /* Don't show the scroll bar if its height is not enough to
             display the scroll bar thumb.  */
@@ -5218,7 +5519,7 @@ static void
 x_scroll_bar_handle_click (bar, part_code, er, bufp)
      struct scroll_bar *bar;
      ControlPartCode part_code;
-     EventRecord *er;
+     const EventRecord *er;
      struct input_event *bufp;
 {
   int win_y, top_range;
@@ -5326,19 +5627,24 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
      unsigned long *time;
 {
   struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
-  ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
+  ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
 #if TARGET_API_MAC_CARBON
-  WindowPtr wp = GetControlOwner (ch);
+  WindowRef wp = GetControlOwner (ch);
 #else
-  WindowPtr wp = (*ch)->contrlOwner;
+  WindowRef wp = (*ch)->contrlOwner;
 #endif
   Point mouse_pos;
   struct frame *f = mac_window_to_frame (wp);
   int win_y, top_range;
 
+#if TARGET_API_MAC_CARBON
+  GetGlobalMouse (&mouse_pos);
+  mouse_pos.h -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
+  mouse_pos.v -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
+#else
   SetPortWindowPort (wp);
-
   GetMouse (&mouse_pos);
+#endif
 
   win_y = mouse_pos.v - XINT (bar->top);
   top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
@@ -5392,84 +5698,617 @@ x_scroll_bar_clear (f)
 
 \f
 /***********************************************************************
-                            Text Cursor
+                              Tool-bars
  ***********************************************************************/
+#if USE_MAC_TOOLBAR
 
-/* Set clipping for output in glyph row ROW.  W is the window in which
-   we operate.  GC is the graphics context to set clipping in.
+/* In identifiers such as function/variable names, Emacs tool bar is
+   referred to as `tool_bar', and Carbon HIToolbar as `toolbar'.  */
 
-   ROW may be a text row or, e.g., a mode line.  Text rows must be
-   clipped to the interior of the window dedicated to text display,
-   mode lines must be clipped to the whole window.  */
+#define TOOLBAR_IDENTIFIER (CFSTR ("org.gnu.Emacs.toolbar"))
+#define TOOLBAR_ICON_ITEM_IDENTIFIER (CFSTR ("org.gnu.Emacs.toolbar.icon"))
+
+#define TOOLBAR_ITEM_COMMAND_ID_OFFSET 'Tb\0\0'
+#define TOOLBAR_ITEM_COMMAND_ID_P(id)                  \
+  (((id) & ~0xffff) == TOOLBAR_ITEM_COMMAND_ID_OFFSET)
+#define TOOLBAR_ITEM_COMMAND_ID_VALUE(id)      \
+  ((id) - TOOLBAR_ITEM_COMMAND_ID_OFFSET)
+#define TOOLBAR_ITEM_MAKE_COMMAND_ID(value)    \
+  ((value) + TOOLBAR_ITEM_COMMAND_ID_OFFSET)
+
+static int mac_event_to_emacs_modifiers P_ ((EventRef));
+static void mac_handle_origin_change P_ ((struct frame *));
+static OSStatus mac_handle_toolbar_command_event P_ ((EventHandlerCallRef,
+                                                     EventRef, void *));
 
 static void
-x_clip_to_row (w, row, area, gc)
-     struct window *w;
-     struct glyph_row *row;
-     int area;
-     GC gc;
+mac_move_window_with_gravity (f, win_gravity, left, top)
+     struct frame *f;
+     int win_gravity;
+     short left, top;
 {
-  struct frame *f = XFRAME (WINDOW_FRAME (w));
-  Rect clip_rect;
-  int window_x, window_y, window_width;
+  Rect inner, outer;
 
-  window_box (w, area, &window_x, &window_y, &window_width, 0);
+  mac_get_window_bounds (f, &inner, &outer);
 
-  clip_rect.left = window_x;
-  clip_rect.top = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
-  clip_rect.top = max (clip_rect.top, window_y);
-  clip_rect.right = clip_rect.left + window_width;
-  clip_rect.bottom = clip_rect.top + row->visible_height;
+  switch (win_gravity)
+    {
+    case NorthWestGravity:
+    case WestGravity:
+    case SouthWestGravity:
+      left += inner.left - outer.left;
+      break;
 
-  mac_set_clip_rectangles (FRAME_MAC_DISPLAY (f), gc, &clip_rect, 1);
-}
+    case NorthGravity:
+    case CenterGravity:
+    case SouthGravity:
+      left += ((inner.left - outer.left) + (inner.right - outer.right)) / 2;
+      break;
+
+    case NorthEastGravity:
+    case EastGravity:
+    case SouthEastGravity:
+      left += inner.right - outer.right;
+      break;
+    }
+
+  switch (win_gravity)
+    {
+    case NorthWestGravity:
+    case NorthGravity:
+    case NorthEastGravity:
+      top += inner.top - outer.top;
+      break;
 
+    case WestGravity:
+    case CenterGravity:
+    case EastGravity:
+      top += ((inner.top - outer.top) + (inner.bottom - outer.bottom)) / 2;
+      break;
 
-/* Draw a hollow box cursor on window W in glyph row ROW.  */
+    case SouthWestGravity:
+    case SouthGravity:
+    case SouthEastGravity:
+      top += inner.bottom - outer.bottom;
+      break;
+    }
+
+  MoveWindow (FRAME_MAC_WINDOW (f), left, top, false);
+}
 
 static void
-x_draw_hollow_cursor (w, row)
-     struct window *w;
-     struct glyph_row *row;
+mac_get_window_origin_with_gravity (f, win_gravity, left, top)
+     struct frame *f;
+     int win_gravity;
+     short *left, *top;
 {
-  struct frame *f = XFRAME (WINDOW_FRAME (w));
-  struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
-  Display *dpy = FRAME_MAC_DISPLAY (f);
-  int x, y, wd, h;
-  XGCValues xgcv;
-  struct glyph *cursor_glyph;
-  GC gc;
+  Rect inner, outer;
 
-  /* Get the glyph the cursor is on.  If we can't tell because
-     the current matrix is invalid or such, give up.  */
-  cursor_glyph = get_phys_cursor_glyph (w);
-  if (cursor_glyph == NULL)
-    return;
+  mac_get_window_bounds (f, &inner, &outer);
 
-  /* Compute frame-relative coordinates for phys cursor.  */
-  get_phys_cursor_geometry (w, row, cursor_glyph, &x, &y, &h);
-  wd = w->phys_cursor_width;
+  switch (win_gravity)
+    {
+    case NorthWestGravity:
+    case WestGravity:
+    case SouthWestGravity:
+      *left = outer.left;
+      break;
 
-  /* The foreground of cursor_gc is typically the same as the normal
-     background color, which can cause the cursor box to be invisible.  */
-  xgcv.foreground = f->output_data.mac->cursor_pixel;
-  if (dpyinfo->scratch_cursor_gc)
-    XChangeGC (dpy, dpyinfo->scratch_cursor_gc, GCForeground, &xgcv);
-  else
-    dpyinfo->scratch_cursor_gc = XCreateGC (dpy, FRAME_MAC_WINDOW (f),
-                                           GCForeground, &xgcv);
-  gc = dpyinfo->scratch_cursor_gc;
+    case NorthGravity:
+    case CenterGravity:
+    case SouthGravity:
+      *left = outer.left + ((outer.right - outer.left)
+                           - (inner.right - inner.left)) / 2;
+      break;
 
-  /* Set clipping, draw the rectangle, and reset clipping again.  */
-  x_clip_to_row (w, row, TEXT_AREA, gc);
-  mac_draw_rectangle (f, gc, x, y, wd, h - 1);
-  mac_reset_clip_rectangles (dpy, gc);
-}
+    case NorthEastGravity:
+    case EastGravity:
+    case SouthEastGravity:
+      *left = outer.right - (inner.right - inner.left);
+      break;
+    }
 
+  switch (win_gravity)
+    {
+    case NorthWestGravity:
+    case NorthGravity:
+    case NorthEastGravity:
+      *top = outer.top;
+      break;
 
-/* Draw a bar cursor on window W in glyph row ROW.
+    case WestGravity:
+    case CenterGravity:
+    case EastGravity:
+      *top = outer.top + ((outer.bottom - outer.top)
+                         - (inner.bottom - inner.top)) / 2;
+      break;
 
-   Implementation note: One would like to draw a bar cursor with an
+    case SouthWestGravity:
+    case SouthGravity:
+    case SouthEastGravity:
+      *top = outer.bottom - (inner.bottom - inner.top);
+      break;
+    }
+}
+
+static OSStatus
+mac_handle_toolbar_event (next_handler, event, data)
+     EventHandlerCallRef next_handler;
+     EventRef event;
+     void *data;
+{
+  OSStatus err, result = eventNotHandledErr;
+
+  switch (GetEventKind (event))
+    {
+    case kEventToolbarGetDefaultIdentifiers:
+      result = noErr;
+      break;
+
+    case kEventToolbarGetAllowedIdentifiers:
+      {
+       CFMutableArrayRef array;
+
+       GetEventParameter (event, kEventParamMutableArray,
+                          typeCFMutableArrayRef, NULL,
+                          sizeof (CFMutableArrayRef), NULL, &array);
+       CFArrayAppendValue (array, TOOLBAR_ICON_ITEM_IDENTIFIER);
+       result = noErr;
+      }
+      break;
+
+    case kEventToolbarCreateItemWithIdentifier:
+      {
+       CFStringRef identifier;
+       HIToolbarItemRef item = NULL;
+
+       GetEventParameter (event, kEventParamToolbarItemIdentifier,
+                          typeCFStringRef, NULL,
+                          sizeof (CFStringRef), NULL, &identifier);
+
+       if (CFStringCompare (identifier, TOOLBAR_ICON_ITEM_IDENTIFIER, 0)
+           == kCFCompareEqualTo)
+         HIToolbarItemCreate (identifier,
+                              kHIToolbarItemAllowDuplicates
+                              | kHIToolbarItemCantBeRemoved, &item);
+
+       if (item)
+         {
+           SetEventParameter (event, kEventParamToolbarItem,
+                              typeHIToolbarItemRef,
+                              sizeof (HIToolbarItemRef), &item);
+           result = noErr;
+         }
+      }
+      break;
+
+    default:
+      abort ();
+    }
+
+  return result;
+}
+
+static CGImageRef
+mac_image_spec_to_cg_image (f, image)
+     struct frame *f;
+     Lisp_Object image;
+{
+  if (!valid_image_p (image))
+    return NULL;
+  else
+    {
+      int img_id = lookup_image (f, image);
+      struct image *img = IMAGE_FROM_ID (f, img_id);
+
+      prepare_image_for_display (f, img);
+
+      return img->data.ptr_val;
+    }
+}
+
+/* Create a tool bar for frame F.  */
+
+static OSStatus
+mac_create_frame_tool_bar (f)
+     FRAME_PTR f;
+{
+  OSStatus err;
+  HIToolbarRef toolbar;
+
+  err = HIToolbarCreate (TOOLBAR_IDENTIFIER, kHIToolbarNoAttributes,
+                        &toolbar);
+  if (err == noErr)
+    {
+      static const EventTypeSpec specs[] =
+       {{kEventClassToolbar, kEventToolbarGetDefaultIdentifiers},
+        {kEventClassToolbar, kEventToolbarGetAllowedIdentifiers},
+        {kEventClassToolbar, kEventToolbarCreateItemWithIdentifier}};
+
+      err = InstallEventHandler (HIObjectGetEventTarget (toolbar),
+                                mac_handle_toolbar_event,
+                                GetEventTypeCount (specs), specs,
+                                f, NULL);
+    }
+
+  if (err == noErr)
+    err = HIToolbarSetDisplayMode (toolbar, kHIToolbarDisplayModeIconOnly);
+  if (err == noErr)
+    {
+      static const EventTypeSpec specs[] =
+       {{kEventClassCommand, kEventCommandProcess}};
+
+      err = InstallWindowEventHandler (FRAME_MAC_WINDOW (f),
+                                      mac_handle_toolbar_command_event,
+                                      GetEventTypeCount (specs),
+                                      specs, f, NULL);
+    }
+  if (err == noErr)
+    err = SetWindowToolbar (FRAME_MAC_WINDOW (f), toolbar);
+
+  if (toolbar)
+    CFRelease (toolbar);
+
+  return err;
+}
+
+/* Update the tool bar for frame F.  Add new buttons and remove old.  */
+
+void
+update_frame_tool_bar (f)
+     FRAME_PTR f;
+{
+  HIToolbarRef toolbar = NULL;
+  short left, top;
+  CFArrayRef old_items = NULL;
+  CFIndex old_count;
+  int i, pos, win_gravity = f->output_data.mac->toolbar_win_gravity;
+  struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+
+  BLOCK_INPUT;
+
+  GetWindowToolbar (FRAME_MAC_WINDOW (f), &toolbar);
+  if (toolbar == NULL)
+    {
+      mac_create_frame_tool_bar (f);
+      GetWindowToolbar (FRAME_MAC_WINDOW (f), &toolbar);
+      if (toolbar == NULL)
+       goto out;
+      if (win_gravity >= NorthWestGravity && win_gravity <= SouthEastGravity)
+       mac_get_window_origin_with_gravity (f, win_gravity, &left, &top);
+    }
+
+  HIToolbarCopyItems (toolbar, &old_items);
+  if (old_items == NULL)
+    goto out;
+
+  old_count = CFArrayGetCount (old_items);
+  pos = 0;
+  for (i = 0; i < f->n_tool_bar_items; ++i)
+    {
+#define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
+
+      int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
+      int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
+      int idx;
+      Lisp_Object image;
+      CGImageRef cg_image;
+      CFStringRef label;
+      HIToolbarItemRef item;
+
+      /* If image is a vector, choose the image according to the
+        button state.  */
+      image = PROP (TOOL_BAR_ITEM_IMAGES);
+      if (VECTORP (image))
+       {
+         if (enabled_p)
+           idx = (selected_p
+                  ? TOOL_BAR_IMAGE_ENABLED_SELECTED
+                  : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
+         else
+           idx = (selected_p
+                  ? TOOL_BAR_IMAGE_DISABLED_SELECTED
+                  : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
+
+         xassert (ASIZE (image) >= idx);
+         image = AREF (image, idx);
+       }
+      else
+       idx = -1;
+
+      cg_image = mac_image_spec_to_cg_image (f, image);
+      /* Ignore invalid image specifications.  */
+      if (cg_image == NULL)
+       continue;
+
+      label = cfstring_create_with_string (PROP (TOOL_BAR_ITEM_CAPTION));
+      if (label == NULL)
+       label = CFSTR ("");
+
+      if (pos < old_count)
+       {
+         CGImageRef old_cg_image = NULL;
+         CFStringRef old_label = NULL;
+         Boolean old_enabled_p;
+
+         item = (HIToolbarItemRef) CFArrayGetValueAtIndex (old_items, pos);
+
+         HIToolbarItemCopyImage (item, &old_cg_image);
+         if (cg_image != old_cg_image)
+           HIToolbarItemSetImage (item, cg_image);
+         CGImageRelease (old_cg_image);
+
+         HIToolbarItemCopyLabel (item, &old_label);
+         if (CFStringCompare (label, old_label, 0) != kCFCompareEqualTo)
+           HIToolbarItemSetLabel (item, label);
+         CFRelease (old_label);
+
+         old_enabled_p = HIToolbarItemIsEnabled (item);
+         if ((enabled_p || idx >= 0) != old_enabled_p)
+           HIToolbarItemSetEnabled (item, (enabled_p || idx >= 0));
+       }
+      else
+       {
+         item = NULL;
+         HIToolbarCreateItemWithIdentifier (toolbar,
+                                            TOOLBAR_ICON_ITEM_IDENTIFIER,
+                                            NULL, &item);
+         if (item)
+           {
+             HIToolbarItemSetImage (item, cg_image);
+             HIToolbarItemSetLabel (item, label);
+             HIToolbarItemSetEnabled (item, (enabled_p || idx >= 0));
+             HIToolbarAppendItem (toolbar, item);
+             CFRelease (item);
+           }
+       }
+
+      CFRelease (label);
+      if (item)
+       {
+         HIToolbarItemSetCommandID (item, TOOLBAR_ITEM_MAKE_COMMAND_ID (i));
+         pos++;
+       }
+    }
+
+  CFRelease (old_items);
+
+  while (pos < old_count)
+    HIToolbarRemoveItemAtIndex (toolbar, --old_count);
+
+  ShowHideWindowToolbar (FRAME_MAC_WINDOW (f), true,
+                        !win_gravity && f == mac_focus_frame (dpyinfo));
+  /* Mac OS X 10.3 does not issue kEventWindowBoundsChanged events on
+     toolbar visibility change.  */
+  mac_handle_origin_change (f);
+  if (win_gravity >= NorthWestGravity && win_gravity <= SouthEastGravity)
+    {
+      mac_move_window_with_gravity (f, win_gravity, left, top);
+      /* If the title bar is completely outside the screen, adjust the
+        position. */
+      ConstrainWindowToScreen (FRAME_MAC_WINDOW (f), kWindowTitleBarRgn,
+                              kWindowConstrainMoveRegardlessOfFit
+                              | kWindowConstrainAllowPartial, NULL, NULL);
+      f->output_data.mac->toolbar_win_gravity = 0;
+    }
+
+ out:
+  UNBLOCK_INPUT;
+}
+
+/* Hide the tool bar on frame F.  Unlike the counterpart on GTK+, it
+   doesn't deallocate the resources.  */
+
+void
+free_frame_tool_bar (f)
+     FRAME_PTR f;
+{
+  if (IsWindowToolbarVisible (FRAME_MAC_WINDOW (f)))
+    {
+      struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+
+      BLOCK_INPUT;
+      ShowHideWindowToolbar (FRAME_MAC_WINDOW (f), false,
+                            f == mac_focus_frame (dpyinfo));
+      /* Mac OS X 10.3 does not issue kEventWindowBoundsChanged events
+        on toolbar visibility change.  */
+      mac_handle_origin_change (f);
+      UNBLOCK_INPUT;
+    }
+}
+
+static void
+mac_tool_bar_note_mouse_movement (f, event)
+     struct frame *f;
+     EventRef event;
+{
+  OSStatus err;
+  struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+  int mouse_down_p;
+  HIViewRef item_view;
+  UInt32 command_id;
+
+  mouse_down_p = (dpyinfo->grabbed
+                 && f == last_mouse_frame
+                 && FRAME_LIVE_P (f));
+  if (mouse_down_p)
+    return;
+
+  err = HIViewGetViewForMouseEvent (HIViewGetRoot (FRAME_MAC_WINDOW (f)),
+                                   event, &item_view);
+  /* This doesn't work on Mac OS X 10.2.  On Mac OS X 10.3 and 10.4, a
+     toolbar item view seems to have the same command ID with that of
+     the toolbar item.  */
+  if (err == noErr)
+    err = GetControlCommandID (item_view, &command_id);
+  if (err == noErr && TOOLBAR_ITEM_COMMAND_ID_P (command_id))
+    {
+      int i = TOOLBAR_ITEM_COMMAND_ID_VALUE (command_id);
+
+      if (i < f->n_tool_bar_items)
+       {
+         HIRect bounds;
+         HIViewRef content_view;
+
+         err = HIViewGetBounds (item_view, &bounds);
+         if (err == noErr)
+           err = HIViewFindByID (HIViewGetRoot (FRAME_MAC_WINDOW (f)),
+                                 kHIViewWindowContentID, &content_view);
+         if (err == noErr)
+           err = HIViewConvertRect (&bounds, item_view, content_view);
+         if (err == noErr)
+           SetRect (&last_mouse_glyph,
+                    CGRectGetMinX (bounds), CGRectGetMinY (bounds),
+                    CGRectGetMaxX (bounds), CGRectGetMaxY (bounds));
+
+         help_echo_object = help_echo_window = Qnil;
+         help_echo_pos = -1;
+         help_echo_string = PROP (TOOL_BAR_ITEM_HELP);
+         if (NILP (help_echo_string))
+           help_echo_string = PROP (TOOL_BAR_ITEM_CAPTION);
+       }
+    }
+}
+
+static OSStatus
+mac_handle_toolbar_command_event (next_handler, event, data)
+     EventHandlerCallRef next_handler;
+     EventRef event;
+     void *data;
+{
+  OSStatus err, result = eventNotHandledErr;
+  struct frame *f = (struct frame *) data;
+  HICommand command;
+
+  err = GetEventParameter (event, kEventParamDirectObject,
+                          typeHICommand, NULL,
+                          sizeof (HICommand), NULL, &command);
+  if (err != noErr)
+    return result;
+
+  switch (GetEventKind (event))
+    {
+    case kEventCommandProcess:
+      if (!TOOLBAR_ITEM_COMMAND_ID_P (command.commandID))
+       result = CallNextEventHandler (next_handler, event);
+      else
+       {
+         int i = TOOLBAR_ITEM_COMMAND_ID_VALUE (command.commandID);
+
+         if (i < f->n_tool_bar_items
+             && !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P)))
+           {
+             Lisp_Object frame;
+             struct input_event buf;
+
+             EVENT_INIT (buf);
+
+             XSETFRAME (frame, f);
+             buf.kind = TOOL_BAR_EVENT;
+             buf.frame_or_window = frame;
+             buf.arg = frame;
+             kbd_buffer_store_event (&buf);
+
+             buf.kind = TOOL_BAR_EVENT;
+             buf.frame_or_window = frame;
+             buf.arg = PROP (TOOL_BAR_ITEM_KEY);
+             buf.modifiers = mac_event_to_emacs_modifiers (event);
+             kbd_buffer_store_event (&buf);
+
+             result = noErr;
+           }
+       }
+      break;
+
+    default:
+      abort ();
+    }
+#undef PROP
+
+  return result;
+}
+#endif /* USE_MAC_TOOLBAR */
+
+\f
+/***********************************************************************
+                            Text Cursor
+ ***********************************************************************/
+
+/* Set clipping for output in glyph row ROW.  W is the window in which
+   we operate.  GC is the graphics context to set clipping in.
+
+   ROW may be a text row or, e.g., a mode line.  Text rows must be
+   clipped to the interior of the window dedicated to text display,
+   mode lines must be clipped to the whole window.  */
+
+static void
+x_clip_to_row (w, row, area, gc)
+     struct window *w;
+     struct glyph_row *row;
+     int area;
+     GC gc;
+{
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  Rect clip_rect;
+  int window_x, window_y, window_width;
+
+  window_box (w, area, &window_x, &window_y, &window_width, 0);
+
+  clip_rect.left = window_x;
+  clip_rect.top = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
+  clip_rect.top = max (clip_rect.top, window_y);
+  clip_rect.right = clip_rect.left + window_width;
+  clip_rect.bottom = clip_rect.top + row->visible_height;
+
+  mac_set_clip_rectangles (FRAME_MAC_DISPLAY (f), gc, &clip_rect, 1);
+}
+
+
+/* Draw a hollow box cursor on window W in glyph row ROW.  */
+
+static void
+x_draw_hollow_cursor (w, row)
+     struct window *w;
+     struct glyph_row *row;
+{
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+  Display *dpy = FRAME_MAC_DISPLAY (f);
+  int x, y, wd, h;
+  XGCValues xgcv;
+  struct glyph *cursor_glyph;
+  GC gc;
+
+  /* Get the glyph the cursor is on.  If we can't tell because
+     the current matrix is invalid or such, give up.  */
+  cursor_glyph = get_phys_cursor_glyph (w);
+  if (cursor_glyph == NULL)
+    return;
+
+  /* Compute frame-relative coordinates for phys cursor.  */
+  get_phys_cursor_geometry (w, row, cursor_glyph, &x, &y, &h);
+  wd = w->phys_cursor_width;
+
+  /* The foreground of cursor_gc is typically the same as the normal
+     background color, which can cause the cursor box to be invisible.  */
+  xgcv.foreground = f->output_data.mac->cursor_pixel;
+  if (dpyinfo->scratch_cursor_gc)
+    XChangeGC (dpy, dpyinfo->scratch_cursor_gc, GCForeground, &xgcv);
+  else
+    dpyinfo->scratch_cursor_gc = XCreateGC (dpy, FRAME_MAC_WINDOW (f),
+                                           GCForeground, &xgcv);
+  gc = dpyinfo->scratch_cursor_gc;
+
+  /* Set clipping, draw the rectangle, and reset clipping again.  */
+  x_clip_to_row (w, row, TEXT_AREA, gc);
+  mac_draw_rectangle (f, gc, x, y, wd, h - 1);
+  mac_reset_clip_rectangles (dpy, gc);
+}
+
+
+/* Draw a bar cursor on window W in glyph row ROW.
+
+   Implementation note: One would like to draw a bar cursor with an
    angle equal to the one given by the font property XA_ITALIC_ANGLE.
    Unfortunately, I didn't find a font yet that has this property set.
    --gerd.  */
@@ -5904,7 +6743,9 @@ x_calc_absolute_position (f)
 
   /* Find the offsets of the outside upper-left corner of
      the inner window, with respect to the outer window.  */
+  BLOCK_INPUT;
   mac_get_window_bounds (f, &inner, &outer);
+  UNBLOCK_INPUT;
 
   width_diff = (outer.right - outer.left) - (inner.right - inner.left);
   height_diff = (outer.bottom - outer.top) - (inner.bottom - inner.top);
@@ -5964,9 +6805,7 @@ x_set_offset (f, xoff, yoff, change_gravity)
   ConstrainWindowToScreen (FRAME_MAC_WINDOW (f), kWindowTitleBarRgn,
                           kWindowConstrainMoveRegardlessOfFit
                           | kWindowConstrainAllowPartial, NULL, NULL);
-#if USE_CARBON_EVENTS
   if (!NILP (tip_frame) && XFRAME (tip_frame) == f)
-#endif
     mac_handle_origin_change (f);
 #else
   {
@@ -6042,11 +6881,21 @@ x_set_window_size (f, change_gravity, cols, rows)
 
   SizeWindow (FRAME_MAC_WINDOW (f), pixelwidth, pixelheight, 0);
 
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
   if (!NILP (tip_frame) && f == XFRAME (tip_frame))
 #endif
     mac_handle_size_change (f, pixelwidth, pixelheight);
 
+  if (f->output_data.mac->internal_border_width
+      != FRAME_INTERNAL_BORDER_WIDTH (f))
+    {
+      mac_clear_window (f);
+      f->output_data.mac->internal_border_width
+       = FRAME_INTERNAL_BORDER_WIDTH (f);
+    }
+
+  SET_FRAME_GARBAGED (f);
+
   UNBLOCK_INPUT;
 }
 \f
@@ -6079,17 +6928,11 @@ x_set_mouse_pixel_position (f, pix_x, pix_y)
      int pix_x, pix_y;
 {
 #ifdef MAC_OSX
-  Point p;
-  CGPoint point;
+  pix_x += f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
+  pix_y += f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
 
   BLOCK_INPUT;
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
-  p.h = pix_x;
-  p.v = pix_y;
-  LocalToGlobal (&p);
-  point.x = p.h;
-  point.y = p.v;
-  CGWarpMouseCursorPosition (point);
+  CGWarpMouseCursorPosition (CGPointMake (pix_x, pix_y));
   UNBLOCK_INPUT;
 #else
 #if 0 /* MAC_TODO: LMSetMouseLocation and CursorDeviceMoveTo are non-Carbon */
@@ -6171,7 +7014,7 @@ static void
 mac_handle_visibility_change (f)
      struct frame *f;
 {
-  WindowPtr wp = FRAME_MAC_WINDOW (f);
+  WindowRef wp = FRAME_MAC_WINDOW (f);
   int visible = 0, iconified = 0;
   struct input_event buf;
 
@@ -6231,40 +7074,15 @@ x_make_frame_visible (f)
 {
   BLOCK_INPUT;
 
-  if (! FRAME_VISIBLE_P (f))
-    {
-      /* We test FRAME_GARBAGED_P here to make sure we don't
-        call x_set_offset a second time
-        if we get to x_make_frame_visible a second time
-        before the window gets really visible.  */
-      if (! FRAME_ICONIFIED_P (f)
-         && ! f->output_data.mac->asked_for_visible)
-       {
-#if TARGET_API_MAC_CARBON
-         if (!(FRAME_SIZE_HINTS (f)->flags & (USPosition | PPosition)))
-           {
-             struct frame *sf = SELECTED_FRAME ();
-             if (!FRAME_MAC_P (sf))
-               RepositionWindow (FRAME_MAC_WINDOW (f), NULL,
-                                 kWindowCenterOnMainScreen);
-             else
-               RepositionWindow (FRAME_MAC_WINDOW (f),
-                                 FRAME_MAC_WINDOW (sf),
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
-                                 kWindowCascadeStartAtParentWindowScreen
-#else
-                                 kWindowCascadeOnParentWindowScreen
-#endif
-                                 );
-#if USE_CARBON_EVENTS
-             if (!NILP (tip_frame) && f == XFRAME (tip_frame))
-#endif
-               mac_handle_origin_change (f);
-           }
-         else
-#endif
-           x_set_offset (f, f->left_pos, f->top_pos, 0);
-       }
+  if (! FRAME_VISIBLE_P (f))
+    {
+      /* We test FRAME_GARBAGED_P here to make sure we don't
+        call x_set_offset a second time
+        if we get to x_make_frame_visible a second time
+        before the window gets really visible.  */
+      if (! FRAME_ICONIFIED_P (f)
+         && ! f->output_data.mac->asked_for_visible)
+       x_set_offset (f, f->left_pos, f->top_pos, 0);
 
       f->output_data.mac->asked_for_visible = 1;
 
@@ -6338,18 +7156,20 @@ x_make_frame_invisible (f)
 
   BLOCK_INPUT;
 
+#if !TARGET_API_MAC_CARBON
   /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
      that the current position of the window is user-specified, rather than
      program-specified, so that when the window is mapped again, it will be
      placed at the same location, without forcing the user to position it
      by hand again (they have already done that once for this window.)  */
   x_wm_set_size_hint (f, (long) 0, 1);
+#endif
 
   HideWindow (FRAME_MAC_WINDOW (f));
 
   UNBLOCK_INPUT;
 
-#if !USE_CARBON_EVENTS
+#if !TARGET_API_MAC_CARBON
   mac_handle_visibility_change (f);
 #endif
 }
@@ -6388,7 +7208,7 @@ x_iconify_frame (f)
   if (err != noErr)
     error ("Can't notify window manager of iconification");
 
-#if !USE_CARBON_EVENTS
+#if !TARGET_API_MAC_CARBON
   mac_handle_visibility_change (f);
 #endif
 }
@@ -6401,13 +7221,16 @@ x_free_frame_resources (f)
      struct frame *f;
 {
   struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
-  WindowPtr wp = FRAME_MAC_WINDOW (f);
+  WindowRef wp = FRAME_MAC_WINDOW (f);
 
   BLOCK_INPUT;
 
   if (wp != tip_window)
     remove_window_handler (wp);
 
+#if USE_CG_DRAWING
+  mac_prepare_for_quickdraw (f);
+#endif
   DisposeWindow (wp);
   if (wp == tip_window)
     /* Neither WaitNextEvent nor ReceiveNextEvent receives `window
@@ -6681,11 +7504,12 @@ xlfdpat_destroy (pat)
 
 static struct xlfdpat *
 xlfdpat_create (pattern)
-     char *pattern;
+     const char *pattern;
 {
   struct xlfdpat *pat;
   int nblocks, i, skip;
   unsigned char last_char, *p, *q, *anychar_head;
+  const unsigned char *ptr;
   struct xlfdpat_block *blk;
 
   pat = xmalloc (sizeof (struct xlfdpat));
@@ -6696,9 +7520,9 @@ xlfdpat_create (pattern)
   anychar_head = NULL;
   q = pat->buf;
   last_char = '\0';
-  for (p = pattern; *p; p++)
+  for (ptr = pattern; *ptr; ptr++)
     {
-      unsigned char c = *p;
+      unsigned char c = *ptr;
 
       if (c == '*')
        if (last_char == '*')
@@ -6802,14 +7626,15 @@ xlfdpat_exact_p (pat)
    that the pattern in *BLK matches with its prefix.  Return NULL
    there is no such strings.  STRING must be lowered in advance.  */
 
-static char *
+static const char *
 xlfdpat_block_match_1 (blk, string, start_max)
      struct xlfdpat_block *blk;
-     unsigned char *string;
+     const unsigned char *string;
      int start_max;
 {
   int start, infinity;
-  unsigned char *p, *s;
+  unsigned char *p;
+  const unsigned char *s;
 
   xassert (blk->len > 0);
   xassert (start_max + blk->len <= strlen (string));
@@ -6866,17 +7691,17 @@ xlfdpat_block_match_1 (blk, string, start_max)
   ((b)->len == 1 ? memchr ((s), (b)->last_char, (m) + 1) \
    : xlfdpat_block_match_1 (b, s, m))
 
-/* Check if XLFD pattern PAT, which is generated by `xfldpat_create',
+/* Check if XLFD pattern PAT, which is generated by `xlfdpat_create',
    matches with STRING.  STRING must be lowered in advance.  */
 
 static int
 xlfdpat_match (pat, string)
      struct xlfdpat *pat;
-     unsigned char *string;
+     const unsigned char *string;
 {
   int str_len, nblocks, i, start_max;
   struct xlfdpat_block *blk;
-  unsigned char *s;
+  const unsigned char *s;
 
   xassert (pat->nblocks > 0);
 
@@ -6959,7 +7784,6 @@ static Lisp_Object fm_font_family_alist;
 static Lisp_Object atsu_font_id_hash;
 /* Alist linking Font Manager style to face attributes.  */
 static Lisp_Object fm_style_face_attributes_alist;
-static Lisp_Object Vmac_atsu_font_table;
 extern Lisp_Object QCfamily, QCweight, QCslant, Qnormal, Qbold, Qitalic;
 #endif
 
@@ -6979,11 +7803,14 @@ create_text_encoding_info_alist ()
       Lisp_Object existing_info;
 
       if (!(CONSP (charset_info)
-           && STRINGP (charset = XCAR (charset_info))
+           && (charset = XCAR (charset_info),
+               STRINGP (charset))
            && CONSP (XCDR (charset_info))
-           && INTEGERP (text_encoding = XCAR (XCDR (charset_info)))
+           && (text_encoding = XCAR (XCDR (charset_info)),
+               INTEGERP (text_encoding))
            && CONSP (XCDR (XCDR (charset_info)))
-           && SYMBOLP (coding_system = XCAR (XCDR (XCDR (charset_info))))))
+           && (coding_system = XCAR (XCDR (XCDR (charset_info))),
+               SYMBOLP (coding_system))))
        continue;
 
       existing_info = assq_no_quit (text_encoding, result);
@@ -7047,7 +7874,7 @@ decode_mac_font_name (name, size, coding_system)
 
 static char *
 mac_to_x_fontname (name, size, style, charset)
-     char *name;
+     const char *name;
      int size;
      Style style;
      char *charset;
@@ -7094,7 +7921,8 @@ const int kDefaultFontSize = 12;
 
 static int
 parse_x_font_name (xf, family, size, style, charset)
-     char *xf, *family;
+     const char *xf;
+     char *family;
      int *size;
      Style *style;
      char *charset;
@@ -7177,10 +8005,10 @@ add_font_name_table_entry (char *font_name)
 
 static void
 add_mac_font_name (name, size, style, charset)
-     char *name;
+     const char *name;
      int size;
      Style style;
-     char *charset;
+     const char *charset;
 {
   if (size > 0)
     add_font_name_table_entry (mac_to_x_fontname (name, size, style, charset));
@@ -7195,6 +8023,73 @@ add_mac_font_name (name, size, style, charset)
 }
 
 #if USE_ATSUI
+static FMFontStyle
+fm_get_style_from_font (font)
+     FMFont font;
+{
+  OSStatus err;
+  FMFontStyle style = normal;
+  ByteCount len;
+  UInt16 mac_style;
+  FMFontFamily font_family;
+#define FONT_HEADER_MAC_STYLE_OFFSET (4*4 + 2*2 + 8*2 + 2*4)
+
+  /* FMGetFontFamilyInstanceFromFont returns `normal' as the style of
+     some font (e.g., Optima) even if it is `bold'.  */
+  err = FMGetFontTable (font, 'head', FONT_HEADER_MAC_STYLE_OFFSET,
+                       sizeof (mac_style), &mac_style, &len);
+  if (err == noErr
+      && len >= FONT_HEADER_MAC_STYLE_OFFSET + sizeof (mac_style))
+    style = EndianU16_BtoN (mac_style);
+  else
+    FMGetFontFamilyInstanceFromFont (font, &font_family, &style);
+
+  return style;
+}
+
+static ATSUFontID
+atsu_find_font_from_family_name (family)
+     const char *family;
+{
+  struct Lisp_Hash_Table *h = XHASH_TABLE (atsu_font_id_hash);
+  unsigned hash_code;
+  int i;
+  Lisp_Object rest, best;
+  FMFontStyle min_style, style;
+
+  i = hash_lookup (h, make_unibyte_string (family, strlen (family)),
+                  &hash_code);
+  if (i < 0)
+    return kATSUInvalidFontID;
+
+  rest = HASH_VALUE (h, i);
+  if (INTEGERP (rest) || (CONSP (rest) && INTEGERP (XCDR (rest))))
+    return cons_to_long (rest);
+
+  rest = Fnreverse (rest);
+  best = XCAR (rest);
+  rest = XCDR (rest);
+  if (!NILP (rest)
+      && (min_style = fm_get_style_from_font (cons_to_long (best))) != normal)
+    do
+      {
+       style = fm_get_style_from_font (cons_to_long (XCAR (rest)));
+       if (style < min_style)
+         {
+           best = XCAR (rest);
+           if (style == normal)
+             break;
+           else
+             min_style = style;
+         }
+       rest = XCDR (rest);
+      }
+    while (!NILP (rest));
+
+  HASH_VALUE (h, i) = best;
+  return cons_to_long (best);
+}
+
 static Lisp_Object
 fm_style_to_face_attributes (fm_style)
      FMFontStyle fm_style;
@@ -7215,6 +8110,44 @@ fm_style_to_face_attributes (fm_style)
 
   return tem;
 }
+
+static Lisp_Object
+atsu_find_font_family_name (font_id)
+     ATSUFontID font_id;
+{
+  OSStatus err;
+  ByteCount len;
+  Lisp_Object family = Qnil;
+
+  err = ATSUFindFontName (font_id, kFontFamilyName,
+                         kFontMacintoshPlatform, kFontNoScript,
+                         kFontNoLanguage, 0, NULL, &len, NULL);
+  if (err == noErr)
+    {
+      family = make_uninit_string (len);
+      err = ATSUFindFontName (font_id, kFontFamilyName,
+                             kFontMacintoshPlatform, kFontNoScript,
+                             kFontNoLanguage, len, SDATA (family),
+                             NULL, NULL);
+    }
+  if (err == noErr)
+    decode_mac_font_name (SDATA (family), len + 1, Qnil);
+
+  return family;
+}
+
+Lisp_Object
+mac_atsu_font_face_attributes (font_id)
+     ATSUFontID font_id;
+{
+  Lisp_Object family, style_attrs;
+
+  family = atsu_find_font_family_name (font_id);
+  if (NILP (family))
+    return Qnil;
+  style_attrs = fm_style_to_face_attributes (fm_get_style_from_font (font_id));
+  return Fcons (QCfamily, Fcons (family, style_attrs));
+}
 #endif
 
 /* Sets up the table font_name_table to contain the list of all fonts
@@ -7246,15 +8179,14 @@ init_font_name_table ()
       unsigned hash_code;
       ItemCount nfonts, i;
       ATSUFontID *font_ids = NULL;
-      Ptr name;
-      ByteCount name_len;
-      Lisp_Object family;
+      Lisp_Object prev_family = Qnil;
+      int j;
 
       atsu_font_id_hash =
        make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE),
                         make_float (DEFAULT_REHASH_SIZE),
                         make_float (DEFAULT_REHASH_THRESHOLD),
-                        Qnil, Qnil, Qnil);;
+                        Qnil, Qnil, Qnil);
       h = XHASH_TABLE (atsu_font_id_hash);
 
       err = ATSUFontCount (&nfonts);
@@ -7266,41 +8198,25 @@ init_font_name_table ()
       if (err == noErr)
        for (i = 0; i < nfonts; i++)
          {
-           err = ATSUFindFontName (font_ids[i], kFontFamilyName,
-                                   kFontMacintoshPlatform, kFontNoScript,
-                                   kFontNoLanguage, 0, NULL, &name_len, NULL);
-           if (err != noErr)
+           Lisp_Object family;
+
+           family = atsu_find_font_family_name (font_ids[i]);
+           if (NILP (family) || SREF (family, 0) == '.')
              continue;
-           name = xmalloc (name_len + 1);
-           name[name_len] = '\0';
-           err = ATSUFindFontName (font_ids[i], kFontFamilyName,
-                                   kFontMacintoshPlatform, kFontNoScript,
-                                   kFontNoLanguage, name_len, name,
-                                   NULL, NULL);
-           if (err == noErr)
+           if (!NILP (Fequal (prev_family, family)))
+             family = prev_family;
+           else
+             j = hash_lookup (h, family, &hash_code);
+           if (j < 0)
              {
-               FMFontFamily ff;
-               FMFontStyle style = normal;
-
-               decode_mac_font_name (name, name_len + 1, Qnil);
-               family = make_unibyte_string (name, name_len);
-               FMGetFontFamilyInstanceFromFont (font_ids[i], &ff, &style);
-               Fputhash ((font_ids[i] > MOST_POSITIVE_FIXNUM
-                          ? make_float (font_ids[i])
-                          : make_number (font_ids[i])),
-                         Fcons (QCfamily,
-                                Fcons (family,
-                                       fm_style_to_face_attributes (style))),
-                         Vmac_atsu_font_table);
-               if (*name != '.'
-                   && hash_lookup (h, family, &hash_code) < 0)
-                 {
-                   add_mac_font_name (name, 0, normal, "iso10646-1");
-                   hash_put (h, family, long_to_cons (font_ids[i]),
-                             hash_code);
-                 }
+               add_mac_font_name (SDATA (family), 0, normal, "iso10646-1");
+               j = hash_put (h, family, Fcons (long_to_cons (font_ids[i]),
+                                               Qnil), hash_code);
              }
-           xfree (name);
+           else if (EQ (prev_family, family))
+             HASH_VALUE (h, j) = Fcons (long_to_cons (font_ids[i]),
+                                        HASH_VALUE (h, j));
+           prev_family = family;
          }
       if (font_ids)
        xfree (font_ids);
@@ -7482,7 +8398,7 @@ enum xlfd_scalable_field_index
     XLFD_SCL_LAST
   };
 
-static int xlfd_scalable_fields[] =
+static const int xlfd_scalable_fields[] =
   {
     6,                         /* PIXEL_SIZE */
     7,                         /* POINT_SIZE */
@@ -7492,14 +8408,16 @@ static int xlfd_scalable_fields[] =
 
 static Lisp_Object
 mac_do_list_fonts (pattern, maxnames)
-     char *pattern;
+     const char *pattern;
      int maxnames;
 {
   int i, n_fonts = 0;
   Lisp_Object font_list = Qnil;
   struct xlfdpat *pat;
-  char *scaled, *ptr;
-  int scl_val[XLFD_SCL_LAST], *field, *val;
+  char *scaled;
+  const char *ptr;
+  int scl_val[XLFD_SCL_LAST], *val;
+  const int *field;
   int exact;
 
   if (font_name_table == NULL)  /* Initialize when first used.  */
@@ -7749,7 +8667,8 @@ x_compute_min_glyph_bounds (f)
    fields are present, none is '*'.  */
 
 static int
-is_fully_specified_xlfd (char *p)
+is_fully_specified_xlfd (p)
+     const char *p;
 {
   int i;
   char *q;
@@ -7777,14 +8696,16 @@ is_fully_specified_xlfd (char *p)
 }
 
 
-/* XLoadQueryFont creates and returns an internal representation for a
-   font in a MacFontStruct struct.  There is really no concept
+/* mac_load_query_font creates and returns an internal representation
+   for a font in a MacFontStruct struct.  There is really no concept
    corresponding to "loading" a font on the Mac.  But we check its
    existence and find the font number and all other information for it
    and store them in the returned MacFontStruct.  */
 
 static MacFontStruct *
-XLoadQueryFont (Display *dpy, char *fontname)
+mac_load_query_font (f, fontname)
+     struct frame *f;
+     char *fontname;
 {
   int size;
   char *name;
@@ -7824,26 +8745,26 @@ XLoadQueryFont (Display *dpy, char *fontname)
   if (strcmp (charset, "iso10646-1") == 0) /* XXX */
     {
       OSStatus err;
-      ATSUAttributeTag tags[] = {kATSUFontTag, kATSUSizeTag,
-                                kATSUQDBoldfaceTag, kATSUQDItalicTag};
-      ByteCount sizes[] = {sizeof (ATSUFontID), sizeof (Fixed),
-                          sizeof (Boolean), sizeof (Boolean)};
+      static const ATSUAttributeTag tags[] =
+       {kATSUFontTag, kATSUSizeTag,
+        kATSUQDBoldfaceTag, kATSUQDItalicTag};
+      static const ByteCount sizes[] =
+       {sizeof (ATSUFontID), sizeof (Fixed),
+        sizeof (Boolean), sizeof (Boolean)};
       static Fixed size_fixed;
       static Boolean bold_p, italic_p;
-      ATSUAttributeValuePtr values[] = {&font_id, &size_fixed,
-                                       &bold_p, &italic_p};
-      ATSUFontFeatureType types[] = {kAllTypographicFeaturesType,
-                                    kDiacriticsType};
-      ATSUFontFeatureSelector selectors[] = {kAllTypeFeaturesOffSelector,
-                                            kDecomposeDiacriticsSelector};
-      Lisp_Object font_id_cons;
+      static const ATSUAttributeValuePtr values[] =
+       {&font_id, &size_fixed,
+        &bold_p, &italic_p};
+      static const ATSUFontFeatureType types[] =
+       {kAllTypographicFeaturesType, kDiacriticsType};
+      static const ATSUFontFeatureSelector selectors[] =
+       {kAllTypeFeaturesOffSelector, kDecomposeDiacriticsSelector};
       FMFontStyle style;
 
-      font_id_cons = Fgethash (make_unibyte_string (family, strlen (family)),
-                              atsu_font_id_hash, Qnil);
-      if (NILP (font_id_cons))
-       return NULL;
-      font_id = cons_to_long (font_id_cons);
+      font_id = atsu_find_font_from_family_name (family);
+      if (font_id == kATSUInvalidFontID)
+       return;
       size_fixed = Long2Fix (size);
       bold_p = (fontface & bold) != 0;
       italic_p = (fontface & italic) != 0;
@@ -7952,7 +8873,8 @@ XLoadQueryFont (Display *dpy, char *fontname)
                                    NULL
 #endif
                                    );
-      if (err != noErr)
+      if (err != noErr
+         || space_bounds->width <= 0 || FONT_HEIGHT (font) <= 0)
        {
          mac_unload_font (&one_mac_display_info, font);
          return NULL;
@@ -7966,11 +8888,19 @@ XLoadQueryFont (Display *dpy, char *fontname)
            continue;
          else if (c == 0x7f)
            {
-             c = 0x9f;
-             continue;
+#if USE_CG_TEXT_DRAWING
+             if (font->cg_glyphs)
+               {
+                 c = 0x9f;
+                 pcm = NULL;
+                 continue;
+               }
+#endif
+             break;
            }
 
-         mac_query_char_extents (font->mac_style, c, NULL, NULL, pcm + c,
+         mac_query_char_extents (font->mac_style, c, NULL, NULL,
+                                 pcm ? pcm + c : NULL,
 #if USE_CG_TEXT_DRAWING
                                  (font->cg_glyphs ? font->cg_glyphs + c
                                   : NULL)
@@ -7988,6 +8918,8 @@ XLoadQueryFont (Display *dpy, char *fontname)
              font->cg_font = NULL;
              xfree (font->cg_glyphs);
              font->cg_glyphs = NULL;
+             if (pcm == NULL)
+               break;
            }
 #endif
        }
@@ -7995,23 +8927,14 @@ XLoadQueryFont (Display *dpy, char *fontname)
   else
 #endif
     {
-      GrafPtr port;
-      SInt16 old_fontnum, old_fontsize;
-      Style old_fontface;
+      OSStatus err;
       FontInfo the_fontinfo;
       int is_two_byte_font;
 
-      /* Save the current font number used.  */
-      GetPort (&port);
-#if TARGET_API_MAC_CARBON
-      old_fontnum = GetPortTextFont (port);
-      old_fontsize = GetPortTextSize (port);
-      old_fontface = GetPortTextFace (port);
-#else
-      old_fontnum = port->txFont;
-      old_fontsize = port->txSize;
-      old_fontface = port->txFace;
+#if USE_CG_DRAWING
+      mac_prepare_for_quickdraw (f);
 #endif
+      SetPortWindowPort (FRAME_MAC_WINDOW (f));
 
       TextFont (fontnum);
       TextSize (size);
@@ -8087,17 +9010,17 @@ XLoadQueryFont (Display *dpy, char *fontname)
                 sizeof (XCharStruct) * (0xff - 0x20 + 1));
 
          space_bounds = font->bounds.per_char;
-         mac_query_char_extents (NULL, 0x20, &font->ascent, &font->descent,
-                                 space_bounds, NULL);
+         err = mac_query_char_extents (NULL, 0x20, &font->ascent,
+                                       &font->descent, space_bounds, NULL);
+         if (err != noErr || space_bounds->width <= 0)
+           {
+             mac_unload_font (&one_mac_display_info, font);
+             return 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.  */
-      TextFont (old_fontnum);
-      TextSize (old_fontsize);
-      TextFace (old_fontface);
     }
 
   if (space_bounds)
@@ -8237,7 +9160,7 @@ x_load_font (f, fontname, size)
     fontname = (char *) SDATA (XCAR (font_names));
 
     BLOCK_INPUT;
-    font = (MacFontStruct *) XLoadQueryFont (FRAME_MAC_DISPLAY (f), fontname);
+    font = mac_load_query_font (f, fontname);
     UNBLOCK_INPUT;
     if (!font)
       return NULL;
@@ -8433,16 +9356,93 @@ x_find_ccl_program (fontp)
    possible.  */
 static int font_panel_shown_p = 0;
 
+extern Lisp_Object Qfont;
+static Lisp_Object Qpanel_closed, Qselection;
+
+static OSStatus mac_store_event_ref_as_apple_event P_ ((AEEventClass, AEEventID,
+                                                       Lisp_Object,
+                                                       Lisp_Object,
+                                                       EventRef, UInt32,
+                                                       const EventParamName *,
+                                                       const EventParamType *));
+
 int
 mac_font_panel_visible_p ()
 {
   return font_panel_shown_p && FPIsFontPanelVisible ();
 }
 
+static pascal OSStatus
+mac_handle_font_event (next_handler, event, data)
+     EventHandlerCallRef next_handler;
+     EventRef event;
+     void *data;
+{
+  OSStatus result, err;
+  Lisp_Object id_key;
+  int num_params;
+  const EventParamName *names;
+  const EventParamType *types;
+  static const EventParamName names_sel[] = {kEventParamATSUFontID,
+                                            kEventParamATSUFontSize,
+                                            kEventParamFMFontFamily,
+                                            kEventParamFMFontSize,
+                                            kEventParamFontColor};
+  static const EventParamType types_sel[] = {typeATSUFontID,
+                                            typeATSUSize,
+                                            typeFMFontFamily,
+                                            typeFMFontSize,
+                                            typeFontColor};
+
+  result = CallNextEventHandler (next_handler, event);
+  if (result != eventNotHandledErr)
+    return result;
+
+  switch (GetEventKind (event))
+    {
+    case kEventFontPanelClosed:
+      id_key = Qpanel_closed;
+      num_params = 0;
+      names = NULL;
+      types = NULL;
+      break;
+
+    case kEventFontSelection:
+      id_key = Qselection;
+      num_params = sizeof (names_sel) / sizeof (names_sel[0]);
+      names = names_sel;
+      types = types_sel;
+      break;
+    }
+
+  err = mac_store_event_ref_as_apple_event (0, 0, Qfont, id_key,
+                                           event, num_params,
+                                           names, types);
+  if (err == noErr)
+    result = noErr;
+
+  return result;
+}
+
 OSStatus
 mac_show_hide_font_panel ()
 {
-  font_panel_shown_p = 1;
+  if (!font_panel_shown_p)
+    {
+      OSStatus err;
+
+      static const EventTypeSpec specs[] =
+       {{kEventClassFont, kEventFontPanelClosed},
+        {kEventClassFont, kEventFontSelection}};
+
+      err = InstallApplicationEventHandler (mac_handle_font_event,
+                                           GetEventTypeCount (specs),
+                                           specs, NULL, NULL);
+      if (err != noErr)
+       return err;
+
+      font_panel_shown_p = 1;
+    }
 
   return FPShowHideFontPanel ();
 }
@@ -8527,9 +9527,6 @@ mac_set_font_info_for_selection (f, face_id, c)
 #define M_APPLE 234
 #define I_ABOUT 1
 
-#define WINDOW_RESOURCE 128
-#define TERM_WINDOW_RESOURCE 129
-
 #define DEFAULT_NUM_COLS 80
 
 #define MIN_DOC_SIZE 64
@@ -8561,7 +9558,7 @@ Lisp_Object Vmac_function_modifier;
    a three button mouse */
 Lisp_Object Vmac_emulate_three_button_mouse;
 
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
 /* Non-zero if the mouse wheel button (i.e. button 4) should map to
    mouse-2, instead of mouse-3.  */
 int mac_wheel_button_is_mouse_2;
@@ -8580,19 +9577,18 @@ int mac_pass_control_to_system;
    Carbon/Apple event handlers.  */
 static struct input_event *read_socket_inev = NULL;
 
+/* Whether or not the screen configuration has changed.  */
+static int mac_screen_config_changed = 0;
+
 Point saved_menu_event_location;
 
 /* Apple Events */
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
 static Lisp_Object Qhi_command;
 #ifdef MAC_OSX
 extern Lisp_Object Qwindow;
 static Lisp_Object Qtoolbar_switch_mode;
 #endif
-#if USE_MAC_FONT_PANEL
-extern Lisp_Object Qfont;
-static Lisp_Object Qpanel_closed, Qselection;
-#endif
 #if USE_MAC_TSM
 static TSMDocumentID tsm_document_id;
 static Lisp_Object Qtext_input;
@@ -8604,7 +9600,7 @@ static Lisp_Object saved_ts_script_language_on_focus;
 static ScriptLanguageRecord saved_ts_language;
 static Component saved_ts_component;
 #endif
-#endif
+#endif /* TARGET_API_MAC_CARBON */
 extern int mac_ready_for_apple_events;
 extern Lisp_Object Qundefined;
 extern void init_apple_event_handler P_ ((void));
@@ -8614,19 +9610,18 @@ extern void mac_find_apple_event_spec P_ ((AEEventClass, AEEventID,
 extern OSErr init_coercion_handler P_ ((void));
 
 /* Drag and Drop */
-OSErr install_drag_handler P_ ((WindowRef));
-void remove_drag_handler P_ ((WindowRef));
+extern OSErr install_drag_handler P_ ((WindowRef));
+extern void remove_drag_handler P_ ((WindowRef));
+
+#if TARGET_API_MAC_CARBON
+/* Showing help echo string during menu tracking  */
+extern OSStatus install_menu_target_item_handler P_ ((void));
 
-#if USE_CARBON_EVENTS
 #ifdef MAC_OSX
-extern void init_service_handler ();
+extern OSStatus install_service_handler ();
 static Lisp_Object Qservice, Qpaste, Qperform;
 #endif
-/* Window Event Handler */
-static pascal OSStatus mac_handle_window_event (EventHandlerCallRef,
-                                               EventRef, void *);
 #endif
-OSStatus install_window_handler (WindowPtr);
 
 extern void init_emacs_passwd_dir ();
 extern int emacs_main (int, char **, char **);
@@ -8640,7 +9635,7 @@ extern void terminate_applescript();
    except `clear' (-> <clear>) on the KeyPad, `enter' (-> <kp-enter>)
    on the right of the Cmd key on laptops, and fn + `enter' (->
    <linefeed>). */
-static unsigned char keycode_to_xkeysym_table[] = {
+static const unsigned char keycode_to_xkeysym_table[] = {
   /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -8677,7 +9672,7 @@ static unsigned char keycode_to_xkeysym_table[] = {
    keyboard, and they may not be the same on other types of keyboards.
    If the destination is identical to the source (f1 ... f12), it
    doesn't map `fn' key to a modifier.  */
-static unsigned char fn_keycode_to_keycode_table[] = {
+static const unsigned char fn_keycode_to_keycode_table[] = {
   /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   /*0x20*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -8709,8 +9704,8 @@ static unsigned char fn_keycode_to_keycode_table[] = {
 };
 #endif /* MAC_OSX */
 
-static unsigned int
-#if USE_CARBON_EVENTS
+static int
+#if TARGET_API_MAC_CARBON
 mac_to_emacs_modifiers (UInt32 mods)
 #else
 mac_to_emacs_modifiers (EventModifiers mods)
@@ -8756,6 +9751,23 @@ mac_to_emacs_modifiers (EventModifiers mods)
   return result;
 }
 
+static UInt32
+mac_mapped_modifiers (modifiers)
+     UInt32 modifiers;
+{
+  UInt32 mapped_modifiers_all =
+    (NILP (Vmac_control_modifier) ? 0 : controlKey)
+    | (NILP (Vmac_option_modifier) ? 0 : optionKey)
+    | (NILP (Vmac_command_modifier) ? 0 : cmdKey);
+
+#ifdef MAC_OSX
+  mapped_modifiers_all |=
+    (NILP (Vmac_function_modifier) ? 0 : kEventKeyModifierFnMask);
+#endif
+
+  return mapped_modifiers_all & modifiers;
+}
+
 static int
 mac_get_emulated_btn ( UInt32 modifiers )
 {
@@ -8770,17 +9782,51 @@ mac_get_emulated_btn ( UInt32 modifiers )
   return result;
 }
 
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
+/***** Code to handle C-g testing  *****/
+extern int quit_char;
+extern int make_ctrl_char P_ ((int));
+
+int
+mac_quit_char_key_p (modifiers, key_code)
+     UInt32 modifiers, key_code;
+{
+  UInt32 char_code;
+  unsigned long some_state = 0;
+  Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
+  int c, emacs_modifiers;
+
+  /* Mask off modifier keys that are mapped to some Emacs modifiers.  */
+  key_code |= (modifiers & ~(mac_mapped_modifiers (modifiers)));
+  char_code = KeyTranslate (kchr_ptr, key_code, &some_state);
+  if (char_code & ~0xff)
+    return 0;
+
+  emacs_modifiers = mac_to_emacs_modifiers (modifiers);
+  if (emacs_modifiers & ctrl_modifier)
+    c = make_ctrl_char (char_code);
+
+  c |= (emacs_modifiers
+       & (meta_modifier | alt_modifier
+          | hyper_modifier | super_modifier));
+
+  return c == quit_char;
+}
+#endif
+
+#if TARGET_API_MAC_CARBON
 /* Obtains the event modifiers from the event ref and then calls
    mac_to_emacs_modifiers.  */
-static UInt32
+static int
 mac_event_to_emacs_modifiers (EventRef eventRef)
 {
-  UInt32 mods = 0;
+  UInt32 mods = 0, class;
+
   GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, NULL,
                    sizeof (UInt32), NULL, &mods);
+  class = GetEventClass (eventRef);
   if (!NILP (Vmac_emulate_three_button_mouse) &&
-      GetEventClass(eventRef) == kEventClassMouse)
+      (class == kEventClassMouse || class == kEventClassCommand))
     {
       mods &= ~(optionKey | cmdKey);
     }
@@ -8818,15 +9864,16 @@ mac_get_mouse_btn (EventRef ref)
 
 /* Normally, ConvertEventRefToEventRecord will correctly handle all
    events.  However the click of the mouse wheel is not converted to a
-   mouseDown or mouseUp event.  Likewise for dead key down events.
-   This calls ConvertEventRef, but then checks to see if it is a mouse
-   up/down, or a dead key down carbon event that has not been
+   mouseDown or mouseUp event.  Likewise for dead key events.  This
+   calls ConvertEventRefToEventRecord, but then checks to see if it is
+   a mouse up/down, or a dead key Carbon event that has not been
    converted, and if so, converts it by hand (to be picked up in the
    XTread_socket loop).  */
 static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec)
 {
   OSStatus err;
   Boolean result = ConvertEventRefToEventRecord (eventRef, eventRec);
+  EventKind action;
 
   if (result)
     return result;
@@ -8855,6 +9902,14 @@ static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec)
       switch (GetEventKind (eventRef))
        {
        case kEventRawKeyDown:
+         action = keyDown;
+         goto keystroke_common;
+       case kEventRawKeyRepeat:
+         action = autoKey;
+         goto keystroke_common;
+       case kEventRawKeyUp:
+         action = keyUp;
+       keystroke_common:
          {
            unsigned char char_codes;
            UInt32 key_code;
@@ -8868,7 +9923,7 @@ static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec)
                                       NULL, &key_code);
            if (err == noErr)
              {
-               eventRec->what = keyDown;
+               eventRec->what = action;
                eventRec->message = char_codes | ((key_code & 0xff) << 8);
                result = 1;
              }
@@ -8910,7 +9965,7 @@ static void
 do_get_menus (void)
 {
   Handle menubar_handle;
-  MenuHandle menu_handle;
+  MenuRef menu;
 
   menubar_handle = GetNewMBar (128);
   if(menubar_handle == NULL)
@@ -8919,9 +9974,9 @@ do_get_menus (void)
   DrawMenuBar ();
 
 #if !TARGET_API_MAC_CARBON
-  menu_handle = GetMenuHandle (M_APPLE);
-  if(menu_handle != NULL)
-    AppendResMenu (menu_handle,'DRVR');
+  menu = GetMenuRef (M_APPLE);
+  if (menu != NULL)
+    AppendResMenu (menu'DRVR');
   else
     abort ();
 #endif
@@ -8970,7 +10025,7 @@ do_check_ram_size (void)
 #endif /* MAC_OS8 */
 
 static void
-do_window_update (WindowPtr win)
+do_window_update (WindowRef win)
 {
   struct frame *f = mac_window_to_frame (win);
 
@@ -8998,6 +10053,9 @@ do_window_update (WindowPtr win)
          GetPortVisibleRegion (GetWindowPort (win), region);
          GetRegionBounds (region, &r);
          expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top);
+#if USE_CG_DRAWING
+         mac_prepare_for_quickdraw (f);
+#endif
          UpdateControls (win, region);
          DisposeRgn (region);
 #else
@@ -9012,7 +10070,7 @@ do_window_update (WindowPtr win)
 }
 
 static int
-is_emacs_window (WindowPtr win)
+is_emacs_window (WindowRef win)
 {
   Lisp_Object tail, frame;
 
@@ -9125,7 +10183,7 @@ do_apple_menu (SInt16 menu_item)
     NoteAlert (ABOUT_ALERT_ID, NULL);
   else
     {
-      GetMenuItemText (GetMenuHandle (M_APPLE), menu_item, item_name);
+      GetMenuItemText (GetMenuRef (M_APPLE), menu_item, item_name);
       da_driver_refnum = OpenDeskAcc (item_name);
     }
 }
@@ -9135,7 +10193,9 @@ do_apple_menu (SInt16 menu_item)
    Mesander and IM - Window Manager A.  */
 
 static void
-do_grow_window (WindowPtr w, EventRecord *e)
+do_grow_window (w, e)
+     WindowRef w;
+     const EventRecord *e;
 {
   Rect limit_rect;
   int rows, columns, width, height;
@@ -9186,7 +10246,7 @@ mac_get_ideal_size (f)
      struct frame *f;
 {
   struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
-  WindowPtr w = FRAME_MAC_WINDOW (f);
+  WindowRef w = FRAME_MAC_WINDOW (f);
   Point ideal_size;
   Rect standard_rect;
   int height, width, columns, rows;
@@ -9212,7 +10272,7 @@ mac_get_ideal_size (f)
    wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen.  */
 
 static void
-do_zoom_window (WindowPtr w, int zoom_in_or_out)
+do_zoom_window (WindowRef w, int zoom_in_or_out)
 {
   Rect zoom_rect, port_rect;
   int width, height;
@@ -9275,19 +10335,219 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out)
   SetPort (save_port);
 #endif /* not TARGET_API_MAC_CARBON */
 
-#if !USE_CARBON_EVENTS
+#if !TARGET_API_MAC_CARBON
   /* retrieve window size and update application values */
-#if TARGET_API_MAC_CARBON
-  GetWindowPortBounds (w, &port_rect);
-#else
   port_rect = w->portRect;
-#endif
   height = port_rect.bottom - port_rect.top;
   width = port_rect.right - port_rect.left;
 
-  mac_handle_size_change (f, width, height);
-  mac_handle_origin_change (f);
+  mac_handle_size_change (f, width, height);
+  mac_handle_origin_change (f);
+#endif
+}
+
+static void
+mac_set_unicode_keystroke_event (code, buf)
+     UniChar code;
+     struct input_event *buf;
+{
+  int charset_id, c1, c2;
+
+  if (code < 0x80)
+    {
+      buf->kind = ASCII_KEYSTROKE_EVENT;
+      buf->code = code;
+    }
+  else if (code < 0x100)
+    {
+      if (code < 0xA0)
+       charset_id = CHARSET_8_BIT_CONTROL;
+      else
+       charset_id = charset_latin_iso8859_1;
+      buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+      buf->code = MAKE_CHAR (charset_id, code, 0);
+    }
+  else
+    {
+      if (code < 0x2500)
+       charset_id = charset_mule_unicode_0100_24ff,
+         code -= 0x100;
+      else if (code < 0x33FF)
+       charset_id = charset_mule_unicode_2500_33ff,
+         code -= 0x2500;
+      else if (code >= 0xE000)
+       charset_id = charset_mule_unicode_e000_ffff,
+         code -= 0xE000;
+      c1 = (code / 96) + 32, c2 = (code % 96) + 32;
+      buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+      buf->code = MAKE_CHAR (charset_id, c1, c2);
+    }
+}
+
+static void
+do_keystroke (action, char_code, key_code, modifiers, timestamp, buf)
+     EventKind action;
+     unsigned char char_code;
+     UInt32 key_code, modifiers;
+     unsigned long timestamp;
+     struct input_event *buf;
+{
+  static SInt16 last_key_script = -1;
+  SInt16 current_key_script = GetScriptManagerVariable (smKeyScript);
+  UInt32 mapped_modifiers = mac_mapped_modifiers (modifiers);
+
+#ifdef MAC_OSX
+  if (mapped_modifiers & kEventKeyModifierFnMask
+      && key_code <= 0x7f
+      && fn_keycode_to_keycode_table[key_code])
+    key_code = fn_keycode_to_keycode_table[key_code];
+#endif
+
+  if (key_code <= 0x7f && keycode_to_xkeysym_table[key_code])
+    {
+      buf->kind = NON_ASCII_KEYSTROKE_EVENT;
+      buf->code = 0xff00 | keycode_to_xkeysym_table[key_code];
+#ifdef MAC_OSX
+      if (modifiers & kEventKeyModifierFnMask
+         && key_code <= 0x7f
+         && fn_keycode_to_keycode_table[key_code] == key_code)
+       modifiers &= ~kEventKeyModifierFnMask;
+#endif
+    }
+  else if (mapped_modifiers)
+    {
+      /* translate the keycode back to determine the original key */
+#ifdef MAC_OSX
+      UCKeyboardLayout *uchr_ptr = NULL;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+      OSStatus err;
+      KeyboardLayoutRef layout;
+
+      err = KLGetCurrentKeyboardLayout (&layout);
+      if (err == noErr)
+       err = KLGetKeyboardLayoutProperty (layout, kKLuchrData,
+                                          (const void **) &uchr_ptr);
+#else
+      static SInt16 last_key_layout_id = 0;
+      static Handle uchr_handle = (Handle)-1;
+      SInt16 current_key_layout_id =
+       GetScriptVariable (current_key_script, smScriptKeys);
+
+      if (uchr_handle == (Handle)-1
+         || last_key_layout_id != current_key_layout_id)
+       {
+         uchr_handle = GetResource ('uchr', current_key_layout_id);
+         last_key_layout_id = current_key_layout_id;
+       }
+      if (uchr_handle)
+       uchr_ptr = (UCKeyboardLayout *)*uchr_handle;
+#endif
+
+      if (uchr_ptr)
+       {
+         OSStatus status;
+         UInt16 key_action = action - keyDown;
+         UInt32 modifier_key_state = (modifiers & ~mapped_modifiers) >> 8;
+         UInt32 keyboard_type = LMGetKbdType ();
+         SInt32 dead_key_state = 0;
+         UniChar code;
+         UniCharCount actual_length;
+
+         status = UCKeyTranslate (uchr_ptr, key_code, key_action,
+                                  modifier_key_state, keyboard_type,
+                                  kUCKeyTranslateNoDeadKeysMask,
+                                  &dead_key_state,
+                                  1, &actual_length, &code);
+         if (status == noErr && actual_length == 1)
+           mac_set_unicode_keystroke_event (code, buf);
+       }
+#endif /* MAC_OSX */
+
+      if (buf->kind == NO_EVENT)
+       {
+         /* This code comes from Keyboard Resource, Appendix C of IM
+            - Text.  This is necessary since shift is ignored in KCHR
+            table translation when option or command is pressed.  It
+            also does not translate correctly control-shift chars
+            like C-% so mask off shift here also.  */
+         /* Mask off modifier keys that are mapped to some Emacs
+            modifiers.  */
+         int new_modifiers = modifiers & ~mapped_modifiers;
+         /* set high byte of keycode to modifier high byte*/
+         int new_key_code = key_code | new_modifiers;
+         Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
+         unsigned long some_state = 0;
+         UInt32 new_char_code;
+
+         new_char_code = KeyTranslate (kchr_ptr, new_key_code, &some_state);
+         if (new_char_code == 0)
+           /* Seems like a dead key.  Append up-stroke.  */
+           new_char_code = KeyTranslate (kchr_ptr, new_key_code | 0x80,
+                                         &some_state);
+         if (new_char_code)
+           {
+             buf->kind = ASCII_KEYSTROKE_EVENT;
+             buf->code = new_char_code & 0xff;
+           }
+       }
+    }
+
+  if (buf->kind == NO_EVENT)
+    {
+      buf->kind = ASCII_KEYSTROKE_EVENT;
+      buf->code = char_code;
+    }
+
+  buf->modifiers = mac_to_emacs_modifiers (modifiers);
+  buf->modifiers |= (extra_keyboard_modifiers
+                    & (meta_modifier | alt_modifier
+                       | hyper_modifier | super_modifier));
+
+#if TARGET_API_MAC_CARBON
+  if (buf->kind == ASCII_KEYSTROKE_EVENT
+      && buf->code >= 0x80 && buf->modifiers)
+    {
+      OSStatus err;
+      TextEncoding encoding = kTextEncodingMacRoman;
+      TextToUnicodeInfo ttu_info;
+
+      UpgradeScriptInfoToTextEncoding (current_key_script,
+                                      kTextLanguageDontCare,
+                                      kTextRegionDontCare,
+                                      NULL, &encoding);
+      err = CreateTextToUnicodeInfoByEncoding (encoding, &ttu_info);
+      if (err == noErr)
+       {
+         UniChar code;
+         Str255 pstr;
+         ByteCount unicode_len;
+
+         pstr[0] = 1;
+         pstr[1] = buf->code;
+         err = ConvertFromPStringToUnicode (ttu_info, pstr,
+                                            sizeof (UniChar),
+                                            &unicode_len, &code);
+         if (err == noErr && unicode_len == sizeof (UniChar))
+           mac_set_unicode_keystroke_event (code, buf);
+         DisposeTextToUnicodeInfo (&ttu_info);
+       }
+    }
 #endif
+
+  if (buf->kind == ASCII_KEYSTROKE_EVENT
+      && buf->code >= 0x80
+      && last_key_script != current_key_script)
+    {
+      struct input_event event;
+
+      EVENT_INIT (event);
+      event.kind = LANGUAGE_CHANGE_EVENT;
+      event.arg = Qnil;
+      event.code = current_key_script;
+      event.timestamp = timestamp;
+      kbd_buffer_store_event (&event);
+      last_key_script = current_key_script;
+    }
 }
 
 void
@@ -9319,8 +10579,8 @@ mac_store_event_ref_as_apple_event (class, id, class_key, id_key,
      Lisp_Object class_key, id_key;
      EventRef event;
      UInt32 num_params;
-     EventParamName *names;
-     EventParamType *types;
+     const EventParamName *names;
+     const EventParamType *types;
 {
   OSStatus err = eventNotHandledErr;
   Lisp_Object binding;
@@ -9340,9 +10600,7 @@ mac_store_event_ref_as_apple_event (class, id, class_key, id_key,
            {
              mac_store_apple_event (class_key, id_key, &apple_event);
              AEDisposeDesc (&apple_event);
-             /* Post a harmless event so as to wake up from
-                ReceiveNextEvent.  */
-             mac_post_mouse_moved_event ();
+             mac_wakeup_from_rne ();
            }
        }
     }
@@ -9370,53 +10628,49 @@ mac_store_drag_event (window, mouse_pos, modifiers, desc)
   buf.arg = mac_aedesc_to_lisp (desc);
   kbd_buffer_store_event (&buf);
 }
-#endif
 
-#if USE_CARBON_EVENTS
-static pascal OSStatus
-mac_handle_command_event (next_handler, event, data)
-     EventHandlerCallRef next_handler;
+#ifdef MAC_OSX
+OSStatus
+mac_store_service_event (event)
      EventRef event;
-     void *data;
 {
-  OSStatus result, err;
-  HICommand command;
-  static EventParamName names[] = {kEventParamDirectObject,
-                                  kEventParamKeyModifiers};
-  static EventParamType types[] = {typeHICommand,
-                                  typeUInt32};
-  int num_params = sizeof (names) / sizeof (names[0]);
-
-  result = CallNextEventHandler (next_handler, event);
-  if (result != eventNotHandledErr)
-    return result;
+  OSStatus err;
+  Lisp_Object id_key;
+  int num_params;
+  const EventParamName *names;
+  const EventParamType *types;
+  static const EventParamName names_pfm[] =
+    {kEventParamServiceMessageName, kEventParamServiceUserData};
+  static const EventParamType types_pfm[] =
+    {typeCFStringRef, typeCFStringRef};
 
-  err = GetEventParameter (event, kEventParamDirectObject, typeHICommand,
-                          NULL, sizeof (HICommand), NULL, &command);
+  switch (GetEventKind (event))
+    {
+    case kEventServicePaste:
+      id_key = Qpaste;
+      num_params = 0;
+      names = NULL;
+      types = NULL;
+      break;
 
-  if (err != noErr || command.commandID == 0)
-    return eventNotHandledErr;
+    case kEventServicePerform:
+      id_key = Qperform;
+      num_params = sizeof (names_pfm) / sizeof (names_pfm[0]);
+      names = names_pfm;
+      types = types_pfm;
+      break;
 
-  /* A HI command event is mapped to an Apple event whose event class
-     symbol is `hi-command' and event ID is its command ID.  */
-  err = mac_store_event_ref_as_apple_event (0, command.commandID,
-                                           Qhi_command, Qnil,
-                                           event, num_params, names, types);
-  return err == noErr ? noErr : eventNotHandledErr;
-}
+    default:
+      abort ();
+    }
 
-static OSStatus
-init_command_handler ()
-{
-  EventTypeSpec specs[] = {{kEventClassCommand, kEventCommandProcess}};
-  static EventHandlerUPP handle_command_eventUPP = NULL;
+  err = mac_store_event_ref_as_apple_event (0, 0, Qservice, id_key,
+                                           event, num_params,
+                                           names, types);
 
-  if (handle_command_eventUPP == NULL)
-    handle_command_eventUPP = NewEventHandlerUPP (mac_handle_command_event);
-  return InstallApplicationEventHandler (handle_command_eventUPP,
-                                        GetEventTypeCount (specs), specs,
-                                        NULL, NULL);
+  return err;
 }
+#endif /* MAC_OSX */
 
 static pascal OSStatus
 mac_handle_window_event (next_handler, event, data)
@@ -9424,47 +10678,85 @@ mac_handle_window_event (next_handler, event, data)
      EventRef event;
      void *data;
 {
-  WindowPtr wp;
-  OSStatus result, err;
+  WindowRef wp;
+  OSStatus err, result = eventNotHandledErr;
   struct frame *f;
   UInt32 attributes;
   XSizeHints *size_hints;
 
   err = GetEventParameter (event, kEventParamDirectObject, typeWindowRef,
-                          NULL, sizeof (WindowPtr), NULL, &wp);
+                          NULL, sizeof (WindowRef), NULL, &wp);
   if (err != noErr)
     return eventNotHandledErr;
 
   f = mac_window_to_frame (wp);
   switch (GetEventKind (event))
     {
+      /* -- window refresh events -- */
+
     case kEventWindowUpdate:
       result = CallNextEventHandler (next_handler, event);
       if (result != eventNotHandledErr)
-       return result;
+       break;
 
       do_window_update (wp);
-      return noErr;
+      result = noErr;
+      break;
 
-    case kEventWindowGetIdealSize:
-      result = CallNextEventHandler (next_handler, event);
-      if (result != eventNotHandledErr)
-       return result;
+      /* -- window state change events -- */
 
-      {
-       Point ideal_size = mac_get_ideal_size (f);
+    case kEventWindowShowing:
+      size_hints = FRAME_SIZE_HINTS (f);
+      if (!(size_hints->flags & (USPosition | PPosition)))
+       {
+         struct frame *sf = SELECTED_FRAME ();
 
-       err = SetEventParameter (event, kEventParamDimensions,
-                                typeQDPoint, sizeof (Point), &ideal_size);
-       if (err == noErr)
-         return noErr;
-      }
+         if (!(FRAME_MAC_P (sf)))
+           RepositionWindow (wp, NULL, kWindowCenterOnMainScreen);
+         else
+           {
+             RepositionWindow (wp, FRAME_MAC_WINDOW (sf),
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+                               kWindowCascadeStartAtParentWindowScreen
+#else
+                               kWindowCascadeOnParentWindowScreen
+#endif
+                               );
+#if USE_MAC_TOOLBAR
+             /* This is a workaround.  RepositionWindow fails to put
+                a window at the cascading position when its parent
+                window has a Carbon HIToolbar.  */
+             if (f->top_pos == sf->top_pos && f->left_pos == sf->left_pos)
+               MoveWindowStructure (wp,  f->left_pos + 10, f->top_pos + 32);
+#endif
+           }
+         result = noErr;
+       }
+      break;
+
+    case kEventWindowHiding:
+      /* Before unmapping the window, update the WM_SIZE_HINTS
+        property to claim that the current position of the window is
+        user-specified, rather than program-specified, so that when
+        the window is mapped again, it will be placed at the same
+        location, without forcing the user to position it by hand
+        again (they have already done that once for this window.)  */
+      x_wm_set_size_hint (f, (long) 0, 1);
+      result = noErr;
+      break;
+
+    case kEventWindowShown:
+    case kEventWindowHidden:
+    case kEventWindowCollapsed:
+    case kEventWindowExpanded:
+      mac_handle_visibility_change (f);
+      result = noErr;
       break;
 
     case kEventWindowBoundsChanging:
       result = CallNextEventHandler (next_handler, event);
       if (result != eventNotHandledErr)
-       return result;
+       break;
 
       err = GetEventParameter (event, kEventParamAttributes, typeUInt32,
                               NULL, sizeof (UInt32), NULL, &attributes);
@@ -9508,7 +10800,7 @@ mac_handle_window_event (next_handler, event, data)
          bounds.bottom = bounds.top + height;
          SetEventParameter (event, kEventParamCurrentBounds,
                             typeQDRectangle, sizeof (Rect), &bounds);
-         return noErr;
+         result = noErr;
        }
       break;
 
@@ -9532,27 +10824,19 @@ mac_handle_window_event (next_handler, event, data)
              width = bounds.right - bounds.left;
              height = bounds.bottom - bounds.top;
              mac_handle_size_change (f, width, height);
+             mac_wakeup_from_rne ();
            }
        }
 
       if (attributes & kWindowBoundsChangeOriginChanged)
        mac_handle_origin_change (f);
 
-      return noErr;
-
-    case kEventWindowShown:
-    case kEventWindowHidden:
-    case kEventWindowExpanded:
-    case kEventWindowCollapsed:
-      result = CallNextEventHandler (next_handler, event);
-
-      mac_handle_visibility_change (f);
-      return noErr;
-
+      result = noErr;
       break;
 
+      /* -- window action events -- */
+
     case kEventWindowClose:
-      result = CallNextEventHandler (next_handler, event);
       {
        struct input_event buf;
 
@@ -9562,24 +10846,39 @@ mac_handle_window_event (next_handler, event, data)
        buf.arg = Qnil;
        kbd_buffer_store_event (&buf);
       }
-      return noErr;
+      result = noErr;
+      break;
+
+    case kEventWindowGetIdealSize:
+      result = CallNextEventHandler (next_handler, event);
+      if (result != eventNotHandledErr)
+       break;
+
+      {
+       Point ideal_size = mac_get_ideal_size (f);
+
+       err = SetEventParameter (event, kEventParamDimensions,
+                                typeQDPoint, sizeof (Point), &ideal_size);
+       if (err == noErr)
+         result = noErr;
+      }
+      break;
 
 #ifdef MAC_OSX
     case kEventWindowToolbarSwitchMode:
-      result = CallNextEventHandler (next_handler, event);
       {
-       static EventParamName names[] = {kEventParamDirectObject,
-                                        kEventParamWindowMouseLocation,
-                                        kEventParamKeyModifiers,
-                                        kEventParamMouseButton,
-                                        kEventParamClickCount,
-                                        kEventParamMouseChord};
-       static EventParamType types[] = {typeWindowRef,
-                                        typeQDPoint,
-                                        typeUInt32,
-                                        typeMouseButton,
-                                        typeUInt32,
-                                        typeUInt32};
+       static const EventParamName names[] = {kEventParamDirectObject,
+                                              kEventParamWindowMouseLocation,
+                                              kEventParamKeyModifiers,
+                                              kEventParamMouseButton,
+                                              kEventParamClickCount,
+                                              kEventParamMouseChord};
+       static const EventParamType types[] = {typeWindowRef,
+                                              typeQDPoint,
+                                              typeUInt32,
+                                              typeMouseButton,
+                                              typeUInt32,
+                                              typeUInt32};
        int num_params = sizeof (names) / sizeof (names[0]);
 
        err = mac_store_event_ref_as_apple_event (0, 0,
@@ -9588,23 +10887,194 @@ mac_handle_window_event (next_handler, event, data)
                                                  event, num_params,
                                                  names, types);
       }
-      return err == noErr ? noErr : result;
+      if (err == noErr)
+       result = noErr;
+      break;
 #endif
 
 #if USE_MAC_TSM
+      /* -- window focus events -- */
+
     case kEventWindowFocusAcquired:
-      result = CallNextEventHandler (next_handler, event);
       err = mac_tsm_resume ();
-      return err == noErr ? noErr : result;
+      if (err == noErr)
+       result = noErr;
+      break;
 
     case kEventWindowFocusRelinquish:
-      result = CallNextEventHandler (next_handler, event);
       err = mac_tsm_suspend ();
-      return err == noErr ? noErr : result;
+      if (err == noErr)
+       result = noErr;
+      break;
+#endif
+
+    default:
+      abort ();
+    }
+
+  return result;
+}
+
+static pascal OSStatus
+mac_handle_application_event (next_handler, event, data)
+     EventHandlerCallRef next_handler;
+     EventRef event;
+     void *data;
+{
+  OSStatus err, result = eventNotHandledErr;
+
+  switch (GetEventKind (event))
+    {
+#if USE_MAC_TSM
+    case kEventAppActivated:
+      err = mac_tsm_resume ();
+      break;
+
+    case kEventAppDeactivated:
+      err = mac_tsm_suspend ();
+      break;
+#endif
+
+    default:
+      abort ();
+    }
+
+  if (err == noErr)
+    result = noErr;
+
+  return result;
+}
+
+static pascal OSStatus
+mac_handle_keyboard_event (next_handler, event, data)
+     EventHandlerCallRef next_handler;
+     EventRef event;
+     void *data;
+{
+  OSStatus err, result = eventNotHandledErr;
+  UInt32 event_kind, key_code, modifiers, mapped_modifiers;
+  unsigned char char_code;
+
+  event_kind = GetEventKind (event);
+  switch (event_kind)
+    {
+    case kEventRawKeyDown:
+    case kEventRawKeyRepeat:
+    case kEventRawKeyUp:
+      if (read_socket_inev == NULL)
+       {
+         result = CallNextEventHandler (next_handler, event);
+         break;
+       }
+
+      err = GetEventParameter (event, kEventParamKeyModifiers,
+                              typeUInt32, NULL,
+                              sizeof (UInt32), NULL, &modifiers);
+      if (err != noErr)
+       break;
+
+      mapped_modifiers = mac_mapped_modifiers (modifiers);
+
+      /* When using Carbon Events, we need to pass raw keyboard events
+        to the TSM ourselves.  If TSM handles it, it will pass back
+        noErr, otherwise it will pass back "eventNotHandledErr" and
+        we can process it normally.  */
+      if (!(mapped_modifiers
+           & ~(mac_pass_command_to_system ? cmdKey : 0)
+           & ~(mac_pass_control_to_system ? controlKey : 0)))
+       {
+         result = CallNextEventHandler (next_handler, event);
+         if (result != eventNotHandledErr)
+           break;
+       }
+
+#if USE_MAC_TSM
+      if (read_socket_inev->kind != NO_EVENT)
+       {
+         result = noErr;
+         break;
+       }
 #endif
+
+      if (event_kind == kEventRawKeyUp)
+       break;
+
+      err = GetEventParameter (event, kEventParamKeyMacCharCodes,
+                              typeChar, NULL,
+                              sizeof (char), NULL, &char_code);
+      if (err != noErr)
+       break;
+
+      err = GetEventParameter (event, kEventParamKeyCode,
+                              typeUInt32, NULL,
+                              sizeof (UInt32), NULL, &key_code);
+      if (err != noErr)
+       break;
+
+      do_keystroke ((event_kind == kEventRawKeyDown ? keyDown : autoKey),
+                   char_code, key_code, modifiers,
+                   ((unsigned long)
+                    (GetEventTime (event) / kEventDurationMillisecond)),
+                   read_socket_inev);
+      result = noErr;
+      break;
+
+    default:
+      abort ();
+    }
+
+  return result;
+}
+
+static pascal OSStatus
+mac_handle_command_event (next_handler, event, data)
+     EventHandlerCallRef next_handler;
+     EventRef event;
+     void *data;
+{
+  OSStatus err, result = eventNotHandledErr;
+  HICommand command;
+  static const EventParamName names[] =
+    {kEventParamDirectObject, kEventParamKeyModifiers};
+  static const EventParamType types[] =
+    {typeHICommand, typeUInt32};
+  int num_params = sizeof (names) / sizeof (names[0]);
+
+  err = GetEventParameter (event, kEventParamDirectObject, typeHICommand,
+                          NULL, sizeof (HICommand), NULL, &command);
+  if (err != noErr)
+    return eventNotHandledErr;
+
+  switch (GetEventKind (event))
+    {
+    case kEventCommandProcess:
+      result = CallNextEventHandler (next_handler, event);
+      if (result != eventNotHandledErr)
+       break;
+
+      err = GetEventParameter (event, kEventParamDirectObject,
+                              typeHICommand, NULL,
+                              sizeof (HICommand), NULL, &command);
+
+      if (err != noErr || command.commandID == 0)
+       break;
+
+      /* A HI command event is mapped to an Apple event whose event
+        class symbol is `hi-command' and event ID is its command
+        ID.  */
+      err = mac_store_event_ref_as_apple_event (0, command.commandID,
+                                               Qhi_command, Qnil,
+                                               event, num_params,
+                                               names, types);
+      if (err == noErr)
+       result = noErr;
+      break;
+
+    default:
+      abort ();
     }
 
-  return eventNotHandledErr;
+  return result;
 }
 
 static pascal OSStatus
@@ -9613,13 +11083,13 @@ mac_handle_mouse_event (next_handler, event, data)
      EventRef event;
      void *data;
 {
-  OSStatus result, err;
+  OSStatus err, result = eventNotHandledErr;
 
   switch (GetEventKind (event))
     {
     case kEventMouseWheelMoved:
       {
-       WindowPtr wp;
+       WindowRef wp;
        struct frame *f;
        EventMouseWheelAxis axis;
        SInt32 delta;
@@ -9627,15 +11097,14 @@ mac_handle_mouse_event (next_handler, event, data)
 
        result = CallNextEventHandler (next_handler, event);
        if (result != eventNotHandledErr || read_socket_inev == NULL)
-         return result;
+         break;
+
+       f = mac_focus_frame (&one_mac_display_info);
 
        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))
+       if (err != noErr
+           || wp != FRAME_MAC_WINDOW (f))
          break;
 
        err = GetEventParameter (event, kEventParamMouseWheelAxis,
@@ -9644,89 +11113,44 @@ mac_handle_mouse_event (next_handler, event, data)
        if (err != noErr || axis != kEventMouseWheelAxisY)
          break;
 
-       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;
+
+       point.h -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
+       point.v -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
+       if (point.h < 0 || point.v < 0
+           || EQ (window_from_coordinates (f, point.h, point.v, 0, 0, 0, 1),
+                  f->tool_bar_window))
+         break;
+
+       err = GetEventParameter (event, kEventParamMouseWheelDelta,
+                                typeSInt32, NULL, sizeof (SInt32),
+                                NULL, &delta);
+       if (err != noErr)
+         break;
+
        read_socket_inev->kind = WHEEL_EVENT;
        read_socket_inev->code = 0;
        read_socket_inev->modifiers =
          (mac_event_to_emacs_modifiers (event)
           | ((delta < 0) ? down_modifier : up_modifier));
-       SetPortWindowPort (wp);
-       GlobalToLocal (&point);
        XSETINT (read_socket_inev->x, point.h);
        XSETINT (read_socket_inev->y, point.v);
        XSETFRAME (read_socket_inev->frame_or_window, f);
 
-       return noErr;
+       result = noErr;
       }
       break;
 
     default:
-      break;
-    }
-
-  return eventNotHandledErr;
-}
-
-#if USE_MAC_FONT_PANEL
-static pascal OSStatus
-mac_handle_font_event (next_handler, event, data)
-     EventHandlerCallRef next_handler;
-     EventRef event;
-     void *data;
-{
-  OSStatus result, err;
-  Lisp_Object id_key;
-  int num_params;
-  EventParamName *names;
-  EventParamType *types;
-  static EventParamName names_sel[] = {kEventParamATSUFontID,
-                                      kEventParamATSUFontSize,
-                                      kEventParamFMFontFamily,
-                                      kEventParamFMFontSize,
-                                      kEventParamFontColor};
-  static EventParamType types_sel[] = {typeATSUFontID,
-                                      typeATSUSize,
-                                      typeFMFontFamily,
-                                      typeFMFontSize,
-                                      typeFontColor};
-
-  result = CallNextEventHandler (next_handler, event);
-  if (result != eventNotHandledErr)
-    return result;
-
-  switch (GetEventKind (event))
-    {
-    case kEventFontPanelClosed:
-      id_key = Qpanel_closed;
-      num_params = 0;
-      names = NULL;
-      types = NULL;
-      break;
-
-    case kEventFontSelection:
-      id_key = Qselection;
-      num_params = sizeof (names_sel) / sizeof (names_sel[0]);
-      names = names_sel;
-      types = types_sel;
-      break;
+      abort ();
     }
 
-  err = mac_store_event_ref_as_apple_event (0, 0, Qfont, id_key,
-                                           event, num_params,
-                                           names, types);
-
-  return err == noErr ? noErr : eventNotHandledErr;
+  return result;
 }
-#endif
 
 #if USE_MAC_TSM
 static pascal OSStatus
@@ -9735,13 +11159,13 @@ mac_handle_text_input_event (next_handler, event, data)
      EventRef event;
      void *data;
 {
-  OSStatus result, err = noErr;
+  OSStatus err, result;
   Lisp_Object id_key = Qnil;
   int num_params;
-  EventParamName *names;
-  EventParamType *types;
+  const EventParamName *names;
+  const EventParamType *types;
   static UInt32 seqno_uaia = 0;
-  static EventParamName names_uaia[] =
+  static const EventParamName names_uaia[] =
     {kEventParamTextInputSendComponentInstance,
      kEventParamTextInputSendRefCon,
      kEventParamTextInputSendSLRec,
@@ -9754,7 +11178,7 @@ mac_handle_text_input_event (next_handler, event, data)
      kEventParamTextInputSendTextServiceEncoding,
      kEventParamTextInputSendTextServiceMacEncoding,
      EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER};
-  static EventParamType types_uaia[] =
+  static const EventParamType types_uaia[] =
     {typeComponentInstance,
      typeLongInteger,
      typeIntlWritingCode,
@@ -9771,18 +11195,20 @@ mac_handle_text_input_event (next_handler, event, data)
      typeUInt32,
      typeUInt32,
      typeUInt32};
-  static EventParamName names_ufke[] =
+  static const EventParamName names_ufke[] =
     {kEventParamTextInputSendComponentInstance,
      kEventParamTextInputSendRefCon,
      kEventParamTextInputSendSLRec,
      kEventParamTextInputSendText};
-  static EventParamType types_ufke[] =
+  static const EventParamType types_ufke[] =
     {typeComponentInstance,
      typeLongInteger,
      typeIntlWritingCode,
      typeUnicodeText};
 
   result = CallNextEventHandler (next_handler, event);
+  if (result != eventNotHandledErr)
+    return result;
 
   switch (GetEventKind (event))
     {
@@ -9794,12 +11220,13 @@ mac_handle_text_input_event (next_handler, event, data)
       SetEventParameter (event, EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER,
                         typeUInt32, sizeof (UInt32), &seqno_uaia);
       seqno_uaia++;
+      result = noErr;
       break;
 
     case kEventTextInputUnicodeForKeyEvent:
       {
        EventRef kbd_event;
-       UInt32 actual_size, modifiers, mapped_modifiers;
+       UInt32 actual_size, modifiers;
 
        err = GetEventParameter (event, kEventParamTextInputSendKeyboardEvent,
                                 typeEventRef, NULL, sizeof (EventRef), NULL,
@@ -9808,21 +11235,10 @@ mac_handle_text_input_event (next_handler, event, data)
          err = GetEventParameter (kbd_event, kEventParamKeyModifiers,
                                   typeUInt32, NULL,
                                   sizeof (UInt32), NULL, &modifiers);
-       if (err == noErr)
-         {
-           mapped_modifiers =
-             (NILP (Vmac_control_modifier) ? 0 : controlKey)
-             | (NILP (Vmac_option_modifier) ? 0 : optionKey)
-             | (NILP (Vmac_command_modifier) ? 0 : cmdKey);
-#ifdef MAC_OSX
-           mapped_modifiers |=
-             (NILP (Vmac_function_modifier) ? 0 : kEventKeyModifierFnMask);
-#endif
-           if (modifiers & mapped_modifiers)
-             /* There're mapped modifier keys.  Process it in
-                XTread_socket.  */
-             return eventNotHandledErr;
-         }
+       if (err == noErr && mac_mapped_modifiers (modifiers))
+         /* There're mapped modifier keys.  Process it in
+            do_keystroke.  */
+         break;
        if (err == noErr)
          err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
                                   typeUnicodeText, NULL, 0, &actual_size,
@@ -9836,7 +11252,7 @@ mac_handle_text_input_event (next_handler, event, data)
                                     sizeof (UniChar), NULL, &code);
            if (err == noErr && code < 0x80)
              {
-               /* ASCII character.  Process it in XTread_socket.  */
+               /* ASCII character.  Process it in do_keystroke.  */
                if (read_socket_inev && code >= 0x20 && code <= 0x7e)
                  {
                    UInt32 key_code;
@@ -9861,16 +11277,20 @@ mac_handle_text_input_event (next_handler, event, data)
                        XSETFRAME (read_socket_inev->frame_or_window, f);
                      }
                  }
-               return eventNotHandledErr;
+               break;
              }
          }
+       if (err == noErr)
+         {
+           /* Non-ASCII keystrokes without mapped modifiers are
+              processed at the Lisp level.  */
+           id_key = Qunicode_for_key_event;
+           num_params = sizeof (names_ufke) / sizeof (names_ufke[0]);
+           names = names_ufke;
+           types = types_ufke;
+           result = noErr;
+         }
       }
-      /* Non-ASCII keystrokes without mapped modifiers are processed
-        at the Lisp level.  */
-      id_key = Qunicode_for_key_event;
-      num_params = sizeof (names_ufke) / sizeof (names_ufke[0]);
-      names = names_ufke;
-      types = types_ufke;
       break;
 
     case kEventTextInputOffsetToPos:
@@ -9880,31 +11300,35 @@ mac_handle_text_input_event (next_handler, event, data)
        Point p;
 
        if (!OVERLAYP (Vmac_ts_active_input_overlay))
-         return eventNotHandledErr;
+         break;
 
        /* Strictly speaking, this is not always correct because
           previous events may change some states about display.  */
-       if (NILP (Foverlay_get (Vmac_ts_active_input_overlay, Qbefore_string)))
+       if (!NILP (Foverlay_get (Vmac_ts_active_input_overlay, Qbefore_string)))
+         {
+           /* Active input area is displayed around the current point.  */
+           f = SELECTED_FRAME ();
+           w = XWINDOW (f->selected_window);
+         }
+       else if (WINDOWP (echo_area_window))
          {
            /* Active input area is displayed in the echo area.  */
            w = XWINDOW (echo_area_window);
            f = WINDOW_XFRAME (w);
          }
        else
-         {
-           /* Active input area is displayed around the current point.  */
-           f = SELECTED_FRAME ();
-           w = XWINDOW (f->selected_window);
-         }
+         break;
 
        p.h = (WINDOW_TO_FRAME_PIXEL_X (w, w->cursor.x)
-              + WINDOW_LEFT_FRINGE_WIDTH (w));
+              + WINDOW_LEFT_FRINGE_WIDTH (w)
+              + f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f));
        p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, w->cursor.y)
-              + FONT_BASE (FRAME_FONT (f)));
-       SetPortWindowPort (FRAME_MAC_WINDOW (f));
-       LocalToGlobal (&p);
+              + FONT_BASE (FRAME_FONT (f))
+              + f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f));
        err = SetEventParameter (event, kEventParamTextInputReplyPoint,
                                 typeQDPoint, sizeof (typeQDPoint), &p);
+       if (err == noErr)
+         result = noErr;
       }
       break;
 
@@ -9916,140 +11340,259 @@ mac_handle_text_input_event (next_handler, event, data)
     err = mac_store_event_ref_as_apple_event (0, 0, Qtext_input, id_key,
                                              event, num_params,
                                              names, types);
-
-  return err == noErr ? noErr : result;
+  return result;
 }
 #endif
+#endif /* TARGET_API_MAC_CARBON */
+
 
-#ifdef MAC_OSX
 OSStatus
-mac_store_service_event (event)
-     EventRef event;
+install_window_handler (window)
+     WindowRef window;
 {
-  OSStatus err;
-  Lisp_Object id_key;
-  int num_params;
-  EventParamName *names;
-  EventParamType *types;
-  static EventParamName names_pfm[] = {kEventParamServiceMessageName,
-                                      kEventParamServiceUserData};
-  static EventParamType types_pfm[] = {typeCFStringRef,
-                                      typeCFStringRef};
+  OSStatus err = noErr;
 
-  switch (GetEventKind (event))
+#if TARGET_API_MAC_CARBON
+  if (err == noErr)
     {
-    case kEventServicePaste:
-      id_key = Qpaste;
-      num_params = 0;
-      names = NULL;
-      types = NULL;
-      break;
+      static const EventTypeSpec specs[] =
+       {
+         /* -- window refresh events -- */
+         {kEventClassWindow, kEventWindowUpdate},
+         /* -- window state change events -- */
+         {kEventClassWindow, kEventWindowShowing},
+         {kEventClassWindow, kEventWindowHiding},
+         {kEventClassWindow, kEventWindowShown},
+         {kEventClassWindow, kEventWindowHidden},
+         {kEventClassWindow, kEventWindowCollapsed},
+         {kEventClassWindow, kEventWindowExpanded},
+         {kEventClassWindow, kEventWindowBoundsChanging},
+         {kEventClassWindow, kEventWindowBoundsChanged},
+         /* -- window action events -- */
+         {kEventClassWindow, kEventWindowClose},
+         {kEventClassWindow, kEventWindowGetIdealSize},
+#ifdef MAC_OSX
+         {kEventClassWindow, kEventWindowToolbarSwitchMode},
+#endif
+#if USE_MAC_TSM
+         /* -- window focus events -- */
+         {kEventClassWindow, kEventWindowFocusAcquired},
+         {kEventClassWindow, kEventWindowFocusRelinquish},
+#endif
+       };
+      static EventHandlerUPP handle_window_eventUPP = NULL;
 
-    case kEventServicePerform:
-      id_key = Qperform;
-      num_params = sizeof (names_pfm) / sizeof (names_pfm[0]);
-      names = names_pfm;
-      types = types_pfm;
-      break;
+      if (handle_window_eventUPP == NULL)
+       handle_window_eventUPP = NewEventHandlerUPP (mac_handle_window_event);
 
-    default:
-      abort ();
+      err = InstallWindowEventHandler (window, handle_window_eventUPP,
+                                      GetEventTypeCount (specs),
+                                      specs, NULL, NULL);
     }
+#endif
 
-  err = mac_store_event_ref_as_apple_event (0, 0, Qservice, id_key,
-                                           event, num_params,
-                                           names, types);
+  if (err == noErr)
+    err = install_drag_handler (window);
 
   return err;
 }
-#endif /* MAC_OSX */
-#endif /* USE_CARBON_EVENTS */
 
+void
+remove_window_handler (window)
+     WindowRef window;
+{
+  remove_drag_handler (window);
+}
 
-OSStatus
-install_window_handler (window)
-     WindowPtr window;
+#if TARGET_API_MAC_CARBON
+static OSStatus
+install_application_handler ()
 {
   OSStatus err = noErr;
-#if USE_CARBON_EVENTS
-  EventTypeSpec specs_window[] =
-    {{kEventClassWindow, kEventWindowUpdate},
-     {kEventClassWindow, kEventWindowGetIdealSize},
-     {kEventClassWindow, kEventWindowBoundsChanging},
-     {kEventClassWindow, kEventWindowBoundsChanged},
-     {kEventClassWindow, kEventWindowShown},
-     {kEventClassWindow, kEventWindowHidden},
-     {kEventClassWindow, kEventWindowExpanded},
-     {kEventClassWindow, kEventWindowCollapsed},
-     {kEventClassWindow, kEventWindowClose},
-#ifdef MAC_OSX
-     {kEventClassWindow, kEventWindowToolbarSwitchMode},
-#endif
-#if USE_MAC_TSM
-     {kEventClassWindow, kEventWindowFocusAcquired},
-     {kEventClassWindow, kEventWindowFocusRelinquish},
-#endif
-  };
-  EventTypeSpec specs_mouse[] = {{kEventClassMouse, kEventMouseWheelMoved}};
-  static EventHandlerUPP handle_window_eventUPP = NULL;
-  static EventHandlerUPP handle_mouse_eventUPP = NULL;
-#if USE_MAC_FONT_PANEL
-  EventTypeSpec specs_font[] = {{kEventClassFont, kEventFontPanelClosed},
-                               {kEventClassFont, kEventFontSelection}};
-  static EventHandlerUPP handle_font_eventUPP = NULL;
-#endif
+
+  if (err == noErr)
+    {
+      static const EventTypeSpec specs[] = {
 #if USE_MAC_TSM
-  EventTypeSpec specs_text_input[] =
-    {{kEventClassTextInput, kEventTextInputUpdateActiveInputArea},
-     {kEventClassTextInput, kEventTextInputUnicodeForKeyEvent},
-     {kEventClassTextInput, kEventTextInputOffsetToPos}};
-  static EventHandlerUPP handle_text_input_eventUPP = NULL;
+       {kEventClassApplication, kEventAppActivated},
+       {kEventClassApplication, kEventAppDeactivated},
 #endif
+      };
+
+      err = InstallApplicationEventHandler (NewEventHandlerUPP
+                                           (mac_handle_application_event),
+                                           GetEventTypeCount (specs),
+                                           specs, NULL, NULL);
+    }
+
+  if (err == noErr)
+    {
+      static const EventTypeSpec specs[] =
+       {{kEventClassKeyboard, kEventRawKeyDown},
+        {kEventClassKeyboard, kEventRawKeyRepeat},
+        {kEventClassKeyboard, kEventRawKeyUp}};
+
+      err = InstallApplicationEventHandler (NewEventHandlerUPP
+                                           (mac_handle_keyboard_event),
+                                           GetEventTypeCount (specs),
+                                           specs, NULL, NULL);
+    }
+
+  if (err == noErr)
+    {
+      static const EventTypeSpec specs[] =
+       {{kEventClassCommand, kEventCommandProcess}};
+
+      err = InstallApplicationEventHandler (NewEventHandlerUPP
+                                           (mac_handle_command_event),
+                                           GetEventTypeCount (specs),
+                                           specs, NULL, NULL);
+    }
+
+  if (err == noErr)
+    {
+      static const EventTypeSpec specs[] =
+       {{kEventClassMouse, kEventMouseWheelMoved}};
+
+      err = InstallApplicationEventHandler (NewEventHandlerUPP
+                                           (mac_handle_mouse_event),
+                                           GetEventTypeCount (specs),
+                                           specs, NULL, NULL);
+    }
 
-  if (handle_window_eventUPP == NULL)
-    handle_window_eventUPP = NewEventHandlerUPP (mac_handle_window_event);
-  if (handle_mouse_eventUPP == NULL)
-    handle_mouse_eventUPP = NewEventHandlerUPP (mac_handle_mouse_event);
-#if USE_MAC_FONT_PANEL
-  if (handle_font_eventUPP == NULL)
-    handle_font_eventUPP = NewEventHandlerUPP (mac_handle_font_event);
-#endif
 #if USE_MAC_TSM
-  if (handle_text_input_eventUPP == NULL)
-    handle_text_input_eventUPP =
-      NewEventHandlerUPP (mac_handle_text_input_event);
+  if (err == noErr)
+    {
+      static const EventTypeSpec spec[] =
+       {{kEventClassTextInput, kEventTextInputUpdateActiveInputArea},
+        {kEventClassTextInput, kEventTextInputUnicodeForKeyEvent},
+        {kEventClassTextInput, kEventTextInputOffsetToPos}};
+
+      err = InstallApplicationEventHandler (NewEventHandlerUPP
+                                           (mac_handle_text_input_event),
+                                           GetEventTypeCount (spec),
+                                           spec, NULL, NULL);
+    }
 #endif
-  err = InstallWindowEventHandler (window, handle_window_eventUPP,
-                                  GetEventTypeCount (specs_window),
-                                  specs_window, NULL, NULL);
+
   if (err == noErr)
-    err = InstallWindowEventHandler (window, handle_mouse_eventUPP,
-                                    GetEventTypeCount (specs_mouse),
-                                    specs_mouse, NULL, NULL);
-#if USE_MAC_FONT_PANEL
+    err = install_menu_target_item_handler ();
+
+#ifdef MAC_OSX
   if (err == noErr)
-    err = InstallWindowEventHandler (window, handle_font_eventUPP,
-                                    GetEventTypeCount (specs_font),
-                                    specs_font, NULL, NULL);
+    err = install_service_handler ();
 #endif
-#if USE_MAC_TSM
-  if (err == noErr)
-    err = InstallWindowEventHandler (window, handle_text_input_eventUPP,
-                                    GetEventTypeCount (specs_text_input),
-                                    specs_text_input, window, NULL);
+
+  return err;
+}
 #endif
+
+static pascal void
+mac_handle_dm_notification (event)
+     AppleEvent *event;
+{
+  mac_screen_config_changed = 1;
+}
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+static void
+mac_handle_cg_display_reconfig (display, flags, user_info)
+     CGDirectDisplayID display;
+     CGDisplayChangeSummaryFlags flags;
+     void *user_info;
+{
+  mac_screen_config_changed = 1;
+}
+#endif
+
+static OSErr
+init_dm_notification_handler ()
+{
+  OSErr err = noErr;
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+  if (CGDisplayRegisterReconfigurationCallback != NULL)
+#endif
+    {
+      CGDisplayRegisterReconfigurationCallback (mac_handle_cg_display_reconfig,
+                                               NULL);
+    }
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+  else         /* CGDisplayRegisterReconfigurationCallback == NULL */
+#endif
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+    {
+      static DMNotificationUPP handle_dm_notificationUPP = NULL;
+      ProcessSerialNumber psn;
+
+      if (handle_dm_notificationUPP == NULL)
+       handle_dm_notificationUPP =
+         NewDMNotificationUPP (mac_handle_dm_notification);
+
+      err = GetCurrentProcess (&psn);
+      if (err == noErr)
+       err = DMRegisterNotifyProc (handle_dm_notificationUPP, &psn);
+    }
 #endif
-  if (err == noErr)
-    err = install_drag_handler (window);
 
   return err;
 }
 
-void
-remove_window_handler (window)
-     WindowPtr window;
+static void
+mac_get_screen_info (dpyinfo)
+     struct mac_display_info *dpyinfo;
 {
-  remove_drag_handler (window);
+#ifdef MAC_OSX
+  /* HasDepth returns true if it is possible to have a 32 bit display,
+     but this may not be what is actually used.  Mac OSX can do better.  */
+  dpyinfo->color_p = CGDisplaySamplesPerPixel (kCGDirectMainDisplay) > 1;
+  dpyinfo->n_planes = CGDisplayBitsPerPixel (kCGDirectMainDisplay);
+  {
+    CGDisplayErr err;
+    CGDisplayCount ndisps;
+    CGDirectDisplayID *displays;
+
+    err = CGGetActiveDisplayList (0, NULL, &ndisps);
+    if (err == noErr)
+      {
+       displays = alloca (sizeof (CGDirectDisplayID) * ndisps);
+       err = CGGetActiveDisplayList (ndisps, displays, &ndisps);
+      }
+    if (err == noErr)
+      {
+       CGRect bounds = CGRectZero;
+
+       while (ndisps-- > 0)
+         bounds = CGRectUnion (bounds, CGDisplayBounds (displays[ndisps]));
+       dpyinfo->height = CGRectGetHeight (bounds);
+       dpyinfo->width = CGRectGetWidth (bounds);
+      }
+    else
+      {
+       dpyinfo->height = CGDisplayPixelsHigh (kCGDirectMainDisplay);
+       dpyinfo->width = CGDisplayPixelsWide (kCGDirectMainDisplay);
+      }
+  }
+#else  /* !MAC_OSX */
+  {
+    GDHandle gdh = GetMainDevice ();
+    Rect rect = (**gdh).gdRect;
+
+    dpyinfo->color_p = TestDeviceAttribute (gdh, gdDevType);
+    for (dpyinfo->n_planes = 32; dpyinfo->n_planes > 0; dpyinfo->n_planes >>= 1)
+      if (HasDepth (gdh, dpyinfo->n_planes, gdDevType, dpyinfo->color_p))
+       break;
+
+    for (gdh = DMGetFirstScreenDevice (dmOnlyActiveDisplays); gdh;
+        gdh = DMGetNextScreenDevice (gdh, dmOnlyActiveDisplays))
+      UnionRect (&rect, &(**gdh).gdRect, &rect);
+
+    dpyinfo->height = rect.bottom - rect.top;
+    dpyinfo->width = rect.right - rect.left;
+  }
+#endif  /* !MAC_OSX */
 }
 
 
@@ -10088,7 +11631,7 @@ main (void)
 
 #if __MWERKS__
   /* set creator and type for files created by MSL */
-  _fcreator = 'EMAx';
+  _fcreator = MAC_EMACS_CREATOR_CODE;
   _ftype = 'TEXT';
 #endif
 
@@ -10110,6 +11653,8 @@ main (void)
 
   init_apple_event_handler ();
 
+  init_dm_notification_handler ();
+
   {
     char **argv;
     int argc = 0;
@@ -10135,7 +11680,7 @@ main (void)
 }
 #endif
 
-#if !USE_CARBON_EVENTS
+#if !TARGET_API_MAC_CARBON
 static RgnHandle mouse_region = NULL;
 
 Boolean
@@ -10172,7 +11717,7 @@ mac_wait_next_event (er, sleep_time, dequeue)
     er_buf.what = nullEvent;
   return true;
 }
-#endif /* not USE_CARBON_EVENTS */
+#endif /* not TARGET_API_MAC_CARBON */
 
 #if TARGET_API_MAC_CARBON
 OSStatus
@@ -10187,8 +11732,7 @@ mac_post_mouse_moved_event ()
     {
       Point mouse_pos;
 
-      GetMouse (&mouse_pos);
-      LocalToGlobal (&mouse_pos);
+      GetGlobalMouse (&mouse_pos);
       err = SetEventParameter (event, kEventParamMouseLocation, typeQDPoint,
                               sizeof (Point), &mouse_pos);
     }
@@ -10207,44 +11751,6 @@ mac_post_mouse_moved_event ()
 
   return err;
 }
-
-static void
-mac_set_unicode_keystroke_event (code, buf)
-     UniChar code;
-     struct input_event *buf;
-{
-  int charset_id, c1, c2;
-
-  if (code < 0x80)
-    {
-      buf->kind = ASCII_KEYSTROKE_EVENT;
-      buf->code = code;
-    }
-  else if (code < 0x100)
-    {
-      if (code < 0xA0)
-       charset_id = CHARSET_8_BIT_CONTROL;
-      else
-       charset_id = charset_latin_iso8859_1;
-      buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
-      buf->code = MAKE_CHAR (charset_id, code, 0);
-    }
-  else
-    {
-      if (code < 0x2500)
-       charset_id = charset_mule_unicode_0100_24ff,
-         code -= 0x100;
-      else if (code < 0x33FF)
-       charset_id = charset_mule_unicode_2500_33ff,
-         code -= 0x2500;
-      else if (code >= 0xE000)
-       charset_id = charset_mule_unicode_e000_ffff,
-         code -= 0xE000;
-      c1 = (code / 96) + 32, c2 = (code % 96) + 32;
-      buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
-      buf->code = MAKE_CHAR (charset_id, c1, c2);
-    }
-}
 #endif
 
 /* Emacs calls this whenever it wants to read an input event from the
@@ -10256,7 +11762,7 @@ XTread_socket (sd, expected, hold_quit)
 {
   struct input_event inev;
   int count = 0;
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
   EventRef eventRef;
   EventTargetRef toolbox_dispatcher;
 #endif
@@ -10277,7 +11783,7 @@ XTread_socket (sd, expected, hold_quit)
 
   ++handling_signal;
 
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
   toolbox_dispatcher = GetEventDispatcherTarget ();
 
   while (
@@ -10286,9 +11792,9 @@ XTread_socket (sd, expected, hold_quit)
 #endif
         !ReceiveNextEvent (0, NULL, kEventDurationNoWait,
                            kEventRemoveFromQueue, &eventRef))
-#else /* !USE_CARBON_EVENTS */
+#else /* !TARGET_API_MAC_CARBON */
   while (mac_wait_next_event (&er, 0, true))
-#endif /* !USE_CARBON_EVENTS */
+#endif /* !TARGET_API_MAC_CARBON */
     {
       int do_help = 0;
       struct frame *f;
@@ -10298,44 +11804,33 @@ XTread_socket (sd, expected, hold_quit)
       inev.kind = NO_EVENT;
       inev.arg = Qnil;
 
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
       timestamp = GetEventTime (eventRef) / kEventDurationMillisecond;
-#else
-      timestamp = er.when * (1000 / 60); /* ticks to milliseconds */
-#endif
 
-#if USE_CARBON_EVENTS
-      /* Handle new events */
       if (!mac_convert_event_ref (eventRef, &er))
-       {
-         /* There used to be a handler for the kEventMouseWheelMoved
-            event here.  But as of Mac OS X 10.4, this kind of event
-            is not directly posted to the main event queue by
-            two-finger scrolling on the trackpad.  Instead, some
-            private event is posted and it is converted to a wheel
-            event by the default handler for the application target.
-            The converted one can be received by a Carbon event
-            handler installed on a window target.  */
-         read_socket_inev = &inev;
-         SendEventToEventTarget (eventRef, toolbox_dispatcher);
-         read_socket_inev = NULL;
-       }
-      else
-#endif /* USE_CARBON_EVENTS */
+       goto OTHER;
+#else  /* !TARGET_API_MAC_CARBON */
+      timestamp = er.when * (1000 / 60); /* ticks to milliseconds */
+#endif  /* !TARGET_API_MAC_CARBON */
+
       switch (er.what)
        {
        case mouseDown:
        case mouseUp:
          {
-           WindowPtr window_ptr;
+           WindowRef window_ptr;
            ControlPartCode part_code;
            int tool_bar_p = 0;
 
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
+           OSStatus err;
+
            /* This is needed to send mouse events like aqua window
               buttons to the correct handler.  */
-           if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
-               != eventNotHandledErr)
+           read_socket_inev = &inev;
+           err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
+           read_socket_inev = NULL;
+           if (err != eventNotHandledErr)
              break;
 #endif
            last_mouse_glyph_frame = 0;
@@ -10376,22 +11871,27 @@ XTread_socket (sd, expected, hold_quit)
 #else
                    FrontWindow ()
 #endif
-                   != window_ptr)
+                   != window_ptr
+                   || (mac_window_to_frame (window_ptr)
+                       != dpyinfo->x_focus_frame))
                  SelectWindow (window_ptr);
                else
                  {
                    ControlPartCode control_part_code;
-                   ControlHandle ch;
-                   Point mouse_loc = er.where;
+                   ControlRef ch;
+                   Point mouse_loc;
 #ifdef MAC_OSX
                    ControlKind control_kind;
 #endif
 
                    f = mac_window_to_frame (window_ptr);
                    /* convert to local coordinates of new window */
-                   SetPortWindowPort (window_ptr);
-
-                   GlobalToLocal (&mouse_loc);
+                   mouse_loc.h = (er.where.h
+                                  - (f->left_pos
+                                     + FRAME_OUTER_TO_INNER_DIFF_X (f)));
+                   mouse_loc.v = (er.where.v
+                                  - (f->top_pos
+                                     + FRAME_OUTER_TO_INNER_DIFF_Y (f)));
 #if TARGET_API_MAC_CARBON
                    ch = FindControlUnderMouse (mouse_loc, window_ptr,
                                                &control_part_code);
@@ -10404,7 +11904,7 @@ XTread_socket (sd, expected, hold_quit)
                                                     &ch);
 #endif
 
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
                    inev.code = mac_get_mouse_btn (eventRef);
                    inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
 #else
@@ -10441,12 +11941,12 @@ XTread_socket (sd, expected, hold_quit)
 #ifdef USE_TOOLKIT_SCROLL_BARS
                        /* Make the "Ctrl-Mouse-2 splits window" work
                           for toolkit scroll bars.  */
-                       if (er.modifiers & controlKey)
+                       if (inev.modifiers & ctrl_modifier)
                          x_scroll_bar_handle_click (bar, control_part_code,
                                                     &er, &inev);
                        else if (er.what == mouseDown)
                          x_scroll_bar_handle_press (bar, control_part_code,
-                                                    &inev);
+                                                    mouse_loc, &inev);
                        else
                          x_scroll_bar_handle_release (bar, &inev);
 #else  /* not USE_TOOLKIT_SCROLL_BARS */
@@ -10509,7 +12009,9 @@ XTread_socket (sd, expected, hold_quit)
                      f->mouse_moved = 0;
 
 #ifdef USE_TOOLKIT_SCROLL_BARS
-                   if (inev.kind == MOUSE_CLICK_EVENT)
+                   if (inev.kind == MOUSE_CLICK_EVENT
+                       || (inev.kind == SCROLL_BAR_CLICK_EVENT
+                           && (inev.modifiers & ctrl_modifier)))
 #endif
                      switch (er.what)
                        {
@@ -10538,16 +12040,14 @@ XTread_socket (sd, expected, hold_quit)
                DragWindow (window_ptr, er.where, NULL);
 #else /* not TARGET_API_MAC_CARBON */
                DragWindow (window_ptr, er.where, &qd.screenBits.bounds);
-#endif /* not TARGET_API_MAC_CARBON */
                /* Update the frame parameters.  */
-#if !USE_CARBON_EVENTS
                {
                  struct frame *f = mac_window_to_frame (window_ptr);
 
                  if (f && !f->async_iconified)
                    mac_handle_origin_change (f);
                }
-#endif
+#endif /* not TARGET_API_MAC_CARBON */
                break;
 
              case inGoAway:
@@ -10571,41 +12071,38 @@ XTread_socket (sd, expected, hold_quit)
                  do_zoom_window (window_ptr, part_code);
                break;
 
+#if USE_MAC_TOOLBAR
+             case inStructure:
+               {
+                 OSStatus err;
+                 HIViewRef ch;
+
+                 err = HIViewGetViewForMouseEvent (HIViewGetRoot (window_ptr),
+                                                   eventRef, &ch);
+                 /* This doesn't work on Mac OS X 10.2.  */
+                 if (err == noErr)
+                   HIViewClick (ch, eventRef);
+               }
+               break;
+#endif /* USE_MAC_TOOLBAR */
+
              default:
                break;
              }
          }
          break;
 
+#if !TARGET_API_MAC_CARBON
        case updateEvt:
-#if USE_CARBON_EVENTS
-         if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
-             != eventNotHandledErr)
-           break;
-#else
-         do_window_update ((WindowPtr) er.message);
-#endif
+         do_window_update ((WindowRef) er.message);
          break;
+#endif
 
        case osEvt:
-#if USE_CARBON_EVENTS
-         if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
-             != eventNotHandledErr)
-           break;
-#endif
          switch ((er.message >> 24) & 0x000000FF)
            {
-           case suspendResumeMessage:
-#if USE_MAC_TSM
-             if (er.message & resumeFlag)
-               mac_tsm_resume ();
-             else
-               mac_tsm_suspend ();
-#endif
-             break;
-
            case mouseMovedMessage:
-#if !USE_CARBON_EVENTS
+#if !TARGET_API_MAC_CARBON
              SetRectRgn (mouse_region, er.where.h, er.where.v,
                          er.where.h + 1, er.where.v + 1);
 #endif
@@ -10626,13 +12123,15 @@ XTread_socket (sd, expected, hold_quit)
 
              if (f)
                {
-                 WindowPtr wp = FRAME_MAC_WINDOW (f);
-                 Point mouse_pos = er.where;
-
-                 SetPortWindowPort (wp);
-
-                 GlobalToLocal (&mouse_pos);
-
+                 WindowRef wp = FRAME_MAC_WINDOW (f);
+                 Point mouse_pos;
+
+                 mouse_pos.h = (er.where.h
+                                - (f->left_pos
+                                   + FRAME_OUTER_TO_INNER_DIFF_X (f)));
+                 mouse_pos.v = (er.where.v
+                                - (f->top_pos
+                                   + FRAME_OUTER_TO_INNER_DIFF_Y (f)));
                  if (dpyinfo->grabbed && tracked_scroll_bar)
 #ifdef USE_TOOLKIT_SCROLL_BARS
                    x_scroll_bar_handle_drag (wp, tracked_scroll_bar,
@@ -10671,6 +12170,10 @@ XTread_socket (sd, expected, hold_quit)
                        }
                      if (!note_mouse_movement (f, &mouse_pos))
                        help_echo_string = previous_help_echo_string;
+#if USE_MAC_TOOLBAR
+                     else
+                       mac_tool_bar_note_mouse_movement (f, eventRef);
+#endif
                    }
                }
 
@@ -10680,18 +12183,16 @@ XTread_socket (sd, expected, hold_quit)
              if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
                do_help = 1;
              break;
+
+           default:
+             goto OTHER;
            }
          break;
 
        case activateEvt:
          {
-           WindowPtr window_ptr = (WindowPtr) er.message;
+           WindowRef window_ptr = (WindowRef) er.message;
 
-#if USE_CARBON_EVENTS
-           if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
-               != eventNotHandledErr)
-             break;
-#endif
            if (window_ptr == tip_window)
              {
                HideWindow (tip_window);
@@ -10699,26 +12200,31 @@ XTread_socket (sd, expected, hold_quit)
              }
 
            if (!is_emacs_window (window_ptr))
-             break;
+             goto OTHER;
+
+           f = mac_window_to_frame (window_ptr);
 
            if ((er.modifiers & activeFlag) != 0)
              {
                /* A window has been activated */
-               Point mouse_loc = er.where;
+               Point mouse_loc;
 
                x_detect_focus_change (dpyinfo, &er, &inev);
 
-               SetPortWindowPort (window_ptr);
-               GlobalToLocal (&mouse_loc);
+               mouse_loc.h = (er.where.h
+                              - (f->left_pos
+                                 + FRAME_OUTER_TO_INNER_DIFF_X (f)));
+               mouse_loc.v = (er.where.v
+                              - (f->top_pos
+                                 + FRAME_OUTER_TO_INNER_DIFF_Y (f)));
                /* Window-activated event counts as mouse movement,
                   so update things that depend on mouse position.  */
-               note_mouse_movement (mac_window_to_frame (window_ptr),
-                                    &mouse_loc);
+               note_mouse_movement (f, &mouse_loc);
              }
            else
              {
                /* A window has been deactivated */
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
                if (dpyinfo->grabbed && tracked_scroll_bar)
                  {
                    struct input_event event;
@@ -10738,7 +12244,6 @@ XTread_socket (sd, expected, hold_quit)
 
                x_detect_focus_change (dpyinfo, &er, &inev);
 
-               f = mac_window_to_frame (window_ptr);
                if (f == dpyinfo->mouse_face_mouse_frame)
                  {
                    /* If we move outside the frame, then we're
@@ -10761,213 +12266,26 @@ XTread_socket (sd, expected, hold_quit)
        case keyDown:
        case keyUp:
        case autoKey:
-         {
-           int keycode = (er.message & keyCodeMask) >> 8;
-           static SInt16 last_key_script = -1;
-           SInt16 current_key_script;
-           UInt32 modifiers = er.modifiers, mapped_modifiers;
-
-           mapped_modifiers =
-             (NILP (Vmac_control_modifier) ? 0 : controlKey)
-             | (NILP (Vmac_option_modifier) ? 0 : optionKey)
-             | (NILP (Vmac_command_modifier) ? 0 : cmdKey);
-
-#if USE_CARBON_EVENTS && defined (MAC_OSX)
-           mapped_modifiers |=
-             (NILP (Vmac_function_modifier) ? 0 : kEventKeyModifierFnMask);
-
-           GetEventParameter (eventRef, kEventParamKeyModifiers,
-                              typeUInt32, NULL,
-                              sizeof (UInt32), NULL, &modifiers);
-#endif
-           mapped_modifiers &= modifiers;
-
-#if USE_CARBON_EVENTS && (defined (MAC_OSX) || USE_MAC_TSM)
-           /* When using Carbon Events, we need to pass raw keyboard
-              events to the TSM ourselves.  If TSM handles it, it
-              will pass back noErr, otherwise it will pass back
-              "eventNotHandledErr" and we can process it
-              normally.  */
-           if (!(mapped_modifiers
-                 & ~(mac_pass_command_to_system ? cmdKey : 0)
-                 & ~(mac_pass_control_to_system ? controlKey : 0)))
-             {
-               OSStatus err;
-
-               read_socket_inev = &inev;
-               err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
-               read_socket_inev = NULL;
-               if (err != eventNotHandledErr)
-                 break;
-             }
-#endif
-           if (er.what == keyUp)
-             break;
-
-           ObscureCursor ();
-
-           f = mac_focus_frame (dpyinfo);
-
-           if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
-               && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
-             {
-               clear_mouse_face (dpyinfo);
-               dpyinfo->mouse_face_hidden = 1;
-             }
+         ObscureCursor ();
 
-           current_key_script = GetScriptManagerVariable (smKeyScript);
-           if (last_key_script != current_key_script)
-             {
-               struct input_event event;
-
-               EVENT_INIT (event);
-               event.kind = LANGUAGE_CHANGE_EVENT;
-               event.arg = Qnil;
-               event.code = current_key_script;
-               event.timestamp = timestamp;
-               kbd_buffer_store_event (&event);
-               count++;
-               last_key_script = current_key_script;
-             }
-
-#if USE_MAC_TSM
-           if (inev.kind != NO_EVENT)
-             break;
-#endif
-
-#ifdef MAC_OSX
-           if (mapped_modifiers & kEventKeyModifierFnMask
-               && keycode <= 0x7f
-               && fn_keycode_to_keycode_table[keycode])
-             keycode = fn_keycode_to_keycode_table[keycode];
-#endif
-           if (keycode <= 0x7f && keycode_to_xkeysym_table [keycode])
-             {
-               inev.kind = NON_ASCII_KEYSTROKE_EVENT;
-               inev.code = 0xff00 | keycode_to_xkeysym_table [keycode];
-#ifdef MAC_OSX
-               if (modifiers & kEventKeyModifierFnMask
-                   && keycode <= 0x7f
-                   && fn_keycode_to_keycode_table[keycode] == keycode)
-                 modifiers &= ~kEventKeyModifierFnMask;
-#endif
-             }
-           else if (mapped_modifiers)
-             {
-               /* translate the keycode back to determine the
-                  original key */
-#ifdef MAC_OSX
-               static SInt16 last_key_layout_id = 0;
-               static Handle uchr_handle = (Handle)-1;
-               SInt16 current_key_layout_id =
-                 GetScriptVariable (current_key_script, smScriptKeys);
-
-               if (uchr_handle == (Handle)-1
-                   || last_key_layout_id != current_key_layout_id)
-                 {
-                   uchr_handle = GetResource ('uchr', current_key_layout_id);
-                   last_key_layout_id = current_key_layout_id;
-                 }
-
-               if (uchr_handle)
-                 {
-                   OSStatus status;
-                   UInt16 key_action = er.what - keyDown;
-                   UInt32 modifier_key_state =
-                     (modifiers & ~mapped_modifiers) >> 8;
-                   UInt32 keyboard_type = LMGetKbdType ();
-                   SInt32 dead_key_state = 0;
-                   UniChar code;
-                   UniCharCount actual_length;
-
-                   status = UCKeyTranslate ((UCKeyboardLayout *)*uchr_handle,
-                                            keycode, key_action,
-                                            modifier_key_state,
-                                            keyboard_type,
-                                            kUCKeyTranslateNoDeadKeysMask,
-                                            &dead_key_state,
-                                            1, &actual_length, &code);
-                   if (status == noErr && actual_length == 1)
-                     mac_set_unicode_keystroke_event (code, &inev);
-                 }
-#endif /* MAC_OSX */
-
-               if (inev.kind == NO_EVENT)
-                 {
-                   /* This code comes from Keyboard Resource,
-                      Appendix C of IM - Text.  This is necessary
-                      since shift is ignored in KCHR table
-                      translation when option or command is pressed.
-                      It also does not translate correctly
-                      control-shift chars like C-% so mask off shift
-                      here also.  */
-                   /* Mask off modifier keys that are mapped to some
-                      Emacs modifiers.  */
-                   int new_modifiers = er.modifiers & ~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;
-                   UInt32 new_char_code;
-
-                   new_char_code = KeyTranslate (kchr_ptr, new_keycode,
-                                                 &some_state);
-                   if (new_char_code == 0)
-                     /* Seems like a dead key.  Append up-stroke.  */
-                     new_char_code = KeyTranslate (kchr_ptr,
-                                                   new_keycode | 0x80,
-                                                   &some_state);
-                   if (new_char_code)
-                     {
-                       inev.kind = ASCII_KEYSTROKE_EVENT;
-                       inev.code = new_char_code & 0xff;
-                     }
-                 }
-             }
-
-           if (inev.kind == NO_EVENT)
-             {
-               inev.kind = ASCII_KEYSTROKE_EVENT;
-               inev.code = er.message & charCodeMask;
-             }
-
-           inev.modifiers = mac_to_emacs_modifiers (modifiers);
-           inev.modifiers |= (extra_keyboard_modifiers
-                              & (meta_modifier | alt_modifier
-                                 | hyper_modifier | super_modifier));
-           XSETFRAME (inev.frame_or_window, f);
+         f = mac_focus_frame (dpyinfo);
+         XSETFRAME (inev.frame_or_window, f);
 
+         /* If mouse-highlight is an integer, input clears out mouse
+            highlighting.  */
+         if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
+             && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
+           {
+             clear_mouse_face (dpyinfo);
+             dpyinfo->mouse_face_hidden = 1;
+           }
 #if TARGET_API_MAC_CARBON
-           if (inev.kind == ASCII_KEYSTROKE_EVENT
-               && inev.code >= 0x80 && inev.modifiers)
-             {
-               OSStatus err;
-               TextEncoding encoding = kTextEncodingMacRoman;
-               TextToUnicodeInfo ttu_info;
-
-               UpgradeScriptInfoToTextEncoding (current_key_script,
-                                                kTextLanguageDontCare,
-                                                kTextRegionDontCare,
-                                                NULL, &encoding);
-               err = CreateTextToUnicodeInfoByEncoding (encoding, &ttu_info);
-               if (err == noErr)
-                 {
-                   UniChar code;
-                   Str255 pstr;
-                   ByteCount unicode_len;
-
-                   pstr[0] = 1;
-                   pstr[1] = inev.code;
-                   err = ConvertFromPStringToUnicode (ttu_info, pstr,
-                                                      sizeof (UniChar),
-                                                      &unicode_len, &code);
-                   if (err == noErr && unicode_len == sizeof (UniChar))
-                     mac_set_unicode_keystroke_event (code, &inev);
-                   DisposeTextToUnicodeInfo (&ttu_info);
-                 }
-             }
+         goto OTHER;
+#else
+         do_keystroke (er.what, er.message & charCodeMask,
+                       (er.message & keyCodeMask) >> 8,
+                       er.modifiers, timestamp, &inev);
 #endif
-         }
          break;
 
        case kHighLevelEvent:
@@ -10975,9 +12293,19 @@ XTread_socket (sd, expected, hold_quit)
          break;
 
        default:
+       OTHER:
+#if TARGET_API_MAC_CARBON
+         {
+           OSStatus err;
+
+           read_socket_inev = &inev;
+           err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
+           read_socket_inev = NULL;
+         }
+#endif
          break;
        }
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
       ReleaseEvent (eventRef);
 #endif
 
@@ -11023,7 +12351,13 @@ XTread_socket (sd, expected, hold_quit)
       pending_autoraise_frame = 0;
     }
 
-#if !USE_CARBON_EVENTS
+  if (mac_screen_config_changed)
+    {
+      mac_get_screen_info (dpyinfo);
+      mac_screen_config_changed = 0;
+    }
+
+#if !TARGET_API_MAC_CARBON
   /* Check which frames are still visible.  We do this here because
      there doesn't seem to be any direct notification from the Window
      Manager that the visibility of a window has changed (at least,
@@ -11128,7 +12462,7 @@ make_mac_terminal_frame (struct frame *f)
 
   if (!(FRAME_MAC_WINDOW (f) =
        NewCWindow (NULL, &r, "\p", true, dBoxProc,
-                   (WindowPtr) -1, 1, (long) f->output_data.mac)))
+                   (WindowRef) -1, 1, (long) f->output_data.mac)))
     abort ();
   /* so that update events can find this mac_output struct */
   f->output_data.mac->mFP = f;  /* point back to emacs frame */
@@ -11157,66 +12491,11 @@ make_mac_terminal_frame (struct frame *f)
                            Initialization
  ***********************************************************************/
 
-int mac_initialized = 0;
-
-void
-mac_initialize_display_info ()
-{
-  struct mac_display_info *dpyinfo = &one_mac_display_info;
-
-  bzero (dpyinfo, sizeof (*dpyinfo));
-
-#ifdef MAC_OSX
-  dpyinfo->mac_id_name
-    = (char *) xmalloc (SCHARS (Vinvocation_name)
-                       + SCHARS (Vsystem_name)
-                       + 2);
-  sprintf (dpyinfo->mac_id_name, "%s@%s",
-          SDATA (Vinvocation_name), SDATA (Vsystem_name));
-#else
-  dpyinfo->mac_id_name = (char *) xmalloc (strlen ("Mac Display") + 1);
-  strcpy (dpyinfo->mac_id_name, "Mac Display");
-#endif
-
-  dpyinfo->reference_count = 0;
-  dpyinfo->resx = 72.0;
-  dpyinfo->resy = 72.0;
-#ifdef MAC_OSX
-  /* HasDepth returns true if it is possible to have a 32 bit display,
-     but this may not be what is actually used.  Mac OSX can do better.  */
-  dpyinfo->color_p = CGDisplaySamplesPerPixel (kCGDirectMainDisplay) > 1;
-  dpyinfo->n_planes = CGDisplayBitsPerPixel (kCGDirectMainDisplay);
-  dpyinfo->height = CGDisplayPixelsHigh (kCGDirectMainDisplay);
-  dpyinfo->width = CGDisplayPixelsWide (kCGDirectMainDisplay);
-#else
-  {
-    GDHandle main_device_handle = LMGetMainDevice();
-
-    dpyinfo->color_p = TestDeviceAttribute (main_device_handle, gdDevType);
-    for (dpyinfo->n_planes = 32; dpyinfo->n_planes > 0; dpyinfo->n_planes >>= 1)
-      if (HasDepth (main_device_handle, dpyinfo->n_planes,
-                   gdDevType, dpyinfo->color_p))
-       break;
-    dpyinfo->height = (**main_device_handle).gdRect.bottom;
-    dpyinfo->width = (**main_device_handle).gdRect.right;
-  }
-#endif
-  dpyinfo->grabbed = 0;
-  dpyinfo->root_window = NULL;
-  dpyinfo->image_cache = make_image_cache ();
-
-  dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
-  dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
-  dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID;
-  dpyinfo->mouse_face_window = Qnil;
-  dpyinfo->mouse_face_overlay = Qnil;
-  dpyinfo->mouse_face_hidden = 0;
-}
-
+static int mac_initialized = 0;
 
 static XrmDatabase
 mac_make_rdb (xrm_option)
-     char *xrm_option;
+     const char *xrm_option;
 {
   XrmDatabase database;
 
@@ -11234,6 +12513,7 @@ mac_term_init (display_name, xrm_option, resource_name)
      char *resource_name;
 {
   struct mac_display_info *dpyinfo;
+  struct terminal *terminal;
 
   BLOCK_INPUT;
 
@@ -11246,9 +12526,44 @@ mac_term_init (display_name, xrm_option, resource_name)
   if (x_display_list)
     error ("Sorry, this version can only handle one display");
 
-  mac_initialize_display_info ();
-
   dpyinfo = &one_mac_display_info;
+  bzero (dpyinfo, sizeof (*dpyinfo));
+
+  terminal = mac_create_terminal (dpyinfo);
+
+  /* Set the name of the terminal. */
+  terminal->name = (char *) xmalloc (SBYTES (display_name) + 1);
+  strncpy (terminal->name, SDATA (display_name), SBYTES (display_name));
+  terminal->name[SBYTES (display_name)] = 0;
+
+#ifdef MAC_OSX
+  dpyinfo->mac_id_name
+    = (char *) xmalloc (SCHARS (Vinvocation_name)
+                       + SCHARS (Vsystem_name)
+                       + 2);
+  sprintf (dpyinfo->mac_id_name, "%s@%s",
+          SDATA (Vinvocation_name), SDATA (Vsystem_name));
+#else
+  dpyinfo->mac_id_name = (char *) xmalloc (strlen ("Mac Display") + 1);
+  strcpy (dpyinfo->mac_id_name, "Mac Display");
+#endif
+
+  dpyinfo->reference_count = 0;
+  dpyinfo->resx = 72.0;
+  dpyinfo->resy = 72.0;
+
+  mac_get_screen_info (dpyinfo);
+
+  dpyinfo->grabbed = 0;
+  dpyinfo->root_window = NULL;
+  dpyinfo->image_cache = make_image_cache ();
+
+  dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
+  dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
+  dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID;
+  dpyinfo->mouse_face_window = Qnil;
+  dpyinfo->mouse_face_overlay = Qnil;
+  dpyinfo->mouse_face_hidden = 0;
 
   dpyinfo->xrdb = mac_make_rdb (xrm_option);
 
@@ -11266,6 +12581,7 @@ mac_term_init (display_name, xrm_option, resource_name)
 
   return dpyinfo;
 }
+\f
 /* Get rid of display DPYINFO, assuming all frames are already gone.  */
 
 void
@@ -11332,79 +12648,6 @@ x_delete_display (dpyinfo)
 }
 
 \f
-#ifdef MAC_OSX
-void
-mac_check_bundle()
-{
-  extern int inhibit_window_system;
-  extern int noninteractive;
-  CFBundleRef appsBundle;
-
-  /* No need to test if already -nw*/
-  if (inhibit_window_system || noninteractive)
-    return;
-
-  appsBundle = CFBundleGetMainBundle();
-  if (appsBundle != NULL)
-    {
-      CFStringRef cfBI = CFSTR("CFBundleIdentifier");
-      CFTypeRef res = CFBundleGetValueForInfoDictionaryKey(appsBundle, cfBI);
-      /* We found the bundle identifier, now we know we are valid. */
-      if (res != NULL)
-       {
-         CFRelease(res);
-         return;
-       }
-    }
-  /* MAC_TODO:  Have this start the bundled executable */
-
-  /* For now, prevent the fatal error by bringing it up in the terminal */
-  inhibit_window_system = 1;
-}
-
-void
-MakeMeTheFrontProcess ()
-{
-  ProcessSerialNumber psn;
-  OSErr err;
-
-  err = GetCurrentProcess (&psn);
-  if (err == noErr)
-    (void) SetFrontProcess (&psn);
-}
-
-/***** Code to handle C-g testing  *****/
-
-/* Contains the Mac modifier formed from quit_char */
-int mac_quit_char_modifiers = 0;
-int mac_quit_char_keycode;
-extern int quit_char;
-
-static void
-mac_determine_quit_char_modifiers()
-{
-  /* Todo: Determine modifiers from quit_char. */
-  UInt32 qc_modifiers = ctrl_modifier;
-
-  /* Map modifiers */
-  mac_quit_char_modifiers = 0;
-  if (qc_modifiers & ctrl_modifier)  mac_quit_char_modifiers |= controlKey;
-  if (qc_modifiers & shift_modifier) mac_quit_char_modifiers |= shiftKey;
-  if (qc_modifiers & alt_modifier)   mac_quit_char_modifiers |= optionKey;
-}
-
-static void
-init_quit_char_handler ()
-{
-  /* TODO: Let this support keys other the 'g' */
-  mac_quit_char_keycode = 5;
-  /* Look at <architecture/adb_kb_map.h> for details */
-  /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
-
-  mac_determine_quit_char_modifiers();
-}
-#endif /* MAC_OSX */
-
 static void
 init_menu_bar ()
 {
@@ -11417,7 +12660,6 @@ init_menu_bar ()
                                     &menu, &menu_index);
   if (err == noErr)
     SetMenuItemCommandKey (menu, menu_index, false, 0);
-#if USE_CARBON_EVENTS
   EnableMenuCommand (NULL, kHICommandPreferences);
   err = GetIndMenuItemWithCommandID (NULL, kHICommandPreferences, 1,
                                     &menu, &menu_index);
@@ -11429,10 +12671,9 @@ init_menu_bar ()
       InsertMenuItemTextWithCFString (menu, CFSTR ("About Emacs"),
                                      0, 0, kHICommandAbout);
     }
-#endif /* USE_CARBON_EVENTS */
 #else  /* !MAC_OSX */
-#if USE_CARBON_EVENTS
-  SetMenuItemCommandID (GetMenuHandle (M_APPLE), I_ABOUT, kHICommandAbout);
+#if TARGET_API_MAC_CARBON
+  SetMenuItemCommandID (GetMenuRef (M_APPLE), I_ABOUT, kHICommandAbout);
 #endif
 #endif
 }
@@ -11469,7 +12710,11 @@ static struct redisplay_interface x_redisplay_interface =
   x_update_window_end,
   x_cursor_to,
   x_flush,
+#if USE_CG_DRAWING
+  mac_flush_display_optional,
+#else
   0, /* flush_display_optional */
+#endif
   x_clear_window_mouse_face,
   x_get_glyph_overhangs,
   x_fix_overlapping_area,
@@ -11492,80 +12737,108 @@ static struct redisplay_interface x_redisplay_interface =
   mac_shift_glyphs_for_insert
 };
 
-void
+static struct terminal *
+mac_create_terminal (struct mac_display_info *dpyinfo)
+{
+  struct terminal *terminal;
+  
+  terminal = create_terminal ();
+
+  terminal->type = output_mac;
+  terminal->display_info.mac = dpyinfo;
+  dpyinfo->terminal = terminal;
+
+  terminal->clear_frame_hook = x_clear_frame;
+  terminal->ins_del_lines_hook = x_ins_del_lines;
+  terminal->delete_glyphs_hook = x_delete_glyphs;
+  terminal->ring_bell_hook = XTring_bell;
+  terminal->reset_terminal_modes_hook = XTreset_terminal_modes;
+  terminal->set_terminal_modes_hook = XTset_terminal_modes;
+  terminal->update_begin_hook = x_update_begin;
+  terminal->update_end_hook = x_update_end;
+  terminal->set_terminal_window_hook = XTset_terminal_window;
+  terminal->read_socket_hook = XTread_socket;
+  terminal->frame_up_to_date_hook = XTframe_up_to_date;
+  terminal->mouse_position_hook = XTmouse_position;
+  terminal->frame_rehighlight_hook = XTframe_rehighlight;
+  terminal->frame_raise_lower_hook = XTframe_raise_lower;
+  /* terminal->fullscreen_hook = XTfullscreen_hook; */
+  terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
+  terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars;
+  terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar;
+  terminal->judge_scroll_bars_hook = XTjudge_scroll_bars;
+  terminal->delete_frame_hook = x_destroy_window;
+  /* terminal->delete_terminal_hook = x_delete_terminal; */
+
+  terminal->rif = &x_redisplay_interface;
+#if 0
+  TTY_SCROLL_REGION_OK (CURTTY ()) = 1; /* we'll scroll partial frames */
+  TTY_CHAR_INS_DEL_OK (CURTTY ()) = 1;
+  TTY_LINE_INS_DEL_OK (CURTTY ()) = 1; /* we'll just blt 'em */
+  TTY_FAST_CLEAR_END_OF_LINE (CURTTY ()) = 1; /* X does this well */
+  TTY_MEMORY_BELOW_FRAME (CURTTY ()) = 0; /* we don't remember what
+                                                         scrolls off the
+                                                         bottom */
+#else
+  terminal->scroll_region_ok = 1;    /* We'll scroll partial frames. */
+  terminal->char_ins_del_ok = 1;
+  terminal->line_ins_del_ok = 1;         /* We'll just blt 'em. */
+  terminal->fast_clear_end_of_line = 1;  /* X does this well. */
+  terminal->memory_below_frame = 0;   /* We don't remember what scrolls
+                                        off the bottom. */
+
+#endif
+  return terminal;
+}
+
+static void
 mac_initialize ()
 {
-  rif = &x_redisplay_interface;
-
-  clear_frame_hook = x_clear_frame;
-  ins_del_lines_hook = x_ins_del_lines;
-  delete_glyphs_hook = x_delete_glyphs;
-  ring_bell_hook = XTring_bell;
-  reset_terminal_modes_hook = XTreset_terminal_modes;
-  set_terminal_modes_hook = XTset_terminal_modes;
-  update_begin_hook = x_update_begin;
-  update_end_hook = x_update_end;
-  set_terminal_window_hook = XTset_terminal_window;
-  read_socket_hook = XTread_socket;
-  frame_up_to_date_hook = XTframe_up_to_date;
-  mouse_position_hook = XTmouse_position;
-  frame_rehighlight_hook = XTframe_rehighlight;
-  frame_raise_lower_hook = XTframe_raise_lower;
-
-  set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
-  condemn_scroll_bars_hook = XTcondemn_scroll_bars;
-  redeem_scroll_bar_hook = XTredeem_scroll_bar;
-  judge_scroll_bars_hook = XTjudge_scroll_bars;
-
-  scroll_region_ok = 1;         /* we'll scroll partial frames */
-  char_ins_del_ok = 1;
-  line_ins_del_ok = 1;          /* we'll just blt 'em */
-  fast_clear_end_of_line = 1;   /* X does this well */
-  memory_below_frame = 0;       /* we don't remember what scrolls
-                                  off the bottom */
+
   baud_rate = 19200;
 
   last_tool_bar_item = -1;
   any_help_event_p = 0;
 
   /* Try to use interrupt input; if we can't, then start polling.  */
-  Fset_input_mode (Qt, Qnil, Qt, Qnil);
+  Fset_input_interrupt_mode (Qt);
 
   BLOCK_INPUT;
 
 #if TARGET_API_MAC_CARBON
 
-#if USE_CARBON_EVENTS
-#ifdef MAC_OSX
-  init_service_handler ();
-
-  init_quit_char_handler ();
-#endif /* MAC_OSX */
-
-  init_command_handler ();
+  install_application_handler ();
 
   init_menu_bar ();
 
 #if USE_MAC_TSM
   init_tsm ();
 #endif
-#endif /* USE_CARBON_EVENTS */
 
 #ifdef MAC_OSX
   init_coercion_handler ();
 
   init_apple_event_handler ();
 
+  init_dm_notification_handler ();
+
   if (!inhibit_window_system)
-    MakeMeTheFrontProcess ();
+    {
+      static const ProcessSerialNumber psn = {0, kCurrentProcess};
+
+      SetFrontProcess (&psn);
+    }
 #endif
 #endif
 
 #if USE_CG_DRAWING
+  init_cg_color ();
+
   mac_init_fringe ();
 #endif
 
   UNBLOCK_INPUT;
+
 }
 
 
@@ -11591,7 +12864,7 @@ syms_of_macterm ()
   Fput (Qhyper,   Qmodifier_value, make_number (hyper_modifier));
   Fput (Qsuper,   Qmodifier_value, make_number (super_modifier));
 
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
   Qhi_command   = intern ("hi-command");    staticpro (&Qhi_command);
 #ifdef MAC_OSX
   Qtoolbar_switch_mode = intern ("toolbar-switch-mode");
@@ -11648,7 +12921,7 @@ syms_of_macterm ()
   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
+A value of 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.
 
@@ -11658,9 +12931,9 @@ NOTE: Not supported on Mac yet.  */);
   DEFVAR_BOOL ("x-underline-at-descent-line",
               &x_underline_at_descent_line,
      doc: /* *Non-nil means to draw the underline at the same place as the descent line.
-nil means to draw the underline according to the value of the variable
-`x-use-underline-position-properties', which is usually at the baseline
-level.  The default value is nil.  */);
+A value of nil means to draw the underline according to the value of the
+variable `x-use-underline-position-properties', which is usually at the
+baseline level.  The default value is nil.  */);
   x_underline_at_descent_line = 0;
 
   DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
@@ -11707,8 +12980,8 @@ unexpected results for some keys on non-US/GB keyboards.  */);
               &Vmac_emulate_three_button_mouse,
     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.
+A value of nil means that no emulation should be done and the modifiers
+should be placed on the mouse-1 event.
 t means that when the option-key is held down while pressing the mouse
 button, the click will register as mouse-2 and while the command-key
 is held down, the click will register as mouse-3.
@@ -11716,7 +12989,7 @@ The symbol `reverse' means that the option-key will register for
 mouse-3 and the command-key will register for mouse-2.  */);
   Vmac_emulate_three_button_mouse = Qnil;
 
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
   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
@@ -11759,15 +13032,6 @@ CODING_SYSTEM is a coding system corresponding to TEXT-ENCODING.  */);
     Fcons (list3 (build_string ("mac-roman"),
                  make_number (smRoman), Qnil), Qnil);
 
-#if USE_ATSUI
-  DEFVAR_LISP ("mac-atsu-font-table", &Vmac_atsu_font_table,
-    doc: /* Hash table of ATSU font IDs vs plist of attributes and values.  */);
-  Vmac_atsu_font_table =
-    make_hash_table (Qeql, make_number (DEFAULT_HASH_SIZE),
-                    make_float (DEFAULT_REHASH_SIZE),
-                    make_float (DEFAULT_REHASH_THRESHOLD),
-                    Qnil, Qnil, Qnil);
-#endif
 #if USE_MAC_TSM
   DEFVAR_LISP ("mac-ts-active-input-overlay", &Vmac_ts_active_input_overlay,
     doc: /* Overlay used to display Mac TSM active input area.  */);