]> code.delx.au - gnu-emacs/blobdiff - src/macterm.c
Merged in changes from CVS HEAD
[gnu-emacs] / src / macterm.c
index 510269c8ca50687bdc43d137b12309b40e67bdf2..93f3e73472447590b86037a4d7618d9781bc47b8 100644 (file)
@@ -1,5 +1,5 @@
 /* Implementation of GUI terminal on the Mac OS.
-   Copyright (C) 2000, 2001, 2002 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.  */
@@ -132,6 +109,10 @@ static int any_help_event_p;
 
 int x_autoselect_window_p;
 
+/* Non-zero means make use of UNDERLINE_POSITION font properties.  */
+
+int x_use_underline_position_properties;
+
 /* Non-zero means draw block and hollow cursor as wide as the glyph
    under it.  For example, if a block cursor is over a tab, it will be
    drawn as wide as that tab on the display.  */
@@ -249,8 +230,6 @@ 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.  */
@@ -263,8 +242,6 @@ static Lisp_Object Qvendor_specific_keysyms;
 extern XrmDatabase x_load_resources P_ ((Display *, char *, char *, char *));
 #endif
 
-extern Lisp_Object x_icon_type P_ ((struct frame *));
-
 extern int inhibit_window_system;
 
 #if __MRC__
@@ -303,9 +280,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, int));
+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 *, 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 +295,6 @@ void deactivate_scroll_bars (FRAME_PTR);
 static int is_emacs_window (WindowPtr);
 
 extern int image_ascent (struct image *, struct face *);
-void x_set_offset (struct frame *, int, int, int);
 int x_bitmap_icon (struct frame *, Lisp_Object);
 void x_make_frame_visible (struct frame *);
 
@@ -329,15 +306,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 +323,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 +339,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);
 }
@@ -403,6 +377,23 @@ 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;
+{
+  SetGWorld (p, NULL);
+
+  mac_set_colors (gc);
+
+  LockPixels (GetGWorldPixMap (p));
+  MoveTo (x1, y1);
+  LineTo (x2, y2);
+  UnlockPixels (GetGWorldPixMap (p));
+}
+
 /* Mac version of XClearArea.  */
 
 void
@@ -469,15 +460,21 @@ 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;
 
+  bitmap.rowBytes = sizeof(unsigned short);
+  bitmap.baseAddr = (char *)bits;
+  SetRect (&(bitmap.bounds), 0, 0, width, height);
+
 #if TARGET_API_MAC_CARBON
   SetPort (GetWindowPort (w));
 #else
@@ -485,19 +482,16 @@ mac_draw_bitmap (display, w, gc, x, y, bitmap)
 #endif
 
   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 */
 }
 
@@ -540,6 +534,23 @@ mac_reset_clipping (display, w)
 }
 
 
+/* 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 +559,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 +584,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;
+
+#if TARGET_API_MAC_CARBON
+  SetPort (GetWindowPort (w));
+#else
+  SetPort (w);
+#endif
+
+  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;
+
+  pixmap = XCreatePixmap (display, w, width, height, depth);
+  if (pixmap == NULL)
+    return NULL;
+
+  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));
+  mac_free_bitmap (&bitmap);
+
+  return pixmap;
+}
+
+
 /* Mac replacement for XFillRectangle.  */
 
 static void
@@ -597,6 +670,26 @@ XFillRectangle (display, w, gc, x, y, width, height)
 }
 
 
+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;
+{
+  Rect r;
+
+  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));
+}
+
+
 /* Mac replacement for XDrawRectangle: dest is a window.  */
 
 static void
@@ -632,20 +725,15 @@ 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 */
   Rect r;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
-
+  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));
 }
 
 
@@ -760,23 +848,66 @@ mac_copy_area (display, src, dest, gc, src_x, src_y, width, height, dest_x,
   SetPort (dest);
 #endif
 
-  mac_set_colors (gc);
-
   SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
   SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
 
+  ForeColor (blackColor);
+  BackColor (whiteColor);
+
+  LockPixels (GetGWorldPixMap (src));
 #if TARGET_API_MAC_CARBON
-  {
-    PixMapHandle pmh;
+  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));
+}
 
-    LockPortBits (GetWindowPort (dest));
-    pmh = GetPortPixMap (GetWindowPort (dest));
-    CopyBits ((BitMap *) &src, (BitMap *) *pmh, &src_r, &dest_r, srcCopy, 0);
-    UnlockPortBits (GetWindowPort (dest));
-  }
+
+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;
+
+#if TARGET_API_MAC_CARBON
+  SetPort (GetWindowPort (dest));
+#else
+  SetPort (dest);
+#endif
+
+  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));
+  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,7 +942,6 @@ 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);
@@ -822,8 +952,10 @@ mac_scroll_area (display, w, gc, src_x, src_y, width, height, dest_x, dest_y)
   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 +998,67 @@ 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;
 {
   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);
+  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));
+}
+
+
+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;
+{
+  Rect src_r, dest_r;
 
-  SetRect (&src_r, src_x, src_y, src_right, src_bottom);
-  SetRect (&dest_r, dest_x, dest_y, dest_x + w, dest_y + h);
+  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);
 
-  CopyBits ((BitMap *) &src, (BitMap *) &dest, &src_r, &dest_r, srcCopy, 0);
+  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));
 }
 
 
@@ -941,7 +1115,7 @@ XGetGCValues (void* ignore, XGCValues *gc,
 
 /* Mac replacement for XSetForeground.  */
 
-static void
+void
 XSetForeground (display, gc, color)
      Display *display;
      GC gc;
@@ -1145,6 +1319,9 @@ x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
                                output_cursor.x, output_cursor.y);
 
       x_draw_vertical_border (w);
+
+      draw_window_fringes (w);
+
       UNBLOCK_INPUT;
     }
 
@@ -1241,11 +1418,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
@@ -1272,7 +1445,7 @@ x_after_update_window_line (desired_row)
       XClearArea (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
                  0, y, width, height, 0);
       XClearArea (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
-                 f->output_data.mac->pixel_width - width, y,
+                 FRAME_PIXEL_WIDTH (f) - width, y,
                  width, height, 0);
 
       UNBLOCK_INPUT;
@@ -1297,11 +1470,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, 1);
+  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, gc);
+      row->y = oldY;
+      row->visible_height = oldVH;
+    }
+  else
+    x_clip_to_row (w, row, gc);
 
-  if (p->bx >= 0)
+  if (p->bx >= 0 && !p->overlay_p)
     {
       XGCValues gcv;
       gcv.foreground = face->background;
@@ -1327,18 +1515,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);
@@ -2119,6 +2307,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 +2337,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 +2417,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 +2448,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;
@@ -2247,9 +2485,11 @@ static void
 x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
                    raised_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, 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 +2497,41 @@ 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,
+    XDrawLine (dpy, window, gc,
               left_x + i * left_p, top_y + i,
-              right_x + 1 - i * right_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,
+    XDrawLine (dpy, window, gc,
               left_x + i * left_p, bottom_y - i,
-              right_x + 1 - i * right_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 +2546,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 +2556,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);
 }
