]> code.delx.au - gnu-emacs/blobdiff - src/xdisp.c
Merge from emacs--devo--0
[gnu-emacs] / src / xdisp.c
index 27ab728502a1553ff3bc5b9379f2fbefc47a4f1a..0cb34a2fef86a9c3996570fa176129f6accea37c 100644 (file)
@@ -1,7 +1,7 @@
 /* Display generation from window structure and buffer text.
    Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
                  1997, 1998, 1999, 2000, 2001, 2002, 2003,
-                 2004, 2005 Free Software Foundation, Inc.
+                 2004, 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -202,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
@@ -270,6 +276,12 @@ int auto_raise_tool_bar_buttons_p;
 
 int make_cursor_line_fully_visible_p;
 
+/* Margin below tool bar in pixels.  0 or nil means no margin.
+   If value is `internal-border-width' or `border-width',
+   the corresponding frame parameter is used.  */
+
+Lisp_Object Vtool_bar_border;
+
 /* Margin around tool bar buttons in pixels.  */
 
 Lisp_Object Vtool_bar_button_margin;
@@ -855,7 +867,7 @@ static void store_mode_line_noprop_char P_ ((char));
 static int store_mode_line_noprop P_ ((const unsigned char *, int, int));
 static void x_consider_frame_title P_ ((Lisp_Object));
 static void handle_stop P_ ((struct it *));
-static int tool_bar_lines_needed P_ ((struct frame *));
+static int tool_bar_lines_needed P_ ((struct frame *, int *));
 static int single_display_spec_intangible_p P_ ((Lisp_Object));
 static void ensure_echo_area_buffers P_ ((void));
 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
@@ -966,7 +978,7 @@ static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
 static void update_tool_bar P_ ((struct frame *, int));
 static void build_desired_tool_bar_string P_ ((struct frame *f));
 static int redisplay_tool_bar P_ ((struct frame *));
-static void display_tool_bar_line P_ ((struct it *));
+static void display_tool_bar_line P_ ((struct it *, int));
 static void notice_overwritten_cursor P_ ((struct window *,
                                           enum glyph_row_area,
                                           int, int, int, int));
@@ -1351,7 +1363,7 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
   current_header_line_height = current_mode_line_height = -1;
 
   if (visible_p && XFASTINT (w->hscroll) > 0)
-    *x -= XFASTINT (w->hscroll);
+    *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
 
   return visible_p;
 }
@@ -1771,15 +1783,20 @@ frame_to_window_pixel_xy (w, x, y)
 }
 
 /* EXPORT:
-   Return in *R the clipping rectangle for glyph string S.  */
+   Return in RECTS[] at most N clipping rectangles for glyph string S.
+   Return the number of stored rectangles.  */
 
-void
-get_glyph_string_clip_rect (s, nr)
+int
+get_glyph_string_clip_rects (s, rects, n)
      struct glyph_string *s;
-     NativeRectangle *nr;
+     NativeRectangle *rects;
+     int n;
 {
   XRectangle r;
 
+  if (n <= 0)
+    return 0;
+
   if (s->row->full_width_p)
     {
       /* Draw full-width.  X coordinates are relative to S->w->left_col.  */
@@ -1822,10 +1839,27 @@ get_glyph_string_clip_rect (s, nr)
   /* If S draws overlapping rows, it's sufficient to use the top and
      bottom of the window for clipping because this glyph string
      intentionally draws over other lines.  */
-  if (s->for_overlaps_p)
+  if (s->for_overlaps)
     {
       r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
       r.height = window_text_bottom_y (s->w) - r.y;
+
+      /* Alas, the above simple strategy does not work for the
+        environments with anti-aliased text: if the same text is
+        drawn onto the same place multiple times, it gets thicker.
+        If the overlap we are processing is for the erased cursor, we
+        take the intersection with the rectagle of the cursor.  */
+      if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
+       {
+         XRectangle rc, r_save = r;
+
+         rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
+         rc.y = s->w->phys_cursor.y;
+         rc.width = s->w->phys_cursor_width;
+         rc.height = s->w->phys_cursor_height;
+
+         x_intersect_rectangles (&r_save, &rc, &r);
+       }
     }
   else
     {
@@ -1884,11 +1918,75 @@ get_glyph_string_clip_rect (s, nr)
        }
     }
 
+  if ((s->for_overlaps & OVERLAPS_BOTH) == 0
+      || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
+    {
+#ifdef CONVERT_FROM_XRECT
+      CONVERT_FROM_XRECT (r, *rects);
+#else
+      *rects = r;
+#endif
+      return 1;
+    }
+  else
+    {
+      /* If we are processing overlapping and allowed to return
+        multiple clipping rectangles, we exclude the row of the glyph
+        string from the clipping rectangle.  This is to avoid drawing
+        the same text on the environment with anti-aliasing.  */
 #ifdef CONVERT_FROM_XRECT
-  CONVERT_FROM_XRECT (r, *nr);
+      XRectangle rs[2];
 #else
-  *nr = r;
+      XRectangle *rs = rects;
 #endif
+      int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
+
+      if (s->for_overlaps & OVERLAPS_PRED)
+       {
+         rs[i] = r;
+         if (r.y + r.height > row_y)
+           {
+             if (r.y < row_y)
+               rs[i].height = row_y - r.y;
+             else
+               rs[i].height = 0;
+           }
+         i++;
+       }
+      if (s->for_overlaps & OVERLAPS_SUCC)
+       {
+         rs[i] = r;
+         if (r.y < row_y + s->row->visible_height)
+           {
+             if (r.y + r.height > row_y + s->row->visible_height)
+               {
+                 rs[i].y = row_y + s->row->visible_height;
+                 rs[i].height = r.y + r.height - rs[i].y;
+               }
+             else
+               rs[i].height = 0;
+           }
+         i++;
+       }
+
+      n = i;
+#ifdef CONVERT_FROM_XRECT
+      for (i = 0; i < n; i++)
+       CONVERT_FROM_XRECT (rs[i], rects[i]);
+#endif
+      return n;
+    }
+}
+
+/* EXPORT:
+   Return in *NR the clipping rectangle for glyph string S.  */
+
+void
+get_glyph_string_clip_rect (s, nr)
+     struct glyph_string *s;
+     NativeRectangle *nr;
+{
+  get_glyph_string_clip_rects (s, nr, 1);
 }
 
 
@@ -1897,15 +1995,15 @@ get_glyph_string_clip_rect (s, nr)
    Set w->phys_cursor_width to width of phys cursor.
 */
 
-int
-get_phys_cursor_geometry (w, row, glyph, heightp)
+void
+get_phys_cursor_geometry (w, row, glyph, xp, yp, heightp)
      struct window *w;
      struct glyph_row *row;
      struct glyph *glyph;
-     int *heightp;
+     int *xp, *yp, *heightp;
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
-  int y, wd, h, h0, y0;
+  int x, y, wd, h, h0, y0;
 
   /* Compute the width of the rectangle to draw.  If on a stretch
      glyph, and `x-stretch-block-cursor' is nil, don't draw a
@@ -1915,6 +2013,14 @@ get_phys_cursor_geometry (w, row, glyph, heightp)
 #ifdef HAVE_NTGUI
   wd++; /* Why? */
 #endif
+
+  x = w->phys_cursor.x;
+  if (x < 0)
+    {
+      wd += x;
+      x = 0;
+    }
+
   if (glyph->type == STRETCH_GLYPH
       && !x_stretch_cursor_p)
     wd = min (FRAME_COLUMN_WIDTH (f), wd);
@@ -1944,8 +2050,201 @@ get_phys_cursor_geometry (w, row, glyph, heightp)
        }
     }
 
