]> code.delx.au - gnu-emacs/blobdiff - src/macterm.c
Merged from miles@gnu.org--gnu-2005 (patch 60-65, 246-265)
[gnu-emacs] / src / macterm.c
index eaf7517d71a157d1832fce7e22ecdf5da9753c9c..5aab6ec5364446c12f1f1c05fb524fa64a12354d 100644 (file)
@@ -1,5 +1,5 @@
 /* Implementation of GUI terminal on the Mac OS.
-   Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -34,12 +34,12 @@ Boston, MA 02111-1307, USA.  */
 #include <alloca.h>
 #endif
 
-#ifdef MAC_OSX
+#if TARGET_API_MAC_CARBON
 /* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to
    obtain events from the event queue.  If set to 0, WaitNextEvent is
    used instead.  */
 #define USE_CARBON_EVENTS 1
-#else /* not MAC_OSX */
+#else /* not TARGET_API_MAC_CARBON */
 #include <Quickdraw.h>
 #include <ToolUtils.h>
 #include <Sound.h>
@@ -50,6 +50,7 @@ Boston, MA 02111-1307, USA.  */
 #include <TextUtils.h>
 #include <LowMem.h>
 #include <Controls.h>
+#include <Windows.h>
 #if defined (__MRC__) || (__MSL__ >= 0x6000)
 #include <ControlDefinitions.h>
 #endif
@@ -57,7 +58,7 @@ Boston, MA 02111-1307, USA.  */
 #if __profile__
 #include <profiler.h>
 #endif
-#endif /* not MAC_OSX */
+#endif /* not TARGET_API_MAC_CARBON */
 
 #include "systty.h"
 #include "systime.h"
@@ -68,6 +69,7 @@ Boston, MA 02111-1307, USA.  */
 #include <errno.h>
 #include <setjmp.h>
 #include <sys/stat.h>
+#include <sys/param.h>
 
 #include "keyboard.h"
 #include "frame.h"
@@ -93,20 +95,24 @@ Boston, MA 02111-1307, USA.  */
                        : controlKey)
 #define macAltKey      (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey)
 
+#define mac_window_to_frame(wp) (((mac_output *) GetWRefCon (wp))->mFP)
 \f
 
 /* Non-nil means Emacs uses toolkit scroll bars.  */
 
 Lisp_Object Vx_toolkit_scroll_bars;
 
+/* If Non-nil, the text will be rendered using Core Graphics text rendering which may anti-alias the text.  */
+Lisp_Object Vmac_use_core_graphics;
+
+
 /* Non-zero means that a HELP_EVENT has been generated since Emacs
    start.  */
 
 static int any_help_event_p;
 
-/* Non-zero means autoselect window with the mouse cursor.  */
-
-int x_autoselect_window_p;
+/* Last window where we saw the mouse.  Used by mouse-autoselect-window.  */
+static Lisp_Object last_window;
 
 /* Non-zero means make use of UNDERLINE_POSITION font properties.  */
 
@@ -123,9 +129,12 @@ int x_use_underline_position_properties;
 struct x_display_info *x_display_list;
 
 /* This is a list of cons cells, each of the form (NAME
-   . FONT-LIST-CACHE), one for each element of x_display_list and in
-   the same order.  NAME is the name of the frame.  FONT-LIST-CACHE
-   records previous values returned by x-list-fonts.  */
+   FONT-LIST-CACHE . RESOURCE-DATABASE), one for each element of
+   x_display_list and in the same order.  NAME is the name of the
+   frame.  FONT-LIST-CACHE records previous values returned by
+   x-list-fonts.  RESOURCE-DATABASE preserves the X Resource Database
+   equivalent, which is implemented with a Lisp object, for the
+   display. */
 
 Lisp_Object x_display_name_list;
 
@@ -227,6 +236,10 @@ extern int errno;
 
 extern int extra_keyboard_modifiers;
 
+/* The keysyms to use for the various modifiers.  */
+
+static Lisp_Object Qalt, Qhyper, Qsuper, Qmodifier_value;
+
 static Lisp_Object Qvendor_specific_keysyms;
 
 #if 0
@@ -235,7 +248,7 @@ extern XrmDatabase x_load_resources P_ ((Display *, char *, char *, char *));
 
 extern int inhibit_window_system;
 
-#if __MRC__
+#if __MRC__ && !TARGET_API_MAC_CARBON
 QDGlobals qd;  /* QuickDraw global information structure.  */
 #endif
 
@@ -260,29 +273,28 @@ static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
 static int x_compute_min_glyph_bounds P_ ((struct frame *));
 static void x_update_end P_ ((struct frame *));
 static void XTframe_up_to_date P_ ((struct frame *));
-static void XTreassert_line_highlight P_ ((int, int));
-static void x_change_line_highlight P_ ((int, int, int, int));
 static void XTset_terminal_modes P_ ((void));
 static void XTreset_terminal_modes P_ ((void));
 static void x_clear_frame P_ ((void));
 static void frame_highlight P_ ((struct frame *));
 static void frame_unhighlight P_ ((struct frame *));
 static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
+static void mac_focus_changed P_ ((int, struct mac_display_info *,
+                                  struct frame *, struct input_event *));
+static void x_detect_focus_change P_ ((struct mac_display_info *,
+                                      EventRecord *, struct input_event *));
 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,
                                   enum text_cursor_kinds));
 
-static void x_clip_to_row P_ ((struct window *, struct glyph_row *, GC));
+static void x_clip_to_row P_ ((struct window *, struct glyph_row *, int, GC));
 static void x_flush P_ ((struct frame *f));
 static void x_update_begin P_ ((struct frame *));
 static void x_update_window_begin P_ ((struct window *));
 static void x_after_update_window_line P_ ((struct glyph_row *));
 
-void activate_scroll_bars (FRAME_PTR);
-void deactivate_scroll_bars (FRAME_PTR);
-
 static int is_emacs_window (WindowPtr);
 
 int x_bitmap_icon (struct frame *, Lisp_Object);
@@ -340,8 +352,12 @@ mac_set_backcolor (unsigned long color)
    commands.  Assume that the graphic port has already been set.  */
 
 static void
-mac_set_colors (GC gc)
+mac_set_colors (gc, bg_save)
+     GC gc;
+     RGBColor *bg_save;
 {
+  if (bg_save)
+    GetBackColor (bg_save);
   mac_set_forecolor (gc->foreground);
   mac_set_backcolor (gc->background);
 }
@@ -355,12 +371,16 @@ XDrawLine (display, w, gc, x1, y1, x2, y2)
      GC gc;
      int x1, y1, x2, y2;
 {
+  RGBColor old_bg;
+
   SetPortWindowPort (w);
 
-  mac_set_colors (gc);
+  mac_set_colors (gc, &old_bg);
 
   MoveTo (x1, y1);
   LineTo (x2, y2);
+
+  RGBBackColor (&old_bg);
 }
 
 void
@@ -376,7 +396,7 @@ mac_draw_line_to_pixmap (display, p, gc, x1, y1, x2, y2)
   GetGWorld (&old_port, &old_gdh);
   SetGWorld (p, NULL);
 
-  mac_set_colors (gc);
+  mac_set_colors (gc, NULL);
 
   LockPixels (GetGWorldPixMap (p));
   MoveTo (x1, y1);
@@ -399,16 +419,19 @@ XClearArea (display, w, x, y, width, height, exposures)
   struct mac_output *mwp = (mac_output *) GetWRefCon (w);
   Rect r;
   XGCValues xgc;
+  RGBColor old_bg;
 
   xgc.foreground = mwp->x_compatible.foreground_pixel;
   xgc.background = mwp->x_compatible.background_pixel;
 
   SetPortWindowPort (w);
 
-  mac_set_colors (&xgc);
+  mac_set_colors (&xgc, &old_bg);
   SetRect (&r, x, y, x + width, y + height);
 
   EraseRect (&r);
+
+  RGBBackColor (&old_bg);
 }
 
 /* Mac version of XClearWindow.  */
@@ -426,7 +449,7 @@ XClearWindow (display, w)
 
   SetPortWindowPort (w);
 
-  mac_set_colors (&xgc);
+  mac_set_colors (&xgc, NULL);
 
 #if TARGET_API_MAC_CARBON
   {
@@ -454,6 +477,7 @@ mac_draw_bitmap (display, w, gc, x, y, width, height, bits, overlay_p)
 {
   BitMap bitmap;
   Rect r;
+  RGBColor old_bg;
 
   bitmap.rowBytes = sizeof(unsigned short);
   bitmap.baseAddr = (char *)bits;
@@ -461,7 +485,7 @@ mac_draw_bitmap (display, w, gc, x, y, width, height, bits, overlay_p)
 
   SetPortWindowPort (w);
 
-  mac_set_colors (gc);
+  mac_set_colors (gc, &old_bg);
   SetRect (&r, x, y, x + width, y + height);
 
 #if TARGET_API_MAC_CARBON
@@ -473,6 +497,8 @@ mac_draw_bitmap (display, w, gc, x, y, width, height, bits, overlay_p)
   CopyBits (&bitmap, &(w->portBits), &(bitmap.bounds), &r,
            overlay_p ? srcOr : srcCopy, 0);
 #endif /* not TARGET_API_MAC_CARBON */
+
+  RGBBackColor (&old_bg);
 }
 
 
@@ -506,23 +532,6 @@ 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
@@ -531,6 +540,11 @@ mac_create_bitmap_from_bitmap_data (bitmap, bits, w, h)
      char *bits;
      int w, h;
 {
+  static unsigned char swap_nibble[16]
+    = { 0x0, 0x8, 0x4, 0xc,    /* 0000 1000 0100 1100 */
+       0x2, 0xa, 0x6, 0xe,    /* 0010 1010 0110 1110 */
+       0x1, 0x9, 0x5, 0xd,    /* 0001 1001 0101 1101 */
+       0x3, 0xb, 0x7, 0xf };  /* 0011 1011 0111 1111 */
   int i, j, w1;
   char *p;
 
@@ -542,7 +556,12 @@ mac_create_bitmap_from_bitmap_data (bitmap, bits, w, h)
     {
       p = bitmap->baseAddr + i * bitmap->rowBytes;
       for (j = 0; j < w1; j++)
-        *p++ = reflect_byte (*bits++);
+       {
+         /* Bitswap XBM bytes to match how Mac does things.  */
+         unsigned char c = *bits++;
+         *p++ = (unsigned char)((swap_nibble[c & 0xf] << 4)
+                                | (swap_nibble[(c>>4) & 0xf]));;
+       }
     }
 
   SetRect (&(bitmap->bounds), 0, 0, w, h);
@@ -562,7 +581,7 @@ XCreatePixmap (display, w, width, height, depth)
      Display *display;         /* not used */
      WindowPtr w;
      unsigned int width, height;
-     unsigned int depth;       /* not used */
+     unsigned int depth;
 {
   Pixmap pixmap;
   Rect r;
@@ -628,16 +647,20 @@ XFillRectangle (display, w, gc, x, y, width, height)
      unsigned int width, height;
 {
   Rect r;
+  RGBColor old_bg;
 
   SetPortWindowPort (w);
 
-  mac_set_colors (gc);
+  mac_set_colors (gc, &old_bg);
   SetRect (&r, x, y, x + width, y + height);
 
   PaintRect (&r); /* using foreground color of gc */
+
+  RGBBackColor (&old_bg);
 }
 
 
+#if 0 /* TODO: figure out if we need to do this on Mac.  */
 static void
 mac_fill_rectangle_to_pixmap (display, p, gc, x, y, width, height)
      Display *display;
@@ -652,7 +675,7 @@ mac_fill_rectangle_to_pixmap (display, p, gc, x, y, width, height)
 
   GetGWorld (&old_port, &old_gdh);
   SetGWorld (p, NULL);
-  mac_set_colors (gc);
+  mac_set_colors (gc, NULL);
   SetRect (&r, x, y, x + width, y + height);
 
   LockPixels (GetGWorldPixMap (p));
@@ -661,6 +684,7 @@ mac_fill_rectangle_to_pixmap (display, p, gc, x, y, width, height)
 
   SetGWorld (old_port, old_gdh);
 }
+#endif
 
 
 /* Mac replacement for XDrawRectangle: dest is a window.  */
@@ -674,16 +698,20 @@ mac_draw_rectangle (display, w, gc, x, y, width, height)
      unsigned int width, height;
 {
   Rect r;
+  RGBColor old_bg;
 
   SetPortWindowPort (w);
 
-  mac_set_colors (gc);
+  mac_set_colors (gc, &old_bg);
   SetRect (&r, x, y, x + width + 1, y + height + 1);
 
   FrameRect (&r); /* using foreground color of gc */
+
+  RGBBackColor (&old_bg);
 }
 
 
+#if 0 /* TODO: figure out if we need to do this on Mac.  */
 /* Mac replacement for XDrawRectangle: dest is a Pixmap.  */
 
 static void
@@ -700,7 +728,7 @@ mac_draw_rectangle_to_pixmap (display, p, gc, x, y, width, height)
 
   GetGWorld (&old_port, &old_gdh);
   SetGWorld (p, NULL);
-  mac_set_colors (gc);
+  mac_set_colors (gc, NULL);
   SetRect (&r, x, y, x + width + 1, y + height + 1);
 
   LockPixels (GetGWorldPixMap (p));
@@ -709,6 +737,7 @@ mac_draw_rectangle_to_pixmap (display, p, gc, x, y, width, height)
 
   SetGWorld (old_port, old_gdh);
 }
+#endif
 
 
 static void
@@ -721,9 +750,18 @@ mac_draw_string_common (display, w, gc, x, y, buf, nchars, mode,
      char *buf;
      int nchars, mode, bytes_per_char;
 {
+  RGBColor old_bg;
+
   SetPortWindowPort (w);
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+  UInt32 textFlags, savedFlags;
+  if (!NILP(Vmac_use_core_graphics)) {
+    textFlags = kQDUseCGTextRendering;
+    savedFlags = SwapQDTextFlags(textFlags);
+  }
+#endif
 
-  mac_set_colors (gc);
+  mac_set_colors (gc, &old_bg);
 
   TextFont (gc->font->mac_fontnum);
   TextSize (gc->font->mac_fontsize);
@@ -732,6 +770,12 @@ mac_draw_string_common (display, w, gc, x, y, buf, nchars, mode,
 
   MoveTo (x, y);
   DrawText (buf, 0, nchars * bytes_per_char);
+
+  RGBBackColor (&old_bg);
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+  if (!NILP(Vmac_use_core_graphics))
+    SwapQDTextFlags(savedFlags);
+#endif
 }
 
 
@@ -903,30 +947,19 @@ mac_scroll_area (display, w, gc, src_x, src_y, width, height, dest_x, dest_y)
      int dest_x, dest_y;
 {
 #if TARGET_API_MAC_CARBON
-  Rect gw_r, src_r, dest_r;
+  Rect src_r;
+  RgnHandle dummy = NewRgn (); /* For avoiding update events.  */
 
   SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
-  SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
-
-  SetPortWindowPort (w);
-
-  ForeColor (blackColor);
-  BackColor (whiteColor);
-
-  LockPortBits (GetWindowPort (w));
-  {
-    const BitMap *bitmap = GetPortBitMapForCopyBits (GetWindowPort (w));
-    CopyBits (bitmap, bitmap, &src_r, &dest_r, srcCopy, 0);
-  }
-  UnlockPortBits (GetWindowPort (w));
-
-  mac_set_colors (gc);
+  ScrollWindowRect (w, &src_r, dest_x - src_x, dest_y - src_y,
+                   kScrollWindowNoOptions, dummy);
+  DisposeRgn (dummy);
 #else /* not TARGET_API_MAC_CARBON */
   Rect src_r, dest_r;
 
   SetPort (w);
 #if 0
-  mac_set_colors (gc);
+  mac_set_colors (gc, NULL);
 #endif
 
   SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
@@ -948,12 +981,13 @@ mac_scroll_area (display, w, gc, src_x, src_y, width, height, dest_x, dest_y)
   BackColor (whiteColor);
   CopyBits (&(w->portBits), &(w->portBits), &src_r, &dest_r, srcCopy, 0);
 
-  mac_set_colors (gc);
+  mac_set_colors (gc, NULL);
 #endif
 #endif /* not TARGET_API_MAC_CARBON */
 }
 
 
+#if 0 /* TODO: figure out if we need to do this on Mac.  */
 /* Mac replacement for XCopyArea: dest must be Pixmap.  */
 
 static void
@@ -1032,6 +1066,7 @@ mac_copy_area_with_mask_to_pixmap (display, src, mask, dest, gc, src_x, src_y,
 
   SetGWorld (old_port, old_gdh);
 }
+#endif
 
 
 /* Mac replacement for XChangeGC.  */
@@ -1097,24 +1132,71 @@ XSetForeground (display, gc, color)
 }
 
 
-/* Mac replacement for XSetFont.  */
+/* Mac replacement for XSetBackground.  */
 
-static void
-XSetFont (display, gc, font)
+void
+XSetBackground (display, gc, color)
      Display *display;
      GC gc;
-     XFontStruct *font;
+     unsigned long color;
 {
-  gc->font = font;
+  gc->background = color;
+}
+
+
+/* Mac replacement for XSetWindowBackground.  */
+
+void
+XSetWindowBackground (display, w, color)
+     Display *display;
+     WindowPtr w;
+     unsigned long color;
+{
+#if !TARGET_API_MAC_CARBON
+  AuxWinHandle aw_handle;
+  CTabHandle ctab_handle;
+  ColorSpecPtr ct_table;
+  short ct_size;
+#endif
+  RGBColor bg_color;
+
+  bg_color.red = RED16_FROM_ULONG (color);
+  bg_color.green = GREEN16_FROM_ULONG (color);
+  bg_color.blue = BLUE16_FROM_ULONG (color);
+
+#if TARGET_API_MAC_CARBON
+  SetWindowContentColor (w, &bg_color);
+#else
+  if (GetAuxWin (w, &aw_handle))
+    {
+      ctab_handle = (*aw_handle)->awCTable;
+      HandToHand ((Handle *) &ctab_handle);
+      ct_table = (*ctab_handle)->ctTable;
+      ct_size = (*ctab_handle)->ctSize;
+      while (ct_size > -1)
+       {
+         if (ct_table->value == 0)
+           {
+             ct_table->rgb = bg_color;
+             CTabChanged (ctab_handle);
+             SetWinColor (w, (WCTabHandle) ctab_handle);
+           }
+         ct_size--;
+       }
+    }
+#endif
 }
 
 
+/* Mac replacement for XSetFont.  */
+
 static void
-XTextExtents16 (XFontStruct *font, XChar2b *text, int nchars,
-                     int *direction,int *font_ascent,
-                     int *font_descent, XCharStruct *cs)
+XSetFont (display, gc, font)
+     Display *display;
+     GC gc;
+     XFontStruct *font;
 {
-  /* MAC_TODO: Use GetTextMetrics to do this and inline it below. */
+  gc->font = font;
 }
 
 
@@ -1126,40 +1208,32 @@ x_sync (f)
 }
 
 
-/* Remove calls to XFlush by defining XFlush to an empty replacement.
-   Calls to XFlush should be unnecessary because the X output buffer
-   is flushed automatically as needed by calls to XPending,
-   XNextEvent, or XWindowEvent according to the XFlush man page.
-   XTread_socket calls XPending.  Removing XFlush improves
-   performance.  */
-
-#if TARGET_API_MAC_CARBON
-#define XFlush(DISPLAY) QDFlushPortBuffer (GetQDGlobalsThePort (), NULL)
-#else
-#define XFlush(DISPLAY)        (void) 0
-#endif
-
 /* Flush display of frame F, or of all frames if F is null.  */
 
-void
+static void
 x_flush (f)
      struct frame *f;
 {
 #if TARGET_API_MAC_CARBON
   BLOCK_INPUT;
-  if (f == NULL)
-    {
-      Lisp_Object rest, frame;
-      FOR_EACH_FRAME (rest, frame)
-       x_flush (XFRAME (frame));
-    }
-  else if (FRAME_MAC_P (f))
-    XFlush (FRAME_MAC_DISPLAY (f));
+  if (f)
+    QDFlushPortBuffer (GetWindowPort (FRAME_MAC_WINDOW (f)), NULL);
+  else
+    QDFlushPortBuffer (GetQDGlobalsThePort (), NULL);
   UNBLOCK_INPUT;
-#endif /* TARGET_API_MAC_CARBON */
+#endif
 }
 
 
+/* Remove calls to XFlush by defining XFlush to an empty replacement.
+   Calls to XFlush should be unnecessary because the X output buffer
+   is flushed automatically as needed by calls to XPending,
+   XNextEvent, or XWindowEvent according to the XFlush man page.
+   XTread_socket calls XPending.  Removing XFlush improves
+   performance.  */
+
+#define XFlush(DISPLAY)        (void) 0
+
 \f
 /* Return the struct mac_display_info corresponding to DPY.  There's
    only one.  */
@@ -1186,7 +1260,17 @@ static void
 x_update_begin (f)
      struct frame *f;
 {
-  /* Nothing to do.  */
+#if TARGET_API_MAC_CARBON
+  /* During update of a frame, availability of input events is
+     periodically checked with ReceiveNextEvent if
+     redisplay-dont-pause is nil.  That normally flushes window buffer
+     changes for every check, and thus screen update looks waving even
+     if no input is available.  So we disable screen updates during
+     update of a frame.  */
+  BLOCK_INPUT;
+  DisableScreenUpdates ();
+  UNBLOCK_INPUT;
+#endif
 }
 
 
@@ -1271,7 +1355,7 @@ mac_draw_vertical_window_border (w, x, y0, y1)
    make sure that the mouse-highlight is properly redrawn.
 
    W may be a menu bar pseudo-window in case we don't have X toolkit
-   support. Such windows don't have a cursor, so don't display it
+   support.  Such windows don't have a cursor, so don't display it
    here. */
 
 static void
@@ -1290,9 +1374,8 @@ x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
                                output_cursor.vpos,
                                output_cursor.x, output_cursor.y);
 
