]> code.delx.au - gnu-emacs/blobdiff - src/macterm.c
(x_clip_to_row): Add area arg. Callers changed.
[gnu-emacs] / src / macterm.c
index 0bcf85f6ff2b586d22285196e954b900784c0c33..f4f9235c8464df4688204c9821b975c5c76343b1 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,17 +504,30 @@ 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);
 }
 
 
+/* XBM bits seem to be backward within bytes compared with how
+   Mac does things.  */
+static unsigned char
+reflect_byte (orig)
+     unsigned char orig;
+{
+  int i;
+  unsigned char reflected = 0x00;
+  for (i = 0; i < 8; i++)
+    {
+      if (orig & (0x01 << i))
+       reflected |= 0x80 >> i;
+    }
+  return reflected;
+}
+
+
 /* Mac replacement for XCreateBitmapFromBitmapData.  */
 
 static void
@@ -548,18 +536,19 @@ mac_create_bitmap_from_bitmap_data (bitmap, bits, w, h)
      char *bits;
      int w, h;
 {
-  int bytes_per_row, i, j;
+  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++)
+        *p++ = reflect_byte (*bits++);
+    }
 
   SetRect (&(bitmap->bounds), 0, 0, w, h);
 }
@@ -572,6 +561,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;       /* not used */
+{
+  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,16 +634,37 @@ 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);
+
+  PaintRect (&r); /* using foreground color of gc */
+}
+
+
+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);
 }
 
 
@@ -609,11 +680,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);
@@ -632,20 +699,20 @@ 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);
 }
 
 
@@ -659,11 +726,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 +817,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));
 }
 
 
@@ -811,19 +909,20 @@ mac_scroll_area (display, w, gc, src_x, src_y, width, height, dest_x, dest_y)
 {
 #if TARGET_API_MAC_CARBON
   Rect gw_r, src_r, dest_r;
-  PixMapHandle pmh;
 
   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));
+  SetPortWindowPort (w);
 
   ForeColor (blackColor);
   BackColor (whiteColor);
 
   LockPortBits (GetWindowPort (w));
-  pmh = GetPortPixMap (GetWindowPort (w));
-  CopyBits ((BitMap *) *pmh, (BitMap *) *pmh, &src_r, &dest_r, srcCopy, 0);
+  {
+    const BitMap *bitmap = GetPortBitMapForCopyBits (GetWindowPort (w));
+    CopyBits (bitmap, bitmap, &src_r, &dest_r, srcCopy, 0);
+  }
   UnlockPortBits (GetWindowPort (w));
 
   mac_set_colors (gc);
@@ -866,25 +965,77 @@ 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);
 }
 
 
@@ -941,7 +1092,7 @@ XGetGCValues (void* ignore, XGCValues *gc,
 
 /* Mac replacement for XSetForeground.  */
 
-static void
+void
 XSetForeground (display, gc, color)
      Display *display;
      GC gc;
@@ -1007,7 +1158,7 @@ x_flush (f)
       FOR_EACH_FRAME (rest, frame)
        x_flush (XFRAME (frame));
     }
-  else if (FRAME_X_P (f))
+  else if (FRAME_MAC_P (f))
     XFlush (FRAME_MAC_DISPLAY (f));
   UNBLOCK_INPUT;
 #endif /* TARGET_API_MAC_CARBON */
@@ -1087,7 +1238,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 +1260,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);
 }
@@ -1144,7 +1295,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 +1329,17 @@ 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;
   XFlush (FRAME_MAC_DISPLAY (f));
   UNBLOCK_INPUT;
 }
@@ -1204,7 +1353,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 +1390,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 +1442,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 +1487,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 +1731,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 *));
 
@@ -2119,6 +2280,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 +2310,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 +2390,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 +2421,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 +2456,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 +2471,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 +2522,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 +2532,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 +2581,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 +2605,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 +2616,57 @@ 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 */
       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;
+         Rect nr;
          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);
+         get_glyph_string_clip_rect (s, &nr);
+         CONVERT_TO_XRECT (clip_rect, nr);
          image_rect.x = x;
          image_rect.y = y;
