]> code.delx.au - gnu-emacs/blobdiff - src/macterm.c
*** empty log message ***
[gnu-emacs] / src / macterm.c
index f087c78870e8e3ee8cf387a522383ba5d62a2e4e..dda0cc8311faacdf7d3d0843380d528e4fb38e52 100644 (file)
@@ -1,5 +1,5 @@
 /* Implementation of GUI terminal on the Mac OS.
-   Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -35,29 +35,6 @@ Boston, MA 02111-1307, USA.  */
 #endif
 
 #ifdef MAC_OSX
-#undef mktime
-#undef DEBUG
-#undef free
-#undef malloc
-#undef realloc
-/* Macros max and min defined in lisp.h conflict with those in
-   precompiled header Carbon.h.  */
-#undef max
-#undef min
-#undef init_process
-#include <Carbon/Carbon.h>
-#undef free
-#define free unexec_free
-#undef malloc
-#define malloc unexec_malloc
-#undef realloc
-#define realloc unexec_realloc
-#undef min
-#define min(a, b) ((a) < (b) ? (a) : (b))
-#undef max
-#define max(a, b) ((a) > (b) ? (a) : (b))
-#undef init_process
-#define init_process emacs_init_process
 /* 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.  */
@@ -73,10 +50,10 @@ Boston, MA 02111-1307, USA.  */
 #include <TextUtils.h>
 #include <LowMem.h>
 #include <Controls.h>
+#include <Windows.h>
 #if defined (__MRC__) || (__MSL__ >= 0x6000)
 #include <ControlDefinitions.h>
 #endif
-#include <Gestalt.h>
 
 #if __profile__
 #include <profiler.h>
@@ -219,14 +196,6 @@ static Lisp_Object last_mouse_scroll_bar;
 
 static Time last_mouse_movement_time;
 
-enum mouse_tracking_type {
-  mouse_tracking_none,
-  mouse_tracking_mouse_movement,
-  mouse_tracking_scroll_bar
-};
-
-enum mouse_tracking_type mouse_tracking_in_progress = mouse_tracking_none;
-
 struct scroll_bar *tracked_scroll_bar = NULL;
 
 /* Incremented by XTread_socket whenever it really tries to read
@@ -253,14 +222,16 @@ extern Lisp_Object Vcommand_line_args, Vsystem_name;
 
 extern Lisp_Object Vx_no_window_manager;
 
-extern Lisp_Object Qface, Qmouse_face;
-
 extern int errno;
 
 /* A mask of extra modifier bits to put into every keyboard char.  */
 
 extern int extra_keyboard_modifiers;
 
+/* The keysyms to use for the various modifiers.  */
+
+static Lisp_Object Qalt, Qhyper, Qsuper, Qmodifier_value;
+
 static Lisp_Object Qvendor_specific_keysyms;
 
 #if 0
@@ -305,8 +276,10 @@ static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
 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 *));
-static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int));
-static void x_clip_to_row P_ ((struct window *, struct glyph_row *, GC));
+static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int,
+                                  enum text_cursor_kinds));
+
+static void x_clip_to_row P_ ((struct window *, struct glyph_row *, int, GC));
 static void x_flush P_ ((struct frame *f));
 static void x_update_begin P_ ((struct frame *));
 static void x_update_window_begin P_ ((struct window *));
@@ -317,7 +290,6 @@ void deactivate_scroll_bars (FRAME_PTR);
 
 static int is_emacs_window (WindowPtr);
 
-extern int image_ascent (struct image *, struct face *);
 int x_bitmap_icon (struct frame *, Lisp_Object);
 void x_make_frame_visible (struct frame *);
 
@@ -329,15 +301,12 @@ extern void set_frame_menubar (FRAME_PTR, int, int);
 
 /* X display function emulation */
 
-static void
+void
 XFreePixmap (display, pixmap)
-     Display *display;
+     Display *display;         /* not used */
      Pixmap pixmap;
 {
-  PixMap *p = (PixMap *) pixmap;
-
-  xfree (p->baseAddr);
-  xfree (p);
+  DisposeGWorld (pixmap);
 }
 
 
@@ -349,9 +318,9 @@ mac_set_forecolor (unsigned long color)
 {
   RGBColor fg_color;
 
-  fg_color.red = RED_FROM_ULONG (color) * 256;
-  fg_color.green = GREEN_FROM_ULONG (color) * 256;
-  fg_color.blue = BLUE_FROM_ULONG (color) * 256;
+  fg_color.red = RED16_FROM_ULONG (color);
+  fg_color.green = GREEN16_FROM_ULONG (color);
+  fg_color.blue = BLUE16_FROM_ULONG (color);
 
   RGBForeColor (&fg_color);
 }
@@ -365,9 +334,9 @@ mac_set_backcolor (unsigned long color)
 {
   RGBColor bg_color;
 
-  bg_color.red = RED_FROM_ULONG (color) * 256;
-  bg_color.green = GREEN_FROM_ULONG (color) * 256;
-  bg_color.blue = BLUE_FROM_ULONG (color) * 256;
+  bg_color.red = RED16_FROM_ULONG (color);
+  bg_color.green = GREEN16_FROM_ULONG (color);
+  bg_color.blue = BLUE16_FROM_ULONG (color);
 
   RGBBackColor (&bg_color);
 }
@@ -391,11 +360,7 @@ XDrawLine (display, w, gc, x1, y1, x2, y2)
      GC gc;
      int x1, y1, x2, y2;
 {
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  SetPortWindowPort (w);
 
   mac_set_colors (gc);
 
@@ -403,6 +368,29 @@ XDrawLine (display, w, gc, x1, y1, x2, y2)
   LineTo (x2, y2);
 }
 
+void
+mac_draw_line_to_pixmap (display, p, gc, x1, y1, x2, y2)
+     Display *display;
+     Pixmap p;
+     GC gc;
+     int x1, y1, x2, y2;
+{
+  CGrafPtr old_port;
+  GDHandle old_gdh;
+
+  GetGWorld (&old_port, &old_gdh);
+  SetGWorld (p, NULL);
+
+  mac_set_colors (gc);
+
+  LockPixels (GetGWorldPixMap (p));
+  MoveTo (x1, y1);
+  LineTo (x2, y2);
+  UnlockPixels (GetGWorldPixMap (p));
+
+  SetGWorld (old_port, old_gdh);
+}
+
 /* Mac version of XClearArea.  */
 
 void
@@ -420,11 +408,7 @@ XClearArea (display, w, x, y, width, height, exposures)
   xgc.foreground = mwp->x_compatible.foreground_pixel;
   xgc.background = mwp->x_compatible.background_pixel;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  SetPortWindowPort (w);
 
   mac_set_colors (&xgc);
   SetRect (&r, x, y, x + width, y + height);
@@ -445,11 +429,7 @@ XClearWindow (display, w)
   xgc.foreground = mwp->x_compatible.foreground_pixel;
   xgc.background = mwp->x_compatible.background_pixel;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  SetPortWindowPort (w);
 
   mac_set_colors (&xgc);
 
@@ -469,35 +449,34 @@ XClearWindow (display, w)
 /* Mac replacement for XCopyArea.  */
 
 static void
-mac_draw_bitmap (display, w, gc, x, y, bitmap)
+mac_draw_bitmap (display, w, gc, x, y, width, height, bits, overlay_p)
      Display *display;
      WindowPtr w;
      GC gc;
-     int x, y;
-     BitMap *bitmap;
+     int x, y, width, height;
+     unsigned short *bits;
+     int overlay_p;
 {
+  BitMap bitmap;
   Rect r;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  bitmap.rowBytes = sizeof(unsigned short);
+  bitmap.baseAddr = (char *)bits;
+  SetRect (&(bitmap.bounds), 0, 0, width, height);
+
+  SetPortWindowPort (w);
 
   mac_set_colors (gc);
-  SetRect (&r, x, y, x + bitmap->bounds.right, y + bitmap->bounds.bottom);
+  SetRect (&r, x, y, x + width, y + height);
 
 #if TARGET_API_MAC_CARBON
-  {
-    PixMapHandle pmh;
-
-    LockPortBits (GetWindowPort (w));
-    pmh = GetPortPixMap (GetWindowPort (w));
-    CopyBits (bitmap, (BitMap *) *pmh, &(bitmap->bounds), &r, srcCopy, 0);
-    UnlockPortBits (GetWindowPort (w));
-  }
+  LockPortBits (GetWindowPort (w));
+  CopyBits (&bitmap, GetPortBitMapForCopyBits (GetWindowPort (w)),
+           &(bitmap.bounds), &r, overlay_p ? srcOr : srcCopy, 0);
+  UnlockPortBits (GetWindowPort (w));
 #else /* not TARGET_API_MAC_CARBON */
-  CopyBits (bitmap, &(w->portBits), &(bitmap->bounds), &r, srcCopy, 0);
+  CopyBits (&bitmap, &(w->portBits), &(bitmap.bounds), &r,
+           overlay_p ? srcOr : srcCopy, 0);
 #endif /* not TARGET_API_MAC_CARBON */
 }
 
@@ -510,11 +489,7 @@ mac_set_clip_rectangle (display, w, r)
      WindowPtr w;
      Rect *r;
 {
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  SetPortWindowPort (w);
 
   ClipRect (r);
 }
@@ -529,11 +504,7 @@ mac_reset_clipping (display, w)
 {
   Rect r;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  SetPortWindowPort (w);
 
   SetRect (&r, -32767, -32767, 32767, 32767);
   ClipRect (&r);
@@ -548,18 +519,29 @@ mac_create_bitmap_from_bitmap_data (bitmap, bits, w, h)
      char *bits;
      int w, h;
 {
-  int bytes_per_row, i, j;
+  static 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 */
+       0x3, 0xb, 0x7, 0xf };  /* 0011 1011 0111 1111 */
+  int i, j, w1;
+  char *p;
 
-  bitmap->rowBytes = (w + 15) / 16 * 2;  /* must be on word boundary */
+  w1 = (w + 7) / 8;         /* nb of 8bits elt in X bitmap */
+  bitmap->rowBytes = ((w + 15) / 16) * 2; /* nb of 16bits elt in Mac bitmap */
   bitmap->baseAddr = xmalloc (bitmap->rowBytes * h);
-  if (!bitmap->baseAddr)
-    abort ();
-
   bzero (bitmap->baseAddr, bitmap->rowBytes * h);
   for (i = 0; i < h; i++)
-    for (j = 0; j < w; j++)
-      if (BitTst (bits, i * w + j))
-        BitSet (bitmap->baseAddr, i * bitmap->rowBytes * 8 + j);
+    {
+      p = bitmap->baseAddr + i * bitmap->rowBytes;
+      for (j = 0; j < w1; j++)
+       {
+         /* 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]));;
+       }
+    }
 
   SetRect (&(bitmap->bounds), 0, 0, w, h);
 }
@@ -572,6 +554,67 @@ mac_free_bitmap (bitmap)
   xfree (bitmap->baseAddr);
 }
 
+
+Pixmap
+XCreatePixmap (display, w, width, height, depth)
+     Display *display;         /* not used */
+     WindowPtr w;
+     unsigned int width, height;
+     unsigned int depth;
+{
+  Pixmap pixmap;
+  Rect r;
+  QDErr err;
+
+  SetPortWindowPort (w);
+
+  SetRect (&r, 0, 0, width, height);
+  err = NewGWorld (&pixmap, depth, &r, NULL, NULL, 0);
+  if (err != noErr)
+    return NULL;
+  return pixmap;
+}
+
+
+Pixmap
+XCreatePixmapFromBitmapData (display, w, data, width, height, fg, bg, depth)
+     Display *display;         /* not used */
+     WindowPtr w;
+     char *data;
+     unsigned int width, height;
+     unsigned long fg, bg;
+     unsigned int depth;       /* not used */
+{
+  Pixmap pixmap;
+  BitMap bitmap;
+  CGrafPtr old_port;
+  GDHandle old_gdh;
+
+  pixmap = XCreatePixmap (display, w, width, height, depth);
+  if (pixmap == NULL)
+    return NULL;
+
+  GetGWorld (&old_port, &old_gdh);
+  SetGWorld (pixmap, NULL);
+  mac_create_bitmap_from_bitmap_data (&bitmap, data, width, height);
+  mac_set_forecolor (fg);
+  mac_set_backcolor (bg);
+  LockPixels (GetGWorldPixMap (pixmap));
+#if TARGET_API_MAC_CARBON
+  CopyBits (&bitmap, GetPortBitMapForCopyBits (pixmap),
+           &bitmap.bounds, &bitmap.bounds, srcCopy, 0);
+#else /* not TARGET_API_MAC_CARBON */
+  CopyBits (&bitmap, &(((GrafPtr)pixmap)->portBits),
+           &bitmap.bounds, &bitmap.bounds, srcCopy, 0);
+#endif /* not TARGET_API_MAC_CARBON */
+  UnlockPixels (GetGWorldPixMap (pixmap));
+  SetGWorld (old_port, old_gdh);
+  mac_free_bitmap (&bitmap);
+
+  return pixmap;
+}
+
+
 /* Mac replacement for XFillRectangle.  */
 
 static void
@@ -584,11 +627,7 @@ XFillRectangle (display, w, gc, x, y, width, height)
 {
   Rect r;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  SetPortWindowPort (w);
 
   mac_set_colors (gc);
   SetRect (&r, x, y, x + width, y + height);
@@ -597,6 +636,33 @@ XFillRectangle (display, w, gc, x, y, width, height)
 }
 
 
+#if 0 /* TODO: figure out if we need to do this on Mac.  */
+static void
+mac_fill_rectangle_to_pixmap (display, p, gc, x, y, width, height)
+     Display *display;
+     Pixmap p;
+     GC gc;
+     int x, y;
+     unsigned int width, height;
+{
+  CGrafPtr old_port;
+  GDHandle old_gdh;
+  Rect r;
+
+  GetGWorld (&old_port, &old_gdh);
+  SetGWorld (p, NULL);
+  mac_set_colors (gc);
+  SetRect (&r, x, y, x + width, y + height);
+
+  LockPixels (GetGWorldPixMap (p));
+  PaintRect (&r); /* using foreground color of gc */
+  UnlockPixels (GetGWorldPixMap (p));
+
+  SetGWorld (old_port, old_gdh);
+}
+#endif
+
+
 /* Mac replacement for XDrawRectangle: dest is a window.  */
 
 static void
@@ -609,11 +675,7 @@ mac_draw_rectangle (display, w, gc, x, y, width, height)
 {
   Rect r;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  SetPortWindowPort (w);
 
   mac_set_colors (gc);
   SetRect (&r, x, y, x + width + 1, y + height + 1);
@@ -622,6 +684,7 @@ mac_draw_rectangle (display, w, gc, x, y, width, height)
 }
 
 
+#if 0 /* TODO: figure out if we need to do this on Mac.  */
 /* Mac replacement for XDrawRectangle: dest is a Pixmap.  */
 
 static void
@@ -632,21 +695,22 @@ mac_draw_rectangle_to_pixmap (display, p, gc, x, y, width, height)
      int x, y;
      unsigned int width, height;
 {
-#if 0 /* MAC_TODO: draw a rectangle in a PixMap */
+  CGrafPtr old_port;
+  GDHandle old_gdh;
   Rect r;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
-
+  GetGWorld (&old_port, &old_gdh);
+  SetGWorld (p, NULL);
   mac_set_colors (gc);
-  SetRect (&r, x, y, x + width, y + height);
+  SetRect (&r, x, y, x + width + 1, y + height + 1);
 
+  LockPixels (GetGWorldPixMap (p));
   FrameRect (&r); /* using foreground color of gc */
-#endif /* 0 */
+  UnlockPixels (GetGWorldPixMap (p));
+
+  SetGWorld (old_port, old_gdh);
 }
+#endif
 
 
 static void
@@ -659,11 +723,7 @@ mac_draw_string_common (display, w, gc, x, y, buf, nchars, mode,
      char *buf;
      int nchars, mode, bytes_per_char;
 {
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  SetPortWindowPort (w);
 
   mac_set_colors (gc);
 
@@ -754,29 +814,64 @@ mac_copy_area (display, src, dest, gc, src_x, src_y, width, height, dest_x,
 {
   Rect src_r, dest_r;
 
+  SetPortWindowPort (dest);
+
+  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);
+
+  ForeColor (blackColor);
+  BackColor (whiteColor);
+
+  LockPixels (GetGWorldPixMap (src));
 #if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (dest));
-#else
-  SetPort (dest);
-#endif
+  LockPortBits (GetWindowPort (dest));
+  CopyBits (GetPortBitMapForCopyBits (src),
+           GetPortBitMapForCopyBits (GetWindowPort (dest)),
+           &src_r, &dest_r, srcCopy, 0);
+  UnlockPortBits (GetWindowPort (dest));
+#else /* not TARGET_API_MAC_CARBON */
+  CopyBits (&(((GrafPtr)src)->portBits), &(dest->portBits),
+           &src_r, &dest_r, srcCopy, 0);
+#endif /* not TARGET_API_MAC_CARBON */
+  UnlockPixels (GetGWorldPixMap (src));
+}
 
-  mac_set_colors (gc);
+
+static void
+mac_copy_area_with_mask (display, src, mask, dest, gc, src_x, src_y,
+                        width, height, dest_x, dest_y)
+     Display *display;
+     Pixmap src, mask;
+     WindowPtr dest;
+     GC gc;
+     int src_x, src_y;
+     unsigned int width, height;
+     int dest_x, dest_y;
+{
+  Rect src_r, dest_r;
+
+  SetPortWindowPort (dest);
 
   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);
 
-#if TARGET_API_MAC_CARBON
-  {
-    PixMapHandle pmh;
+  ForeColor (blackColor);
+  BackColor (whiteColor);
 
-    LockPortBits (GetWindowPort (dest));
-    pmh = GetPortPixMap (GetWindowPort (dest));
-    CopyBits ((BitMap *) &src, (BitMap *) *pmh, &src_r, &dest_r, srcCopy, 0);
-    UnlockPortBits (GetWindowPort (dest));
-  }
+  LockPixels (GetGWorldPixMap (src));
+  LockPixels (GetGWorldPixMap (mask));
+#if TARGET_API_MAC_CARBON
+  LockPortBits (GetWindowPort (dest));
+  CopyMask (GetPortBitMapForCopyBits (src), GetPortBitMapForCopyBits (mask),
+           GetPortBitMapForCopyBits (GetWindowPort (dest)),
+           &src_r, &src_r, &dest_r);
+  UnlockPortBits (GetWindowPort (dest));
 #else /* not TARGET_API_MAC_CARBON */
-  CopyBits ((BitMap *) &src, &(dest->portBits), &src_r, &dest_r, srcCopy, 0);
+  CopyMask (&(((GrafPtr)src)->portBits), &(((GrafPtr)mask)->portBits),
+           &(dest->portBits), &src_r, &src_r, &dest_r);
 #endif /* not TARGET_API_MAC_CARBON */
+  UnlockPixels (GetGWorldPixMap (mask));
+  UnlockPixels (GetGWorldPixMap (src));
 }
 
 
@@ -810,23 +905,13 @@ mac_scroll_area (display, w, gc, src_x, src_y, width, height, dest_x, dest_y)
      int dest_x, dest_y;
 {
 #if TARGET_API_MAC_CARBON
-  Rect gw_r, src_r, dest_r;
-  PixMapHandle pmh;
+  Rect src_r;
+  RgnHandle dummy = NewRgn (); /* For avoiding update events.  */
 
   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);
-
-  SetPort (GetWindowPort (w));
-
-  ForeColor (blackColor);
-  BackColor (whiteColor);
-
-  LockPortBits (GetWindowPort (w));
-  pmh = GetPortPixMap (GetWindowPort (w));
-  CopyBits ((BitMap *) *pmh, (BitMap *) *pmh, &src_r, &dest_r, srcCopy, 0);
-  UnlockPortBits (GetWindowPort (w));
-
-  mac_set_colors (gc);
+  ScrollWindowRect (w, &src_r, dest_x - src_x, dest_y - src_y,
+                   kScrollWindowNoOptions, dummy);
+  DisposeRgn (dummy);
 #else /* not TARGET_API_MAC_CARBON */
   Rect src_r, dest_r;
 
@@ -860,32 +945,86 @@ mac_scroll_area (display, w, gc, src_x, src_y, width, height, dest_x, dest_y)
 }
 
 
+#if 0 /* TODO: figure out if we need to do this on Mac.  */
 /* Mac replacement for XCopyArea: dest must be Pixmap.  */
 
 static void
 mac_copy_area_to_pixmap (display, src, dest, gc, src_x, src_y, width, height,
                      dest_x, dest_y)
      Display *display;
-     Pixmap src;
-     Pixmap dest;
+     Pixmap src, dest;
      GC gc;
      int src_x, src_y;
      unsigned int width, height;
      int dest_x, dest_y;
 {
+  CGrafPtr old_port;
+  GDHandle old_gdh;
   Rect src_r, dest_r;
-  int src_right = ((PixMap *) src)->bounds.right;
-  int src_bottom = ((PixMap *) src)->bounds.bottom;
-  int w = src_right - src_x;
-  int h = src_bottom - src_y;
 
-  mac_set_colors (gc);
+  GetGWorld (&old_port, &old_gdh);
+  SetGWorld (dest, NULL);
+  ForeColor (blackColor);
+  BackColor (whiteColor);
+
+  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);
+
+  LockPixels (GetGWorldPixMap (src));
+  LockPixels (GetGWorldPixMap (dest));
+#if TARGET_API_MAC_CARBON
+  CopyBits (GetPortBitMapForCopyBits (src), GetPortBitMapForCopyBits (dest),
+           &src_r, &dest_r, srcCopy, 0);
+#else /* not TARGET_API_MAC_CARBON */
+  CopyBits (&(((GrafPtr)src)->portBits), &(((GrafPtr)dest)->portBits),
+           &src_r, &dest_r, srcCopy, 0);
+#endif /* not TARGET_API_MAC_CARBON */
+  UnlockPixels (GetGWorldPixMap (dest));
+  UnlockPixels (GetGWorldPixMap (src));
+
+  SetGWorld (old_port, old_gdh);
+}
+
+
+static void
+mac_copy_area_with_mask_to_pixmap (display, src, mask, dest, gc, src_x, src_y,
+                                  width, height, dest_x, dest_y)
+     Display *display;
+     Pixmap src, mask, dest;
+     GC gc;
+     int src_x, src_y;
+     unsigned int width, height;
+     int dest_x, dest_y;
+{
+  CGrafPtr old_port;
+  GDHandle old_gdh;
+  Rect src_r, dest_r;
+
+  GetGWorld (&old_port, &old_gdh);
+  SetGWorld (dest, NULL);
+  ForeColor (blackColor);
+  BackColor (whiteColor);
+
+  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);
 
-  SetRect (&src_r, src_x, src_y, src_right, src_bottom);
-  SetRect (&dest_r, dest_x, dest_y, dest_x + w, dest_y + h);
+  LockPixels (GetGWorldPixMap (src));
+  LockPixels (GetGWorldPixMap (mask));
+  LockPixels (GetGWorldPixMap (dest));
+#if TARGET_API_MAC_CARBON
+  CopyMask (GetPortBitMapForCopyBits (src), GetPortBitMapForCopyBits (mask),
+           GetPortBitMapForCopyBits (dest), &src_r, &src_r, &dest_r);
+#else /* not TARGET_API_MAC_CARBON */
+  CopyMask (&(((GrafPtr)src)->portBits), &(((GrafPtr)mask)->portBits),
+           &(((GrafPtr)dest)->portBits), &src_r, &src_r, &dest_r);
+#endif /* not TARGET_API_MAC_CARBON */
+  UnlockPixels (GetGWorldPixMap (dest));
+  UnlockPixels (GetGWorldPixMap (mask));
+  UnlockPixels (GetGWorldPixMap (src));
 
-  CopyBits ((BitMap *) &src, (BitMap *) &dest, &src_r, &dest_r, srcCopy, 0);
+  SetGWorld (old_port, old_gdh);
 }
+#endif
 
 
 /* Mac replacement for XChangeGC.  */
@@ -941,7 +1080,7 @@ XGetGCValues (void* ignore, XGCValues *gc,
 
 /* Mac replacement for XSetForeground.  */
 
-static void
+void
 XSetForeground (display, gc, color)
      Display *display;
      GC gc;
@@ -980,40 +1119,32 @@ x_sync (f)
 }
 
 
-/* Remove calls to XFlush by defining XFlush to an empty replacement.
-   Calls to XFlush should be unnecessary because the X output buffer
-   is flushed automatically as needed by calls to XPending,
-   XNextEvent, or XWindowEvent according to the XFlush man page.
-   XTread_socket calls XPending.  Removing XFlush improves
-   performance.  */
-
-#if TARGET_API_MAC_CARBON
-#define XFlush(DISPLAY) QDFlushPortBuffer (GetQDGlobalsThePort (), NULL)
-#else
-#define XFlush(DISPLAY)        (void) 0
-#endif
-
 /* Flush display of frame F, or of all frames if F is null.  */
 
-void
+static void
 x_flush (f)
      struct frame *f;
 {
 #if TARGET_API_MAC_CARBON
   BLOCK_INPUT;
-  if (f == NULL)
-    {
-      Lisp_Object rest, frame;
-      FOR_EACH_FRAME (rest, frame)
-       x_flush (XFRAME (frame));
-    }
-  else if (FRAME_X_P (f))
-    XFlush (FRAME_MAC_DISPLAY (f));
+  if (f)
+    QDFlushPortBuffer (GetWindowPort (FRAME_MAC_WINDOW (f)), NULL);
+  else
+    QDFlushPortBuffer (GetQDGlobalsThePort (), NULL);
   UNBLOCK_INPUT;
-#endif /* TARGET_API_MAC_CARBON */
+#endif
 }
 
 
+/* Remove calls to XFlush by defining XFlush to an empty replacement.
+   Calls to XFlush should be unnecessary because the X output buffer
+   is flushed automatically as needed by calls to XPending,
+   XNextEvent, or XWindowEvent according to the XFlush man page.
+   XTread_socket calls XPending.  Removing XFlush improves
+   performance.  */
+
+#define XFlush(DISPLAY)        (void) 0
+
 \f
 /* Return the struct mac_display_info corresponding to DPY.  There's
    only one.  */
@@ -1040,7 +1171,17 @@ static void
 x_update_begin (f)
      struct frame *f;
 {
-  /* Nothing to do.  */
+#if TARGET_API_MAC_CARBON
+  /* During update of a frame, availability of input events is
+     periodically checked with ReceiveNextEvent if
+     redisplay-dont-pause is nil.  That normally flushes window buffer
+     changes for every check, and thus screen update looks waving even
+     if no input is available.  So we disable screen updates during
+     update of a frame.  */
+  BLOCK_INPUT;
+  DisableScreenUpdates ();
+  UNBLOCK_INPUT;
+#endif
 }
 
 
@@ -1087,7 +1228,7 @@ x_update_window_begin (w)
        {
          int i;
 
-          for (i = 0; i < w->desired_matrix->nrows; ++i)
+         for (i = 0; i < w->desired_matrix->nrows; ++i)
            if (MATRIX_ROW_ENABLED_P (w->desired_matrix, i))
              break;
 
@@ -1109,7 +1250,7 @@ mac_draw_vertical_window_border (w, x, y0, y1)
      int x, y0, y1;
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
-  
+
   XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
             f->output_data.mac->normal_gc, x, y0, x, y1);
 }
