(version): New variable, set by configure.
[bpt/emacs.git] / src / macterm.c
index 1f25b02..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);
            }
        }
@@ -4154,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;
@@ -5167,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;
@@ -5396,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
@@ -5783,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
@@ -5863,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;
@@ -5937,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;
 }
@@ -6013,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.  */
@@ -6116,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)))
@@ -6129,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);
       }
 
@@ -6174,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
@@ -6275,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
@@ -6339,11 +6450,6 @@ 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;
 
@@ -6601,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));
@@ -6616,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 == '*')
@@ -6722,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));
@@ -6786,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);
 
@@ -6877,6 +6985,8 @@ 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
@@ -6965,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;
@@ -7012,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;
@@ -7095,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));
@@ -7112,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
@@ -7136,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;
@@ -7180,14 +7314,12 @@ init_font_name_table ()
                decode_mac_font_name (name, name_len + 1, Qnil);
                family = make_unibyte_string (name, name_len);
                FMGetFontFamilyInstanceFromFont (font_ids[i], &ff, &style);
-               Fputhash (make_unibyte_string ((char *)(font_ids + i),
-                                              sizeof (ATSUFontID)),
+               Fputhash ((font_ids[i] > MOST_POSITIVE_FIXNUM
+                          ? make_float (font_ids[i])
+                          : make_number (font_ids[i])),
                          Fcons (QCfamily,
-                                list5 (family,
-                                       QCweight,
-                                       style & bold ? Qbold : Qnormal,
-                                       QCslant,
-                                       style & italic ? Qitalic : Qnormal)),
+                                Fcons (family,
+                                       fm_style_to_face_attributes (style))),
                          Vmac_atsu_font_table);
                if (*name != '.'
                    && hash_lookup (h, family, &hash_code) < 0)
@@ -7379,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 */
@@ -7389,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.  */
@@ -7646,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;
@@ -7674,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;
@@ -7720,19 +7857,22 @@ 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;
 
@@ -7803,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;
@@ -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;
 }
@@ -8320,6 +8450,26 @@ 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;
@@ -8329,6 +8479,9 @@ mac_set_font_info_for_selection (f, face_id, c)
   EventTargetRef target = NULL;
   XFontStruct *font = NULL;
 
+  if (!mac_font_panel_visible_p ())
+    return noErr;
+
   if (f)
     {
       target = GetWindowEventTarget (FRAME_MAC_WINDOW (f));
@@ -8394,7 +8547,7 @@ mac_set_font_info_for_selection (f, face_id, c)
 #endif
 #endif /* ! TARGET_API_MAC_CARBON */
 
-#define M_APPLE 128
+#define M_APPLE 234
 #define I_ABOUT 1
 
 #define WINDOW_RESOURCE 128
@@ -8454,7 +8607,7 @@ 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;
@@ -8463,6 +8616,17 @@ static Lisp_Object Qtoolbar_switch_mode;
 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;
@@ -8485,7 +8649,7 @@ static Lisp_Object Qservice, Qpaste, Qperform;
 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 **);
@@ -8493,6 +8657,81 @@ extern int emacs_main (int, char **, char **);
 extern void initialize_applescript();
 extern void terminate_applescript();
 
+/* Table for translating Mac keycode to X keysym values.  Contributed
+   by Sudhir Shenoy.
+   Mapping for special keys is now identical to that in Apple X11
+   except `clear' (-> <clear>) on the KeyPad, `enter' (-> <kp-enter>)
+   on the right of the Cmd key on laptops, and fn + `enter' (->
+   <linefeed>). */
+static 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)
@@ -8811,76 +9050,117 @@ is_emacs_window (WindowPtr win)
   return 0;
 }
 
-static void
-do_app_resume ()
-{
-  /* Window-activate events will do the job. */
-}
-
-static void
-do_app_suspend ()
+#if USE_MAC_TSM
+static OSStatus
+mac_tsm_resume ()
 {
-  /* Window-deactivate events will do the job. */
-}
-
+  OSStatus err;
+  ScriptLanguageRecord slrec, *slptr = NULL;
 
