Improve API of recently-added bool vector functions.
[bpt/emacs.git] / src / xdisp.c
index 44a8630..47855a1 100644 (file)
@@ -1,7 +1,6 @@
 /* Display generation from window structure and buffer text.
 
-Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software Foundation,
-Inc.
+Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -299,19 +298,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "font.h"
 #include "fontset.h"
 #include "blockinput.h"
-
-#ifdef HAVE_X_WINDOWS
-#include "xterm.h"
-#endif
-#ifdef HAVE_NTGUI
-#include "w32term.h"
-#endif
-#ifdef HAVE_NS
-#include "nsterm.h"
-#endif
-#ifdef USE_GTK
-#include "gtkutil.h"
-#endif
+#ifdef HAVE_WINDOW_SYSTEM
+#include TERM_HEADER
+#endif /* HAVE_WINDOW_SYSTEM */
 
 #ifndef FRAME_X_OUTPUT
 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
@@ -426,11 +415,11 @@ Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
 /* Non-zero means print newline to stdout before next mini-buffer
    message.  */
 
-int noninteractive_need_newline;
+bool noninteractive_need_newline;
 
 /* Non-zero means print newline to message log before next message.  */
 
-static int message_log_need_newline;
+static bool message_log_need_newline;
 
 /* Three markers that message_dolog uses.
    It could allocate them itself, but that causes trouble
@@ -489,7 +478,7 @@ Lisp_Object Qmenu_bar_update_hook;
 
 /* Nonzero if an overlay arrow has been displayed in this window.  */
 
-static int overlay_arrow_seen;
+static bool overlay_arrow_seen;
 
 /* Vector containing glyphs for an ellipsis `...'.  */
 
@@ -511,7 +500,7 @@ static Lisp_Object Vmessage_stack;
 /* Nonzero means multibyte characters were enabled when the echo area
    message was specified.  */
 
-static int message_enable_multibyte;
+static bool message_enable_multibyte;
 
 /* Nonzero if we should redraw the mode lines on the next redisplay.  */
 
@@ -522,14 +511,10 @@ int update_mode_lines;
 
 int windows_or_buffers_changed;
 
-/* Nonzero means a frame's cursor type has been changed.  */
-
-static int cursor_type_changed;
-
 /* Nonzero after display_mode_line if %l was used and it displayed a
    line number.  */
 
-static int line_number_displayed;
+static bool line_number_displayed;
 
 /* The name of the *Messages* buffer, a string.  */
 
@@ -551,12 +536,12 @@ static Lisp_Object Vwith_echo_area_save_vector;
 /* Non-zero means display_echo_area should display the last echo area
    message again.  Set by redisplay_preserve_echo_area.  */
 
-static int display_last_displayed_message_p;
+static bool display_last_displayed_message_p;
 
 /* Nonzero if echo area is being used by print; zero if being used by
    message.  */
 
-static int message_buf_print;
+static bool message_buf_print;
 
 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable.  */
 
@@ -566,7 +551,7 @@ static Lisp_Object Qmessage_truncate_lines;
 /* Set to 1 in clear_message to make redisplay_internal aware
    of an emptied echo area.  */
 
-static int message_cleared_p;
+static bool message_cleared_p;
 
 /* A scratch glyph row with contents used for generating truncation
    glyphs.  Also used in direct_output_for_insert.  */
@@ -581,13 +566,7 @@ static int last_height;
 
 /* Non-zero if there's a help-echo in the echo area.  */
 
-int help_echo_showing_p;
-
-/* If >= 0, computed, exact values of mode-line and header-line height
-   to use in the macros CURRENT_MODE_LINE_HEIGHT and
-   CURRENT_HEADER_LINE_HEIGHT.  */
-
-int current_mode_line_height, current_header_line_height;
+bool help_echo_showing_p;
 
 /* The maximum distance to look ahead for text properties.  Values
    that are too small let us call compute_char_face and similar
@@ -758,17 +737,21 @@ ptrdiff_t help_echo_pos;
 
 Lisp_Object previous_help_echo_string;
 
-/* Platform-independent portion of hourglass implementation. */
+/* Platform-independent portion of hourglass implementation.  */
+
+#ifdef HAVE_WINDOW_SYSTEM
 
 /* Non-zero means an hourglass cursor is currently shown.  */
-int hourglass_shown_p;
+bool hourglass_shown_p;
 
 /* If non-null, an asynchronous timer that, when it expires, displays
    an hourglass cursor on all frames.  */
 struct atimer *hourglass_atimer;
 
+#endif /* HAVE_WINDOW_SYSTEM */
+
 /* Name of the face used to display glyphless characters.  */
-Lisp_Object Qglyphless_char;
+static Lisp_Object Qglyphless_char;
 
 /* Symbol for the purpose of Vglyphless_char_display.  */
 static Lisp_Object Qglyphless_char_display;
@@ -776,14 +759,17 @@ static Lisp_Object Qglyphless_char_display;
 /* Method symbols for Vglyphless_char_display.  */
 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
 
-/* Default pixel width of `thin-space' display method.  */
-#define THIN_SPACE_WIDTH 1
-
 /* Default number of seconds to wait before displaying an hourglass
    cursor.  */
 #define DEFAULT_HOURGLASS_DELAY 1
 
-\f
+#ifdef HAVE_WINDOW_SYSTEM
+
+/* Default pixel width of `thin-space' display method.  */
+#define THIN_SPACE_WIDTH 1
+
+#endif /* HAVE_WINDOW_SYSTEM */
+
 /* Function prototypes.  */
 
 static void setup_for_ellipsis (struct it *, int);
@@ -926,11 +912,8 @@ static int in_ellipses_for_invisible_text_p (struct display_pos *,
 #ifdef HAVE_WINDOW_SYSTEM
 
 static void x_consider_frame_title (Lisp_Object);
-static int tool_bar_lines_needed (struct frame *, int *);
 static void update_tool_bar (struct frame *, int);
-static void build_desired_tool_bar_string (struct frame *f);
 static int redisplay_tool_bar (struct frame *);
-static void display_tool_bar_line (struct it *, int);
 static void notice_overwritten_cursor (struct window *,
                                        enum glyph_row_area,
                                        int, int, int, int);
@@ -966,12 +949,12 @@ window_text_bottom_y (struct window *w)
   return height;
 }
 
-/* Return the pixel width of display area AREA of window W.  AREA < 0
-   means return the total width of W, not including fringes to
-   the left and right of the window.  */
+/* Return the pixel width of display area AREA of window W.
+   ANY_AREA means return the total width of W, not including
+   fringes to the left and right of the window.  */
 
 int
-window_box_width (struct window *w, int area)
+window_box_width (struct window *w, enum glyph_row_area area)
 {
   int cols = w->total_cols;
   int pixels = 0;
@@ -1049,11 +1032,11 @@ window_box_height (struct window *w)
 }
 
 /* Return the window-relative coordinate of the left edge of display
-   area AREA of window W.  AREA < 0 means return the left edge of the
+   area AREA of window W.  ANY_AREA means return the left edge of the
    whole window, to the right of the left fringe of W.  */
 
 int
-window_box_left_offset (struct window *w, int area)
+window_box_left_offset (struct window *w, enum glyph_row_area area)
 {
   int x;
 
@@ -1081,21 +1064,21 @@ window_box_left_offset (struct window *w, int area)
 
 
 /* Return the window-relative coordinate of the right edge of display
-   area AREA of window W.  AREA < 0 means return the right edge of the
+   area AREA of window W.  ANY_AREA means return the right edge of the
    whole window, to the left of the right fringe of W.  */
 
 int
-window_box_right_offset (struct window *w, int area)
+window_box_right_offset (struct window *w, enum glyph_row_area area)
 {
   return window_box_left_offset (w, area) + window_box_width (w, area);
 }
 
 /* Return the frame-relative coordinate of the left edge of display
-   area AREA of window W.  AREA < 0 means return the left edge of the
+   area AREA of window W.  ANY_AREA means return the left edge of the
    whole window, to the right of the left fringe of W.  */
 
 int
-window_box_left (struct window *w, int area)
+window_box_left (struct window *w, enum glyph_row_area area)
 {
   struct frame *f = XFRAME (w->frame);
   int x;
@@ -1111,25 +1094,25 @@ window_box_left (struct window *w, int area)
 
 
 /* Return the frame-relative coordinate of the right edge of display
-   area AREA of window W.  AREA < 0 means return the right edge of the
+   area AREA of window W.  ANY_AREA means return the right edge of the
    whole window, to the left of the right fringe of W.  */
 
 int
-window_box_right (struct window *w, int area)
+window_box_right (struct window *w, enum glyph_row_area area)
 {
   return window_box_left (w, area) + window_box_width (w, area);
 }
 
 /* Get the bounding box of the display area AREA of window W, without
-   mode lines, in frame-relative coordinates.  AREA < 0 means the
+   mode lines, in frame-relative coordinates.  ANY_AREA means the
    whole window, not including the left and right fringes of
    the window.  Return in *BOX_X and *BOX_Y the frame-relative pixel
    coordinates of the upper-left corner of the box.  Return in
    *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box.  */
 
 void
-window_box (struct window *w, int area, int *box_x, int *box_y,
-           int *box_width, int *box_height)
+window_box (struct window *w, enum glyph_row_area area, int *box_x,
+           int *box_y, int *box_width, int *box_height)
 {
   if (box_width)
     *box_width = window_box_width (w, area);
@@ -1145,27 +1128,27 @@ window_box (struct window *w, int area, int *box_x, int *box_y,
     }
 }
 
+#ifdef HAVE_WINDOW_SYSTEM
 
 /* Get the bounding box of the display area AREA of window W, without
-   mode lines.  AREA < 0 means the whole window, not including the
-   left and right fringe of the window.  Return in *TOP_LEFT_X
+   mode lines and both fringes of the window.  Return in *TOP_LEFT_X
    and TOP_LEFT_Y the frame-relative pixel coordinates of the
    upper-left corner of the box.  Return in *BOTTOM_RIGHT_X, and
    *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
    box.  */
 
 static void
-window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
-                  int *bottom_right_x, int *bottom_right_y)
+window_box_edges (struct window *w, int *top_left_x, int *top_left_y,
+                 int *bottom_right_x, int *bottom_right_y)
 {
-  window_box (w, area, top_left_x, top_left_y, bottom_right_x,
-             bottom_right_y);
+  window_box (w, ANY_AREA, top_left_x, top_left_y,
+             bottom_right_x, bottom_right_y);
   *bottom_right_x += *top_left_x;
   *bottom_right_y += *top_left_y;
 }
 
+#endif /* HAVE_WINDOW_SYSTEM */
 
-\f
 /***********************************************************************
                              Utilities
  ***********************************************************************/
@@ -1352,12 +1335,12 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
 
   /* Compute exact mode line heights.  */
   if (WINDOW_WANTS_MODELINE_P (w))
-    current_mode_line_height
+    w->mode_line_height
       = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
                           BVAR (current_buffer, mode_line_format));
 
   if (WINDOW_WANTS_HEADER_LINE_P (w))