-         image_rect.width = s->img->width;
-         image_rect.height = s->img->height;
+         image_rect.width = s->slice.width;
+         image_rect.height = s->slice.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 + r.x - x, s->slice.y + r.y - y,
+                                    r.width, r.height, r.x, r.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);
+         Rect nr;
+         XRectangle clip_rect, image_rect, r;
+
+         get_glyph_string_clip_rect (s, &nr);
+         CONVERT_TO_XRECT (clip_rect, nr);
+         image_rect.x = x;
+         image_rect.y = y;
+         image_rect.width = s->slice.width;
+         image_rect.height = s->slice.height;
+         if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
+           mac_copy_area (s->display, s->img->pixmap, s->window, s->gc,
+                          s->slice.x + r.x - x, s->slice.y + r.y - y,
+                          r.width, r.height, r.x, r.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 +2678,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 +2700,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,12 +2731,17 @@ 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);
 }
 
 
@@ -2529,51 +2752,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,15 +2794,16 @@ 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);
 }
 
 
@@ -2626,7 +2836,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 +2855,41 @@ 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 (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,18 +2899,19 @@ 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);
            }
        }
       else
-#endif
        x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
 
       s->background_filled_p = 1;
@@ -2715,7 +2923,7 @@ x_draw_image_glyph_string (s)
       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);
     }
@@ -2752,10 +2960,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 +3023,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 +3059,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 +3136,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 +3158,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 +3212,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 +3316,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 +3352,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 +3474,6 @@ static void
 XTframe_rehighlight (frame)
      struct frame *frame;
 {
-
-
   x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame));
 }
 
@@ -3483,11 +3688,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);
@@ -3516,6 +3717,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 +3732,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
@@ -3630,7 +3840,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 +3890,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 +3941,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 +3960,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 +3998,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));
 }
@@ -4229,6 +4455,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 ();
 
@@ -4263,6 +4491,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 +4558,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 +4615,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 +4652,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 +4666,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 +4693,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 +4707,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 +4761,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 +4791,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 +4824,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 +4843,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:
@@ -4681,7 +4969,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
@@ -4756,6 +5044,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 +5071,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
-
-#if TARGET_API_MAC_CARBON
-      {
-        Rect r;
+  mac_get_window_bounds (f, &inner, &outer);
 
-        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 +5119,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 +5135,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 +5322,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 +5335,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
@@ -5045,7 +5388,6 @@ x_make_frame_visible (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 +5431,6 @@ x_make_frame_visible (f)
        FRAME_SAMPLE_VISIBILITY (f);
       }
   }
-#endif /* MAC_TODO */
 }
 
 /* Change from mapped state to withdrawn state.  */
@@ -5145,23 +5486,33 @@ 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);
 
   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 +5520,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 +5533,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.  */
 
@@ -5450,6 +5814,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 +5894,53 @@ 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 (char *name, int size, short scriptcode)
+{
+  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)
 {
   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)
     {
@@ -5594,6 +5999,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 +6010,29 @@ 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)
+    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';
+    }
 }
 
 
@@ -5673,36 +6096,45 @@ init_font_name_table ()
          if (FMGetFontFamilyName (ff, name) != noErr)
            break;
          p2cstr (name);
+         if (*name == '.')
+           continue;
 
          sc = FontToScript (ff);
+         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 +6176,7 @@ init_font_name_table ()
 
          TextFont (fontnum);
          scriptcode = FontToScript (fontnum);
+         decode_mac_font_name (name, sizeof (name), scriptcode);
          do
            {
              HLock (font_handle);
@@ -5778,9 +6211,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,61 +6240,179 @@ init_font_name_table ()
 }
 
 
-/* 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
-   calling mac_font_pattern_match (slow).  Return as many matching
-   fonts as possible if MAXNAMES = -1.  */
+enum xlfd_scalable_field_index
+  {
+    XLFD_SCL_PIXEL_SIZE,
+    XLFD_SCL_POINT_SIZE,
+    XLFD_SCL_AVGWIDTH,
+    XLFD_SCL_LAST
+  };
 