@@ -1125,7 +1266,7 @@ mac_draw_vertical_window_border (w, x, y0, y1)
    make sure that the mouse-highlight is properly redrawn.
 
    W may be a menu bar pseudo-window in case we don't have X toolkit
-   support. Such windows don't have a cursor, so don't display it
+   support.  Such windows don't have a cursor, so don't display it
    here. */
 
 static void
@@ -1144,7 +1285,9 @@ x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
                                output_cursor.vpos,
                                output_cursor.x, output_cursor.y);
 
-      x_draw_vertical_border (w);
+      if (draw_window_fringes (w, 1))
+       x_draw_vertical_border (w);
+
       UNBLOCK_INPUT;
     }
 
@@ -1176,21 +1319,20 @@ static void
 x_update_end (f)
      struct frame *f;
 {
+  /* Mouse highlight may be displayed again.  */
+  FRAME_MAC_DISPLAY_INFO (f)->mouse_face_defer = 0;
+
+  BLOCK_INPUT;
   /* Reset the background color of Mac OS Window to that of the frame after
      update so that it is used by Mac Toolbox to clear the update region before
      an update event is generated.  */
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (FRAME_MAC_WINDOW (f)));
-#else
-  SetPort (FRAME_MAC_WINDOW (f));
-#endif
+  SetPortWindowPort (FRAME_MAC_WINDOW (f));
 
   mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f));
 
-  /* Mouse highlight may be displayed again.  */
-  FRAME_MAC_DISPLAY_INFO (f)->mouse_face_defer = 0;
-
-  BLOCK_INPUT;
+#if TARGET_API_MAC_CARBON
+  EnableScreenUpdates ();
+#endif
   XFlush (FRAME_MAC_DISPLAY (f));
   UNBLOCK_INPUT;
 }
@@ -1204,7 +1346,7 @@ static void
 XTframe_up_to_date (f)
      struct frame *f;
 {
-  if (FRAME_X_P (f))
+  if (FRAME_MAC_P (f))
     {
       struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
 
@@ -1241,11 +1383,7 @@ x_after_update_window_line (desired_row)
   xassert (w);
 
   if (!desired_row->mode_line_p && !w->pseudo_window_p)
-    {
-      BLOCK_INPUT;
-      draw_row_fringe_bitmaps (w, desired_row);
-      UNBLOCK_INPUT;
-    }
+    desired_row->redraw_fringe_bitmaps_p = 1;
 
   /* When a window has disappeared, make sure that no rest of
      full-width rows stays visible in the internal border.  Could
@@ -1297,11 +1435,26 @@ x_draw_fringe_bitmap (w, row, p)
   XGCValues gcv;
   GC gc = f->output_data.mac->normal_gc;
   struct face *face = p->face;
+  int rowY;
 
   /* Must clip because of partially visible lines.  */
-  x_clip_to_row (w, row, gc);
+  rowY = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
+  if (p->y < rowY)
+    {
+      /* Adjust position of "bottom aligned" bitmap on partially
+        visible last row.  */
+      int oldY = row->y;
+      int oldVH = row->visible_height;
+      row->visible_height = p->h;
+      row->y -= rowY - p->y;
+      x_clip_to_row (w, row, -1, gc);
+      row->y = oldY;
+      row->visible_height = oldVH;
+    }
+  else
+    x_clip_to_row (w, row, -1, gc);
 
-  if (p->bx >= 0)
+  if (p->bx >= 0 && !p->overlay_p)
     {
       XGCValues gcv;
       gcv.foreground = face->background;
@@ -1327,18 +1480,18 @@ x_draw_fringe_bitmap (w, row, p)
 #endif
     }
 
-  if (p->which != NO_FRINGE_BITMAP)
+  if (p->which)
     {
-      unsigned char *bits = fringe_bitmaps[p->which].bits + p->dh;
-      BitMap bitmap;
+      unsigned short *bits = p->bits + p->dh;
 
-      mac_create_bitmap_from_bitmap_data (&bitmap, bits, p->wd, p->h);
-      gcv.foreground = face->foreground;
+      gcv.foreground = (p->cursor_p
+                       ? (p->overlay_p ? face->background
+                          : f->output_data.mac->cursor_pixel)
+                       : face->foreground);
       gcv.background = face->background;
 
-      mac_draw_bitmap (display, window, &gcv, p->x, p->y, &bitmap);
-
-      mac_free_bitmap (&bitmap);
+      mac_draw_bitmap (display, window, &gcv, p->x, p->y,
+                      p->wd, p->h, bits, p->overlay_p);
     }
 
   mac_reset_clipping (display, window);
@@ -1571,7 +1724,8 @@ static void x_draw_image_foreground_1 P_ ((struct glyph_string *, Pixmap));
 static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int,
                                           int, int, int));
 static void x_draw_relief_rect P_ ((struct frame *, int, int, int, int,
-                                   int, int, int, int, Rect *));
+                                   int, int, int, int, int, int,
+                                   Rect *));
 static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
                                 int, int, int, Rect *));
 
@@ -1796,6 +1950,14 @@ x_clear_glyph_string_rect (s, x, y, w, h)
 }
 
 
+/* We prefer not to use XDrawImageString (srcCopy text transfer mode)
+   on Mac OS X because:
+   - Screen is double-buffered.  (In srcCopy mode, a text is drawn
+     into an offscreen graphics world first.  So performance gain
+     cannot be expected.)
+   - It lowers rendering quality.
+   - Some fonts leave garbage on cursor movement.  */
+
 /* Draw the background of glyph_string S.  If S->background_filled_p
    is non-zero don't draw it.  FORCE_P non-zero means draw the
    background even if it wouldn't be drawn normally.  This is used
@@ -1827,10 +1989,12 @@ x_draw_glyph_string_background (s, force_p)
        }
       else
 #endif
+#ifdef MAC_OS8
         if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
               || s->font_not_found_p
               || s->extends_to_end_of_line_p
               || force_p)
+#endif
        {
          x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
                                     s->background_width,
@@ -1883,6 +2047,7 @@ x_draw_glyph_string_foreground (s)
        for (i = 0; i < s->nchars; ++i)
          char1b[i] = s->char2b[i].byte2;
 
+#ifdef MAC_OS8
       /* Draw text with XDrawString if background has already been
         filled.  Otherwise, use XDrawImageString.  (Note that
         XDrawImageString is usually faster than XDrawString.)  Always
@@ -1890,6 +2055,7 @@ x_draw_glyph_string_foreground (s)
         no chance that characters under a box cursor are invisible.  */
       if (s->for_overlaps_p
          || (s->background_filled_p && s->hl != DRAW_CURSOR))
+#endif
        {
          /* Draw characters with 16-bit or 8-bit functions.  */
          if (s->two_byte_p)
@@ -1899,6 +2065,7 @@ x_draw_glyph_string_foreground (s)
            XDrawString (s->display, s->window, s->gc, x,
                         s->ybase - boff, char1b, s->nchars);
        }
+#ifdef MAC_OS8
       else
        {
          if (s->two_byte_p)
@@ -1908,6 +2075,7 @@ x_draw_glyph_string_foreground (s)
            XDrawImageString (s->display, s->window, s->gc, x,
                              s->ybase - boff, char1b, s->nchars);
        }
+#endif
     }
 }
 
@@ -2119,6 +2287,21 @@ x_copy_dpy_color (dpy, cmap, pixel)
 
 #endif /* MAC_TODO */
 
+
+/* Brightness beyond which a color won't have its highlight brightness
+   boosted.
+
+   Nominally, highlight colors for `3d' faces are calculated by
+   brightening an object's color by a constant scale factor, but this
+   doesn't yield good results for dark colors, so for colors who's
+   brightness is less than this value (on a scale of 0-255) have to
+   use an additional additive factor.
+
+   The value here is set so that the default menu-bar/mode-line color
+   (grey75) will not have its highlights changed at all.  */
+#define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
+
+
 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
    or DELTA.  Try a color with RGB values multiplied by FACTOR first.
    If this produces the same color as COLOR, try a color where all RGB
@@ -2134,12 +2317,42 @@ mac_alloc_lighter_color (f, color, factor, delta)
      int delta;
 {
   unsigned long new;
+  long bright;
+
+  /* On Mac, RGB values are 0-255, not 0-65535, so scale delta. */
+  delta /= 256;
 
   /* Change RGB values by specified FACTOR.  Avoid overflow!  */
   xassert (factor >= 0);
   new = RGB_TO_ULONG (min (0xff, (int) (factor * RED_FROM_ULONG (*color))),
                     min (0xff, (int) (factor * GREEN_FROM_ULONG (*color))),
                     min (0xff, (int) (factor * BLUE_FROM_ULONG (*color))));
+
+  /* Calculate brightness of COLOR.  */
+  bright = (2 * RED_FROM_ULONG (*color) + 3 * GREEN_FROM_ULONG (*color)
+            + BLUE_FROM_ULONG (*color)) / 6;
+
+  /* We only boost colors that are darker than
+     HIGHLIGHT_COLOR_DARK_BOOST_LIMIT.  */
+  if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
+    /* Make an additive adjustment to NEW, because it's dark enough so
+       that scaling by FACTOR alone isn't enough.  */
+    {
+      /* How far below the limit this color is (0 - 1, 1 being darker).  */
+      double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
+      /* The additive adjustment.  */
+      int min_delta = delta * dimness * factor / 2;
+
+      if (factor < 1)
+        new = RGB_TO_ULONG (max (0, min (0xff, (int) (RED_FROM_ULONG (*color)) - min_delta)),
+                           max (0, min (0xff, (int) (GREEN_FROM_ULONG (*color)) - min_delta)),
+                           max (0, min (0xff, (int) (BLUE_FROM_ULONG (*color)) - min_delta)));
+      else
+        new = RGB_TO_ULONG (max (0, min (0xff, (int) (min_delta + RED_FROM_ULONG (*color)))),
+                           max (0, min (0xff, (int) (min_delta + GREEN_FROM_ULONG (*color)))),
+                           max (0, min (0xff, (int) (min_delta + BLUE_FROM_ULONG (*color)))));
+    }
+
   if (new == *color)
     new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta + RED_FROM_ULONG (*color)))),
                       max (0, min (0xff, (int) (delta + GREEN_FROM_ULONG (*color)))),
@@ -2184,7 +2397,8 @@ x_setup_relief_color (f, relief, factor, delta, default_pixel)
   /* Allocate new color.  */
   xgcv.foreground = default_pixel;
   pixel = background;
-  if (mac_alloc_lighter_color (f, &pixel, factor, delta))
+  if (dpyinfo->n_planes != 1
+      && mac_alloc_lighter_color (f, &pixel, factor, delta))
     {
       relief->allocated_p = 1;
       xgcv.foreground = relief->pixel = pixel;
@@ -2214,6 +2428,10 @@ x_setup_relief_colors (s)
 
   if (s->face->use_box_color_for_shadows_p)
     color = s->face->box_color;
+  else if (s->first_glyph->type == IMAGE_GLYPH
+          && s->img->pixmap
+          && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
+    color = IMAGE_BACKGROUND (s->img, s->f, 0);
   else
     {
       XGCValues xgcv;
@@ -2245,11 +2463,14 @@ x_setup_relief_colors (s)
 
 static void
 x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
-                   raised_p, left_p, right_p, clip_rect)
+                   raised_p, top_p, bot_p, left_p, right_p, clip_rect)
      struct frame *f;
-     int left_x, top_y, right_x, bottom_y, left_p, right_p, raised_p;
+     int left_x, top_y, right_x, bottom_y, width;
+     int top_p, bot_p, left_p, right_p, raised_p;
      Rect *clip_rect;
 {
+  Display *dpy = FRAME_MAC_DISPLAY (f);
+  Window window = FRAME_MAC_WINDOW (f);
   int i;
   GC gc;
 
@@ -2257,41 +2478,43 @@ x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
     gc = f->output_data.mac->white_relief.gc;
   else
     gc = f->output_data.mac->black_relief.gc;
-  mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), clip_rect);
+  mac_set_clip_rectangle (dpy, window, clip_rect);
 
   /* Top.  */
-  for (i = 0; i < width; ++i)
-    XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc,
-              left_x + i * left_p, top_y + i,
-              right_x + 1 - i * right_p, top_y + i);
+  if (top_p)
+    for (i = 0; i < width; ++i)
+      XDrawLine (dpy, window, gc,
+                left_x + i * left_p, top_y + i,
+                right_x - i * right_p, top_y + i);
 
   /* Left.  */
   if (left_p)
     for (i = 0; i < width; ++i)
-      XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc,
+      XDrawLine (dpy, window, gc,
                 left_x + i, top_y + i, left_x + i, bottom_y - i);
 
-  mac_reset_clipping (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f));
+  mac_reset_clipping (dpy, window);
   if (raised_p)
     gc = f->output_data.mac->black_relief.gc;
   else
     gc = f->output_data.mac->white_relief.gc;
-  mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
+  mac_set_clip_rectangle (dpy, window,
                          clip_rect);
 
   /* Bottom.  */
-  for (i = 0; i < width; ++i)
-    XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc,
-              left_x + i * left_p, bottom_y - i,
-              right_x + 1 - i * right_p, bottom_y - i);
+  if (bot_p)
+    for (i = 0; i < width; ++i)
+      XDrawLine (dpy, window, gc,
+                left_x + i * left_p, bottom_y - i,
+                right_x - i * right_p, bottom_y - i);
 
   /* Right.  */
   if (right_p)
     for (i = 0; i < width; ++i)
-      XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc,
-                right_x - i, top_y + i + 1, right_x - i, bottom_y - i);
+      XDrawLine (dpy, window, gc,
+                right_x - i, top_y + i + 1, right_x - i, bottom_y - i - 1);
 
-  mac_reset_clipping (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f));
+  mac_reset_clipping (dpy, window);
 }
 
 
@@ -2306,7 +2529,7 @@ static void
 x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
                 left_p, right_p, clip_rect)
      struct glyph_string *s;
-     int left_x, top_y, right_x, bottom_y, left_p, right_p;
+     int left_x, top_y, right_x, bottom_y, width, left_p, right_p;
      Rect *clip_rect;
 {
   XGCValues xgcv;
@@ -2316,21 +2539,21 @@ x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
 
   /* Top.  */
   XFillRectangle (s->display, s->window, &xgcv,
-                 left_x, top_y, right_x - left_x, width);
+                 left_x, top_y, right_x - left_x + 1, width);
 
   /* Left.  */
   if (left_p)
     XFillRectangle (s->display, s->window, &xgcv,
-                   left_x, top_y, width, bottom_y - top_y);
+                   left_x, top_y, width, bottom_y - top_y + 1);
 
   /* Bottom.  */
   XFillRectangle (s->display, s->window, &xgcv,
-                 left_x, bottom_y - width, right_x - left_x, width);
+                 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
 
   /* Right.  */
   if (right_p)
     XFillRectangle (s->display, s->window, &xgcv,
-                   right_x - width, top_y, width, bottom_y - top_y);
+                   right_x - width + 1, top_y, width, bottom_y - top_y + 1);
 
   mac_reset_clipping (s->display, s->window);
 }
@@ -2365,9 +2588,9 @@ x_draw_glyph_string_box (s)
   width = abs (s->face->box_line_width);
   raised_p = s->face->box == FACE_RAISED_BOX;
   left_x = s->x;
-  right_x = ((s->row->full_width_p && s->extends_to_end_of_line_p
-             ? last_x - 1
-             : min (last_x, s->x + s->background_width) - 1));
+  right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
+            ? last_x - 1
+            : min (last_x, s->x + s->background_width) - 1);
   top_y = s->y;
   bottom_y = top_y + s->height - 1;
 
@@ -2389,7 +2612,7 @@ x_draw_glyph_string_box (s)
     {
       x_setup_relief_colors (s);
       x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
-                         width, raised_p, left_p, right_p, &clip_rect);
+                         width, raised_p, 1, 1, left_p, right_p, &clip_rect);
     }
 }
 
@@ -2400,57 +2623,36 @@ static void
 x_draw_image_foreground (s)
      struct glyph_string *s;
 {
-  int x;
-  int y = s->ybase - image_ascent (s->img, s->face);
+  int x = s->x;
+  int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
 
   /* If first glyph of S has a left box line, start drawing it to the
      right of that line.  */
   if (s->face->box != FACE_NO_BOX
-      && s->first_glyph->left_box_line_p)
-    x = s->x + abs (s->face->box_line_width);
-  else
-    x = s->x;
+      && s->first_glyph->left_box_line_p
+      && s->slice.x == 0)
+    x += abs (s->face->box_line_width);
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
-  x += s->img->hmargin;
-  y += s->img->vmargin;
+  if (s->slice.x == 0)
+    x += s->img->hmargin;
+  if (s->slice.y == 0)
+    y += s->img->vmargin;
 
   if (s->img->pixmap)
     {
-#if 0 /* MAC_TODO: image mask */
+      x_set_glyph_string_clipping (s);
+
       if (s->img->mask)
-       {
-         /* We can't set both a clip mask and use XSetClipRectangles
-            because the latter also sets a clip mask.  We also can't
-            trust on the shape extension to be available
-            (XShapeCombineRegion).  So, compute the rectangle to draw
-            manually.  */
-         unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
-                               | GCFunction);
-         XGCValues xgcv;
-         XRectangle clip_rect, image_rect, r;
-
-         xgcv.clip_mask = s->img->mask;
-         xgcv.clip_x_origin = x;
-         xgcv.clip_y_origin = y;
-         xgcv.function = GXcopy;
-         XChangeGC (s->display, s->gc, mask, &xgcv);
-
-         get_glyph_string_clip_rect (s, &clip_rect);
-         image_rect.x = x;
-         image_rect.y = y;
-         image_rect.width = s->img->width;
-         image_rect.height = s->img->height;
-         if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
-           XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
-                      r.x - x, r.y - y, r.width, r.height, r.x, r.y);
-       }
+       mac_copy_area_with_mask (s->display, s->img->pixmap, s->img->mask,
+                                s->window, s->gc, s->slice.x, s->slice.y,
+                                s->slice.width, s->slice.height, x, y);
       else
-#endif /* MAC_TODO */
        {
-         mac_copy_area (s->display, s->img->pixmap, s->window, s->gc,
-                      0, 0, s->img->width, s->img->height, x, y);
+         mac_copy_area (s->display, s->img->pixmap,
+                        s->window, s->gc, s->slice.x, s->slice.y,
+                        s->slice.width, s->slice.height, x, y);
 
          /* When the image has a mask, we can expect that at
             least part of a mouse highlight or a block cursor will
@@ -2462,19 +2664,20 @@ x_draw_image_foreground (s)
            {
              int r = s->img->relief;
              if (r < 0) r = -r;
-             mac_draw_rectangle (s->display, s->window, s->gc, x - r, y - r,
-                                 s->img->width + r*2 - 1, s->img->height + r*2 - 1);
+             mac_draw_rectangle (s->display, s->window, s->gc,
+                                 x - r, y - r,
+                                 s->slice.width + r*2 - 1,
+                                 s->slice.height + r*2 - 1);
            }
        }
     }
   else
     /* Draw a rectangle if image could not be loaded.  */
     mac_draw_rectangle (s->display, s->window, s->gc, x, y,
-                     s->img->width - 1, s->img->height - 1);
+                       s->slice.width - 1, s->slice.height - 1);
 }
 
 
-
 /* Draw a relief around the image glyph string S.  */
 
 static void
@@ -2483,21 +2686,22 @@ x_draw_image_relief (s)
 {
   int x0, y0, x1, y1, thick, raised_p;
   Rect r;
-  int x;
-  int y = s->ybase - image_ascent (s->img, s->face);
+  int x = s->x;
+  int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
 
   /* If first glyph of S has a left box line, start drawing it to the
      right of that line.  */
   if (s->face->box != FACE_NO_BOX
-      && s->first_glyph->left_box_line_p)
-    x = s->x + abs (s->face->box_line_width);
-  else
-    x = s->x;
+      && s->first_glyph->left_box_line_p
+      && s->slice.x == 0)
+    x += abs (s->face->box_line_width);
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
-  x += s->img->hmargin;
-  y += s->img->vmargin;
+  if (s->slice.x == 0)
+    x += s->img->hmargin;
+  if (s->slice.y == 0)
+    y += s->img->vmargin;
 
   if (s->hl == DRAW_IMAGE_SUNKEN
       || s->hl == DRAW_IMAGE_RAISED)
@@ -2513,15 +2717,21 @@ x_draw_image_relief (s)
 
   x0 = x - thick;
   y0 = y - thick;
-  x1 = x + s->img->width + thick - 1;
-  y1 = y + s->img->height + thick - 1;
+  x1 = x + s->slice.width + thick - 1;
+  y1 = y + s->slice.height + thick - 1;
 
   x_setup_relief_colors (s);
   get_glyph_string_clip_rect (s, &r);
-  x_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r);
+  x_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p,
+                     s->slice.y == 0,
+                     s->slice.y + s->slice.height == s->img->height,
+                     s->slice.x == 0,
+                     s->slice.x + s->slice.width == s->img->width,
+                     &r);
 }
 
 
+#if 0 /* TODO: figure out if we need to do this on Mac.  */
 /* Draw the foreground of image glyph string S to PIXMAP.  */
 
 static void
@@ -2529,51 +2739,37 @@ x_draw_image_foreground_1 (s, pixmap)
      struct glyph_string *s;
      Pixmap pixmap;
 {
-  int x;
-  int y = s->ybase - s->y - image_ascent (s->img, s->face);
+  int x = 0;
+  int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
 
   /* If first glyph of S has a left box line, start drawing it to the
      right of that line.  */
   if (s->face->box != FACE_NO_BOX
-      && s->first_glyph->left_box_line_p)
-    x = abs (s->face->box_line_width);
-  else
-    x = 0;
+      && s->first_glyph->left_box_line_p
+      && s->slice.x == 0)
+    x += abs (s->face->box_line_width);
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
-  x += s->img->hmargin;
-  y += s->img->vmargin;
+  if (s->slice.x == 0)
+    x += s->img->hmargin;
+  if (s->slice.y == 0)
+    y += s->img->vmargin;
 
   if (s->img->pixmap)
     {
-#if 0 /* MAC_TODO: image mask */
       if (s->img->mask)
-       {
-         /* We can't set both a clip mask and use XSetClipRectangles
-            because the latter also sets a clip mask.  We also can't
-            trust on the shape extension to be available
-            (XShapeCombineRegion).  So, compute the rectangle to draw
-            manually.  */
-         unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
-                               | GCFunction);
-         XGCValues xgcv;
-
-         xgcv.clip_mask = s->img->mask;
-         xgcv.clip_x_origin = x;
-         xgcv.clip_y_origin = y;
-         xgcv.function = GXcopy;
-         XChangeGC (s->display, s->gc, mask, &xgcv);
-
-         XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
-                    0, 0, s->img->width, s->img->height, x, y);
-         XSetClipMask (s->display, s->gc, None);
-       }
+       mac_copy_area_with_mask_to_pixmap (s->display, s->img->pixmap,
+                                          s->img->mask, pixmap, s->gc,
+                                          s->slice.x, s->slice.y,
+                                          s->slice.width, s->slice.height,
+                                          x, y);
       else