@@ -2351,9 +2591,10 @@ x_draw_glyph_string_box (s)
   if (s->row->full_width_p
       && !s->w->pseudo_window_p)
     {
-      last_x += FRAME_X_RIGHT_FRINGE_WIDTH (s->f);
-      if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s->f))
-       last_x += FRAME_SCROLL_BAR_WIDTH (s->f) * CANON_X_UNIT (s->f);
+      last_x += WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH (s->w);
+      if (s->area != RIGHT_MARGIN_AREA
+         || WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s->w))
+       last_x += WINDOW_RIGHT_FRINGE_WIDTH (s->w);
     }
 
   /* The glyph that may have a right box line.  */
@@ -2364,9 +2605,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;
 
@@ -2417,39 +2658,36 @@ x_draw_image_foreground (s)
 
   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;
          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, r.x - x, 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->img->width;
+         image_rect.height = s->img->height;
+         if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
+           mac_copy_area (s->display, s->img->pixmap, s->window, s->gc,
+                          r.x - x, 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
@@ -2473,7 +2711,6 @@ x_draw_image_foreground (s)
 }
 
 
-
 /* Draw a relief around the image glyph string S.  */
 
 static void
@@ -2546,30 +2783,12 @@ x_draw_image_foreground_1 (s, pixmap)
 
   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,
+                                          0, 0, s->img->width, s->img->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);
@@ -2584,15 +2803,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->img->width + r*2 - 1,
+                                 s->img->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->img->width - 1, s->img->height - 1);
 }
 
 
@@ -2625,7 +2845,7 @@ x_draw_glyph_string_bg_rect (s, x, y, w, h)
             |   s->face->box
             |
             |     +-------------------------
-            |     |  s->img->vmargin
+            |     |  s->img->margin
             |     |
             |     |       +-------------------
             |     |       |  the image
@@ -2644,6 +2864,7 @@ 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.  */
@@ -2651,9 +2872,7 @@ x_draw_image_glyph_string (s)
   if (height > s->img->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)
     {
@@ -2663,25 +2882,21 @@ x_draw_image_glyph_string (s)
        x = s->x;
 
       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.  */
@@ -2691,18 +2906,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;
@@ -2714,7 +2930,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);
     }
@@ -2743,7 +2959,7 @@ x_draw_stretch_glyph_string (s)
     {
       /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
         as wide as the stretch glyph.  */
-      int width = min (CANON_X_UNIT (s->f), s->background_width);
+      int width = min (FRAME_COLUMN_WIDTH (s->f), s->background_width);
 
       /* Draw cursor.  */
       x_draw_glyph_string_bg_rect (s, s->x, s->y, width, s->height);
@@ -2751,10 +2967,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))
@@ -2814,7 +3030,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.  */
@@ -2851,7 +3066,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;
 
@@ -2928,9 +3143,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.  */
@@ -2950,7 +3165,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.  */
 
@@ -3005,6 +3219,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.  */
 
@@ -3108,7 +3323,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;
 {
@@ -3144,10 +3359,8 @@ 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);
-  width += FRAME_X_FRINGE_WIDTH (f);
-  x -= FRAME_X_LEFT_FRINGE_WIDTH (f);
 
   from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
   to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
@@ -3234,7 +3447,7 @@ x_new_focus_frame (dpyinfo, frame)
       selected_frame = frame;
       XSETFRAME (XWINDOW (selected_frame->selected_window)->frame,
                 selected_frame);
-      Fselect_window (selected_frame->selected_window);
+      Fselect_window (selected_frame->selected_window, Qnil);
       choose_minibuf_frame ();
 #endif /* ! 0 */
 
@@ -3268,8 +3481,6 @@ static void
 XTframe_rehighlight (frame)
      struct frame *frame;
 {
-
-
   x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame));
 }
 
@@ -3464,107 +3675,6 @@ x_get_keysym_name (keysym)
 \f
 /* Mouse clicks and mouse movement.  Rah.  */
 
-/* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
-   co-ordinates in (*X, *Y).  Set *BOUNDS to the rectangle that the
-   glyph at X, Y occupies, if BOUNDS != 0.  If NOCLIP is non-zero, do
-   not force the value into range.  */
-
-void
-pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
-     FRAME_PTR f;
-     register int pix_x, pix_y;
-     register int *x, *y;
-     Rect *bounds;
-     int noclip;
-{
-  /* Support tty mode: if Vwindow_system is nil, behave correctly. */
-  if (NILP (Vwindow_system))
-    {
-      *x = pix_x;
-      *y = pix_y;
-      return;
-    }
-
-  /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
-     even for negative values.  */
-  if (pix_x < 0)
-    pix_x -= FONT_WIDTH (FRAME_FONT (f)) - 1;
-  if (pix_y < 0)
-    pix_y -= (f)->output_data.mac->line_height - 1;
-
-  pix_x = PIXEL_TO_CHAR_COL (f, pix_x);
-  pix_y = PIXEL_TO_CHAR_ROW (f, pix_y);
-
-  if (bounds)
-    {
-      bounds->left = CHAR_TO_PIXEL_COL (f, pix_x);
-      bounds->top = CHAR_TO_PIXEL_ROW (f, pix_y);
-      bounds->right  = bounds->left + FONT_WIDTH  (FRAME_FONT (f)) - 1;
-      bounds->bottom = bounds->top + f->output_data.mac->line_height - 1;
-    }
-
-  if (!noclip)
-    {
-      if (pix_x < 0)
-       pix_x = 0;
-      else if (pix_x > FRAME_WINDOW_WIDTH (f))
-       pix_x = FRAME_WINDOW_WIDTH (f);
-
-      if (pix_y < 0)
-       pix_y = 0;
-      else if (pix_y > f->height)
-       pix_y = f->height;
-    }
-
-  *x = pix_x;
-  *y = pix_y;
-}
-
-
-/* Given HPOS/VPOS in the current matrix of W, return corresponding
-   frame-relative pixel positions in *FRAME_X and *FRAME_Y.  If we
-   can't tell the positions because W's display is not up to date,
-   return 0.  */
-
-int
-glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
-     struct window *w;
-     int hpos, vpos;
-     int *frame_x, *frame_y;
-{
-  int success_p;
-
-  xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
-  xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
-
-  if (display_completed)
-    {
-      struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
-      struct glyph *glyph = row->glyphs[TEXT_AREA];
-      struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
-
-      *frame_y = row->y;
-      *frame_x = row->x;
-      while (glyph < end)
-       {
-         *frame_x += glyph->pixel_width;
-         ++glyph;
-       }
-
-      success_p = 1;
-    }
-  else
-    {
-      *frame_y = *frame_x = 0;
-      success_p = 0;
-    }
-
-  *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, *frame_y);
-  *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, *frame_x);
-  return success_p;
-}
-
-
 /* Prepare a mouse-event in *RESULT for placement in the input queue.
 
    If the event is a button press, then note that we have grabbed
@@ -3691,15 +3801,14 @@ glyph_rect (f, x, y, rect)
 {
   Lisp_Object window;
 
-  window = window_from_coordinates (f, x, y, 0, 0);
+  window = window_from_coordinates (f, x, y, 0, &x, &y, 0);
+
   if (!NILP (window))
     {
       struct window *w = XWINDOW (window);
       struct glyph_row *r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
       struct glyph_row *end = r + w->current_matrix->nrows - 1;
 
-      frame_to_window_pixel_xy (w, &x, &y);
-
       for (; r < end && r->enabled_p; ++r)
        if (r->y <= y && r->y + r->height > y)
          {
@@ -3714,7 +3823,10 @@ glyph_rect (f, x, y, rect)
            if (x < r->x)
              {
                /* x is to the left of the first glyph in the row.  */