-    current_header_line_height
+    w->header_line_height
       = display_mode_line (w, HEADER_LINE_FACE_ID,
                           BVAR (current_buffer, header_line_format));
 
@@ -1650,8 +1633,6 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
   if (old_buffer)
     set_buffer_internal_1 (old_buffer);
 
-  current_header_line_height = current_mode_line_height = -1;
-
   if (visible_p && w->hscroll > 0)
     *x -=
       window_hscroll_limited (w, WINDOW_XFRAME (w))
@@ -1901,8 +1882,7 @@ pixel_to_glyph_coords (struct frame *f, register int pix_x, register int pix_y,
    text, or we can't tell because W's current matrix is not up to
    date.  */
 
-static
-struct glyph *
+static struct glyph *
 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
                  int *dx, int *dy, int *area)
 {
@@ -2621,24 +2601,6 @@ check_window_end (struct window *w)
 
 #endif /* GLYPH_DEBUG and ENABLE_CHECKING */
 
-/* Return mark position if current buffer has the region of non-zero length,
-   or -1 otherwise.  */
-
-static ptrdiff_t
-markpos_of_region (void)
-{
-  if (!NILP (Vtransient_mark_mode)
-      && !NILP (BVAR (current_buffer, mark_active))
-      && XMARKER (BVAR (current_buffer, mark))->buffer != NULL)
-    {
-      ptrdiff_t markpos = XMARKER (BVAR (current_buffer, mark))->charpos;
-
-      if (markpos != PT)
-       return markpos;
-    }
-  return -1;
-}
-
 /***********************************************************************
                       Iterator initialization
  ***********************************************************************/
@@ -2667,7 +2629,6 @@ init_iterator (struct it *it, struct window *w,
               ptrdiff_t charpos, ptrdiff_t bytepos,
               struct glyph_row *row, enum face_id base_face_id)
 {
-  ptrdiff_t markpos;
   enum face_id remapped_base_face_id = base_face_id;
 
   /* Some precondition checks.  */
@@ -2771,28 +2732,6 @@ init_iterator (struct it *it, struct window *w,
   /* Are multibyte characters enabled in current_buffer?  */
   it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
 
-  /* If visible region is of non-zero length, set IT->region_beg_charpos
-     and IT->region_end_charpos to the start and end of a visible region
-     in window IT->w.  Set both to -1 to indicate no region.  */
-  markpos = markpos_of_region ();
-  if (markpos >= 0
-      /* Maybe highlight only in selected window.  */
-      && (/* Either show region everywhere.  */
-         highlight_nonselected_windows
-         /* Or show region in the selected window.  */
-         || w == XWINDOW (selected_window)
-         /* Or show the region if we are in the mini-buffer and W is
-            the window the mini-buffer refers to.  */
-         || (MINI_WINDOW_P (XWINDOW (selected_window))
-             && WINDOWP (minibuf_selected_window)
-             && w == XWINDOW (minibuf_selected_window))))
-    {
-      it->region_beg_charpos = min (PT, markpos);
-      it->region_end_charpos = max (PT, markpos);
-    }
-  else
-    it->region_beg_charpos = it->region_end_charpos = -1;
-
   /* Get the position at which the redisplay_end_trigger hook should
      be run, if it is to be run at all.  */
   if (MARKERP (w->redisplay_end_trigger)
@@ -3426,16 +3365,6 @@ compute_stop_pos (struct it *it)
       if (pos < it->stop_charpos)
        it->stop_charpos = pos;
 
-      /* If showing the region, we have to stop at the region
-        start or end because the face might change there.  */
-      if (it->region_beg_charpos > 0)
-       {
-         if (IT_CHARPOS (*it) < it->region_beg_charpos)
-           it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
-         else if (IT_CHARPOS (*it) < it->region_end_charpos)
-           it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
-       }
-
       /* Set up variables for computing the stop position from text
          property changes.  */
       XSETBUFFER (object, current_buffer);
@@ -3718,8 +3647,8 @@ handle_fontified_prop (struct it *it)
       ptrdiff_t count = SPECPDL_INDEX ();
       Lisp_Object val;
       struct buffer *obuf = current_buffer;
-      int begv = BEGV, zv = ZV;
-      int old_clip_changed = current_buffer->clip_changed;
+      ptrdiff_t begv = BEGV, zv = ZV;
+      bool old_clip_changed = current_buffer->clip_changed;
 
       val = Vfontification_functions;
       specbind (Qfontification_functions, Qnil);
@@ -3819,8 +3748,6 @@ handle_face_prop (struct it *it)
       new_face_id
        = face_at_buffer_position (it->w,
                                   IT_CHARPOS (*it),
-                                  it->region_beg_charpos,
-                                  it->region_end_charpos,
                                   &next_stop,
                                   (IT_CHARPOS (*it)
                                    + TEXT_PROP_DISTANCE_LIMIT),
@@ -3897,8 +3824,6 @@ handle_face_prop (struct it *it)
          base_face_id
            = face_for_overlay_string (it->w,
                                       IT_CHARPOS (*it),
-                                      it->region_beg_charpos,
-                                      it->region_end_charpos,
                                       &next_stop,
                                       (IT_CHARPOS (*it)
                                        + TEXT_PROP_DISTANCE_LIMIT),
@@ -3927,8 +3852,6 @@ handle_face_prop (struct it *it)
                                             it->string,
                                             IT_STRING_CHARPOS (*it),
                                             bufpos,
-                                            it->region_beg_charpos,
-                                            it->region_end_charpos,
                                             &next_stop,
                                             base_face_id, 0);
 
@@ -4071,8 +3994,6 @@ face_before_or_after_it_pos (struct it *it, int before_p)
                                         it->string,
                                         charpos,
                                         bufpos,
-                                        it->region_beg_charpos,
-                                        it->region_end_charpos,
                                         &next_check_charpos,
                                         base_face_id, 0);
 
@@ -4162,8 +4083,6 @@ face_before_or_after_it_pos (struct it *it, int before_p)
       /* Determine face for CHARSET_ASCII, or unibyte.  */
       face_id = face_at_buffer_position (it->w,
                                         CHARPOS (pos),
-                                        it->region_beg_charpos,
-                                        it->region_end_charpos,
                                         &next_check_charpos,
                                         limit, 0, -1);
 
@@ -6461,9 +6380,6 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string,
                  ptrdiff_t charpos, ptrdiff_t precision, int field_width,
                  int multibyte)
 {
-  /* No region in strings.  */
-  it->region_beg_charpos = it->region_end_charpos = -1;
-
   /* No text property checks performed by default, but see below.  */
   it->stop_charpos = -1;
 
@@ -6638,8 +6554,8 @@ lookup_glyphless_char_display (int c, struct it *it)
       if (c >= 0)
        {
          glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
-         if (CONSP (glyphless_method))
-           glyphless_method = FRAME_WINDOW_P (it->f)
+      if (CONSP (glyphless_method))
+       glyphless_method = FRAME_WINDOW_P (it->f)
              ? XCAR (glyphless_method)
              : XCDR (glyphless_method);
        }
@@ -6681,17 +6597,59 @@ lookup_glyphless_char_display (int c, struct it *it)
   return glyphless_method;
 }
 
-/* Load IT's display element fields with information about the next
-   display element from the current position of IT.  Value is zero if
-   end of buffer (or C string) is reached.  */
+/* Merge escape glyph face and cache the result.  */
 
 static struct frame *last_escape_glyph_frame = NULL;
 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
 static int last_escape_glyph_merged_face_id = 0;
 
-struct frame *last_glyphless_glyph_frame = NULL;
-int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
-int last_glyphless_glyph_merged_face_id = 0;
+static int
+merge_escape_glyph_face (struct it *it)
+{
+  int face_id;
+
+  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;
+    }
+  return face_id;
+}
+
+/* Likewise for glyphless glyph face.  */
+
+static struct frame *last_glyphless_glyph_frame = NULL;
+static int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
+static int last_glyphless_glyph_merged_face_id = 0;
+
+int
+merge_glyphless_glyph_face (struct it *it)
+{
+  int face_id;
+
+  if (it->f == last_glyphless_glyph_frame
+      && it->face_id == last_glyphless_glyph_face_id)
+    face_id = last_glyphless_glyph_merged_face_id;
+  else
+    {
+      /* Merge the `glyphless-char' face into the current face.  */
+      face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
+      last_glyphless_glyph_frame = it->f;
+      last_glyphless_glyph_face_id = it->face_id;
+      last_glyphless_glyph_merged_face_id = face_id;
+    }
+  return face_id;
+}
+
+/* Load IT's display element fields with information about the next
+   display element from the current position of IT.  Value is zero if
+   end of buffer (or C string) is reached.  */
 
 static int
 get_next_display_element (struct it *it)
@@ -6801,7 +6759,7 @@ get_next_display_element (struct it *it)
 
             Non-printable characters and raw-byte characters are also
             translated to octal form.  */
-         if (((c < ' ' || c == 127) /* ASCII control chars */
+         if (((c < ' ' || c == 127) /* ASCII control chars */
               ? (it->area != TEXT_AREA
                  /* In mode line, treat \n, \t like other crl chars.  */
                  || (c != '\t'
@@ -6839,24 +6797,10 @@ get_next_display_element (struct it *it)
                      g = GLYPH_CODE_CHAR (gc);
                      lface_id = GLYPH_CODE_FACE (gc);
                    }
-                 if (lface_id)
-                   {
-                     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;
-                   }
+
+                 face_id = (lface_id
+                            ? merge_faces (it->f, Qt, lface_id, it->face_id)
+                            : merge_escape_glyph_face (it));
 
                  XSETINT (it->ctl_chars[0], g);
                  XSETINT (it->ctl_chars[1], c ^ 0100);
@@ -6888,27 +6832,10 @@ get_next_display_element (struct it *it)
                  escape_glyph = GLYPH_CODE_CHAR (gc);
                  lface_id = GLYPH_CODE_FACE (gc);
                }
-             if (lface_id)
-               {
-                 /* The display table specified a face.
-                    Merge it into face_id and also into escape_glyph.  */
-                 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;
-               }
+
+             face_id = (lface_id
+                        ? merge_faces (it->f, Qt, lface_id, it->face_id)
+                        : merge_escape_glyph_face (it));
 
              /* Draw non-ASCII hyphen with just highlighting: */
 
@@ -6964,6 +6891,7 @@ get_next_display_element (struct it *it)
        }
     }
 
+#ifdef HAVE_WINDOW_SYSTEM
   /* Adjust face id for a multibyte character.  There are no multibyte
      character in unibyte text.  */
   if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
@@ -7004,6 +6932,7 @@ get_next_display_element (struct it *it)
          it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
        }
     }
+#endif /* HAVE_WINDOW_SYSTEM */
 
  done:
   /* Is this character the last one of a run of characters with
@@ -7040,8 +6969,7 @@ get_next_display_element (struct it *it)
                  INC_TEXT_POS (pos, it->multibyte_p);
 
                  next_face_id = face_at_buffer_position
-                   (it->w, CHARPOS (pos), it->region_beg_charpos,
-                    it->region_end_charpos, &ignore,
+                   (it->w, CHARPOS (pos), &ignore,
                     (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
                     -1);
                  it->end_of_box_run_p
@@ -9344,7 +9272,7 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos)
 
   /* The commented-out optimization uses vmotion on terminals.  This
      gives bad results, because elements like it->what, on which
-     callers such as pos_visible_p rely, aren't updated. */
+     callers such as pos_visible_p rely, aren't updated.  */
   /* struct position pos;
     if (!FRAME_WINDOW_P (it->f))
     {
@@ -9362,7 +9290,7 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos)
     {
       /* DVPOS == 0 means move to the start of the screen line.  */
       move_it_vertically_backward (it, 0);
-      /* Let next call to line_bottom_y calculate real line height */
+      /* Let next call to line_bottom_y calculate real line height */
       last_height = 0;
     }
   else if (dvpos > 0)
@@ -9545,8 +9473,22 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
 
       old_deactivate_mark = Vdeactivate_mark;
       oldbuf = current_buffer;
-      Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
+
+      /* Ensure the Messages buffer exists, and switch to it.
+         If we created it, set the major-mode.  */
+      {
+        int newbuffer = 0;
+        if (NILP (Fget_buffer (Vmessages_buffer_name))) newbuffer = 1;
+
+        Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
+
+        if (newbuffer &&
+            !NILP (Ffboundp (intern ("messages-buffer-mode"))))
+          call0 (intern ("messages-buffer-mode"));
+      }
+
       bset_undo_list (current_buffer, Qt);
+      bset_cache_long_scans (current_buffer, Qnil);
 
       oldpoint = message_dolog_marker1;
       set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
@@ -9692,7 +9634,7 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
         shown in some window.  So we must manually incrementing
         windows_or_buffers_changed here to make up for that.  */
       if (shown)
-       windows_or_buffers_changed++;
+       windows_or_buffers_changed = 41;
       else
        windows_or_buffers_changed = old_windows_or_buffers_changed;
       message_log_need_newline = !nlflag;
@@ -9787,7 +9729,11 @@ message3_nolog (Lisp_Object m)
        putc ('\n', stderr);
       noninteractive_need_newline = 0;
       if (STRINGP (m))
-       fwrite (SDATA (m), SBYTES (m), 1, stderr);
+       {
+         Lisp_Object s = ENCODE_SYSTEM (m);
+
+         fwrite (SDATA (s), SBYTES (s), 1, stderr);
+       }
       if (cursor_in_echo_area == 0)
        fprintf (stderr, "\n");
       fflush (stderr);
@@ -9862,13 +9808,19 @@ message_with_string (const char *m, Lisp_Object string, int log)
     {
       if (m)
        {
+         /* ENCODE_SYSTEM below can GC and/or relocate the Lisp
+            String whose data pointer might be passed to us in M.  So
+            we use a local copy.  */
+         char *fmt = xstrdup (m);
+
          if (noninteractive_need_newline)
            putc ('\n', stderr);
          noninteractive_need_newline = 0;
-         fprintf (stderr, m, SDATA (string));
+         fprintf (stderr, fmt, SDATA (ENCODE_SYSTEM (string)));
          if (!cursor_in_echo_area)
            fprintf (stderr, "\n");
          fflush (stderr);
+         xfree (fmt);
        }
     }
   else if (INTERACTIVE)
@@ -10385,8 +10337,8 @@ resize_echo_area_exactly (void)
                                         (intptr_t) w, resize_exactly);
       if (resized_p)
        {
-         ++windows_or_buffers_changed;
-         ++update_mode_lines;
+         windows_or_buffers_changed = 42;
+         update_mode_lines = 30;
          redisplay_internal ();
        }
     }
