Merge from emacs--devo--0
[bpt/emacs.git] / src / macterm.c
index b4b096f..4156000 100644 (file)
@@ -77,7 +77,6 @@ Boston, MA 02110-1301, USA.  */
 #include "termhooks.h"
 #include "termopts.h"
 #include "termchar.h"
-#include "gnu.h"
 #include "disptab.h"
 #include "buffer.h"
 #include "window.h"
@@ -199,6 +198,8 @@ static int input_signal_count;
 
 extern Lisp_Object Vsystem_name;
 
+extern Lisp_Object Qeql;
+
 /* A mask of extra modifier bits to put into every keyboard char.  */
 
 extern EMACS_INT extra_keyboard_modifiers;
@@ -217,7 +218,6 @@ QDGlobals qd;  /* QuickDraw global information structure.  */
 
 struct mac_display_info *mac_display_info_for_display (Display *);
 static void x_update_window_end P_ ((struct window *, int, int));
-static int x_io_error_quitter P_ ((Display *));
 int x_catch_errors P_ ((Display *));
 void x_uncatch_errors P_ ((Display *, int));
 void x_lower_frame P_ ((struct frame *));
@@ -393,16 +393,37 @@ mac_draw_line (f, gc, x1, y1, x2, y2)
 {
 #if USE_CG_DRAWING
   CGContextRef context;
+  float gx1 = x1, gy1 = y1, gx2 = x2, gy2 = y2;
+
+  if (y1 != y2)
+    gx1 += 0.5f, gx2 += 0.5f;
+  if (x1 != x2)
+    gy1 += 0.5f, gy2 += 0.5f;
 
   context = mac_begin_cg_clip (f, gc);
   CG_SET_STROKE_COLOR (context, gc->xgcv.foreground);
   CGContextBeginPath (context);
-  CGContextMoveToPoint (context, x1 + 0.5f, y1 + 0.5f);
-  CGContextAddLineToPoint (context, x2 + 0.5f, y2 + 0.5f);
+  CGContextMoveToPoint (context, gx1, gy1);
+  CGContextAddLineToPoint (context, gx2, gy2);
   CGContextClosePath (context);
   CGContextStrokePath (context);
   mac_end_cg_clip (f);
 #else
+  if (x1 == x2)
+    {
+      if (y1 > y2)
+       y1--;
+      else if (y2 > y1)
+       y2--;
+    }
+  else if (y1 == y2)
+    {
+      if (x1 > x2)
+       x1--;
+      else
+       x2--;
+    }
+
   SetPortWindowPort (FRAME_MAC_WINDOW (f));
 
   RGBForeColor (GC_FORE_COLOR (gc));
@@ -424,6 +445,21 @@ mac_draw_line_to_pixmap (display, p, gc, x1, y1, x2, y2)
   CGrafPtr old_port;
   GDHandle old_gdh;
 
+  if (x1 == x2)
+    {
+      if (y1 > y2)
+       y1--;
+      else if (y2 > y1)
+       y2--;
+    }
+  else if (y1 == y2)
+    {
+      if (x1 > x2)
+       x1--;
+      else
+       x2--;
+    }
+
   GetGWorld (&old_port, &old_gdh);
   SetGWorld (p, NULL);
 
@@ -868,7 +904,7 @@ mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width, bytes_per_char)
 #if USE_ATSUI
   if (GC_FONT (gc)->mac_style)
     {
-      OSErr err;
+      OSStatus err;
       ATSUTextLayout text_layout;
 
       xassert (bytes_per_char == 2);
@@ -1095,7 +1131,7 @@ mac_draw_image_string_16 (f, gc, x, y, buf, nchars, bg_width)
    the font of the current graphics port.  If CG_GLYPH is not NULL,
    *CG_GLYPH is set to the glyph ID or 0 if it cannot be obtained.  */
 
-static OSErr
+static OSStatus
 mac_query_char_extents (style, c,
                        font_ascent_return, font_descent_return,
                        overall_return, cg_glyph)
@@ -1113,7 +1149,7 @@ mac_query_char_extents (style, c,
      void *cg_glyph;
 #endif
 {
-  OSErr err = noErr;
+  OSStatus err = noErr;
   int width;
   Rect char_bounds;
 
@@ -1159,7 +1195,7 @@ mac_query_char_extents (style, c,
 #if USE_CG_TEXT_DRAWING
          if (err == noErr && cg_glyph)
            {
-             OSErr err1;
+             OSStatus err1;
              ATSUGlyphInfoArray glyph_info_array;
              ByteCount count = sizeof (ATSUGlyphInfoArray);
 
@@ -1512,11 +1548,8 @@ XCreateGC (display, window, mask, xgcv)
 {
   GC gc = xmalloc (sizeof (*gc));
 
-  if (gc)
-    {
-      bzero (gc, sizeof (*gc));
-      XChangeGC (display, gc, mask, xgcv);
-    }
+  bzero (gc, sizeof (*gc));
+  XChangeGC (display, gc, mask, xgcv);
 
   return gc;
 }
@@ -1632,7 +1665,7 @@ mac_set_clip_rectangles (display, gc, rectangles, n)
          DisposeRgn (region);
        }
     }
-#if defined (MAC_OSX) && USE_ATSUI
+#if defined (MAC_OSX) && (USE_ATSUI || USE_CG_DRAWING)
   for (i = 0; i < n; i++)
     {
       Rect *rect = rectangles + i;
@@ -1699,14 +1732,6 @@ XSetWindowBackground (display, w, color)
 #endif
 }
 
-/* x_sync is a no-op on Mac.  */
-void
-x_sync (f)
-     void *f;
-{
-}
-
-
 /* Flush display of frame F, or of all frames if F is null.  */
 
 static void
@@ -2082,7 +2107,6 @@ mac_define_fringe_bitmap (which, bits, h, wd)
      unsigned short *bits;
      int h, wd;
 {
-  unsigned short *mask_bits;
   int i;
   CGDataProviderRef provider;
 
@@ -2153,6 +2177,29 @@ static int mac_encode_char P_ ((int, XChar2b *, struct font_info *,
                                struct charset *, int *));
 
 
+static void
+pcm_init (pcm, count)
+     XCharStruct *pcm;
+     int count;
+{
+  bzero (pcm, sizeof (XCharStruct) * count);
+  while (--count >= 0)
+    {
+      pcm->descent = PCM_INVALID;
+      pcm++;
+    }
+}
+
+static enum pcm_status
+pcm_get_status (pcm)
+     XCharStruct *pcm;
+{
+  int height = pcm->ascent + pcm->descent;
+
+  /* Negative height means some special status.  */
+  return height >= 0 ? PCM_VALID : height;
+}
+
 /* Get metrics of character CHAR2B in FONT.  Value is null if CHAR2B
    is not contained in the font.  */
 
@@ -2169,26 +2216,21 @@ x_per_char_metric (font, char2b)
 #if USE_ATSUI
   if (font->mac_style)
     {
-      XCharStructRow **row = font->bounds.rows + char2b->byte1;
+      XCharStruct **row = font->bounds.rows + char2b->byte1;
 
       if (*row == NULL)
        {
-         *row = xmalloc (sizeof (XCharStructRow));
-         if (*row)
-           bzero (*row, sizeof (XCharStructRow));
+         *row = xmalloc (sizeof (XCharStruct) * 0x100);
+         pcm_init (*row, 0x100);
        }
-      if (*row)
+      pcm = *row + char2b->byte2;
+      if (pcm_get_status (pcm) != PCM_VALID)
        {
-         pcm = (*row)->per_char + char2b->byte2;
-         if (!XCHARSTRUCTROW_CHAR_VALID_P (*row, char2b->byte2))
-           {
-             BLOCK_INPUT;
-             mac_query_char_extents (font->mac_style,
-                                     (char2b->byte1 << 8) + char2b->byte2,
-                                     NULL, NULL, pcm, NULL);
-             UNBLOCK_INPUT;
-             XCHARSTRUCTROW_SET_CHAR_VALID (*row, char2b->byte2);
-           }
+         BLOCK_INPUT;
+         mac_query_char_extents (font->mac_style,
+                                 (char2b->byte1 << 8) + char2b->byte2,
+                                 NULL, NULL, pcm, NULL);
+         UNBLOCK_INPUT;
        }
     }
   else
@@ -2251,7 +2293,11 @@ x_per_char_metric (font, char2b)
 #endif
 
   return ((pcm == NULL
-          || (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0))
+          || (pcm->width == 0
+#if 0 /* Show hollow boxes for zero-width glyphs such as combining diacritics.  */
+              && (pcm->rbearing - pcm->lbearing) == 0
+#endif
+              ))
          ? NULL : pcm);
 }
 
@@ -2368,7 +2414,6 @@ static void x_setup_relief_colors P_ ((struct glyph_string *));
 static void x_draw_image_glyph_string P_ ((struct glyph_string *));
 static void x_draw_image_relief P_ ((struct glyph_string *));
 static void x_draw_image_foreground P_ ((struct glyph_string *));
-static void x_draw_image_foreground_1 P_ ((struct glyph_string *, Pixmap));
 static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int,
                                           int, int, int));
 static void x_draw_relief_rect P_ ((struct frame *, int, int, int, int,
@@ -2569,34 +2614,36 @@ static void
 mac_compute_glyph_string_overhangs (s)
      struct glyph_string *s;
 {
-  if (s->cmp == NULL
-      && s->first_glyph->type == CHAR_GLYPH)
-    if (!s->two_byte_p
+  if (!(s->cmp == NULL
+       && s->first_glyph->type == CHAR_GLYPH))
+    return;
+
+  if (!s->two_byte_p
 #if USE_ATSUI
-       || s->font->mac_style
+      || s->font->mac_style
 #endif
-       )
-      {
-       XCharStruct cs;
+      )
+    {
+      XCharStruct cs;
 
-       mac_text_extents_16 (s->font, s->char2b, s->nchars, &cs);
-       s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0;
-       s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0;
-      }
-    else
-      {
-       Rect r;
-       MacFontStruct *font = s->font;
+      mac_text_extents_16 (s->font, s->char2b, s->nchars, &cs);
+      s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0;
+      s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0;
+    }
+  else
+    {
+      Rect r;
+      MacFontStruct *font = s->font;
 
-       TextFont (font->mac_fontnum);
-       TextSize (font->mac_fontsize);
-       TextFace (font->mac_fontface);
+      TextFont (font->mac_fontnum);
+      TextSize (font->mac_fontsize);
+      TextFace (font->mac_fontface);
 
-       QDTextBounds (s->nchars * 2, (char *)s->char2b, &r);
+      QDTextBounds (s->nchars * 2, (char *)s->char2b, &r);
 
-       s->right_overhang = r.right > s->width ? r.right - s->width : 0;
-       s->left_overhang = r.left < 0 ? -r.left : 0;
-      }
+      s->right_overhang = r.right > s->width ? r.right - s->width : 0;
+      s->left_overhang = r.left < 0 ? -r.left : 0;
+    }
 }
 
 
@@ -3137,13 +3184,13 @@ x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
     for (i = 0; i < width; ++i)
       mac_draw_line (f, gc,
                     left_x + i * left_p, top_y + i,
-                    right_x - i * right_p, top_y + i);
+                    right_x + 1 - i * right_p, top_y + i);
 
   /* Left.  */
   if (left_p)
     for (i = 0; i < width; ++i)
       mac_draw_line (f, gc,
-                    left_x + i, top_y + i, left_x + i, bottom_y - i);
+                    left_x + i, top_y + i, left_x + i, bottom_y - i + 1);
 
   mac_reset_clip_rectangles (dpy, gc);
   if (raised_p)
@@ -3157,13 +3204,13 @@ x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
     for (i = 0; i < width; ++i)
       mac_draw_line (f, gc,
                     left_x + i * left_p, bottom_y - i,
-                    right_x - i * right_p, bottom_y - i);
+                    right_x + 1 - i * right_p, bottom_y - i);
 
   /* Right.  */
   if (right_p)
     for (i = 0; i < width; ++i)
       mac_draw_line (f, gc,
-                    right_x - i, top_y + i + 1, right_x - i, bottom_y - i - 1);
+                    right_x - i, top_y + i + 1, right_x - i, bottom_y - i);
 
   mac_reset_clip_rectangles (dpy, gc);
 }
@@ -3432,7 +3479,6 @@ x_draw_image_glyph_string (s)
   int box_line_hwidth = abs (s->face->box_line_width);
   int box_line_vwidth = max (s->face->box_line_width, 0);
   int height;
-  Pixmap pixmap = 0;
 
   height = s->height - 2 * box_line_vwidth;
 
@@ -3487,19 +3533,28 @@ x_draw_stretch_glyph_string (s)
     {
       /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
         as wide as the stretch glyph.  */
-      int width = min (FRAME_COLUMN_WIDTH (s->f), s->background_width);
+      int width, background_width = s->background_width;
+      int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+      if (x < left_x)
+       {
+         background_width -= left_x - x;
+         x = left_x;
+       }
+      width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
 
       /* Draw cursor.  */
-      x_draw_glyph_string_bg_rect (s, s->x, s->y, width, s->height);
+      x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
 
       /* Clear rest using the GC of the original non-cursor face.  */
-      if (width < s->background_width)
+      if (width < background_width)
        {
-         int x = s->x + width, y = s->y;
-         int w = s->background_width - width, h = s->height;
+         int y = s->y;
+         int w = background_width - width, h = s->height;
          Rect r;
          GC gc;
 
+         x += width;
          if (s->row->mouse_face_p
              && cursor_in_mouse_face_p (s->w))
            {
@@ -3526,8 +3581,20 @@ x_draw_stretch_glyph_string (s)
        }
     }
   else if (!s->background_filled_p)
-    x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width,
-                                s->height);
+    {
+      int background_width = s->background_width;
+      int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+      /* Don't draw into left margin, fringe or scrollbar area
+         except for header line and mode line.  */
+      if (x < left_x && !s->row->mode_line_p)
+       {
+         background_width -= left_x - x;
+         x = left_x;
+       }
+      if (background_width > 0)
+       x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
+    }
 
   s->background_filled_p = 1;
 }
@@ -3614,14 +3681,14 @@ x_draw_glyph_string (s)
 
          if (s->face->underline_defaulted_p)
            mac_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
-                               s->width, h);
+                               s->background_width, h);
          else
            {
              XGCValues xgcv;
              XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
              XSetForeground (s->display, s->gc, s->face->underline_color);
              mac_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
-                                 s->width, h);
+                                 s->background_width, h);
              XSetForeground (s->display, s->gc, xgcv.foreground);
            }
        }
@@ -3633,14 +3700,14 @@ x_draw_glyph_string (s)
 
          if (s->face->overline_color_defaulted_p)
            mac_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
-                               s->width, h);
+                               s->background_width, h);
          else
            {
              XGCValues xgcv;
              XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
              XSetForeground (s->display, s->gc, s->face->overline_color);
              mac_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
-                                 s->width, h);
+                                 s->background_width, h);
              XSetForeground (s->display, s->gc, xgcv.foreground);
            }
        }