-static void
-do_apple_menu (SInt16 menu_item)
-{
-#if !TARGET_API_MAC_CARBON
-  Str255 item_name;
-  SInt16 da_driver_refnum;
+  err = ActivateTSMDocument (tsm_document_id);
 
-  if (menu_item == I_ABOUT)
-    NoteAlert (ABOUT_ALERT_ID, NULL);
-  else
+  if (err == noErr)
     {
-      GetMenuItemText (GetMenuHandle (M_APPLE), menu_item, item_name);
-      da_driver_refnum = OpenDeskAcc (item_name);
+      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;
+       }
     }
-#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)
+  if (slptr)
     {
-    case 0:
-      break;
+#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);
 
-    case M_APPLE:
-      do_apple_menu (menu_item);
-      break;
+      /* Seems to be needed on Mac OS X 10.2.  */
+      if (err == noErr)
+       KeyScript (slptr->fScript | smKeyForceKeyScriptMask);
+    }
 
-    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);
-          }
-      }
+  return err;
+}
+
+static OSStatus
+mac_tsm_suspend ()
+{
+  OSStatus err;
+  ScriptLanguageRecord slrec, *slptr = NULL;
+
+  saved_ts_script_language_on_focus = Vmac_ts_script_language_on_focus;
+
+  if (EQ (Vmac_ts_script_language_on_focus, Qt))
+    {
+      err = GetTextServiceLanguage (&saved_ts_language);
+      if (err == noErr)
+       slptr = &saved_ts_language;
+    }
+  else if (CONSP (Vmac_ts_script_language_on_focus)
+          && INTEGERP (XCAR (Vmac_ts_script_language_on_focus))
+          && INTEGERP (XCDR (Vmac_ts_script_language_on_focus)))
+    {
+      slrec.fScript = XINT (XCAR (Vmac_ts_script_language_on_focus));
+      slrec.fLanguage = XINT (XCDR (Vmac_ts_script_language_on_focus));
+      slptr = &slrec;
+    }
+
+  if (slptr)
+    {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+      GetDefaultInputMethodOfClass (&saved_ts_component, slptr,
+                                   kKeyboardInputMethodClass);
+#else
+      GetDefaultInputMethod (&saved_ts_component, slptr);
+#endif
     }
 
-  HiliteMenu (0);
+  err = DeactivateTSMDocument (tsm_document_id);
+
+  return err;
 }
+#endif
 
+#if !TARGET_API_MAC_CARBON
+void
+do_apple_menu (SInt16 menu_item)
+{
+  Str255 item_name;
+  SInt16 da_driver_refnum;
+
+  if (menu_item == I_ABOUT)
+    NoteAlert (ABOUT_ALERT_ID, NULL);
+  else
+    {
+      GetMenuItemText (GetMenuHandle (M_APPLE), menu_item, item_name);
+      da_driver_refnum = OpenDeskAcc (item_name);
+    }
+}
+#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;
@@ -8925,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
@@ -8934,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.  */
+    zoom_in_or_out = inZoomOut;
 
-      columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, zoom_rect.right - zoom_rect.left);
-      rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, zoom_rect.bottom - zoom_rect.top);
-      standard_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, columns);
-      standard_size.v = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
-      GetWindowBounds (w, kWindowContentRgn, &port_rect);
-      if (IsWindowInStandardState (w, &standard_size, &zoom_rect)
-         && port_rect.left == zoom_rect.left
-         && port_rect.top == zoom_rect.top)
-       zoom_in_or_out = inZoomIn;
-      else
-       zoom_in_or_out = inZoomOut;
-    }
-
-  ZoomWindowIdeal (w, zoom_in_or_out, &standard_size);
+#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);
 
@@ -9005,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);
@@ -9014,20 +9310,9 @@ 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
 }
 
 void
