(version): New variable, set by configure.
[bpt/emacs.git] / src / macterm.c
index 60b5545..e36fafa 100644 (file)
@@ -108,6 +108,10 @@ static Lisp_Object last_window;
    (Not yet supported.)  */
 int x_use_underline_position_properties;
 
+/* Non-zero means to draw the underline at the same place as the descent line.  */
+
+int x_underline_at_descent_line;
+
 /* This is a chain of structures for all the X displays currently in
    use.  */
 
@@ -196,6 +200,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;
@@ -238,7 +244,8 @@ static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
 static void mac_focus_changed P_ ((int, struct mac_display_info *,
                                   struct frame *, struct input_event *));
 static void x_detect_focus_change P_ ((struct mac_display_info *,
-                                      EventRecord *, struct input_event *));
+                                      const EventRecord *,
+                                      struct input_event *));
 static void XTframe_rehighlight P_ ((struct frame *));
 static void x_frame_rehighlight P_ ((struct x_display_info *));
 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
@@ -259,9 +266,6 @@ static int is_emacs_window P_ ((WindowPtr));
 static XCharStruct *mac_per_char_metric P_ ((XFontStruct *, XChar2b *, int));
 static void XSetFont P_ ((Display *, GC, XFontStruct *));
 
-/* Defined in macmenu.h.  */
-extern void menubar_selection_callback (FRAME_PTR, int);
-
 #define GC_FORE_COLOR(gc)      (&(gc)->fore_color)
 #define GC_BACK_COLOR(gc)      (&(gc)->back_color)
 #define GC_FONT(gc)            ((gc)->xgcv.font)
@@ -637,7 +641,7 @@ mac_create_bitmap_from_bitmap_data (bitmap, bits, w, h)
      char *bits;
      int w, h;
 {
-  static unsigned char swap_nibble[16]
+  static const unsigned char swap_nibble[16]
     = { 0x0, 0x8, 0x4, 0xc,    /* 0000 1000 0100 1100 */
        0x2, 0xa, 0x6, 0xe,    /* 0010 1010 0110 1110 */
        0x1, 0x9, 0x5, 0xd,    /* 0001 1001 0101 1101 */
@@ -823,9 +827,9 @@ atsu_get_text_layout_with_text_ptr (text, text_length, style, text_layout)
 
   if (saved_text_layout == NULL)
     {
-      UniCharCount lengths[] = {kATSUToTextEnd};
-      ATSUAttributeTag tags[] = {kATSULineLayoutOptionsTag};
-      ByteCount sizes[] = {sizeof (ATSLineLayoutOptions)};
+      static const UniCharCount lengths[] = {kATSUToTextEnd};
+      static const ATSUAttributeTag tags[] = {kATSULineLayoutOptionsTag};
+      static const ByteCount sizes[] = {sizeof (ATSLineLayoutOptions)};
       static ATSLineLayoutOptions line_layout =
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
        kATSLineDisableAllLayoutOperations | kATSLineUseDeviceMetrics
@@ -834,7 +838,7 @@ atsu_get_text_layout_with_text_ptr (text, text_length, style, text_layout)
        kATSLineIsDisplayOnly | kATSLineFractDisable
 #endif
        ;
-      ATSUAttributeValuePtr values[] = {&line_layout};
+      static const ATSUAttributeValuePtr values[] = {&line_layout};
 
       err = ATSUCreateTextLayoutWithTextPtr (text,
                                             kATSUFromTextBeginning,
@@ -888,19 +892,20 @@ mac_invert_rectangle (f, x, y, width, height)
 
 
 static void
-mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width, bytes_per_char)
+mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width,
+                       overstrike_p, bytes_per_char)
      struct frame *f;
      GC gc;
      int x, y;
      char *buf;
-     int nchars, bg_width, bytes_per_char;
+     int nchars, bg_width, overstrike_p, bytes_per_char;
 {
   SetPortWindowPort (FRAME_MAC_WINDOW (f));
 
 #if USE_ATSUI
   if (GC_FONT (gc)->mac_style)
     {
-      OSErr err;
+      OSStatus err;
       ATSUTextLayout text_layout;
 
       xassert (bytes_per_char == 2);
@@ -943,17 +948,24 @@ mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width, bytes_per_char)
          ATSUDrawText (text_layout,
                        kATSUFromTextBeginning, kATSUToTextEnd,
                        kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
+         if (overstrike_p)
+           {
+             MoveTo (x + 1, y);
+             ATSUDrawText (text_layout,
+                           kATSUFromTextBeginning, kATSUToTextEnd,
+                           kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
+           }
          mac_end_clip (gc);
 #ifdef MAC_OSX
        }
       else
        {
          CGrafPtr port;
-         CGContextRef context;
+         static CGContextRef context;
          float port_height = FRAME_PIXEL_HEIGHT (f);
-         ATSUAttributeTag tags[] = {kATSUCGContextTag};
-         ByteCount sizes[] = {sizeof (CGContextRef)};
-         ATSUAttributeValuePtr values[] = {&context};
+         static const ATSUAttributeTag tags[] = {kATSUCGContextTag};
+         static const ByteCount sizes[] = {sizeof (CGContextRef)};
+         static const ATSUAttributeValuePtr values[] = {&context};
 
 #if USE_CG_DRAWING
          context = mac_begin_cg_clip (f, gc);
@@ -986,9 +998,15 @@ mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width, bytes_per_char)
                                       sizeof (tags) / sizeof (tags[0]),
                                       tags, sizes, values);
          if (err == noErr)
-           ATSUDrawText (text_layout,
-                         kATSUFromTextBeginning, kATSUToTextEnd,
-                         Long2Fix (x), Long2Fix (port_height - y));
+           {
+             ATSUDrawText (text_layout,
+                           kATSUFromTextBeginning, kATSUToTextEnd,
+                           Long2Fix (x), Long2Fix (port_height - y));
+             if (overstrike_p)
+               ATSUDrawText (text_layout,
+                             kATSUFromTextBeginning, kATSUToTextEnd,
+                             Long2Fix (x + 1), Long2Fix (port_height - y));
+           }
 #if USE_CG_DRAWING
          mac_end_cg_clip (f);
          context = NULL;
@@ -1054,6 +1072,12 @@ mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width, bytes_per_char)
       TextFace (GC_FONT (gc)->mac_fontface);
       MoveTo (x, y);
       DrawText (buf, 0, nchars * bytes_per_char);
+      if (overstrike_p)
+       {
+         TextMode (srcOr);
+         MoveTo (x + 1, y);
+         DrawText (buf, 0, nchars * bytes_per_char);
+       }
       if (bg_width)
        RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
       mac_end_clip (gc);
@@ -1066,59 +1090,33 @@ mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width, bytes_per_char)
 }
 
 