@@ -4055,6 +4122,11 @@ x_new_focus_frame (dpyinfo, frame)
        pending_autoraise_frame = dpyinfo->x_focus_frame;
       else
        pending_autoraise_frame = 0;
+
+#if USE_MAC_FONT_PANEL
+      if (frame)
+       mac_set_font_info_for_selection (frame, DEFAULT_FACE_ID, 0);
+#endif
     }
 
   x_frame_rehighlight (dpyinfo);
@@ -4178,142 +4250,6 @@ x_frame_rehighlight (dpyinfo)
 
 
 \f
-/* Keyboard processing - modifier keys, vendor-specific keysyms, etc.  */
-
-#if 0 /* MAC_TODO */
-/* Initialize mode_switch_bit and modifier_meaning.  */
-static void
-x_find_modifier_meanings (dpyinfo)
-     struct x_display_info *dpyinfo;
-{
-  int min_code, max_code;
-  KeySym *syms;
-  int syms_per_code;
-  XModifierKeymap *mods;
-
-  dpyinfo->meta_mod_mask = 0;
-  dpyinfo->shift_lock_mask = 0;
-  dpyinfo->alt_mod_mask = 0;
-  dpyinfo->super_mod_mask = 0;
-  dpyinfo->hyper_mod_mask = 0;
-
-#ifdef HAVE_X11R4
-  XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
-#else
-  min_code = dpyinfo->display->min_keycode;
-  max_code = dpyinfo->display->max_keycode;
-#endif
-
-  syms = XGetKeyboardMapping (dpyinfo->display,
-                             min_code, max_code - min_code + 1,
-                             &syms_per_code);
-  mods = XGetModifierMapping (dpyinfo->display);
-
-  /* Scan the modifier table to see which modifier bits the Meta and
-     Alt keysyms are on.  */
-  {
-    int row, col;      /* The row and column in the modifier table.  */
-
-    for (row = 3; row < 8; row++)
-      for (col = 0; col < mods->max_keypermod; col++)
-       {
-         KeyCode code
-           = mods->modifiermap[(row * mods->max_keypermod) + col];
-
-         /* Zeroes are used for filler.  Skip them.  */
-         if (code == 0)
-           continue;
-
-         /* Are any of this keycode's keysyms a meta key?  */
-         {
-           int code_col;
-
-           for (code_col = 0; code_col < syms_per_code; code_col++)
-             {
-               int sym = syms[((code - min_code) * syms_per_code) + code_col];
-
-               switch (sym)
-                 {
-                 case XK_Meta_L:
-                 case XK_Meta_R:
-                   dpyinfo->meta_mod_mask |= (1 << row);
-                   break;
-
-                 case XK_Alt_L:
-                 case XK_Alt_R:
-                   dpyinfo->alt_mod_mask |= (1 << row);
-                   break;
-
-                 case XK_Hyper_L:
-                 case XK_Hyper_R:
-                   dpyinfo->hyper_mod_mask |= (1 << row);
-                   break;
-
-                 case XK_Super_L:
-                 case XK_Super_R:
-                   dpyinfo->super_mod_mask |= (1 << row);
-                   break;
-
-                 case XK_Shift_Lock:
-                   /* Ignore this if it's not on the lock modifier.  */
-                   if ((1 << row) == LockMask)
-                     dpyinfo->shift_lock_mask = LockMask;
-                   break;
-                 }
-             }
-         }
-       }
-  }
-
-  /* If we couldn't find any meta keys, accept any alt keys as meta keys.  */
-  if (! dpyinfo->meta_mod_mask)
-    {
-      dpyinfo->meta_mod_mask = dpyinfo->alt_mod_mask;
-      dpyinfo->alt_mod_mask = 0;
-    }
-
-  /* If some keys are both alt and meta,
-     make them just meta, not alt.  */
-  if (dpyinfo->alt_mod_mask & dpyinfo->meta_mod_mask)
-    {
-      dpyinfo->alt_mod_mask &= ~dpyinfo->meta_mod_mask;
-    }
-
-  XFree ((char *) syms);
-  XFreeModifiermap (mods);
-}
-
-#endif /* MAC_TODO */
-
-/* Convert between the modifier bits X uses and the modifier bits
-   Emacs uses.  */
-
-static unsigned int
-x_mac_to_emacs_modifiers (dpyinfo, state)
-     struct x_display_info *dpyinfo;
-     unsigned short state;
-{
-  return (((state & shiftKey) ? shift_modifier : 0)
-         | ((state & controlKey) ? ctrl_modifier : 0)
-         | ((state & cmdKey) ? meta_modifier : 0)
-         | ((state & optionKey) ? alt_modifier : 0));
-}
-
-#if 0 /* MAC_TODO */
-static unsigned short
-x_emacs_to_x_modifiers (dpyinfo, state)
-     struct x_display_info *dpyinfo;
-     unsigned int state;
-{
-  return (  ((state & alt_modifier)    ? dpyinfo->alt_mod_mask   : 0)
-         | ((state & super_modifier)   ? dpyinfo->super_mod_mask : 0)
-         | ((state & hyper_modifier)   ? dpyinfo->hyper_mod_mask : 0)
-         | ((state & shift_modifier)   ? ShiftMask        : 0)
-         | ((state & ctrl_modifier)    ? ControlMask      : 0)
-         | ((state & meta_modifier)    ? dpyinfo->meta_mod_mask  : 0));
-}
-#endif /* MAC_TODO */
-
 /* Convert a keysym to its name.  */
 
 char *
@@ -4548,35 +4484,11 @@ scroll_bar_timer_callback (timer, data)
      EventLoopTimerRef timer;
      void *data;
 {
-  EventRef event = NULL;
-  OSErr err;
-
-  err = CreateEvent (NULL, kEventClassMouse, kEventMouseMoved, 0,
-                    kEventAttributeNone, &event);
-  if (err == noErr)
-    {
-      Point mouse_pos;
-
-      GetMouse (&mouse_pos);
-      LocalToGlobal (&mouse_pos);
-      err = SetEventParameter (event, kEventParamMouseLocation, typeQDPoint,
-                              sizeof (Point), &mouse_pos);
-    }
-  if (err == noErr)
-    {
-      UInt32 modifiers = GetCurrentKeyModifiers ();
+  OSStatus err;
 
-      err = SetEventParameter (event, kEventParamKeyModifiers, typeUInt32,
-                              sizeof (UInt32), &modifiers);
-    }
-  if (err == noErr)
-    err = PostEventToQueue (GetCurrentEventQueue (), event,
-                           kEventPriorityStandard);
+  err = mac_post_mouse_moved_event ();
   if (err == noErr)
     scroll_bar_timer_event_posted_p = 1;
-
-  if (event)
-    ReleaseEvent (event);
 }
 
 static OSStatus
@@ -5104,41 +5016,43 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
 
 #ifdef USE_TOOLKIT_SCROLL_BARS
   if (NILP (bar->track_top))
-    if (sb_width >= disp_height)
-      {
-       XSETINT (bar->track_top, 0);
-       XSETINT (bar->track_height, 0);
-      }
-    else
-      {
-       ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
-       Rect r0, r1;
+    {
+      if (sb_width >= disp_height)
+       {
+         XSETINT (bar->track_top, 0);
+         XSETINT (bar->track_height, 0);
+       }
+      else
+       {
+         ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
+         Rect r0, r1;
 
-       BLOCK_INPUT;
+         BLOCK_INPUT;
 
-       SetControl32BitMinimum (ch, 0);
-       SetControl32BitMaximum (ch, 1);
-       SetControlViewSize (ch, 1);
+         SetControl32BitMinimum (ch, 0);
+         SetControl32BitMaximum (ch, 1);
+         SetControlViewSize (ch, 1);
 
-       /* Move the scroll bar thumb to the top.  */
-       SetControl32BitValue (ch, 0);
-       get_control_part_bounds (ch, kControlIndicatorPart, &r0);
+         /* Move the scroll bar thumb to the top.  */
+         SetControl32BitValue (ch, 0);
+         get_control_part_bounds (ch, kControlIndicatorPart, &r0);
 
-       /* Move the scroll bar thumb to the bottom.  */
-       SetControl32BitValue (ch, 1);
-       get_control_part_bounds (ch, kControlIndicatorPart, &r1);
+         /* Move the scroll bar thumb to the bottom.  */
+         SetControl32BitValue (ch, 1);
+         get_control_part_bounds (ch, kControlIndicatorPart, &r1);
 
-       UnionRect (&r0, &r1, &r0);
-       XSETINT (bar->track_top, r0.top);
-       XSETINT (bar->track_height, r0.bottom - r0.top);
+         UnionRect (&r0, &r1, &r0);
+         XSETINT (bar->track_top, r0.top);
+         XSETINT (bar->track_height, r0.bottom - r0.top);
 
-       /* Don't show the scroll bar if its height is not enough to
-          display the scroll bar thumb.  */
-       if (r0.bottom - r0.top > 0)
-         ShowControl (ch);
+         /* Don't show the scroll bar if its height is not enough to
+            display the scroll bar thumb.  */
+         if (r0.bottom - r0.top > 0)
+           ShowControl (ch);
 
-       UNBLOCK_INPUT;
-      }
+         UNBLOCK_INPUT;
+       }
+    }
 
   x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
 #else /* not USE_TOOLKIT_SCROLL_BARS */
@@ -5507,8 +5421,7 @@ x_draw_hollow_cursor (w, row)
     return;
 
   /* Compute frame-relative coordinates for phys cursor.  */
-  x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
-  y = get_phys_cursor_geometry (w, row, cursor_glyph, &h);
+  get_phys_cursor_geometry (w, row, cursor_glyph, &x, &y, &h);
   wd = w->phys_cursor_width;
 
   /* The foreground of cursor_gc is typically the same as the normal
@@ -6141,13 +6054,28 @@ x_set_mouse_pixel_position (f, pix_x, pix_y)
      struct frame *f;
      int pix_x, pix_y;
 {
-#if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
+#ifdef MAC_OSX
+  Point p;
+  CGPoint point;
+
+  BLOCK_INPUT;
+  SetPortWindowPort (FRAME_MAC_WINDOW (f));
+  p.h = pix_x;
+  p.v = pix_y;
+  LocalToGlobal (&p);
+  point.x = p.h;
+  point.y = p.v;
+  CGWarpMouseCursorPosition (point);
+  UNBLOCK_INPUT;
+#else
+#if 0 /* MAC_TODO: LMSetMouseLocation and CursorDeviceMoveTo are non-Carbon */
   BLOCK_INPUT;
 
   XWarpPointer (FRAME_X_DISPLAY (f), None, FRAME_X_WINDOW (f),
                0, 0, 0, 0, pix_x, pix_y);
   UNBLOCK_INPUT;
 #endif
+#endif
 }
 \f
 /* focus shifting, raising and lowering.  */
@@ -6224,10 +6152,12 @@ mac_handle_visibility_change (f)
   struct input_event buf;
 
   if (IsWindowVisible (wp))
-    if (IsWindowCollapsed (wp))
-      iconified = 1;
-    else
-      visible = 1;
+    {
+      if (IsWindowCollapsed (wp))
+       iconified = 1;
+      else
+       visible = 1;
+    }
 
   if (!f->async_visible && visible)
     {
@@ -6242,6 +6172,7 @@ mac_handle_visibility_change (f)
          EVENT_INIT (buf);
          buf.kind = DEICONIFY_EVENT;
          XSETFRAME (buf.frame_or_window, f);
+         buf.arg = Qnil;
          kbd_buffer_store_event (&buf);
        }
       else if (! NILP (Vframe_list) && ! NILP (XCDR (Vframe_list)))
@@ -6255,6 +6186,7 @@ mac_handle_visibility_change (f)
        EVENT_INIT (buf);
        buf.kind = ICONIFY_EVENT;
        XSETFRAME (buf.frame_or_window, f);
+       buf.arg = Qnil;
        kbd_buffer_store_event (&buf);
       }
 
@@ -6273,9 +6205,6 @@ void
 x_make_frame_visible (f)
      struct frame *f;
 {
-  Lisp_Object type;
-  int original_top, original_left;
-
   BLOCK_INPUT;
 
   if (! FRAME_VISIBLE_P (f))
@@ -6286,27 +6215,29 @@ x_make_frame_visible (f)
         before the window gets really visible.  */
       if (! FRAME_ICONIFIED_P (f)
          && ! f->output_data.mac->asked_for_visible)
+       {
 #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 (!(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
+                                 kWindowCascadeStartAtParentWindowScreen
 #else
-                               kWindowCascadeOnParentWindowScreen
+                                 kWindowCascadeOnParentWindowScreen
 #endif
-                               );
-           x_real_positions (f, &f->left_pos, &f->top_pos);
-         }
-       else
+                                 );
+             x_real_positions (f, &f->left_pos, &f->top_pos);
+           }
+         else
 #endif
-         x_set_offset (f, f->left_pos, f->top_pos, 0);
+           x_set_offset (f, f->left_pos, f->top_pos, 0);
+       }
 
       f->output_data.mac->asked_for_visible = 1;
 
@@ -6402,7 +6333,7 @@ void
 x_iconify_frame (f)
      struct frame *f;
 {
-  OSErr err;
+  OSStatus err;
 
   /* A deactivate event does not occur when the last visible frame is
      iconified.  So if we clear the highlight here, it will not be
@@ -6470,7 +6401,12 @@ x_free_frame_resources (f)
   f->output_data.mac = NULL;
 
   if (f == dpyinfo->x_focus_frame)
-    dpyinfo->x_focus_frame = 0;
+    {
+      dpyinfo->x_focus_frame = 0;
+#if USE_MAC_FONT_PANEL
+      mac_set_font_info_for_selection (NULL, DEFAULT_FACE_ID, 0);
+#endif
+    }
   if (f == dpyinfo->x_focus_event_frame)
     dpyinfo->x_focus_event_frame = 0;
   if (f == dpyinfo->x_highlight_frame)
@@ -6726,12 +6662,7 @@ xlfdpat_create (pattern)
   struct xlfdpat_block *blk;
 
   pat = xmalloc (sizeof (struct xlfdpat));
-  if (pat == NULL)
-    goto error;
-
   pat->buf = xmalloc (strlen (pattern) + 1);
-  if (pat->buf == NULL)
-    goto error;
 
   /* Normalize the pattern string and store it to `pat->buf'.  */
   nblocks = 0;
@@ -6749,15 +6680,17 @@ xlfdpat_create (pattern)
        else
          {
            if (last_char == '?')
-             if (anychar_head > pat->buf && *(anychar_head - 1) == '*')
-               /*  ...*??* -> ...*??  */
-               continue;
-             else
-               /*  ...a??* -> ...a*??  */
-               {
-                 *anychar_head++ = '*';
-                 c = '?';
-               }
+             {
+               if (anychar_head > pat->buf && *(anychar_head - 1) == '*')
+                 /*  ...*??* -> ...*??  */
+                 continue;
+               else
+                 /*  ...a??* -> ...a*??  */
+                 {
+                   *anychar_head++ = '*';
+                   c = '?';
+                 }
+             }
            nblocks++;
          }
       else if (c == '?')
@@ -6793,8 +6726,6 @@ xlfdpat_create (pattern)
     }
 
   pat->blocks = xmalloc (sizeof (struct xlfdpat_block) * nblocks);