-               rect->left = XINT (w->left);
+               /* Shouldn't this be a pixel value?
+                  WINDOW_LEFT_EDGE_X (w) seems to be the right value.
+                  ++KFS */
+               rect->left = WINDOW_LEFT_EDGE_COL (w);
                rect->right = WINDOW_TO_FRAME_PIXEL_X (w, r->x);
                return 1;
              }
@@ -3730,7 +3842,10 @@ 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);
-           rect->right = XINT (w->left) + XINT (w->width);
+           /* 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);
            return 1;
          }
     }
@@ -3752,7 +3867,7 @@ remember_mouse_glyph (f1, gx, gy)
       int width = FRAME_SMALLEST_CHAR_WIDTH (f1);
       int height = FRAME_SMALLEST_FONT_HEIGHT (f1);
 
-      /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
+      /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
         round down even for negative values.  */
       if (gx < 0)
        gx -= width - 1;
@@ -4038,35 +4153,30 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
   struct frame *f = XFRAME (w->frame);
   struct scroll_bar *bar;
   int top, height, left, sb_left, width, sb_width, disp_top, disp_height;
-  int window_x, window_y, window_width, window_height;
+  int window_y, window_height;
 
   /* Get window dimensions.  */
-  window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
+  window_box (w, -1, 0, &window_y, 0, &window_height);
   top = window_y;
 #ifdef MAC_OSX
   width = 16;
 #else
-  width = FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f);
+  width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f);
 #endif
   height = window_height;
 
   /* Compute the left edge of the scroll bar area.  */
-  if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
-    left = XINT (w->left) + XINT (w->width) - FRAME_SCROLL_BAR_COLS (f);
-  else
-    left = XFASTINT (w->left);
-  left *= CANON_X_UNIT (f);
-  left += FRAME_INTERNAL_BORDER_WIDTH (f);
+  left = WINDOW_SCROLL_BAR_AREA_X (w);
 
   /* Compute the width of the scroll bar which might be less than
      the width of the area reserved for the scroll bar.  */
-  if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0)
-    sb_width = FRAME_SCROLL_BAR_PIXEL_WIDTH (f);
+  if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) > 0)
+    sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
   else
     sb_width = width;
 
   /* Compute the left edge of the scroll bar.  */
-  if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
+  if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
     sb_left = left + width - sb_width - (width - sb_width) / 2;
   else
     sb_left = left + (width - sb_width) / 2;
@@ -4079,13 +4189,13 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
       disp_top = -1;
       disp_height++;
     }
-  else if (disp_top == PIXEL_HEIGHT (f) - 16)
+  else if (disp_top == FRAME_PIXEL_HEIGHT (f) - 16)
     {
       disp_top++;
       disp_height--;
     }
 
-  if (sb_left + sb_width == PIXEL_WIDTH (f))
+  if (sb_left + sb_width == FRAME_PIXEL_WIDTH (f))
     sb_left++;
 
   /* Does the scroll bar exist yet?  */
@@ -4121,12 +4231,12 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
             wide as the area reserved for it .  This makes sure a
             previous mode line display is cleared after C-x 2 C-x 1, for
             example.  */
-         int area_width = FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f);
+         int area_width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
          XClearArea (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
                      left, top, area_width, height, 0);
 
 #if 0
-          if (sb_left + sb_width >= PIXEL_WIDTH (f))
+          if (sb_left + sb_width >= FRAME_PIXEL_WIDTH (f))
             XClearArea (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
                        sb_left - 1, top, 1, height, 0);
 #endif
@@ -4469,25 +4579,22 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
 
 /* Set clipping for output in glyph row ROW.  W is the window in which
    we operate.  GC is the graphics context to set clipping in.
-   WHOLE_LINE_P non-zero means include the areas used for truncation
-   mark display and alike in the clipping rectangle.
 
    ROW may be a text row or, e.g., a mode line.  Text rows must be
    clipped to the interior of the window dedicated to text display,
    mode lines must be clipped to the whole window.  */
 
 static void
-x_clip_to_row (w, row, gc, whole_line_p)
+x_clip_to_row (w, row, gc)
      struct window *w;
      struct glyph_row *row;
      GC gc;
-     int whole_line_p;
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   Rect clip_rect;
-  int window_x, window_y, window_width, window_height;
+  int window_y, window_width;
 
-  window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
+  window_box (w, -1, 0, &window_y, &window_width, 0);
 
   clip_rect.left = WINDOW_TO_FRAME_PIXEL_X (w, 0);
   clip_rect.top = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
@@ -4495,14 +4602,6 @@ x_clip_to_row (w, row, gc, whole_line_p)
   clip_rect.right = clip_rect.left + window_width;
   clip_rect.bottom = clip_rect.top + row->visible_height;
 
-  /* If clipping to the whole line, including trunc marks, extend
-     the rectangle to the left and increase its width.  */
-  if (whole_line_p)
-    {
-      clip_rect.left -= FRAME_X_LEFT_FRINGE_WIDTH (f);
-      clip_rect.right += FRAME_X_FRINGE_WIDTH (f);
-    }
-
   mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), &clip_rect);
 }
 
@@ -4522,13 +4621,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);
@@ -4542,7 +4634,21 @@ x_draw_hollow_cursor (w, row)
   wd = cursor_glyph->pixel_width - 1;
   if (cursor_glyph->type == STRETCH_GLYPH
       && !x_stretch_cursor_p)
-    wd = min (CANON_X_UNIT (f), wd);
+    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 (FRAME_LINE_HEIGHT (f), 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.  */
@@ -4555,7 +4661,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, 0);
+  x_clip_to_row (w, row, gc);
   mac_draw_rectangle (dpy, FRAME_MAC_WINDOW (f), gc, x, y, wd, h);
   mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f));
 }
@@ -4569,35 +4675,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);
@@ -4609,14 +4729,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, 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, 0);
-      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));
     }
 }
@@ -4648,19 +4778,26 @@ mac_clear_frame_area (f, x, y, width, height)
 /* RIF: Draw cursor on window W.  */
 
 static void
-mac_draw_window_cursor (w, glyph_row, on, x, y, new_cursor_type, new_cursor_width)
+mac_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, active_p)
      struct window *w;
      struct glyph_row *glyph_row;