@@ -9059,8 +9344,8 @@ mac_store_event_ref_as_apple_event (class, id, class_key, id_key,
      Lisp_Object class_key, id_key;
      EventRef event;
      UInt32 num_params;
-     EventParamName *names;
-     EventParamType *types;
+     const EventParamName *names;
+     const EventParamType *types;
 {
   OSStatus err = eventNotHandledErr;
   Lisp_Object binding;
@@ -9080,6 +9365,9 @@ mac_store_event_ref_as_apple_event (class, id, class_key, id_key,
            {
              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 ();
            }
        }
     }
@@ -9118,10 +9406,10 @@ mac_handle_command_event (next_handler, event, data)
 {
   OSStatus result, err;
   HICommand command;
-  static EventParamName names[] = {kEventParamDirectObject,
-                                  kEventParamKeyModifiers};
-  static EventParamType types[] = {typeHICommand,
-                                  typeUInt32};
+  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);
@@ -9134,18 +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.  */
+  /* 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,
-                                           Qhicommand, Qnil,
+                                           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)
@@ -9163,6 +9452,7 @@ mac_handle_window_event (next_handler, event, data)
 {
   WindowPtr wp;
   OSStatus result, err;
+  struct frame *f;
   UInt32 attributes;
   XSizeHints *size_hints;
 
@@ -9171,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:
@@ -9181,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)
@@ -9191,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)))
@@ -9232,33 +9538,74 @@ 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 EventParamName names[] = {kEventParamDirectObject,
-                                        kEventParamWindowMouseLocation,
-                                        kEventParamKeyModifiers,
-                                        kEventParamMouseButton,
-                                        kEventParamClickCount,
-                                        kEventParamMouseChord};
-       static EventParamType types[] = {typeWindowRef,
-                                        typeQDPoint,
-                                        typeUInt32,
-                                        typeMouseButton,
-                                        typeUInt32,
-                                        typeUInt32};
+       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,
@@ -9269,6 +9616,18 @@ mac_handle_window_event (next_handler, event, data)
       }
       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;
@@ -9353,18 +9712,18 @@ mac_handle_font_event (next_handler, event, data)
   OSStatus result, err;
   Lisp_Object id_key;
   int num_params;
-  EventParamName *names;
-  EventParamType *types;
-  static EventParamName names_sel[] = {kEventParamATSUFontID,
-                                      kEventParamATSUFontSize,
-                                      kEventParamFMFontFamily,
-                                      kEventParamFMFontSize,
-                                      kEventParamFontColor};
-  static EventParamType types_sel[] = {typeATSUFontID,
-                                      typeATSUSize,
-                                      typeFMFontFamily,
-                                      typeFMFontSize,
-                                      typeFontColor};
+  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)
@@ -9395,6 +9754,199 @@ mac_handle_font_event (next_handler, event, data)
 }
 #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:
+      {
+       EventRef kbd_event;
+       UInt32 actual_size, modifiers, mapped_modifiers;
+
+       err = GetEventParameter (event, kEventParamTextInputSendKeyboardEvent,
+                                typeEventRef, NULL, sizeof (EventRef), NULL,
+                                &kbd_event);
+       if (err == noErr)
+         err = GetEventParameter (kbd_event, kEventParamKeyModifiers,
+                                  typeUInt32, NULL,
+                                  sizeof (UInt32), NULL, &modifiers);
+       if (err == noErr)
+         {
+           mapped_modifiers =
+             (NILP (Vmac_control_modifier) ? 0 : controlKey)
+             | (NILP (Vmac_option_modifier) ? 0 : optionKey)
+             | (NILP (Vmac_command_modifier) ? 0 : cmdKey);
+#ifdef MAC_OSX
+           mapped_modifiers |=
+             (NILP (Vmac_function_modifier) ? 0 : kEventKeyModifierFnMask);
+#endif
+           if (modifiers & mapped_modifiers)
+             /* There're mapped modifier keys.  Process it in
+                XTread_socket.  */
+             return eventNotHandledErr;
+         }
+       if (err == noErr)
+         err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
+                                  typeUnicodeText, NULL, 0, &actual_size,
+                                  NULL);
+       if (err == noErr && actual_size == sizeof (UniChar))
+         {
+           UniChar code;
+
+           err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
+                                    typeUnicodeText, NULL,
+                                    sizeof (UniChar), NULL, &code);
+           if (err == noErr && code < 0x80)
+             {
+               /* ASCII character.  Process it in XTread_socket.  */
+               if (read_socket_inev && code >= 0x20 && code <= 0x7e)
+                 {
+                   UInt32 key_code;
+
+                   err = GetEventParameter (kbd_event, kEventParamKeyCode,
+                                            typeUInt32, NULL, sizeof (UInt32),
+                                            NULL, &key_code);
+                   if (!(err == noErr && key_code <= 0x7f
+                         && keycode_to_xkeysym_table [key_code]))
+                     {
+                       struct frame *f =
+                         mac_focus_frame (&one_mac_display_info);
+
+                       read_socket_inev->kind = ASCII_KEYSTROKE_EVENT;
+                       read_socket_inev->code = code;
+                       read_socket_inev->modifiers =
+                         mac_to_emacs_modifiers (modifiers);
+                       read_socket_inev->modifiers |=
+                         (extra_keyboard_modifiers
+                          & (meta_modifier | alt_modifier
+                             | hyper_modifier | super_modifier));
+                       XSETFRAME (read_socket_inev->frame_or_window, f);
+                     }
+                 }
+               return eventNotHandledErr;
+             }
+         }
+      }
+      /* Non-ASCII keystrokes without mapped modifiers are processed
+        at the Lisp level.  */
+      id_key = Qunicode_for_key_event;
+      num_params = sizeof (names_ufke) / sizeof (names_ufke[0]);
+      names = names_ufke;
+      types = types_ufke;
+      break;
+
+    case kEventTextInputOffsetToPos:
+      {
+       struct frame *f;
+       struct window *w;
+       Point p;
+
+       if (!OVERLAYP (Vmac_ts_active_input_overlay))
+         return eventNotHandledErr;
+
+       /* Strictly speaking, this is not always correct because
+          previous events may change some states about display.  */
+       if (NILP (Foverlay_get (Vmac_ts_active_input_overlay, Qbefore_string)))
+         {
+           /* Active input area is displayed in the echo area.  */
+           w = XWINDOW (echo_area_window);
+           f = WINDOW_XFRAME (w);
+         }
+       else
+         {
+           /* Active input area is displayed around the current point.  */
+           f = SELECTED_FRAME ();
+           w = XWINDOW (f->selected_window);
+         }
+
+       p.h = (WINDOW_TO_FRAME_PIXEL_X (w, w->cursor.x)
+              + WINDOW_LEFT_FRINGE_WIDTH (w));
+       p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, w->cursor.y)
+              + FONT_BASE (FRAME_FONT (f)));
+       SetPortWindowPort (FRAME_MAC_WINDOW (f));
+       LocalToGlobal (&p);
+       err = SetEventParameter (event, kEventParamTextInputReplyPoint,
+                                typeQDPoint, sizeof (typeQDPoint), &p);
+      }
+      break;
+
+    default:
+      abort ();
+    }
+
+  if (!NILP (id_key))
+    err = mac_store_event_ref_as_apple_event (0, 0, Qtext_input, id_key,
+                                             event, num_params,
+                                             names, types);
+
+  return err == noErr ? noErr : result;
+}
+#endif
+
 #ifdef MAC_OSX
 OSStatus
 mac_store_service_event (event)