-  if (pat->blocks == NULL)
-    goto error;
 
   /* Divide the normalized pattern into blocks.  */
   p = pat->buf;
@@ -6831,10 +6762,6 @@ xlfdpat_create (pattern)
       }
 
   return pat;
-
- error:
-  xlfdpat_destroy (pat);
-  return NULL;
 }
 
 static INLINE int
@@ -7003,6 +6930,10 @@ static Lisp_Object fm_font_family_alist;
 #if USE_ATSUI
 /* Hash table linking font family names to ATSU font IDs.  */
 static Lisp_Object atsu_font_id_hash;
+/* Alist linking Font Manager style to face attributes.  */
+static Lisp_Object fm_style_face_attributes_alist;
+static Lisp_Object Vmac_atsu_font_table;
+extern Lisp_Object QCfamily, QCweight, QCslant, Qnormal, Qbold, Qitalic;
 #endif
 
 /* Alist linking character set strings to Mac text encoding and Emacs
@@ -7217,6 +7148,48 @@ add_font_name_table_entry (char *font_name)
   font_name_table[font_name_count++] = font_name;
 }
 
+static void
+add_mac_font_name (name, size, style, charset)
+     char *name;
+     int size;
+     Style style;
+     char *charset;
+{
+  if (size > 0)
+    add_font_name_table_entry (mac_to_x_fontname (name, size, style, charset));
+  else
+    {
+      add_font_name_table_entry (mac_to_x_fontname (name, 0, style, charset));
+      add_font_name_table_entry (mac_to_x_fontname (name, 0, italic, charset));
+      add_font_name_table_entry (mac_to_x_fontname (name, 0, bold, charset));
+      add_font_name_table_entry (mac_to_x_fontname (name, 0, italic | bold,
+                                                   charset));
+    }
+}
+
+#if USE_ATSUI
+static Lisp_Object
+fm_style_to_face_attributes (fm_style)
+     FMFontStyle fm_style;
+{
+  Lisp_Object tem;
+
+  fm_style &= (bold | italic);
+  tem = assq_no_quit (make_number (fm_style),
+                     fm_style_face_attributes_alist);
+  if (!NILP (tem))
+    return XCDR (tem);
+
+  tem = list4 (QCweight, fm_style & bold ? Qbold : Qnormal,
+              QCslant, fm_style & italic ? Qitalic : Qnormal);
+  fm_style_face_attributes_alist =
+    Fcons (Fcons (make_number (fm_style), tem),
+          fm_style_face_attributes_alist);
+
+  return tem;
+}
+#endif
+
 /* Sets up the table font_name_table to contain the list of all fonts
    in the system the first time the table is used so that the Resource
    Manager need not be accessed every time this information is
@@ -7241,22 +7214,28 @@ init_font_name_table ()
   if (!NILP (assq_no_quit (make_number (kTextEncodingMacUnicode),
                           text_encoding_info_alist)))
     {
-      OSErr err;
+      OSStatus err;
+      struct Lisp_Hash_Table *h;
+      unsigned hash_code;
       ItemCount nfonts, i;
       ATSUFontID *font_ids = NULL;
-      Ptr name, prev_name = NULL;
+      Ptr name;
       ByteCount name_len;
+      Lisp_Object family;
 
       atsu_font_id_hash =
        make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE),
                         make_float (DEFAULT_REHASH_SIZE),
                         make_float (DEFAULT_REHASH_THRESHOLD),
                         Qnil, Qnil, Qnil);;
+      h = XHASH_TABLE (atsu_font_id_hash);
+
       err = ATSUFontCount (&nfonts);
       if (err == noErr)
-       font_ids = xmalloc (sizeof (ATSUFontID) * nfonts);
-      if (font_ids)
-       err = ATSUGetFontIDs (font_ids, nfonts, NULL);
+       {
+         font_ids = xmalloc (sizeof (ATSUFontID) * nfonts);
+         err = ATSUGetFontIDs (font_ids, nfonts, NULL);
+       }
       if (err == noErr)
        for (i = 0; i < nfonts; i++)
          {
@@ -7266,40 +7245,36 @@ init_font_name_table ()
            if (err != noErr)
              continue;
            name = xmalloc (name_len + 1);
-           if (name == NULL)
-             continue;
            name[name_len] = '\0';
            err = ATSUFindFontName (font_ids[i], kFontFamilyName,
                                    kFontMacintoshPlatform, kFontNoScript,
                                    kFontNoLanguage, name_len, name,
                                    NULL, NULL);
            if (err == noErr)
-             decode_mac_font_name (name, name_len + 1, Qnil);
-           if (err == noErr
-               && *name != '.'
-               && (prev_name == NULL
-                   || strcmp (name, prev_name) != 0))
              {
-               static char *cs = "iso10646-1";
-
-               add_font_name_table_entry (mac_to_x_fontname (name, 0,
-                                                             normal, cs));
-               add_font_name_table_entry (mac_to_x_fontname (name, 0,
-                                                             italic, cs));
-               add_font_name_table_entry (mac_to_x_fontname (name, 0,
-                                                             bold, cs));
-               add_font_name_table_entry (mac_to_x_fontname (name, 0,
-                                                             italic | bold, cs));
-               Fputhash (make_unibyte_string (name, name_len),
-                         long_to_cons (font_ids[i]), atsu_font_id_hash);
-               xfree (prev_name);
-               prev_name = name;
+               FMFontFamily ff;
+               FMFontStyle style = normal;
+
+               decode_mac_font_name (name, name_len + 1, Qnil);
+               family = make_unibyte_string (name, name_len);
+               FMGetFontFamilyInstanceFromFont (font_ids[i], &ff, &style);
+               Fputhash ((font_ids[i] > MOST_POSITIVE_FIXNUM
+                          ? make_float (font_ids[i])
+                          : make_number (font_ids[i])),
+                         Fcons (QCfamily,
+                                Fcons (family,
+                                       fm_style_to_face_attributes (style))),
+                         Vmac_atsu_font_table);
+               if (*name != '.'
+                   && hash_lookup (h, family, &hash_code) < 0)
+                 {
+                   add_mac_font_name (name, 0, normal, "iso10646-1");
+                   hash_put (h, family, long_to_cons (font_ids[i]),
+                             hash_code);
+                 }
              }
-           else
-             xfree (name);
+           xfree (name);
          }
-      if (prev_name)
-       xfree (prev_name);
       if (font_ids)
        xfree (font_ids);
     }
@@ -7327,16 +7302,16 @@ init_font_name_table ()
       FMFontSize size;
       TextEncoding encoding;
       TextEncodingBase sc;
-      Lisp_Object text_encoding_info;
+      Lisp_Object text_encoding_info, family;
 
       if (FMGetFontFamilyName (ff, name) != noErr)
-       break;
+       continue;
       p2cstr (name);
       if (*name == '.')
        continue;
 
       if (FMGetFontFamilyTextEncoding (ff, &encoding) != noErr)
-       break;
+       continue;
       sc = GetTextEncodingBase (encoding);
       text_encoding_info = assq_no_quit (make_number (sc),
                                         text_encoding_info_alist);
@@ -7345,13 +7320,15 @@ init_font_name_table ()
                                           text_encoding_info_alist);
       decode_mac_font_name (name, sizeof (name),
                            XCAR (XCDR (text_encoding_info)));
-      fm_font_family_alist = Fcons (Fcons (build_string (name),
-                                          make_number (ff)),
+      family = build_string (name);
+      if (!NILP (Fassoc (family, fm_font_family_alist)))
+       continue;
+      fm_font_family_alist = Fcons (Fcons (family, make_number (ff)),
                                    fm_font_family_alist);
 
       /* Point the instance iterator at the current font family.  */
       if (FMResetFontFamilyInstanceIterator (ff, &ffii) != noErr)
-       break;
+       continue;
 
       while (FMGetNextFontFamilyInstance (&ffii, &font, &style, &size)
             == noErr)
@@ -7360,27 +7337,7 @@ init_font_name_table ()
 
          if (size > 0 || style == normal)
            for (; !NILP (rest); rest = XCDR (rest))
-             {
-               char *cs = SDATA (XCAR (rest));
-
-               if (size == 0)
-                 {
-                   add_font_name_table_entry (mac_to_x_fontname (name, size,
-                                                                 style, cs));
-                   add_font_name_table_entry (mac_to_x_fontname (name, size,
-                                                                 italic, cs));
-                   add_font_name_table_entry (mac_to_x_fontname (name, size,
-                                                                 bold, cs));
-                   add_font_name_table_entry (mac_to_x_fontname (name, size,
-                                                                 italic | bold,
-                                                                 cs));
-                 }
-               else
-                 {
-                   add_font_name_table_entry (mac_to_x_fontname (name, size,
-                                                                 style, cs));
-                 }
-             }
+             add_mac_font_name (name, size, style, SDATA (XCAR (rest)));
        }
     }
 
@@ -7400,7 +7357,7 @@ init_font_name_table ()
   Str255 name;
   struct FontAssoc *fat;
   struct AsscEntry *assc_entry;
-  Lisp_Object text_encoding_info_alist, text_encoding_info;
+  Lisp_Object text_encoding_info_alist, text_encoding_info, family;
   struct gcpro gcpro1;
 
   GetPort (&port);  /* save the current font number used */
@@ -7419,7 +7376,7 @@ init_font_name_table ()
       GetResInfo (font_handle, &id, &type, name);
       GetFNum (name, &fontnum);
       p2cstr (name);
-      if (fontnum == 0)
+      if (fontnum == 0 || *name == '.')
        continue;
 
       TextFont (fontnum);
@@ -7431,8 +7388,10 @@ init_font_name_table ()
                                           text_encoding_info_alist);
       decode_mac_font_name (name, sizeof (name),
                            XCAR (XCDR (text_encoding_info)));
-      fm_font_family_alist = Fcons (Fcons (build_string (name),
-                                          make_number (fontnum)),
+      family = build_string (name);
+      if (!NILP (Fassoc (family, fm_font_family_alist)))
+       continue;
+      fm_font_family_alist = Fcons (Fcons (family, make_number (fontnum)),
                                    fm_font_family_alist);
       do
        {
@@ -7453,14 +7412,9 @@ init_font_name_table ()
                  Lisp_Object rest = XCDR (XCDR (text_encoding_info));
 
                  for (; !NILP (rest); rest = XCDR (rest))
-                   {
-                     char *cs = SDATA (XCAR (rest));
-
-                     add_font_name_table_entry (mac_to_x_fontname (name,
-                                                                   assc_entry->fontSize,
-                                                                   assc_entry->fontStyle,
-                                                                   cs));
-                   }
+                   add_mac_font_name (name, assc_entry->fontSize,
+                                      assc_entry->fontStyle,
+                                      SDATA (XCAR (rest)));
                }
            }
 