-      x_draw_vertical_border (w);
-
-      draw_window_fringes (w);
+      if (draw_window_fringes (w, 1))
+       x_draw_vertical_border (w);
 
       UNBLOCK_INPUT;
     }
@@ -1325,17 +1408,13 @@ static void
 x_update_end (f)
      struct frame *f;
 {
-  /* Reset the background color of Mac OS Window to that of the frame after
-     update so that it is used by Mac Toolbox to clear the update region before
-     an update event is generated.  */
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
-  mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f));
-
   /* Mouse highlight may be displayed again.  */
   FRAME_MAC_DISPLAY_INFO (f)->mouse_face_defer = 0;
 
   BLOCK_INPUT;
+#if TARGET_API_MAC_CARBON
+  EnableScreenUpdates ();
+#endif
   XFlush (FRAME_MAC_DISPLAY (f));
   UNBLOCK_INPUT;
 }
@@ -1450,12 +1529,12 @@ x_draw_fringe_bitmap (w, row, p)
       int oldVH = row->visible_height;
       row->visible_height = p->h;
       row->y -= rowY - p->y;
-      x_clip_to_row (w, row, gc);
+      x_clip_to_row (w, row, -1, gc);
       row->y = oldY;
       row->visible_height = oldVH;
     }
   else
-    x_clip_to_row (w, row, gc);
+    x_clip_to_row (w, row, -1, gc);
 
   if (p->bx >= 0 && !p->overlay_p)
     {
@@ -1922,20 +2001,33 @@ static void
 mac_compute_glyph_string_overhangs (s)
      struct glyph_string *s;
 {
-#if 0
-  /* MAC_TODO: XTextExtents16 does nothing yet... */
+  Rect r;
+  MacFontStruct *font = s->font;
 
-  if (s->cmp == NULL
-      && s->first_glyph->type == CHAR_GLYPH)
+  TextFont (font->mac_fontnum);
+  TextSize (font->mac_fontsize);
+  TextFace (font->mac_fontface);
+
+  if (s->two_byte_p)
+    QDTextBounds (s->nchars * 2, (char *)s->char2b, &r);
+  else
     {
-      XCharStruct cs;
-      int direction, font_ascent, font_descent;
-      XTextExtents16 (s->font, s->char2b, s->nchars, &direction,
-                     &font_ascent, &font_descent, &cs);
-      s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0;
-      s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0;
+      int i;
+      char *buf = xmalloc (s->nchars);
+
+      if (buf == NULL)
+       SetRect (&r, 0, 0, 0, 0);
+      else
+       {
+         for (i = 0; i < s->nchars; ++i)
+           buf[i] = s->char2b[i].byte2;
+         QDTextBounds (s->nchars, buf, &r);
+         xfree (buf);
+       }
     }
-#endif
+
+  s->right_overhang = r.right > s->width ? r.right - s->width : 0;
+  s->left_overhang = r.left < 0 ? -r.left : 0;
 }
 
 
@@ -1953,6 +2045,14 @@ x_clear_glyph_string_rect (s, x, y, w, h)
 }
 
 
+/* We prefer not to use XDrawImageString (srcCopy text transfer mode)
+   on Mac OS X because:
+   - Screen is double-buffered.  (In srcCopy mode, a text is drawn
+     into an offscreen graphics world first.  So performance gain
+     cannot be expected.)
+   - It lowers rendering quality.
+   - Some fonts leave garbage on cursor movement.  */
+
 /* Draw the background of glyph_string S.  If S->background_filled_p
    is non-zero don't draw it.  FORCE_P non-zero means draw the
    background even if it wouldn't be drawn normally.  This is used
@@ -1984,10 +2084,12 @@ x_draw_glyph_string_background (s, force_p)
        }
       else
 #endif
+#ifdef MAC_OS8
         if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
               || s->font_not_found_p
               || s->extends_to_end_of_line_p
               || force_p)
+#endif
        {
          x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
                                     s->background_width,
@@ -2040,6 +2142,7 @@ x_draw_glyph_string_foreground (s)
        for (i = 0; i < s->nchars; ++i)
          char1b[i] = s->char2b[i].byte2;
 
+#ifdef MAC_OS8
       /* Draw text with XDrawString if background has already been
         filled.  Otherwise, use XDrawImageString.  (Note that
         XDrawImageString is usually faster than XDrawString.)  Always
@@ -2047,6 +2150,7 @@ x_draw_glyph_string_foreground (s)
         no chance that characters under a box cursor are invisible.  */
       if (s->for_overlaps_p
          || (s->background_filled_p && s->hl != DRAW_CURSOR))
+#endif
        {
          /* Draw characters with 16-bit or 8-bit functions.  */
          if (s->two_byte_p)
@@ -2056,6 +2160,7 @@ x_draw_glyph_string_foreground (s)
            XDrawString (s->display, s->window, s->gc, x,
                         s->ybase - boff, char1b, s->nchars);
        }
+#ifdef MAC_OS8
       else
        {
          if (s->two_byte_p)
@@ -2065,6 +2170,7 @@ x_draw_glyph_string_foreground (s)
            XDrawImageString (s->display, s->window, s->gc, x,
                              s->ybase - boff, char1b, s->nchars);
        }
+#endif
     }
 }
 
@@ -2559,15 +2665,9 @@ x_draw_glyph_string_box (s)
   struct glyph *last_glyph;
   Rect clip_rect;
 
-  last_x = window_box_right (s->w, s->area);
-  if (s->row->full_width_p
-      && !s->w->pseudo_window_p)
-    {
-      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);
-    }
+  last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
+           ? WINDOW_RIGHT_EDGE_X (s->w)
+           : window_box_right (s->w, s->area));
 
   /* The glyph that may have a right box line.  */
   last_glyph = (s->cmp || s->img
@@ -2631,38 +2731,17 @@ x_draw_image_foreground (s)
 
   if (s->img->pixmap)
     {
+      x_set_glyph_string_clipping (s);
+
       if (s->img->mask)
-       {
-         Rect nr;
-         XRectangle clip_rect, image_rect, r;
-
-         get_glyph_string_clip_rect (s, &nr);
-         CONVERT_TO_XRECT (clip_rect, nr);
-         image_rect.x = x;
-         image_rect.y = y;
-         image_rect.width = s->slice.width;
-         image_rect.height = s->slice.height;
-         if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
-           mac_copy_area_with_mask (s->display, s->img->pixmap, s->img->mask,
-                                    s->window, s->gc,
-                                    s->slice.x + r.x - x, s->slice.y + r.y - y,
-                                    r.width, r.height, r.x, r.y);
-       }
+       mac_copy_area_with_mask (s->display, s->img->pixmap, s->img->mask,
+                                s->window, s->gc, s->slice.x, s->slice.y,
+                                s->slice.width, s->slice.height, x, y);
       else
        {
-         Rect nr;
-         XRectangle clip_rect, image_rect, r;
-
-         get_glyph_string_clip_rect (s, &nr);
-         CONVERT_TO_XRECT (clip_rect, nr);
-         image_rect.x = x;
-         image_rect.y = y;
-         image_rect.width = s->slice.width;
-         image_rect.height = s->slice.height;
-         if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
-           mac_copy_area (s->display, s->img->pixmap, s->window, s->gc,
-                          s->slice.x + r.x - x, s->slice.y + r.y - y,
-                          r.width, r.height, r.x, r.y);
+         mac_copy_area (s->display, s->img->pixmap,
+                        s->window, s->gc, s->slice.x, s->slice.y,
+                        s->slice.width, s->slice.height, x, y);
 
          /* When the image has a mask, we can expect that at
             least part of a mouse highlight or a block cursor will
@@ -2741,6 +2820,7 @@ x_draw_image_relief (s)
 }
 
 
+#if 0 /* TODO: figure out if we need to do this on Mac.  */
 /* Draw the foreground of image glyph string S to PIXMAP.  */
 
 static void
@@ -2801,6 +2881,7 @@ x_draw_image_foreground_1 (s, pixmap)
     mac_draw_rectangle_to_pixmap (s->display, pixmap, s->gc, x, y,
                                  s->slice.width - 1, s->slice.height - 1);
 }
+#endif
 
 
 /* Draw part of the background of glyph string S.  X, Y, W, and H
@@ -2872,6 +2953,7 @@ x_draw_image_glyph_string (s)
       if (s->slice.y == 0)
        y += box_line_vwidth;
 
+#if 0 /* TODO: figure out if we need to do this on Mac.  */
       if (s->img->mask)
        {
          /* Create a pixmap as large as the glyph string.  Fill it
@@ -2908,12 +2990,14 @@ x_draw_image_glyph_string (s)
            }
        }
       else
+#endif
        x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
 
       s->background_filled_p = 1;
     }
 
   /* Draw the foreground.  */
+#if 0 /* TODO: figure out if we need to do this on Mac.  */
   if (pixmap != 0)
     {
       x_draw_image_foreground_1 (s, pixmap);
@@ -2924,6 +3008,7 @@ x_draw_image_glyph_string (s)
       XFreePixmap (s->display, pixmap);
     }
   else
+#endif
     x_draw_image_foreground (s);
 
   /* If we must draw a relief around the image, do it.  */
@@ -3010,10 +3095,12 @@ x_draw_glyph_string (s)
 {
   int relief_drawn_p = 0;
 
-  /* If S draws into the background of its successor, draw the
-     background of the successor first so that S can draw into it.
-     This makes S->next use XDrawString instead of XDrawImageString.  */
-  if (s->next && s->right_overhang && !s->for_overlaps_p)
+  /* If S draws into the background of its successor that does not
+     draw a cursor, draw the background of the successor first so that
+     S can draw into it.  This makes S->next use XDrawString instead
+     of XDrawImageString.  */
+  if (s->next && s->right_overhang && !s->for_overlaps_p
+      && s->next->hl != DRAW_CURSOR)
     {
       xassert (s->next->img == NULL);
       x_set_glyph_string_gc (s->next);
@@ -3400,6 +3487,14 @@ static void
 frame_highlight (f)
      struct frame *f;
 {
+  OSErr err;
+  ControlRef root_control;
+
+  BLOCK_INPUT;
+  err = GetRootControl (FRAME_MAC_WINDOW (f), &root_control);
+  if (err == noErr)
+    ActivateControl (root_control);
+  UNBLOCK_INPUT;
   x_update_cursor (f, 1);
 }
 
@@ -3407,6 +3502,14 @@ static void
 frame_unhighlight (f)
      struct frame *f;
 {
+  OSErr err;
+  ControlRef root_control;
+
+  BLOCK_INPUT;
+  err = GetRootControl (FRAME_MAC_WINDOW (f), &root_control);
+  if (err == noErr)
+    DeactivateControl (root_control);
+  UNBLOCK_INPUT;
   x_update_cursor (f, 1);
 }
 
@@ -3449,6 +3552,68 @@ x_new_focus_frame (dpyinfo, frame)
   x_frame_rehighlight (dpyinfo);
 }
 
+/* Handle FocusIn and FocusOut state changes for FRAME.
+   If FRAME has focus and there exists more than one frame, puts
+   a FOCUS_IN_EVENT into *BUFP.  */
+
+static void
+mac_focus_changed (type, dpyinfo, frame, bufp)
+     int type;
+     struct mac_display_info *dpyinfo;
+     struct frame *frame;
+     struct input_event *bufp;
+{
+  if (type == activeFlag)
+    {
+      if (dpyinfo->x_focus_event_frame != frame)
+        {
+          x_new_focus_frame (dpyinfo, frame);
+          dpyinfo->x_focus_event_frame = frame;
+
+          /* Don't stop displaying the initial startup message
+             for a switch-frame event we don't need.  */
+          if (GC_NILP (Vterminal_frame)
+              && GC_CONSP (Vframe_list)
+              && !GC_NILP (XCDR (Vframe_list)))
+            {
+              bufp->kind = FOCUS_IN_EVENT;
+              XSETFRAME (bufp->frame_or_window, frame);
+            }
+        }
+    }
+  else
+    {
+      if (dpyinfo->x_focus_event_frame == frame)
+        {
+          dpyinfo->x_focus_event_frame = 0;
+          x_new_focus_frame (dpyinfo, 0);
+        }
+    }
+}
+
+/* The focus may have changed.  Figure out if it is a real focus change,
+   by checking both FocusIn/Out and Enter/LeaveNotify events.
+
+   Returns FOCUS_IN_EVENT event in *BUFP. */
+
+static void
+x_detect_focus_change (dpyinfo, event, bufp)
+     struct mac_display_info *dpyinfo;
+     EventRecord *event;
+     struct input_event *bufp;
+{
+  struct frame *frame;
+
+  frame = mac_window_to_frame ((WindowPtr) event->message);
+  if (! frame)
+    return;
+
+  /* On Mac, this is only called from focus events, so no switch needed.  */
+  mac_focus_changed ((event->modifiers & activeFlag),
+                    dpyinfo, frame, bufp);
+}
+
+
 /* Handle an event saying the mouse has moved out of an Emacs frame.  */
 
 void
@@ -3662,6 +3827,7 @@ x_get_keysym_name (keysym)
 
 
 \f
+#if 0
 /* Mouse clicks and mouse movement.  Rah.  */
 
 /* Prepare a mouse-event in *RESULT for placement in the input queue.
@@ -3695,6 +3861,7 @@ construct_mouse_click (result, event, f)
   result->arg = Qnil;
   return Qnil;
 }
+#endif
 
 \f
 /* Function to report a mouse movement to the mainstream Emacs code.
@@ -3764,8 +3931,6 @@ int disable_mouse_highlight;
 
 static struct scroll_bar *x_window_to_scroll_bar ();
 static void x_scroll_bar_report_motion ();
-static void x_check_fullscreen P_ ((struct frame *));
-static void x_check_fullscreen_move P_ ((struct frame *));
 static int glyph_rect P_ ((struct frame *f, int, int, Rect *));
 
 
@@ -3886,22 +4051,19 @@ remember_mouse_glyph (f1, gx, gy)
 }
 
 
-static WindowPtr
-mac_front_window ()
+static struct frame *
+mac_focus_frame (dpyinfo)
+     struct mac_display_info *dpyinfo;
 {
-#if TARGET_API_MAC_CARBON
-  return GetFrontWindowOfClass (kDocumentWindowClass, true);
-#else
-  WindowPtr front_window = FrontWindow ();
-
-  if (tip_window && front_window == tip_window)
-    return GetNextWindow (front_window);
+  if (dpyinfo->x_focus_frame)
+    return dpyinfo->x_focus_frame;
   else
-    return front_window;
-#endif
+    /* Mac version may get events, such as a menu bar click, even when
+       all the frames are invisible.  In this case, we regard the
+       event came to the selected frame.  */
+    return SELECTED_FRAME ();
 }
 
-#define mac_window_to_frame(wp) (((mac_output *) GetWRefCon (wp))->mFP)
 
 /* Return the current position of the mouse.
    *fp should be a frame which indicates which display to ask about.
@@ -3934,13 +4096,10 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
 {
   Point mouse_pos;
   int ignore1, ignore2;
-  WindowPtr wp = mac_front_window ();
-  struct frame *f;
+  struct frame *f = mac_focus_frame (FRAME_MAC_DISPLAY_INFO (*fp));
+  WindowPtr wp = FRAME_MAC_WINDOW (f);
   Lisp_Object frame, tail;
 
-  if (is_emacs_window(wp))
-    f = mac_window_to_frame (wp);
-
   BLOCK_INPUT;
 
   if (! NILP (last_mouse_scroll_bar) && insist == 0)
@@ -4024,7 +4183,7 @@ x_scroll_bar_create (w, top, left, width, height, disp_top, disp_height)
   r.right = left + width;
   r.bottom = disp_top + disp_height;
 
-#ifdef TARGET_API_MAC_CARBON
+#if TARGET_API_MAC_CARBON
   ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p", 1, 0, 0, 0,
                   kControlScrollBarProc, 0L);
 #else
@@ -4391,50 +4550,6 @@ XTjudge_scroll_bars (f)
 }
 
 
-void
-activate_scroll_bars (frame)
-     FRAME_PTR frame;
-{
-  Lisp_Object bar;
-  ControlHandle ch;
-
-  bar = FRAME_SCROLL_BARS (frame);
-  while (! NILP (bar))
-    {
-      ch = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar));
-#ifdef TARGET_API_MAC_CARBON
-      ActivateControl (ch);
-#else
-      SetControlMaximum (ch,
-                        VERTICAL_SCROLL_BAR_TOP_RANGE (frame,
-                                                       XINT (XSCROLL_BAR (bar)
-                                                             ->height)) - 1);
-#endif
-      bar = XSCROLL_BAR (bar)->next;
-    }
-}
-
-
-void
-deactivate_scroll_bars (frame)
-     FRAME_PTR frame;
-{
-  Lisp_Object bar;
-  ControlHandle ch;
-
-  bar = FRAME_SCROLL_BARS (frame);
-  while (! NILP (bar))
-    {
-      ch = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar));
-#ifdef TARGET_API_MAC_CARBON
-      DeactivateControl (ch);
-#else
-      SetControlMaximum (ch, XINT (-1));
-#endif
-      bar = XSCROLL_BAR (bar)->next;
-    }
-}
-
 /* Handle a mouse click on the scroll bar BAR.  If *EMACS_EVENT's kind
    is set to something other than NO_EVENT, it is enqueued.
 
@@ -4473,7 +4588,7 @@ x_scroll_bar_handle_click (bar, part_code, er, bufp)
     case kControlPageDownPart:
       bufp->part = scroll_bar_below_handle;
       break;
-#ifdef TARGET_API_MAC_CARBON
+#if TARGET_API_MAC_CARBON
     default:
 #else
     case kControlIndicatorPart:
@@ -4551,7 +4666,12 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
      unsigned long *time;
 {
   struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
-  WindowPtr wp = mac_front_window ();
+  ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
+#if TARGET_API_MAC_CARBON
+  WindowPtr wp = GetControlOwner (ch);
+#else
+  WindowPtr wp = (*ch)->contrlOwner;
+#endif
   Point mouse_pos;
   struct frame *f = mac_window_to_frame (wp);
   int win_y, top_range;
@@ -4608,18 +4728,19 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
    mode lines must be clipped to the whole window.  */
 
 static void
-x_clip_to_row (w, row, gc)
+x_clip_to_row (w, row, area, gc)
      struct window *w;
      struct glyph_row *row;
+     int area;
      GC gc;
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   Rect clip_rect;
-  int window_y, window_width;
+  int window_x, window_y, window_width;
 
-  window_box (w, -1, 0, &window_y, &window_width, 0);
+  window_box (w, area, &window_x, &window_y, &window_width, 0);
 
-  clip_rect.left = WINDOW_TO_FRAME_PIXEL_X (w, 0);
+  clip_rect.left = window_x;
   clip_rect.top = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
   clip_rect.top = max (clip_rect.top, window_y);
   clip_rect.right = clip_rect.left + window_width;
@@ -4650,29 +4771,10 @@ x_draw_hollow_cursor (w, row)
   if (cursor_glyph == NULL)
     return;
 
-  /* Compute the width of the rectangle to draw.  If on a stretch
-     glyph, and `x-stretch-block-cursor' is nil, don't draw a
-     rectangle as wide as the glyph, but use a canonical character
-     width instead.  */
-  wd = cursor_glyph->pixel_width - 1;
-  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.  */
+  /* Compute frame-relative coordinates for phys cursor.  */
   x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
-  y = WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y);
-
-  /* Compute the proper height and ascent of the rectangle, based
-     on the actual glyph.  Using the full height of the row looks
-     bad when there are tall images on that row.  */
-  h = max (min (FRAME_LINE_HEIGHT (f), row->height),
-          cursor_glyph->ascent + cursor_glyph->descent);
-  if (h < row->height)
-    y += row->ascent /* - w->phys_cursor_ascent */ + cursor_glyph->descent - h;
-  h--;
+  y = get_phys_cursor_geometry (w, row, cursor_glyph, &h);
+  wd = w->phys_cursor_width;
 
   /* The foreground of cursor_gc is typically the same as the normal
      background color, which can cause the cursor box to be invisible.  */
@@ -4685,7 +4787,7 @@ x_draw_hollow_cursor (w, row)
   gc = dpyinfo->scratch_cursor_gc;
 
   /* Set clipping, draw the rectangle, and reset clipping again.  */
-  x_clip_to_row (w, row, gc);
+  x_clip_to_row (w, row, TEXT_AREA, gc);
   mac_draw_rectangle (dpy, FRAME_MAC_WINDOW (f), gc, x, y, wd, h);
   mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f));
 }
