Merge from emacs--devo--0
[bpt/emacs.git] / src / xdisp.c
index f53e528..8e24fba 100644 (file)
@@ -7,7 +7,7 @@ This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -177,6 +177,7 @@ Boston, MA 02110-1301, USA.  */
 #include "termchar.h"
 #include "dispextern.h"
 #include "buffer.h"
+#include "character.h"
 #include "charset.h"
 #include "indent.h"
 #include "commands.h"
@@ -201,6 +202,12 @@ Boston, MA 02110-1301, USA.  */
 #include "macterm.h"
 #endif
 
+#ifdef HAVE_WINDOW_SYSTEM
+#ifdef USE_FONT_BACKEND
+#include "font.h"
+#endif /* USE_FONT_BACKEND */
+#endif /* HAVE_WINDOW_SYSTEM */
+
 #ifndef FRAME_X_OUTPUT
 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
 #endif
@@ -580,21 +587,12 @@ Lisp_Object Vmessage_log_max;
 
 static Lisp_Object Vmessages_buffer_name;
 
-/* Index 0 is the buffer that holds the current (desired) echo area message,
-   or nil if none is desired right now.
-
-   Index 1 is the buffer that holds the previously displayed echo area message,
-   or nil to indicate no message.  This is normally what's on the screen now.
-
-   These two can point to the same buffer.  That happens when the last
-   message output by the user (or made by echoing) has been displayed.  */
+/* Current, index 0, and last displayed echo area message.  Either
+   buffers from echo_buffers, or nil to indicate no message.  */
 
 Lisp_Object echo_area_buffer[2];
 
-/* Permanent pointers to the two buffers that are used for echo area
-   purposes.  Once the two buffers are made, and their pointers are
-   placed here, these two slots remain unchanged unless those buffers
-   need to be created afresh.  */
+/* The buffers referenced from echo_area_buffer.  */
 
 static Lisp_Object echo_buffer[2];
 
@@ -753,6 +751,7 @@ 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.  */
 
@@ -764,6 +763,7 @@ 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}
 };
@@ -813,10 +813,6 @@ static int clear_face_cache_count;
 static int clear_image_cache_count;
 #endif
 
-/* Record the previous terminal frame we displayed.  */
-
-static struct frame *previous_terminal_frame;
-
 /* Non-zero while redisplay_internal is in progress.  */
 
 int redisplaying_p;
@@ -967,8 +963,8 @@ static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
 static int face_before_or_after_it_pos P_ ((struct it *, int));
 static int next_overlay_change P_ ((int));
 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
-                                          Lisp_Object, struct text_pos *,
-                                          int));
+                                          Lisp_Object, Lisp_Object,
+                                          struct text_pos *, int));
 static int underlying_face_id P_ ((struct it *));
 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
                                                 struct window *));
@@ -1936,6 +1932,14 @@ get_glyph_string_clip_rects (s, rects, n)
        }
     }
 
+  if (s->row->clip)
+    {
+      XRectangle r_save = r;
+
+      if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
+       r.width = 0;
+    }
+
   if ((s->for_overlaps & OVERLAPS_BOTH) == 0
       || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
     {
@@ -2508,7 +2512,7 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
   XSETWINDOW (it->window, w);
   it->w = w;
   it->f = XFRAME (w->frame);
-
+  
   /* Extra space between lines (on window systems only).  */
   if (base_face_id == DEFAULT_FACE_ID
       && FRAME_WINDOW_P (it->f))
@@ -2525,9 +2529,9 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
 
   /* If realized faces have been removed, e.g. because of face
      attribute changes of named faces, recompute them.  When running
-     in batch mode, the face cache of Vterminal_frame is null.  If
+     in batch mode, the face cache of the initial frame is null.  If
      we happen to get called, make a dummy face cache.  */
-  if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
+  if (FRAME_FACE_CACHE (it->f) == NULL)
     init_frame_faces (it->f);
   if (FRAME_FACE_CACHE (it->f)->used == 0)
     recompute_basic_faces (it->f);
@@ -3073,16 +3077,18 @@ handle_stop (it)
          if (it->method == GET_FROM_DISPLAY_VECTOR)
            handle_overlay_change_p = 0;
 
-         /* Handle overlay changes.  */
+         /* Handle overlay changes.
+            This sets HANDLED to HANDLED_RECOMPUTE_PROPS
+            if it finds overlays.  */
          if (handle_overlay_change_p)
            handled = handle_overlay_change (it);
-
-         /* Determine where to stop next.  */
-         if (handled == HANDLED_NORMALLY)
-           compute_stop_pos (it);
        }
     }
   while (handled == HANDLED_RECOMPUTE_PROPS);
+
+  /* Determine where to stop next.  */
+  if (handled == HANDLED_NORMALLY)
+    compute_stop_pos (it);
 }
 
 
@@ -3363,18 +3369,58 @@ handle_face_prop (it)
   else
     {
       int base_face_id, bufpos;
+      int i;
+      Lisp_Object from_overlay
+       = (it->current.overlay_string_index >= 0
+          ? it->string_overlays[it->current.overlay_string_index]
+          : Qnil);
+
+      /* See if we got to this string directly or indirectly from
+        an overlay property.  That includes the before-string or
+        after-string of an overlay, strings in display properties
+        provided by an overlay, their text properties, etc.
+
+        FROM_OVERLAY is the overlay that brought us here, or nil if none.  */
+      if (! NILP (from_overlay))
+       for (i = it->sp - 1; i >= 0; i--)
+         {
+           if (it->stack[i].current.overlay_string_index >= 0)
+             from_overlay
+               = it->string_overlays[it->stack[i].current.overlay_string_index];
+           else if (! NILP (it->stack[i].from_overlay))
+             from_overlay = it->stack[i].from_overlay;
 
-      if (it->current.overlay_string_index >= 0)
-       bufpos = IT_CHARPOS (*it);
+           if (!NILP (from_overlay))
+             break;
+         }
+
+      if (! NILP (from_overlay))
+       {
+         bufpos = IT_CHARPOS (*it);
+         /* For a string from an overlay, the base face depends
+            only on text properties and ignores overlays.  */
+         base_face_id
+           = face_for_overlay_string (it->w,
+                                      IT_CHARPOS (*it),
+                                      it->region_beg_charpos,
+                                      it->region_end_charpos,
+                                      &next_stop,
+                                      (IT_CHARPOS (*it)
+                                       + TEXT_PROP_DISTANCE_LIMIT),
+                                      0,
+                                      from_overlay);
+       }
       else
-       bufpos = 0;
+       {
+         bufpos = 0;
 
-      /* For strings from a buffer, i.e. overlay strings or strings
-        from a `display' property, use the face at IT's current
-        buffer position as the base face to merge with, so that
-        overlay strings appear in the same face as surrounding
-        text, unless they specify their own faces.  */
-      base_face_id = underlying_face_id (it);
+         /* For strings from a `display' property, use the face at
+            IT's current buffer position as the base face to merge
+            with, so that overlay strings appear in the same face as
+            surrounding text, unless they specify their own
+            faces.  */
+         base_face_id = underlying_face_id (it);
+       }
 
       new_face_id = face_at_string_position (it->w,
                                             it->string,
@@ -3504,7 +3550,7 @@ face_before_or_after_it_pos (it, before_p)
          struct face *face = FACE_FROM_ID (it->f, face_id);
 
          c = string_char_and_length (p, rest, &len);
-         face_id = FACE_FOR_CHAR (it->f, face, c);
+         face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
        }
     }
   else
@@ -3543,7 +3589,7 @@ face_before_or_after_it_pos (it, before_p)
        {
          int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
          struct face *face = FACE_FROM_ID (it->f, face_id);
-         face_id = FACE_FOR_CHAR (it->f, face, c);
+         face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
        }
     }
 
@@ -3622,7 +3668,8 @@ handle_invisible_prop (it)
     }
   else
     {
-      int invis_p, newpos, next_stop, start_charpos;
+      int invis_p;
+      EMACS_INT newpos, next_stop, start_charpos;
       Lisp_Object pos, prop, overlay;
 
       /* First of all, is there invisible text at this position?  */
@@ -3719,6 +3766,10 @@ handle_invisible_prop (it)
                  it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
                }
               setup_for_ellipsis (it, 0);
+             /* Let the ellipsis display before
+                considering any properties of the following char.
+                Fixes jasonr@gnu.org 01 Oct 07 bug.  */
+             handled = HANDLED_RETURN;
             }
        }
     }