@@ -10771,11 +10723,9 @@ clear_garbaged_frames (void)
          if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
            {
              if (f->resized_p)
-               {
-                 redraw_frame (f);
-                 f->force_flush_display_p = 1;
-               }
-             clear_current_matrices (f);
+               redraw_frame (f);
+             else
+               clear_current_matrices (f);
              changed_count++;
              f->garbaged = 0;
              f->resized_p = 0;
@@ -10784,7 +10734,7 @@ clear_garbaged_frames (void)
 
       frame_garbaged = 0;
       if (changed_count)
-       ++windows_or_buffers_changed;
+       windows_or_buffers_changed = 43;
     }
 }
 
@@ -10853,7 +10803,7 @@ echo_area_display (int update_frame_p)
                 pending input.  */
              ptrdiff_t count = SPECPDL_INDEX ();
              specbind (Qredisplay_dont_pause, Qt);
-             windows_or_buffers_changed = 1;
+             windows_or_buffers_changed = 44;
              redisplay_internal ();
              unbind_to (count, Qnil);
            }
@@ -10863,7 +10813,7 @@ echo_area_display (int update_frame_p)
                 Can do with a display update of the echo area,
                 unless we displayed some mode lines.  */
              update_single_window (w, 1);
-             FRAME_RIF (f)->flush_display (f);
+             flush_frame (f);
            }
          else
            update_frame (f, 1, 1);
@@ -10872,11 +10822,11 @@ echo_area_display (int update_frame_p)
             redisplay displays the minibuffer, so that the cursor will
             be replaced with what the minibuffer wants.  */
          if (cursor_in_echo_area)
-           ++windows_or_buffers_changed;
+           windows_or_buffers_changed = 45;
        }
     }
   else if (!EQ (mini_window, selected_window))
-    windows_or_buffers_changed++;
+    windows_or_buffers_changed = 46;
 
   /* Last displayed message is now the current message.  */
   echo_area_buffer[1] = echo_area_buffer[0];
@@ -10902,8 +10852,7 @@ buffer_shared_and_changed (void)
          && UNCHANGED_MODIFIED < MODIFF);
 }
 
-/* Nonzero if W's buffer was changed but not saved or Transient Mark mode
-   is enabled and mark of W's buffer was changed since last W's update.  */
+/* Nonzero if W's buffer was changed but not saved.  */
 
 static int
 window_buffer_changed (struct window *w)
@@ -10912,9 +10861,7 @@ window_buffer_changed (struct window *w)
 
   eassert (BUFFER_LIVE_P (b));
 
-  return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star)
-         || ((!NILP (Vtransient_mark_mode) && !NILP (BVAR (b, mark_active)))
-             != (w->region_showing != 0)));
+  return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star));
 }
 
 /* Nonzero if W has %c in its mode line and mode line should be updated.  */
@@ -11221,7 +11168,7 @@ x_consider_frame_title (Lisp_Object frame)
 /* Prepare for redisplay by updating menu-bar item lists when
    appropriate.  This can call eval.  */
 
-void
+static void
 prepare_menu_bars (void)
 {
   int all_windows;
@@ -11269,6 +11216,10 @@ prepare_menu_bars (void)
   all_windows = (update_mode_lines
                 || buffer_shared_and_changed ()
                 || windows_or_buffers_changed);
+
+  if (FUNCTIONP (Vpre_redisplay_function))
+    safe_call1 (Vpre_redisplay_function, all_windows ? Qt : Qnil);
+
   if (all_windows)
     {
       Lisp_Object tail, frame;
@@ -11451,10 +11402,6 @@ update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
 
 #ifdef HAVE_WINDOW_SYSTEM
 
-/* Where the mouse was last time we reported a mouse event.  */
-
-struct frame *last_mouse_frame;
-
 /* Tool-bar item index of the item on which a mouse button was pressed
    or -1.  */
 
@@ -11572,6 +11519,7 @@ update_tool_bar (struct frame *f, int save_match_data)
     }
 }
 