-Lisp_Object
-x_list_fonts (struct frame *f,
-              Lisp_Object pattern,
-              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;
+static int xlfd_scalable_fields[] =
+  {
+    6,                         /* PIXEL_SIZE */
+    7,                         /* POINT_SIZE */
+    11,                                /* AVGWIDTH */
+    -1
+  };
 
-  if (font_name_table == NULL)  /* Initialize when first used.  */
-    init_font_name_table ();
+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;
+
+  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 (dpyinfo)
+  if (i == 14 && ptr == NULL)
     {
-      tem = XCDR (dpyinfo->name_list_element);
-      key = Fcons (pattern, make_number (maxnames));
-
-      newlist = Fassoc (key, tem);
-      if (!NILP (newlist))
+      if (scl_val[XLFD_SCL_POINT_SIZE] > 0)
        {
-         newlist = Fcdr_safe (newlist);
-         goto label_cached;
+         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;
 
-  ptnstr = SDATA (pattern);
-
-  GCPRO2 (pattern, newlist);
+  ptr = regex;
+  *ptr++ = '^';
 
-  /* Scan and matching bitmap fonts.  */
-  for (i = 0; i < font_name_count; i++)
+  /* Turn pattern into a regexp and do a regexp match.  */
+  for (; *pattern; pattern++)
     {
-      if (mac_font_pattern_match (font_name_table[i], ptnstr))
+      if (*pattern == '?')
+        *ptr++ = '.';
+      else if (*pattern == '*')
         {
-          newlist = Fcons (build_string (font_name_table[i]), newlist);
-
-          n_fonts++;
+          *ptr++ = '.';
+          *ptr++ = '*';
+        }
+      else
+        *ptr++ = tolower (*pattern);
+    }
+  *ptr = '$';
+  *(ptr + 1) = '\0';
+
+  pattern_regex = build_string (regex);
+
+  for (i = 0; i < font_name_count; i++)
+    {
+      fontname = build_string (font_name_table[i]);
+      if (fast_string_match (pattern_regex, fontname) >= 0)
+       {
+         font_list = Fcons (fontname, font_list);
+
+          n_fonts++;
           if (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 = build_string (scaled);
+         if (fast_string_match (pattern_regex, fontname) >= 0)
+           {
+             font_list = Fcons (fontname, font_list);
+
+             n_fonts++;
+             if (maxnames > 0 && n_fonts >= maxnames)
+               break;
+           }
+       }
     }
+  return font_list;
+}
 
-  /* MAC_TODO: add code for matching outline fonts here */
+/* 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
+   calling mac_font_pattern_match (slow).  Return as many matching
+   fonts as possible if MAXNAMES = -1.  */
+
+Lisp_Object
+x_list_fonts (struct frame *f,
+              Lisp_Object pattern,
+              int size,
+              int maxnames)
+{
+  Lisp_Object newlist = Qnil, tem, key;
+  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);
+      key = Fcons (pattern, make_number (maxnames));
+
+      newlist = Fassoc (key, tem);
+      if (!NILP (newlist))
+       {
+         newlist = Fcdr_safe (newlist);
+         goto label_cached;
+       }
+    }
 
-  UNGCPRO;
+  newlist = mac_do_list_fonts (SDATA (pattern), maxnames);
+
+  /* MAC_TODO: add code for matching outline fonts here */
 
   if (dpyinfo)
     {
@@ -6022,14 +6573,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 */
@@ -6151,7 +6700,8 @@ XLoadQueryFont (Display *dpy, char *fontname)
         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].width =
+             font->per_char[c - 0x20].rbearing = CharWidth (c);
           }
       }
     }