-#endif /* MAC_TODO */
        {
          mac_copy_area_to_pixmap (s->display, s->img->pixmap, pixmap, s->gc,
-                              0, 0, s->img->width, s->img->height, x, y);
+                                  s->slice.x, s->slice.y,
+                                  s->slice.width, s->slice.height,
+                                  x, y);
 
          /* When the image has a mask, we can expect that at
             least part of a mouse highlight or a block cursor will
@@ -2585,16 +2781,18 @@ x_draw_image_foreground_1 (s, pixmap)
            {
              int r = s->img->relief;
              if (r < 0) r = -r;
-             mac_draw_rectangle_to_pixmap (s->display, pixmap, s->gc, x - r, y - r,
-                                 s->img->width + r*2 - 1, s->img->height + r*2 - 1);
+             mac_draw_rectangle (s->display, s->window, s->gc, x - r, y - r,
+                                 s->slice.width + r*2 - 1,
+                                 s->slice.height + r*2 - 1);
            }
        }
     }
   else
     /* Draw a rectangle if image could not be loaded.  */
     mac_draw_rectangle_to_pixmap (s->display, pixmap, s->gc, x, y,
-                             s->img->width - 1, s->img->height - 1);
+                                 s->slice.width - 1, s->slice.height - 1);
 }
+#endif
 
 
 /* Draw part of the background of glyph string S.  X, Y, W, and H
@@ -2626,7 +2824,7 @@ x_draw_glyph_string_bg_rect (s, x, y, w, h)
             |   s->face->box
             |
             |     +-------------------------
-            |     |  s->img->vmargin
+            |     |  s->img->margin
             |     |
             |     |       +-------------------
             |     |       |  the image
@@ -2645,44 +2843,42 @@ x_draw_image_glyph_string (s)
 
   height = s->height - 2 * box_line_vwidth;
 
+
   /* Fill background with face under the image.  Do it only if row is
      taller than image or if image has a clip mask to reduce
      flickering.  */
   s->stippled_p = s->face->stipple != 0;
-  if (height > s->img->height
+  if (height > s->slice.height
       || s->img->hmargin
       || s->img->vmargin
-#if 0 /* TODO: image mask */
       || s->img->mask
-#endif
       || s->img->pixmap == 0
       || s->width != s->background_width)
     {
-      if (box_line_hwidth && s->first_glyph->left_box_line_p)
-       x = s->x + box_line_hwidth;
-      else
-       x = s->x;
+      x = s->x;
+      if (s->first_glyph->left_box_line_p
+         && s->slice.x == 0)
+       x += box_line_hwidth;
+
+      y = s->y;
+      if (s->slice.y == 0)
+       y += box_line_vwidth;
 
-      y = s->y + box_line_vwidth;
-#if 0 /* TODO: image mask */
+#if 0 /* TODO: figure out if we need to do this on Mac.  */
       if (s->img->mask)
        {
          /* Create a pixmap as large as the glyph string.  Fill it
             with the background color.  Copy the image to it, using
             its mask.  Copy the temporary pixmap to the display.  */
-         Screen *screen = FRAME_X_SCREEN (s->f);
-         int depth = DefaultDepthOfScreen (screen);
+         int depth = one_mac_display_info.n_planes;
 
          /* Create a pixmap as large as the glyph string.  */
          pixmap = XCreatePixmap (s->display, s->window,
                                  s->background_width,
                                  s->height, depth);
 
-         /* Don't clip in the following because we're working on the
-            pixmap.  */
-         XSetClipMask (s->display, s->gc, None);
-
          /* Fill the pixmap with the background color/stipple.  */
+#if 0 /* TODO: stipple */
          if (s->stippled_p)
            {
              /* Fill background with a stipple pattern.  */
@@ -2692,13 +2888,15 @@ x_draw_image_glyph_string (s)
              XSetFillStyle (s->display, s->gc, FillSolid);
            }
          else
+#endif
            {
              XGCValues xgcv;
              XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
                            &xgcv);
              XSetForeground (s->display, s->gc, xgcv.background);
-             XFillRectangle (s->display, pixmap, s->gc,
-                             0, 0, s->background_width, s->height);
+             mac_fill_rectangle_to_pixmap (s->display, pixmap, s->gc,
+                                           0, 0, s->background_width,
+                                           s->height);
              XSetForeground (s->display, s->gc, xgcv.foreground);
            }
        }
@@ -2710,16 +2908,18 @@ x_draw_image_glyph_string (s)
     }
 
   /* Draw the foreground.  */
+#if 0 /* TODO: figure out if we need to do this on Mac.  */
   if (pixmap != 0)
     {
       x_draw_image_foreground_1 (s, pixmap);
       x_set_glyph_string_clipping (s);
       mac_copy_area (s->display, pixmap, s->window, s->gc,
-                  0, 0, s->background_width, s->height, s->x, s->y);
+                    0, 0, s->background_width, s->height, s->x, s->y);
       mac_reset_clipping (s->display, s->window);
       XFreePixmap (s->display, pixmap);
     }
   else
+#endif
     x_draw_image_foreground (s);
 
   /* If we must draw a relief around the image, do it.  */
@@ -2752,10 +2952,10 @@ x_draw_stretch_glyph_string (s)
       /* Clear rest using the GC of the original non-cursor face.  */
       if (width < s->background_width)
        {
-         GC gc = s->face->gc;
          int x = s->x + width, y = s->y;
          int w = s->background_width - width, h = s->height;
          Rect r;
+         GC gc;
 
          if (s->row->mouse_face_p
              && cursor_in_mouse_face_p (s->w))
@@ -2815,7 +3015,6 @@ x_draw_glyph_string (s)
       x_set_glyph_string_gc (s->next);
       x_set_glyph_string_clipping (s->next);
       x_draw_glyph_string_background (s->next, 1);
-
     }
 
   /* Set up S->gc, set clipping and draw S.  */
@@ -2852,7 +3051,7 @@ x_draw_glyph_string (s)
       if (s->for_overlaps_p)
        s->background_filled_p = 1;
       else
-        x_draw_glyph_string_background (s, 0);
+       x_draw_glyph_string_background (s, 0);
       x_draw_glyph_string_foreground (s);
       break;
 
@@ -2929,9 +3128,9 @@ x_draw_glyph_string (s)
            }
        }
 
-      /* Draw relief.  */
+      /* Draw relief if not yet drawn.  */
       if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
-        x_draw_glyph_string_box (s);
+       x_draw_glyph_string_box (s);
     }
 
   /* Reset clipping.  */
@@ -2951,7 +3150,6 @@ mac_shift_glyphs_for_insert (f, x, y, width, height, shift_by)
                   x + shift_by, y);
 }
 
-
 /* Delete N glyphs at the nominal cursor position.  Not implemented
    for X frames.  */
 
@@ -3006,6 +3204,7 @@ x_clear_frame ()
 
 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
 
+
 /* Subtract the `struct timeval' values X and Y, storing the result in
    *RESULT.  Return 1 if the difference is negative, otherwise 0.  */
 
@@ -3109,7 +3308,7 @@ XTring_bell ()
    This, and those operations, are used only within an update
    that is bounded by calls to x_update_begin and x_update_end.  */
 
-void
+static void
 XTset_terminal_window (n)
      register int n;
 {
@@ -3145,7 +3344,7 @@ x_scroll_run (w, run)
 
   /* Get frame-relative bounding box of the text display area of W,
      without mode lines.  Include in this box the left and right
-     fringes of W.  */
+     fringe of W.  */
   window_box (w, -1, &x, &y, &width, &height);
 
   from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
@@ -3267,8 +3466,6 @@ static void
 XTframe_rehighlight (frame)
      struct frame *frame;
 {
-
-
   x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame));
 }
 
@@ -3461,6 +3658,7 @@ x_get_keysym_name (keysym)
 
 
 \f
+#if 0
 /* Mouse clicks and mouse movement.  Rah.  */
 
 /* Prepare a mouse-event in *RESULT for placement in the input queue.
@@ -3483,11 +3681,7 @@ construct_mouse_click (result, event, f)
 
   mouseLoc = event->where;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (FRAME_MAC_WINDOW (f)));
-#else
-  SetPort (FRAME_MAC_WINDOW (f));
-#endif
+  SetPortWindowPort (FRAME_MAC_WINDOW (f));
 
   GlobalToLocal (&mouseLoc);
   XSETINT (result->x, mouseLoc.h);
@@ -3498,6 +3692,7 @@ construct_mouse_click (result, event, f)
   result->arg = Qnil;
   return Qnil;
 }
+#endif
 
 \f
 /* Function to report a mouse movement to the mainstream Emacs code.
@@ -3516,6 +3711,7 @@ note_mouse_movement (frame, pos)
      FRAME_PTR frame;
      Point *pos;
 {
+  struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (frame);
 #if TARGET_API_MAC_CARBON
   Rect r;
 #endif
@@ -3530,9 +3726,17 @@ note_mouse_movement (frame, pos)
   if (!PtInRect (*pos, &FRAME_MAC_WINDOW (frame)->portRect))
 #endif
     {
-      frame->mouse_moved = 1;
-      last_mouse_scroll_bar = Qnil;
-      note_mouse_highlight (frame, -1, -1);
+      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);
+       }
     }
   /* Has the mouse moved off the glyph it was on at the last sighting?  */
   else if (pos->h < last_mouse_glyph.left
@@ -3558,8 +3762,6 @@ int disable_mouse_highlight;
 
 static struct scroll_bar *x_window_to_scroll_bar ();
 static void x_scroll_bar_report_motion ();
-static void x_check_fullscreen P_ ((struct frame *));
-static void x_check_fullscreen_move P_ ((struct frame *));
 static int glyph_rect P_ ((struct frame *f, int, int, Rect *));
 
 
@@ -3630,7 +3832,7 @@ glyph_rect (f, x, y, rect)
 
            /* x is to the right of the last glyph in the row.  */
            rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx);
-           /* Shouldn't this be a pixel value?  
+           /* Shouldn't this be a pixel value?
               WINDOW_RIGHT_EDGE_X (w) seems to be the right value.
               ++KFS */
            rect->right = WINDOW_RIGHT_EDGE_COL (w);
@@ -3680,6 +3882,26 @@ remember_mouse_glyph (f1, gx, gy)
 }
 
 
+static WindowPtr
+front_emacs_window ()
+{
+#if TARGET_API_MAC_CARBON
+  WindowPtr wp = GetFrontWindowOfClass (kDocumentWindowClass, true);
+
+  while (wp && !is_emacs_window (wp))
+    wp = GetNextWindowOfClass (wp, kDocumentWindowClass, true);
+#else
+  WindowPtr wp = FrontWindow ();
+
+  while (wp && (wp == tip_window || !is_emacs_window (wp)))
+    wp = GetNextWindow (wp);
+#endif
+
+  return wp;
+}
+
+#define mac_window_to_frame(wp) (((mac_output *) GetWRefCon (wp))->mFP)
+
 /* Return the current position of the mouse.
    *fp should be a frame which indicates which display to ask about.
 
@@ -3711,12 +3933,12 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
 {
   Point mouse_pos;
   int ignore1, ignore2;
-  WindowPtr wp = FrontWindow ();
+  WindowPtr wp = front_emacs_window ();
   struct frame *f;
   Lisp_Object frame, tail;
 
   if (is_emacs_window(wp))
-    f = ((mac_output *) GetWRefCon (wp))->mFP;
+    f = mac_window_to_frame (wp);
 
   BLOCK_INPUT;
 
@@ -3730,11 +3952,7 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
 
       last_mouse_scroll_bar = Qnil;
 
-#if TARGET_API_MAC_CARBON
-      SetPort (GetWindowPort (wp));
-#else
-      SetPort (wp);
-#endif
+      SetPortWindowPort (wp);
 
       GetMouse (&mouse_pos);
 
@@ -3772,7 +3990,7 @@ mac_handle_tool_bar_click (f, button_event)
   if (button_event->what == mouseDown)
     handle_tool_bar_click (f, x, y, 1, 0);
   else
-    handle_tool_bar_click (f, x, y, 0, 
+    handle_tool_bar_click (f, x, y, 0,
                           x_mac_to_emacs_modifiers (FRAME_MAC_DISPLAY_INFO (f),
                                                     button_event->modifiers));
 }
@@ -3805,7 +4023,7 @@ x_scroll_bar_create (w, top, left, width, height, disp_top, disp_height)
   r.right = left + width;
   r.bottom = disp_top + disp_height;
 
-#ifdef TARGET_API_MAC_CARBON
+#if TARGET_API_MAC_CARBON
   ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p", 1, 0, 0, 0,
                   kControlScrollBarProc, 0L);
 #else
@@ -4183,7 +4401,7 @@ activate_scroll_bars (frame)
   while (! NILP (bar))
     {
       ch = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar));
-#ifdef TARGET_API_MAC_CARBON
+#if 1 /* TARGET_API_MAC_CARBON */
       ActivateControl (ch);
 #else
       SetControlMaximum (ch,
@@ -4207,10 +4425,10 @@ deactivate_scroll_bars (frame)
   while (! NILP (bar))
     {
       ch = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar));
-#ifdef TARGET_API_MAC_CARBON
+#if 1 /* TARGET_API_MAC_CARBON */
       DeactivateControl (ch);
 #else
-      SetControlMaximum (ch, XINT (-1));
+      SetControlMaximum (ch, -1);
 #endif
       bar = XSCROLL_BAR (bar)->next;
     }
@@ -4229,6 +4447,8 @@ x_scroll_bar_handle_click (bar, part_code, er, bufp)
      EventRecord *er;
      struct input_event *bufp;
 {
+  int win_y, top_range;
+
   if (! GC_WINDOWP (bar->window))
     abort ();
 
@@ -4252,7 +4472,7 @@ x_scroll_bar_handle_click (bar, part_code, er, bufp)
     case kControlPageDownPart:
       bufp->part = scroll_bar_below_handle;
       break;
-#ifdef TARGET_API_MAC_CARBON
+#if TARGET_API_MAC_CARBON
     default:
 #else
     case kControlIndicatorPart:
@@ -4263,6 +4483,24 @@ x_scroll_bar_handle_click (bar, part_code, er, bufp)
       bufp->part = scroll_bar_handle;
       break;
     }
+
+  win_y = XINT (bufp->y) - XINT (bar->top);
+  top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (0/*dummy*/, XINT (bar->height));
+
+  win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
+
+  win_y -= 24;
+
+  if (! NILP (bar->dragging))
+    win_y -= XINT (bar->dragging);
+
+  if (win_y < 0)
+    win_y = 0;
+  if (win_y > top_range)
+    win_y = top_range;
+
+  XSETINT (bufp->x, win_y);
+  XSETINT (bufp->y, top_range);
 }
 
 
@@ -4312,16 +4550,12 @@ 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);
-  WindowPtr wp = FrontWindow ();
+  WindowPtr wp = front_emacs_window ();
   Point mouse_pos;
-  struct frame *f = ((mac_output *) GetWRefCon (wp))->mFP;
+  struct frame *f = mac_window_to_frame (wp);
   int win_y, top_range;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (wp));
-#else
-  SetPort (wp);
-#endif
+  SetPortWindowPort (wp);
 
   GetMouse (&mouse_pos);
 
@@ -4373,18 +4607,19 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
    mode lines must be clipped to the whole window.  */
 
 static void
-x_clip_to_row (w, row, gc)
+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_y, window_width;
+  int window_x, window_y, window_width;
 
-  window_box (w, -1, 0, &window_y, &window_width, 0);
+  window_box (w, area, &window_x, &window_y, &window_width, 0);
 
-  clip_rect.left = WINDOW_TO_FRAME_PIXEL_X (w, 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;
@@ -4409,13 +4644,6 @@ x_draw_hollow_cursor (w, row)
   struct glyph *cursor_glyph;
   GC gc;
 
-  /* Compute frame-relative coordinates from window-relative
-     coordinates.  */
-  x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
-  y = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
-       + row->ascent - w->phys_cursor_ascent);
-  h = row->height - 1;
-
   /* 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);
@@ -4430,6 +4658,21 @@ x_draw_hollow_cursor (w, row)
   if (cursor_glyph->type == STRETCH_GLYPH
       && !x_stretch_cursor_p)
     wd = min (FRAME_COLUMN_WIDTH (f), wd);
+  w->phys_cursor_width = wd;
+
+  /* Compute frame-relative coordinates from window-relative
+     coordinates.  */
+  x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
+  y = WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y);
+
+  /* Compute the proper height and ascent of the rectangle, based
+     on the actual glyph.  Using the full height of the row looks
+     bad when there are tall images on that row.  */
+  h = max (min (FRAME_LINE_HEIGHT (f), row->height),
+          cursor_glyph->ascent + cursor_glyph->descent);
+  if (h < row->height)
+    y += row->ascent /* - w->phys_cursor_ascent */ + cursor_glyph->descent - h;
+  h--;
 
   /* The foreground of cursor_gc is typically the same as the normal
      background color, which can cause the cursor box to be invisible.  */
@@ -4442,7 +4685,7 @@ x_draw_hollow_cursor (w, row)
   gc = dpyinfo->scratch_cursor_gc;
 
   /* Set clipping, draw the rectangle, and reset clipping again.  */
-  x_clip_to_row (w, row, gc);
+  x_clip_to_row (w, row, TEXT_AREA, gc);
   mac_draw_rectangle (dpy, FRAME_MAC_WINDOW (f), gc, x, y, wd, h);
   mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f));
 }
@@ -4456,35 +4699,49 @@ x_draw_hollow_cursor (w, row)
    --gerd.  */
 
 static void
-x_draw_bar_cursor (w, row, width)
+x_draw_bar_cursor (w, row, width, kind)
      struct window *w;
      struct glyph_row *row;
      int width;
+     enum text_cursor_kinds kind;
 {
-  /* If cursor hpos is out of bounds, don't draw garbage.  This can
-     happen in mini-buffer windows when switching between echo area
-     glyphs and mini-buffer.  */
-  if (w->phys_cursor.hpos < row->used[TEXT_AREA])
+  struct frame *f = XFRAME (w->frame);
+  struct glyph *cursor_glyph;
+
+  /* If cursor is out of bounds, don't draw garbage.  This can happen
+     in mini-buffer windows when switching between echo area glyphs
+     and mini-buffer.  */
+  cursor_glyph = get_phys_cursor_glyph (w);
+  if (cursor_glyph == NULL)
+    return;
+
+  /* If on an image, draw like a normal cursor.  That's usually better
+     visible than drawing a bar, esp. if the image is large so that
+     the bar might not be in the window.  */
+  if (cursor_glyph->type == IMAGE_GLYPH)
     {
-      struct frame *f = XFRAME (w->frame);
-      struct glyph *cursor_glyph;
-      GC gc;
-      int x;
-      unsigned long mask;
+      struct glyph_row *row;
+      row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
+      draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
+    }
+  else
+    {
+      Display *dpy = FRAME_MAC_DISPLAY (f);
+      Window window = FRAME_MAC_WINDOW (f);
+      GC gc = FRAME_MAC_DISPLAY_INFO (f)->scratch_cursor_gc;
+      unsigned long mask = GCForeground | GCBackground;
+      struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
       XGCValues xgcv;
-      Display *dpy;
-      Window window;
-
-      cursor_glyph = get_phys_cursor_glyph (w);
-      if (cursor_glyph == NULL)
-       return;
 
-      xgcv.background = f->output_data.mac->cursor_pixel;
-      xgcv.foreground = f->output_data.mac->cursor_pixel;
-      mask = GCForeground | GCBackground;
-      dpy = FRAME_MAC_DISPLAY (f);
-      window = FRAME_MAC_WINDOW (f);
-      gc = FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc;
+      /* If the glyph's background equals the color we normally draw
+        the bar cursor in, the bar cursor in its normal color is
+        invisible.  Use the glyph's foreground color instead in this
+        case, on the assumption that the glyph's colors are chosen so
+        that the glyph is legible.  */
+      if (face->background == f->output_data.mac->cursor_pixel)
+       xgcv.background = xgcv.foreground = face->foreground;
+      else
+       xgcv.background = xgcv.foreground = f->output_data.mac->cursor_pixel;
 
       if (gc)
        XChangeGC (dpy, gc, mask, &xgcv);
@@ -4496,14 +4753,24 @@ x_draw_bar_cursor (w, row, width)
 
       if (width < 0)
        width = FRAME_CURSOR_WIDTH (f);
+      width = min (cursor_glyph->pixel_width, width);
+
+      w->phys_cursor_width = width;
+      x_clip_to_row (w, row, TEXT_AREA, gc);
+
+      if (kind == BAR_CURSOR)
+       XFillRectangle (dpy, window, gc,
+                       WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x),
+                       WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
+                       width, row->height);
+      else
+       XFillRectangle (dpy, window, gc,
+                       WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x),
+                       WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
+                                                row->height - width),
+                       cursor_glyph->pixel_width,
+                       width);
 
-      x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
-      x_clip_to_row (w, row, gc);
-      XFillRectangle (dpy, window, gc,
-                     x,
-                     WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
-                     min (cursor_glyph->pixel_width, width),
-                     row->height);
       mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f));
     }
 }
@@ -4516,7 +4783,11 @@ mac_define_frame_cursor (f, cursor)
      struct frame *f;
      Cursor cursor;
 {
-  /* MAC TODO */
+#if TARGET_API_MAC_CARBON
+  SetThemeCursor (cursor);
+#else
+  SetCursor (*cursor);
+#endif
 }
 
 
@@ -4545,9 +4816,15 @@ mac_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, act
   if (on_p)
     {
       w->phys_cursor_type = cursor_type;
-      w->phys_cursor_width = cursor_width;
       w->phys_cursor_on_p = 1;
 
+      if (glyph_row->exact_window_width_line_p
+         && w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])
+       {
+         glyph_row->cursor_in_fringe_p = 1;
+         draw_fringe_bitmap (w, glyph_row, 0);
+       }
+      else
       switch (cursor_type)
        {
        case HOLLOW_BOX_CURSOR:
@@ -4558,13 +4835,16 @@ mac_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, act
          draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
          break;
 
-       case HBAR_CURSOR:
-         /* TODO.  For now, just draw bar cursor. */
        case BAR_CURSOR:
-         x_draw_bar_cursor (w, glyph_row, cursor_width);
+         x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
+         break;
+
+       case HBAR_CURSOR:
+         x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
          break;
 
        case NO_CURSOR:
+         w->phys_cursor_width = 0;
          break;
 
        default:
@@ -4672,7 +4952,8 @@ x_new_font (f, fontname)
   FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset;
   FRAME_FONTSET (f) = -1;
 
-  FRAME_COLUMN_WIDTH (f) = FONT_WIDTH (FRAME_FONT (f));
+  FRAME_COLUMN_WIDTH (f) = fontp->average_width;
+  FRAME_SPACE_WIDTH (f) = fontp->space_width;
   FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (FRAME_FONT (f));
 
   compute_fringe_widths (f, 1);
@@ -4681,7 +4962,7 @@ x_new_font (f, fontname)
   if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
     {
       int wid = FRAME_COLUMN_WIDTH (f);
-      FRAME_CONFIG_SCROLL_BAR_COLS (f) 
+      FRAME_CONFIG_SCROLL_BAR_COLS (f)
        = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid-1) / wid;
     }
   else
@@ -4700,13 +4981,16 @@ x_new_font (f, fontname)
       XSetFont (FRAME_MAC_DISPLAY (f), f->output_data.mac->cursor_gc,
                FRAME_FONT (f));
 
+      /* Don't change the size of a tip frame; there's no point in
+        doing it because it's done in Fx_show_tip, and it leads to
+        problems because the tip frame has no widget.  */
       if (NILP (tip_frame) || XFRAME (tip_frame) != f)
         x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
     }
 
   return build_string (fontp->full_name);
 }
-\f
+
 /* Give frame F the fontset named FONTSETNAME as its default font, and
    return the full name of that fontset.  FONTSETNAME may be a wildcard
    pattern; in that case, we choose some fontset that fits the pattern.
@@ -4756,6 +5040,26 @@ xim_close_dpy (dpyinfo)
  */
 
 \f
+void
+mac_get_window_bounds (f, inner, outer)
+     struct frame *f;
+     Rect *inner, *outer;
+{
+#if TARGET_API_MAC_CARBON
+  GetWindowBounds (FRAME_MAC_WINDOW (f), kWindowContentRgn, inner);
+  GetWindowBounds (FRAME_MAC_WINDOW (f), kWindowStructureRgn, outer);
+#else /* not TARGET_API_MAC_CARBON */
+  RgnHandle region = NewRgn ();
+
+  GetWindowRegion (FRAME_MAC_WINDOW (f), kWindowContentRgn, region);
+  *inner = (*region)->rgnBBox;
+  GetWindowRegion (FRAME_MAC_WINDOW (f), kWindowStructureRgn, region);
+  *outer = (*region)->rgnBBox;
+  DisposeRgn (region);
+#endif /* not TARGET_API_MAC_CARBON */
+}
+
+
 /* Calculate the absolute position in frame F
    from its current recorded position values and gravity.  */
 