-  *heightp = h - 1;
-  return WINDOW_TO_FRAME_PIXEL_Y (w, y);
+  *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
+  *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
+  *heightp = h;
+}
+
+/*
+ * Remember which glyph the mouse is over.
+ */
+
+void
+remember_mouse_glyph (f, gx, gy, rect)
+     struct frame *f;
+     int gx, gy;
+     NativeRectangle *rect;
+{
+  Lisp_Object window;
+  struct window *w;
+  struct glyph_row *r, *gr, *end_row;
+  enum window_part part;
+  enum glyph_row_area area;
+  int x, y, width, height;
+
+  /* Try to determine frame pixel position and size of the glyph under
+     frame pixel coordinates X/Y on frame F.  */
+
+  window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0);
+  if (NILP (window))
+    {
+      width = FRAME_SMALLEST_CHAR_WIDTH (f);
+      height = FRAME_SMALLEST_FONT_HEIGHT (f);
+      goto virtual_glyph;
+    }
+
+  w = XWINDOW (window);
+  width = WINDOW_FRAME_COLUMN_WIDTH (w);
+  height = WINDOW_FRAME_LINE_HEIGHT (w);
+
+  r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
+  end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
+
+  if (w->pseudo_window_p)
+    {
+      area = TEXT_AREA;
+      part = ON_MODE_LINE; /* Don't adjust margin. */
+      goto text_glyph;
+    }
+
+  switch (part)
+    {
+    case ON_LEFT_MARGIN:
+      area = LEFT_MARGIN_AREA;
+      goto text_glyph;
+
+    case ON_RIGHT_MARGIN:
+      area = RIGHT_MARGIN_AREA;
+      goto text_glyph;
+
+    case ON_HEADER_LINE:
+    case ON_MODE_LINE:
+      gr = (part == ON_HEADER_LINE
+           ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
+           : MATRIX_MODE_LINE_ROW (w->current_matrix));
+      gy = gr->y;
+      area = TEXT_AREA;
+      goto text_glyph_row_found;
+
+    case ON_TEXT:
+      area = TEXT_AREA;
+
+    text_glyph:
+      gr = 0; gy = 0;
+      for (; r <= end_row && r->enabled_p; ++r)
+       if (r->y + r->height > y)
+         {
+           gr = r; gy = r->y;
+           break;
+         }
+
+    text_glyph_row_found:
+      if (gr && gy <= y)
+       {
+         struct glyph *g = gr->glyphs[area];
+         struct glyph *end = g + gr->used[area];
+
+         height = gr->height;
+         for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
+           if (gx + g->pixel_width > x)
+             break;
+
+         if (g < end)
+           {
+             if (g->type == IMAGE_GLYPH)
+               {
+                 /* Don't remember when mouse is over image, as
+                    image may have hot-spots.  */
+                 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
+                 return;
+               }
+             width = g->pixel_width;
+           }
+         else
+           {
+             /* Use nominal char spacing at end of line.  */
+             x -= gx;
+             gx += (x / width) * width;
+           }
+
+         if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
+           gx += window_box_left_offset (w, area);
+       }
+      else
+       {
+         /* Use nominal line height at end of window.  */
+         gx = (x / width) * width;
+         y -= gy;
+         gy += (y / height) * height;
+       }
+      break;
+
+    case ON_LEFT_FRINGE:
+      gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+           ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
+           : window_box_right_offset (w, LEFT_MARGIN_AREA));
+      width = WINDOW_LEFT_FRINGE_WIDTH (w);
+      goto row_glyph;
+
+    case ON_RIGHT_FRINGE:
+      gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+           ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
+           : window_box_right_offset (w, TEXT_AREA));
+      width = WINDOW_RIGHT_FRINGE_WIDTH (w);
+      goto row_glyph;
+
+    case ON_SCROLL_BAR:
+      gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
+           ? 0
+           : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
+              + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+                 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
+                 : 0)));
+      width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
+
+    row_glyph:
+      gr = 0, gy = 0;
+      for (; r <= end_row && r->enabled_p; ++r)
+       if (r->y + r->height > y)
+         {
+           gr = r; gy = r->y;
+           break;
+         }
+
+      if (gr && gy <= y)
+       height = gr->height;
+      else
+       {
+         /* Use nominal line height at end of window.  */
+         y -= gy;
+         gy += (y / height) * height;
+       }
+      break;
+
+    default:
+      ;
+    virtual_glyph:
+      /* If there is no glyph under the mouse, then we divide the screen
+        into a grid of the smallest glyph in the frame, and use that
+        as our "glyph".  */
+
+      /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
+        round down even for negative values.  */
+      if (gx < 0)
+       gx -= width - 1;
+      if (gy < 0)
+       gy -= height - 1;
+
+      gx = (gx / width) * width;
+      gy = (gy / height) * height;
+
+      goto store_rect;
+    }
+
+  gx += WINDOW_LEFT_EDGE_X (w);
+  gy += WINDOW_TOP_EDGE_Y (w);
+
+ store_rect:
+  STORE_NATIVE_RECT (*rect, gx, gy, width, height);
+
+  /* Visible feedback for debugging.  */
+#if 0
+#if HAVE_X_WINDOWS
+  XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                 f->output_data.x->normal_gc,
+                 gx, gy, width, height);
+#endif
+#endif
 }
 
 
@@ -2707,11 +3006,13 @@ handle_stop (it)
      struct it *it;
 {
   enum prop_handled handled;
-  int handle_overlay_change_p = 1;
+  int handle_overlay_change_p;
   struct props *p;
 
   it->dpvec = NULL;
   it->current.dpvec_index = -1;
+  handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
+  it->ignore_overlay_strings_at_pos_p = 0;
 
   /* Use face of preceding text for ellipsis (if invisible) */
   if (it->selective_display_ellipsis_p)
@@ -2905,6 +3206,9 @@ handle_fontified_prop (it)
   Lisp_Object prop, pos;
   enum prop_handled handled = HANDLED_NORMALLY;
 
+  if (!NILP (Vmemory_full))
+    return handled;
+
   /* Get the value of the `fontified' property at IT's current buffer
      position.  (The `fontified' property doesn't have a special
      meaning in strings.)  If the value is nil, call functions from
@@ -3338,6 +3642,11 @@ handle_invisible_prop (it)
                 skip starting with next_stop.  */
              if (invis_p)
                IT_CHARPOS (*it) = next_stop;
+
+              /* If there are adjacent invisible texts, don't lose the
+                 second one's ellipsis. */
+              if (invis_p == 2)
+                display_ellipsis_p = 1;
            }
          while (invis_p);
 
@@ -3358,7 +3667,26 @@ handle_invisible_prop (it)
              it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
            }
          else if (display_ellipsis_p)
-           setup_for_ellipsis (it, 0);
+            {
+              /* Make sure that the glyphs of the ellipsis will get
+                 correct `charpos' values.  If we would not update
+                 it->position here, the glyphs would belong to the
+                 last visible character _before_ the invisible
+                 text, which confuses `set_cursor_from_row'.
+
+                 We use the last invisible position instead of the
+                 first because this way the cursor is always drawn on
+                 the first "." of the ellipsis, whenever PT is inside
+                 the invisible text.  Otherwise the cursor would be
+                 placed _after_ the ellipsis when the point is after the
+                 first invisible character.  */
+             if (!STRINGP (it->object))
+               {
+                 it->position.charpos = IT_CHARPOS (*it) - 1;
+                 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
+               }
+              setup_for_ellipsis (it, 0);
+            }
        }
     }
 