+#if ! defined (USE_GTK) && ! defined (HAVE_NS)
 
 /* Set F->desired_tool_bar_string to a Lisp string representing frame
    F's desired tool-bar contents.  F->tool_bar_items must have
@@ -11909,6 +11857,11 @@ tool_bar_lines_needed (struct frame *f, int *n_rows)
   return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
 }
 
+#endif /* !USE_GTK && !HAVE_NS */
+
+#if defined USE_GTK || defined HAVE_NS
+EXFUN (Ftool_bar_lines_needed, 1) ATTRIBUTE_CONST;
+#endif
 
 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
        0, 1, 0,
@@ -11916,9 +11869,10 @@ DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
 If FRAME is nil or omitted, use the selected frame.  */)
   (Lisp_Object frame)
 {
+  int nlines = 0;
+#if ! defined (USE_GTK) && ! defined (HAVE_NS)
   struct frame *f = decode_any_frame (frame);
   struct window *w;
-  int nlines = 0;
 
   if (WINDOWP (f->tool_bar_window)
       && (w = XWINDOW (f->tool_bar_window),
@@ -11931,7 +11885,7 @@ If FRAME is nil or omitted, use the selected frame.  */)
          nlines = tool_bar_lines_needed (f, NULL);
        }
     }
-
+#endif
   return make_number (nlines);
 }
 
@@ -11942,15 +11896,17 @@ If FRAME is nil or omitted, use the selected frame.  */)
 static int
 redisplay_tool_bar (struct frame *f)
 {
-  struct window *w;
-  struct it it;
-  struct glyph_row *row;
-
 #if defined (USE_GTK) || defined (HAVE_NS)
+
   if (FRAME_EXTERNAL_TOOL_BAR (f))
     update_frame_tool_bar (f);
   return 0;
-#endif
+
+#else /* !USE_GTK && !HAVE_NS */
+
+  struct window *w;
+  struct it it;
+  struct glyph_row *row;
 
   /* If frame hasn't a tool-bar window or if it is zero-height, don't
      do anything.  This means you must start with tool-bar-lines
@@ -11996,7 +11952,7 @@ redisplay_tool_bar (struct frame *f)
          if (WINDOW_TOTAL_LINES (w) != old_height)
            {
              clear_glyph_matrix (w->desired_matrix);
-             fonts_changed_p = 1;
+             f->fonts_changed = 1;
              return 1;
            }
        }
@@ -12097,7 +12053,7 @@ redisplay_tool_bar (struct frame *f)
                {
                  clear_glyph_matrix (w->desired_matrix);
                  f->n_tool_bar_rows = nrows;
-                 fonts_changed_p = 1;
+                 f->fonts_changed = 1;
                  return 1;
                }
            }
@@ -12106,8 +12062,11 @@ redisplay_tool_bar (struct frame *f)
 
   f->minimize_tool_bar_window_p = 0;
   return 0;
+
+#endif /* USE_GTK || HAVE_NS */
 }
 
+#if ! defined (USE_GTK) && ! defined (HAVE_NS)
 
 /* Get information about the tool-bar item which is displayed in GLYPH
    on frame F.  Return in *PROP_IDX the index where tool-bar item
@@ -12272,7 +12231,7 @@ note_tool_bar_highlight (struct frame *f, int x, int y)
 {
   Lisp_Object window = f->tool_bar_window;
   struct window *w = XWINDOW (window);
-  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
   Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
   int hpos, vpos;
   struct glyph *glyph;
@@ -12305,9 +12264,9 @@ note_tool_bar_highlight (struct frame *f, int x, int y)
   clear_mouse_face (hlinfo);
 
   /* Mouse is down, but on different tool-bar item?  */
-  mouse_down_p = (dpyinfo->grabbed
-                 && f == last_mouse_frame
-                 && FRAME_LIVE_P (f));
+  mouse_down_p = (x_mouse_grabbed (dpyinfo)
+                 && f == dpyinfo->last_mouse_frame);
+
   if (mouse_down_p
       && last_tool_bar_item != prop_idx)
     return;
@@ -12351,6 +12310,8 @@ note_tool_bar_highlight (struct frame *f, int x, int y)
     help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
 }
 
+#endif /* !USE_GTK && !HAVE_NS */
+
 #endif /* HAVE_WINDOW_SYSTEM */
 
 
@@ -12926,12 +12887,12 @@ redisplay_internal (void)
   int polling_stopped_here = 0;
   Lisp_Object tail, frame;
 
-  /* Non-zero means redisplay has to consider all windows on all
-     frames.  Zero means, only selected_window is considered.  */
-  int consider_all_windows_p;
+  /* True means redisplay has to consider all windows on all
+     frames.  False, only selected_window is considered.  */
+  bool consider_all_windows_p;
 
-  /* Non-zero means redisplay has to redisplay the miniwindow.  */
-  int update_miniwindow_p = 0;
+  /* True means redisplay has to redisplay the miniwindow.  */
+  bool update_miniwindow_p = false;
 
   TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
 
@@ -12983,20 +12944,11 @@ redisplay_internal (void)
   last_glyphless_glyph_frame = NULL;
   last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
 
-  /* If new fonts have been loaded that make a glyph matrix adjustment
-     necessary, do it.  */
-  if (fonts_changed_p)
-    {
-      adjust_glyphs (NULL);
-      ++windows_or_buffers_changed;
-      fonts_changed_p = 0;
-    }
-
   /* If face_change_count is non-zero, init_iterator will free all
      realized faces, which includes the faces referenced from current
      matrices.  So, we can't reuse current matrices in this case.  */
   if (face_change_count)
-    ++windows_or_buffers_changed;
+    windows_or_buffers_changed = 47;
 
   if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
       && FRAME_TTY (sf)->previous_frame != sf)
@@ -13004,7 +12956,7 @@ redisplay_internal (void)
       /* Since frames on a single ASCII terminal share the same
         display area, displaying a different frame means redisplay
         the whole thing.  */
-      windows_or_buffers_changed++;
+      windows_or_buffers_changed = 48;
       SET_FRAME_GARBAGED (sf);
 #ifndef DOS_NT
       set_tty_color_mode (FRAME_TTY (sf), sf);
@@ -13022,7 +12974,19 @@ redisplay_internal (void)
       struct frame *f = XFRAME (frame);
 
       if (FRAME_VISIBLE_P (f))
-       ++number_of_visible_frames;
+       {
+         ++number_of_visible_frames;
+         /* Adjust matrices for visible frames only.  */
+         if (f->fonts_changed)
+           {
+             adjust_frame_glyphs (f);
+             f->fonts_changed = 0;
+           }
+         /* If cursor type has been changed on the frame
+            other than selected, consider all frames.  */
+         if (f != sf && f->cursor_type_changed)
+           update_mode_lines = 31;
+       }
       clear_desired_matrices (f);
     }
 
@@ -13041,8 +13005,8 @@ redisplay_internal (void)
   if (NILP (Vmemory_full))
     prepare_menu_bars ();
 
-  if (windows_or_buffers_changed)
-    update_mode_lines++;
+  if (windows_or_buffers_changed && !update_mode_lines)
+    update_mode_lines = 32;
 
   reconsider_clip_changes (w);
 
@@ -13050,34 +13014,28 @@ redisplay_internal (void)
   match_p = XBUFFER (w->contents) == current_buffer;
   if (match_p)
     {
-      ptrdiff_t count1;
-
       /* Detect case that we need to write or remove a star in the mode line.  */
       if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
        {
          w->update_mode_line = 1;
          if (buffer_shared_and_changed ())
-           update_mode_lines++;
+           update_mode_lines = 33;
        }
 
-      /* Avoid invocation of point motion hooks by `current_column' below.  */
-      count1 = SPECPDL_INDEX ();
-      specbind (Qinhibit_point_motion_hooks, Qt);
-
       if (mode_line_update_needed (w))
        w->update_mode_line = 1;
-
-      unbind_to (count1, Qnil);
     }
 
   consider_all_windows_p = (update_mode_lines
-                           || buffer_shared_and_changed ()
-                           || cursor_type_changed);
+                           || buffer_shared_and_changed ());
 
   /* If specs for an arrow have changed, do thorough redisplay
      to ensure we remove any arrow that should no longer exist.  */
   if (overlay_arrows_changed_p ())
-    consider_all_windows_p = windows_or_buffers_changed = 1;
+    {
+      consider_all_windows_p = true;
+      windows_or_buffers_changed = 49;
+    }
 
   /* Normally the message* functions will have already displayed and
      updated the echo area, but the frame may have been trashed, or
@@ -13095,7 +13053,7 @@ redisplay_internal (void)
       int window_height_changed_p = echo_area_display (0);
 
       if (message_cleared_p)
-       update_miniwindow_p = 1;
+       update_miniwindow_p = true;
 
       must_finish = 1;
 
@@ -13106,13 +13064,11 @@ redisplay_internal (void)
       if (!display_last_displayed_message_p)
        message_cleared_p = 0;
 
-      if (fonts_changed_p)
-       goto retry;
-      else if (window_height_changed_p)
+      if (window_height_changed_p)
        {
-         consider_all_windows_p = 1;
-         ++update_mode_lines;
-         ++windows_or_buffers_changed;
+         consider_all_windows_p = true;
+         update_mode_lines = 34;
+         windows_or_buffers_changed = 50;
 
          /* If window configuration was changed, frames may have been
             marked garbaged.  Clear them or we will experience
@@ -13131,9 +13087,9 @@ redisplay_internal (void)
         since only the current frame needs to be considered.  This function
         needs to be rewritten with two variables, consider_all_windows and
         consider_all_frames.  */
