]> code.delx.au - gnu-emacs/blobdiff - src/xdisp.c
(ses-call-printer-return): Doc fix (Nil -> nil).
[gnu-emacs] / src / xdisp.c
index 83483039b5413d56d5718ba834a22e17ed4ef5b3..8dc34b776c4010a1383c32f5765584a9ea0fffb8 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.
 
@@ -256,9 +256,9 @@ Lisp_Object list_of_error;
 Lisp_Object Vfontification_functions;
 Lisp_Object Qfontification_functions;
 
-/* Non-zero means automatically select any window when the mouse
+/* Non-nil means automatically select any window when the mouse
    cursor moves into it.  */
-int mouse_autoselect_window;
+Lisp_Object Vmouse_autoselect_window;
 
 /* Non-zero means draw tool bar buttons raised when the mouse moves
    over them.  */
@@ -269,6 +269,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;
@@ -609,6 +615,11 @@ int message_buf_print;
 Lisp_Object Qinhibit_menubar_update;
 int inhibit_menubar_update;
 
+/* When evaluating expressions from menu bar items (enable conditions,
+   for instance), this is the frame they are being processed for.  */
+
+Lisp_Object Vmenu_updating_frame;
+
 /* Maximum height for resizing mini-windows.  Either a float
    specifying a fraction of the available height, or an integer
    specifying a number of lines.  */
@@ -704,6 +715,10 @@ Lisp_Object Vresize_mini_windows;
 
 struct buffer *displayed_buffer;
 
+/* Space between overline and text. */
+
+EMACS_INT overline_margin;
+
 /* Value returned from text property handlers (see below).  */
 
 enum prop_handled
@@ -852,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));
@@ -894,7 +909,7 @@ static void redisplay_window P_ ((Lisp_Object, int));
 static Lisp_Object redisplay_window_error ();
 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
-static void update_menu_bar P_ ((struct frame *, int));
+static int update_menu_bar P_ ((struct frame *, int, int));
 static int try_window_reusing_current_matrix P_ ((struct window *));
 static int try_window_id P_ ((struct window *));
 static int display_line P_ ((struct it *));
@@ -910,6 +925,7 @@ static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
 static void compute_line_metrics P_ ((struct it *));
 static void run_redisplay_end_trigger_hook P_ ((struct it *));
 static int get_overlay_strings P_ ((struct it *, int));
+static int get_overlay_strings_1 P_ ((struct it *, int, int));
 static void next_overlay_string P_ ((struct it *));
 static void reseat P_ ((struct it *, struct text_pos, int));
 static void reseat_1 P_ ((struct it *, struct text_pos, int));
@@ -963,7 +979,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));
@@ -1259,15 +1275,15 @@ line_bottom_y (it)
 
 
 /* Return 1 if position CHARPOS is visible in window W.
+   CHARPOS < 0 means return info about WINDOW_END position.
    If visible, set *X and *Y to pixel coordinates of top left corner.
    Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
-   EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
-   and header-lines heights.  */
+   Set *ROWH and *VPOS to row's visible height and VPOS (row number).  */
 
 int
-pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
+pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
      struct window *w;
-     int charpos, *x, *y, *rtop, *rbot, exact_mode_line_heights_p;
+     int charpos, *x, *y, *rtop, *rbot, *rowh, *vpos;
 {
   struct it it;
   struct text_pos top;
@@ -1285,26 +1301,23 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
 
   SET_TEXT_POS_FROM_MARKER (top, w->start);
 
-  /* Compute exact mode line heights, if requested.  */
-  if (exact_mode_line_heights_p)
-    {
-      if (WINDOW_WANTS_MODELINE_P (w))
-       current_mode_line_height
-         = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
-                              current_buffer->mode_line_format);
+  /* Compute exact mode line heights.  */
+  if (WINDOW_WANTS_MODELINE_P (w))
+    current_mode_line_height
+      = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
+                          current_buffer->mode_line_format);
 
-      if (WINDOW_WANTS_HEADER_LINE_P (w))
-       current_header_line_height
-         = display_mode_line (w, HEADER_LINE_FACE_ID,
+  if (WINDOW_WANTS_HEADER_LINE_P (w))
+    current_header_line_height
+      = display_mode_line (w, HEADER_LINE_FACE_ID,
                               current_buffer->header_line_format);
-    }
 
   start_display (&it, w, top);
-  move_it_to (&it, charpos, -1, it.last_visible_y, -1,
-             MOVE_TO_POS | MOVE_TO_Y);
+  move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
+             (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
 
   /* Note that we may overshoot because of invisible text.  */
-  if (IT_CHARPOS (it) >= charpos)
+  if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
     {
       int top_x = it.current_x;
       int top_y = it.current_y;
@@ -1321,6 +1334,9 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
          *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
          *rtop = max (0, window_top_y - top_y);
          *rbot = max (0, bottom_y - it.last_visible_y);
+         *rowh = max (0, (min (bottom_y, it.last_visible_y)
+                          - max (top_y, window_top_y)));
+         *vpos = it.vpos;
        }
     }
   else
@@ -1330,7 +1346,8 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
       it2 = it;
       if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
        move_it_by_lines (&it, 1, 0);
-      if (charpos < IT_CHARPOS (it))
+      if (charpos < IT_CHARPOS (it)
+         || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
        {
          visible_p = 1;
          move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
@@ -1339,6 +1356,11 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
          *rtop = max (0, -it2.current_y);
          *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
                           - it.last_visible_y));
+         *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
+                               it.last_visible_y)
+                          - max (it2.current_y,
+                                 WINDOW_HEADER_LINE_HEIGHT (w))));
+         *vpos = it2.vpos;
        }
     }
 
@@ -1347,8 +1369,17 @@ 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 && w->hscroll > 0)
-    *x -= w->hscroll;
+  if (visible_p && XFASTINT (w->hscroll) > 0)
+    *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
+
+#if 0
+  /* Debugging code.  */
+  if (visible_p)
+    fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
+            charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
+  else
+    fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
+#endif
 
   return visible_p;
 }
@@ -1768,15 +1799,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.  */
@@ -1819,10 +1855,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
     {
@@ -1881,11 +1934,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, *nr);
+      CONVERT_FROM_XRECT (r, *rects);
 #else
-  *nr = r;
+      *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
+      XRectangle rs[2];
+#else
+      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);
 }
 
 
@@ -1894,15 +2011,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
@@ -1912,6 +2029,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);
@@ -1941,8 +2066,202 @@ 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.  */
+
+  if (!f->glyphs_initialized_p
+      || (window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0),
+         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
 }
 
 
@@ -2616,8 +2935,8 @@ init_from_display_pos (it, w, pos)
         also ``processed'' overlay strings at ZV.  */
       while (it->sp)
        pop_it (it);
-      it->current.overlay_string_index = -1;
-      it->method = GET_FROM_BUFFER;
+      xassert (it->current.overlay_string_index == -1);
+      xassert (it->method == GET_FROM_BUFFER);
       if (CHARPOS (pos->pos) == ZV)
        it->overlay_strings_at_end_processed_p = 1;
     }