@@ -7588,7 +7542,7 @@ mac_do_list_fonts (pattern, maxnames)
       if (xlfdpat_match (pat, font_name_table[i]))
        {
          font_list = Fcons (build_string (font_name_table[i]), font_list);
-         if (exact || maxnames > 0 && ++n_fonts >= maxnames)
+         if (exact || (maxnames > 0 && ++n_fonts >= maxnames))
            break;
        }
       else if (scl_val[XLFD_SCL_PIXEL_SIZE] > 0
@@ -7597,8 +7551,6 @@ mac_do_list_fonts (pattern, maxnames)
          int former_len = ptr - font_name_table[i];
 
          scaled = xmalloc (strlen (font_name_table[i]) + 20 + 1);
-         if (scaled == NULL)
-           continue;
          memcpy (scaled, font_name_table[i], former_len);
          sprintf (scaled + former_len,
                   "-%d-%d-72-72-m-%d-%s",
@@ -7611,7 +7563,7 @@ mac_do_list_fonts (pattern, maxnames)
            {
              font_list = Fcons (build_string (scaled), font_list);
              xfree (scaled);
-             if (exact || maxnames > 0 && ++n_fonts >= maxnames)
+             if (exact || (maxnames > 0 && ++n_fonts >= maxnames))
                  break;
            }
          else
@@ -7844,7 +7796,7 @@ XLoadQueryFont (Display *dpy, char *fontname)
 #if USE_ATSUI
   if (strcmp (charset, "iso10646-1") == 0) /* XXX */
     {
-      OSErr err;
+      OSStatus err;
       ATSUAttributeTag tags[] = {kATSUFontTag, kATSUSizeTag,
                                 kATSUQDBoldfaceTag, kATSUQDItalicTag};
       ByteCount sizes[] = {sizeof (ATSUFontID), sizeof (Fixed),
@@ -7858,6 +7810,7 @@ XLoadQueryFont (Display *dpy, char *fontname)
       ATSUFontFeatureSelector selectors[] = {kAllTypeFeaturesOffSelector,
                                             kDecomposeDiacriticsSelector};
       Lisp_Object font_id_cons;
+      FMFontStyle style;
 
       font_id_cons = Fgethash (make_unibyte_string (family, strlen (family)),
                               atsu_font_id_hash, Qnil);
@@ -7876,7 +7829,11 @@ XLoadQueryFont (Display *dpy, char *fontname)
        return NULL;
       err = ATSUSetAttributes (mac_style, sizeof (tags) / sizeof (tags[0]),
                               tags, sizes, values);
-      fontnum = -1;
+      if (err != noErr)
+       return NULL;
+      err = FMGetFontFamilyInstanceFromFont (font_id, &fontnum, &style);
+      if (err != noErr)
+       fontnum = -1;
       scriptcode = kTextEncodingMacUnicode;
     }
   else
@@ -7922,7 +7879,7 @@ XLoadQueryFont (Display *dpy, char *fontname)
 #if USE_ATSUI
   if (font->mac_style)
     {
-      OSErr err;
+      OSStatus err;
       UniChar c;
 
       font->min_byte1 = 0;
@@ -7930,45 +7887,34 @@ XLoadQueryFont (Display *dpy, char *fontname)
       font->min_char_or_byte2 = 0;
       font->max_char_or_byte2 = 0xff;
 
-      font->bounds.rows = xmalloc (sizeof (XCharStructRow *) * 0x100);
-      if (font->bounds.rows == NULL)
-       {
-         mac_unload_font (&one_mac_display_info, font);
-         return NULL;
-       }
-      bzero (font->bounds.rows, sizeof (XCharStructRow *) * 0x100);
-      font->bounds.rows[0] = xmalloc (sizeof (XCharStructRow));
-      if (font->bounds.rows[0] == NULL)
-       {
-         mac_unload_font (&one_mac_display_info, font);
-         return NULL;
-       }
-      bzero (font->bounds.rows[0], sizeof (XCharStructRow));
+      font->bounds.rows = xmalloc (sizeof (XCharStruct *) * 0x100);
+      bzero (font->bounds.rows, sizeof (XCharStruct *) * 0x100);
+      font->bounds.rows[0] = xmalloc (sizeof (XCharStruct) * 0x100);
+      pcm_init (font->bounds.rows[0], 0x100);
 
 #if USE_CG_TEXT_DRAWING
-      {
-       FMFontFamily font_family;
-       FMFontStyle style;
-       ATSFontRef ats_font;
+      if (fontnum != -1)
+       {
+         FMFontStyle style;
+         ATSFontRef ats_font;
 
-       err = FMGetFontFamilyInstanceFromFont (font_id, &font_family, &style);
-       if (err == noErr)
-         err = FMGetFontFromFontFamilyInstance (font_family, fontface,
+         err = FMGetFontFromFontFamilyInstance (fontnum, fontface,
                                                 &font_id, &style);
-       /* Use CG text drawing if italic/bold is not synthesized.  */
-       if (err == noErr && style == fontface)
-         {
-           ats_font = FMGetATSFontRefFromFont (font_id);
-           font->cg_font = CGFontCreateWithPlatformFont (&ats_font);
-         }
-      }
+         /* Use CG text drawing if italic/bold is not synthesized.  */
+         if (err == noErr && style == fontface)
+           {
+             ats_font = FMGetATSFontRefFromFont (font_id);
+             font->cg_font = CGFontCreateWithPlatformFont (&ats_font);
+           }
+       }
 
       if (font->cg_font)
-       font->cg_glyphs = xmalloc (sizeof (CGGlyph) * 0x100);
-      if (font->cg_glyphs)
-       bzero (font->cg_glyphs, sizeof (CGGlyph) * 0x100);
+       {
+         font->cg_glyphs = xmalloc (sizeof (CGGlyph) * 0x100);
+         bzero (font->cg_glyphs, sizeof (CGGlyph) * 0x100);
+       }
 #endif
-      space_bounds = font->bounds.rows[0]->per_char + 0x20;
+      space_bounds = font->bounds.rows[0] + 0x20;
       err = mac_query_char_extents (font->mac_style, 0x20,
                                    &font->ascent, &font->descent,
                                    space_bounds,
@@ -7984,9 +7930,8 @@ XLoadQueryFont (Display *dpy, char *fontname)
          mac_unload_font (&one_mac_display_info, font);
          return NULL;
        }
-      XCHARSTRUCTROW_SET_CHAR_VALID (font->bounds.rows[0], 0x20);
 
-      pcm = font->bounds.rows[0]->per_char;
+      pcm = font->bounds.rows[0];
       for (c = 0x21; c <= 0xff; c++)
        {
          if (c == 0xad)
@@ -8006,7 +7951,6 @@ XLoadQueryFont (Display *dpy, char *fontname)
                                    NULL
 #endif
                                  );
-         XCHARSTRUCTROW_SET_CHAR_VALID (font->bounds.rows[0], c);
 
 #if USE_CG_TEXT_DRAWING
          if (font->cg_glyphs && font->cg_glyphs[c] == 0)
@@ -8112,11 +8056,6 @@ XLoadQueryFont (Display *dpy, char *fontname)
 
          font->bounds.per_char =
            xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
-         if (font->bounds.per_char == NULL)
-           {
-             mac_unload_font (&one_mac_display_info, font);
-             return NULL;
-           }
          bzero (font->bounds.per_char,
                 sizeof (XCharStruct) * (0xff - 0x20 + 1));
 
@@ -8260,10 +8199,8 @@ x_load_font (f, fontname, size)
 
   /* Load the font and add it to the table.  */
   {
-    char *full_name;
     struct MacFontStruct *font;
     struct font_info *fontp;
-    unsigned long value;
     int i;
 
     fontname = (char *) SDATA (XCAR (font_names));
@@ -8423,8 +8360,8 @@ x_query_font (f, fontname)
 
   for (i = 0; i < dpyinfo->n_fonts; i++)
     if (dpyinfo->font_table[i].name
-       && (!strcmp (dpyinfo->font_table[i].name, fontname)
-           || !strcmp (dpyinfo->font_table[i].full_name, fontname)))
+       && (!xstricmp (dpyinfo->font_table[i].name, fontname)
+           || !xstricmp (dpyinfo->font_table[i].full_name, fontname)))
       return (dpyinfo->font_table + i);
   return NULL;
 }
@@ -8460,6 +8397,78 @@ x_find_ccl_program (fontp)
     }
 }
 
+#if USE_MAC_FONT_PANEL
+/* Whether Font Panel has been shown before.  The first call to font
+   panel functions (FPIsFontPanelVisible, SetFontInfoForSelection) is
+   slow.  This variable is used for deferring such a call as much as
+   possible.  */
+static int font_panel_shown_p = 0;
+
+int
+mac_font_panel_visible_p ()
+{
+  return font_panel_shown_p && FPIsFontPanelVisible ();
+}
+
+OSStatus
+mac_show_hide_font_panel ()
+{
+  font_panel_shown_p = 1;
+
+  return FPShowHideFontPanel ();
+}
+
+OSStatus
+mac_set_font_info_for_selection (f, face_id, c)
+     struct frame *f;
+     int face_id, c;
+{
+  OSStatus err;
+  EventTargetRef target = NULL;
+  XFontStruct *font = NULL;
+
+  if (!mac_font_panel_visible_p ())
+    return noErr;
+
+  if (f)
+    {
+      target = GetWindowEventTarget (FRAME_MAC_WINDOW (f));
+
+      if (FRAME_FACE_CACHE (f) && CHAR_VALID_P (c, 0))
+       {
+         struct face *face;
+
+         face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c);
+         face = FACE_FROM_ID (f, face_id);
+         font = face->font;
+       }
+    }
+
+  if (font == NULL)
+    err = SetFontInfoForSelection (kFontSelectionATSUIType, 0, NULL, target);
+  else
+    {
+      if (font->mac_fontnum != -1)
+       {
+         FontSelectionQDStyle qd_style;
+
+         qd_style.version = kFontSelectionQDStyleVersionZero;
+         qd_style.instance.fontFamily = font->mac_fontnum;
+         qd_style.instance.fontStyle = font->mac_fontface;
+         qd_style.size = font->mac_fontsize;
+         qd_style.hasColor = false;
+
+         err = SetFontInfoForSelection (kFontSelectionQDType,
+                                        1, &qd_style, target);
+       }
+      else
+       err = SetFontInfoForSelection (kFontSelectionATSUIType,
+                                      1, &font->mac_style, target);
+    }
+
+  return err;
+}
+#endif
 
 \f
 /* The Mac Event loop code */
@@ -8546,7 +8555,26 @@ Point saved_menu_event_location;
 
 /* Apple Events */
 #if USE_CARBON_EVENTS
-static Lisp_Object Qhicommand;
+static Lisp_Object Qhi_command;
+#ifdef MAC_OSX
+extern Lisp_Object Qwindow;
+static Lisp_Object Qtoolbar_switch_mode;
+#endif
+#if USE_MAC_FONT_PANEL
+extern Lisp_Object Qfont;
+static Lisp_Object Qpanel_closed, Qselection;
+#endif
+#if USE_MAC_TSM
+static TSMDocumentID tsm_document_id;
+static Lisp_Object Qtext_input;
+static Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event;
+static Lisp_Object Vmac_ts_active_input_overlay;
+extern Lisp_Object Qbefore_string;
+static Lisp_Object Vmac_ts_script_language_on_focus;
+static Lisp_Object saved_ts_script_language_on_focus;
+static ScriptLanguageRecord saved_ts_language;
+static Component saved_ts_component;
+#endif
 #endif
 extern int mac_ready_for_apple_events;
 extern Lisp_Object Qundefined;
@@ -8556,24 +8584,20 @@ extern void mac_find_apple_event_spec P_ ((AEEventClass, AEEventID,
                                           Lisp_Object *));
 extern OSErr init_coercion_handler P_ ((void));
 
-#if TARGET_API_MAC_CARBON
 /* Drag and 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
+OSErr install_drag_handler P_ ((WindowRef));
+void remove_drag_handler P_ ((WindowRef));
 
 #if USE_CARBON_EVENTS
 #ifdef MAC_OSX
 extern void init_service_handler ();
-static Lisp_Object Qservices, Qpaste, Qperform;
+static Lisp_Object Qservice, Qpaste, Qperform;
 #endif
 /* Window Event Handler */
 static pascal OSStatus mac_handle_window_event (EventHandlerCallRef,
                                                EventRef, void *);
 #endif
-OSErr install_window_handler (WindowPtr);
+OSStatus install_window_handler (WindowPtr);
 
 extern void init_emacs_passwd_dir ();
 extern int emacs_main (int, char **, char **);
@@ -8581,6 +8605,81 @@ extern int emacs_main (int, char **, char **);
 extern void initialize_applescript();
 extern void terminate_applescript();
 
+/* Table for translating Mac keycode to X keysym values.  Contributed
+   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*/ 0x8d /*enter on laptops*/, 0x1b /*escape*/, 0, 0,
+  /*0x38*/ 0, 0, 0, 0,
+  /*0x3C*/ 0, 0, 0, 0,
+
+  /*0x40*/ 0, 0xae /*kp-decimal*/, 0, 0xaa /*kp-multiply*/,
+  /*0x44*/ 0, 0xab /*kp-add*/, 0, 0x0b /*clear*/,
+  /*0x48*/ 0, 0, 0, 0xaf /*kp-divide*/,
+  /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp-subtract*/, 0,
+
+  /*0x50*/ 0, 0xbd /*kp-equal*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
+  /*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
+  /*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
+  /*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
+
+  /*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
+  /*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
+  /*0x68*/ 0, 0xca /*f13*/, 0xcd /*f16*/, 0xcb /*f14*/,
+  /*0x6C*/ 0, 0xc7 /*f10*/, 0x0a /*fn+enter on laptops*/, 0xc9 /*f12*/,
+
+  /*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
+};
+
+#ifdef MAC_OSX
+/* Table for translating Mac keycode with the laptop `fn' key to that
+   without it.  Destination symbols in comments are keys on US
+   keyboard, and they may not be the same on other types of keyboards.
+   If the destination is identical to the source (f1 ... f12), it
+   doesn't map `fn' key to a modifier.  */
+static unsigned char fn_keycode_to_keycode_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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+  /*0x30*/ 0, 0, 0, 0,
+  /*0x34*/ 0, 0, 0, 0,
+  /*0x38*/ 0, 0, 0, 0,
+  /*0x3C*/ 0, 0, 0, 0,
+
+  /*0x40*/ 0, 0x2f /*kp-decimal -> '.'*/, 0, 0x23 /*kp-multiply -> 'p'*/,
+  /*0x44*/ 0, 0x2c /*kp-add -> '/'*/, 0, 0x16 /*clear -> '6'*/,
+  /*0x48*/ 0, 0, 0, 0x1d /*kp-/ -> '0'*/,
+  /*0x4C*/ 0x24 /*kp-enter -> return*/, 0, 0x29 /*kp-subtract -> ';'*/, 0,
+
+  /*0x50*/ 0, 0x1b /*kp-equal -> '-'*/, 0x2e /*kp-0 -> 'm'*/, 0x26 /*kp-1 -> 'j'*/,
+  /*0x54*/ 0x28 /*kp-2 -> 'k'*/, 0x25 /*kp-3 -> 'l'*/, 0x20 /*kp-4 -> 'u'*/, 0x22 /*kp-5 ->'i'*/,
+  /*0x58*/ 0x1f /*kp-6 -> 'o'*/, 0x1a /*kp-7 -> '7'*/, 0, 0x1c /*kp-8 -> '8'*/,
+  /*0x5C*/ 0x19 /*kp-9 -> '9'*/, 0, 0, 0,
+
+  /*0x60*/ 0x60 /*f5 = f5*/, 0x61 /*f6 = f6*/, 0x62 /*f7 = f7*/, 0x63 /*f3 = f3*/,
+  /*0x64*/ 0x64 /*f8 = f8*/, 0x65 /*f9 = f9*/, 0, 0x67 /*f11 = f11*/,
+  /*0x68*/ 0, 0, 0, 0,
+  /*0x6C*/ 0, 0x6d /*f10 = f10*/, 0, 0x6f /*f12 = f12*/,
+
+  /*0x70*/ 0, 0, 0, 0x7b /*home -> left*/,
+  /*0x74*/ 0x7e /*pgup -> up*/, 0x33 /*delete -> backspace*/, 0x76 /*f4 = f4*/, 0x7c /*end -> right*/,
+  /*0x78*/ 0x78 /*f2 = f2*/, 0x7d /*pgdown -> down*/, 0x7a /*f1 = f1*/, 0,
+  /*0x7C*/ 0, 0, 0, 0
+};
+#endif /* MAC_OSX */
+
 static unsigned int
 #if USE_CARBON_EVENTS
 mac_to_emacs_modifiers (UInt32 mods)
@@ -8777,6 +8876,7 @@ static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec)
 
 #endif
 
+#ifdef MAC_OS8
 static void
 do_get_menus (void)
 {
@@ -8838,6 +8938,7 @@ do_check_ram_size (void)
       exit (1);
     }
 }
+#endif /* MAC_OS8 */
 
 static void
 do_window_update (WindowPtr win)
@@ -8897,18 +8998,92 @@ is_emacs_window (WindowPtr win)
   return 0;
 }
 
-static void
-do_app_resume ()
+#if USE_MAC_TSM
+static OSStatus
+mac_tsm_resume ()
 {
-  /* Window-activate events will do the job. */
+  OSStatus err;
+  ScriptLanguageRecord slrec, *slptr = NULL;
+
+  err = ActivateTSMDocument (tsm_document_id);
+
+  if (err == noErr)
+    {
+      if (EQ (Vmac_ts_script_language_on_focus, Qt)
+         && EQ (saved_ts_script_language_on_focus, Qt))
+       slptr = &saved_ts_language;
+      else if (CONSP (Vmac_ts_script_language_on_focus)
+              && INTEGERP (XCAR (Vmac_ts_script_language_on_focus))
+              && INTEGERP (XCDR (Vmac_ts_script_language_on_focus))
+              && CONSP (saved_ts_script_language_on_focus)
+              && EQ (XCAR (saved_ts_script_language_on_focus),
+                     XCAR (Vmac_ts_script_language_on_focus))
+              && EQ (XCDR (saved_ts_script_language_on_focus),
+                     XCDR (Vmac_ts_script_language_on_focus)))
+       {
+         slrec.fScript = XINT (XCAR (Vmac_ts_script_language_on_focus));
+         slrec.fLanguage = XINT (XCDR (Vmac_ts_script_language_on_focus));
+         slptr = &slrec;
+       }
+    }
+
+  if (slptr)
+    {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+      err = SetDefaultInputMethodOfClass (saved_ts_component, slptr,
+                                         kKeyboardInputMethodClass);
+#else
+      err = SetDefaultInputMethod (saved_ts_component, slptr);
+#endif
+      if (err == noErr)
+       err = SetTextServiceLanguage (slptr);
+
+      /* Seems to be needed on Mac OS X 10.2.  */
+      if (err == noErr)
+       KeyScript (slptr->fScript | smKeyForceKeyScriptMask);
+    }
+
+  return err;
 }
 