-      consider_all_windows_p = 1;
-      ++windows_or_buffers_changed;
-      ++update_mode_lines;
+      consider_all_windows_p = true;
+      windows_or_buffers_changed = 51;
+      update_mode_lines = 35;
 
       /* If window configuration was changed, frames may have been
         marked garbaged.  Clear them or we will experience
@@ -13141,16 +13097,23 @@ redisplay_internal (void)
       clear_garbaged_frames ();
     }
 
-  /* If showing the region, and mark has changed, we must redisplay
-     the whole window.  The assignment to this_line_start_pos prevents
-     the optimization directly below this if-statement.  */
-  if (((!NILP (Vtransient_mark_mode)
-       && !NILP (BVAR (XBUFFER (w->contents), mark_active)))
-       != (w->region_showing > 0))
-      || (w->region_showing
-         && w->region_showing
-         != XINT (Fmarker_position (BVAR (XBUFFER (w->contents), mark)))))
-    CHARPOS (this_line_start_pos) = 0;
+  if (VECTORP (Vredisplay__all_windows_cause)
+      && windows_or_buffers_changed >= 0
+      && windows_or_buffers_changed < ASIZE (Vredisplay__all_windows_cause)
+      && INTEGERP (AREF (Vredisplay__all_windows_cause,
+                        windows_or_buffers_changed)))
+    ASET (Vredisplay__all_windows_cause, windows_or_buffers_changed,
+         make_number (1 + XINT (AREF (Vredisplay__all_windows_cause,
+                                      windows_or_buffers_changed))));
+
+  if (VECTORP (Vredisplay__mode_lines_cause)
+      && update_mode_lines >= 0
+      && update_mode_lines < ASIZE (Vredisplay__mode_lines_cause)
+      && INTEGERP (AREF (Vredisplay__mode_lines_cause,
+                        update_mode_lines)))
+    ASET (Vredisplay__mode_lines_cause, update_mode_lines,
+         make_number (1 + XINT (AREF (Vredisplay__mode_lines_cause,
+                                      update_mode_lines))));
 
   /* Optimize the case that only the line containing the cursor in the
      selected window has changed.  Variables starting with this_ are
@@ -13165,6 +13128,7 @@ redisplay_internal (void)
       && !current_buffer->prevent_redisplay_optimizations_p
       && FRAME_VISIBLE_P (XFRAME (w->frame))
       && !FRAME_OBSCURED_P (XFRAME (w->frame))
+      && !XFRAME (w->frame)->cursor_type_changed
       /* Make sure recorded data applies to current buffer, etc.  */
       && this_line_buffer == current_buffer
       && match_p
@@ -13310,13 +13274,7 @@ redisplay_internal (void)
        }
       /* If highlighting the region, or if the cursor is in the echo area,
         then we can't just move the cursor.  */
-      else if (! (!NILP (Vtransient_mark_mode)
-                 && !NILP (BVAR (current_buffer, mark_active)))
-              && (EQ (selected_window,
-                      BVAR (current_buffer, last_selected_window))
-                  || highlight_nonselected_windows)
-              && !w->region_showing
-              && NILP (Vshow_trailing_whitespace)
+      else if (NILP (Vshow_trailing_whitespace)
               && !cursor_in_echo_area)
        {
          struct it it;
@@ -13358,7 +13316,6 @@ redisplay_internal (void)
     }
 
   CHARPOS (this_line_start_pos) = 0;
-  consider_all_windows_p |= buffer_shared_and_changed ();
   ++clear_face_cache_count;
 #ifdef HAVE_WINDOW_SYSTEM
   ++clear_image_cache_count;
@@ -13383,6 +13340,8 @@ redisplay_internal (void)
              && !EQ (FRAME_TTY (f)->top_frame, frame))
            continue;
 
+       retry_frame:
+
          if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
            {
              /* Mark all the scroll bars to be removed; we'll redeem
@@ -13402,20 +13361,22 @@ redisplay_internal (void)
              if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
                FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
 
-             /* If fonts changed, display again.  */
-             /* ??? rms: I suspect it is a mistake to jump all the way
-                back to retry here.  It should just retry this frame.  */
-             if (fonts_changed_p)
-               goto retry;
-
              if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
                {
+                 /* If fonts changed on visible frame, display again.  */
+                 if (f->fonts_changed)
+                   {
+                     adjust_frame_glyphs (f);
+                     f->fonts_changed = 0;
+                     goto retry_frame;
+                   }
+
                  /* See if we have to hscroll.  */
                  if (!f->already_hscrolled_p)
                    {
                      f->already_hscrolled_p = 1;
                      if (hscroll_windows (f->root_window))
-                       goto retry;
+                       goto retry_frame;
                    }
 
                  /* Prevent various kinds of signals during display
@@ -13426,9 +13387,15 @@ redisplay_internal (void)
                    unrequest_sigio ();
                  STOP_POLLING;
 
-                 /* Update the display.  */
-                 set_window_update_flags (XWINDOW (f->root_window), 1);
+                 /* Mark windows on frame F to update.  If we decide to
+                    update all frames but windows_or_buffers_changed is
+                    zero, we assume that only the windows that shows
+                    current buffer should be really updated.  */
+                 set_window_update_flags
+                   (XWINDOW (f->root_window),
+                    (windows_or_buffers_changed ? NULL : current_buffer), 1);
                  pending |= update_frame (f, 0, 0);
+                 f->cursor_type_changed = 0;
                  f->updated_p = 1;
                }
            }
@@ -13473,7 +13440,7 @@ redisplay_internal (void)
 
     update:
       /* If fonts changed, display again.  */
-      if (fonts_changed_p)
+      if (sf->fonts_changed)
        goto retry;
 
       /* Prevent various kinds of signals during display update.
@@ -13490,6 +13457,7 @@ redisplay_internal (void)
 
          XWINDOW (selected_window)->must_be_updated_p = 1;
          pending = update_frame (sf, 0, 0);
+         sf->cursor_type_changed = 0;
        }
 
       /* We may have called echo_area_display at the top of this
@@ -13504,6 +13472,7 @@ redisplay_internal (void)
        {
          XWINDOW (mini_window)->must_be_updated_p = 1;
          pending |= update_frame (mini_frame, 0, 0);
+         mini_frame->cursor_type_changed = 0;
          if (!pending && hscroll_windows (mini_window))
            goto retry;
        }
@@ -13525,7 +13494,7 @@ redisplay_internal (void)
         matrices of some windows are not valid.  */
       if (!WINDOW_FULL_WIDTH_P (w)
          && !FRAME_WINDOW_P (XFRAME (w->frame)))
-       update_mode_lines = 1;
+       update_mode_lines = 36;
     }
   else
     {
@@ -13544,7 +13513,6 @@ redisplay_internal (void)
 
       update_mode_lines = 0;
       windows_or_buffers_changed = 0;
-      cursor_type_changed = 0;
     }
 
   /* Start SIGIO interrupts coming again.  Having them off during the
@@ -13577,7 +13545,7 @@ redisplay_internal (void)
        }
 
       if (new_count != number_of_visible_frames)
-       windows_or_buffers_changed++;
+       windows_or_buffers_changed = 52;
     }
 
   /* Change frame size now if a change is pending.  */
@@ -13642,9 +13610,7 @@ redisplay_preserve_echo_area (int from_where)
   else
     redisplay_internal ();
 
-  if (FRAME_RIF (SELECTED_FRAME ()) != NULL
-      && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
-    FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
+  flush_frame (SELECTED_FRAME ());
 }
 
 
@@ -14986,12 +14952,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
         cases.  */
       && !update_mode_lines
       && !windows_or_buffers_changed
-      && !cursor_type_changed
-      /* Can't use this case if highlighting a region.  When a
-         region exists, cursor movement has to do more than just
-         set the cursor.  */
-      && markpos_of_region () < 0
-      && !w->region_showing
+      && !f->cursor_type_changed
       && NILP (Vshow_trailing_whitespace)
       /* This code is not used for mini-buffer for the sake of the case
         of redisplaying to replace an echo area message; since in
@@ -15333,9 +15294,8 @@ set_vertical_scroll_bar (struct window *w)
 /* Redisplay leaf window WINDOW.  JUST_THIS_ONE_P non-zero means only
    selected_window is redisplayed.
 
-   We can return without actually redisplaying the window if
-   fonts_changed_p.  In that case, redisplay_internal will
-   retry.  */
+   We can return without actually redisplaying the window if fonts has been
+   changed on window's frame.  In that case, redisplay_internal will retry.  */
 
 static void
 redisplay_window (Lisp_Object window, int just_this_one_p)
@@ -15398,7 +15358,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
        }
       else if ((w != XWINDOW (minibuf_window)
                || minibuf_level == 0)
-              /* When buffer is nonempty, redisplay window normally. */
+              /* When buffer is nonempty, redisplay window normally.  */
               && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
               /* Quail displays non-mini buffers in minibuffer window.
                  In that case, redisplay the window normally.  */
@@ -15607,7 +15567,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
             Move it back to a fully-visible line.  */
          new_vpos = window_box_height (w);
        }
-      else if (w->cursor.vpos >=0)
+      else if (w->cursor.vpos >= 0)
        {
          /* Some people insist on not letting point enter the scroll
             margin, even though this part handles windows that didn't
@@ -15665,12 +15625,14 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
 
          /* If we are highlighting the region, then we just changed
             the region, so redisplay to show it.  */
-         if (markpos_of_region () >= 0)
+         /* FIXME: We need to (re)run pre-redisplay-function!  */
+         /* if (markpos_of_region () >= 0)
            {
              clear_glyph_matrix (w->desired_matrix);
              if (!try_window (window, startp, 0))
                goto need_larger_matrices;
            }
+         */
        }
 
 #ifdef GLYPH_DEBUG
@@ -15720,7 +15682,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
       debug_method_add (w, "try_window_id %d", tem);
 #endif
 
-      if (fonts_changed_p)
+      if (f->fonts_changed)
        goto need_larger_matrices;
       if (tem > 0)
        goto done;