@@ -4763,51 +5067,36 @@ void
 x_calc_absolute_position (f)
      struct frame *f;
 {
-  Point pt;
+  int width_diff = 0, height_diff = 0;
   int flags = f->size_hint_flags;
+  Rect inner, outer;
 
-  pt.h = pt.v = 0;
+  /* We have nothing to do if the current position
+     is already for the top-left corner.  */
+  if (! ((flags & XNegative) || (flags & YNegative)))
+    return;
 
-  /* Find the position of the outside upper-left corner of
+  /* Find the offsets of the outside upper-left corner of
      the inner window, with respect to the outer window.  */
-  if (f->output_data.mac->parent_desc != FRAME_MAC_DISPLAY_INFO (f)->root_window)
-    {
-      GrafPtr savePort;
-      GetPort (&savePort);
-
-#if TARGET_API_MAC_CARBON
-      SetPort (GetWindowPort (FRAME_MAC_WINDOW (f)));
-#else
-      SetPort (FRAME_MAC_WINDOW (f));
-#endif
+  mac_get_window_bounds (f, &inner, &outer);
 
-#if TARGET_API_MAC_CARBON
-      {
-        Rect r;
-
-        GetWindowPortBounds (FRAME_MAC_WINDOW (f), &r);
-        SetPt(&pt, r.left,  r.top);
-      }
-#else /* not TARGET_API_MAC_CARBON */
-      SetPt(&pt, FRAME_MAC_WINDOW (f)->portRect.left,  FRAME_MAC_WINDOW (f)->portRect.top);
-#endif /* not TARGET_API_MAC_CARBON */
-      LocalToGlobal (&pt);
-      SetPort (savePort);
-    }
+  width_diff = (outer.right - outer.left) - (inner.right - inner.left);
+  height_diff = (outer.bottom - outer.top) - (inner.bottom - inner.top);
 
   /* Treat negative positions as relative to the leftmost bottommost
      position that fits on the screen.  */
   if (flags & XNegative)
     f->left_pos = (FRAME_MAC_DISPLAY_INFO (f)->width
-                  - 2 * f->border_width - pt.h
+                   - width_diff
                   - FRAME_PIXEL_WIDTH (f)
                   + f->left_pos);
-  /* NTEMACS_TODO: Subtract menubar height?  */
+
   if (flags & YNegative)
     f->top_pos = (FRAME_MAC_DISPLAY_INFO (f)->height
-                 - 2 * f->border_width - pt.v
+                 - height_diff
                  - FRAME_PIXEL_HEIGHT (f)
                  + f->top_pos);
+
   /* The left_pos and top_pos
      are now relative to the top and left screen edges,
      so the flags should correspond.  */
@@ -4826,8 +5115,6 @@ x_set_offset (f, xoff, yoff, change_gravity)
      register int xoff, yoff;
      int change_gravity;
 {
-  int modified_top, modified_left;
-
   if (change_gravity > 0)
     {
       f->top_pos = yoff;
@@ -4844,11 +5131,55 @@ x_set_offset (f, xoff, yoff, change_gravity)
   BLOCK_INPUT;
   x_wm_set_size_hint (f, (long) 0, 0);
 
-  modified_left = f->left_pos;
-  modified_top = f->top_pos;
-
-  MoveWindow (f->output_data.mac->mWP, modified_left + 6,
-             modified_top + 42, false);
+#if TARGET_API_MAC_CARBON
+  MoveWindowStructure (FRAME_MAC_WINDOW (f), f->left_pos, f->top_pos);
+  /* If the title bar is completely outside the screen, adjust the
+     position. */
+  ConstrainWindowToScreen (FRAME_MAC_WINDOW (f), kWindowTitleBarRgn,
+                          kWindowConstrainMoveRegardlessOfFit
+                          | kWindowConstrainAllowPartial, NULL, NULL);
+  x_real_positions (f, &f->left_pos, &f->top_pos);
+#else
+  {
+    Rect inner, outer, screen_rect, dummy;
+    RgnHandle region = NewRgn ();
+
+    mac_get_window_bounds (f, &inner, &outer);
+    f->x_pixels_diff = inner.left - outer.left;
+    f->y_pixels_diff = inner.top - outer.top;
+    MoveWindow (FRAME_MAC_WINDOW (f), f->left_pos + f->x_pixels_diff,
+               f->top_pos + f->y_pixels_diff, false);
+
+    /* If the title bar is completely outside the screen, adjust the
+       position.  The variable `outer' holds the title bar rectangle.
+       The variable `inner' holds slightly smaller one than `outer',
+       so that the calculation of overlapping may not become too
+       strict.  */
+    GetWindowRegion (FRAME_MAC_WINDOW (f), kWindowTitleBarRgn, region);
+    outer = (*region)->rgnBBox;
+    DisposeRgn (region);
+    inner = outer;
+    InsetRect (&inner, 8, 8);
+    screen_rect = qd.screenBits.bounds;
+    screen_rect.top += GetMBarHeight ();
+
+    if (!SectRect (&inner, &screen_rect, &dummy))
+      {
+       if (inner.right <= screen_rect.left)
+         f->left_pos = screen_rect.left;
+       else if (inner.left >= screen_rect.right)
+         f->left_pos = screen_rect.right - (outer.right - outer.left);
+
+       if (inner.bottom <= screen_rect.top)
+         f->top_pos = screen_rect.top;
+       else if (inner.top >= screen_rect.bottom)
+         f->top_pos = screen_rect.bottom - (outer.bottom - outer.top);
+
+       MoveWindow (FRAME_MAC_WINDOW (f), f->left_pos + f->x_pixels_diff,
+                   f->top_pos + f->y_pixels_diff, false);
+      }
+  }
+#endif
 
   UNBLOCK_INPUT;
 }
@@ -4987,7 +5318,11 @@ x_raise_frame (f)
      struct frame *f;
 {
   if (f->async_visible)
-    SelectWindow (FRAME_MAC_WINDOW (f));
+    {
+      BLOCK_INPUT;
+      SelectWindow (FRAME_MAC_WINDOW (f));
+      UNBLOCK_INPUT;
+    }
 }
 
 /* Lower frame F.  */
@@ -4996,7 +5331,11 @@ x_lower_frame (f)
      struct frame *f;
 {
   if (f->async_visible)
-    SendBehind (FRAME_MAC_WINDOW (f), nil);
+    {
+      BLOCK_INPUT;
+      SendBehind (FRAME_MAC_WINDOW (f), nil);
+      UNBLOCK_INPUT;
+    }
 }
 
 static void
@@ -5040,12 +5379,30 @@ x_make_frame_visible (f)
 
       f->output_data.mac->asked_for_visible = 1;
 
+#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),
+#ifdef MAC_OS_X_VERSION_10_2
+                             kWindowCascadeStartAtParentWindowScreen
+#else
+                             kWindowCascadeOnParentWindowScreen
+#endif
+                             );
+         x_real_positions (f, &f->left_pos, &f->top_pos);
+       }
+#endif
       ShowWindow (FRAME_MAC_WINDOW (f));
     }
 
   XFlush (FRAME_MAC_DISPLAY (f));
 
-#if 0 /* MAC_TODO */
   /* Synchronize to ensure Emacs knows the frame is visible
      before we do anything else.  We do this loop with input not blocked
      so that incoming events are handled.  */
@@ -5089,7 +5446,6 @@ x_make_frame_visible (f)
        FRAME_SAMPLE_VISIBILITY (f);
       }
   }
-#endif /* MAC_TODO */
 }
 
 /* Change from mapped state to withdrawn state.  */
@@ -5145,23 +5501,36 @@ x_iconify_frame (f)
 }
 
 \f
-/* Destroy the X window of frame F.  */
+/* Free X resources of frame F.  */
 
 void
-x_destroy_window (f)
+x_free_frame_resources (f)
      struct frame *f;
 {
   struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+  WindowPtr wp = FRAME_MAC_WINDOW (f);
 
   BLOCK_INPUT;
 
-  DisposeWindow (FRAME_MAC_WINDOW (f));
+  DisposeWindow (wp);
+  if (wp == tip_window)
+    /* Neither WaitNextEvent nor ReceiveNextEvent receives `window
+       closed' event.  So we reset tip_window here.  */
+    tip_window = NULL;
 
   free_frame_menubar (f);
-  free_frame_faces (f);
+
+  if (FRAME_FACE_CACHE (f))
+    free_frame_faces (f);
+
+  x_free_gcs (f);
+
+  if (FRAME_SIZE_HINTS (f))
+    xfree (FRAME_SIZE_HINTS (f));
 
   xfree (f->output_data.mac);
-  f->output_data.mac = 0;
+  f->output_data.mac = NULL;
+
   if (f == dpyinfo->x_focus_frame)
     dpyinfo->x_focus_frame = 0;
   if (f == dpyinfo->x_focus_event_frame)
@@ -5169,8 +5538,6 @@ x_destroy_window (f)
   if (f == dpyinfo->x_highlight_frame)
     dpyinfo->x_highlight_frame = 0;
 
-  dpyinfo->reference_count--;
-
   if (f == dpyinfo->mouse_face_mouse_frame)
     {
       dpyinfo->mouse_face_beg_row
@@ -5184,6 +5551,21 @@ x_destroy_window (f)
 
   UNBLOCK_INPUT;
 }
+
+
+/* Destroy the X window of frame F.  */
+
+void
+x_destroy_window (f)
+     struct frame *f;
+{
+  struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+
+  x_free_frame_resources (f);
+
+  dpyinfo->reference_count--;
+}
+
 \f
 /* Setting window manager hints.  */
 
@@ -5198,153 +5580,49 @@ x_wm_set_size_hint (f, flags, user_position)
      long flags;
      int user_position;
 {
-#if 0 /* MAC_TODO: connect this to the Appearance Manager */
-  XSizeHints size_hints;
-
-#ifdef USE_X_TOOLKIT
-  Arg al[2];
-  int ac = 0;
-  Dimension widget_width, widget_height;
-  Window window = XtWindow (f->output_data.x->widget);
-#else /* not USE_X_TOOLKIT */
-  Window window = FRAME_X_WINDOW (f);
-#endif /* not USE_X_TOOLKIT */
-
-  /* Setting PMaxSize caused various problems.  */
-  size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */;
+  int base_width, base_height, width_inc, height_inc;
+  int min_rows = 0, min_cols = 0;
+  XSizeHints *size_hints;
 
-  size_hints.x = f->left_pos;
-  size_hints.y = f->top_pos;
+  base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
+  base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
+  width_inc = FRAME_COLUMN_WIDTH (f);
+  height_inc = FRAME_LINE_HEIGHT (f);
 
-#ifdef USE_X_TOOLKIT
-  XtSetArg (al[ac], XtNwidth, &widget_width); ac++;
-  XtSetArg (al[ac], XtNheight, &widget_height); ac++;
-  XtGetValues (f->output_data.x->widget, al, ac);
-  size_hints.height = widget_height;
-  size_hints.width = widget_width;
-#else /* not USE_X_TOOLKIT */
-  size_hints.height = FRAME_PIXEL_HEIGHT (f);
-  size_hints.width = FRAME_PIXEL_WIDTH (f);
-#endif /* not USE_X_TOOLKIT */
-
-  size_hints.width_inc = FRAME_COLUMN_WIDTH (f);
-  size_hints.height_inc = FRAME_LINE_HEIGHT (f);
-  size_hints.max_width
-    = FRAME_X_DISPLAY_INFO (f)->width - FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
-  size_hints.max_height
-    = FRAME_X_DISPLAY_INFO (f)->height - FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
-
-  /* Calculate the base and minimum sizes.
-
-     (When we use the X toolkit, we don't do it here.
-     Instead we copy the values that the widgets are using, below.)  */
-#ifndef USE_X_TOOLKIT
-  {
-    int base_width, base_height;
-    int min_rows = 0, min_cols = 0;
+  check_frame_size (f, &min_rows, &min_cols);
 
-    base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
-    base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
-
-    check_frame_size (f, &min_rows, &min_cols);
-
-    /* The window manager uses the base width hints to calculate the
-       current number of rows and columns in the frame while
-       resizing; min_width and min_height aren't useful for this
-       purpose, since they might not give the dimensions for a
-       zero-row, zero-column frame.
-
-       We use the base_width and base_height members if we have
-       them; otherwise, we set the min_width and min_height members
-       to the size for a zero x zero frame.  */
+  size_hints = FRAME_SIZE_HINTS (f);
+  if (size_hints == NULL)
+    {
+      size_hints = FRAME_SIZE_HINTS (f) = xmalloc (sizeof (XSizeHints));
+      bzero (size_hints, sizeof (XSizeHints));
+    }
 
-#ifdef HAVE_X11R4
-    size_hints.flags |= PBaseSize;
-    size_hints.base_width = base_width;
-    size_hints.base_height = base_height;
-    size_hints.min_width  = base_width + min_cols * size_hints.width_inc;
-    size_hints.min_height = base_height + min_rows * size_hints.height_inc;
-#else
-    size_hints.min_width = base_width;
-    size_hints.min_height = base_height;
-#endif
-  }
+  size_hints->flags |= PResizeInc | PMinSize | PBaseSize ;
+  size_hints->width_inc  = width_inc;
+  size_hints->height_inc = height_inc;
+  size_hints->min_width  = base_width + min_cols * width_inc;
+  size_hints->min_height = base_height + min_rows * height_inc;
+  size_hints->base_width  = base_width;
+  size_hints->base_height = base_height;
 
-  /* If we don't need the old flags, we don't need the old hint at all.  */
   if (flags)
+    size_hints->flags = flags;
+  else if (user_position)
     {
-      size_hints.flags |= flags;
-      goto no_read;
+      size_hints->flags &= ~ PPosition;
+      size_hints->flags |= USPosition;
     }
-#endif /* not USE_X_TOOLKIT */
-
-  {
-    XSizeHints hints;          /* Sometimes I hate X Windows... */
-    long supplied_return;
-    int value;
+}
 
-#ifdef HAVE_X11R4
-    value = XGetWMNormalHints (FRAME_X_DISPLAY (f), window, &hints,
-                              &supplied_return);
-#else
-    value = XGetNormalHints (FRAME_X_DISPLAY (f), window, &hints);
-#endif
+#if 0 /* MAC_TODO: hide application instead of iconify? */
+/* Used for IconicState or NormalState */
 
-#ifdef USE_X_TOOLKIT
-    size_hints.base_height = hints.base_height;
-    size_hints.base_width = hints.base_width;
-    size_hints.min_height = hints.min_height;
-    size_hints.min_width = hints.min_width;
-#endif
-
-    if (flags)
-      size_hints.flags |= flags;
-    else
-      {
-       if (value == 0)
-         hints.flags = 0;
-       if (hints.flags & PSize)
-         size_hints.flags |= PSize;
-       if (hints.flags & PPosition)
-         size_hints.flags |= PPosition;
-       if (hints.flags & USPosition)
-         size_hints.flags |= USPosition;
-       if (hints.flags & USSize)
-         size_hints.flags |= USSize;
-      }
-  }
-
-#ifndef USE_X_TOOLKIT
- no_read:
-#endif
-
-#ifdef PWinGravity
-  size_hints.win_gravity = f->win_gravity;
-  size_hints.flags |= PWinGravity;
-
-  if (user_position)
-    {
-      size_hints.flags &= ~ PPosition;
-      size_hints.flags |= USPosition;
-    }
-#endif /* PWinGravity */
-
-#ifdef HAVE_X11R4
-  XSetWMNormalHints (FRAME_X_DISPLAY (f), window, &size_hints);
-#else
-  XSetNormalHints (FRAME_X_DISPLAY (f), window, &size_hints);
-#endif
-#endif /* MAC_TODO */
-}
-
-#if 0 /* MAC_TODO: hide application instead of iconify? */
-/* Used for IconicState or NormalState */
-
-void
-x_wm_set_window_state (f, state)
-     struct frame *f;
-     int state;
-{
+void
+x_wm_set_window_state (f, state)
+     struct frame *f;
+     int state;
+{
 #ifdef USE_X_TOOLKIT
   Arg al[1];
 
@@ -5450,6 +5728,7 @@ char **font_name_table = NULL;
 int font_name_table_size = 0;
 int font_name_count = 0;
 
+#if 0
 /* compare two strings ignoring case */
 static int
 stricmp (const char *s, const char *t)
@@ -5529,13 +5808,68 @@ mac_font_match (char *mf, char *xf)
           && wildstrieq (m_charset, x_charset))
          || mac_font_pattern_match (mf, xf);
 }
+#endif
+
+static Lisp_Object Qbig5, Qcn_gb, Qsjis, Qeuc_kr;
+
+static void
+decode_mac_font_name (name, size, scriptcode)
+     char *name;
+     int size;
+#if TARGET_API_MAC_CARBON
+     int scriptcode;
+#else
+     short scriptcode;
+#endif
+{
+  Lisp_Object coding_system;
+  struct coding_system coding;
+  char *buf;
+
+  switch (scriptcode)
+    {
+    case smTradChinese:
+      coding_system = Qbig5;
+      break;
+    case smSimpChinese:
+      coding_system = Qcn_gb;
+      break;
+    case smJapanese:
+      coding_system = Qsjis;
+      break;
+    case smKorean:
+      coding_system = Qeuc_kr;
+      break;
+    default:
+      return;
+    }
+
+  setup_coding_system (coding_system, &coding);
+  coding.src_multibyte = 0;
+  coding.dst_multibyte = 1;
+  coding.mode |= CODING_MODE_LAST_BLOCK;
+  coding.composing = COMPOSITION_DISABLED;
+  buf = (char *) alloca (size);
+
+  decode_coding (&coding, name, buf, strlen (name), size - 1);
+  bcopy (buf, name, coding.produced);
+  name[coding.produced] = '\0';
+}
 
 
 static char *
-mac_to_x_fontname (char *name, int size, Style style, short scriptcode)
+mac_to_x_fontname (name, size, style, scriptcode, encoding_base)
+     char *name;
+     int size;
+     Style style;
+#if TARGET_API_MAC_CARBON
+     int scriptcode;
+#else
+     short scriptcode;
+#endif
 {
   char foundry[32], family[32], cs[32];
-  char xf[255], *result, *p;
+  char xf[256], *result, *p;
 
   if (sscanf (name, "%31[^-]-%31[^-]-%31s", foundry, family, cs) != 3)
     {
@@ -5544,13 +5878,13 @@ mac_to_x_fontname (char *name, int size, Style style, short scriptcode)
 
       switch (scriptcode)
       {
-      case smTradChinese:
+      case smTradChinese:      /* == kTextEncodingMacChineseTrad */
         strcpy(cs, "big5-0");
         break;
-      case smSimpChinese:
+      case smSimpChinese:      /* == kTextEncodingMacChineseSimp */
         strcpy(cs, "gb2312.1980-0");
         break;
-      case smJapanese:
+      case smJapanese:         /* == kTextEncodingMacJapanese */
         strcpy(cs, "jisx0208.1983-sjis");
         break;
       case -smJapanese:
@@ -5562,12 +5896,24 @@ mac_to_x_fontname (char *name, int size, Style style, short scriptcode)
           font is being built.  */
        strcpy(cs, "jisx0201.1976-0");
        break;
-      case smKorean:
+      case smKorean:           /* == kTextEncodingMacKorean */
         strcpy(cs, "ksc5601.1989-0");
         break;
+#if TARGET_API_MAC_CARBON
+      case kTextEncodingMacCyrillic:
+       strcpy(cs, "mac-cyrillic");
+       break;
+      case kTextEncodingMacCentralEurRoman:
+       strcpy(cs, "mac-centraleurroman");
+       break;
+      case kTextEncodingMacSymbol:
+      case kTextEncodingMacDingbats:
+       strcpy(cs, "adobe-fontspecific");
+       break;
+#endif
       default:
-        strcpy(cs, "mac-roman");
-        break;
+       strcpy(cs, "mac-roman");
+       break;
       }
     }
 
@@ -5594,6 +5940,8 @@ static void
 x_font_name_to_mac_font_name (char *xf, char *mf)
 {
   char foundry[32], family[32], weight[20], slant[2], cs[32];
+  Lisp_Object coding_system = Qnil;
+  struct coding_system coding;
 
   strcpy (mf, "");
 
@@ -5603,13 +5951,32 @@ x_font_name_to_mac_font_name (char *xf, char *mf)
               foundry, family, weight, slant, cs) != 5)
     return;
 
-  if (strcmp (cs, "big5-0") == 0 || strcmp (cs, "gb2312.1980-0") == 0
-      || strcmp (cs, "jisx0208.1983-sjis") == 0
-      || strcmp (cs, "jisx0201.1976-0") == 0
-      || strcmp (cs, "ksc5601.1989-0") == 0 || strcmp (cs, "mac-roman") == 0)
-    strcpy(mf, family);
+  if (strcmp (cs, "big5-0") == 0)
+    coding_system = Qbig5;
+  else if (strcmp (cs, "gb2312.1980-0") == 0)
+    coding_system = Qcn_gb;
+  else if (strcmp (cs, "jisx0208.1983-sjis") == 0
+          || strcmp (cs, "jisx0201.1976-0") == 0)
+    coding_system = Qsjis;
+  else if (strcmp (cs, "ksc5601.1989-0") == 0)
+    coding_system = Qeuc_kr;
+  else if (strcmp (cs, "mac-roman") == 0
+          || strcmp (cs, "mac-cyrillic") == 0
+          || strcmp (cs, "mac-centraleurroman") == 0
+          || strcmp (cs, "adobe-fontspecific") == 0)
+    strcpy (mf, family);
   else
-    sprintf(mf, "%s-%s-%s", foundry, family, cs);
+    sprintf (mf, "%s-%s-%s", foundry, family, cs);
+
+  if (!NILP (coding_system))
+    {
+      setup_coding_system (coding_system, &coding);
+      coding.src_multibyte = 1;
+      coding.dst_multibyte = 1;
+      coding.mode |= CODING_MODE_LAST_BLOCK;
+      encode_coding (&coding, family, mf, strlen (family), sizeof (Str32) - 1);
+      mf[coding.produced] = '\0';
+    }
 }
 
 
@@ -5668,41 +6035,53 @@ init_font_name_table ()
          FMFont font;
          FMFontStyle style;
          FMFontSize size;
-         SInt16 sc;
+         TextEncoding encoding;
+         TextEncodingBase sc;
 
          if (FMGetFontFamilyName (ff, name) != noErr)
            break;
          p2cstr (name);
+         if (*name == '.')
+           continue;
 
-         sc = FontToScript (ff);
+         if (FMGetFontFamilyTextEncoding (ff, &encoding) != noErr)
+           break;
+         sc = GetTextEncodingBase (encoding);
+         decode_mac_font_name (name, sizeof (name), sc);
 
          /* Point the instance iterator at the current font family.  */
-         if (FMResetFontFamilyInstanceIterator(ff, &ffii) != noErr)
+         if (FMResetFontFamilyInstanceIterator (ff, &ffii) != noErr)
            break;
 
          while (FMGetNextFontFamilyInstance (&ffii, &font, &style, &size)
                 == noErr)
-           if (size == 0)
-             {
-               add_font_name_table_entry (mac_to_x_fontname (name, size,
-                                                             style, sc));
-               add_font_name_table_entry (mac_to_x_fontname (name, size,
-                                                             italic, sc));
-               add_font_name_table_entry (mac_to_x_fontname (name, size,
-                                                             bold, sc));
-               add_font_name_table_entry (mac_to_x_fontname (name, size,
-                                                             italic | bold,
-                                                             sc));
-             }
-           else
-             {
+           {
+             /* Both jisx0208.1983-sjis and jisx0201.1976-0 parts are
+                contained in Apple Japanese (SJIS) font.  */
+           again:
+             if (size == 0)
+               {
+                 add_font_name_table_entry (mac_to_x_fontname (name, size,
+                                                               style, sc));
+                 add_font_name_table_entry (mac_to_x_fontname (name, size,
+                                                               italic, sc));
+                 add_font_name_table_entry (mac_to_x_fontname (name, size,
+                                                               bold, sc));
+                 add_font_name_table_entry (mac_to_x_fontname (name, size,
+                                                               italic | bold,
+                                                               sc));
+               }
+             else
                add_font_name_table_entry (mac_to_x_fontname (name, size,
                                                              style, sc));
-               if (smJapanese == sc)
-                 add_font_name_table_entry (mac_to_x_fontname (name, size,
-                                                               style,
-                                                               -smJapanese));
-             }
+             if (sc == smJapanese)
+               {
+                 sc = -smJapanese;
+                 goto again;
+               }
+             else if (sc == -smJapanese)
+               sc = smJapanese;
+           }
        }
 
       /* Dispose of the iterators.  */
@@ -5744,6 +6123,7 @@ init_font_name_table ()
 
          TextFont (fontnum);
          scriptcode = FontToScript (fontnum);
+         decode_mac_font_name (name, sizeof (name), scriptcode);
          do
            {
              HLock (font_handle);
@@ -5778,9 +6158,9 @@ init_font_name_table ()
                                             assc_entry->fontSize,
                                             assc_entry->fontStyle,
                                             scriptcode);
-                     /* Both jisx0208.1983-sjis and
-                        jisx0201.1976-sjis parts are contained in
-                        Apple Japanese (SJIS) font.  */
+                     /* Both jisx0208.1983-sjis and jisx0201.1976-0
+                        parts are contained in Apple Japanese (SJIS)
+                        font.  */
                      if (smJapanese == scriptcode)
                        {
                          font_name_table[font_name_count++]
@@ -5807,6 +6187,213 @@ init_font_name_table ()
 }
 
 