@@ -3872,7 +4200,7 @@ handle_single_display_spec (it, spec, object, position,
        {
          it->method = GET_FROM_STRETCH;
          it->object = value;
-         it->current.pos = it->position = start_pos;
+         *position = it->position = start_pos;
        }
 #ifdef HAVE_WINDOW_SYSTEM
       else
@@ -4230,9 +4558,32 @@ handle_composition_prop (it)
 
       if (id >= 0)
        {
+         struct composition *cmp = composition_table[id];
+
+         if (cmp->glyph_len == 0)
+           {
+             /* No glyph.  */
+             if (STRINGP (it->string))
+               {
+                 IT_STRING_CHARPOS (*it) = end;
+                 IT_STRING_BYTEPOS (*it) = string_char_to_byte (it->string,
+                                                                end);
+               }
+             else
+               {
+                 IT_CHARPOS (*it) = end;
+                 IT_BYTEPOS (*it) = CHAR_TO_BYTE (end);
+               }
+             return HANDLED_RECOMPUTE_PROPS;
+           }
          it->method = GET_FROM_COMPOSITION;
          it->cmp_id = id;
          it->cmp_len = COMPOSITION_LENGTH (prop);
+#ifdef USE_FONT_BACKEND
+         if (composition_table[id]->method == COMPOSITION_WITH_GLYPH_STRING)
+           it->c = ' ';
+         else
+#endif /* USE_FONT_BACKEND */
          /* For a terminal, draw only the first character of the
              components.  */
          it->c = COMPOSITION_GLYPH (composition_table[id], 0);
@@ -5125,6 +5476,10 @@ static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
    display element from the current position of IT.  Value is zero if
    end of buffer (or C string) is reached.  */
 
+static struct frame *last_escape_glyph_frame = NULL;
+static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
+static int last_escape_glyph_merged_face_id = 0;
+
 int
 get_next_display_element (it)
      struct it *it;
@@ -5236,11 +5591,19 @@ get_next_display_element (it)
                       face_id = merge_faces (it->f, Qt, lface_id,
                                              it->face_id);
                    }
+                 else if (it->f == last_escape_glyph_frame
+                          && it->face_id == last_escape_glyph_face_id)
+                   {
+                     face_id = last_escape_glyph_merged_face_id;
+                   }
                  else
                    {
                      /* Merge the escape-glyph face into the current face.  */
                      face_id = merge_faces (it->f, Qescape_glyph, 0,
                                             it->face_id);
+                     last_escape_glyph_frame = it->f;
+                     last_escape_glyph_face_id = it->face_id;
+                     last_escape_glyph_merged_face_id = face_id;
                    }
 
                  XSETINT (it->ctl_chars[0], g);
@@ -5286,11 +5649,19 @@ get_next_display_element (it)
                  face_id = merge_faces (it->f, Qt, lface_id,
                                         it->face_id);
                }
+             else if (it->f == last_escape_glyph_frame
+                      && it->face_id == last_escape_glyph_face_id)
+               {
+                 face_id = last_escape_glyph_merged_face_id;
+               }
              else
                {
                  /* Merge the escape-glyph face into the current face.  */
                  face_id = merge_faces (it->f, Qescape_glyph, 0,
                                         it->face_id);
+                 last_escape_glyph_frame = it->f;
+                 last_escape_glyph_face_id = it->face_id;
+                 last_escape_glyph_merged_face_id = face_id;
                }
 
              /* Handle soft hyphens in the mode where they only get
@@ -5488,6 +5859,8 @@ set_iterator_to_next (it, reseat_p)
 
       if (it->dpvec + it->current.dpvec_index == it->dpend)
        {
+         int recheck_faces = it->ellipsis_p;
+
          if (it->s)
            it->method = GET_FROM_C_STRING;
          else if (STRINGP (it->string))
@@ -5503,12 +5876,16 @@ set_iterator_to_next (it, reseat_p)
            reseat_at_next_visible_line_start (it, 1);
          else if (it->dpvec_char_len > 0)
            {
+             if (it->method == GET_FROM_STRING
+                 && it->n_overlay_strings > 0)
+               it->ignore_overlay_strings_at_pos_p = 1;
              it->len = it->dpvec_char_len;
              set_iterator_to_next (it, reseat_p);
            }
 
-         /* Recheck faces after display vector */
-         it->stop_charpos = IT_CHARPOS (*it);
+         /* Maybe recheck faces after display vector */
+         if (recheck_faces)
+           it->stop_charpos = IT_CHARPOS (*it);
        }
       break;
 
@@ -5966,6 +6343,8 @@ next_element_from_composition (it)
   it->position = (STRINGP (it->string)
                  ? it->current.string_pos
                  : it->current.pos);
+  if (STRINGP (it->string))
+    it->object = it->string;
   return 1;
 }
 
@@ -8448,7 +8827,7 @@ static Lisp_Object mode_line_string_face_prop;
 static Lisp_Object Vmode_line_unwind_vector;
 
 static Lisp_Object
-format_mode_line_unwind_data (obuf)
+format_mode_line_unwind_data (obuf, save_proptrans)
      struct buffer *obuf;
 {
   Lisp_Object vector;
@@ -8464,7 +8843,7 @@ format_mode_line_unwind_data (obuf)
   AREF (vector, 0) = make_number (mode_line_target);
   AREF (vector, 1) = make_number (MODE_LINE_NOPROP_LEN (0));
   AREF (vector, 2) = mode_line_string_list;
-  AREF (vector, 3) = mode_line_proptrans_alist;
+  AREF (vector, 3) = (save_proptrans ? mode_line_proptrans_alist : Qt);
   AREF (vector, 4) = mode_line_string_face;
   AREF (vector, 5) = mode_line_string_face_prop;
 
@@ -8483,7 +8862,8 @@ unwind_format_mode_line (vector)
   mode_line_target = XINT (AREF (vector, 0));
   mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
   mode_line_string_list = AREF (vector, 2);
-  mode_line_proptrans_alist = AREF (vector, 3);
+  if (! EQ (AREF (vector, 3), Qt))
+    mode_line_proptrans_alist = AREF (vector, 3);
   mode_line_string_face = AREF (vector, 4);
   mode_line_string_face_prop = AREF (vector, 5);
 
@@ -8606,7 +8986,7 @@ x_consider_frame_title (frame)
         mode_line_target so that display_mode_element will output into
         mode_line_noprop_buf; then display the title.  */
       record_unwind_protect (unwind_format_mode_line,
-                            format_mode_line_unwind_data (current_buffer));
+                            format_mode_line_unwind_data (current_buffer, 0));
 
       set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
       fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
@@ -8720,6 +9100,9 @@ prepare_menu_bars ()
          update_menu_bar (f, 0);
 #ifdef HAVE_WINDOW_SYSTEM
          update_tool_bar (f, 0);
+#ifdef MAC_OS
+         mac_update_title_bar (f, 0);
+#endif
 #endif
          UNGCPRO;
        }
@@ -8732,6 +9115,9 @@ prepare_menu_bars ()
       update_menu_bar (sf, 1);
 #ifdef HAVE_WINDOW_SYSTEM
       update_tool_bar (sf, 1);
+#ifdef MAC_OS
+      mac_update_title_bar (sf, 1);
+#endif
 #endif
     }
 
@@ -8831,14 +9217,15 @@ update_menu_bar (f, save_match_data)
          /* Redisplay the menu bar in case we changed it.  */
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
     || defined (USE_GTK)
-         if (FRAME_WINDOW_P (f)
-#if defined (MAC_OS)
-              /* All frames on Mac OS share the same menubar.  So only the
-                 selected frame should be allowed to set it.  */
-              && f == SELECTED_FRAME ()
+         if (FRAME_WINDOW_P (f))
+           {
+#ifdef MAC_OS
+              /* All frames on Mac OS share the same menubar.  So only
+                 the selected frame should be allowed to set it.  */
+              if (f == SELECTED_FRAME ())
 #endif
-            )
-           set_frame_menubar (f, 0, 0);
+               set_frame_menubar (f, 0, 0);
+           }
          else
            /* On a terminal screen, the menu bar is an ordinary screen
               line, and this makes it get updated.  */
@@ -9202,11 +9589,22 @@ build_desired_tool_bar_string (f)
 }
 
 
-/* Display one line of the tool-bar of frame IT->f.  */
+/* Display one line of the tool-bar of frame IT->f.
+
+   HEIGHT specifies the desired height of the tool-bar line.
+   If the actual height of the glyph row is less than HEIGHT, the
+   row's height is increased to HEIGHT, and the icons are centered
+   vertically in the new height.
+
+   If HEIGHT is -1, we are counting needed tool-bar lines, so don't
+   count a final empty row in case the tool-bar width exactly matches
+   the window width.
+*/
 
 static void
-display_tool_bar_line (it)
+display_tool_bar_line (it, height)
      struct it *it;