@@ -15790,12 +15752,12 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
          IF_DEBUG (debug_method_add (w, "1"));
          if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
            /* -1 means we need to scroll.
-              0 means we need new matrices, but fonts_changed_p
+              0 means we need new matrices, but fonts_changed
               is set in that case, so we will detect it below.  */
            goto try_to_scroll;
        }
 
-      if (fonts_changed_p)
+      if (f->fonts_changed)
        goto need_larger_matrices;
 
       if (w->cursor.vpos >= 0)
@@ -15983,7 +15945,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
   /* Redisplay the window.  */
   if (!current_matrix_up_to_date_p
       || windows_or_buffers_changed
-      || cursor_type_changed
+      || f->cursor_type_changed
       /* Don't use try_window_reusing_current_matrix in this case
         because it can have changed the buffer.  */
       || !NILP (Vwindow_scroll_functions)
@@ -15996,7 +15958,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
   /* If new fonts have been loaded (due to fontsets), give up.  We
      have to start a new redisplay since we need to re-adjust glyph
      matrices.  */
-  if (fonts_changed_p)
+  if (f->fonts_changed)
     goto need_larger_matrices;
 
   /* If cursor did not appear assume that the middle of the window is
@@ -16109,7 +16071,8 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
       if (WINDOW_WANTS_MODELINE_P (w)
          && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
        {
-         fonts_changed_p = 1;
+         f->fonts_changed = 1;
+         w->mode_line_height = -1;
          MATRIX_MODE_LINE_ROW (w->current_matrix)->height
            = DESIRED_MODE_LINE_HEIGHT (w);
        }
@@ -16119,12 +16082,13 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
       if (WINDOW_WANTS_HEADER_LINE_P (w)
          && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
        {
-         fonts_changed_p = 1;
+         f->fonts_changed = 1;
+         w->header_line_height = -1;
          MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
            = DESIRED_HEADER_LINE_HEIGHT (w);
        }
 
-      if (fonts_changed_p)
+      if (f->fonts_changed)
        goto need_larger_matrices;
     }
 
@@ -16189,8 +16153,8 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
     }
 #endif /* HAVE_WINDOW_SYSTEM */
 
-  /* We go to this label, with fonts_changed_p set,
-     if it is necessary to try again using larger glyph matrices.
+  /* We go to this label, with fonts_changed set, if it is
+     necessary to try again using larger glyph matrices.
      We have to redeem the scroll bar even in this case,
      because the loop in redisplay_internal expects that.  */
  need_larger_matrices:
@@ -16262,7 +16226,7 @@ try_window (Lisp_Object window, struct text_pos pos, int flags)
     {
       if (display_line (&it))
        last_text_row = it.glyph_row - 1;
-      if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
+      if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
        return 0;
     }
 
@@ -16360,13 +16324,11 @@ try_window_reusing_current_matrix (struct window *w)
       /* Don't try to reuse the display if windows have been split
         or such.  */
       || windows_or_buffers_changed
-      || cursor_type_changed)
+      || f->cursor_type_changed)
     return 0;
 
-  /* Can't do this if region may have changed.  */
-  if (markpos_of_region () >= 0
-      || w->region_showing
-      || !NILP (Vshow_trailing_whitespace))
+  /* Can't do this if showing trailing whitespace.  */
+  if (!NILP (Vshow_trailing_whitespace))
     return 0;
 
   /* If top-line visibility has changed, give up.  */
@@ -16408,8 +16370,7 @@ try_window_reusing_current_matrix (struct window *w)
       w->cursor.vpos = -1;
       last_text_row = last_reused_text_row = NULL;
 
-      while (it.current_y < it.last_visible_y
-            && !fonts_changed_p)
+      while (it.current_y < it.last_visible_y && !f->fonts_changed)
        {
          /* If we have reached into the characters in the START row,
             that means the line boundaries have changed.  So we
@@ -16620,7 +16581,7 @@ try_window_reusing_current_matrix (struct window *w)
       if (pt_row == NULL)
        w->cursor.vpos = -1;
       last_text_row = NULL;
-      while (it.current_y < it.last_visible_y && !fonts_changed_p)
+      while (it.current_y < it.last_visible_y && !f->fonts_changed)
        if (display_line (&it))
          last_text_row = it.glyph_row - 1;
 
@@ -17132,7 +17093,7 @@ try_window_id (struct window *w)
     GIVE_UP (1);
 
   /* This flag is used to prevent redisplay optimizations.  */
-  if (windows_or_buffers_changed || cursor_type_changed)
+  if (windows_or_buffers_changed || f->cursor_type_changed)
     GIVE_UP (2);
 
   /* Verify that narrowing has not changed.
@@ -17165,19 +17126,10 @@ try_window_id (struct window *w)
   if (!w->window_end_valid)
     GIVE_UP (8);
 
-  /* Can't use this if highlighting a region because a cursor movement
-     will do more than just set the cursor.  */
-  if (markpos_of_region () >= 0)
-    GIVE_UP (9);
-
   /* Likewise if highlighting trailing whitespace.  */
   if (!NILP (Vshow_trailing_whitespace))
     GIVE_UP (11);
 
-  /* Likewise if showing a region.  */
-  if (w->region_showing)
-    GIVE_UP (10);
-
   /* Can't use this if overlay arrow position and/or string have
      changed.  */
   if (overlay_arrows_changed_p ())
@@ -17273,8 +17225,6 @@ try_window_id (struct window *w)
          row = row_containing_pos (w, PT, r0, NULL, 0);
          if (row)
            set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
-         else
-           emacs_abort ();
          return 1;
        }
     }
@@ -17315,8 +17265,6 @@ try_window_id (struct window *w)
          row = row_containing_pos (w, PT, r0, NULL, 0);
          if (row)
            set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
-         else
-           emacs_abort ();
          return 2;
        }
     }
@@ -17463,7 +17411,7 @@ try_window_id (struct window *w)
   last_text_row = NULL;
   overlay_arrow_seen = 0;
   while (it.current_y < it.last_visible_y
-        && !fonts_changed_p
+        && !f->fonts_changed
         && (first_unchanged_at_end_row == NULL
             || IT_CHARPOS (it) < stop_pos))
     {
@@ -17471,7 +17419,7 @@ try_window_id (struct window *w)
        last_text_row = it.glyph_row - 1;
     }
 
-  if (fonts_changed_p)
+  if (f->fonts_changed)
     return -1;
 
 
@@ -17718,8 +17666,7 @@ try_window_id (struct window *w)
 
       /* Display the rest of the lines at the window end.  */
       it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
-      while (it.current_y < it.last_visible_y
-            && !fonts_changed_p)
+      while (it.current_y < it.last_visible_y && !f->fonts_changed)
        {
          /* Is it always sure that the display agrees with lines in
             the current matrix?  I don't think so, so we mark rows
@@ -18097,9 +18044,13 @@ DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
        doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
 GLYPH 0 means don't dump glyphs.
 GLYPH 1 means dump glyphs in short form.
-GLYPH > 1 or omitted means dump glyphs in long form.  */)
+GLYPH > 1 or omitted means dump glyphs in long form.
+
+If there's no tool-bar, or if the tool-bar is not drawn by Emacs,
+do nothing.  */)
   (Lisp_Object row, Lisp_Object glyphs)
 {
+#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
   struct frame *sf = SELECTED_FRAME ();
   struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
   EMACS_INT vpos;
@@ -18109,6 +18060,7 @@ GLYPH > 1 or omitted means dump glyphs in long form.  */)
   if (vpos >= 0 && vpos < m->nrows)
     dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
                    TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
+#endif
   return Qnil;
 }
 
@@ -18521,7 +18473,7 @@ append_space_for_newline (struct it *it, int default_face_p)
          it->len = 1;
 
          /* If the default face was remapped, be sure to use the
-            remapped face for the appended newline. */
+            remapped face for the appended newline.  */
          if (default_face_p)
            it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
          else if (it->face_before_selective_p)
@@ -18599,7 +18551,9 @@ extend_face_to_end_of_line (struct it *it)
       && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
       && face->box == FACE_NO_BOX
       && face->background == FRAME_BACKGROUND_PIXEL (f)
+#ifdef HAVE_WINDOW_SYSTEM
       && !face->stipple
+#endif
       && !it->glyph_row->reversed_p)
     return;
 
@@ -19255,13 +19209,10 @@ display_line (struct it *it)
       >= it->w->desired_matrix->nrows)
     {
       it->w->nrows_scale_factor++;
-      fonts_changed_p = 1;
+      it->f->fonts_changed = 1;
       return 0;
     }
 
-  /* Is IT->w showing the region?  */
-  it->w->region_showing = it->region_beg_charpos > 0 ? it->region_beg_charpos : 0;
-
   /* Clear the result glyph row and enable it.  */
   prepare_desired_row (row);
 
@@ -20568,7 +20519,129 @@ display_menu_bar (struct window *w)
   compute_line_metrics (&it);
 }
 
