diff src/macterm.c @ 83066:887bb2eb4a89

Merged in changes from CVS HEAD Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-116 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-117 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-106
author Karoly Lorentey <lorentey@elte.hu>
date Sat, 28 Feb 2004 01:33:17 +0000
parents 03a73693678e 6c8849d06ab3
children b44978264e1d
line wrap: on
line diff
--- a/src/macterm.c	Sat Feb 28 01:23:39 2004 +0000
+++ b/src/macterm.c	Sat Feb 28 01:33:17 2004 +0000
@@ -35,29 +35,6 @@
 #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.  */
@@ -303,7 +280,9 @@
 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_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 *));
@@ -327,15 +306,12 @@
 
 /* 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); 
 }
 
 
@@ -347,9 +323,9 @@
 {
   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);
 }
@@ -363,9 +339,9 @@
 {
   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);
 }
@@ -401,6 +377,23 @@
   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
@@ -479,7 +472,7 @@
   Rect r;
 
   bitmap.rowBytes = sizeof(unsigned short);
-  bitmap.baseAddr = bits;
+  bitmap.baseAddr = (char *)bits;
   SetRect (&(bitmap.bounds), 0, 0, width, height);
 
 #if TARGET_API_MAC_CARBON
@@ -489,18 +482,13 @@
 #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,
-	      overlay_p ? srcOr : 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,
 	    overlay_p ? srcOr : srcCopy, 0);
@@ -546,6 +534,23 @@
 }
 
 
+/* 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
@@ -554,18 +559,19 @@
      char *bits;
      int w, h;
 {
-  int bytes_per_row, i, j;
-
-  bitmap->rowBytes = (w + 15) / 16 * 2;  /* must be on word boundary */
+  int i, j, w1;
+  char *p;
+
+  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);
 }
@@ -578,6 +584,67 @@
   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
@@ -603,6 +670,26 @@
 }
 
 
+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
@@ -638,20 +725,15 @@
      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));
 }
 
 
@@ -766,23 +848,66 @@
   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
+  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));
+}
+
+
+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
-  {
-    PixMapHandle pmh;
-
-    LockPortBits (GetWindowPort (dest));
-    pmh = GetPortPixMap (GetWindowPort (dest));
-    CopyBits ((BitMap *) &src, (BitMap *) *pmh, &src_r, &dest_r, srcCopy, 0);
-    UnlockPortBits (GetWindowPort (dest));
-  }
+  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));
 }
 
 
@@ -817,7 +942,6 @@
 {
 #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);
@@ -828,8 +952,10 @@
   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);
@@ -872,25 +998,67 @@
 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);
-
-  SetRect (&src_r, src_x, src_y, src_right, src_bottom);
-  SetRect (&dest_r, dest_x, dest_y, dest_x + w, dest_y + h);
-
-  CopyBits ((BitMap *) &src, (BitMap *) &dest, &src_r, &dest_r, srcCopy, 0);
+
+  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;
+
+  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 (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));
 }
 
 
@@ -947,7 +1115,7 @@
 
 /* Mac replacement for XSetForeground.  */
 
-static void
+void
 XSetForeground (display, gc, color)
      Display *display;
      GC gc;
@@ -2139,6 +2307,21 @@
 
 #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
@@ -2154,12 +2337,42 @@
      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)))),
@@ -2204,7 +2417,8 @@
   /* 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;
@@ -2234,6 +2448,10 @@
 
   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;
@@ -2267,9 +2485,11 @@
 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;
 
@@ -2277,41 +2497,41 @@
     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);
-
-  mac_reset_clipping (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f));
+      XDrawLine (dpy, window, gc,
+		 right_x - i, top_y + i + 1, right_x - i, bottom_y - i - 1);
+
+  mac_reset_clipping (dpy, window);
 }
 
 
@@ -2326,7 +2546,7 @@
 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;
@@ -2336,21 +2556,21 @@
 
   /* 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);
 }
@@ -2385,9 +2605,9 @@
   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;
 
@@ -2438,39 +2658,36 @@
 
   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
@@ -2494,7 +2711,6 @@
 }
 
 
-
 /* Draw a relief around the image glyph string S.  */
 
 static void