-     int on, x, y;
-     int new_cursor_type, new_cursor_width;
+     int x, y;
+     int cursor_type, cursor_width;
+     int on_p, active_p;
 {
-  if (on)
+  if (on_p)
     {
-      w->phys_cursor_type = new_cursor_type;
-      w->phys_cursor_width = new_cursor_width;
+      w->phys_cursor_type = cursor_type;
       w->phys_cursor_on_p = 1;
 
-      switch (new_cursor_type)
+      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:
          x_draw_hollow_cursor (w, glyph_row);
@@ -4670,13 +4807,16 @@ mac_draw_window_cursor (w, glyph_row, on, x, y, new_cursor_type, new_cursor_widt
          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, new_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:
@@ -4784,36 +4924,37 @@ x_new_font (f, fontname)
   FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset;
   FRAME_FONTSET (f) = -1;
 
+  FRAME_COLUMN_WIDTH (f) = FONT_WIDTH (FRAME_FONT (f));
+  FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (FRAME_FONT (f));
+
+  compute_fringe_widths (f, 1);
+
   /* Compute the scroll bar width in character columns.  */
-  if (f->scroll_bar_pixel_width > 0)
+  if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
     {
-      int wid = FONT_WIDTH (FRAME_FONT (f));
-      f->scroll_bar_cols = (f->scroll_bar_pixel_width + wid-1) / wid;
+      int wid = FRAME_COLUMN_WIDTH (f);
+      FRAME_CONFIG_SCROLL_BAR_COLS (f) 
+       = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid-1) / wid;
     }
   else
     {
-      int wid = FONT_WIDTH (FRAME_FONT (f));
-      f->scroll_bar_cols = (14 + wid - 1) / wid;
+      int wid = FRAME_COLUMN_WIDTH (f);
+      FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
     }
 
   /* Now make the frame display the given font.  */
   if (FRAME_MAC_WINDOW (f) != 0)
     {
       XSetFont (FRAME_MAC_DISPLAY (f), f->output_data.mac->normal_gc,
-               f->output_data.mac->font);
+               FRAME_FONT (f));
       XSetFont (FRAME_MAC_DISPLAY (f), f->output_data.mac->reverse_gc,
-               f->output_data.mac->font);
+               FRAME_FONT (f));
       XSetFont (FRAME_MAC_DISPLAY (f), f->output_data.mac->cursor_gc,
-               f->output_data.mac->font);
+               FRAME_FONT (f));
 
-      frame_update_line_height (f);
       if (NILP (tip_frame) || XFRAME (tip_frame) != f)
-        x_set_window_size (f, 0, f->width, f->height);
+        x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
     }
-  else
-    /* If we are setting a new frame's font for the first time,
-       there are no faces yet, so this font's height is the line height.  */
-    f->output_data.mac->line_height = FONT_HEIGHT (FRAME_FONT (f));
 
   return build_string (fontp->full_name);
 }
@@ -4875,7 +5016,7 @@ x_calc_absolute_position (f)
      struct frame *f;
 {
   Point pt;
-  int flags = f->output_data.mac->size_hint_flags;
+  int flags = f->size_hint_flags;
 
   pt.h = pt.v = 0;
 
@@ -4909,20 +5050,20 @@ x_calc_absolute_position (f)
   /* Treat negative positions as relative to the leftmost bottommost
      position that fits on the screen.  */
   if (flags & XNegative)
-    f->output_data.mac->left_pos = (FRAME_MAC_DISPLAY_INFO (f)->width
-                             - 2 * f->output_data.mac->border_width - pt.h
-                             - PIXEL_WIDTH (f)
-                             + f->output_data.mac->left_pos);
+    f->left_pos = (FRAME_MAC_DISPLAY_INFO (f)->width
+                  - 2 * f->border_width - pt.h
+                  - FRAME_PIXEL_WIDTH (f)
+                  + f->left_pos);
   /* NTEMACS_TODO: Subtract menubar height?  */
   if (flags & YNegative)
-    f->output_data.mac->top_pos = (FRAME_MAC_DISPLAY_INFO (f)->height
-                            - 2 * f->output_data.mac->border_width - pt.v
-                            - PIXEL_HEIGHT (f)
-                            + f->output_data.mac->top_pos);
+    f->top_pos = (FRAME_MAC_DISPLAY_INFO (f)->height
+                 - 2 * f->border_width - pt.v
+                 - 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.  */
-  f->output_data.mac->size_hint_flags &= ~ (XNegative | YNegative);
+  f->size_hint_flags &= ~ (XNegative | YNegative);
 }
 
 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
@@ -4941,22 +5082,22 @@ x_set_offset (f, xoff, yoff, change_gravity)
 
   if (change_gravity > 0)
     {
-      f->output_data.mac->top_pos = yoff;
-      f->output_data.mac->left_pos = xoff;
-      f->output_data.mac->size_hint_flags &= ~ (XNegative | YNegative);
+      f->top_pos = yoff;
+      f->left_pos = xoff;
+      f->size_hint_flags &= ~ (XNegative | YNegative);
       if (xoff < 0)
-       f->output_data.mac->size_hint_flags |= XNegative;
+       f->size_hint_flags |= XNegative;
       if (yoff < 0)
-       f->output_data.mac->size_hint_flags |= YNegative;
-      f->output_data.mac->win_gravity = NorthWestGravity;
+       f->size_hint_flags |= YNegative;
+      f->win_gravity = NorthWestGravity;
     }
   x_calc_absolute_position (f);
 
   BLOCK_INPUT;
   x_wm_set_size_hint (f, (long) 0, 0);
 
-  modified_left = f->output_data.mac->left_pos;
-  modified_top = f->output_data.mac->top_pos;
+  modified_left = f->left_pos;
+  modified_top = f->top_pos;
 
   MoveWindow (f->output_data.mac->mWP, modified_left + 6,
              modified_top + 42, false);
@@ -4980,17 +5121,15 @@ x_set_window_size (f, change_gravity, cols, rows)
   BLOCK_INPUT;
 
   check_frame_size (f, &rows, &cols);
-  f->output_data.mac->vertical_scroll_bar_extra
-    = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
-       ? 0
-       : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.mac->font)));
+  f->scroll_bar_actual_width
+    = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
 
   compute_fringe_widths (f, 0);
 
-  pixelwidth = CHAR_TO_PIXEL_WIDTH (f, cols);
-  pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows);
+  pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols);
+  pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
 
-  f->output_data.mac->win_gravity = NorthWestGravity;
+  f->win_gravity = NorthWestGravity;
   x_wm_set_size_hint (f, (long) 0, 0);
 
   SizeWindow (FRAME_MAC_WINDOW (f), pixelwidth, pixelheight, 0);
@@ -5009,8 +5148,8 @@ x_set_window_size (f, change_gravity, cols, rows)
      We pass 1 for DELAY since we can't run Lisp code inside of
      a BLOCK_INPUT.  */
   change_frame_size (f, rows, cols, 0, 1, 0);
-  PIXEL_WIDTH (f) = pixelwidth;
-  PIXEL_HEIGHT (f) = pixelheight;
+  FRAME_PIXEL_WIDTH (f) = pixelwidth;
+  FRAME_PIXEL_HEIGHT (f) = pixelheight;
 
   /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
      receive in the ConfigureNotify event; if we get what we asked
@@ -5043,14 +5182,14 @@ x_set_mouse_position (f, x, y)
 {
   int pix_x, pix_y;
 
-  pix_x = CHAR_TO_PIXEL_COL (f, x) + FONT_WIDTH  (f->output_data.mac->font) / 2;
-  pix_y = CHAR_TO_PIXEL_ROW (f, y) + f->output_data.mac->line_height / 2;
+  pix_x = FRAME_COL_TO_PIXEL_X (f, x) + FRAME_COLUMN_WIDTH (f) / 2;
+  pix_y = FRAME_LINE_TO_PIXEL_Y (f, y) + FRAME_LINE_HEIGHT (f) / 2;
 
   if (pix_x < 0) pix_x = 0;
-  if (pix_x > PIXEL_WIDTH (f)) pix_x = PIXEL_WIDTH (f);
+  if (pix_x > FRAME_PIXEL_WIDTH (f)) pix_x = FRAME_PIXEL_WIDTH (f);
 
   if (pix_y < 0) pix_y = 0;
-  if (pix_y > PIXEL_HEIGHT (f)) pix_y = PIXEL_HEIGHT (f);
+  if (pix_y > FRAME_PIXEL_HEIGHT (f)) pix_y = FRAME_PIXEL_HEIGHT (f);
 
   x_set_mouse_pixel_position (f, pix_x, pix_y);
 }