@@ -2704,11 +3023,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)
@@ -2726,7 +3047,19 @@ handle_stop (it)
          if (handled == HANDLED_RECOMPUTE_PROPS)
            break;
          else if (handled == HANDLED_RETURN)
-           return;
+           {
+             /* We still want to show before and after strings from
+                overlays even if the actual buffer text is replaced.  */
+             if (!handle_overlay_change_p || it->sp > 1)
+               return;
+             if (!get_overlay_strings_1 (it, 0, 0))
+               return;
+             it->ignore_overlay_strings_at_pos_p = 1;
+             it->string_from_display_prop_p = 0;
+             handle_overlay_change_p = 0;
+             handled = HANDLED_RECOMPUTE_PROPS;
+             break;
+           }
          else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
            handle_overlay_change_p = 0;
        }
@@ -2902,6 +3235,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
@@ -2912,7 +3248,9 @@ handle_fontified_prop (it)
       && !NILP (Vrun_hooks)
       && (pos = make_number (IT_CHARPOS (*it)),
          prop = Fget_char_property (pos, Qfontified, Qnil),
-         NILP (prop)))
+         /* Ignore the special cased nil value always present at EOB since
+            no amount of fontifying will be able to change it.  */
+         NILP (prop) && IT_CHARPOS (*it) < Z))
     {
       int count = SPECPDL_INDEX ();
       Lisp_Object val;
@@ -3335,6 +3673,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);
 
@@ -3355,7 +3698,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);
+            }
        }
     }
 
@@ -3428,7 +3790,7 @@ handle_display_prop (it)
     }
   else
     {
-      object = it->w->buffer;
+      XSETWINDOW (object, it->w);
       position = &it->current.pos;
     }
 
@@ -3449,6 +3811,9 @@ handle_display_prop (it)
   if (NILP (prop))
     return HANDLED_NORMALLY;
 