@@ -9403,12 +9955,12 @@ mac_store_service_event (event)
   OSStatus err;
   Lisp_Object id_key;
   int num_params;
-  EventParamName *names;
-  EventParamType *types;
-  static EventParamName names_pfm[] = {kEventParamServiceMessageName,
-                                      kEventParamServiceUserData};
-  static EventParamType types_pfm[] = {typeCFStringRef,
-                                      typeCFStringRef};
+  const EventParamName *names;
+  const EventParamType *types;
+  static const EventParamName names_pfm[] =
+    {kEventParamServiceMessageName, kEventParamServiceUserData};
+  static const EventParamType types_pfm[] =
+    {typeCFStringRef, typeCFStringRef};
 
   switch (GetEventKind (event))
     {
@@ -9440,31 +9992,47 @@ mac_store_service_event (event)
 #endif /* USE_CARBON_EVENTS */
 
 
-OSErr
+OSStatus
 install_window_handler (window)
      WindowPtr window;
 {
-  OSErr err = noErr;
+  OSStatus err = noErr;
 #if USE_CARBON_EVENTS
-  EventTypeSpec specs_window[] =
+  static const EventTypeSpec specs_window[] =
     {{kEventClassWindow, kEventWindowUpdate},
+     {kEventClassWindow, kEventWindowGetIdealSize},
      {kEventClassWindow, kEventWindowBoundsChanging},
+     {kEventClassWindow, kEventWindowBoundsChanged},
      {kEventClassWindow, kEventWindowShown},
      {kEventClassWindow, kEventWindowHidden},
      {kEventClassWindow, kEventWindowExpanded},
      {kEventClassWindow, kEventWindowCollapsed},
+     {kEventClassWindow, kEventWindowClose},
 #ifdef MAC_OSX
      {kEventClassWindow, kEventWindowToolbarSwitchMode},
+#endif
+#if USE_MAC_TSM
+     {kEventClassWindow, kEventWindowFocusAcquired},
+     {kEventClassWindow, kEventWindowFocusRelinquish},
 #endif
   };
-  EventTypeSpec specs_mouse[] = {{kEventClassMouse, kEventMouseWheelMoved}};
+  static const EventTypeSpec specs_mouse[] =
+    {{kEventClassMouse, kEventMouseWheelMoved}};
   static EventHandlerUPP handle_window_eventUPP = NULL;
   static EventHandlerUPP handle_mouse_eventUPP = NULL;
 #if USE_MAC_FONT_PANEL
-  EventTypeSpec specs_font[] = {{kEventClassFont, kEventFontPanelClosed},
-                               {kEventClassFont, kEventFontSelection}};
+  static 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);
@@ -9473,6 +10041,11 @@ install_window_handler (window)
 #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),
@@ -9487,6 +10060,12 @@ install_window_handler (window)
                                     GetEventTypeCount (specs_font),
                                     specs_font, NULL, NULL);
 #endif