-static void
-do_app_suspend ()
+static OSStatus
+mac_tsm_suspend ()
 {
-  /* Window-deactivate events will do the job. */
-}
+  OSStatus err;
+  ScriptLanguageRecord slrec, *slptr = NULL;
+
+  saved_ts_script_language_on_focus = Vmac_ts_script_language_on_focus;
+
+  if (EQ (Vmac_ts_script_language_on_focus, Qt))
+    {
+      err = GetTextServiceLanguage (&saved_ts_language);
+      if (err == noErr)
+       slptr = &saved_ts_language;
+    }
+  else if (CONSP (Vmac_ts_script_language_on_focus)
+          && INTEGERP (XCAR (Vmac_ts_script_language_on_focus))
+          && INTEGERP (XCDR (Vmac_ts_script_language_on_focus)))
+    {
+      slrec.fScript = XINT (XCAR (Vmac_ts_script_language_on_focus));
+      slrec.fLanguage = XINT (XCDR (Vmac_ts_script_language_on_focus));
+      slptr = &slrec;
+    }
+
+  if (slptr)
+    {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+      GetDefaultInputMethodOfClass (&saved_ts_component, slptr,
+                                   kKeyboardInputMethodClass);
+#else
+      GetDefaultInputMethod (&saved_ts_component, slptr);
+#endif
+    }
 
+  err = DeactivateTSMDocument (tsm_document_id);
+
+  return err;
+}
+#endif
 
 static void
 do_apple_menu (SInt16 menu_item)
@@ -9019,42 +9194,41 @@ do_grow_window (WindowPtr w, EventRecord *e)
 static void
 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;
+  int columns, rows, width, height;
   struct frame *f = mac_window_to_frame (w);
   struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
-
 #if TARGET_API_MAC_CARBON
-  {
-    Point standard_size;
+  Point standard_size;
 
-    standard_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
-    standard_size.v = dpyinfo->height;
+  standard_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
+  standard_size.v = dpyinfo->height;
 
-    if (IsWindowInStandardState (w, &standard_size, &zoom_rect))
-      zoom_in_or_out = inZoomIn;
-    else
-      {
-       /* 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;
-      }
+  if (IsWindowInStandardState (w, &standard_size, &zoom_rect))
+    zoom_in_or_out = inZoomIn;
+  else
+    {
+      /* Adjust the standard size according to character boundaries.  */
 
-    ZoomWindowIdeal (w, zoom_in_or_out, &standard_size);
-  }
+      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 */
+  GrafPtr save_port;
+  Point top_left;
+  int w_title_height;
+
   GetPort (&save_port);
 
   SetPortWindowPort (w);
@@ -9117,50 +9291,87 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out)
   x_real_positions (f, &f->left_pos, &f->top_pos);
 }
 
-OSErr
+void
 mac_store_apple_event (class, id, desc)
      Lisp_Object class, id;
      const AEDesc *desc;
 {
-  OSErr err = noErr;
   struct input_event buf;
-  AEDesc *desc_copy;
 
-  desc_copy = xmalloc (sizeof (AEDesc));
-  if (desc_copy == NULL)
-    err = memFullErr;
-  else
-    err = AEDuplicateDesc (desc, desc_copy);
-  if (err == noErr)
-    {
-      EVENT_INIT (buf);
+  EVENT_INIT (buf);
+
+  buf.kind = MAC_APPLE_EVENT;
+  buf.x = class;
+  buf.y = id;
+  XSETFRAME (buf.frame_or_window,
+            mac_focus_frame (&one_mac_display_info));
+  /* Now that Lisp object allocations are protected by BLOCK_INPUT, it
+     is safe to use them during read_socket_hook.  */
+  buf.arg = mac_aedesc_to_lisp (desc);
+  kbd_buffer_store_event (&buf);
+}
+
+#if TARGET_API_MAC_CARBON
+static OSStatus
+mac_store_event_ref_as_apple_event (class, id, class_key, id_key,
+                                   event, num_params, names, types)
+     AEEventClass class;
+     AEEventID id;
+     Lisp_Object class_key, id_key;
+     EventRef event;
+     UInt32 num_params;
+     EventParamName *names;
+     EventParamType *types;
+{
+  OSStatus err = eventNotHandledErr;
+  Lisp_Object binding;
 
-      buf.kind = MAC_APPLE_EVENT;
-      buf.x = class;
-      buf.y = id;
-      buf.code = (int)desc_copy;
-      XSETFRAME (buf.frame_or_window,
-                mac_focus_frame (&one_mac_display_info));
-      buf.arg = Qnil;
-      kbd_buffer_store_event (&buf);
+  mac_find_apple_event_spec (class, id, &class_key, &id_key, &binding);
+  if (!NILP (binding) && !EQ (binding, Qundefined))
+    {
+      if (INTEGERP (binding))
+       err = XINT (binding);
+      else
+       {
+         AppleEvent apple_event;
+         err = create_apple_event_from_event_ref (event, num_params,
+                                                  names, types,
+                                                  &apple_event);
+         if (err == noErr)
+           {
+             mac_store_apple_event (class_key, id_key, &apple_event);
+             AEDisposeDesc (&apple_event);
+             /* Post a harmless event so as to wake up from
+                ReceiveNextEvent.  */
+             mac_post_mouse_moved_event ();
+           }
+       }
     }
 
   return err;
 }
 
-Lisp_Object
-mac_make_lispy_event_code (code)
-     int code;
+void
+mac_store_drag_event (window, mouse_pos, modifiers, desc)
+     WindowRef window;
+     Point mouse_pos;
+     SInt16 modifiers;
+     const AEDesc *desc;
 {
-  AEDesc *desc = (AEDesc *)code;
-  Lisp_Object obj;
+  struct input_event buf;
 
-  obj = mac_aedesc_to_lisp (desc);
-  AEDisposeDesc (desc);
-  xfree (desc);
+  EVENT_INIT (buf);
 
-  return obj;
+  buf.kind = DRAG_N_DROP_EVENT;
+  buf.modifiers = mac_to_emacs_modifiers (modifiers);
+  buf.timestamp = TickCount () * (1000 / 60);
+  XSETINT (buf.x, mouse_pos.h);
+  XSETINT (buf.y, mouse_pos.v);
+  XSETFRAME (buf.frame_or_window, mac_window_to_frame (window));
+  buf.arg = mac_aedesc_to_lisp (desc);
+  kbd_buffer_store_event (&buf);
 }
+#endif
 
 #if USE_CARBON_EVENTS
 static pascal OSStatus
@@ -9171,7 +9382,11 @@ mac_handle_command_event (next_handler, event, data)
 {
   OSStatus result, err;
   HICommand command;
-  Lisp_Object class_key, id_key, binding;
+  static EventParamName names[] = {kEventParamDirectObject,
+                                  kEventParamKeyModifiers};
+  static EventParamType types[] = {typeHICommand,
+                                  typeUInt32};
+  int num_params = sizeof (names) / sizeof (names[0]);
 
   result = CallNextEventHandler (next_handler, event);
   if (result != eventNotHandledErr)
@@ -9183,40 +9398,17 @@ mac_handle_command_event (next_handler, event, data)
   if (err != noErr || command.commandID == 0)
     return eventNotHandledErr;
 
-  /* A HICommand event is mapped to an Apple event whose event class
-     symbol is `hicommand' and event ID is its command ID.  */
-  class_key = Qhicommand;
-  mac_find_apple_event_spec (0, command.commandID,
-                            &class_key, &id_key, &binding);
-  if (!NILP (binding) && !EQ (binding, Qundefined))
-    if (INTEGERP (binding))
-      return XINT (binding);
-    else
-      {
-       AppleEvent apple_event;
-       UInt32 modifiers;
-       static EventParamName names[] = {kEventParamDirectObject,
-                                        kEventParamKeyModifiers};
-       static EventParamType types[] = {typeHICommand,
-                                        typeUInt32};
-       err = create_apple_event_from_event_ref (event, 2, names, types,
-                                                &apple_event);
-       if (err == noErr)
-         {
-           err = mac_store_apple_event (class_key, id_key, &apple_event);
-           AEDisposeDesc (&apple_event);
-         }
-       if (err == noErr)
-         return noErr;
-      }
-
-  return eventNotHandledErr;
+  /* A HI command event is mapped to an Apple event whose event class
+     symbol is `hi-command' and event ID is its command ID.  */
+  err = mac_store_event_ref_as_apple_event (0, command.commandID,
+                                           Qhi_command, Qnil,
+                                           event, num_params, names, types);
+  return err == noErr ? noErr : eventNotHandledErr;
 }
 
-static OSErr
+static OSStatus
 init_command_handler ()
 {
-  OSErr err = noErr;
   EventTypeSpec specs[] = {{kEventClassCommand, kEventCommandProcess}};
   static EventHandlerUPP handle_command_eventUPP = NULL;
 
@@ -9314,6 +9506,57 @@ mac_handle_window_event (next_handler, event, data)
       return noErr;
 
       break;
+
+    case kEventWindowClose:
+      {
+       struct input_event buf;
+
+       EVENT_INIT (buf);
+       buf.kind = DELETE_WINDOW_EVENT;
+       XSETFRAME (buf.frame_or_window, mac_window_to_frame (wp));
+       buf.arg = Qnil;
+       kbd_buffer_store_event (&buf);
+      }
+      return noErr;
+
+#ifdef MAC_OSX
+    case kEventWindowToolbarSwitchMode:
+      result = CallNextEventHandler (next_handler, event);
+      {
+       static EventParamName names[] = {kEventParamDirectObject,
+                                        kEventParamWindowMouseLocation,
+                                        kEventParamKeyModifiers,
+                                        kEventParamMouseButton,
+                                        kEventParamClickCount,
+                                        kEventParamMouseChord};
+       static EventParamType types[] = {typeWindowRef,
+                                        typeQDPoint,
+                                        typeUInt32,
+                                        typeMouseButton,
+                                        typeUInt32,
+                                        typeUInt32};
+       int num_params = sizeof (names) / sizeof (names[0]);
+
+       err = mac_store_event_ref_as_apple_event (0, 0,
+                                                 Qwindow,
+                                                 Qtoolbar_switch_mode,
+                                                 event, num_params,
+                                                 names, types);
+      }
+      return err == noErr ? noErr : result;
+#endif
+
+#if USE_MAC_TSM
+    case kEventWindowFocusAcquired:
+      result = CallNextEventHandler (next_handler, event);
+      err = mac_tsm_resume ();
+      return err == noErr ? noErr : result;
+
+    case kEventWindowFocusRelinquish:
+      result = CallNextEventHandler (next_handler, event);
+      err = mac_tsm_suspend ();
+      return err == noErr ? noErr : result;
+#endif
     }
 
   return eventNotHandledErr;
@@ -9388,45 +9631,289 @@ mac_handle_mouse_event (next_handler, event, data)
   return eventNotHandledErr;
 }
 
-#ifdef MAC_OSX
-OSErr
-mac_store_services_event (event)
+#if USE_MAC_FONT_PANEL
+static pascal OSStatus
+mac_handle_font_event (next_handler, event, data)
+     EventHandlerCallRef next_handler;
      EventRef event;