-/* Mac replacement for XDrawString.  */
-
-static void
-mac_draw_string (f, gc, x, y, buf, nchars)
-     struct frame *f;
-     GC gc;
-     int x, y;
-     char *buf;
-     int nchars;
-{
-  mac_draw_string_common (f, gc, x, y, buf, nchars, 0, 1);
-}
-
-
-/* Mac replacement for XDrawString16. */
-
-static void
-mac_draw_string_16 (f, gc, x, y, buf, nchars)
-     struct frame *f;
-     GC gc;
-     int x, y;
-     XChar2b *buf;
-     int nchars;
-{
-  mac_draw_string_common (f, gc, x, y, (char *) buf, nchars, 0, 2);
-}
-
-
 /* Mac replacement for XDrawImageString.  */
 
 static void
-mac_draw_image_string (f, gc, x, y, buf, nchars, bg_width)
+mac_draw_image_string (f, gc, x, y, buf, nchars, bg_width, overstrike_p)
      struct frame *f;
      GC gc;
      int x, y;
      char *buf;
-     int nchars, bg_width;
+     int nchars, bg_width, overstrike_p;
 {
-  mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width, 1);
+  mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width,
+                         overstrike_p, 1);
 }
 
 
-/* Mac replacement for XDrawString16.  */
+/* Mac replacement for XDrawImageString16.  */
 
 static void
-mac_draw_image_string_16 (f, gc, x, y, buf, nchars, bg_width)
+mac_draw_image_string_16 (f, gc, x, y, buf, nchars, bg_width, overstrike_p)
      struct frame *f;
      GC gc;
      int x, y;
      XChar2b *buf;
-     int nchars, bg_width;
+     int nchars, bg_width, overstrike_p;
 {
-  mac_draw_string_common (f, gc, x, y, (char *) buf, nchars, bg_width, 2);
+  mac_draw_string_common (f, gc, x, y, (char *) buf, nchars, bg_width,
+                         overstrike_p, 2);
 }
 
 
@@ -1127,7 +1125,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)
@@ -1145,7 +1143,7 @@ mac_query_char_extents (style, c,
      void *cg_glyph;
 #endif
 {
-  OSErr err = noErr;
+  OSStatus err = noErr;
   int width;
   Rect char_bounds;
 
@@ -1191,7 +1189,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);
 
@@ -1201,7 +1199,12 @@ mac_query_char_extents (style, c,
                err1 = ATSUGetGlyphInfo (text_layout, kATSUFromTextBeginning,
                                         kATSUToTextEnd, &count,
                                         &glyph_info_array);
-             if (err1 == noErr)
+             if (err1 == noErr
+                 /* Make sure that we don't have to make layout
+                    adjustments.  */
+                 && glyph_info_array.glyphs[0].deltaY == 0.0f
+                 && glyph_info_array.glyphs[0].idealX == 0.0f
+                 && glyph_info_array.glyphs[0].screenX == 0)
                {
                  xassert (glyph_info_array.glyphs[0].glyphID);
                  *cg_glyph = glyph_info_array.glyphs[0].glyphID;
@@ -1292,12 +1295,12 @@ init_cg_text_anti_aliasing_threshold ()
 }
 
 static int
-mac_draw_image_string_cg (f, gc, x, y, buf, nchars, bg_width)
+mac_draw_image_string_cg (f, gc, x, y, buf, nchars, bg_width, overstrike_p)
      struct frame *f;
      GC gc;
      int x, y;
      XChar2b *buf;
-     int nchars, bg_width;
+     int nchars, bg_width, overstrike_p;
 {
   CGrafPtr port;
   float port_height, gx, gy;
@@ -1357,13 +1360,31 @@ mac_draw_image_string_cg (f, gc, x, y, buf, nchars, bg_width)
   if (GC_FONT (gc)->mac_fontsize <= cg_text_anti_aliasing_threshold)
     CGContextSetShouldAntialias (context, false);
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-  CGContextSetTextPosition (context, gx, gy);
-  CGContextShowGlyphsWithAdvances (context, glyphs, advances, nchars);
-#else
-  for (i = 0; i < nchars; i++)
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+  if (CGContextShowGlyphsWithAdvances != NULL)
+#endif
+    {
+      CGContextSetTextPosition (context, gx, gy);
+      CGContextShowGlyphsWithAdvances (context, glyphs, advances, nchars);
+      if (overstrike_p)
+       {
+         CGContextSetTextPosition (context, gx + 1.0f, gy);
+         CGContextShowGlyphsWithAdvances (context, glyphs, advances, nchars);
+       }
+    }
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+  else
+#endif
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030  */
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
     {
-      CGContextShowGlyphsAtPoint (context, gx, gy, glyphs + i, 1);
-      gx += advances[i].width;
+      for (i = 0; i < nchars; i++)
+       {
+         CGContextShowGlyphsAtPoint (context, gx, gy, glyphs + i, 1);
+         if (overstrike_p)
+           CGContextShowGlyphsAtPoint (context, gx + 1.0f, gy, glyphs + i, 1);
+         gx += advances[i].width;
+       }
     }
 #endif
 #if USE_CG_DRAWING
@@ -2187,7 +2208,7 @@ pcm_init (pcm, count)
 
 static enum pcm_status
 pcm_get_status (pcm)
-     XCharStruct *pcm;
+     const XCharStruct *pcm;
 {
   int height = pcm->ascent + pcm->descent;
 
@@ -2631,6 +2652,11 @@ mac_compute_glyph_string_overhangs (s)
       Rect r;
       MacFontStruct *font = s->font;
 
+#if USE_CG_DRAWING
+      mac_prepare_for_quickdraw (s->f);
+#endif
+      SetPortWindowPort (FRAME_MAC_WINDOW (s->f));
+
       TextFont (font->mac_fontnum);
       TextSize (font->mac_fontsize);
       TextFace (font->mac_fontface);
@@ -2763,15 +2789,18 @@ x_draw_glyph_string_foreground (s)
 #if USE_CG_TEXT_DRAWING
        if (!s->two_byte_p
            && mac_draw_image_string_cg (s->f, s->gc, x, s->ybase - boff,
-                                        s->char2b, s->nchars, bg_width))
+                                        s->char2b, s->nchars, bg_width,
+                                        s->face->overstrike))
          ;
        else
 #endif
          mac_draw_image_string_16 (s->f, s->gc, x, s->ybase - boff,
-                                   s->char2b, s->nchars, bg_width);
+                                   s->char2b, s->nchars, bg_width,
+                                   s->face->overstrike);
       else
        mac_draw_image_string (s->f, s->gc, x, s->ybase - boff,
-                              char1b, s->nchars, bg_width);
+                              char1b, s->nchars, bg_width,
+                              s->face->overstrike);
     }
 }
 
@@ -2807,10 +2836,10 @@ x_draw_composite_glyph_string_foreground (s)
   else
     {
       for (i = 0; i < s->nchars; i++, ++s->gidx)
-       mac_draw_string_16 (s->f, s->gc,
-                           x + s->cmp->offsets[s->gidx * 2],
-                           s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
-                           s->char2b + i, 1);
+       mac_draw_image_string_16 (s->f, s->gc,
+                                 x + s->cmp->offsets[s->gidx * 2],
+                                 s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
+                                 s->char2b + i, 1, 0, s->face->overstrike);
     }
 }
 
@@ -3529,19 +3558,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))
            {
@@ -3568,8 +3606,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;
 }