+  if (!STRINGP (it->string))
+    object = it->w->buffer;
+
   if (CONSP (prop)
       /* Simple properties.  */
       && !EQ (XCAR (prop), Qimage)
@@ -3542,7 +3907,7 @@ handle_single_display_spec (it, spec, object, position,
 {
   Lisp_Object form;
   Lisp_Object location, value;
-  struct text_pos start_pos;
+  struct text_pos start_pos, save_pos;
   int valid_p;
 
   /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
@@ -3759,7 +4124,10 @@ handle_single_display_spec (it, spec, object, position,
       /* Save current settings of IT so that we can restore them
         when we are finished with the glyph property value.  */
 
+      save_pos = it->position;
+      it->position = *position;
       push_it (it);
+      it->position = save_pos;
 
       it->area = TEXT_AREA;
       it->what = IT_IMAGE;
@@ -3833,7 +4201,10 @@ handle_single_display_spec (it, spec, object, position,
     {
       /* Save current settings of IT so that we can restore them
         when we are finished with the glyph property value.  */
+      save_pos = it->position;
+      it->position = *position;
       push_it (it);
+      it->position = save_pos;
 
       if (NILP (location))
        it->area = TEXT_AREA;
@@ -3866,7 +4237,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
@@ -4131,6 +4502,28 @@ 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->stop_charpos = end;
+         push_it (it);
+
          it->method = GET_FROM_COMPOSITION;
          it->cmp_id = id;
          it->cmp_len = COMPOSITION_LENGTH (prop);
@@ -4140,7 +4533,6 @@ handle_composition_prop (it)
          it->len = (STRINGP (it->string)
                     ? string_char_to_byte (it->string, end)
                     : CHAR_TO_BYTE (end)) - pos_byte;
-         it->stop_charpos = end;
          handled = HANDLED_RETURN;
        }
     }
@@ -4200,13 +4592,14 @@ next_overlay_string (it)
       int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
 
       pop_it (it);
-      xassert (it->stop_charpos >= BEGV
-              && it->stop_charpos <= it->end_charpos);
-      it->string = Qnil;
+      xassert (it->sp > 0
+              || it->method == GET_FROM_COMPOSITION
+              || (NILP (it->string)
+                  && it->method == GET_FROM_BUFFER
+                  && it->stop_charpos >= BEGV
+                  && it->stop_charpos <= it->end_charpos));
       it->current.overlay_string_index = -1;
-      SET_TEXT_POS (it->current.string_pos, -1, -1);
       it->n_overlay_strings = 0;
-      it->method = GET_FROM_BUFFER;
 
       /* If we're at the end of the buffer, record that we have
         processed the overlay strings there already, so that
@@ -4462,7 +4855,7 @@ load_overlay_strings (it, charpos)
    least one overlay string was found.  */
 
 static int
-get_overlay_strings (it, charpos)
+get_overlay_strings_1 (it, charpos, compute_stop_p)
      struct it *it;
      int charpos;
 {
@@ -4484,12 +4877,13 @@ get_overlay_strings (it, charpos)
       /* Make sure we know settings in current_buffer, so that we can
         restore meaningful values when we're done with the overlay
         strings.  */
-      compute_stop_pos (it);
+      if (compute_stop_p)
+       compute_stop_pos (it);
       xassert (it->face_id >= 0);
 
       /* Save IT's settings.  They are restored after all overlay
         strings have been processed.  */
-      xassert (it->sp == 0);
+      xassert (!compute_stop_p || it->sp == 0);
       push_it (it);
 
       /* Set up IT to deliver display elements from the first overlay
@@ -4501,14 +4895,23 @@ get_overlay_strings (it, charpos)
       it->end_charpos = SCHARS (it->string);
       it->multibyte_p = STRING_MULTIBYTE (it->string);
       it->method = GET_FROM_STRING;
-    }
-  else
-    {
-      it->string = Qnil;
-      it->current.overlay_string_index = -1;
-      it->method = GET_FROM_BUFFER;
+      return 1;
     }
 
+  it->current.overlay_string_index = -1;
+  return 0;
+}
+
+static int
+get_overlay_strings (it, charpos)
+     struct it *it;
+     int charpos;
+{
+  it->string = Qnil;
+  it->method = GET_FROM_BUFFER;
+
+  (void) get_overlay_strings_1 (it, charpos, 1);
+
   CHECK_IT (it);
 
   /* Value is non-zero if we found at least one overlay string.  */
@@ -4532,19 +4935,38 @@ push_it (it)
 {
   struct iterator_stack_entry *p;
 
-  xassert (it->sp < 2);
+  xassert (it->sp < IT_STACK_SIZE);
   p = it->stack + it->sp;
 
   p->stop_charpos = it->stop_charpos;
   xassert (it->face_id >= 0);
   p->face_id = it->face_id;
   p->string = it->string;
-  p->pos = it->current;
+  p->method = it->method;
+  switch (p->method)
+    {
+    case GET_FROM_IMAGE:
+      p->u.image.object = it->object;
+      p->u.image.image_id = it->image_id;
+      p->u.image.slice = it->slice;
+      break;
+    case GET_FROM_COMPOSITION:
+      p->u.comp.object = it->object;
+      p->u.comp.c = it->c;
+      p->u.comp.len = it->len;
+      p->u.comp.cmp_id = it->cmp_id;
+      p->u.comp.cmp_len = it->cmp_len;
+      break;
+    case GET_FROM_STRETCH:
+      p->u.stretch.object = it->object;
+      break;
+    }
+  p->position = it->position;
+  p->current = it->current;
   p->end_charpos = it->end_charpos;
   p->string_nchars = it->string_nchars;
   p->area = it->area;
   p->multibyte_p = it->multibyte_p;
-  p->slice = it->slice;
   p->space_width = it->space_width;
   p->font_height = it->font_height;
   p->voffset = it->voffset;
@@ -4571,13 +4993,40 @@ pop_it (it)
   p = it->stack + it->sp;
   it->stop_charpos = p->stop_charpos;
   it->face_id = p->face_id;
+  it->current = p->current;
+  it->position = p->position;
   it->string = p->string;
-  it->current = p->pos;
+  if (NILP (it->string))
+    SET_TEXT_POS (it->current.string_pos, -1, -1);
+  it->method = p->method;
+  switch (it->method)
+    {
+    case GET_FROM_IMAGE:
+      it->image_id = p->u.image.image_id;
+      it->object = p->u.image.object;
+      it->slice = p->u.image.slice;
+      break;
+    case GET_FROM_COMPOSITION:
+      it->object = p->u.comp.object;
+      it->c = p->u.comp.c;
+      it->len = p->u.comp.len;
+      it->cmp_id = p->u.comp.cmp_id;
+      it->cmp_len = p->u.comp.cmp_len;
+      break;
+    case GET_FROM_STRETCH:
+      it->object = p->u.comp.object;
+      break;
+    case GET_FROM_BUFFER:
+      it->object = it->w->buffer;
+      break;
+    case GET_FROM_STRING:
+      it->object = it->string;
+      break;
+    }
   it->end_charpos = p->end_charpos;
   it->string_nchars = p->string_nchars;
   it->area = p->area;
   it->multibyte_p = p->multibyte_p;
-  it->slice = p->slice;
   it->space_width = p->space_width;
   it->font_height = p->font_height;
   it->voffset = p->voffset;
@@ -4709,6 +5158,7 @@ back_to_previous_visible_line_start (it)
   while (IT_CHARPOS (*it) > BEGV)
     {
       back_to_previous_line_start (it);
+
       if (IT_CHARPOS (*it) <= BEGV)
        break;
 
@@ -4728,37 +5178,47 @@ back_to_previous_visible_line_start (it)
          continue;
       }
 
-      /* If newline has a display property that replaces the newline with something
-        else (image or text), find start of overlay or interval and continue search
-        from that point.  */
-      if (IT_CHARPOS (*it) > BEGV)
-       {
-         struct it it2 = *it;
-         int pos;
-         int beg, end;
-         Lisp_Object val, overlay;
-
-         pos = --IT_CHARPOS (it2);
-         --IT_BYTEPOS (it2);
-         it2.sp = 0;
-         if (handle_display_prop (&it2) == HANDLED_RETURN
-             && !NILP (val = get_char_property_and_overlay
-                       (make_number (pos), Qdisplay, Qnil, &overlay))
-             && (OVERLAYP (overlay)
-                 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
-                 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
-           {
-             if (beg < BEGV)
-               beg = BEGV;
-             IT_CHARPOS (*it) = beg;
-             IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
-             continue;
-           }
-       }
+      if (IT_CHARPOS (*it) <= BEGV)
+       break;
 
-      break;
+      {
+       struct it it2;
+       int pos;
+       int beg, end;
+       Lisp_Object val, overlay;
+
+       /* If newline is part of a composition, continue from start of composition */
+       if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
+           && beg < IT_CHARPOS (*it))
+         goto replaced;
+
+       /* If newline is replaced by a display property, find start of overlay
+          or interval and continue search from that point.  */
+       it2 = *it;
+       pos = --IT_CHARPOS (it2);
+       --IT_BYTEPOS (it2);
+       it2.sp = 0;
+       if (handle_display_prop (&it2) == HANDLED_RETURN
+           && !NILP (val = get_char_property_and_overlay
+                     (make_number (pos), Qdisplay, Qnil, &overlay))
+           && (OVERLAYP (overlay)
+               ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
+               : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
+         goto replaced;
+
+       /* Newline is not replaced by anything -- so we are done.  */
+       break;
+
+      replaced:
+       if (beg < BEGV)
+         beg = BEGV;
+       IT_CHARPOS (*it) = beg;
+       IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
+      }
     }
 
+  it->continuation_lines_width = 0;
+
   xassert (IT_CHARPOS (*it) >= BEGV);
   xassert (IT_CHARPOS (*it) == BEGV
           || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
@@ -4804,7 +5264,8 @@ reseat_at_next_visible_line_start (it, on_newline_p)
           && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
                                 (double) it->selective)) /* iftc */
       {
-       xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
+       xassert (IT_BYTEPOS (*it) == BEGV
+                || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
        newline_found_p = forward_to_next_line_start (it, &skipped_p);
       }
 
@@ -4880,7 +5341,6 @@ reseat_1 (it, pos, set_stop_p)
   xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
 
   it->current.pos = it->position = pos;
-  XSETBUFFER (it->object, current_buffer);
   it->end_charpos = ZV;
   it->dpvec = NULL;
   it->current.dpvec_index = -1;
@@ -4889,15 +5349,11 @@ reseat_1 (it, pos, set_stop_p)
   IT_STRING_BYTEPOS (*it) = -1;
   it->string = Qnil;
   it->method = GET_FROM_BUFFER;
-  /* RMS: I added this to fix a bug in move_it_vertically_backward
-     where it->area continued to relate to the starting point
-     for the backward motion.  Bug report from
-     Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
-     However, I am not sure whether reseat still does the right thing
-     in general after this change.  */
+  it->object = it->w->buffer;
   it->area = TEXT_AREA;
   it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
   it->sp = 0;
+  it->string_from_display_prop_p = 0;
   it->face_before_selective_p = 0;
 
   if (set_stop_p)
@@ -5025,6 +5481,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;
@@ -5141,11 +5601,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);
@@ -5192,11 +5660,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
@@ -5356,18 +5832,18 @@ set_iterator_to_next (it, reseat_p)
 
     case GET_FROM_COMPOSITION:
       xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
-      if (STRINGP (it->string))
+      xassert (it->sp > 0);
+      pop_it (it);
+      if (it->method == GET_FROM_STRING)
        {
          IT_STRING_BYTEPOS (*it) += it->len;
          IT_STRING_CHARPOS (*it) += it->cmp_len;
-         it->method = GET_FROM_STRING;
          goto consider_string_end;
        }
-      else
+      else if (it->method == GET_FROM_BUFFER)
        {
          IT_BYTEPOS (*it) += it->len;
          IT_CHARPOS (*it) += it->cmp_len;
-         it->method = GET_FROM_BUFFER;
        }
       break;
 
@@ -5390,12 +5866,17 @@ 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))
            it->method = GET_FROM_STRING;
          else
-           it->method = GET_FROM_BUFFER;
+           {
+             it->method = GET_FROM_BUFFER;
+             it->object = it->w->buffer;
+           }
 
          it->dpvec = NULL;
          it->current.dpvec_index = -1;
@@ -5405,12 +5886,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;
 
@@ -5439,9 +5924,8 @@ set_iterator_to_next (it, reseat_p)
              && it->sp > 0)
            {
              pop_it (it);
-             if (STRINGP (it->string))
+             if (it->method == GET_FROM_STRING)
                goto consider_string_end;
-             it->method = GET_FROM_BUFFER;
            }
        }
       break;
@@ -5453,13 +5937,8 @@ set_iterator_to_next (it, reseat_p)
          if the `display' property takes up the whole string.  */
       xassert (it->sp > 0);
       pop_it (it);
-      it->image_id = 0;
-      if (STRINGP (it->string))
-       {
-         it->method = GET_FROM_STRING;
-         goto consider_string_end;
-       }
-      it->method = GET_FROM_BUFFER;
+      if (it->method == GET_FROM_STRING)
+       goto consider_string_end;
       break;
 
     default:
@@ -5604,9 +6083,7 @@ next_element_from_string (it)
        }
     }
 
-  /* Record what we have and where it came from.  Note that we store a
-     buffer position in IT->position although it could arguably be a
-     string position.  */
+  /* Record what we have and where it came from.  */
   it->what = IT_CHARACTER;
   it->object = it->string;
   it->position = position;
@@ -5682,6 +6159,7 @@ next_element_from_ellipsis (it)
         setting face_before_selective_p.  */
       it->saved_face_id = it->face_id;
       it->method = GET_FROM_BUFFER;
+      it->object = it->w->buffer;
       reseat_at_next_visible_line_start (it, 1);
       it->face_before_selective_p = 1;
     }
@@ -5868,6 +6346,10 @@ 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;
+  else
+    it->object = it->w->buffer;
   return 1;
 }
 
@@ -6012,6 +6494,8 @@ move_it_in_display_line_to (it, to_charpos, to_x, op)
             glyphs have the same width.  */
          int single_glyph_width = it->pixel_width / it->nglyphs;
          int new_x;
+         int x_before_this_char = x;
+         int hpos_before_this_char = it->hpos;
 
          for (i = 0; i < it->nglyphs; ++i, x = new_x)
            {
@@ -6043,8 +6527,22 @@ move_it_in_display_line_to (it, to_charpos, to_x, op)
                    {
                      ++it->hpos;
                      it->current_x = new_x;
+
+                     /* The character's last glyph just barely fits
+                        in this row.  */
                      if (i == it->nglyphs - 1)
                        {
+                         /* If this is the destination position,
+                            return a position *before* it in this row,
+                            now that we know it fits in this row.  */
+                         if (BUFFER_POS_REACHED_P ())
+                           {
+                             it->hpos = hpos_before_this_char;
+                             it->current_x = x_before_this_char;
+                             result = MOVE_POS_MATCH_OR_ZV;
+                             break;
+                           }
+
                          set_iterator_to_next (it, 1);
 #ifdef HAVE_WINDOW_SYSTEM
                          if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
@@ -6300,6 +6798,10 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
          if (reached)
            break;
        }
+      else if (BUFFERP (it->object)
+              && it->method == GET_FROM_BUFFER
+              && IT_CHARPOS (*it) >= to_charpos)
+       skip = MOVE_POS_MATCH_OR_ZV;
       else
        skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
 
@@ -6506,6 +7008,7 @@ move_it_vertically (it, dy)
       /* If buffer ends in ZV without a newline, move to the start of
         the line to satisfy the post-condition.  */
       if (IT_CHARPOS (*it) == ZV
+         && ZV > BEGV
          && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
        move_it_by_lines (it, 0, 0);
     }
@@ -6731,7 +7234,10 @@ message_log_maybe_newline ()
    terminated with a newline when NLFLAG is non-zero.  MULTIBYTE, if
    nonzero, means interpret the contents of M as multibyte.  This
    function calls low-level routines in order to bypass text property
-   hooks, etc. which might not be safe to run.  */
+   hooks, etc. which might not be safe to run.
+
+   This may GC (insert may run before/after change hooks),
+   so the buffer M must NOT point to a Lisp string.  */
 
 void
 message_dolog (m, nbytes, nlflag, multibyte)
@@ -6942,10 +7448,7 @@ message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
    out any existing message, and let the mini-buffer text show
    through.
 
-   The buffer M must continue to exist until after the echo area gets
-   cleared or some other message gets displayed there.  This means do
-   not pass text that is stored in a Lisp string; do not pass text in
-   a buffer that was alloca'd.  */
+   This may GC, so the buffer M must NOT point to a Lisp string.  */
 
 void
 message2 (m, nbytes, multibyte)
@@ -7042,7 +7545,15 @@ message3 (m, nbytes, multibyte)
   /* First flush out any partial line written with print.  */
   message_log_maybe_newline ();
   if (STRINGP (m))
-    message_dolog (SDATA (m), nbytes, 1, multibyte);
+    {
+      char *buffer;
+      USE_SAFE_ALLOCA;
+
+      SAFE_ALLOCA (buffer, char *, nbytes);
+      bcopy (SDATA (m), buffer, nbytes);
+      message_dolog (buffer, nbytes, 1, multibyte);
+      SAFE_FREE ();
+    }
   message3_nolog (m, nbytes, multibyte);
 
   UNGCPRO;
@@ -7697,7 +8208,7 @@ resize_mini_window_1 (a1, exactly, a3, a4)
 /* Resize mini-window W to fit the size of its contents.  EXACT:P
    means size the window exactly to the size needed.  Otherwise, it's
    only enlarged until W's buffer is empty.
-   
+
    Set W->start to the right place to begin display.  If the whole
    contents fit, start at the beginning.  Otherwise, start so as
    to make the end of the contents appear.  This is particularly
@@ -7786,7 +8297,6 @@ resize_mini_window (w, exact_p)
          init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
          move_it_vertically_backward (&it, (height - 1) * unit);
          start = it.current.pos;
-         SET_PT_BOTH (CHARPOS (start), BYTEPOS (start));
        }
       else
        SET_TEXT_POS (start, BEGV, BEGV_BYTE);
@@ -7995,7 +8505,11 @@ truncate_message_1 (nchars, a2, a3, a4)
 
    If S is not null, set the message to the first LEN bytes of S.  LEN
    zero means use the whole string.  MULTIBYTE_P non-zero means S is
-   multibyte.  Display the message multibyte in that case.  */
+   multibyte.  Display the message multibyte in that case.
+
+   Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
+   to t before calling set_message_1 (which calls insert).
+  */
 
 void
 set_message (s, string, nbytes, multibyte_p)
@@ -8310,7 +8824,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;
@@ -8326,7 +8840,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;
 
@@ -8345,7 +8859,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);
 
@@ -8468,7 +8983,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;
@@ -8548,6 +9063,9 @@ prepare_menu_bars ()
     {
       Lisp_Object tail, frame;
       int count = SPECPDL_INDEX ();
+      /* 1 means that update_menu_bar has run its hooks
+        so any further calls to update_menu_bar shouldn't do so again.  */
+      int menu_bar_hooks_run = 0;
 
       record_unwind_save_match_data ();
 
@@ -8579,9 +9097,12 @@ prepare_menu_bars ()
            }
 
          GCPRO1 (tail);
-         update_menu_bar (f, 0);
+         menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
 #ifdef HAVE_WINDOW_SYSTEM
          update_tool_bar (f, 0);
+#ifdef MAC_OS
+         mac_update_title_bar (f, 0);
+#endif
 #endif
          UNGCPRO;
        }
@@ -8591,9 +9112,12 @@ prepare_menu_bars ()
   else
     {
       struct frame *sf = SELECTED_FRAME ();
-      update_menu_bar (sf, 1);
+      update_menu_bar (sf, 1, 0);
 #ifdef HAVE_WINDOW_SYSTEM
       update_tool_bar (sf, 1);
+#ifdef MAC_OS
+      mac_update_title_bar (sf, 1);
+#endif
 #endif
     }
 
@@ -8609,12 +9133,18 @@ prepare_menu_bars ()
    before we start to fill in any display lines, because it can call
    eval.
 
-   If SAVE_MATCH_DATA is non-zero, we must save and restore it here.  */
+   If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
 
-static void
-update_menu_bar (f, save_match_data)
+   If HOOKS_RUN is 1, that means a previous call to update_menu_bar
+   already ran the menu bar hooks for this redisplay, so there
+   is no need to run them again.  The return value is the
+   updated value of this flag, to pass to the next call.  */
+
+static int
+update_menu_bar (f, save_match_data, hooks_run)
      struct frame *f;
      int save_match_data;
+     int hooks_run;
 {
   Lisp_Object window;
   register struct window *w;
@@ -8623,7 +9153,7 @@ update_menu_bar (f, save_match_data)
      happen when, for instance, an activate-menubar-hook causes a
      redisplay.  */
   if (inhibit_menubar_update)
-    return;
+    return hooks_run;
 
   window = FRAME_SELECTED_WINDOW (f);
   w = XWINDOW (window);
@@ -8679,28 +9209,36 @@ update_menu_bar (f, save_match_data)
              specbind (Qoverriding_local_map, Qnil);
            }
 
-         /* Run the Lucid hook.  */
-         safe_run_hooks (Qactivate_menubar_hook);
+         if (!hooks_run)
+           {
+             /* Run the Lucid hook.  */
+             safe_run_hooks (Qactivate_menubar_hook);
+
+             /* If it has changed current-menubar from previous value,
+                really recompute the menu-bar from the value.  */
+             if (! NILP (Vlucid_menu_bar_dirty_flag))
+               call0 (Qrecompute_lucid_menubar);
 
-         /* If it has changed current-menubar from previous value,
-            really recompute the menu-bar from the value.  */
-         if (! NILP (Vlucid_menu_bar_dirty_flag))
-           call0 (Qrecompute_lucid_menubar);
+             safe_run_hooks (Qmenu_bar_update_hook);
+
+             hooks_run = 1;
+           }
 
-         safe_run_hooks (Qmenu_bar_update_hook);
+         XSETFRAME (Vmenu_updating_frame, f);
          FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
 
          /* Redisplay the menu bar in case we changed it.  */
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
     || defined (USE_GTK)
-         if (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.  */
@@ -8715,6 +9253,8 @@ update_menu_bar (f, save_match_data)
          set_buffer_internal_1 (prev);
        }
     }
+
+  return hooks_run;
 }
 
 
@@ -8879,7 +9419,8 @@ update_tool_bar (f, save_match_data)
                                          &new_n_tool_bar);
 
          /* Redisplay the tool-bar if we changed it.  */
-         if (NILP (Fequal (new_tool_bar, f->tool_bar_items)))
+         if (new_n_tool_bar != f->n_tool_bar_items
+             || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
             {
               /* Redisplay that happens asynchronously due to an expose event
                  may access f->tool_bar_items.  Make sure we update both
@@ -9064,11 +9605,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;
@@ -9083,29 +9635,42 @@ 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;
+             /* If this is the only glyph on this line, it will never fit on the
+                toolbar, so skip it.   But ensure there is at least one glyph,
+                so we don't accidentally disable the tool-bar.  */
+             if (n_glyphs_before == 0
+                 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
+               break;
              goto out;
            }
 
@@ -9124,11 +9689,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.  */
@@ -9151,29 +9729,45 @@ display_tool_bar_line (it)
 }
 
 
+/* Max tool-bar height.  */
+
+#define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
+  ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
+
 /* 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;
+  /* tool_bar_lines_needed is called from redisplay_tool_bar after building
+     the desired matrix, so use (unused) mode-line row as temporary row to
+     avoid destroying the first tool-bar row.  */
+  struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
 
   /* 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);
 }
@@ -9203,7 +9797,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);
        }
     }
 
@@ -9248,9 +9842,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);
+         Fmodify_frame_parameters (frame,
+                                   Fcons (Fcons (Qtool_bar_lines,
+                                                 make_number (nlines)),
+                                          Qnil));
+         if (WINDOW_TOTAL_LINES (w) != old_height)
+           {
+             clear_glyph_matrix (w->desired_matrix);
+             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.  */
@@ -9259,17 +9912,20 @@ redisplay_tool_bar (f)
 
   if (auto_resize_tool_bars_p)
     {
-      int nlines;
+      int nlines, nrows;
+      int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
 
       /* If we couldn't display everything, change the tool-bar's
-        height.  */
-      if (IT_STRING_CHARPOS (it) < it.end_charpos)
+        height if there is room for more.  */
+      if (IT_STRING_CHARPOS (it) < it.end_charpos
+         && it.current_y < max_tool_bar_height)
        change_height_p = 1;
 
+      row = it.glyph_row - 1;
+
       /* If there are blank lines at the end, except for a partially
         visible blank line at the end that is smaller than
         FRAME_LINE_HEIGHT, change the tool-bar's height.  */
-      row = it.glyph_row - 1;
       if (!row->displays_text_p
          && row->height >= FRAME_LINE_HEIGHT (f))
        change_height_p = 1;
@@ -9277,13 +9933,14 @@ redisplay_tool_bar (f)
       /* If row displays tool-bar items, but is partially visible,
         change the tool-bar's height.  */
       if (row->displays_text_p
-         && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
+         && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
+         && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
        change_height_p = 1;
 
       /* 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, &nrows),
              nlines != WINDOW_TOTAL_LINES (w)))
        {
          extern Lisp_Object Qtool_bar_lines;
@@ -9291,13 +9948,16 @@ redisplay_tool_bar (f)
          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;
+           {
+             clear_glyph_matrix (w->desired_matrix);
+             f->n_tool_bar_rows = nrows;
+             fonts_changed_p = 1;
+           }
        }
     }
 
@@ -9991,12 +10651,14 @@ overlay_arrow_at_row (it, row)
          if (FRAME_WINDOW_P (it->f)
              && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
            {
+#ifdef HAVE_WINDOW_SYSTEM
              if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
                {
                  int fringe_bitmap;
                  if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
                    return make_number (fringe_bitmap);
                }
+#endif
              return make_number (-1); /* Use default arrow bitmap */
            }
          return overlay_arrow_string_or_property (var);
@@ -10144,13 +10806,13 @@ redisplay_internal (preserve_echo_area)
      int preserve_echo_area;
 {
   struct window *w = XWINDOW (selected_window);
-  struct frame *f = XFRAME (w->frame);
+  struct frame *f;
   int pause;
   int must_finish = 0;
   struct text_pos tlbufpos, tlendpos;
   int number_of_visible_frames;
   int count;
-  struct frame *sf = SELECTED_FRAME ();
+  struct frame *sf;
   int polling_stopped_here = 0;
 
   /* Non-zero means redisplay has to consider all windows on all
@@ -10163,8 +10825,16 @@ redisplay_internal (preserve_echo_area)
      initialized, or redisplay is explicitly turned off by setting
      Vinhibit_redisplay.  */
   if (noninteractive
-      || !NILP (Vinhibit_redisplay)
-      || !f->glyphs_initialized_p)
+      || !NILP (Vinhibit_redisplay))
+    return;
+
+  /* Don't examine these until after testing Vinhibit_redisplay.
+     When Emacs is shutting down, perhaps because its connection to
+     X has dropped, we should not look at them at all.  */
+  f = XFRAME (w->frame);
+  sf = SELECTED_FRAME ();
+
+  if (!f->glyphs_initialized_p)
     return;
 
   /* The flag redisplay_performed_directly_p is set by
@@ -10207,6 +10877,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.  */
@@ -10263,7 +10935,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++;
@@ -10597,9 +11270,9 @@ redisplay_internal (preserve_echo_area)
   if (consider_all_windows_p)
     {
       Lisp_Object tail, frame;
-      int i, n = 0, size = 50;
-      struct frame **updated
-       = (struct frame **) alloca (size * sizeof *updated);
+
+      FOR_EACH_FRAME (tail, frame)
+       XFRAME (frame)->updated_p = 0;
 
       /* Recompute # windows showing selected buffer.  This will be
         incremented each time such a window is displayed.  */
@@ -10661,15 +11334,7 @@ redisplay_internal (preserve_echo_area)
                    break;
 #endif
 
-                 if (n == size)
-                   {
-                     int nbytes = size * sizeof *updated;
-                     struct frame **p = (struct frame **) alloca (2 * nbytes);
-                     bcopy (updated, p, nbytes);
-                     size *= 2;
-                   }
-
-                 updated[n++] = f;
+                 f->updated_p = 1;
                }
            }
        }
@@ -10679,12 +11344,15 @@ redisplay_internal (preserve_echo_area)
          /* Do the mark_window_display_accurate after all windows have
             been redisplayed because this call resets flags in buffers
             which are needed for proper redisplay.  */
-         for (i = 0; i < n; ++i)
+         FOR_EACH_FRAME (tail, frame)
            {
-             struct frame *f = updated[i];
-             mark_window_display_accurate (f->root_window, 1);
-             if (frame_up_to_date_hook)
-               frame_up_to_date_hook (f);
+             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);
+               }
            }
        }
     }
@@ -11116,9 +11784,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;
@@ -11165,7 +11835,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;
@@ -11173,16 +11843,21 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
        }
       else
        {
-         string_before_pos = last_pos;
-         string_start = glyph;
-         string_start_x = x;
+         if (string_start == NULL)
+           {
+             string_before_pos = last_pos;
+             string_start = glyph;
+             string_start_x = x;
+           }
          /* 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 */
@@ -11193,14 +11868,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));
        }
     }
 
@@ -11230,25 +11906,25 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
         glyph on point by scanning from string_start again.  */
       Lisp_Object limit;
       Lisp_Object string;
+      struct glyph *stop = glyph;
       int pos;
 
       limit = make_number (pt_old + 1);
-      end = glyph;
       glyph = string_start;
       x = string_start_x;
       string = glyph->object;
       pos = string_buffer_position (w, string, string_before_pos);
       /* If STRING is from overlay, LAST_POS == 0.  We skip such glyphs
         because we always put cursor after overlay strings.  */
-      while (pos == 0 && glyph < end)
+      while (pos == 0 && glyph < stop)
        {
          string = glyph->object;
-         SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
-         if (glyph < end)
+         SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
+         if (glyph < stop)
            pos = string_buffer_position (w, glyph->object, string_before_pos);
        }
 
-      while (glyph < end)
+      while (glyph < stop)
        {
          pos = XINT (Fnext_single_char_property_change
                      (make_number (pos), Qdisplay, Qnil, limit));
@@ -11256,15 +11932,20 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
            break;
          /* Skip glyphs from the same string.  */
          string = glyph->object;
-         SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
+         SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
          /* Skip glyphs from an overlay.  */
-         while (glyph < end
+         while (glyph < stop
                 && ! string_buffer_position (w, glyph->object, pos))
            {
              string = glyph->object;
-             SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
+             SKIP_GLYPHS (glyph, stop, 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];
@@ -11298,6 +11979,8 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
       else
        CHARPOS (this_line_start_pos) = 0;
     }
+
+  return 1;
 }
 
 
@@ -11346,6 +12029,7 @@ static int
 cursor_row_fully_visible_p (w, force_p, current_matrix_p)
      struct window *w;
      int force_p;
+     int current_matrix_p;
 {
   struct glyph_matrix *matrix;
   struct glyph_row *row;
@@ -11371,7 +12055,8 @@ cursor_row_fully_visible_p (w, force_p, current_matrix_p)
   window_height = window_box_height (w);
   if (row->height >= window_height)
     {
-      if (!force_p || MINI_WINDOW_P (w) || w->vscroll)
+      if (!force_p || MINI_WINDOW_P (w)
+         || w->vscroll || w->cursor.vpos == 0)
        return 1;
     }
   return 0;
@@ -11980,8 +12665,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));
            }
        }
     }
@@ -12242,8 +12937,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,
@@ -12413,6 +13106,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
@@ -12811,15 +13534,16 @@ try_window (window, pos, check_margins)
   if (check_margins
       && !MINI_WINDOW_P (w))
     {
-      int this_scroll_margin, cursor_height;
+      int this_scroll_margin;
 
       this_scroll_margin = max (0, scroll_margin);
       this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
       this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
-      cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
 
-      if ((w->cursor.y < this_scroll_margin
-          && CHARPOS (pos) > BEGV)
+      if ((w->cursor.y >= 0    /* not vscrolled */
+          && w->cursor.y < this_scroll_margin
+          && 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
@@ -13067,7 +13791,7 @@ try_window_reusing_current_matrix (w)
          /* Disable lines in the current matrix which are now
             below the window.  */
          for (++row; row < bottom_row; ++row)
-           row->enabled_p = 0;
+           row->enabled_p = row->mode_line_p = 0;
        }
 
       /* Update window_end_pos etc.; last_reused_text_row is the last
@@ -14406,6 +15130,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);
+    }
 }
 
 
@@ -14421,7 +15164,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\
@@ -14925,6 +15668,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)
@@ -15370,7 +16114,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)
                        {
@@ -15846,6 +16592,9 @@ display_mode_line (w, face_id, format)
   int count = SPECPDL_INDEX ();
 
   init_iterator (&it, w, -1, -1, NULL, face_id);
+  /* Don't extend on a previously drawn mode-line.
+     This may happen if called from pos_visible_p.  */
+  it.glyph_row->enabled_p = 0;
   prepare_desired_row (it.glyph_row);
 
   it.glyph_row->mode_line_p = 1;
@@ -15855,7 +16604,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;
 
@@ -15863,6 +16612,7 @@ display_mode_line (w, face_id, format)
      kboard-local variables in the mode_line_format will get the right
      values.  */
   push_frame_kboard (it.f);
+  record_unwind_save_match_data ();
   display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
   pop_frame_kboard ();
 
@@ -15890,6 +16640,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.
 
@@ -15937,9 +16725,10 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky)
       {
        /* A string: output it and check for %-constructs within it.  */
        unsigned char c;
-       const unsigned char *this, *lisp_string;
+       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);
@@ -15970,14 +16759,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);
@@ -15995,8 +16792,7 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky)
              }
          }
 
-       this = SDATA (elt);
-       lisp_string = this;
+       offset = 0;
 
        if (literal)
          {
@@ -16019,42 +16815,44 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky)
            break;
          }
 
+       /* Handle the non-literal case.  */
+
        while ((precision <= 0 || n < precision)
-              && *this
+              && SREF (elt, offset) != 0
               && (mode_line_target != MODE_LINE_DISPLAY
                   || it->current_x < it->last_visible_x))
          {
-           const unsigned char *last = this;
+           int last_offset = offset;
 
            /* Advance to end of string or next format specifier.  */
-           while ((c = *this++) != '\0' && c != '%')
+           while ((c = SREF (elt, offset++)) != '\0' && c != '%')
              ;
 
-           if (this - 1 != last)
+           if (offset - 1 != last_offset)
              {
                int nchars, nbytes;
 
                /* Output to end of string or up to '%'.  Field width
                   is length of string.  Don't output more than
                   PRECISION allows us.  */
-               --this;
+               offset--;
 
-               prec = c_string_width (last, this - last, precision - n,
+               prec = c_string_width (SDATA (elt) + last_offset,
+                                      offset - last_offset, precision - n,
                                       &nchars, &nbytes);
 
                switch (mode_line_target)
                  {
                  case MODE_LINE_NOPROP:
                  case MODE_LINE_TITLE:
-                   n += store_mode_line_noprop (last, 0, prec);
+                   n += store_mode_line_noprop (SDATA (elt) + last_offset, 0, prec);
                    break;
                  case MODE_LINE_STRING:
                    {
-                     int bytepos = last - lisp_string;
+                     int bytepos = last_offset;
                      int charpos = string_byte_to_char (elt, bytepos);
                      int endpos = (precision <= 0
-                                   ? string_byte_to_char (elt,
-                                                          this - lisp_string)
+                                   ? string_byte_to_char (elt, offset)
                                    : charpos + nchars);
 
                      n += store_mode_line_string (NULL,
@@ -16065,10 +16863,13 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky)
                    break;
                  case MODE_LINE_DISPLAY:
                    {
-                     int bytepos = last - lisp_string;
+                     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;
@@ -16076,12 +16877,12 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky)
              }
            else /* c == '%' */
              {
-               const unsigned char *percent_position = this;
+               int percent_position = offset;
 
                /* Get the specified minimum width.  Zero means
                   don't pad.  */
                field = 0;
-               while ((c = *this++) >= '0' && c <= '9')
+               while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
                  field = field * 10 + c - '0';
 
                /* Don't pad beyond the total padding allowed.  */
@@ -16101,7 +16902,7 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky)
                    int bytepos, charpos;
                    unsigned char *spec;
 
-                   bytepos = percent_position - lisp_string;
+                   bytepos = percent_position;
                    charpos = (STRING_MULTIBYTE (elt)
                               ? string_byte_to_char (elt, bytepos)
                               : bytepos);
@@ -16501,8 +17302,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));
@@ -16880,12 +17684,32 @@ decode_mode_spec (w, c, field_width, precision, multibyte)
       break;
 
     case 'c':
+      /* %c and %l are ignored in `frame-title-format'.
+         (In redisplay_internal, the frame title is drawn _before_ the
+         windows are updated, so the stuff which depends on actual
+         window contents (such as %l) may fail to render properly, or
+         even crash emacs.)  */
+      if (mode_line_target == MODE_LINE_TITLE)
+       return "";
+      else
+       {
+         int col = (int) current_column (); /* iftc */
+         w->column_number_displayed = make_number (col);
+         pint2str (decode_mode_spec_buf, field_width, col);
+         return decode_mode_spec_buf;
+       }
+
+    case 'e':
+#ifndef SYSTEM_MALLOC
       {
-       int col = (int) current_column (); /* iftc */
-       w->column_number_displayed = make_number (col);
-       pint2str (decode_mode_spec_buf, field_width, col);
-       return decode_mode_spec_buf;
+       if (NILP (Vmemory_full))
+         return "";
+       else
+         return "!MEM FULL! ";
       }
+#else
+      return "";
+#endif
 
     case 'F':
       /* %F displays the frame name.  */
@@ -16915,11 +17739,16 @@ decode_mode_spec (w, c, field_width, precision, multibyte)
 
     case 'l':
       {
-       int startpos = XMARKER (w->start)->charpos;
-       int startpos_byte = marker_byte_position (w->start);
-       int line, linepos, linepos_byte, topline;
-       int nlines, junk;
-       int height = WINDOW_TOTAL_LINES (w);
+       int startpos, startpos_byte, line, linepos, linepos_byte;
+       int topline, nlines, junk, height;
+
+       /* %c and %l are ignored in `frame-title-format'.  */
+       if (mode_line_target == MODE_LINE_TITLE)
+         return "";
+
+       startpos = XMARKER (w->start)->charpos;
+       startpos_byte = marker_byte_position (w->start);
+       height = WINDOW_TOTAL_LINES (w);
 
        /* If we decided that this buffer isn't suitable for line numbers,
           don't forget that too fast.  */
@@ -17302,7 +18131,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,
@@ -17952,8 +18781,7 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
         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);
@@ -17992,22 +18820,23 @@ 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;
@@ -18051,16 +18880,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;
@@ -18070,7 +18899,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;
@@ -18163,6 +18992,7 @@ fill_stretch_glyph_string (s, row, area, start, end)
   s->font = s->face->font;
   s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
   s->width = glyph->pixel_width;
+  s->nchars = 1;
   voffset = glyph->voffset;
 
   for (++glyph;
@@ -18353,7 +19183,7 @@ get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
       face_id = FACE_FOR_CHAR (f, face, c);
       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);
@@ -18405,19 +19235,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
@@ -18547,7 +19373,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)
 
@@ -18600,7 +19426,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;                                                             \
@@ -18669,20 +19495,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;
      int start, end;
      enum draw_glyphs_face hl;
-     int overlaps_p;
+     int overlaps;
 {
   struct glyph_string *head, *tail;
   struct glyph_string *s;
@@ -18731,7 +19563,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;
@@ -18824,7 +19656,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
@@ -18975,7 +19807,7 @@ produce_image_glyph (it)
 {
   struct image *img;
   struct face *face;
-  int glyph_ascent;
+  int glyph_ascent, crop;
   struct glyph_slice slice;
 
   xassert (it->what == IT_IMAGE);
@@ -19083,6 +19915,15 @@ produce_image_glyph (it)
 
   take_vertical_position_into_account (it);
 
+  /* Automatically crop wide image glyphs at right edge so we can
+     draw the cursor on same display row.  */
+  if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
+      && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
+    {
+      it->pixel_width -= crop;
+      slice.width -= crop;
+    }
+
   if (it->glyph_row)
     {
       struct glyph *glyph;
@@ -19289,6 +20130,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;
@@ -19302,20 +20147,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);
 }
 
@@ -19429,8 +20260,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)
@@ -19589,7 +20420,7 @@ x_produce_glyphs (it)
          /* If face has an overline, add the height of the overline
             (1 pixel) and a 1 pixel margin to the character height.  */
          if (face->overline_p)
-           it->ascent += 2;
+           it->ascent += overline_margin;
 
          if (it->constrain_row_ascent_descent_p)
            {
@@ -19791,7 +20622,7 @@ x_produce_glyphs (it)
          /* If face has an overline, add the height of the overline
             (1 pixel) and a 1 pixel margin to the character height.  */
          if (face->overline_p)
-           it->ascent += 2;
+           it->ascent += overline_margin;
 
          take_vertical_position_into_account (it);
 
@@ -20066,7 +20897,7 @@ x_produce_glyphs (it)
       /* If face has an overline, add the height of the overline
         (1 pixel) and a 1 pixel margin to the character height.  */
       if (face->overline_p)
-       it->ascent += 2;
+       it->ascent += overline_margin;
 
       take_vertical_position_into_account (it);
 
@@ -20390,8 +21221,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;
@@ -20420,7 +21256,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);
     }
 
@@ -20436,10 +21272,35 @@ get_window_cursor_type (w, glyph, width, active_cursor)
   /* Use normal cursor if not blinked off.  */
   if (!w->cursor_off_p)
     {
-      if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
-       if (cursor_type == FILLED_BOX_CURSOR)
-         cursor_type = HOLLOW_BOX_CURSOR;
+#ifdef HAVE_WINDOW_SYSTEM
+      if (glyph != NULL && glyph->type == IMAGE_GLYPH)
+       {
+         if (cursor_type == FILLED_BOX_CURSOR)
+           {
+             /* Using a block cursor on large images can be very annoying.
+                So use a hollow cursor for "large" images.
+                If image is not transparent (no mask), also use hollow cursor.  */
+             struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
+             if (img != NULL && IMAGEP (img->spec))
+               {
+                 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
+                    where N = size of default frame font size.
+                    This should cover most of the "tiny" icons people may use.  */
+                 if (!img->mask
+                     || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
+                     || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
+                   cursor_type = HOLLOW_BOX_CURSOR;
+               }
+           }
+         else if (cursor_type != NO_CURSOR)
+           {
+             /* Display current only supports BOX and HOLLOW cursors for images.
+                So for now, unconditionally use a HOLLOW cursor when cursor is
+                not a solid box cursor.  */
+             cursor_type = HOLLOW_BOX_CURSOR;
+           }
       }
+#endif
       return cursor_type;
     }
 
@@ -20557,13 +21418,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;
 
@@ -20586,7 +21449,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
        {
@@ -20628,13 +21491,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);
        }
     }
 }
