Add 2009 to copyright years.
[bpt/emacs.git] / src / xdisp.c
index 56db272..cea8616 100644 (file)
@@ -1,7 +1,7 @@
 /* Display generation from window structure and buffer text.
    Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
                  1997, 1998, 1999, 2000, 2001, 2002, 2003,
-                 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+                 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -167,6 +167,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include <stdio.h>
+#include <limits.h>
 
 #include "lisp.h"
 #include "keyboard.h"
@@ -187,6 +188,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "coding.h"
 #include "process.h"
 #include "region-cache.h"
+#include "font.h"
 #include "fontset.h"
 #include "blockinput.h"
 
@@ -196,8 +198,11 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #ifdef WINDOWSNT
 #include "w32term.h"
 #endif
-#ifdef MAC_OS
-#include "macterm.h"
+#ifdef HAVE_NS
+#include "nsterm.h"
+#endif
+#ifdef USE_GTK
+#include "gtkutil.h"
 #endif
 
 #include "font.h"
@@ -208,8 +213,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #define INFINITY 10000000
 
-#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
-    || defined (USE_GTK)
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
+    || defined(HAVE_NS) || defined (USE_GTK)
 extern void set_frame_menubar P_ ((struct frame *f, int, int));
 extern int pending_menu_activation;
 #endif
@@ -262,6 +267,9 @@ Lisp_Object Qfontification_functions;
    cursor moves into it.  */
 Lisp_Object Vmouse_autoselect_window;
 
+Lisp_Object Vwrap_prefix, Qwrap_prefix;
+Lisp_Object Vline_prefix, Qline_prefix;
+
 /* Non-zero means draw tool bar buttons raised when the mouse moves
    over them.  */
 
@@ -343,10 +351,17 @@ extern Lisp_Object Voverflow_newline_into_fringe;
   (!NILP (Voverflow_newline_into_fringe)       \
    && FRAME_WINDOW_P (it->f)                   \
    && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0    \
-   && it->current_x == it->last_visible_x)
+   && it->current_x == it->last_visible_x      \
+   && it->line_wrap != WORD_WRAP)
 
 #endif /* HAVE_WINDOW_SYSTEM */
 
+/* Test if the display element loaded in IT is a space or tab
+   character.  This is used to determine word wrapping.  */
+
+#define IT_DISPLAYING_WHITESPACE(it)                           \
+  (it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t'))
+
 /* Non-nil means show the text cursor in void text areas
    i.e. in blank areas after eol and eob.  This used to be
    the default in 21.3.  */
@@ -420,7 +435,7 @@ static struct buffer *this_line_buffer;
 /* Nonzero means truncate lines in all windows less wide than the
    frame.  */
 
-int truncate_partial_width_windows;
+Lisp_Object Vtruncate_partial_width_windows;
 
 /* A flag to control how to display unibyte 8-bit character.  */
 
@@ -628,7 +643,7 @@ int message_truncate_lines;
 Lisp_Object Qmessage_truncate_lines;
 
 /* Set to 1 in clear_message to make redisplay_internal aware
-   of an emptied echo area.   */
+   of an emptied echo area.  */
 
 static int message_cleared_p;
 
@@ -715,6 +730,12 @@ struct buffer *displayed_buffer;
 
 EMACS_INT overline_margin;
 
+/* Require underline to be at least this many screen pixels below baseline
+   This to avoid underline "merging" with the base of letters at small
+   font sizes, particularly when x_use_underline_position_properties is on. */
+
+EMACS_INT underline_minimum_offset;
+
 /* Value returned from text property handlers (see below).  */
 
 enum prop_handled
@@ -747,7 +768,6 @@ static enum prop_handled handle_display_prop P_ ((struct it *));
 static enum prop_handled handle_composition_prop P_ ((struct it *));
 static enum prop_handled handle_overlay_change P_ ((struct it *));
 static enum prop_handled handle_fontified_prop P_ ((struct it *));
-static enum prop_handled handle_auto_composed_prop P_ ((struct it *));
 
 /* Properties handled by iterators.  */
 
@@ -759,7 +779,6 @@ static struct props it_props[] =
   {&Qface,             FACE_PROP_IDX,          handle_face_prop},
   {&Qdisplay,          DISPLAY_PROP_IDX,       handle_display_prop},
   {&Qinvisible,                INVISIBLE_PROP_IDX,     handle_invisible_prop},
-  {&Qauto_composed,    AUTO_COMPOSED_PROP_IDX, handle_auto_composed_prop},
   {&Qcomposition,      COMPOSITION_PROP_IDX,   handle_composition_prop},
   {NULL,               0,                      NULL}
 };
@@ -836,6 +855,25 @@ Lisp_Object previous_help_echo_string;
 
 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
 
+/* Platform-independent portion of hourglass implementation. */
+
+/* Non-zero means we're allowed to display a hourglass pointer.  */
+int display_hourglass_p;
+
+/* Non-zero means an hourglass cursor is currently shown.  */
+int hourglass_shown_p;
+
+/* If non-null, an asynchronous timer that, when it expires, displays
+   an hourglass cursor on all frames.  */
+struct atimer *hourglass_atimer;
+
+/* Number of seconds to wait before displaying an hourglass cursor.  */
+Lisp_Object Vhourglass_delay;
+
+/* Default number of seconds to wait before displaying an hourglass
+   cursor.  */
+#define DEFAULT_HOURGLASS_DELAY 1
+
 \f
 /* Function prototypes.  */
 
@@ -847,9 +885,9 @@ static int cursor_row_p P_ ((struct window *, struct glyph_row *));
 static int redisplay_mode_lines P_ ((Lisp_Object, int));
 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
 
-#if 0
-static int invisible_text_between_p P_ ((struct it *, int, int));
-#endif
+static Lisp_Object get_it_property P_ ((struct it *it, Lisp_Object prop));
+
+static void handle_line_prefix P_ ((struct it *));
 
 static void pint2str P_ ((char *, int, int));
 static void pint2hrstr P_ ((char *, int, int));
@@ -1285,7 +1323,7 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
   int visible_p = 0;
   struct buffer *old_buffer = NULL;
 
-  if (noninteractive)
+  if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
     return visible_p;
 
   if (XBUFFER (w->buffer) != current_buffer)
@@ -1718,9 +1756,7 @@ glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
    text, or we can't tell because W's current matrix is not up to
    date.  */
 
-#ifndef HAVE_CARBON
 static
-#endif
 struct glyph *
 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
      struct window *w;
@@ -2057,7 +2093,7 @@ get_phys_cursor_geometry (w, row, glyph, xp, yp, heightp)
      rectangle as wide as the glyph, but use a canonical character
      width instead.  */
   wd = glyph->pixel_width - 1;
-#ifdef HAVE_NTGUI
+#if defined(HAVE_NTGUI) || defined(HAVE_NS)
   wd++; /* Why? */
 #endif
 
@@ -2537,6 +2573,8 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
   it->w = w;
   it->f = XFRAME (w->frame);
 
+  it->cmp_it.id = -1;
+
   /* Extra space between lines (on window systems only).  */
   if (base_face_id == DEFAULT_FACE_ID
       && FRAME_WINDOW_P (it->f))
@@ -2628,19 +2666,27 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
     it->tab_width = 8;
 
   /* Are lines in the display truncated?  */