+     int height;
 {
   struct glyph_row *row = it->glyph_row;
   int max_x = it->last_visible_x;
@@ -9221,29 +9619,36 @@ display_tool_bar_line (it)
 
   while (it->current_x < max_x)
     {
-      int x_before, x, n_glyphs_before, i, nglyphs;
+      int x, n_glyphs_before, i, nglyphs;
+      struct it it_before;
 
       /* Get the next display element.  */
       if (!get_next_display_element (it))
-       break;
+       {
+         /* Don't count empty row if we are counting needed tool-bar lines.  */
+         if (height < 0 && !it->hpos)
+           return;
+         break;
+       }
 
       /* Produce glyphs.  */
-      x_before = it->current_x;
-      n_glyphs_before = it->glyph_row->used[TEXT_AREA];
+      n_glyphs_before = row->used[TEXT_AREA];
+      it_before = *it;
+
       PRODUCE_GLYPHS (it);
 
-      nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
+      nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
       i = 0;
-      x = x_before;
+      x = it_before.current_x;
       while (i < nglyphs)
        {
          struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
 
          if (x + glyph->pixel_width > max_x)
            {
-             /* Glyph doesn't fit on line.  */
-             it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
-             it->current_x = x;
+             /* Glyph doesn't fit on line.  Backtrack.  */
+             row->used[TEXT_AREA] = n_glyphs_before;
+             *it = it_before;
              goto out;
            }
 
@@ -9262,11 +9667,24 @@ display_tool_bar_line (it)
  out:;
 
   row->displays_text_p = row->used[TEXT_AREA] != 0;
+  /* Use default face for the border below the tool bar.  */
+  if (!row->displays_text_p)
+    it->face_id = DEFAULT_FACE_ID;
   extend_face_to_end_of_line (it);
   last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
   last->right_box_line_p = 1;
   if (last == row->glyphs[TEXT_AREA])
     last->left_box_line_p = 1;
+
+  /* Make line the desired height and center it vertically.  */
+  if ((height -= it->max_ascent + it->max_descent) > 0)
+    {
+      /* Don't add more than one line height.  */
+      height %= FRAME_LINE_HEIGHT (it->f);
+      it->max_ascent += height / 2;
+      it->max_descent += (height + 1) / 2;
+    }
+
   compute_line_metrics (it);
 
   /* If line is empty, make it occupy the rest of the tool-bar.  */
@@ -9290,28 +9708,36 @@ display_tool_bar_line (it)
 
 
 /* Value is the number of screen lines needed to make all tool-bar
-   items of frame F visible.  */
+   items of frame F visible.  The number of actual rows needed is
+   returned in *N_ROWS if non-NULL.  */
 
 static int
-tool_bar_lines_needed (f)
+tool_bar_lines_needed (f, n_rows)
      struct frame *f;
+     int *n_rows;
 {
   struct window *w = XWINDOW (f->tool_bar_window);
   struct it it;
+  struct glyph_row *temp_row = w->desired_matrix->rows;
 
   /* Initialize an iterator for iteration over
      F->desired_tool_bar_string in the tool-bar window of frame F.  */
-  init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
+  init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
   it.first_visible_x = 0;
   it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
   reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
 
   while (!ITERATOR_AT_END_P (&it))
     {
-      it.glyph_row = w->desired_matrix->rows;
-      clear_glyph_row (it.glyph_row);
-      display_tool_bar_line (&it);
+      clear_glyph_row (temp_row);
+      it.glyph_row = temp_row;
+      display_tool_bar_line (&it, -1);
     }
+  clear_glyph_row (temp_row);
+
+  /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar.  */
+  if (n_rows)
+    *n_rows = it.vpos > 0 ? it.vpos : -1;
 
   return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
 }
@@ -9341,7 +9767,7 @@ DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
       if (f->n_tool_bar_items)
        {
          build_desired_tool_bar_string (f);
-         nlines = tool_bar_lines_needed (f);
+         nlines = tool_bar_lines_needed (f, NULL);
        }
     }
 
@@ -9386,9 +9812,68 @@ redisplay_tool_bar (f)
   build_desired_tool_bar_string (f);
   reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
 
+  if (f->n_tool_bar_rows == 0)
+    {
+      int nlines;
+
+      if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
+          nlines != WINDOW_TOTAL_LINES (w)))
+       {
+         extern Lisp_Object Qtool_bar_lines;
+         Lisp_Object frame;
+         int old_height = WINDOW_TOTAL_LINES (w);
+
+         XSETFRAME (frame, f);
+         clear_glyph_matrix (w->desired_matrix);
+         Fmodify_frame_parameters (frame,
+                                   Fcons (Fcons (Qtool_bar_lines,
+                                                 make_number (nlines)),
+                                          Qnil));
+         if (WINDOW_TOTAL_LINES (w) != old_height)
+           {
+             fonts_changed_p = 1;
+             return 1;
+           }
+       }
+    }
+
   /* Display as many lines as needed to display all tool-bar items.  */
-  while (it.current_y < it.last_visible_y)
-    display_tool_bar_line (&it);
+
+  if (f->n_tool_bar_rows > 0)
+    {
+      int border, rows, height, extra;
+
+      if (INTEGERP (Vtool_bar_border))
+       border = XINT (Vtool_bar_border);
+      else if (EQ (Vtool_bar_border, Qinternal_border_width))
+       border = FRAME_INTERNAL_BORDER_WIDTH (f);
+      else if (EQ (Vtool_bar_border, Qborder_width))
+       border = f->border_width;
+      else
+       border = 0;
+      if (border < 0)
+       border = 0;
+
+      rows = f->n_tool_bar_rows;
+      height = max (1, (it.last_visible_y - border) / rows);
+      extra = it.last_visible_y - border - height * rows;
+
+      while (it.current_y < it.last_visible_y)
+       {
+         int h = 0;
+         if (extra > 0 && rows-- > 0)
+           {
+             h = (extra + rows - 1) / rows;
+             extra -= h;
+           }
+         display_tool_bar_line (&it, height + h);
+       }
+    }
+  else
+    {
+      while (it.current_y < it.last_visible_y)
+       display_tool_bar_line (&it, 0);
+    }
 
   /* It doesn't make much sense to try scrolling in the tool-bar
      window, so don't do it.  */
@@ -9421,7 +9906,7 @@ redisplay_tool_bar (f)
       /* Resize windows as needed by changing the `tool-bar-lines'
         frame parameter.  */
       if (change_height_p
-         && (nlines = tool_bar_lines_needed (f),
+         && (nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
              nlines != WINDOW_TOTAL_LINES (w)))
        {
          extern Lisp_Object Qtool_bar_lines;
@@ -10347,6 +10832,8 @@ redisplay_internal (preserve_echo_area)
  retry:
   pause = 0;
   reconsider_clip_changes (w, current_buffer);
+  last_escape_glyph_frame = NULL;
+  last_escape_glyph_face_id = (1 << FACE_ID_BITS);
 
   /* If new fonts have been loaded that make a glyph matrix adjustment
      necessary, do it.  */
@@ -10403,7 +10890,8 @@ redisplay_internal (preserve_echo_area)
     clear_garbaged_frames ();
 
   /* Build menubar and tool-bar items.  */
-  prepare_menu_bars ();
+  if (NILP (Vmemory_full))
+    prepare_menu_bars ();
 
   if (windows_or_buffers_changed)
     update_mode_lines++;
@@ -11240,9 +11728,11 @@ redisplay_window_1 (window)
 
 /* Set cursor position of W.  PT is assumed to be displayed in ROW.
    DELTA is the number of bytes by which positions recorded in ROW
-   differ from current buffer positions.  */
+   differ from current buffer positions.
 
-void
+   Return 0 if cursor is not on this row.  1 otherwise.  */
+
+int
 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
      struct window *w;
      struct glyph_row *row;
@@ -11289,7 +11779,7 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
          x += glyph->pixel_width;
          ++glyph;
          if (cursor_from_overlay_pos
-             && last_pos > cursor_from_overlay_pos)
+             && last_pos >= cursor_from_overlay_pos)
            {
              cursor_from_overlay_pos = 0;
              cursor = 0;
@@ -11303,10 +11793,12 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
          /* Skip all glyphs from string.  */
          do
            {
+             Lisp_Object cprop;
              int pos;
              if ((cursor == NULL || glyph > cursor)
-                 && !NILP (Fget_char_property (make_number ((glyph)->charpos),
-                                               Qcursor, (glyph)->object))
+                 && (cprop = Fget_char_property (make_number ((glyph)->charpos),
+                                                 Qcursor, (glyph)->object),
+                     !NILP (cprop))
                  && (pos = string_buffer_position (w, glyph->object,
                                                    string_before_pos),
                      (pos == 0   /* From overlay */
@@ -11317,14 +11809,15 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
                     Add 1 to last_pos so that if point corresponds to the
                     glyph right after the overlay, we still use a 'cursor'
                     property found in that overlay.  */
-                 cursor_from_overlay_pos = pos == 0 ? last_pos+1 : 0;
+                 cursor_from_overlay_pos = (pos ? 0 : last_pos
+                                            + (INTEGERP (cprop) ? XINT (cprop) : 0));
                  cursor = glyph;
                  cursor_x = x;
                }
              x += glyph->pixel_width;
              ++glyph;
            }
-         while (glyph < end && STRINGP (glyph->object));
+         while (glyph < end && EQ (glyph->object, string_start->object));
        }
     }
 
@@ -11389,6 +11882,11 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
              SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
            }
        }