@@ -20719,7 +21586,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;
 
@@ -20727,11 +21594,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);
     }
 
@@ -20949,7 +21821,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)
            {
@@ -21760,7 +22636,7 @@ note_mouse_highlight (f, x, y)
   struct buffer *b;
 
   /* When a menu is active, don't highlight because this looks odd.  */
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
   if (popup_activated ())
     return;
 #endif
@@ -21820,7 +22696,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;
@@ -22425,13 +23304,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);
       }
 }
 
@@ -23124,9 +24003,10 @@ This variable is not guaranteed to be accurate except while processing
   DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
     doc: /* Template for displaying the title bar of visible frames.
 \(Assuming the window manager supports this feature.)
-This variable has the same structure as `mode-line-format' (which see),
-and is used only on frames for which no explicit name has been set
-\(see `modify-frame-parameters').  */);
+
+This variable has the same structure as `mode-line-format', except that
+the %c and %l constructs are ignored.  It is used only on frames for
+which no explicit name has been set \(see `modify-frame-parameters').  */);
 
   DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
     doc: /* Template for displaying the title bar of an iconified frame.
@@ -23172,9 +24052,22 @@ Each function is called with two arguments, the window and the end trigger value
 See `set-window-redisplay-end-trigger'.  */);
   Vredisplay_end_trigger_functions = Qnil;
 