-  it->truncate_lines_p
-    = (base_face_id != DEFAULT_FACE_ID
-       || XINT (it->w->hscroll)
-       || (truncate_partial_width_windows
-          && !WINDOW_FULL_WIDTH_P (it->w))
-       || !NILP (current_buffer->truncate_lines));
+  if (base_face_id != DEFAULT_FACE_ID
+      || XINT (it->w->hscroll)
+      || (! WINDOW_FULL_WIDTH_P (it->w)
+         && ((!NILP (Vtruncate_partial_width_windows)
+              && !INTEGERP (Vtruncate_partial_width_windows))
+             || (INTEGERP (Vtruncate_partial_width_windows)
+                 && (WINDOW_TOTAL_COLS (it->w)
+                     < XINT (Vtruncate_partial_width_windows))))))
+    it->line_wrap = TRUNCATE;
+  else if (NILP (current_buffer->truncate_lines))
+    it->line_wrap = NILP (current_buffer->word_wrap)
+      ? WINDOW_WRAP : WORD_WRAP;
+  else
+    it->line_wrap = TRUNCATE;
 
   /* Get dimensions of truncation and continuation glyphs.  These are
      displayed as fringe bitmaps under X, so we don't need them for such
      frames.  */
   if (!FRAME_WINDOW_P (it->f))
     {
-      if (it->truncate_lines_p)
+      if (it->line_wrap == TRUNCATE)
        {
          /* We will need the truncation glyph.  */
          xassert (it->glyph_row == NULL);
@@ -2690,7 +2736,7 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
         for window-based redisplay.  */
       if (!FRAME_WINDOW_P (it->f))
        {
-         if (it->truncate_lines_p)
+         if (it->line_wrap == TRUNCATE)
            it->last_visible_x -= it->truncation_pixel_width;
          else
            it->last_visible_x -= it->continuation_pixel_width;
@@ -2763,7 +2809,7 @@ start_display (it, w, pos)
 
   /* Don't reseat to previous visible line start if current start
      position is in a string or image.  */
-  if (it->method == GET_FROM_BUFFER && !it->truncate_lines_p)
+  if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
     {
       int start_at_line_beg_p;
       int first_y = it->current_y;
@@ -2788,7 +2834,7 @@ start_display (it, w, pos)
             taken us to the start of the continuation line but to the
             end of the continued line.  */
          if (it->current_x > 0
-             && !it->truncate_lines_p /* Lines are continued.  */
+             && it->line_wrap != TRUNCATE /* Lines are continued.  */
              && (/* And glyph doesn't fit on the line.  */
                  new_x > it->last_visible_x
                  /* Or it fits exactly and we're on a window
@@ -2953,25 +2999,6 @@ init_from_display_pos (it, w, pos)
       it->method = GET_FROM_STRING;
     }
 
-#if 0 /* This is bogus because POS not having an overlay string
-        position does not mean it's after the string.  Example: A
-        line starting with a before-string and initialization of IT
-        to the previous row's end position.  */
-  else if (it->current.overlay_string_index >= 0)
-    {
-      /* If POS says we're already after an overlay string ending at
-        POS, make sure to pop the iterator because it will be in
-        front of that overlay string.  When POS is ZV, we've thereby
-        also ``processed'' overlay strings at ZV.  */
-      while (it->sp)
-       pop_it (it);
-      xassert (it->current.overlay_string_index == -1);
-      xassert (it->method == GET_FROM_BUFFER);
-      if (CHARPOS (pos->pos) == ZV)
-       it->overlay_strings_at_end_processed_p = 1;
-    }
-#endif /* 0 */
-
   if (CHARPOS (pos->string_pos) >= 0)
     {
       /* Recorded position is not in an overlay string, but in another
@@ -3060,6 +3087,7 @@ handle_stop (it)
   it->current.dpvec_index = -1;
   handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
   it->ignore_overlay_strings_at_pos_p = 0;
+  it->ellipsis_p = 0;
 
   /* Use face of preceding text for ellipsis (if invisible) */
   if (it->selective_display_ellipsis_p)
@@ -3080,13 +3108,29 @@ handle_stop (it)
            {
              /* We still want to show before and after strings from
                 overlays even if the actual buffer text is replaced.  */
-             if (!handle_overlay_change_p || it->sp > 1)
-               return;
-             if (!get_overlay_strings_1 (it, 0, 0))
-               return;
-             it->ignore_overlay_strings_at_pos_p = 1;
-             it->string_from_display_prop_p = 0;
-             handle_overlay_change_p = 0;
+             if (!handle_overlay_change_p
+                 || it->sp > 1
+                 || !get_overlay_strings_1 (it, 0, 0))
+               {
+                 if (it->ellipsis_p)
+                   setup_for_ellipsis (it, 0);
+                 /* When handling a display spec, we might load an
+                    empty string.  In that case, discard it here.  We
+                    used to discard it in handle_single_display_spec,
+                    but that causes get_overlay_strings_1, above, to
+                    ignore overlay strings that we must check.  */
+                 if (STRINGP (it->string) && !SCHARS (it->string))
+                   pop_it (it);
+                 return;
+               }
+             else if (STRINGP (it->string) && !SCHARS (it->string))
+               pop_it (it);
+             else
+               {
+                 it->ignore_overlay_strings_at_pos_p = 1;
+                 it->string_from_display_prop_p = 0;
+                 handle_overlay_change_p = 0;
+               }
              handled = HANDLED_RECOMPUTE_PROPS;
              break;
            }
@@ -3107,6 +3151,12 @@ handle_stop (it)
          if (handle_overlay_change_p)
            handled = handle_overlay_change (it);
        }
+
+      if (it->ellipsis_p)
+       {
+         setup_for_ellipsis (it, 0);
+         break;
+       }
     }
   while (handled == HANDLED_RECOMPUTE_PROPS);
 
@@ -3125,6 +3175,7 @@ compute_stop_pos (it)
 {
   register INTERVAL iv, next_iv;
   Lisp_Object object, limit, position;
+  EMACS_INT charpos, bytepos;
 
   /* If nowhere else, stop at the end.  */
   it->stop_charpos = it->end_charpos;
@@ -3135,19 +3186,22 @@ compute_stop_pos (it)
         properties.  */
       object = it->string;
       limit = Qnil;
-      position = make_number (IT_STRING_CHARPOS (*it));
+      charpos = IT_STRING_CHARPOS (*it);
+      bytepos = IT_STRING_BYTEPOS (*it);
     }
   else
     {
-      int charpos;
+      EMACS_INT pos;
 
       /* If next overlay change is in front of the current stop pos
         (which is IT->end_charpos), stop there.  Note: value of
         next_overlay_change is point-max if no overlay change
         follows.  */
-      charpos = next_overlay_change (IT_CHARPOS (*it));
-      if (charpos < it->stop_charpos)
-       it->stop_charpos = charpos;
+      charpos = IT_CHARPOS (*it);
+      bytepos = IT_BYTEPOS (*it);
+      pos = next_overlay_change (charpos);
+      if (pos < it->stop_charpos)
+       it->stop_charpos = pos;
 
       /* If showing the region, we have to stop at the region
         start or end because the face might change there.  */
@@ -3163,12 +3217,11 @@ compute_stop_pos (it)
          property changes.  */
       XSETBUFFER (object, current_buffer);
       limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
-      position = make_number (IT_CHARPOS (*it));
-
     }
 
   /* Get the interval containing IT's position.  Value is a null
      interval if there isn't such an interval.  */
+  position = make_number (charpos);
   iv = validate_interval_range (object, &position, &position, 0);
   if (!NULL_INTERVAL_P (iv))
     {
@@ -3212,6 +3265,9 @@ compute_stop_pos (it)
        }
     }
 
+  composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
+                               it->stop_charpos, it->string);
+
   xassert (STRINGP (it->string)
           || (it->stop_charpos >= BEGV
               && it->stop_charpos >= IT_CHARPOS (*it)));
@@ -3544,7 +3600,8 @@ face_before_or_after_it_pos (it, before_p)
        /* For composition, we must check the character after the
            composition.  */
        pos = (it->what == IT_COMPOSITION
-              ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
+              ? string_pos (IT_STRING_CHARPOS (*it)
+                            + it->cmp_it.nchars, it->string)
               : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
 
       if (it->current.overlay_string_index >= 0)
@@ -3594,7 +3651,7 @@ face_before_or_after_it_pos (it, before_p)
          if (it->what == IT_COMPOSITION)
            /* For composition, we must check the position after the
               composition.  */
-           pos.charpos += it->cmp_len, pos.bytepos += it->len;
+           pos.charpos += it->cmp_it.nchars, pos.bytepos += it->len;
          else
            INC_TEXT_POS (pos, it->multibyte_p);
        }
@@ -3790,7 +3847,7 @@ handle_invisible_prop (it)
                  it->position.charpos = IT_CHARPOS (*it) - 1;
                  it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
                }
-              setup_for_ellipsis (it, 0);
+             it->ellipsis_p = 1;
              /* Let the ellipsis display before
                 considering any properties of the following char.
                 Fixes jasonr@gnu.org 01 Oct 07 bug.  */
@@ -3938,11 +3995,8 @@ handle_display_prop (it)
     }
   else
     {
-      int ret = handle_single_display_spec (it, prop, object, overlay,
-                                           position, 0);
-      if (ret < 0)  /* Replaced by "", i.e. nothing. */
-       return HANDLED_RECOMPUTE_PROPS;
-      if (ret)
+      if (handle_single_display_spec (it, prop, object, overlay,
+                                     position, 0))
        display_replaced_p = 1;
     }
 
@@ -3989,8 +4043,7 @@ display_prop_end (it, object, start_pos)
    property ends.
 
    Value is non-zero if something was found which replaces the display
-   of buffer or string text.  Specifically, the value is -1 if that
-   "something" is "nothing". */
+   of buffer or string text.  */
 
 static int
 handle_single_display_spec (it, spec, object, overlay, position,
@@ -4315,11 +4368,6 @@ handle_single_display_spec (it, spec, object, overlay, position,
 
       if (STRINGP (value))
        {
-         if (SCHARS (value) == 0)
-           {
-             pop_it (it);
-             return -1;  /* Replaced by "", i.e. nothing.  */
-           }
          it->string = value;
          it->multibyte_p = STRING_MULTIBYTE (it->string);
          it->current.overlay_string_index = -1;
@@ -4568,95 +4616,6 @@ string_buffer_position (w, string, around_charpos)
                        `composition' property
  ***********************************************************************/
 
-static enum prop_handled
-handle_auto_composed_prop (it)
-     struct it *it;
-{
-  enum prop_handled handled = HANDLED_NORMALLY;
-
-  if (FRAME_WINDOW_P (it->f) && FUNCTIONP (Vauto_composition_function))
-    {
-      Lisp_Object val = Qnil;
-      EMACS_INT pos, limit = -1;
-
-      if (STRINGP (it->string))
-       pos = IT_STRING_CHARPOS (*it);
-      else
-       pos = IT_CHARPOS (*it);
-
-      val = Fget_text_property (make_number (pos), Qauto_composed, it->string);
-      if (! NILP (val))
-       {
-         Lisp_Object cmp_prop;
-         EMACS_INT cmp_start, cmp_end;
-
-         if (get_property_and_range (pos, Qcomposition, &cmp_prop,
-                                     &cmp_start, &cmp_end, it->string)
-             && cmp_start == pos
-             && COMPOSITION_METHOD (cmp_prop) == COMPOSITION_WITH_GLYPH_STRING)
-           {
-             Lisp_Object gstring = COMPOSITION_COMPONENTS (cmp_prop);
-             Lisp_Object font_object = LGSTRING_FONT (gstring);
-
-             if (! EQ (font_object,
-                       font_at (-1, pos, FACE_FROM_ID (it->f, it->face_id),
-                                it->w, it->string)))
-               /* We must re-compute the composition for the
-                  different font.  */
-               val = Qnil;
-           }
-
-         if (! NILP (val))
-           {
-             Lisp_Object end;
-
-             /* As Fnext_single_char_property_change is very slow, we
-                limit the search to the current line.  */
-             if (STRINGP (it->string))
-               limit = SCHARS (it->string);
-             else
-               limit = find_next_newline_no_quit (pos, 1);
-             end = Fnext_single_char_property_change (make_number (pos),
-                                                      Qauto_composed,
-                                                      it->string,
-                                                      make_number (limit));
-
-             if (XINT (end) < limit)
-               /* The current point is auto-composed, but there exist
-                  characters not yet composed beyond the
-                  auto-composed region.  There's a possiblity that
-                  the last characters in the region may be newly
-                  composed.  */
-               val = Qnil;
-           }
-       }
-      if (NILP (val) && ! STRINGP (it->string))
-       {
-         if (limit < 0)
-           limit = (STRINGP (it->string) ? SCHARS (it->string)
-                    : find_next_newline_no_quit (pos, 1));
-         if (pos < limit)
-           {
-             int count = SPECPDL_INDEX ();
-             Lisp_Object args[5];
-
-             limit = font_range (pos, limit, FACE_FROM_ID (it->f, it->face_id),
-                                 it->f, it->string);
-             args[0] = Vauto_composition_function;
-             specbind (Qauto_composition_function, Qnil);
-             args[1] = make_number (pos);
-             args[2] = make_number (limit);
-             args[3] = it->window;
-             args[4] = it->string;
-             safe_call (5, args);
-             unbind_to (count, Qnil);
-           }
-       }
-    }
-
-  return handled;
-}
-
 /* Set up iterator IT from `composition' property at its current
    position.  Called from handle_stop.  */
 
@@ -4666,7 +4625,6 @@ handle_composition_prop (it)
 {
   Lisp_Object prop, string;
   EMACS_INT pos, pos_byte, start, end;
-  enum prop_handled handled = HANDLED_NORMALLY;
 
   if (STRINGP (it->string))
     {
@@ -4693,8 +4651,6 @@ handle_composition_prop (it)
       && COMPOSITION_VALID_P (start, end, prop)
       && (STRINGP (it->string) || (PT <= start || PT >= end)))
     {
-      int id;
-
       if (start != pos)
        {
          if (STRINGP (it->string))
@@ -4702,63 +4658,18 @@ handle_composition_prop (it)
          else
            pos_byte = CHAR_TO_BYTE (start);
        }
-      id = get_composition_id (start, pos_byte, end - start, prop, string);
+      it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
+                                              prop, string);
 
-      if (id >= 0)
+      if (it->cmp_it.id >= 0)
        {
-         struct composition *cmp = composition_table[id];
-
-         if (cmp->glyph_len == 0)
-           {
-             /* No glyph.  */
-             if (STRINGP (it->string))
-               {
-                 IT_STRING_CHARPOS (*it) = end;
-                 IT_STRING_BYTEPOS (*it) = string_char_to_byte (it->string,
-                                                                end);
-               }
-             else
-               {
-                 IT_CHARPOS (*it) = end;
-                 IT_BYTEPOS (*it) = CHAR_TO_BYTE (end);
-               }
-             return HANDLED_RECOMPUTE_PROPS;
-           }
-
-         it->stop_charpos = end;
-         push_it (it);
-
-         it->method = GET_FROM_COMPOSITION;
-         it->cmp_id = id;
-         it->cmp_len = COMPOSITION_LENGTH (prop);
-         /* For a terminal, draw only the first (non-TAB) character
-            of the components.  */
-         if (composition_table[id]->method == COMPOSITION_WITH_GLYPH_STRING)
-           {
-             /* FIXME: This doesn't do anything!?! */
-             Lisp_Object lgstring = AREF (XHASH_TABLE (composition_hash_table)
-                                          ->key_and_value,
-                                          cmp->hash_index * 2);
-           }
-         else
-           {
-             int i;
-
-             for (i = 0; i < cmp->glyph_len; i++)
-               if ((it->c = COMPOSITION_GLYPH (composition_table[id], i))
-                   != '\t')
-                 break;
-           }
-         if (it->c == '\t')
-           it->c = ' ';
-         it->len = (STRINGP (it->string)
-                    ? string_char_to_byte (it->string, end)
-                    : CHAR_TO_BYTE (end)) - pos_byte;
-         handled = HANDLED_RETURN;
+         it->cmp_it.ch = -1;
+         it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
+         it->cmp_it.nglyphs = -1;
        }
     }
 
-  return handled;
+  return HANDLED_NORMALLY;
 }
 
 
@@ -4810,11 +4721,10 @@ next_overlay_string (it)
       /* No more overlay strings.  Restore IT's settings to what
         they were before overlay strings were processed, and
         continue to deliver from current_buffer.  */
-      int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
 
+      it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
       pop_it (it);
       xassert (it->sp > 0
-              || it->method == GET_FROM_COMPOSITION
               || (NILP (it->string)
                   && it->method == GET_FROM_BUFFER
                   && it->stop_charpos >= BEGV
@@ -4827,11 +4737,6 @@ next_overlay_string (it)
         next_element_from_buffer doesn't try it again.  */
       if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
        it->overlay_strings_at_end_processed_p = 1;
-
-      /* If we have to display `...' for invisible text, set
-        the iterator up for that.  */
-      if (display_ellipsis_p)
-       setup_for_ellipsis (it, 0);
     }
   else
     {
@@ -4851,6 +4756,8 @@ next_overlay_string (it)
       SET_TEXT_POS (it->current.string_pos, 0, 0);
       it->method = GET_FROM_STRING;
       it->stop_charpos = 0;
+      if (it->cmp_it.stop_pos >= 0)
+       it->cmp_it.stop_pos = 0;
     }
 
   CHECK_IT (it);
@@ -5109,7 +5016,11 @@ get_overlay_strings_1 (it, charpos, compute_stop_p)
       /* Save IT's settings.  They are restored after all overlay
         strings have been processed.  */
       xassert (!compute_stop_p || it->sp == 0);
-      push_it (it);
+
+      /* When called from handle_stop, there might be an empty display
+         string loaded.  In that case, don't bother saving it.  */
+      if (!STRINGP (it->string) || SCHARS (it->string))
+       push_it (it);
 
       /* Set up IT to deliver display elements from the first overlay
         string.  */
@@ -5165,6 +5076,7 @@ push_it (it)
   p = it->stack + it->sp;
 
   p->stop_charpos = it->stop_charpos;
+  p->cmp_it = it->cmp_it;
   xassert (it->face_id >= 0);
   p->face_id = it->face_id;
   p->string = it->string;
@@ -5177,13 +5089,6 @@ push_it (it)
       p->u.image.image_id = it->image_id;
       p->u.image.slice = it->slice;
       break;
-    case GET_FROM_COMPOSITION:
-      p->u.comp.object = it->object;
-      p->u.comp.c = it->c;
-      p->u.comp.len = it->len;
-      p->u.comp.cmp_id = it->cmp_id;
-      p->u.comp.cmp_len = it->cmp_len;
-      break;
     case GET_FROM_STRETCH:
       p->u.stretch.object = it->object;
       break;
@@ -5194,6 +5099,7 @@ push_it (it)
   p->string_nchars = it->string_nchars;
   p->area = it->area;
   p->multibyte_p = it->multibyte_p;
+  p->avoid_cursor_p = it->avoid_cursor_p;
   p->space_width = it->space_width;
   p->font_height = it->font_height;
   p->voffset = it->voffset;
@@ -5219,6 +5125,7 @@ pop_it (it)
   --it->sp;
   p = it->stack + it->sp;
   it->stop_charpos = p->stop_charpos;
+  it->cmp_it = p->cmp_it;
   it->face_id = p->face_id;
   it->current = p->current;
   it->position = p->position;
@@ -5234,13 +5141,6 @@ pop_it (it)
       it->object = p->u.image.object;
       it->slice = p->u.image.slice;
       break;
-    case GET_FROM_COMPOSITION:
-      it->object = p->u.comp.object;
-      it->c = p->u.comp.c;
-      it->len = p->u.comp.len;
-      it->cmp_id = p->u.comp.cmp_id;
-      it->cmp_len = p->u.comp.cmp_len;
-      break;
     case GET_FROM_STRETCH:
       it->object = p->u.comp.object;
       break;
@@ -5255,6 +5155,7 @@ pop_it (it)
   it->string_nchars = p->string_nchars;
   it->area = p->area;
   it->multibyte_p = p->multibyte_p;
+  it->avoid_cursor_p = p->avoid_cursor_p;
   it->space_width = p->space_width;
   it->font_height = p->font_height;
   it->voffset = p->voffset;
@@ -5426,6 +5327,7 @@ back_to_previous_visible_line_start (it)
        pos = --IT_CHARPOS (it2);
        --IT_BYTEPOS (it2);
        it2.sp = 0;
+       it2.string_from_display_prop_p = 0;
        if (handle_display_prop (&it2) == HANDLED_RETURN
            && !NILP (val = get_char_property_and_overlay
                      (make_number (pos), Qdisplay, Qnil, &overlay))
@@ -5576,6 +5478,7 @@ reseat_1 (it, pos, set_stop_p)
   IT_STRING_CHARPOS (*it) = -1;
   IT_STRING_BYTEPOS (*it) = -1;
   it->string = Qnil;
+  it->string_from_display_prop_p = 0;
   it->method = GET_FROM_BUFFER;
   it->object = it->w->buffer;
   it->area = TEXT_AREA;
@@ -5697,7 +5600,6 @@ static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
 {
   next_element_from_buffer,
   next_element_from_display_vector,
-  next_element_from_composition,
   next_element_from_string,
   next_element_from_c_string,
   next_element_from_image,
@@ -5706,6 +5608,19 @@ static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
 
 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
 
+
+/* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
+   (possibly with the following characters).  */
+
+#define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS)                            \
+  ((IT)->cmp_it.id >= 0                                                        \
+   || ((IT)->cmp_it.stop_pos == (CHARPOS)                              \
+       && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS,      \
+                                (IT)->end_charpos, (IT)->w,            \
+                                FACE_FROM_ID ((IT)->f, (IT)->face_id), \
+                                (IT)->string)))
+
+
 /* Load IT's display element fields with information about the next
    display element from the current position of IT.  Value is zero if
    end of buffer (or C string) is reached.  */
@@ -5980,6 +5895,7 @@ get_next_display_element (it)
        }
     }
 
+#ifdef HAVE_WINDOW_SYSTEM
   /* Adjust face id for a multibyte character.  There are no multibyte
      character in unibyte text.  */
   if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
@@ -5988,26 +5904,75 @@ get_next_display_element (it)
       && FRAME_WINDOW_P (it->f))
     {
       struct face *face = FACE_FROM_ID (it->f, it->face_id);
-      int pos = (it->s ? -1
-                : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
-                : IT_CHARPOS (*it));
 
-      it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
+      if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
+       {
+         /* Automatic composition with glyph-string.   */
+         Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
+
+         it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
+       }
+      else
+       {
+         int pos = (it->s ? -1
+                    : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
+                    : IT_CHARPOS (*it));
+
+         it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
+       }
     }
+#endif
 
   /* Is this character the last one of a run of characters with
      box?  If yes, set IT->end_of_box_run_p to 1.  */
   if (it->face_box_p
       && it->s == NULL)
     {
-      int face_id;
-      struct face *face;
+      if (it->method == GET_FROM_STRING && it->sp)
+       {
+         int face_id = underlying_face_id (it);
+         struct face *face = FACE_FROM_ID (it->f, face_id);
 
-      it->end_of_box_run_p
-       = ((face_id = face_after_it_pos (it),
-           face_id != it->face_id)
-          && (face = FACE_FROM_ID (it->f, face_id),
-              face->box == FACE_NO_BOX));
+         if (face)
+           {
+             if (face->box == FACE_NO_BOX)
+               {
+                 /* If the box comes from face properties in a
+                    display string, check faces in that string.  */
+                 int string_face_id = face_after_it_pos (it);
+                 it->end_of_box_run_p
+                   = (FACE_FROM_ID (it->f, string_face_id)->box
+                      == FACE_NO_BOX);
+               }
+             /* Otherwise, the box comes from the underlying face.
+                If this is the last string character displayed, check
+                the next buffer location.  */
+             else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
+                      && (it->current.overlay_string_index
+                          == it->n_overlay_strings - 1))
+               {
+                 EMACS_INT ignore;
+                 int next_face_id;
+                 struct text_pos pos = it->current.pos;
+                 INC_TEXT_POS (pos, it->multibyte_p);
+
+                 next_face_id = face_at_buffer_position
+                   (it->w, CHARPOS (pos), it->region_beg_charpos,
+                    it->region_end_charpos, &ignore,
+                    (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0);
+                 it->end_of_box_run_p
+                   = (FACE_FROM_ID (it->f, next_face_id)->box
+                      == FACE_NO_BOX);
+               }
+           }
+       }
+      else
+       {
+         int face_id = face_after_it_pos (it);
+         it->end_of_box_run_p
+           = (face_id != it->face_id
+              && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
+       }
     }
 
   /* Value is 0 if end of buffer or string reached.  */
@@ -6048,6 +6013,20 @@ set_iterator_to_next (it, reseat_p)
         invisible lines that are so because of selective display.  */
       if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
        reseat_at_next_visible_line_start (it, 0);
+      else if (it->cmp_it.id >= 0)
+       {
+         IT_CHARPOS (*it) += it->cmp_it.nchars;
+         IT_BYTEPOS (*it) += it->cmp_it.nbytes;
+         if (it->cmp_it.to < it->cmp_it.nglyphs)
+           it->cmp_it.from = it->cmp_it.to;
+         else
+           {
+             it->cmp_it.id = -1;
+             composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
+                                           IT_BYTEPOS (*it), it->stop_charpos,
+                                           Qnil);
+           }
+       }
       else
        {
          xassert (it->len != 0);
@@ -6057,23 +6036,6 @@ set_iterator_to_next (it, reseat_p)
        }
       break;
 
-    case GET_FROM_COMPOSITION:
-      xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
-      xassert (it->sp > 0);
-      pop_it (it);
-      if (it->method == GET_FROM_STRING)
-       {
-         IT_STRING_BYTEPOS (*it) += it->len;
-         IT_STRING_CHARPOS (*it) += it->cmp_len;
-         goto consider_string_end;
-       }
-      else if (it->method == GET_FROM_BUFFER)
-       {
-         IT_BYTEPOS (*it) += it->len;
-         IT_CHARPOS (*it) += it->cmp_len;
-       }
-      break;
-
     case GET_FROM_C_STRING:
       /* Current display element of IT is from a C string.  */
       IT_BYTEPOS (*it) += it->len;
@@ -6129,8 +6091,26 @@ set_iterator_to_next (it, reseat_p)
     case GET_FROM_STRING:
       /* Current display element is a character from a Lisp string.  */
       xassert (it->s == NULL && STRINGP (it->string));
-      IT_STRING_BYTEPOS (*it) += it->len;
-      IT_STRING_CHARPOS (*it) += 1;
+      if (it->cmp_it.id >= 0)
+       {
+         IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
+         IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
+         if (it->cmp_it.to < it->cmp_it.nglyphs)
+           it->cmp_it.from = it->cmp_it.to;
+         else
+           {
+             it->cmp_it.id = -1;
+             composition_compute_stop_pos (&it->cmp_it,
+                                           IT_STRING_CHARPOS (*it),
+                                           IT_STRING_BYTEPOS (*it),
+                                           it->stop_charpos, it->string);
+           }
+       }
+      else
+       {
+         IT_STRING_BYTEPOS (*it) += it->len;
+         IT_STRING_CHARPOS (*it) += 1;
+       }
 
     consider_string_end:
 
@@ -6139,7 +6119,12 @@ set_iterator_to_next (it, reseat_p)
          /* IT->string is an overlay string.  Advance to the
             next, if there is one.  */
          if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
-           next_overlay_string (it);
+           {
+             it->ellipsis_p = 0;
+             next_overlay_string (it);
+             if (it->ellipsis_p)
+               setup_for_ellipsis (it, 0);
+           }
        }
       else
        {
@@ -6200,9 +6185,9 @@ next_element_from_display_vector (it)
 
   /* KFS: This code used to check ip->dpvec[0] instead of the current element.
           That seemed totally bogus - so I changed it...  */
+  gc = it->dpvec[it->current.dpvec_index];
 
-  if ((gc = it->dpvec[it->current.dpvec_index], GLYPH_CODE_P (gc))
-      && GLYPH_CODE_CHAR_VALID_P (gc))
+  if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc))
     {
       it->c = GLYPH_CODE_CHAR (gc);
       it->len = CHAR_BYTES (it->c);
@@ -6268,6 +6253,12 @@ next_element_from_string (it)
          it->what = IT_EOB;
          return 0;
        }