+
+      /* If we reached the end of the line, and end was from a string,
+        cursor is not on this line.  */
+      if (glyph == end && row->continued_p)
+       return 0;
     }
 
   w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
@@ -11422,6 +11920,8 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
       else
        CHARPOS (this_line_start_pos) = 0;
     }
+
+  return 1;
 }
 
 
@@ -12105,8 +12605,18 @@ try_cursor_movement (window, startp, scroll_step)
            rc = CURSOR_MOVEMENT_MUST_SCROLL;
          else
            {
-             set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
-             rc = CURSOR_MOVEMENT_SUCCESS;
+             do
+               {
+                 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
+                   {
+                     rc = CURSOR_MOVEMENT_SUCCESS;
+                     break;
+                   }
+                 ++row;
+               }
+             while (MATRIX_ROW_BOTTOM_Y (row) < last_y
+                    && MATRIX_ROW_START_CHARPOS (row) == PT
+                    && cursor_row_p (w, row));
            }
        }
     }
@@ -12367,8 +12877,6 @@ redisplay_window (window, just_this_one_p)
       /* IT may overshoot PT if text at PT is invisible.  */
       else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
        w->force_start = Qt;
-
-
     }
 
   /* Handle case where place to start displaying has been specified,
@@ -12538,6 +13046,36 @@ redisplay_window (window, just_this_one_p)
               || (XFASTINT (w->last_modified) >= MODIFF
                   && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
     {
+
+      /* If first window line is a continuation line, and window start
+        is inside the modified region, but the first change is before
+        current window start, we must select a new window start.*/
+      if (NILP (w->start_at_line_beg)
+         && CHARPOS (startp) > BEGV)
+       {
+         /* Make sure beg_unchanged and end_unchanged are up to date.
+            Do it only if buffer has really changed.  This may or may
+            not have been done by try_window_id (see which) already. */
+         if (MODIFF > SAVE_MODIFF
+             /* This seems to happen sometimes after saving a buffer.  */
+             || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
+           {
+             if (GPT - BEG < BEG_UNCHANGED)
+               BEG_UNCHANGED = GPT - BEG;
+             if (Z - GPT < END_UNCHANGED)
+               END_UNCHANGED = Z - GPT;
+           }
+
+         if (CHARPOS (startp) > BEG + BEG_UNCHANGED
+             && CHARPOS (startp) <= Z - END_UNCHANGED)
+           {
+             /* There doesn't seems to be a simple way to find a new
+                window start that is near the old window start, so
+                we just recenter.  */
+             goto recenter;
+           }
+       }
+
 #if GLYPH_DEBUG
       debug_method_add (w, "same window start");
 #endif
@@ -12943,7 +13481,8 @@ try_window (window, pos, check_margins)
       this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
 
       if ((w->cursor.y < this_scroll_margin
-          && CHARPOS (pos) > BEGV)
+          && CHARPOS (pos) > BEGV
+          && IT_CHARPOS (it) < ZV)
          /* rms: considering make_cursor_line_fully_visible_p here
             seems to give wrong results.  We don't want to recenter
             when the last line is partly visible, we want to allow
@@ -14530,6 +15069,25 @@ dump_glyph (row, glyph, area)
               glyph->left_box_line_p,
               glyph->right_box_line_p);
     }
+  else if (glyph->type == COMPOSITE_GLYPH)
+    {
+      fprintf (stderr,
+              "  %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
+              glyph - row->glyphs[TEXT_AREA],
+              '+',
+              glyph->charpos,
+              (BUFFERP (glyph->object)
+               ? 'B'
+               : (STRINGP (glyph->object)
+                  ? 'S'
+                  : '-')),
+              glyph->pixel_width,
+              glyph->u.cmp_id,
+              '.',
+              glyph->face_id,
+              glyph->left_box_line_p,
+              glyph->right_box_line_p);
+    }
 }
 
 
@@ -14545,7 +15103,7 @@ dump_glyph_row (row, vpos, glyphs)
 {
   if (glyphs != 1)
     {
-      fprintf (stderr, "Row Start   End Used oEI><\\CTZFesm     X    Y    W    H    V    A    P\n");
+      fprintf (stderr, "Row Start   End Used oE><\\CTZFesm     X    Y    W    H    V    A    P\n");
       fprintf (stderr, "======================================================================\n");
 
       fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
@@ -15049,6 +15607,7 @@ extend_face_to_end_of_line (it)
     face = FACE_FROM_ID (f, it->face_id);
 
   if (FRAME_WINDOW_P (f)
+      && it->glyph_row->displays_text_p
       && face->box == FACE_NO_BOX
       && face->background == FRAME_BACKGROUND_PIXEL (f)
       && !face->stipple)
@@ -15494,7 +16053,9 @@ display_line (it)
                        produce_special_glyphs (it, IT_CONTINUATION);
                      row->continued_p = 1;
 
+                     it->current_x = x_before;
                      it->continuation_lines_width += x;
+                     extend_face_to_end_of_line (it);
 
                      if (nglyphs > 1 && i > 0)
                        {
@@ -15979,7 +16540,7 @@ display_mode_line (w, face_id, format)
     it.base_face_id = it.face_id = DEFAULT_FACE_ID;
 
   record_unwind_protect (unwind_format_mode_line,
-                        format_mode_line_unwind_data (NULL));
+                        format_mode_line_unwind_data (NULL, 0));
 
   mode_line_target = MODE_LINE_DISPLAY;
 
@@ -16014,6 +16575,44 @@ display_mode_line (w, face_id, format)
   return it.glyph_row->height;
 }
 
+/* Move element ELT in LIST to the front of LIST.
+   Return the updated list.  */
+
+static Lisp_Object
+move_elt_to_front (elt, list)
+     Lisp_Object elt, list;
+{
+  register Lisp_Object tail, prev;
+  register Lisp_Object tem;
+
+  tail = list;
+  prev = Qnil;
+  while (CONSP (tail))
+    {
+      tem = XCAR (tail);
+
+      if (EQ (elt, tem))
+       {
+         /* Splice out the link TAIL.  */
+         if (NILP (prev))
+           list = XCDR (tail);
+         else
+           Fsetcdr (prev, XCDR (tail));
+
+         /* Now make it the first.  */
+         Fsetcdr (tail, list);
+         return tail;
+       }
+      else
+       prev = tail;
+      tail = XCDR (tail);
+      QUIT;
+    }
+
+  /* Not found--return unchanged LIST.  */
+  return list;
+}
+
 /* Contribute ELT to the mode line for window IT->w.  How it
    translates into text depends on its data type.
 
@@ -16063,7 +16662,8 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky)
        unsigned char c;
        int offset = 0;
 
-       if (!NILP (props) || risky)
+       if (SCHARS (elt) > 0
+           && (!NILP (props) || risky))
          {
            Lisp_Object oprops, aelt;
            oprops = Ftext_properties_at (make_number (0), elt);
@@ -16094,14 +16694,22 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky)
                aelt = Fassoc (elt, mode_line_proptrans_alist);
                if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
                  {
-                   mode_line_proptrans_alist
-                     = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
+                   /* AELT is what we want.  Move it to the front
+                      without consing.  */
                    elt = XCAR (aelt);
+                   mode_line_proptrans_alist
+                     = move_elt_to_front (aelt, mode_line_proptrans_alist);
                  }
                else
                  {
                    Lisp_Object tem;
 
+                   /* If AELT has the wrong props, it is useless.
+                      so get rid of it.  */
+                   if (! NILP (aelt))
+                     mode_line_proptrans_alist
+                       = Fdelq (aelt, mode_line_proptrans_alist);
+
                    elt = Fcopy_sequence (elt);
                    Fset_text_properties (make_number (0), Flength (elt),
                                          props, elt);
@@ -16192,8 +16800,11 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky)
                    {
                      int bytepos = last_offset;
                      int charpos = string_byte_to_char (elt, bytepos);
+
+                     if (precision <= 0)
+                       nchars = string_byte_to_char (elt, offset) - charpos;
                      n += display_string (NULL, elt, Qnil, 0, charpos,
-                                          it, 0, prec, 0,
+                                          it, 0, nchars, 0,
                                           STRING_MULTIBYTE (elt));
                    }
                    break;