+     void *data;
 {
-  OSErr err;
-  AppleEvent apple_event;
+  OSStatus result, err;
   Lisp_Object id_key;
+  int num_params;
+  EventParamName *names;
+  EventParamType *types;
+  static EventParamName names_sel[] = {kEventParamATSUFontID,
+                                      kEventParamATSUFontSize,
+                                      kEventParamFMFontFamily,
+                                      kEventParamFMFontSize,
+                                      kEventParamFontColor};
+  static EventParamType types_sel[] = {typeATSUFontID,
+                                      typeATSUSize,
+                                      typeFMFontFamily,
+                                      typeFMFontSize,
+                                      typeFontColor};
+
+  result = CallNextEventHandler (next_handler, event);
+  if (result != eventNotHandledErr)
+    return result;
 
   switch (GetEventKind (event))
     {
-    case kEventServicePaste:
-      id_key = Qpaste;
-      err = create_apple_event_from_event_ref (event, 0, NULL, NULL,
-                                              &apple_event);
+    case kEventFontPanelClosed:
+      id_key = Qpanel_closed;
+      num_params = 0;
+      names = NULL;
+      types = NULL;
       break;
 
-    case kEventServicePerform:
-      {
-       static EventParamName names[] = {kEventParamServiceMessageName,
-                                        kEventParamServiceUserData};
-       static EventParamType types[] = {typeCFStringRef,
-                                        typeCFStringRef};
-
-       id_key = Qperform;
-       err = create_apple_event_from_event_ref (event, 2, names, types,
-                                                &apple_event);
-      }
+    case kEventFontSelection:
+      id_key = Qselection;
+      num_params = sizeof (names_sel) / sizeof (names_sel[0]);
+      names = names_sel;
+      types = types_sel;
       break;
-
-    default:
-      abort ();
     }
 
-  if (err == noErr)
-    {
-      err = mac_store_apple_event (Qservices, id_key, &apple_event);
-      AEDisposeDesc (&apple_event);
-    }
+  err = mac_store_event_ref_as_apple_event (0, 0, Qfont, id_key,
+                                           event, num_params,
+                                           names, types);
+
+  return err == noErr ? noErr : eventNotHandledErr;
+}
+#endif
+
+#if USE_MAC_TSM
+static pascal OSStatus
+mac_handle_text_input_event (next_handler, event, data)
+     EventHandlerCallRef next_handler;
+     EventRef event;
+     void *data;
+{
+  OSStatus result, err = noErr;
+  Lisp_Object id_key = Qnil;
+  int num_params;
+  EventParamName *names;
+  EventParamType *types;
+  static UInt32 seqno_uaia = 0;
+  static EventParamName names_uaia[] =
+    {kEventParamTextInputSendComponentInstance,
+     kEventParamTextInputSendRefCon,
+     kEventParamTextInputSendSLRec,
+     kEventParamTextInputSendFixLen,
+     kEventParamTextInputSendText,
+     kEventParamTextInputSendUpdateRng,
+     kEventParamTextInputSendHiliteRng,
+     kEventParamTextInputSendClauseRng,
+     kEventParamTextInputSendPinRng,
+     kEventParamTextInputSendTextServiceEncoding,
+     kEventParamTextInputSendTextServiceMacEncoding,
+     EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER};
+  static EventParamType types_uaia[] =
+    {typeComponentInstance,
+     typeLongInteger,
+     typeIntlWritingCode,
+     typeLongInteger,
+#ifdef MAC_OSX
+     typeUnicodeText,
+#else
+     typeChar,
+#endif
+     typeTextRangeArray,
+     typeTextRangeArray,
+     typeOffsetArray,
+     typeTextRange,
+     typeUInt32,
+     typeUInt32,
+     typeUInt32};
+  static EventParamName names_ufke[] =
+    {kEventParamTextInputSendComponentInstance,
+     kEventParamTextInputSendRefCon,
+     kEventParamTextInputSendSLRec,
+     kEventParamTextInputSendText};
+  static EventParamType types_ufke[] =
+    {typeComponentInstance,
+     typeLongInteger,
+     typeIntlWritingCode,
+     typeUnicodeText};
+
+  result = CallNextEventHandler (next_handler, event);
+
+  switch (GetEventKind (event))
+    {
+    case kEventTextInputUpdateActiveInputArea:
+      id_key = Qupdate_active_input_area;
+      num_params = sizeof (names_uaia) / sizeof (names_uaia[0]);
+      names = names_uaia;
+      types = types_uaia;
+      SetEventParameter (event, EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER,
+                        typeUInt32, sizeof (UInt32), &seqno_uaia);
+      seqno_uaia++;
+      break;
+
+    case kEventTextInputUnicodeForKeyEvent:
+      {
+       EventRef kbd_event;
+       UInt32 actual_size, modifiers, mapped_modifiers;
+
+       err = GetEventParameter (event, kEventParamTextInputSendKeyboardEvent,
+                                typeEventRef, NULL, sizeof (EventRef), NULL,
+                                &kbd_event);
+       if (err == noErr)
+         err = GetEventParameter (kbd_event, kEventParamKeyModifiers,
+                                  typeUInt32, NULL,
+                                  sizeof (UInt32), NULL, &modifiers);
+       if (err == noErr)
+         {
+           mapped_modifiers =
+             (NILP (Vmac_control_modifier) ? 0 : controlKey)
+             | (NILP (Vmac_option_modifier) ? 0 : optionKey)
+             | (NILP (Vmac_command_modifier) ? 0 : cmdKey);
+#ifdef MAC_OSX
+           mapped_modifiers |=
+             (NILP (Vmac_function_modifier) ? 0 : kEventKeyModifierFnMask);
+#endif
+           if (modifiers & mapped_modifiers)
+             /* There're mapped modifier keys.  Process it in
+                XTread_socket.  */
+             return eventNotHandledErr;
+         }
+       if (err == noErr)
+         err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
+                                  typeUnicodeText, NULL, 0, &actual_size,
+                                  NULL);
+       if (err == noErr && actual_size == sizeof (UniChar))
+         {
+           UniChar code;
+
+           err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
+                                    typeUnicodeText, NULL,
+                                    sizeof (UniChar), NULL, &code);
+           if (err == noErr && code < 0x80)
+             {
+               /* ASCII character.  Process it in XTread_socket.  */
+               if (read_socket_inev && code >= 0x20 && code <= 0x7e)
+                 {
+                   UInt32 key_code;
+
+                   err = GetEventParameter (kbd_event, kEventParamKeyCode,
+                                            typeUInt32, NULL, sizeof (UInt32),
+                                            NULL, &key_code);
+                   if (!(err == noErr && key_code <= 0x7f
+                         && keycode_to_xkeysym_table [key_code]))
+                     {
+                       struct frame *f =
+                         mac_focus_frame (&one_mac_display_info);
+
+                       read_socket_inev->kind = ASCII_KEYSTROKE_EVENT;
+                       read_socket_inev->code = code;
+                       read_socket_inev->modifiers =
+                         mac_to_emacs_modifiers (modifiers);
+                       read_socket_inev->modifiers |=
+                         (extra_keyboard_modifiers
+                          & (meta_modifier | alt_modifier
+                             | hyper_modifier | super_modifier));
+                       XSETFRAME (read_socket_inev->frame_or_window, f);
+                     }
+                 }
+               return eventNotHandledErr;
+             }
+         }
+      }
+      /* Non-ASCII keystrokes without mapped modifiers are processed
+        at the Lisp level.  */
+      id_key = Qunicode_for_key_event;
+      num_params = sizeof (names_ufke) / sizeof (names_ufke[0]);
+      names = names_ufke;
+      types = types_ufke;
+      break;
+
+    case kEventTextInputOffsetToPos:
+      {
+       struct frame *f;
+       struct window *w;
+       Point p;
+
+       if (!OVERLAYP (Vmac_ts_active_input_overlay))
+         return eventNotHandledErr;
+
+       /* Strictly speaking, this is not always correct because
+          previous events may change some states about display.  */
+       if (NILP (Foverlay_get (Vmac_ts_active_input_overlay, Qbefore_string)))
+         {
+           /* Active input area is displayed in the echo area.  */
+           w = XWINDOW (echo_area_window);
+           f = WINDOW_XFRAME (w);
+         }
+       else
+         {
+           /* Active input area is displayed around the current point.  */
+           f = SELECTED_FRAME ();
+           w = XWINDOW (f->selected_window);
+         }
+
+       p.h = (WINDOW_TO_FRAME_PIXEL_X (w, w->cursor.x)
+              + WINDOW_LEFT_FRINGE_WIDTH (w));
+       p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, w->cursor.y)
+              + FONT_BASE (FRAME_FONT (f)));
+       SetPortWindowPort (FRAME_MAC_WINDOW (f));
+       LocalToGlobal (&p);
+       err = SetEventParameter (event, kEventParamTextInputReplyPoint,
+                                typeQDPoint, sizeof (typeQDPoint), &p);
+      }
+      break;
+
+    default:
+      abort ();
+    }
+
+  if (!NILP (id_key))
+    err = mac_store_event_ref_as_apple_event (0, 0, Qtext_input, id_key,
+                                             event, num_params,
+                                             names, types);
+
+  return err == noErr ? noErr : result;
+}
+#endif
+
+#ifdef MAC_OSX
+OSStatus
+mac_store_service_event (event)
+     EventRef event;
+{
+  OSStatus err;
+  Lisp_Object id_key;
+  int num_params;
+  EventParamName *names;
+  EventParamType *types;
+  static EventParamName names_pfm[] = {kEventParamServiceMessageName,
+                                      kEventParamServiceUserData};
+  static EventParamType types_pfm[] = {typeCFStringRef,
+                                      typeCFStringRef};
+
+  switch (GetEventKind (event))
+    {
+    case kEventServicePaste:
+      id_key = Qpaste;
+      num_params = 0;
+      names = NULL;
+      types = NULL;
+      break;
+
+    case kEventServicePerform:
+      id_key = Qperform;
+      num_params = sizeof (names_pfm) / sizeof (names_pfm[0]);
+      names = names_pfm;
+      types = types_pfm;
+      break;
+
+    default:
+      abort ();
+    }
+
+  err = mac_store_event_ref_as_apple_event (0, 0, Qservice, id_key,
+                                           event, num_params,
+                                           names, types);
 
   return err;
 }
@@ -9434,11 +9921,11 @@ mac_store_services_event (event)
 #endif /* USE_CARBON_EVENTS */
 
 
-OSErr
+OSStatus
 install_window_handler (window)
      WindowPtr window;
 {
-  OSErr err = noErr;
+  OSStatus err = noErr;
 #if USE_CARBON_EVENTS
   EventTypeSpec specs_window[] =
     {{kEventClassWindow, kEventWindowUpdate},
@@ -9446,15 +9933,45 @@ install_window_handler (window)
      {kEventClassWindow, kEventWindowShown},
      {kEventClassWindow, kEventWindowHidden},
      {kEventClassWindow, kEventWindowExpanded},
-     {kEventClassWindow, kEventWindowCollapsed}};
+     {kEventClassWindow, kEventWindowCollapsed},
+     {kEventClassWindow, kEventWindowClose},
+#ifdef MAC_OSX
+     {kEventClassWindow, kEventWindowToolbarSwitchMode},
+#endif
+#if USE_MAC_TSM
+     {kEventClassWindow, kEventWindowFocusAcquired},
+     {kEventClassWindow, kEventWindowFocusRelinquish},
+#endif
+  };
   EventTypeSpec specs_mouse[] = {{kEventClassMouse, kEventMouseWheelMoved}};
   static EventHandlerUPP handle_window_eventUPP = NULL;
   static EventHandlerUPP handle_mouse_eventUPP = NULL;
+#if USE_MAC_FONT_PANEL
+  EventTypeSpec specs_font[] = {{kEventClassFont, kEventFontPanelClosed},
+                               {kEventClassFont, kEventFontSelection}};
+  static EventHandlerUPP handle_font_eventUPP = NULL;
+#endif
+#if USE_MAC_TSM
+  EventTypeSpec specs_text_input[] =
+    {{kEventClassTextInput, kEventTextInputUpdateActiveInputArea},
+     {kEventClassTextInput, kEventTextInputUnicodeForKeyEvent},
+     {kEventClassTextInput, kEventTextInputOffsetToPos}};
+  static EventHandlerUPP handle_text_input_eventUPP = NULL;
+#endif
 
   if (handle_window_eventUPP == NULL)
     handle_window_eventUPP = NewEventHandlerUPP (mac_handle_window_event);
   if (handle_mouse_eventUPP == NULL)
     handle_mouse_eventUPP = NewEventHandlerUPP (mac_handle_mouse_event);
+#if USE_MAC_FONT_PANEL
+  if (handle_font_eventUPP == NULL)
+    handle_font_eventUPP = NewEventHandlerUPP (mac_handle_font_event);
+#endif
+#if USE_MAC_TSM
+  if (handle_text_input_eventUPP == NULL)
+    handle_text_input_eventUPP =
+      NewEventHandlerUPP (mac_handle_text_input_event);
+#endif
   err = InstallWindowEventHandler (window, handle_window_eventUPP,
                                   GetEventTypeCount (specs_window),
                                   specs_window, NULL, NULL);
@@ -9462,18 +9979,22 @@ install_window_handler (window)
     err = InstallWindowEventHandler (window, handle_mouse_eventUPP,
                                     GetEventTypeCount (specs_mouse),
                                     specs_mouse, 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 USE_MAC_FONT_PANEL
   if (err == noErr)
-    err = InstallTrackingHandler (mac_do_track_dragUPP, window, NULL);
+    err = InstallWindowEventHandler (window, handle_font_eventUPP,
+                                    GetEventTypeCount (specs_font),
+                                    specs_font, NULL, NULL);
+#endif
+#if USE_MAC_TSM
   if (err == noErr)
-    err = InstallReceiveHandler (mac_do_receive_dragUPP, window, NULL);
+    err = InstallWindowEventHandler (window, handle_text_input_eventUPP,
+                                    GetEventTypeCount (specs_text_input),
+                                    specs_text_input, window, NULL);
 #endif
+#endif
+  if (err == noErr)
+    err = install_drag_handler (window);
+
   return err;
 }
 
@@ -9481,167 +10002,9 @@ 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
-}
-
-#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;
+  remove_drag_handler (window);
 }
 
-static pascal OSErr
-mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
-                    DragReference theDrag)
-{
-  short items;
-  short index;
-  FlavorFlags theFlags;
-  Point mouse;
-  OSErr result;
-  ItemReference theItem;
-  HFSFlavor data;
-  Size size = sizeof (HFSFlavor);
-  Lisp_Object file_list;
-
-  if (GetFrontWindowOfClass (kMovableModalWindowClass, false))
-    return dragNotAcceptedErr;
-
-  file_list = Qnil;
-  GetDragMouse (theDrag, &mouse, 0L);
-  CountDragItems (theDrag, &items);
-  for (index = 1; index <= items; index++)
-    {
-      /* Only handle file references.  */
-      GetDragItemReferenceNumber (theDrag, index, &theItem);
-      result = GetFlavorFlags (theDrag, theItem, flavorTypeHFS, &theFlags);
-      if (result == noErr)
-       {
-         OSErr err;
-         AEDesc desc;
-
-         err = GetFlavorData (theDrag, theItem, flavorTypeHFS,
-                              &data, &size, 0L);
-         if (err == noErr)
-           err = AECoercePtr (typeFSS, &data.fileSpec, sizeof (FSSpec),
-                              TYPE_FILE_NAME, &desc);
-         if (err == noErr)
-           {
-             Lisp_Object file;
-
-             /* x-dnd functions expect undecoded filenames.  */
-             file = make_uninit_string (AEGetDescDataSize (&desc));
-             err = AEGetDescData (&desc, SDATA (file), SBYTES (file));
-             if (err == noErr)
-               file_list = Fcons (file, file_list);
-             AEDisposeDesc (&desc);
-           }
-       }
-    }
-  /* If there are items in the list, construct an event and post it to
-     the queue like an interrupt using kbd_buffer_store_event.  */
-  if (!NILP (file_list))
-    {
-      struct input_event event;
-      Lisp_Object frame;
-      struct frame *f = mac_window_to_frame (window);
-      SInt16 modifiers;
-
-      GlobalToLocal (&mouse);
-      GetDragModifiers (theDrag, NULL, NULL, &modifiers);
-
-      event.kind = DRAG_N_DROP_EVENT;
-      event.code = 0;
-      event.modifiers = mac_to_emacs_modifiers (modifiers);
-      event.timestamp = TickCount () * (1000 / 60);
-      XSETINT (event.x, mouse.h);
-      XSETINT (event.y, mouse.v);
-      XSETFRAME (frame, f);
-      event.frame_or_window = frame;
-      event.arg = file_list;
-      /* Post to the interrupt queue */
-      kbd_buffer_store_event (&event);
-      /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */
-      {
-       ProcessSerialNumber psn;
-       GetCurrentProcess (&psn);
-       SetFrontProcess (&psn);
-      }
-
-      return noErr;
-    }
-  else
-    return dragNotAcceptedErr;
-}
-#endif
-
 
 #if __profile__
 void
@@ -9725,169 +10088,6 @@ main (void)
 }
 #endif
 