+#ifdef HAVE_MENUS
+/* Deep copy of a glyph row, including the glyphs.  */
+static void
+deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
+{
+  struct glyph *pointers[1 + LAST_AREA];
+  int to_used = to->used[TEXT_AREA];
+
+  /* Save glyph pointers of TO.  */
+  memcpy (pointers, to->glyphs, sizeof to->glyphs);
+
+  /* Do a structure assignment.  */
+  *to = *from;
 
+  /* Restore original glyph pointers of TO.  */
+  memcpy (to->glyphs, pointers, sizeof to->glyphs);
+
+  /* Copy the glyphs.  */
+  memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA],
+         min (from->used[TEXT_AREA], to_used) * sizeof (struct glyph));
+
+  /* If we filled only part of the TO row, fill the rest with
+     space_glyph (which will display as empty space).  */
+  if (to_used > from->used[TEXT_AREA])
+    fill_up_frame_row_with_spaces (to, to_used);
+}
+
+/* Display one menu item on a TTY, by overwriting the glyphs in the
+   frame F's desired glyph matrix with glyphs produced from the menu
+   item text.  Called from term.c to display TTY drop-down menus one
+   item at a time.
+
+   ITEM_TEXT is the menu item text as a C string.
+
+   FACE_ID is the face ID to be used for this menu item.  FACE_ID
+   could specify one of 3 faces: a face for an enabled item, a face
+   for a disabled item, or a face for a selected item.
+
+   X and Y are coordinates of the first glyph in the frame's desired
+   matrix to be overwritten by the menu item.  Since this is a TTY, Y
+   is the zero-based number of the glyph row and X is the zero-based
+   glyph number in the row, starting from left, where to start
+   displaying the item.
+
+   SUBMENU non-zero means this menu item drops down a submenu, which
+   should be indicated by displaying a proper visual cue after the
+   item text.  */
+
+void
+display_tty_menu_item (const char *item_text, int width, int face_id,
+                      int x, int y, int submenu)
+{
+  struct it it;
+  struct frame *f = SELECTED_FRAME ();
+  struct window *w = XWINDOW (f->selected_window);
+  int saved_used, saved_truncated, saved_width, saved_reversed;
+  struct glyph_row *row;
+  size_t item_len = strlen (item_text);
+
+  eassert (FRAME_TERMCAP_P (f));
+
+  /* Don't write beyond the matrix's last row.  This can happen for
+     TTY screens that are not high enough to show the entire menu.
+     (This is actually a bit of defensive programming, as
+     tty_menu_display already limits the number of menu items to one
+     less than the number of screen lines.)  */
+  if (y >= f->desired_matrix->nrows)
+    return;
+
+  init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID);
+  it.first_visible_x = 0;
+  it.last_visible_x = FRAME_COLS (f) - 1;
+  row = it.glyph_row;
+  /* Start with the row contents from the current matrix.  */
+  deep_copy_glyph_row (row, f->current_matrix->rows + y);
+  saved_width = row->full_width_p;
+  row->full_width_p = 1;
+  saved_reversed = row->reversed_p;
+  row->reversed_p = 0;
+  row->enabled_p = 1;
+
+  /* Arrange for the menu item glyphs to start at (X,Y) and have the
+     desired face.  */
+  eassert (x < f->desired_matrix->matrix_w);
+  it.current_x = it.hpos = x;
+  it.current_y = it.vpos = y;
+  saved_used = row->used[TEXT_AREA];
+  saved_truncated = row->truncated_on_right_p;
+  row->used[TEXT_AREA] = x;
+  it.face_id = face_id;
+  it.line_wrap = TRUNCATE;
+
+  /* FIXME: This should be controlled by a user option.  See the
+     comments in redisplay_tool_bar and display_mode_line about this.
+     Also, if paragraph_embedding could ever be R2L, changes will be
+     needed to avoid shifting to the right the row characters in
+     term.c:append_glyph.  */
+  it.paragraph_embedding = L2R;
+
+  /* Pad with a space on the left.  */
+  display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, FRAME_COLS (f) - 1, -1);
+  width--;
+  /* Display the menu item, pad with spaces to WIDTH.  */
+  if (submenu)
+    {
+      display_string (item_text, Qnil, Qnil, 0, 0, &it,
+                     item_len, 0, FRAME_COLS (f) - 1, -1);
+      width -= item_len;
+      /* Indicate with " >" that there's a submenu.  */
+      display_string (" >", Qnil, Qnil, 0, 0, &it, width, 0,
+                     FRAME_COLS (f) - 1, -1);
+    }
+  else
+    display_string (item_text, Qnil, Qnil, 0, 0, &it,
+                   width, 0, FRAME_COLS (f) - 1, -1);
+
+  row->used[TEXT_AREA] = max (saved_used, row->used[TEXT_AREA]);
+  row->truncated_on_right_p = saved_truncated;
+  row->hash = row_hash (row);
+  row->full_width_p = saved_width;
+  row->reversed_p = saved_reversed;
+}
+#endif /* HAVE_MENUS */
 \f
 /***********************************************************************
                              Mode Line
@@ -20607,13 +20680,8 @@ redisplay_mode_lines (Lisp_Object window, int force)
            {
              struct text_pos pt;
 
-             SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
-             if (CHARPOS (pt) < BEGV)
-               TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
-             else if (CHARPOS (pt) > (ZV - 1))
-               TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
-             else
-               TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
+             CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
+             TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
            }
 
          /* Display mode lines.  */
@@ -22278,9 +22346,7 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st
 
       it->face_id
        = face_at_string_position (it->w, face_string, face_string_pos,
-                                  0, it->region_beg_charpos,
-                                  it->region_end_charpos,
-                                  &endptr, it->base_face_id, 0);
+                                  0, &endptr, it->base_face_id, 0);
       face = FACE_FROM_ID (it->f, it->face_id);
       it->face_box_p = face->box != FACE_NO_BOX;
     }