@@ -3780,7 +3831,7 @@ static enum prop_handled
 handle_display_prop (it)
      struct it *it;
 {
-  Lisp_Object prop, object;
+  Lisp_Object prop, object, overlay;
   struct text_pos *position;
   /* Nonzero if some property replaces the display of the text itself.  */
   int display_replaced_p = 0;
@@ -3808,10 +3859,12 @@ handle_display_prop (it)
   if (!it->string_from_display_prop_p)
     it->area = TEXT_AREA;
 
-  prop = Fget_char_property (make_number (position->charpos),
-                            Qdisplay, object);
+  prop = get_char_property_and_overlay (make_number (position->charpos),
+                                       Qdisplay, object, &overlay);
   if (NILP (prop))
     return HANDLED_NORMALLY;
+  /* Now OVERLAY is the overlay that gave us this property, or nil
+     if it was a text property.  */
 
   if (!STRINGP (it->string))
     object = it->w->buffer;
@@ -3833,22 +3886,35 @@ handle_display_prop (it)
     {
       for (; CONSP (prop); prop = XCDR (prop))
        {
-         if (handle_single_display_spec (it, XCAR (prop), object,
+         if (handle_single_display_spec (it, XCAR (prop), object, overlay,
                                          position, display_replaced_p))
-           display_replaced_p = 1;
+           {
+             display_replaced_p = 1;
+             /* If some text in a string is replaced, `position' no
+                longer points to the position of `object'.  */
+             if (STRINGP (object))
+               break;
+           }
        }
     }
   else if (VECTORP (prop))
     {
       int i;
       for (i = 0; i < ASIZE (prop); ++i)
-       if (handle_single_display_spec (it, AREF (prop, i), object,
+       if (handle_single_display_spec (it, AREF (prop, i), object, overlay,
                                        position, display_replaced_p))
-         display_replaced_p = 1;
+         {
+           display_replaced_p = 1;
+           /* If some text in a string is replaced, `position' no
+              longer points to the position of `object'.  */
+           if (STRINGP (object))
+             break;
+         }
     }
   else
     {
-      int ret = handle_single_display_spec (it, prop, object, position, 0);
+      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)
@@ -3890,6 +3956,9 @@ display_prop_end (it, object, start_pos)
    replaced text display with something else, for example an image;
    we ignore such properties after the first one has been processed.
 
+   OVERLAY is the overlay this `display' property came from,
+   or nil if it was a text property.
+
    If PROP is a `space' or `image' specification, and in some other
    cases too, set *POSITION to the position where the `display'
    property ends.
@@ -3899,11 +3968,12 @@ display_prop_end (it, object, start_pos)
    "something" is "nothing". */
 
 static int
-handle_single_display_spec (it, spec, object, position,
+handle_single_display_spec (it, spec, object, overlay, position,
                            display_replaced_before_p)
      struct it *it;
      Lisp_Object spec;
      Lisp_Object object;
+     Lisp_Object overlay;
      struct text_pos *position;
      int display_replaced_before_p;
 {
@@ -3952,7 +4022,7 @@ handle_single_display_spec (it, spec, object, position,
       && EQ (XCAR (spec), Qheight)
       && CONSP (XCDR (spec)))
     {
-      if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+      if (!FRAME_WINDOW_P (it->f))
        return 0;
 
       it->font_height = XCAR (XCDR (spec));
@@ -4013,12 +4083,12 @@ handle_single_display_spec (it, spec, object, position,
       return 0;
     }
 
-  /* Handle `(space_width WIDTH)'.  */
+  /* Handle `(space-width WIDTH)'.  */
   if (CONSP (spec)
       && EQ (XCAR (spec), Qspace_width)
       && CONSP (XCDR (spec)))
     {
-      if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+      if (!FRAME_WINDOW_P (it->f))
        return 0;
 
       value = XCAR (XCDR (spec));
@@ -4034,7 +4104,7 @@ handle_single_display_spec (it, spec, object, position,
     {
       Lisp_Object tem;
 
-      if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+      if (!FRAME_WINDOW_P (it->f))
        return 0;
 
       if (tem = XCDR (spec), CONSP (tem))
@@ -4060,7 +4130,7 @@ handle_single_display_spec (it, spec, object, position,
       && EQ (XCAR (spec), Qraise)
       && CONSP (XCDR (spec)))
     {
-      if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+      if (!FRAME_WINDOW_P (it->f))
        return 0;
 
 #ifdef HAVE_WINDOW_SYSTEM
@@ -4101,7 +4171,7 @@ handle_single_display_spec (it, spec, object, position,
       int face_id = DEFAULT_FACE_ID;
       int fringe_bitmap;
 
-      if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+      if (!FRAME_WINDOW_P (it->f))
        /* If we return here, POSITION has been advanced
           across the text with this property.  */
        return 0;
@@ -4118,7 +4188,7 @@ handle_single_display_spec (it, spec, object, position,
        {
          Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
          int face_id2 = lookup_derived_face (it->f, face_name,
-                                             'A', FRINGE_FACE_ID, 0);
+                                             FRINGE_FACE_ID, 0);
          if (face_id2 >= 0)
            face_id = face_id2;
        }
@@ -4137,6 +4207,7 @@ handle_single_display_spec (it, spec, object, position,
       it->position = start_pos;
       it->object = NILP (object) ? it->w->buffer : object;
       it->method = GET_FROM_IMAGE;
+      it->from_overlay = Qnil;
       it->face_id = face_id;
 
       /* Say that we haven't consumed the characters with
@@ -4150,7 +4221,7 @@ handle_single_display_spec (it, spec, object, position,
          it->left_user_fringe_face_id = face_id;
        }
       else
-       {
+        {
          it->right_user_fringe_bitmap = fringe_bitmap;
          it->right_user_fringe_face_id = face_id;
        }
@@ -4195,9 +4266,9 @@ handle_single_display_spec (it, spec, object, position,
 
   valid_p = (STRINGP (value)
 #ifdef HAVE_WINDOW_SYSTEM
-            || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
+             || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
 #endif /* not HAVE_WINDOW_SYSTEM */
-            || (CONSP (value) && EQ (XCAR (value), Qspace)));
+             || (CONSP (value) && EQ (XCAR (value), Qspace)));
 
   if (valid_p && !display_replaced_before_p)
     {
@@ -4207,6 +4278,7 @@ handle_single_display_spec (it, spec, object, position,
       it->position = *position;
       push_it (it);
       it->position = save_pos;
+      it->from_overlay = overlay;
 
       if (NILP (location))
        it->area = TEXT_AREA;
@@ -4233,13 +4305,16 @@ handle_single_display_spec (it, spec, object, position,
          /* Say that we haven't consumed the characters with
             `display' property yet.  The call to pop_it in
             set_iterator_to_next will clean this up.  */
-         *position = start_pos;
+         if (BUFFERP (object))
+           it->current.pos = start_pos;
        }
       else if (CONSP (value) && EQ (XCAR (value), Qspace))
        {
          it->method = GET_FROM_STRETCH;
          it->object = value;
-         *position = it->position = start_pos;
+         it->position = start_pos;
+         if (BUFFERP (object))
+           it->current.pos = start_pos;
        }
 #ifdef HAVE_WINDOW_SYSTEM
       else
@@ -4253,7 +4328,8 @@ handle_single_display_spec (it, spec, object, position,
          /* Say that we haven't consumed the characters with
             `display' property yet.  The call to pop_it in
             set_iterator_to_next will clean this up.  */
-         *position = start_pos;
+         if (BUFFERP (object))
+           it->current.pos = start_pos;
        }
 #endif /* HAVE_WINDOW_SYSTEM */
 
@@ -4267,7 +4343,7 @@ handle_single_display_spec (it, spec, object, position,
 }
 
 
-/* Check if SPEC is a display specification value whose text should be
+/* Check if SPEC is a display sub-property value whose text should be
    treated as intangible.  */
 
 static int
@@ -4469,6 +4545,100 @@ 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 (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;
+
+#ifdef USE_FONT_BACKEND
+         if (enable_font_backend
+             && 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;
+           }
+#endif
+         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))
+       {
+         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];
+
+             args[0] = Vauto_composition_function;
+             specbind (Qauto_composition_function, Qnil);
+             args[1] = make_number (pos);
+             args[2] = make_number (limit);
+#ifdef USE_FONT_BACKEND
+             if (enable_font_backend)
+               args[3] = it->window;
+             else
+#endif /* USE_FONT_BACKEND */
+               args[3] = Qnil;
+             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.  */
 
@@ -4477,7 +4647,7 @@ handle_composition_prop (it)
      struct it *it;
 {
   Lisp_Object prop, string;
-  int pos, pos_byte, end;
+  EMACS_INT pos, pos_byte, start, end;
   enum prop_handled handled = HANDLED_NORMALLY;
 
   if (STRINGP (it->string))
@@ -4496,11 +4666,20 @@ handle_composition_prop (it)
   /* If there's a valid composition and point is not inside of the
      composition (in the case that the composition is from the current
      buffer), draw a glyph composed from the composition components.  */
-  if (find_composition (pos, -1, &pos, &end, &prop, string)
-      && COMPOSITION_VALID_P (pos, end, prop)
-      && (STRINGP (it->string) || (PT <= pos || PT >= end)))
+  if (find_composition (pos, -1, &start, &end, &prop, string)
+      && COMPOSITION_VALID_P (start, end, prop)
+      && (STRINGP (it->string) || (PT <= start || PT >= end)))
     {
-      int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
+      int id;
+
+      if (start != pos)
+       {
+         if (STRINGP (it->string))
+           pos_byte = string_char_to_byte (it->string, start);
+         else
+           pos_byte = CHAR_TO_BYTE (start);
+       }
+      id = get_composition_id (start, pos_byte, end - start, prop, string);
 
       if (id >= 0)
        {
@@ -4529,9 +4708,29 @@ handle_composition_prop (it)
          it->method = GET_FROM_COMPOSITION;
          it->cmp_id = id;
          it->cmp_len = COMPOSITION_LENGTH (prop);
-         /* For a terminal, draw only the first character of the
-             components.  */
-         it->c = COMPOSITION_GLYPH (composition_table[id], 0);
+         /* For a terminal, draw only the first (non-TAB) character
+            of the components.  */
+#ifdef USE_FONT_BACKEND
+         if (composition_table[id]->method == COMPOSITION_WITH_GLYPH_STRING)
+           {
+             Lisp_Object lgstring = AREF (XHASH_TABLE (composition_hash_table)
+                                          ->key_and_value,
+                                          cmp->hash_index * 2);
+
+             it->c = LGLYPH_CHAR (LGSTRING_GLYPH (lgstring, 0));
+           }
+         else
+#endif /* USE_FONT_BACKEND */
+           {
+             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;
@@ -4846,7 +5045,10 @@ load_overlay_strings (it, charpos)
   i = 0;
   j = it->current.overlay_string_index;
   while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
-    it->overlay_strings[i++] = entries[j++].string;
+    {
+      it->overlay_strings[i] = entries[j].string;
+      it->string_overlays[i++] = entries[j++].overlay;
+    }
 
   CHECK_IT (it);
 }
@@ -4892,6 +5094,7 @@ get_overlay_strings_1 (it, charpos, compute_stop_p)
         string.  */
       IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
       it->string = it->overlay_strings[0];
+      it->from_overlay = Qnil;
       it->stop_charpos = 0;
       xassert (STRINGP (it->string));
       it->end_charpos = SCHARS (it->string);
@@ -4945,6 +5148,7 @@ push_it (it)
   p->face_id = it->face_id;
   p->string = it->string;
   p->method = it->method;
+  p->from_overlay = it->from_overlay;
   switch (p->method)
     {
     case GET_FROM_IMAGE:
@@ -4998,6 +5202,7 @@ pop_it (it)
   it->current = p->current;
   it->position = p->position;
   it->string = p->string;
+  it->from_overlay = p->from_overlay;
   if (NILP (it->string))
     SET_TEXT_POS (it->current.string_pos, -1, -1);
   it->method = p->method;
@@ -5186,7 +5391,7 @@ back_to_previous_visible_line_start (it)
       {
        struct it it2;
        int pos;
-       int beg, end;
+       EMACS_INT beg, end;
        Lisp_Object val, overlay;
 
        /* If newline is part of a composition, continue from start of composition */
@@ -5548,31 +5753,26 @@ get_next_display_element (it)
             the translation.  This could easily be changed but I
             don't believe that it is worth doing.
 
-            If it->multibyte_p is nonzero, eight-bit characters and
-            non-printable multibyte characters are also translated to
-            octal form.
+            If it->multibyte_p is nonzero, non-printable non-ASCII
+            characters are also translated to octal form.
 
             If it->multibyte_p is zero, eight-bit characters that
             don't have corresponding multibyte char code are also
             translated to octal form.  */
          else if ((it->c < ' '
-                   && (it->area != TEXT_AREA
-                       /* In mode line, treat \n like other crl chars.  */
-                       || (it->c != '\t'
-                           && it->glyph_row && it->glyph_row->mode_line_p)
-                       || (it->c != '\n' && it->c != '\t')))
-                  || (it->multibyte_p
-                      ? ((it->c >= 127
-                          && it->len == 1)
-                         || !CHAR_PRINTABLE_P (it->c)
+                   ? (it->area != TEXT_AREA
+                      /* In mode line, treat \n, \t like other crl chars.  */
+                      || (it->c != '\t'
+                          && it->glyph_row && it->glyph_row->mode_line_p)
+                      || (it->c != '\n' && it->c != '\t'))
+                   : (it->multibyte_p
+                      ? (!CHAR_PRINTABLE_P (it->c)
                          || (!NILP (Vnobreak_char_display)
-                             && (it->c == 0x8a0 || it->c == 0x8ad
-                                 || it->c == 0x920 || it->c == 0x92d
-                                 || it->c == 0xe20 || it->c == 0xe2d
-                                 || it->c == 0xf20 || it->c == 0xf2d)))
+                             && (it->c == 0xA0 /* NO-BREAK SPACE */
+                                 || it->c == 0xAD /* SOFT HYPHEN */)))
                       : (it->c >= 127
-                         && (!unibyte_display_via_language_environment
-                             || it->c == unibyte_char_to_multibyte (it->c)))))
+                         && (! unibyte_display_via_language_environment
+                             || (UNIBYTE_CHAR_HAS_MULTIBYTE_P (it->c)))))))
            {
              /* IT->c is a control character which must be displayed
                 either as '\003' or as `^C' where the '\\' and '^'
@@ -5629,8 +5829,7 @@ get_next_display_element (it)
                 highlighting.  */
 
              if (EQ (Vnobreak_char_display, Qt)
-                 && (it->c == 0x8a0 || it->c == 0x920
-                     || it->c == 0xe20 || it->c == 0xf20))
+                 && it->c == 0xA0)
                {
                  /* Merge the no-break-space face into the current face.  */
                  face_id = merge_faces (it->f, Qnobreak_space, 0,
@@ -5681,8 +5880,7 @@ get_next_display_element (it)
                 highlighting.  */
 
              if (EQ (Vnobreak_char_display, Qt)
-                 && (it->c == 0x8ad || it->c == 0x92d
-                     || it->c == 0xe2d || it->c == 0xf2d))
+                 && it->c == 0xAD)
                {
                  g = it->c = '-';
                  XSETINT (it->ctl_chars[0], g);
@@ -5693,13 +5891,10 @@ get_next_display_element (it)
              /* Handle non-break space and soft hyphen
                 with the escape glyph.  */
 
-             if (it->c == 0x8a0 || it->c == 0x8ad
-                 || it->c == 0x920 || it->c == 0x92d
-                 || it->c == 0xe20 || it->c == 0xe2d
-                 || it->c == 0xf20 || it->c == 0xf2d)
+             if (it->c == 0xA0 || it->c == 0xAD)
                {
                  XSETINT (it->ctl_chars[0], escape_glyph);
-                 g = it->c = ((it->c & 0xf) == 0 ? ' ' : '-');
+                 g = it->c = (it->c == 0xA0 ? ' ' : '-');
                  XSETINT (it->ctl_chars[1], g);
                  ctl_len = 2;
                  goto display_control;
@@ -5711,23 +5906,27 @@ get_next_display_element (it)
                int i;
 
                /* Set IT->ctl_chars[0] to the glyph for `\\'.  */
-               if (SINGLE_BYTE_CHAR_P (it->c))
-                 str[0] = it->c, len = 1;
+               if (CHAR_BYTE8_P (it->c))
+                 {
+                   str[0] = CHAR_TO_BYTE8 (it->c);
+                   len = 1;
+                 }
+               else if (it->c < 256)
+                 {
+                   str[0] = it->c;
+                   len = 1;
+                 }
                else
                  {
-                   len = CHAR_STRING_NO_SIGNAL (it->c, str);
-                   if (len < 0)
-                     {
-                       /* It's an invalid character, which shouldn't
-                          happen actually, but due to bugs it may
-                          happen.  Let's print the char as is, there's
-                          not much meaningful we can do with it.  */
-                         str[0] = it->c;
-                         str[1] = it->c >> 8;
-                         str[2] = it->c >> 16;
-                         str[3] = it->c >> 24;
-                         len = 4;
-                       }
+                   /* It's an invalid character, which shouldn't
+                      happen actually, but due to bugs it may
+                      happen.  Let's print the char as is, there's
+                      not much meaningful we can do with it.  */
+                     str[0] = it->c;
+                     str[1] = it->c >> 8;
+                     str[2] = it->c >> 16;
+                     str[3] = it->c >> 24;
+                     len = 4;
                    }
 
                for (i = 0; i < len; i++)
@@ -5758,16 +5957,21 @@ get_next_display_element (it)
              goto get_next;
            }
        }
+    }
 
-      /* Adjust face id for a multibyte character.  There are no
-         multibyte character in unibyte text.  */
-      if (it->multibyte_p
-         && success_p
-         && FRAME_WINDOW_P (it->f))
-       {
-         struct face *face = FACE_FROM_ID (it->f, it->face_id);
-         it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
-       }
+  /* Adjust face id for a multibyte character.  There are no multibyte
+     character in unibyte text.  */
+  if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
+      && it->multibyte_p
+      && success_p
+      && 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);
     }
 
   /* Is this character the last one of a run of characters with
@@ -6769,6 +6973,16 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
             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.  */
+             line_height = it->max_ascent + it->max_descent;
+             if (to_y >= it->current_y
+                 && to_y < it->current_y + line_height)
+               {
+                 reached = 6;
+                 break;
+               }
              it_backup = *it;
              TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
              skip2 = move_it_in_display_line_to (it, to_charpos, -1,
@@ -7087,18 +7301,22 @@ move_it_by_lines (it, dvpos, need_y_p)
 {
   struct position pos;
 
-  if (!FRAME_WINDOW_P (it->f))
+  /* The commented-out optimization uses vmotion on terminals.  This
+     gives bad results, because elements like it->what, on which
+     callers such as pos_visible_p rely, aren't updated. */
+  /*  if (!FRAME_WINDOW_P (it->f))
     {
       struct text_pos textpos;
 
-      /* We can use vmotion on frames without proportional fonts.  */
       pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
       SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
       reseat (it, textpos, 1);
       it->vpos += pos.vpos;
       it->current_y += pos.vpos;
     }
-  else if (dvpos == 0)
+    else */
+
+  if (dvpos == 0)
     {
       /* DVPOS == 0 means move to the start of the screen line.  */
       move_it_vertically_backward (it, 0);
@@ -7301,7 +7519,7 @@ message_dolog (m, nbytes, nlflag, multibyte)
          for (i = 0; i < nbytes; i += char_bytes)
            {
              c = string_char_and_length (m + i, nbytes - i, &char_bytes);
-             work[0] = (SINGLE_BYTE_CHAR_P (c)
+             work[0] = (ASCII_CHAR_P (c)
                         ? c
                         : multibyte_char_to_unibyte (c, Qnil));
              insert_1_both (work, 1, 1, 1, 0, 0);
@@ -7317,7 +7535,8 @@ message_dolog (m, nbytes, nlflag, multibyte)
             for the *Message* buffer.  */
          for (i = 0; i < nbytes; i++)
            {
-             c = unibyte_char_to_multibyte (msg[i]);
+             c = msg[i];
+             c = unibyte_char_to_multibyte (c);
              char_bytes = CHAR_STRING (c, str);
              insert_1_both (str, 1, char_bytes, 1, 0, 0);
            }
@@ -7524,8 +7743,8 @@ message2_nolog (m, nbytes, multibyte)
       do_pending_window_change (0);
       echo_area_display (1);
       do_pending_window_change (0);
-      if (frame_up_to_date_hook != 0 && ! gc_in_progress)
-       (*frame_up_to_date_hook) (f);
+      if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
+       (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
     }
 }
 
@@ -7628,8 +7847,8 @@ message3_nolog (m, nbytes, multibyte)
       do_pending_window_change (0);
       echo_area_display (1);
       do_pending_window_change (0);
-      if (frame_up_to_date_hook != 0 && ! gc_in_progress)
-       (*frame_up_to_date_hook) (f);
+      if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
+       (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
     }
 }
 
@@ -7867,6 +8086,10 @@ ensure_echo_area_buffers ()
    WHICH > 0 means use echo_area_buffer[1].  If that is nil, choose a
    suitable buffer from echo_buffer[] and clear it.
 
+   If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
+   that the current message becomes the last displayed one, make
+   choose a suitable buffer for echo_area_buffer[0], and clear it.
+
    Value is what FN returns.  */
 
 static int
@@ -7891,6 +8114,17 @@ with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
     this_one = 0, the_other = 1;
   else if (which > 0)
     this_one = 1, the_other = 0;
+  else
+    {
+      this_one = 0, the_other = 1;
+      clear_buffer_p = 1;
+
+      /* We need a fresh one in case the current echo buffer equals
+        the one containing the last displayed echo area message.  */
+      if (!NILP (echo_area_buffer[this_one])
+         && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
+       echo_area_buffer[this_one] = Qnil;
+    }
 
   /* Choose a suitable buffer from echo_buffer[] is we don't
      have one.  */
@@ -8528,7 +8762,7 @@ set_message (s, string, nbytes, multibyte_p)
     = ((s && multibyte_p)
        || (STRINGP (string) && STRING_MULTIBYTE (string)));
 
-  with_echo_area_buffer (0, 0, set_message_1,
+  with_echo_area_buffer (0, -1, set_message_1,
                         (EMACS_INT) s, string, nbytes, multibyte_p);
   message_buf_print = 0;
   help_echo_showing_p = 0;
@@ -8558,7 +8792,6 @@ set_message_1 (a1, a2, nbytes, multibyte_p)
 
   /* Insert new message at BEG.  */
   TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
-  Ferase_buffer ();
 
   if (STRINGP (string))
     {
@@ -8588,7 +8821,7 @@ set_message_1 (a1, a2, nbytes, multibyte_p)
          for (i = 0; i < nbytes; i += n)
            {
              c = string_char_and_length (s + i, nbytes - i, &n);
-             work[0] = (SINGLE_BYTE_CHAR_P (c)
+             work[0] = (ASCII_CHAR_P (c)
                         ? c
                         : multibyte_char_to_unibyte (c, Qnil));
              insert_1_both (work, 1, 1, 1, 0, 0);
@@ -8605,7 +8838,8 @@ set_message_1 (a1, a2, nbytes, multibyte_p)
          /* Convert a single-byte string to multibyte.  */
          for (i = 0; i < nbytes; i++)
            {
-             c = unibyte_char_to_multibyte (msg[i]);
+             c = msg[i];
+             c = unibyte_char_to_multibyte (c);
              n = CHAR_STRING (c, str);
              insert_1_both (str, 1, n, 1, 0, 0);
            }
@@ -8654,11 +8888,11 @@ clear_garbaged_frames ()
     {
       Lisp_Object tail, frame;
       int changed_count = 0;
-
+      
       FOR_EACH_FRAME (tail, frame)
        {
          struct frame *f = XFRAME (frame);
-
+         
          if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
            {
              if (f->resized_p)
@@ -8672,7 +8906,7 @@ clear_garbaged_frames ()
              f->resized_p = 0;
            }
        }
-
+      
       frame_garbaged = 0;
       if (changed_count)
        ++windows_or_buffers_changed;
@@ -8705,11 +8939,10 @@ echo_area_display (update_frame_p)
 /* The terminal frame is used as the first Emacs frame on the Mac OS.  */
 #ifndef MAC_OS8
 #ifdef HAVE_WINDOW_SYSTEM
-  /* When Emacs starts, selected_frame may be a visible terminal
-     frame, even if we run under a window system.  If we let this
-     through, a message would be displayed on the terminal.  */
-  if (EQ (selected_frame, Vterminal_frame)
-      && !NILP (Vwindow_system))
+  /* When Emacs starts, selected_frame may be the initial terminal
+     frame.  If we let this through, a message would be displayed on
+     the terminal.  */
+  if (FRAME_INITIAL_P (XFRAME (selected_frame)))
     return 0;
 #endif /* HAVE_WINDOW_SYSTEM */
 #endif
@@ -8760,7 +8993,7 @@ echo_area_display (update_frame_p)
                 Can do with a display update of the echo area,
                 unless we displayed some mode lines.  */
              update_single_window (w, 1);
-             rif->flush_display (f);
+             FRAME_RIF (f)->flush_display (f);
            }
          else
            update_frame (f, 1, 1);
@@ -8775,8 +9008,10 @@ echo_area_display (update_frame_p)
   else if (!EQ (mini_window, selected_window))
     windows_or_buffers_changed++;
 
-  /* The current message is now also the last one displayed.  */
+  /* Last displayed message is now the current message.  */
   echo_area_buffer[1] = echo_area_buffer[0];
+  /* Inform read_char that we're not echoing.  */
+  echo_message_buffer = Qnil;
 
   /* Prevent redisplay optimization in redisplay_internal by resetting
      this_line_start_pos.  This is done because the mini-buffer now
@@ -9330,8 +9565,8 @@ x_cursor_to (vpos, hpos, y, x)
     {
       BLOCK_INPUT;
       display_and_set_cursor (w, 1, hpos, vpos, x, y);
-      if (rif->flush_display_optional)
-       rif->flush_display_optional (SELECTED_FRAME ());
+      if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
+       FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
       UNBLOCK_INPUT;
     }
 }
@@ -10702,7 +10937,7 @@ check_point_in_composition (prev_buf, prev_pt, buf, pt)
      struct buffer *prev_buf, *buf;
      int prev_pt, pt;
 {
-  int start, end;
+  EMACS_INT start, end;
   Lisp_Object prop;
   Lisp_Object buffer;
 
@@ -10783,6 +11018,8 @@ select_frame_for_redisplay (frame)
   Lisp_Object tail, sym, val;
   Lisp_Object old = selected_frame;
 
+  xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
+
   selected_frame = frame;
 
   for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
@@ -10791,8 +11028,7 @@ select_frame_for_redisplay (frame)
            SYMBOLP (sym))
        && (sym = indirect_variable (sym),
            val = SYMBOL_VALUE (sym),
-           (BUFFER_LOCAL_VALUEP (val)
-            || SOME_BUFFER_LOCAL_VALUEP (val)))
+           (BUFFER_LOCAL_VALUEP (val)))
        && XBUFFER_LOCAL_VALUE (val)->check_frame)
       /* Use find_symbol_value rather than Fsymbol_value
         to avoid an error if it is void.  */
@@ -10804,8 +11040,7 @@ select_frame_for_redisplay (frame)
            SYMBOLP (sym))
        && (sym = indirect_variable (sym),
            val = SYMBOL_VALUE (sym),
-           (BUFFER_LOCAL_VALUEP (val)
-            || SOME_BUFFER_LOCAL_VALUEP (val)))
+           (BUFFER_LOCAL_VALUEP (val)))
        && XBUFFER_LOCAL_VALUE (val)->check_frame)
       find_symbol_value (sym);
 }
@@ -10839,6 +11074,7 @@ redisplay_internal (preserve_echo_area)
   int count, count1;
   struct frame *sf;
   int polling_stopped_here = 0;
+  Lisp_Object old_frame = selected_frame;
 
   /* Non-zero means redisplay has to consider all windows on all
      frames.  Zero means, only selected_window is considered.  */
@@ -10900,6 +11136,14 @@ redisplay_internal (preserve_echo_area)
   }
 
  retry:
+  if (!EQ (old_frame, selected_frame)
+      && FRAME_LIVE_P (XFRAME (old_frame)))
+    /* When running redisplay, we play a bit fast-and-loose and allow e.g.
+       selected_frame and selected_window to be temporarily out-of-sync so
+       when we come back here via `goto retry', we need to resync because we
+       may need to run Elisp code (via prepare_menu_bars).  */
+    select_frame_for_redisplay (old_frame);
+
   pause = 0;
   reconsider_clip_changes (w, current_buffer);
   last_escape_glyph_frame = NULL;
@@ -10920,17 +11164,16 @@ redisplay_internal (preserve_echo_area)
   if (face_change_count)
     ++windows_or_buffers_changed;
 
-  if (! FRAME_WINDOW_P (sf)
-      && previous_terminal_frame != sf)
+  if (FRAME_TERMCAP_P (sf)
+      && FRAME_TTY (sf)->previous_frame != sf)
     {
-      /* Since frames on an ASCII terminal share the same display
-        area, displaying a different frame means redisplay the whole
-        thing.  */
+      /* Since frames on a single ASCII terminal share the same
+        display area, displaying a different frame means redisplay
+        the whole thing.  */
       windows_or_buffers_changed++;
       SET_FRAME_GARBAGED (sf);
-      XSETFRAME (Vterminal_frame, sf);
+      FRAME_TTY (sf)->previous_frame = sf;
     }
-  previous_terminal_frame = sf;
 
   /* Set the visible flags for all frames.  Do this before checking
      for resized or garbaged frames; they want to know if their frames
@@ -10952,6 +11195,7 @@ redisplay_internal (preserve_echo_area)
       }
   }
 
+  
   /* Notice any pending interrupt request to change frame size.  */
   do_pending_window_change (1);
 
@@ -11313,7 +11557,7 @@ redisplay_internal (preserve_echo_area)
        {
          struct frame *f = XFRAME (frame);
 
-         if (FRAME_WINDOW_P (f) || f == sf)
+         if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
            {
              if (! EQ (frame, selected_frame))
                /* Select the frame, for the sake of frame-local
@@ -11322,16 +11566,16 @@ redisplay_internal (preserve_echo_area)
 
              /* Mark all the scroll bars to be removed; we'll redeem
                 the ones we want when we redisplay their windows.  */
-             if (condemn_scroll_bars_hook)
-               condemn_scroll_bars_hook (f);
+             if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
+               FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
 
              if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
                redisplay_windows (FRAME_ROOT_WINDOW (f));
 
              /* Any scroll bars which redisplay_windows should have
                 nuked should now go away.  */
-             if (judge_scroll_bars_hook)
-               judge_scroll_bars_hook (f);
+             if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
+               FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
 
              /* If fonts changed, display again.  */
              /* ??? rms: I suspect it is a mistake to jump all the way
@@ -11378,12 +11622,12 @@ redisplay_internal (preserve_echo_area)
          FOR_EACH_FRAME (tail, frame)
            {
              struct frame *f = XFRAME (frame);
-             if (f->updated_p)
-               {
-                 mark_window_display_accurate (f->root_window, 1);
-                 if (frame_up_to_date_hook)
-                   frame_up_to_date_hook (f);
-               }
+              if (f->updated_p)
+                {
+                  mark_window_display_accurate (f->root_window, 1);
+                  if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
+                    FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
+                }
            }
        }
     }
@@ -11468,8 +11712,8 @@ redisplay_internal (preserve_echo_area)
          /* Say overlay arrows are up to date.  */
          update_overlay_arrows (1);
 
-         if (frame_up_to_date_hook != 0)
-           frame_up_to_date_hook (sf);
+         if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
+           FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
        }
 
       update_mode_lines = 0;
@@ -11579,8 +11823,9 @@ redisplay_preserve_echo_area (from_where)
   else
     redisplay_internal (1);
 
-  if (rif != NULL && rif->flush_display_optional)
-    rif->flush_display_optional (NULL);
+  if (FRAME_RIF (SELECTED_FRAME ()) != NULL
+      && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
+    FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
 }
 
 
@@ -11588,7 +11833,8 @@ redisplay_preserve_echo_area (from_where)
    redisplay_internal.  Reset redisplaying_p to the value it had
    before redisplay_internal was called, and clear
    prevent_freeing_realized_faces_p.  It also selects the previously
-   selected frame.  */
+   selected frame, unless it has been deleted (by an X connection
+   failure during redisplay, for example).  */
 
 static Lisp_Object
 unwind_redisplay (val)
@@ -11599,7 +11845,8 @@ unwind_redisplay (val)
   old_redisplaying_p = XCAR (val);
   redisplaying_p = XFASTINT (old_redisplaying_p);
   old_frame = XCDR (val);
-  if (! EQ (old_frame, selected_frame))
+  if (! EQ (old_frame, selected_frame)
+      && FRAME_LIVE_P (XFRAME (old_frame)))
     select_frame_for_redisplay (old_frame);
   return Qnil;
 }
@@ -11710,35 +11957,24 @@ disp_char_vector (dp, c)
      struct Lisp_Char_Table *dp;
      int c;
 {
-  int code[4], i;
   Lisp_Object val;
 
-  if (SINGLE_BYTE_CHAR_P (c))
-    return (dp->contents[c]);
-
-  SPLIT_CHAR (c, code[0], code[1], code[2]);
-  if (code[1] < 32)
-    code[1] = -1;
-  else if (code[2] < 32)
-    code[2] = -1;
-
-  /* Here, the possible range of code[0] (== charset ID) is
-     128..max_charset.  Since the top level char table contains data
-     for multibyte characters after 256th element, we must increment
-     code[0] by 128 to get a correct index.  */
-  code[0] += 128;
-  code[3] = -1;                /* anchor */
-
-  for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
+  if (ASCII_CHAR_P (c))
     {
-      val = dp->contents[code[i]];
-      if (!SUB_CHAR_TABLE_P (val))
-       return (NILP (val) ? dp->defalt : val);
+      val = dp->ascii;
+      if (SUB_CHAR_TABLE_P (val))
+       val = XSUB_CHAR_TABLE (val)->contents[c];
     }
+  else
+    {
+      Lisp_Object table;
 
-  /* Here, val is a sub char table.  We return the default value of
-     it.  */
-  return (dp->defalt);
+      XSETCHAR_TABLE (table, dp);
+      val = char_table_ref (table, c);
+    }
+  if (NILP (val))
+    val = dp->defalt;
+  return val;
 }
 
 
@@ -12447,7 +12683,7 @@ compute_window_start_on_continuation_line (w)
             minimum distance from the old window start.  */
          pos = it.current.pos;
          min_distance = INFINITY;
-         while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
+         while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
                 distance < min_distance)
            {
              min_distance = distance;
@@ -12748,7 +12984,9 @@ set_vertical_scroll_bar (w)
     start = end = whole = 0;
 
   /* Indicate what this scroll bar ought to be displaying now.  */
-  set_vertical_scroll_bar_hook (w, end - start, whole, start);
+  if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
+    (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
+      (w, end - start, whole, start);
 }
 
 
@@ -13467,20 +13705,22 @@ redisplay_window (window, just_this_one_p)
         display_menu_bar (w);
 
 #ifdef HAVE_WINDOW_SYSTEM
+      if (FRAME_WINDOW_P (f))
+        {
 #if defined (USE_GTK) || USE_MAC_TOOLBAR
-      redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
+          redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
 #else
-      redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
-        && (FRAME_TOOL_BAR_LINES (f) > 0
-            || !NILP (Vauto_resize_tool_bars));
-
+          redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
+            && (FRAME_TOOL_BAR_LINES (f) > 0
+                || !NILP (Vauto_resize_tool_bars));
 #endif
 
-      if (redisplay_tool_bar_p && redisplay_tool_bar (f))
-       {
-         extern int ignore_mouse_drag_p;
-         ignore_mouse_drag_p = 1;
-       }
+          if (redisplay_tool_bar_p && redisplay_tool_bar (f))
+           {
+             extern int ignore_mouse_drag_p;
+             ignore_mouse_drag_p = 1;
+           }
+        }
 #endif
     }
 
@@ -13514,13 +13754,17 @@ redisplay_window (window, just_this_one_p)
 
       /* Note that we actually used the scroll bar attached to this
         window, so it shouldn't be deleted at the end of redisplay.  */
-      redeem_scroll_bar_hook (w);
+      if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
+        (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
     }
 
   /* Restore current_buffer and value of point in it.  */
   TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
   set_buffer_internal_1 (old);
-  TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
+  /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
+     shorter.  This can be caused by log truncation in *Messages*. */
+  if (CHARPOS (lpoint) <= ZV)
+    TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
 
   unbind_to (count, Qnil);
 }
@@ -13780,10 +14024,10 @@ try_window_reusing_current_matrix (w)
          if (run.height > 0 && run.current_y != run.desired_y)
            {
              update_begin (f);
-             rif->update_window_begin_hook (w);
-             rif->clear_window_mouse_face (w);
-             rif->scroll_run_hook (w, &run);
-             rif->update_window_end_hook (w, 0, 0);
+             FRAME_RIF (f)->update_window_begin_hook (w);
+             FRAME_RIF (f)->clear_window_mouse_face (w);
+             FRAME_RIF (f)->scroll_run_hook (w, &run);
+             FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
              update_end (f);
            }
 
@@ -13952,10 +14196,10 @@ try_window_reusing_current_matrix (w)
       if (run.height)
        {
          update_begin (f);
-         rif->update_window_begin_hook (w);
-         rif->clear_window_mouse_face (w);
-         rif->scroll_run_hook (w, &run);
-         rif->update_window_end_hook (w, 0, 0);
+         FRAME_RIF (f)->update_window_begin_hook (w);
+         FRAME_RIF (f)->clear_window_mouse_face (w);
+         FRAME_RIF (f)->scroll_run_hook (w, &run);
+         FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
          update_end (f);
        }
 
@@ -14405,7 +14649,7 @@ try_window_id (w)
 
   /* Window must either use window-based redisplay or be full width.  */
   if (!FRAME_WINDOW_P (f)
-      && (!line_ins_del_ok
+      && (!FRAME_LINE_INS_DEL_OK (f)
          || !WINDOW_FULL_WIDTH_P (w)))
     GIVE_UP (4);
 
@@ -14814,10 +15058,10 @@ try_window_id (w)
 
       if (FRAME_WINDOW_P (f))
        {
-         rif->update_window_begin_hook (w);
-         rif->clear_window_mouse_face (w);
-         rif->scroll_run_hook (w, &run);
-         rif->update_window_end_hook (w, 0, 0);
+         FRAME_RIF (f)->update_window_begin_hook (w);
+         FRAME_RIF (f)->clear_window_mouse_face (w);
+         FRAME_RIF (f)->scroll_run_hook (w, &run);
+         FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
        }
       else
        {
@@ -14835,36 +15079,36 @@ try_window_id (w)
            {
              /* Scroll last_unchanged_at_beg_row to the end of the
                 window down dvpos lines.  */
-             set_terminal_window (end);
+             set_terminal_window (f, end);
 
              /* On dumb terminals delete dvpos lines at the end
                 before inserting dvpos empty lines.  */
-             if (!scroll_region_ok)
-               ins_del_lines (end - dvpos, -dvpos);
+             if (!FRAME_SCROLL_REGION_OK (f))
+               ins_del_lines (f, end - dvpos, -dvpos);
 
              /* Insert dvpos empty lines in front of
                  last_unchanged_at_beg_row.  */
-             ins_del_lines (from, dvpos);
+             ins_del_lines (f, from, dvpos);
            }
          else if (dvpos < 0)
            {
              /* Scroll up last_unchanged_at_beg_vpos to the end of
                 the window to last_unchanged_at_beg_vpos - |dvpos|.  */
-             set_terminal_window (end);
+             set_terminal_window (f, end);
 
              /* Delete dvpos lines in front of
                 last_unchanged_at_beg_vpos.  ins_del_lines will set
                 the cursor to the given vpos and emit |dvpos| delete
                 line sequences.  */
-             ins_del_lines (from + dvpos, dvpos);
+             ins_del_lines (f, from + dvpos, dvpos);
 
              /* On a dumb terminal insert dvpos empty lines at the
                  end.  */
-             if (!scroll_region_ok)
-               ins_del_lines (end + dvpos, -dvpos);
+             if (!FRAME_SCROLL_REGION_OK (f))
+               ins_del_lines (f, end + dvpos, -dvpos);
            }
 
-         set_terminal_window (0);
+         set_terminal_window (f, 0);
        }
 
       update_end (f);
@@ -15656,7 +15900,7 @@ append_space_for_newline (it, default_face_p)
          else if (it->face_before_selective_p)
            it->face_id = it->saved_face_id;
          face = FACE_FROM_ID (it->f, it->face_id);
-         it->face_id = FACE_FOR_CHAR (it->f, face, 0);
+         it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
 
          PRODUCE_GLYPHS (it);
 
@@ -15716,9 +15960,9 @@ extend_face_to_end_of_line (it)
          ASCII face.  This will be automatically undone the next time
          get_next_display_element returns a multibyte character.  Note
          that the character will always be single byte in unibyte text.  */
-  if (!SINGLE_BYTE_CHAR_P (it->c))
+  if (!ASCII_CHAR_P (it->c))
     {
-      it->face_id = FACE_FOR_CHAR (f, face, 0);
+      it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
     }
 
   if (FRAME_WINDOW_P (f))
@@ -15824,7 +16068,7 @@ highlight_trailing_whitespace (f, row)
                  && glyph->u.ch == ' '))
          && trailing_whitespace_p (glyph->charpos))
        {
-         int face_id = lookup_named_face (f, Qtrailing_whitespace, 0, 0);
+         int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
          if (face_id < 0)
            return;
 
@@ -16438,7 +16682,7 @@ display_menu_bar (w)
 
   /* Don't do all this for graphical frames.  */
 #ifdef HAVE_NTGUI
-  if (!NILP (Vwindow_system))
+  if (FRAME_W32_P (f))
     return;
 #endif
 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
@@ -16669,10 +16913,10 @@ display_mode_line (w, face_id, format)
   /* Temporarily make frame's keyboard the current kboard so that
      kboard-local variables in the mode_line_format will get the right
      values.  */
-  push_frame_kboard (it.f);
+  push_kboard (FRAME_KBOARD (it.f));
   record_unwind_save_match_data ();
   display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
-  pop_frame_kboard ();
+  pop_kboard ();
 
   unbind_to (count, Qnil);
 
@@ -17341,7 +17585,9 @@ are the selected window and the window's buffer).  */)
     buffer = w->buffer;
   CHECK_BUFFER (buffer);
 
-  if (NILP (format))
+  /* Make formatting the modeline a non-op when noninteractive, otherwise
+     there will be problems later caused by a partially initialized frame.  */
+  if (NILP (format) || noninteractive)
     return empty_unibyte_string;
 
   if (no_props)
@@ -17351,7 +17597,7 @@ are the selected window and the window's buffer).  */)
     {
       if (EQ (face, Qt))
        face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
-      face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0, 0);
+      face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0);
     }
 
   if (face_id < 0)
@@ -17387,9 +17633,9 @@ are the selected window and the window's buffer).  */)
        = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
     }
 
-  push_frame_kboard (it.f);
+  push_kboard (FRAME_KBOARD (it.f));
   display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
-  pop_frame_kboard ();
+  pop_kboard ();
 
   if (no_props)
     {
@@ -17574,7 +17820,7 @@ decode_mode_spec_coding (coding_system, buf, eol_flag)
   /* The EOL conversion we are using.  */
   Lisp_Object eoltype;
 
-  val = Fget (coding_system, Qcoding_system);
+  val = CODING_SYSTEM_SPEC (coding_system);
   eoltype = Qnil;
 
   if (!VECTORP (val))          /* Not yet decided.  */
@@ -17587,12 +17833,14 @@ decode_mode_spec_coding (coding_system, buf, eol_flag)
     }
   else
     {
+      Lisp_Object attrs;
       Lisp_Object eolvalue;
 
-      eolvalue = Fget (coding_system, Qeol_type);
+      attrs = AREF (val, 0);
+      eolvalue = AREF (val, 2);
 
       if (multibyte)
-       *buf++ = XFASTINT (AREF (val, 1));
+       *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
 
       if (eol_flag)
        {
@@ -17602,10 +17850,10 @@ decode_mode_spec_coding (coding_system, buf, eol_flag)
            eoltype = eol_mnemonic_undecided;
          else if (VECTORP (eolvalue)) /* Not yet decided.  */
            eoltype = eol_mnemonic_undecided;
-         else                  /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
-           eoltype = (XFASTINT (eolvalue) == 0
+         else                  /* eolvalue is Qunix, Qdos, or Qmac.  */
+           eoltype = (EQ (eolvalue, Qunix)
                       ? eol_mnemonic_unix
-                      : (XFASTINT (eolvalue) == 1
+                      : (EQ (eolvalue, Qdos) == 1
                          ? eol_mnemonic_dos : eol_mnemonic_mac));
        }
     }
@@ -17618,8 +17866,7 @@ decode_mode_spec_coding (coding_system, buf, eol_flag)
          eol_str = SDATA (eoltype);
          eol_str_len = SBYTES (eoltype);
        }
-      else if (INTEGERP (eoltype)
-              && CHAR_VALID_P (XINT (eoltype), 0))
+      else if (CHARACTERP (eoltype))
        {
          unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
          eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
@@ -17994,7 +18241,7 @@ decode_mode_spec (w, c, field_width, precision, multibyte)
 #endif
       break;
 
-    case 'R':
+    case '@':
       {
        Lisp_Object val;
        val = call1 (intern ("file-remote-p"), current_buffer->directory);
@@ -18023,8 +18270,12 @@ decode_mode_spec (w, c, field_width, precision, multibyte)
          {
            /* No need to mention EOL here--the terminal never needs
               to do EOL conversion.  */
-           p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
-           p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
+           p = decode_mode_spec_coding (CODING_ID_NAME
+                                        (FRAME_KEYBOARD_CODING (f)->id),
+                                        p, 0);
+           p = decode_mode_spec_coding (CODING_ID_NAME
+                                        (FRAME_TERMINAL_CODING (f)->id),
+                                        p, 0);
          }
        p = decode_mode_spec_coding (b->buffer_file_coding_system,
                                     p, eol_flag);
@@ -18296,7 +18547,7 @@ display_string (string, lisp_string, face_string, face_string_pos,
                }
              break;
            }
-         else if (x + glyph->pixel_width > it->first_visible_x)
+         else if (x + glyph->pixel_width >= it->first_visible_x)
            {
              /* Glyph is at least partially visible.  */
              ++it->hpos;
@@ -18428,6 +18679,27 @@ invisible_p (propval, list)
   return 0;
 }
 
+DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
+       doc: /* Non-nil if the property makes the text invisible.
+POS-OR-PROP can be a marker or number, in which case it is taken to be
+a position in the current buffer and the value of the `invisible' property
+is checked; or it can be some other value, which is then presumed to be the
+value of the `invisible' property of the text of interest.
+The non-nil value returned can be t for truly invisible text or something
+else if the text is replaced by an ellipsis.  */)
+     (pos_or_prop)
+     Lisp_Object pos_or_prop;
+{
+  Lisp_Object prop
+    = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
+       ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
+       : pos_or_prop);
+  int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
+  return (invis == 0 ? Qnil
+         : invis == 1 ? Qt
+         : make_number (invis));
+}
+
 /* Calculate a width or height in pixels from a specification using
    the following elements:
 
@@ -18516,6 +18788,8 @@ calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
   if (NILP (prop))
     return OK_PIXELS (0);
 
+  xassert (FRAME_LIVE_P (it->f));
+
   if (SYMBOLP (prop))
     {
       if (SCHARS (SYMBOL_NAME (prop)) == 2)
@@ -18632,7 +18906,8 @@ calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
       if (SYMBOLP (car))
        {
 #ifdef HAVE_WINDOW_SYSTEM
-         if (valid_image_p (prop))
+         if (FRAME_WINDOW_P (it->f)
+             && valid_image_p (prop))
            {
              int id = lookup_image (it->f, prop);
              struct image *img = IMAGE_FROM_ID (it->f, id);
@@ -18824,6 +19099,80 @@ append_glyph_string (head, tail, s)
 }
 
 
+/* Get face and two-byte form of character C in face FACE_ID on frame
+   F.  The encoding of C is returned in *CHAR2B.  MULTIBYTE_P non-zero
+   means we want to display multibyte text.  DISPLAY_P non-zero means
+   make sure that X resources for the face returned are allocated.
+   Value is a pointer to a realized face that is ready for display if
+   DISPLAY_P is non-zero.  */
+
+static INLINE struct face *
+get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
+     struct frame *f;
+     int c, face_id;
+     XChar2b *char2b;
+     int multibyte_p, display_p;
+{
+  struct face *face = FACE_FROM_ID (f, face_id);
+
+#ifdef USE_FONT_BACKEND
+  if (enable_font_backend)
+    {
+      struct font *font = (struct font *) face->font_info;
+
+      if (font)
+       {
+         unsigned code = font->driver->encode_char (font, c);
+
+         if (code != FONT_INVALID_CODE)
+           STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
+         else
+           STORE_XCHAR2B (char2b, 0, 0);
+       }
+    }
+  else
+#endif /* USE_FONT_BACKEND */
+  if (!multibyte_p)
+    {
+      /* Unibyte case.  We don't have to encode, but we have to make
+        sure to use a face suitable for unibyte.  */
+      STORE_XCHAR2B (char2b, 0, c);
+      face_id = FACE_FOR_CHAR (f, face, c, -1, Qnil);
+      face = FACE_FROM_ID (f, face_id);
+    }
+  else if (c < 128)
+    {
+      /* Case of ASCII in a face known to fit ASCII.  */
+      STORE_XCHAR2B (char2b, 0, c);
+    }
+  else if (face->font != NULL)
+    {
+      struct font_info *font_info
+       = FONT_INFO_FROM_ID (f, face->font_info_id);
+      struct charset *charset = CHARSET_FROM_ID (font_info->charset);
+      unsigned code = ENCODE_CHAR (charset, c);
+
+      if (CHARSET_DIMENSION (charset) == 1)
+       STORE_XCHAR2B (char2b, 0, code);
+      else
+       STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
+       /* Maybe encode the character in *CHAR2B.  */
+      FRAME_RIF (f)->encode_char (c, char2b, font_info, charset, NULL);
+    }
+
+  /* Make sure X resources of the face are allocated.  */
+#ifdef HAVE_X_WINDOWS
+  if (display_p)
+#endif
+    {
+      xassert (face != NULL);
+      PREPARE_FACE_FOR_DISPLAY (f, face);
+    }
+
+  return face;
+}
+
+
 /* Get face and two-byte form of character glyph GLYPH on frame F.
    The encoding of GLYPH->u.ch is returned in *CHAR2B.  Value is
    a pointer to a realized face that is ready for display.  */
@@ -18843,6 +19192,23 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
   if (two_byte_p)
     *two_byte_p = 0;
 
+#ifdef USE_FONT_BACKEND
+  if (enable_font_backend)
+    {
+      struct font *font = (struct font *) face->font_info;
+
+      if (font)
+       {
+         unsigned code = font->driver->encode_char (font, glyph->u.ch);
+
+         if (code != FONT_INVALID_CODE)
+           STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
+         else
+           STORE_XCHAR2B (char2b, 0, code);
+       }
+    }
+  else
+#endif /* USE_FONT_BACKEND */
   if (!glyph->multibyte_p)
     {
       /* Unibyte case.  We don't have to encode, but we have to make
@@ -18856,24 +19222,25 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
     }
   else
     {
-      int c1, c2, charset;
+      struct font_info *font_info
+       = FONT_INFO_FROM_ID (f, face->font_info_id);
+      if (font_info)
+       {
+         struct charset *charset = CHARSET_FROM_ID (font_info->charset);
+         unsigned code = ENCODE_CHAR (charset, glyph->u.ch);
 
-      /* Split characters into bytes.  If c2 is -1 afterwards, C is
-        really a one-byte character so that byte1 is zero.  */
-      SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
-      if (c2 > 0)
-       STORE_XCHAR2B (char2b, c1, c2);
-      else
-       STORE_XCHAR2B (char2b, 0, c1);
+         if (CHARSET_DIMENSION (charset) == 1)
+           STORE_XCHAR2B (char2b, 0, code);
+         else
+           STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
 
-      /* Maybe encode the character in *CHAR2B.  */
-      if (charset != CHARSET_ASCII)
-       {
-         struct font_info *font_info
-           = FONT_INFO_FROM_ID (f, face->font_info_id);
-         if (font_info)
-           glyph->font_type
-             = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
+         /* Maybe encode the character in *CHAR2B.  */
+         if (CHARSET_ID (charset) != charset_ascii)
+           {
+             glyph->font_type
+               = FRAME_RIF (f)->encode_char (glyph->u.ch, char2b, font_info,
+                                             charset, two_byte_p);
+           }
        }
     }
 
@@ -18886,7 +19253,7 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
 
 /* Fill glyph string S with composition components specified by S->cmp.
 
-   FACES is an array of faces for all components of this composition.
+   BASE_FACE is the base face of the composition.
    S->gidx is the index of the first component for S.
 
    OVERLAPS non-zero means S should draw the foreground only, and use
@@ -18895,9 +19262,9 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
    Value is the index of a component not in S.  */
 
 static int
-fill_composite_glyph_string (s, faces, overlaps)
+fill_composite_glyph_string (s, base_face, overlaps)
      struct glyph_string *s;
-     struct face **faces;
+     struct face *base_face;
      int overlaps;
 {
   int i;
@@ -18906,21 +19273,69 @@ fill_composite_glyph_string (s, faces, overlaps)
 
   s->for_overlaps = overlaps;
 
-  s->face = faces[s->gidx];
-  s->font = s->face->font;
-  s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
+#ifdef USE_FONT_BACKEND
+  if (enable_font_backend && 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_info = s->cmp->font;
+      s->font = s->font_info->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
+#endif /* USE_FONT_BACKEND */
+    {
+      /* 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;
 
-  /* 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.  */
-  ++s->nchars;
-  for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
-    ++s->nchars;
+      s->face = NULL;
+      s->font = NULL;
+      s->font_info = NULL;
+      for (i = s->gidx; i < s->cmp->glyph_len; i++)
+       {
+         int c = COMPOSITION_GLYPH (s->cmp, i);
 
-  /* All glyph strings for the same composition has the same width,
-     i.e. the width set for the first component of the composition.  */
+         if (c != '\t')
+           {
+             int face_id = FACE_FOR_CHAR (s->f, base_face, c, -1, Qnil);
 
-  s->width = s->first_glyph->pixel_width;
+             face = get_char_face_and_encoding (s->f, c, face_id,
+                                                s->char2b + i, 1, 1);
+             if (face)
+               {
+                 if (! s->face)
+                   {
+                     s->face = face;
+                     s->font = s->face->font;
+                     s->font_info = FONT_INFO_FROM_FACE (s->f, s->face);
+                   }
+                 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;
+    }
 
   /* 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
@@ -18935,8 +19350,6 @@ fill_composite_glyph_string (s, faces, overlaps)
   /* Adjust base line for subscript/superscript text.  */
   s->ybase += s->first_glyph->voffset;
 
-  xassert (s->face && s->face->gc);
-
   /* This glyph string must always be drawn with 16-bit functions.  */
   s->two_byte_p = 1;
 
@@ -18994,7 +19407,7 @@ fill_glyph_string (s, face_id, start, end, overlaps)
     }
 
   s->font = s->face->font;
-  s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
+  s->font_info = FONT_INFO_FROM_FACE (s->f, s->face);
 
   /* If the specified font could not be loaded, use the frame's font,
      but record the fact that we couldn't load it in
@@ -19058,7 +19471,7 @@ fill_stretch_glyph_string (s, row, area, start, end)
   face_id = glyph->face_id;
   s->face = FACE_FROM_ID (s->f, face_id);
   s->font = s->face->font;
-  s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
+  s->font_info = FONT_INFO_FROM_FACE (s->f, s->face);
   s->width = glyph->pixel_width;
   s->nchars = 1;
   voffset = glyph->voffset;
@@ -19080,6 +19493,36 @@ fill_stretch_glyph_string (s, row, area, start, end)
   return glyph - s->row->glyphs[s->area];
 }
 
+static XCharStruct *
+get_per_char_metric (f, font, font_info, char2b, font_type)
+     struct frame *f;
+     XFontStruct *font;
+     struct font_info *font_info;
+     XChar2b *char2b;
+     int font_type;
+{
+#ifdef USE_FONT_BACKEND
+  if (enable_font_backend)
+    {
+      static XCharStruct pcm_value;
+      unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
+      struct font *fontp;
+      struct font_metrics metrics;
+
+      if (! font_info || code == FONT_INVALID_CODE)
+       return NULL;
+      fontp = (struct font *) font_info;
+      fontp->driver->text_extents (fontp, &code, 1, &metrics);
+      pcm_value.lbearing = metrics.lbearing;
+      pcm_value.rbearing = metrics.rbearing;
+      pcm_value.ascent = metrics.ascent;
+      pcm_value.descent = metrics.descent;
+      pcm_value.width = metrics.width;
+      return &pcm_value;
+    }
+#endif /* USE_FONT_BACKEND */
+  return FRAME_RIF (f)->per_char_metric (font, char2b, font_type);
+}
 
 /* EXPORT for RIF:
    Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
@@ -19104,9 +19547,9 @@ x_get_glyph_overhangs (glyph, f, left, right)
 
       face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
       font = face->font;
-      font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
+      font_info = FONT_INFO_FROM_FACE (f, face);
       if (font  /* ++KFS: Should this be font_info ?  */
-         && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
+         && (pcm = get_per_char_metric (f, font, font_info, &char2b, glyph->font_type)))
        {
          if (pcm->rbearing > pcm->width)
            *right = pcm->rbearing - pcm->width;
@@ -19114,6 +19557,13 @@ x_get_glyph_overhangs (glyph, f, left, right)
            *left = -pcm->lbearing;
        }
     }
+  else if (glyph->type == COMPOSITE_GLYPH)
+    {
+      struct composition *cmp = composition_table[glyph->u.cmp_id];
+
+      *right = cmp->rbearing - cmp->pixel_width;
+      *left = - cmp->lbearing;
+    }
 }
 
 
@@ -19227,70 +19677,6 @@ right_overwriting (s)
 }
 
 
-/* Get face and two-byte form of character C in face FACE_ID on frame
-   F.  The encoding of C is returned in *CHAR2B.  MULTIBYTE_P non-zero
-   means we want to display multibyte text.  DISPLAY_P non-zero means
-   make sure that X resources for the face returned are allocated.
-   Value is a pointer to a realized face that is ready for display if
-   DISPLAY_P is non-zero.  */
-
-static INLINE struct face *
-get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
-     struct frame *f;
-     int c, face_id;
-     XChar2b *char2b;
-     int multibyte_p, display_p;
-{
-  struct face *face = FACE_FROM_ID (f, face_id);
-
-  if (!multibyte_p)
-    {
-      /* Unibyte case.  We don't have to encode, but we have to make
-        sure to use a face suitable for unibyte.  */
-      STORE_XCHAR2B (char2b, 0, c);
-      face_id = FACE_FOR_CHAR (f, face, c);
-      face = FACE_FROM_ID (f, face_id);
-    }
-  else if (c < 128)
-    {
-      /* Case of ASCII in a face known to fit ASCII.  */
-      STORE_XCHAR2B (char2b, 0, c);
-    }
-  else
-    {
-      int c1, c2, charset;
-
-      /* Split characters into bytes.  If c2 is -1 afterwards, C is
-        really a one-byte character so that byte1 is zero.  */
-      SPLIT_CHAR (c, charset, c1, c2);
-      if (c2 > 0)
-       STORE_XCHAR2B (char2b, c1, c2);
-      else
-       STORE_XCHAR2B (char2b, 0, c1);
-
-      /* Maybe encode the character in *CHAR2B.  */
-      if (face->font != NULL)
-       {
-         struct font_info *font_info
-           = FONT_INFO_FROM_ID (f, face->font_info_id);
-         if (font_info)
-           rif->encode_char (c, char2b, font_info, 0);
-       }
-    }
-
-  /* Make sure X resources of the face are allocated.  */
-#ifdef HAVE_X_WINDOWS
-  if (display_p)
-#endif
-    {
-      xassert (face != NULL);
-      PREPARE_FACE_FOR_DISPLAY (f, face);
-    }
-
-  return face;
-}
-
-
 /* Set background width of glyph string S.  START is the index of the
    first glyph following S.  LAST_X is the right-most x-position + 1
    in the drawing area.  */
@@ -19337,8 +19723,8 @@ compute_overhangs_and_x (s, x, backward_p)
     {
       while (s)
        {
-         if (rif->compute_glyph_string_overhangs)
-           rif->compute_glyph_string_overhangs (s);
+         if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
+           FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
          x -= s->width;
          s->x = x;
          s = s->prev;
@@ -19348,8 +19734,8 @@ compute_overhangs_and_x (s, x, backward_p)
     {
       while (s)
        {
-         if (rif->compute_glyph_string_overhangs)
-           rif->compute_glyph_string_overhangs (s);
+         if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
+           FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
          s->x = x;
          x += s->width;
          s = s->next;
@@ -19430,10 +19816,9 @@ compute_overhangs_and_x (s, x, backward_p)
 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X)           \
      do                                                                           \
        {                                                                  \
-        int c, face_id;                                                   \
+        int face_id;                                                      \
         XChar2b *char2b;                                                  \
                                                                           \
-        c = (row)->glyphs[area][START].u.ch;                              \
         face_id = (row)->glyphs[area][START].face_id;                     \
                                                                           \
         s = (struct glyph_string *) alloca (sizeof *s);                   \
@@ -19456,49 +19841,35 @@ compute_overhangs_and_x (s, x, backward_p)
    x-position of the drawing area.  */
 
 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
-  do {                                                                   \
-    int cmp_id = (row)->glyphs[area][START].u.cmp_id;                    \
-    int face_id = (row)->glyphs[area][START].face_id;                    \
-    struct face *base_face = FACE_FROM_ID (f, face_id);                          \
-    struct composition *cmp = composition_table[cmp_id];                 \
-    int glyph_len = cmp->glyph_len;                                      \
-    XChar2b *char2b;                                                     \
-    struct face **faces;                                                 \
-    struct glyph_string *first_s = NULL;                                 \
-    int n;                                                               \
-                                                                         \
-    base_face = base_face->ascii_face;                                   \
-    char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len);                  \
-    faces = (struct face **) alloca ((sizeof *faces) * glyph_len);       \
-    /* At first, fill in `char2b' and `faces'.  */                       \
-    for (n = 0; n < glyph_len; n++)                                      \
-      {                                                                          \
-       int c = COMPOSITION_GLYPH (cmp, n);                               \
-       int this_face_id = FACE_FOR_CHAR (f, base_face, c);               \
-       faces[n] = FACE_FROM_ID (f, this_face_id);                        \
-       get_char_face_and_encoding (f, c, this_face_id,                   \
-                                   char2b + n, 1, 1);                    \
-      }                                                                          \
-                                                                         \
-    /* Make glyph_strings for each glyph sequence that is drawable by    \
-       the same face, and append them to HEAD/TAIL.  */                          \
-    for (n = 0; n < cmp->glyph_len;)                                     \
-      {                                                                          \
-       s = (struct glyph_string *) alloca (sizeof *s);                   \
-       INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL);       \
-       append_glyph_string (&(HEAD), &(TAIL), s);                        \
-       s->cmp = cmp;                                                     \
-       s->gidx = n;                                                      \
-       s->x = (X);                                                       \
-                                                                         \
-       if (n == 0)                                                       \
-         first_s = s;                                                    \
-                                                                         \
-       n = fill_composite_glyph_string (s, faces, overlaps);             \
-      }                                                                          \
-                                                                         \
-    ++START;                                                             \
-    s = first_s;                                                         \
+  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;                      \
+    struct composition *cmp = composition_table[cmp_id];                   \
+    XChar2b *char2b;                                                       \
+    struct glyph_string *first_s;                                          \
+    int n;                                                                 \
+                                                                           \
+    char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len);       \
+    base_face = base_face->ascii_face;                                     \
+                                                                           \
+    /* Make glyph_strings for each glyph sequence that is drawable by      \
+       the same face, and append them to HEAD/TAIL.  */                            \
+    for (n = 0; n < cmp->glyph_len;)                                       \
+      {                                                                            \
+       s = (struct glyph_string *) alloca (sizeof *s);                     \
+       INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL);             \
+       append_glyph_string (&(HEAD), &(TAIL), s);                          \
+       s->cmp = cmp;                                                       \
+       s->gidx = n;                                                        \
+       s->x = (X);                                                         \
+       if (n == 0)                                                         \
+         first_s = s;                                                      \
+       n = fill_composite_glyph_string (s, base_face, overlaps);           \
+      }                                                                            \
+                                                                           \
+    ++START;                                                               \
+    s = first_s;                                                           \
   } while (0)
 
 
@@ -19545,8 +19916,11 @@ compute_overhangs_and_x (s, x, backward_p)
                 abort ();                                                 \
               }                                                           \
                                                                           \
-             set_glyph_string_background_width (s, START, LAST_X);        \
-            (X) += s->width;                                              \
+            if (s)                                                        \
+              {                                                           \
+                set_glyph_string_background_width (s, START, LAST_X);     \
+                (X) += s->width;                                          \
+              }                                                           \
             }                                                             \
        }                                                                  \
      while (0)
@@ -19580,7 +19954,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps)
      int x;
      struct glyph_row *row;
      enum glyph_row_area area;