+      else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
+                               IT_STRING_BYTEPOS (*it))
+              && next_element_from_composition (it))
+       {
+         return 1;
+       }
       else if (STRING_MULTIBYTE (it->string))
        {
          int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
@@ -6298,6 +6289,12 @@ next_element_from_string (it)
          it->c = ' ', it->len = 1;
          CHARPOS (position) = BYTEPOS (position) = -1;
        }
+      else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
+                               IT_STRING_BYTEPOS (*it))
+              && next_element_from_composition (it))
+       {
+         return 1;
+       }
       else if (STRING_MULTIBYTE (it->string))
        {
          int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
@@ -6435,10 +6432,7 @@ next_element_from_buffer (it)
 {
   int success_p = 1;
 
-  /* Check this assumption, otherwise, we would never enter the
-     if-statement, below.  */
-  xassert (IT_CHARPOS (*it) >= BEGV
-          && IT_CHARPOS (*it) <= it->stop_charpos);
+  xassert (IT_CHARPOS (*it) >= BEGV);
 
   if (IT_CHARPOS (*it) >= it->stop_charpos)
     {
@@ -6484,14 +6478,16 @@ next_element_from_buffer (it)
          && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
        run_redisplay_end_trigger_hook (it);
 
+      if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it))
+         && next_element_from_composition (it))
+       {
+         return 1;
+       }
+
       /* Get the next character, maybe multibyte.  */
       p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
       if (it->multibyte_p && !ASCII_BYTE_P (*p))
-       {
-         int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
-                       - IT_BYTEPOS (*it));
-         it->c = string_char_and_length (p, maxlen, &it->len);
-       }
+       it->c = STRING_CHAR_AND_LENGTH (p, 0, it->len);
       else
        it->c = *p, it->len = 1;
 
@@ -6563,22 +6559,43 @@ run_redisplay_end_trigger_hook (it)
 }
 
 
-/* Deliver a composition display element.  The iterator IT is already
-   filled with composition information (done in
-   handle_composition_prop).  Value is always 1.  */
+/* Deliver a composition display element.  Unlike the other
+   next_element_from_XXX, this function is not registered in the array
+   get_next_element[].  It is called from next_element_from_buffer and
+   next_element_from_string when necessary.  */
 
 static int
 next_element_from_composition (it)
      struct it *it;
 {
   it->what = IT_COMPOSITION;
-  it->position = (STRINGP (it->string)
-                 ? it->current.string_pos
-                 : it->current.pos);
+  it->len = it->cmp_it.nbytes;
   if (STRINGP (it->string))
-    it->object = it->string;
+    {
+      if (it->c < 0)
+       {
+         IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
+         IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
+         return 0;
+       }
+      it->position = it->current.string_pos;
+      it->object = it->string;
+      it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
+                                    IT_STRING_BYTEPOS (*it), it->string);
+    }
   else
-    it->object = it->w->buffer;
+    {
+      if (it->c < 0)
+       {
+         IT_CHARPOS (*it) += it->cmp_it.nchars;
+         IT_BYTEPOS (*it) += it->cmp_it.nbytes;
+         return 0;
+       }
+      it->position = it->current.pos;
+      it->object = it->w->buffer;
+      it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
+                                    IT_BYTEPOS (*it), Qnil);
+    }
   return 1;
 }
 