@@ -3651,19 +3701,46 @@ x_draw_glyph_string (s)
       /* Draw underline.  */
       if (s->face->underline_p)
        {
-          unsigned long h = 1;
-          unsigned long dy = s->height - h;
+         unsigned long tem, h;
+         int y;
+
+#if 0
+         /* Get the underline thickness.  Default is 1 pixel.  */
+         if (!XGetFontProperty (s->font, XA_UNDERLINE_THICKNESS, &h))
+#endif
+           h = 1;
+
+         y = s->y + s->height - h;
+         if (!x_underline_at_descent_line)
+            {
+             /* Get the underline position.  This is the recommended
+                 vertical offset in pixels from the baseline to the top of
+                 the underline.  This is a signed value according to the
+                 specs, and its default is
+
+                ROUND ((maximum descent) / 2), with
+                ROUND(x) = floor (x + 0.5)  */
+
+#if 0
+              if (x_use_underline_position_properties
+                  && XGetFontProperty (s->font, XA_UNDERLINE_POSITION, &tem))
+                y = s->ybase + (long) tem;
+              else
+#endif
+             if (s->face->font)
+                y = s->ybase + (s->face->font->max_bounds.descent + 1) / 2;
+            }
 
          if (s->face->underline_defaulted_p)
-           mac_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
-                               s->width, h);
+           mac_fill_rectangle (s->f, s->gc, s->x, y,
+                               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);
+             mac_fill_rectangle (s->f, s->gc, s->x, y,
+                                 s->background_width, h);
              XSetForeground (s->display, s->gc, xgcv.foreground);
            }
        }
@@ -3675,14 +3752,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);
            }
        }
@@ -4097,6 +4174,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);
@@ -4149,7 +4231,7 @@ mac_focus_changed (type, dpyinfo, frame, bufp)
 static void
 x_detect_focus_change (dpyinfo, event, bufp)
      struct mac_display_info *dpyinfo;
-     EventRecord *event;
+     const EventRecord *event;
      struct input_event *bufp;
 {
   struct frame *frame;
@@ -4454,35 +4536,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
@@ -5186,7 +5244,7 @@ static void
 x_scroll_bar_handle_click (bar, part_code, er, bufp)
      struct scroll_bar *bar;
      ControlPartCode part_code;
-     EventRecord *er;
+     const EventRecord *er;
      struct input_event *bufp;
 {
   int win_y, top_range;
@@ -5415,8 +5473,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
@@ -5802,6 +5859,57 @@ mac_get_window_bounds (f, inner, outer)
 #endif /* not TARGET_API_MAC_CARBON */
 }
 
+static void
+mac_handle_origin_change (f)
+     struct frame *f;
+{
+  x_real_positions (f, &f->left_pos, &f->top_pos);
+}
+
+static void
+mac_handle_size_change (f, pixelwidth, pixelheight)
+     struct frame *f;
+     int pixelwidth, pixelheight;
+{
+  int cols, rows;
+
+  cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixelwidth);
+  rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixelheight);
+
+  if (cols != FRAME_COLS (f)
+      || rows != FRAME_LINES (f)
+      || pixelwidth != FRAME_PIXEL_WIDTH (f)
+      || pixelheight != FRAME_PIXEL_HEIGHT (f))
+    {
+      /* We pass 1 for DELAY since we can't run Lisp code inside of
+        a BLOCK_INPUT.  */
+      change_frame_size (f, rows, cols, 0, 1, 0);
+      FRAME_PIXEL_WIDTH (f) = pixelwidth;
+      FRAME_PIXEL_HEIGHT (f) = pixelheight;
+      SET_FRAME_GARBAGED (f);
+
+      /* If cursor was outside the new size, mark it as off.  */
+      mark_window_cursors_off (XWINDOW (f->root_window));
+
+      /* Clear out any recollection of where the mouse highlighting
+        was, since it might be in a place that's outside the new
+        frame size.  Actually checking whether it is outside is a
+        pain in the neck, so don't try--just let the highlighting be
+        done afresh with new size.  */
+      cancel_mouse_face (f);
+
+#if TARGET_API_MAC_CARBON
+      if (f->output_data.mac->hourglass_control)
+       {
+#if USE_CG_DRAWING
+         mac_prepare_for_quickdraw (f);
+#endif
+         MoveControl (f->output_data.mac->hourglass_control,
+                      pixelwidth - HOURGLASS_WIDTH, 0);
+       }
+#endif
+    }
+}
 
 \f
 /* Calculate the absolute position in frame F
@@ -5882,7 +5990,10 @@ x_set_offset (f, xoff, yoff, change_gravity)
   ConstrainWindowToScreen (FRAME_MAC_WINDOW (f), kWindowTitleBarRgn,
                           kWindowConstrainMoveRegardlessOfFit
                           | kWindowConstrainAllowPartial, NULL, NULL);
-  x_real_positions (f, &f->left_pos, &f->top_pos);
+#if USE_CARBON_EVENTS
+  if (!NILP (tip_frame) && XFRAME (tip_frame) == f)
+#endif
+    mac_handle_origin_change (f);
 #else
   {
     Rect inner, outer, screen_rect, dummy;
@@ -5956,50 +6067,11 @@ x_set_window_size (f, change_gravity, cols, rows)
   x_wm_set_size_hint (f, (long) 0, 0);
 
   SizeWindow (FRAME_MAC_WINDOW (f), pixelwidth, pixelheight, 0);
-#if TARGET_API_MAC_CARBON
-  if (f->output_data.mac->hourglass_control)
-    {
-#if USE_CG_DRAWING
-      mac_prepare_for_quickdraw (f);
-#endif
-      MoveControl (f->output_data.mac->hourglass_control,
-                  pixelwidth - HOURGLASS_WIDTH, 0);
-    }
-#endif
-
-  /* Now, strictly speaking, we can't be sure that this is accurate,
-     but the window manager will get around to dealing with the size
-     change request eventually, and we'll hear how it went when the
-     ConfigureNotify event gets here.
-
-     We could just not bother storing any of this information here,
-     and let the ConfigureNotify event set everything up, but that
-     might be kind of confusing to the Lisp code, since size changes
-     wouldn't be reported in the frame parameters until some random
-     point in the future when the ConfigureNotify event arrives.
-
-     We pass 1 for DELAY since we can't run Lisp code inside of
-     a BLOCK_INPUT.  */
-  change_frame_size (f, rows, cols, 0, 1, 0);
-  FRAME_PIXEL_WIDTH (f) = pixelwidth;
-  FRAME_PIXEL_HEIGHT (f) = pixelheight;
-
-  /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
-     receive in the ConfigureNotify event; if we get what we asked
-     for, then the event won't cause the screen to become garbaged, so
-     we have to make sure to do it here.  */
-  SET_FRAME_GARBAGED (f);
-
-  XFlush (FRAME_X_DISPLAY (f));
 