-     int start, end;
+     EMACS_INT start, end;
      enum draw_glyphs_face hl;
      int overlaps;
 {
@@ -19637,9 +20011,9 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps)
       struct glyph_string *h, *t;
 
       /* Compute overhangs for all glyph strings.  */
-      if (rif->compute_glyph_string_overhangs)
+      if (FRAME_RIF (f)->compute_glyph_string_overhangs)
        for (s = head; s; s = s->next)
-         rif->compute_glyph_string_overhangs (s);
+         FRAME_RIF (f)->compute_glyph_string_overhangs (s);
 
       /* Prepend glyph strings for glyphs in front of the first glyph
         string that are overwritten because of the first glyph
@@ -19700,6 +20074,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps)
       if (i >= 0)
        {
          clip_tail = tail;
+         i++;                  /* We must include the Ith glyph.  */
          BUILD_GLYPH_STRINGS (end, i, h, t,
                               DRAW_NORMAL_TEXT, x, last_x);
          for (s = h; s; s = s->next)
@@ -19717,7 +20092,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps)
 
   /* Draw all strings.  */
   for (s = head; s; s = s->next)
-    rif->draw_glyph_string (s);
+    FRAME_RIF (f)->draw_glyph_string (s);
 
   if (area == TEXT_AREA
       && !row->full_width_p
@@ -19976,9 +20351,9 @@ produce_image_glyph (it)
        }
 
       if (it->start_of_box_run_p && slice.x == 0)