@@ -6240,6 +6790,7 @@ 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);
@@ -6373,81 +6924,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 +6967,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 +6977,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 +6987,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 +7030,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
@@ -6584,6 +7077,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 +7109,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 +7128,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 +7227,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 +7246,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,8 +7257,12 @@ 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 (win == tip_window)
+    /* The tooltip has been drawn already.  Avoid the
+       SET_FRAME_GARBAGED below.  */
+    return;
 
   if (f)
     {
@@ -6779,56 +7310,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 +7332,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 +7357,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 +7431,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)
           {
@@ -6991,8 +7456,7 @@ 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;
+  struct frame *f = mac_window_to_frame (w);
 
   SetRect(&limit_rect, MIN_DOC_SIZE, MIN_DOC_SIZE, MAX_DOC_SIZE, MAX_DOC_SIZE);
 
@@ -7020,46 +7484,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;
-
-  GetPort (&save_port);
-
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  int w_title_height, columns, rows;
+  struct frame *f = mac_window_to_frame (w);
 
-  /* 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 +7539,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
@@ -7093,9 +7561,8 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out)
 #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);
-
-  SetPort (save_port);
+  x_set_window_size (f, 0, columns, rows);
+  x_real_positions (f, &f->left_pos, &f->top_pos);
 }
 
 /* Initialize Drag And Drop to allow files to be dropped onto emacs frames */
@@ -7424,8 +7891,8 @@ 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);
+      SetPortWindowPort (window);
       GlobalToLocal (&mouse);
 
       event.kind = DRAG_N_DROP_EVENT;
@@ -7519,7 +7986,9 @@ main (void)
 
   do_get_menus ();
 
+#ifndef USE_LSB_TAG
   do_check_ram_size ();
+#endif
 
   init_emacs_passwd_dir ();
 
@@ -7597,25 +8066,26 @@ keycode_to_xkeysym (int keyCode, int *xKeySym)
 /* 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 = GetEventDispatcherTarget ();
+#else
+  EventMask event_mask;
 #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 +8093,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 +8107,57 @@ 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
   event_mask = everyEvent;
   if (NILP (Fboundp (Qmac_ready_for_drag_n_drop)))
     event_mask -= highLevelEventMask;
 
-#if USE_CARBON_EVENTS
-  rneResult = ReceiveNextEvent (0, NULL,
-                               expected
-                               ? TicksToEventTime (app_sleep_time)
-                               : 0,
-                               kEventRemoveFromQueue, &eventRef);
-  if (!rneResult)
+  while (WaitNextEvent (event_mask, &er, 0L, NULL))
+#else /* USE_CARBON_EVENTS */
+  while (!ReceiveNextEvent (0, NULL, kEventDurationNoWait,
+                           kEventRemoveFromQueue, &eventRef))
+#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
       /* 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,443 +8166,578 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
                GetEventParameter(eventRef, kEventParamMouseLocation,
                                  typeQDPoint, NULL, sizeof (Point),
                                  NULL, &point);
-               bufp->kind = MOUSE_WHEEL_EVENT;
-               bufp->code = delta;
-               bufp->modifiers = mac_event_to_emacs_modifiers(eventRef);
-               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;
-#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;
-
-             /* Convert to local coordinates of new window.  */
-#if TARGET_API_MAC_CARBON
-              SetPort (GetWindowPort (window_ptr));
-#else
-              SetPort (window_ptr);
+           /* This is needed to send mouse events like aqua window
+              buttons to the correct handler.  */
+           if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
+               != eventNotHandledErr)
+             break;
 #endif
 
-             GlobalToLocal (&mouse_loc);
+           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);
+                 }
+             }
 
-#if USE_CARBON_EVENTS
-             bufp->code = mac_get_mouse_btn (eventRef);
-#else
-             bufp->code = 0;  /* only one mouse button */
-#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);
-#else
-             bufp->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;
-            }
+           if (er.what != mouseDown && part_code != inContent)
+             break;
 
-         part_code = FindWindow (er.where, &window_ptr);
+           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;
 