-  /* If cursor was outside the new size, mark it as off.  */
-  mark_window_cursors_off (XWINDOW (f->root_window));
-
-  /* Clear out any recollection of where the mouse highlighting was,
-     since it might be in a place that's outside the new frame size.
-     Actually checking whether it is outside is a pain in the neck,
-     so don't try--just let the highlighting be done afresh with new size.  */
-  cancel_mouse_face (f);
+#if USE_CARBON_EVENTS
+  if (!NILP (tip_frame) && f == XFRAME (tip_frame))
+#endif
+    mac_handle_size_change (f, pixelwidth, pixelheight);
 
   UNBLOCK_INPUT;
 }
@@ -6032,13 +6104,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.  */
@@ -6135,6 +6222,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)))
@@ -6148,6 +6236,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);
       }
 
@@ -6193,7 +6282,10 @@ x_make_frame_visible (f)
                                  kWindowCascadeOnParentWindowScreen
 #endif
                                  );
-             x_real_positions (f, &f->left_pos, &f->top_pos);
+#if USE_CARBON_EVENTS
+             if (!NILP (tip_frame) && f == XFRAME (tip_frame))
+#endif
+               mac_handle_origin_change (f);
            }
          else
 #endif
@@ -6294,7 +6386,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
@@ -6358,16 +6450,16 @@ x_free_frame_resources (f)
   if (FRAME_SIZE_HINTS (f))
     xfree (FRAME_SIZE_HINTS (f));
 
-#if TARGET_API_MAC_CARBON
-  if (FRAME_FILE_NAME (f))
-    xfree (FRAME_FILE_NAME (f));
-#endif
-
   xfree (f->output_data.mac);
   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)
@@ -6615,11 +6707,12 @@ xlfdpat_destroy (pat)
 
 static struct xlfdpat *
 xlfdpat_create (pattern)
-     char *pattern;
+     const char *pattern;
 {
   struct xlfdpat *pat;
   int nblocks, i, skip;
   unsigned char last_char, *p, *q, *anychar_head;
+  const unsigned char *ptr;
   struct xlfdpat_block *blk;
 
   pat = xmalloc (sizeof (struct xlfdpat));
@@ -6630,9 +6723,9 @@ xlfdpat_create (pattern)
   anychar_head = NULL;
   q = pat->buf;
   last_char = '\0';
-  for (p = pattern; *p; p++)
+  for (ptr = pattern; *ptr; ptr++)
     {
-      unsigned char c = *p;
+      unsigned char c = *ptr;
 
       if (c == '*')
        if (last_char == '*')
@@ -6723,10 +6816,6 @@ xlfdpat_create (pattern)
       }
 
   return pat;
-
- error:
-  xlfdpat_destroy (pat);
-  return NULL;
 }
 
 static INLINE int
@@ -6740,14 +6829,15 @@ xlfdpat_exact_p (pat)
    that the pattern in *BLK matches with its prefix.  Return NULL
    there is no such strings.  STRING must be lowered in advance.  */
 
-static char *
+static const char *
 xlfdpat_block_match_1 (blk, string, start_max)
      struct xlfdpat_block *blk;