-       it->pixel_width += abs (face->box_line_width);
+       it->pixel_width += eabs (face->box_line_width);
       if (it->end_of_box_run_p && slice.x + slice.width == img->width)
-       it->pixel_width += abs (face->box_line_width);
+       it->pixel_width += eabs (face->box_line_width);
     }
 
   take_vertical_position_into_account (it);
@@ -20289,7 +20664,7 @@ calc_line_height_property (it, val, font, boff, override)
       struct face *face;
       struct font_info *font_info;
 
-      face_id = lookup_named_face (it->f, face_name, ' ', 0);
+      face_id = lookup_named_face (it->f, face_name, 0);
       if (face_id < 0)
        return make_number (-1);
 
@@ -20298,7 +20673,7 @@ calc_line_height_property (it, val, font, boff, override)
       if (font == NULL)
        return make_number (-1);
 
-      font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
+      font_info = FONT_INFO_FROM_FACE (it->f, face);
       boff = font_info->baseline_offset;
       if (font_info->vertical_centering)
        boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
@@ -20362,23 +20737,17 @@ x_produce_glyphs (it)
       /* Maybe translate single-byte characters to multibyte, or the
         other way.  */
       it->char_to_display = it->c;
-      if (!ASCII_BYTE_P (it->c))
+      if (!ASCII_BYTE_P (it->c)
+         && ! it->multibyte_p)
        {
-         if (unibyte_display_via_language_environment
-             && SINGLE_BYTE_CHAR_P (it->c)
-             && (it->c >= 0240
-                 || !NILP (Vnonascii_translation_table)))
+         if (SINGLE_BYTE_CHAR_P (it->c)
+             && unibyte_display_via_language_environment)
+           it->char_to_display = unibyte_char_to_multibyte (it->c);
+         if (! SINGLE_BYTE_CHAR_P (it->char_to_display))
            {
-             it->char_to_display = unibyte_char_to_multibyte (it->c);
              it->multibyte_p = 1;
-             it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
-             face = FACE_FROM_ID (it->f, it->face_id);
-           }
-         else if (!SINGLE_BYTE_CHAR_P (it->c)
-                  && !it->multibyte_p)
-           {
-             it->multibyte_p = 1;
-             it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
+             it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
+                                          -1, Qnil);
              face = FACE_FROM_ID (it->f, it->face_id);
            }
        }