+void
+mac_clear_font_name_table ()
+{
+  int i;
+
+  for (i = 0; i < font_name_count; i++)
+    xfree (font_name_table[i]);
+  xfree (font_name_table);
+  font_name_table = NULL;
+  font_name_table_size = font_name_count = 0;
+}
+
+
+enum xlfd_scalable_field_index
+  {
+    XLFD_SCL_PIXEL_SIZE,
+    XLFD_SCL_POINT_SIZE,
+    XLFD_SCL_AVGWIDTH,
+    XLFD_SCL_LAST
+  };
+
+static int xlfd_scalable_fields[] =
+  {
+    6,                         /* PIXEL_SIZE */
+    7,                         /* POINT_SIZE */
+    11,                                /* AVGWIDTH */
+    -1
+  };
+
+static Lisp_Object
+mac_c_string_match (regexp, string, nonspecial, exact)
+     Lisp_Object regexp;
+     const char *string, *nonspecial;
+     int exact;
+{
+  if (exact)
+    {
+      if (strcmp (string, nonspecial) == 0)
+       return build_string (string);
+    }
+  else if (strstr (string, nonspecial))
+    {
+      Lisp_Object str = build_string (string);
+
+      if (fast_string_match (regexp, str) >= 0)
+       return str;
+    }
+
+  return Qnil;
+}
+
+static Lisp_Object
+mac_do_list_fonts (pattern, maxnames)
+     char *pattern;
+     int maxnames;
+{
+  int i, n_fonts = 0;
+  Lisp_Object font_list = Qnil, pattern_regex, fontname;
+  char *regex = (char *) alloca (strlen (pattern) * 2 + 3);
+  char scaled[256];
+  char *ptr;
+  int scl_val[XLFD_SCL_LAST], *field, *val;
+  char *longest_start, *cur_start, *nonspecial;
+  int longest_len, exact;
+
+  if (font_name_table == NULL)  /* Initialize when first used.  */
+    init_font_name_table ();
+
+  for (i = 0; i < XLFD_SCL_LAST; i++)
+    scl_val[i] = -1;
+
+  /* If the pattern contains 14 dashes and one of PIXEL_SIZE,
+     POINT_SIZE, and AVGWIDTH fields is explicitly specified, scalable
+     fonts are scaled according to the specified size.  */
+  ptr = pattern;
+  i = 0;
+  field = xlfd_scalable_fields;
+  val = scl_val;
+  if (*ptr == '-')
+    do
+      {
+       ptr++;
+       if (i == *field)
+         {
+           if ('1' <= *ptr && *ptr <= '9')
+             {
+               *val = *ptr++ - '0';
+               while ('0' <= *ptr && *ptr <= '9' && *val < 10000)
+                 *val = *val * 10 + *ptr++ - '0';
+               if (*ptr != '-')
+                 *val = -1;
+             }
+           field++;
+           val++;
+         }
+       ptr = strchr (ptr, '-');
+       i++;
+      }
+    while (ptr && i < 14);
+
+  if (i == 14 && ptr == NULL)
+    {
+      if (scl_val[XLFD_SCL_POINT_SIZE] > 0)
+       {
+         scl_val[XLFD_SCL_PIXEL_SIZE] = scl_val[XLFD_SCL_POINT_SIZE] / 10;
+         scl_val[XLFD_SCL_AVGWIDTH] = scl_val[XLFD_SCL_POINT_SIZE];
+       }
+      else if (scl_val[XLFD_SCL_PIXEL_SIZE] > 0)
+       {
+         scl_val[XLFD_SCL_POINT_SIZE] =
+           scl_val[XLFD_SCL_AVGWIDTH] = scl_val[XLFD_SCL_PIXEL_SIZE] * 10;
+       }
+      else if (scl_val[XLFD_SCL_AVGWIDTH] > 0)
+       {
+         scl_val[XLFD_SCL_PIXEL_SIZE] = scl_val[XLFD_SCL_AVGWIDTH] / 10;
+         scl_val[XLFD_SCL_POINT_SIZE] = scl_val[XLFD_SCL_AVGWIDTH];
+       }
+    }
+  else
+    scl_val[XLFD_SCL_PIXEL_SIZE] = -1;
+
+  ptr = regex;
+  *ptr++ = '^';
+
+  longest_start = cur_start = ptr;
+  longest_len = 0;
+  exact = 1;
+
+  /* Turn pattern into a regexp and do a regexp match.  Also find the
+     longest substring containing no special characters.  */
+  for (; *pattern; pattern++)
+    {
+      if (*pattern == '?' || *pattern == '*')
+       {
+         if (ptr - cur_start > longest_len)
+           {
+             longest_start = cur_start;
+             longest_len = ptr - cur_start;
+           }
+         exact = 0;
+
+         if (*pattern == '?')
+           *ptr++ = '.';
+         else /* if (*pattern == '*') */
+           {
+             *ptr++ = '.';
+             *ptr++ = '*';
+           }
+         cur_start = ptr;
+       }
+      else
+       *ptr++ = tolower (*pattern);
+    }
+
+  if (ptr - cur_start > longest_len)
+    {
+      longest_start = cur_start;
+      longest_len = ptr - cur_start;
+    }
+
+  *ptr = '$';
+  *(ptr + 1) = '\0';
+
+  nonspecial = xmalloc (longest_len + 1);
+  strncpy (nonspecial, longest_start, longest_len);
+  nonspecial[longest_len] = '\0';
+
+  pattern_regex = build_string (regex);
+
+  for (i = 0; i < font_name_count; i++)
+    {
+      fontname = mac_c_string_match (pattern_regex, font_name_table[i],
+                                    nonspecial, exact);
+      if (!NILP (fontname))
+       {
+         font_list = Fcons (fontname, font_list);
+         if (exact || maxnames > 0 && ++n_fonts >= maxnames)
+           break;
+       }
+      else if (scl_val[XLFD_SCL_PIXEL_SIZE] > 0
+              && (ptr = strstr (font_name_table[i], "-0-0-75-75-m-0-")))
+       {
+         int former_len = ptr - font_name_table[i];
+
+         memcpy (scaled, font_name_table[i], former_len);
+         sprintf (scaled + former_len,
+                  "-%d-%d-75-75-m-%d-%s",
+                  scl_val[XLFD_SCL_PIXEL_SIZE],
+                  scl_val[XLFD_SCL_POINT_SIZE],
+                  scl_val[XLFD_SCL_AVGWIDTH],
+                  ptr + sizeof ("-0-0-75-75-m-0-") - 1);
+         fontname = mac_c_string_match (pattern_regex, scaled,
+                                        nonspecial, exact);
+         if (!NILP (fontname))
+           {
+             font_list = Fcons (fontname, font_list);
+             if (exact || maxnames > 0 && ++n_fonts >= maxnames)
+               break;
+           }
+       }
+    }
+
+  xfree (nonspecial);
+
+  return font_list;
+}
+
 /* Return a list of at most MAXNAMES font specs matching the one in
    PATTERN.  Cache matching fonts for patterns in
    dpyinfo->name_list_element to avoid looking them up again by
@@ -5819,16 +6406,9 @@ x_list_fonts (struct frame *f,
               int size,
               int maxnames)
 {
-  char *ptnstr;
   Lisp_Object newlist = Qnil, tem, key;
-  int n_fonts = 0;
-  int i;
-  struct gcpro gcpro1, gcpro2;
   struct mac_display_info *dpyinfo = f ? FRAME_MAC_DISPLAY_INFO (f) : NULL;
 
-  if (font_name_table == NULL)  /* Initialize when first used.  */
-    init_font_name_table ();
-
   if (dpyinfo)
     {
       tem = XCDR (dpyinfo->name_list_element);
@@ -5842,27 +6422,12 @@ x_list_fonts (struct frame *f,
        }
     }
 
-  ptnstr = SDATA (pattern);
-
-  GCPRO2 (pattern, newlist);
-
-  /* Scan and matching bitmap fonts.  */
-  for (i = 0; i < font_name_count; i++)
-    {
-      if (mac_font_pattern_match (font_name_table[i], ptnstr))
-        {
-          newlist = Fcons (build_string (font_name_table[i]), newlist);
-
-          n_fonts++;
-          if (maxnames > 0 && n_fonts >= maxnames)
-            break;
-        }
-    }
+  BLOCK_INPUT;
+  newlist = mac_do_list_fonts (SDATA (pattern), maxnames);
+  UNBLOCK_INPUT;
 
   /* MAC_TODO: add code for matching outline fonts here */
 
-  UNGCPRO;
-
   if (dpyinfo)
     {
       XSETCDR (dpyinfo->name_list_element,
@@ -5911,12 +6476,8 @@ x_font_min_bounds (font, w, h)
      MacFontStruct *font;
      int *w, *h;
 {
-  /*
-   * TODO: Windows does not appear to offer min bound, only
-   * average and maximum width, and maximum height.
-   */
   *h = FONT_HEIGHT (font);
-  *w = FONT_WIDTH (font);
+  *w = font->min_bounds.width;
 }
 
 
@@ -6022,14 +6583,12 @@ XLoadQueryFont (Display *dpy, char *fontname)
     name = fontname;
   else
     {
-      for (i = 0; i < font_name_count; i++)
-        if (mac_font_pattern_match (font_name_table[i], fontname))
-          break;
-
-      if (i >= font_name_count)
-        return NULL;
+      Lisp_Object matched_fonts;
 
-      name = font_name_table[i];
+      matched_fonts = mac_do_list_fonts (fontname, 1);
+      if (NILP (matched_fonts))
+       return NULL;
+      name = SDATA (XCAR (matched_fonts));
     }
 
   GetPort (&port);  /* save the current font number used */
@@ -6146,13 +6705,20 @@ XLoadQueryFont (Display *dpy, char *fontname)
       font->per_char = (XCharStruct *)
        xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
       {
-        int c;
+        int c, min_width, max_width;
 
+       min_width = max_width = char_width;
         for (c = 0x20; c <= 0xff; c++)
           {
-            font->per_char[c - 0x20] = font->max_bounds;
-            font->per_char[c - 0x20].width = CharWidth (c);
+           font->per_char[c - 0x20] = font->max_bounds;
+           char_width = CharWidth (c);
+           font->per_char[c - 0x20].width = char_width;
+           font->per_char[c - 0x20].rbearing = char_width;
+           min_width = min (min_width, char_width);
+           max_width = max (max_width, char_width);
           }
+       font->min_bounds.width = min_width;
+       font->max_bounds.width = max_width;
       }
     }
 
@@ -6164,6 +6730,18 @@ XLoadQueryFont (Display *dpy, char *fontname)
 }
 
 
+void
+mac_unload_font (dpyinfo, font)
+     struct mac_display_info *dpyinfo;
+     XFontStruct *font;
+{
+  xfree (font->fontname);
+  if (font->per_char)
+    xfree (font->per_char);
+  xfree (font);
+}
+
+
 /* Load font named FONTNAME of the size SIZE for frame F, and return a
    pointer to the structure font_info while allocating it dynamically.
    If SIZE is 0, load any size of font.
@@ -6214,7 +6792,9 @@ x_load_font (f, fontname, size)
     if (size > 0 && !NILP (font_names))
       fontname = (char *) SDATA (XCAR (font_names));
 
+    BLOCK_INPUT;
     font = (MacFontStruct *) XLoadQueryFont (FRAME_MAC_DISPLAY (f), fontname);
+    UNBLOCK_INPUT;
     if (!font)
       return NULL;
 
@@ -6240,11 +6820,41 @@ x_load_font (f, fontname, size)
 
     /* Now fill in the slots of *FONTP.  */
     BLOCK_INPUT;
+    bzero (fontp, sizeof (*fontp));
     fontp->font = font;
     fontp->font_idx = i;
     fontp->name = (char *) xmalloc (strlen (font->fontname) + 1);
     bcopy (font->fontname, fontp->name, strlen (font->fontname) + 1);
 
+    if (font->min_bounds.width == font->max_bounds.width)
+      {
+       /* Fixed width font.  */
+       fontp->average_width = fontp->space_width = font->min_bounds.width;
+      }
+    else
+      {
+       XChar2b char2b;
+       XCharStruct *pcm;
+
+       char2b.byte1 = 0x00, char2b.byte2 = 0x20;
+       pcm = mac_per_char_metric (font, &char2b, 0);
+       if (pcm)
+         fontp->space_width = pcm->width;
+       else
+         fontp->space_width = FONT_WIDTH (font);
+
+       if (pcm)
+         {
+           int width = pcm->width;
+           for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++)
+             if ((pcm = mac_per_char_metric (font, &char2b, 0)) != NULL)
+               width += pcm->width;
+           fontp->average_width = width / 95;
+         }
+       else
+         fontp->average_width = FONT_WIDTH (font);
+      }
+
     fontp->full_name = fontp->name;
 
     fontp->size = font->max_bounds.width;
@@ -6373,81 +6983,6 @@ x_find_ccl_program (fontp)
 
 
 \f
-/***********************************************************************
-                           Initialization
- ***********************************************************************/
-
-#ifdef USE_X_TOOLKIT
-static XrmOptionDescRec emacs_options[] = {
-  {"-geometry",        ".geometry", XrmoptionSepArg, NULL},
-  {"-iconic",  ".iconic", XrmoptionNoArg, (XtPointer) "yes"},
-
-  {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
-     XrmoptionSepArg, NULL},
-  {"-ib",      "*EmacsScreen.internalBorderWidth", XrmoptionSepArg, NULL},
-
-  {"-T",       "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
-  {"-wn",      "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
-  {"-title",   "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
-  {"-iconname",        "*EmacsShell.iconName", XrmoptionSepArg, (XtPointer) NULL},
-  {"-in",      "*EmacsShell.iconName", XrmoptionSepArg, (XtPointer) NULL},
-  {"-mc",      "*pointerColor", XrmoptionSepArg, (XtPointer) NULL},
-  {"-cr",      "*cursorColor", XrmoptionSepArg, (XtPointer) NULL}
-};
-#endif /* USE_X_TOOLKIT */
-
-static int x_initialized;
-
-#ifdef MULTI_KBOARD
-/* Test whether two display-name strings agree up to the dot that separates
-   the screen number from the server number.  */
-static int
-same_x_server (name1, name2)
-     char *name1, *name2;
-{
-  int seen_colon = 0;
-  unsigned char *system_name = SDATA (Vsystem_name);
-  int system_name_length = strlen (system_name);
-  int length_until_period = 0;
-
-  while (system_name[length_until_period] != 0
-        && system_name[length_until_period] != '.')
-    length_until_period++;
-
-  /* Treat `unix' like an empty host name.  */
-  if (! strncmp (name1, "unix:", 5))
-    name1 += 4;
-  if (! strncmp (name2, "unix:", 5))
-    name2 += 4;
-  /* Treat this host's name like an empty host name.  */
-  if (! strncmp (name1, system_name, system_name_length)
-      && name1[system_name_length] == ':')
-    name1 += system_name_length;
-  if (! strncmp (name2, system_name, system_name_length)
-      && name2[system_name_length] == ':')
-    name2 += system_name_length;
-  /* Treat this host's domainless name like an empty host name.  */
-  if (! strncmp (name1, system_name, length_until_period)
-      && name1[length_until_period] == ':')
-    name1 += length_until_period;
-  if (! strncmp (name2, system_name, length_until_period)
-      && name2[length_until_period] == ':')
-    name2 += length_until_period;
-
-  for (; *name1 != '\0' && *name1 == *name2; name1++, name2++)
-    {
-      if (*name1 == ':')
-       seen_colon++;
-      if (seen_colon && *name1 == '.')
-       return 1;
-    }
-  return (seen_colon
-         && (*name1 == '.' || *name1 == '\0')
-         && (*name2 == '.' || *name2 == '\0'));
-}
-#endif
-
-
 /* The Mac Event loop code */
 
 #ifndef MAC_OSX
@@ -6491,6 +7026,7 @@ same_x_server (name1, name2)
 /* true when cannot handle any Mac OS events */
 static int handling_window_update = 0;
 
+#if 0
 /* the flag appl_is_suspended is used both for determining the sleep
    time to be passed to WaitNextEvent and whether the cursor should be
    drawn when updating the display.  The cursor is turned off when
@@ -6500,6 +7036,7 @@ static int handling_window_update = 0;
    suspended.  */
 static Boolean app_is_suspended = false;
 static long app_sleep_time = WNE_SLEEP_AT_RESUME;
+#endif
 
 #define EXTRA_STACK_ALLOC (256 * 1024)
 
@@ -6509,12 +7046,22 @@ static long app_sleep_time = WNE_SLEEP_AT_RESUME;
 
 Boolean        terminate_flag = false;
 
+/* Contains the string "reverse", which is a constant for mouse button emu.*/
+Lisp_Object Qreverse;
+
 /* True if using command key as meta key.  */
 Lisp_Object Vmac_command_key_is_meta;
 
+/* Modifier associated with the option key, or nil for normal behavior. */
+Lisp_Object Vmac_option_modifier;
+
 /* True if the ctrl and meta keys should be reversed.  */
 Lisp_Object Vmac_reverse_ctrl_meta;
 
+/* True if the option and command modifiers should be used to emulate
+   a three button mouse */
+Lisp_Object Vmac_emulate_three_button_mouse;
+
 #if USE_CARBON_EVENTS
 /* True if the mouse wheel button (i.e. button 4) should map to
    mouse-2, instead of mouse-3.  */
@@ -6542,6 +7089,11 @@ Lisp_Object drag_and_drop_file_list;
 
 Point saved_menu_event_location;
 
+#if !TARGET_API_MAC_CARBON
+/* Place holder for the default arrow cursor.  */
+CursPtr arrow_cursor;
+#endif
+
 /* Apple Events */
 static void init_required_apple_events (void);
 static pascal OSErr
@@ -6551,15 +7103,21 @@ do_ae_print_documents (const AppleEvent *, AppleEvent *, long);
 static pascal OSErr do_ae_open_documents (AppleEvent *, AppleEvent *, long);
 static pascal OSErr do_ae_quit_application (AppleEvent *, AppleEvent *, long);
 
+#if TARGET_API_MAC_CARBON
 /* Drag and Drop */
-static OSErr init_mac_drag_n_drop ();
+static pascal OSErr mac_do_track_drag (DragTrackingMessage, WindowPtr, void*, DragReference);
 static pascal OSErr mac_do_receive_drag (WindowPtr, void*, DragReference);
+#endif
 
 #if USE_CARBON_EVENTS
 /* Preliminary Support for the OSX Services Menu */
 static OSStatus mac_handle_service_event (EventHandlerCallRef,EventRef,void*);
 static void init_service_handler ();
+/* Window Event Handler */
+static pascal OSStatus mac_handle_window_event (EventHandlerCallRef,
+                                               EventRef, void *);
 #endif
+OSErr install_window_handler (WindowPtr);
 
 extern void init_emacs_passwd_dir ();
 extern int emacs_main (int, char **, char **);
@@ -6584,6 +7142,26 @@ mac_to_emacs_modifiers (EventModifiers mods)
     result |= meta_modifier;
   if (NILP (Vmac_command_key_is_meta) && (mods & macAltKey))
     result |= alt_modifier;
+  if (!NILP (Vmac_option_modifier) && (mods & optionKey)) {
+      Lisp_Object val = Fget(Vmac_option_modifier, Qmodifier_value);
+      if (!NILP(val))
+          result |= XUINT(val);
+  }
+
+  return result;
+}
+
+static int
+mac_get_emulated_btn ( UInt32 modifiers )
+{
+  int result = 0;
+  if (!NILP (Vmac_emulate_three_button_mouse)) {
+    int cmdIs3 = !EQ (Vmac_emulate_three_button_mouse, Qreverse);
+    if (modifiers & cmdKey)
+      result = cmdIs3 ? 2 : 1;
+    else if (modifiers & optionKey)
+      result = cmdIs3 ? 1 : 2;
+  }
   return result;
 }
 
@@ -6596,6 +7174,11 @@ mac_event_to_emacs_modifiers (EventRef eventRef)
   UInt32 mods = 0;
   GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, NULL,
                    sizeof (UInt32), NULL, &mods);
+  if (!NILP (Vmac_emulate_three_button_mouse) &&
+      GetEventClass(eventRef) == kEventClassMouse)
+    {
+      mods &= ~(optionKey | cmdKey);
+    }
   return mac_to_emacs_modifiers (mods);
 }
 
@@ -6610,7 +7193,14 @@ mac_get_mouse_btn (EventRef ref)
   switch (result)
     {
     case kEventMouseButtonPrimary:
-      return 0;
+      if (NILP (Vmac_emulate_three_button_mouse))
+       return 0;
+      else {
+       UInt32 mods = 0;
+       GetEventParameter (ref, kEventParamKeyModifiers, typeUInt32, NULL,
+                          sizeof (UInt32), NULL, &mods);
+       return mac_get_emulated_btn(mods);
+      }
     case kEventMouseButtonSecondary:
       return NILP (Vmac_wheel_button_is_mouse_2) ? 1 : 2;
     case kEventMouseButtonTertiary:
@@ -6702,6 +7292,8 @@ do_init_managers (void)
   InitCursor ();
 
 #if !TARGET_API_MAC_CARBON
+  arrow_cursor = &qd.arrow;
+
   /* set up some extra stack space for use by emacs */
   SetApplLimit ((Ptr) ((long) GetApplLimit () - EXTRA_STACK_ALLOC));
 
@@ -6719,8 +7311,8 @@ do_check_ram_size (void)
 
   if (Gestalt (gestaltPhysicalRAMSize, &physical_ram_size) != noErr
       || Gestalt (gestaltLogicalRAMSize, &logical_ram_size) != noErr
-      || physical_ram_size > 256 * 1024 * 1024
-      || logical_ram_size > 256 * 1024 * 1024)
+      || physical_ram_size > (1 << VALBITS)
+      || logical_ram_size > (1 << VALBITS))
     {
       StopAlert (RAM_TOO_LARGE_ALERT_ID, NULL);
       exit (1);
@@ -6730,10 +7322,13 @@ do_check_ram_size (void)
 static void
 do_window_update (WindowPtr win)
 {
-  struct mac_output *mwp = (mac_output *) GetWRefCon (win);
-  struct frame *f = mwp->mFP;
+  struct frame *f = mac_window_to_frame (win);
 
-  if (f)
+  BeginUpdate (win);
+
+  /* The tooltip has been drawn already.  Avoid the SET_FRAME_GARBAGED
+     below.  */
+  if (win != tip_window)
     {
       if (f->async_visible == 0)
         {
@@ -6750,17 +7345,30 @@ do_window_update (WindowPtr win)
         }
       else
         {
-          BeginUpdate (win);
+         Rect r;
+
           handling_window_update = 1;
 
-         XClearWindow (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f));
+#if TARGET_API_MAC_CARBON
+         {
+           RgnHandle region = NewRgn ();
 
-          expose_frame (f, 0, 0, 0, 0);
+           GetPortVisibleRegion (GetWindowPort (win), region);
+           UpdateControls (win, region);
+           GetRegionBounds (region, &r);
+           DisposeRgn (region);
+         }
+#else
+         UpdateControls (win, win->visRgn);
+         r = (*win->visRgn)->rgnBBox;
+#endif
+         expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top);
 
           handling_window_update = 0;
-          EndUpdate (win);
         }
     }
+
+  EndUpdate (win);
 }
 
 static int
@@ -6779,56 +7387,18 @@ is_emacs_window (WindowPtr win)
   return 0;
 }
 