-         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;
+             case inContent:
+               if (window_ptr != front_emacs_window ())
+                 SelectWindow (window_ptr);
+               else
+                 {
+                   SInt16 control_part_code;
+                   ControlHandle ch;
+                   Point mouse_loc = er.where;
 
-           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 TARGET_API_MAC_CARBON
-                  SetPort (GetWindowPort (window_ptr));
-#else
-                  SetPort (window_ptr);
-#endif
+                   f = mac_window_to_frame (window_ptr);
+                   /* convert to local coordinates of new window */
+                   SetPortWindowPort (window_ptr);
 
-                 GlobalToLocal (&mouse_loc);
+                   GlobalToLocal (&mouse_loc);
 #if TARGET_API_MAC_CARBON
-                 ch = FindControlUnderMouse (mouse_loc, window_ptr,
-                                             &control_part_code);
+                   ch = FindControlUnderMouse (mouse_loc, window_ptr,
+                                               &control_part_code);
 #else
-                 control_part_code = FindControl (mouse_loc, window_ptr, &ch);
+                   control_part_code = FindControl (mouse_loc, window_ptr,
+                                                    &ch);
 #endif
 
 #if USE_CARBON_EVENTS
-                 bufp->code = mac_get_mouse_btn (eventRef);
+                   inev.code = mac_get_mouse_btn (eventRef);
+                   inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
 #else
-                 bufp->code = 0;  /* only one mouse button */
+                   inev.code = mac_get_emulated_btn (er.modifiers);
+                   inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
 #endif
-                 XSETINT (bufp->x, mouse_loc.h);
-                 XSETINT (bufp->y, mouse_loc.v);
-                 bufp->timestamp = er.when * (1000 / 60);
+                   XSETINT (inev.x, mouse_loc.h);
+                   XSETINT (inev.y, mouse_loc.v);
+                   inev.timestamp = er.when * (1000 / 60);
                    /* ticks to milliseconds */
 
+                   if (dpyinfo->grabbed && tracked_scroll_bar
 #if TARGET_API_MAC_CARBON
-                 if (ch != 0)
+                       || ch != 0
 #else
-                 if (control_part_code != 0)
+                       || control_part_code != 0
 #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;
-                   }
+                       )
+                     {
+                       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;
 
-#if USE_CARBON_EVENTS
-                 bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
-#else
-                 bufp->modifiers = mac_to_emacs_modifiers (er.modifiers);
-#endif
+             case inDrag:
+#if TARGET_API_MAC_CARBON
+               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);
 
-                 switch (er.what)
-                   {
-                   case mouseDown:
-                     bufp->modifiers |= down_modifier;
-                     break;
-                   case mouseUp:
-                     bufp->modifiers |= up_modifier;
-                     break;
-                   }
+                 if (f && !f->async_iconified)
+                   x_real_positions (f, &f->left_pos, &f->top_pos);
+               }
+               break;
 
-                 count++;
-               }
-             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;
 
-           case inDrag:
-#if TARGET_API_MAC_CARBON
-             {
-               BitMap bm;
+               /* window resize handling added --ben */
+             case inGrow:
+               do_grow_window (window_ptr, &er);
+               break;
 
-               GetQDGlobalsScreenBits (&bm);
-               DragWindow (window_ptr, er.where, &bm.bounds);
+               /* 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;
              }
-#else /* not TARGET_API_MAC_CARBON */
-             DragWindow (window_ptr, er.where, &qd.screenBits.bounds);
-#endif /* not TARGET_API_MAC_CARBON */
-             break;
+         }
+         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++;
-               }
-             break;
+       case updateEvt:
+#if USE_CARBON_EVENTS
+         if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
+             != eventNotHandledErr)
+           break;
+#endif
+         do_window_update ((WindowPtr) er.message);
+         break;
 