@@ -16626,8 +17237,11 @@ are the selected window and the window's buffer).  */)
   if (XBUFFER (buffer) != current_buffer)
     old_buffer = current_buffer;
 
+  /* Save things including mode_line_proptrans_alist,
+     and set that to nil so that we don't alter the outer value.  */
   record_unwind_protect (unwind_format_mode_line,
-                        format_mode_line_unwind_data (old_buffer));
+                        format_mode_line_unwind_data (old_buffer, 1));
+  mode_line_proptrans_alist = Qnil;
 
   if (old_buffer)
     set_buffer_internal_1 (XBUFFER (buffer));
@@ -17013,6 +17627,18 @@ decode_mode_spec (w, c, field_width, precision, multibyte)
        return decode_mode_spec_buf;
       }
 
+    case 'e':
+#ifndef SYSTEM_MALLOC
+      {
+       if (NILP (Vmemory_full))
+         return "";
+       else
+         return "!MEM FULL! ";
+      }
+#else
+      return "";
+#endif
+
     case 'F':
       /* %F displays the frame name.  */
       if (!NILP (f->title))
@@ -17430,7 +18056,7 @@ display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
    display them, and < 0 means obey the current buffer's value of
    enable_multibyte_characters.
 
-   Value is the number of glyphs produced.  */
+   Value is the number of columns displayed.  */
 
 static int
 display_string (string, lisp_string, face_string, face_string_pos,
@@ -18074,14 +18700,30 @@ 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
         sure to use a face suitable for unibyte.  */
       STORE_XCHAR2B (char2b, 0, glyph->u.ch);
     }
-  else if (glyph->u.ch < 128
-          && glyph->face_id < BASIC_FACE_ID_SENTINEL)
+  else if (glyph->u.ch < 128)
     {
       /* Case of ASCII in a face known to fit ASCII.  */
       STORE_XCHAR2B (char2b, 0, glyph->u.ch);
@@ -18121,38 +18763,72 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
 
    FACES is an array of faces for all components of this composition.
    S->gidx is the index of the first component for S.
-   OVERLAPS_P non-zero means S should draw the foreground only, and
-   use its physical height for clipping.
+
+   OVERLAPS non-zero means S should draw the foreground only, and use
+   its physical height for clipping.  See also draw_glyphs.
 
    Value is the index of a component not in S.  */
 
 static int
-fill_composite_glyph_string (s, faces, overlaps_p)
+fill_composite_glyph_string (s, faces, overlaps)
      struct glyph_string *s;
      struct face **faces;
-     int overlaps_p;
+     int overlaps;
 {
   int i;
 
   xassert (s);
 
-  s->for_overlaps_p = overlaps_p;
+  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);
+  if (s->face == NULL)
+    {
+      s->font = NULL;
+      s->font_info = NULL;
+    }
+  else
+    {
+      s->font = s->face->font;
+      s->font_info = FONT_INFO_FROM_FACE (s->f, s->face);
+    }
 
+#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);
+
+      for (i = 0; i < s->cmp->glyph_len; i++)
+       {
+         Lisp_Object g = LGSTRING_GLYPH (gstring, i);
+         unsigned code = XUINT (LGLYPH_CODE (g));
+
+         STORE_XCHAR2B (s->char2b + i, code >> 8, code & 0xFF);
+       }
+      s->nchars = s->cmp->glyph_len;
+      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.  */
   ++s->nchars;
-  for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
+  for (i = s->gidx + 1;
+       i < s->cmp->glyph_len && (faces[i] == s->face || ! faces[i] || ! s->face);
+       ++i)
     ++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;
+#ifdef USE_FONT_BACKEND
+    }
+#endif /* USE_FONT_BACKEND */
 
   /* 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
@@ -18167,8 +18843,6 @@ fill_composite_glyph_string (s, faces, overlaps_p)
   /* 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;
 
@@ -18180,16 +18854,16 @@ fill_composite_glyph_string (s, faces, overlaps_p)
 
    FACE_ID is the face id of the string.  START is the index of the
    first glyph to consider, END is the index of the last + 1.
-   OVERLAPS_P non-zero means S should draw the foreground only, and
-   use its physical height for clipping.
+   OVERLAPS non-zero means S should draw the foreground only, and use
+   its physical height for clipping.  See also draw_glyphs.
 
    Value is the index of the first glyph not in S.  */
 
 static int
-fill_glyph_string (s, face_id, start, end, overlaps_p)
+fill_glyph_string (s, face_id, start, end, overlaps)
      struct glyph_string *s;
      int face_id;
-     int start, end, overlaps_p;
+     int start, end, overlaps;
 {
   struct glyph *glyph, *last;
   int voffset;
@@ -18199,7 +18873,7 @@ fill_glyph_string (s, face_id, start, end, overlaps_p)
   xassert (s->nchars == 0);
   xassert (start >= 0 && end > start);
 
-  s->for_overlaps_p = overlaps_p,
+  s->for_overlaps = overlaps,
   glyph = s->row->glyphs[s->area] + start;
   last = s->row->glyphs[s->area] + end;
   voffset = glyph->voffset;
@@ -18226,7 +18900,7 @@ fill_glyph_string (s, face_id, start, end, overlaps_p)
     }
 
   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
@@ -18290,8 +18964,9 @@ 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;
 
   for (++glyph;
@@ -18311,6 +18986,35 @@ fill_stretch_glyph_string (s, row, area, start, end)
   return glyph - s->row->glyphs[s->area];
 }
 
+static XCharStruct *
+get_per_char_metric (font, font_info, char2b, font_type)
+     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 rif->per_char_metric (font, char2b, font_type);
+}
 
 /* EXPORT for RIF:
    Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
@@ -18335,9 +19039,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 (font, font_info, &char2b, glyph->font_type)))
        {
          if (pcm->rbearing > pcm->width)
            *right = pcm->rbearing - pcm->width;
@@ -18481,6 +19185,23 @@ get_char_face_and_encoding (f, c, face_id, char2b, 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
@@ -18489,7 +19210,7 @@ get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
       face_id = FACE_FOR_CHAR (f, face, c, -1, Qnil);
       face = FACE_FROM_ID (f, face_id);
     }
-  else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
+  else if (c < 128)
     {
       /* Case of ASCII in a face known to fit ASCII.  */
       STORE_XCHAR2B (char2b, 0, c);