-  DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
-    doc: /* *Non-nil means autoselect window with mouse pointer.  */);
-  mouse_autoselect_window = 0;
+  DEFVAR_LISP ("mouse-autoselect-window", &Vmouse_autoselect_window,
+     doc: /* *Non-nil means autoselect window with mouse pointer.
+If nil, do not autoselect windows.
+A positive number means delay autoselection by that many seconds: a
+window is autoselected only after the mouse has remained in that
+window for the duration of the delay.
+A negative number has a similar effect, but causes windows to be
+autoselected only after the mouse has stopped moving.  \(Because of
+the way Emacs compares mouse events, you will occasionally wait twice
+that time before the window gets selected.\)
+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.  */);
+  Vmouse_autoselect_window = Qnil;
 
   DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
     doc: /* *Non-nil means automatically resize tool-bars.
@@ -23191,6 +24084,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.
@@ -23240,7 +24141,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,
@@ -23254,7 +24159,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
@@ -23282,6 +24187,11 @@ This is used to update submenus such as Buffers,
 whose contents depend on various data.  */);
   Vmenu_bar_update_hook = Qnil;
 
+  DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame,
+              doc: /* Frame for which we are updating a menu.
+The enable predicate for a menu binding should check this variable.  */);
+  Vmenu_updating_frame = Qnil;
+
   DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
     doc: /* Non-nil means don't update menu bars.  Internal use only.  */);
   inhibit_menubar_update = 0;
@@ -23307,6 +24217,12 @@ whose contents depend on various data.  */);
               doc: /* Inhibit try_cursor_movement display optimization.  */);
   inhibit_try_cursor_movement = 0;
 #endif /* GLYPH_DEBUG */
+
+  DEFVAR_INT ("overline-margin", &overline_margin,
+              doc: /* *Space between overline and text, in pixels.
+The default value is 2: the height of the overline (1 pixel) plus 1 pixel
+margin to the caracter height.  */);
+  overline_margin = 2;
 }