@@ -23988,12 +24054,12 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
 
 #define IT_EXPAND_MATRIX_WIDTH(it, area)               \
   {                                                    \
-    if (!fonts_changed_p                               \
+    if (!it->f->fonts_changed                          \
        && (it->glyph_row->glyphs[area]                 \
            < it->glyph_row->glyphs[area + 1]))         \
       {                                                        \
        it->w->ncols_scale_factor++;                    \
-       fonts_changed_p = 1;                            \
+       it->f->fonts_changed = 1;                       \
       }                                                        \
   }
 
@@ -24909,21 +24975,7 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
   base_height = it->ascent + it->descent;
   base_width = font->average_width;
 
-  /* Get a face ID for the glyph by utilizing a cache (the same way as
-     done for `escape-glyph' in get_next_display_element).  */
-  if (it->f == last_glyphless_glyph_frame
-      && it->face_id == last_glyphless_glyph_face_id)
-    {
-      face_id = last_glyphless_glyph_merged_face_id;
-    }
-  else
-    {
-      /* Merge the `glyphless-char' face into the current face.  */
-      face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
-      last_glyphless_glyph_frame = it->f;
-      last_glyphless_glyph_face_id = it->face_id;
-      last_glyphless_glyph_merged_face_id = face_id;
-    }
+  face_id = merge_glyphless_glyph_face (it);
 
   if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
     {
@@ -25021,7 +25073,7 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
       lower_yoff = descent - 2 - metrics_lower.descent;
       upper_yoff = (lower_yoff - metrics_lower.ascent - 1
                    - metrics_upper.descent);
-      /* Don't make the height shorter than the base height. */
+      /* Don't make the height shorter than the base height.  */
       if (height > base_height)
        {
          it->ascent = ascent;
@@ -25058,16 +25110,16 @@ x_produce_glyphs (struct it *it)
       struct face *face = FACE_FROM_ID (it->f, it->face_id);
       struct font *font = face->font;
       struct font_metrics *pcm = NULL;
-      int boff;                        /* baseline offset */
+      int boff;                        /* Baseline offset.  */
 
       if (font == NULL)
        {
          /* When no suitable font is found, display this character by
             the method specified in the first extra slot of
             Vglyphless_char_display.  */
-         Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
+             Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
 
-         eassert (it->what == IT_GLYPHLESS);
+             eassert (it->what == IT_GLYPHLESS);
          produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
          goto done;
        }
@@ -25205,7 +25257,7 @@ x_produce_glyphs (struct it *it)
        {
          /* A newline has no width, but we need the height of the
             line.  But if previous part of the line sets a height,
-            don't increase that height */
+            don't increase that height */
 
          Lisp_Object height;
          Lisp_Object total_height = Qnil;
@@ -25215,7 +25267,7 @@ x_produce_glyphs (struct it *it)
          it->nglyphs = 0;
 
          height = get_it_property (it, Qline_height);
-         /* Split (line-height total-height) list */
+         /* Split (line-height total-height) list */
          if (CONSP (height)
              && CONSP (XCDR (height))
              && NILP (XCDR (XCDR (height))))
@@ -25964,7 +26016,7 @@ set_frame_cursor_types (struct frame *f, Lisp_Object arg)
     FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
 
   /* Make sure the cursor gets redrawn.  */
-  cursor_type_changed = 1;
+  f->cursor_type_changed = 1;
 }
 
 
@@ -26015,7 +26067,7 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
 
   /* Detect a nonselected window or nonselected frame.  */
   else if (w != XWINDOW (f->selected_window)
-          || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
+          || f != FRAME_DISPLAY_INFO (f)->x_highlight_frame)
     {
       *active_cursor = 0;
 
@@ -26291,9 +26343,11 @@ draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
 }
 
 
-/* EXPORT:
-   Erase the image of a cursor of window W from the screen.  */
+/* Erase the image of a cursor of window W from the screen.  */
 
+#ifndef HAVE_NTGUI
+static
+#endif
 void
 erase_phys_cursor (struct window *w)
 {
@@ -26712,10 +26766,13 @@ show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
   /* Change the mouse cursor.  */
   if (FRAME_WINDOW_P (f))
     {
+#if ! defined (USE_GTK) && ! defined (HAVE_NS)
       if (draw == DRAW_NORMAL_TEXT
          && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
        FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
-      else if (draw == DRAW_MOUSE_FACE)
+      else
+#endif
+      if (draw == DRAW_MOUSE_FACE)
        FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
       else
        FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
@@ -27293,7 +27350,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
 
   hlinfo->mouse_face_window = window;
   hlinfo->mouse_face_face_id
-    = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
+    = face_at_buffer_position (w, mouse_charpos, &ignore,
                               mouse_charpos + 1,
                               !hlinfo->mouse_face_hidden, -1);
   show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
@@ -27384,7 +27441,7 @@ fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
 #endif /* not used */
 
 /* Find the positions of the first and the last glyphs in window W's
-   current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
+   current matrix that occlude positions [STARTPOS..ENDPOS) in OBJECT
    (assumed to be a string), and return in HLINFO's mouse_face_*
    members the pixel and column/row coordinates of those glyphs.  */
 
@@ -27400,7 +27457,7 @@ mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
   int found = 0;
 
   /* Find the glyph row with at least one position in the range
-     [STARTPOS..ENDPOS], and the first glyph in that row whose
+     [STARTPOS..ENDPOS), and the first glyph in that row whose
      position belongs to that range.  */
   for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
        r->enabled_p && r->y < yb;
@@ -27412,7 +27469,7 @@ mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
          e = g + r->used[TEXT_AREA];
          for (gx = r->x; g < e; gx += g->pixel_width, ++g)
            if (EQ (g->object, object)
-               && startpos <= g->charpos && g->charpos <= endpos)
+               && startpos <= g->charpos && g->charpos < endpos)
              {
                hlinfo->mouse_face_beg_row
                  = MATRIX_ROW_VPOS (r, w->current_matrix);
@@ -27430,7 +27487,7 @@ mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
          g = e + r->used[TEXT_AREA];
          for ( ; g > e; --g)
            if (EQ ((g-1)->object, object)
-               && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
+               && startpos <= (g-1)->charpos && (g-1)->charpos < endpos)
              {
                hlinfo->mouse_face_beg_row
                  = MATRIX_ROW_VPOS (r, w->current_matrix);
@@ -27458,7 +27515,7 @@ mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
       found = 0;
       for ( ; g < e; ++g)
        if (EQ (g->object, object)
-           && startpos <= g->charpos && g->charpos <= endpos)
+           && startpos <= g->charpos && g->charpos < endpos)
          {
            found = 1;
            break;
@@ -27481,7 +27538,7 @@ mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
       e = g + r->used[TEXT_AREA];
       for ( ; e > g; --e)
        if (EQ ((e-1)->object, object)
-           && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
+           && startpos <= (e-1)->charpos && (e-1)->charpos < endpos)
          break;
       hlinfo->mouse_face_end_col = e - g;
 
@@ -27496,7 +27553,7 @@ mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
       for (gx = r->x ; e < g; ++e)
        {
          if (EQ (e->object, object)
-             && startpos <= e->charpos && e->charpos <= endpos)
+             && startpos <= e->charpos && e->charpos < endpos)
            break;
          gx += e->pixel_width;
        }
@@ -27665,7 +27722,7 @@ define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
        cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
 #ifdef HAVE_X_WINDOWS
       else if (EQ (pointer, intern ("vdrag")))
-       cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
+       cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
 #endif
       else if (EQ (pointer, intern ("hourglass")))
        cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
@@ -27828,7 +27885,7 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
       /* Change the mouse pointer according to what is under it.  */
       if (FRAME_WINDOW_P (f))
        {
-         dpyinfo = FRAME_X_DISPLAY_INFO (f);
+         dpyinfo = FRAME_DISPLAY_INFO (f);
          if (STRINGP (string))
            {
              cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
@@ -27850,7 +27907,7 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
            }
          else
            /* Default mode-line pointer.  */
-           cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
+           cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
        }
 #endif
     }
@@ -27974,8 +28031,7 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
 
          hlinfo->mouse_face_face_id = face_at_string_position (w, string,
                                                                charpos,
-                                                               0, 0, 0,
-                                                               &ignore,
+                                                               0, &ignore,
                                                                glyph->face_id,
                                                                1);
          show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
@@ -28053,7 +28109,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
   w = XWINDOW (window);
   frame_to_window_pixel_xy (w, &x, &y);
 
-#ifdef HAVE_WINDOW_SYSTEM
+#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
   /* Handle tool-bar window differently since it doesn't display a
      buffer.  */
   if (EQ (window, f->tool_bar_window))
@@ -28270,13 +28326,13 @@ note_mouse_highlight (struct frame *f, int x, int y)
              if (NILP (s))
                s = make_number (0);
              if (NILP (e))
-               e = make_number (SCHARS (object) - 1);
+               e = make_number (SCHARS (object));
              mouse_face_from_string_pos (w, hlinfo, object,
                                          XINT (s), XINT (e));
              hlinfo->mouse_face_past_end = 0;
              hlinfo->mouse_face_window = window;
              hlinfo->mouse_face_face_id
-               = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
+               = face_at_string_position (w, object, pos, 0, &ignore,
                                           glyph->face_id, 1);
              show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
              cursor = No_Cursor;
@@ -28323,13 +28379,14 @@ note_mouse_highlight (struct frame *f, int x, int y)
                     the first row visible in a window does not
                     necessarily display the character whose position
                     is the smallest.  */
-                 Lisp_Object lim1 =
-                   NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
+                 Lisp_Object lim1
+                   NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
                    ? Fmarker_position (w->start)
                    : Qnil;
-                 Lisp_Object lim2 =
-                   NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
-                   ? make_number (BUF_Z (XBUFFER (buffer)) - w->window_end_pos)
+                 Lisp_Object lim2
+                   = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
+                   ? make_number (BUF_Z (XBUFFER (buffer))
+                                  - w->window_end_pos)
                    : Qnil;
 
                  if (NILP (overlay))
@@ -28727,7 +28784,7 @@ x_draw_vertical_border (struct window *w)
     {
       int x0, x1, y0, y1;
 
-      window_box_edges (w, -1, &x0, &y0, &x1, &y1);
+      window_box_edges (w, &x0, &y0, &x1, &y1);
       y1 -= 1;
 
       if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
@@ -28740,7 +28797,7 @@ x_draw_vertical_border (struct window *w)
     {
       int x0, x1, y0, y1;
 
-      window_box_edges (w, -1, &x0, &y0, &x1, &y1);
+      window_box_edges (w, &x0, &y0, &x1, &y1);
       y1 -= 1;
 
       if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
@@ -28966,9 +29023,11 @@ expose_frame (struct frame *f, int x, int y, int w, int h)
   TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
   mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
 
+#if ! defined (USE_GTK) && ! defined (HAVE_NS)
   if (WINDOWP (f->tool_bar_window))
     mouse_face_overwritten_p
       |= expose_window (XWINDOW (f->tool_bar_window), &r);
+#endif
 
 #ifdef HAVE_X_WINDOWS
 #ifndef MSDOS
@@ -29649,8 +29708,10 @@ cursor shapes.  */);
               doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy.  */);
   Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
 
+#ifdef HAVE_WINDOW_SYSTEM
   hourglass_atimer = NULL;
   hourglass_shown_p = 0;
+#endif /* HAVE_WINDOW_SYSTEM */
 
   DEFSYM (Qglyphless_char, "glyphless-char");
   DEFSYM (Qhex_code, "hex-code");
@@ -29658,6 +29719,13 @@ cursor shapes.  */);
   DEFSYM (Qthin_space, "thin-space");
   DEFSYM (Qzero_width, "zero-width");
 
+  DEFVAR_LISP ("pre-redisplay-function", Vpre_redisplay_function,
+              doc: /* Function run just before redisplay.
+It is called with one argument, which is the set of windows that are to
+be redisplayed.  This set can be nil (meaning, only the selected window),
+or t (meaning all windows).  */);
+  Vpre_redisplay_function = intern ("ignore");
+
   DEFSYM (Qglyphless_char_display, "glyphless-char-display");
   Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
 
@@ -29676,7 +29744,11 @@ GRAPHICAL and TEXT should each have one of the values listed above.
 The char-table has one extra slot to control the display of a character for
 which no font is found.  This slot only takes effect on graphical terminals.
 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
-`thin-space'.  The default is `empty-box'.  */);
+`thin-space'.  The default is `empty-box'.
+
+If a character has a non-nil entry in an active display table, the
+display table takes effect; in this case, Emacs does not consult
+`glyphless-char-display' at all.  */);
   Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
   Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
                              Qempty_box);
@@ -29684,6 +29756,16 @@ Its value should be an ASCII acronym string, `hex-code', `empty-box', or
   DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
               doc: /* If non-nil, debug if a message matching this regexp is displayed.  */);
   Vdebug_on_message = Qnil;
+
+  DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause,
+              doc: /*  */);
+  Vredisplay__all_windows_cause
+    = Fmake_vector (make_number (100), make_number (0));
+
+  DEFVAR_LISP ("redisplay--mode-lines-cause", Vredisplay__mode_lines_cause,
+              doc: /*  */);
+  Vredisplay__mode_lines_cause
+    = Fmake_vector (make_number (100), make_number (0));
 }
 
 
@@ -29692,8 +29774,6 @@ Its value should be an ASCII acronym string, `hex-code', `empty-box', or
 void
 init_xdisp (void)
 {
-  current_header_line_height = current_mode_line_height = -1;
-
   CHARPOS (this_line_start_pos) = 0;
 
   if (!noninteractive)
@@ -29737,13 +29817,14 @@ init_xdisp (void)
   help_echo_showing_p = 0;
 }
 
+#ifdef HAVE_WINDOW_SYSTEM
+
 /* Platform-independent portion of hourglass implementation.  */
 
 /* Cancel a currently active hourglass timer, and start a new one.  */
 void
 start_hourglass (void)
 {
-#if defined (HAVE_WINDOW_SYSTEM)
   struct timespec delay;
 
   cancel_hourglass ();
@@ -29768,7 +29849,6 @@ start_hourglass (void)
 
   hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
                                   show_hourglass, NULL);
-#endif
 }
 
 
@@ -29777,7 +29857,6 @@ start_hourglass (void)
 void
 cancel_hourglass (void)
 {
-#if defined (HAVE_WINDOW_SYSTEM)
   if (hourglass_atimer)
     {
       cancel_atimer (hourglass_atimer);
@@ -29786,5 +29865,6 @@ cancel_hourglass (void)
 
   if (hourglass_shown_p)
     hide_hourglass ();
-#endif
 }
+
+#endif /* HAVE_WINDOW_SYSTEM */