@@ -4756,7 +4858,7 @@ x_draw_bar_cursor (w, row, width, kind)
       width = min (cursor_glyph->pixel_width, width);
 
       w->phys_cursor_width = width;
-      x_clip_to_row (w, row, gc);
+      x_clip_to_row (w, row, TEXT_AREA, gc);
 
       if (kind == BAR_CURSOR)
        XFillRectangle (dpy, window, gc,
@@ -4783,11 +4885,7 @@ mac_define_frame_cursor (f, cursor)
      struct frame *f;
      Cursor cursor;
 {
-#if TARGET_API_MAC_CARBON
   SetThemeCursor (cursor);
-#else
-  SetCursor (*cursor);
-#endif
 }
 
 
@@ -4952,7 +5050,8 @@ x_new_font (f, fontname)
   FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset;
   FRAME_FONTSET (f) = -1;
 
-  FRAME_COLUMN_WIDTH (f) = FONT_WIDTH (FRAME_FONT (f));
+  FRAME_COLUMN_WIDTH (f) = fontp->average_width;
+  FRAME_SPACE_WIDTH (f) = fontp->space_width;
   FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (FRAME_FONT (f));
 
   compute_fringe_widths (f, 1);
@@ -4980,13 +5079,16 @@ x_new_font (f, fontname)
       XSetFont (FRAME_MAC_DISPLAY (f), f->output_data.mac->cursor_gc,
                FRAME_FONT (f));
 
+      /* Don't change the size of a tip frame; there's no point in
+        doing it because it's done in Fx_show_tip, and it leads to
+        problems because the tip frame has no widget.  */
       if (NILP (tip_frame) || XFRAME (tip_frame) != f)
         x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
     }
 
   return build_string (fontp->full_name);
 }
-\f
+
 /* Give frame F the fontset named FONTSETNAME as its default font, and
    return the full name of that fontset.  FONTSETNAME may be a wildcard
    pattern; in that case, we choose some fontset that fits the pattern.
@@ -5015,7 +5117,7 @@ x_new_fontset (f, fontsetname)
     return Qnil;
 
   /* Since x_new_font doesn't update any fontset information, do it now.  */
-  FRAME_FONTSET(f) = fontset;
+  FRAME_FONTSET (f) = fontset;
 
   return build_string (fontsetname);
 }
@@ -5036,6 +5138,26 @@ xim_close_dpy (dpyinfo)
  */
 
 \f
+void
+mac_get_window_bounds (f, inner, outer)
+     struct frame *f;
+     Rect *inner, *outer;
+{
+#if TARGET_API_MAC_CARBON
+  GetWindowBounds (FRAME_MAC_WINDOW (f), kWindowContentRgn, inner);
+  GetWindowBounds (FRAME_MAC_WINDOW (f), kWindowStructureRgn, outer);
+#else /* not TARGET_API_MAC_CARBON */
+  RgnHandle region = NewRgn ();
+
+  GetWindowRegion (FRAME_MAC_WINDOW (f), kWindowContentRgn, region);
+  *inner = (*region)->rgnBBox;
+  GetWindowRegion (FRAME_MAC_WINDOW (f), kWindowStructureRgn, region);
+  *outer = (*region)->rgnBBox;
+  DisposeRgn (region);
+#endif /* not TARGET_API_MAC_CARBON */
+}
+
+
 /* Calculate the absolute position in frame F
    from its current recorded position values and gravity.  */
 
@@ -5043,47 +5165,36 @@ void
 x_calc_absolute_position (f)
      struct frame *f;
 {
-  Point pt;
+  int width_diff = 0, height_diff = 0;
   int flags = f->size_hint_flags;
+  Rect inner, outer;
 
-  pt.h = pt.v = 0;
+  /* We have nothing to do if the current position
+     is already for the top-left corner.  */
+  if (! ((flags & XNegative) || (flags & YNegative)))
+    return;
 
-  /* Find the position of the outside upper-left corner of
+  /* Find the offsets of the outside upper-left corner of
      the inner window, with respect to the outer window.  */
-  if (f->output_data.mac->parent_desc != FRAME_MAC_DISPLAY_INFO (f)->root_window)
-    {
-      GrafPtr savePort;
-      GetPort (&savePort);
-
-      SetPortWindowPort (FRAME_MAC_WINDOW (f));
+  mac_get_window_bounds (f, &inner, &outer);
 
-#if TARGET_API_MAC_CARBON
-      {
-        Rect r;
-
-        GetWindowPortBounds (FRAME_MAC_WINDOW (f), &r);
-        SetPt(&pt, r.left,  r.top);
-      }
-#else /* not TARGET_API_MAC_CARBON */
-      SetPt(&pt, FRAME_MAC_WINDOW (f)->portRect.left,  FRAME_MAC_WINDOW (f)->portRect.top);
-#endif /* not TARGET_API_MAC_CARBON */
-      LocalToGlobal (&pt);
-      SetPort (savePort);
-    }
+  width_diff = (outer.right - outer.left) - (inner.right - inner.left);
+  height_diff = (outer.bottom - outer.top) - (inner.bottom - inner.top);
 
   /* Treat negative positions as relative to the leftmost bottommost
      position that fits on the screen.  */
   if (flags & XNegative)
     f->left_pos = (FRAME_MAC_DISPLAY_INFO (f)->width
-                  - 2 * f->border_width - pt.h
+                   - width_diff
                   - FRAME_PIXEL_WIDTH (f)
                   + f->left_pos);
-  /* NTEMACS_TODO: Subtract menubar height?  */
+
   if (flags & YNegative)
     f->top_pos = (FRAME_MAC_DISPLAY_INFO (f)->height
-                 - 2 * f->border_width - pt.v
+                 - height_diff
                  - FRAME_PIXEL_HEIGHT (f)
                  + f->top_pos);
+
   /* The left_pos and top_pos
      are now relative to the top and left screen edges,
      so the flags should correspond.  */
@@ -5102,8 +5213,6 @@ x_set_offset (f, xoff, yoff, change_gravity)
      register int xoff, yoff;
      int change_gravity;
 {
-  int modified_top, modified_left;
-
   if (change_gravity > 0)
     {
       f->top_pos = yoff;
@@ -5120,11 +5229,55 @@ x_set_offset (f, xoff, yoff, change_gravity)
   BLOCK_INPUT;
   x_wm_set_size_hint (f, (long) 0, 0);
 
-  modified_left = f->left_pos;
-  modified_top = f->top_pos;
-
-  MoveWindow (f->output_data.mac->mWP, modified_left + 6,
-             modified_top + 42, false);
+#if TARGET_API_MAC_CARBON
+  MoveWindowStructure (FRAME_MAC_WINDOW (f), f->left_pos, f->top_pos);
+  /* If the title bar is completely outside the screen, adjust the
+     position. */
+  ConstrainWindowToScreen (FRAME_MAC_WINDOW (f), kWindowTitleBarRgn,
+                          kWindowConstrainMoveRegardlessOfFit
+                          | kWindowConstrainAllowPartial, NULL, NULL);
+  x_real_positions (f, &f->left_pos, &f->top_pos);
+#else
+  {
+    Rect inner, outer, screen_rect, dummy;
+    RgnHandle region = NewRgn ();
+
+    mac_get_window_bounds (f, &inner, &outer);
+    f->x_pixels_diff = inner.left - outer.left;
+    f->y_pixels_diff = inner.top - outer.top;
+    MoveWindow (FRAME_MAC_WINDOW (f), f->left_pos + f->x_pixels_diff,
+               f->top_pos + f->y_pixels_diff, false);
+
+    /* If the title bar is completely outside the screen, adjust the
+       position.  The variable `outer' holds the title bar rectangle.
+       The variable `inner' holds slightly smaller one than `outer',
+       so that the calculation of overlapping may not become too
+       strict.  */
+    GetWindowRegion (FRAME_MAC_WINDOW (f), kWindowTitleBarRgn, region);
+    outer = (*region)->rgnBBox;
+    DisposeRgn (region);
+    inner = outer;
+    InsetRect (&inner, 8, 8);
+    screen_rect = qd.screenBits.bounds;
+    screen_rect.top += GetMBarHeight ();
+
+    if (!SectRect (&inner, &screen_rect, &dummy))
+      {
+       if (inner.right <= screen_rect.left)
+         f->left_pos = screen_rect.left;
+       else if (inner.left >= screen_rect.right)
+         f->left_pos = screen_rect.right - (outer.right - outer.left);
+
+       if (inner.bottom <= screen_rect.top)
+         f->top_pos = screen_rect.top;
+       else if (inner.top >= screen_rect.bottom)
+         f->top_pos = screen_rect.bottom - (outer.bottom - outer.top);
+
+       MoveWindow (FRAME_MAC_WINDOW (f), f->left_pos + f->x_pixels_diff,
+                   f->top_pos + f->y_pixels_diff, false);
+      }
+  }
+#endif
 
   UNBLOCK_INPUT;
 }
@@ -5157,6 +5310,11 @@ x_set_window_size (f, change_gravity, cols, rows)
   x_wm_set_size_hint (f, (long) 0, 0);
 
   SizeWindow (FRAME_MAC_WINDOW (f), pixelwidth, pixelheight, 0);
+#if TARGET_API_MAC_CARBON
+  if (f->output_data.mac->hourglass_control)
+    MoveControl (f->output_data.mac->hourglass_control,
+                pixelwidth - HOURGLASS_WIDTH, 0);
+#endif
 
   /* Now, strictly speaking, we can't be sure that this is accurate,
      but the window manager will get around to dealing with the size
@@ -5263,7 +5421,11 @@ x_raise_frame (f)
      struct frame *f;
 {
   if (f->async_visible)
-    SelectWindow (FRAME_MAC_WINDOW (f));
+    {
+      BLOCK_INPUT;
+      SelectWindow (FRAME_MAC_WINDOW (f));
+      UNBLOCK_INPUT;
+    }
 }
 
 /* Lower frame F.  */
@@ -5272,7 +5434,11 @@ x_lower_frame (f)
      struct frame *f;
 {
   if (f->async_visible)
-    SendBehind (FRAME_MAC_WINDOW (f), nil);
+    {
+      BLOCK_INPUT;
+      SendBehind (FRAME_MAC_WINDOW (f), nil);
+      UNBLOCK_INPUT;
+    }
 }
 
 static void
@@ -5316,6 +5482,25 @@ x_make_frame_visible (f)
 
       f->output_data.mac->asked_for_visible = 1;
 
+#if TARGET_API_MAC_CARBON
+      if (!(FRAME_SIZE_HINTS (f)->flags & (USPosition | PPosition)))
+       {
+         struct frame *sf = SELECTED_FRAME ();
+         if (!FRAME_MAC_P (sf))
+           RepositionWindow (FRAME_MAC_WINDOW (f), NULL,
+                             kWindowCenterOnMainScreen);
+         else
+           RepositionWindow (FRAME_MAC_WINDOW (f),
+                             FRAME_MAC_WINDOW (sf),
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+                             kWindowCascadeStartAtParentWindowScreen
+#else
+                             kWindowCascadeOnParentWindowScreen
+#endif
+                             );
+         x_real_positions (f, &f->left_pos, &f->top_pos);
+       }
+#endif
       ShowWindow (FRAME_MAC_WINDOW (f));
     }
 
@@ -5380,6 +5565,13 @@ x_make_frame_invisible (f)
 
   BLOCK_INPUT;
 
+  /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
+     that the current position of the window is user-specified, rather than
+     program-specified, so that when the window is mapped again, it will be
+     placed at the same location, without forcing the user to position it
+     by hand again (they have already done that once for this window.)  */
+  x_wm_set_size_hint (f, (long) 0, 1);
+
   HideWindow (FRAME_MAC_WINDOW (f));
 
   /* We can't distinguish this from iconification
@@ -5430,6 +5622,9 @@ x_free_frame_resources (f)
 
   BLOCK_INPUT;
 
+  if (wp != tip_window)
+    remove_window_handler (wp);
+
   DisposeWindow (wp);
   if (wp == tip_window)
     /* Neither WaitNextEvent nor ReceiveNextEvent receives `window
@@ -5443,6 +5638,9 @@ x_free_frame_resources (f)
 
   x_free_gcs (f);
 
+  if (FRAME_SIZE_HINTS (f))
+    xfree (FRAME_SIZE_HINTS (f));
+
   xfree (f->output_data.mac);
   f->output_data.mac = NULL;
 
@@ -5495,143 +5693,39 @@ x_wm_set_size_hint (f, flags, user_position)
      long flags;
      int user_position;
 {
-#if 0 /* MAC_TODO: connect this to the Appearance Manager */
-  XSizeHints size_hints;
+  int base_width, base_height, width_inc, height_inc;
+  int min_rows = 0, min_cols = 0;
+  XSizeHints *size_hints;
 
-#ifdef USE_X_TOOLKIT
-  Arg al[2];
-  int ac = 0;
-  Dimension widget_width, widget_height;
-  Window window = XtWindow (f->output_data.x->widget);
-#else /* not USE_X_TOOLKIT */
-  Window window = FRAME_X_WINDOW (f);
-#endif /* not USE_X_TOOLKIT */
-
-  /* Setting PMaxSize caused various problems.  */
-  size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */;
-
-  size_hints.x = f->left_pos;
-  size_hints.y = f->top_pos;
-
-#ifdef USE_X_TOOLKIT
-  XtSetArg (al[ac], XtNwidth, &widget_width); ac++;
-  XtSetArg (al[ac], XtNheight, &widget_height); ac++;
-  XtGetValues (f->output_data.x->widget, al, ac);
-  size_hints.height = widget_height;
-  size_hints.width = widget_width;
-#else /* not USE_X_TOOLKIT */
-  size_hints.height = FRAME_PIXEL_HEIGHT (f);
-  size_hints.width = FRAME_PIXEL_WIDTH (f);
-#endif /* not USE_X_TOOLKIT */
-
-  size_hints.width_inc = FRAME_COLUMN_WIDTH (f);
-  size_hints.height_inc = FRAME_LINE_HEIGHT (f);
-  size_hints.max_width
-    = FRAME_X_DISPLAY_INFO (f)->width - FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
-  size_hints.max_height
-    = FRAME_X_DISPLAY_INFO (f)->height - FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
-
-  /* Calculate the base and minimum sizes.
-
-     (When we use the X toolkit, we don't do it here.
-     Instead we copy the values that the widgets are using, below.)  */
-#ifndef USE_X_TOOLKIT
-  {
-    int base_width, base_height;
-    int min_rows = 0, min_cols = 0;
+  base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
+  base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
+  width_inc = FRAME_COLUMN_WIDTH (f);
+  height_inc = FRAME_LINE_HEIGHT (f);
 
-    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);
 
-    check_frame_size (f, &min_rows, &min_cols);
-
-    /* The window manager uses the base width hints to calculate the
-       current number of rows and columns in the frame while
-       resizing; min_width and min_height aren't useful for this
-       purpose, since they might not give the dimensions for a
-       zero-row, zero-column frame.
-
-       We use the base_width and base_height members if we have
-       them; otherwise, we set the min_width and min_height members
-       to the size for a zero x zero frame.  */
-
-#ifdef HAVE_X11R4
-    size_hints.flags |= PBaseSize;
-    size_hints.base_width = base_width;
-    size_hints.base_height = base_height;
-    size_hints.min_width  = base_width + min_cols * size_hints.width_inc;
-    size_hints.min_height = base_height + min_rows * size_hints.height_inc;
-#else
-    size_hints.min_width = base_width;
-    size_hints.min_height = base_height;
-#endif
-  }
-
-  /* If we don't need the old flags, we don't need the old hint at all.  */
-  if (flags)
+  size_hints = FRAME_SIZE_HINTS (f);
+  if (size_hints == NULL)
     {
-      size_hints.flags |= flags;
-      goto no_read;
+      size_hints = FRAME_SIZE_HINTS (f) = xmalloc (sizeof (XSizeHints));
+      bzero (size_hints, sizeof (XSizeHints));
     }