+#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);
@@ -9584,89 +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;
-}
-
-#ifdef MAC_OSX
-/* Table for translating Mac keycode with the laptop `fn' key to that
-   without it.  Destination symbols in comments are keys on US
-   keyboard, and they may not be the same on other types of keyboards.
-   If the destination is identical to the source (f1 ... f12), it
-   doesn't map `fn' key to a modifier.  */
-static unsigned char fn_keycode_to_keycode_table[] = {
-  /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  /*0x20*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
-  /*0x30*/ 0, 0, 0, 0,
-  /*0x34*/ 0, 0, 0, 0,
-  /*0x38*/ 0, 0, 0, 0,
-  /*0x3C*/ 0, 0, 0, 0,
-
-  /*0x40*/ 0, 0x2f /*kp-. -> '.'*/, 0, 0x23 /*kp-* -> 'p'*/,
-  /*0x44*/ 0, 0x2c /*kp-+ -> '/'*/, 0, 0x16 /*clear -> '6'*/,
-  /*0x48*/ 0, 0, 0, 0x1d /*kp-/ -> '0'*/,
-  /*0x4C*/ 0x24 /*kp-enter -> return*/, 0, 0x29 /*kp-- -> ';'*/, 0,
-
-  /*0x50*/ 0, 0x1b /*kp-= -> '-'*/, 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 */
-
 #if !USE_CARBON_EVENTS
 static RgnHandle mouse_region = NULL;
 
@@ -9826,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;
@@ -10076,12 +10568,14 @@ XTread_socket (sd, expected, hold_quit)
                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:
@@ -10130,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:
@@ -10178,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;
 
@@ -10295,7 +10791,6 @@ XTread_socket (sd, expected, hold_quit)
        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;
@@ -10315,7 +10810,7 @@ XTread_socket (sd, expected, hold_quit)
 #endif
            mapped_modifiers &= modifiers;
 
-#if USE_CARBON_EVENTS && defined (MAC_OSX)
+#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
@@ -10324,9 +10819,15 @@ XTread_socket (sd, expected, hold_quit)
            if (!(mapped_modifiers
                  & ~(mac_pass_command_to_system ? cmdKey : 0)
                  & ~(mac_pass_control_to_system ? controlKey : 0)))
-             if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
-                 != eventNotHandledErr)
+             {
+               OSStatus err;
+
+               read_socket_inev = &inev;
+               err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
+               read_socket_inev = NULL;
+               if (err != eventNotHandledErr)
                  break;
+             }
 #endif
            if (er.what == keyUp)
              break;