@@ -5149,8 +5288,7 @@ x_make_frame_visible (f)
         before the window gets really visible.  */
       if (! FRAME_ICONIFIED_P (f)
          && ! f->output_data.mac->asked_for_visible)
-       x_set_offset (f, f->output_data.mac->left_pos,
-                     f->output_data.mac->top_pos, 0);
+       x_set_offset (f, f->left_pos, f->top_pos, 0);
 
       f->output_data.mac->asked_for_visible = 1;
 
@@ -5203,6 +5341,8 @@ x_make_frame_visible (f)
        FRAME_SAMPLE_VISIBILITY (f);
       }
   }
+#else
+  UNBLOCK_INPUT;
 #endif /* MAC_TODO */
 }
 
@@ -5259,10 +5399,10 @@ 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);
@@ -5272,10 +5412,15 @@ x_destroy_window (f)
   DisposeWindow (FRAME_MAC_WINDOW (f));
 
   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)
@@ -5283,8 +5428,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
@@ -5298,6 +5441,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.  */
 
@@ -5327,8 +5485,8 @@ x_wm_set_size_hint (f, flags, user_position)
   /* Setting PMaxSize caused various problems.  */
   size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */;
 
-  size_hints.x = f->output_data.x->left_pos;
-  size_hints.y = f->output_data.x->top_pos;
+  size_hints.x = f->left_pos;
+  size_hints.y = f->top_pos;
 
 #ifdef USE_X_TOOLKIT
   XtSetArg (al[ac], XtNwidth, &widget_width); ac++;
@@ -5337,16 +5495,16 @@ x_wm_set_size_hint (f, flags, user_position)
   size_hints.height = widget_height;
   size_hints.width = widget_width;
 #else /* not USE_X_TOOLKIT */
-  size_hints.height = PIXEL_HEIGHT (f);
-  size_hints.width = PIXEL_WIDTH (f);
+  size_hints.height = FRAME_PIXEL_HEIGHT (f);
+  size_hints.width = FRAME_PIXEL_WIDTH (f);
 #endif /* not USE_X_TOOLKIT */
 
-  size_hints.width_inc = FONT_WIDTH (f->output_data.x->font);
-  size_hints.height_inc = f->output_data.x->line_height;
+  size_hints.width_inc = FRAME_COLUMN_WIDTH (f);
+  size_hints.height_inc = FRAME_LINE_HEIGHT (f);
   size_hints.max_width
-    = FRAME_X_DISPLAY_INFO (f)->width - CHAR_TO_PIXEL_WIDTH (f, 0);
+    = FRAME_X_DISPLAY_INFO (f)->width - FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
   size_hints.max_height
-    = FRAME_X_DISPLAY_INFO (f)->height - CHAR_TO_PIXEL_HEIGHT (f, 0);
+    = FRAME_X_DISPLAY_INFO (f)->height - FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
 
   /* Calculate the base and minimum sizes.
 
@@ -5357,8 +5515,8 @@ x_wm_set_size_hint (f, flags, user_position)
     int base_width, base_height;
     int min_rows = 0, min_cols = 0;
 
-    base_width = CHAR_TO_PIXEL_WIDTH (f, 0);
-    base_height = CHAR_TO_PIXEL_HEIGHT (f, 0);
+    base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
+    base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
 
     check_frame_size (f, &min_rows, &min_cols);
 
@@ -5433,7 +5591,7 @@ x_wm_set_size_hint (f, flags, user_position)
 #endif
 
 #ifdef PWinGravity
-  size_hints.win_gravity = f->output_data.x->win_gravity;
+  size_hints.win_gravity = f->win_gravity;
   size_hints.flags |= PWinGravity;
 
   if (user_position)
@@ -5564,6 +5722,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)
@@ -5643,13 +5802,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)
     {
@@ -5708,6 +5907,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, "");
 
@@ -5717,13 +5918,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';
+    }
 }
 
 
@@ -5787,36 +6004,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.  */
@@ -5858,6 +6084,7 @@ init_font_name_table ()
 
          TextFont (fontnum);
          scriptcode = FontToScript (fontnum);
+         decode_mac_font_name (name, sizeof (name), scriptcode);
          do
            {
              HLock (font_handle);
@@ -5892,9 +6119,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++]
@@ -5921,10 +6148,150 @@ init_font_name_table ()
 }
 
 
+enum xlfd_scalable_field_index
+  {
+    XLFD_SCL_PIXEL_SIZE,
+    XLFD_SCL_POINT_SIZE,
+    XLFD_SCL_AVGWIDTH,
+    XLFD_SCL_LAST
+  };
+
+static int xlfd_scalable_fields[] =
+  {
+    6,                         /* PIXEL_SIZE */
+    7,                         /* POINT_SIZE */
+    11,                                /* AVGWIDTH */
+    -1
+  };
+
+static Lisp_Object
+mac_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 (i == 14 && ptr == NULL)
+    {
+      if (scl_val[XLFD_SCL_POINT_SIZE] > 0)
+       {
+         scl_val[XLFD_SCL_PIXEL_SIZE] = scl_val[XLFD_SCL_POINT_SIZE] / 10;
+         scl_val[XLFD_SCL_AVGWIDTH] = scl_val[XLFD_SCL_POINT_SIZE];
+       }
+      else if (scl_val[XLFD_SCL_PIXEL_SIZE] > 0)
+       {
+         scl_val[XLFD_SCL_POINT_SIZE] =
+           scl_val[XLFD_SCL_AVGWIDTH] = scl_val[XLFD_SCL_PIXEL_SIZE] * 10;
+       }
+      else if (scl_val[XLFD_SCL_AVGWIDTH] > 0)
+       {
+         scl_val[XLFD_SCL_PIXEL_SIZE] = scl_val[XLFD_SCL_AVGWIDTH] / 10;
+         scl_val[XLFD_SCL_POINT_SIZE] = scl_val[XLFD_SCL_AVGWIDTH];
+       }
+    }
+  else
+    scl_val[XLFD_SCL_PIXEL_SIZE] = -1;
+
+  ptr = regex;
+  *ptr++ = '^';
+
+  /* Turn pattern into a regexp and do a regexp match.  */
+  for (; *pattern; pattern++)
+    {
+      if (*pattern == '?')
+        *ptr++ = '.';
+      else if (*pattern == '*')
+        {
+          *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;
+}
+
 /* 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).  */
+   calling mac_font_pattern_match (slow).  Return as many matching
+   fonts as possible if MAXNAMES = -1.  */
 
 Lisp_Object
 x_list_fonts (struct frame *f,
@@ -5932,11 +6299,7 @@ x_list_fonts (struct frame *f,
               int size,
               int maxnames)
 {
-  char *ptnstr;
   Lisp_Object newlist = Qnil, tem, key;
-  int n_fonts = 0;
-  int i;
-  struct gcpro gcpro1, gcpro2;
   struct mac_display_info *dpyinfo = f ? FRAME_MAC_DISPLAY_INFO (f) : NULL;
 
   if (font_name_table == NULL)  /* Initialize when first used.  */
@@ -5955,27 +6318,10 @@ x_list_fonts (struct frame *f,
        }
     }
 
-  ptnstr = SDATA (pattern);
-
-  GCPRO2 (pattern, newlist);
-
-  /* Scan and matching bitmap fonts.  */
-  for (i = 0; i < font_name_count; i++)
-    {
-      if (mac_font_pattern_match (font_name_table[i], ptnstr))
-        {
-          newlist = Fcons (build_string (font_name_table[i]), newlist);
-
-          n_fonts++;
-          if (n_fonts >= maxnames)
-            break;
-        }
-    }
+  newlist = mac_do_list_fonts (SDATA (pattern), maxnames);
 
   /* MAC_TODO: add code for matching outline fonts here */
 
-  UNGCPRO;
-
   if (dpyinfo)
     {
       XSETCDR (dpyinfo->name_list_element,
@@ -6135,14 +6481,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 */
@@ -6264,7 +6608,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);
           }
       }
     }