-#endif /* not USE_X_TOOLKIT */
-
-  {
-    XSizeHints hints;          /* Sometimes I hate X Windows... */
-    long supplied_return;
-    int value;
-
-#ifdef HAVE_X11R4
-    value = XGetWMNormalHints (FRAME_X_DISPLAY (f), window, &hints,
-                              &supplied_return);
-#else
-    value = XGetNormalHints (FRAME_X_DISPLAY (f), window, &hints);
-#endif
 
-#ifdef USE_X_TOOLKIT
-    size_hints.base_height = hints.base_height;
-    size_hints.base_width = hints.base_width;
-    size_hints.min_height = hints.min_height;
-    size_hints.min_width = hints.min_width;
-#endif
-
-    if (flags)
-      size_hints.flags |= flags;
-    else
-      {
-       if (value == 0)
-         hints.flags = 0;
-       if (hints.flags & PSize)
-         size_hints.flags |= PSize;
-       if (hints.flags & PPosition)
-         size_hints.flags |= PPosition;
-       if (hints.flags & USPosition)
-         size_hints.flags |= USPosition;
-       if (hints.flags & USSize)
-         size_hints.flags |= USSize;
-      }
-  }
-
-#ifndef USE_X_TOOLKIT
- no_read:
-#endif
+  size_hints->flags |= PResizeInc | PMinSize | PBaseSize ;
+  size_hints->width_inc  = width_inc;
+  size_hints->height_inc = height_inc;
+  size_hints->min_width  = base_width + min_cols * width_inc;
+  size_hints->min_height = base_height + min_rows * height_inc;
+  size_hints->base_width  = base_width;
+  size_hints->base_height = base_height;
 
-#ifdef PWinGravity
-  size_hints.win_gravity = f->win_gravity;
-  size_hints.flags |= PWinGravity;
-
-  if (user_position)
+  if (flags)
+    size_hints->flags = flags;
+  else if (user_position)
     {
-      size_hints.flags &= ~ PPosition;
-      size_hints.flags |= USPosition;
+      size_hints->flags &= ~ PPosition;
+      size_hints->flags |= USPosition;
     }
-#endif /* PWinGravity */
-
-#ifdef HAVE_X11R4
-  XSetWMNormalHints (FRAME_X_DISPLAY (f), window, &size_hints);
-#else
-  XSetNormalHints (FRAME_X_DISPLAY (f), window, &size_hints);
-#endif
-#endif /* MAC_TODO */
 }
 
 #if 0 /* MAC_TODO: hide application instead of iconify? */
@@ -5832,7 +5926,14 @@ mac_font_match (char *mf, char *xf)
 static Lisp_Object Qbig5, Qcn_gb, Qsjis, Qeuc_kr;
 
 static void
-decode_mac_font_name (char *name, int size, short scriptcode)
+decode_mac_font_name (name, size, scriptcode)
+     char *name;
+     int size;
+#if TARGET_API_MAC_CARBON
+     int scriptcode;
+#else
+     short scriptcode;
+#endif
 {
   Lisp_Object coding_system;
   struct coding_system coding;
@@ -5870,7 +5971,15 @@ decode_mac_font_name (char *name, int size, short scriptcode)
 
 
 static char *
-mac_to_x_fontname (char *name, int size, Style style, short scriptcode)
+mac_to_x_fontname (name, size, style, scriptcode)
+     char *name;
+     int size;
+     Style style;
+#if TARGET_API_MAC_CARBON
+     int scriptcode;
+#else
+     short scriptcode;
+#endif
 {
   char foundry[32], family[32], cs[32];
   char xf[256], *result, *p;
@@ -5882,13 +5991,13 @@ mac_to_x_fontname (char *name, int size, Style style, short scriptcode)
 
       switch (scriptcode)
       {
-      case smTradChinese:
+      case smTradChinese:      /* == kTextEncodingMacChineseTrad */
         strcpy(cs, "big5-0");
         break;
-      case smSimpChinese:
+      case smSimpChinese:      /* == kTextEncodingMacChineseSimp */
         strcpy(cs, "gb2312.1980-0");
         break;
-      case smJapanese:
+      case smJapanese:         /* == kTextEncodingMacJapanese */
         strcpy(cs, "jisx0208.1983-sjis");
         break;
       case -smJapanese:
@@ -5900,12 +6009,24 @@ mac_to_x_fontname (char *name, int size, Style style, short scriptcode)
           font is being built.  */
        strcpy(cs, "jisx0201.1976-0");
        break;
-      case smKorean:
+      case smKorean:           /* == kTextEncodingMacKorean */
         strcpy(cs, "ksc5601.1989-0");
         break;
+#if TARGET_API_MAC_CARBON
+      case kTextEncodingMacCyrillic:
+       strcpy(cs, "mac-cyrillic");
+       break;
+      case kTextEncodingMacCentralEurRoman:
+       strcpy(cs, "mac-centraleurroman");
+       break;
+      case kTextEncodingMacSymbol:
+      case kTextEncodingMacDingbats:
+       strcpy(cs, "adobe-fontspecific");
+       break;
+#endif
       default:
-        strcpy(cs, "mac-roman");
-        break;
+       strcpy(cs, "mac-roman");
+       break;
       }
     }
 
@@ -5952,7 +6073,10 @@ x_font_name_to_mac_font_name (char *xf, char *mf)
     coding_system = Qsjis;
   else if (strcmp (cs, "ksc5601.1989-0") == 0)
     coding_system = Qeuc_kr;
-  else if (strcmp (cs, "mac-roman") == 0)
+  else if (strcmp (cs, "mac-roman") == 0
+          || strcmp (cs, "mac-cyrillic") == 0
+          || strcmp (cs, "mac-centraleurroman") == 0
+          || strcmp (cs, "adobe-fontspecific") == 0)
     strcpy (mf, family);
   else
     sprintf (mf, "%s-%s-%s", foundry, family, cs);
@@ -6024,7 +6148,8 @@ init_font_name_table ()
          FMFont font;
          FMFontStyle style;
          FMFontSize size;
-         SInt16 sc;
+         TextEncoding encoding;
+         TextEncodingBase sc;
 
          if (FMGetFontFamilyName (ff, name) != noErr)
            break;
@@ -6032,7 +6157,9 @@ init_font_name_table ()
          if (*name == '.')
            continue;
 
-         sc = FontToScript (ff);
+         if (FMGetFontFamilyTextEncoding (ff, &encoding) != noErr)
+           break;
+         sc = GetTextEncodingBase (encoding);
          decode_mac_font_name (name, sizeof (name), sc);
 
          /* Point the instance iterator at the current font family.  */
@@ -6173,6 +6300,19 @@ init_font_name_table ()
 }
 
 
+void
+mac_clear_font_name_table ()
+{
+  int i;
+
+  for (i = 0; i < font_name_count; i++)
+    xfree (font_name_table[i]);
+  xfree (font_name_table);
+  font_name_table = NULL;
+  font_name_table_size = font_name_count = 0;
+}
+
+
 enum xlfd_scalable_field_index
   {
     XLFD_SCL_PIXEL_SIZE,
@@ -6189,6 +6329,28 @@ static int xlfd_scalable_fields[] =
     -1
   };
 
+static Lisp_Object
+mac_c_string_match (regexp, string, nonspecial, exact)
+     Lisp_Object regexp;
+     const char *string, *nonspecial;
+     int exact;
+{
+  if (exact)
+    {
+      if (strcmp (string, nonspecial) == 0)
+       return build_string (string);
+    }
+  else if (strstr (string, nonspecial))
+    {
+      Lisp_Object str = build_string (string);
+
+      if (fast_string_match (regexp, str) >= 0)
+       return str;
+    }
+
+  return Qnil;
+}
+
 static Lisp_Object
 mac_do_list_fonts (pattern, maxnames)
      char *pattern;
@@ -6200,6 +6362,11 @@ mac_do_list_fonts (pattern, maxnames)
   char scaled[256];
   char *ptr;
   int scl_val[XLFD_SCL_LAST], *field, *val;
+  char *longest_start, *cur_start, *nonspecial;
+  int longest_len, exact;
+
+  if (font_name_table == NULL)  /* Initialize when first used.  */
+    init_font_name_table ();
 
   for (i = 0; i < XLFD_SCL_LAST; i++)
     scl_val[i] = -1;
@@ -6257,34 +6424,60 @@ mac_do_list_fonts (pattern, maxnames)
   ptr = regex;
   *ptr++ = '^';
 
-  /* Turn pattern into a regexp and do a regexp match.  */
+  longest_start = cur_start = ptr;
+  longest_len = 0;
+  exact = 1;
+
+  /* Turn pattern into a regexp and do a regexp match.  Also find the
+     longest substring containing no special characters.  */
   for (; *pattern; pattern++)
     {
-      if (*pattern == '?')
-        *ptr++ = '.';
-      else if (*pattern == '*')
-        {
-          *ptr++ = '.';
-          *ptr++ = '*';
-        }
+      if (*pattern == '?' || *pattern == '*')
+       {
+         if (ptr - cur_start > longest_len)
+           {
+             longest_start = cur_start;
+             longest_len = ptr - cur_start;
+           }
+         exact = 0;
+
+         if (*pattern == '?')
+           *ptr++ = '.';
+         else /* if (*pattern == '*') */
+           {
+             *ptr++ = '.';
+             *ptr++ = '*';
+           }
+         cur_start = ptr;
+       }
       else
-        *ptr++ = tolower (*pattern);
+       *ptr++ = tolower (*pattern);
+    }
+
+  if (ptr - cur_start > longest_len)
+    {
+      longest_start = cur_start;
+      longest_len = ptr - cur_start;
     }
+
   *ptr = '$';
   *(ptr + 1) = '\0';
 
+  nonspecial = xmalloc (longest_len + 1);
+  strncpy (nonspecial, longest_start, longest_len);
+  nonspecial[longest_len] = '\0';
+
   pattern_regex = build_string (regex);
 
   for (i = 0; i < font_name_count; i++)
     {
-      fontname = build_string (font_name_table[i]);
-      if (fast_string_match (pattern_regex, fontname) >= 0)
+      fontname = mac_c_string_match (pattern_regex, font_name_table[i],
+                                    nonspecial, exact);
+      if (!NILP (fontname))
        {
          font_list = Fcons (fontname, font_list);
-
-          n_fonts++;
-          if (maxnames > 0 && n_fonts >= maxnames)
-            break;
+         if (exact || maxnames > 0 && ++n_fonts >= maxnames)
+           break;
        }
       else if (scl_val[XLFD_SCL_PIXEL_SIZE] > 0
               && (ptr = strstr (font_name_table[i], "-0-0-75-75-m-0-")))
@@ -6298,17 +6491,19 @@ mac_do_list_fonts (pattern, maxnames)
                   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)
+         fontname = mac_c_string_match (pattern_regex, scaled,
+                                        nonspecial, exact);
+         if (!NILP (fontname))
            {
              font_list = Fcons (fontname, font_list);
-
-             n_fonts++;
-             if (maxnames > 0 && n_fonts >= maxnames)
+             if (exact || maxnames > 0 && ++n_fonts >= maxnames)
                break;
            }
        }
     }
+
+  xfree (nonspecial);
+
   return font_list;
 }
 
@@ -6327,12 +6522,9 @@ x_list_fonts (struct frame *f,
   Lisp_Object newlist = Qnil, tem, key;
   struct mac_display_info *dpyinfo = f ? FRAME_MAC_DISPLAY_INFO (f) : NULL;
 
-  if (font_name_table == NULL)  /* Initialize when first used.  */
-    init_font_name_table ();
-
   if (dpyinfo)
     {
-      tem = XCDR (dpyinfo->name_list_element);
+      tem = XCAR (XCDR (dpyinfo->name_list_element));
       key = Fcons (pattern, make_number (maxnames));
 
       newlist = Fassoc (key, tem);
@@ -6343,15 +6535,17 @@ x_list_fonts (struct frame *f,
        }
     }
 
+  BLOCK_INPUT;
   newlist = mac_do_list_fonts (SDATA (pattern), maxnames);
+  UNBLOCK_INPUT;
 
   /* MAC_TODO: add code for matching outline fonts here */
 
   if (dpyinfo)
     {
-      XSETCDR (dpyinfo->name_list_element,
+      XSETCAR (XCDR (dpyinfo->name_list_element),
               Fcons (Fcons (key, newlist),
-                     XCDR (dpyinfo->name_list_element)));
+                     XCAR (XCDR (dpyinfo->name_list_element))));
     }
  label_cached:
 
