]> code.delx.au - gnu-emacs/blobdiff - src/dispnew.c
Use INTERNAL_FIELD for windows.
[gnu-emacs] / src / dispnew.c
index c116c3f7c47986cc422a008a4a3319843bc622dd..f6b5e426071c4082fca37680b3c03f0acc47f0b0 100644 (file)
@@ -1,7 +1,6 @@
 /* Updating of data structures for redisplay.
-   Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
-                 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-                 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+
+Copyright (C) 1985-1988, 1993-1995, 1997-2012 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -23,10 +22,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <stdio.h>
 #include <ctype.h>
 #include <setjmp.h>
-
-#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif
 
 #include "lisp.h"
 #include "termchar.h"
@@ -34,8 +30,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 /* cm.h must come after dispextern.h on Windows.  */
 #include "dispextern.h"
 #include "cm.h"
-#include "buffer.h"
 #include "character.h"
+#include "buffer.h"
 #include "keyboard.h"
 #include "frame.h"
 #include "termhooks.h"
@@ -47,9 +43,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "blockinput.h"
 #include "process.h"
 
-/* I don't know why DEC Alpha OSF1 fail to compile this file if we
-   include the following file.  */
-/* #include "systty.h" */
 #include "syssignal.h"
 
 #ifdef HAVE_X_WINDOWS
@@ -69,39 +62,34 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "systime.h"
 #include <errno.h>
 
-/* To get the prototype for `sleep'.  */
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
 /* Get number of chars of output now in the buffer of a stdio stream.
-   This ought to be built in in stdio, but it isn't.  Some s- files
+   This ought to be built in stdio, but it isn't.  Some s- files
    override this because their stdio internals differ.  */
-
 #ifdef __GNU_LIBRARY__
 
 /* The s- file might have overridden the definition with one that
    works for the system's C library.  But we are using the GNU C
    library, so this is the right definition for every system.  */
-
 #ifdef GNU_LIBRARY_PENDING_OUTPUT_COUNT
 #define PENDING_OUTPUT_COUNT GNU_LIBRARY_PENDING_OUTPUT_COUNT
 #else
 #undef PENDING_OUTPUT_COUNT
 #define        PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer)
 #endif
-#else /* not __GNU_LIBRARY__ */
-#if !defined (PENDING_OUTPUT_COUNT) && HAVE_STDIO_EXT_H && HAVE___FPENDING
+
+/* not __GNU_LIBRARY__ and no PENDING_OUTPUT_COUNT defined  */
+#elif !defined (PENDING_OUTPUT_COUNT)
+
+#if HAVE_STDIO_EXT_H && HAVE___FPENDING
 #include <stdio_ext.h>
 #define PENDING_OUTPUT_COUNT(FILE) __fpending (FILE)
-#endif
-#ifndef PENDING_OUTPUT_COUNT
+#else
 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
 #endif
-#endif /* not __GNU_LIBRARY__ */
 
-#if defined(HAVE_TERM_H) && defined (GNU_LINUX) && defined (HAVE_LIBNCURSES)
+#endif /* not __GNU_LIBRARY__ and no PENDING_OUTPUT_COUNT defined */
+
+#if defined (HAVE_TERM_H) && defined (GNU_LINUX)
 #include <term.h>              /* for tgetent */
 #endif
 \f
@@ -117,103 +105,44 @@ struct dim
 \f
 /* Function prototypes.  */
 
-static struct glyph_matrix *save_current_matrix P_ ((struct frame *));
-static void restore_current_matrix P_ ((struct frame *, struct glyph_matrix *));
-static int showing_window_margins_p P_ ((struct window *));
-static void fake_current_matrices P_ ((Lisp_Object));
-static void redraw_overlapping_rows P_ ((struct window *, int));
-static void redraw_overlapped_rows P_ ((struct window *, int));
-static int count_blanks P_ ((struct glyph *, int));
-static int count_match P_ ((struct glyph *, struct glyph *,
-                           struct glyph *, struct glyph *));
-static unsigned line_draw_cost P_ ((struct glyph_matrix *, int));
-static void update_frame_line P_ ((struct frame *, int));
-static struct dim allocate_matrices_for_frame_redisplay
-     P_ ((Lisp_Object, int, int, int, int *));
-static void allocate_matrices_for_window_redisplay P_ ((struct window *));
-static int realloc_glyph_pool P_ ((struct glyph_pool *, struct dim));
-static void adjust_frame_glyphs P_ ((struct frame *));
-struct glyph_matrix *new_glyph_matrix P_ ((struct glyph_pool *));
-static void free_glyph_matrix P_ ((struct glyph_matrix *));
-static void adjust_glyph_matrix P_ ((struct window *, struct glyph_matrix *,
-                                    int, int, struct dim));
-static void change_frame_size_1 P_ ((struct frame *, int, int, int, int, int));
-static void swap_glyph_pointers P_ ((struct glyph_row *, struct glyph_row *));
-#if GLYPH_DEBUG
-static int glyph_row_slice_p P_ ((struct glyph_row *, struct glyph_row *));
-#endif
-static void fill_up_frame_row_with_spaces P_ ((struct glyph_row *, int));
-static void build_frame_matrix_from_window_tree P_ ((struct glyph_matrix *,
-                                                    struct window *));
-static void build_frame_matrix_from_leaf_window P_ ((struct glyph_matrix *,
-                                                    struct window *));
-static struct glyph_pool *new_glyph_pool P_ ((void));
-static void free_glyph_pool P_ ((struct glyph_pool *));
-static void adjust_frame_glyphs_initially P_ ((void));
-static void adjust_frame_message_buffer P_ ((struct frame *));
-static void adjust_decode_mode_spec_buffer P_ ((struct frame *));
-static void fill_up_glyph_row_with_spaces P_ ((struct glyph_row *));
-static void build_frame_matrix P_ ((struct frame *));
-void clear_current_matrices P_ ((struct frame *));
-void scroll_glyph_matrix_range P_ ((struct glyph_matrix *, int, int,
-                                   int, int));
-static void clear_window_matrices P_ ((struct window *, int));
-static void fill_up_glyph_row_area_with_spaces P_ ((struct glyph_row *, int));
-static int scrolling_window P_ ((struct window *, int));
-static int update_window_line P_ ((struct window *, int, int *));
-static void update_marginal_area P_ ((struct window *, int, int));
-static int update_text_area P_ ((struct window *, int));
-static void make_current P_ ((struct glyph_matrix *, struct glyph_matrix *,
-                             int));
-static void mirror_make_current P_ ((struct window *, int));
-void check_window_matrix_pointers P_ ((struct window *));
-#if GLYPH_DEBUG
-static void check_matrix_pointers P_ ((struct glyph_matrix *,
-                                      struct glyph_matrix *));
+static void update_frame_line (struct frame *, int);
+static int required_matrix_height (struct window *);
+static int required_matrix_width (struct window *);
+static void adjust_frame_glyphs (struct frame *);
+static void change_frame_size_1 (struct frame *, int, int, int, int, int);
+static void increment_row_positions (struct glyph_row *, ptrdiff_t, ptrdiff_t);
+static void fill_up_frame_row_with_spaces (struct glyph_row *, int);
+static void build_frame_matrix_from_window_tree (struct glyph_matrix *,
+                                                 struct window *);
+static void build_frame_matrix_from_leaf_window (struct glyph_matrix *,
+                                                 struct window *);
+static void adjust_frame_message_buffer (struct frame *);
+static void adjust_decode_mode_spec_buffer (struct frame *);
+static void fill_up_glyph_row_with_spaces (struct glyph_row *);
+static void clear_window_matrices (struct window *, int);
+static void fill_up_glyph_row_area_with_spaces (struct glyph_row *, int);
+static int scrolling_window (struct window *, int);
+static int update_window_line (struct window *, int, int *);
+static void mirror_make_current (struct window *, int);
+#ifdef GLYPH_DEBUG
+static void check_matrix_pointers (struct glyph_matrix *,
+                                   struct glyph_matrix *);
 #endif
-static void mirror_line_dance P_ ((struct window *, int, int, int *, char *));
-static int update_window_tree P_ ((struct window *, int));
-static int update_window P_ ((struct window *, int));
-static int update_frame_1 P_ ((struct frame *, int, int));
-static void set_window_cursor_after_update P_ ((struct window *));
-static int row_equal_p P_ ((struct window *, struct glyph_row *,
-                           struct glyph_row *, int));
-static void adjust_frame_glyphs_for_window_redisplay P_ ((struct frame *));
-static void adjust_frame_glyphs_for_frame_redisplay P_ ((struct frame *));
-static void reverse_rows P_ ((struct glyph_matrix *, int, int));
-static int margin_glyphs_to_reserve P_ ((struct window *, int, Lisp_Object));
-static void sync_window_with_frame_matrix_rows P_ ((struct window *));
-struct window *frame_row_to_window P_ ((struct window *, int));
+static void mirror_line_dance (struct window *, int, int, int *, char *);
+static int update_window_tree (struct window *, int);
+static int update_window (struct window *, int);
+static int update_frame_1 (struct frame *, int, int);
+static int scrolling (struct frame *);
+static void set_window_cursor_after_update (struct window *);
+static void adjust_frame_glyphs_for_window_redisplay (struct frame *);
+static void adjust_frame_glyphs_for_frame_redisplay (struct frame *);
 
 \f
-/* Non-zero means don't pause redisplay for pending input.  (This is
-   for debugging and for a future implementation of EDT-like
-   scrolling.  */
-
-int redisplay_dont_pause;
-
-/* Define PERIODIC_PREEMPTION_CHECKING to 1, if micro-second timers
-   are supported, so we can check for input during redisplay at
-   regular intervals.  */
-#ifdef EMACS_HAS_USECS
-#define PERIODIC_PREEMPTION_CHECKING 1
-#else
-#define PERIODIC_PREEMPTION_CHECKING 0
-#endif
-
-#if PERIODIC_PREEMPTION_CHECKING
-
-/* If a number (float), check for user input every N seconds.  */
-
-Lisp_Object Vredisplay_preemption_period;
-
 /* Redisplay preemption timers.  */
 
 static EMACS_TIME preemption_period;
 static EMACS_TIME preemption_next_check;
 
-#endif
-
 /* Nonzero upon entry to redisplay means do not assume anything about
    current contents of actual terminal frame; clear and redraw it.  */
 
@@ -223,49 +152,6 @@ int frame_garbaged;
 
 int display_completed;
 
-/* Lisp variable visible-bell; enables use of screen-flash instead of
-   audible bell.  */
-
-int visible_bell;
-
-/* Invert the color of the whole frame, at a low level.  */
-
-int inverse_video;
-
-/* Line speed of the terminal.  */
-
-EMACS_INT baud_rate;
-
-/* Either nil or a symbol naming the window system under which Emacs
-   creates the first frame.  */
-
-Lisp_Object Vinitial_window_system;
-
-/* Version number of X windows: 10, 11 or nil.  */
-
-Lisp_Object Vwindow_system_version;
-
-/* Vector of glyph definitions.  Indexed by glyph number, the contents
-   are a string which is how to output the glyph.
-
-   If Vglyph_table is nil, a glyph is output by using its low 8 bits
-   as a character code.
-
-   This is an obsolete feature that is no longer used.  The variable
-   is retained for compatibility.  */
-
-Lisp_Object Vglyph_table;
-
-/* Display table to use for vectors that don't specify their own.  */
-
-Lisp_Object Vstandard_display_table;
-
-/* Nonzero means reading single-character input with prompt so put
-   cursor on mini-buffer after the prompt.  Positive means at end of
-   text in echo area; negative means at beginning of line.  */
-
-int cursor_in_echo_area;
-
 Lisp_Object Qdisplay_table, Qredisplay_dont_pause;
 
 \f
@@ -283,7 +169,7 @@ struct frame *last_nonminibuf_frame;
 
 /* 1 means SIGWINCH happened when not safe.  */
 
-int delayed_size_change;
+static int delayed_size_change;
 
 /* 1 means glyph initialization has been completed at startup.  */
 
@@ -302,17 +188,11 @@ int updated_area;
 
 struct glyph space_glyph;
 
-/* Non-zero means update has been performed directly, so that there's
-   no need for redisplay_internal to do much work.  Set by
-   direct_output_for_insert.  */
-
-int redisplay_performed_directly_p;
-
 /* Counts of allocated structures.  These counts serve to diagnose
    memory leaks and double frees.  */
 
-int glyph_matrix_count;
-int glyph_pool_count;
+static int glyph_matrix_count;
+static int glyph_pool_count;
 
 /* If non-null, the frame whose frame matrices are manipulated.  If
    null, window matrices are worked on.  */
@@ -332,10 +212,10 @@ int fonts_changed_p;
 /* Convert vpos and hpos from frame to window and vice versa.
    This may only be used for terminal frames.  */
 
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
 
-static int window_to_frame_vpos P_ ((struct window *, int));
-static int window_to_frame_hpos P_ ((struct window *, int));
+static int window_to_frame_vpos (struct window *, int);
+static int window_to_frame_hpos (struct window *, int);
 #define WINDOW_TO_FRAME_VPOS(W, VPOS) window_to_frame_vpos ((W), (VPOS))
 #define WINDOW_TO_FRAME_HPOS(W, HPOS) window_to_frame_hpos ((W), (HPOS))
 
@@ -362,10 +242,9 @@ static int history_idx;
 /* A tick that's incremented each time something is added to the
    history.  */
 
-static unsigned history_tick;
+static uprintmax_t history_tick;
 
-static void add_frame_display_history P_ ((struct frame *, int));
-static void add_window_display_history P_ ((struct window *, char *, int));
+static void add_frame_display_history (struct frame *, int);
 \f
 /* Add to the redisplay history how window W has been displayed.
    MSG is a trace containing the information how W's glyph matrix
@@ -373,10 +252,7 @@ static void add_window_display_history P_ ((struct window *, char *, int));
    has been interrupted for pending input.  */
 
 static void
-add_window_display_history (w, msg, paused_p)
-     struct window *w;
-     char *msg;
-     int paused_p;
+add_window_display_history (struct window *w, const char *msg, int paused_p)
 {
   char *buf;
 
@@ -385,15 +261,16 @@ add_window_display_history (w, msg, paused_p)
   buf = redisplay_history[history_idx].trace;
   ++history_idx;
 
-  sprintf (buf, "%d: window %p (`%s')%s\n",
-          history_tick++,
-          w,
-          ((BUFFERP (w->buffer)
-            && STRINGP (XBUFFER (w->buffer)->name))
-           ? (char *) SDATA (XBUFFER (w->buffer)->name)
-           : "???"),
-          paused_p ? " ***paused***" : "");
-  strcat (buf, msg);
+  snprintf (buf, sizeof redisplay_history[0].trace,
+           "%"pMu": window %p (`%s')%s\n%s",
+           history_tick++,
+           w,
+           ((BUFFERP (WVAR (w, buffer))
+             && STRINGP (BVAR (XBUFFER (WVAR (w, buffer)), name)))
+            ? SSDATA (BVAR (XBUFFER (WVAR (w, buffer)), name))
+            : "???"),
+           paused_p ? " ***paused***" : "",
+           msg);
 }
 
 
@@ -402,9 +279,7 @@ add_window_display_history (w, msg, paused_p)
    pending input.  */
 
 static void