@@ -6637,11 +6654,22 @@ move_it_in_display_line_to (struct it *it,
 {
   enum move_it_result result = MOVE_UNDEFINED;
   struct glyph_row *saved_glyph_row;
+  struct it wrap_it, atpos_it, atx_it;
+  int may_wrap = 0;
 
   /* Don't produce glyphs in produce_glyphs.  */
   saved_glyph_row = it->glyph_row;
   it->glyph_row = NULL;
 
+  /* Use wrap_it to save a copy of IT wherever a word wrap could
+     occur.  Use atpos_it to save a copy of IT at the desired buffer
+     position, if found, so that we can scan ahead and check if the
+     word later overshoots the window edge.  Use atx_it similarly, for
+     pixel positions.  */
+  wrap_it.sp = -1;
+  atpos_it.sp = -1;
+  atx_it.sp = -1;
+
 #define BUFFER_POS_REACHED_P()                                 \
   ((op & MOVE_TO_POS) != 0                                     \
    && BUFFERP (it->object)                                     \
@@ -6650,47 +6678,98 @@ move_it_in_display_line_to (struct it *it,
        || (it->method == GET_FROM_DISPLAY_VECTOR               \
           && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
 
+  /* If there's a line-/wrap-prefix, handle it.  */
+  if (it->hpos == 0 && it->method == GET_FROM_BUFFER
+      && it->current_y < it->last_visible_y)
+    handle_line_prefix (it);
 
   while (1)
     {
       int x, i, ascent = 0, descent = 0;
 
-      /* Stop if we move beyond TO_CHARPOS (after an image or stretch glyph).  */
+/* Utility macro to reset an iterator with x, ascent, and descent.  */
+#define IT_RESET_X_ASCENT_DESCENT(IT)                  \
+  ((IT)->current_x = x, (IT)->max_ascent = ascent,     \
+   (IT)->max_descent = descent)
+
+      /* Stop if we move beyond TO_CHARPOS (after an image or stretch
+        glyph).  */
       if ((op & MOVE_TO_POS) != 0
          && BUFFERP (it->object)
          && it->method == GET_FROM_BUFFER
          && IT_CHARPOS (*it) > to_charpos)
        {
-         result = MOVE_POS_MATCH_OR_ZV;
-         break;
+         if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
+           {
+             result = MOVE_POS_MATCH_OR_ZV;
+             break;
+           }
+         else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
+           /* If wrap_it is valid, the current position might be in a
+              word that is wrapped.  So, save the iterator in
+              atpos_it and continue to see if wrapping happens.  */
+           atpos_it = *it;
        }
 
       /* Stop when ZV reached.
          We used to stop here when TO_CHARPOS reached as well, but that is
          too soon if this glyph does not fit on this line.  So we handle it
          explicitly below.  */
-      if (!get_next_display_element (it)
-         || (it->truncate_lines_p
-             && BUFFER_POS_REACHED_P ()))
+      if (!get_next_display_element (it))
        {
          result = MOVE_POS_MATCH_OR_ZV;
          break;
        }
 
-      /* The call to produce_glyphs will get the metrics of the
-        display element IT is loaded with.  We record in x the
-        x-position before this display element in case it does not
-        fit on the line.  */
-      x = it->current_x;
-
-      /* Remember the line height so far in case the next element doesn't
-        fit on the line.  */
-      if (!it->truncate_lines_p)
+      if (it->line_wrap == TRUNCATE)
        {
-         ascent = it->max_ascent;
-         descent = it->max_descent;
+         if (BUFFER_POS_REACHED_P ())
+           {
+             result = MOVE_POS_MATCH_OR_ZV;
+             break;
+           }
+       }
+      else
+       {
+         if (it->line_wrap == WORD_WRAP)
+           {
+             if (IT_DISPLAYING_WHITESPACE (it))
+               may_wrap = 1;
+             else if (may_wrap)
+               {
+                 /* We have reached a glyph that follows one or more
+                    whitespace characters.  If the position is
+                    already found, we are done.  */
+                 if (atpos_it.sp >= 0)
+                   {
+                     *it = atpos_it;
+                     result = MOVE_POS_MATCH_OR_ZV;
+                     goto done;
+                   }
+                 if (atx_it.sp >= 0)
+                   {
+                     *it = atx_it;
+                     result = MOVE_X_REACHED;
+                     goto done;
+                   }
+                 /* Otherwise, we can wrap here.  */
+                 wrap_it = *it;
+                 may_wrap = 0;
+               }
+           }
        }
 
+      /* Remember the line height for the current line, in case
+        the next element doesn't fit on the line.  */
+      ascent = it->max_ascent;
+      descent = it->max_descent;
+
+      /* The call to produce_glyphs will get the metrics of the
+        display element IT is loaded with.  Record the x-position
+        before this display element, in case it doesn't fit on the
+        line.  */
+      x = it->current_x;
+
       PRODUCE_GLYPHS (it);
 
       if (it->area != TEXT_AREA)
@@ -6716,7 +6795,7 @@ move_it_in_display_line_to (struct it *it,
         next line.
 
         Note that both for tabs and padding glyphs, all glyphs have
-        the same width.   */
+        the same width.  */
       if (it->nglyphs)
        {
          /* More than one glyph or glyph doesn't fit on line.  All
@@ -6734,19 +6813,39 @@ move_it_in_display_line_to (struct it *it,
              if ((op & MOVE_TO_X) && new_x > to_x)
                {
                  if (BUFFER_POS_REACHED_P ())
-                   goto buffer_pos_reached;
-                 it->current_x = x;
-                 result = MOVE_X_REACHED;
-                 break;
+                   {
+                     if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
+                       goto buffer_pos_reached;
+                     if (atpos_it.sp < 0)
+                       {
+                         atpos_it = *it;
+                         IT_RESET_X_ASCENT_DESCENT (&atpos_it);
+                       }
+                   }
+                 else
+                   {
+                     if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
+                       {
+                         it->current_x = x;
+                         result = MOVE_X_REACHED;
+                         break;
+                       }
+                     if (atx_it.sp < 0)
+                       {
+                         atx_it = *it;
+                         IT_RESET_X_ASCENT_DESCENT (&atx_it);
+                       }
+                   }
                }
-             else if (/* Lines are continued.  */
-                      !it->truncate_lines_p
-                      && (/* And glyph doesn't fit on the line.  */
-                          new_x > it->last_visible_x
-                          /* Or it fits exactly and we're on a window
-                             system frame.  */
-                          || (new_x == it->last_visible_x
-                              && FRAME_WINDOW_P (it->f))))
+
+             if (/* Lines are continued.  */
+                 it->line_wrap != TRUNCATE
+                 && (/* And glyph doesn't fit on the line.  */
+                     new_x > it->last_visible_x
+                     /* Or it fits exactly and we're on a window
+                        system frame.  */
+                     || (new_x == it->last_visible_x
+                         && FRAME_WINDOW_P (it->f))))
                {
                  if (/* IT->hpos == 0 means the very first glyph
                         doesn't fit on the line, e.g. a wide image.  */
@@ -6766,10 +6865,21 @@ move_it_in_display_line_to (struct it *it,
                             now that we know it fits in this row.  */
                          if (BUFFER_POS_REACHED_P ())
                            {
-                             it->hpos = hpos_before_this_char;
-                             it->current_x = x_before_this_char;
-                             result = MOVE_POS_MATCH_OR_ZV;
-                             break;
+                             if (it->line_wrap != WORD_WRAP
+                                 || wrap_it.sp < 0)
+                               {
+                                 it->hpos = hpos_before_this_char;
+                                 it->current_x = x_before_this_char;
+                                 result = MOVE_POS_MATCH_OR_ZV;
+                                 break;
+                               }
+                             if (it->line_wrap == WORD_WRAP
+                                 && atpos_it.sp < 0)
+                               {
+                                 atpos_it = *it;
+                                 atpos_it.current_x = x_before_this_char;
+                                 atpos_it.hpos = hpos_before_this_char;
+                               }
                            }
 
                          set_iterator_to_next (it, 1);
@@ -6799,10 +6909,13 @@ move_it_in_display_line_to (struct it *it,
                        }
                    }
                  else
+                   IT_RESET_X_ASCENT_DESCENT (it);
+
+                 if (wrap_it.sp >= 0)
                    {
-                     it->current_x = x;
-                     it->max_ascent = ascent;
-                     it->max_descent = descent;
+                     *it = wrap_it;
+                     atpos_it.sp = -1;
+                     atx_it.sp = -1;
                    }
 
                  TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
@@ -6810,19 +6923,24 @@ move_it_in_display_line_to (struct it *it,
                  result = MOVE_LINE_CONTINUED;
                  break;
                }
-             else if (BUFFER_POS_REACHED_P ())
-               goto buffer_pos_reached;
-             else if (new_x > it->first_visible_x)
+
+             if (BUFFER_POS_REACHED_P ())
+               {
+                 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
+                   goto buffer_pos_reached;
+                 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
+                   {
+                     atpos_it = *it;
+                     IT_RESET_X_ASCENT_DESCENT (&atpos_it);
+                   }
+               }
+
+             if (new_x > it->first_visible_x)
                {
                  /* Glyph is visible.  Increment number of glyphs that
                     would be displayed.  */
                  ++it->hpos;
                }
-             else
-               {
-                 /* Glyph is completely off the left margin of the display
-                    area.  Nothing to do.  */
-               }
            }
 
          if (result != MOVE_UNDEFINED)
@@ -6831,9 +6949,7 @@ move_it_in_display_line_to (struct it *it,
       else if (BUFFER_POS_REACHED_P ())
        {
        buffer_pos_reached:
-         it->current_x = x;
-         it->max_ascent = ascent;
-         it->max_descent = descent;
+         IT_RESET_X_ASCENT_DESCENT (it);
          result = MOVE_POS_MATCH_OR_ZV;
          break;
        }
@@ -6861,7 +6977,7 @@ move_it_in_display_line_to (struct it *it,
 
       /* Stop if lines are truncated and IT's current x-position is
         past the right edge of the window now.  */
-      if (it->truncate_lines_p
+      if (it->line_wrap == TRUNCATE
          && it->current_x >= it->last_visible_x)
        {
 #ifdef HAVE_WINDOW_SYSTEM
@@ -6883,10 +6999,20 @@ move_it_in_display_line_to (struct it *it,
          result = MOVE_LINE_TRUNCATED;
          break;
        }
+#undef IT_RESET_X_ASCENT_DESCENT
     }
 
 #undef BUFFER_POS_REACHED_P
 
+  /* If we scanned beyond to_pos and didn't find a point to wrap at,
+     restore the saved iterator.  */
+  if (atpos_it.sp >= 0)
+    *it = atpos_it;
+  else if (atx_it.sp >= 0)
+    *it = atx_it;
+
+ done:
+
   /* Restore the iterator settings altered at the beginning of this
      function.  */
   it->glyph_row = saved_glyph_row;
@@ -6899,7 +7025,25 @@ move_it_in_display_line (struct it *it,
                         EMACS_INT to_charpos, int to_x,
                         enum move_operation_enum op)
 {
-  move_it_in_display_line_to (it, to_charpos, to_x, op);
+  if (it->line_wrap == WORD_WRAP
+      && (op & MOVE_TO_X))
+    {
+      struct it save_it = *it;
+      int skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
+      /* When word-wrap is on, TO_X may lie past the end
+        of a wrapped line.  Then it->current is the
+        character on the next line, so backtrack to the
+        space before the wrap point.  */
+      if (skip == MOVE_LINE_CONTINUED)
+       {
+         int prev_x = max (it->current_x - 1, 0);
+         *it = save_it;
+         move_it_in_display_line_to
+           (it, -1, prev_x, MOVE_TO_X);
+       }
+    }
+  else
+    move_it_in_display_line_to (it, to_charpos, to_x, op);
 }
 
 
@@ -6974,6 +7118,9 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
        {
          struct it it_backup;
 
+         if (it->line_wrap == WORD_WRAP)
+           it_backup = *it;
+
          /* TO_Y specified means stop at TO_X in the line containing
             TO_Y---or at TO_CHARPOS if this is reached first.  The
             problem is that we can't really tell whether the line
@@ -6986,28 +7133,19 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
             If we didn't use TO_X == 0, we would stop at the end of
             the line which is probably not what a caller would expect
             to happen.  */
-         skip = move_it_in_display_line_to (it, to_charpos,
-                                            ((op & MOVE_TO_X)
-                                             ? to_x : 0),
-                                            (MOVE_TO_X
-                                             | (op & MOVE_TO_POS)));
+         skip = move_it_in_display_line_to
+           (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
+            (MOVE_TO_X | (op & MOVE_TO_POS)));
 
          /* If TO_CHARPOS is reached or ZV, we don't have to do more.  */
          if (skip == MOVE_POS_MATCH_OR_ZV)
+           reached = 5;
+         else if (skip == MOVE_X_REACHED)
            {
-             reached = 5;
-             break;
-           }
-
-         /* If TO_X was reached, we would like to know whether TO_Y
-            is in the line.  This can only be said if we know the
-            total line height which requires us to scan the rest of
-            the line.  */
-         if (skip == MOVE_X_REACHED)
-           {
-             /* Wait!  We can conclude that TO_Y is in the line if
-                the already scanned glyphs make the line tall enough
-                because further scanning doesn't make it shorter.  */
+             /* If TO_X was reached, we want to know whether TO_Y is
+                in the line.  We know this is the case if the already
+                scanned glyphs make the line tall enough.  Otherwise,
+                we must check by scanning the rest of the line.  */
              line_height = it->max_ascent + it->max_descent;
              if (to_y >= it->current_y
                  && to_y < it->current_y + line_height)
@@ -7020,34 +7158,56 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
              skip2 = move_it_in_display_line_to (it, to_charpos, -1,
                                                  op & MOVE_TO_POS);
              TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
-           }
-
-         /* Now, decide whether TO_Y is in this line.  */
-         line_height = it->max_ascent + it->max_descent;
-         TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
+             line_height = it->max_ascent + it->max_descent;
+             TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
 
-         if (to_y >= it->current_y
-             && to_y < it->current_y + line_height)
-           {
-             if (skip == MOVE_X_REACHED)
-               /* If TO_Y is in this line and TO_X was reached above,
-                  we scanned too far.  We have to restore IT's settings
-                  to the ones before skipping.  */
-               *it = it_backup;
-             reached = 6;
+             if (to_y >= it->current_y
+                 && to_y < it->current_y + line_height)
+               {
+                 /* If TO_Y is in this line and TO_X was reached
+                    above, we scanned too far.  We have to restore
+                    IT's settings to the ones before skipping.  */
+                 *it = it_backup;
+                 reached = 6;
+               }
+             else
+               {
+                 skip = skip2;
+                 if (skip == MOVE_POS_MATCH_OR_ZV)
+                   reached = 7;
+               }
            }
-         else if (skip == MOVE_X_REACHED)
+         else
            {
-             skip = skip2;
-             if (skip == MOVE_POS_MATCH_OR_ZV)
-               reached = 7;
+             /* Check whether TO_Y is in this line.  */
+             line_height = it->max_ascent + it->max_descent;
+             TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
+
+             if (to_y >= it->current_y
+                 && to_y < it->current_y + line_height)
+               {
+                 /* When word-wrap is on, TO_X may lie past the end
+                    of a wrapped line.  Then it->current is the
+                    character on the next line, so backtrack to the
+                    space before the wrap point.  */
+                 if (skip == MOVE_LINE_CONTINUED
+                     && it->line_wrap == WORD_WRAP)
+                   {
+                     int prev_x = max (it->current_x - 1, 0);
+                     *it = it_backup;
+                     skip = move_it_in_display_line_to
+                       (it, -1, prev_x, MOVE_TO_X);
+                   }
+                 reached = 6;
+               }
            }
 
          if (reached)
            break;
        }
       else if (BUFFERP (it->object)
-              && it->method == GET_FROM_BUFFER
+              && (it->method == GET_FROM_BUFFER
+                  || it->method == GET_FROM_STRETCH)
               && IT_CHARPOS (*it) >= to_charpos)
        skip = MOVE_POS_MATCH_OR_ZV;
       else
@@ -7080,8 +7240,19 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
             associated with the tab are displayed on the current
             line.  Since it->current_x does not include these glyphs,
             we use it->last_visible_x instead.  */
-         it->continuation_lines_width +=
-           (it->c == '\t') ? it->last_visible_x : it->current_x;
+         if (it->c == '\t')
+           {
+             it->continuation_lines_width += it->last_visible_x;
+             /* When moving by vpos, ensure that the iterator really
+                advances to the next line (bug#847, bug#969).  Fixme:
+                do we need to do this in other circumstances?  */
+             if (it->current_x != it->last_visible_x
+                 && (op & MOVE_TO_VPOS)
+                 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
+               set_iterator_to_next (it, 0);
+           }
+         else
+           it->continuation_lines_width += it->current_x;
          break;
 
        default:
@@ -7100,6 +7271,30 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
 
  out:
 
+  /* On text terminals, we may stop at the end of a line in the middle
+     of a multi-character glyph.  If the glyph itself is continued,
+     i.e. it is actually displayed on the next line, don't treat this
+     stopping point as valid; move to the next line instead (unless
+     that brings us offscreen).  */
+  if (!FRAME_WINDOW_P (it->f)
+      && op & MOVE_TO_POS
+      && IT_CHARPOS (*it) == to_charpos
+      && it->what == IT_CHARACTER
+      && it->nglyphs > 1
+      && it->line_wrap == WINDOW_WRAP
+      && it->current_x == it->last_visible_x - 1
+      && it->c != '\n'
+      && it->c != '\t'
+      && it->vpos < XFASTINT (it->w->window_end_vpos))
+    {
+      it->continuation_lines_width += it->current_x;
+      it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
+      it->current_y += it->max_ascent + it->max_descent;
+      ++it->vpos;
+      last_height = it->max_ascent + it->max_descent;
+      last_max_ascent = it->max_ascent;
+    }
+
   TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
 }
 
@@ -7282,41 +7477,6 @@ move_it_past_eol (it)
 }
 
 
-#if 0 /* Currently not used.  */
-
-/* Return non-zero if some text between buffer positions START_CHARPOS
-   and END_CHARPOS is invisible.  IT->window is the window for text
-   property lookup.  */
-
-static int
-invisible_text_between_p (it, start_charpos, end_charpos)
-     struct it *it;
-     int start_charpos, end_charpos;
-{
-  Lisp_Object prop, limit;
-  int invisible_found_p;
-
-  xassert (it != NULL && start_charpos <= end_charpos);
-
-  /* Is text at START invisible?  */
-  prop = Fget_char_property (make_number (start_charpos), Qinvisible,
-                            it->window);
-  if (TEXT_PROP_MEANS_INVISIBLE (prop))
-    invisible_found_p = 1;
-  else
-    {
-      limit = Fnext_single_char_property_change (make_number (start_charpos),
-                                                Qinvisible, Qnil,
-                                                make_number (end_charpos));
-      invisible_found_p = XFASTINT (limit) < end_charpos;
-    }
-
-  return invisible_found_p;
-}
-
-#endif /* 0 */
-
-
 /* Move IT by a specified number DVPOS of screen lines down.  DVPOS
    negative means move up.  DVPOS == 0 means move to the start of the
    screen line.  NEED_Y_P non-zero means calculate IT->current_y.  If
@@ -7732,7 +7892,7 @@ message2_nolog (m, nbytes, multibyte)
   struct frame *sf = SELECTED_FRAME ();
   message_enable_multibyte = multibyte;
 
-  if (noninteractive)
+  if (FRAME_INITIAL_P (sf))
     {
       if (noninteractive_need_newline)
        putc ('\n', stderr);
@@ -7831,7 +7991,7 @@ message3_nolog (m, nbytes, multibyte)
   struct frame *sf = SELECTED_FRAME ();
   message_enable_multibyte = multibyte;
 
-  if (noninteractive)
+  if (FRAME_INITIAL_P (sf))
     {
       if (noninteractive_need_newline)
        putc ('\n', stderr);
@@ -7929,7 +8089,7 @@ message_with_string (m, string, log)
            putc ('\n', stderr);
          noninteractive_need_newline = 0;
          fprintf (stderr, m, SDATA (string));
-         if (cursor_in_echo_area == 0)
+         if (!cursor_in_echo_area)
            fprintf (stderr, "\n");
          fflush (stderr);
        }
@@ -8100,6 +8260,9 @@ ensure_echo_area_buffers ()
        sprintf (name, " *Echo Area %d*", i);
        echo_buffer[i] = Fget_buffer_create (build_string (name));
        XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
+       /* to force word wrap in echo area -
+          it was decided to postpone this*/
+       /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
 
        for (j = 0; j < 2; ++j)
          if (EQ (old_buffer, echo_area_buffer[j]))
@@ -8549,7 +8712,7 @@ resize_mini_window (w, exact_p)
       max_height = min (total_height, max_height);
 
       /* Find out the height of the text in the window.  */
-      if (it.truncate_lines_p)
+      if (it.line_wrap == TRUNCATE)
        height = 1;
       else
        {
@@ -9285,7 +9448,32 @@ x_consider_frame_title (frame)
       if (! STRINGP (f->name)
          || SBYTES (f->name) != len
          || bcmp (title, SDATA (f->name), len) != 0)
-       x_implicitly_set_name (f, make_string (title, len), Qnil);
+        {
+#ifdef HAVE_NS
+          if (FRAME_NS_P (f))
+            {
+              if (!MINI_WINDOW_P(XWINDOW(f->selected_window)))
+                {
+                  if (EQ (fmt, Qt))
+                    ns_set_name_as_filename (f);
+                  else
+                    x_implicitly_set_name (f, make_string(title, len),
+                                           Qnil);
+                }
+            }
+          else
+#endif
+           x_implicitly_set_name (f, make_string (title, len), Qnil);
+        }
+#ifdef HAVE_NS
+      if (FRAME_NS_P (f))
+        {
+          /* do this also for frames with explicit names */
+          ns_implicitly_set_icon_type(f);
+          ns_set_doc_edited(f, Fbuffer_modified_p
+                            (XWINDOW (f->selected_window)->buffer), Qnil);
+        }
+#endif
     }
 }
 
@@ -9370,7 +9558,8 @@ prepare_menu_bars ()
 
              while (CONSP (functions))
                {
-                 call1 (XCAR (functions), frame);
+                 if (!EQ (XCAR (functions), Qt))
+                   call1 (XCAR (functions), frame);
                  functions = XCDR (functions);
                }
              UNGCPRO;
@@ -9380,9 +9569,6 @@ prepare_menu_bars ()
          menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
 #ifdef HAVE_WINDOW_SYSTEM
          update_tool_bar (f, 0);
-#ifdef MAC_OS
-         mac_update_title_bar (f, 0);
-#endif
 #endif
          UNGCPRO;
        }
@@ -9395,9 +9581,6 @@ prepare_menu_bars ()
       update_menu_bar (sf, 1, 0);
 #ifdef HAVE_WINDOW_SYSTEM
       update_tool_bar (sf, 1);
-#ifdef MAC_OS
-      mac_update_title_bar (sf, 1);
-#endif
 #endif
     }
 
@@ -9438,19 +9621,10 @@ update_menu_bar (f, save_match_data, hooks_run)
   window = FRAME_SELECTED_WINDOW (f);
   w = XWINDOW (window);
 
-#if 0 /* The if statement below this if statement used to include the
-         condition !NILP (w->update_mode_line), rather than using
-         update_mode_lines directly, and this if statement may have
-         been added to make that condition work.  Now the if
-         statement below matches its comment, this isn't needed.  */
-  if (update_mode_lines)
-    w->update_mode_line = Qt;
-#endif
-
   if (FRAME_WINDOW_P (f)
       ?
-#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
-    || defined (USE_GTK)
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
+    || defined (HAVE_NS) || defined (USE_GTK)
       FRAME_EXTERNAL_MENU_BAR (f)
 #else
       FRAME_MENU_BAR_LINES (f) > 0
@@ -9508,11 +9682,11 @@ update_menu_bar (f, save_match_data, hooks_run)
          FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
 
          /* Redisplay the menu bar in case we changed it.  */
-#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
-    || defined (USE_GTK)
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
+    || defined (HAVE_NS) || defined (USE_GTK)
          if (FRAME_WINDOW_P (f))
-           {
-#ifdef MAC_OS
+            {
+#if defined (HAVE_NS)
               /* All frames on Mac OS share the same menubar.  So only
                  the selected frame should be allowed to set it.  */
               if (f == SELECTED_FRAME ())
@@ -9523,11 +9697,11 @@ update_menu_bar (f, save_match_data, hooks_run)
            /* On a terminal screen, the menu bar is an ordinary screen
               line, and this makes it get updated.  */
            w->update_mode_line = Qt;
-#else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
+#else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
          /* In the non-toolkit version, the menu bar is an ordinary screen
             line, and this makes it get updated.  */
          w->update_mode_line = Qt;
-#endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
+#endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
 
          unbind_to (count, Qnil);
          set_buffer_internal_1 (prev);
@@ -9628,6 +9802,14 @@ FRAME_PTR last_mouse_frame;
 int last_tool_bar_item;
 
 
+static Lisp_Object
+update_tool_bar_unwind (frame)
+     Lisp_Object frame;
+{
+  selected_frame = frame;
+  return Qnil;
+}
+
 /* Update the tool-bar item list for frame F.  This has to be done
    before we start to fill in any display lines.  Called from
    prepare_menu_bars.  If SAVE_MATCH_DATA is non-zero, we must save
@@ -9638,7 +9820,7 @@ update_tool_bar (f, save_match_data)
      struct frame *f;
      int save_match_data;
 {
-#if defined (USE_GTK) || USE_MAC_TOOLBAR
+#if defined (USE_GTK) || defined (HAVE_NS) || USE_MAC_TOOLBAR
   int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
 #else
   int do_update = WINDOWP (f->tool_bar_window)
@@ -9672,7 +9854,7 @@ update_tool_bar (f, save_match_data)
        {
          struct buffer *prev = current_buffer;
          int count = SPECPDL_INDEX ();
-         Lisp_Object new_tool_bar;
+         Lisp_Object frame, new_tool_bar;
           int new_n_tool_bar;
          struct gcpro gcpro1;
 
@@ -9694,6 +9876,14 @@ update_tool_bar (f, save_match_data)
 
          GCPRO1 (new_tool_bar);
 
+         /* We must temporarily set the selected frame to this frame
+            before calling tool_bar_items, because the calculation of
+            the tool-bar keymap uses the selected frame (see
+            `tool-bar-make-keymap' in tool-bar.el).  */
+         record_unwind_protect (update_tool_bar_unwind, selected_frame);
+         XSETFRAME (frame, f);
+         selected_frame = frame;
+
          /* Build desired tool-bar items from keymaps.  */
           new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
                                          &new_n_tool_bar);
@@ -9946,7 +10136,7 @@ display_tool_bar_line (it, height)
              row->used[TEXT_AREA] = n_glyphs_before;
              *it = it_before;
              /* If this is the only glyph on this line, it will never fit on the
-                toolbar, so skip it.   But ensure there is at least one glyph,
+                toolbar, so skip it.  But ensure there is at least one glyph,
                 so we don't accidentally disable the tool-bar.  */
              if (n_glyphs_before == 0
                  && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
@@ -10104,7 +10294,7 @@ redisplay_tool_bar (f)
   struct it it;
   struct glyph_row *row;
 
-#if defined (USE_GTK) || USE_MAC_TOOLBAR
+#if defined (USE_GTK) || defined (HAVE_NS) || USE_MAC_TOOLBAR
   if (FRAME_EXTERNAL_TOOL_BAR (f))
     update_frame_tool_bar (f);
   return 0;
@@ -11111,7 +11301,7 @@ redisplay_internal (preserve_echo_area)
   /* No redisplay if running in batch mode or frame is not yet fully
      initialized, or redisplay is explicitly turned off by setting
      Vinhibit_redisplay.  */
-  if (noninteractive
+  if (FRAME_INITIAL_P (SELECTED_FRAME ())
       || !NILP (Vinhibit_redisplay))
     return;
 
@@ -11134,7 +11324,7 @@ redisplay_internal (preserve_echo_area)
        return;
     }
 
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS)
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
   if (popup_activated ())
     return;
 #endif
@@ -11190,7 +11380,7 @@ redisplay_internal (preserve_echo_area)
   if (face_change_count)
     ++windows_or_buffers_changed;
 
-  if (FRAME_TERMCAP_P (sf)
+  if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
       && FRAME_TTY (sf)->previous_frame != sf)
     {
       /* Since frames on a single ASCII terminal share the same
@@ -11198,7 +11388,7 @@ redisplay_internal (preserve_echo_area)
         the whole thing.  */
       windows_or_buffers_changed++;
       SET_FRAME_GARBAGED (sf);
-#ifndef WINDOWSNT
+#ifndef DOS_NT
       set_tty_color_mode (FRAME_TTY (sf), sf);
 #endif
       FRAME_TTY (sf)->previous_frame = sf;
@@ -11324,6 +11514,10 @@ redisplay_internal (preserve_echo_area)
       /* Resized active mini-window to fit the size of what it is
          showing if its contents might have changed.  */
       must_finish = 1;
+/* FIXME: this causes all frames to be updated, which seems unnecessary
+   since only the current frame needs to be considered.  This function needs
+   to be rewritten with two variables, consider_all_windows and
+   consider_all_frames. */
       consider_all_windows_p = 1;
       ++windows_or_buffers_changed;
       ++update_mode_lines;
@@ -11633,11 +11827,6 @@ redisplay_internal (preserve_echo_area)
                  /* Update the display.  */
                  set_window_update_flags (XWINDOW (f->root_window), 1);
                  pause |= update_frame (f, 0, 0);
-#if 0  /* Exiting the loop can leave the wrong value for buffer_shared.  */
-                 if (pause)
-                   break;
-#endif
-
                  f->updated_p = 1;
                }
            }
@@ -11931,11 +12120,6 @@ mark_window_display_accurate_1 (w, accurate_p)
   if (accurate_p)
     {
       w->window_end_valid = w->buffer;
-#if 0 /* This is incorrect with variable-height lines.  */
-      xassert (XINT (w->window_end_vpos)
-              < (WINDOW_TOTAL_LINES (w)
-                 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
-#endif
       w->update_mode_line = Qnil;
     }
 }
@@ -12125,7 +12309,8 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
   while (glyph < end
         && !INTEGERP (glyph->object)
         && (!BUFFERP (glyph->object)
-            || (last_pos = glyph->charpos) < pt_old))
+            || (last_pos = glyph->charpos) < pt_old
+            || glyph->avoid_cursor_p))
     {
       if (! STRINGP (glyph->object))
        {
@@ -12435,19 +12620,13 @@ try_scrolling (window, just_this_one_p, scroll_conservatively,
 {
   struct window *w = XWINDOW (window);
   struct frame *f = XFRAME (w->frame);
-  struct text_pos scroll_margin_pos;
-  struct text_pos pos;
-  struct text_pos startp;
+  struct text_pos pos, startp;
   struct it it;
-  Lisp_Object window_end;
-  int this_scroll_margin;
-  int dy = 0;
-  int scroll_max;
-  int rc;
-  int amount_to_scroll = 0;
-  Lisp_Object aggressive;
-  int height;
+  int this_scroll_margin, scroll_max, rc, height;
+  int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
   int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
+  Lisp_Object aggressive;
+  int scroll_limit = INT_MAX / FRAME_LINE_HEIGHT (f);
 
 #if GLYPH_DEBUG
   debug_method_add (w, "try_scrolling");
@@ -12458,84 +12637,77 @@ try_scrolling (window, just_this_one_p, scroll_conservatively,
   /* Compute scroll margin height in pixels.  We scroll when point is
      within this distance from the top or bottom of the window.  */
   if (scroll_margin > 0)
-    {
-      this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
-      this_scroll_margin *= FRAME_LINE_HEIGHT (f);
-    }
+    this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
+      * FRAME_LINE_HEIGHT (f);
   else
     this_scroll_margin = 0;
 
-  /* Force scroll_conservatively to have a reasonable value so it doesn't
-     cause an overflow while computing how much to scroll.  */
-  if (scroll_conservatively)
-    scroll_conservatively = min (scroll_conservatively,
-                                 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
-
-  /* Compute how much we should try to scroll maximally to bring point
-     into view.  */
-  if (scroll_step || scroll_conservatively || temp_scroll_step)
-    scroll_max = max (scroll_step,
-                     max (scroll_conservatively, temp_scroll_step));
+  /* Force scroll_conservatively to have a reasonable value, to avoid
+     overflow while computing how much to scroll.  Note that the user
+     can supply scroll-conservatively equal to `most-positive-fixnum',
+     which can be larger than INT_MAX.  */
+  if (scroll_conservatively > scroll_limit)
+    {
+      scroll_conservatively = scroll_limit;
+      scroll_max = INT_MAX;
+    }
+  else if (scroll_step || scroll_conservatively || temp_scroll_step)
+    /* Compute how much we should try to scroll maximally to bring
+       point into view.  */
+    scroll_max = (max (scroll_step,
+                      max (scroll_conservatively, temp_scroll_step))
+                 * FRAME_LINE_HEIGHT (f));
   else if (NUMBERP (current_buffer->scroll_down_aggressively)
           || NUMBERP (current_buffer->scroll_up_aggressively))
-    /* We're trying to scroll because of aggressive scrolling
-       but no scroll_step is set.  Choose an arbitrary one.  Maybe
-       there should be a variable for this.  */
-    scroll_max = 10;
+    /* We're trying to scroll because of aggressive scrolling but no
+       scroll_step is set.  Choose an arbitrary one.  */
+    scroll_max = 10 * FRAME_LINE_HEIGHT (f);
   else
     scroll_max = 0;
-  scroll_max *= FRAME_LINE_HEIGHT (f);
-
-  /* Decide whether we have to scroll down.  Start at the window end
-     and move this_scroll_margin up to find the position of the scroll
-     margin.  */
-  window_end = Fwindow_end (window, Qt);
 
  too_near_end:
 
-  CHARPOS (scroll_margin_pos) = XINT (window_end);
-  BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
-
-  if (this_scroll_margin || extra_scroll_margin_lines)
+  /* Decide whether to scroll down.  */
+  if (PT > CHARPOS (startp))
     {
-      start_display (&it, w, scroll_margin_pos);
-      if (this_scroll_margin)
-       move_it_vertically_backward (&it, this_scroll_margin);
-      if (extra_scroll_margin_lines)
-       move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
-      scroll_margin_pos = it.current.pos;
-    }
+      int scroll_margin_y;
 
-  if (PT >= CHARPOS (scroll_margin_pos))
-    {
-      int y0;
-
-      /* Point is in the scroll margin at the bottom of the window, or
-        below.  Compute a new window start that makes point visible.  */
+      /* Compute the pixel ypos of the scroll margin, then move it to
+        either that ypos or PT, whichever comes first.  */
+      start_display (&it, w, startp);
+      scroll_margin_y = it.last_visible_y - this_scroll_margin
+       - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
+      move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
+                 (MOVE_TO_POS | MOVE_TO_Y));
 
-      /* Compute the distance from the scroll margin to PT.
-        Give up if the distance is greater than scroll_max.  */
-      start_display (&it, w, scroll_margin_pos);
-      y0 = it.current_y;
-      move_it_to (&it, PT, 0, it.last_visible_y, -1,
-                 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
+      if (PT > CHARPOS (it.current.pos))
+       {
+         int y0 = line_bottom_y (&it);
 
-      /* To make point visible, we have to move the window start
-        down so that the line the cursor is in is visible, which
-        means we have to add in the height of the cursor line.  */
-      dy = line_bottom_y (&it) - y0;
+         /* Compute the distance from the scroll margin to PT
+            (including the height of the cursor line).  Moving the
+            iterator unconditionally to PT can be slow if PT is far
+            away, so stop 10 lines past the window bottom (is there a
+            way to do the right thing quickly?).  */
+         move_it_to (&it, PT, -1,
+                     it.last_visible_y + 10 * FRAME_LINE_HEIGHT (f),
+                     -1, MOVE_TO_POS | MOVE_TO_Y);
+         dy = line_bottom_y (&it) - y0;
 
-      if (dy > scroll_max)
-       return SCROLLING_FAILED;
+         if (dy > scroll_max)
+           return SCROLLING_FAILED;
 
-      /* Move the window start down.  If scrolling conservatively,
-        move it just enough down to make point visible.  If
-        scroll_step is set, move it down by scroll_step.  */
-      start_display (&it, w, startp);
+         scroll_down_p = 1;
+       }
+    }
 
+  if (scroll_down_p)
+    {
+      /* Point is in or below the bottom scroll margin, so move the
+        window start down.  If scrolling conservatively, move it just
+        enough down to make point visible.  If scroll_step is set,
+        move it down by scroll_step.  */
       if (scroll_conservatively)
-       /* Set AMOUNT_TO_SCROLL to at least one line,
-          and at most scroll_conservatively lines.  */
        amount_to_scroll
          = min (max (dy, FRAME_LINE_HEIGHT (f)),
                 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
@@ -12557,19 +12729,20 @@ try_scrolling (window, just_this_one_p, scroll_conservatively,
       if (amount_to_scroll <= 0)
        return SCROLLING_FAILED;
 
-      /* If moving by amount_to_scroll leaves STARTP unchanged,
-        move it down one screen line.  */
-
+      start_display (&it, w, startp);
       move_it_vertically (&it, amount_to_scroll);
+
+      /* If STARTP is unchanged, move it down another screen line.  */
       if (CHARPOS (it.current.pos) == CHARPOS (startp))
        move_it_by_lines (&it, 1, 1);
       startp = it.current.pos;
     }
   else
     {
+      struct text_pos scroll_margin_pos = startp;
+
       /* See if point is inside the scroll margin at the top of the
          window.  */
-      scroll_margin_pos = startp;
       if (this_scroll_margin)
        {
          start_display (&it, w, startp);
@@ -12818,9 +12991,13 @@ try_cursor_movement (window, startp, scroll_step)
 
       /* Scroll if point within this distance from the top or bottom
         of the window.  This is a pixel value.  */
-      this_scroll_margin = max (0, scroll_margin);
-      this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
-      this_scroll_margin *= FRAME_LINE_HEIGHT (f);
+      if (scroll_margin > 0)
+       {
+         this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
+         this_scroll_margin *= FRAME_LINE_HEIGHT (f);
+       }
+      else
+       this_scroll_margin = 0;
 
       top_scroll_margin = this_scroll_margin;
       if (WINDOW_WANTS_HEADER_LINE_P (w))
@@ -13264,7 +13441,6 @@ redisplay_window (window, just_this_one_p)
     {
       /* We set this later on if we have to adjust point.  */
       int new_vpos = -1;
-      int val;
 
       w->force_start = Qnil;
       w->vscroll = 0;
@@ -13298,16 +13474,15 @@ redisplay_window (window, just_this_one_p)
 
       /* Redisplay, then check if cursor has been set during the
         redisplay.  Give up if new fonts were loaded.  */
-      val = try_window (window, startp, 1);
-      if (!val)
+      /* We used to issue a CHECK_MARGINS argument to try_window here,
+        but this causes scrolling to fail when point begins inside
+        the scroll margin (bug#148) -- cyd  */
+      if (!try_window (window, startp, 0))
        {
          w->force_start = Qt;
          clear_glyph_matrix (w->desired_matrix);
          goto need_larger_matrices;
        }
-      /* Point was outside the scroll margins.  */
-      if (val < 0)
-       new_vpos = window_box_height (w) / 2;
 
       if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
        {
@@ -13438,11 +13613,16 @@ redisplay_window (window, just_this_one_p)
          && NILP (do_mouse_tracking)
          && CHARPOS (startp) > BEGV
          && CHARPOS (startp) > BEG + beg_unchanged
-         && CHARPOS (startp) <= Z - end_unchanged)
+         && CHARPOS (startp) <= Z - end_unchanged
+         /* Even if w->start_at_line_beg is nil, a new window may
+            start at a line_beg, since that's how set_buffer_window
+            sets it.  So, we need to check the return value of
+            compute_window_start_on_continuation_line.  (See also
+            bug#197).  */
+         && XMARKER (w->start)->buffer == current_buffer
+         && compute_window_start_on_continuation_line (w))
        {
          w->force_start = Qt;
-         if (XMARKER (w->start)->buffer == current_buffer)
-           compute_window_start_on_continuation_line (w);
          SET_TEXT_POS_FROM_MARKER (startp, w->start);
          goto force_start;
        }
@@ -13569,11 +13749,6 @@ redisplay_window (window, just_this_one_p)
     {
       init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
       move_it_vertically_backward (&it, 0);
-#if 0
-      /* I think this assert is bogus if buffer contains
-        invisible text or images.  KFS.  */
-      xassert (IT_CHARPOS (it) <= PT);
-#endif
       it.current_y = 0;
     }
 
@@ -13734,8 +13909,8 @@ redisplay_window (window, just_this_one_p)
 
       if (FRAME_WINDOW_P (f))
        {
-#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
-    || defined (USE_GTK)
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
+    || defined (HAVE_NS) || defined (USE_GTK)
          redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
 #else
          redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
@@ -13750,7 +13925,7 @@ redisplay_window (window, just_this_one_p)
 #ifdef HAVE_WINDOW_SYSTEM
       if (FRAME_WINDOW_P (f))
         {
-#if defined (USE_GTK) || USE_MAC_TOOLBAR
+#if defined (USE_GTK) || defined (HAVE_NS) || USE_MAC_TOOLBAR
           redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
 #else
           redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
@@ -13857,9 +14032,13 @@ try_window (window, pos, check_margins)
     {
       int this_scroll_margin;
 
-      this_scroll_margin = max (0, scroll_margin);
-      this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
-      this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
+      if (scroll_margin > 0)
+       {
+         this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
+         this_scroll_margin *= FRAME_LINE_HEIGHT (f);
+       }
+      else
+       this_scroll_margin = 0;
 
       if ((w->cursor.y >= 0    /* not vscrolled */
           && w->cursor.y < this_scroll_margin
@@ -13869,7 +14048,7 @@ try_window (window, pos, check_margins)
             seems to give wrong results.  We don't want to recenter
             when the last line is partly visible, we want to allow
             that case to be handled in the usual way.  */
-         || (w->cursor.y + 1) > it.last_visible_y)
+         || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
        {
          w->cursor.vpos = -1;
          clear_glyph_matrix (w->desired_matrix);
@@ -14215,13 +14394,6 @@ try_window_reusing_current_matrix (w)
        if (display_line (&it))
          last_text_row = it.glyph_row - 1;
 
-      /* Give up If point isn't in a row displayed or reused.  */
-      if (w->cursor.vpos < 0)
-       {
-         clear_glyph_matrix (w->desired_matrix);
-         return 0;
-       }
-
       /* If point is in a reused row, adjust y and vpos of the cursor
         position.  */
       if (pt_row)
@@ -14230,6 +14402,16 @@ try_window_reusing_current_matrix (w)
          w->cursor.y -= first_reusable_row->y - start_row->y;
        }
 
+      /* Give up if point isn't in a row displayed or reused.  (This
+        also handles the case where w->cursor.vpos < nrows_scrolled
+        after the calls to display_line, which can happen with scroll
+        margins.  See bug#1295.)  */
+      if (w->cursor.vpos < 0)
+       {
+         clear_glyph_matrix (w->desired_matrix);
+         return 0;
+       }
+
       /* Scroll the display.  */
       run.current_y = first_reusable_row->y;
       run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
@@ -14390,9 +14572,10 @@ find_last_unchanged_at_beg_row (w)
   int yb = window_text_bottom_y (w);
 
   /* Find the last row displaying unchanged text.  */
-  row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
-  while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
-        && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
+  for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
+       MATRIX_ROW_DISPLAYS_TEXT_P (row)
+        && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
+       ++row)
     {
       if (/* If row ends before first_changed_pos, it is unchanged,
             except in some case.  */
@@ -14409,10 +14592,8 @@ find_last_unchanged_at_beg_row (w)
        row_found = row;
 
       /* Stop if last visible row.  */
-     if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
+      if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
        break;
-
-      ++row;
     }
 
   return row_found;
@@ -14728,6 +14909,12 @@ try_window_id (w)
   if (overlay_arrows_changed_p ())
     GIVE_UP (12);
 
+  /* When word-wrap is on, adding a space to the first word of a
+     wrapped line can change the wrap position, altering the line
+     above it.  It might be worthwhile to handle this more
+     intelligently, but for now just redisplay from scratch.  */
+  if (!NILP (XBUFFER (w->buffer)->word_wrap))
+    GIVE_UP (21);
 
   /* Make sure beg_unchanged and end_unchanged are up to date.  Do it
      only if buffer has really changed.  The reason is that the gap is
@@ -15453,7 +15640,7 @@ dump_glyph (row, glyph, area)
   else if (glyph->type == COMPOSITE_GLYPH)
     {
       fprintf (stderr,
-              "  %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
+              "  %5d %4c %6d %c %3d 0x%05x",
               glyph - row->glyphs[TEXT_AREA],
               '+',
               glyph->charpos,
@@ -15463,8 +15650,12 @@ dump_glyph (row, glyph, area)
                   ? 'S'
                   : '-')),
               glyph->pixel_width,
-              glyph->u.cmp_id,
-              '.',
+              glyph->u.cmp.id);
+      if (glyph->u.cmp.automatic)
+       fprintf (stderr,
+                "[%d-%d]",
+                glyph->u.cmp.from, glyph->u.cmp.to);
+      fprintf (stderr, " . %4d %1.1d%1.1d\n"
               glyph->face_id,
               glyph->left_box_line_p,
               glyph->right_box_line_p);
@@ -16182,17 +16373,108 @@ cursor_row_p (w, row)
             We want that position to be displayed after the ellipsis.  */
            cursor_row_p = 0;
        }
-      /* If the row ends at ZV, display the cursor at the end of that
-        row instead of at the start of the row below.  */
-      else if (row->ends_at_zv_p)
-       cursor_row_p = 1;
-      else
-       cursor_row_p = 0;
+      /* If the row ends at ZV, display the cursor at the end of that
+        row instead of at the start of the row below.  */
+      else if (row->ends_at_zv_p)
+       cursor_row_p = 1;
+      else
+       cursor_row_p = 0;
+    }
+
+  return cursor_row_p;
+}
+
+\f
+
+/* Push the display property PROP so that it will be rendered at the
+   current position in IT.  */
+
+static void
+push_display_prop (struct it *it, Lisp_Object prop)
+{
+  push_it (it);
+
+  /* Never display a cursor on the prefix.  */
+  it->avoid_cursor_p = 1;
+
+  if (STRINGP (prop))
+    {
+      if (SCHARS (prop) == 0)
+       {
+         pop_it (it);
+         return;
+       }
+
+      it->string = prop;
+      it->multibyte_p = STRING_MULTIBYTE (it->string);
+      it->current.overlay_string_index = -1;
+      IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
+      it->end_charpos = it->string_nchars = SCHARS (it->string);
+      it->method = GET_FROM_STRING;
+      it->stop_charpos = 0;
+    }
+  else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
+    {
+      it->method = GET_FROM_STRETCH;
+      it->object = prop;
+    }
+#ifdef HAVE_WINDOW_SYSTEM
+  else if (IMAGEP (prop))
+    {
+      it->what = IT_IMAGE;
+      it->image_id = lookup_image (it->f, prop);
+      it->method = GET_FROM_IMAGE;
+    }
+#endif /* HAVE_WINDOW_SYSTEM */
+  else
+    {
+      pop_it (it);             /* bogus display property, give up */
+      return;
     }
+}
 
-  return cursor_row_p;
+/* Return the character-property PROP at the current position in IT.  */
+
+static Lisp_Object
+get_it_property (it, prop)
+     struct it *it;
+     Lisp_Object prop;
+{
+  Lisp_Object position;
+
+  if (STRINGP (it->object))
+    position = make_number (IT_STRING_CHARPOS (*it));
+  else if (BUFFERP (it->object))
+    position = make_number (IT_CHARPOS (*it));
+  else
+    return Qnil;
+
+  return Fget_char_property (position, prop, it->object);
+}
+
+/* See if there's a line- or wrap-prefix, and if so, push it on IT.  */
+
+static void
+handle_line_prefix (struct it *it)
+{
+  Lisp_Object prefix;
+  if (it->continuation_lines_width > 0)
+    {
+      prefix = get_it_property (it, Qwrap_prefix);
+      if (NILP (prefix))
+       prefix = Vwrap_prefix;
+    }
+  else
+    {
+      prefix = get_it_property (it, Qline_prefix);
+      if (NILP (prefix))
+       prefix = Vline_prefix;
+    }
+  if (! NILP (prefix))
+    push_display_prop (it, prefix);
 }
 
+\f
 
 /* Construct the glyph row IT->glyph_row in the desired matrix of
    IT->w from text at the current position of IT.  See dispextern.h
@@ -16206,6 +16488,11 @@ display_line (it)
 {
   struct glyph_row *row = it->glyph_row;
   Lisp_Object overlay_arrow_string;
+  struct it wrap_it;
+  int may_wrap = 0, wrap_x;
+  int wrap_row_used = -1, wrap_row_ascent, wrap_row_height;
+  int wrap_row_phys_ascent, wrap_row_phys_height;
+  int wrap_row_extra_line_spacing;
 
   /* We always start displaying at hpos zero even if hscrolled.  */
   xassert (it->hpos == 0 && it->current_x == 0);
@@ -16246,6 +16533,13 @@ display_line (it)
       move_it_in_display_line_to (it, ZV, it->first_visible_x,
                                  MOVE_TO_POS | MOVE_TO_X);
     }
+  else
+    {
+      /* We only do this when not calling `move_it_in_display_line_to'
+        above, because move_it_in_display_line_to calls
+        handle_line_prefix itself.  */
+      handle_line_prefix (it);
+    }
 
   /* Get the initial row height.  This is either the height of the
      text hscrolled, if there is any, or zero.  */
@@ -16300,12 +16594,30 @@ display_line (it)
 
       /* Remember the line height so far in case the next element doesn't
         fit on the line.  */
-      if (!it->truncate_lines_p)
+      if (it->line_wrap != TRUNCATE)
        {
          ascent = it->max_ascent;
          descent = it->max_descent;
          phys_ascent = it->max_phys_ascent;
          phys_descent = it->max_phys_descent;
+
+         if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
+           {
+             if (IT_DISPLAYING_WHITESPACE (it))
+               may_wrap = 1;
+             else if (may_wrap)
+               {
+                 wrap_it = *it;
+                 wrap_x = x;
+                 wrap_row_used = row->used[TEXT_AREA];
+                 wrap_row_ascent = row->ascent;
+                 wrap_row_height = row->height;
+                 wrap_row_phys_ascent = row->phys_ascent;
+                 wrap_row_phys_height = row->phys_height;
+                 wrap_row_extra_line_spacing = row->extra_line_spacing;
+                 may_wrap = 0;
+               }
+           }
        }
 
       PRODUCE_GLYPHS (it);
@@ -16365,7 +16677,7 @@ display_line (it)
              new_x = x + glyph->pixel_width;
 
              if (/* Lines are continued.  */
-                 !it->truncate_lines_p
+                 it->line_wrap != TRUNCATE
                  && (/* Glyph doesn't fit on the line.  */
                      new_x > it->last_visible_x
                      /* Or it fits exactly on a window system frame.  */
@@ -16388,6 +16700,18 @@ display_line (it)
                      ++it->hpos;
                      if (i == nglyphs - 1)
                        {
+                         /* If line-wrap is on, check if a previous
+                            wrap point was found.  */
+                         if (wrap_row_used > 0
+                             /* Even if there is a previous wrap
+                                point, continue the line here as
+                                usual, if (i) the previous character
+                                was a space or tab AND (ii) the
+                                current character is not.  */
+                             && (!may_wrap
+                                 || IT_DISPLAYING_WHITESPACE (it)))
+                           goto back_to_wrap;
+
                          set_iterator_to_next (it, 1);
 #ifdef HAVE_WINDOW_SYSTEM
                          if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
@@ -16433,6 +16757,26 @@ display_line (it)
                      it->max_phys_ascent = phys_ascent;
                      it->max_phys_descent = phys_descent;
                    }
+                 else if (wrap_row_used > 0)
+                   {
+                   back_to_wrap:
+                     *it = wrap_it;
+                     it->continuation_lines_width += wrap_x;
+                     row->used[TEXT_AREA] = wrap_row_used;
+                     row->ascent = wrap_row_ascent;
+                     row->height = wrap_row_height;
+                     row->phys_ascent = wrap_row_phys_ascent;
+                     row->phys_height = wrap_row_phys_height;
+                     row->extra_line_spacing = wrap_row_extra_line_spacing;
+                     row->continued_p = 1;
+                     row->ends_at_zv_p = 0;
+                     row->exact_window_width_line_p = 0;
+                     it->continuation_lines_width += x;
+
+                     /* Make sure that a non-default face is extended
+                        up to the right margin of the window.  */
+                     extend_face_to_end_of_line (it);
+                   }
                  else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
                    {
                      /* A TAB that extends past the right edge of the
@@ -16548,7 +16892,7 @@ display_line (it)
 
       /* If we truncate lines, we are done when the last displayed
         glyphs reach past the right margin of the window.  */
-      if (it->truncate_lines_p
+      if (it->line_wrap == TRUNCATE
          && (FRAME_WINDOW_P (it->f)
              ? (it->current_x >= it->last_visible_x)
              : (it->current_x > it->last_visible_x)))
@@ -16731,10 +17075,11 @@ display_menu_bar (w)
   if (FRAME_X_P (f))
     return;
 #endif
-#ifdef MAC_OS
-  if (FRAME_MAC_P (f))
+
+#ifdef HAVE_NS
+  if (FRAME_NS_P (f))
     return;
-#endif
+#endif /* HAVE_NS */
 
 #ifdef USE_X_TOOLKIT
   xassert (!FRAME_WINDOW_P (f));
@@ -17604,7 +17949,7 @@ If FACE is an integer, the value string has no text properties.
 Optional third and fourth args WINDOW and BUFFER specify the window
 and buffer to use as the context for the formatting (defaults
 are the selected window and the window's buffer).  */)
-  (format, face, window, buffer)
+     (format, face, window, buffer)
      Lisp_Object format, face, window, buffer;
 {
   struct it it;
@@ -18573,7 +18918,7 @@ display_string (string, lisp_string, face_string, face_string_pos,
        {
          struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
 
-         if (!it->truncate_lines_p
+         if (it->line_wrap != TRUNCATE
              && x + glyph->pixel_width > max_x)
            {
              /* End of continued line or max_x reached.  */
@@ -18629,7 +18974,7 @@ display_string (string, lisp_string, face_string, face_string_pos,
       set_iterator_to_next (it, 1);
 
       /* Stop if truncating at the right edge.  */
-      if (it->truncate_lines_p
+      if (it->line_wrap == TRUNCATE
          && it->current_x >= it->last_visible_x)
        {
          /* Add truncation mark, but don't do it if the line is
@@ -19207,7 +19552,7 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
       if (code != FONT_INVALID_CODE)
        STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
       else
-       STORE_XCHAR2B (char2b, 0, code);
+       STORE_XCHAR2B (char2b, 0, 0);
     }
 
   /* Make sure X resources of the face are allocated.  */
@@ -19220,7 +19565,7 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
 /* Fill glyph string S with composition components specified by S->cmp.
 
    BASE_FACE is the base face of the composition.
-   S->gidx is the index of the first component for S.
+   S->cmp_from is the index of the first component for S.
 
    OVERLAPS non-zero means S should draw the foreground only, and use
    its physical height for clipping.  See also draw_glyphs.
@@ -19234,70 +19579,45 @@ fill_composite_glyph_string (s, base_face, overlaps)
      int overlaps;
 {
   int i;
+  /* For all glyphs of this composition, starting at the offset
+     S->cmp_from, until we reach the end of the definition or encounter a
+     glyph that requires the different face, add it to S.  */
+  struct face *face;
 
   xassert (s);
 
   s->for_overlaps = overlaps;
-
-  if (s->cmp->method == COMPOSITION_WITH_GLYPH_STRING)
-    {
-      Lisp_Object gstring
-       = AREF (XHASH_TABLE (composition_hash_table)->key_and_value,
-               s->cmp->hash_index * 2);
-
-      s->face = base_face;
-      s->font = base_face->font;
-      for (i = 0, s->nchars = 0; i < s->cmp->glyph_len; i++, s->nchars++)
-       {
-         Lisp_Object g = LGSTRING_GLYPH (gstring, i);
-         unsigned code;
-          XChar2b * store_pos;
-         if (NILP (g))
-           break;
-         code = LGLYPH_CODE (g);
-          store_pos = s->char2b + i;
-         STORE_XCHAR2B (store_pos, code >> 8, code & 0xFF);
-       }
-      s->width = s->cmp->pixel_width;
-    }
-  else
+  s->face = NULL;
+  s->font = NULL;
+  for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
     {
-      /* For all glyphs of this composition, starting at the offset
-        S->gidx, until we reach the end of the definition or encounter a
-        glyph that requires the different face, add it to S.  */
-      struct face *face;
+      int c = COMPOSITION_GLYPH (s->cmp, i);
 
-      s->face = NULL;
-      s->font = NULL;
-      for (i = s->gidx; i < s->cmp->glyph_len; i++)
+      if (c != '\t')
        {
-         int c = COMPOSITION_GLYPH (s->cmp, i);
+         int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
+                                      -1, Qnil);
 
-         if (c != '\t')
+         face = get_char_face_and_encoding (s->f, c, face_id,
+                                            s->char2b + i, 1, 1);
+         if (face)
            {
-             int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
-                                          -1, Qnil);
-
-             face = get_char_face_and_encoding (s->f, c, face_id,
-                                                s->char2b + i, 1, 1);
-             if (face)
+             if (! s->face)
                {
-                 if (! s->face)
-                   {
-                     s->face = face;
-                     s->font = s->face->font;
-                   }
-                 else if (s->face != face)
-                   break;
+                 s->face = face;
+                 s->font = s->face->font;
                }
+             else if (s->face != face)
+               break;
            }
-         ++s->nchars;
        }
-
-      /* All glyph strings for the same composition has the same width,
-        i.e. the width set for the first component of the composition.  */
-      s->width = s->first_glyph->pixel_width;
+      ++s->nchars;
     }
+  s->cmp_to = i;
+
+  /* All glyph strings for the same composition has the same width,
+     i.e. the width set for the first component of the composition.  */
+  s->width = s->first_glyph->pixel_width;
 
   /* If the specified font could not be loaded, use the frame's
      default font, but record the fact that we couldn't load it in
@@ -19315,7 +19635,43 @@ fill_composite_glyph_string (s, base_face, overlaps)
   /* This glyph string must always be drawn with 16-bit functions.  */
   s->two_byte_p = 1;
 
-  return s->gidx + s->nchars;
+  return s->cmp_to;
+}
+
+static int
+fill_gstring_glyph_string (s, face_id, start, end, overlaps)
+     struct glyph_string *s;
+     int face_id;
+     int start, end, overlaps;
+{
+  struct glyph *glyph, *last;
+  Lisp_Object lgstring;
+  int i;
+
+  s->for_overlaps = overlaps;
+  glyph = s->row->glyphs[s->area] + start;
+  last = s->row->glyphs[s->area] + end;
+  s->cmp_id = glyph->u.cmp.id;
+  s->cmp_from = glyph->u.cmp.from;
+  s->cmp_to = glyph->u.cmp.to;
+  s->face = FACE_FROM_ID (s->f, face_id);
+  lgstring = composition_gstring_from_id (s->cmp_id);
+  s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
+  glyph++;
+  while (glyph < last
+        && glyph->u.cmp.automatic
+        && glyph->u.cmp.id == s->cmp_id)
+    s->cmp_to = (glyph++)->u.cmp.to;
+
+  for (i = s->cmp_from; i < s->cmp_to; i++)
+    {
+      Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
+      unsigned code = LGLYPH_CODE (lglyph);
+
+      STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
+    }
+  s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
+  return glyph - s->row->glyphs[s->area];
 }
 
 
@@ -19342,7 +19698,7 @@ fill_glyph_string (s, face_id, start, end, overlaps)
   xassert (s->nchars == 0);
   xassert (start >= 0 && end > start);
 
-  s->for_overlaps = overlaps,
+  s->for_overlaps = overlaps;
   glyph = s->row->glyphs[s->area] + start;
   last = s->row->glyphs[s->area] + end;
   voffset = glyph->voffset;
@@ -19462,7 +19818,6 @@ get_per_char_metric (f, font, char2b)
 {
   static struct font_metrics metrics;
   unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
-  struct font *fontp;
 
   if (! font || code == FONT_INVALID_CODE)
     return NULL;
@@ -19500,10 +19855,27 @@ x_get_glyph_overhangs (glyph, f, left, right)
     }
   else if (glyph->type == COMPOSITE_GLYPH)
     {
-      struct composition *cmp = composition_table[glyph->u.cmp_id];
+      if (! glyph->u.cmp.automatic)
+       {
+         struct composition *cmp = composition_table[glyph->u.cmp.id];
+
+         if (cmp->rbearing - cmp->pixel_width)
+           *right = cmp->rbearing - cmp->pixel_width;
+         if (cmp->lbearing < 0);
+         *left = - cmp->lbearing;
+       }
+      else
+       {
+         Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
+         struct font_metrics metrics;
 
-      *right = cmp->rbearing - cmp->pixel_width;
-      *left = - cmp->lbearing;
+         composition_gstring_width (gstring, glyph->u.cmp.from,
+                                    glyph->u.cmp.to, &metrics);
+         if (metrics.rbearing > metrics.width)
+           *right = metrics.rbearing;
+         if (metrics.lbearing < 0)
+           *left = - metrics.lbearing;
+       }
     }
 }
 
@@ -19564,7 +19936,7 @@ left_overwriting (s)
 
 
 /* Return the index of the last glyph following glyph string S that is
-   not overwritten by S because of S's right overhang.  Value is -1 if
+   overwritten by S because of S's right overhang.  Value is -1 if
    no such glyph is found.  */
 
 static int
@@ -19767,7 +20139,7 @@ compute_overhangs_and_x (s, x, backward_p)
         INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL);           \
         append_glyph_string (&HEAD, &TAIL, s);                            \
         s->x = (X);                                                       \
-        START = fill_glyph_string (s, face_id, START, END, overlaps);   \
+        START = fill_glyph_string (s, face_id, START, END, overlaps);     \
        }                                                                  \
      while (0)
 
@@ -19785,7 +20157,7 @@ compute_overhangs_and_x (s, x, backward_p)
   do {                                                                     \
     int face_id = (row)->glyphs[area][START].face_id;                      \
     struct face *base_face = FACE_FROM_ID (f, face_id);                            \
-    int cmp_id = (row)->glyphs[area][START].u.cmp_id;                      \
+    int cmp_id = (row)->glyphs[area][START].u.cmp.id;                      \
     struct composition *cmp = composition_table[cmp_id];                   \
     XChar2b *char2b;                                                       \
     struct glyph_string *first_s;                                          \
@@ -19801,7 +20173,7 @@ compute_overhangs_and_x (s, x, backward_p)
        INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL);             \
        append_glyph_string (&(HEAD), &(TAIL), s);                          \
        s->cmp = cmp;                                                       \
-       s->gidx = n;                                                        \
+       s->cmp_from = n;                                                    \
        s->x = (X);                                                         \
        if (n == 0)                                                         \
          first_s = s;                                                      \
@@ -19813,6 +20185,28 @@ compute_overhangs_and_x (s, x, backward_p)
   } while (0)
 
 
+/* Add a glyph string for a glyph-string sequence to the list of strings
+   between HEAD and TAIL.  */
+
+#define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
+  do {                                                                   \
+    int face_id;                                                         \
+    XChar2b *char2b;                                                     \
+    Lisp_Object gstring;                                                 \
+                                                                         \
+    face_id = (row)->glyphs[area][START].face_id;                        \
+    gstring = (composition_gstring_from_id                               \
+              ((row)->glyphs[area][START].u.cmp.id));                    \
+    s = (struct glyph_string *) alloca (sizeof *s);                      \
+    char2b = (XChar2b *) alloca ((sizeof *char2b)                        \
+                                * LGSTRING_GLYPH_LEN (gstring));         \
+    INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL);              \
+    append_glyph_string (&(HEAD), &(TAIL), s);                           \
+    s->x = (X);                                                                  \
+    START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
+  } while (0)
+
+
 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
    of AREA of glyph row ROW on window W between indices START and END.
    HL overrides the face for drawing glyph strings, e.g. it is
@@ -19823,47 +20217,50 @@ compute_overhangs_and_x (s, x, backward_p)
    to allocate glyph strings (because draw_glyphs can be called
    asynchronously).  */
 
-#define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X)        \
-     do                                                                           \
-       {                                                                  \
-        HEAD = TAIL = NULL;                                               \
-        while (START < END)                                               \
-          {                                                               \
-             struct glyph *first_glyph = (row)->glyphs[area] + START;     \
-             switch (first_glyph->type)                                           \
-              {                                                           \
-              case CHAR_GLYPH:                                            \
-                 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL,        \
-                                          HL, X, LAST_X);                 \
-                break;                                                    \
-                                                                          \
-              case COMPOSITE_GLYPH:                                       \
-                 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL,    \
-                                              HL, X, LAST_X);             \
-                break;                                                    \
-                                                                          \
-              case STRETCH_GLYPH:                                         \
-                BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL,       \
-                                            HL, X, LAST_X);               \
-                break;                                                    \
-                                                                          \
-              case IMAGE_GLYPH:                                           \
-                BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL,         \
-                                          HL, X, LAST_X);                 \
-                break;                                                    \
-                                                                          \
-              default:                                                    \
-                abort ();                                                 \
-              }                                                           \
-                                                                          \
-            if (s)                                                        \
-              {                                                           \
-                set_glyph_string_background_width (s, START, LAST_X);     \
-                (X) += s->width;                                          \
-              }                                                           \
-            }                                                             \
-       }                                                                  \
-     while (0)
+#define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X)     \
+  do                                                                   \
+    {                                                                  \
+      HEAD = TAIL = NULL;                                              \
+      while (START < END)                                              \
+       {                                                               \
+         struct glyph *first_glyph = (row)->glyphs[area] + START;      \
+         switch (first_glyph->type)                                    \
+           {                                                           \
+           case CHAR_GLYPH:                                            \
+             BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL,         \
+                                       HL, X, LAST_X);                 \
+             break;                                                    \
+                                                                       \
+           case COMPOSITE_GLYPH:                                       \
+             if (first_glyph->u.cmp.automatic)                         \
+               BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL,     \
+                                           HL, X, LAST_X);             \
+             else                                                      \
+               BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL,   \
+                                             HL, X, LAST_X);           \
+             break;                                                    \
+                                                                       \
+           case STRETCH_GLYPH:                                         \
+             BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL,       \
+                                         HL, X, LAST_X);               \
+             break;                                                    \
+                                                                       \
+           case IMAGE_GLYPH:                                           \
+             BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL,         \
+                                       HL, X, LAST_X);                 \
+             break;                                                    \
+                                                                       \
+           default:                                                    \
+             abort ();                                                 \
+           }                                                           \
+                                                                       \
+         if (s)                                                        \
+           {                                                           \
+             set_glyph_string_background_width (s, START, LAST_X);     \
+             (X) += s->width;                                          \
+           }                                                           \
+       }                                                               \
+    } while (0)
 
 
 /* Draw glyphs between START and END in AREA of ROW on window W,
@@ -20090,6 +20487,9 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps)
   for (s = head; s; s = s->next)
     FRAME_RIF (f)->draw_glyph_string (s);
 
+#ifndef HAVE_NS
+  /* When focus a sole frame and move horizontally, this sets on_p to 0
+     causing a failure to erase prev cursor position. */
   if (area == TEXT_AREA
       && !row->full_width_p
       /* When drawing overlapping rows, only the glyph strings'
@@ -20106,6 +20506,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps)
       notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
                                 row->y, MATRIX_ROW_BOTTOM_Y (row));
     }
+#endif
 
   /* Value is the x-position up to which drawn, relative to AREA of W.
      This doesn't include parts drawn because of overhangs.  */
@@ -20167,6 +20568,7 @@ append_glyph (it)
       glyph->descent = it->descent;
       glyph->voffset = it->voffset;
       glyph->type = CHAR_GLYPH;
+      glyph->avoid_cursor_p = it->avoid_cursor_p;
       glyph->multibyte_p = it->multibyte_p;
       glyph->left_box_line_p = it->start_of_box_run_p;
       glyph->right_box_line_p = it->end_of_box_run_p;
@@ -20183,8 +20585,9 @@ append_glyph (it)
     IT_EXPAND_MATRIX_WIDTH (it, area);
 }
 
-/* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
-   Called from x_produce_glyphs when IT->glyph_row is non-null.  */
+/* Store one glyph for the composition IT->cmp_it.id in
+   IT->glyph_row.  Called from x_produce_glyphs when IT->glyph_row is
+   non-null.  */
 
 static INLINE void
 append_composite_glyph (it)
@@ -20205,6 +20608,19 @@ append_composite_glyph (it)
       glyph->descent = it->descent;
       glyph->voffset = it->voffset;
       glyph->type = COMPOSITE_GLYPH;
+      if (it->cmp_it.ch < 0)
+       {
+         glyph->u.cmp.automatic = 0;
+         glyph->u.cmp.id = it->cmp_it.id;
+       }
+      else
+       {
+         glyph->u.cmp.automatic = 1;
+         glyph->u.cmp.id = it->cmp_it.id;
+         glyph->u.cmp.from = it->cmp_it.from;
+         glyph->u.cmp.to = it->cmp_it.to;
+       }
+      glyph->avoid_cursor_p = it->avoid_cursor_p;
       glyph->multibyte_p = it->multibyte_p;
       glyph->left_box_line_p = it->start_of_box_run_p;
       glyph->right_box_line_p = it->end_of_box_run_p;
@@ -20213,7 +20629,6 @@ append_composite_glyph (it)
       glyph->padding_p = 0;
       glyph->glyph_not_available_p = 0;
       glyph->face_id = it->face_id;
-      glyph->u.cmp_id = it->cmp_id;
       glyph->slice = null_glyph_slice;
       glyph->font_type = FONT_TYPE_UNKNOWN;
       ++it->glyph_row->used[area];
@@ -20386,6 +20801,7 @@ produce_image_glyph (it)
          glyph->descent = it->descent;
          glyph->voffset = it->voffset;
          glyph->type = IMAGE_GLYPH;
+         glyph->avoid_cursor_p = it->avoid_cursor_p;
          glyph->multibyte_p = it->multibyte_p;
          glyph->left_box_line_p = it->start_of_box_run_p;
          glyph->right_box_line_p = it->end_of_box_run_p;
@@ -20430,6 +20846,7 @@ append_stretch_glyph (it, object, width, height, ascent)
       glyph->descent = height - ascent;
       glyph->voffset = it->voffset;
       glyph->type = STRETCH_GLYPH;
+      glyph->avoid_cursor_p = it->avoid_cursor_p;
       glyph->multibyte_p = it->multibyte_p;
       glyph->left_box_line_p = it->start_of_box_run_p;
       glyph->right_box_line_p = it->end_of_box_run_p;
@@ -20577,7 +20994,7 @@ produce_stretch_glyph (it)
   else
     ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
 
-  if (width > 0 && !it->truncate_lines_p
+  if (width > 0 && it->line_wrap != TRUNCATE
       && it->current_x + width > it->last_visible_x)
     width = it->last_visible_x - it->current_x - 1;
 
@@ -20597,27 +21014,6 @@ produce_stretch_glyph (it)
   take_vertical_position_into_account (it);
 }
 
-/* Get line-height and line-spacing property at point.
-   If line-height has format (HEIGHT TOTAL), return TOTAL
-   in TOTAL_HEIGHT.  */
-
-static Lisp_Object
-get_line_height_property (it, prop)
-     struct it *it;
-     Lisp_Object prop;
-{
-  Lisp_Object position;
-
-  if (STRINGP (it->object))
-    position = make_number (IT_STRING_CHARPOS (*it));
-  else if (BUFFERP (it->object))
-    position = make_number (IT_CHARPOS (*it));
-  else
-    return Qnil;
-
-  return Fget_char_property (position, prop, it->object);
-}
-
 /* Calculate line-height and line-spacing properties.
    An integer value specifies explicit pixel value.
    A float value specifies relative value to current face height.
@@ -20905,7 +21301,7 @@ x_produce_glyphs (it)
          it->pixel_width = 0;
          it->nglyphs = 0;
 
-         height = get_line_height_property(it, Qline_height);
+         height = get_it_property(it, Qline_height);
          /* Split (line-height total-height) list */
          if (CONSP (height)
              && CONSP (XCDR (height))
@@ -20967,7 +21363,7 @@ x_produce_glyphs (it)
                spacing = calc_line_height_property(it, total_height, font, boff, 0);
              else
                {
-                 spacing = get_line_height_property(it, Qline_spacing);
+                 spacing = get_it_property(it, Qline_spacing);
                  spacing = calc_line_height_property(it, spacing, font, boff, 0);
                }
              if (INTEGERP (spacing))
@@ -20980,25 +21376,33 @@ x_produce_glyphs (it)
        }
       else if (it->char_to_display == '\t')
        {
-         int tab_width = it->tab_width * FRAME_SPACE_WIDTH (it->f);
-         int x = it->current_x + it->continuation_lines_width;
-         int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
-
-         /* If the distance from the current position to the next tab
-            stop is less than a space character width, use the
-            tab stop after that.  */
-         if (next_tab_x - x < FRAME_SPACE_WIDTH (it->f))
-           next_tab_x += tab_width;
-
-         it->pixel_width = next_tab_x - x;
-         it->nglyphs = 1;
-         it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
-         it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
-
-         if (it->glyph_row)
+         if (font->space_width > 0)
+           {
+             int tab_width = it->tab_width * font->space_width;
+             int x = it->current_x + it->continuation_lines_width;
+             int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
+
+             /* If the distance from the current position to the next tab
+                stop is less than a space character width, use the
+                tab stop after that.  */
+             if (next_tab_x - x < font->space_width)
+               next_tab_x += tab_width;
+
+             it->pixel_width = next_tab_x - x;
+             it->nglyphs = 1;
+             it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
+             it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
+
+             if (it->glyph_row)
+               {
+                 append_stretch_glyph (it, it->object, it->pixel_width,
+                                       it->ascent + it->descent, it->ascent);
+               }
+           }
+         else
            {
-             append_stretch_glyph (it, it->object, it->pixel_width,
-                                   it->ascent + it->descent, it->ascent);
+             it->pixel_width = 0;
+             it->nglyphs = 1;
            }
        }
       else
@@ -21081,9 +21485,11 @@ x_produce_glyphs (it)
        }
       it->multibyte_p = saved_multibyte_p;
     }
-  else if (it->what == IT_COMPOSITION)
+  else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
     {
-      /* Note: A composition is represented as one glyph in the
+      /* A static compositoin.
+
+        Note: A composition is represented as one glyph in the
         glyph matrix.  There are no padding glyphs.
 
         Important is that pixel_width, ascent, and descent are the
@@ -21091,18 +21497,12 @@ x_produce_glyphs (it)
         the overall glyphs composed).  */
       struct face *face = FACE_FROM_ID (it->f, it->face_id);
       int boff;                        /* baseline offset */
-      struct composition *cmp = composition_table[it->cmp_id];
+      struct composition *cmp = composition_table[it->cmp_it.id];
       int glyph_len = cmp->glyph_len;
       struct font *font = face->font;
 
       it->nglyphs = 1;
 
-      if (cmp->method == COMPOSITION_WITH_GLYPH_STRING)
-       {
-         PREPARE_FACE_FOR_DISPLAY (it->f, face);
-         font_prepare_composition (cmp, it->f);
-       }
-      else
       /* If we have not yet calculated pixel size data of glyphs of
         the composition for the current face font, calculate them
         now.  Theoretically, we have to check all fonts for the
@@ -21122,7 +21522,6 @@ x_produce_glyphs (it)
          int lbearing, rbearing;
          int i, width, ascent, descent;
          int left_padded = 0, right_padded = 0;
-         int face_id;
          int c;
          XChar2b char2b;
          struct font_metrics *pcm;
@@ -21402,6 +21801,52 @@ x_produce_glyphs (it)
       if (it->descent < 0)
        it->descent = 0;
 
+      if (it->glyph_row)
+       append_composite_glyph (it);
+    }
+  else if (it->what == IT_COMPOSITION)
+    {
+      /* A dynamic (automatic) composition.  */
+      struct face *face = FACE_FROM_ID (it->f, it->face_id);
+      Lisp_Object gstring;
+      struct font_metrics metrics;
+
+      gstring = composition_gstring_from_id (it->cmp_it.id);
+      it->pixel_width
+       = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
+                                    &metrics);
+      if (it->glyph_row
+         && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
+       it->glyph_row->contains_overlapping_glyphs_p = 1;
+      it->ascent = it->phys_ascent = metrics.ascent;
+      it->descent = it->phys_descent = metrics.descent;
+      if (face->box != FACE_NO_BOX)
+       {
+         int thick = face->box_line_width;
+
+         if (thick > 0)
+           {
+             it->ascent += thick;
+             it->descent += thick;
+           }
+         else
+           thick = - thick;
+
+         if (it->start_of_box_run_p)
+           it->pixel_width += thick;
+         if (it->end_of_box_run_p)
+           it->pixel_width += thick;
+       }
+      /* If face has an overline, add the height of the overline
+        (1 pixel) and a 1 pixel margin to the character height.  */
+      if (face->overline_p)
+       it->ascent += overline_margin;
+      take_vertical_position_into_account (it);
+      if (it->ascent < 0)
+       it->ascent = 0;
+      if (it->descent < 0)
+       it->descent = 0;
+
       if (it->glyph_row)
        append_composite_glyph (it);
     }
@@ -21471,7 +21916,7 @@ x_write_glyphs (start, len)
 
 
 /* EXPORT for RIF:
-   Insert LEN glyphs from START at the nominal cursor position.   */
+   Insert LEN glyphs from START at the nominal cursor position.  */
 
 void
 x_insert_glyphs (start, len)
@@ -22220,7 +22665,10 @@ display_and_set_cursor (w, on, hpos, vpos, x, y)
 /* Switch the display of W's cursor on or off, according to the value
    of ON.  */
 
-static void
+#ifndef HAVE_NS
+static
+#endif
+void
 update_window_cursor (w, on)
      struct window *w;
      int on;
@@ -22439,9 +22887,7 @@ cursor_in_mouse_face_p (w)
         in 20.x as well, and I think it's too risky to install
         so near the release of 21.1.  2001-09-25 gerd.  */
 
-#ifndef HAVE_CARBON
 static
-#endif
 int
 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
      struct window *w;
@@ -22839,7 +23285,7 @@ and the radius of the circle; r may be a float or integer.
 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
 vector describes one corner in the polygon.
 Returns the alist element for the first matching AREA in MAP.  */)
-  (map, x, y)
+     (map, x, y)
      Lisp_Object map;
      Lisp_Object x, y;
 {
@@ -23153,7 +23599,7 @@ note_mouse_highlight (f, x, y)
   struct buffer *b;
 
   /* When a menu is active, don't highlight because this looks odd.  */
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS)
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
   if (popup_activated ())
     return;
 #endif
@@ -24511,7 +24957,7 @@ If you want scrolling to always be a line at a time, you should set
     doc: /* *Scroll up to this many lines, to bring point back on screen.
 If point moves off-screen, redisplay will scroll by up to
 `scroll-conservatively' lines in order to bring point just barely
-onto the screen again.   If that cannot be done, then redisplay
+onto the screen again.  If that cannot be done, then redisplay
 recenters point as usual.
 
 A value of zero means always recenter point if it moves off screen.  */);
@@ -24532,11 +24978,20 @@ Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI).  */);
   DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask.  */);
 #endif
 
-  DEFVAR_BOOL ("truncate-partial-width-windows",
-              &truncate_partial_width_windows,
-    doc: /* *Non-nil means truncate lines in all windows less than full frame wide.
-Nil means to respect the value of `truncate-lines'.  */);
-  truncate_partial_width_windows = 1;
+  DEFVAR_LISP ("truncate-partial-width-windows",
+              &Vtruncate_partial_width_windows,
+    doc: /* Non-nil means truncate lines in windows with less than the frame width.
+For an integer value, truncate lines in each window with less than the
+full frame width, provided the window width is less than that integer;
+otherwise, respect the value of `truncate-lines'.
+
+For any other non-nil value, truncate lines in all windows with
+less than the full frame width.
+
+A value of nil means to respect the value of `truncate-lines'.
+
+If `word-wrap' is enabled, you might want to reduce this.  */);
+  Vtruncate_partial_width_windows = make_number (50);
 
   DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
     doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
@@ -24608,9 +25063,10 @@ all the functions in the list are called, with the frame as argument.  */);
 
   DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
     doc: /* List of functions to call before redisplaying a window with scrolling.
-Each function is called with two arguments, the window
-and its new display-start position.  Note that the value of `window-end'
-is not valid when these functions are called.  */);
+Each function is called with two arguments, the window and its new
+display-start position.  Note that these functions are also called by
+`set-window-buffer'.  Also note that the value of `window-end' is not
+valid when these functions are called.  */);
   Vwindow_scroll_functions = Qnil;
 
   DEFVAR_LISP ("window-text-change-functions",
@@ -24774,6 +25230,32 @@ The enable predicate for a menu binding should check this variable.  */);
     doc: /* Non-nil means don't update menu bars.  Internal use only.  */);
   inhibit_menubar_update = 0;
 
+  DEFVAR_LISP ("wrap-prefix", &Vwrap_prefix,
+    doc: /* Prefix added to the beginning of all continuation lines at display-time.
+May be a string, an image, or a stretch-glyph such as used by the
+`display' text-property.
+
+This variable is overridden by any `wrap-prefix' text-property.
+
+To add a prefix to non-continuation lines, use the `line-prefix' variable.  */);
+  Vwrap_prefix = Qnil;
+  staticpro (&Qwrap_prefix);
+  Qwrap_prefix = intern ("wrap-prefix");
+  Fmake_variable_buffer_local (Qwrap_prefix);
+
+  DEFVAR_LISP ("line-prefix", &Vline_prefix,
+    doc: /* Prefix added to the beginning of all non-continuation lines at display-time.
+May be a string, an image, or a stretch-glyph such as used by the
+`display' text-property.
+
+This variable is overridden by any `line-prefix' text-property.
+
+To add a prefix to continuation lines, use the `wrap-prefix' variable.  */);
+  Vline_prefix = Qnil;
+  staticpro (&Qline_prefix);
+  Qline_prefix = intern ("line-prefix");
+  Fmake_variable_buffer_local (Qline_prefix);
+
   DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
     doc: /* Non-nil means don't eval Lisp during redisplay.  */);
   inhibit_eval_during_redisplay = 0;
@@ -24801,6 +25283,27 @@ The enable predicate for a menu binding should check this variable.  */);
 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
 margin to the caracter height.  */);
   overline_margin = 2;