@@ -18534,19 +19255,15 @@ set_glyph_string_background_width (s, start, last_x)
 {
   /* If the face of this glyph string has to be drawn to the end of
      the drawing area, set S->extends_to_end_of_line_p.  */
-  struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
 
   if (start == s->row->used[s->area]
       && s->area == TEXT_AREA
-      && ((s->hl == DRAW_NORMAL_TEXT
-          && (s->row->fill_line_p
-              || s->face->background != default_face->background
-              || s->face->stipple != default_face->stipple
-              || s->row->mouse_face_p))
-         || s->hl == DRAW_MOUSE_FACE
-         || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
-             && s->row->fill_line_p)))
-      s->extends_to_end_of_line_p = 1;
+      && ((s->row->fill_line_p
+          && (s->hl == DRAW_NORMAL_TEXT
+              || s->hl == DRAW_IMAGE_RAISED
+              || s->hl == DRAW_IMAGE_SUNKEN))
+         || s->hl == DRAW_MOUSE_FACE))
+    s->extends_to_end_of_line_p = 1;
 
   /* If S extends its face to the end of the line, set its
      background_width to the distance to the right edge of the drawing
@@ -18675,7 +19392,7 @@ compute_overhangs_and_x (s, x, backward_p)
         INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL);           \
         append_glyph_string (&HEAD, &TAIL, s);                            \
         s->x = (X);                                                       \
-        START = fill_glyph_string (s, face_id, START, END, overlaps_p);   \
+        START = fill_glyph_string (s, face_id, START, END, overlaps);   \
        }                                                                  \
      while (0)
 
@@ -18701,6 +19418,14 @@ compute_overhangs_and_x (s, x, backward_p)
     struct glyph_string *first_s = NULL;                                 \
     int n;                                                               \
                                                                          \
+    if (cmp->method > COMPOSITION_WITH_RULE_ALTCHARS)                    \
+      {                                                                          \
+       /* This happens only when USE_FONT_BACKEND is defined.  */        \
+       char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len);       \
+       faces = &base_face;                                               \
+      }                                                                          \
+    else                                                                 \
+      {                                                                          \
     base_face = base_face->ascii_face;                                   \
     char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len);                  \
     faces = (struct face **) alloca ((sizeof *faces) * glyph_len);       \