@@ -6395,12 +6589,8 @@ x_font_min_bounds (font, w, h)
      MacFontStruct *font;
      int *w, *h;
 {
-  /*
-   * TODO: Windows does not appear to offer min bound, only
-   * average and maximum width, and maximum height.
-   */
   *h = FONT_HEIGHT (font);
-  *w = FONT_WIDTH (font);
+  *w = font->min_bounds.width;
 }
 
 
@@ -6613,29 +6803,66 @@ XLoadQueryFont (Display *dpy, char *fontname)
        returns 15 for 12-point Monaco! */
     char_width = CharWidth ('m');
 
-  font->max_bounds.rbearing = char_width;
-  font->max_bounds.lbearing = 0;
-  font->max_bounds.width = char_width;
-  font->max_bounds.ascent = the_fontinfo.ascent;
-  font->max_bounds.descent = the_fontinfo.descent;
+  if (is_two_byte_font)
+    {
+      font->per_char = NULL;
 
-  font->min_bounds = font->max_bounds;
+      if (fontface & italic)
+       font->max_bounds.rbearing = char_width + 1;
+      else
+       font->max_bounds.rbearing = char_width;
+      font->max_bounds.lbearing = 0;
+      font->max_bounds.width = char_width;
+      font->max_bounds.ascent = the_fontinfo.ascent;
+      font->max_bounds.descent = the_fontinfo.descent;
 
-  if (is_two_byte_font || CharWidth ('m') == CharWidth ('i'))
-    font->per_char = NULL;
+      font->min_bounds = font->max_bounds;
+    }
   else
     {
       font->per_char = (XCharStruct *)
        xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
       {
-        int c;
+       int c, min_width, max_width;
+       Rect char_bounds, min_bounds, max_bounds;
+       char ch;
 
+       min_width = max_width = char_width;
+       SetRect (&min_bounds, -32767, -32767, 32767, 32767);
+       SetRect (&max_bounds, 0, 0, 0, 0);
         for (c = 0x20; c <= 0xff; c++)
           {
-            font->per_char[c - 0x20] = font->max_bounds;
-            font->per_char[c - 0x20].width =
-             font->per_char[c - 0x20].rbearing = CharWidth (c);
-          }
+           ch = c;
+           char_width = CharWidth (ch);
+           QDTextBounds (1, &ch, &char_bounds);
+           STORE_XCHARSTRUCT (font->per_char[c - 0x20],
+                              char_width, char_bounds);
+           /* Some Japanese fonts (in SJIS encoding) return 0 as the
+              character width of 0x7f.  */
+           if (char_width > 0)
+             {
+               min_width = min (min_width, char_width);
+               max_width = max (max_width, char_width);
+             }
+           if (!EmptyRect (&char_bounds))
+             {
+               SetRect (&min_bounds,
+                        max (min_bounds.left, char_bounds.left),
+                        max (min_bounds.top, char_bounds.top),
+                        min (min_bounds.right, char_bounds.right),
+                        min (min_bounds.bottom, char_bounds.bottom));
+               UnionRect (&max_bounds, &char_bounds, &max_bounds);
+             }
+         }
+       STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds);
+       STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
+       if (min_width == max_width
+           && max_bounds.left >= 0 && max_bounds.right <= max_width)
+         {
+           /* Fixed width and no overhangs.  */
+           xfree (font->per_char);
+           font->per_char = NULL;
+         }
       }
     }
 
@@ -6647,6 +6874,18 @@ XLoadQueryFont (Display *dpy, char *fontname)
 }
 
 
+void
+mac_unload_font (dpyinfo, font)
+     struct mac_display_info *dpyinfo;
+     XFontStruct *font;
+{
+  xfree (font->fontname);
+  if (font->per_char)
+    xfree (font->per_char);
+  xfree (font);
+}
+
+
 /* Load font named FONTNAME of the size SIZE for frame F, and return a
    pointer to the structure font_info while allocating it dynamically.
    If SIZE is 0, load any size of font.
@@ -6697,7 +6936,9 @@ x_load_font (f, fontname, size)
     if (size > 0 && !NILP (font_names))
       fontname = (char *) SDATA (XCAR (font_names));
 
+    BLOCK_INPUT;
     font = (MacFontStruct *) XLoadQueryFont (FRAME_MAC_DISPLAY (f), fontname);
+    UNBLOCK_INPUT;
     if (!font)
       return NULL;
 
@@ -6729,6 +6970,35 @@ x_load_font (f, fontname, size)
     fontp->name = (char *) xmalloc (strlen (font->fontname) + 1);
     bcopy (font->fontname, fontp->name, strlen (font->fontname) + 1);
 
+    if (font->min_bounds.width == font->max_bounds.width)
+      {
+       /* Fixed width font.  */
+       fontp->average_width = fontp->space_width = font->min_bounds.width;
+      }
+    else
+      {
+       XChar2b char2b;
+       XCharStruct *pcm;
+
+       char2b.byte1 = 0x00, char2b.byte2 = 0x20;
+       pcm = mac_per_char_metric (font, &char2b, 0);
+       if (pcm)
+         fontp->space_width = pcm->width;
+       else
+         fontp->space_width = FONT_WIDTH (font);
+
+       if (pcm)
+         {
+           int width = pcm->width;
+           for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++)
+             if ((pcm = mac_per_char_metric (font, &char2b, 0)) != NULL)
+               width += pcm->width;
+           fontp->average_width = width / 95;
+         }
+       else
+         fontp->average_width = FONT_WIDTH (font);
+      }
+
     fontp->full_name = fontp->name;
 
     fontp->size = font->max_bounds.width;
@@ -6859,7 +7129,7 @@ x_find_ccl_program (fontp)
 \f
 /* The Mac Event loop code */
 
-#ifndef MAC_OSX
+#if !TARGET_API_MAC_CARBON
 #include <Events.h>
 #include <Quickdraw.h>
 #include <Balloons.h>
@@ -6874,13 +7144,12 @@ x_find_ccl_program (fontp)
 #include <Dialogs.h>
 #include <Script.h>
 #include <Types.h>
-#include <TextEncodingConverter.h>
 #include <Resources.h>
 
 #if __MWERKS__
 #include <unix.h>
 #endif
-#endif /* ! MAC_OSX */
+#endif /* ! TARGET_API_MAC_CARBON */
 
 #define M_APPLE 128
 #define I_ABOUT 1
@@ -6900,6 +7169,7 @@ x_find_ccl_program (fontp)
 /* true when cannot handle any Mac OS events */
 static int handling_window_update = 0;
 
+#if 0
 /* the flag appl_is_suspended is used both for determining the sleep
    time to be passed to WaitNextEvent and whether the cursor should be
    drawn when updating the display.  The cursor is turned off when
@@ -6909,6 +7179,7 @@ static int handling_window_update = 0;
    suspended.  */
 static Boolean app_is_suspended = false;
 static long app_sleep_time = WNE_SLEEP_AT_RESUME;
+#endif
 
 #define EXTRA_STACK_ALLOC (256 * 1024)
 
@@ -6924,6 +7195,9 @@ Lisp_Object Qreverse;
 /* True if using command key as meta key.  */
 Lisp_Object Vmac_command_key_is_meta;
 
+/* Modifier associated with the option key, or nil for normal behavior. */
+Lisp_Object Vmac_option_modifier;
+
 /* True if the ctrl and meta keys should be reversed.  */
 Lisp_Object Vmac_reverse_ctrl_meta;
 
@@ -6945,11 +7219,6 @@ Lisp_Object Vmac_pass_command_to_system;
 Lisp_Object Vmac_pass_control_to_system;
 #endif
 
-/* convert input from Mac keyboard (assumed to be in Mac Roman coding)
-   to this text encoding */
-int mac_keyboard_text_encoding;
-int current_mac_keyboard_text_encoding = kTextEncodingMacRoman;
-
 /* Set in term/mac-win.el to indicate that event loop can now generate
    drag and drop events.  */
 Lisp_Object Qmac_ready_for_drag_n_drop;
@@ -6958,11 +7227,6 @@ Lisp_Object drag_and_drop_file_list;
 
 Point saved_menu_event_location;
 
-#if !TARGET_API_MAC_CARBON
-/* Place holder for the default arrow cursor.  */
-CursPtr arrow_cursor;
-#endif
-
 /* Apple Events */
 static void init_required_apple_events (void);
 static pascal OSErr
@@ -6972,15 +7236,25 @@ do_ae_print_documents (const AppleEvent *, AppleEvent *, long);
 static pascal OSErr do_ae_open_documents (AppleEvent *, AppleEvent *, long);
 static pascal OSErr do_ae_quit_application (AppleEvent *, AppleEvent *, long);
 
+#if TARGET_API_MAC_CARBON
 /* Drag and Drop */
-static OSErr init_mac_drag_n_drop ();
+static pascal OSErr mac_do_track_drag (DragTrackingMessage, WindowPtr, void*, DragReference);
 static pascal OSErr mac_do_receive_drag (WindowPtr, void*, DragReference);
+static DragTrackingHandlerUPP mac_do_track_dragUPP = NULL;
+static DragReceiveHandlerUPP mac_do_receive_dragUPP = NULL;
+#endif
 
 #if USE_CARBON_EVENTS
+#ifdef MAC_OSX
 /* Preliminary Support for the OSX Services Menu */
 static OSStatus mac_handle_service_event (EventHandlerCallRef,EventRef,void*);
 static void init_service_handler ();
 #endif
+/* Window Event Handler */
+static pascal OSStatus mac_handle_window_event (EventHandlerCallRef,
+                                               EventRef, void *);
+#endif
+OSErr install_window_handler (WindowPtr);
 
 extern void init_emacs_passwd_dir ();
 extern int emacs_main (int, char **, char **);
@@ -7005,6 +7279,12 @@ mac_to_emacs_modifiers (EventModifiers mods)
     result |= meta_modifier;
   if (NILP (Vmac_command_key_is_meta) && (mods & macAltKey))
     result |= alt_modifier;
+  if (!NILP (Vmac_option_modifier) && (mods & optionKey)) {
+      Lisp_Object val = Fget(Vmac_option_modifier, Qmodifier_value);
+      if (!NILP(val))
+          result |= XUINT(val);
+  }
+
   return result;
 }
 
@@ -7149,8 +7429,6 @@ do_init_managers (void)
   InitCursor ();
 
 #if !TARGET_API_MAC_CARBON
-  arrow_cursor = &qd.arrow;
-
   /* set up some extra stack space for use by emacs */
   SetApplLimit ((Ptr) ((long) GetApplLimit () - EXTRA_STACK_ALLOC));
 
@@ -7181,12 +7459,11 @@ do_window_update (WindowPtr win)
 {
   struct frame *f = mac_window_to_frame (win);
 
-  if (win == tip_window)
-    /* The tooltip has been drawn already.  Avoid the
-       SET_FRAME_GARBAGED below.  */
-    return;
+  BeginUpdate (win);
 
-  if (f)
+  /* The tooltip has been drawn already.  Avoid the SET_FRAME_GARBAGED
+     below.  */
+  if (win != tip_window)
     {
       if (f->async_visible == 0)
         {
@@ -7203,17 +7480,31 @@ do_window_update (WindowPtr win)
         }
       else
         {
-          BeginUpdate (win);
+         Rect r;
+
           handling_window_update = 1;
 
-         XClearWindow (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f));
+#if TARGET_API_MAC_CARBON
+         {
+           RgnHandle region = NewRgn ();
 
-          expose_frame (f, 0, 0, 0, 0);
+           GetPortVisibleRegion (GetWindowPort (win), region);
+           GetRegionBounds (region, &r);
+           expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top);
+           UpdateControls (win, region);
+           DisposeRgn (region);
+         }
+#else
+         r = (*win->visRgn)->rgnBBox;
+         expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top);
+         UpdateControls (win, win->visRgn);
+#endif
 
           handling_window_update = 0;
-          EndUpdate (win);
         }
     }
+
+  EndUpdate (win);
 }
 
 static int
@@ -7235,79 +7526,21 @@ is_emacs_window (WindowPtr win)
 static void
 do_app_resume ()
 {
-  WindowPtr wp;
-  struct frame *f;
-
-  wp = mac_front_window ();
-  if (is_emacs_window (wp))
-    {
-      f = mac_window_to_frame (wp);
-
-      if (f)
-       {
-         x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f), f);
-         activate_scroll_bars (f);
-       }
-    }
-
+  /* Window-activate events will do the job. */
+#if 0
   app_is_suspended = false;
   app_sleep_time = WNE_SLEEP_AT_RESUME;
+#endif
 }
 
 static void
 do_app_suspend ()
 {
-  WindowPtr wp;
-  struct frame *f;
-
-  wp = mac_front_window ();
-  if (is_emacs_window (wp))
-    {
-      f = mac_window_to_frame (wp);
-
-      if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
-       {
-         x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f), 0);
-         deactivate_scroll_bars (f);
-       }
-    }
-
+  /* Window-deactivate events will do the job. */
+#if 0
   app_is_suspended = true;
   app_sleep_time = WNE_SLEEP_AT_SUSPEND;
-}
-
-
-static void
-do_mouse_moved (mouse_pos, f)
-     Point mouse_pos;
-     FRAME_PTR *f;
-{
-  WindowPtr wp = mac_front_window ();
-  struct x_display_info *dpyinfo;
-
-  if (is_emacs_window (wp))
-    {
-      *f = mac_window_to_frame (wp);
-      dpyinfo = FRAME_MAC_DISPLAY_INFO (*f);
-
-      if (dpyinfo->mouse_face_hidden)
-       {
-         dpyinfo->mouse_face_hidden = 0;
-         clear_mouse_face (dpyinfo);
-       }
-
-      SetPortWindowPort (wp);
-
-      GlobalToLocal (&mouse_pos);
-
-      if (dpyinfo->grabbed && tracked_scroll_bar)
-       x_scroll_bar_note_movement (tracked_scroll_bar,
-                                   mouse_pos.v
-                                   - XINT (tracked_scroll_bar->top),
-                                   TickCount() * (1000 / 60));
-      else
-       note_mouse_movement (*f, &mouse_pos);
-    }
+#endif
 }
 
 
@@ -7347,7 +7580,7 @@ do_menu_choice (SInt32 menu_choice)
 
     default:
       {
-        struct frame *f = mac_window_to_frame (mac_front_window ());
+        struct frame *f = mac_focus_frame (&one_mac_display_info);
         MenuHandle menu = GetMenuHandle (menu_id);
         if (menu)
           {
@@ -7369,20 +7602,43 @@ do_menu_choice (SInt32 menu_choice)
 static void
 do_grow_window (WindowPtr w, EventRecord *e)
 {
-  long grow_size;
   Rect limit_rect;
-  int rows, columns;
+  int rows, columns, width, height;
   struct frame *f = mac_window_to_frame (w);
+  XSizeHints *size_hints = FRAME_SIZE_HINTS (f);
+  int min_width = MIN_DOC_SIZE, min_height = MIN_DOC_SIZE;
+#if TARGET_API_MAC_CARBON
+  Rect new_rect;
+#else
+  long grow_size;
+#endif
 
-  SetRect(&limit_rect, MIN_DOC_SIZE, MIN_DOC_SIZE, MAX_DOC_SIZE, MAX_DOC_SIZE);
-
-  grow_size = GrowWindow (w, e->where, &limit_rect);
+  if (size_hints->flags & PMinSize)
+    {
+      min_width  = size_hints->min_width;
+      min_height = size_hints->min_height;
+    }
+  SetRect (&limit_rect, min_width, min_height, MAX_DOC_SIZE, MAX_DOC_SIZE);
 
+#if TARGET_API_MAC_CARBON
+  if (!ResizeWindow (w, e->where, &limit_rect, &new_rect))
+    return;
+  height = new_rect.bottom - new_rect.top;
+  width = new_rect.right - new_rect.left;
+#else
+  grow_size = GrowWindow (w, e->where, &limit_rect);
   /* see if it really changed size */
-  if (grow_size != 0)
+  if (grow_size == 0)
+    return;
+  height = HiWord (grow_size);
+  width = LoWord (grow_size);
+#endif
+
+  if (width != FRAME_PIXEL_WIDTH (f)
+      || height != FRAME_PIXEL_HEIGHT (f))
     {
-      rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, HiWord (grow_size));
-      columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, LoWord (grow_size));
+      rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
+      columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
 
       x_set_window_size (f, 0, columns, rows);
     }
@@ -7400,41 +7656,44 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out)
   GrafPtr save_port;
   Rect zoom_rect, port_rect;
   Point top_left;
-  int w_title_height, columns, rows, width, height, dummy, x, y;
+  int w_title_height, columns, rows, width, height;
   struct frame *f = mac_window_to_frame (w);
+  struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
 