@@ -6353,6 +6698,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);
@@ -6486,81 +6832,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
@@ -6622,12 +6893,19 @@ 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;
 
 /* 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.  */
@@ -6700,6 +6978,20 @@ mac_to_emacs_modifiers (EventModifiers mods)
   return result;
 }
 
+static int
+mac_get_emulated_btn ( UInt32 modifiers )
+{
+  int result = 0;
+  if (Vmac_emulate_three_button_mouse != Qnil) {
+    int cmdIs3 = (Vmac_emulate_three_button_mouse != Qreverse);
+    if (modifiers & controlKey)
+      result = cmdIs3 ? 2 : 1;
+    else if (modifiers & optionKey)
+      result = cmdIs3 ? 1 : 2;      
+  }
+  return result;
+}
+
 #if USE_CARBON_EVENTS
 /* Obtains the event modifiers from the event ref and then calls
    mac_to_emacs_modifiers.  */
@@ -6709,6 +7001,11 @@ mac_event_to_emacs_modifiers (EventRef eventRef)
   UInt32 mods = 0;
   GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, NULL,
                    sizeof (UInt32), NULL, &mods);
+  if (Vmac_emulate_three_button_mouse != Qnil &&
+      GetEventClass(eventRef) == kEventClassMouse)
+    {
+      mods &= ~(optionKey & cmdKey);
+    }
   return mac_to_emacs_modifiers (mods);
 }
 
@@ -6723,7 +7020,14 @@ mac_get_mouse_btn (EventRef ref)
   switch (result)
     {
     case kEventMouseButtonPrimary:
-      return 0;
+      if (Vmac_emulate_three_button_mouse == Qnil) 
+       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:
@@ -6832,8 +7136,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);
@@ -7114,8 +7418,8 @@ do_grow_window (WindowPtr w, EventRecord *e)
   /* see if it really changed size */
   if (grow_size != 0)
     {
-      rows = PIXEL_TO_CHAR_HEIGHT (f, HiWord (grow_size));
-      columns = PIXEL_TO_CHAR_WIDTH (f, LoWord (grow_size));
+      rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, HiWord (grow_size));
+      columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, LoWord (grow_size));
 
       x_set_window_size (f, 0, columns, rows);
     }
@@ -7167,7 +7471,7 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out)
         InsetRect (&zoom_rect, 8, 4);  /* not too tight */
 
         zoom_rect.right = zoom_rect.left
-         + CHAR_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
+         + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
 
         SetWindowStandardState (w, &zoom_rect);
       }
@@ -7189,7 +7493,7 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out)
       InsetRect (&zoom_rect, 8, 4);  /* not too tight */
 
       zoom_rect.right = zoom_rect.left
-       + CHAR_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
+       + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
 
       (**((WStateDataHandle) ((WindowPeek) w)->dataHandle)).stdState
        = zoom_rect;
@@ -7204,8 +7508,8 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out)
 #else
   port_rect = w->portRect;
 #endif
-  rows = PIXEL_TO_CHAR_HEIGHT (f, port_rect.bottom - port_rect.top);
-  columns = PIXEL_TO_CHAR_WIDTH (f, port_rect.right - port_rect.left);
+  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);
@@ -7632,7 +7936,9 @@ main (void)
 
   do_get_menus ();
 
+#ifndef USE_LSB_TAG
   do_check_ram_size ();
+#endif
 
   init_emacs_passwd_dir ();
 
@@ -7710,8 +8016,9 @@ 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 (int sd, int expected, struct input_event *hold_quit)
 {
+  struct input_event inev;
   int count = 0;
 #if USE_CARBON_EVENTS
   OSStatus rneResult;
@@ -7736,9 +8043,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
@@ -7757,7 +8061,9 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
      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;
+  EVENT_INIT (inev);
+  inev.kind = NO_EVENT;
+  inev.arg = Qnil;
 
   event_mask = everyEvent;
   if (NILP (Fboundp (Qmac_ready_for_drag_n_drop)))
@@ -7795,16 +8101,17 @@ 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);
+               inev.kind = WHEEL_EVENT;
+               inev.code = 0;
+               inev.modifiers = (mac_event_to_emacs_modifiers(eventRef)
+                                 | ((delta < 0) ? down_modifier
+                                    : up_modifier));
                SetPort (GetWindowPort (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, mwp->mFP);
+               inev.timestamp = EventTimeToTicks (GetEventTime (eventRef))*(1000/60);
              }
            else
              SendEventToEventTarget (eventRef, GetEventDispatcherTarget ());
@@ -7853,28 +8160,27 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
              GlobalToLocal (&mouse_loc);
 
 #if USE_CARBON_EVENTS
-             bufp->code = mac_get_mouse_btn (eventRef);
+             inev.code = mac_get_mouse_btn (eventRef);
 #else
-             bufp->code = 0;  /* only one mouse button */
+             inev.code = mac_get_emulate_btn (er.modifiers);
 #endif
-              bufp->kind = SCROLL_BAR_CLICK_EVENT;
-              bufp->frame_or_window = tracked_scroll_bar->window;
-              bufp->part = scroll_bar_handle;
+              inev.kind = SCROLL_BAR_CLICK_EVENT;
+              inev.frame_or_window = tracked_scroll_bar->window;
+              inev.part = scroll_bar_handle;
 #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
-              bufp->modifiers |= up_modifier;
-             bufp->timestamp = er.when * (1000 / 60);
+              inev.modifiers |= up_modifier;
+             inev.timestamp = er.when * (1000 / 60);
                /* ticks to milliseconds */
 
-              XSETINT (bufp->x, tracked_scroll_bar->left + 2);
-              XSETINT (bufp->y, mouse_loc.v - 24);
+              XSETINT (inev.x, tracked_scroll_bar->left + 2);
+              XSETINT (inev.y, mouse_loc.v - 24);
               tracked_scroll_bar->dragging = Qnil;
               mouse_tracking_in_progress = mouse_tracking_none;
               tracked_scroll_bar = NULL;
-              count++;
               break;
             }
 
@@ -7883,14 +8189,14 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
          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++;
-              }
+             if (er.what == mouseDown)  
+               {
+                 struct frame *f = ((mac_output *)
+                                    GetWRefCon (FrontWindow ()))->mFP;
+                 saved_menu_event_location = er.where;
+                 inev.kind = MENU_BAR_ACTIVATE_EVENT;
+                 XSETFRAME (inev.frame_or_window, f);
+               }
              break;
 
            case inContent:
@@ -7920,13 +8226,13 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
 #endif
 
 #if USE_CARBON_EVENTS
-                 bufp->code = mac_get_mouse_btn (eventRef);
+                 inev.code = mac_get_mouse_btn (eventRef);
 #else
-                 bufp->code = 0;  /* only one mouse button */
+                 inev.code = mac_get_emulate_btn (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 TARGET_API_MAC_CARBON
@@ -7938,7 +8244,7 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
                      struct scroll_bar *bar = (struct scroll_bar *)
                        GetControlReference (ch);
                      x_scroll_bar_handle_click (bar, control_part_code, &er,
-                                                bufp);
+                                                &inev);
                      if (er.what == mouseDown
                          && control_part_code == kControlIndicatorPart)
                        {
@@ -7954,43 +8260,61 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
                    }
                  else
                    {
-                     bufp->kind = MOUSE_CLICK_EVENT;
-                     XSETFRAME (bufp->frame_or_window, mwp->mFP);
+                     Lisp_Object window;
+
+                     XSETFRAME (inev.frame_or_window, mwp->mFP);
                      if (er.what == mouseDown)
-                       mouse_tracking_in_progress
+                       mouse_tracking_in_progress
                          = mouse_tracking_mouse_movement;
                      else
-                       mouse_tracking_in_progress = mouse_tracking_none;
-                   }
+                       mouse_tracking_in_progress = mouse_tracking_none;
+                     window = window_from_coordinates (mwp->mFP, inev.x, inev.y, 0, 0, 0, 1);
+                     
+                     if (EQ (window, mwp->mFP->tool_bar_window))
+                       {
+                         if (er.what == mouseDown)
+                           handle_tool_bar_click (mwp->mFP, inev.x, inev.y, 1, 0);
+                         else
+                           handle_tool_bar_click (mwp->mFP, inev.x, inev.y, 0,
+#if USE_CARBON_EVENTS
+                                                  mac_event_to_emacs_modifiers (eventRef)
+#else
+                                                  er.modifiers
+#endif
+                                                  );
+                         break;
+                       }
+                     else
+                       inev.kind = MOUSE_CLICK_EVENT;
+                   }
 
 #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
 
                  switch (er.what)
                    {
                    case mouseDown:
-                     bufp->modifiers |= down_modifier;
+                     inev.modifiers |= down_modifier;
                      break;
                    case mouseUp:
-                     bufp->modifiers |= up_modifier;
+                     inev.modifiers |= up_modifier;
                      break;
                    }
-
-                 count++;
                }
              break;
 
            case inDrag:
 #if TARGET_API_MAC_CARBON
-             {
-               BitMap bm;
-
-               GetQDGlobalsScreenBits (&bm);
-               DragWindow (window_ptr, er.where, &bm.bounds);
-             }
+              if (er.what == mouseDown)  
+               {
+                 BitMap bm;
+                 
+                 GetQDGlobalsScreenBits (&bm);
+                 DragWindow (window_ptr, er.where, &bm.bounds);
+               }
 #else /* not TARGET_API_MAC_CARBON */
              DragWindow (window_ptr, er.where, &qd.screenBits.bounds);
 #endif /* not TARGET_API_MAC_CARBON */
@@ -7999,17 +8323,19 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
            case inGoAway:
              if (TrackGoAway (window_ptr, er.where))
                {
-                 bufp->kind = DELETE_WINDOW_EVENT;
-                 XSETFRAME (bufp->frame_or_window,
+                 inev.kind = DELETE_WINDOW_EVENT;
+                 XSETFRAME (inev.frame_or_window,
                             ((mac_output *) GetWRefCon (window_ptr))->mFP);
-                 count++;
                }
              break;
 
            /* window resize handling added --ben */
            case inGrow:
-             do_grow_window(window_ptr, &er);
-             break;
+              if (er.what == mouseDown)  
+               {
+                 do_grow_window(window_ptr, &er);
+                 break;
+               }
 
            /* window zoom handling added --ben */
            case inZoomIn:
@@ -8068,8 +8394,8 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
 
          if (keycode_to_xkeysym (keycode, &xkeysym))
            {
-             bufp->code = 0xff00 | xkeysym;
-             bufp->kind = NON_ASCII_KEYSTROKE_EVENT;
+             inev.code = 0xff00 | xkeysym;
+             inev.kind = NON_ASCII_KEYSTROKE_EVENT;
            }
          else
            {
@@ -8088,12 +8414,12 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
                  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;
+                 inev.code = KeyTranslate (kchr_ptr, new_keycode,
+                                           &some_state) & 0xff;
                }
              else
-               bufp->code = er.message & charCodeMask;
-             bufp->kind = ASCII_KEYSTROKE_EVENT;
+               inev.code = er.message & charCodeMask;
+             inev.kind = ASCII_KEYSTROKE_EVENT;
            }
        }
 
@@ -8104,7 +8430,7 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
           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)
+           && inev.kind == ASCII_KEYSTROKE_EVENT && inev.code >= 128)
          {
            static TECObjectRef converter = NULL;
            OSStatus the_err = noErr;
@@ -8133,7 +8459,7 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
 
            if (the_err == noErr)
              {
-               unsigned char ch = bufp->code;
+               unsigned char ch = inev.code;
                ByteCount actual_input_length, actual_output_length;
                unsigned char outch;
 
@@ -8144,25 +8470,23 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
                if (convert_status == noErr
                    && actual_input_length == 1
                    && actual_output_length == 1)
-                 bufp->code = outch;
+                 inev.code = outch;
              }
          }
 
 #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
 
        {
          mac_output *mwp
            = (mac_output *) GetWRefCon (FrontNonFloatingWindow ());
-         XSETFRAME (bufp->frame_or_window, mwp->mFP);
+         XSETFRAME (inev.frame_or_window, mwp->mFP);
        }
 
-       bufp->timestamp = er.when * (1000 / 60);  /* ticks to milliseconds */
-
-       count++;
+       inev.timestamp = er.when * (1000 / 60);  /* ticks to milliseconds */
        break;
 
       case kHighLevelEvent:
@@ -8190,21 +8514,21 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
             if (wp && is_emacs_window(wp))
                f = ((mac_output *) GetWRefCon (wp))->mFP;
 
-            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);
+            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.
@@ -8221,8 +8545,6 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
 #else /* not TARGET_API_MAC_CARBON */
               InvalRect (&(wp->portRect));
 #endif /* not TARGET_API_MAC_CARBON */
-
-            count++;
           }
       default:
        break;
@@ -8291,8 +8613,13 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
       }
   }
 
-  UNBLOCK_INPUT;
+  if (inev.kind != NO_EVENT)
+    {
+      kbd_buffer_store_event_hold (&inev, hold_quit);
+      count++;
+    }
 
+  UNBLOCK_INPUT;
   return count;
 }
 
@@ -8354,7 +8681,7 @@ NewMacWindow (FRAME_PTR fp)
 
   mwp->fontset = -1;
 
-  SizeWindow (mwp->mWP, mwp->pixel_width, mwp->pixel_height, false);
+  SizeWindow (mwp->mWP, FRAME_PIXEL_WIDTH (fp), FRAME_PIXEL_HEIGHT (fp), false);
   ShowWindow (mwp->mWP);
 
 }