@@ -20398,7 +20767,7 @@ x_produce_glyphs (it)
        }
       else
        {
-         font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
+         font_info = FONT_INFO_FROM_FACE (it->f, face);
          boff = font_info->baseline_offset;
          if (font_info->vertical_centering)
            boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
@@ -20412,20 +20781,20 @@ x_produce_glyphs (it)
 
          it->nglyphs = 1;
 
-         pcm = rif->per_char_metric (font, &char2b,
-                                     FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
-
-         if (it->override_ascent >= 0)
-           {
-             it->ascent = it->override_ascent;
-             it->descent = it->override_descent;
-             boff = it->override_boff;
-           }
-         else
-           {
-             it->ascent = FONT_BASE (font) + boff;
-             it->descent = FONT_DESCENT (font) - boff;
-           }
+         pcm = get_per_char_metric (it->f, font, font_info, &char2b,
+                                    FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
+
+         if (it->override_ascent >= 0)
+           {
+             it->ascent = it->override_ascent;
+             it->descent = it->override_descent;
+             boff = it->override_boff;
+           }
+         else
+           {
+             it->ascent = FONT_BASE (font) + boff;
+             it->descent = FONT_DESCENT (font) - boff;
+           }
 
          if (pcm)
            {
@@ -20639,20 +21008,24 @@ x_produce_glyphs (it)
 
          /* If we found a font, this font should give us the right
             metrics.  If we didn't find a font, use the frame's
-            default font and calculate the width of the character
-            from the charset width; this is what old redisplay code
-            did.  */
+            default font and calculate the width of the character by
+            multiplying the width of font by the width of the
+            character.  */
 
-         pcm = rif->per_char_metric (font, &char2b,
-                                     FONT_TYPE_FOR_MULTIBYTE (font, it->c));
+           pcm = get_per_char_metric (it->f, font, font_info, &char2b,
+                                      FONT_TYPE_FOR_MULTIBYTE (font, it->c));
 
          if (font_not_found_p || !pcm)
            {
-             int charset = CHAR_CHARSET (it->char_to_display);
+             int char_width = CHAR_WIDTH (it->char_to_display);
 
+             if (char_width == 0)
+               /* This is a non spacing character.  But, as we are
+                  going to display an empty box, the box must occupy
+                  at least one column.  */
+               char_width = 1;
              it->glyph_not_available_p = 1;
-             it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
-                                * CHARSET_WIDTH (charset));
+             it->pixel_width = FRAME_COLUMN_WIDTH (it->f) * char_width;
              it->phys_ascent = FONT_BASE (font) + boff;
              it->phys_descent = FONT_DESCENT (font) - boff;
            }
@@ -20702,99 +21075,120 @@ x_produce_glyphs (it)
   else if (it->what == IT_COMPOSITION)
     {
       /* Note: A composition is represented as one glyph in the
-        glyph matrix.  There are no padding glyphs.  */
-      XChar2b char2b;
-      XFontStruct *font;
+        glyph matrix.  There are no padding glyphs.
+
+        Important is that pixel_width, ascent, and descent are the
+        values of what is drawn by draw_glyphs (i.e. the values of
+        the overall glyphs composed).  */
       struct face *face = FACE_FROM_ID (it->f, it->face_id);
-      XCharStruct *pcm;
-      int font_not_found_p;
-      struct font_info *font_info;
       int boff;                        /* baseline offset */
       struct composition *cmp = composition_table[it->cmp_id];
+      int glyph_len = cmp->glyph_len;
+      XFontStruct *font = face->font;
 
-      /* Maybe translate single-byte characters to multibyte.  */
-      it->char_to_display = it->c;
-      if (unibyte_display_via_language_environment
-         && SINGLE_BYTE_CHAR_P (it->c)
-         && (it->c >= 0240
-             || (it->c >= 0200
-                 && !NILP (Vnonascii_translation_table))))
-       {
-         it->char_to_display = unibyte_char_to_multibyte (it->c);
-       }
-
-      /* Get face and font to use.  Encode IT->char_to_display.  */
-      it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
-      face = FACE_FROM_ID (it->f, it->face_id);
-      get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
-                                 &char2b, it->multibyte_p, 0);
-      font = face->font;
+      it->nglyphs = 1;
 
-      /* When no suitable font found, use the default font.  */
-      font_not_found_p = font == NULL;
-      if (font_not_found_p)
+#ifdef USE_FONT_BACKEND
+      if (cmp->method == COMPOSITION_WITH_GLYPH_STRING)
        {
-         font = FRAME_FONT (it->f);
-         boff = FRAME_BASELINE_OFFSET (it->f);
-         font_info = NULL;
+         if (! cmp->font || cmp->font != font)
+           font_prepare_composition (cmp, it->f);
        }
       else
-       {
-         font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
-         boff = font_info->baseline_offset;
-         if (font_info->vertical_centering)
-           boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
-       }
-
-      /* There are no padding glyphs, so there is only one glyph to
-        produce for the composition.  Important is that pixel_width,
-        ascent and descent are the values of what is drawn by
-        draw_glyphs (i.e. the values of the overall glyphs composed).  */
-      it->nglyphs = 1;
-
+#endif /* USE_FONT_BACKEND */
       /* 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
         glyphs, but that requires much time and memory space.  So,
         here we check only the font of the first glyph.  This leads
-        to incorrect display very rarely, and C-l (recenter) can
-        correct the display anyway.  */
-      if (cmp->font != (void *) font)
-       {
-         /* Ascent and descent of the font of the first character of
-            this composition (adjusted by baseline offset).  Ascent
-            and descent of overall glyphs should not be less than
-            them respectively.  */
-         int font_ascent = FONT_BASE (font) + boff;
-         int font_descent = FONT_DESCENT (font) - boff;
+        to incorrect display, but it's very rare, and C-l (recenter)
+        can correct the display anyway.  */
+      if (! cmp->font || cmp->font != font)
+       {
+         /* Ascent and descent of the font of the first character
+            of this composition (adjusted by baseline offset).
+            Ascent and descent of overall glyphs should not be less
+            than them respectively.  */
+         int font_ascent, font_descent, font_height;
          /* Bounding box of the overall glyphs.  */
          int leftmost, rightmost, lowest, highest;
+         int lbearing, rbearing;
          int i, width, ascent, descent;
+         int left_padded = 0, right_padded = 0;
+         int face_id;
+         int c;
+         XChar2b char2b;
+         XCharStruct *pcm;
+         int font_not_found_p;
+         struct font_info *font_info;
+         int pos;
+
+         for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
+           if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
+             break;
+         if (glyph_len < cmp->glyph_len)
+           right_padded = 1;
+         for (i = 0; i < glyph_len; i++)
+           {
+             if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
+               break;
+             cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
+           }
+         if (i > 0)
+           left_padded = 1;
+
+         pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
+                : IT_CHARPOS (*it));
+         /* When no suitable font found, use the default font.  */
+         font_not_found_p = font == NULL;
+         if (font_not_found_p)
+           {
+             face = face->ascii_face;
+             font = face->font;
+           }
+         font_info = FONT_INFO_FROM_FACE (it->f, face);
+         boff = font_info->baseline_offset;
+         if (font_info->vertical_centering)
+           boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
+         font_ascent = FONT_BASE (font) + boff;
+         font_descent = FONT_DESCENT (font) - boff;
+         font_height = FONT_HEIGHT (font);
 
          cmp->font = (void *) font;
 
+         pcm = NULL;
+         if (! font_not_found_p)
+           {
+             get_char_face_and_encoding (it->f, c, it->face_id,
+                                         &char2b, it->multibyte_p, 0);
+             pcm = get_per_char_metric (it->f, font, font_info, &char2b,
+                                        FONT_TYPE_FOR_MULTIBYTE (font, c));
+           }
+
          /* Initialize the bounding box.  */
-         if (font_info
-             && (pcm = rif->per_char_metric (font, &char2b,
-                                             FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
+         if (pcm)
            {
              width = pcm->width;
              ascent = pcm->ascent;
              descent = pcm->descent;
+             lbearing = pcm->lbearing;
+             rbearing = pcm->rbearing;
            }
          else
            {
              width = FONT_WIDTH (font);
              ascent = FONT_BASE (font);
              descent = FONT_DESCENT (font);
+             lbearing = 0;
+             rbearing = width;
            }
 
          rightmost = width;
+         leftmost = 0;
          lowest = - descent + boff;
          highest = ascent + boff;
-         leftmost = 0;
 
-         if (font_info
+         if (! font_not_found_p
              && font_info->default_ascent
              && CHAR_TABLE_P (Vuse_default_ascent)
              && !NILP (Faref (Vuse_default_ascent,
@@ -20802,123 +21196,138 @@ x_produce_glyphs (it)
            highest = font_info->default_ascent + boff;
 
          /* Draw the first glyph at the normal position.  It may be
-            shifted to right later if some other glyphs are drawn at
-            the left.  */
-         cmp->offsets[0] = 0;
-         cmp->offsets[1] = boff;
+            shifted to right later if some other glyphs are drawn
+            at the left.  */
+         cmp->offsets[i * 2] = 0;
+         cmp->offsets[i * 2 + 1] = boff;
+         cmp->lbearing = lbearing;
+         cmp->rbearing = rbearing;
 
          /* Set cmp->offsets for the remaining glyphs.  */
-         for (i = 1; i < cmp->glyph_len; i++)
+         for (i++; i < glyph_len; i++)
            {
              int left, right, btm, top;
              int ch = COMPOSITION_GLYPH (cmp, i);
-             int face_id = FACE_FOR_CHAR (it->f, face, ch);
+             int face_id;
+             struct face *this_face;
+             int this_boff;
+
+             if (ch == '\t')
+               ch = ' ';
+             face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
+             this_face = FACE_FROM_ID (it->f, face_id);
+             font = this_face->font;
 
-             face = FACE_FROM_ID (it->f, face_id);
-             get_char_face_and_encoding (it->f, ch, face->id,
-                                         &char2b, it->multibyte_p, 0);
-             font = face->font;
              if (font == NULL)
-               {
-                 font = FRAME_FONT (it->f);
-                 boff = FRAME_BASELINE_OFFSET (it->f);
-                 font_info = NULL;
-               }
+               pcm = NULL;
              else
                {
-                 font_info
-                   = FONT_INFO_FROM_ID (it->f, face->font_info_id);
-                 boff = font_info->baseline_offset;
+                 font_info = FONT_INFO_FROM_FACE (it->f, this_face);
+                 this_boff = font_info->baseline_offset;
                  if (font_info->vertical_centering)
-                   boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
+                   this_boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
+                 get_char_face_and_encoding (it->f, ch, face_id,
+                                             &char2b, it->multibyte_p, 0);
+                 pcm = get_per_char_metric (it->f, font, font_info, &char2b,
+                                            FONT_TYPE_FOR_MULTIBYTE (font,
+                                                                     ch));
                }
-
-             if (font_info
-                 && (pcm = rif->per_char_metric (font, &char2b,
-                                                 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
+             if (! pcm)
+               cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
+             else
                {
                  width = pcm->width;
                  ascent = pcm->ascent;
                  descent = pcm->descent;
-               }
-             else
-               {
-                 width = FONT_WIDTH (font);
-                 ascent = 1;
-                 descent = 0;
-               }
+                 lbearing = pcm->lbearing;
+                 rbearing = pcm->rbearing;
+                 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
+                   {
+                     /* Relative composition with or without
+                        alternate chars.  */
+                     left = (leftmost + rightmost - width) / 2;
+                     btm = - descent + boff;
+                     if (font_info->relative_compose
+                         && (! CHAR_TABLE_P (Vignore_relative_composition)
+                             || NILP (Faref (Vignore_relative_composition,
+                                             make_number (ch)))))
+                       {
 
-             if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
-               {
-                 /* Relative composition with or without
-                    alternate chars.  */
-                 left = (leftmost + rightmost - width) / 2;
-                 btm = - descent + boff;
-                 if (font_info && font_info->relative_compose
-                     && (! CHAR_TABLE_P (Vignore_relative_composition)
-                         || NILP (Faref (Vignore_relative_composition,
-                                         make_number (ch)))))
+                         if (- descent >= font_info->relative_compose)
+                           /* One extra pixel between two glyphs.  */
+                           btm = highest + 1;
+                         else if (ascent <= 0)
+                           /* One extra pixel between two glyphs.  */
+                           btm = lowest - 1 - ascent - descent;
+                       }
+                   }
+                 else
                    {
+                     /* A composition rule is specified by an integer
+                        value that encodes global and new reference
+                        points (GREF and NREF).  GREF and NREF are
+                        specified by numbers as below:
+
+                        0---1---2 -- ascent
+                        |       |
+                        |       |
+                        |       |
+                        9--10--11 -- center
+                        |       |
+                        ---3---4---5--- baseline
+                        |       |
+                        6---7---8 -- descent
+                     */
+                     int rule = COMPOSITION_RULE (cmp, i);
+                     int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
+
+                     COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
+                     grefx = gref % 3, nrefx = nref % 3;
+                     grefy = gref / 3, nrefy = nref / 3;
+                     if (xoff)
+                       xoff = font_height * (xoff - 128) / 256;
+                     if (yoff)
+                       yoff = font_height * (yoff - 128) / 256;
+
+                     left = (leftmost
+                             + grefx * (rightmost - leftmost) / 2
+                             - nrefx * width / 2
+                             + xoff);
+                 
+                     btm = ((grefy == 0 ? highest
+                             : grefy == 1 ? 0
+                             : grefy == 2 ? lowest
+                             : (highest + lowest) / 2)
+                            - (nrefy == 0 ? ascent + descent
+                               : nrefy == 1 ? descent - boff
+                               : nrefy == 2 ? 0
+                               : (ascent + descent) / 2)
+                            + yoff);
+                   }
+
+                 cmp->offsets[i * 2] = left;
+                 cmp->offsets[i * 2 + 1] = btm + descent;
 
-                     if (- descent >= font_info->relative_compose)
-                       /* One extra pixel between two glyphs.  */
-                       btm = highest + 1;
-                     else if (ascent <= 0)
-                       /* One extra pixel between two glyphs.  */
-                       btm = lowest - 1 - ascent - descent;
+                 /* Update the bounding box of the overall glyphs. */
+                 if (width > 0)
+                   {
+                     right = left + width;
+                     if (left < leftmost)
+                       leftmost = left;
+                     if (right > rightmost)
+                       rightmost = right;
                    }
+                 top = btm + descent + ascent;
+                 if (top > highest)
+                   highest = top;
+                 if (btm < lowest)
+                   lowest = btm;
+
+                 if (cmp->lbearing > left + lbearing)
+                   cmp->lbearing = left + lbearing;
+                 if (cmp->rbearing < left + rbearing)
+                   cmp->rbearing = left + rbearing;
                }
-             else
-               {
-                 /* A composition rule is specified by an integer
-                    value that encodes global and new reference
-                    points (GREF and NREF).  GREF and NREF are
-                    specified by numbers as below:
-
-                       0---1---2 -- ascent
-                       |       |
-                       |       |
-                       |       |
-                       9--10--11 -- center
-                       |       |
-                    ---3---4---5--- baseline
-                       |       |
-                       6---7---8 -- descent
-                 */
-                 int rule = COMPOSITION_RULE (cmp, i);
-                 int gref, nref, grefx, grefy, nrefx, nrefy;
-
-                 COMPOSITION_DECODE_RULE (rule, gref, nref);
-                 grefx = gref % 3, nrefx = nref % 3;
-                 grefy = gref / 3, nrefy = nref / 3;
-
-                 left = (leftmost
-                         + grefx * (rightmost - leftmost) / 2
-                         - nrefx * width / 2);
-                 btm = ((grefy == 0 ? highest
-                         : grefy == 1 ? 0
-                         : grefy == 2 ? lowest
-                         : (highest + lowest) / 2)
-                        - (nrefy == 0 ? ascent + descent
-                           : nrefy == 1 ? descent - boff
-                           : nrefy == 2 ? 0
-                           : (ascent + descent) / 2));
-               }
-
-             cmp->offsets[i * 2] = left;
-             cmp->offsets[i * 2 + 1] = btm + descent;
-
-             /* Update the bounding box of the overall glyphs. */
-             right = left + width;
-             top = btm + descent + ascent;
-             if (left < leftmost)
-               leftmost = left;
-             if (right > rightmost)
-               rightmost = right;
-             if (top > highest)
-               highest = top;
-             if (btm < lowest)
-               lowest = btm;
            }
 
          /* If there are glyphs whose x-offsets are negative,
@@ -20929,6 +21338,21 @@ x_produce_glyphs (it)
              for (i = 0; i < cmp->glyph_len; i++)
                cmp->offsets[i * 2] -= leftmost;
              rightmost -= leftmost;
+             cmp->lbearing -= leftmost;
+             cmp->rbearing -= leftmost;
+           }
+
+         if (left_padded && cmp->lbearing < 0)
+           {
+             for (i = 0; i < cmp->glyph_len; i++)
+               cmp->offsets[i * 2] -= cmp->lbearing;
+             rightmost -= cmp->lbearing;
+             cmp->rbearing -= cmp->lbearing;
+             cmp->lbearing = 0;
+           }
+         if (right_padded && rightmost < cmp->rbearing)
+           {
+             rightmost = cmp->rbearing;
            }
 
          cmp->pixel_width = rightmost;
@@ -20940,6 +21364,11 @@ x_produce_glyphs (it)
            cmp->descent = font_descent;
        }
 
+      if (it->glyph_row
+         && (cmp->lbearing < 0
+             || cmp->rbearing > cmp->pixel_width))
+       it->glyph_row->contains_overlapping_glyphs_p = 1;
+
       it->pixel_width = cmp->pixel_width;
       it->ascent = it->phys_ascent = cmp->ascent;
       it->descent = it->phys_descent = cmp->descent;
@@ -21050,7 +21479,8 @@ x_insert_glyphs (start, len)
   int line_height, shift_by_width, shifted_region_width;
   struct glyph_row *row;
   struct glyph *glyph;
-  int frame_x, frame_y, hpos;
+  int frame_x, frame_y;
+  EMACS_INT hpos;
 
   xassert (updated_window && updated_row);
   BLOCK_INPUT;
@@ -21075,8 +21505,8 @@ x_insert_glyphs (start, len)
   frame_x = window_box_left (w, updated_area) + output_cursor.x;
   frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
 
-  rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
-                               line_height, shift_by_width);
+  FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
+                                          line_height, shift_by_width);
 
   /* Write the glyphs.  */
   hpos = start - row->glyphs[updated_area];
@@ -21158,8 +21588,8 @@ x_clear_end_of_line (to_x)
   if (to_x > from_x && to_y > from_y)
     {
       BLOCK_INPUT;
-      rif->clear_frame_area (f, from_x, from_y,
-                            to_x - from_x, to_y - from_y);
+      FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
+                                       to_x - from_x, to_y - from_y);
       UNBLOCK_INPUT;
     }
 }
@@ -21302,7 +21732,7 @@ get_window_cursor_type (w, glyph, width, active_cursor)
       non_selected = 1;
     }
 
-  /* Nonselected window or nonselected frame.  */
+  /* Detect a nonselected window or nonselected frame.  */
   else if (w != XWINDOW (f->selected_window)
 #ifdef HAVE_WINDOW_SYSTEM
           || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
@@ -21321,13 +21751,6 @@ get_window_cursor_type (w, glyph, width, active_cursor)
   if (NILP (b->cursor_type))
     return NO_CURSOR;
 
-  /* Use cursor-in-non-selected-windows for non-selected window or frame.  */
-  if (non_selected)
-    {
-      alt_cursor = b->cursor_in_non_selected_windows;
-      return get_specified_cursor_type (alt_cursor, width);
-    }
-
   /* Get the normal cursor type for this window.  */
   if (EQ (b->cursor_type, Qt))
     {
@@ -21337,6 +21760,21 @@ get_window_cursor_type (w, glyph, width, active_cursor)
   else
     cursor_type = get_specified_cursor_type (b->cursor_type, width);
 
+  /* Use cursor-in-non-selected-windows instead
+     for non-selected window or frame.  */
+  if (non_selected)
+    {
+      alt_cursor = b->cursor_in_non_selected_windows;
+      if (!EQ (Qt, alt_cursor))
+       return get_specified_cursor_type (alt_cursor, width);
+      /* t means modify the normal cursor type.  */
+      if (cursor_type == FILLED_BOX_CURSOR)
+       cursor_type = HOLLOW_BOX_CURSOR;
+      else if (cursor_type == BAR_CURSOR && *width > 1)
+       --*width;
+      return cursor_type;
+    }
+
   /* Use normal cursor if not blinked off.  */
   if (!w->cursor_off_p)
     {
@@ -21672,7 +22110,7 @@ erase_phys_cursor (w)
       x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
 
       if (width > 0)
-      rif->clear_frame_area (f, x, y, width, cursor_row->visible_height);
+       FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
     }
 
   /* Erase the cursor by redrawing the character underneath it.  */
@@ -21769,9 +22207,9 @@ display_and_set_cursor (w, on, hpos, vpos, x, y)
       w->phys_cursor.vpos = vpos;
     }
 
-  rif->draw_window_cursor (w, glyph_row, x, y,
-                          new_cursor_type, new_cursor_width,
-                          on, active_cursor);
+  FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
+                                     new_cursor_type, new_cursor_width,
+                                     on, active_cursor);
 }
 
 
@@ -21920,11 +22358,11 @@ show_mouse_face (dpyinfo, draw)
 
   /* Change the mouse cursor.  */
   if (draw == DRAW_NORMAL_TEXT && !EQ (dpyinfo->mouse_face_window, f->tool_bar_window))
-    rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
+    FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
   else if (draw == DRAW_MOUSE_FACE)
-    rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
+    FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
   else
-    rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
+    FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
 }
 
 /* EXPORT:
@@ -22000,7 +22438,7 @@ cursor_in_mouse_face_p (w)
 static int
 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
      struct window *w;
-     int charpos;
+     EMACS_INT charpos;
      int *hpos, *vpos, *x, *y;
      Lisp_Object stop;
 {
@@ -22088,7 +22526,7 @@ fast_find_position (w, charpos, hpos, vpos, x, y, stop)
 static int
 fast_find_position (w, pos, hpos, vpos, x, y, stop)
      struct window *w;
-     int pos;
+     EMACS_INT pos;
      int *hpos, *vpos, *x, *y;
      Lisp_Object stop;
 {
@@ -22202,7 +22640,7 @@ fast_find_position (w, pos, hpos, vpos, x, y, stop)
 static int
 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
      struct window *w;
-     int pos;
+     EMACS_INT pos;
      Lisp_Object object;
      int *hpos, *vpos, *x, *y;
      int right_p;
@@ -22232,8 +22670,8 @@ fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
                goto found;
              }
            else if (best_glyph == NULL
-                    || ((abs (g->charpos - pos)
-                        < abs (best_glyph->charpos - pos))
+                    || ((eabs (g->charpos - pos)
+                        < eabs (best_glyph->charpos - pos))
                         && (right_p
                             ? g->charpos < pos
                             : g->charpos > pos)))
@@ -22363,7 +22801,6 @@ on_hot_spot_p (hot_spot, x, y)
          return inside;
        }
     }
-  /* If we don't understand the format, pretend we're not in the hot-spot.  */
   return 0;
 }
 
@@ -22443,7 +22880,7 @@ define_frame_cursor1 (f, cursor, pointer)
     }
 
   if (cursor != No_Cursor)
-    rif->define_frame_cursor (f, cursor);
+    FRAME_RIF (f)->define_frame_cursor (f, cursor);
 }
 
 /* Take proper action when mouse has moved to the mode or header line
@@ -23364,10 +23801,11 @@ expose_line (w, row, r)
    LAST_OVERLAPPING_ROW is the last such row.  */
 
 static void
-expose_overlaps (w, first_overlapping_row, last_overlapping_row)
+expose_overlaps (w, first_overlapping_row, last_overlapping_row, r)
      struct window *w;
      struct glyph_row *first_overlapping_row;
      struct glyph_row *last_overlapping_row;
+     XRectangle *r;
 {
   struct glyph_row *row;
 
@@ -23376,6 +23814,7 @@ expose_overlaps (w, first_overlapping_row, last_overlapping_row)
       {
        xassert (row->enabled_p && !row->mode_line_p);
 
+       row->clip = r;
        if (row->used[LEFT_MARGIN_AREA])
          x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
 
@@ -23384,6 +23823,7 @@ expose_overlaps (w, first_overlapping_row, last_overlapping_row)
 
        if (row->used[RIGHT_MARGIN_AREA])
          x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
+       row->clip = NULL;
       }
 }
 
@@ -23397,6 +23837,24 @@ phys_cursor_in_rect_p (w, r)
 {
   XRectangle cr, result;
   struct glyph *cursor_glyph;
+  struct glyph_row *row;
+
+  if (w->phys_cursor.vpos >= 0
+      && w->phys_cursor.vpos < w->current_matrix->nrows
+      && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
+         row->enabled_p)
+      && row->cursor_in_fringe_p)
+    {
+      /* Cursor is in the fringe.  */
+      cr.x = window_box_right_offset (w,
+                                     (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+                                      ? RIGHT_MARGIN_AREA
+                                      : TEXT_AREA));
+      cr.y = row->y;
+      cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
+      cr.height = row->height;
+      return x_intersect_rectangles (&cr, r, &result);
+    }
 
   cursor_glyph = get_phys_cursor_glyph (w);
   if (cursor_glyph)
@@ -23411,8 +23869,8 @@ phys_cursor_in_rect_p (w, r)
         I assume the effect is the same -- and this is portable.  */
       return x_intersect_rectangles (&cr, r, &result);
     }
-  else
-    return 0;
+  /* If we don't understand the format, pretend we're not in the hot-spot.  */
+  return 0;
 }
 
 
@@ -23424,6 +23882,8 @@ void
 x_draw_vertical_border (w)
      struct window *w;
 {
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  
   /* We could do better, if we knew what type of scroll-bar the adjacent
      windows (on either side) have...  But we don't :-(
      However, I think this works ok.  ++KFS 2003-04-25 */
@@ -23444,9 +23904,9 @@ x_draw_vertical_border (w)
       y1 -= 1;
 
       if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
-       x1 -= 1;
+        x1 -= 1;
 
-      rif->draw_vertical_window_border (w, x1, y0, y1);
+      FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
     }
   else if (!WINDOW_LEFTMOST_P (w)
           && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
@@ -23457,9 +23917,9 @@ x_draw_vertical_border (w)
       y1 -= 1;
 
       if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
-       x0 -= 1;
+        x0 -= 1;
 
-      rif->draw_vertical_window_border (w, x0, y0, y1);
+      FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
     }
 }
 
@@ -23547,8 +24007,22 @@ expose_window (w, fr)
                  last_overlapping_row = row;
                }
 
+             row->clip = fr;
              if (expose_line (w, row, &r))
                mouse_face_overwritten_p = 1;
+             row->clip = NULL;
+           }
+         else if (row->overlapping_p)
+           {
+             /* We must redraw a row overlapping the exposed area.  */
+             if (y0 < r.y
+                 ? y0 + row->phys_height > r.y
+                 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
+               {
+                 if (first_overlapping_row == NULL)
+                   first_overlapping_row = row;
+                 last_overlapping_row = row;
+               }
            }
 
          if (y1 >= yb)
@@ -23569,7 +24043,8 @@ expose_window (w, fr)
        {
          /* Fix the display of overlapping rows.  */
          if (first_overlapping_row)
-           expose_overlaps (w, first_overlapping_row, last_overlapping_row);
+           expose_overlaps (w, first_overlapping_row, last_overlapping_row,
+                            fr);
 
          /* Draw border between windows.  */
          x_draw_vertical_border (w);
@@ -23799,6 +24274,7 @@ syms_of_xdisp ()
   defsubr (&Slookup_image_map);
 #endif
   defsubr (&Sformat_mode_line);
+  defsubr (&Sinvisible_p);
 
   staticpro (&Qmenu_bar_update_hook);
   Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
@@ -24020,8 +24496,12 @@ If you want scrolling to always be a line at a time, you should set
 
   DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
     doc: /* *Scroll up to this many lines, to bring point back on screen.
-A value of zero means to scroll the text to center point vertically
-in the window.  */);
+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
+recenters point as usual.
+
+A value of zero means always recenter point if it moves off screen.  */);
   scroll_conservatively = 0;
 
   DEFVAR_INT ("scroll-margin", &scroll_margin,
@@ -24139,7 +24619,10 @@ Any other value means to autoselect window instantaneously when the
 mouse pointer enters it.
 
 Autoselection selects the minibuffer only if it is active, and never
-unselects the minibuffer if it is active.  */);
+unselects the minibuffer if it is active.
+
+When customizing this variable make sure that the actual value of
+`focus-follows-mouse' matches the behavior of your window manager.  */);
   Vmouse_autoselect_window = Qnil;
 
   DEFVAR_LISP ("auto-resize-tool-bars", &Vauto_resize_tool_bars,