-     unsigned char *string;
+     const unsigned char *string;
      int start_max;
 {
   int start, infinity;
-  unsigned char *p, *s;
+  unsigned char *p;
+  const unsigned char *s;
 
   xassert (blk->len > 0);
   xassert (start_max + blk->len <= strlen (string));
@@ -6804,17 +6894,17 @@ xlfdpat_block_match_1 (blk, string, start_max)
   ((b)->len == 1 ? memchr ((s), (b)->last_char, (m) + 1) \
    : xlfdpat_block_match_1 (b, s, m))
 
-/* Check if XLFD pattern PAT, which is generated by `xfldpat_create',
+/* Check if XLFD pattern PAT, which is generated by `xlfdpat_create',
    matches with STRING.  STRING must be lowered in advance.  */
 
 static int
 xlfdpat_match (pat, string)
      struct xlfdpat *pat;
-     unsigned char *string;
+     const unsigned char *string;
 {
   int str_len, nblocks, i, start_max;
   struct xlfdpat_block *blk;
-  unsigned char *s;
+  const unsigned char *s;
 
   xassert (pat->nblocks > 0);
 
@@ -6895,6 +6985,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
@@ -6981,7 +7075,7 @@ decode_mac_font_name (name, size, coding_system)
 
 static char *
 mac_to_x_fontname (name, size, style, charset)
-     char *name;
+     const char *name;
      int size;
      Style style;
      char *charset;
@@ -7028,7 +7122,8 @@ const int kDefaultFontSize = 12;
 
 static int
 parse_x_font_name (xf, family, size, style, charset)
-     char *xf, *family;
+     const char *xf;
+     char *family;
      int *size;
      Style *style;
      char *charset;
@@ -7111,10 +7206,10 @@ add_font_name_table_entry (char *font_name)
 
 static void
 add_mac_font_name (name, size, style, charset)
-     char *name;
+     const char *name;
      int size;
      Style style;
-     char *charset;
+     const char *charset;
 {
   if (size > 0)
     add_font_name_table_entry (mac_to_x_fontname (name, size, style, charset));
@@ -7128,6 +7223,29 @@ add_mac_font_name (name, size, style, 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
@@ -7152,7 +7270,7 @@ 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;
@@ -7190,8 +7308,19 @@ init_font_name_table ()
                                    NULL, NULL);
            if (err == noErr)
              {
+               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)
                  {
@@ -7382,7 +7511,7 @@ enum xlfd_scalable_field_index
     XLFD_SCL_LAST
   };
 
-static int xlfd_scalable_fields[] =
+static const int xlfd_scalable_fields[] =
   {
     6,                         /* PIXEL_SIZE */
     7,                         /* POINT_SIZE */
@@ -7392,14 +7521,16 @@ static int xlfd_scalable_fields[] =
 
 static Lisp_Object
 mac_do_list_fonts (pattern, maxnames)
-     char *pattern;
+     const char *pattern;
      int maxnames;
 {
   int i, n_fonts = 0;
   Lisp_Object font_list = Qnil;
   struct xlfdpat *pat;
-  char *scaled, *ptr;
-  int scl_val[XLFD_SCL_LAST], *field, *val;
+  char *scaled;
+  const char *ptr;
+  int scl_val[XLFD_SCL_LAST], *val;
+  const int *field;
   int exact;
 
   if (font_name_table == NULL)  /* Initialize when first used.  */
@@ -7649,7 +7780,8 @@ x_compute_min_glyph_bounds (f)
    fields are present, none is '*'.  */
 
 static int
-is_fully_specified_xlfd (char *p)
+is_fully_specified_xlfd (p)
+     const char *p;
 {
   int i;
   char *q;
@@ -7677,14 +7809,16 @@ is_fully_specified_xlfd (char *p)
 }
 
 
-/* XLoadQueryFont creates and returns an internal representation for a
-   font in a MacFontStruct struct.  There is really no concept
+/* mac_load_query_font creates and returns an internal representation
+   for a font in a MacFontStruct struct.  There is really no concept
    corresponding to "loading" a font on the Mac.  But we check its
    existence and find the font number and all other information for it
    and store them in the returned MacFontStruct.  */
 
 static MacFontStruct *
-XLoadQueryFont (Display *dpy, char *fontname)
+mac_load_query_font (f, fontname)
+     struct frame *f;
+     char *fontname;
 {
   int size;
   char *name;
@@ -7723,20 +7857,24 @@ XLoadQueryFont (Display *dpy, char *fontname)
 #if USE_ATSUI
   if (strcmp (charset, "iso10646-1") == 0) /* XXX */
     {
-      OSErr err;
-      ATSUAttributeTag tags[] = {kATSUFontTag, kATSUSizeTag,
-                                kATSUQDBoldfaceTag, kATSUQDItalicTag};
-      ByteCount sizes[] = {sizeof (ATSUFontID), sizeof (Fixed),
-                          sizeof (Boolean), sizeof (Boolean)};
+      OSStatus err;
+      static const ATSUAttributeTag tags[] =
+       {kATSUFontTag, kATSUSizeTag,
+        kATSUQDBoldfaceTag, kATSUQDItalicTag};
+      static const ByteCount sizes[] =
+       {sizeof (ATSUFontID), sizeof (Fixed),
+        sizeof (Boolean), sizeof (Boolean)};
       static Fixed size_fixed;
       static Boolean bold_p, italic_p;
-      ATSUAttributeValuePtr values[] = {&font_id, &size_fixed,
-                                       &bold_p, &italic_p};
-      ATSUFontFeatureType types[] = {kAllTypographicFeaturesType,
-                                    kDiacriticsType};
-      ATSUFontFeatureSelector selectors[] = {kAllTypeFeaturesOffSelector,
-                                            kDecomposeDiacriticsSelector};
+      static const ATSUAttributeValuePtr values[] =
+       {&font_id, &size_fixed,
+        &bold_p, &italic_p};
+      static const ATSUFontFeatureType types[] =
+       {kAllTypographicFeaturesType, kDiacriticsType};
+      static const 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);
@@ -7755,7 +7893,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
@@ -7801,7 +7943,7 @@ XLoadQueryFont (Display *dpy, char *fontname)
 #if USE_ATSUI
   if (font->mac_style)
     {
-      OSErr err;
+      OSStatus err;
       UniChar c;
 
       font->min_byte1 = 0;
@@ -7815,22 +7957,20 @@ XLoadQueryFont (Display *dpy, char *fontname)
       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)
        {
@@ -7849,7 +7989,8 @@ XLoadQueryFont (Display *dpy, char *fontname)
                                    NULL
 #endif
                                    );
-      if (err != noErr)
+      if (err != noErr
+         || space_bounds->width <= 0 || FONT_HEIGHT (font) <= 0)
        {
          mac_unload_font (&one_mac_display_info, font);
          return NULL;
@@ -7892,23 +8033,13 @@ XLoadQueryFont (Display *dpy, char *fontname)
   else
 #endif
     {
-      GrafPtr port;
-      SInt16 old_fontnum, old_fontsize;
-      Style old_fontface;
       FontInfo the_fontinfo;
       int is_two_byte_font;
 
-      /* Save the current font number used.  */
-      GetPort (&port);
-#if TARGET_API_MAC_CARBON
-      old_fontnum = GetPortTextFont (port);
-      old_fontsize = GetPortTextSize (port);
-      old_fontface = GetPortTextFace (port);
-#else
-      old_fontnum = port->txFont;
-      old_fontsize = port->txSize;
-      old_fontface = port->txFace;
+#if USE_CG_DRAWING
+      mac_prepare_for_quickdraw (f);
 #endif
+      SetPortWindowPort (FRAME_MAC_WINDOW (f));
 
       TextFont (fontnum);
       TextSize (size);
@@ -7990,11 +8121,6 @@ XLoadQueryFont (Display *dpy, char *fontname)
          for (c = 0x21, pcm = space_bounds + 1; c <= 0xff; c++, pcm++)
            mac_query_char_extents (NULL, c, NULL, NULL, pcm, NULL);
        }
-
-      /* Restore previous font number, size and face.  */
-      TextFont (old_fontnum);
-      TextSize (old_fontsize);
-      TextFace (old_fontface);
     }
 
   if (space_bounds)
@@ -8013,6 +8139,8 @@ XLoadQueryFont (Display *dpy, char *fontname)
                                             pcm->width);
            font->min_bounds.ascent   = min (font->min_bounds.ascent,
                                             pcm->ascent);
+           font->min_bounds.descent  = min (font->min_bounds.descent,
+                                            pcm->descent);
 
            font->max_bounds.lbearing = max (font->max_bounds.lbearing,
                                             pcm->lbearing);
@@ -8022,6 +8150,8 @@ XLoadQueryFont (Display *dpy, char *fontname)
                                             pcm->width);
            font->max_bounds.ascent   = max (font->max_bounds.ascent,
                                             pcm->ascent);
+           font->max_bounds.descent  = max (font->max_bounds.descent,
+                                            pcm->descent);
          }
       if (
 #if USE_ATSUI
@@ -8130,7 +8260,7 @@ x_load_font (f, fontname, size)
     fontname = (char *) SDATA (XCAR (font_names));
 
     BLOCK_INPUT;
-    font = (MacFontStruct *) XLoadQueryFont (FRAME_MAC_DISPLAY (f), fontname);
+    font = mac_load_query_font (f, fontname);
     UNBLOCK_INPUT;
     if (!font)
       return NULL;
@@ -8282,8 +8412,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;
 }
@@ -8319,6 +8449,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 */
@@ -8345,7 +8547,7 @@ x_find_ccl_program (fontp)
 #endif
 #endif /* ! TARGET_API_MAC_CARBON */
 
-#define M_APPLE 128
+#define M_APPLE 234
 #define I_ABOUT 1
 
 #define WINDOW_RESOURCE 128
@@ -8405,7 +8607,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;
@@ -8415,24 +8636,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 **);
@@ -8440,20 +8657,95 @@ extern int emacs_main (int, char **, char **);
 extern void initialize_applescript();
 extern void terminate_applescript();
 
-static unsigned int
-#if USE_CARBON_EVENTS
-mac_to_emacs_modifiers (UInt32 mods)
-#else
-mac_to_emacs_modifiers (EventModifiers mods)
-#endif
-{
-  unsigned int result = 0;
-  if (mods & shiftKey)
-    result |= shift_modifier;
-
-  /* Deactivated to simplify configuration:
-     if Vmac_option_modifier is non-NIL, we fully process the Option
-     key. Otherwise, we only process it if an additional Ctrl or Command
+/* 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 const 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 const 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)
+#else
+mac_to_emacs_modifiers (EventModifiers mods)
+#endif
+{
+  unsigned int result = 0;
+  if (mods & shiftKey)
+    result |= shift_modifier;
+
+  /* Deactivated to simplify configuration:
+     if Vmac_option_modifier is non-NIL, we fully process the Option
+     key. Otherwise, we only process it if an additional Ctrl or Command
      is pressed. That way the system may convert the character to a
      composed one.
      if ((mods & optionKey) &&
@@ -8758,23 +9050,97 @@ 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;
 
-static void
+  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
+
+#if !TARGET_API_MAC_CARBON
+void
 do_apple_menu (SInt16 menu_item)
 {
-#if !TARGET_API_MAC_CARBON
   Str255 item_name;
   SInt16 da_driver_refnum;
 
@@ -8785,49 +9151,16 @@ do_apple_menu (SInt16 menu_item)
       GetMenuItemText (GetMenuHandle (M_APPLE), menu_item, item_name);
       da_driver_refnum = OpenDeskAcc (item_name);
     }
-#endif /* !TARGET_API_MAC_CARBON */
 }
-
-void
-do_menu_choice (SInt32 menu_choice)
-{
-  SInt16 menu_id, menu_item;
-
-  menu_id = HiWord (menu_choice);
-  menu_item = LoWord (menu_choice);
-
-  switch (menu_id)
-    {
-    case 0:
-      break;
-
-    case M_APPLE:
-      do_apple_menu (menu_item);
-      break;
-
-    default:
-      {
-        struct frame *f = mac_focus_frame (&one_mac_display_info);
-        MenuHandle menu = GetMenuHandle (menu_id);
-        if (menu)
-          {
-            UInt32 refcon;
-
-            GetMenuItemRefCon (menu, menu_item, &refcon);
-            menubar_selection_callback (f, refcon);
-          }
-      }
-    }
-
-  HiliteMenu (0);
-}
-
+#endif /* !TARGET_API_MAC_CARBON */
 
 /* Handle drags in size box.  Based on code contributed by Ben
    Mesander and IM - Window Manager A.  */
 
 static void
-do_grow_window (WindowPtr w, EventRecord *e)
+do_grow_window (w, e)
+     WindowPtr w;
+     const EventRecord *e;
 {
   Rect limit_rect;
   int rows, columns, width, height;
@@ -8872,6 +9205,32 @@ do_grow_window (WindowPtr w, EventRecord *e)
 }
 
 
+#if TARGET_API_MAC_CARBON
+static Point
+mac_get_ideal_size (f)
+     struct frame *f;
+{
+  struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+  WindowPtr w = FRAME_MAC_WINDOW (f);
+  Point ideal_size;
+  Rect standard_rect;
+  int height, width, columns, rows;
+
+  ideal_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
+  ideal_size.v = dpyinfo->height;
+  IsWindowInStandardState (w, &ideal_size, &standard_rect);
+  /* Adjust the standard size according to character boundaries.  */
+  width = standard_rect.right - standard_rect.left;
+  height = standard_rect.bottom - standard_rect.top;
+  columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
+  rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
+  ideal_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, columns);
+  ideal_size.v = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
+
+  return ideal_size;
+}
+#endif
+
 /* Handle clicks in zoom box.  Calculation of "standard state" based
    on code in IM - Window Manager A and code contributed by Ben
    Mesander.  The standard state of an Emacs window is 80-characters
@@ -8881,39 +9240,28 @@ static void
 do_zoom_window (WindowPtr w, int zoom_in_or_out)
 {
   Rect zoom_rect, port_rect;
-  int columns, rows, width, height;
+  int 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;
-
-  standard_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
-  standard_size.v = dpyinfo->height;
+  Point ideal_size = mac_get_ideal_size (f);
 
-  if (IsWindowInStandardState (w, &standard_size, &zoom_rect))
+  GetWindowBounds (w, kWindowContentRgn, &port_rect);
+  if (IsWindowInStandardState (w, &ideal_size, &zoom_rect)
+      && port_rect.left == zoom_rect.left
+      && port_rect.top == zoom_rect.top)
     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;
-    }
+    zoom_in_or_out = inZoomOut;
 
-  ZoomWindowIdeal (w, zoom_in_or_out, &standard_size);
+#ifdef MAC_OS8
+  mac_clear_window (f);
+#endif
+  ZoomWindowIdeal (w, zoom_in_or_out, &ideal_size);
 #else /* not TARGET_API_MAC_CARBON */
   GrafPtr save_port;
   Point top_left;
-  int w_title_height;
+  int w_title_height, rows;
+  struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
 
   GetPort (&save_port);
 
@@ -8952,6 +9300,7 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out)
   SetPort (save_port);
 #endif /* not TARGET_API_MAC_CARBON */
 