@@ -8363,9 +8690,6 @@ NewMacWindow (FRAME_PTR fp)
 void
 make_mac_frame (struct frame *f)
 {
-  FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
-  FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_right;
-
   FRAME_DESIRED_CURSOR (f) = FILLED_BOX_CURSOR;
 
   NewMacWindow(f);
@@ -8375,23 +8699,23 @@ make_mac_frame (struct frame *f)
   f->output_data.mac->mouse_pixel = 0xff00ff;
   f->output_data.mac->cursor_foreground_pixel = 0x0000ff;
 
-  f->output_data.mac->fontset = -1;
+  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->left_pos = 4;
-  f->output_data.mac->top_pos = 4;
-  f->output_data.mac->border_width = 0;
   f->output_data.mac->explicit_parent = 0;
+  f->left_pos = 4;
+  f->top_pos = 4;
+  f->border_width = 0;
 
-  f->output_data.mac->internal_border_width = 0;
+  f->internal_border_width = 0;
 
   f->output_method = output_mac;
 
   f->auto_raise = 1;
   f->auto_lower = 1;
 
-  f->new_width = 0;
-  f->new_height = 0;
+  f->new_text_cols = 0;
+  f->new_text_lines = 0;
 }
 
 void
@@ -8405,14 +8729,17 @@ make_mac_terminal_frame (struct frame *f)
   f->output_data.mac = (struct mac_output *)
     xmalloc (sizeof (struct mac_output));
   bzero (f->output_data.mac, sizeof (struct mac_output));
-  f->output_data.mac->fontset = -1;
+  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);
 
-  f->width = 96;
-  f->height = 4;
+  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;
 
   make_mac_frame (f);
 
@@ -8437,74 +8764,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
@@ -8537,12 +8796,16 @@ 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);
+  for (dpyinfo->n_planes = 32; dpyinfo->n_planes > 0; dpyinfo->n_planes >>= 1)
+    if (HasDepth (main_device_handle, dpyinfo->n_planes,
+                 gdDevType, dpyinfo->color_p))
+      break;
   dpyinfo->height = (**main_device_handle).gdRect.bottom;
   dpyinfo->width = (**main_device_handle).gdRect.right;
   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;
@@ -8674,34 +8937,48 @@ quit_char_comp (EventRef inEvent, void *inCompData)
 }
 
 void
-mac_check_for_quit_char()
+mac_check_for_quit_char ()
 {
   EventRef event;
-  /* If windows are not initialized, return immediately (keep it bouncin')*/
+  static EMACS_TIME last_check_time = { 0, 0 };
+  static EMACS_TIME one_second = { 1, 0 };
+  EMACS_TIME now, t;
+
+  /* If windows are not initialized, return immediately (keep it bouncin').  */
   if (!mac_quit_char_modifiers)
     return;
 
+  /* Don't check if last check is less than a second ago.  */
+  EMACS_GET_TIME (now);
+  EMACS_SUB_TIME (t, now, last_check_time);
+  if (EMACS_TIME_LT (t, one_second))
+    return;
+  last_check_time = now;
+
   /* Redetermine modifiers because they are based on lisp variables */
-  mac_determine_quit_char_modifiers();
+  mac_determine_quit_char_modifiers ();
 
   /* Fill the queue with events */
   ReceiveNextEvent (0, NULL, kEventDurationNoWait, false, &event);
-  event = FindSpecificEventInQueue (GetMainEventQueue(), quit_char_comp, NULL);
+  event = FindSpecificEventInQueue (GetMainEventQueue (), quit_char_comp,
+                                   NULL);
   if (event)
     {
       struct input_event e;
-      struct mac_output *mwp = (mac_output*) GetWRefCon (FrontNonFloatingWindow ());
+      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.modifiers = NULL;
-      e.timestamp = EventTimeToTicks(GetEventTime(event))*(1000/60);
-      XSETFRAME(e.frame_or_window, mwp->mFP);
+      e.timestamp = EventTimeToTicks (GetEventTime (event)) * (1000/60);
+      XSETFRAME (e.frame_or_window, mwp->mFP);
       /* Remove event from queue to prevent looping. */
-      RemoveEventFromQueue(GetMainEventQueue(), event);
-      ReleaseEvent(event);
-      kbd_buffer_store_event(&e);
+      RemoveEventFromQueue (GetMainEventQueue (), event);
+      ReleaseEvent (event);
+      kbd_buffer_store_event (&e);
     }
 }
 
@@ -8709,8 +8986,11 @@ mac_check_for_quit_char()
 
 /* Set up use of X before we make the first connection.  */
 
+extern frame_parm_handler mac_frame_parm_handlers[];
+
 static struct redisplay_interface x_redisplay_interface =
 {
+  mac_frame_parm_handlers,
   x_produce_glyphs,
   x_write_glyphs,
   x_insert_glyphs,
@@ -8726,6 +9006,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 */
@@ -8733,6 +9015,7 @@ static struct redisplay_interface x_redisplay_interface =
   mac_define_frame_cursor,
   mac_clear_frame_area,
   mac_draw_window_cursor,
+  mac_draw_vertical_window_border,
   mac_shift_glyphs_for_insert
 };
 
@@ -8761,12 +9044,13 @@ mac_initialize ()
   redeem_scroll_bar_hook = XTredeem_scroll_bar;
   judge_scroll_bars_hook = XTjudge_scroll_bars;
 
-  scroll_region_ok = 1;         /* we'll scroll partial frames */
-  char_ins_del_ok = 1;
-  line_ins_del_ok = 1;          /* we'll just blt 'em */
-  fast_clear_end_of_line = 1;   /* X does this well */
-  memory_below_frame = 0;       /* we don't remember what scrolls
-                                  off the bottom */
+  TTY_SCROLL_REGION_OK (CURTTY ()) = 1; /* we'll scroll partial frames */
+  TTY_CHAR_INS_DEL_OK (CURTTY ()) = 1;
+  TTY_LINE_INS_DEL_OK (CURTTY ()) = 1; /* we'll just blt 'em */
+  TTY_FAST_CLEAR_END_OF_LINE (CURTTY ()) = 1; /* X does this well */
+  TTY_MEMORY_BELOW_FRAME (CURTTY ()) = 0; /* we don't remember what
+                                                         scrolls off the
+                                                         bottom */
   baud_rate = 19200;
 
   x_noop_count = 0;
@@ -8843,6 +9127,9 @@ syms_of_macterm ()
 
   Fprovide (intern ("mac-carbon"), Qnil);
 
+  staticpro (&Qreverse);
+  Qreverse = intern ("reverse");
+
   staticpro (&x_display_name_list);
   x_display_name_list = Qnil;
 
@@ -8858,6 +9145,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;
@@ -8866,6 +9165,14 @@ syms_of_macterm ()
               doc: /* If not nil, Emacs uses toolkit scroll bars.  */);
   Vx_toolkit_scroll_bars = Qt;
 
+  DEFVAR_BOOL ("x-use-underline-position-properties",
+               &x_use_underline_position_properties,
+     doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
+nil means ignore them.  If you encounter fonts with bogus
+UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
+to 4.1, set this to nil.  */);
+  x_use_underline_position_properties = 0;
+
   staticpro (&last_mouse_motion_frame);
   last_mouse_motion_frame = Qnil;
 
@@ -8879,6 +9186,17 @@ Otherwise the option key is used.  */);
            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
@@ -8912,3 +9230,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) */