+
+  DEFVAR_INT ("underline-minimum-offset",
+              &underline_minimum_offset,
+     doc: /* Minimum distance between baseline and underline.
+This can improve legibility of underlined text at small font sizes,
+particularly when using variable `x-use-underline-position-properties'
+with fonts that specify an UNDERLINE_POSITION relatively close to the
+baseline.  The default value is 1.  */);
+  underline_minimum_offset = 1;
+
+  DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
+              doc: /* Non-zero means Emacs displays an hourglass pointer on window systems.  */);
+  display_hourglass_p = 1;
+
+  DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
+              doc: /* *Seconds to wait before displaying an hourglass pointer.
+Value must be an integer or float.  */);
+  Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
+
+  hourglass_atimer = NULL;
+  hourglass_shown_p = 0;
 }
 
 
@@ -24856,6 +25359,67 @@ init_xdisp ()
   help_echo_showing_p = 0;
 }
 
+/* Since w32 does not support atimers, it defines its own implementation of
+   the following three functions in w32fns.c.  */
+#ifndef WINDOWSNT
+
+/* Platform-independent portion of hourglass implementation. */
+
+/* Return non-zero if houglass timer has been started or hourglass is shown.  */
+int
+hourglass_started ()
+{
+  return hourglass_shown_p || hourglass_atimer != NULL;
+}
+
+/* Cancel a currently active hourglass timer, and start a new one.  */
+void
+start_hourglass ()
+{
+#if defined (HAVE_WINDOW_SYSTEM)
+  EMACS_TIME delay;
+  int secs, usecs = 0;
+
+  cancel_hourglass ();
+
+  if (INTEGERP (Vhourglass_delay)
+      && XINT (Vhourglass_delay) > 0)
+    secs = XFASTINT (Vhourglass_delay);
+  else if (FLOATP (Vhourglass_delay)
+          && XFLOAT_DATA (Vhourglass_delay) > 0)
+    {
+      Lisp_Object tem;
+      tem = Ftruncate (Vhourglass_delay, Qnil);
+      secs = XFASTINT (tem);
+      usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
+    }
+  else
+    secs = DEFAULT_HOURGLASS_DELAY;
+
+  EMACS_SET_SECS_USECS (delay, secs, usecs);
+  hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
+                                  show_hourglass, NULL);
+#endif
+}
+
+
+/* Cancel the hourglass cursor timer if active, hide a busy cursor if
+   shown.  */
+void
+cancel_hourglass ()
+{
+#if defined (HAVE_WINDOW_SYSTEM)
+  if (hourglass_atimer)
+    {
+      cancel_atimer (hourglass_atimer);
+      hourglass_atimer = NULL;
+    }
+
+  if (hourglass_shown_p)
+    hide_hourglass ();
+#endif
+}
+#endif /* ! WINDOWSNT  */
 
 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
    (do not change this comment) */