-  GetPort (&save_port);
-
-  SetPortWindowPort (w);
-
-  /* Clear window to avoid flicker.  */
 #if TARGET_API_MAC_CARBON
   {
-    Rect r;
-    BitMap bm;
+    Point standard_size;
 
-    GetWindowPortBounds (w, &r);
-    EraseRect (&r);
+    standard_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
+    standard_size.v = dpyinfo->height;
 
-    if (zoom_in_or_out == inZoomOut)
+    if (IsWindowInStandardState (w, &standard_size, &zoom_rect))
+      zoom_in_or_out = inZoomIn;
+    else
       {
-        /* calculate height of window's title bar (hard card it for now).  */
-        w_title_height = 20 + GetMBarHeight ();
-
-        /* get maximum height of window into zoom_rect.bottom -
-          zoom_rect.top */
-        GetQDGlobalsScreenBits (&bm);
-        zoom_rect = bm.bounds;
-        zoom_rect.top += w_title_height;
-        InsetRect (&zoom_rect, 8, 4);  /* not too tight */
-
-        zoom_rect.right = zoom_rect.left
-         + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
-
-        SetWindowStandardState (w, &zoom_rect);
+       /* Adjust the standard size according to character boundaries.  */
+
+       columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, zoom_rect.right - zoom_rect.left);
+       rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, zoom_rect.bottom - zoom_rect.top);
+       standard_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, columns);
+       standard_size.v = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
+       GetWindowBounds (w, kWindowContentRgn, &port_rect);
+       if (IsWindowInStandardState (w, &standard_size, &zoom_rect)
+           && port_rect.left == zoom_rect.left
+           && port_rect.top == zoom_rect.top)
+         zoom_in_or_out = inZoomIn;
+       else
+         zoom_in_or_out = inZoomOut;
       }
+
+    ZoomWindowIdeal (w, zoom_in_or_out, &standard_size);
   }
 #else /* not TARGET_API_MAC_CARBON */
+  GetPort (&save_port);
+
+  SetPortWindowPort (w);
+
+  /* Clear window to avoid flicker.  */
   EraseRect (&(w->portRect));
   if (zoom_in_or_out == inZoomOut)
     {
@@ -7453,12 +7712,19 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out)
       zoom_rect.right = zoom_rect.left
        + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
 
+      /* Adjust the standard size according to character boundaries.  */
+      rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, zoom_rect.bottom - zoom_rect.top);
+      zoom_rect.bottom =
+       zoom_rect.top + FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
+
       (**((WStateDataHandle) ((WindowPeek) w)->dataHandle)).stdState
        = zoom_rect;
     }
-#endif /* not TARGET_API_MAC_CARBON */
 
-  ZoomWindow (w, zoom_in_or_out, w == mac_front_window ());
+  ZoomWindow (w, zoom_in_or_out, f == mac_focus_frame (dpyinfo));
+
+  SetPort (save_port);
+#endif /* not TARGET_API_MAC_CARBON */
 
   /* retrieve window size and update application values */
 #if TARGET_API_MAC_CARBON
@@ -7466,19 +7732,23 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out)
 #else
   port_rect = w->portRect;
 #endif
-  rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, port_rect.bottom - port_rect.top);
-  columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, port_rect.right - port_rect.left);
-  x_set_window_size (f, 0, columns, rows);
+  height = port_rect.bottom - port_rect.top;
+  width = port_rect.right - port_rect.left;
 
-  SetPort (save_port);
-}
+  if (width != FRAME_PIXEL_WIDTH (f)
+      || height != FRAME_PIXEL_HEIGHT (f))
+    {
+      rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
+      columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
 
-/* Initialize Drag And Drop to allow files to be dropped onto emacs frames */
-static OSErr
-init_mac_drag_n_drop ()
-{
-  OSErr result = InstallReceiveHandler (mac_do_receive_drag, 0L, NULL);
-  return result;
+      change_frame_size (f, rows, columns, 0, 1, 0);
+      SET_FRAME_GARBAGED (f);
+      cancel_mouse_face (f);
+
+      FRAME_PIXEL_WIDTH (f) = width;
+      FRAME_PIXEL_HEIGHT (f) = height;
+    }
+  x_real_positions (f, &f->left_pos, &f->top_pos);
 }
 
 /* Intialize AppleEvent dispatcher table for the required events.  */
@@ -7554,7 +7824,7 @@ init_required_apple_events ()
 }
 
 #if USE_CARBON_EVENTS
-
+#ifdef MAC_OSX
 void
 init_service_handler ()
 {
@@ -7652,6 +7922,124 @@ mac_handle_service_event (EventHandlerCallRef callRef,
 }
 #endif
 
+static pascal OSStatus
+mac_handle_window_event (next_handler, event, data)
+     EventHandlerCallRef next_handler;
+     EventRef event;
+     void *data;
+{
+  WindowPtr wp;
+  OSStatus result;
+  UInt32 attributes;
+  XSizeHints *size_hints;
+
+  GetEventParameter (event, kEventParamDirectObject, typeWindowRef,
+                    NULL, sizeof (WindowPtr), NULL, &wp);
+
+  switch (GetEventKind (event))
+    {
+    case kEventWindowUpdate:
+      result = CallNextEventHandler (next_handler, event);
+      if (result != eventNotHandledErr)
+       return result;
+
+      do_window_update (wp);
+      break;
+
+    case kEventWindowBoundsChanging:
+      result = CallNextEventHandler (next_handler, event);
+      if (result != eventNotHandledErr)
+       return result;
+
+      GetEventParameter (event, kEventParamAttributes, typeUInt32,
+                        NULL, sizeof (UInt32), NULL, &attributes);
+      size_hints = FRAME_SIZE_HINTS (mac_window_to_frame (wp));
+      if ((attributes & kWindowBoundsChangeUserResize)
+         && ((size_hints->flags & (PResizeInc | PBaseSize | PMinSize))
+             == (PResizeInc | PBaseSize | PMinSize)))
+       {
+         Rect bounds;
+         int width, height;
+
+         GetEventParameter (event, kEventParamCurrentBounds,
+                            typeQDRectangle,
+                            NULL, sizeof (Rect), NULL, &bounds);
+         width = bounds.right - bounds.left;
+         height = bounds.bottom - bounds.top;
+
+         if (width < size_hints->min_width)
+           width = size_hints->min_width;
+         else
+           width = size_hints->base_width
+             + (int) ((width - size_hints->base_width)
+                      / (float) size_hints->width_inc + .5)
+             * size_hints->width_inc;
+
+         if (height < size_hints->min_height)
+           height = size_hints->min_height;
+         else
+           height = size_hints->base_height
+             + (int) ((height - size_hints->base_height)
+                      / (float) size_hints->height_inc + .5)
+             * size_hints->height_inc;
+
+         bounds.right = bounds.left + width;
+         bounds.bottom = bounds.top + height;
+         SetEventParameter (event, kEventParamCurrentBounds,
+                            typeQDRectangle, sizeof (Rect), &bounds);
+         return noErr;
+       }
+      break;
+    }
+
+  return eventNotHandledErr;
+}
+#endif /* USE_CARBON_EVENTS */
+
+
+OSErr
+install_window_handler (window)
+     WindowPtr window;
+{
+  OSErr err = noErr;
+#if USE_CARBON_EVENTS
+  EventTypeSpec specs[] = {{kEventClassWindow, kEventWindowUpdate},
+                          {kEventClassWindow, kEventWindowBoundsChanging}};
+  static EventHandlerUPP handle_window_event_UPP = NULL;
+
+  if (handle_window_event_UPP == NULL)
+    handle_window_event_UPP = NewEventHandlerUPP (mac_handle_window_event);
+
+  err = InstallWindowEventHandler (window, handle_window_event_UPP,
+                                  GetEventTypeCount (specs), specs,
+                                  NULL, NULL);
+#endif
+#if TARGET_API_MAC_CARBON
+  if (mac_do_track_dragUPP == NULL)
+    mac_do_track_dragUPP = NewDragTrackingHandlerUPP (mac_do_track_drag);
+  if (mac_do_receive_dragUPP == NULL)
+    mac_do_receive_dragUPP = NewDragReceiveHandlerUPP (mac_do_receive_drag);
+
+  if (err == noErr)
+    err = InstallTrackingHandler (mac_do_track_dragUPP, window, NULL);
+  if (err == noErr)
+    err = InstallReceiveHandler (mac_do_receive_dragUPP, window, NULL);
+#endif
+  return err;
+}
+
+void
+remove_window_handler (window)
+     WindowPtr window;
+{
+#if TARGET_API_MAC_CARBON
+  if (mac_do_track_dragUPP)
+    RemoveTrackingHandler (mac_do_track_dragUPP, window);
+  if (mac_do_receive_dragUPP)
+    RemoveReceiveHandler (mac_do_receive_dragUPP, window);
+#endif
+}
+
 /* Open Application Apple Event */
 static pascal OSErr
 do_ae_open_application(const AppleEvent *pae, AppleEvent *preply, long prefcon)
@@ -7668,6 +8056,17 @@ path_from_vol_dir_name (char *, int, short, long, char *);
 /* Called when we receive an AppleEvent with an ID of
    "kAEOpenDocuments".  This routine gets the direct parameter,
    extracts the FSSpecs in it, and puts their names on a list.  */
+#pragma options align=mac68k
+typedef struct SelectionRange {
+  short unused1; // 0 (not used)
+  short lineNum; // line to select (<0 to specify range)
+  long startRange; // start of selection range (if line < 0)
+  long endRange; // end of selection range (if line < 0)
+  long unused2; // 0 (not used)
+  long theDate; // modification date/time
+} SelectionRange;
+#pragma options align=reset
+
 static pascal OSErr
 do_ae_open_documents(AppleEvent *message, AppleEvent *reply, long refcon)
 {
@@ -7676,11 +8075,19 @@ do_ae_open_documents(AppleEvent *message, AppleEvent *reply, long refcon)
   AEKeyword keyword;
   DescType actual_type;
   Size actual_size;
+  SelectionRange position;
 
   err = AEGetParamDesc (message, keyDirectObject, typeAEList, &the_desc);
   if (err != noErr)
     goto descriptor_error_exit;
 
+  err = AEGetParamPtr (message, keyAEPosition, typeChar, &actual_type, &position, sizeof(SelectionRange), &actual_size);
+  if (err == noErr)
+    drag_and_drop_file_list = Fcons (list3 (make_number (position.lineNum + 1),
+                                           make_number (position.startRange + 1),
+                                           make_number (position.endRange + 1)),
+                                    drag_and_drop_file_list);
+
   /* Check to see that we got all of the required parameters from the
      event descriptor.  For an 'odoc' event this should just be the
      file list.  */
@@ -7708,30 +8115,35 @@ do_ae_open_documents(AppleEvent *message, AppleEvent *reply, long refcon)
         int i;
 
         /* AE file list is one based so just use that for indexing here.  */
-        for (i = 1; (err == noErr) && (i <= num_files_to_open); i++)
+        for (i = 1; i <= num_files_to_open; i++)
          {
-           FSSpec fs;
-           Str255 path_name, unix_path_name;
+           char unix_path_name[MAXPATHLEN];
 #ifdef MAC_OSX
            FSRef fref;
-#endif
+
+           err = AEGetNthPtr (&the_desc, i, typeFSRef, &keyword,
+                              &actual_type, &fref, sizeof (FSRef),
+                              &actual_size);
+           if (err != noErr || actual_type != typeFSRef)
+             continue;
+
+           if (FSRefMakePath (&fref, unix_path_name, sizeof (unix_path_name))
+               == noErr)
+#else
+           FSSpec fs;
 
            err = AEGetNthPtr(&the_desc, i, typeFSS, &keyword, &actual_type,
                              (Ptr) &fs, sizeof (fs), &actual_size);
-           if (err != noErr) break;
+           if (err != noErr) continue;
 
-#ifdef MAC_OSX
-           err = FSpMakeFSRef (&fs, &fref);
-           if (err != noErr) break;
-
-           if (FSRefMakePath (&fref, unix_path_name, 255) == noErr)
-#else
-           if (path_from_vol_dir_name (path_name, 255, fs.vRefNum, fs.parID,
-                                       fs.name) &&
-               mac_to_posix_pathname (path_name, unix_path_name, 255))
+           if (fsspec_to_posix_pathname (&fs, unix_path_name,
+                                         sizeof (unix_path_name) - 1) == noErr)
 #endif
-             drag_and_drop_file_list = Fcons (build_string (unix_path_name),
-                                              drag_and_drop_file_list);
+             /* x-dnd functions expect undecoded filenames.  */
+             drag_and_drop_file_list =
+               Fcons (make_unibyte_string (unix_path_name,
+                                           strlen (unix_path_name)),
+                      drag_and_drop_file_list);
          }
       }
   }
@@ -7746,6 +8158,74 @@ descriptor_error_exit:
 }
 
 
+#if TARGET_API_MAC_CARBON
+static pascal OSErr
+mac_do_track_drag (DragTrackingMessage message, WindowPtr window,
+                  void *handlerRefCon, DragReference theDrag)
+{
+  static int can_accept;
+  short items;
+  short index;
+  ItemReference theItem;
+  FlavorFlags theFlags;
+  OSErr result;
+
+  if (GetFrontWindowOfClass (kMovableModalWindowClass, false))
+    return dragNotAcceptedErr;
+
+  switch (message)
+    {
+    case kDragTrackingEnterHandler:
+      CountDragItems (theDrag, &items);
+      can_accept = 0;
+      for (index = 1; index <= items; index++)
+       {
+         GetDragItemReferenceNumber (theDrag, index, &theItem);
+         result = GetFlavorFlags (theDrag, theItem, flavorTypeHFS, &theFlags);
+         if (result == noErr)
+           {
+             can_accept = 1;
+             break;
+           }
+       }
+      break;
+
+    case kDragTrackingEnterWindow:
+      if (can_accept)
+       {
+         RgnHandle hilite_rgn = NewRgn ();
+         Rect r;
+         struct frame *f = mac_window_to_frame (window);
+
+         GetWindowPortBounds (window, &r);
+         OffsetRect (&r, -r.left, -r.top);
+         RectRgn (hilite_rgn, &r);
+         ShowDragHilite (theDrag, hilite_rgn, true);
+         DisposeRgn (hilite_rgn);
+         SetThemeCursor (kThemeCopyArrowCursor);
+       }
+      break;
+
+    case kDragTrackingInWindow:
+      break;
+
+    case kDragTrackingLeaveWindow:
+      if (can_accept)
+       {
+         struct frame *f = mac_window_to_frame (window);
+
+         HideDragHilite (theDrag);
+         SetThemeCursor (kThemeArrowCursor);
+       }
+      break;
+
+    case kDragTrackingLeaveHandler:
+      break;
+    }
+
+  return noErr;
+}
+
 static pascal OSErr
 mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
                     DragReference theDrag)
@@ -7757,9 +8237,11 @@ mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
   OSErr result;
   ItemReference theItem;
   HFSFlavor data;
-  FSRef fref;
   Size size = sizeof (HFSFlavor);
 
+  if (GetFrontWindowOfClass (kMovableModalWindowClass, false))
+    return dragNotAcceptedErr;
+
   drag_and_drop_file_list = Qnil;
   GetDragMouse (theDrag, &mouse, 0L);
   CountDragItems (theDrag, &items);
@@ -7771,11 +8253,10 @@ mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
       if (result == noErr)
        {
 #ifdef MAC_OSX
-         FSRef frref;
-#else
-         Str255 path_name;
+         FSRef fref;
 #endif
-         Str255 unix_path_name;
+         char unix_path_name[MAXPATHLEN];
+
          GetFlavorData (theDrag, theItem, flavorTypeHFS, &data, &size, 0L);
 #ifdef MAC_OSX
          /* Use Carbon routines, otherwise it converts the file name
@@ -7783,15 +8264,15 @@ mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
          FSpMakeFSRef (&data.fileSpec, &fref);
          if (! FSRefMakePath (&fref, unix_path_name, sizeof (unix_path_name)));
 #else
-         if (path_from_vol_dir_name (path_name, 255, data.fileSpec.vRefNum,
-                                     data.fileSpec.parID, data.fileSpec.name) &&
-             mac_to_posix_pathname (path_name, unix_path_name, 255))
+         if (fsspec_to_posix_pathname (&data.fileSpec, unix_path_name,
+                                       sizeof (unix_path_name) - 1) == noErr)
 #endif
-            drag_and_drop_file_list = Fcons (build_string (unix_path_name),
-                                            drag_and_drop_file_list);
+           /* x-dnd functions expect undecoded filenames.  */
+            drag_and_drop_file_list =
+             Fcons (make_unibyte_string (unix_path_name,
+                                         strlen (unix_path_name)),
+                    drag_and_drop_file_list);
        }
-      else
-       return;
     }
   /* If there are items in the list, construct an event and post it to
      the queue like an interrupt using kbd_buffer_store_event.  */
@@ -7800,12 +8281,14 @@ mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
       struct input_event event;
       Lisp_Object frame;
       struct frame *f = mac_window_to_frame (window);
-      SetPortWindowPort (window);
+      SInt16 modifiers;
+
       GlobalToLocal (&mouse);
+      GetDragModifiers (theDrag, NULL, NULL, &modifiers);
 
       event.kind = DRAG_N_DROP_EVENT;
       event.code = 0;
-      event.modifiers = 0;
+      event.modifiers = mac_to_emacs_modifiers (modifiers);
       event.timestamp = TickCount () * (1000 / 60);
       XSETINT (event.x, mouse.h);
       XSETINT (event.y, mouse.v);
@@ -7820,8 +8303,13 @@ mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
        GetCurrentProcess (&psn);
        SetFrontProcess (&psn);
       }
+
+      return noErr;
     }
+  else
+    return dragNotAcceptedErr;
 }
+#endif
 
 
 /* Print Document Apple Event */
@@ -7874,7 +8362,7 @@ profiler_exit_proc ()
    hints and prompts in the minibuffer after the user stops typing for
    a wait, etc.  */
 
-#if !TARGET_API_MAC_CARBON
+#ifdef MAC_OS8
 #undef main
 int
 main (void)