+#if !USE_CARBON_EVENTS
   /* retrieve window size and update application values */
 #if TARGET_API_MAC_CARBON
   GetWindowPortBounds (w, &port_rect);
@@ -8961,63 +9310,92 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out)
   height = port_rect.bottom - port_rect.top;
   width = port_rect.right - port_rect.left;
 
-  if (width != FRAME_PIXEL_WIDTH (f)
-      || height != FRAME_PIXEL_HEIGHT (f))
-    {
-      rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
-      columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
-
-      change_frame_size (f, rows, columns, 0, 1, 0);
-      SET_FRAME_GARBAGED (f);
-      cancel_mouse_face (f);
-
-      FRAME_PIXEL_WIDTH (f) = width;
-      FRAME_PIXEL_HEIGHT (f) = height;
-    }
-  x_real_positions (f, &f->left_pos, &f->top_pos);
+  mac_handle_size_change (f, width, height);
+  mac_handle_origin_change (f);
+#endif
 }
 
-OSErr
+void
 mac_store_apple_event (class, id, desc)
      Lisp_Object class, id;
      const AEDesc *desc;
 {
-  OSErr err;
   struct input_event buf;
-  AEDesc *desc_copy;
 
-  desc_copy = xmalloc (sizeof (AEDesc));
-  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);
+}
 