-           /* window resize handling added --ben */
-           case inGrow:
-             do_grow_window(window_ptr, &er);
+       case osEvt:
+#if USE_CARBON_EVENTS
+         if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
+             != eventNotHandledErr)
+           break;
+#endif
+         switch ((er.message >> 24) & 0x000000FF)
+           {
+           case suspendResumeMessage:
+             if ((er.message & resumeFlag) == 1)
+               do_app_resume ();
+             else
+               do_app_suspend ();
              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;
+           case mouseMovedMessage:
+             previous_help_echo_string = help_echo_string;
+             help_echo_string = help_echo_object = help_echo_window = Qnil;
+             help_echo_pos = -1;
+
+             do_mouse_moved (er.where, &f);
 
-           default:
+             /* 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;
+         break;
+
+       case activateEvt:
+         {
+           WindowPtr window_ptr = (WindowPtr) er.message;
 
-      case updateEvt:
-      case osEvt:
-      case activateEvt:
 #if USE_CARBON_EVENTS
-       if (eventNotHandledErr == SendEventToEventTarget (eventRef, GetEventDispatcherTarget ()))
+           if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
+               != eventNotHandledErr)
+             break;
 #endif
-       do_events (&er);
-       break;
+           if (window_ptr == tip_window)
+             {
+               HideWindow (tip_window);
+               break;
+             }
 
-      case keyDown:
-      case autoKey:
-       {
-         int keycode = (er.message & keyCodeMask) >> 8;
-         int xkeysym;
+           if (!is_emacs_window (window_ptr))
+             break;
 
-#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)
-               break;
-           }
-#endif
+           f = mac_window_to_frame (window_ptr);
 
-         if (!IsValidWindowPtr (FrontNonFloatingWindow ()))
-           {
-             SysBeep (1);
-             UNBLOCK_INPUT;
-             return 0;
-           }
+           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;
 
-         ObscureCursor ();
+               if (f == dpyinfo->x_focus_frame)
+                 {
+                   x_new_focus_frame (dpyinfo, 0);
+                   deactivate_scroll_bars (f);
+                 }
 
-         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;
-           }
-       }
 
-       /* 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)
+               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:
          {
-           static TECObjectRef converter = NULL;
-           OSStatus the_err = noErr;
-           OSStatus convert_status = noErr;
+           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)))
+             if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
+                 != eventNotHandledErr)
+               break;
+#endif
 
-           if (converter ==  NULL)
+#if TARGET_API_MAC_CARBON
+           if (!IsValidWindowPtr (front_emacs_window ()))
              {
-               the_err = TECCreateConverter (&converter,
-                                             kTextEncodingMacRoman,
-                                             mac_keyboard_text_encoding);
-               current_mac_keyboard_text_encoding
-                 = mac_keyboard_text_encoding;
+               SysBeep (1);
+               break;
              }
-           else if (mac_keyboard_text_encoding
-                    != current_mac_keyboard_text_encoding)
+#endif
+
+           ObscureCursor ();
+
+           if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
              {
-               /* 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;
+               clear_mouse_face (dpyinfo);
+               dpyinfo->mouse_face_hidden = 1;
              }
 
-           if (the_err == noErr)
+           if (keycode_to_xkeysym (keycode, &xkeysym))
+             {
+               inev.code = 0xff00 | xkeysym;
+               inev.kind = NON_ASCII_KEYSTROKE_EVENT;
+             }
+           else
              {
-               unsigned char ch = bufp->code;
-               ByteCount actual_input_length, actual_output_length;
-               unsigned char outch;
-
-               convert_status = TECConvertText (converter, &ch, 1,
-                                                &actual_input_length,
-                                                &outch, 1,
-                                                &actual_output_length);
-               if (convert_status == noErr
-                   && actual_input_length == 1
-                   && actual_output_length == 1)
-                 bufp->code = outch;
+               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 USE_CARBON_EVENTS
-       bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
-#else
-       bufp->modifiers = mac_to_emacs_modifiers (er.modifiers);
-#endif
+         /* 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;
 
-       {
-         mac_output *mwp
-           = (mac_output *) GetWRefCon (FrontNonFloatingWindow ());
-         XSETFRAME (bufp->frame_or_window, mwp->mFP);
-       }
+             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;
+               }
 
-       bufp->timestamp = er.when * (1000 / 60);  /* ticks to milliseconds */
+             if (the_err == noErr)
+               {
+                 unsigned char ch = inev.code;
+                 ByteCount actual_input_length, actual_output_length;
+                 unsigned char outch;
+
+                 convert_status = TECConvertText (converter, &ch, 1,
+                                                  &actual_input_length,
+                                                  &outch, 1,
+                                                  &actual_output_length);
+                 if (convert_status == noErr
+                     && actual_input_length == 1
+                     && actual_output_length == 1)
+                   inev.code = outch;
+               }
+           }
 
-       count++;
-       break;
+#if USE_CARBON_EVENTS
+         inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
+#else
+         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;
 
-      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.  */
@@ -8132,54 +8751,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;
 }
 