@@ -7932,19 +8420,23 @@ main (void)
 #endif
 
 /* Table for translating Mac keycode to X keysym values.  Contributed
-   by Sudhir Shenoy.  */
+   by Sudhir Shenoy.
+   Mapping for special keys is now identical to that in Apple X11
+   except `clear' (-> <clear>) on the KeyPad, `enter' (-> <kp-enter>)
+   on the right of the Cmd key on laptops, and fn + `enter' (->
+   <linefeed>). */
 static unsigned char keycode_to_xkeysym_table[] = {
   /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 
   /*0x30*/ 0x09 /*tab*/, 0 /*0x0020 space*/, 0, 0x08 /*backspace*/,
-  /*0x34*/ 0, 0x1b /*escape*/, 0, 0,
+  /*0x34*/ 0x8d /*enter on laptops*/, 0x1b /*escape*/, 0, 0,
   /*0x38*/ 0, 0, 0, 0,
   /*0x3C*/ 0, 0, 0, 0,
 
   /*0x40*/ 0, 0xae /*kp-.*/, 0, 0xaa /*kp-**/,
-  /*0x44*/ 0, 0xab /*kp-+*/, 0, 0x7f /*kp-clear*/,
+  /*0x44*/ 0, 0xab /*kp-+*/, 0, 0x0b /*clear*/,
   /*0x48*/ 0, 0, 0, 0xaf /*kp-/*/,
   /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp--*/, 0,
 
@@ -7956,11 +8448,11 @@ static unsigned char keycode_to_xkeysym_table[] = {
   /*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
   /*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
   /*0x68*/ 0, 0xca /*f13*/, 0, 0xcb /*f14*/,
-  /*0x6C*/ 0, 0xc7 /*f10*/, 0, 0xc9 /*f12*/,
+  /*0x6C*/ 0, 0xc7 /*f10*/, 0x0a /*fn+enter on laptops*/, 0xc9 /*f12*/,
 
-  /*0x70*/ 0, 0xcc /*f15*/, 0x9e /*insert (or 0x6a==help)*/, 0x95 /*home*/,
-  /*0x74*/ 0x9a /*pgup*/, 0x9f /*delete*/, 0xc1 /*f4*/, 0x9c /*end*/,
-  /*0x78*/ 0xbf /*f2*/, 0x9b /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
+  /*0x70*/ 0, 0xcc /*f15*/, 0x6a /*help*/, 0x50 /*home*/,
+  /*0x74*/ 0x55 /*pgup*/, 0xff /*delete*/, 0xc1 /*f4*/, 0x57 /*end*/,
+  /*0x78*/ 0xbf /*f2*/, 0x56 /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
   /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
 };
 
@@ -7971,6 +8463,45 @@ keycode_to_xkeysym (int keyCode, int *xKeySym)
   return *xKeySym != 0;
 }
 
+#if !USE_CARBON_EVENTS
+static RgnHandle mouse_region = NULL;
+
+Boolean
+mac_wait_next_event (er, sleep_time, dequeue)
+     EventRecord *er;
+     UInt32 sleep_time;
+     Boolean dequeue;
+{
+  static EventRecord er_buf = {nullEvent};
+  UInt32 target_tick, current_tick;
+  EventMask event_mask;
+
+  if (mouse_region == NULL)
+    mouse_region = NewRgn ();
+
+  event_mask = everyEvent;
+  if (NILP (Fboundp (Qmac_ready_for_drag_n_drop)))
+    event_mask -= highLevelEventMask;
+
+  current_tick = TickCount ();
+  target_tick = current_tick + sleep_time;
+
+  if (er_buf.what == nullEvent)
+    while (!WaitNextEvent (event_mask, &er_buf,
+                          target_tick - current_tick, mouse_region))
+      {
+       current_tick = TickCount ();
+       if (target_tick <= current_tick)
+         return false;
+      }
+
+  *er = er_buf;
+  if (dequeue)
+    er_buf.what = nullEvent;
+  return true;
+}
+#endif /* not USE_CARBON_EVENTS */
+
 /* Emacs calls this whenever it wants to read an input event from the
    user. */
 int
@@ -7982,9 +8513,7 @@ XTread_socket (sd, expected, hold_quit)
   int count = 0;
 #if USE_CARBON_EVENTS
   EventRef eventRef;
-  EventTargetRef toolbox_dispatcher = GetEventDispatcherTarget ();
-#else
-  EventMask event_mask;
+  EventTargetRef toolbox_dispatcher;
 #endif
   EventRecord er;
   struct mac_display_info *dpyinfo = &one_mac_display_info;
@@ -8015,24 +8544,18 @@ XTread_socket (sd, expected, hold_quit)
   if (terminate_flag)
     Fkill_emacs (make_number (1));
 
-#if !USE_CARBON_EVENTS
-  event_mask = everyEvent;
-  if (NILP (Fboundp (Qmac_ready_for_drag_n_drop)))
-    event_mask -= highLevelEventMask;
+#if USE_CARBON_EVENTS
+  toolbox_dispatcher = GetEventDispatcherTarget ();
 
-  while (WaitNextEvent (event_mask, &er,
-                       (expected ? app_sleep_time : 0L), NULL))
-#else
-  while (!ReceiveNextEvent (0, NULL,
-                           (expected ? TicksToEventTime (app_sleep_time) : 0),
+  while (!ReceiveNextEvent (0, NULL, kEventDurationNoWait,
                            kEventRemoveFromQueue, &eventRef))
+#else /* !USE_CARBON_EVENTS */
+  while (mac_wait_next_event (&er, 0, true))
 #endif /* !USE_CARBON_EVENTS */
     {
       int do_help = 0;
       struct frame *f;
 
-      expected = 0;
-
       /* It is necessary to set this (additional) argument slot of an
         event to nil because keyboard.c protects incompletely
         processed event from being garbage collected by placing them
@@ -8047,7 +8570,7 @@ XTread_socket (sd, expected, hold_quit)
        switch (GetEventClass (eventRef))
          {
          case kEventClassWindow:
-           if (GetEventKind (eventRef) == kEventWindowBoundsChanged) 
+           if (GetEventKind (eventRef) == kEventWindowBoundsChanged)
              {
                WindowPtr window_ptr;
                GetEventParameter(eventRef, kEventParamDirectObject,
@@ -8055,13 +8578,7 @@ XTread_socket (sd, expected, hold_quit)
                                  NULL, &window_ptr);
                f = mac_window_to_frame (window_ptr);
                if (f && !f->async_iconified)
-                 {
-                   int x, y;
-                   
-                   x_real_positions (f, &x, &y);
-                   f->left_pos = x;
-                   f->top_pos = y;
-                 }
+                 x_real_positions (f, &f->left_pos, &f->top_pos);
                SendEventToEventTarget (eventRef, toolbox_dispatcher);
              }
            break;
@@ -8070,10 +8587,13 @@ XTread_socket (sd, expected, hold_quit)
              {
                SInt32 delta;
                Point point;
-               WindowPtr window_ptr = mac_front_window ();
+               struct frame *f = mac_focus_frame (dpyinfo);
+               WindowPtr window_ptr;
 
-               if (!IsValidWindowPtr (window_ptr))
+               if (!f)
                  {
+                   /* Beep if wheel move occurs when all the frames
+                      are invisible.  */
                    SysBeep(1);
                    break;
                  }
@@ -8089,6 +8609,7 @@ XTread_socket (sd, expected, hold_quit)
                inev.modifiers = (mac_event_to_emacs_modifiers (eventRef)
                                  | ((delta < 0) ? down_modifier
                                     : up_modifier));
+               window_ptr = FRAME_MAC_WINDOW (f);
                SetPortWindowPort (window_ptr);
                GlobalToLocal (&point);
                XSETINT (inev.x, point.h);
@@ -8101,6 +8622,7 @@ XTread_socket (sd, expected, hold_quit)
              SendEventToEventTarget (eventRef, toolbox_dispatcher);
 
            break;
+
          default:
            /* Send the event to the appropriate receiver.  */
            SendEventToEventTarget (eventRef, toolbox_dispatcher);
@@ -8132,33 +8654,28 @@ XTread_socket (sd, expected, hold_quit)
              }
            else
              {
-               window_ptr = FrontWindow ();
+               part_code = FindWindow (er.where, &window_ptr);
                if (tip_window && window_ptr == tip_window)
                  {
                    HideWindow (tip_window);
-                   window_ptr = FrontWindow ();
+                   part_code = FindWindow (er.where, &window_ptr);
                  }
-
-               if (!is_emacs_window (window_ptr))
-                 break;
-
-               part_code = FindWindow (er.where, &window_ptr);
              }
 
+           if (er.what != mouseDown && part_code != inContent)
+             break;
+
            switch (part_code)
              {
              case inMenuBar:
-               if (er.what == mouseDown)
-                 {
-                   f = mac_window_to_frame (mac_front_window ());
-                   saved_menu_event_location = er.where;
-                   inev.kind = MENU_BAR_ACTIVATE_EVENT;
-                   XSETFRAME (inev.frame_or_window, f);
-                 }
+               f = mac_focus_frame (dpyinfo);
+               saved_menu_event_location = er.where;
+               inev.kind = MENU_BAR_ACTIVATE_EVENT;
+               XSETFRAME (inev.frame_or_window, f);
                break;
 
              case inContent:
-               if (window_ptr != mac_front_window ())
+               if (window_ptr != FRAME_MAC_WINDOW (mac_focus_frame (dpyinfo)))
                  SelectWindow (window_ptr);
                else
                  {
@@ -8192,12 +8709,9 @@ XTread_socket (sd, expected, hold_quit)
                    /* ticks to milliseconds */
 
                    if (dpyinfo->grabbed && tracked_scroll_bar
-#if TARGET_API_MAC_CARBON
-                       || ch != 0
-#else
-                       || control_part_code != 0
-#endif
-                       )
+                       /* control_part_code becomes kControlNoPart if
+                          a progress indicator is clicked.  */
+                       || ch != 0 && control_part_code != kControlNoPart)
                      {
                        struct scroll_bar *bar;
 
@@ -8255,7 +8769,7 @@ XTread_socket (sd, expected, hold_quit)
                      }
                    else
                      {
-                       if (dpyinfo->grabbed & (1 << inev.code) == 0)
+                       if ((dpyinfo->grabbed & (1 << inev.code)) == 0)
                          /* If a button is released though it was not
                             previously pressed, that would be because
                             of multi-button emulation.  */
@@ -8278,27 +8792,16 @@ XTread_socket (sd, expected, hold_quit)
 
              case inDrag:
 #if TARGET_API_MAC_CARBON
-               if (er.what == mouseDown)
-                 {
-                   BitMap bm;
-
-                   GetQDGlobalsScreenBits (&bm);
-                   DragWindow (window_ptr, er.where, &bm.bounds);
-                 }
+               DragWindow (window_ptr, er.where, NULL);
 #else /* not TARGET_API_MAC_CARBON */
                DragWindow (window_ptr, er.where, &qd.screenBits.bounds);
 #endif /* not TARGET_API_MAC_CARBON */
                /* Update the frame parameters.  */
                {
                  struct frame *f = mac_window_to_frame (window_ptr);
+
                  if (f && !f->async_iconified)
-                   {
-                     int x, y;
-                     
-                     x_real_positions (f, &x, &y);
-                     f->left_pos = x;
-                     f->top_pos = y;
-                   }
+                   x_real_positions (f, &f->left_pos, &f->top_pos);
                }
                break;
 
@@ -8313,11 +8816,8 @@ XTread_socket (sd, expected, hold_quit)
 
                /* window resize handling added --ben */
              case inGrow:
-               if (er.what == mouseDown)
-                 {
-                   do_grow_window(window_ptr, &er);
-                   break;
-                 }
+               do_grow_window (window_ptr, &er);
+               break;
 
                /* window zoom handling added --ben */
              case inZoomIn:
@@ -8337,8 +8837,9 @@ XTread_socket (sd, expected, hold_quit)
          if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
              != eventNotHandledErr)
            break;
-#endif
+#else
          do_window_update ((WindowPtr) er.message);
+#endif
          break;
 
        case osEvt:
@@ -8357,11 +8858,69 @@ XTread_socket (sd, expected, hold_quit)
              break;
 
            case mouseMovedMessage:
+#if !USE_CARBON_EVENTS
+             SetRectRgn (mouse_region, er.where.h, er.where.v,
+                         er.where.h + 1, er.where.v + 1);
+#endif
              previous_help_echo_string = help_echo_string;
              help_echo_string = help_echo_object = help_echo_window = Qnil;
              help_echo_pos = -1;
 
-             do_mouse_moved (er.where, &f);
+             if (dpyinfo->grabbed && last_mouse_frame
+                 && FRAME_LIVE_P (last_mouse_frame))
+               f = last_mouse_frame;
+             else
+               f = dpyinfo->x_focus_frame;
+
+             if (dpyinfo->mouse_face_hidden)
+               {
+                 dpyinfo->mouse_face_hidden = 0;
+                 clear_mouse_face (dpyinfo);
+               }
+
+             if (f)
+               {
+                 WindowPtr wp = FRAME_MAC_WINDOW (f);
+                 Point mouse_pos = er.where;
+
+                 SetPortWindowPort (wp);
+
+                 GlobalToLocal (&mouse_pos);
+
+                 if (dpyinfo->grabbed && tracked_scroll_bar)
+                   x_scroll_bar_note_movement (tracked_scroll_bar,
+                                               mouse_pos.v
+                                               - XINT (tracked_scroll_bar->top),
+                                               TickCount() * (1000 / 60));
+                 else
+                   {
+                     /* Generate SELECT_WINDOW_EVENTs when needed.  */
+                     if (mouse_autoselect_window)
+                       {
+                         Lisp_Object window;
+
+                         window = window_from_coordinates (f,
+                                                           mouse_pos.h,
+                                                           mouse_pos.v,
+                                                           0, 0, 0, 0);
+
+                         /* Window will be selected only when it is
+                            not selected now and last mouse movement
+                            event was not in it.  Minibuffer window
+                            will be selected iff it is active.  */
+                         if (WINDOWP (window)
+                             && !EQ (window, last_window)
+                             && !EQ (window, selected_window))
+                           {
+                             inev.kind = SELECT_WINDOW_EVENT;
+                             inev.frame_or_window = window;
+                           }
+
+                         last_window=window;
+                       }
+                     note_mouse_movement (f, &mouse_pos);
+                   }
+               }
 
              /* If the contents of the global variable
                 help_echo_string has changed, generate a
@@ -8389,16 +8948,13 @@ XTread_socket (sd, expected, hold_quit)
 
            if (!is_emacs_window (window_ptr))
              break;
-           
-           f = mac_window_to_frame (window_ptr);
 
            if ((er.modifiers & activeFlag) != 0)
              {
                /* A window has been activated */
                Point mouse_loc = er.where;
 
-               x_new_focus_frame (dpyinfo, f);
-               activate_scroll_bars (f);
+               x_detect_focus_change (dpyinfo, &er, &inev);
 
                SetPortWindowPort (window_ptr);
                GlobalToLocal (&mouse_loc);
@@ -8412,13 +8968,9 @@ XTread_socket (sd, expected, hold_quit)
                /* A window has been deactivated */
                dpyinfo->grabbed = 0;
 
-               if (f == dpyinfo->x_focus_frame)
-                 {
-                   x_new_focus_frame (dpyinfo, 0);
-                   deactivate_scroll_bars (f);
-                 }
-
+               x_detect_focus_change (dpyinfo, &er, &inev);
 
+               f = mac_window_to_frame (window_ptr);
                if (f == dpyinfo->mouse_face_mouse_frame)
                  {
                    /* If we move outside the frame, then we're
@@ -8444,7 +8996,7 @@ XTread_socket (sd, expected, hold_quit)
            int keycode = (er.message & keyCodeMask) >> 8;
            int xkeysym;
 
-#if USE_CARBON_EVENTS
+#if USE_CARBON_EVENTS && defined (MAC_OSX)
            /* When using Carbon Events, we need to pass raw keyboard
               events to the TSM ourselves.  If TSM handles it, it
               will pass back noErr, otherwise it will pass back
@@ -8459,13 +9011,31 @@ XTread_socket (sd, expected, hold_quit)
                break;
 #endif
 
-#if TARGET_API_MAC_CARBON
-           if (!IsValidWindowPtr (mac_front_window ()))
+           if (dpyinfo->x_focus_frame == NULL)
              {
+               /* Beep if keyboard input occurs when all the frames
+                  are invisible.  */
                SysBeep (1);
                break;
              }
-#endif
+
+           {
+             static SInt16 last_key_script = -1;
+             SInt16 current_key_script = GetScriptManagerVariable (smKeyScript);
+
+             if (last_key_script != current_key_script)
+               {
+                 struct input_event event;
+
+                 EVENT_INIT (event);
+                 event.kind = LANGUAGE_CHANGE_EVENT;
+                 event.arg = Qnil;
+                 event.code = current_key_script;
+                 kbd_buffer_store_event (&event);
+                 count++;
+               }
+             last_key_script = current_key_script;
+           }
 
            ObscureCursor ();
 
@@ -8501,70 +9071,31 @@ XTread_socket (sd, expected, hold_quit)
                    inev.code = KeyTranslate (kchr_ptr, new_keycode,
                                              &some_state) & 0xff;
                  }
+               else if (!NILP (Vmac_option_modifier)
+                        && (er.modifiers & optionKey))
+                 {
+                   /* When using the option key as an emacs modifier,
+                      convert the pressed key code back to one
+                      without the Mac option modifier applied. */
+                   int new_modifiers = er.modifiers & ~optionKey;
+                   int new_keycode = keycode | new_modifiers;
+                   Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
+                   unsigned long some_state = 0;
+                   inev.code = KeyTranslate (kchr_ptr, new_keycode,
+                                             &some_state) & 0xff;
+                 }
                else
                  inev.code = er.message & charCodeMask;
                inev.kind = ASCII_KEYSTROKE_EVENT;
              }
          }
 
-         /* If variable mac-convert-keyboard-input-to-latin-1 is
-            non-nil, convert non-ASCII characters typed at the Mac
-            keyboard (presumed to be in the Mac Roman encoding) to
-            iso-latin-1 encoding before they are passed to Emacs.
-            This enables the Mac keyboard to be used to enter
-            non-ASCII iso-latin-1 characters directly.  */
-         if (mac_keyboard_text_encoding != kTextEncodingMacRoman
-             && inev.kind == ASCII_KEYSTROKE_EVENT && inev.code >= 128)
-           {
-             static TECObjectRef converter = NULL;
-             OSStatus the_err = noErr;
-             OSStatus convert_status = noErr;
-
-             if (converter ==  NULL)
-               {
-                 the_err = TECCreateConverter (&converter,
-                                               kTextEncodingMacRoman,
-                                               mac_keyboard_text_encoding);
-                 current_mac_keyboard_text_encoding
-                   = mac_keyboard_text_encoding;
-               }
-             else if (mac_keyboard_text_encoding
-                      != current_mac_keyboard_text_encoding)
-               {
-                 /* Free the converter for the current encoding
-                    before creating a new one.  */
-                 TECDisposeConverter (converter);
-                 the_err = TECCreateConverter (&converter,
-                                               kTextEncodingMacRoman,
-                                               mac_keyboard_text_encoding);
-                 current_mac_keyboard_text_encoding
-                   = mac_keyboard_text_encoding;
-               }
-
-             if (the_err == noErr)
-               {
-                 unsigned char ch = inev.code;
-                 ByteCount actual_input_length, actual_output_length;
-                 unsigned char outch;
-
-                 convert_status = TECConvertText (converter, &ch, 1,
-                                                  &actual_input_length,
-                                                  &outch, 1,
-                                                  &actual_output_length);
-                 if (convert_status == noErr
-                     && actual_input_length == 1
-                     && actual_output_length == 1)
-                   inev.code = outch;
-               }
-           }
-
 #if USE_CARBON_EVENTS
          inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
 #else
          inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
 #endif
-         XSETFRAME (inev.frame_or_window,
-                    mac_window_to_frame (mac_front_window ()));
+         XSETFRAME (inev.frame_or_window, mac_focus_frame (dpyinfo));
          inev.timestamp = er.when * (1000 / 60);  /* ticks to milliseconds */
          break;
 
@@ -8577,22 +9108,10 @@ XTread_socket (sd, expected, hold_quit)
             constuct_drag_n_drop in w32term.c.  */
          if (!NILP (drag_and_drop_file_list))
            {
-             struct frame *f = NULL;
+             struct frame *f = mac_focus_frame (dpyinfo);
              WindowPtr wp;
              Lisp_Object frame;
 
-             wp = mac_front_window ();
-
-             if (!wp)
-               {
-                 struct frame *f = XFRAME (XCAR (Vframe_list));
-                 CollapseWindow (FRAME_MAC_WINDOW (f), false);
-                 wp = mac_front_window ();
-               }
-
-             if (wp && is_emacs_window (wp))
-               f = mac_window_to_frame (wp);
-
              inev.kind = DRAG_N_DROP_EVENT;
              inev.code = 0;
              inev.timestamp = er.when * (1000 / 60);
@@ -8609,10 +9128,12 @@ XTread_socket (sd, expected, hold_quit)
              XSETFRAME (frame, f);
              inev.frame_or_window = Fcons (frame, drag_and_drop_file_list);
 
+#if 0
              /* Regardless of whether Emacs was suspended or in the
                 foreground, ask it to redraw its entire screen.
                 Otherwise parts of the screen can be left in an
                 inconsistent state.  */
+             wp = FRAME_MAC_WINDOW (f);
              if (wp)
 #if TARGET_API_MAC_CARBON
                {
@@ -8624,6 +9145,7 @@ XTread_socket (sd, expected, hold_quit)
 #else /* not TARGET_API_MAC_CARBON */
                 InvalRect (&(wp->portRect));
 #endif /* not TARGET_API_MAC_CARBON */
+#endif
            }
        default:
          break;
@@ -8700,59 +9222,12 @@ __convert_from_newlines (unsigned char * p, size_t * n)
 }
 #endif
 
-
-/* Initialize the struct pointed to by MW to represent a new COLS x
-   ROWS Macintosh window, using font with name FONTNAME and size
-   FONTSIZE.  */
-void
-make_mac_frame (FRAME_PTR fp)
-{
-  mac_output *mwp;
-#if TARGET_API_MAC_CARBON
-  static int making_terminal_window = 0;
-#else
-  static int making_terminal_window = 1;
-#endif
-
-  mwp = fp->output_data.mac;
-
-  if (making_terminal_window)
-    {
-      if (!(mwp->mWP = GetNewCWindow (TERM_WINDOW_RESOURCE, NULL,
-                                     (WindowPtr) -1)))
-        abort ();
-      making_terminal_window = 0;
-    }
-  else
-    {
-#if TARGET_API_MAC_CARBON
-      Rect r;
-
-      SetRect (&r, 0, 0, 1, 1);
-      if (CreateNewWindow (kDocumentWindowClass,
-                          kWindowStandardDocumentAttributes
-                          /* | kWindowToolbarButtonAttribute */,
-                          &r, &mwp->mWP) != noErr)
-#else
-      if (!(mwp->mWP = GetNewCWindow (WINDOW_RESOURCE, NULL, (WindowPtr) -1)))
-#endif
-       abort ();
-    }
-
-  SetWRefCon (mwp->mWP, (long) mwp);
-    /* so that update events can find this mac_output struct */
-  mwp->mFP = fp;  /* point back to emacs frame */
-
-  SetPortWindowPort (mwp->mWP);
-
-  SizeWindow (mwp->mWP, FRAME_PIXEL_WIDTH (fp), FRAME_PIXEL_HEIGHT (fp), false);
-}
-
-
+#ifdef MAC_OS8
 void
 make_mac_terminal_frame (struct frame *f)
 {
   Lisp_Object frame;
+  Rect r;
 
   XSETFRAME (frame, f);
 
@@ -8776,10 +9251,17 @@ make_mac_terminal_frame (struct frame *f)
   f->output_data.mac->mouse_pixel = 0xff00ff;
   f->output_data.mac->cursor_foreground_pixel = 0x0000ff;
 
+  f->output_data.mac->text_cursor = kThemeIBeamCursor;
+  f->output_data.mac->nontext_cursor = kThemeArrowCursor;
+  f->output_data.mac->modeline_cursor = kThemeArrowCursor;
+  f->output_data.mac->hand_cursor = kThemePointingHandCursor;
+  f->output_data.mac->hourglass_cursor = kThemeWatchCursor;
+  f->output_data.mac->horizontal_drag_cursor = kThemeResizeLeftRightCursor;
+
   FRAME_FONTSET (f) = -1;
   f->output_data.mac->explicit_parent = 0;
-  f->left_pos = 4;
-  f->top_pos = 4;
+  f->left_pos = 8;
+  f->top_pos = 32;
   f->border_width = 0;
 
   f->internal_border_width = 0;
@@ -8790,7 +9272,20 @@ make_mac_terminal_frame (struct frame *f)
   f->new_text_cols = 0;
   f->new_text_lines = 0;
 
-  make_mac_frame (f);
+  SetRect (&r, f->left_pos, f->top_pos,
+           f->left_pos + FRAME_PIXEL_WIDTH (f),
+           f->top_pos + FRAME_PIXEL_HEIGHT (f));
+
+  BLOCK_INPUT;
+
+  if (!(FRAME_MAC_WINDOW (f) =
+       NewCWindow (NULL, &r, "\p", true, dBoxProc,
+                   (WindowPtr) -1, 1, (long) f->output_data.mac)))
+    abort ();
+  /* so that update events can find this mac_output struct */
+  f->output_data.mac->mFP = f;  /* point back to emacs frame */
+
+  UNBLOCK_INPUT;
 
   x_make_gc (f);
 
@@ -8806,9 +9301,8 @@ make_mac_terminal_frame (struct frame *f)
   Fmodify_frame_parameters (frame,
                             Fcons (Fcons (Qbackground_color,
                                           build_string ("white")), Qnil));
-
-  ShowWindow (f->output_data.mac->mWP);
 }
+#endif
 
 \f
 /***********************************************************************
@@ -8825,12 +9319,7 @@ mac_initialize_display_info ()
 
   bzero (dpyinfo, sizeof (*dpyinfo));
 
-  /* Put it on x_display_name_list.  */
-  x_display_name_list = Fcons (Fcons (build_string ("Mac"), Qnil),
-                               x_display_name_list);
-  dpyinfo->name_list_element = XCAR (x_display_name_list);
-
-#if 0
+#ifdef MAC_OSX
   dpyinfo->mac_id_name
     = (char *) xmalloc (SCHARS (Vinvocation_name)
                        + SCHARS (Vsystem_name)
@@ -8885,6 +9374,20 @@ mac_initialize_display_info ()
   dpyinfo->mouse_face_hidden = 0;
 }
 
+
+static XrmDatabase
+mac_make_rdb (xrm_option)
+     char *xrm_option;
+{
+  XrmDatabase database;
+
+  database = xrm_get_preference_database (NULL);
+  if (xrm_option)
+    xrm_merge_string_database (database, xrm_option);
+
+  return database;
+}
+
 struct mac_display_info *
 mac_term_init (display_name, xrm_option, resource_name)
      Lisp_Object display_name;
@@ -8892,7 +9395,8 @@ mac_term_init (display_name, xrm_option, resource_name)
      char *resource_name;
 {
   struct mac_display_info *dpyinfo;
-  GDHandle main_device_handle;
+
+  BLOCK_INPUT;
 
   if (!mac_initialized)
     {
@@ -8900,17 +9404,91 @@ mac_term_init (display_name, xrm_option, resource_name)
       mac_initialized = 1;
     }
 
-  mac_initialize_display_info (display_name);
+  if (x_display_list)
+    error ("Sorry, this version can only handle one display");
+
+  mac_initialize_display_info ();
 
   dpyinfo = &one_mac_display_info;
 
-  main_device_handle = LMGetMainDevice();
+  dpyinfo->xrdb = mac_make_rdb (xrm_option);
 
-  dpyinfo->height = (**main_device_handle).gdRect.bottom;
-  dpyinfo->width = (**main_device_handle).gdRect.right;
+  /* Put this display on the chain.  */
+  dpyinfo->next = x_display_list;
+  x_display_list = dpyinfo;
+
+  /* Put it on x_display_name_list.  */
+  x_display_name_list = Fcons (Fcons (display_name,
+                                     Fcons (Qnil, dpyinfo->xrdb)),
+                               x_display_name_list);
+  dpyinfo->name_list_element = XCAR (x_display_name_list);
+
+  UNBLOCK_INPUT;
 
   return dpyinfo;
 }
+/* Get rid of display DPYINFO, assuming all frames are already gone.  */
+
+void
+x_delete_display (dpyinfo)
+     struct mac_display_info *dpyinfo;
+{
+  int i;
+
+  /* Discard this display from x_display_name_list and x_display_list.
+     We can't use Fdelq because that can quit.  */
+  if (! NILP (x_display_name_list)
+      && EQ (XCAR (x_display_name_list), dpyinfo->name_list_element))
+    x_display_name_list = XCDR (x_display_name_list);
+  else
+    {
+      Lisp_Object tail;
+
+      tail = x_display_name_list;
+      while (CONSP (tail) && CONSP (XCDR (tail)))
+       {
+         if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
+           {
+             XSETCDR (tail, XCDR (XCDR (tail)));
+             break;
+           }
+         tail = XCDR (tail);
+       }
+    }
+
+  if (x_display_list == dpyinfo)
+    x_display_list = dpyinfo->next;
+  else
+    {
+      struct x_display_info *tail;
+
+      for (tail = x_display_list; tail; tail = tail->next)
+       if (tail->next == dpyinfo)
+         tail->next = tail->next->next;
+    }
+
+  /* Free the font names in the font table.  */
+  for (i = 0; i < dpyinfo->n_fonts; i++)
+    if (dpyinfo->font_table[i].name)
+      {
+       if (dpyinfo->font_table[i].name != dpyinfo->font_table[i].full_name)
+         xfree (dpyinfo->font_table[i].full_name);
+       xfree (dpyinfo->font_table[i].name);
+      }
+
+  if (dpyinfo->font_table->font_encoder)
+    xfree (dpyinfo->font_table->font_encoder);
+
+  xfree (dpyinfo->font_table);
+  xfree (dpyinfo->mac_id_name);
+
+  if (x_display_list == 0)
+    {
+      mac_clear_font_name_table ();
+      bzero (dpyinfo, sizeof (*dpyinfo));
+    }
+}
+
 \f
 #ifdef MAC_OSX
 void
@@ -9047,7 +9625,7 @@ mac_check_for_quit_char ()
       e.arg = Qnil;
       e.modifiers = NULL;
       e.timestamp = EventTimeToTicks (GetEventTime (event)) * (1000/60);
-      XSETFRAME (e.frame_or_window, mac_window_to_frame (mac_front_window ()));
+      XSETFRAME (e.frame_or_window, mac_focus_frame (&one_mac_display_info));
       /* Remove event from queue to prevent looping. */
       RemoveEventFromQueue (GetMainEventQueue (), event);
       ReleaseEvent (event);
@@ -9074,7 +9652,7 @@ static struct redisplay_interface x_redisplay_interface =
   x_update_window_end,
   x_cursor_to,
   x_flush,
-  x_flush,
+  0, /* flush_display_optional */
   x_clear_window_mouse_face,
   x_get_glyph_overhangs,
   x_fix_overlapping_area,
@@ -9083,7 +9661,7 @@ static struct redisplay_interface x_redisplay_interface =
   0, /* destroy_fringe_bitmap */
   mac_per_char_metric,
   mac_encode_char,
-  NULL, /* mac_compute_glyph_string_overhangs */
+  mac_compute_glyph_string_overhangs,
   x_draw_glyph_string,
   mac_define_frame_cursor,
   mac_clear_frame_area,
@@ -9169,14 +9747,12 @@ mac_initialize ()
   signal (SIGPIPE, x_connection_signal);
 #endif
 
-  mac_initialize_display_info ();
+  BLOCK_INPUT;
 
 #if TARGET_API_MAC_CARBON
   init_required_apple_events ();
 
-  init_mac_drag_n_drop ();
-
-#if USE_CARBON_EVENTS
+#if USE_CARBON_EVENTS && defined (MAC_OSX)
   init_service_handler ();
 
   init_quit_char_handler ();
@@ -9184,9 +9760,12 @@ mac_initialize ()
 
   DisableMenuCommand (NULL, kHICommandQuit);
 
+#ifdef MAC_OSX
   if (!inhibit_window_system)
     MakeMeTheFrontProcess ();
 #endif
+#endif
+  UNBLOCK_INPUT;
 }
 
 
@@ -9198,7 +9777,17 @@ syms_of_macterm ()
   x_error_message_string = Qnil;
 #endif
 
+  Qmodifier_value = intern ("modifier-value");
+  Qalt = intern ("alt");
+  Fput (Qalt, Qmodifier_value, make_number (alt_modifier));
+  Qhyper = intern ("hyper");
+  Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier));
+  Qsuper = intern ("super");
+  Fput (Qsuper, Qmodifier_value, make_number (super_modifier));
+
+#ifdef MAC_OSX
   Fprovide (intern ("mac-carbon"), Qnil);
+#endif
 
   staticpro (&Qreverse);
   Qreverse = intern ("reverse");
@@ -9230,10 +9819,6 @@ syms_of_macterm ()
   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;
-
   DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
               doc: /* If not nil, Emacs uses toolkit scroll bars.  */);
   Vx_toolkit_scroll_bars = Qt;
@@ -9254,20 +9839,26 @@ to 4.1, set this to nil.  */);
 Otherwise the option key is used.  */);
   Vmac_command_key_is_meta = Qt;
 
+  DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier,
+    doc: /* Modifier to use for the Mac alt/option key.  The value can
+be alt, hyper, or super for the respective modifier.  If the value is
+nil then the key will act as the normal Mac option modifier.  */);
+  Vmac_option_modifier = Qnil;
+
   DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta,
     doc: /* Non-nil means that the control and meta keys are reversed.  This is
-           useful for non-standard keyboard layouts.  */);
+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. */);
+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
+no 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
@@ -9286,22 +9877,14 @@ Toolbox for processing before Emacs sees it.  */);
    doc: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
 Toolbox for processing before Emacs sees it.  */);
   Vmac_pass_control_to_system = Qt;
+
 #endif
 
-  DEFVAR_INT ("mac-keyboard-text-encoding", &mac_keyboard_text_encoding,
-    doc: /* One of the Text Encoding Base constant values defined in the
-Basic Text Constants section of Inside Macintosh - Text Encoding
-Conversion Manager.  Its value determines the encoding characters
-typed at the Mac keyboard (presumed to be in the MacRoman encoding)
-will convert into.  E.g., if it is set to kTextEncodingMacRoman (0),
-its default value, no conversion takes place.  If it is set to
-kTextEncodingISOLatin1 (0x201) or kTextEncodingISOLatin2 (0x202),
-characters typed on Mac keyboard are first converted into the
-ISO Latin-1 or ISO Latin-2 encoding, respectively before being
-passed to Emacs.  Together with Emacs's set-keyboard-coding-system
-command, this enables the Mac keyboard to be used to enter non-ASCII
-characters directly.  */);
-  mac_keyboard_text_encoding = kTextEncodingMacRoman;
+  DEFVAR_LISP ("mac-allow-anti-aliasing", &Vmac_use_core_graphics,
+   doc: /* If non-nil, allow anti-aliasing.
+The text will be rendered using Core Graphics text rendering which
+may anti-alias the text.  */);
+  Vmac_use_core_graphics = Qnil;
 }
 
 /* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b