@@ -18708,11 +19433,18 @@ compute_overhangs_and_x (s, x, backward_p)
     for (n = 0; n < glyph_len; n++)                                      \
       {                                                                          \
        int c = COMPOSITION_GLYPH (cmp, n);                               \
-       int this_face_id = FACE_FOR_CHAR (f, base_face, c, -1, Qnil);     \
-       faces[n] = FACE_FROM_ID (f, this_face_id);                        \
-       get_char_face_and_encoding (f, c, this_face_id,                   \
+                                                                         \
+       if (c == '\t')                                                    \
+         faces[n] = NULL;                                                \
+       else                                                              \
+         {                                                               \
+           int this_face_id = FACE_FOR_CHAR (f, base_face, c, -1, Qnil); \
+           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.  */                          \
@@ -18728,7 +19460,7 @@ compute_overhangs_and_x (s, x, backward_p)
        if (n == 0)                                                       \
          first_s = s;                                                    \
                                                                          \
-       n = fill_composite_glyph_string (s, faces, overlaps_p);           \
+       n = fill_composite_glyph_string (s, faces, overlaps);             \
       }                                                                          \
                                                                          \
     ++START;                                                             \
@@ -18800,20 +19532,26 @@ compute_overhangs_and_x (s, x, backward_p)
    DRAW_IMAGE_SUNKEN   draw an image with a sunken relief around it
    DRAW_IMAGE_RAISED   draw an image with a raised relief around it
 
-   If OVERLAPS_P is non-zero, draw only the foreground of characters
-   and clip to the physical height of ROW.
+   If OVERLAPS is non-zero, draw only the foreground of characters and
+   clip to the physical height of ROW.  Non-zero value also defines
+   the overlapping part to be drawn:
+
+   OVERLAPS_PRED               overlap with preceding rows
+   OVERLAPS_SUCC               overlap with succeeding rows
+   OVERLAPS_BOTH               overlap with both preceding/succeeding rows
+   OVERLAPS_ERASED_CURSOR      overlap with erased cursor area
 
    Value is the x-position reached, relative to AREA of W.  */
 
 static int
-draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
+draw_glyphs (w, x, row, area, start, end, hl, overlaps)
      struct window *w;
      int x;
      struct glyph_row *row;
      enum glyph_row_area area;
      EMACS_INT start, end;
      enum draw_glyphs_face hl;
-     int overlaps_p;
+     int overlaps;
 {
   struct glyph_string *head, *tail;
   struct glyph_string *s;
@@ -18862,7 +19600,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
   /* If there are any glyphs with lbearing < 0 or rbearing > width in
      the row, redraw some glyphs in front or following the glyph
      strings built above.  */
-  if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
+  if (head && !overlaps && row->contains_overlapping_glyphs_p)
     {
       int dummy_x = 0;
       struct glyph_string *h, *t;
@@ -18931,6 +19669,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
       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)
@@ -18955,7 +19694,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
       /* When drawing overlapping rows, only the glyph strings'
         foreground is drawn, which doesn't erase a cursor
         completely. */
-      && !overlaps_p)
+      && !overlaps)
     {
       int x0 = clip_head ? clip_head->x : (head ? head->x : x);
       int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
@@ -19420,6 +20159,10 @@ produce_stretch_glyph (it)
   else
     ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
 
+  if (width > 0 && !it->truncate_lines_p
+      && it->current_x + width > it->last_visible_x)
+    width = it->last_visible_x - it->current_x - 1;
+
   if (width > 0 && height > 0 && it->glyph_row)
     {
       Lisp_Object object = it->stack[it->sp - 1].string;
@@ -19433,20 +20176,6 @@ produce_stretch_glyph (it)
   it->descent = it->phys_descent = height - it->ascent;
   it->nglyphs = width > 0 && height > 0 ? 1 : 0;
 
-  if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
-    {
-      if (face->box_line_width > 0)
-       {
-         it->ascent += face->box_line_width;
-         it->descent += face->box_line_width;
-       }
-
-      if (it->start_of_box_run_p)
-       it->pixel_width += abs (face->box_line_width);
-      if (it->end_of_box_run_p)
-       it->pixel_width += abs (face->box_line_width);
-    }
-
   take_vertical_position_into_account (it);
 }
 
@@ -19530,7 +20259,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;
@@ -19560,8 +20289,8 @@ calc_line_height_property (it, val, font, boff, override)
 
 /* RIF:
    Produce glyphs/get display metrics for the display element IT is
-   loaded with.  See the description of struct display_iterator in
-   dispextern.h for an overview of struct display_iterator.  */
+   loaded with.  See the description of struct it in dispextern.h
+   for an overview of struct it.  */
 
 void
 x_produce_glyphs (it)
@@ -19624,7 +20353,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;
@@ -19638,7 +20367,7 @@ x_produce_glyphs (it)
 
          it->nglyphs = 1;
 
-         pcm = rif->per_char_metric (font, &char2b,
+         pcm = get_per_char_metric (font, font_info, &char2b,
                                      FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
 
          if (it->override_ascent >= 0)
@@ -19869,7 +20598,7 @@ x_produce_glyphs (it)
             multiplying the width of font by the width of the
             character.  */
 
-         pcm = rif->per_char_metric (font, &char2b,
+         pcm = get_per_char_metric (font, font_info, &char2b,
                                      FONT_TYPE_FOR_MULTIBYTE (font, it->c));
 
          if (font_not_found_p || !pcm)
@@ -19964,7 +20693,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;
@@ -19988,6 +20717,13 @@ x_produce_glyphs (it)
          cmp->lbearing = cmp->rbearing = 0;
          cmp->pixel_width = cmp->ascent = cmp->descent = 0;
        }
+#ifdef USE_FONT_BACKEND
+      else if (cmp->method == COMPOSITION_WITH_GLYPH_STRING)
+       {
+         if (! cmp->font)
+           font_prepare_composition (cmp);
+       }
+#endif /* USE_FONT_BACKEND */
       else if (cmp->font != (void *) font)
        {
          /* Ascent and descent of the font of the first character of
@@ -20001,12 +20737,13 @@ x_produce_glyphs (it)
          int leftmost, rightmost, lowest, highest;
          int lbearing, rbearing;
          int i, width, ascent, descent;
+         int fully_padded = 0;
 
          cmp->font = (void *) font;
 
          /* Initialize the bounding box.  */
          if (font_info
-             && (pcm = rif->per_char_metric (font, &char2b,
+             && (pcm = get_per_char_metric (font, font_info, &char2b,
                                              FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
            {
              width = pcm->width;
@@ -20053,8 +20790,17 @@ x_produce_glyphs (it)
            {
              int left, right, btm, top;
              int ch = COMPOSITION_GLYPH (cmp, i);
-             int face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
+             int face_id;
 
+             if (ch == '\t')
+               {
+                 fully_padded = 1;
+                 cmp->offsets[i * 2] = 0;
+                 cmp->offsets[i * 2 + 1] = boff;
+                 continue;
+               }
+
+             face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
              face = FACE_FROM_ID (it->f, face_id);
              get_char_face_and_encoding (it->f, ch, face->id,
                                          &char2b, it->multibyte_p, 0);
@@ -20068,14 +20814,14 @@ x_produce_glyphs (it)
              else
                {
                  font_info
-                   = FONT_INFO_FROM_ID (it->f, face->font_info_id);
+                   = 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;
                }
 
              if (font_info
-                 && (pcm = rif->per_char_metric (font, &char2b,
+                 && (pcm = get_per_char_metric (font, font_info, &char2b,
                                                  FONT_TYPE_FOR_MULTIBYTE (font, ch))))
                {
                  width = pcm->width;
@@ -20197,6 +20943,15 @@ x_produce_glyphs (it)
              cmp->rbearing -= leftmost;
            }
 
+         if (fully_padded)
+           {
+             for (i = 0; i < cmp->glyph_len; i++)
+               cmp->offsets[i * 2] -= cmp->lbearing;
+             rightmost = cmp->rbearing - cmp->lbearing;
+             cmp->lbearing = 0;
+             cmp->rbearing = rightmost; 
+           }
+
          cmp->pixel_width = rightmost;
          cmp->ascent = highest;
          cmp->descent = - lowest;
@@ -20561,8 +21316,13 @@ get_window_cursor_type (w, glyph, width, active_cursor)
     {
       if (w == XWINDOW (echo_area_window))
        {
-         *width = FRAME_CURSOR_WIDTH (f);
-         return FRAME_DESIRED_CURSOR (f);
+         if (EQ (b->cursor_type, Qt) || NILP (b->cursor_type))
+           {
+             *width = FRAME_CURSOR_WIDTH (f);
+             return FRAME_DESIRED_CURSOR (f);
+           }
+         else
+           return get_specified_cursor_type (b->cursor_type, width);
        }
 
       *active_cursor = 0;
@@ -20591,7 +21351,7 @@ get_window_cursor_type (w, glyph, width, active_cursor)
   /* Use cursor-in-non-selected-windows for non-selected window or frame.  */
   if (non_selected)
     {
-      alt_cursor = XBUFFER (w->buffer)->cursor_in_non_selected_windows;
+      alt_cursor = b->cursor_in_non_selected_windows;
       return get_specified_cursor_type (alt_cursor, width);
     }
 
@@ -20728,13 +21488,15 @@ notice_overwritten_cursor (w, area, x0, x1, y0, y1)
 #ifdef HAVE_WINDOW_SYSTEM
 
 /* EXPORT for RIF:
-   Fix the display of area AREA of overlapping row ROW in window W.  */
+   Fix the display of area AREA of overlapping row ROW in window W
+   with respect to the overlapping part OVERLAPS.  */
 
 void
-x_fix_overlapping_area (w, row, area)
+x_fix_overlapping_area (w, row, area, overlaps)
      struct window *w;
      struct glyph_row *row;
      enum glyph_row_area area;
+     int overlaps;
 {
   int i, x;
 
@@ -20757,7 +21519,7 @@ x_fix_overlapping_area (w, row, area)
 
          draw_glyphs (w, start_x, row, area,
                       start, i,
-                      DRAW_NORMAL_TEXT, 1);
+                      DRAW_NORMAL_TEXT, overlaps);
        }
       else
        {
@@ -20799,13 +21561,17 @@ draw_phys_cursor_glyph (w, row, hl)
         are redrawn.  */
       else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
        {
+         w->phys_cursor_width = x1 - w->phys_cursor.x;
+
          if (row > w->current_matrix->rows
              && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
-           x_fix_overlapping_area (w, row - 1, TEXT_AREA);
+           x_fix_overlapping_area (w, row - 1, TEXT_AREA,
+                                   OVERLAPS_ERASED_CURSOR);
 
          if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
              && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
-           x_fix_overlapping_area (w, row + 1, TEXT_AREA);
+           x_fix_overlapping_area (w, row + 1, TEXT_AREA,
+                                   OVERLAPS_ERASED_CURSOR);
        }
     }
 }
@@ -20890,7 +21656,7 @@ erase_phys_cursor (w)
   /* Maybe clear the display under the cursor.  */
   if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
     {
-      int x, y;
+      int x, y, left_x;
       int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
       int width;
 
@@ -20898,11 +21664,16 @@ erase_phys_cursor (w)
       if (cursor_glyph == NULL)
        goto mark_cursor_off;
 
-      x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
+      width = cursor_glyph->pixel_width;
+      left_x = window_box_left_offset (w, TEXT_AREA);
+      x = w->phys_cursor.x;
+      if (x < left_x)
+       width -= left_x - x;
+      width = min (width, window_box_width (w, TEXT_AREA) - x);
       y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
-      width = min (cursor_glyph->pixel_width,
-                  window_box_width (w, TEXT_AREA) - w->phys_cursor.x);
+      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);
     }
 
@@ -21120,7 +21891,11 @@ show_mouse_face (dpyinfo, draw)
          if (row == last)
            end_hpos = dpyinfo->mouse_face_end_col;
          else
-           end_hpos = row->used[TEXT_AREA];
+           {
+             end_hpos = row->used[TEXT_AREA];
+             if (draw == DRAW_NORMAL_TEXT)
+               row->fill_line_p = 1; /* Clear to end of line */
+           }
 
          if (end_hpos > start_hpos)
            {
@@ -21991,7 +22766,10 @@ note_mouse_highlight (f, x, y)
     }
 
   if (part == ON_VERTICAL_BORDER)
-    cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
+    {
+      cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
+      help_echo_string = build_string ("drag-mouse-1: resize");
+    }
   else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
           || part == ON_SCROLL_BAR)
     cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
@@ -22596,13 +23374,13 @@ expose_overlaps (w, first_overlapping_row, last_overlapping_row)
        xassert (row->enabled_p && !row->mode_line_p);
 
        if (row->used[LEFT_MARGIN_AREA])
-         x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
+         x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
 
        if (row->used[TEXT_AREA])
-         x_fix_overlapping_area (w, row, TEXT_AREA);
+         x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
 
        if (row->used[RIGHT_MARGIN_AREA])
-         x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
+         x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
       }
 }
 
@@ -23362,6 +24140,14 @@ otherwise.  */);
     doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible.  */);
   make_cursor_line_fully_visible_p = 1;
 
+  DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border,
+    doc: /* *Border below tool-bar in pixels.
+If an integer, use it as the height of the border.
+If it is one of `internal-border-width' or `border-width', use the
+value of the corresponding frame parameter.
+Otherwise, no border is added below the tool-bar.  */);
+  Vtool_bar_border = Qinternal_border_width;
+
   DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
     doc: /* *Margin around tool-bar buttons in pixels.
 If an integer, use that for both horizontal and vertical margins.
@@ -23411,7 +24197,11 @@ go back to their normal size.  */);
 Each element has the form (ON-STATE . OFF-STATE).  Whenever the
 `cursor-type' frame-parameter or variable equals ON-STATE,
 comparing using `equal', Emacs uses OFF-STATE to specify
-how to blink it off.  */);
+how to blink it off.  ON-STATE and OFF-STATE are values for
+the `cursor-type' frame parameter.
+
+If a frame's ON-STATE has no entry in this list,
+the frame's other specifications determine how to blink the cursor off.  */);
   Vblink_cursor_alist = Qnil;
 
   DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
@@ -23425,7 +24215,7 @@ before automatic hscrolling will horizontally scroll the window.  */);
 
   DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
     doc: /* *How many columns to scroll the window when point gets too close to the edge.
-When point is less than `automatic-hscroll-margin' columns from the window
+When point is less than `hscroll-margin' columns from the window
 edge, automatic hscrolling will scroll the window by the amount of columns
 determined by this variable.  If its value is a positive integer, scroll that
 many columns.  If it's a positive floating-point number, it specifies the