@@ -2567,30 +2783,12 @@
 
   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);
@@ -2605,15 +2803,16 @@
 	    {
 	      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);
 }
 
 
@@ -2646,7 +2845,7 @@
 	     |   s->face->box
 	     |
 	     |     +-------------------------
-	     |     |  s->img->vmargin
+	     |     |  s->img->margin
 	     |     |
 	     |     |       +-------------------
 	     |     |       |  the image
@@ -2665,6 +2864,7 @@
 
   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.  */
@@ -2672,9 +2872,7 @@
   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)
     {
@@ -2684,25 +2882,21 @@
 	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.  */
@@ -2712,18 +2906,19 @@
 	      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;
@@ -2735,7 +2930,7 @@
       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);
     }
@@ -2772,10 +2967,10 @@
       /* 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))
@@ -2835,7 +3030,6 @@
       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.  */
@@ -2872,7 +3066,7 @@
       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;
 
@@ -2949,9 +3143,9 @@
 	    }
 	}
 
-      /* 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.  */
@@ -2971,7 +3165,6 @@
 		   x + shift_by, y);
 }
 
-
 /* Delete N glyphs at the nominal cursor position.  Not implemented
    for X frames.  */
 
@@ -3026,6 +3219,7 @@
 
 #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.  */
 
@@ -3129,7 +3323,7 @@
    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;
 {
@@ -3165,7 +3359,7 @@
 
   /* Get frame-relative bounding box of the text display area of W,
      without mode lines.  Include in this box the left and right
-     fringes of W.  */
+     fringe of W.  */
   window_box (w, -1, &x, &y, &width, &height);
 
   from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
@@ -3287,8 +3481,6 @@
 XTframe_rehighlight (frame)
      struct frame *frame;
 {
-
-
   x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame));
 }
 
@@ -4429,13 +4621,6 @@
   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);
@@ -4450,6 +4635,20 @@
   if (cursor_glyph->type == STRETCH_GLYPH
       && !x_stretch_cursor_p)
     wd = min (FRAME_COLUMN_WIDTH (f), wd);
+  w->phys_cursor_width = wd;
+
+  /* Compute frame-relative coordinates from window-relative
+     coordinates.  */
+  x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
+  y = WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y);
+
+  /* Compute the proper height and ascent of the rectangle, based
+     on the actual glyph.  Using the full height of the row looks
+     bad when there are tall images on that row.  */
+  h = max (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.  */
@@ -4476,35 +4675,49 @@
    --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;
-{
-  /* 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;
-      GC gc;
-      int x;
-      unsigned long mask;
+     enum text_cursor_kinds kind;
+{
+  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 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);
@@ -4516,14 +4729,24 @@
 
       if (width < 0)
 	width = FRAME_CURSOR_WIDTH (f);
-
-      x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
+      width = min (cursor_glyph->pixel_width, width);
+
+      w->phys_cursor_width = width;
       x_clip_to_row (w, row, gc);
-      XFillRectangle (dpy, window, gc,
-		      x,
-		      WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
-		      min (cursor_glyph->pixel_width, width),
-		      row->height);
+
+      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);
+
       mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f));
     }
 }
@@ -4565,7 +4788,6 @@
   if (on_p)
     {
       w->phys_cursor_type = cursor_type;
-      w->phys_cursor_width = cursor_width;
       w->phys_cursor_on_p = 1;
 
       if (glyph_row->exact_window_width_line_p
@@ -4573,9 +4795,8 @@
 	{
 	  glyph_row->cursor_in_fringe_p = 1;
 	  draw_fringe_bitmap (w, glyph_row, 0);
-	  return;
 	}
-
+      else
       switch (cursor_type)
 	{
 	case HOLLOW_BOX_CURSOR:
@@ -4586,13 +4807,16 @@
 	  draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
 	  break;
 
+	case BAR_CURSOR:
+	  x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
+	  break;
+
 	case HBAR_CURSOR:
-	  /* TODO.  For now, just draw bar cursor. */
-	case BAR_CURSOR:
-	  x_draw_bar_cursor (w, glyph_row, cursor_width);
+	  x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
 	  break;
 
 	case NO_CURSOR:
+	  w->phys_cursor_width = 0;
 	  break;
 
 	default:
@@ -5117,6 +5341,8 @@
 	FRAME_SAMPLE_VISIBILITY (f);
       }
   }