-      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);
+#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;
+     const EventParamName *names;
+     const EventParamType *types;
+{
+  OSStatus err = eventNotHandledErr;
+  Lisp_Object binding;
+
+  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
@@ -9028,7 +9406,11 @@ mac_handle_command_event (next_handler, event, data)
 {
   OSStatus result, err;
   HICommand command;
-  Lisp_Object class_key, id_key, binding;
+  static const EventParamName names[] =
+    {kEventParamDirectObject, kEventParamKeyModifiers};
+  static const EventParamType types[] =
+    {typeHICommand, typeUInt32};
+  int num_params = sizeof (names) / sizeof (names[0]);
 
   result = CallNextEventHandler (next_handler, event);
   if (result != eventNotHandledErr)
@@ -9040,41 +9422,19 @@ 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;
-         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 ()
 {
-  EventTypeSpec specs[] = {{kEventClassCommand, kEventCommandProcess}};
+  static const EventTypeSpec specs[] =
+    {{kEventClassCommand, kEventCommandProcess}};
   static EventHandlerUPP handle_command_eventUPP = NULL;
 
   if (handle_command_eventUPP == NULL)
@@ -9092,6 +9452,7 @@ mac_handle_window_event (next_handler, event, data)
 {
   WindowPtr wp;
   OSStatus result, err;
+  struct frame *f;
   UInt32 attributes;
   XSizeHints *size_hints;
 
@@ -9100,6 +9461,7 @@ mac_handle_window_event (next_handler, event, data)
   if (err != noErr)
     return eventNotHandledErr;
 
+  f = mac_window_to_frame (wp);
   switch (GetEventKind (event))
     {
     case kEventWindowUpdate:
@@ -9110,6 +9472,21 @@ mac_handle_window_event (next_handler, event, data)
       do_window_update (wp);
       return noErr;
 
+    case kEventWindowGetIdealSize:
+      result = CallNextEventHandler (next_handler, event);
+      if (result != eventNotHandledErr)
+       return result;
+
+      {
+       Point ideal_size = mac_get_ideal_size (f);
+
+       err = SetEventParameter (event, kEventParamDimensions,
+                                typeQDPoint, sizeof (Point), &ideal_size);
+       if (err == noErr)
+         return noErr;
+      }
+      break;
+
     case kEventWindowBoundsChanging:
       result = CallNextEventHandler (next_handler, event);
       if (result != eventNotHandledErr)
@@ -9120,7 +9497,7 @@ mac_handle_window_event (next_handler, event, data)
       if (err != noErr)
        break;
 
-      size_hints = FRAME_SIZE_HINTS (mac_window_to_frame (wp));
+      size_hints = FRAME_SIZE_HINTS (f);
       if ((attributes & kWindowBoundsChangeUserResize)
          && ((size_hints->flags & (PResizeInc | PBaseSize | PMinSize))
              == (PResizeInc | PBaseSize | PMinSize)))
@@ -9161,16 +9538,96 @@ mac_handle_window_event (next_handler, event, data)
        }
       break;
 
+    case kEventWindowBoundsChanged:
+      err = GetEventParameter (event, kEventParamAttributes, typeUInt32,
+                              NULL, sizeof (UInt32), NULL, &attributes);
+      if (err != noErr)
+       break;
+
+      if (attributes & kWindowBoundsChangeSizeChanged)
+       {
+         Rect bounds;
+
+         err = GetEventParameter (event, kEventParamCurrentBounds,
+                                  typeQDRectangle, NULL, sizeof (Rect),
+                                  NULL, &bounds);
+         if (err == noErr)
+           {
+             int width, height;
+
+             width = bounds.right - bounds.left;
+             height = bounds.bottom - bounds.top;
+             mac_handle_size_change (f, width, height);
+           }
+       }
+
+      if (attributes & kWindowBoundsChangeOriginChanged)
+       mac_handle_origin_change (f);
+
+      return noErr;
+
     case kEventWindowShown:
     case kEventWindowHidden:
     case kEventWindowExpanded:
     case kEventWindowCollapsed:
       result = CallNextEventHandler (next_handler, event);
 
-      mac_handle_visibility_change (mac_window_to_frame (wp));
+      mac_handle_visibility_change (f);
       return noErr;
 
       break;
+
+    case kEventWindowClose:
+      result = CallNextEventHandler (next_handler, event);
+      {
+       struct input_event buf;
+
+       EVENT_INIT (buf);
+       buf.kind = DELETE_WINDOW_EVENT;
+       XSETFRAME (buf.frame_or_window, f);
+       buf.arg = Qnil;
+       kbd_buffer_store_event (&buf);
+      }
+      return noErr;
+
+#ifdef MAC_OSX
+    case kEventWindowToolbarSwitchMode:
+      result = CallNextEventHandler (next_handler, event);
+      {
+       static const EventParamName names[] = {kEventParamDirectObject,
+                                              kEventParamWindowMouseLocation,
+                                              kEventParamKeyModifiers,
+                                              kEventParamMouseButton,
+                                              kEventParamClickCount,
+                                              kEventParamMouseChord};
+       static const 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;
@@ -9245,33 +9702,235 @@ 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;
+  const EventParamName *names;
+  const EventParamType *types;
+  static const EventParamName names_sel[] = {kEventParamATSUFontID,
+                                            kEventParamATSUFontSize,
+                                            kEventParamFMFontFamily,
+                                            kEventParamFMFontSize,
+                                            kEventParamFontColor};
+  static const 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:
+    case kEventFontSelection:
+      id_key = Qselection;
+      num_params = sizeof (names_sel) / sizeof (names_sel[0]);
+      names = names_sel;
+      types = types_sel;
+      break;
+    }
+
+  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;
+  const EventParamName *names;
+  const EventParamType *types;
+  static UInt32 seqno_uaia = 0;
+  static const EventParamName names_uaia[] =
+    {kEventParamTextInputSendComponentInstance,
+     kEventParamTextInputSendRefCon,
+     kEventParamTextInputSendSLRec,
+     kEventParamTextInputSendFixLen,
+     kEventParamTextInputSendText,
+     kEventParamTextInputSendUpdateRng,
+     kEventParamTextInputSendHiliteRng,
+     kEventParamTextInputSendClauseRng,
+     kEventParamTextInputSendPinRng,
+     kEventParamTextInputSendTextServiceEncoding,
+     kEventParamTextInputSendTextServiceMacEncoding,
+     EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER};
+  static const EventParamType types_uaia[] =
+    {typeComponentInstance,
+     typeLongInteger,
+     typeIntlWritingCode,
+     typeLongInteger,
+#ifdef MAC_OSX
+     typeUnicodeText,
+#else
+     typeChar,
+#endif
+     typeTextRangeArray,
+     typeTextRangeArray,
+     typeOffsetArray,
+     typeTextRange,
+     typeUInt32,
+     typeUInt32,
+     typeUInt32};
+  static const EventParamName names_ufke[] =
+    {kEventParamTextInputSendComponentInstance,
+     kEventParamTextInputSendRefCon,
+     kEventParamTextInputSendSLRec,
+     kEventParamTextInputSendText};
+  static const 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:
       {
-       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);
+       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;
 
@@ -9279,39 +9938,115 @@ mac_store_services_event (event)
       abort ();
     }
 
-  if (err == noErr)
+  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;
+  const EventParamName *names;
+  const EventParamType *types;
+  static const EventParamName names_pfm[] =
+    {kEventParamServiceMessageName, kEventParamServiceUserData};
+  static const EventParamType types_pfm[] =
+    {typeCFStringRef, typeCFStringRef};
+
+  switch (GetEventKind (event))
     {
-      err = mac_store_apple_event (Qservices, id_key, &apple_event);
-      AEDisposeDesc (&apple_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;
 }
 #endif /* MAC_OSX */
 #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[] =
+  static const EventTypeSpec specs_window[] =
     {{kEventClassWindow, kEventWindowUpdate},
+     {kEventClassWindow, kEventWindowGetIdealSize},
      {kEventClassWindow, kEventWindowBoundsChanging},
+     {kEventClassWindow, kEventWindowBoundsChanged},
      {kEventClassWindow, kEventWindowShown},
      {kEventClassWindow, kEventWindowHidden},
      {kEventClassWindow, kEventWindowExpanded},
-     {kEventClassWindow, kEventWindowCollapsed}};
-  EventTypeSpec specs_mouse[] = {{kEventClassMouse, kEventMouseWheelMoved}};
+     {kEventClassWindow, kEventWindowCollapsed},
+     {kEventClassWindow, kEventWindowClose},
+#ifdef MAC_OSX
+     {kEventClassWindow, kEventWindowToolbarSwitchMode},
+#endif
+#if USE_MAC_TSM
+     {kEventClassWindow, kEventWindowFocusAcquired},
+     {kEventClassWindow, kEventWindowFocusRelinquish},
+#endif
+  };
+  static const EventTypeSpec specs_mouse[] =
+    {{kEventClassMouse, kEventMouseWheelMoved}};
   static EventHandlerUPP handle_window_eventUPP = NULL;
   static EventHandlerUPP handle_mouse_eventUPP = NULL;
+#if USE_MAC_FONT_PANEL
+  static const EventTypeSpec specs_font[] =
+    {{kEventClassFont, kEventFontPanelClosed},
+     {kEventClassFont, kEventFontSelection}};
+  static EventHandlerUPP handle_font_eventUPP = NULL;
+#endif
+#if USE_MAC_TSM
+  static const 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);
@@ -9319,185 +10054,31 @@ 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 (err == noErr)
-    err = InstallTrackingHandler (mac_do_track_dragUPP, window, NULL);
+#if USE_MAC_FONT_PANEL
   if (err == noErr)
-    err = InstallReceiveHandler (mac_do_receive_dragUPP, window, NULL);
-#endif
-  return err;
-}
-
-void
-remove_window_handler (window)
-     WindowPtr window;
-{
-#if TARGET_API_MAC_CARBON
-  if (mac_do_track_dragUPP)
-    RemoveTrackingHandler (mac_do_track_dragUPP, window);
-  if (mac_do_receive_dragUPP)
-    RemoveReceiveHandler (mac_do_receive_dragUPP, window);
+    err = InstallWindowEventHandler (window, handle_font_eventUPP,
+                                    GetEventTypeCount (specs_font),
+                                    specs_font, NULL, NULL);
 #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;
-    }
+#if USE_MAC_TSM
+  if (err == noErr)
+    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 noErr;
+  return err;
 }
 