@@ -8207,7 +8779,7 @@ __convert_from_newlines (unsigned char * p, size_t * n)
    ROWS Macintosh window, using font with name FONTNAME and size
    FONTSIZE.  */
 void
-NewMacWindow (FRAME_PTR fp)
+make_mac_frame (FRAME_PTR fp)
 {
   mac_output *mwp;
 #if TARGET_API_MAC_CARBON
@@ -8218,6 +8790,7 @@ NewMacWindow (FRAME_PTR fp)
 
   mwp = fp->output_data.mac;
 
+  BLOCK_INPUT;
   if (making_terminal_window)
     {
       if (!(mwp->mWP = GetNewCWindow (TERM_WINDOW_RESOURCE, NULL,
@@ -8226,45 +8799,58 @@ NewMacWindow (FRAME_PTR fp)
       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));
+      Rect r;
+
+      SetRect (&r, 0, 0, 1, 1);
+      if (CreateNewWindow (kDocumentWindowClass,
+                          kWindowStandardDocumentAttributes
+                          /* | kWindowToolbarButtonAttribute */,
+                          &r, &mwp->mWP) != noErr)
 #else
-  SetPort (mwp->mWP);
+      if (!(mwp->mWP = GetNewCWindow (WINDOW_RESOURCE, NULL, (WindowPtr) -1)))
 #endif
+       abort ();
+    }
 
-  mwp->fontset = -1;
+  SetWRefCon (mwp->mWP, (long) mwp);
+    /* so that update events can find this mac_output struct */
+  mwp->mFP = fp;  /* point back to emacs frame */
 
   SizeWindow (mwp->mWP, FRAME_PIXEL_WIDTH (fp), FRAME_PIXEL_HEIGHT (fp), false);
-  ShowWindow (mwp->mWP);
-
+  UNBLOCK_INPUT;
 }
 
 
 void
-make_mac_frame (struct frame *f)
+make_mac_terminal_frame (struct frame *f)
 {
+  Lisp_Object frame;
+
+  XSETFRAME (frame, 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));
+
+  XSETFRAME (FRAME_KBOARD (f)->Vdefault_minibuffer_frame, f);
+
+  FRAME_COLS (f) = 96;
+  FRAME_LINES (f) = 4;
+
   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;
 
   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;
@@ -8272,34 +8858,11 @@ make_mac_frame (struct frame *f)
 
   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);
-
-  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);
-
-  FRAME_COLS (f) = 96;
-  FRAME_LINES (f) = 4;
 
   make_mac_frame (f);
 
@@ -8317,6 +8880,8 @@ make_mac_terminal_frame (struct frame *f)
   Fmodify_frame_parameters (frame,
                             Fcons (Fcons (Qbackground_color,
                                           build_string ("white")), Qnil));
+
+  ShowWindow (f->output_data.mac->mWP);
 }
 
 \f
@@ -8324,74 +8889,6 @@ make_mac_terminal_frame (struct frame *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
@@ -8424,17 +8921,42 @@ 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;
 }
 
 struct mac_display_info *
@@ -8583,21 +9105,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);
@@ -8629,6 +9153,8 @@ static struct redisplay_interface x_redisplay_interface =
   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 */
@@ -8716,6 +9242,7 @@ mac_initialize ()
   signal (SIGPIPE, x_connection_signal);
 #endif
 
+  BLOCK_INPUT;
   mac_initialize_display_info ();
 
 #if TARGET_API_MAC_CARBON
@@ -8734,6 +9261,7 @@ mac_initialize ()
   if (!inhibit_window_system)
     MakeMeTheFrontProcess ();
 #endif
+  UNBLOCK_INPUT;
 }
 
 
@@ -8745,8 +9273,19 @@ 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));
+
   Fprovide (intern ("mac-carbon"), Qnil);
 
+  staticpro (&Qreverse);
+  Qreverse = intern ("reverse");
+
   staticpro (&x_display_name_list);
   x_display_name_list = Qnil;
 
@@ -8762,6 +9301,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;
@@ -8786,11 +9337,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
@@ -8824,3 +9392,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) */