-static void
-do_window_activate (WindowPtr win)
-{
-  mac_output *mwp;
-  struct frame *f;
-
-  if (is_emacs_window (win))
-    {
-      mwp = (mac_output *) GetWRefCon (win);
-      f = mwp->mFP;
-
-      if (f)
-       {
-         x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f), f);
-         activate_scroll_bars (f);
-       }
-    }
-}
-
-static void
-do_window_deactivate (WindowPtr win)
-{
-  mac_output *mwp;
-  struct frame *f;
-
-  if (is_emacs_window (win))
-    {
-      mwp = (mac_output *) GetWRefCon (win);
-      f = mwp->mFP;
-
-      if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
-       {
-         x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f), 0);
-         deactivate_scroll_bars (f);
-       }
-    }
-}
-
 static void
 do_app_resume ()
 {
+  /* Window-activate events will do the job. */
+#if 0
   WindowPtr wp;
-  mac_output *mwp;
   struct frame *f;
 
-  wp = FrontWindow();
-  if (is_emacs_window (wp))
+  wp = front_emacs_window ();
+  if (wp)
     {
-      mwp = (mac_output *) GetWRefCon (wp);
-      f = mwp->mFP;
+      f = mac_window_to_frame (wp);
 
       if (f)
        {
@@ -6839,20 +7409,21 @@ do_app_resume ()
 
   app_is_suspended = false;
   app_sleep_time = WNE_SLEEP_AT_RESUME;
+#endif
 }
 
 static void
 do_app_suspend ()
 {
+  /* Window-deactivate events will do the job. */
+#if 0
   WindowPtr wp;
-  mac_output *mwp;
   struct frame *f;
 
-  wp = FrontWindow();
-  if (is_emacs_window (wp))
+  wp = front_emacs_window ();
+  if (wp)
     {
-      mwp = (mac_output *) GetWRefCon (wp);
-      f = mwp->mFP;
+      f = mac_window_to_frame (wp);
 
       if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
        {
@@ -6863,71 +7434,43 @@ do_app_suspend ()
 
   app_is_suspended = true;
   app_sleep_time = WNE_SLEEP_AT_SUSPEND;
+#endif
 }
 
 
 static void
-do_mouse_moved (Point mouse_pos)
+do_mouse_moved (mouse_pos, f)
+     Point mouse_pos;
+     FRAME_PTR *f;
 {
-  WindowPtr wp = FrontWindow ();
-  struct frame *f;
+  WindowPtr wp = front_emacs_window ();
+  struct x_display_info *dpyinfo;
 
-  if (is_emacs_window (wp))
+  if (wp)
     {
-      f = ((mac_output *) GetWRefCon (wp))->mFP;
-
-#if TARGET_API_MAC_CARBON
-      SetPort (GetWindowPort (wp));
-#else
-      SetPort (wp);
-#endif
+      *f = mac_window_to_frame (wp);
+      dpyinfo = FRAME_MAC_DISPLAY_INFO (*f);
 
-      GlobalToLocal (&mouse_pos);
+      if (dpyinfo->mouse_face_hidden)
+       {
+         dpyinfo->mouse_face_hidden = 0;
+         clear_mouse_face (dpyinfo);
+       }
 
-      note_mouse_movement (f, &mouse_pos);
-    }
-}
+      SetPortWindowPort (wp);
 
+      GlobalToLocal (&mouse_pos);
 
-static void
-do_os_event (EventRecord *erp)
-{
-  switch((erp->message >> 24) & 0x000000FF)
-    {
-    case suspendResumeMessage:
-      if((erp->message & resumeFlag) == 1)
-       do_app_resume ();
+      if (dpyinfo->grabbed && tracked_scroll_bar)
+       x_scroll_bar_note_movement (tracked_scroll_bar,
+                                   mouse_pos.v
+                                   - XINT (tracked_scroll_bar->top),
+                                   TickCount() * (1000 / 60));
       else
-       do_app_suspend ();
-      break;
-
-    case mouseMovedMessage:
-      do_mouse_moved (erp->where);
-      break;
+       note_mouse_movement (*f, &mouse_pos);
     }
 }
 
-static void
-do_events (EventRecord *erp)
-{
-  switch (erp->what)
-    {
-    case updateEvt:
-      do_window_update ((WindowPtr) erp->message);
-      break;
-
-    case osEvt:
-      do_os_event (erp);
-      break;
-
-    case activateEvt:
-      if ((erp->modifiers & activeFlag) != 0)
-       do_window_activate ((WindowPtr) erp->message);
-      else
-       do_window_deactivate ((WindowPtr) erp->message);
-      break;
-    }
-}
 
 static void
 do_apple_menu (SInt16 menu_item)
@@ -6965,8 +7508,7 @@ do_menu_choice (SInt32 menu_choice)
 
     default:
       {
-        WindowPtr wp = FrontWindow ();
-        struct frame *f = ((mac_output *) GetWRefCon (wp))->mFP;
+        struct frame *f = mac_window_to_frame (front_emacs_window ());
         MenuHandle menu = GetMenuHandle (menu_id);
         if (menu)
           {
@@ -6988,21 +7530,43 @@ do_menu_choice (SInt32 menu_choice)
 static void
 do_grow_window (WindowPtr w, EventRecord *e)
 {
-  long grow_size;
   Rect limit_rect;
-  int rows, columns;
-  mac_output *mwp = (mac_output *) GetWRefCon (w);
-  struct frame *f = mwp->mFP;
+  int rows, columns, width, height;
+  struct frame *f = mac_window_to_frame (w);
+  XSizeHints *size_hints = FRAME_SIZE_HINTS (f);
+  int min_width = MIN_DOC_SIZE, min_height = MIN_DOC_SIZE;
+#if TARGET_API_MAC_CARBON
+  Rect new_rect;
+#else
+  long grow_size;
+#endif
 
-  SetRect(&limit_rect, MIN_DOC_SIZE, MIN_DOC_SIZE, MAX_DOC_SIZE, MAX_DOC_SIZE);
+  if (size_hints->flags & PMinSize)
+    {
+      min_width  = size_hints->min_width;
+      min_height = size_hints->min_height;
+    }
+  SetRect (&limit_rect, min_width, min_height, MAX_DOC_SIZE, MAX_DOC_SIZE);
 
+#if TARGET_API_MAC_CARBON
+  if (!ResizeWindow (w, e->where, &limit_rect, &new_rect))
+    return;
+  height = new_rect.bottom - new_rect.top;
+  width = new_rect.right - new_rect.left;
+#else
   grow_size = GrowWindow (w, e->where, &limit_rect);
-
   /* see if it really changed size */
-  if (grow_size != 0)
+  if (grow_size == 0)
+    return;
+  height = HiWord (grow_size);
+  width = LoWord (grow_size);
+#endif
+
+  if (width != FRAME_PIXEL_WIDTH (f)
+      || height != FRAME_PIXEL_HEIGHT (f))
     {
-      rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, HiWord (grow_size));
-      columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, LoWord (grow_size));
+      rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
+      columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
 
       x_set_window_size (f, 0, columns, rows);
     }
@@ -7020,46 +7584,43 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out)
   GrafPtr save_port;
   Rect zoom_rect, port_rect;
   Point top_left;
-  int w_title_height, columns, rows, width, height, dummy, x, y;
-  mac_output *mwp = (mac_output *) GetWRefCon (w);
-  struct frame *f = mwp->mFP;
+  int w_title_height, columns, rows, width, height;
+  struct frame *f = mac_window_to_frame (w);
 
-  GetPort (&save_port);
-
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
-
-  /* Clear window to avoid flicker.  */
 #if TARGET_API_MAC_CARBON
   {
-    Rect r;
-    BitMap bm;
+    Point standard_size;
 
-    GetWindowPortBounds (w, &r);
-    EraseRect (&r);
+    standard_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
+    standard_size.v = FRAME_MAC_DISPLAY_INFO (f)->height;
 
-    if (zoom_in_or_out == inZoomOut)
+    if (IsWindowInStandardState (w, &standard_size, &zoom_rect))
+      zoom_in_or_out = inZoomIn;
+    else
       {
-        /* calculate height of window's title bar (hard card it for now).  */
-        w_title_height = 20 + GetMBarHeight ();
-
-        /* get maximum height of window into zoom_rect.bottom -
-          zoom_rect.top */
-        GetQDGlobalsScreenBits (&bm);
-        zoom_rect = bm.bounds;
-        zoom_rect.top += w_title_height;
-        InsetRect (&zoom_rect, 8, 4);  /* not too tight */
-
-        zoom_rect.right = zoom_rect.left
-         + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
-
-        SetWindowStandardState (w, &zoom_rect);
+       /* Adjust the standard size according to character boundaries.  */
+
+       columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, zoom_rect.right - zoom_rect.left);
+       rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, zoom_rect.bottom - zoom_rect.top);
+       standard_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, columns);
+       standard_size.v = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
+       GetWindowBounds (w, kWindowContentRgn, &port_rect);
+       if (IsWindowInStandardState (w, &standard_size, &zoom_rect)
+           && port_rect.left == zoom_rect.left
+           && port_rect.top == zoom_rect.top)
+         zoom_in_or_out = inZoomIn;
+       else
+         zoom_in_or_out = inZoomOut;
       }
+
+    ZoomWindowIdeal (w, zoom_in_or_out, &standard_size);
   }
 #else /* not TARGET_API_MAC_CARBON */
+  GetPort (&save_port);
+
+  SetPortWindowPort (w);
+
+  /* Clear window to avoid flicker.  */
   EraseRect (&(w->portRect));
   if (zoom_in_or_out == inZoomOut)
     {
@@ -7078,12 +7639,19 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out)
       zoom_rect.right = zoom_rect.left
        + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
 
+      /* Adjust the standard size according to character boundaries.  */
+      rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, zoom_rect.bottom - zoom_rect.top);
+      zoom_rect.bottom =
+       zoom_rect.top + FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
+
       (**((WStateDataHandle) ((WindowPeek) w)->dataHandle)).stdState
        = zoom_rect;
     }
-#endif /* not TARGET_API_MAC_CARBON */
 
-  ZoomWindow (w, zoom_in_or_out, w == FrontWindow ());
+  ZoomWindow (w, zoom_in_or_out, w == front_emacs_window ());
+
+  SetPort (save_port);
+#endif /* not TARGET_API_MAC_CARBON */
 
   /* retrieve window size and update application values */
 #if TARGET_API_MAC_CARBON
@@ -7091,19 +7659,23 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out)
 #else
   port_rect = w->portRect;
 #endif
-  rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, port_rect.bottom - port_rect.top);
-  columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, port_rect.right - port_rect.left);
-  x_set_window_size (mwp->mFP, 0, columns, rows);
+  height = port_rect.bottom - port_rect.top;
+  width = port_rect.right - port_rect.left;
 
-  SetPort (save_port);
-}
+  if (width != FRAME_PIXEL_WIDTH (f)
+      || height != FRAME_PIXEL_HEIGHT (f))
+    {
+      rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
+      columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
 
-/* Initialize Drag And Drop to allow files to be dropped onto emacs frames */
-static OSErr
-init_mac_drag_n_drop ()
-{
-  OSErr result = InstallReceiveHandler (mac_do_receive_drag, 0L, NULL);
-  return result;
+      change_frame_size (f, rows, columns, 0, 1, 0);
+      SET_FRAME_GARBAGED (f);
+      cancel_mouse_face (f);
+
+      FRAME_PIXEL_WIDTH (f) = width;
+      FRAME_PIXEL_HEIGHT (f) = height;
+    }
+  x_real_positions (f, &f->left_pos, &f->top_pos);
 }
 
 /* Intialize AppleEvent dispatcher table for the required events.  */
@@ -7275,7 +7847,102 @@ mac_handle_service_event (EventHandlerCallRef callRef,
     }
   return err;
 }
+
+
+static pascal OSStatus
+mac_handle_window_event (next_handler, event, data)
+     EventHandlerCallRef next_handler;
+     EventRef event;
+     void *data;
+{
+  extern Lisp_Object Qcontrol;
+
+  WindowPtr wp;
+  OSStatus result;
+  UInt32 attributes;
+  XSizeHints *size_hints;
+
+  GetEventParameter (event, kEventParamDirectObject, typeWindowRef,
+                    NULL, sizeof (WindowPtr), NULL, &wp);
+
+  switch (GetEventKind (event))
+    {
+    case kEventWindowBoundsChanging:
+      result = CallNextEventHandler (next_handler, event);
+      if (result != eventNotHandledErr)
+       return result;
+
+      GetEventParameter (event, kEventParamAttributes, typeUInt32,
+                        NULL, sizeof (UInt32), NULL, &attributes);
+      size_hints = FRAME_SIZE_HINTS (mac_window_to_frame (wp));
+      if ((attributes & kWindowBoundsChangeUserResize)
+         && ((size_hints->flags & (PResizeInc | PBaseSize | PMinSize))
+             == (PResizeInc | PBaseSize | PMinSize)))
+       {
+         Rect bounds;
+         int width, height;
+
+         GetEventParameter (event, kEventParamCurrentBounds,
+                            typeQDRectangle,
+                            NULL, sizeof (Rect), NULL, &bounds);
+         width = bounds.right - bounds.left;
+         height = bounds.bottom - bounds.top;
+
+         if (width < size_hints->min_width)
+           width = size_hints->min_width;
+         else
+           width = size_hints->base_width
+             + (int) ((width - size_hints->base_width)
+                      / (float) size_hints->width_inc + .5)
+             * size_hints->width_inc;
+
+         if (height < size_hints->min_height)
+           height = size_hints->min_height;
+         else
+           height = size_hints->base_height
+             + (int) ((height - size_hints->base_height)
+                      / (float) size_hints->height_inc + .5)
+             * size_hints->height_inc;
+
+         bounds.right = bounds.left + width;
+         bounds.bottom = bounds.top + height;
+         SetEventParameter (event, kEventParamCurrentBounds,
+                            typeQDRectangle, sizeof (Rect), &bounds);
+         return noErr;
+       }
+      break;
+    }
+
+  return eventNotHandledErr;
+}
+#endif /* USE_CARBON_EVENTS */
+
+
+OSErr
+install_window_handler (window)
+     WindowPtr window;
+{
+  OSErr err = noErr;
+#if USE_CARBON_EVENTS
+  EventTypeSpec specs[] = {{kEventClassWindow, kEventWindowBoundsChanging}};
+  static EventHandlerUPP handle_window_event_UPP = NULL;
+
+  if (handle_window_event_UPP == NULL)
+    handle_window_event_UPP = NewEventHandlerUPP (mac_handle_window_event);
+
+  err = InstallWindowEventHandler (window, handle_window_event_UPP,
+                                  GetEventTypeCount (specs), specs,
+                                  NULL, NULL);
+#endif
+#if TARGET_API_MAC_CARBON
+  if (err == noErr)
+    err = InstallTrackingHandler (mac_do_track_drag, window, NULL);
+  if (err == noErr)
+    err = InstallReceiveHandler (mac_do_receive_drag, window, NULL);
 #endif
+  return err;
+}
+
 
 /* Open Application Apple Event */
 static pascal OSErr
@@ -7293,6 +7960,17 @@ path_from_vol_dir_name (char *, int, short, long, char *);
 /* Called when we receive an AppleEvent with an ID of
    "kAEOpenDocuments".  This routine gets the direct parameter,
    extracts the FSSpecs in it, and puts their names on a list.  */
+#pragma options align=mac68k
+typedef struct SelectionRange {
+  short unused1; // 0 (not used)
+  short lineNum; // line to select (<0 to specify range)
+  long startRange; // start of selection range (if line < 0)
+  long endRange; // end of selection range (if line < 0)
+  long unused2; // 0 (not used)
+  long theDate; // modification date/time
+} SelectionRange;
+#pragma options align=reset
+
 static pascal OSErr
 do_ae_open_documents(AppleEvent *message, AppleEvent *reply, long refcon)
 {
@@ -7301,11 +7979,19 @@ do_ae_open_documents(AppleEvent *message, AppleEvent *reply, long refcon)
   AEKeyword keyword;
   DescType actual_type;
   Size actual_size;
+  SelectionRange position;
 
   err = AEGetParamDesc (message, keyDirectObject, typeAEList, &the_desc);
   if (err != noErr)
     goto descriptor_error_exit;
 
+  err = AEGetParamPtr (message, keyAEPosition, typeChar, &actual_type, &position, sizeof(SelectionRange), &actual_size);
+  if (err == noErr)
+    drag_and_drop_file_list = Fcons (list3 (make_number (position.lineNum + 1),
+                                           make_number (position.startRange + 1),
+                                           make_number (position.endRange + 1)),
+                                    drag_and_drop_file_list);
+
   /* Check to see that we got all of the required parameters from the
      event descriptor.  For an 'odoc' event this should just be the
      file list.  */
@@ -7355,8 +8041,11 @@ do_ae_open_documents(AppleEvent *message, AppleEvent *reply, long refcon)
                                        fs.name) &&
                mac_to_posix_pathname (path_name, unix_path_name, 255))
 #endif
-             drag_and_drop_file_list = Fcons (build_string (unix_path_name),
-                                              drag_and_drop_file_list);
+             /* x-dnd functions expect undecoded filenames.  */
+             drag_and_drop_file_list =
+               Fcons (make_unibyte_string (unix_path_name,
+                                           strlen (unix_path_name)),
+                      drag_and_drop_file_list);
          }
       }
   }
@@ -7371,6 +8060,68 @@ descriptor_error_exit:
 }
 
 
+#if TARGET_API_MAC_CARBON
+static pascal OSErr
+mac_do_track_drag (DragTrackingMessage message, WindowPtr window,
+                  void *handlerRefCon, DragReference theDrag)
+{
+  static int can_accept;
+  short items;
+  short index;
+  ItemReference theItem;
+  FlavorFlags theFlags;
+  OSErr result;
+
+  switch (message)
+    {
+    case kDragTrackingEnterHandler:
+      CountDragItems (theDrag, &items);
+      can_accept = 1;
+      for (index = 1; index <= items; index++)
+       {
+         GetDragItemReferenceNumber (theDrag, index, &theItem);
+         result = GetFlavorFlags (theDrag, theItem, flavorTypeHFS, &theFlags);
+         if (result != noErr)
+           {
+             can_accept = 0;
+             break;
+           }
+       }
+      break;
+
+    case kDragTrackingEnterWindow:
+      if (can_accept)
+       {
+         RgnHandle hilite_rgn = NewRgn ();
+         Rect r;
+
+         GetWindowPortBounds (window, &r);
+         OffsetRect (&r, -r.left, -r.top);
+         RectRgn (hilite_rgn, &r);
+         ShowDragHilite (theDrag, hilite_rgn, true);
+         DisposeRgn (hilite_rgn);
+         SetThemeCursor (kThemeCopyArrowCursor);
+       }
+      break;
+
+    case kDragTrackingInWindow:
+      break;
+
+    case kDragTrackingLeaveWindow:
+      if (can_accept)
+       {
+         HideDragHilite (theDrag);
+         SetThemeCursor (kThemeArrowCursor);
+       }
+      break;
+
+    case kDragTrackingLeaveHandler:
+      break;
+    }
+
+  return noErr;
+}
+
 static pascal OSErr
 mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
                     DragReference theDrag)
@@ -7412,11 +8163,14 @@ mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
                                      data.fileSpec.parID, data.fileSpec.name) &&
              mac_to_posix_pathname (path_name, unix_path_name, 255))
 #endif
-            drag_and_drop_file_list = Fcons (build_string (unix_path_name),
-                                            drag_and_drop_file_list);
+           /* x-dnd functions expect undecoded filenames.  */
+            drag_and_drop_file_list =
+             Fcons (make_unibyte_string (unix_path_name,
+                                         strlen (unix_path_name)),
+                    drag_and_drop_file_list);
        }
       else
-       return;
+       continue;
     }
   /* If there are items in the list, construct an event and post it to
      the queue like an interrupt using kbd_buffer_store_event.  */
@@ -7424,13 +8178,15 @@ mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
     {
       struct input_event event;
       Lisp_Object frame;
-      struct frame *f = ((mac_output *) GetWRefCon(window))->mFP;
-      SetPort (GetWindowPort (window));
+      struct frame *f = mac_window_to_frame (window);
+      SInt16 modifiers;
+
       GlobalToLocal (&mouse);
+      GetDragModifiers (theDrag, NULL, NULL, &modifiers);
 
       event.kind = DRAG_N_DROP_EVENT;
       event.code = 0;
-      event.modifiers = 0;
+      event.modifiers = mac_to_emacs_modifiers (modifiers);
       event.timestamp = TickCount () * (1000 / 60);
       XSETINT (event.x, mouse.h);
       XSETINT (event.y, mouse.v);
@@ -7445,8 +8201,13 @@ mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
        GetCurrentProcess (&psn);
        SetFrontProcess (&psn);
       }
+
+      return noErr;
     }
+  else
+    return dragNotAcceptedErr;
 }
+#endif
 
 
 /* Print Document Apple Event */
@@ -7519,7 +8280,9 @@ main (void)
 
   do_get_menus ();
 
+#ifndef USE_LSB_TAG
   do_check_ram_size ();
+#endif
 
   init_emacs_passwd_dir ();
 
@@ -7594,28 +8357,66 @@ keycode_to_xkeysym (int keyCode, int *xKeySym)
   return *xKeySym != 0;
 }
 
+#if !USE_CARBON_EVENTS
+static RgnHandle mouse_region = NULL;
+
+Boolean
+mac_wait_next_event (er, sleep_time, dequeue)
+     EventRecord *er;
+     UInt32 sleep_time;
+     Boolean dequeue;
+{
+  static EventRecord er_buf = {nullEvent};
+  UInt32 target_tick, current_tick;
+  EventMask event_mask;
+
+  if (mouse_region == NULL)
+    mouse_region = NewRgn ();
+
+  event_mask = everyEvent;
+  if (NILP (Fboundp (Qmac_ready_for_drag_n_drop)))
+    event_mask -= highLevelEventMask;
+
+  current_tick = TickCount ();
+  target_tick = current_tick + sleep_time;
+
+  if (er_buf.what == nullEvent)
+    while (!WaitNextEvent (event_mask, &er_buf,
+                          target_tick - current_tick, mouse_region))
+      {
+       current_tick = TickCount ();
+       if (target_tick <= current_tick)
+         return false;
+      }
+
+  *er = er_buf;
+  if (dequeue)
+    er_buf.what = nullEvent;
+  return true;
+}
+#endif /* not USE_CARBON_EVENTS */
+
 /* Emacs calls this whenever it wants to read an input event from the
    user. */
 int
-XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
+XTread_socket (sd, expected, hold_quit)
+     int sd, expected;
+     struct input_event *hold_quit;
 {
+  struct input_event inev;
   int count = 0;
 #if USE_CARBON_EVENTS
-  OSStatus rneResult;
   EventRef eventRef;
-  EventMouseButton mouseBtn;
+  EventTargetRef toolbox_dispatcher;
 #endif
   EventRecord er;
-  int the_modifiers;
-  EventMask event_mask;
+  struct mac_display_info *dpyinfo = &one_mac_display_info;
 
-#if 0
   if (interrupt_input_blocked)
     {
       interrupt_input_pending = 1;
       return -1;
     }
-#endif
 
   interrupt_input_pending = 0;
   BLOCK_INPUT;
@@ -7623,9 +8424,6 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
   /* So people can tell when we have read the available input.  */
   input_signal_count++;
 
-  if (numchars <= 0)
-    abort ();
-
   /* Don't poll for events to process (specifically updateEvt) if
      window update currently already in progress.  A call to redisplay
      (in do_window_update) can be preempted by another call to
@@ -7640,40 +8438,55 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
   if (terminate_flag)
     Fkill_emacs (make_number (1));
 
-  /* It is necessary to set this (additional) argument slot of an
-     event to nil because keyboard.c protects incompletely processed
-     event from being garbage collected by placing them in the
-     kbd_buffer_gcpro vector.  */
-  bufp->arg = Qnil;
+#if USE_CARBON_EVENTS
+  toolbox_dispatcher = GetEventDispatcherTarget ();
 
-  event_mask = everyEvent;
-  if (NILP (Fboundp (Qmac_ready_for_drag_n_drop)))
-    event_mask -= highLevelEventMask;
+  while (!ReceiveNextEvent (0, NULL, kEventDurationNoWait,
+                           kEventRemoveFromQueue, &eventRef))
+#else /* !USE_CARBON_EVENTS */
+  while (mac_wait_next_event (&er, 0, true))
+#endif /* !USE_CARBON_EVENTS */
+    {
+      int do_help = 0;
+      struct frame *f;
+
+      /* It is necessary to set this (additional) argument slot of an
+        event to nil because keyboard.c protects incompletely
+        processed event from being garbage collected by placing them
+        in the kbd_buffer_gcpro vector.  */
+      EVENT_INIT (inev);
+      inev.kind = NO_EVENT;
+      inev.arg = Qnil;
 
 #if USE_CARBON_EVENTS
-  rneResult = ReceiveNextEvent (0, NULL,
-                               expected
-                               ? TicksToEventTime (app_sleep_time)
-                               : 0,
-                               kEventRemoveFromQueue, &eventRef);
-  if (!rneResult)
-    {
       /* Handle new events */
       if (!mac_convert_event_ref (eventRef, &er))
        switch (GetEventClass (eventRef))
          {
+         case kEventClassWindow:
+           if (GetEventKind (eventRef) == kEventWindowBoundsChanged)
+             {
+               WindowPtr window_ptr;
+               GetEventParameter(eventRef, kEventParamDirectObject,
+                                 typeWindowRef, NULL, sizeof(WindowPtr),
+                                 NULL, &window_ptr);
+               f = mac_window_to_frame (window_ptr);
+               if (f && !f->async_iconified)
+                 x_real_positions (f, &f->left_pos, &f->top_pos);
+               SendEventToEventTarget (eventRef, toolbox_dispatcher);
+             }
+           break;
          case kEventClassMouse:
            if (GetEventKind (eventRef) == kEventMouseWheelMoved)
              {
                SInt32 delta;
                Point point;
-               WindowPtr window_ptr = FrontNonFloatingWindow ();
-               struct mac_output *mwp = (mac_output *) GetWRefCon (window_ptr);
+               WindowPtr window_ptr = front_emacs_window ();
+
                if (!IsValidWindowPtr (window_ptr))
                  {
                    SysBeep(1);
-                   UNBLOCK_INPUT;
-                   return 0;
+                   break;
                  }
 
                GetEventParameter(eventRef, kEventParamMouseWheelDelta,
@@ -7682,445 +8495,596 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
                GetEventParameter(eventRef, kEventParamMouseLocation,
                                  typeQDPoint, NULL, sizeof (Point),
                                  NULL, &point);
-               bufp->kind = WHEEL_EVENT;
-               bufp->code = 0;
-               bufp->modifiers = (mac_event_to_emacs_modifiers(eventRef)
-                                  | ((delta < 0) ? down_modifier
-                                                 : up_modifier));
-               SetPort (GetWindowPort (window_ptr));
+               inev.kind = WHEEL_EVENT;
+               inev.code = 0;
+               inev.modifiers = (mac_event_to_emacs_modifiers (eventRef)
+                                 | ((delta < 0) ? down_modifier
+                                    : up_modifier));
+               SetPortWindowPort (window_ptr);
                GlobalToLocal (&point);
-               XSETINT (bufp->x, point.h);
-               XSETINT (bufp->y, point.v);
-               XSETFRAME (bufp->frame_or_window, mwp->mFP);
-               bufp->timestamp = EventTimeToTicks (GetEventTime (eventRef))*(1000/60);
-               count++;
+               XSETINT (inev.x, point.h);
+               XSETINT (inev.y, point.v);
+               XSETFRAME (inev.frame_or_window,
+                          mac_window_to_frame (window_ptr));
+               inev.timestamp = EventTimeToTicks (GetEventTime (eventRef))*(1000/60);
              }
            else
-             SendEventToEventTarget (eventRef, GetEventDispatcherTarget ());
+             SendEventToEventTarget (eventRef, toolbox_dispatcher);
 
            break;
+
          default:
            /* Send the event to the appropriate receiver.  */
-           SendEventToEventTarget (eventRef, GetEventDispatcherTarget ());
+           SendEventToEventTarget (eventRef, toolbox_dispatcher);
          }
       else
-#else
-  if (WaitNextEvent (event_mask, &er, (expected ? app_sleep_time : 0L), NULL))
 #endif /* USE_CARBON_EVENTS */
-    switch (er.what)
-      {
-      case mouseDown:
-      case mouseUp:
+      switch (er.what)
        {
-         WindowPtr window_ptr = FrontWindow ();
-         SInt16 part_code;
+       case mouseDown:
+       case mouseUp:
+         {
+           WindowPtr window_ptr;
+           SInt16 part_code;
+           int tool_bar_p = 0;
 
 #if USE_CARBON_EVENTS
-         /* This is needed to send mouse events like aqua window buttons
-            to the correct handler.  */
-         if (eventNotHandledErr != SendEventToEventTarget (eventRef, GetEventDispatcherTarget ())) {
-           break;
-         }
-
-         if (!is_emacs_window(window_ptr))
-           break;
+           /* This is needed to send mouse events like aqua window
+              buttons to the correct handler.  */
+           if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
+               != eventNotHandledErr)
+             break;
 #endif
 
-          if (mouse_tracking_in_progress == mouse_tracking_scroll_bar
-             && er.what == mouseUp)
-            {
-             struct mac_output *mwp = (mac_output *) GetWRefCon (window_ptr);
-             Point mouse_loc = er.where;
+           if (dpyinfo->grabbed && last_mouse_frame
+               && FRAME_LIVE_P (last_mouse_frame))
+             {
+               window_ptr = FRAME_MAC_WINDOW (last_mouse_frame);
+               part_code = inContent;
+             }
+           else
+             {
+               part_code = FindWindow (er.where, &window_ptr);
+               if (tip_window && window_ptr == tip_window)
+                 {
+                   HideWindow (tip_window);
+                   part_code = FindWindow (er.where, &window_ptr);
+                 }
+             }
 
-             /* Convert to local coordinates of new window.  */
-#if TARGET_API_MAC_CARBON
-              SetPort (GetWindowPort (window_ptr));
-#else
-              SetPort (window_ptr);
-#endif
+           if (er.what != mouseDown && part_code != inContent)
+             break;
+
+           switch (part_code)
+             {
+             case inMenuBar:
+               f = mac_window_to_frame (front_emacs_window ());
+               saved_menu_event_location = er.where;
+               inev.kind = MENU_BAR_ACTIVATE_EVENT;
+               XSETFRAME (inev.frame_or_window, f);
+               break;
+
+             case inContent:
+               if (window_ptr != front_emacs_window ())
+                 SelectWindow (window_ptr);
+               else
+                 {
+                   SInt16 control_part_code;
+                   ControlHandle ch;
+                   Point mouse_loc = er.where;
 
-             GlobalToLocal (&mouse_loc);
+                   f = mac_window_to_frame (window_ptr);
+                   /* convert to local coordinates of new window */
+                   SetPortWindowPort (window_ptr);
 
-#if USE_CARBON_EVENTS
-             bufp->code = mac_get_mouse_btn (eventRef);
+                   GlobalToLocal (&mouse_loc);
+#if TARGET_API_MAC_CARBON
+                   ch = FindControlUnderMouse (mouse_loc, window_ptr,
+                                               &control_part_code);
 #else
-             bufp->code = 0;  /* only one mouse button */
+                   control_part_code = FindControl (mouse_loc, window_ptr,
+                                                    &ch);
 #endif
-              bufp->kind = SCROLL_BAR_CLICK_EVENT;
-              bufp->frame_or_window = tracked_scroll_bar->window;
-              bufp->part = scroll_bar_handle;
+
 #if USE_CARBON_EVENTS
-             bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
+                   inev.code = mac_get_mouse_btn (eventRef);
+                   inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
 #else
-             bufp->modifiers = mac_to_emacs_modifiers (er.modifiers);
+                   inev.code = mac_get_emulated_btn (er.modifiers);
+                   inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
 #endif
-              bufp->modifiers |= up_modifier;
-             bufp->timestamp = er.when * (1000 / 60);
-               /* ticks to milliseconds */
-
-              XSETINT (bufp->x, tracked_scroll_bar->left + 2);
-              XSETINT (bufp->y, mouse_loc.v - 24);
-              tracked_scroll_bar->dragging = Qnil;
-              mouse_tracking_in_progress = mouse_tracking_none;
-              tracked_scroll_bar = NULL;
-              count++;
-              break;
-            }
-
-         part_code = FindWindow (er.where, &window_ptr);
-
-         switch (part_code)
-           {
-           case inMenuBar:
-              {
-                struct frame *f = ((mac_output *)
-                                  GetWRefCon (FrontWindow ()))->mFP;
-                saved_menu_event_location = er.where;
-                bufp->kind = MENU_BAR_ACTIVATE_EVENT;
-                XSETFRAME (bufp->frame_or_window, f);
-                count++;
-              }
-             break;
+                   XSETINT (inev.x, mouse_loc.h);
+                   XSETINT (inev.y, mouse_loc.v);
+                   inev.timestamp = er.when * (1000 / 60);
+                   /* ticks to milliseconds */
 
-           case inContent:
-             if (window_ptr != FrontWindow ())
-               SelectWindow (window_ptr);
-             else
-               {
-                 SInt16 control_part_code;
-                 ControlHandle ch;
-                 struct mac_output *mwp = (mac_output *)
-                   GetWRefCon (window_ptr);
-                 Point mouse_loc = er.where;
-
-                 /* convert to local coordinates of new window */
+                   if (dpyinfo->grabbed && tracked_scroll_bar
 #if TARGET_API_MAC_CARBON
-                  SetPort (GetWindowPort (window_ptr));
+                       || ch != 0
 #else
-                  SetPort (window_ptr);
+                       || control_part_code != 0
 #endif
+                       )
+                     {
+                       struct scroll_bar *bar;
+
+                       if (dpyinfo->grabbed && tracked_scroll_bar)
+                         {
+                           bar = tracked_scroll_bar;
+                           control_part_code = kControlIndicatorPart;
+                         }
+                       else
+                         bar = (struct scroll_bar *) GetControlReference (ch);
+                       x_scroll_bar_handle_click (bar, control_part_code,
+                                                  &er, &inev);
+                       if (er.what == mouseDown
+                           && control_part_code == kControlIndicatorPart)
+                         tracked_scroll_bar = bar;
+                       else
+                         tracked_scroll_bar = NULL;
+                     }
+                   else
+                     {
+                       Lisp_Object window;
+                       int x = mouse_loc.h;
+                       int y = mouse_loc.v;
+
+                       window = window_from_coordinates (f, x, y, 0, 0, 0, 1);
+                       if (EQ (window, f->tool_bar_window))
+                         {
+                           if (er.what == mouseDown)
+                             handle_tool_bar_click (f, x, y, 1, 0);
+                           else
+                             handle_tool_bar_click (f, x, y, 0,
+                                                    inev.modifiers);
+                           tool_bar_p = 1;
+                         }
+                       else
+                         {
+                           XSETFRAME (inev.frame_or_window, f);
+                           inev.kind = MOUSE_CLICK_EVENT;
+                         }
+                     }
+
+                   if (er.what == mouseDown)
+                     {
+                       dpyinfo->grabbed |= (1 << inev.code);
+                       last_mouse_frame = f;
+                       /* Ignore any mouse motion that happened
+                          before this event; any subsequent
+                          mouse-movement Emacs events should reflect
+                          only motion after the ButtonPress.  */
+                       if (f != 0)
+                         f->mouse_moved = 0;
+
+                       if (!tool_bar_p)
+                         last_tool_bar_item = -1;
+                     }
+                   else
+                     {
+                       if ((dpyinfo->grabbed & (1 << inev.code)) == 0)
+                         /* If a button is released though it was not
+                            previously pressed, that would be because
+                            of multi-button emulation.  */
+                         dpyinfo->grabbed = 0;
+                       else
+                         dpyinfo->grabbed &= ~(1 << inev.code);
+                     }
+
+                   switch (er.what)
+                     {
+                     case mouseDown:
+                       inev.modifiers |= down_modifier;
+                       break;
+                     case mouseUp:
+                       inev.modifiers |= up_modifier;
+                       break;
+                     }
+                 }
+               break;
 
-                 GlobalToLocal (&mouse_loc);
+             case inDrag:
 #if TARGET_API_MAC_CARBON
-                 ch = FindControlUnderMouse (mouse_loc, window_ptr,
-                                             &control_part_code);
-#else
-                 control_part_code = FindControl (mouse_loc, window_ptr, &ch);
-#endif
+               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.  */
+               {
+                 struct frame *f = mac_window_to_frame (window_ptr);
+
+                 if (f && !f->async_iconified)
+                   x_real_positions (f, &f->left_pos, &f->top_pos);
+               }
+               break;
+
+             case inGoAway:
+               if (TrackGoAway (window_ptr, er.where))
+                 {
+                   inev.kind = DELETE_WINDOW_EVENT;
+                   XSETFRAME (inev.frame_or_window,
+                              mac_window_to_frame (window_ptr));
+                 }
+               break;
+
+               /* window resize handling added --ben */
+             case inGrow:
+               do_grow_window (window_ptr, &er);
+               break;
 
+               /* window zoom handling added --ben */
+             case inZoomIn:
+             case inZoomOut:
+               if (TrackBox (window_ptr, er.where, part_code))
+                 do_zoom_window (window_ptr, part_code);
+               break;
+
+             default:
+               break;
+             }
+         }
+         break;
+
+       case updateEvt:
 #if USE_CARBON_EVENTS
-                 bufp->code = mac_get_mouse_btn (eventRef);
-#else
-                 bufp->code = 0;  /* only one mouse button */
+         if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
+             != eventNotHandledErr)
+           break;
 #endif
-                 XSETINT (bufp->x, mouse_loc.h);
-                 XSETINT (bufp->y, mouse_loc.v);
-                 bufp->timestamp = er.when * (1000 / 60);
-                   /* ticks to milliseconds */
+         do_window_update ((WindowPtr) er.message);
+         break;
 
-#if TARGET_API_MAC_CARBON
-                 if (ch != 0)
-#else
-                 if (control_part_code != 0)
+       case osEvt:
+#if USE_CARBON_EVENTS
+         if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
+             != eventNotHandledErr)
+           break;
 #endif
-                   {
-                     struct scroll_bar *bar = (struct scroll_bar *)
-                       GetControlReference (ch);
-                     x_scroll_bar_handle_click (bar, control_part_code, &er,
-                                                bufp);
-                     if (er.what == mouseDown
-                         && control_part_code == kControlIndicatorPart)
-                       {
-                         mouse_tracking_in_progress
-                           = mouse_tracking_scroll_bar;
-                         tracked_scroll_bar = bar;
-                       }
-                     else
-                       {
-                         mouse_tracking_in_progress = mouse_tracking_none;
-                         tracked_scroll_bar = NULL;
-                       }
-                   }
-                 else
-                   {
-                     bufp->kind = MOUSE_CLICK_EVENT;
-                     XSETFRAME (bufp->frame_or_window, mwp->mFP);
-                     if (er.what == mouseDown)
-                       mouse_tracking_in_progress
-                         = mouse_tracking_mouse_movement;
-                     else
-                       mouse_tracking_in_progress = mouse_tracking_none;
-                   }
+         switch ((er.message >> 24) & 0x000000FF)
+           {
+           case suspendResumeMessage:
+             if ((er.message & resumeFlag) == 1)
+               do_app_resume ();
+             else
+               do_app_suspend ();
+             break;
 
-#if USE_CARBON_EVENTS
-                 bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
-#else
-                 bufp->modifiers = mac_to_emacs_modifiers (er.modifiers);
+           case mouseMovedMessage:
+#if !USE_CARBON_EVENTS
+             SetRectRgn (mouse_region, er.where.h, er.where.v,
+                         er.where.h + 1, er.where.v + 1);
 #endif
+             previous_help_echo_string = help_echo_string;
+             help_echo_string = help_echo_object = help_echo_window = Qnil;
+             help_echo_pos = -1;
 
-                 switch (er.what)
-                   {
-                   case mouseDown:
-                     bufp->modifiers |= down_modifier;
-                     break;
-                   case mouseUp:
-                     bufp->modifiers |= up_modifier;
-                     break;
-                   }
+             do_mouse_moved (er.where, &f);
 
-                 count++;
-               }
+             /* If the contents of the global variable
+                help_echo_string has changed, generate a
+                HELP_EVENT.  */
+             if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
+               do_help = 1;
              break;
+           }
+         break;
 
-           case inDrag:
-#if TARGET_API_MAC_CARBON
-             {
-               BitMap bm;
+       case activateEvt:
+         {
+           WindowPtr window_ptr = (WindowPtr) er.message;
 
-               GetQDGlobalsScreenBits (&bm);
-               DragWindow (window_ptr, er.where, &bm.bounds);
-             }
-#else /* not TARGET_API_MAC_CARBON */
-             DragWindow (window_ptr, er.where, &qd.screenBits.bounds);
-#endif /* not TARGET_API_MAC_CARBON */
+#if USE_CARBON_EVENTS
+           if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
+               != eventNotHandledErr)
              break;
+#endif
+           if (window_ptr == tip_window)
+             {
+               HideWindow (tip_window);
+               break;
+             }
 
-           case inGoAway:
-             if (TrackGoAway (window_ptr, er.where))
-               {
-                 bufp->kind = DELETE_WINDOW_EVENT;
-                 XSETFRAME (bufp->frame_or_window,
-                            ((mac_output *) GetWRefCon (window_ptr))->mFP);
-                 count++;
-               }
+           if (!is_emacs_window (window_ptr))
              break;
 
-           /* window resize handling added --ben */
-           case inGrow:
-             do_grow_window(window_ptr, &er);
-             break;
+           f = mac_window_to_frame (window_ptr);
 
-           /* window zoom handling added --ben */
-           case inZoomIn:
-           case inZoomOut:
-             if (TrackBox (window_ptr, er.where, part_code))
-               do_zoom_window (window_ptr, part_code);
-             break;
+           if ((er.modifiers & activeFlag) != 0)
+             {
+               /* A window has been activated */
+               Point mouse_loc = er.where;
+
+               x_new_focus_frame (dpyinfo, f);
+               activate_scroll_bars (f);
+
+               SetPortWindowPort (window_ptr);
+               GlobalToLocal (&mouse_loc);
+               /* 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);
+             }
+           else
+             {
+               /* A window has been deactivated */
+               dpyinfo->grabbed = 0;
 
-           default:
-             break;
-           }
-       }
-       break;
+               if (f == dpyinfo->x_focus_frame)
+                 {
+                   x_new_focus_frame (dpyinfo, 0);
+                   deactivate_scroll_bars (f);
+                 }
 
-      case updateEvt:
-      case osEvt:
-      case activateEvt:
-#if USE_CARBON_EVENTS
-       if (eventNotHandledErr == SendEventToEventTarget (eventRef, GetEventDispatcherTarget ()))
-#endif
-       do_events (&er);
-       break;
 
-      case keyDown:
-      case autoKey:
-       {
-         int keycode = (er.message & keyCodeMask) >> 8;
-         int xkeysym;
+               if (f == dpyinfo->mouse_face_mouse_frame)
+                 {
+                   /* 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;
+                 }
+
+               /* Generate a nil HELP_EVENT to cancel a help-echo.
+                  Do it only if there's something to cancel.
+                  Otherwise, the startup message is cleared when the
+                  mouse leaves the frame.  */
+               if (any_help_event_p)
+                 do_help = -1;
+             }
+         }
+         break;
+
+       case keyDown:
+       case autoKey:
+         {
+           int keycode = (er.message & keyCodeMask) >> 8;
+           int xkeysym;
 
 #if USE_CARBON_EVENTS
-         /* 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 ((!NILP (Vmac_pass_command_to_system)
-              || !(er.modifiers & cmdKey))
-             && (!NILP (Vmac_pass_control_to_system)
-                 || !(er.modifiers & controlKey)))
-           {
-             OSStatus err;
-             err = SendEventToEventTarget (eventRef,
-                                           GetEventDispatcherTarget ());
-             if (err != eventNotHandledErr)
+           /* 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 ((!NILP (Vmac_pass_command_to_system)
+                || !(er.modifiers & cmdKey))
+               && (!NILP (Vmac_pass_control_to_system)
+                   || !(er.modifiers & controlKey)))
+             if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
+                 != eventNotHandledErr)
                break;
-           }
 #endif
 
-         if (!IsValidWindowPtr (FrontNonFloatingWindow ()))
-           {
-             SysBeep (1);
-             UNBLOCK_INPUT;
-             return 0;
-           }
-
-         ObscureCursor ();
+#if TARGET_API_MAC_CARBON
+           if (!IsValidWindowPtr (front_emacs_window ()))
+             {
+               SysBeep (1);
+               break;
+             }
+#endif
 
-         if (keycode_to_xkeysym (keycode, &xkeysym))
-           {
-             bufp->code = 0xff00 | xkeysym;
-             bufp->kind = NON_ASCII_KEYSTROKE_EVENT;
-           }
-         else
-           {
-             if (er.modifiers & (controlKey |
-                                 (NILP (Vmac_command_key_is_meta) ? optionKey
-                                  : cmdKey)))
-               {
-                 /* 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 */
-                 int new_modifiers = er.modifiers & 0xe600;
-                 /* mask off option and command */
-                 int new_keycode = keycode | new_modifiers;
-                 Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
-                 unsigned long some_state = 0;
-                 bufp->code = KeyTranslate (kchr_ptr, new_keycode,
-                                            &some_state) & 0xff;
-               }
-             else
-               bufp->code = er.message & charCodeMask;
-             bufp->kind = ASCII_KEYSTROKE_EVENT;
-           }
-       }
+           ObscureCursor ();
 
-       /* If variable mac-convert-keyboard-input-to-latin-1 is non-nil,
-          convert non-ASCII characters typed at the Mac keyboard
-          (presumed to be in the Mac Roman encoding) to iso-latin-1
-          encoding before they are passed to Emacs.  This enables the
-          Mac keyboard to be used to enter non-ASCII iso-latin-1
-          characters directly.  */
-       if (mac_keyboard_text_encoding != kTextEncodingMacRoman
-           && bufp->kind == ASCII_KEYSTROKE_EVENT && bufp->code >= 128)
-         {
-           static TECObjectRef converter = NULL;
-           OSStatus the_err = noErr;
-           OSStatus convert_status = noErr;
+           if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
+             {
+               clear_mouse_face (dpyinfo);
+               dpyinfo->mouse_face_hidden = 1;
+             }
 
-           if (converter ==  NULL)
+           if (keycode_to_xkeysym (keycode, &xkeysym))
              {
-               the_err = TECCreateConverter (&converter,
-                                             kTextEncodingMacRoman,
-                                             mac_keyboard_text_encoding);
-               current_mac_keyboard_text_encoding
-                 = mac_keyboard_text_encoding;
+               inev.code = 0xff00 | xkeysym;
+               inev.kind = NON_ASCII_KEYSTROKE_EVENT;
              }
-           else if (mac_keyboard_text_encoding
-                    != current_mac_keyboard_text_encoding)
+           else
              {
-               /* Free the converter for the current encoding before
-                  creating a new one.  */
-               TECDisposeConverter (converter);
-               the_err = TECCreateConverter (&converter,
-                                             kTextEncodingMacRoman,
-                                             mac_keyboard_text_encoding);
-               current_mac_keyboard_text_encoding
-                 = mac_keyboard_text_encoding;
+               if (er.modifiers & (controlKey |
+                                   (NILP (Vmac_command_key_is_meta) ? optionKey
+                                    : cmdKey)))
+                 {
+                   /* 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 */
+                   int new_modifiers = er.modifiers & 0xe600;
+                   /* mask off option and command */
+                   int new_keycode = keycode | new_modifiers;
+                   Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
+                   unsigned long some_state = 0;
+                   inev.code = KeyTranslate (kchr_ptr, new_keycode,
+                                             &some_state) & 0xff;
+                 } else if (!NILP(Vmac_option_modifier) && (er.modifiers & optionKey))
+            {
+                /* When using the option key as an emacs modifier, convert
+                   the pressed key code back to one without the Mac option
+                   modifier applied. */
+                int new_modifiers = er.modifiers & ~optionKey;
+                int new_keycode = keycode | new_modifiers;
+                Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
+                unsigned long some_state = 0;
+                inev.code = KeyTranslate (kchr_ptr, new_keycode,
+                                          &some_state) & 0xff;
+            }
+               else
+                 inev.code = er.message & charCodeMask;
+               inev.kind = ASCII_KEYSTROKE_EVENT;
              }
+         }
 
-           if (the_err == noErr)
-             {
-               unsigned char ch = bufp->code;
-               ByteCount actual_input_length, actual_output_length;
-               unsigned char outch;
+         /* If variable mac-convert-keyboard-input-to-latin-1 is
+            non-nil, convert non-ASCII characters typed at the Mac
+            keyboard (presumed to be in the Mac Roman encoding) to
+            iso-latin-1 encoding before they are passed to Emacs.
+            This enables the Mac keyboard to be used to enter
+            non-ASCII iso-latin-1 characters directly.  */
+         if (mac_keyboard_text_encoding != kTextEncodingMacRoman
+             && inev.kind == ASCII_KEYSTROKE_EVENT && inev.code >= 128)
+           {
+             static TECObjectRef converter = NULL;
+             OSStatus the_err = noErr;
+             OSStatus convert_status = noErr;
 
-               convert_status = TECConvertText (converter, &ch, 1,
-                                                &actual_input_length,
-                                                &outch, 1,
+             if (converter ==  NULL)
+               {
+                 the_err = TECCreateConverter (&converter,
+                                               kTextEncodingMacRoman,
+                                               mac_keyboard_text_encoding);
+                 current_mac_keyboard_text_encoding
+                   = mac_keyboard_text_encoding;
+               }
+             else if (mac_keyboard_text_encoding
+                      != current_mac_keyboard_text_encoding)
+               {
+                 /* Free the converter for the current encoding
+                    before creating a new one.  */
+                 TECDisposeConverter (converter);
+                 the_err = TECCreateConverter (&converter,
+                                               kTextEncodingMacRoman,
+                                               mac_keyboard_text_encoding);
+                 current_mac_keyboard_text_encoding
+                   = mac_keyboard_text_encoding;
+               }
+
+             if (the_err == noErr)
+               {
+                 unsigned char ch = inev.code;
+                 ByteCount actual_input_length, actual_output_length;
+                 unsigned char outbuf[32];
+
+                 convert_status = TECConvertText (converter, &ch, 1,
+                                                  &actual_input_length,
+                                                  outbuf, 1,
+                                                  &actual_output_length);
+                 if (convert_status == noErr
+                     && actual_input_length == 1
+                     && actual_output_length == 1)
+                   inev.code = *outbuf;
+
+                 /* Reset internal states of the converter object.
+                    If it fails, create another one. */
+                 convert_status = TECFlushText (converter, outbuf,
+                                                sizeof (outbuf),
                                                 &actual_output_length);
-               if (convert_status == noErr
-                   && actual_input_length == 1
-                   && actual_output_length == 1)
-                 bufp->code = outch;
-             }
-         }
+                 if (convert_status != noErr)
+                   {
+                     TECDisposeConverter (converter);
+                     TECCreateConverter (&converter,
+                                         kTextEncodingMacRoman,
+                                         mac_keyboard_text_encoding);
+                   }
+               }
+           }
 
 #if USE_CARBON_EVENTS
-       bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
+         inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
 #else
-       bufp->modifiers = mac_to_emacs_modifiers (er.modifiers);
+         inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
 #endif
+         XSETFRAME (inev.frame_or_window,
+                    mac_window_to_frame (front_emacs_window ()));
+         inev.timestamp = er.when * (1000 / 60);  /* ticks to milliseconds */
+         break;
 
-       {
-         mac_output *mwp
-           = (mac_output *) GetWRefCon (FrontNonFloatingWindow ());
-         XSETFRAME (bufp->frame_or_window, mwp->mFP);
-       }
-
-       bufp->timestamp = er.when * (1000 / 60);  /* ticks to milliseconds */
-
-       count++;
-       break;
-
-      case kHighLevelEvent:
-        drag_and_drop_file_list = Qnil;
+       case kHighLevelEvent:
+         drag_and_drop_file_list = Qnil;
 
-        AEProcessAppleEvent(&er);
+         AEProcessAppleEvent(&er);
 
-        /* Build a DRAG_N_DROP_EVENT type event as is done in
-           constuct_drag_n_drop in w32term.c.  */
-        if (!NILP (drag_and_drop_file_list))
-          {
-            struct frame *f = NULL;
-            WindowPtr wp;
-            Lisp_Object frame;
+         /* Build a DRAG_N_DROP_EVENT type event as is done in
+            constuct_drag_n_drop in w32term.c.  */
+         if (!NILP (drag_and_drop_file_list))
+           {
+             struct frame *f = NULL;
+             WindowPtr wp;
+             Lisp_Object frame;
 
-            wp = FrontNonFloatingWindow ();
+             wp = front_emacs_window ();
 
-           if (!wp)
-             {
-               struct frame *f = XFRAME (XCAR (Vframe_list));
-               CollapseWindow (FRAME_MAC_WINDOW (f), false);
-               wp = FrontNonFloatingWindow ();
-             }
+             if (!wp)
+               {
+                 struct frame *f = XFRAME (XCAR (Vframe_list));
+                 CollapseWindow (FRAME_MAC_WINDOW (f), false);
+                 wp = front_emacs_window ();
+               }
 
-            if (wp && is_emacs_window(wp))
-               f = ((mac_output *) GetWRefCon (wp))->mFP;
+             if (wp)
+               f = mac_window_to_frame (wp);
 
-            bufp->kind = DRAG_N_DROP_EVENT;
-            bufp->code = 0;
-            bufp->timestamp = er.when * (1000 / 60);
+             inev.kind = DRAG_N_DROP_EVENT;
+             inev.code = 0;
+             inev.timestamp = er.when * (1000 / 60);
              /* ticks to milliseconds */
 #if USE_CARBON_EVENTS
-           bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
+             inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
 #else
-           bufp->modifiers = mac_to_emacs_modifiers (er.modifiers);
+             inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
 #endif
 
-            XSETINT (bufp->x, 0);
-            XSETINT (bufp->y, 0);
+             XSETINT (inev.x, 0);
+             XSETINT (inev.y, 0);
 
-            XSETFRAME (frame, f);
-            bufp->frame_or_window = Fcons (frame, drag_and_drop_file_list);
+             XSETFRAME (frame, f);
+             inev.frame_or_window = Fcons (frame, drag_and_drop_file_list);
 
-            /* Regardless of whether Emacs was suspended or in the
-               foreground, ask it to redraw its entire screen.
-               Otherwise parts of the screen can be left in an
-               inconsistent state.  */
-            if (wp)
+             /* Regardless of whether Emacs was suspended or in the
+                foreground, ask it to redraw its entire screen.
+                Otherwise parts of the screen can be left in an
+                inconsistent state.  */
+             if (wp)
 #if TARGET_API_MAC_CARBON
-             {
-               Rect r;
+               {
+                 Rect r;
 
-               GetWindowPortBounds (wp, &r);
-               InvalWindowRect (wp, &r);
-             }
+                 GetWindowPortBounds (wp, &r);
+                 InvalWindowRect (wp, &r);
+               }
 #else /* not TARGET_API_MAC_CARBON */
-              InvalRect (&(wp->portRect));
+                InvalRect (&(wp->portRect));
 #endif /* not TARGET_API_MAC_CARBON */
-
-            count++;
-          }
-      default:
-       break;
-      }
+           }
+       default:
+         break;
+       }
 #if USE_CARBON_EVENTS
       ReleaseEvent (eventRef);