+#else
+  UNBLOCK_INPUT;
 #endif /* MAC_TODO */
 }
 
@@ -5173,10 +5399,10 @@
 }
 
 
-/* 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);
@@ -5186,10 +5412,15 @@
   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)
@@ -5197,8 +5428,6 @@
   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
@@ -5212,6 +5441,21 @@
 
   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--;
+}
+
 
 /* Setting window manager hints.  */
 
@@ -5478,6 +5722,7 @@
 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)
@@ -5557,13 +5802,53 @@
           && 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)
     {
@@ -5622,6 +5907,8 @@
 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, "");
 
@@ -5631,13 +5918,29 @@
               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';
+    }
 }
 
 
@@ -5701,36 +6004,45 @@
 	  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)
-	      {
+	    {
+	      /* 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));
-		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.  */
@@ -5772,6 +6084,7 @@
 
 	  TextFont (fontnum);
 	  scriptcode = FontToScript (fontnum);
+	  decode_mac_font_name (name, sizeof (name), scriptcode);
 	  do
 	    {
 	      HLock (font_handle);
@@ -5806,9 +6119,9 @@
 					     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++]
@@ -5835,6 +6148,145 @@
 }
 
 
+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
@@ -5847,11 +6299,7 @@
               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.  */
@@ -5870,27 +6318,10 @@
 	}
     }
 
-  ptnstr = SDATA (pattern);
-
-  GCPRO2 (pattern, newlist);
-
-  /* Scan and matching bitmap fonts.  */
-  for (i = 0; i < font_name_count; i++)
-    {
-      if (mac_font_pattern_match (font_name_table[i], ptnstr))
-        {
-          newlist = Fcons (build_string (font_name_table[i]), newlist);
-
-          n_fonts++;
-          if (maxnames > 0 && n_fonts >= maxnames)
-            break;
-        }
-    }
+  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,
@@ -6050,14 +6481,12 @@
     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;
-
-      name = font_name_table[i];
+      Lisp_Object matched_fonts;
+
+      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 */
@@ -6179,7 +6608,8 @@
         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);
           }
       }
     }
@@ -7833,14 +8263,32 @@
 		    }
 		  else
 	            {
-	              bufp->kind = MOUSE_CLICK_EVENT;
+		      Lisp_Object window;
+		      
+		      bufp->kind = MOUSE_CLICK_EVENT;
 		      XSETFRAME (bufp->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, bufp->x, bufp->y, 0, 0, 0, 1);
+		      
+		      if (EQ (window, mwp->mFP->tool_bar_window))
+			{
+			  if (er.what == mouseDown)
+			    handle_tool_bar_click (mwp->mFP, bufp->x, bufp->y, 1, 0);
+			  else
+			    handle_tool_bar_click (mwp->mFP, bufp->x, bufp->y, 0,
+#if USE_CARBON_EVENTS
+						   mac_event_to_emacs_modifiers (eventRef)
+#else
+						   er.modifiers
+#endif
+						   );
+			  break;
+			}
+		    }
 
 #if USE_CARBON_EVENTS
 		  bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
@@ -8352,12 +8800,16 @@
   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;
@@ -8697,6 +9149,18 @@
   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;