-add_frame_display_history (f, paused_p)
-     struct frame *f;
-     int paused_p;
+add_frame_display_history (struct frame *f, int paused_p)
 {
   char *buf;
 
@@ -413,7 +288,7 @@ add_frame_display_history (f, paused_p)
   buf = redisplay_history[history_idx].trace;
   ++history_idx;
 
-  sprintf (buf, "%d: update frame %p%s",
+  sprintf (buf, "%"pMu": update frame %p%s",
           history_tick++,
           f, paused_p ? " ***paused***" : "");
 }
@@ -422,7 +297,7 @@ add_frame_display_history (f, paused_p)
 DEFUN ("dump-redisplay-history", Fdump_redisplay_history,
        Sdump_redisplay_history, 0, 0, "",
        doc: /* Dump redisplay history to stderr.  */)
-     ()
+  (void)
 {
   int i;
 
@@ -437,73 +312,25 @@ DEFUN ("dump-redisplay-history", Fdump_redisplay_history,
 }
 
 
-#else /* GLYPH_DEBUG == 0 */
+#else /* not GLYPH_DEBUG */
 
 #define WINDOW_TO_FRAME_VPOS(W, VPOS) ((VPOS) + WINDOW_TOP_EDGE_LINE (W))
 #define WINDOW_TO_FRAME_HPOS(W, HPOS) ((HPOS) + WINDOW_LEFT_EDGE_COL (W))
 
-#endif /* GLYPH_DEBUG == 0 */
-
+#endif /* GLYPH_DEBUG */
 
-/* Like bcopy except never gets confused by overlap.  Let this be the
-   first function defined in this file, or change emacs.c where the
-   address of this function is used.  */
 
+#if (defined PROFILING \
+     && (defined __FreeBSD__ || defined GNU_LINUX || defined __MINGW32__) \
+     && !HAVE___EXECUTABLE_START)
+/* This function comes first in the Emacs executable and is used only
+   to estimate the text start for profiling.  */
 void
-safe_bcopy (from, to, size)
-     const char *from;
-     char *to;
-     int size;
+__executable_start (void)
 {
-  if (size <= 0 || from == to)
-    return;
-
-  /* If the source and destination don't overlap, then bcopy can
-     handle it.  If they do overlap, but the destination is lower in
-     memory than the source, we'll assume bcopy can handle that.  */
-  if (to < from || from + size <= to)
-    bcopy (from, to, size);
-
-  /* Otherwise, we'll copy from the end.  */
-  else
-    {
-      register const char *endf = from + size;
-      register char *endt = to + size;
-
-      /* If TO - FROM is large, then we should break the copy into
-        nonoverlapping chunks of TO - FROM bytes each.  However, if
-        TO - FROM is small, then the bcopy function call overhead
-        makes this not worth it.  The crossover point could be about
-        anywhere.  Since I don't think the obvious copy loop is too
-        bad, I'm trying to err in its favor.  */
-      if (to - from < 64)
-       {
-         do
-           *--endt = *--endf;
-         while (endf != from);
-       }
-      else
-       {
-         for (;;)
-           {
-             endt -= (to - from);
-             endf -= (to - from);
-
-             if (endt < to)
-               break;
-
-             bcopy (endf, endt, to - from);
-           }
-
-         /* If SIZE wasn't a multiple of TO - FROM, there will be a
-            little left over.  The amount left over is (endt + (to -
-            from)) - to, which is endt - from.  */
-         bcopy (from, to, endt - from);
-       }
-    }
+  abort ();
 }
-
-
+#endif
 \f
 /***********************************************************************
                            Glyph Matrices
@@ -515,15 +342,10 @@ safe_bcopy (from, to, size)
    member `pool' of the glyph matrix structure returned is set to
    POOL, the structure is otherwise zeroed.  */
 
-struct glyph_matrix *
-new_glyph_matrix (pool)
-     struct glyph_pool *pool;
+static struct glyph_matrix *
+new_glyph_matrix (struct glyph_pool *pool)
 {
-  struct glyph_matrix *result;
-
-  /* Allocate and clear.  */
-  result = (struct glyph_matrix *) xmalloc (sizeof *result);
-  bzero (result, sizeof *result);
+  struct glyph_matrix *result = xzalloc (sizeof *result);
 
   /* Increment number of allocated matrices.  This count is used
      to detect memory leaks.  */
@@ -547,8 +369,7 @@ new_glyph_matrix (pool)
    matrix also frees the glyph memory in this case.  */
 
 static void
-free_glyph_matrix (matrix)
-     struct glyph_matrix *matrix;
+free_glyph_matrix (struct glyph_matrix *matrix)
 {
   if (matrix)
     {
@@ -578,16 +399,13 @@ free_glyph_matrix (matrix)
    or a float.  */
 
 static int
-margin_glyphs_to_reserve (w, total_glyphs, margin)
-     struct window *w;
-     int total_glyphs;
-     Lisp_Object margin;
+margin_glyphs_to_reserve (struct window *w, int total_glyphs, Lisp_Object margin)
 {
   int n;
 
   if (NUMBERP (margin))
     {
-      int width = XFASTINT (w->total_cols);
+      int width = XFASTINT (WVAR (w, total_cols));
       double d = max (0, XFLOATINT (margin));
       d = min (width / 2 - 1, d);
       n = (int) ((double) total_glyphs / width * d);
@@ -598,6 +416,14 @@ margin_glyphs_to_reserve (w, total_glyphs, margin)
   return n;
 }
 
+/* Return non-zero if ROW's hash value is correct, zero if not.
+   Optimized away if ENABLE_CHECKING is not defined.  */
+
+static int
+verify_row_hash (struct glyph_row *row)
+{
+  return row->hash == row_hash (row);
+}
 
 /* Adjust glyph matrix MATRIX on window W or on a frame to changed
    window sizes.
@@ -622,11 +448,7 @@ margin_glyphs_to_reserve (w, total_glyphs, margin)
    leads to screen flickering.  */
 
 static void
-adjust_glyph_matrix (w, matrix, x, y, dim)
-     struct window *w;
-     struct glyph_matrix *matrix;
-     int x, y;
-     struct dim dim;
+adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y, struct dim dim)
 {
   int i;
   int new_rows;
@@ -653,9 +475,9 @@ adjust_glyph_matrix (w, matrix, x, y, dim)
      the matrix means preventing redisplay.  */
   if (matrix->pool == NULL)
     {
-      left = margin_glyphs_to_reserve (w, dim.width, w->left_margin_cols);
-      right = margin_glyphs_to_reserve (w, dim.width, w->right_margin_cols);
-      xassert (left >= 0 && right >= 0);
+      left = margin_glyphs_to_reserve (w, dim.width, WVAR (w, left_margin_cols));
+      right = margin_glyphs_to_reserve (w, dim.width, WVAR (w, right_margin_cols));
+      eassert (left >= 0 && right >= 0);
       marginal_areas_changed_p = (left != matrix->left_margin_glyphs
                                  || right != matrix->right_margin_glyphs);
 
@@ -673,12 +495,12 @@ adjust_glyph_matrix (w, matrix, x, y, dim)
   /* Enlarge MATRIX->rows if necessary.  New rows are cleared.  */
   if (matrix->rows_allocated < dim.height)
     {
-      int size = dim.height * sizeof (struct glyph_row);
+      int old_alloc = matrix->rows_allocated;
       new_rows = dim.height - matrix->rows_allocated;
-      matrix->rows = (struct glyph_row *) xrealloc (matrix->rows, size);
-      bzero (matrix->rows + matrix->rows_allocated,
-            new_rows * sizeof *matrix->rows);
-      matrix->rows_allocated = dim.height;
+      matrix->rows = xpalloc (matrix->rows, &matrix->rows_allocated,
+                             new_rows, INT_MAX, sizeof *matrix->rows);
+      memset (matrix->rows + old_alloc, 0,
+             (matrix->rows_allocated - old_alloc) * sizeof *matrix->rows);
     }
   else
     new_rows = 0;
@@ -688,14 +510,14 @@ adjust_glyph_matrix (w, matrix, x, y, dim)
      each row into the glyph pool.  */
   if (matrix->pool)
     {
-      xassert (matrix->pool->glyphs);
+      eassert (matrix->pool->glyphs);
 
       if (w)
        {
          left = margin_glyphs_to_reserve (w, dim.width,
-                                          w->left_margin_cols);
+                                          WVAR (w, left_margin_cols));
          right = margin_glyphs_to_reserve (w, dim.width,
-                                           w->right_margin_cols);
+                                           WVAR (w, right_margin_cols));
        }
       else
        left = right = 0;
@@ -750,9 +572,8 @@ adjust_glyph_matrix (w, matrix, x, y, dim)
          while (row < end)
            {
              row->glyphs[LEFT_MARGIN_AREA]
-               = (struct glyph *) xrealloc (row->glyphs[LEFT_MARGIN_AREA],
-                                            (dim.width
-                                             * sizeof (struct glyph)));
+               = xnrealloc (row->glyphs[LEFT_MARGIN_AREA],
+                            dim.width, sizeof (struct glyph));
 
              /* The mode line never has marginal areas.  */
              if (row == matrix->rows + dim.height - 1
@@ -778,14 +599,14 @@ adjust_glyph_matrix (w, matrix, x, y, dim)
            }
        }
 
-      xassert (left >= 0 && right >= 0);
+      eassert (left >= 0 && right >= 0);
       matrix->left_margin_glyphs = left;
       matrix->right_margin_glyphs = right;
     }
 
   /* Number of rows to be used by MATRIX.  */
   matrix->nrows = dim.height;
-  xassert (matrix->nrows >= 0);
+  eassert (matrix->nrows >= 0);
 
   if (w)
     {
@@ -819,9 +640,9 @@ adjust_glyph_matrix (w, matrix, x, y, dim)
 
              /* Window end is invalid, if inside of the rows that
                 are invalidated below.  */
-             if (INTEGERP (w->window_end_vpos)
-                 && XFASTINT (w->window_end_vpos) >= i)
-               w->window_end_valid = Qnil;
+             if (INTEGERP (WVAR (w, window_end_vpos))
+                 && XFASTINT (WVAR (w, window_end_vpos)) >= i)
+               WVAR (w, window_end_valid) = Qnil;
 
              while (i < matrix->nrows)
                matrix->rows[i++].enabled_p = 0;
@@ -869,9 +690,7 @@ adjust_glyph_matrix (w, matrix, x, y, dim)
    below).  */
 
 static void
-reverse_rows (matrix, start, end)
-     struct glyph_matrix *matrix;
-     int start, end;
+reverse_rows (struct glyph_matrix *matrix, int start, int end)
 {
   int i, j;
 
@@ -900,9 +719,7 @@ reverse_rows (matrix, start, end)
    rotating right.  */
 
 void
-rotate_matrix (matrix, first, last, by)
-     struct glyph_matrix *matrix;
-     int first, last, by;
+rotate_matrix (struct glyph_matrix *matrix, int first, int last, int by)
 {
   if (by < 0)
     {
@@ -927,14 +744,13 @@ rotate_matrix (matrix, first, last, by)
    DELTA_BYTES.  */
 
 void
-increment_matrix_positions (matrix, start, end, delta, delta_bytes)
-     struct glyph_matrix *matrix;
-     int start, end, delta, delta_bytes;
+increment_matrix_positions (struct glyph_matrix *matrix, int start, int end,
+                           ptrdiff_t delta, ptrdiff_t delta_bytes)
 {
   /* Check that START and END are reasonable values.  */
-  xassert (start >= 0 && start <= matrix->nrows);
-  xassert (end >= 0 && end <= matrix->nrows);
-  xassert (start <= end);
+  eassert (start >= 0 && start <= matrix->nrows);
+  eassert (end >= 0 && end <= matrix->nrows);
+  eassert (start <= end);
 
   for (; start < end; ++start)
     increment_row_positions (matrix->rows + start, delta, delta_bytes);
@@ -946,14 +762,11 @@ increment_matrix_positions (matrix, start, end, delta, delta_bytes)
    ENABLED_P is non-zero, enabled_p flags in rows will be set to 1.  */
 
 void
-enable_glyph_matrix_rows (matrix, start, end, enabled_p)
-     struct glyph_matrix *matrix;
-     int start, end;
-     int enabled_p;
+enable_glyph_matrix_rows (struct glyph_matrix *matrix, int start, int end, int enabled_p)
 {
-  xassert (start <= end);
-  xassert (start >= 0 && start < matrix->nrows);
-  xassert (end >= 0 && end <= matrix->nrows);
+  eassert (start <= end);
+  eassert (start >= 0 && start < matrix->nrows);
+  eassert (end >= 0 && end <= matrix->nrows);
 
   for (; start < end; ++start)
     matrix->rows[start].enabled_p = enabled_p != 0;
@@ -971,8 +784,7 @@ enable_glyph_matrix_rows (matrix, start, end, enabled_p)
    currently present is the flag MATRIX->no_scrolling_p.  */
 
 void
-clear_glyph_matrix (matrix)
-     struct glyph_matrix *matrix;
+clear_glyph_matrix (struct glyph_matrix *matrix)
 {
   if (matrix)
     {
@@ -987,16 +799,13 @@ clear_glyph_matrix (matrix)
    and recompute their visible height.  */
 
 void
-shift_glyph_matrix (w, matrix, start, end, dy)
-     struct window *w;
-     struct glyph_matrix *matrix;
-     int start, end, dy;
+shift_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int start, int end, int dy)
 {
   int min_y, max_y;
 
-  xassert (start <= end);
-  xassert (start >= 0 && start < matrix->nrows);
-  xassert (end >= 0 && end <= matrix->nrows);
+  eassert (start <= end);
+  eassert (start >= 0 && start < matrix->nrows);
+  eassert (end >= 0 && end <= matrix->nrows);
 
   min_y = WINDOW_HEADER_LINE_HEIGHT (w);
   max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (w);
@@ -1023,8 +832,7 @@ shift_glyph_matrix (w, matrix, start, end, dy)
    current matrix.  */
 
 void
-clear_current_matrices (f)
-     register struct frame *f;
+clear_current_matrices (register struct frame *f)
 {
   /* Clear frame current matrix, if we have one.  */
   if (f->current_matrix)
@@ -1033,15 +841,15 @@ clear_current_matrices (f)
   /* Clear the matrix of the menu bar window, if such a window exists.
      The menu bar window is currently used to display menus on X when
      no toolkit support is compiled in.  */
-  if (WINDOWP (f->menu_bar_window))
-    clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
+  if (WINDOWP (FVAR (f, menu_bar_window)))
+    clear_glyph_matrix (XWINDOW (FVAR (f, menu_bar_window))->current_matrix);
 
   /* Clear the matrix of the tool-bar window, if any.  */
-  if (WINDOWP (f->tool_bar_window))
-    clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
+  if (WINDOWP (FVAR (f, tool_bar_window)))
+    clear_glyph_matrix (XWINDOW (FVAR (f, tool_bar_window))->current_matrix);
 
   /* Clear current window matrices.  */
-  xassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
+  eassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
   clear_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)), 0);
 }
 
@@ -1049,20 +857,19 @@ clear_current_matrices (f)
 /* Clear out all display lines of F for a coming redisplay.  */
 
 void
-clear_desired_matrices (f)
-     register struct frame *f;
+clear_desired_matrices (register struct frame *f)
 {
   if (f->desired_matrix)
     clear_glyph_matrix (f->desired_matrix);
 
-  if (WINDOWP (f->menu_bar_window))
-    clear_glyph_matrix (XWINDOW (f->menu_bar_window)->desired_matrix);
+  if (WINDOWP (FVAR (f, menu_bar_window)))
+    clear_glyph_matrix (XWINDOW (FVAR (f, menu_bar_window))->desired_matrix);
 
-  if (WINDOWP (f->tool_bar_window))
-    clear_glyph_matrix (XWINDOW (f->tool_bar_window)->desired_matrix);
+  if (WINDOWP (FVAR (f, tool_bar_window)))
+    clear_glyph_matrix (XWINDOW (FVAR (f, tool_bar_window))->desired_matrix);
 
   /* Do it for window matrices.  */
-  xassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
+  eassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
   clear_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)), 1);
 }
 
@@ -1071,21 +878,19 @@ clear_desired_matrices (f)
    non-zero clear desired matrices, otherwise clear current matrices.  */
 
 static void
-clear_window_matrices (w, desired_p)
-     struct window *w;
-     int desired_p;
+clear_window_matrices (struct window *w, int desired_p)
 {
   while (w)
     {
-      if (!NILP (w->hchild))
+      if (!NILP (WVAR (w, hchild)))
        {
-         xassert (WINDOWP (w->hchild));
-         clear_window_matrices (XWINDOW (w->hchild), desired_p);
+         eassert (WINDOWP (WVAR (w, hchild)));
+         clear_window_matrices (XWINDOW (WVAR (w, hchild)), desired_p);
        }
-      else if (!NILP (w->vchild))
+      else if (!NILP (WVAR (w, vchild)))
        {
-         xassert (WINDOWP (w->vchild));
-         clear_window_matrices (XWINDOW (w->vchild), desired_p);
+         eassert (WINDOWP (WVAR (w, vchild)));
+         clear_window_matrices (XWINDOW (WVAR (w, vchild)), desired_p);
        }
       else
        {
@@ -1094,11 +899,11 @@ clear_window_matrices (w, desired_p)
          else
            {
              clear_glyph_matrix (w->current_matrix);
-             w->window_end_valid = Qnil;
+             WVAR (w, window_end_valid) = Qnil;
            }
        }
 
-      w = NILP (w->next) ? 0 : XWINDOW (w->next);
+      w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
     }
 }
 
@@ -1117,8 +922,7 @@ clear_window_matrices (w, desired_p)
 static struct glyph_row null_row;
 
 void
-clear_glyph_row (row)
-     struct glyph_row *row;
+clear_glyph_row (struct glyph_row *row)
 {
   struct glyph *p[1 + LAST_AREA];
 
@@ -1144,7 +948,7 @@ clear_glyph_row (row)
         returned by xmalloc.  If flickering happens again, activate
         the code below.  If the flickering is gone with that, chances
         are that the flickering has the same reason as here.  */
-  bzero (p[0], (char *) p[LAST_AREA] - (char *) p[0]);
+  memset (p[0], 0, (char *) p[LAST_AREA] - (char *) p[0]);
 #endif
 }
 
@@ -1153,10 +957,7 @@ clear_glyph_row (row)
    in window W starting at y-position Y.  */
 
 void
-blank_row (w, row, y)
-     struct window *w;
-     struct glyph_row *row;
-     int y;
+blank_row (struct window *w, struct glyph_row *row, int y)
 {
   int min_y, max_y;
 
@@ -1166,7 +967,7 @@ blank_row (w, row, y)
   clear_glyph_row (row);
   row->y = y;
   row->ascent = row->phys_ascent = 0;
-  row->height = row->phys_height = FRAME_LINE_HEIGHT (XFRAME (w->frame));
+  row->height = row->phys_height = FRAME_LINE_HEIGHT (XFRAME (WVAR (w, frame)));
   row->visible_height = row->height;
 
   if (row->y < min_y)
@@ -1184,10 +985,9 @@ blank_row (w, row, y)
    the used count of the text area is zero.  Such rows display line
    ends.  */
 
-void
-increment_row_positions (row, delta, delta_bytes)
-     struct glyph_row *row;
-     int delta, delta_bytes;
+static void
+increment_row_positions (struct glyph_row *row,
+                        ptrdiff_t delta, ptrdiff_t delta_bytes)
 {
   int area, i;
 
@@ -1196,6 +996,10 @@ increment_row_positions (row, delta, delta_bytes)
   MATRIX_ROW_START_BYTEPOS (row) += delta_bytes;
   MATRIX_ROW_END_CHARPOS (row) += delta;
   MATRIX_ROW_END_BYTEPOS (row) += delta_bytes;
+  CHARPOS (row->start.pos) += delta;
+  BYTEPOS (row->start.pos) += delta_bytes;
+  CHARPOS (row->end.pos) += delta;
+  BYTEPOS (row->end.pos) += delta_bytes;
 
   if (!row->enabled_p)
     return;
@@ -1220,8 +1024,7 @@ increment_row_positions (row, delta, delta_bytes)
    B without changing glyph pointers in A and B.  */
 
 static void
-swap_glyphs_in_rows (a, b)
-     struct glyph_row *a, *b;
+swap_glyphs_in_rows (struct glyph_row *a, struct glyph_row *b)
 {
   int area;
 
@@ -1255,66 +1058,59 @@ swap_glyphs_in_rows (a, b)
 
 #endif /* 0 */
 
-/* Exchange pointers to glyph memory between glyph rows A and B.  */
+/* Exchange pointers to glyph memory between glyph rows A and B.  Also
+   exchange the used[] array and the hash values of the rows, because
+   these should all go together for the row's hash value to be
+   correct.  */
 
-static INLINE void
-swap_glyph_pointers (a, b)
-     struct glyph_row *a, *b;
+static inline void
+swap_glyph_pointers (struct glyph_row *a, struct glyph_row *b)
 {
   int i;
+  unsigned hash_tem = a->hash;
+
   for (i = 0; i < LAST_AREA + 1; ++i)
     {
       struct glyph *temp = a->glyphs[i];
+
       a->glyphs[i] = b->glyphs[i];
       b->glyphs[i] = temp;
+      if (i < LAST_AREA)
+       {
+         short used_tem = a->used[i];
+
+         a->used[i] = b->used[i];
+         b->used[i] = used_tem;
+       }
     }
+  a->hash = b->hash;
+  b->hash = hash_tem;
 }
 
 
 /* Copy glyph row structure FROM to glyph row structure TO, except
-   that glyph pointers in the structures are left unchanged.  */
+   that glyph pointers, the `used' counts, and the hash values in the
+   structures are left unchanged.  */
 
-INLINE void
-copy_row_except_pointers (to, from)
-     struct glyph_row *to, *from;
+static inline void
+copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from)
 {
   struct glyph *pointers[1 + LAST_AREA];
+  short used[LAST_AREA];
+  unsigned hashval;
 
   /* Save glyph pointers of TO.  */
-  bcopy (to->glyphs, pointers, sizeof to->glyphs);
+  memcpy (pointers, to->glyphs, sizeof to->glyphs);
+  memcpy (used, to->used, sizeof to->used);
+  hashval = to->hash;
 
   /* Do a structure assignment.  */
   *to = *from;
 
   /* Restore original pointers of TO.  */
-  bcopy (pointers, to->glyphs, sizeof to->glyphs);
-}
-
-
-/* Copy contents of glyph row FROM to glyph row TO.  Glyph pointers in
-   TO and FROM are left unchanged.  Glyph contents are copied from the
-   glyph memory of FROM to the glyph memory of TO.  Increment buffer
-   positions in row TO by DELTA/ DELTA_BYTES.  */
-
-void
-copy_glyph_row_contents (to, from, delta, delta_bytes)
-     struct glyph_row *to, *from;
-     int delta, delta_bytes;
-{
-  int area;
-
-  /* This is like a structure assignment TO = FROM, except that
-     glyph pointers in the rows are left unchanged.  */
-  copy_row_except_pointers (to, from);
-
-  /* Copy glyphs from FROM to TO.  */
-  for (area = 0; area < LAST_AREA; ++area)
-    if (from->used[area])
-      bcopy (from->glyphs[area], to->glyphs[area],
-            from->used[area] * sizeof (struct glyph));
-
-  /* Increment buffer positions in TO by DELTA.  */
-  increment_row_positions (to, delta, delta_bytes);
+  memcpy (to->glyphs, pointers, sizeof to->glyphs);
+  memcpy (to->used, used, sizeof to->used);
+  to->hash = hashval;
 }
 
 
@@ -1323,9 +1119,8 @@ copy_glyph_row_contents (to, from, delta, delta_bytes)
    exchanged between TO and FROM.  Pointers must be exchanged to avoid
    a memory leak.  */
 
-static INLINE void
-assign_row (to, from)
-     struct glyph_row *to, *from;
+static inline void
+assign_row (struct glyph_row *to, struct glyph_row *from)
 {
   swap_glyph_pointers (to, from);
   copy_row_except_pointers (to, from);
@@ -1338,11 +1133,10 @@ assign_row (to, from)
    is non-zero if the glyph memory of WINDOW_ROW is part of the glyph
    memory of FRAME_ROW.  */
 
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
 
 static int
-glyph_row_slice_p (window_row, frame_row)
-     struct glyph_row *window_row, *frame_row;
+glyph_row_slice_p (struct glyph_row *window_row, struct glyph_row *frame_row)
 {
   struct glyph *window_glyph_start = window_row->glyphs[0];
   struct glyph *frame_glyph_start = frame_row->glyphs[0];
@@ -1361,13 +1155,12 @@ glyph_row_slice_p (window_row, frame_row)
    in WINDOW_MATRIX is found satisfying the condition.  */
 
 static struct glyph_row *
-find_glyph_row_slice (window_matrix, frame_matrix, row)
-     struct glyph_matrix *window_matrix, *frame_matrix;
-     int row;
+find_glyph_row_slice (struct glyph_matrix *window_matrix,
+                     struct glyph_matrix *frame_matrix, int row)
 {
   int i;
 
-  xassert (row >= 0 && row < frame_matrix->nrows);
+  eassert (row >= 0 && row < frame_matrix->nrows);
 
   for (i = 0; i < window_matrix->nrows; ++i)
     if (glyph_row_slice_p (window_matrix->rows + i,
@@ -1385,22 +1178,23 @@ find_glyph_row_slice (window_matrix, frame_matrix, row)
    call to this function really clears it.  */
 
 void
-prepare_desired_row (row)
-     struct glyph_row *row;
+prepare_desired_row (struct glyph_row *row)
 {
   if (!row->enabled_p)
     {
+      int rp = row->reversed_p;
+
       clear_glyph_row (row);
       row->enabled_p = 1;
+      row->reversed_p = rp;
     }
 }
 
 
 /* Return a hash code for glyph row ROW.  */
 
-int
-line_hash_code (row)
-     struct glyph_row *row;
+static int
+line_hash_code (struct glyph_row *row)
 {
   int hash = 0;
 
@@ -1432,17 +1226,15 @@ line_hash_code (row)
    the number of characters in the line.  If must_write_spaces is
    zero, leading and trailing spaces are ignored.  */
 
-static unsigned int
-line_draw_cost (matrix, vpos)
-     struct glyph_matrix *matrix;
-     int vpos;
+static int
+line_draw_cost (struct glyph_matrix *matrix, int vpos)
 {
   struct glyph_row *row = matrix->rows + vpos;
   struct glyph *beg = row->glyphs[TEXT_AREA];
   struct glyph *end = beg + row->used[TEXT_AREA];
   int len;
   Lisp_Object *glyph_table_base = GLYPH_TABLE_BASE;
-  int glyph_table_len = GLYPH_TABLE_LENGTH;
+  ptrdiff_t glyph_table_len = GLYPH_TABLE_LENGTH;
 
   /* Ignore trailing and leading spaces if we can.  */
   if (!FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */
@@ -1490,17 +1282,15 @@ line_draw_cost (matrix, vpos)
 
 
 /* Test two glyph rows A and B for equality.  Value is non-zero if A
-   and B have equal contents.  W is the window to which the glyphs
-   rows A and B belong.  It is needed here to test for partial row
-   visibility.  MOUSE_FACE_P non-zero means compare the mouse_face_p
-   flags of A and B, too.  */
-
-static INLINE int
-row_equal_p (w, a, b, mouse_face_p)
-     struct window *w;
-     struct glyph_row *a, *b;
-     int mouse_face_p;
+   and B have equal contents.  MOUSE_FACE_P non-zero means compare the
+   mouse_face_p flags of A and B, too.  */
+
+static inline int
+row_equal_p (struct glyph_row *a, struct glyph_row *b, int mouse_face_p)
 {
+  eassert (verify_row_hash (a));
+  eassert (verify_row_hash (b));
+
   if (a == b)
     return 1;
   else if (a->hash != b->hash)
@@ -1545,6 +1335,7 @@ row_equal_p (w, a, b, mouse_face_p)
          || a->overlapped_p != b->overlapped_p
          || (MATRIX_ROW_CONTINUATION_LINE_P (a)
              != MATRIX_ROW_CONTINUATION_LINE_P (b))
+         || a->reversed_p != b->reversed_p
          /* Different partially visible characters on left margin.  */
          || a->x != b->x
          /* Different height.  */
@@ -1571,13 +1362,9 @@ row_equal_p (w, a, b, mouse_face_p)
    incremented for each pool allocated.  */
 
 static struct glyph_pool *
-new_glyph_pool ()
+new_glyph_pool (void)
 {
-  struct glyph_pool *result;
-
-  /* Allocate a new glyph_pool and clear it.  */
-  result = (struct glyph_pool *) xmalloc (sizeof *result);
-  bzero (result, sizeof *result);
+  struct glyph_pool *result = xzalloc (sizeof *result);
 
   /* For memory leak and double deletion checking.  */
   ++glyph_pool_count;
@@ -1594,14 +1381,13 @@ new_glyph_pool ()
    was passed to free_glyph_pool.  */
 
 static void
-free_glyph_pool (pool)
-     struct glyph_pool *pool;
+free_glyph_pool (struct glyph_pool *pool)
 {
   if (pool)
     {
       /* More freed than allocated?  */
       --glyph_pool_count;
-      xassert (glyph_pool_count >= 0);
+      eassert (glyph_pool_count >= 0);
 
       xfree (pool->glyphs);
       xfree (pool);
@@ -1619,11 +1405,9 @@ free_glyph_pool (pool)
    re-adjusting window glyph matrices necessary.  */
 
 static int
-realloc_glyph_pool (pool, matrix_dim)
-     struct glyph_pool *pool;
-     struct dim matrix_dim;
+realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim)
 {
-  int needed;
+  ptrdiff_t needed;
   int changed_p;
 
   changed_p = (pool->glyphs == 0
@@ -1631,20 +1415,17 @@ realloc_glyph_pool (pool, matrix_dim)
               || matrix_dim.width != pool->ncolumns);
 
   /* Enlarge the glyph pool.  */
-  needed = matrix_dim.width * matrix_dim.height;
+  needed = matrix_dim.width;
+  if (INT_MULTIPLY_OVERFLOW (needed, matrix_dim.height))
+    memory_full (SIZE_MAX);
+  needed *= matrix_dim.height;
   if (needed > pool->nglyphs)
     {
-      int size = needed * sizeof (struct glyph);
-
-      if (pool->glyphs)
-       pool->glyphs = (struct glyph *) xrealloc (pool->glyphs, size);
-      else
-       {
-         pool->glyphs = (struct glyph *) xmalloc (size);
-         bzero (pool->glyphs, size);
-       }
-
-      pool->nglyphs = needed;
+      ptrdiff_t old_nglyphs = pool->nglyphs;
+      pool->glyphs = xpalloc (pool->glyphs, &pool->nglyphs,
+                             needed - old_nglyphs, -1, sizeof *pool->glyphs);
+      memset (pool->glyphs + old_nglyphs, 0,
+             (pool->nglyphs - old_nglyphs) * sizeof *pool->glyphs);
     }
 
   /* Remember the number of rows and columns because (a) we use them
@@ -1663,7 +1444,7 @@ realloc_glyph_pool (pool, matrix_dim)
                              Debug Code
  ***********************************************************************/
 
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
 
 
 /* Flush standard output.  This is sometimes useful to call from the debugger.
@@ -1671,8 +1452,10 @@ realloc_glyph_pool (pool, matrix_dim)
    stdout.
 */
 
+void flush_stdout (void) EXTERNALLY_VISIBLE;
+
 void
-flush_stdout ()
+flush_stdout (void)
 {
   fflush (stdout);
 }
@@ -1684,14 +1467,13 @@ flush_stdout ()
    MATRIX.  */
 
 void
-check_matrix_pointer_lossage (matrix)
-     struct glyph_matrix *matrix;
+check_matrix_pointer_lossage (struct glyph_matrix *matrix)
 {
   int i, j;
 
   for (i = 0; i < matrix->nrows; ++i)
     for (j = 0; j < matrix->nrows; ++j)
-      xassert (i == j
+      eassert (i == j
               || (matrix->rows[i].glyphs[TEXT_AREA]
                   != matrix->rows[j].glyphs[TEXT_AREA]));
 }
@@ -1700,12 +1482,10 @@ check_matrix_pointer_lossage (matrix)
 /* Get a pointer to glyph row ROW in MATRIX, with bounds checks.  */
 
 struct glyph_row *
-matrix_row (matrix, row)
-     struct glyph_matrix *matrix;
-     int row;
+matrix_row (struct glyph_matrix *matrix, int row)
 {
-  xassert (matrix && matrix->rows);
-  xassert (row >= 0 && row < matrix->nrows);
+  eassert (matrix && matrix->rows);
+  eassert (row >= 0 && row < matrix->nrows);
 
   /* That's really too slow for normal testing because this function
      is called almost everywhere.  Although---it's still astonishingly
@@ -1726,15 +1506,14 @@ matrix_row (matrix, row)
    window W.  */
 
 static void
-check_matrix_invariants (w)
-     struct window *w;
+check_matrix_invariants (struct window *w)
 {
   struct glyph_matrix *matrix = w->current_matrix;
   int yb = window_text_bottom_y (w);
   struct glyph_row *row = matrix->rows;
   struct glyph_row *last_text_row = NULL;
   struct buffer *saved = current_buffer;
-  struct buffer *buffer = XBUFFER (w->buffer);
+  struct buffer *buffer = XBUFFER (WVAR (w, buffer));
   int c;
 
   /* This can sometimes happen for a fresh window.  */
@@ -1753,36 +1532,44 @@ check_matrix_invariants (w)
        last_text_row = row;
 
       /* Check that character and byte positions are in sync.  */
-      xassert (MATRIX_ROW_START_BYTEPOS (row)
+      eassert (MATRIX_ROW_START_BYTEPOS (row)
               == CHAR_TO_BYTE (MATRIX_ROW_START_CHARPOS (row)));
+      eassert (BYTEPOS (row->start.pos)
+              == CHAR_TO_BYTE (CHARPOS (row->start.pos)));
 
       /* CHAR_TO_BYTE aborts when invoked for a position > Z.  We can
         have such a position temporarily in case of a minibuffer
         displaying something like `[Sole completion]' at its end.  */
       if (MATRIX_ROW_END_CHARPOS (row) < BUF_ZV (current_buffer))
-       xassert (MATRIX_ROW_END_BYTEPOS (row)
-                == CHAR_TO_BYTE (MATRIX_ROW_END_CHARPOS (row)));
+       {
+         eassert (MATRIX_ROW_END_BYTEPOS (row)
+                  == CHAR_TO_BYTE (MATRIX_ROW_END_CHARPOS (row)));
+         eassert (BYTEPOS (row->end.pos)
+                  == CHAR_TO_BYTE (CHARPOS (row->end.pos)));
+       }
 
       /* Check that end position of `row' is equal to start position
         of next row.  */
       if (next->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (next))
        {
-         xassert (MATRIX_ROW_END_CHARPOS (row)
+         eassert (MATRIX_ROW_END_CHARPOS (row)
                   == MATRIX_ROW_START_CHARPOS (next));
-         xassert (MATRIX_ROW_END_BYTEPOS (row)
+         eassert (MATRIX_ROW_END_BYTEPOS (row)
                   == MATRIX_ROW_START_BYTEPOS (next));
+         eassert (CHARPOS (row->end.pos) == CHARPOS (next->start.pos));
+         eassert (BYTEPOS (row->end.pos) == BYTEPOS (next->start.pos));
        }
       row = next;
     }
 
-  xassert (w->current_matrix->nrows == w->desired_matrix->nrows);
-  xassert (w->desired_matrix->rows != NULL);
+  eassert (w->current_matrix->nrows == w->desired_matrix->nrows);
+  eassert (w->desired_matrix->rows != NULL);
   set_buffer_temp (saved);
 }
 
 #endif /* 0  */
 
-#endif /* GLYPH_DEBUG != 0 */
+#endif /* GLYPH_DEBUG */
 
 
 \f
@@ -1871,12 +1658,8 @@ check_matrix_invariants (w)
 #define CHANGED_LEAF_MATRIX    (1 << 1)
 
 static struct dim
-allocate_matrices_for_frame_redisplay (window, x, y, dim_only_p,
-                                      window_change_flags)
-     Lisp_Object window;
-     int x, y;
-     int dim_only_p;
-     int *window_change_flags;
+allocate_matrices_for_frame_redisplay (Lisp_Object window, int x, int y,
+                                      int dim_only_p, int *window_change_flags)
 {
   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
   int x0 = x, y0 = y;
@@ -1893,8 +1676,8 @@ allocate_matrices_for_frame_redisplay (window, x, y, dim_only_p,
      points to the mini-buffer window, if any, which is arranged
      vertically below other windows.  */
   in_horz_combination_p
-    = (!NILP (XWINDOW (window)->parent)
-       && !NILP (XWINDOW (XWINDOW (window)->parent)->hchild));
+    = (!NILP (WVAR (XWINDOW (window), parent))
+       && !NILP (WVAR (XWINDOW (WVAR (XWINDOW (window), parent)), hchild)));
 
   /* For WINDOW and all windows on the same level.  */
   do
@@ -1903,12 +1686,12 @@ allocate_matrices_for_frame_redisplay (window, x, y, dim_only_p,
 
       /* Get the dimension of the window sub-matrix for W, depending
         on whether this is a combination or a leaf window.  */
-      if (!NILP (w->hchild))
-       dim = allocate_matrices_for_frame_redisplay (w->hchild, x, y,
+      if (!NILP (WVAR (w, hchild)))
+       dim = allocate_matrices_for_frame_redisplay (WVAR (w, hchild), x, y,
                                                     dim_only_p,
                                                     window_change_flags);
-      else if (!NILP (w->vchild))
-       dim = allocate_matrices_for_frame_redisplay (w->vchild, x, y,
+      else if (!NILP (WVAR (w, vchild)))
+       dim = allocate_matrices_for_frame_redisplay (WVAR (w, vchild), x, y,
                                                     dim_only_p,
                                                     window_change_flags);
       else
@@ -1932,10 +1715,10 @@ allocate_matrices_for_frame_redisplay (window, x, y, dim_only_p,
              || dim.width != w->desired_matrix->matrix_w
              || dim.height != w->desired_matrix->matrix_h
              || (margin_glyphs_to_reserve (w, dim.width,
-                                           w->left_margin_cols)
+                                           WVAR (w, left_margin_cols))
                  != w->desired_matrix->left_margin_glyphs)
              || (margin_glyphs_to_reserve (w, dim.width,
-                                           w->right_margin_cols)
+                                           WVAR (w, right_margin_cols))
                  != w->desired_matrix->right_margin_glyphs))
            *window_change_flags |= CHANGED_LEAF_MATRIX;
 
@@ -1964,7 +1747,7 @@ allocate_matrices_for_frame_redisplay (window, x, y, dim_only_p,
       hmax = max (hmax, dim.height);
 
       /* Next window on same level.  */
-      window = w->next;
+      window = WVAR (w, next);
     }
   while (!NILP (window));
 
@@ -1991,12 +1774,11 @@ allocate_matrices_for_frame_redisplay (window, x, y, dim_only_p,
 
 /* Return the required height of glyph matrices for window W.  */
 
-int
-required_matrix_height (w)
-     struct window *w;
+static int
+required_matrix_height (struct window *w)
 {
 #ifdef HAVE_WINDOW_SYSTEM
-  struct frame *f = XFRAME (w->frame);
+  struct frame *f = XFRAME (WVAR (w, frame));
 
   if (FRAME_WINDOW_P (f))
     {
@@ -2018,12 +1800,11 @@ required_matrix_height (w)
 
 /* Return the required width of glyph matrices for window W.  */
 
-int
-required_matrix_width (w)
-     struct window *w;
+static int
+required_matrix_width (struct window *w)
 {
 #ifdef HAVE_WINDOW_SYSTEM
-  struct frame *f = XFRAME (w->frame);
+  struct frame *f = XFRAME (WVAR (w, frame));
   if (FRAME_WINDOW_P (f))
     {
       int ch_width = FRAME_SMALLEST_CHAR_WIDTH (f);
@@ -2040,7 +1821,7 @@ required_matrix_width (w)
     }
 #endif /* HAVE_WINDOW_SYSTEM */
 
-  return XINT (w->total_cols);
+  return XINT (WVAR (w, total_cols));
 }
 
 
@@ -2048,15 +1829,14 @@ required_matrix_width (w)
    window whose matrices must be allocated/reallocated.  */
 
 static void
-allocate_matrices_for_window_redisplay (w)
-     struct window *w;
+allocate_matrices_for_window_redisplay (struct window *w)
 {
   while (w)
     {
-      if (!NILP (w->vchild))
-       allocate_matrices_for_window_redisplay (XWINDOW (w->vchild));
-      else if (!NILP (w->hchild))
-       allocate_matrices_for_window_redisplay (XWINDOW (w->hchild));
+      if (!NILP (WVAR (w, vchild)))
+       allocate_matrices_for_window_redisplay (XWINDOW (WVAR (w, vchild)));
+      else if (!NILP (WVAR (w, hchild)))
+       allocate_matrices_for_window_redisplay (XWINDOW (WVAR (w, hchild)));
       else
        {
          /* W is a leaf window.  */
@@ -2075,7 +1855,7 @@ allocate_matrices_for_window_redisplay (w)
          adjust_glyph_matrix (w, w->current_matrix, 0, 0, dim);
        }
 
-      w = NILP (w->next) ? NULL : XWINDOW (w->next);
+      w = NILP (WVAR (w, next)) ? NULL : XWINDOW (WVAR (w, next));
     }
 }
 
@@ -2086,8 +1866,7 @@ allocate_matrices_for_window_redisplay (w)
    changes, or its window configuration changes.  */
 
 void
-adjust_glyphs (f)
-     struct frame *f;
+adjust_glyphs (struct frame *f)
 {
   /* Block input so that expose events and other events that access
      glyph matrices are not processed while we are changing them.  */
@@ -2119,24 +1898,24 @@ adjust_glyphs (f)
    windows to estimated values.  */
 
 static void
-adjust_frame_glyphs_initially ()
+adjust_frame_glyphs_initially (void)
 {
   struct frame *sf = SELECTED_FRAME ();
-  struct window *root = XWINDOW (sf->root_window);
-  struct window *mini = XWINDOW (root->next);
+  struct window *root = XWINDOW (FVAR (sf, root_window));
+  struct window *mini = XWINDOW (WVAR (root, next));
   int frame_lines = FRAME_LINES (sf);
   int frame_cols = FRAME_COLS (sf);
   int top_margin = FRAME_TOP_MARGIN (sf);
 
   /* Do it for the root window.  */
-  XSETFASTINT (root->top_line, top_margin);
-  XSETFASTINT (root->total_cols, frame_cols);
-  set_window_height (sf->root_window, frame_lines - 1 - top_margin, 0);
+  XSETFASTINT (WVAR (root, top_line), top_margin);
+  XSETFASTINT (WVAR (root, total_lines), frame_lines - 1 - top_margin);
+  XSETFASTINT (WVAR (root, total_cols), frame_cols);
 
   /* Do it for the mini-buffer window.  */
-  XSETFASTINT (mini->top_line, frame_lines - 1);
-  XSETFASTINT (mini->total_cols, frame_cols);
-  set_window_height (root->next, 1, 0);
+  XSETFASTINT (WVAR (mini, top_line), frame_lines - 1);
+  XSETFASTINT (WVAR (mini, total_lines), 1);
+  XSETFASTINT (WVAR (mini, total_cols), frame_cols);
 
   adjust_frame_glyphs (sf);
   glyphs_initialized_initially_p = 1;
@@ -2146,8 +1925,7 @@ adjust_frame_glyphs_initially ()
 /* Allocate/reallocate glyph matrices of a single frame F.  */
 
 static void
-adjust_frame_glyphs (f)
-     struct frame *f;
+adjust_frame_glyphs (struct frame *f)
 {
   if (FRAME_WINDOW_P (f))
     adjust_frame_glyphs_for_window_redisplay (f);
@@ -2165,26 +1943,25 @@ adjust_frame_glyphs (f)
 /* Return 1 if any window in the tree has nonzero window margins.  See
    the hack at the end of adjust_frame_glyphs_for_frame_redisplay.  */
 static int
-showing_window_margins_p (w)
-     struct window *w;
+showing_window_margins_p (struct window *w)
 {
   while (w)
     {
-      if (!NILP (w->hchild))
+      if (!NILP (WVAR (w, hchild)))
        {
-         if (showing_window_margins_p (XWINDOW (w->hchild)))
+         if (showing_window_margins_p (XWINDOW (WVAR (w, hchild))))
            return 1;
        }
-      else if (!NILP (w->vchild))
+      else if (!NILP (WVAR (w, vchild)))
        {
-         if (showing_window_margins_p (XWINDOW (w->vchild)))
+         if (showing_window_margins_p (XWINDOW (WVAR (w, vchild))))
            return 1;
        }
-      else if (!NILP (w->left_margin_cols)
-              || !NILP (w->right_margin_cols))
+      else if (!NILP (WVAR (w, left_margin_cols))
+              || !NILP (WVAR (w, right_margin_cols)))
        return 1;
 
-      w = NILP (w->next) ? 0 : XWINDOW (w->next);
+      w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
     }
   return 0;
 }
@@ -2194,35 +1971,34 @@ showing_window_margins_p (w)
    windows from the frame's current matrix.  */
 
 static void
-fake_current_matrices (window)
-     Lisp_Object window;
+fake_current_matrices (Lisp_Object window)
 {
   struct window *w;
 
-  for (; !NILP (window); window = w->next)
+  for (; !NILP (window); window = WVAR (w, next))
     {
       w = XWINDOW (window);
 
-      if (!NILP (w->hchild))
-       fake_current_matrices (w->hchild);
-      else if (!NILP (w->vchild))
-       fake_current_matrices (w->vchild);
+      if (!NILP (WVAR (w, hchild)))
+       fake_current_matrices (WVAR (w, hchild));
+      else if (!NILP (WVAR (w, vchild)))
+       fake_current_matrices (WVAR (w, vchild));
       else
        {
          int i;
-         struct frame *f = XFRAME (w->frame);
+         struct frame *f = XFRAME (WVAR (w, frame));
          struct glyph_matrix *m = w->current_matrix;
          struct glyph_matrix *fm = f->current_matrix;
 
-         xassert (m->matrix_h == WINDOW_TOTAL_LINES (w));
-         xassert (m->matrix_w == WINDOW_TOTAL_COLS (w));
+         eassert (m->matrix_h == WINDOW_TOTAL_LINES (w));
+         eassert (m->matrix_w == WINDOW_TOTAL_COLS (w));
 
          for (i = 0; i < m->matrix_h; ++i)
            {
              struct glyph_row *r = m->rows + i;
              struct glyph_row *fr = fm->rows + i + WINDOW_TOP_EDGE_LINE (w);
 
-             xassert (r->glyphs[TEXT_AREA] >= fr->glyphs[TEXT_AREA]
+             eassert (r->glyphs[TEXT_AREA] >= fr->glyphs[TEXT_AREA]
                       && r->glyphs[LAST_AREA] <= fr->glyphs[LAST_AREA]);
 
              r->enabled_p = fr->enabled_p;
@@ -2245,26 +2021,20 @@ fake_current_matrices (window)
    a glyph matrix holding the contents of F's current frame matrix.  */
 
 static struct glyph_matrix *
-save_current_matrix (f)
-     struct frame *f;
+save_current_matrix (struct frame *f)
 {
   int i;
-  struct glyph_matrix *saved;
-
-  saved = (struct glyph_matrix *) xmalloc (sizeof *saved);
-  bzero (saved, sizeof *saved);
+  struct glyph_matrix *saved = xzalloc (sizeof *saved);
   saved->nrows = f->current_matrix->nrows;
-  saved->rows = (struct glyph_row *) xmalloc (saved->nrows
-                                             * sizeof *saved->rows);
-  bzero (saved->rows, saved->nrows * sizeof *saved->rows);
+  saved->rows = xzalloc (saved->nrows * sizeof *saved->rows);
 
   for (i = 0; i < saved->nrows; ++i)
     {
       struct glyph_row *from = f->current_matrix->rows + i;
       struct glyph_row *to = saved->rows + i;
-      size_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
-      to->glyphs[TEXT_AREA] = (struct glyph *) xmalloc (nbytes);
-      bcopy (from->glyphs[TEXT_AREA], to->glyphs[TEXT_AREA], nbytes);
+      ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
+      to->glyphs[TEXT_AREA] = xmalloc (nbytes);
+      memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
       to->used[TEXT_AREA] = from->used[TEXT_AREA];
     }
 
@@ -2276,9 +2046,7 @@ save_current_matrix (f)
    and free memory associated with SAVED.  */
 
 static void
-restore_current_matrix (f, saved)
-     struct frame *f;
-     struct glyph_matrix *saved;
+restore_current_matrix (struct frame *f, struct glyph_matrix *saved)
 {
   int i;
 
@@ -2286,8 +2054,8 @@ restore_current_matrix (f, saved)
     {
       struct glyph_row *from = saved->rows + i;
       struct glyph_row *to = f->current_matrix->rows + i;
-      size_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
-      bcopy (from->glyphs[TEXT_AREA], to->glyphs[TEXT_AREA], nbytes);
+      ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
+      memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
       to->used[TEXT_AREA] = from->used[TEXT_AREA];
       xfree (from->glyphs[TEXT_AREA]);
     }
@@ -2302,8 +2070,7 @@ restore_current_matrix (f, saved)
    frame-based redisplay.  */
 
 static void
-adjust_frame_glyphs_for_frame_redisplay (f)
-     struct frame *f;
+adjust_frame_glyphs_for_frame_redisplay (struct frame *f)
 {
   struct dim matrix_dim;
   int pool_changed_p;
@@ -2361,7 +2128,7 @@ adjust_frame_glyphs_for_frame_redisplay (f)
       /* Size of frame matrices must equal size of frame.  Note
         that we are called for X frames with window widths NOT equal
         to the frame width (from CHANGE_FRAME_SIZE_1).  */
-      xassert (matrix_dim.width == FRAME_COLS (f)
+      eassert (matrix_dim.width == FRAME_COLS (f)
               && matrix_dim.height == FRAME_LINES (f));
 
       /* Pointers to glyph memory in glyph rows are exchanged during
@@ -2403,12 +2170,9 @@ adjust_frame_glyphs_for_frame_redisplay (f)
    window-based redisplay.  */
 
 static void
-adjust_frame_glyphs_for_window_redisplay (f)
-     struct frame *f;
+adjust_frame_glyphs_for_window_redisplay (struct frame *f)
 {
-  struct window *w;
-
-  xassert (FRAME_WINDOW_P (f) && FRAME_LIVE_P (f));
+  eassert (FRAME_WINDOW_P (f) && FRAME_LIVE_P (f));
 
   /* Allocate/reallocate window matrices.  */
   allocate_matrices_for_window_redisplay (XWINDOW (FRAME_ROOT_WINDOW (f)));
@@ -2419,45 +2183,49 @@ adjust_frame_glyphs_for_window_redisplay (f)
 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
   {
     /* Allocate a dummy window if not already done.  */
-    if (NILP (f->menu_bar_window))
+    struct window *w;
+    if (NILP (FVAR (f, menu_bar_window)))
       {
-       f->menu_bar_window = make_window ();
-       w = XWINDOW (f->menu_bar_window);
-       XSETFRAME (w->frame, f);
+       FVAR (f, menu_bar_window) = make_window ();
+       w = XWINDOW (FVAR (f, menu_bar_window));
+       XSETFRAME (WVAR (w, frame), f);
        w->pseudo_window_p = 1;
       }
     else
-      w = XWINDOW (f->menu_bar_window);
+      w = XWINDOW (FVAR (f, menu_bar_window));
 
     /* Set window dimensions to frame dimensions and allocate or
        adjust glyph matrices of W.  */
-    XSETFASTINT (w->top_line, 0);
-    XSETFASTINT (w->left_col, 0);
-    XSETFASTINT (w->total_lines, FRAME_MENU_BAR_LINES (f));
-    XSETFASTINT (w->total_cols, FRAME_TOTAL_COLS (f));
+    XSETFASTINT (WVAR (w, top_line), 0);
+    XSETFASTINT (WVAR (w, left_col), 0);
+    XSETFASTINT (WVAR (w, total_lines), FRAME_MENU_BAR_LINES (f));
+    XSETFASTINT (WVAR (w, total_cols), FRAME_TOTAL_COLS (f));
     allocate_matrices_for_window_redisplay (w);
   }
 #endif /* not USE_X_TOOLKIT && not USE_GTK */
 #endif /* HAVE_X_WINDOWS */
 
 #ifndef USE_GTK
-  /* Allocate/ reallocate matrices of the tool bar window.  If we
-     don't have a tool bar window yet, make one.  */
-  if (NILP (f->tool_bar_window))
-    {
-      f->tool_bar_window = make_window ();
-      w = XWINDOW (f->tool_bar_window);
-      XSETFRAME (w->frame, f);
-      w->pseudo_window_p = 1;
-    }
-  else
-    w = XWINDOW (f->tool_bar_window);
+  {
+    /* Allocate/ reallocate matrices of the tool bar window.  If we
+       don't have a tool bar window yet, make one.  */
+    struct window *w;
+    if (NILP (FVAR (f, tool_bar_window)))
+      {
+       FVAR (f, tool_bar_window) = make_window ();
+       w = XWINDOW (FVAR (f, tool_bar_window));
+       XSETFRAME (WVAR (w, frame), f);
+       w->pseudo_window_p = 1;
+      }
+    else
+      w = XWINDOW (FVAR (f, tool_bar_window));
 
-  XSETFASTINT (w->top_line, FRAME_MENU_BAR_LINES (f));
-  XSETFASTINT (w->left_col, 0);
-  XSETFASTINT (w->total_lines, FRAME_TOOL_BAR_LINES (f));
-  XSETFASTINT (w->total_cols, FRAME_TOTAL_COLS (f));
-  allocate_matrices_for_window_redisplay (w);
+    XSETFASTINT (WVAR (w, top_line), FRAME_MENU_BAR_LINES (f));
+    XSETFASTINT (WVAR (w, left_col), 0);
+    XSETFASTINT (WVAR (w, total_lines), FRAME_TOOL_BAR_LINES (f));
+    XSETFASTINT (WVAR (w, total_cols), FRAME_TOTAL_COLS (f));
+    allocate_matrices_for_window_redisplay (w);
+  }
 #endif
 }
 
@@ -2472,31 +2240,20 @@ adjust_frame_glyphs_for_window_redisplay (f)
    eventually without causing trouble).  */
 
 static void
-adjust_frame_message_buffer (f)
-     struct frame *f;
+adjust_frame_message_buffer (struct frame *f)
 {
-  int size = FRAME_MESSAGE_BUF_SIZE (f) + 1;
-
-  if (FRAME_MESSAGE_BUF (f))
-    {
-      char *buffer = FRAME_MESSAGE_BUF (f);
-      char *new_buffer = (char *) xrealloc (buffer, size);
-      FRAME_MESSAGE_BUF (f) = new_buffer;
-    }
-  else
-    FRAME_MESSAGE_BUF (f) = (char *) xmalloc (size);
+  FRAME_MESSAGE_BUF (f) = xrealloc (FRAME_MESSAGE_BUF (f),
+                                   FRAME_MESSAGE_BUF_SIZE (f) + 1);
 }
 
 
 /* Re-allocate buffer for decode_mode_spec on frame F.  */
 
 static void
-adjust_decode_mode_spec_buffer (f)
-     struct frame *f;
+adjust_decode_mode_spec_buffer (struct frame *f)
 {
-  f->decode_mode_spec_buffer
-    = (char *) xrealloc (f->decode_mode_spec_buffer,
-                        FRAME_MESSAGE_BUF_SIZE (f) + 1);
+  f->decode_mode_spec_buffer = xrealloc (f->decode_mode_spec_buffer,
+                                        FRAME_MESSAGE_BUF_SIZE (f) + 1);
 }
 
 
@@ -2511,8 +2268,7 @@ adjust_decode_mode_spec_buffer (f)
    the function is called when F is destroyed.  */
 
 void
-free_glyphs (f)
-     struct frame *f;
+free_glyphs (struct frame *f)
 {
   if (f && f->glyphs_initialized_p)
     {
@@ -2522,28 +2278,28 @@ free_glyphs (f)
       f->glyphs_initialized_p = 0;
 
       /* Release window sub-matrices.  */
-      if (!NILP (f->root_window))
-        free_window_matrices (XWINDOW (f->root_window));
+      if (!NILP (FVAR (f, root_window)))
+        free_window_matrices (XWINDOW (FVAR (f, root_window)));
 
       /* Free the dummy window for menu bars without X toolkit and its
         glyph matrices.  */
-      if (!NILP (f->menu_bar_window))
+      if (!NILP (FVAR (f, menu_bar_window)))
        {
-         struct window *w = XWINDOW (f->menu_bar_window);
+         struct window *w = XWINDOW (FVAR (f, menu_bar_window));
          free_glyph_matrix (w->desired_matrix);
          free_glyph_matrix (w->current_matrix);
          w->desired_matrix = w->current_matrix = NULL;
-         f->menu_bar_window = Qnil;
+         FVAR (f, menu_bar_window) = Qnil;
        }
 
       /* Free the tool bar window and its glyph matrices.  */
-      if (!NILP (f->tool_bar_window))
+      if (!NILP (FVAR (f, tool_bar_window)))
        {
-         struct window *w = XWINDOW (f->tool_bar_window);
+         struct window *w = XWINDOW (FVAR (f, tool_bar_window));
          free_glyph_matrix (w->desired_matrix);
          free_glyph_matrix (w->current_matrix);
          w->desired_matrix = w->current_matrix = NULL;
-         f->tool_bar_window = Qnil;
+         FVAR (f, tool_bar_window) = Qnil;
        }
 
       /* Release frame glyph matrices.  Reset fields to zero in
@@ -2573,15 +2329,14 @@ free_glyphs (f)
    the same tree more than once.  */
 
 void
-free_window_matrices (w)
-     struct window *w;
+free_window_matrices (struct window *w)
 {
   while (w)
     {
-      if (!NILP (w->hchild))
-       free_window_matrices (XWINDOW (w->hchild));
-      else if (!NILP (w->vchild))
-       free_window_matrices (XWINDOW (w->vchild));
+      if (!NILP (WVAR (w, hchild)))
+       free_window_matrices (XWINDOW (WVAR (w, hchild)));
+      else if (!NILP (WVAR (w, vchild)))
+       free_window_matrices (XWINDOW (WVAR (w, vchild)));
       else
        {
          /* This is a leaf window.  Free its memory and reset fields
@@ -2593,7 +2348,7 @@ free_window_matrices (w)
        }
 
       /* Next window on same level.  */
-      w = NILP (w->next) ? 0 : XWINDOW (w->next);
+      w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
     }
 }
 
@@ -2604,7 +2359,7 @@ free_window_matrices (w)
    explicitly and check that nothing is left allocated.  */
 
 void
-check_glyph_memory ()
+check_glyph_memory (void)
 {
   Lisp_Object tail, frame;
 
@@ -2688,13 +2443,12 @@ check_glyph_memory ()
    sure not to touch them in this function.  */
 
 static void
-build_frame_matrix (f)
-     struct frame *f;
+build_frame_matrix (struct frame *f)
 {
   int i;
 
   /* F must have a frame matrix when this function is called.  */
-  xassert (!FRAME_WINDOW_P (f));
+  eassert (!FRAME_WINDOW_P (f));
 
   /* Clear all rows in the frame matrix covered by window matrices.
      Menu bar lines are not covered by windows.  */
@@ -2711,20 +2465,18 @@ build_frame_matrix (f)
    matrices.  W is the root of a window tree.  */
 
 static void
-build_frame_matrix_from_window_tree (matrix, w)
-     struct glyph_matrix *matrix;
-     struct window *w;
+build_frame_matrix_from_window_tree (struct glyph_matrix *matrix, struct window *w)
 {
   while (w)
     {
-      if (!NILP (w->hchild))
-       build_frame_matrix_from_window_tree (matrix, XWINDOW (w->hchild));
-      else if (!NILP (w->vchild))
-       build_frame_matrix_from_window_tree (matrix, XWINDOW (w->vchild));
+      if (!NILP (WVAR (w, hchild)))
+       build_frame_matrix_from_window_tree (matrix, XWINDOW (WVAR (w, hchild)));
+      else if (!NILP (WVAR (w, vchild)))
+       build_frame_matrix_from_window_tree (matrix, XWINDOW (WVAR (w, vchild)));
       else
        build_frame_matrix_from_leaf_window (matrix, w);
 
-      w = NILP (w->next) ? 0 : XWINDOW (w->next);
+      w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
     }
 }
 
@@ -2741,9 +2493,7 @@ build_frame_matrix_from_window_tree (matrix, w)
    preserve_other_columns in the old redisplay.  */
 
 static void
-build_frame_matrix_from_leaf_window (frame_matrix, w)
-     struct glyph_matrix *frame_matrix;
-     struct window *w;
+build_frame_matrix_from_leaf_window (struct glyph_matrix *frame_matrix, struct window *w)
 {
   struct glyph_matrix *window_matrix;
   int window_y, frame_y;
@@ -2765,8 +2515,7 @@ build_frame_matrix_from_leaf_window (frame_matrix, w)
 
          SET_GLYPH_FROM_CHAR (right_border_glyph, '|');
          if (dp
-             && (gc = DISP_BORDER_GLYPH (dp), GLYPH_CODE_P (gc))
-             && GLYPH_CODE_CHAR_VALID_P (gc))
+             && (gc = DISP_BORDER_GLYPH (dp), GLYPH_CODE_P (gc)))
            {
              SET_GLYPH_FROM_GLYPH_CODE (right_border_glyph, gc);
              spec_glyph_lookup_face (w, &right_border_glyph);
@@ -2809,13 +2558,13 @@ build_frame_matrix_from_leaf_window (frame_matrix, w)
       if (current_row_p)
        {
          /* Copy window row to frame row.  */
-         bcopy (window_row->glyphs[0],
-                frame_row->glyphs[TEXT_AREA] + window_matrix->matrix_x,
-                window_matrix->matrix_w * sizeof (struct glyph));
+         memcpy (frame_row->glyphs[TEXT_AREA] + window_matrix->matrix_x,
+                 window_row->glyphs[0],
+                 window_matrix->matrix_w * sizeof (struct glyph));
        }
       else
        {
-         xassert (window_row->enabled_p);
+         eassert (window_row->enabled_p);
 
          /* Only when a desired row has been displayed, we want
             the corresponding frame row to be updated.  */
@@ -2829,10 +2578,10 @@ build_frame_matrix_from_leaf_window (frame_matrix, w)
              SET_CHAR_GLYPH_FROM_GLYPH (*border, right_border_glyph);
            }
 
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
          /* Window row window_y must be a slice of frame row
             frame_y.  */
-         xassert (glyph_row_slice_p (window_row, frame_row));
+         eassert (glyph_row_slice_p (window_row, frame_row));
 
          /* If rows are in sync, we don't have to copy glyphs because
             frame and window share glyphs.  */
@@ -2860,15 +2609,13 @@ build_frame_matrix_from_leaf_window (frame_matrix, w)
    for instance, vertical separators, truncation markers, etc.  */
 
 void
-spec_glyph_lookup_face (w, glyph)
-     struct window *w;
-     GLYPH *glyph;
+spec_glyph_lookup_face (struct window *w, GLYPH *glyph)
 {
   int lface_id = GLYPH_FACE (*glyph);
   /* Convert the glyph's specified face to a realized (cache) face.  */
   if (lface_id > 0)
     {
-      int face_id = merge_faces (XFRAME (w->frame),
+      int face_id = merge_faces (XFRAME (WVAR (w, frame)),
                                 Qt, lface_id, DEFAULT_FACE_ID);
       SET_GLYPH_FACE (*glyph, face_id);
     }
@@ -2891,8 +2638,7 @@ spec_glyph_lookup_face (w, glyph)
    To be called for frame-based redisplay, only.  */
 
 static void
-fill_up_glyph_row_with_spaces (row)
-     struct glyph_row *row;
+fill_up_glyph_row_with_spaces (struct glyph_row *row)
 {
   fill_up_glyph_row_area_with_spaces (row, LEFT_MARGIN_AREA);
   fill_up_glyph_row_area_with_spaces (row, TEXT_AREA);
@@ -2904,9 +2650,7 @@ fill_up_glyph_row_with_spaces (row)
    frame-based redisplay only.  */
 
 static void
-fill_up_glyph_row_area_with_spaces (row, area)
-     struct glyph_row *row;
-     int area;
+fill_up_glyph_row_area_with_spaces (struct glyph_row *row, int area)
 {
   if (row->glyphs[area] < row->glyphs[area + 1])
     {
@@ -2924,9 +2668,7 @@ fill_up_glyph_row_area_with_spaces (row, area)
    reached.  In frame matrices only one area, TEXT_AREA, is used.  */
 
 static void
-fill_up_frame_row_with_spaces (row, upto)
-     struct glyph_row *row;
-     int upto;
+fill_up_frame_row_with_spaces (struct glyph_row *row, int upto)
 {
   int i = row->used[TEXT_AREA];
   struct glyph *glyph = row->glyphs[TEXT_AREA];
@@ -2947,9 +2689,8 @@ fill_up_frame_row_with_spaces (row, upto)
    function must be called before updates to make explicit that we are
    working on frame matrices or not.  */
 
-static INLINE void
-set_frame_matrix_frame (f)
-     struct frame *f;
+static inline void
+set_frame_matrix_frame (struct frame *f)
 {
   frame_matrix_frame = f;
 }
@@ -2963,10 +2704,8 @@ set_frame_matrix_frame (f)
    done in frame matrices, and that we have to perform analogous
    operations in window matrices of frame_matrix_frame.  */
 
-static INLINE void
-make_current (desired_matrix, current_matrix, row)
-     struct glyph_matrix *desired_matrix, *current_matrix;
-     int row;
+static inline void
+make_current (struct glyph_matrix *desired_matrix, struct glyph_matrix *current_matrix, int row)
 {
   struct glyph_row *current_row = MATRIX_ROW (current_matrix, row);
   struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, row);
@@ -2983,7 +2722,7 @@ make_current (desired_matrix, current_matrix, row)
   /* If we are called on frame matrices, perform analogous operations
      for window matrices.  */
   if (frame_matrix_frame)
-    mirror_make_current (XWINDOW (frame_matrix_frame->root_window), row);
+    mirror_make_current (XWINDOW (FVAR (frame_matrix_frame, root_window)), row);
 }
 
 
@@ -2993,16 +2732,14 @@ make_current (desired_matrix, current_matrix, row)
    matrices of leaf windows in the window tree rooted at W.  */
 
 static void
-mirror_make_current (w, frame_row)
-     struct window *w;
-     int frame_row;
+mirror_make_current (struct window *w, int frame_row)
 {
   while (w)
     {
-      if (!NILP (w->hchild))
-       mirror_make_current (XWINDOW (w->hchild), frame_row);
-      else if (!NILP (w->vchild))
-       mirror_make_current (XWINDOW (w->vchild), frame_row);
+      if (!NILP (WVAR (w, hchild)))
+       mirror_make_current (XWINDOW (WVAR (w, hchild)), frame_row);
+      else if (!NILP (WVAR (w, vchild)))
+       mirror_make_current (XWINDOW (WVAR (w, vchild)), frame_row);
       else
        {
          /* Row relative to window W.  Don't use FRAME_TO_WINDOW_VPOS
@@ -3024,10 +2761,18 @@ mirror_make_current (w, frame_row)
              else
                swap_glyph_pointers (desired_row, current_row);
              current_row->enabled_p = 1;
+
+             /* Set the Y coordinate of the mode/header line's row.
+                It is needed in draw_row_with_mouse_face to find the
+                screen coordinates.  (Window-based redisplay sets
+                this in update_window, but no one seems to do that
+                for frame-based redisplay.)  */
+             if (current_row->mode_line_p)
+               current_row->y = row;
            }
        }
 
-      w = NILP (w->next) ? 0 : XWINDOW (w->next);
+      w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
     }
 }
 
@@ -3043,12 +2788,8 @@ mirror_make_current (w, frame_row)
    This function is called from do_scrolling and do_direct_scrolling.  */
 
 void
-mirrored_line_dance (matrix, unchanged_at_top, nlines, copy_from,
-                    retained_p)
-     struct glyph_matrix *matrix;
-     int unchanged_at_top, nlines;
-     int *copy_from;
-     char *retained_p;
+mirrored_line_dance (struct glyph_matrix *matrix, int unchanged_at_top, int nlines,
+                    int *copy_from, char *retained_p)
 {
   /* A copy of original rows.  */
   struct glyph_row *old_rows;
@@ -3059,16 +2800,16 @@ mirrored_line_dance (matrix, unchanged_at_top, nlines, copy_from,
   int i;
 
   /* Make a copy of the original rows.  */
-  old_rows = (struct glyph_row *) alloca (nlines * sizeof *old_rows);
-  bcopy (new_rows, old_rows, nlines * sizeof *old_rows);
+  old_rows = alloca (nlines * sizeof *old_rows);
+  memcpy (old_rows, new_rows, nlines * sizeof *old_rows);
 
   /* Assign new rows, maybe clear lines.  */
   for (i = 0; i < nlines; ++i)
     {
       int enabled_before_p = new_rows[i].enabled_p;
 
-      xassert (i + unchanged_at_top < matrix->nrows);
-      xassert (unchanged_at_top + copy_from[i] < matrix->nrows);
+      eassert (i + unchanged_at_top < matrix->nrows);
+      eassert (unchanged_at_top + copy_from[i] < matrix->nrows);
       new_rows[i] = old_rows[copy_from[i]];
       new_rows[i].enabled_p = enabled_before_p;
 
@@ -3079,7 +2820,7 @@ mirrored_line_dance (matrix, unchanged_at_top, nlines, copy_from,
 
   /* Do the same for window matrices, if MATRIX is a frame matrix.  */
   if (frame_matrix_frame)
-    mirror_line_dance (XWINDOW (frame_matrix_frame->root_window),
+    mirror_line_dance (XWINDOW (FVAR (frame_matrix_frame, root_window)),
                       unchanged_at_top, nlines, copy_from, retained_p);
 }
 
@@ -3088,19 +2829,18 @@ mirrored_line_dance (matrix, unchanged_at_top, nlines, copy_from,
    the current frame matrix.  */
 
 static void
-sync_window_with_frame_matrix_rows (w)
-     struct window *w;
+sync_window_with_frame_matrix_rows (struct window *w)
 {
-  struct frame *f = XFRAME (w->frame);
+  struct frame *f = XFRAME (WVAR (w, frame));
   struct glyph_row *window_row, *window_row_end, *frame_row;
   int left, right, x, width;
 
   /* Preconditions: W must be a leaf window on a tty frame.  */
-  xassert (NILP (w->hchild) && NILP (w->vchild));
-  xassert (!FRAME_WINDOW_P (f));
+  eassert (NILP (WVAR (w, hchild)) && NILP (WVAR (w, vchild)));
+  eassert (!FRAME_WINDOW_P (f));
 
-  left = margin_glyphs_to_reserve (w, 1, w->left_margin_cols);
-  right = margin_glyphs_to_reserve (w, 1, w->right_margin_cols);
+  left = margin_glyphs_to_reserve (w, 1, WVAR (w, left_margin_cols));
+  right = margin_glyphs_to_reserve (w, 1, WVAR (w, right_margin_cols));
   x = w->current_matrix->matrix_x;
   width = w->current_matrix->matrix_w;
 
@@ -3125,24 +2865,22 @@ sync_window_with_frame_matrix_rows (w)
 /* Return the window in the window tree rooted in W containing frame
    row ROW.  Value is null if none is found.  */
 
-struct window *
-frame_row_to_window (w, row)
-     struct window *w;
-     int row;
+static struct window *
+frame_row_to_window (struct window *w, int row)
 {
   struct window *found = NULL;
 
   while (w && !found)
     {
-      if (!NILP (w->hchild))
-       found = frame_row_to_window (XWINDOW (w->hchild), row);
-      else if (!NILP (w->vchild))
-       found = frame_row_to_window (XWINDOW (w->vchild), row);
+      if (!NILP (WVAR (w, hchild)))
+       found = frame_row_to_window (XWINDOW (WVAR (w, hchild)), row);
+      else if (!NILP (WVAR (w, vchild)))
+       found = frame_row_to_window (XWINDOW (WVAR (w, vchild)), row);
       else if (row >= WINDOW_TOP_EDGE_LINE (w)
               && row < WINDOW_BOTTOM_EDGE_LINE (w))
        found = w;
 
-      w = NILP (w->next) ? 0 : XWINDOW (w->next);
+      w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
     }
 
   return found;
@@ -3161,19 +2899,15 @@ frame_row_to_window (w, row)
    which is empty.  */
 
 static void
-mirror_line_dance (w, unchanged_at_top, nlines, copy_from, retained_p)
-     struct window *w;
-     int unchanged_at_top, nlines;
-     int *copy_from;
-     char *retained_p;
+mirror_line_dance (struct window *w, int unchanged_at_top, int nlines, int *copy_from, char *retained_p)
 {
   while (w)
     {
-      if (!NILP (w->hchild))
-       mirror_line_dance (XWINDOW (w->hchild), unchanged_at_top,
+      if (!NILP (WVAR (w, hchild)))
+       mirror_line_dance (XWINDOW (WVAR (w, hchild)), unchanged_at_top,
                           nlines, copy_from, retained_p);
-      else if (!NILP (w->vchild))
-       mirror_line_dance (XWINDOW (w->vchild), unchanged_at_top,
+      else if (!NILP (WVAR (w, vchild)))
+       mirror_line_dance (XWINDOW (WVAR (w, vchild)), unchanged_at_top,
                           nlines, copy_from, retained_p);
       else
        {
@@ -3184,8 +2918,8 @@ mirror_line_dance (w, unchanged_at_top, nlines, copy_from, retained_p)
          struct glyph_row *old_rows;
 
          /* Make a copy of the original rows of matrix m.  */
-         old_rows = (struct glyph_row *) alloca (m->nrows * sizeof *old_rows);
-         bcopy (m->rows, old_rows, m->nrows * sizeof *old_rows);
+         old_rows = alloca (m->nrows * sizeof *old_rows);
+         memcpy (old_rows, m->rows, m->nrows * sizeof *old_rows);
 
          for (i = 0; i < nlines; ++i)
            {
@@ -3229,7 +2963,7 @@ mirror_line_dance (w, unchanged_at_top, nlines, copy_from, retained_p)
                {
                  /* A copy between windows.  This is an infrequent
                     case not worth optimizing.  */
-                 struct frame *f = XFRAME (w->frame);
+                 struct frame *f = XFRAME (WVAR (w, frame));
                  struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
                  struct window *w2;
                  struct glyph_matrix *m2;
@@ -3266,12 +3000,12 @@ mirror_line_dance (w, unchanged_at_top, nlines, copy_from, retained_p)
        }
 
       /* Next window on same level.  */
-      w = NILP (w->next) ? 0 : XWINDOW (w->next);
+      w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
     }
 }
 
 
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
 
 /* Check that window and frame matrices agree about their
    understanding where glyphs of the rows are to find.  For each
@@ -3279,24 +3013,23 @@ mirror_line_dance (w, unchanged_at_top, nlines, copy_from, retained_p)
    matrices of leaf window agree with their frame matrices about
    glyph pointers.  */
 
-void
-check_window_matrix_pointers (w)
-     struct window *w;
+static void
+check_window_matrix_pointers (struct window *w)
 {
   while (w)
     {
-      if (!NILP (w->hchild))
-       check_window_matrix_pointers (XWINDOW (w->hchild));
-      else if (!NILP (w->vchild))
-       check_window_matrix_pointers (XWINDOW (w->vchild));
+      if (!NILP (WVAR (w, hchild)))
+       check_window_matrix_pointers (XWINDOW (WVAR (w, hchild)));
+      else if (!NILP (WVAR (w, vchild)))
+       check_window_matrix_pointers (XWINDOW (WVAR (w, vchild)));
       else
        {
-         struct frame *f = XFRAME (w->frame);
+         struct frame *f = XFRAME (WVAR (w, frame));
          check_matrix_pointers (w->desired_matrix, f->desired_matrix);
          check_matrix_pointers (w->current_matrix, f->current_matrix);
        }
 
-      w = NILP (w->next) ? 0 : XWINDOW (w->next);
+      w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
     }
 }
 
@@ -3307,8 +3040,8 @@ check_window_matrix_pointers (w)
    corresponding frame row.  If it isn't, abort.  */
 
 static void
-check_matrix_pointers (window_matrix, frame_matrix)
-     struct glyph_matrix *window_matrix, *frame_matrix;
+check_matrix_pointers (struct glyph_matrix *window_matrix,
+                      struct glyph_matrix *frame_matrix)
 {
   /* Row number in WINDOW_MATRIX.  */
   int i = 0;
@@ -3328,7 +3061,7 @@ check_matrix_pointers (window_matrix, frame_matrix)
     }
 }
 
-#endif /* GLYPH_DEBUG != 0 */
+#endif /* GLYPH_DEBUG */
 
 
 \f
@@ -3336,22 +3069,18 @@ check_matrix_pointers (window_matrix, frame_matrix)
                      VPOS and HPOS translations
  **********************************************************************/
 
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
 
 /* Translate vertical position VPOS which is relative to window W to a
    vertical position relative to W's frame.  */
 
 static int
-window_to_frame_vpos (w, vpos)
-     struct window *w;
-     int vpos;
+window_to_frame_vpos (struct window *w, int vpos)
 {
-  struct frame *f = XFRAME (w->frame);
-
-  xassert (!FRAME_WINDOW_P (f));
-  xassert (vpos >= 0 && vpos <= w->desired_matrix->nrows);
+  eassert (!FRAME_WINDOW_P (XFRAME (WVAR (w, frame))));
+  eassert (vpos >= 0 && vpos <= w->desired_matrix->nrows);
   vpos += WINDOW_TOP_EDGE_LINE (w);
-  xassert (vpos >= 0 && vpos <= FRAME_LINES (f));
+  eassert (vpos >= 0 && vpos <= FRAME_LINES (XFRAME (WVAR (w, frame))));
   return vpos;
 }
 
@@ -3360,11 +3089,9 @@ window_to_frame_vpos (w, vpos)
    a horizontal position relative to W's frame.  */
 
 static int
-window_to_frame_hpos (w, hpos)
-     struct window *w;
-     int hpos;
+window_to_frame_hpos (struct window *w, int hpos)
 {
-  xassert (!FRAME_WINDOW_P (XFRAME (w->frame)));
+  eassert (!FRAME_WINDOW_P (XFRAME (WVAR (w, frame))));
   hpos += WINDOW_LEFT_EDGE_COL (w);
   return hpos;
 }
@@ -3379,8 +3106,7 @@ window_to_frame_hpos (w, hpos)
 
 DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
        doc: /* Clear frame FRAME and output again what is supposed to appear on it.  */)
-     (frame)
-     Lisp_Object frame;
+  (Lisp_Object frame)
 {
   struct frame *f;
 
@@ -3417,8 +3143,7 @@ DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
    function redraw-frame.  */
 
 void
-redraw_frame (f)
-     struct frame *f;
+redraw_frame (struct frame *f)
 {
   Lisp_Object frame;
   XSETFRAME (frame, f);
@@ -3428,7 +3153,7 @@ redraw_frame (f)
 
 DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
        doc: /* Clear and redisplay all visible frames.  */)
-     ()
+  (void)
 {
   Lisp_Object tail, frame;
 
@@ -3440,410 +3165,6 @@ DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
 }
 
 
-/* This is used when frame_garbaged is set.  Call Fredraw_frame on all
-   visible frames marked as garbaged.  */
-
-void
-redraw_garbaged_frames ()
-{
-  Lisp_Object tail, frame;
-
-  FOR_EACH_FRAME (tail, frame)
-    if (FRAME_VISIBLE_P (XFRAME (frame))
-       && FRAME_GARBAGED_P (XFRAME (frame)))
-      Fredraw_frame (frame);
-}
-
-
-\f
-/***********************************************************************
-                         Direct Operations
- ***********************************************************************/
-
-/* Try to update display and current glyph matrix directly.
-
-   This function is called after a character G has been inserted into
-   current_buffer.  It tries to update the current glyph matrix and
-   perform appropriate screen output to reflect the insertion.  If it
-   succeeds, the global flag redisplay_performed_directly_p will be
-   set to 1, and thereby prevent the more costly general redisplay
-   from running (see redisplay_internal).
-
-   This function is not called for `hairy' character insertions.
-   In particular, it is not called when after or before change
-   functions exist, like they are used by font-lock.  See keyboard.c
-   for details where this function is called.  */
-
-int
-direct_output_for_insert (g)
-     int g;
-{
-  register struct frame *f = SELECTED_FRAME ();
-  struct window *w = XWINDOW (selected_window);
-  struct it it, it2;
-  struct glyph_row *glyph_row;
-  struct glyph *glyphs, *glyph, *end;
-  int n;
-  /* Non-null means that redisplay of W is based on window matrices.  */
-  int window_redisplay_p = FRAME_WINDOW_P (f);
-  /* Non-null means we are in overwrite mode.  */
-  int overwrite_p = !NILP (current_buffer->overwrite_mode);
-  int added_width;
-  struct text_pos pos;
-  int delta, delta_bytes;
-
-  /* Not done directly.  */
-  redisplay_performed_directly_p = 0;
-
-  /* Quickly give up for some common cases.  */
-  if (cursor_in_echo_area
-      /* Give up if fonts have changed.  */
-      || fonts_changed_p
-      /* Give up if face attributes have been changed.  */
-      || face_change_count
-      /* Give up if cursor position not really known.  */
-      || !display_completed
-      /* Give up if buffer appears in two places.  */
-      || buffer_shared > 1
-      /* Give up if currently displaying a message instead of the
-        minibuffer contents.  */
-      || (EQ (selected_window, minibuf_window)
-         && EQ (minibuf_window, echo_area_window))
-      /* Give up for hscrolled mini-buffer because display of the prompt
-        is handled specially there (see display_line).  */
-      || (MINI_WINDOW_P (w) && XFASTINT (w->hscroll))
-      /* Give up if overwriting in the middle of a line.  */
-      || (overwrite_p
-         && PT != ZV
-         && FETCH_BYTE (PT) != '\n')
-      /* Give up for tabs and line ends.  */
-      || g == '\t'
-      || g == '\n'
-      || g == '\r'
-      || (g == ' ' && !NILP (current_buffer->word_wrap))
-      /* Give up if unable to display the cursor in the window.  */
-      || w->cursor.vpos < 0
-      /* Give up if we are showing a message or just cleared the message
-        because we might need to resize the echo area window.  */
-      || !NILP (echo_area_buffer[0])
-      || !NILP (echo_area_buffer[1])
-      || (glyph_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos),
-         /* Can't do it in a continued line because continuation
-            lines would change.  */
-         (glyph_row->continued_p
-          || glyph_row->exact_window_width_line_p
-          /* Can't use this method if the line overlaps others or is
-             overlapped by others because these other lines would
-             have to be redisplayed.  */
-          || glyph_row->overlapping_p
-          || glyph_row->overlapped_p))
-      /* Can't do it for partial width windows on terminal frames
-        because we can't clear to eol in such a window.  */
-      || (!window_redisplay_p && !WINDOW_FULL_WIDTH_P (w)))
-    return 0;
-
-  /* If we can't insert glyphs, we can use this method only
-     at the end of a line.  */
-  if (!FRAME_CHAR_INS_DEL_OK (f))
-    if (PT != ZV && FETCH_BYTE (PT_BYTE) != '\n')
-      return 0;
-
-  /* Set up a display iterator structure for W.  Glyphs will be
-     produced in scratch_glyph_row.  Current position is W's cursor
-     position.  */
-  clear_glyph_row (&scratch_glyph_row);
-  SET_TEXT_POS (pos, PT, PT_BYTE);
-  DEC_TEXT_POS (pos, !NILP (current_buffer->enable_multibyte_characters));
-  init_iterator (&it, w, CHARPOS (pos), BYTEPOS (pos), &scratch_glyph_row,
-                DEFAULT_FACE_ID);
-
-  glyph_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
-  if (glyph_row->mouse_face_p)
-    return 0;
-
-  /* Give up if highlighting trailing whitespace and we have trailing
-     whitespace in glyph_row.  We would have to remove the trailing
-     whitespace face in that case.  */
-  if (!NILP (Vshow_trailing_whitespace)
-      && glyph_row->used[TEXT_AREA])
-    {
-      struct glyph *last;
-
-      last = glyph_row->glyphs[TEXT_AREA] + glyph_row->used[TEXT_AREA] - 1;
-      if (last->type == STRETCH_GLYPH
-         || (last->type == CHAR_GLYPH
-             && last->u.ch == ' '))
-       return 0;
-    }
-
-  /* Give up if there are overlay strings at pos.  This would fail
-     if the overlay string has newlines in it.  */
-  if (STRINGP (it.string))
-    return 0;
-
-  it.hpos = w->cursor.hpos;
-  it.vpos = w->cursor.vpos;
-  it.current_x = w->cursor.x + it.first_visible_x;
-  it.current_y = w->cursor.y;
-  it.end_charpos = PT;
-  it.stop_charpos = min (PT, it.stop_charpos);
-  it.stop_charpos = max (IT_CHARPOS (it), it.stop_charpos);
-
-  /* More than one display element may be returned for PT - 1 if
-     (i) it's a control character which is translated into `\003' or
-     `^C', or (ii) it has a display table entry, or (iii) it's a
-     combination of both.  */
-  delta = delta_bytes = 0;
-  while (get_next_display_element (&it))
-    {
-      PRODUCE_GLYPHS (&it);
-
-      /* Give up if glyph doesn't fit completely on the line.  */
-      if (it.current_x >= it.last_visible_x)
-       return 0;
-
-      /* Give up if new glyph has different ascent or descent than
-        the original row, or if it is not a character glyph.  */
-      if (glyph_row->ascent != it.ascent
-         || glyph_row->height != it.ascent + it.descent
-         || glyph_row->phys_ascent != it.phys_ascent
-         || glyph_row->phys_height != it.phys_ascent + it.phys_descent
-         || it.what != IT_CHARACTER)
-       return 0;
-
-      delta += 1;
-      delta_bytes += it.len;
-      set_iterator_to_next (&it, 1);
-    }
-
-  /* Give up if we hit the right edge of the window.  We would have
-     to insert truncation or continuation glyphs.  */
-  added_width = it.current_x - (w->cursor.x + it.first_visible_x);
-  if (glyph_row->pixel_width + added_width >= it.last_visible_x)
-    return 0;
-
-  /* Give up if there is a \t following in the line.  */
-  it2 = it;
-  it2.end_charpos = ZV;
-  it2.stop_charpos = min (it2.stop_charpos, ZV);
-  while (get_next_display_element (&it2)
-        && !ITERATOR_AT_END_OF_LINE_P (&it2))
-    {
-      if (it2.c == '\t')
-       return 0;
-      set_iterator_to_next (&it2, 1);
-    }
-
-  /* Number of new glyphs produced.  */
-  n = it.glyph_row->used[TEXT_AREA];
-
-  /* Start and end of glyphs in original row.  */
-  glyphs = glyph_row->glyphs[TEXT_AREA] + w->cursor.hpos;
-  end = glyph_row->glyphs[1 + TEXT_AREA];
-
-  /* Make room for new glyphs, then insert them.  */
-  xassert (end - glyphs - n >= 0);
-  safe_bcopy ((char *) glyphs, (char *) (glyphs + n),
-             (end - glyphs - n) * sizeof (*end));
-  bcopy (it.glyph_row->glyphs[TEXT_AREA], glyphs, n * sizeof *glyphs);
-  glyph_row->used[TEXT_AREA] = min (glyph_row->used[TEXT_AREA] + n,
-                                   end - glyph_row->glyphs[TEXT_AREA]);
-
-  /* Compute new line width.  */
-  glyph = glyph_row->glyphs[TEXT_AREA];
-  end = glyph + glyph_row->used[TEXT_AREA];
-  glyph_row->pixel_width = glyph_row->x;
-  while (glyph < end)
-    {
-      glyph_row->pixel_width += glyph->pixel_width;
-      ++glyph;
-    }
-
-  /* Increment buffer positions for glyphs following the newly
-     inserted ones.  */
-  for (glyph = glyphs + n; glyph < end; ++glyph)
-    if (glyph->charpos > 0 && BUFFERP (glyph->object))
-      glyph->charpos += delta;
-
-  if (MATRIX_ROW_END_CHARPOS (glyph_row) > 0)
-    {
-      MATRIX_ROW_END_CHARPOS (glyph_row) += delta;
-      MATRIX_ROW_END_BYTEPOS (glyph_row) += delta_bytes;
-    }
-
-  /* Adjust positions in lines following the one we are in.  */
-  increment_matrix_positions (w->current_matrix,
-                             w->cursor.vpos + 1,
-                             w->current_matrix->nrows,
-                             delta, delta_bytes);
-
-  glyph_row->contains_overlapping_glyphs_p
-    |= it.glyph_row->contains_overlapping_glyphs_p;
-
-  glyph_row->displays_text_p = 1;
-  w->window_end_vpos = make_number (max (w->cursor.vpos,
-                                        XFASTINT (w->window_end_vpos)));
-
-  if (!NILP (Vshow_trailing_whitespace))
-    highlight_trailing_whitespace (it.f, glyph_row);
-
-  /* Write glyphs.  If at end of row, we can simply call write_glyphs.
-     In the middle, we have to insert glyphs.  Note that this is now
-     implemented for X frames.  The implementation uses updated_window
-     and updated_row.  */
-  updated_row = glyph_row;
-  updated_area = TEXT_AREA;
-  update_begin (f);
-  if (FRAME_RIF (f))
-    {
-      FRAME_RIF (f)->update_window_begin_hook (w);
-
-      if (glyphs == end - n
-         /* In front of a space added by append_space.  */
-         || (glyphs == end - n - 1
-             && (end - n)->charpos <= 0))
-       FRAME_RIF (f)->write_glyphs (glyphs, n);
-      else
-       FRAME_RIF (f)->insert_glyphs (glyphs, n);
-    }
-  else
-    {
-      if (glyphs == end - n)
-       write_glyphs (f, glyphs, n);
-      else
-       insert_glyphs (f, glyphs, n);
-    }
-
-  w->cursor.hpos += n;
-  w->cursor.x = it.current_x - it.first_visible_x;
-  xassert (w->cursor.hpos >= 0
-          && w->cursor.hpos < w->desired_matrix->matrix_w);
-
-  /* How to set the cursor differs depending on whether we are
-     using a frame matrix or a window matrix.   Note that when
-     a frame matrix is used, cursor_to expects frame coordinates,
-     and the X and Y parameters are not used.  */
-  if (window_redisplay_p)
-    FRAME_RIF (f)->cursor_to (w->cursor.vpos, w->cursor.hpos,
-                              w->cursor.y, w->cursor.x);
-  else
-    {
-      int x, y;
-      x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos)
-          + (INTEGERP (w->left_margin_cols)
-             ? XFASTINT (w->left_margin_cols)
-             : 0));
-      y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
-      cursor_to (f, y, x);
-    }
-
-#ifdef HAVE_WINDOW_SYSTEM
-  update_window_fringes (w, 0);
-#endif
-
-  if (FRAME_RIF (f))
-    FRAME_RIF (f)->update_window_end_hook (w, 1, 0);
-  update_end (f);
-  updated_row = NULL;
-  if (FRAME_TERMCAP_P (f))
-    fflush (FRAME_TTY (f)->output);
-
-  TRACE ((stderr, "direct output for insert\n"));
-  mark_window_display_accurate (it.window, 1);
-  redisplay_performed_directly_p = 1;
-  return 1;
-}
-
-
-/* Perform a direct display update for moving PT by N positions
-   left or right.  N < 0 means a movement backwards.  This function
-   is currently only called for N == 1 or N == -1.  */
-
-int
-direct_output_forward_char (n)
-     int n;
-{
-  struct frame *f = SELECTED_FRAME ();
-  struct window *w = XWINDOW (selected_window);
-  struct glyph_row *row;
-
-  /* Give up if point moved out of or into a composition.  */
-  if (check_point_in_composition (current_buffer, XINT (w->last_point),
-                                 current_buffer, PT))
-    return 0;
-
-  /* Give up if face attributes have been changed.  */
-  if (face_change_count)
-    return 0;
-
-  /* Give up if current matrix is not up to date or we are
-     displaying a message.  */
-  if (!display_completed || cursor_in_echo_area)
-    return 0;
-
-  /* Give up if the buffer's direction is reversed.  */
-  if (!NILP (XBUFFER (w->buffer)->direction_reversed))
-    return 0;
-
-  /* Can't use direct output if highlighting a region.  */
-  if (!NILP (Vtransient_mark_mode) && !NILP (current_buffer->mark_active))
-    return 0;
-
-  /* Can't use direct output if highlighting trailing whitespace.  */
-  if (!NILP (Vshow_trailing_whitespace))
-    return 0;
-
-  /* Give up if we are showing a message or just cleared the message
-     because we might need to resize the echo area window.  */
-  if (!NILP (echo_area_buffer[0]) || !NILP (echo_area_buffer[1]))
-    return 0;
-
-  /* Give up if currently displaying a message instead of the
-     minibuffer contents.  */
-  if (XWINDOW (minibuf_window) == w
-      && EQ (minibuf_window, echo_area_window))
-    return 0;
-
-  /* Give up if we don't know where the cursor is.  */
-  if (w->cursor.vpos < 0)
-    return 0;
-
-  row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
-
-  /* Give up if PT is outside of the last known cursor row.  */
-  if (PT <= MATRIX_ROW_START_CHARPOS (row)
-      || PT >= MATRIX_ROW_END_CHARPOS (row))
-    return 0;
-
-  set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
-
-  w->last_cursor = w->cursor;
-  XSETFASTINT (w->last_point, PT);
-
-  xassert (w->cursor.hpos >= 0
-          && w->cursor.hpos < w->desired_matrix->matrix_w);
-
-  if (FRAME_WINDOW_P (f))
-    FRAME_RIF (f)->cursor_to (w->cursor.vpos, w->cursor.hpos,
-                              w->cursor.y, w->cursor.x);
-  else
-    {
-      int x, y;
-      x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos)
-          + (INTEGERP (w->left_margin_cols)
-             ? XFASTINT (w->left_margin_cols)
-             : 0));
-      y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
-      cursor_to (f, y, x);
-    }
-
-  if (FRAME_TERMCAP_P (f))
-    fflush (FRAME_TTY (f)->output);
-  redisplay_performed_directly_p = 1;
-  return 1;
-}
-
-
 \f
 /***********************************************************************
                             Frame Update
@@ -3858,25 +3179,19 @@ direct_output_forward_char (n)
    Value is non-zero if redisplay was stopped due to pending input.  */
 
 int
-update_frame (f, force_p, inhibit_hairy_id_p)
-     struct frame *f;
-     int force_p;
-     int inhibit_hairy_id_p;
+update_frame (struct frame *f, int force_p, int inhibit_hairy_id_p)
 {
   /* 1 means display has been paused because of pending input.  */
   int paused_p;
-  struct window *root_window = XWINDOW (f->root_window);
+  struct window *root_window = XWINDOW (FVAR (f, root_window));
 
   if (redisplay_dont_pause)
     force_p = 1;
-#if PERIODIC_PREEMPTION_CHECKING
   else if (NILP (Vredisplay_preemption_period))
     force_p = 1;
   else if (!force_p && NUMBERP (Vredisplay_preemption_period))
     {
-      EMACS_TIME tm;
       double p = XFLOATINT (Vredisplay_preemption_period);
-      int sec, usec;
 
       if (detect_input_pending_ignore_squeezables ())
        {
@@ -3884,14 +3199,10 @@ update_frame (f, force_p, inhibit_hairy_id_p)
          goto do_pause;
        }
 
-      sec = (int) p;
-      usec = (p - sec) * 1000000;
-
-      EMACS_GET_TIME (tm);
-      EMACS_SET_SECS_USECS (preemption_period, sec, usec);
-      EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
+      preemption_period = EMACS_TIME_FROM_DOUBLE (p);
+      preemption_next_check = add_emacs_time (current_emacs_time (),
+                                             preemption_period);
     }
-#endif
 
   if (FRAME_WINDOW_P (f))
     {
@@ -3907,13 +3218,13 @@ update_frame (f, force_p, inhibit_hairy_id_p)
 
       /* Update the menu bar on X frames that don't have toolkit
         support.  */
-      if (WINDOWP (f->menu_bar_window))
-       update_window (XWINDOW (f->menu_bar_window), 1);
+      if (WINDOWP (FVAR (f, menu_bar_window)))
+       update_window (XWINDOW (FVAR (f, menu_bar_window)), 1);
 
       /* Update the tool-bar window, if present.  */
-      if (WINDOWP (f->tool_bar_window))
+      if (WINDOWP (FVAR (f, tool_bar_window)))
        {
-         struct window *w = XWINDOW (f->tool_bar_window);
+         struct window *w = XWINDOW (FVAR (f, tool_bar_window));
 
          /* Update tool-bar window.  */
          if (w->must_be_updated_p)
@@ -3925,9 +3236,10 @@ update_frame (f, force_p, inhibit_hairy_id_p)
 
              /* Swap tool-bar strings.  We swap because we want to
                 reuse strings.  */
-             tem = f->current_tool_bar_string;
-             f->current_tool_bar_string = f->desired_tool_bar_string;
-             f->desired_tool_bar_string = tem;
+             tem = FVAR (f, current_tool_bar_string);
+             FVAR (f, current_tool_bar_string) = FVAR (f,
+                                                      desired_tool_bar_string);
+             FVAR (f, desired_tool_bar_string) = tem;
            }
        }
 
@@ -3969,7 +3281,7 @@ update_frame (f, force_p, inhibit_hairy_id_p)
         }
 
       /* Check window matrices for lost pointers.  */
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
       check_window_matrix_pointers (root_window);
       add_frame_display_history (f, paused_p);
 #endif
@@ -3993,22 +3305,20 @@ update_frame (f, force_p, inhibit_hairy_id_p)
    don't stop updating when input is pending.  */
 
 static int
-update_window_tree (w, force_p)
-     struct window *w;
-     int force_p;
+update_window_tree (struct window *w, int force_p)
 {
   int paused_p = 0;
 
   while (w && !paused_p)
     {
-      if (!NILP (w->hchild))
-       paused_p |= update_window_tree (XWINDOW (w->hchild), force_p);
-      else if (!NILP (w->vchild))
-       paused_p |= update_window_tree (XWINDOW (w->vchild), force_p);
+      if (!NILP (WVAR (w, hchild)))
+       paused_p |= update_window_tree (XWINDOW (WVAR (w, hchild)), force_p);
+      else if (!NILP (WVAR (w, vchild)))
+       paused_p |= update_window_tree (XWINDOW (WVAR (w, vchild)), force_p);
       else if (w->must_be_updated_p)
        paused_p |= update_window (w, force_p);
 
-      w = NILP (w->next) ? 0 : XWINDOW (w->next);
+      w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
     }
 
   return paused_p;
@@ -4019,9 +3329,7 @@ update_window_tree (w, force_p)
    FORCE_P is non-zero, don't stop updating if input is pending.  */
 
 void
-update_single_window (w, force_p)
-     struct window *w;
-     int force_p;
+update_single_window (struct window *w, int force_p)
 {
   if (w->must_be_updated_p)
     {
@@ -4032,23 +3340,15 @@ update_single_window (w, force_p)
 
       if (redisplay_dont_pause)
        force_p = 1;
-#if PERIODIC_PREEMPTION_CHECKING
       else if (NILP (Vredisplay_preemption_period))
        force_p = 1;
       else if (!force_p && NUMBERP (Vredisplay_preemption_period))
        {
-         EMACS_TIME tm;
          double p = XFLOATINT (Vredisplay_preemption_period);
-         int sec, usec;
-
-         sec = (int) p;
-         usec = (p - sec) * 1000000;
-
-         EMACS_GET_TIME (tm);
-         EMACS_SET_SECS_USECS (preemption_period, sec, usec);
-         EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
+         preemption_period = EMACS_TIME_FROM_DOUBLE (p);
+         preemption_next_check = add_emacs_time (current_emacs_time (),
+                                                 preemption_period);
        }
-#endif
 
       /* Update W.  */
       update_begin (f);
@@ -4066,9 +3366,7 @@ update_single_window (w, force_p)
    overlapped by other rows.  YB is bottom-most y-position in W.  */
 
 static void
-redraw_overlapped_rows (w, yb)
-     struct window *w;
-     int yb;
+redraw_overlapped_rows (struct window *w, int yb)
 {
   int i;
   struct frame *f = XFRAME (WINDOW_FRAME (w));
@@ -4116,9 +3414,7 @@ redraw_overlapped_rows (w, yb)
    others.  YB is bottom-most y-position in W.  */
 
 static void
-redraw_overlapping_rows (w, yb)
-     struct window *w;
-     int yb;
+redraw_overlapping_rows (struct window *w, int yb)
 {
   int i, bottom_y;
   struct glyph_row *row;
@@ -4157,7 +3453,7 @@ redraw_overlapping_rows (w, yb)
              if (row->used[RIGHT_MARGIN_AREA])
                rif->fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, overlaps);
 
-             /* Record in neighbour rows that ROW overwrites part of
+             /* Record in neighbor rows that ROW overwrites part of
                 their display.  */
              if (overlaps & OVERLAPS_PRED)
                MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p = 1;
@@ -4174,14 +3470,13 @@ redraw_overlapping_rows (w, yb)
 #endif /* HAVE_WINDOW_SYSTEM */
 
 
-#ifdef GLYPH_DEBUG
+#if defined GLYPH_DEBUG && 0
 
 /* Check that no row in the current matrix of window W is enabled
    which is below what's displayed in the window.  */
 
-void
-check_current_matrix_flags (w)
-     struct window *w;
+static void
+check_current_matrix_flags (struct window *w)
 {
   int last_seen_p = 0;
   int i, yb = window_text_bottom_y (w);
@@ -4203,21 +3498,17 @@ check_current_matrix_flags (w)
    not stop when detecting pending input.  */
 
 static int
-update_window (w, force_p)
-     struct window *w;
-     int force_p;
+update_window (struct window *w, int force_p)
 {
   struct glyph_matrix *desired_matrix = w->desired_matrix;
   int paused_p;
 #if !PERIODIC_PREEMPTION_CHECKING
   int preempt_count = baud_rate / 2400 + 1;
 #endif
-  extern int input_pending;
-  extern Lisp_Object do_mouse_tracking;
   struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
   /* Check that W's frame doesn't have glyph matrices.  */
-  xassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))));
+  eassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))));
 #endif
 
   /* Check pending input the first time so that we can quickly return.  */
@@ -4233,16 +3524,18 @@ update_window (w, force_p)
       struct glyph_row *row, *end;
       struct glyph_row *mode_line_row;
       struct glyph_row *header_line_row;
-      int yb, changed_p = 0, mouse_face_overwritten_p = 0, n_updated;
+      int yb, changed_p = 0, mouse_face_overwritten_p = 0;
+#if ! PERIODIC_PREEMPTION_CHECKING
+      int n_updated = 0;
+#endif
 
       rif->update_window_begin_hook (w);
       yb = window_text_bottom_y (w);
-
-      /* If window has a header line, update it before everything else.
-        Adjust y-positions of other rows by the header line height.  */
       row = desired_matrix->rows;
       end = row + desired_matrix->nrows - 1;
 
+      /* Take note of the header line, if there is one.  We will
+        update it below, after updating all of the window's lines.  */
       if (row->mode_line_p)
        {
          header_line_row = row;
@@ -4286,7 +3579,9 @@ update_window (w, force_p)
        }
 
       /* Update the rest of the lines.  */
-      for (n_updated = 0; row < end && (force_p || !input_pending); ++row)
+      for (; row < end && (force_p || !input_pending); ++row)
+       /* scrolling_window resets the enabled_p flag of the rows it
+          reuses from current_matrix.  */
        if (row->enabled_p)
          {
            int vpos = MATRIX_ROW_VPOS (row, desired_matrix);
@@ -4299,12 +3594,11 @@ update_window (w, force_p)
 #if PERIODIC_PREEMPTION_CHECKING
            if (!force_p)
              {
-               EMACS_TIME tm, dif;
-               EMACS_GET_TIME (tm);
-               EMACS_SUB_TIME (dif, preemption_next_check, tm);
-               if (EMACS_TIME_NEG_P (dif))
+               EMACS_TIME tm = current_emacs_time ();
+               if (EMACS_TIME_LT (preemption_next_check, tm))
                  {
-                   EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
+                   preemption_next_check = add_emacs_time (tm,
+                                                           preemption_period);
                    if (detect_input_pending_ignore_squeezables ())
                      break;
                  }
@@ -4364,7 +3658,7 @@ update_window (w, force_p)
 #endif
        }
 
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
       /* Remember the redisplay method used to display the matrix.  */
       strcpy (w->current_matrix->method, w->desired_matrix->method);
 #endif
@@ -4382,7 +3676,7 @@ update_window (w, force_p)
   else
     paused_p = 1;
 
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
   /* check_current_matrix_flags (w); */
   add_window_display_history (w, w->current_matrix->method, paused_p);
 #endif
@@ -4397,9 +3691,7 @@ update_window (w, force_p)
    AREA can be either LEFT_MARGIN_AREA or RIGHT_MARGIN_AREA.  */
 
 static void
-update_marginal_area (w, area, vpos)
-     struct window *w;
-     int area, vpos;
+update_marginal_area (struct window *w, int area, int vpos)
 {
   struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
   struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
@@ -4422,9 +3714,7 @@ update_marginal_area (w, area, vpos)
    Value is non-zero if display has changed.  */
 
 static int
-update_text_area (w, vpos)
-     struct window *w;
-     int vpos;
+update_text_area (struct window *w, int vpos)
 {
   struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
   struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
@@ -4516,7 +3806,7 @@ update_text_area (w, vpos)
              struct glyph *glyph = &current_row->glyphs[TEXT_AREA][i - 1];
              int left, right;
 
-             rif->get_glyph_overhangs (glyph, XFRAME (w->frame),
+             rif->get_glyph_overhangs (glyph, XFRAME (WVAR (w, frame)),
                                        &left, &right);
              can_skip_p = (right == 0 && !abort_skipping);
            }
@@ -4548,7 +3838,8 @@ update_text_area (w, vpos)
                {
                  int left, right;
 
-                 rif->get_glyph_overhangs (current_glyph, XFRAME (w->frame),
+                 rif->get_glyph_overhangs (current_glyph,
+                                           XFRAME (WVAR (w, frame)),
                                            &left, &right);
                  while (left > 0 && i > 0)
                    {
@@ -4617,7 +3908,7 @@ update_text_area (w, vpos)
             has to be cleared, if and only if we did a write_glyphs
             above.  This is made sure by setting desired_stop_pos
             appropriately above.  */
-         xassert (i < desired_row->used[TEXT_AREA]
+         eassert (i < desired_row->used[TEXT_AREA]
                   || ((desired_row->used[TEXT_AREA]
                        == current_row->used[TEXT_AREA])
                       && MATRIX_ROW_EXTENDS_FACE_P (current_row)));
@@ -4635,7 +3926,7 @@ update_text_area (w, vpos)
        {
          /* Otherwise clear to the end of the old row.  Everything
             after that position should be clear already.  */
-         int x;
+         int xlim;
 
          if (i >= desired_row->used[TEXT_AREA])
            rif->cursor_to (vpos, i, desired_row->y,
@@ -4647,14 +3938,16 @@ update_text_area (w, vpos)
             doesn't work with lbearing/rbearing), so we must do it
             this way.  */
          if (vpos == w->phys_cursor.vpos
-             && w->phys_cursor.hpos >= desired_row->used[TEXT_AREA])
+             && (desired_row->reversed_p
+                 ? (w->phys_cursor.hpos < 0)
+                 : (w->phys_cursor.hpos >= desired_row->used[TEXT_AREA])))
            {
              w->phys_cursor_on_p = 0;
-             x = -1;
+             xlim = -1;
            }
          else
-           x = current_row->pixel_width;
-         rif->clear_end_of_line (x);
+           xlim = current_row->pixel_width;
+         rif->clear_end_of_line (xlim);
          changed_p = 1;
        }
     }
@@ -4667,9 +3960,7 @@ update_text_area (w, vpos)
    changed.  */
 
 static int
-update_window_line (w, vpos, mouse_face_overwritten_p)
-     struct window *w;
-     int vpos, *mouse_face_overwritten_p;
+update_window_line (struct window *w, int vpos, int *mouse_face_overwritten_p)
 {
   struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
   struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
@@ -4687,11 +3978,11 @@ update_window_line (w, vpos, mouse_face_overwritten_p)
   if (desired_row->mode_line_p
       || desired_row->visible_height > 0)
     {
-      xassert (desired_row->enabled_p);
+      eassert (desired_row->enabled_p);
 
       /* Update display of the left margin area, if there is one.  */
       if (!desired_row->full_width_p
-         && !NILP (w->left_margin_cols))
+         && !NILP (WVAR (w, left_margin_cols)))
        {
          changed_p = 1;
          update_marginal_area (w, LEFT_MARGIN_AREA, vpos);
@@ -4707,7 +3998,7 @@ update_window_line (w, vpos, mouse_face_overwritten_p)
 
       /* Update display of the right margin area, if there is one.  */
       if (!desired_row->full_width_p
-         && !NILP (w->right_margin_cols))
+         && !NILP (WVAR (w, right_margin_cols)))
        {
          changed_p = 1;
          update_marginal_area (w, RIGHT_MARGIN_AREA, vpos);
@@ -4738,15 +4029,14 @@ update_window_line (w, vpos, mouse_face_overwritten_p)
    be called from update_window.  */
 
 static void
-set_window_cursor_after_update (w)
-     struct window *w;
+set_window_cursor_after_update (struct window *w)
 {
-  struct frame *f = XFRAME (w->frame);
+  struct frame *f = XFRAME (WVAR (w, frame));
   struct redisplay_interface *rif = FRAME_RIF (f);
   int cx, cy, vpos, hpos;
 
   /* Not intended for frame matrix updates.  */
-  xassert (FRAME_WINDOW_P (f));
+  eassert (FRAME_WINDOW_P (f));
 
   if (cursor_in_echo_area
       && !NILP (echo_area_buffer[0])
@@ -4811,7 +4101,7 @@ set_window_cursor_after_update (w)
     }
 
   /* Window cursor can be out of sync for horizontally split windows.  */
-  hpos = max (0, hpos);
+  hpos = max (-1, hpos); /* -1 is for when cursor is on the left fringe */
   hpos = min (w->current_matrix->matrix_w - 1, hpos);
   vpos = max (0, vpos);
   vpos = min (w->current_matrix->nrows - 1, vpos);
@@ -4823,20 +4113,18 @@ set_window_cursor_after_update (w)
    tree rooted at W.  */
 
 void
-set_window_update_flags (w, on_p)
-     struct window *w;
-     int on_p;
+set_window_update_flags (struct window *w, int on_p)
 {
   while (w)
     {
-      if (!NILP (w->hchild))
-       set_window_update_flags (XWINDOW (w->hchild), on_p);
-      else if (!NILP (w->vchild))
-       set_window_update_flags (XWINDOW (w->vchild), on_p);
+      if (!NILP (WVAR (w, hchild)))
+       set_window_update_flags (XWINDOW (WVAR (w, hchild)), on_p);
+      else if (!NILP (WVAR (w, vchild)))
+       set_window_update_flags (XWINDOW (WVAR (w, vchild)), on_p);
       else
        w->must_be_updated_p = on_p;
 
-      w = NILP (w->next) ? 0 : XWINDOW (w->next);
+      w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
     }
 }
 
@@ -4857,7 +4145,7 @@ struct row_entry
   int new_line_number;
 
   /* Bucket index of this row_entry in the hash table row_table.  */
-  int bucket;
+  ptrdiff_t bucket;
 
   /* The row described by this entry.  */
   struct glyph_row *row;
@@ -4871,47 +4159,45 @@ struct row_entry
    that we need a larger one.  */
 
 static struct row_entry *row_entry_pool;
-static int row_entry_pool_size;
+static ptrdiff_t row_entry_pool_size;
 
 /* Index of next free entry in row_entry_pool.  */
 
-static int row_entry_idx;
+static ptrdiff_t row_entry_idx;
 
 /* The hash table used during scrolling, and the table's size.  This
    table is used to quickly identify equal rows in the desired and
    current matrix.  */
 
 static struct row_entry **row_table;
-static int row_table_size;
+static ptrdiff_t row_table_size;
 
 /* Vectors of pointers to row_entry structures belonging to the
    current and desired matrix, and the size of the vectors.  */
 
 static struct row_entry **old_lines, **new_lines;
-static int old_lines_size, new_lines_size;
+static ptrdiff_t old_lines_size, new_lines_size;
 
 /* A pool to allocate run structures from, and its size.  */
 
 static struct run *run_pool;
-static int runs_size;
+static ptrdiff_t runs_size;
 
 /* A vector of runs of lines found during scrolling.  */
 
 static struct run **runs;
 
-/* Add glyph row ROW to the scrolling hash table during the scrolling
-   of window W.  */
+/* Add glyph row ROW to the scrolling hash table.  */
 
-static INLINE struct row_entry *
-add_row_entry (w, row)
-     struct window *w;
-     struct glyph_row *row;
+static inline struct row_entry *
+add_row_entry (struct glyph_row *row)
 {
   struct row_entry *entry;
-  int i = row->hash % row_table_size;
+  ptrdiff_t i = row->hash % row_table_size;
 
   entry = row_table[i];
-  while (entry && !row_equal_p (w, entry->row, row, 1))
+  eassert (entry || verify_row_hash (row));
+  while (entry && !row_equal_p (entry->row, row, 1))
     entry = entry->next;
 
   if (entry == NULL)
@@ -4956,15 +4242,15 @@ add_row_entry (w, row)
    1   if we did scroll.  */
 
 static int
-scrolling_window (w, header_line_p)
-     struct window *w;
-     int header_line_p;
+scrolling_window (struct window *w, int header_line_p)
 {
   struct glyph_matrix *desired_matrix = w->desired_matrix;
   struct glyph_matrix *current_matrix = w->current_matrix;
   int yb = window_text_bottom_y (w);
-  int i, j, first_old, first_new, last_old, last_new;
-  int nruns, nbytes, n, run_idx;
+  ptrdiff_t i;
+  int j, first_old, first_new, last_old, last_new;
+  int nruns, run_idx;
+  ptrdiff_t n;
   struct row_entry *entry;
   struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
 
@@ -4980,7 +4266,7 @@ scrolling_window (w, header_line_p)
          && c->y == d->y
          && MATRIX_ROW_BOTTOM_Y (c) <= yb
          && MATRIX_ROW_BOTTOM_Y (d) <= yb
-         && row_equal_p (w, c, d, 1))
+         && row_equal_p (c, d, 1))
        {
          assign_row (c, d);
          d->enabled_p = 0;
@@ -5035,12 +4321,11 @@ scrolling_window (w, header_line_p)
   j = last_old;
   while (i - 1 > first_new
          && j - 1 > first_old
-        && MATRIX_ROW (current_matrix, j - 1)->enabled_p
+         && MATRIX_ROW (current_matrix, j - 1)->enabled_p
         && (MATRIX_ROW (current_matrix, j - 1)->y
             == MATRIX_ROW (desired_matrix, i - 1)->y)
         && !MATRIX_ROW (desired_matrix, i - 1)->redraw_fringe_bitmaps_p
-         && row_equal_p (w,
-                        MATRIX_ROW (desired_matrix, i - 1),
+         && row_equal_p (MATRIX_ROW (desired_matrix, i - 1),
                          MATRIX_ROW (current_matrix, j - 1), 1))
     --i, --j;
   last_new = i;
@@ -5050,45 +4335,59 @@ scrolling_window (w, header_line_p)
   if (last_new == first_new)
     return 0;
 
+  /* Check for integer overflow in size calculation.
+
+     If next_almost_prime checks (N) for divisibility by 2..10, then
+     it can return at most N + 10, e.g., next_almost_prime (1) == 11.
+     So, set next_almost_prime_increment_max to 10.
+
+     It's just a coincidence that next_almost_prime_increment_max ==
+     NEXT_ALMOST_PRIME_LIMIT - 1.  If NEXT_ALMOST_PRIME_LIMIT were
+     13, then next_almost_prime_increment_max would be 14, e.g.,
+     because next_almost_prime (113) would be 127.  */
+  {
+    verify (NEXT_ALMOST_PRIME_LIMIT == 11);
+    enum { next_almost_prime_increment_max = 10 };
+    ptrdiff_t row_table_max =
+      (min (PTRDIFF_MAX, SIZE_MAX) / (3 * sizeof *row_table)
+       - next_almost_prime_increment_max);
+    ptrdiff_t current_nrows_max = row_table_max - desired_matrix->nrows;
+    if (current_nrows_max < current_matrix->nrows)
+      memory_full (SIZE_MAX);
+  }
+
   /* Reallocate vectors, tables etc. if necessary.  */
 
   if (current_matrix->nrows > old_lines_size)
-    {
-      old_lines_size = current_matrix->nrows;
-      nbytes = old_lines_size * sizeof *old_lines;
-      old_lines = (struct row_entry **) xrealloc (old_lines, nbytes);
-    }
+    old_lines = xpalloc (old_lines, &old_lines_size,
+                        current_matrix->nrows - old_lines_size,
+                        INT_MAX, sizeof *old_lines);
 
   if (desired_matrix->nrows > new_lines_size)
-    {
-      new_lines_size = desired_matrix->nrows;
-      nbytes = new_lines_size * sizeof *new_lines;
-      new_lines = (struct row_entry **) xrealloc (new_lines, nbytes);
-    }
+    new_lines = xpalloc (new_lines, &new_lines_size,
+                        desired_matrix->nrows - new_lines_size,
+                        INT_MAX, sizeof *new_lines);
 
-  n = desired_matrix->nrows + current_matrix->nrows;
-  if (3 * n > row_table_size)
+  n = desired_matrix->nrows;
+  n += current_matrix->nrows;
+  if (row_table_size < 3 * n)
     {
-      row_table_size = next_almost_prime (3 * n);
-      nbytes = row_table_size * sizeof *row_table;
-      row_table = (struct row_entry **) xrealloc (row_table, nbytes);
-      bzero (row_table, nbytes);
+      ptrdiff_t size = next_almost_prime (3 * n);
+      row_table = xnrealloc (row_table, size, sizeof *row_table);
+      row_table_size = size;
+      memset (row_table, 0, size * sizeof *row_table);
     }
 
   if (n > row_entry_pool_size)
-    {
-      row_entry_pool_size = n;
-      nbytes = row_entry_pool_size * sizeof *row_entry_pool;
-      row_entry_pool = (struct row_entry *) xrealloc (row_entry_pool, nbytes);
-    }
+    row_entry_pool = xpalloc (row_entry_pool, &row_entry_pool_size,
+                             n - row_entry_pool_size,
+                             -1, sizeof *row_entry_pool);
 
   if (desired_matrix->nrows > runs_size)
     {
+      runs = xnrealloc (runs, desired_matrix->nrows, sizeof *runs);
+      run_pool = xnrealloc (run_pool, desired_matrix->nrows, sizeof *run_pool);
       runs_size = desired_matrix->nrows;
-      nbytes = runs_size * sizeof *runs;
-      runs = (struct run **) xrealloc (runs, nbytes);
-      nbytes = runs_size * sizeof *run_pool;
-      run_pool = (struct run *) xrealloc (run_pool, nbytes);
     }
 
   nruns = run_idx = 0;
@@ -5101,7 +4400,7 @@ scrolling_window (w, header_line_p)
     {
       if (MATRIX_ROW (current_matrix, i)->enabled_p)
        {
-         entry = add_row_entry (w, MATRIX_ROW (current_matrix, i));
+         entry = add_row_entry (MATRIX_ROW (current_matrix, i));
          old_lines[i] = entry;
          ++entry->old_uses;
        }
@@ -5111,8 +4410,8 @@ scrolling_window (w, header_line_p)
 
   for (i = first_new; i < last_new; ++i)
     {
-      xassert (MATRIX_ROW_ENABLED_P (desired_matrix, i));
-      entry = add_row_entry (w, MATRIX_ROW (desired_matrix, i));
+      eassert (MATRIX_ROW_ENABLED_P (desired_matrix, i));
+      entry = add_row_entry (MATRIX_ROW (desired_matrix, i));
       ++entry->new_uses;
       entry->new_line_number = i;
       new_lines[i] = entry;
@@ -5125,7 +4424,7 @@ scrolling_window (w, header_line_p)
        && old_lines[i]->old_uses == 1
         && old_lines[i]->new_uses == 1)
       {
-       int j, k;
+       int p, q;
        int new_line = old_lines[i]->new_line_number;
        struct run *run = run_pool + run_idx++;
 
@@ -5138,33 +4437,33 @@ scrolling_window (w, header_line_p)
        run->height = MATRIX_ROW (current_matrix, i)->height;
 
        /* Extend backward.  */
-       j = i - 1;
-       k = new_line - 1;
-       while (j > first_old
-              && k > first_new
-              && old_lines[j] == new_lines[k])
+       p = i - 1;
+       q = new_line - 1;
+       while (p > first_old
+              && q > first_new
+              && old_lines[p] == new_lines[q])
          {
-           int h = MATRIX_ROW (current_matrix, j)->height;
+           int h = MATRIX_ROW (current_matrix, p)->height;
            --run->current_vpos;
            --run->desired_vpos;
            ++run->nrows;
            run->height += h;
            run->desired_y -= h;
            run->current_y -= h;
-           --j, --k;
+           --p, --q;
          }
 
        /* Extend forward.  */
-       j = i + 1;
-       k = new_line + 1;
-       while (j < last_old
-              && k < last_new
-              && old_lines[j] == new_lines[k])
+       p = i + 1;
+       q = new_line + 1;
+       while (p < last_old
+              && q < last_new
+              && old_lines[p] == new_lines[q])
          {
-           int h = MATRIX_ROW (current_matrix, j)->height;
+           int h = MATRIX_ROW (current_matrix, p)->height;
            ++run->nrows;
            run->height += h;
-           ++j, ++k;
+           ++p, ++q;
          }
 
        /* Insert run into list of all runs.  Order runs by copied
@@ -5172,11 +4471,11 @@ scrolling_window (w, header_line_p)
           be copied because they are already in place.  This is done
           because we can avoid calling update_window_line in this
           case.  */
-       for (j = 0; j < nruns && runs[j]->height > run->height; ++j)
+       for (p = 0; p < nruns && runs[p]->height > run->height; ++p)
          ;
-       for (k = nruns; k > j; --k)
-         runs[k] = runs[k - 1];
-       runs[j] = run;
+       for (q = nruns; q > p; --q)
+         runs[q] = runs[q - 1];
+       runs[p] = run;
        ++nruns;
 
        i += run->nrows;
@@ -5208,18 +4507,69 @@ scrolling_window (w, header_line_p)
          {
            rif->clear_window_mouse_face (w);
            rif->scroll_run_hook (w, r);
+         }
+
+       /* Truncate runs that copy to where we copied to, and
+          invalidate runs that copy from where we copied to.  */
+       for (j = nruns - 1; j > i; --j)
+         {
+           struct run *p = runs[j];
+           int truncated_p = 0;
 
-           /* Invalidate runs that copy from where we copied to.  */
-           for (j = i + 1; j < nruns; ++j)
+           if (p->nrows > 0
+               && p->desired_y < r->desired_y + r->height
+               && p->desired_y + p->height > r->desired_y)
              {
-               struct run *p = runs[j];
+               if (p->desired_y < r->desired_y)
+                 {
+                   p->nrows = r->desired_vpos - p->desired_vpos;
+                   p->height = r->desired_y - p->desired_y;
+                   truncated_p = 1;
+                 }
+               else
+                 {
+                   int nrows_copied = (r->desired_vpos + r->nrows
+                                       - p->desired_vpos);
+
+                   if (p->nrows <= nrows_copied)
+                     p->nrows = 0;
+                   else
+                     {
+                       int height_copied = (r->desired_y + r->height
+                                            - p->desired_y);
+
+                       p->current_vpos += nrows_copied;
+                       p->desired_vpos += nrows_copied;
+                       p->nrows -= nrows_copied;
+                       p->current_y += height_copied;
+                       p->desired_y += height_copied;
+                       p->height -= height_copied;
+                       truncated_p = 1;
+                     }
+                 }
+             }
 
-               if ((p->current_y >= r->desired_y
+           if (r->current_y != r->desired_y
+               /* The condition below is equivalent to
+                  ((p->current_y >= r->desired_y
                     && p->current_y < r->desired_y + r->height)
-                   || (p->current_y + p->height >= r->desired_y
+                   || (p->current_y + p->height > r->desired_y
                        && (p->current_y + p->height
-                           < r->desired_y + r->height)))
-                 p->nrows = 0;
+                           <= r->desired_y + r->height)))
+                  because we have 0 < p->height <= r->height.  */
+               && p->current_y < r->desired_y + r->height
+               && p->current_y + p->height > r->desired_y)
+             p->nrows = 0;
+
+           /* Reorder runs by copied pixel lines if truncated.  */
+           if (truncated_p && p->nrows > 0)
+             {
+               int k = nruns - 1;
+
+               while (runs[k]->nrows == 0 || runs[k]->height < p->height)
+                 k--;
+               memmove (runs + j, runs + j + 1, (k - j) * sizeof (*runs));
+               runs[k] = p;
              }
          }
 
@@ -5234,7 +4584,14 @@ scrolling_window (w, header_line_p)
            to_overlapped_p = to->overlapped_p;
            from->redraw_fringe_bitmaps_p = from->fringe_bitmap_periodic_p;
            assign_row (to, from);
-           to->enabled_p = 1, from->enabled_p = 0;
+           /* The above `assign_row' actually does swap, so if we had
+              an overlap in the copy destination of two runs, then
+              the second run would assign a previously disabled bogus
+              row.  But thanks to the truncation code in the
+              preceding for-loop, we no longer have such an overlap,
+              and thus the assigned row should always be enabled.  */
+           eassert (to->enabled_p);
+           from->enabled_p = 0;
            to->overlapped_p = to_overlapped_p;
          }
       }
@@ -5243,8 +4600,8 @@ scrolling_window (w, header_line_p)
   for (i = 0; i < row_entry_idx; ++i)
     row_table[row_entry_pool[i].bucket] = NULL;
 
-  /* Value is > 0 to indicate that we scrolled the display.  */
-  return nruns;
+  /* Value is 1 to indicate that we scrolled the display.  */
+  return 0 < nruns;
 }
 
 
@@ -5262,20 +4619,16 @@ scrolling_window (w, header_line_p)
    Value is non-zero if update was stopped due to pending input.  */
 
 static int
-update_frame_1 (f, force_p, inhibit_id_p)
-     struct frame *f;
-     int force_p;
-     int inhibit_id_p;
+update_frame_1 (struct frame *f, int force_p, int inhibit_id_p)
 {
   /* Frame matrices to work on.  */
   struct glyph_matrix *current_matrix = f->current_matrix;
   struct glyph_matrix *desired_matrix = f->desired_matrix;
   int i;
-  int pause;
+  int pause_p;
   int preempt_count = baud_rate / 2400 + 1;
-  extern int input_pending;
 
-  xassert (current_matrix && desired_matrix);
+  eassert (current_matrix && desired_matrix);
 
   if (baud_rate != FRAME_COST_BAUD_RATE (f))
     calculate_costs (f);
@@ -5286,7 +4639,7 @@ update_frame_1 (f, force_p, inhibit_id_p)
 #if !PERIODIC_PREEMPTION_CHECKING
   if (!force_p && detect_input_pending_ignore_squeezables ())
     {
-      pause = 1;
+      pause_p = 1;
       goto do_pause;
     }
 #endif
@@ -5347,12 +4700,10 @@ update_frame_1 (f, force_p, inhibit_id_p)
 #if PERIODIC_PREEMPTION_CHECKING
          if (!force_p)
            {
-             EMACS_TIME tm, dif;
-             EMACS_GET_TIME (tm);
-             EMACS_SUB_TIME (dif, preemption_next_check, tm);
-             if (EMACS_TIME_NEG_P (dif))
+             EMACS_TIME tm = current_emacs_time ();
+             if (EMACS_TIME_LT (preemption_next_check, tm))
                {
-                 EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
+                 preemption_next_check = add_emacs_time (tm, preemption_period);
                  if (detect_input_pending_ignore_squeezables ())
                    break;
                }
@@ -5366,10 +4717,10 @@ update_frame_1 (f, force_p, inhibit_id_p)
        }
     }
 
-  pause = (i < FRAME_LINES (f) - 1) ? i : 0;
+  pause_p = (i < FRAME_LINES (f) - 1) ? i : 0;
 
   /* Now just clean up termcap drivers and set cursor, etc.  */
-  if (!pause)
+  if (!pause_p)
     {
       if ((cursor_in_echo_area
           /* If we are showing a message instead of the mini-buffer,
@@ -5456,8 +4807,8 @@ update_frame_1 (f, force_p, inhibit_id_p)
              int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos);
              int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
 
-             if (INTEGERP (w->left_margin_cols))
-               x += XFASTINT (w->left_margin_cols);
+             if (INTEGERP (WVAR (w, left_margin_cols)))
+               x += XFASTINT (WVAR (w, left_margin_cols));
 
              /* x = max (min (x, FRAME_TOTAL_COLS (f) - 1), 0); */
              cursor_to (f, y, x);
@@ -5465,26 +4816,27 @@ update_frame_1 (f, force_p, inhibit_id_p)
        }
     }
 
+#if !PERIODIC_PREEMPTION_CHECKING
  do_pause:
+#endif
 
   clear_desired_matrices (f);
-  return pause;
+  return pause_p;
 }
 
 
 /* Do line insertions/deletions on frame F for frame-based redisplay.  */
 
-int
-scrolling (frame)
-     struct frame *frame;
+static int
+scrolling (struct frame *frame)
 {
   int unchanged_at_top, unchanged_at_bottom;
   int window_size;
   int changed_lines;
-  int *old_hash = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
-  int *new_hash = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
-  int *draw_cost = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
-  int *old_draw_cost = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
+  int *old_hash = alloca (FRAME_LINES (frame) * sizeof (int));
+  int *new_hash = alloca (FRAME_LINES (frame) * sizeof (int));
+  int *draw_cost = alloca (FRAME_LINES (frame) * sizeof (int));
+  int *old_draw_cost = alloca (FRAME_LINES (frame) * sizeof (int));
   register int i;
   int free_at_end_vpos = FRAME_LINES (frame);
   struct glyph_matrix *current_matrix = frame->current_matrix;
@@ -5570,9 +4922,7 @@ scrolling (frame)
    which is LEN glyphs long.  */
 
 static int
-count_blanks (r, len)
-     struct glyph *r;
-     int len;
+count_blanks (struct glyph *r, int len)
 {
   int i;
 
@@ -5589,8 +4939,7 @@ count_blanks (r, len)
    of STR2.  Value is the number of equal glyphs equal at the start.  */
 
 static int
-count_match (str1, end1, str2, end2)
-     struct glyph *str1, *end1, *str2, *end2;
+count_match (struct glyph *str1, struct glyph *end1, struct glyph *str2, struct glyph *end2)
 {
   struct glyph *p1 = str1;
   struct glyph *p2 = str2;
@@ -5606,16 +4955,13 @@ count_match (str1, end1, str2, end2)
 
 /* Char insertion/deletion cost vector, from term.c */
 
-extern int *char_ins_del_vector;
-#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_TOTAL_COLS((f))])
+#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_TOTAL_COLS ((f))])
 
 
 /* Perform a frame-based update on line VPOS in frame FRAME.  */
 
 static void
-update_frame_line (f, vpos)
-     struct frame *f;
-     int vpos;
+update_frame_line (struct frame *f, int vpos)
 {
   struct glyph *obody, *nbody, *op1, *op2, *np1, *nend;
   int tem;
@@ -5926,18 +5272,18 @@ update_frame_line (f, vpos)
  ***********************************************************************/
 
 /* Determine what's under window-relative pixel position (*X, *Y).
-   Return the object (string or buffer) that's there.
+   Return the OBJECT (string or buffer) that's there.
    Return in *POS the position in that object.
-   Adjust *X and *Y to character positions.  */
+   Adjust *X and *Y to character positions.
+   Return in *DX and *DY the pixel coordinates of the click,
+   relative to the top left corner of OBJECT, or relative to
+   the top left corner of the character glyph at (*X, *Y)
+   if OBJECT is nil.
+   Return WIDTH and HEIGHT of the object at (*X, *Y), or zero
+   if the coordinates point to an empty area of the display.  */
 
 Lisp_Object
-buffer_posn_from_coords (w, x, y, pos, object, dx, dy, width, height)
-     struct window *w;
-     int *x, *y;
-     struct display_pos *pos;
-     Lisp_Object *object;
-     int *dx, *dy;
-     int *width, *height;
+buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *pos, Lisp_Object *object, int *dx, int *dy, int *width, int *height)
 {
   struct it it;
   Lisp_Object old_current_buffer = Fcurrent_buffer ();
@@ -5947,29 +5293,78 @@ buffer_posn_from_coords (w, x, y, pos, object, dx, dy, width, height)
 #ifdef HAVE_WINDOW_SYSTEM
   struct image *img = 0;
 #endif
-  int x0, x1;
+  int x0, x1, to_x;
+  void *itdata = NULL;
 
   /* We used to set current_buffer directly here, but that does the
      wrong thing with `face-remapping-alist' (bug#2044).  */
-  Fset_buffer (w->buffer);
-  SET_TEXT_POS_FROM_MARKER (startp, w->start);
+  Fset_buffer (WVAR (w, buffer));
+  itdata = bidi_shelve_cache ();
+  SET_TEXT_POS_FROM_MARKER (startp, WVAR (w, start));
   CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp)));
   BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp)));
   start_display (&it, w, startp);
-
-  x0 = *x - WINDOW_LEFT_MARGIN_WIDTH (w);
-  move_it_to (&it, -1, x0 + it.first_visible_x, *y, -1,
-             MOVE_TO_X | MOVE_TO_Y);
+  /* start_display takes into account the header-line row, but IT's
+     vpos still counts from the glyph row that includes the window's
+     start position.  Adjust for a possible header-line row.  */
+  it.vpos += WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
+
+  x0 = *x;
+
+  /* First, move to the beginning of the row corresponding to *Y.  We
+     need to be in that row to get the correct value of base paragraph
+     direction for the text at (*X, *Y).  */
+  move_it_to (&it, -1, 0, *y, -1, MOVE_TO_X | MOVE_TO_Y);
+
+  /* TO_X is the pixel position that the iterator will compute for the
+     glyph at *X.  We add it.first_visible_x because iterator
+     positions include the hscroll.  */
+  to_x = x0 + it.first_visible_x;
+  if (it.bidi_it.paragraph_dir == R2L)
+    /* For lines in an R2L paragraph, we need to mirror TO_X wrt the
+       text area.  This is because the iterator, even in R2L
+       paragraphs, delivers glyphs as if they started at the left
+       margin of the window.  (When we actually produce glyphs for
+       display, we reverse their order in PRODUCE_GLYPHS, but the
+       iterator doesn't know about that.)  The following line adjusts
+       the pixel position to the iterator geometry, which is what
+       move_it_* routines use.  (The -1 is because in a window whose
+       text-area width is W, the rightmost pixel position is W-1, and
+       it should be mirrored into zero pixel position.)  */
+    to_x = window_box_width (w, TEXT_AREA) - to_x - 1;
+
+  /* Now move horizontally in the row to the glyph under *X.  Second
+     argument is ZV to prevent move_it_in_display_line from matching
+     based on buffer positions.  */
+  move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X);
+  bidi_unshelve_cache (itdata, 0);
 
   Fset_buffer (old_current_buffer);
 
   *dx = x0 + it.first_visible_x - it.current_x;
   *dy = *y - it.current_y;
 
-  string =  w->buffer;
+  string =  WVAR (w, buffer);
   if (STRINGP (it.string))
     string = it.string;
   *pos = it.current;
+  if (it.what == IT_COMPOSITION
+      && it.cmp_it.nchars > 1
+      && it.cmp_it.reversed_p)
+    {
+      /* The current display element is a grapheme cluster in a
+        composition.  In that case, we need the position of the first
+        character of the cluster.  But, as it.cmp_it.reversed_p is 1,
+        it.current points to the last character of the cluster, thus
+        we must move back to the first character of the same
+        cluster.  */
+      CHARPOS (pos->pos) -= it.cmp_it.nchars - 1;
+      if (STRINGP (it.string))
+       BYTEPOS (pos->pos) = string_char_to_byte (string, CHARPOS (pos->pos));
+      else
+       BYTEPOS (pos->pos) = buf_charpos_to_bytepos (XBUFFER (WVAR (w, buffer)),
+                                                    CHARPOS (pos->pos));
+    }
 
 #ifdef HAVE_WINDOW_SYSTEM
   if (it.what == IT_IMAGE)
@@ -5991,8 +5386,8 @@ buffer_posn_from_coords (w, x, y, pos, object, dx, dy, width, height)
          if (img)
            {
              *dy -= row->ascent - glyph->ascent;
-             *dx += glyph->slice.x;
-             *dy += glyph->slice.y;
+             *dx += glyph->slice.img.x;
+             *dy += glyph->slice.img.y;
              /* Image slices positions are still relative to the entire image */
              *width = img->width;
              *height = img->height;
@@ -6016,7 +5411,7 @@ buffer_posn_from_coords (w, x, y, pos, object, dx, dy, width, height)
     }
 
   /* Add extra (default width) columns if clicked after EOL. */
-  x1 = max(0, it.current_x + it.pixel_width - it.first_visible_x);
+  x1 = max (0, it.current_x + it.pixel_width - it.first_visible_x);
   if (x0 > x1)
     it.hpos += (x0 - x1) / WINDOW_FRAME_COLUMN_WIDTH (w);
 
@@ -6032,14 +5427,9 @@ buffer_posn_from_coords (w, x, y, pos, object, dx, dy, width, height)
    *CHARPOS is set to the position in the string returned.  */
 
 Lisp_Object
-mode_line_string (w, part, x, y, charpos, object, dx, dy, width, height)
-     struct window *w;
-     enum window_part part;
-     int *x, *y;
-     int *charpos;
-     Lisp_Object *object;
-     int *dx, *dy;
-     int *width, *height;
+mode_line_string (struct window *w, enum window_part part,
+                 int *x, int *y, ptrdiff_t *charpos, Lisp_Object *object,
+                 int *dx, int *dy, int *width, int *height)
 {
   struct glyph_row *row;
   struct glyph *glyph, *end;
@@ -6106,14 +5496,9 @@ mode_line_string (w, part, x, y, charpos, object, dx, dy, width, height)
    the string returned.  */
 
 Lisp_Object
-marginal_area_string (w, part, x, y, charpos, object, dx, dy, width, height)
-     struct window *w;
-     enum window_part part;
-     int *x, *y;
-     int *charpos;
-     Lisp_Object *object;
-     int *dx, *dy;
-     int *width, *height;
+marginal_area_string (struct window *w, enum window_part part,
+                     int *x, int *y, ptrdiff_t *charpos, Lisp_Object *object,
+                     int *dx, int *dy, int *width, int *height)
 {
   struct glyph_row *row = w->current_matrix->rows;
   struct glyph *glyph, *end;
@@ -6168,8 +5553,8 @@ marginal_area_string (w, part, x, y, charpos, object, dx, dy, width, height)
              if (img != NULL)
                *object = img->spec;
              y0 -= row->ascent - glyph->ascent;
-             x0 += glyph->slice.x;
-             y0 += glyph->slice.y;
+             x0 += glyph->slice.img.x;
+             y0 += glyph->slice.img.y;
            }
 #endif
        }
@@ -6201,14 +5586,11 @@ marginal_area_string (w, part, x, y, charpos, object, dx, dy, width, height)
 
 #ifdef SIGWINCH
 
-SIGTYPE
-window_change_signal (signalnum) /* If we don't have an argument, */
-     int signalnum;            /* some compilers complain in signal calls.  */
+static void
+window_change_signal (int signalnum) /* If we don't have an argument, */
+                               /* some compilers complain in signal calls.  */
 {
   int width, height;
-#ifndef USE_CRT_DLL
-  extern int errno;
-#endif
   int old_errno = errno;
 
   struct tty_display_info *tty;
@@ -6254,8 +5636,7 @@ window_change_signal (signalnum) /* If we don't have an argument, */
    safe to change frame sizes  while a redisplay is in progress.  */
 
 void
-do_pending_window_change (safe)
-     int safe;
+do_pending_window_change (int safe)
 {
   /* If window_change_signal should have run before, run it now.  */
   if (redisplaying_p && !safe)
@@ -6291,9 +5672,7 @@ do_pending_window_change (safe)
    safe to change frame sizes while a redisplay is in progress.  */
 
 void
-change_frame_size (f, newheight, newwidth, pretend, delay, safe)
-     register struct frame *f;
-     int newheight, newwidth, pretend, delay, safe;
+change_frame_size (register struct frame *f, int newheight, int newwidth, int pretend, int delay, int safe)
 {
   Lisp_Object tail, frame;
 
@@ -6312,12 +5691,10 @@ change_frame_size (f, newheight, newwidth, pretend, delay, safe)
 }
 
 static void
-change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe)
-     register struct frame *f;
-     int newheight, newwidth, pretend, delay, safe;
+change_frame_size_1 (register struct frame *f, int newheight, int newwidth, int pretend, int delay, int safe)
 {
   int new_frame_total_cols;
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
 
   /* If we can't deal with the change now, queue it for later.  */
   if (delay || (redisplaying_p && !safe))
@@ -6338,19 +5715,22 @@ change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe)
   if (newwidth == 0)
     newwidth  = FRAME_COLS  (f);
 
-  /* Compute width of windows in F.
-     This is the width of the frame without vertical scroll bars.  */
-  new_frame_total_cols = FRAME_TOTAL_COLS_ARG (f, newwidth);
-
+  /* Compute width of windows in F.  */
   /* Round up to the smallest acceptable size.  */
   check_frame_size (f, &newheight, &newwidth);
 
+  /* This is the width of the frame with vertical scroll bars and fringe
+     columns.  Do this after rounding - see discussion of bug#9723.  */
+  new_frame_total_cols = FRAME_TOTAL_COLS_ARG (f, newwidth);
+
   /* If we're not changing the frame size, quit now.  */
-  /* Frame width may be unchanged but the text portion may change, for example,
-     fullscreen and remove/add scroll bar.  */
+  /* Frame width may be unchanged but the text portion may change, for
+     example, fullscreen and remove/add scroll bar.  */
   if (newheight == FRAME_LINES (f)
-      && newwidth == FRAME_COLS  (f) // text portion unchanged
-      && new_frame_total_cols == FRAME_TOTAL_COLS (f)) // frame width unchanged
+      /* Text portion unchanged?  */
+      && newwidth == FRAME_COLS  (f)
+      /* Frame width unchanged?  */
+      && new_frame_total_cols == FRAME_TOTAL_COLS (f))
     return;
 
   BLOCK_INPUT;
@@ -6364,24 +5744,7 @@ change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe)
 
   if (newheight != FRAME_LINES (f))
     {
-      if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
-       {
-         /* Frame has both root and mini-buffer.  */
-         XSETFASTINT (XWINDOW (FRAME_ROOT_WINDOW (f))->top_line,
-                      FRAME_TOP_MARGIN (f));
-         set_window_height (FRAME_ROOT_WINDOW (f),
-                            (newheight
-                             - 1
-                             - FRAME_TOP_MARGIN (f)),
-                            2);
-         XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top_line,
-                      newheight - 1);
-         set_window_height (FRAME_MINIBUF_WINDOW (f), 1, 0);
-       }
-      else
-       /* Frame has just one top-level window.  */
-       set_window_height (FRAME_ROOT_WINDOW (f),
-                          newheight - FRAME_TOP_MARGIN (f), 2);
+      resize_frame_windows (f, newheight, 0);
 
       /* MSDOS frames cannot PRETEND, as they change frame size by
         manipulating video hardware.  */
@@ -6391,17 +5754,15 @@ change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe)
 
   if (new_frame_total_cols != FRAME_TOTAL_COLS (f))
     {
-      set_window_width (FRAME_ROOT_WINDOW (f), new_frame_total_cols, 2);
-      if (FRAME_HAS_MINIBUF_P (f))
-       set_window_width (FRAME_MINIBUF_WINDOW (f), new_frame_total_cols, 0);
+      resize_frame_windows (f, new_frame_total_cols, 1);
 
       /* MSDOS frames cannot PRETEND, as they change frame size by
         manipulating video hardware.  */
       if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
        FrameCols (FRAME_TTY (f)) = newwidth;
 
-      if (WINDOWP (f->tool_bar_window))
-       XSETFASTINT (XWINDOW (f->tool_bar_window)->total_cols, newwidth);
+      if (WINDOWP (FVAR (f, tool_bar_window)))
+       XSETFASTINT (WVAR (XWINDOW (FVAR (f, tool_bar_window)), total_cols), newwidth);
     }
 
   FRAME_LINES (f) = newheight;
@@ -6443,8 +5804,7 @@ DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript,
        1, 1, "FOpen termscript file: ",
        doc: /* Start writing all terminal output to FILE as well as the terminal.
 FILE = nil means just close any termscript file currently open.  */)
-     (file)
-     Lisp_Object file;
+  (Lisp_Object file)
 {
   struct tty_display_info *tty;
 
@@ -6465,7 +5825,7 @@ FILE = nil means just close any termscript file currently open.  */)
   if (! NILP (file))
     {
       file = Fexpand_file_name (file, Qnil);
-      tty->termscript = fopen (SDATA (file), "w");
+      tty->termscript = fopen (SSDATA (file), "w");
       if (tty->termscript == 0)
        report_file_error ("Opening termscript", Fcons (file, Qnil));
     }
@@ -6482,9 +5842,7 @@ Optional parameter TERMINAL specifies the tty terminal device to use.
 It may be a terminal object, a frame, or nil for the terminal used by
 the currently selected frame.  In batch mode, STRING is sent to stdout
 when TERMINAL is nil.  */)
-  (string, terminal)
-     Lisp_Object string;
-     Lisp_Object terminal;
+  (Lisp_Object string, Lisp_Object terminal)
 {
   struct terminal *t = get_terminal (terminal, 1);
   FILE *out;
@@ -6525,8 +5883,7 @@ DEFUN ("ding", Fding, Sding, 0, 1, 0,
        doc: /* Beep, or flash the screen.
 Also, unless an argument is given,
 terminate any keyboard macro currently executing.  */)
-     (arg)
-  Lisp_Object arg;
+  (Lisp_Object arg)
 {
   if (!NILP (arg))
     {
@@ -6542,7 +5899,7 @@ terminate any keyboard macro currently executing.  */)
 }
 
 void
-bitch_at_user ()
+bitch_at_user (void)
 {
   if (noninteractive)
     putchar (07);
@@ -6562,47 +5919,24 @@ DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0,
        doc: /* Pause, without updating display, for SECONDS seconds.
 SECONDS may be a floating-point value, meaning that you can wait for a
 fraction of a second.  Optional second arg MILLISECONDS specifies an
-additional wait period, in milliseconds; this may be useful if your
-Emacs was built without floating point support.
+additional wait period, in milliseconds; this is for backwards compatibility.
 \(Not all operating systems support waiting for a fraction of a second.)  */)
-     (seconds, milliseconds)
-     Lisp_Object seconds, milliseconds;
+  (Lisp_Object seconds, Lisp_Object milliseconds)
 {
-  int sec, usec;
-
-  if (NILP (milliseconds))
-    XSETINT (milliseconds, 0);
-  else
-    CHECK_NUMBER (milliseconds);
-  usec = XINT (milliseconds) * 1000;
-
-  {
-    double duration = extract_float (seconds);
-    sec = (int) duration;
-    usec += (duration - sec) * 1000000;
-  }
-
-#ifndef EMACS_HAS_USECS
-  if (sec == 0 && usec != 0)
-    error ("Millisecond `sleep-for' not supported on %s", SYSTEM_TYPE);
-#endif
+  double duration = extract_float (seconds);
 
-  /* Assure that 0 <= usec < 1000000.  */
-  if (usec < 0)
+  if (!NILP (milliseconds))
     {
-      /* We can't rely on the rounding being correct if usec is negative.  */
-      if (-1000000 < usec)
-       sec--, usec += 1000000;
-      else
-       sec -= -usec / 1000000, usec = 1000000 - (-usec % 1000000);
+      CHECK_NUMBER (milliseconds);
+      duration += XINT (milliseconds) / 1000.0;
     }
-  else
-    sec += usec / 1000000, usec %= 1000000;
-
-  if (sec < 0 || (sec == 0 && usec == 0))
-    return Qnil;
 
-  wait_reading_process_output (sec, usec, 0, 0, Qnil, NULL, 0);
+  if (0 < duration)
+    {
+      EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (duration);
+      wait_reading_process_output (min (EMACS_SECS (t), WAIT_READING_MAX),
+                                  EMACS_NSECS (t), 0, 0, Qnil, NULL, 0);
+    }
 
   return Qnil;
 }
@@ -6619,11 +5953,10 @@ Emacs was built without floating point support.
 */
 
 Lisp_Object
-sit_for (timeout, reading, do_display)
-     Lisp_Object timeout;
-     int reading, do_display;
+sit_for (Lisp_Object timeout, int reading, int do_display)
 {
-  int sec, usec;
+  intmax_t sec;
+  int nsec;
 
   swallow_events (do_display);
 
@@ -6637,30 +5970,36 @@ sit_for (timeout, reading, do_display)
   if (INTEGERP (timeout))
     {
       sec = XINT (timeout);
-      usec = 0;
+      if (! (0 < sec))
+       return Qt;
+      nsec = 0;
     }
   else if (FLOATP (timeout))
     {
       double seconds = XFLOAT_DATA (timeout);
-      sec = (int) seconds;
-      usec = (int) ((seconds - sec) * 1000000);
+      if (! (0 < seconds))
+       return Qt;
+      else
+       {
+         EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (seconds);
+         sec = min (EMACS_SECS (t), WAIT_READING_MAX);
+         nsec = EMACS_NSECS (t);
+       }
     }
   else if (EQ (timeout, Qt))
     {
       sec = 0;
-      usec = 0;
+      nsec = 0;
     }
   else
     wrong_type_argument (Qnumberp, timeout);
 
-  if (sec == 0 && usec == 0 && !EQ (timeout, Qt))
-    return Qt;
 
 #ifdef SIGIO
   gobble_input (0);
 #endif
 
-  wait_reading_process_output (sec, usec, reading ? -1 : 1, do_display,
+  wait_reading_process_output (sec, nsec, reading ? -1 : 1, do_display,
                               Qnil, NULL, 0);
 
   return detect_input_pending () ? Qnil : Qt;
@@ -6668,14 +6007,17 @@ sit_for (timeout, reading, do_display)
 
 
 DEFUN ("redisplay", Fredisplay, Sredisplay, 0, 1, 0,
-       doc: /* Perform redisplay if no input is available.
-If optional arg FORCE is non-nil or `redisplay-dont-pause' is non-nil,
-perform a full redisplay even if input is available.
-Return t if redisplay was performed, nil otherwise.  */)
-     (force)
-  Lisp_Object force;
+       doc: /* Perform redisplay.
+Optional arg FORCE, if non-nil, prevents redisplay from being
+preempted by arriving input, even if `redisplay-dont-pause' is nil.
+If `redisplay-dont-pause' is non-nil (the default), redisplay is never
+preempted by arriving input, so FORCE does nothing.
+
+Return t if redisplay was performed, nil if redisplay was preempted
+immediately by pending input.  */)
+  (Lisp_Object force)
 {
-  int count;
+  ptrdiff_t count;
 
   swallow_events (1);
   if ((detect_input_pending_run_timers (1)
@@ -6717,12 +6059,11 @@ the current state.
 
 If VARIABLE is nil, an internal variable is used.  Users should not
 pass nil for VARIABLE.  */)
-     (variable)
-     Lisp_Object variable;
+  (Lisp_Object variable)
 {
   Lisp_Object state, tail, frame, buf;
   Lisp_Object *vecp, *end;
-  int n;
+  ptrdiff_t n;
 
   if (! NILP (variable))
     {
@@ -6735,7 +6076,7 @@ pass nil for VARIABLE.  */)
     state = frame_and_buffer_state;
 
   vecp = XVECTOR (state)->contents;
-  end = vecp + XVECTOR_SIZE (state);
+  end = vecp + ASIZE (state);
 
   FOR_EACH_FRAME (tail, frame)
     {
@@ -6745,7 +6086,7 @@ pass nil for VARIABLE.  */)
        goto changed;
       if (vecp == end)
        goto changed;
-      if (!EQ (*vecp++, XFRAME (frame)->name))
+      if (!EQ (*vecp++, FVAR (XFRAME (frame), name)))
        goto changed;
     }
   /* Check that the buffer info matches.  */
@@ -6753,7 +6094,7 @@ pass nil for VARIABLE.  */)
     {
       buf = XCDR (XCAR (tail));
       /* Ignore buffers that aren't included in buffer lists.  */
-      if (SREF (XBUFFER (buf)->name, 0) == ' ')
+      if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ')
        continue;
       if (vecp == end)
        goto changed;
@@ -6761,7 +6102,7 @@ pass nil for VARIABLE.  */)
        goto changed;
       if (vecp == end)
        goto changed;
-      if (!EQ (*vecp++, XBUFFER (buf)->read_only))
+      if (!EQ (*vecp++, BVAR (XBUFFER (buf), read_only)))
        goto changed;
       if (vecp == end)
        goto changed;
@@ -6786,8 +6127,8 @@ pass nil for VARIABLE.  */)
   /* Reallocate the vector if data has grown to need it,
      or if it has shrunk a lot.  */
   if (! VECTORP (state)
-      || n > XVECTOR_SIZE (state)
-      || n + 20 < XVECTOR_SIZE (state) / 2)
+      || n > ASIZE (state)
+      || n + 20 < ASIZE (state) / 2)
     /* Add 20 extra so we grow it less often.  */
     {
       state = Fmake_vector (make_number (n + 20), Qlambda);
@@ -6802,26 +6143,26 @@ pass nil for VARIABLE.  */)
   FOR_EACH_FRAME (tail, frame)
     {
       *vecp++ = frame;
-      *vecp++ = XFRAME (frame)->name;
+      *vecp++ = FVAR (XFRAME (frame), name);
     }
   for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
     {
       buf = XCDR (XCAR (tail));
       /* Ignore buffers that aren't included in buffer lists.  */
-      if (SREF (XBUFFER (buf)->name, 0) == ' ')
+      if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ')
        continue;
       *vecp++ = buf;
-      *vecp++ = XBUFFER (buf)->read_only;
+      *vecp++ = BVAR (XBUFFER (buf), read_only);
       *vecp++ = Fbuffer_modified_p (buf);
     }
   /* Fill up the vector with lambdas (always at least one).  */
   *vecp++ = Qlambda;
   while (vecp - XVECTOR (state)->contents
-        < XVECTOR_SIZE (state))
+        < ASIZE (state))
     *vecp++ = Qlambda;
   /* Make sure we didn't overflow the vector.  */
   if (vecp - XVECTOR (state)->contents
-      > XVECTOR_SIZE (state))
+      > ASIZE (state))
     abort ();
   return Qt;
 }
@@ -6837,14 +6178,10 @@ pass nil for VARIABLE.  */)
    decoding routine to set up variables in the terminal package.  */
 
 void
-init_display ()
+init_display (void)
 {
   char *terminal_type;
 
-#ifdef HAVE_X_WINDOWS
-  extern int display_arg;
-#endif
-
   /* Construct the space glyph.  */
   space_glyph.type = CHAR_GLYPH;
   SET_CHAR_GLYPH (space_glyph, ' ', DEFAULT_FACE_ID, 0);
@@ -6895,17 +6232,13 @@ init_display ()
        }
     }
 
-  if (!inhibit_window_system && display_arg
-#ifndef CANNOT_DUMP
-     && initialized
-#endif
-     )
+  if (!inhibit_window_system && display_arg)
     {
       Vinitial_window_system = Qx;
 #ifdef HAVE_X11
       Vwindow_system_version = make_number (11);
 #endif
-#if defined (GNU_LINUX) && defined (HAVE_LIBNCURSES)
+#ifdef GNU_LINUX
       /* In some versions of ncurses,
         tputs crashes if we have not called tgetent.
         So call tgetent.  */
@@ -6934,7 +6267,7 @@ init_display ()
       )
     {
       Vinitial_window_system = Qns;
-      Vwindow_system_version = make_number(10);
+      Vwindow_system_version = make_number (10);
       adjust_frame_glyphs_initially ();
       return;
     }
@@ -6978,6 +6311,12 @@ init_display ()
     f->terminal = t;
 
     t->reference_count++;
+#ifdef MSDOS
+    f->output_data.tty->display_info = &the_only_display_info;
+#else
+    if (f->output_method == output_termcap)
+      create_tty_output (f);
+#endif
     t->display_info.tty->top_frame = selected_frame;
     change_frame_size (XFRAME (selected_frame),
                        FrameRows (t->display_info.tty),
@@ -7006,11 +6345,14 @@ init_display ()
     int width = FRAME_TOTAL_COLS (sf);
     int height = FRAME_LINES (sf);
 
-    unsigned int total_glyphs = height * (width + 2) * sizeof (struct glyph);
-
     /* If these sizes are so big they cause overflow, just ignore the
-       change.  It's not clear what better we could do.  */
-    if (total_glyphs / sizeof (struct glyph) / height != width + 2)
+       change.  It's not clear what better we could do.  The rest of
+       the code assumes that (width + 2) * height * sizeof (struct glyph)
+       does not overflow and does not exceed PTRDIFF_MAX or SIZE_MAX.  */
+    if (INT_ADD_RANGE_OVERFLOW (width, 2, INT_MIN, INT_MAX)
+       || INT_MULTIPLY_RANGE_OVERFLOW (width + 2, height, INT_MIN, INT_MAX)
+       || (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph)
+           < (width + 2) * height))
       fatal ("screen size %dx%d too big", width, height);
   }
 
@@ -7024,7 +6366,7 @@ init_display ()
     {
       /* For the initial frame, we don't have any way of knowing what
         are the foreground and background colors of the terminal.  */
-      struct frame *sf = SELECTED_FRAME();
+      struct frame *sf = SELECTED_FRAME ();
 
       FRAME_FOREGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_FG_COLOR;
       FRAME_BACKGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_BG_COLOR;
@@ -7044,8 +6386,7 @@ DEFUN ("internal-show-cursor", Finternal_show_cursor,
 WINDOW nil means use the selected window.  SHOW non-nil means
 show a cursor in WINDOW in the next redisplay.  SHOW nil means
 don't show a cursor.  */)
-     (window, show)
-     Lisp_Object window, show;
+  (Lisp_Object window, Lisp_Object show)
 {
   /* Don't change cursor state while redisplaying.  This could confuse
      output routines.  */
@@ -7067,8 +6408,7 @@ DEFUN ("internal-show-cursor-p", Finternal_show_cursor_p,
        Sinternal_show_cursor_p, 0, 1, 0,
        doc: /* Value is non-nil if next redisplay will display a cursor in WINDOW.
 WINDOW nil or omitted means report on the selected window.  */)
-     (window)
-     Lisp_Object window;
+  (Lisp_Object window)
 {
   struct window *w;
 
@@ -7084,7 +6424,7 @@ WINDOW nil or omitted means report on the selected window.  */)
 DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
        Slast_nonminibuf_frame, 0, 0, 0,
        doc: /* Value is last nonminibuffer frame. */)
-     ()
+  (void)
 {
   Lisp_Object frame = Qnil;
 
@@ -7099,7 +6439,7 @@ DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
  ***********************************************************************/
 
 void
-syms_of_display ()
+syms_of_display (void)
 {
   defsubr (&Sredraw_frame);
   defsubr (&Sredraw_display);
@@ -7113,39 +6453,37 @@ syms_of_display ()
   defsubr (&Sinternal_show_cursor_p);
   defsubr (&Slast_nonminibuf_frame);
 
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
   defsubr (&Sdump_redisplay_history);
 #endif
 
   frame_and_buffer_state = Fmake_vector (make_number (20), Qlambda);
   staticpro (&frame_and_buffer_state);
 
-  Qdisplay_table = intern_c_string ("display-table");
-  staticpro (&Qdisplay_table);
-  Qredisplay_dont_pause = intern_c_string ("redisplay-dont-pause");
-  staticpro (&Qredisplay_dont_pause);
+  DEFSYM (Qdisplay_table, "display-table");
+  DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause");
 
-  DEFVAR_INT ("baud-rate", &baud_rate,
-             doc: /* *The output baud rate of the terminal.
+  DEFVAR_INT ("baud-rate", baud_rate,
+             doc: /* The output baud rate of the terminal.
 On most systems, changing this value will affect the amount of padding
 and the other strategic decisions made during redisplay.  */);
 
-  DEFVAR_BOOL ("inverse-video", &inverse_video,
-              doc: /* *Non-nil means invert the entire frame display.
+  DEFVAR_BOOL ("inverse-video", inverse_video,
+              doc: /* Non-nil means invert the entire frame display.
 This means everything is in inverse video which otherwise would not be.  */);
 
-  DEFVAR_BOOL ("visible-bell", &visible_bell,
-              doc: /* *Non-nil means try to flash the frame to represent a bell.
+  DEFVAR_BOOL ("visible-bell", visible_bell,
+              doc: /* Non-nil means try to flash the frame to represent a bell.
 
 See also `ring-bell-function'.  */);
 
-  DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter,
-              doc: /* *Non-nil means no need to redraw entire frame after suspending.
+  DEFVAR_BOOL ("no-redraw-on-reenter", no_redraw_on_reenter,
+              doc: /* Non-nil means no need to redraw entire frame after suspending.
 A non-nil value is useful if the terminal can automatically preserve
 Emacs's frame display when you reenter Emacs.
 It is up to you to set this variable if your terminal can do that.  */);
 
-  DEFVAR_LISP ("initial-window-system", &Vinitial_window_system,
+  DEFVAR_LISP ("initial-window-system", Vinitial_window_system,
               doc: /* Name of the window system that Emacs uses for the first frame.
 The value is a symbol:
  nil for a termcap frame (a character-only terminal),
@@ -7171,14 +6509,14 @@ Use of this variable as a boolean is deprecated.  Instead,
 use `display-graphic-p' or any of the other `display-*-p'
 predicates which report frame's specific UI-related capabilities.  */);
 
-  DEFVAR_LISP ("window-system-version", &Vwindow_system_version,
+  DEFVAR_LISP ("window-system-version", Vwindow_system_version,
               doc: /* The version number of the window system in use.
 For X windows, this is 11.  */);
 
-  DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area,
+  DEFVAR_BOOL ("cursor-in-echo-area", cursor_in_echo_area,
               doc: /* Non-nil means put cursor in minibuffer, at end of any message there.  */);
 
-  DEFVAR_LISP ("glyph-table", &Vglyph_table,
+  DEFVAR_LISP ("glyph-table", Vglyph_table,
               doc: /* Table defining how to output a glyph code to the frame.
 If not nil, this is a vector indexed by glyph code to define the glyph.
 Each element can be:
@@ -7189,20 +6527,21 @@ Each element can be:
     while outputting it.  */);
   Vglyph_table = Qnil;
 
-  DEFVAR_LISP ("standard-display-table", &Vstandard_display_table,
+  DEFVAR_LISP ("standard-display-table", Vstandard_display_table,
               doc: /* Display table to use for buffers that specify none.
 See `buffer-display-table' for more information.  */);
   Vstandard_display_table = Qnil;
 
-  DEFVAR_BOOL ("redisplay-dont-pause", &redisplay_dont_pause,
-              doc: /* *Non-nil means update isn't paused when input is detected.  */);
-  redisplay_dont_pause = 0;
+  DEFVAR_BOOL ("redisplay-dont-pause", redisplay_dont_pause,
+              doc: /* Non-nil means display update isn't paused when input is detected.  */);
+  redisplay_dont_pause = 1;
 
 #if PERIODIC_PREEMPTION_CHECKING
-  DEFVAR_LISP ("redisplay-preemption-period", &Vredisplay_preemption_period,
-              doc: /* *The period in seconds between checking for input during redisplay.
-If input is detected, redisplay is pre-empted, and the input is processed.
-If nil, never pre-empt redisplay.  */);
+  DEFVAR_LISP ("redisplay-preemption-period", Vredisplay_preemption_period,
+              doc: /* Period in seconds between checking for input during redisplay.
+This has an effect only if `redisplay-dont-pause' is nil; in that
+case, arriving input preempts redisplay until the input is processed.
+If the value is nil, redisplay is never preempted.  */);
   Vredisplay_preemption_period = make_float (0.10);
 #endif
 
@@ -7214,6 +6553,3 @@ If nil, never pre-empt redisplay.  */);
       Vwindow_system_version = Qnil;
     }
 }
-
-/* arch-tag: 8d812b1f-04a2-4195-a9c4-381f8457a413
-   (do not change this comment) */