-/* Table for translating Mac keycode to X keysym values.  Contributed
-   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*/ 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, 0x0b /*clear*/,
-  /*0x48*/ 0, 0, 0, 0xaf /*kp-/*/,
-  /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp--*/, 0,
-
-  /*0x50*/ 0, 0xbd /*kp-=*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
-  /*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
-  /*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
-  /*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
-
-  /*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*/, 0x0a /*fn+enter on laptops*/, 0xc9 /*f12*/,
-
-  /*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
-};
-
-
-static int
-keycode_to_xkeysym (int keyCode, int *xKeySym)
-{
-  *xKeySym = keycode_to_xkeysym_table [keyCode & 0x7f];
-  return *xKeySym != 0;
-}
-
-static unsigned char fn_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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
-  /*0x30*/ 0, 0, 0, 0,
-  /*0x34*/ 0, 0, 0, 0,
-  /*0x38*/ 0, 0, 0, 0,
-  /*0x3C*/ 0, 0, 0, 0,
-
-  /*0x40*/ 0, 0x2e /*kp-. = .*/, 0, 0x50 /*kp-* = 'p'*/,
-  /*0x44*/ 0, '/' /*kp-+*/, 0, 0,
-  /*0x48*/ 0, 0, 0, 0x30 /*kp-/ = '0'*/,
-  /*0x4C*/ 0, 0, 0x3b /*kp-- = ';'*/, 0,
-
-  /*0x50*/ 0, 0x2d /*kp-= = '-'*/, 0x6d /*kp-0 = 'm'*/, 0x6a /*kp-1 = 'j'*/,
-  /*0x54*/ 0x6b /*kp-2 = 'k'*/, 0x6c /*kp-3 = 'l'*/, 'u' /*kp-4*/, 'i' /*kp-5*/,
-  /*0x58*/ 'o' /*kp-6*/, '7' /*kp-7*/, 0, '8' /*kp-8*/,
-  /*0x5C*/ '9' /*kp-9*/, 0, 0, 0,
-
-  /*0x60*/ 0, 0, 0, 0,
-  /*0x64*/ 0, 0, 0, 0,
-  /*0x68*/ 0, 0, 0, 0,
-  /*0x6C*/ 0, 0, 0, 0,
-
-  /*0x70*/ 0, 0, 0, 0,
-  /*0x74*/ 0, 0, 0, 0,
-  /*0x78*/ 0, 0, 0, 0,
-  /*0x7C*/ 0, 0, 0, 0
-};
-static int
-convert_fn_keycode (EventRef eventRef, int keyCode, int *newCode)
-{
-#ifdef MAC_OSX
-  /* Use the special map to translate keys when function modifier is
-     to be caught. KeyTranslate can't be used in that case.
-     We can't detect the function key using the input_event.modifiers,
-     because this uses the high word of an UInt32. Therefore,
-     we'll just read it out of the original eventRef.
-  */
-
-
-  /* TODO / known issues
-
-  - Fn-Shift-j is regonized as Fn-j and not Fn-J.
-  The above table always translates to lower characters. We need to use
-  the KCHR keyboard resource (KeyTranslate() ) to map k->K and 8->*.
-
-  - The table is meant for English language keyboards, and it will work
-  for many others with the exception of key combinations like Fn-ö on
-  a German keyboard, which is currently mapped to Fn-;.
-  How to solve this without keeping separate tables for all keyboards
-  around? KeyTranslate isn't of much help here, as it only takes a 16-bit
-  value for keycode with the modifiers in he high byte, i.e. no room for the
-  Fn modifier. That's why we need the table.
-
-  */
-  OSStatus err;
-  UInt32 mods = 0;
-  if (!NILP(Vmac_function_modifier))
-    {
-      err = GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32,
-                              NULL, sizeof (UInt32), NULL, &mods);
-      if (err != noErr && mods & kEventKeyModifierFnMask)
-       {  *newCode = fn_keycode_to_xkeysym_table [keyCode & 0x7f];
-
-         return (*newCode != 0);
-       }
-    }
-#endif
-  return false;
-}
-
-static int
-backtranslate_modified_keycode(int mods, int keycode, int def)
-{
-  EventModifiers mapped_modifiers =
-    (NILP (Vmac_control_modifier) ? 0 : controlKey)
-    | (NILP (Vmac_option_modifier) ? 0 : optionKey)
-    | (NILP (Vmac_command_modifier) ? 0 : cmdKey);
-
-  if (mods & mapped_modifiers)
-    {
-      /* This code comes from Keyboard Resource,
-        Appendix C of IM - Text.  This is necessary
-        since shift is ignored in KCHR table
-        translation when option or command is pressed.
-        It also does not translate correctly
-        control-shift chars like C-% so mask off shift
-        here also.
-
-        Not done for combinations with the option key (alt)
-        unless it is to be caught by Emacs:  this is
-        to preserve key combinations translated by the OS
-        such as Alt-3.
-      */
-      /* Mask off modifier keys that are mapped to some Emacs
-        modifiers.  */
-      int new_modifiers = mods & ~mapped_modifiers;
-      /* set high byte of keycode to modifier high byte*/
-      int new_keycode = keycode | new_modifiers;
-      Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
-      unsigned long some_state = 0;
-      return (int) KeyTranslate (kchr_ptr, new_keycode,
-                                &some_state) & 0xff;
-      /* TO DO: Recognize two separate resulting characters, "for
-        example, when the user presses Option-E followed by N, you
-        can map this through the KeyTranslate function using the
-        U.S. 'KCHR' resource to produce Â´n, which KeyTranslate
-        returns as two characters in the bytes labeled Character code
-        1 and Character code 2." (from Carbon API doc) */
-
-    }
-  else
-    return def;
-}
-
-
 #if !USE_CARBON_EVENTS
 static RgnHandle mouse_region = NULL;
 
@@ -9927,6 +10127,55 @@ mac_wait_next_event (er, sleep_time, dequeue)
 }
 #endif /* not USE_CARBON_EVENTS */
 
+#if TARGET_API_MAC_CARBON
+OSStatus
+mac_post_mouse_moved_event ()
+{
+  EventRef event = NULL;
+  OSStatus err;
+
+  err = CreateEvent (NULL, kEventClassMouse, kEventMouseMoved, 0,
+                    kEventAttributeNone, &event);
+  if (err == noErr)
+    {
+      Point mouse_pos;
+
+      GetMouse (&mouse_pos);
+      LocalToGlobal (&mouse_pos);
+      err = SetEventParameter (event, kEventParamMouseLocation, typeQDPoint,
+                              sizeof (Point), &mouse_pos);
+    }
+  if (err == noErr)
+    {
+      UInt32 modifiers = GetCurrentKeyModifiers ();
+
+      err = SetEventParameter (event, kEventParamKeyModifiers, typeUInt32,
+                              sizeof (UInt32), &modifiers);
+    }
+  if (err == noErr)
+    err = PostEventToQueue (GetCurrentEventQueue (), event,
+                           kEventPriorityStandard);
+  if (event)
+    ReleaseEvent (event);
+
+  return err;
+}
+
+static void
+mac_set_unicode_keystroke_event (code, buf)
+     UniChar code;
+     struct input_event *buf;
+{
+  int charset_id, c1, c2;
+
+  if (code < 0x80)
+    buf->kind = ASCII_KEYSTROKE_EVENT;
+  else
+    buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+  buf->code = code;
+}
+#endif
+
 /* Emacs calls this whenever it wants to read an input event from the
    user. */
 int
@@ -9974,10 +10223,6 @@ XTread_socket (sd, expected, hold_quit)
       struct frame *f;
       unsigned long timestamp;
 
-      /* It is necessary to set this (additional) argument slot of an
-        event to nil because keyboard.c protects incompletely
-        processed event from being garbage collected by placing them
-        in the kbd_buffer_gcpro vector.  */
       EVENT_INIT (inev);
       inev.kind = NO_EVENT;
       inev.arg = Qnil;
@@ -10054,7 +10299,13 @@ XTread_socket (sd, expected, hold_quit)
                break;
 
              case inContent:
-               if (window_ptr != FRAME_MAC_WINDOW (mac_focus_frame (dpyinfo)))
+               if (
+#if TARGET_API_MAC_CARBON
+                   FrontNonFloatingWindow ()
+#else
+                   FrontWindow ()
+#endif
+                   != window_ptr)
                  SelectWindow (window_ptr);
                else
                  {
@@ -10092,18 +10343,18 @@ XTread_socket (sd, expected, hold_quit)
                    XSETINT (inev.x, mouse_loc.h);
                    XSETINT (inev.y, mouse_loc.v);
 
-                   if (dpyinfo->grabbed && tracked_scroll_bar
-                       || ch != 0
+                   if ((dpyinfo->grabbed && tracked_scroll_bar)
+                       || (ch != 0
 #ifndef USE_TOOLKIT_SCROLL_BARS
-                       /* control_part_code becomes kControlNoPart if
-                          a progress indicator is clicked.  */
-                       && control_part_code != kControlNoPart
+                           /* control_part_code becomes kControlNoPart if
+                              a progress indicator is clicked.  */
+                           && control_part_code != kControlNoPart
 #else  /* USE_TOOLKIT_SCROLL_BARS */
 #ifdef MAC_OSX
-                       && control_kind.kind == kControlKindScrollBar
+                           && control_kind.kind == kControlKindScrollBar
 #endif /* MAC_OSX */
 #endif /* USE_TOOLKIT_SCROLL_BARS */
-                       )
+                           ))
                      {
                        struct scroll_bar *bar;
 
@@ -10203,6 +10454,16 @@ XTread_socket (sd, expected, hold_quit)
 
              case inDrag:
 #if TARGET_API_MAC_CARBON
+             case inProxyIcon:
+               if (IsWindowPathSelectClick (window_ptr, &er))
+                 {
+                   WindowPathSelect (window_ptr, NULL, NULL);
+                   break;
+                 }
+               if (part_code == inProxyIcon
+                   && (TrackWindowProxyDrag (window_ptr, er.where)
+                       != errUserWantsToDragWindow))
+                 break;
                DragWindow (window_ptr, er.where, NULL);
 #else /* not TARGET_API_MAC_CARBON */
                DragWindow (window_ptr, er.where, &qd.screenBits.bounds);
@@ -10262,10 +10523,12 @@ XTread_socket (sd, expected, hold_quit)
          switch ((er.message >> 24) & 0x000000FF)
            {
            case suspendResumeMessage:
-             if ((er.message & resumeFlag) == 1)
-               do_app_resume ();
+#if USE_MAC_TSM
+             if (er.message & resumeFlag)
+               mac_tsm_resume ();
              else
-               do_app_suspend ();
+               mac_tsm_suspend ();
+#endif
              break;
 
            case mouseMovedMessage:
@@ -10423,110 +10686,219 @@ XTread_socket (sd, expected, hold_quit)
          break;
 
        case keyDown:
+       case keyUp:
        case autoKey:
          {
            int keycode = (er.message & keyCodeMask) >> 8;
-           int xkeysym;
+           static SInt16 last_key_script = -1;
+           SInt16 current_key_script;
+           UInt32 modifiers = er.modifiers, mapped_modifiers;
+
+           mapped_modifiers =
+             (NILP (Vmac_control_modifier) ? 0 : controlKey)
+             | (NILP (Vmac_option_modifier) ? 0 : optionKey)
+             | (NILP (Vmac_command_modifier) ? 0 : cmdKey);
 
 #if USE_CARBON_EVENTS && defined (MAC_OSX)
+           mapped_modifiers |=
+             (NILP (Vmac_function_modifier) ? 0 : kEventKeyModifierFnMask);
+
+           GetEventParameter (eventRef, kEventParamKeyModifiers,
+                              typeUInt32, NULL,
+                              sizeof (UInt32), NULL, &modifiers);
+#endif
+           mapped_modifiers &= modifiers;
+
+#if USE_CARBON_EVENTS && (defined (MAC_OSX) || USE_MAC_TSM)
            /* When using Carbon Events, we need to pass raw keyboard
               events to the TSM ourselves.  If TSM handles it, it
               will pass back noErr, otherwise it will pass back
               "eventNotHandledErr" and we can process it
               normally.  */
-           if ((mac_pass_command_to_system
-                || !(er.modifiers & cmdKey))
-               && (mac_pass_control_to_system
-                   || !(er.modifiers & controlKey))
-               && (NILP (Vmac_option_modifier)
-                   || !(er.modifiers & optionKey)))
-             if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
-                 != eventNotHandledErr)
-               break;
-#endif
-
-#if 0
-           if (dpyinfo->x_focus_frame == NULL)
+           if (!(mapped_modifiers
+                 & ~(mac_pass_command_to_system ? cmdKey : 0)
+                 & ~(mac_pass_control_to_system ? controlKey : 0)))
              {
-               /* Beep if keyboard input occurs when all the frames
-                  are invisible.  */
-               SysBeep (1);
-               break;
+               OSStatus err;
+
+               read_socket_inev = &inev;
+               err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
+               read_socket_inev = NULL;
+               if (err != eventNotHandledErr)
+                 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;
-                 event.timestamp = timestamp;
-                 kbd_buffer_store_event (&event);
-                 count++;
-               }
-             last_key_script = current_key_script;
-           }
+           if (er.what == keyUp)
+             break;
 
            ObscureCursor ();
 
-           if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
+           f = mac_focus_frame (dpyinfo);
+
+           if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
+               && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
              {
                clear_mouse_face (dpyinfo);
                dpyinfo->mouse_face_hidden = 1;
              }
 
-           /* translate the keycode back to determine the original key */
-           /* Convert key code if function key is pressed.
-              Otherwise, if non-ASCII-event, take care of that
-              without re-translating the key code. */
-#if USE_CARBON_EVENTS
-           if (convert_fn_keycode (eventRef, keycode, &xkeysym))
+           current_key_script = GetScriptManagerVariable (smKeyScript);
+           if (last_key_script != current_key_script)
              {
-               inev.code = xkeysym;
-               /* this doesn't work - tried to add shift modifiers */
-                 inev.code =
-                   backtranslate_modified_keycode(er.modifiers & (~0x2200),
-                                                  xkeysym | 0x80,  xkeysym);
-               inev.kind = ASCII_KEYSTROKE_EVENT;
+               struct input_event event;
+
+               EVENT_INIT (event);
+               event.kind = LANGUAGE_CHANGE_EVENT;
+               event.arg = Qnil;
+               event.code = current_key_script;
+               event.timestamp = timestamp;
+               kbd_buffer_store_event (&event);
+               count++;
+               last_key_script = current_key_script;
              }
-           else
+
+#if USE_MAC_TSM
+           if (inev.kind != NO_EVENT)
+             break;
 #endif
-             if (keycode_to_xkeysym (keycode, &xkeysym))
-               {
-                 inev.code = 0xff00 | xkeysym;
-                 inev.kind = NON_ASCII_KEYSTROKE_EVENT;
-               }
-             else
-               {
-                 inev.code =
-                   backtranslate_modified_keycode(er.modifiers, keycode,
-                                                  er.message & charCodeMask);
-                 inev.kind = ASCII_KEYSTROKE_EVENT;
-               }
-         }
 
-#if USE_CARBON_EVENTS
-         inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
-#else
-         inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
+#ifdef MAC_OSX
+           if (mapped_modifiers & kEventKeyModifierFnMask
+               && keycode <= 0x7f
+               && fn_keycode_to_keycode_table[keycode])
+             keycode = fn_keycode_to_keycode_table[keycode];
+#endif
+           if (keycode <= 0x7f && keycode_to_xkeysym_table [keycode])
+             {
+               inev.kind = NON_ASCII_KEYSTROKE_EVENT;
+               inev.code = 0xff00 | keycode_to_xkeysym_table [keycode];
+#ifdef MAC_OSX
+               if (modifiers & kEventKeyModifierFnMask
+                   && keycode <= 0x7f
+                   && fn_keycode_to_keycode_table[keycode] == keycode)
+                 modifiers &= ~kEventKeyModifierFnMask;
 #endif
-         inev.modifiers |= (extra_keyboard_modifiers
-                            & (meta_modifier | alt_modifier
-                               | hyper_modifier | super_modifier));
-         XSETFRAME (inev.frame_or_window, mac_focus_frame (dpyinfo));
+             }
+           else if (mapped_modifiers)
+             {
+               /* translate the keycode back to determine the
+                  original key */
+#ifdef MAC_OSX
+               static SInt16 last_key_layout_id = 0;
+               static Handle uchr_handle = (Handle)-1;
+               SInt16 current_key_layout_id =
+                 GetScriptVariable (current_key_script, smScriptKeys);
+
+               if (uchr_handle == (Handle)-1
+                   || last_key_layout_id != current_key_layout_id)
+                 {
+                   uchr_handle = GetResource ('uchr', current_key_layout_id);
+                   last_key_layout_id = current_key_layout_id;
+                 }
+
+               if (uchr_handle)
+                 {
+                   OSStatus status;
+                   UInt16 key_action = er.what - keyDown;
+                   UInt32 modifier_key_state =
+                     (modifiers & ~mapped_modifiers) >> 8;
+                   UInt32 keyboard_type = LMGetKbdType ();
+                   SInt32 dead_key_state = 0;
+                   UniChar code;
+                   UniCharCount actual_length;
+
+                   status = UCKeyTranslate ((UCKeyboardLayout *)*uchr_handle,
+                                            keycode, key_action,
+                                            modifier_key_state,
+                                            keyboard_type,
+                                            kUCKeyTranslateNoDeadKeysMask,
+                                            &dead_key_state,
+                                            1, &actual_length, &code);
+                   if (status == noErr && actual_length == 1)
+                     mac_set_unicode_keystroke_event (code, &inev);
+                 }
+#endif /* MAC_OSX */
+
+               if (inev.kind == NO_EVENT)
+                 {
+                   /* This code comes from Keyboard Resource,
+                      Appendix C of IM - Text.  This is necessary
+                      since shift is ignored in KCHR table
+                      translation when option or command is pressed.
+                      It also does not translate correctly
+                      control-shift chars like C-% so mask off shift
+                      here also.  */
+                   /* Mask off modifier keys that are mapped to some
+                      Emacs modifiers.  */
+                   int new_modifiers = er.modifiers & ~mapped_modifiers;
+                   /* set high byte of keycode to modifier high byte*/
+                   int new_keycode = keycode | new_modifiers;
+                   Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
+                   unsigned long some_state = 0;
+                   UInt32 new_char_code;
+
+                   new_char_code = KeyTranslate (kchr_ptr, new_keycode,
+                                                 &some_state);
+                   if (new_char_code == 0)
+                     /* Seems like a dead key.  Append up-stroke.  */
+                     new_char_code = KeyTranslate (kchr_ptr,
+                                                   new_keycode | 0x80,
+                                                   &some_state);
+                   if (new_char_code)
+                     {
+                       inev.kind = ASCII_KEYSTROKE_EVENT;
+                       inev.code = new_char_code & 0xff;
+                     }
+                 }
+             }
+
+           if (inev.kind == NO_EVENT)
+             {
+               inev.kind = ASCII_KEYSTROKE_EVENT;
+               inev.code = er.message & charCodeMask;
+             }
+
+           inev.modifiers = mac_to_emacs_modifiers (modifiers);
+           inev.modifiers |= (extra_keyboard_modifiers
+                              & (meta_modifier | alt_modifier
+                                 | hyper_modifier | super_modifier));
+           XSETFRAME (inev.frame_or_window, f);
+
+#if TARGET_API_MAC_CARBON
+           if (inev.kind == ASCII_KEYSTROKE_EVENT
+               && inev.code >= 0x80 && inev.modifiers)
+             {
+               OSStatus err;
+               TextEncoding encoding = kTextEncodingMacRoman;
+               TextToUnicodeInfo ttu_info;
+
+               UpgradeScriptInfoToTextEncoding (current_key_script,
+                                                kTextLanguageDontCare,
+                                                kTextRegionDontCare,
+                                                NULL, &encoding);
+               err = CreateTextToUnicodeInfoByEncoding (encoding, &ttu_info);
+               if (err == noErr)
+                 {
+                   UniChar code;
+                   Str255 pstr;
+                   ByteCount unicode_len;
+
+                   pstr[0] = 1;
+                   pstr[1] = inev.code;
+                   err = ConvertFromPStringToUnicode (ttu_info, pstr,
+                                                      sizeof (UniChar),
+                                                      &unicode_len, &code);
+                   if (err == noErr && unicode_len == sizeof (UniChar))
+                     mac_set_unicode_keystroke_event (code, &inev);
+                   DisposeTextToUnicodeInfo (&ttu_info);
+                 }
+             }
+#endif
+         }
          break;
 
        case kHighLevelEvent:
-         read_socket_inev = &inev;
          AEProcessAppleEvent (&er);
-         read_socket_inev = NULL;
          break;
 
        default:
@@ -10718,7 +11090,6 @@ void
 mac_initialize_display_info ()
 {
   struct mac_display_info *dpyinfo = &one_mac_display_info;
-  GDHandle main_device_handle;
 
   bzero (dpyinfo, sizeof (*dpyinfo));
 
@@ -10734,37 +11105,29 @@ mac_initialize_display_info ()
   strcpy (dpyinfo->mac_id_name, "Mac Display");
 #endif
 
-  main_device_handle = LMGetMainDevice();
-
   dpyinfo->reference_count = 0;
   dpyinfo->resx = 72.0;
   dpyinfo->resy = 72.0;
-  dpyinfo->color_p = TestDeviceAttribute (main_device_handle, gdDevType);
 #ifdef MAC_OSX
   /* HasDepth returns true if it is possible to have a 32 bit display,
-     but this may not be what is actually used.  Mac OSX can do better.
-     CGMainDisplayID is only available on OSX 10.2 and higher, but the
-     header for CGGetActiveDisplayList says that the first display returned
-     is the active one, so we use that.  */
+     but this may not be what is actually used.  Mac OSX can do better.  */
+  dpyinfo->color_p = CGDisplaySamplesPerPixel (kCGDirectMainDisplay) > 1;
+  dpyinfo->n_planes = CGDisplayBitsPerPixel (kCGDirectMainDisplay);
+  dpyinfo->height = CGDisplayPixelsHigh (kCGDirectMainDisplay);
+  dpyinfo->width = CGDisplayPixelsWide (kCGDirectMainDisplay);
+#else
   {
-    CGDirectDisplayID disp_id[1];
-    CGDisplayCount disp_count;
-    CGDisplayErr error_code;
-
-    error_code = CGGetActiveDisplayList (1, disp_id, &disp_count);
-    if (error_code != 0)
-      error ("No display found, CGGetActiveDisplayList error %d", error_code);
+    GDHandle main_device_handle = LMGetMainDevice();
 
-    dpyinfo->n_planes = CGDisplayBitsPerPixel (disp_id[0]);
+    dpyinfo->color_p = TestDeviceAttribute (main_device_handle, gdDevType);
+    for (dpyinfo->n_planes = 32; dpyinfo->n_planes > 0; dpyinfo->n_planes >>= 1)
+      if (HasDepth (main_device_handle, dpyinfo->n_planes,
+                   gdDevType, dpyinfo->color_p))
+       break;
+    dpyinfo->height = (**main_device_handle).gdRect.bottom;
+    dpyinfo->width = (**main_device_handle).gdRect.right;
   }
-#else
-  for (dpyinfo->n_planes = 32; dpyinfo->n_planes > 0; dpyinfo->n_planes >>= 1)
-    if (HasDepth (main_device_handle, dpyinfo->n_planes,
-                 gdDevType, dpyinfo->color_p))
-      break;
 #endif
-  dpyinfo->height = (**main_device_handle).gdRect.bottom;
-  dpyinfo->width = (**main_device_handle).gdRect.right;
   dpyinfo->grabbed = 0;
   dpyinfo->root_window = NULL;
   dpyinfo->image_cache = make_image_cache ();
@@ -10879,11 +11242,14 @@ x_delete_display (dpyinfo)
        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 (dpyinfo->font_table)
+    {
+      if (dpyinfo->font_table->font_encoder)
+       xfree (dpyinfo->font_table->font_encoder);
+      xfree (dpyinfo->font_table);
+    }
+  if (dpyinfo->mac_id_name)
+    xfree (dpyinfo->mac_id_name);
 
   if (x_display_list == 0)
     {
@@ -10900,7 +11266,6 @@ mac_check_bundle()
   extern int inhibit_window_system;
   extern int noninteractive;
   CFBundleRef appsBundle;
-  pid_t child;
 
   /* No need to test if already -nw*/
   if (inhibit_window_system || noninteractive)
@@ -10971,7 +11336,7 @@ static void
 init_menu_bar ()
 {
 #ifdef MAC_OSX
-  OSErr err;
+  OSStatus err;
   MenuRef menu;
   MenuItemIndex menu_index;
 
@@ -10999,6 +11364,20 @@ init_menu_bar ()
 #endif
 }
 
+#if USE_MAC_TSM
+static void
+init_tsm ()
+{
+#ifdef MAC_OSX
+  static InterfaceTypeList types = {kUnicodeDocument};
+#else
+  static InterfaceTypeList types = {kTextService};
+#endif
+
+  NewTSMDocument (sizeof (types) / sizeof (types[0]), types,
+                 &tsm_document_id, 0);
+}
+#endif
 
 /* Set up use of X before we make the first connection.  */
 
@@ -11093,6 +11472,10 @@ mac_initialize ()
   init_command_handler ();
 
   init_menu_bar ();
+
+#if USE_MAC_TSM
+  init_tsm ();
+#endif
 #endif /* USE_CARBON_EVENTS */
 
 #ifdef MAC_OSX
@@ -11136,12 +11519,26 @@ syms_of_macterm ()
   Fput (Qsuper,   Qmodifier_value, make_number (super_modifier));
 
 #if USE_CARBON_EVENTS
-  Qhicommand   = intern ("hicommand");    staticpro (&Qhicommand);
+  Qhi_command   = intern ("hi-command");    staticpro (&Qhi_command);
 #ifdef MAC_OSX
-  Qservices    = intern ("services");    staticpro (&Qservices);
+  Qtoolbar_switch_mode = intern ("toolbar-switch-mode");
+  staticpro (&Qtoolbar_switch_mode);
+#if USE_MAC_FONT_PANEL
+  Qpanel_closed = intern ("panel-closed");  staticpro (&Qpanel_closed);
+  Qselection    = intern ("selection");     staticpro (&Qselection);
+#endif
+
+  Qservice     = intern ("service");     staticpro (&Qservice);
   Qpaste       = intern ("paste");       staticpro (&Qpaste);
   Qperform     = intern ("perform");     staticpro (&Qperform);
 #endif
+#if USE_MAC_TSM
+  Qtext_input = intern ("text-input"); staticpro (&Qtext_input);
+  Qupdate_active_input_area = intern ("update-active-input-area");
+  staticpro (&Qupdate_active_input_area);
+  Qunicode_for_key_event = intern ("unicode-for-key-event");
+  staticpro (&Qunicode_for_key_event);
+#endif
 #endif
 
 #ifdef MAC_OSX
@@ -11163,6 +11560,14 @@ syms_of_macterm ()
 #if USE_ATSUI
   staticpro (&atsu_font_id_hash);
   atsu_font_id_hash = Qnil;
+
+  staticpro (&fm_style_face_attributes_alist);
+  fm_style_face_attributes_alist = Qnil;
+#endif
+
+#if USE_MAC_TSM
+  staticpro (&saved_ts_script_language_on_focus);
+  saved_ts_script_language_on_focus = Qnil;
 #endif
 
   /* We don't yet support this, but defining this here avoids whining
@@ -11178,7 +11583,7 @@ NOTE: Not supported on Mac yet.  */);
   x_use_underline_position_properties = 0;
 
   DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
-              doc: /* If not nil, Emacs uses toolkit scroll bars.  */);
+    doc: /* If not nil, Emacs uses toolkit scroll bars.  */);
 #ifdef USE_TOOLKIT_SCROLL_BARS
   Vx_toolkit_scroll_bars = Qt;
 #else
@@ -11232,32 +11637,36 @@ mouse-3 and the command-key will register for mouse-2.  */);
 
 #if USE_CARBON_EVENTS
   DEFVAR_BOOL ("mac-wheel-button-is-mouse-2", &mac_wheel_button_is_mouse_2,
-   doc: /* *Non-nil if the wheel button is mouse-2 and the right click mouse-3.
+    doc: /* *Non-nil if the wheel button is mouse-2 and the right click mouse-3.
 Otherwise, the right click will be treated as mouse-2 and the wheel
 button will be mouse-3.  */);
   mac_wheel_button_is_mouse_2 = 1;
 
   DEFVAR_BOOL ("mac-pass-command-to-system", &mac_pass_command_to_system,
-   doc: /* *Non-nil if command key presses are passed on to the Mac Toolbox.  */);
+    doc: /* *Non-nil if command key presses are passed on to the Mac Toolbox.  */);
   mac_pass_command_to_system = 1;
 
   DEFVAR_BOOL ("mac-pass-control-to-system", &mac_pass_control_to_system,
-   doc: /* *Non-nil if control key presses are passed on to the Mac Toolbox.  */);
+    doc: /* *Non-nil if control key presses are passed on to the Mac Toolbox.  */);
   mac_pass_control_to_system = 1;
 
 #endif
 
   DEFVAR_BOOL ("mac-allow-anti-aliasing", &mac_use_core_graphics,
-   doc: /* *If non-nil, allow anti-aliasing.
+    doc: /* *If non-nil, allow anti-aliasing.
 The text will be rendered using Core Graphics text rendering which
 may anti-alias the text.  */);
+#if USE_CG_DRAWING
+  mac_use_core_graphics = 1;
+#else
   mac_use_core_graphics = 0;
+#endif
 
   /* Register an entry for `mac-roman' so that it can be used when
      creating the terminal frame on Mac OS 9 before loading
      term/mac-win.elc.  */
   DEFVAR_LISP ("mac-charset-info-alist", &Vmac_charset_info_alist,
-               doc: /* Alist of Emacs character sets vs text encodings and coding systems.
+    doc: /* Alist of Emacs character sets vs text encodings and coding systems.
 Each entry should be of the form:
 
    (CHARSET-NAME TEXT-ENCODING CODING-SYSTEM)
@@ -11268,6 +11677,30 @@ CODING_SYSTEM is a coding system corresponding to TEXT-ENCODING.  */);
   Vmac_charset_info_alist =
     Fcons (list3 (build_string ("mac-roman"),
                  make_number (smRoman), Qnil), Qnil);
+
+#if USE_ATSUI
+  DEFVAR_LISP ("mac-atsu-font-table", &Vmac_atsu_font_table,
+    doc: /* Hash table of ATSU font IDs vs plist of attributes and values.  */);
+  Vmac_atsu_font_table =
+    make_hash_table (Qeql, make_number (DEFAULT_HASH_SIZE),
+                    make_float (DEFAULT_REHASH_SIZE),
+                    make_float (DEFAULT_REHASH_THRESHOLD),
+                    Qnil, Qnil, Qnil);
+#endif
+#if USE_MAC_TSM
+  DEFVAR_LISP ("mac-ts-active-input-overlay", &Vmac_ts_active_input_overlay,
+    doc: /* Overlay used to display Mac TSM active input area.  */);
+  Vmac_ts_active_input_overlay = Qnil;
+
+  DEFVAR_LISP ("mac-ts-script-language-on-focus", &Vmac_ts_script_language_on_focus,
+    doc: /* *How to change Mac TSM script/language when a frame gets focus.
+If the value is t, the input script and language are restored to those
+used in the last focus frame.  If the value is a pair of integers, the
+input script and language codes, which are defined in the Script
+Manager, are set to its car and cdr parts, respectively.  Otherwise,
+Emacs doesn't set them and thus follows the system default behavior.  */);
+  Vmac_ts_script_language_on_focus = Qnil;
+#endif
 }
 
 /* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b