@@ -10357,16 +10858,21 @@ XTread_socket (sd, expected, hold_quit)
                last_key_script = current_key_script;
              }
 
+#if USE_MAC_TSM
+           if (inev.kind != NO_EVENT)
+             break;
+#endif
+
 #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_to_xkeysym (keycode, &xkeysym))
+           if (keycode <= 0x7f && keycode_to_xkeysym_table [keycode])
              {
                inev.kind = NON_ASCII_KEYSTROKE_EVENT;
-               inev.code = 0xff00 | xkeysym;
+               inev.code = 0xff00 | keycode_to_xkeysym_table [keycode];
 #ifdef MAC_OSX
                if (modifiers & kEventKeyModifierFnMask
                    && keycode <= 0x7f
@@ -10685,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));
 
@@ -10701,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;
-
-    error_code = CGGetActiveDisplayList (1, disp_id, &disp_count);
-    if (error_code != 0)
-      error ("No display found, CGGetActiveDisplayList error %d", error_code);
+    GDHandle main_device_handle = LMGetMainDevice();
 
-    dpyinfo->n_planes = CGDisplayBitsPerPixel (disp_id[0]);
+    dpyinfo->color_p = TestDeviceAttribute (main_device_handle, gdDevType);
+    for (dpyinfo->n_planes = 32; dpyinfo->n_planes > 0; dpyinfo->n_planes >>= 1)
+      if (HasDepth (main_device_handle, dpyinfo->n_planes,
+                   gdDevType, dpyinfo->color_p))
+       break;
+    dpyinfo->height = (**main_device_handle).gdRect.bottom;
+    dpyinfo->width = (**main_device_handle).gdRect.right;
   }
-#else
-  for (dpyinfo->n_planes = 32; dpyinfo->n_planes > 0; dpyinfo->n_planes >>= 1)
-    if (HasDepth (main_device_handle, dpyinfo->n_planes,
-                 gdDevType, dpyinfo->color_p))
-      break;
 #endif
-  dpyinfo->height = (**main_device_handle).gdRect.bottom;
-  dpyinfo->width = (**main_device_handle).gdRect.right;
   dpyinfo->grabbed = 0;
   dpyinfo->root_window = NULL;
   dpyinfo->image_cache = make_image_cache ();
@@ -10747,7 +11244,7 @@ mac_initialize_display_info ()
 
 static XrmDatabase
 mac_make_rdb (xrm_option)
-     char *xrm_option;
+     const char *xrm_option;
 {
   XrmDatabase database;
 
@@ -10846,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)
     {
@@ -10937,7 +11437,7 @@ static void
 init_menu_bar ()
 {
 #ifdef MAC_OSX
-  OSErr err;
+  OSStatus err;
   MenuRef menu;
   MenuItemIndex menu_index;
 
@@ -10965,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.  */
 
@@ -11059,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
@@ -11102,7 +11620,7 @@ 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
   Qtoolbar_switch_mode = intern ("toolbar-switch-mode");
   staticpro (&Qtoolbar_switch_mode);
@@ -11115,6 +11633,13 @@ syms_of_macterm ()
   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
@@ -11136,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
@@ -11150,6 +11683,14 @@ 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.  */);
 #ifdef USE_TOOLKIT_SCROLL_BARS
@@ -11248,15 +11789,27 @@ CODING_SYSTEM is a coding system corresponding to TEXT-ENCODING.  */);
 
 #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.
-Each font ID is represented as a four-byte string in native byte
-order.  */);
+    doc: /* Hash table of ATSU font IDs vs plist of attributes and values.  */);
   Vmac_atsu_font_table =
-    make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE),
+    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