-static pascal OSErr
-mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
-                    DragReference theDrag)
+void
+remove_window_handler (window)
+     WindowPtr window;
 {
-  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;
+  remove_drag_handler (window);
 }
-#endif
 
 
 #if __profile__
@@ -9582,169 +10163,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;
 
@@ -9784,6 +10202,79 @@ 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;
+      buf->code = code;
+    }
+  else if (code < 0x100)
+    {
+      if (code < 0xA0)
+       charset_id = CHARSET_8_BIT_CONTROL;
+      else
+       charset_id = charset_latin_iso8859_1;
+      buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+      buf->code = MAKE_CHAR (charset_id, code, 0);
+    }
+  else
+    {
+      if (code < 0x2500)
+       charset_id = charset_mule_unicode_0100_24ff,
+         code -= 0x100;
+      else if (code < 0x33FF)
+       charset_id = charset_mule_unicode_2500_33ff,
+         code -= 0x2500;
+      else if (code >= 0xE000)
+       charset_id = charset_mule_unicode_e000_ffff,
+         code -= 0xE000;
+      c1 = (code / 96) + 32, c2 = (code % 96) + 32;
+      buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+      buf->code = MAKE_CHAR (charset_id, c1, c2);
+    }
+}
+#endif
+
 /* Emacs calls this whenever it wants to read an input event from the
    user. */
 int
@@ -9831,10 +10322,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;
@@ -9911,7 +10398,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
                  {
@@ -10058,31 +10551,31 @@ XTread_socket (sd, expected, hold_quit)
                  }
                break;
 
-#if TARGET_API_MAC_CARBON
-             case inProxyIcon:
-               if (TrackWindowProxyDrag (window_ptr, er.where)
-                   != errUserWantsToDragWindow)
-                 break;
-               /* fall through */
-#endif
              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);
 #endif /* not TARGET_API_MAC_CARBON */
                /* Update the frame parameters.  */
+#if !USE_CARBON_EVENTS
                {
                  struct frame *f = mac_window_to_frame (window_ptr);
 
                  if (f && !f->async_iconified)
-                   x_real_positions (f, &f->left_pos, &f->top_pos);
+                   mac_handle_origin_change (f);
                }
+#endif
                break;
 
              case inGoAway:
@@ -10131,10 +10624,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:
@@ -10179,7 +10674,7 @@ XTread_socket (sd, expected, hold_quit)
                  else
                    {
                      /* Generate SELECT_WINDOW_EVENTs when needed.  */
-                     if (mouse_autoselect_window)
+                     if (!NILP (Vmouse_autoselect_window))
                        {
                          Lisp_Object window;
 
@@ -10292,56 +10787,50 @@ 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 ();
 
@@ -10354,51 +10843,163 @@ XTread_socket (sd, expected, hold_quit)
                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
+             }
+           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
-         inev.modifiers |= (extra_keyboard_modifiers
-                            & (meta_modifier | alt_modifier
-                               | hyper_modifier | super_modifier));
-         XSETFRAME (inev.frame_or_window, f);
+         }
          break;
 
        case kHighLevelEvent:
-         read_socket_inev = &inev;
          AEProcessAppleEvent (&er);
-         read_socket_inev = NULL;
          break;
 
        default:
@@ -10590,7 +11191,6 @@ void
 mac_initialize_display_info ()
 {
   struct mac_display_info *dpyinfo = &one_mac_display_info;
-  GDHandle main_device_handle;
 
   bzero (dpyinfo, sizeof (*dpyinfo));
 
@@ -10606,37 +11206,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;
+    GDHandle main_device_handle = LMGetMainDevice();
 
-    error_code = CGGetActiveDisplayList (1, disp_id, &disp_count);
-    if (error_code != 0)
-      error ("No display found, CGGetActiveDisplayList error %d", error_code);
-
-    dpyinfo->n_planes = CGDisplayBitsPerPixel (disp_id[0]);
+    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 ();
@@ -10652,7 +11244,7 @@ mac_initialize_display_info ()
 
 static XrmDatabase
 mac_make_rdb (xrm_option)
-     char *xrm_option;
+     const char *xrm_option;
 {
   XrmDatabase database;
 
@@ -10751,11 +11343,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)
     {
@@ -10842,7 +11437,7 @@ static void
 init_menu_bar ()
 {
 #ifdef MAC_OSX
-  OSErr err;
+  OSStatus err;
   MenuRef menu;
   MenuItemIndex menu_index;
 
@@ -10870,6 +11465,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.  */
 
@@ -10964,6 +11573,10 @@ mac_initialize ()
   init_command_handler ();
 
   init_menu_bar ();
+
+#if USE_MAC_TSM
+  init_tsm ();
+#endif
 #endif /* USE_CARBON_EVENTS */
 
 #ifdef MAC_OSX
@@ -11007,12 +11620,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
@@ -11034,6 +11661,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
@@ -11048,8 +11683,16 @@ to 4.1, set this to nil.
 NOTE: Not supported on Mac yet.  */);
   x_use_underline_position_properties = 0;
 
+  DEFVAR_BOOL ("x-underline-at-descent-line",
+              &x_underline_at_descent_line,
+     doc: /* *Non-nil means to draw the underline at the same place as the descent line.
+nil means to draw the underline according to the value of the variable
+`x-use-underline-position-properties', which is usually at the baseline
+level.  The default value is nil.  */);
+  x_underline_at_descent_line = 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
@@ -11103,23 +11746,23 @@ 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
@@ -11132,7 +11775,7 @@ may anti-alias the text.  */);
      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)
@@ -11143,6 +11786,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