-    }
 #endif
 
+      if (inev.kind != NO_EVENT)
+       {
+         kbd_buffer_store_event_hold (&inev, hold_quit);
+         count++;
+       }
+
+      if (do_help
+         && !(hold_quit && hold_quit->kind != NO_EVENT))
+       {
+         Lisp_Object frame;
+
+         if (f)
+           XSETFRAME (frame, f);
+         else
+           frame = Qnil;
+
+         if (do_help > 0)
+           {
+             any_help_event_p = 1;
+             gen_help_event (help_echo_string, frame, help_echo_window,
+                             help_echo_object, help_echo_pos);
+           }
+         else
+           {
+             help_echo_string = Qnil;
+             gen_help_event (Qnil, frame, Qnil, Qnil, 0);
+           }
+         count++;
+       }
+
+    }
+
   /* If the focus was just given to an autoraising frame,
      raise it now.  */
   /* ??? This ought to be able to handle more than one such frame.  */
@@ -8134,54 +9098,7 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
   check_alarm ();  /* simulate the handling of a SIGALRM */
 #endif
 
-  {
-    static Point old_mouse_pos = { -1, -1 };
-
-    if (app_is_suspended)
-      {
-        old_mouse_pos.h = -1;
-        old_mouse_pos.v = -1;
-      }
-    else
-      {
-        Point mouse_pos;
-        WindowPtr wp;
-        struct frame *f;
-        Lisp_Object bar;
-        struct scroll_bar *sb;
-
-        wp = FrontWindow ();
-       if (is_emacs_window (wp))
-         {
-           f = ((mac_output *) GetWRefCon (wp))->mFP;
-
-#if TARGET_API_MAC_CARBON
-           SetPort (GetWindowPort (wp));
-#else
-           SetPort (wp);
-#endif
-
-           GetMouse (&mouse_pos);
-
-           if (!EqualPt (mouse_pos, old_mouse_pos))
-             {
-               if (mouse_tracking_in_progress == mouse_tracking_scroll_bar
-                   && tracked_scroll_bar)
-                 x_scroll_bar_note_movement (tracked_scroll_bar,
-                                             mouse_pos.v
-                                             - XINT (tracked_scroll_bar->top),
-                                             TickCount() * (1000 / 60));
-               else
-                 note_mouse_movement (f, &mouse_pos);
-
-               old_mouse_pos = mouse_pos;
-             }
-         }
-      }
-  }
-
   UNBLOCK_INPUT;
-
   return count;
 }
 
@@ -8204,106 +9121,70 @@ __convert_from_newlines (unsigned char * p, size_t * n)
 }
 #endif
 
-
-/* Initialize the struct pointed to by MW to represent a new COLS x
-   ROWS Macintosh window, using font with name FONTNAME and size
-   FONTSIZE.  */
+#ifdef MAC_OS8
 void
-NewMacWindow (FRAME_PTR fp)
+make_mac_terminal_frame (struct frame *f)
 {
-  mac_output *mwp;
-#if TARGET_API_MAC_CARBON
-  static int making_terminal_window = 0;
-#else
-  static int making_terminal_window = 1;
-#endif
-
-  mwp = fp->output_data.mac;
-
-  if (making_terminal_window)
-    {
-      if (!(mwp->mWP = GetNewCWindow (TERM_WINDOW_RESOURCE, NULL,
-                                     (WindowPtr) -1)))
-        abort ();
-      making_terminal_window = 0;
-    }
-  else
-    if (!(mwp->mWP = GetNewCWindow (WINDOW_RESOURCE, NULL, (WindowPtr) -1)))
-      abort ();
-
-  SetWRefCon (mwp->mWP, (long) mwp);
-    /* so that update events can find this mac_output struct */
-  mwp->mFP = fp;  /* point back to emacs frame */
-
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (mwp->mWP));
-#else
-  SetPort (mwp->mWP);
-#endif
+  Lisp_Object frame;
+  Rect r;
 
-  mwp->fontset = -1;
+  XSETFRAME (frame, f);
 
-  SizeWindow (mwp->mWP, FRAME_PIXEL_WIDTH (fp), FRAME_PIXEL_HEIGHT (fp), false);
-  ShowWindow (mwp->mWP);
+  f->output_method = output_mac;
+  f->output_data.mac = (struct mac_output *)
+    xmalloc (sizeof (struct mac_output));
+  bzero (f->output_data.mac, sizeof (struct mac_output));
 
-}
+  XSETFRAME (FRAME_KBOARD (f)->Vdefault_minibuffer_frame, f);
 
+  FRAME_COLS (f) = 96;
+  FRAME_LINES (f) = 4;
 
-void
-make_mac_frame (struct frame *f)
-{
   FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
   FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_right;
 
   FRAME_DESIRED_CURSOR (f) = FILLED_BOX_CURSOR;
 
-  NewMacWindow(f);
-
   f->output_data.mac->cursor_pixel = 0;
   f->output_data.mac->border_pixel = 0x00ff00;
   f->output_data.mac->mouse_pixel = 0xff00ff;
   f->output_data.mac->cursor_foreground_pixel = 0x0000ff;
 
+  f->output_data.mac->text_cursor = GetCursor (iBeamCursor);
+  f->output_data.mac->nontext_cursor = &arrow_cursor;
+  f->output_data.mac->modeline_cursor = &arrow_cursor;
+  f->output_data.mac->hand_cursor = &arrow_cursor;
+  f->output_data.mac->hourglass_cursor = GetCursor (watchCursor);
+  f->output_data.mac->horizontal_drag_cursor = &arrow_cursor;
+
   FRAME_FONTSET (f) = -1;
-  f->output_data.mac->scroll_bar_foreground_pixel = -1;
-  f->output_data.mac->scroll_bar_background_pixel = -1;
   f->output_data.mac->explicit_parent = 0;
-  f->left_pos = 4;
-  f->top_pos = 4;
+  f->left_pos = 8;
+  f->top_pos = 32;
   f->border_width = 0;
 
   f->internal_border_width = 0;
 
-  f->output_method = output_mac;
-
   f->auto_raise = 1;
   f->auto_lower = 1;
 
   f->new_text_cols = 0;
   f->new_text_lines = 0;
-}
-
-void
-make_mac_terminal_frame (struct frame *f)
-{
-  Lisp_Object frame;
 
-  XSETFRAME (frame, f);
+  SetRect (&r, f->left_pos, f->top_pos,
+           f->left_pos + FRAME_PIXEL_WIDTH (f),
+           f->top_pos + FRAME_PIXEL_HEIGHT (f));
 
-  f->output_method = output_mac;
-  f->output_data.mac = (struct mac_output *)
-    xmalloc (sizeof (struct mac_output));
-  bzero (f->output_data.mac, sizeof (struct mac_output));
-  FRAME_FONTSET (f) = -1;
-  f->output_data.mac->scroll_bar_foreground_pixel = -1;
-  f->output_data.mac->scroll_bar_background_pixel = -1;
-
-  XSETFRAME (FRAME_KBOARD (f)->Vdefault_minibuffer_frame, f);
+  BLOCK_INPUT;
 
-  FRAME_COLS (f) = 96;
-  FRAME_LINES (f) = 4;
+  if (!(FRAME_MAC_WINDOW (f) =
+       NewCWindow (NULL, &r, "\p", true, dBoxProc,
+                   (WindowPtr) -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 */
 
-  make_mac_frame (f);
+  UNBLOCK_INPUT;
 
   x_make_gc (f);
 
@@ -8320,80 +9201,13 @@ make_mac_terminal_frame (struct frame *f)
                             Fcons (Fcons (Qbackground_color,
                                           build_string ("white")), Qnil));
 }
+#endif
 
 \f
 /***********************************************************************
                            Initialization
  ***********************************************************************/
 
-#ifdef USE_X_TOOLKIT
-static XrmOptionDescRec emacs_options[] = {
-  {"-geometry",        ".geometry", XrmoptionSepArg, NULL},
-  {"-iconic",  ".iconic", XrmoptionNoArg, (XtPointer) "yes"},
-
-  {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
-     XrmoptionSepArg, NULL},
-  {"-ib",      "*EmacsScreen.internalBorderWidth", XrmoptionSepArg, NULL},
-
-  {"-T",       "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
-  {"-wn",      "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
-  {"-title",   "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
-  {"-iconname",        "*EmacsShell.iconName", XrmoptionSepArg, (XtPointer) NULL},
-  {"-in",      "*EmacsShell.iconName", XrmoptionSepArg, (XtPointer) NULL},
-  {"-mc",      "*pointerColor", XrmoptionSepArg, (XtPointer) NULL},
-  {"-cr",      "*cursorColor", XrmoptionSepArg, (XtPointer) NULL}
-};
-#endif /* USE_X_TOOLKIT */
-
-#ifdef MULTI_KBOARD
-/* Test whether two display-name strings agree up to the dot that separates
-   the screen number from the server number.  */
-static int
-same_x_server (name1, name2)
-     char *name1, *name2;
-{
-  int seen_colon = 0;
-  unsigned char *system_name = SDATA (Vsystem_name);
-  int system_name_length = strlen (system_name);
-  int length_until_period = 0;
-
-  while (system_name[length_until_period] != 0
-        && system_name[length_until_period] != '.')
-    length_until_period++;
-
-  /* Treat `unix' like an empty host name.  */
-  if (! strncmp (name1, "unix:", 5))
-    name1 += 4;
-  if (! strncmp (name2, "unix:", 5))
-    name2 += 4;
-  /* Treat this host's name like an empty host name.  */
-  if (! strncmp (name1, system_name, system_name_length)
-      && name1[system_name_length] == ':')
-    name1 += system_name_length;
-  if (! strncmp (name2, system_name, system_name_length)
-      && name2[system_name_length] == ':')
-    name2 += system_name_length;
-  /* Treat this host's domainless name like an empty host name.  */
-  if (! strncmp (name1, system_name, length_until_period)
-      && name1[length_until_period] == ':')
-    name1 += length_until_period;
-  if (! strncmp (name2, system_name, length_until_period)
-      && name2[length_until_period] == ':')
-    name2 += length_until_period;
-
-  for (; *name1 != '\0' && *name1 == *name2; name1++, name2++)
-    {
-      if (*name1 == ':')
-       seen_colon++;
-      if (seen_colon && *name1 == '.')
-       return 1;
-    }
-  return (seen_colon
-         && (*name1 == '.' || *name1 == '\0')
-         && (*name2 == '.' || *name2 == '\0'));
-}
-#endif
-
 int mac_initialized = 0;
 
 void
@@ -8404,12 +9218,7 @@ mac_initialize_display_info ()
 
   bzero (dpyinfo, sizeof (*dpyinfo));
 
-  /* Put it on x_display_name_list.  */
-  x_display_name_list = Fcons (Fcons (build_string ("Mac"), Qnil),
-                               x_display_name_list);
-  dpyinfo->name_list_element = XCAR (x_display_name_list);
-
-#if 0
+#ifdef MAC_OSX
   dpyinfo->mac_id_name
     = (char *) xmalloc (SCHARS (Vinvocation_name)
                        + SCHARS (Vsystem_name)
@@ -8426,17 +9235,97 @@ mac_initialize_display_info ()
   dpyinfo->reference_count = 0;
   dpyinfo->resx = 75.0;
   dpyinfo->resy = 75.0;
-  dpyinfo->n_planes = 1;
-  dpyinfo->n_cbits = 16;
+  dpyinfo->color_p = TestDeviceAttribute (main_device_handle, gdDevType);
+#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.
+     CGMainDisplayID is only available on OSX 10.2 and higher, but the
+     header for CGGetActiveDisplayList says that the first display returned
+     is the active one, so we use that.  */
+  {
+    CGDirectDisplayID disp_id[1];
+    CGDisplayCount disp_count;
+    CGDisplayErr error_code;
+
+    error_code = CGGetActiveDisplayList (1, disp_id, &disp_count);
+    if (error_code != 0)
+      error ("No display found, CGGetActiveDisplayList error %d", error_code);
+
+    dpyinfo->n_planes = CGDisplayBitsPerPixel (disp_id[0]);
+  }
+#else
+  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;
+#endif
   dpyinfo->height = (**main_device_handle).gdRect.bottom;
   dpyinfo->width = (**main_device_handle).gdRect.right;
   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;
+}
+
+/* Create an xrdb-style database of resources to supercede registry settings.
+   The database is just a concatenation of C strings, finished by an additional
+   \0.  The string are submitted to some basic normalization, so
+
+     [ *]option[ *]:[ *]value...
+
+   becomes
+
+     option:value...
+
+   but any whitespace following value is not removed.  */
+
+static char *
+mac_make_rdb (xrm_option)
+     char *xrm_option;
+{
+  char *buffer = xmalloc (strlen (xrm_option) + 2);
+  char *current = buffer;
+  char ch;
+  int in_option = 1;
+  int before_value = 0;
+
+  do {
+    ch = *xrm_option++;
+
+    if (ch == '\n')
+      {
+        *current++ = '\0';
+        in_option = 1;
+        before_value = 0;
+      }
+    else if (ch != ' ')
+      {
+        *current++ = ch;
+        if (in_option && (ch == ':'))
+          {
+            in_option = 0;
+            before_value = 1;
+          }
+        else if (before_value)
+          {
+            before_value = 0;
+          }
+      }
+    else if (!(in_option || before_value))
+      {
+        *current++ = ch;
+      }
+  } while (ch);
+
+  *current = '\0';
+
+  return buffer;
 }
 
 struct mac_display_info *
@@ -8446,7 +9335,8 @@ mac_term_init (display_name, xrm_option, resource_name)
      char *resource_name;
 {
   struct mac_display_info *dpyinfo;
-  GDHandle main_device_handle;
+
+  BLOCK_INPUT;
 
   if (!mac_initialized)
     {
@@ -8454,17 +9344,90 @@ mac_term_init (display_name, xrm_option, resource_name)
       mac_initialized = 1;
     }
 
-  mac_initialize_display_info (display_name);
+  if (x_display_list)
+    error ("Sorry, this version can only handle one display");
+
+  mac_initialize_display_info ();
 
   dpyinfo = &one_mac_display_info;
 
-  main_device_handle = LMGetMainDevice();
+  dpyinfo->xrdb = xrm_option ? mac_make_rdb (xrm_option) : NULL;
 
-  dpyinfo->height = (**main_device_handle).gdRect.bottom;
-  dpyinfo->width = (**main_device_handle).gdRect.right;
+  /* Put this display on the chain.  */
+  dpyinfo->next = x_display_list;
+  x_display_list = dpyinfo;
+
+  /* Put it on x_display_name_list.  */
+  x_display_name_list = Fcons (Fcons (display_name, Qnil),
+                               x_display_name_list);
+  dpyinfo->name_list_element = XCAR (x_display_name_list);
+
+  UNBLOCK_INPUT;
 
   return dpyinfo;
 }
+/* Get rid of display DPYINFO, assuming all frames are already gone.  */
+
+void
+x_delete_display (dpyinfo)
+     struct mac_display_info *dpyinfo;
+{
+  int i;
+
+  /* Discard this display from x_display_name_list and x_display_list.
+     We can't use Fdelq because that can quit.  */
+  if (! NILP (x_display_name_list)
+      && EQ (XCAR (x_display_name_list), dpyinfo->name_list_element))
+    x_display_name_list = XCDR (x_display_name_list);
+  else
+    {
+      Lisp_Object tail;
+
+      tail = x_display_name_list;
+      while (CONSP (tail) && CONSP (XCDR (tail)))
+       {
+         if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
+           {
+             XSETCDR (tail, XCDR (XCDR (tail)));
+             break;
+           }
+         tail = XCDR (tail);
+       }
+    }
+
+  if (x_display_list == dpyinfo)
+    x_display_list = dpyinfo->next;
+  else
+    {
+      struct x_display_info *tail;
+
+      for (tail = x_display_list; tail; tail = tail->next)
+       if (tail->next == dpyinfo)
+         tail->next = tail->next->next;
+    }
+
+  /* Free the font names in the font table.  */
+  for (i = 0; i < dpyinfo->n_fonts; i++)
+    if (dpyinfo->font_table[i].name)
+      {
+       if (dpyinfo->font_table[i].name != dpyinfo->font_table[i].full_name)
+         xfree (dpyinfo->font_table[i].full_name);
+       xfree (dpyinfo->font_table[i].name);
+      }
+
+  if (dpyinfo->font_table->font_encoder)
+    xfree (dpyinfo->font_table->font_encoder);
+
+  xfree (dpyinfo->font_table);
+  xfree (dpyinfo->mac_id_name);
+
+  if (x_display_list == 0)
+    {
+      mac_clear_font_name_table ();
+      bzero (dpyinfo, sizeof (*dpyinfo));
+    }
+}
+
 \f
 #ifdef MAC_OSX
 void
@@ -8585,21 +9548,23 @@ mac_check_for_quit_char ()
   mac_determine_quit_char_modifiers ();
 
   /* Fill the queue with events */
+  BLOCK_INPUT;
   ReceiveNextEvent (0, NULL, kEventDurationNoWait, false, &event);
   event = FindSpecificEventInQueue (GetMainEventQueue (), quit_char_comp,
                                    NULL);
+  UNBLOCK_INPUT;
   if (event)
     {
       struct input_event e;
-      struct mac_output *mwp =
-       (mac_output *) GetWRefCon (FrontNonFloatingWindow ());
+
       /* Use an input_event to emulate what the interrupt handler does. */
+      EVENT_INIT (e);
       e.kind = ASCII_KEYSTROKE_EVENT;
       e.code = quit_char;
-      e.arg = NULL;
+      e.arg = Qnil;
       e.modifiers = NULL;
       e.timestamp = EventTimeToTicks (GetEventTime (event)) * (1000/60);
-      XSETFRAME (e.frame_or_window, mwp->mFP);
+      XSETFRAME (e.frame_or_window, mac_window_to_frame (front_emacs_window ()));
       /* Remove event from queue to prevent looping. */
       RemoveEventFromQueue (GetMainEventQueue (), event);
       ReleaseEvent (event);
@@ -8626,11 +9591,13 @@ static struct redisplay_interface x_redisplay_interface =
   x_update_window_end,
   x_cursor_to,
   x_flush,
-  x_flush,
+  0, /* flush_display_optional */
   x_clear_window_mouse_face,
   x_get_glyph_overhangs,
   x_fix_overlapping_area,
   x_draw_fringe_bitmap,
+  0, /* define_fringe_bitmap */
+  0, /* destroy_fringe_bitmap */
   mac_per_char_metric,
   mac_encode_char,
   NULL, /* mac_compute_glyph_string_overhangs */
@@ -8718,13 +9685,11 @@ mac_initialize ()
   signal (SIGPIPE, x_connection_signal);
 #endif
 
-  mac_initialize_display_info ();
+  BLOCK_INPUT;
 
 #if TARGET_API_MAC_CARBON
   init_required_apple_events ();
 
-  init_mac_drag_n_drop ();
-
 #if USE_CARBON_EVENTS
   init_service_handler ();
 
@@ -8736,6 +9701,7 @@ mac_initialize ()
   if (!inhibit_window_system)
     MakeMeTheFrontProcess ();
 #endif
+  UNBLOCK_INPUT;
 }
 
 
@@ -8747,7 +9713,20 @@ syms_of_macterm ()
   x_error_message_string = Qnil;
 #endif
 
+  Qmodifier_value = intern ("modifier-value");
+  Qalt = intern ("alt");
+  Fput (Qalt, Qmodifier_value, make_number (alt_modifier));
+  Qhyper = intern ("hyper");
+  Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier));
+  Qsuper = intern ("super");
+  Fput (Qsuper, Qmodifier_value, make_number (super_modifier));
+
+#ifdef MAC_OSX
   Fprovide (intern ("mac-carbon"), Qnil);
+#endif
+
+  staticpro (&Qreverse);
+  Qreverse = intern ("reverse");
 
   staticpro (&x_display_name_list);
   x_display_name_list = Qnil;
@@ -8764,6 +9743,18 @@ syms_of_macterm ()
   Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop");
   staticpro (&Qmac_ready_for_drag_n_drop);
 
+  Qbig5 = intern ("big5");
+  staticpro (&Qbig5);
+
+  Qcn_gb = intern ("cn-gb");
+  staticpro (&Qcn_gb);
+
+  Qsjis = intern ("sjis");
+  staticpro (&Qsjis);
+
+  Qeuc_kr = intern ("euc-kr");
+  staticpro (&Qeuc_kr);
+
   DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p,
     doc: /* *Non-nil means autoselect window with mouse pointer.  */);
   x_autoselect_window_p = 0;
@@ -8788,11 +9779,28 @@ to 4.1, set this to nil.  */);
 Otherwise the option key is used.  */);
   Vmac_command_key_is_meta = Qt;
 
+  DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier,
+    doc: /* Modifier to use for the Mac alt/option key.  The value can
+be alt, hyper, or super for the respective modifier.  If the value is
+nil then the key will act as the normal Mac option modifier.  */);
+  Vmac_option_modifier = Qnil;
+
   DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta,
     doc: /* Non-nil means that the control and meta keys are reversed.  This is
            useful for non-standard keyboard layouts.  */);
   Vmac_reverse_ctrl_meta = Qnil;
 
+  DEFVAR_LISP ("mac-emulate-three-button-mouse",
+              &Vmac_emulate_three_button_mouse,
+    doc: /* 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.
+    'reverse means that the the option-key will register for mouse-3
+    and the command-key will register for mouse-2.  nil means that
+    not emulation should be done and the modifiers should be placed
+    on the mouse-1 event. */);
+  Vmac_emulate_three_button_mouse = Qnil;
+
 #if USE_CARBON_EVENTS
   DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2,
    doc: /* Non-nil means that the wheel button will be treated as mouse-2 and
@@ -8826,3 +9834,6 @@ command, this enables the Mac keyboard to be used to enter non-ASCII
 characters directly.  */);
   mac_keyboard_text_encoding = kTextEncodingMacRoman;
 }
+
+/* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b
+   (do not change this comment) */