* dispnew.c (init_display): Use *_RANGE_OVERFLOW macros.
[bpt/emacs.git] / src / dispnew.c
index 1aef70f..d52bbdf 100644 (file)
@@ -103,58 +103,25 @@ struct dim
 \f
 /* Function prototypes.  */
 
-static struct glyph_matrix *save_current_matrix (struct frame *);
-static void restore_current_matrix (struct frame *, struct glyph_matrix *);
-static int showing_window_margins_p (struct window *);
-static void fake_current_matrices (Lisp_Object);
-static void redraw_overlapping_rows (struct window *, int);
-static void redraw_overlapped_rows (struct window *, int);
-static int count_blanks (struct glyph *, int);
-static int count_match (struct glyph *, struct glyph *,
-                        struct glyph *, struct glyph *);
-static unsigned line_draw_cost (struct glyph_matrix *, int);
 static void update_frame_line (struct frame *, int);
-static struct dim allocate_matrices_for_frame_redisplay
-     (Lisp_Object, int, int, int, int *);
 static int required_matrix_height (struct window *);
 static int required_matrix_width (struct window *);
-static void allocate_matrices_for_window_redisplay (struct window *);
-static int realloc_glyph_pool (struct glyph_pool *, struct dim);
 static void adjust_frame_glyphs (struct frame *);
-struct glyph_matrix *new_glyph_matrix (struct glyph_pool *);
-static void free_glyph_matrix (struct glyph_matrix *);
-static void adjust_glyph_matrix (struct window *, struct glyph_matrix *,
-                                 int, int, struct dim);
 static void change_frame_size_1 (struct frame *, int, int, int, int, int);
-static void swap_glyph_pointers (struct glyph_row *, struct glyph_row *);
-#if GLYPH_DEBUG
-static int glyph_row_slice_p (struct glyph_row *, struct glyph_row *);
-#endif
+static void increment_row_positions (struct glyph_row *, EMACS_INT, EMACS_INT);
 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 struct glyph_pool *new_glyph_pool (void);
-static void free_glyph_pool (struct glyph_pool *);
-static void adjust_frame_glyphs_initially (void);
 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 build_frame_matrix (struct frame *);
-void clear_current_matrices (struct frame *);
-void scroll_glyph_matrix_range (struct glyph_matrix *, int, int,
-                                int, int);
 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 update_marginal_area (struct window *, int, int);
-static int update_text_area (struct window *, int);
-static void make_current (struct glyph_matrix *, struct glyph_matrix *,
-                          int);
 static void mirror_make_current (struct window *, int);
-void check_window_matrix_pointers (struct window *);
 #if GLYPH_DEBUG
 static void check_matrix_pointers (struct glyph_matrix *,
                                    struct glyph_matrix *);
@@ -163,6 +130,7 @@ 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 *);
@@ -212,7 +180,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.  */
 
@@ -234,8 +202,8 @@ struct glyph space_glyph;
 /* 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.  */
@@ -285,10 +253,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 (struct frame *, int);
-static void add_window_display_history (struct window *, char *, 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
@@ -296,7 +263,7 @@ static void add_window_display_history (struct window *, char *, int);
    has been interrupted for pending input.  */
 
 static void
-add_window_display_history (struct window *w, char *msg, int paused_p)
+add_window_display_history (struct window *w, const char *msg, int paused_p)
 {
   char *buf;
 
@@ -305,12 +272,12 @@ add_window_display_history (struct window *w, char *msg, int paused_p)
   buf = redisplay_history[history_idx].trace;
   ++history_idx;
 
-  sprintf (buf, "%d: window %p (`%s')%s\n",
+  sprintf (buf, "%"pMu": window %p (`%s')%s\n",
           history_tick++,
           w,
           ((BUFFERP (w->buffer)
-            && STRINGP (XBUFFER (w->buffer)->name))
-           ? SSDATA (XBUFFER (w->buffer)->name)
+            && STRINGP (BVAR (XBUFFER (w->buffer), name)))
+           ? SSDATA (BVAR (XBUFFER (w->buffer), name))
            : "???"),
           paused_p ? " ***paused***" : "");
   strcat (buf, msg);
@@ -331,7 +298,7 @@ add_frame_display_history (struct frame *f, int 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***" : "");
 }
@@ -383,7 +350,7 @@ safe_bcopy (const char *from, char *to, int size)
    member `pool' of the glyph matrix structure returned is set to
    POOL, the structure is otherwise zeroed.  */
 
-struct glyph_matrix *
+static struct glyph_matrix *
 new_glyph_matrix (struct glyph_pool *pool)
 {
   struct glyph_matrix *result;
@@ -532,7 +499,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
   /* Enlarge MATRIX->rows if necessary.  New rows are cleared.  */
   if (matrix->rows_allocated < dim.height)
     {
-      int size = dim.height * sizeof (struct glyph_row);
+      ptrdiff_t size = dim.height * sizeof (struct glyph_row);
       new_rows = dim.height - matrix->rows_allocated;
       matrix->rows = (struct glyph_row *) xrealloc (matrix->rows, size);
       memset (matrix->rows + matrix->rows_allocated, 0,
@@ -859,6 +826,8 @@ shift_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int start, in
        row->visible_height -= min_y - row->y;
       if (row->y + row->height > max_y)
        row->visible_height -= row->y + row->height - max_y;
+      if (row->fringe_bitmap_periodic_p)
+       row->redraw_fringe_bitmaps_p = 1;
     }
 }
 
@@ -1021,7 +990,7 @@ blank_row (struct window *w, struct glyph_row *row, int y)
    the used count of the text area is zero.  Such rows display line
    ends.  */
 
-void
+static void
 increment_row_positions (struct glyph_row *row,
                         EMACS_INT delta, EMACS_INT delta_bytes)
 {
@@ -1060,8 +1029,7 @@ increment_row_positions (struct glyph_row *row,
    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;
 
@@ -1097,7 +1065,7 @@ swap_glyphs_in_rows (a, b)
 
 /* Exchange pointers to glyph memory between glyph rows A and B.  */
 
-static INLINE void
+static inline void
 swap_glyph_pointers (struct glyph_row *a, struct glyph_row *b)
 {
   int i;
@@ -1113,7 +1081,7 @@ swap_glyph_pointers (struct glyph_row *a, struct glyph_row *b)
 /* Copy glyph row structure FROM to glyph row structure TO, except
    that glyph pointers in the structures are left unchanged.  */
 
-static INLINE void
+static inline void
 copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from)
 {
   struct glyph *pointers[1 + LAST_AREA];
@@ -1129,38 +1097,12 @@ copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from)
 }
 
 
-/* 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 (struct glyph_row *to, struct glyph_row *from,
-                        EMACS_INT delta, EMACS_INT 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])
-      memcpy (to->glyphs[area], from->glyphs[area],
-             from->used[area] * sizeof (struct glyph));
-
-  /* Increment buffer positions in TO by DELTA.  */
-  increment_row_positions (to, delta, delta_bytes);
-}
-
-
 /* Assign glyph row FROM to glyph row TO.  This works like a structure
    assignment TO = FROM, except that glyph pointers are not copied but
    exchanged between TO and FROM.  Pointers must be exchanged to avoid
    a memory leak.  */
 
-static INLINE void
+static inline void
 assign_row (struct glyph_row *to, struct glyph_row *from)
 {
   swap_glyph_pointers (to, from);
@@ -1223,7 +1165,7 @@ prepare_desired_row (struct glyph_row *row)
 {
   if (!row->enabled_p)
     {
-      unsigned rp = row->reversed_p;
+      int rp = row->reversed_p;
 
       clear_glyph_row (row);
       row->enabled_p = 1;
@@ -1267,7 +1209,7 @@ line_hash_code (struct glyph_row *row)
    the number of characters in the line.  If must_write_spaces is
    zero, leading and trailing spaces are ignored.  */
 
-static unsigned int
+static int
 line_draw_cost (struct glyph_matrix *matrix, int vpos)
 {
   struct glyph_row *row = matrix->rows + vpos;
@@ -1323,13 +1265,11 @@ line_draw_cost (struct glyph_matrix *matrix, int 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.  */
+   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 window *w, struct glyph_row *a, struct glyph_row *b, int mouse_face_p)
+static inline int
+row_equal_p (struct glyph_row *a, struct glyph_row *b, int mouse_face_p)
 {
   if (a == b)
     return 1;
@@ -1365,8 +1305,11 @@ row_equal_p (struct window *w, struct glyph_row *a, struct glyph_row *b, int mou
          || a->cursor_in_fringe_p != b->cursor_in_fringe_p
          || a->left_fringe_bitmap != b->left_fringe_bitmap
          || a->left_fringe_face_id != b->left_fringe_face_id
+         || a->left_fringe_offset != b->left_fringe_offset
          || a->right_fringe_bitmap != b->right_fringe_bitmap
          || a->right_fringe_face_id != b->right_fringe_face_id
+         || a->right_fringe_offset != b->right_fringe_offset
+         || a->fringe_bitmap_periodic_p != b->fringe_bitmap_periodic_p
          || a->overlay_arrow_bitmap != b->overlay_arrow_bitmap
          || a->exact_window_width_line_p != b->exact_window_width_line_p
          || a->overlapped_p != b->overlapped_p
@@ -1459,7 +1402,7 @@ realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim)
   needed = matrix_dim.width * matrix_dim.height;
   if (needed > pool->nglyphs)
     {
-      int size = needed * sizeof (struct glyph);
+      ptrdiff_t size = needed * sizeof (struct glyph);
 
       if (pool->glyphs)
        {
@@ -1500,6 +1443,8 @@ realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim)
    stdout.
 */
 
+void flush_stdout (void) EXTERNALLY_VISIBLE;
+
 void
 flush_stdout (void)
 {
@@ -1955,13 +1900,13 @@ adjust_frame_glyphs_initially (void)
 
   /* Do it for the root window.  */
   XSETFASTINT (root->top_line, top_margin);
+  XSETFASTINT (root->total_lines, frame_lines - 1 - top_margin);
   XSETFASTINT (root->total_cols, frame_cols);
-  set_window_height (sf->root_window, frame_lines - 1 - top_margin, 0);
 
   /* Do it for the mini-buffer window.  */
   XSETFASTINT (mini->top_line, frame_lines - 1);
+  XSETFASTINT (mini->total_lines, 1);
   XSETFASTINT (mini->total_cols, frame_cols);
-  set_window_height (root->next, 1, 0);
 
   adjust_frame_glyphs (sf);
   glyphs_initialized_initially_p = 1;
@@ -2083,7 +2028,7 @@ save_current_matrix (struct frame *f)
     {
       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);
+      ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
       to->glyphs[TEXT_AREA] = (struct glyph *) xmalloc (nbytes);
       memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
       to->used[TEXT_AREA] = from->used[TEXT_AREA];
@@ -2105,7 +2050,7 @@ restore_current_matrix (struct frame *f, struct glyph_matrix *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);
+      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]);
@@ -2223,8 +2168,6 @@ adjust_frame_glyphs_for_frame_redisplay (struct frame *f)
 static void
 adjust_frame_glyphs_for_window_redisplay (struct frame *f)
 {
-  struct window *w;
-
   xassert (FRAME_WINDOW_P (f) && FRAME_LIVE_P (f));
 
   /* Allocate/reallocate window matrices.  */
@@ -2236,6 +2179,7 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
   {
     /* Allocate a dummy window if not already done.  */
+    struct window *w;
     if (NILP (f->menu_bar_window))
       {
        f->menu_bar_window = make_window ();
@@ -2258,23 +2202,26 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
 #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 ();
+  {
+    /* 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 (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);
-      XSETFRAME (w->frame, f);
-      w->pseudo_window_p = 1;
-    }
-  else
-    w = XWINDOW (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 (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);
+  }
 #endif
 }
 
@@ -2291,7 +2238,7 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
 static void
 adjust_frame_message_buffer (struct frame *f)
 {
-  int size = FRAME_MESSAGE_BUF_SIZE (f) + 1;
+  ptrdiff_t size = FRAME_MESSAGE_BUF_SIZE (f) + 1;
 
   if (FRAME_MESSAGE_BUF (f))
     {
@@ -2748,7 +2695,7 @@ fill_up_frame_row_with_spaces (struct glyph_row *row, int upto)
    function must be called before updates to make explicit that we are
    working on frame matrices or not.  */
 
-static INLINE void
+static inline void
 set_frame_matrix_frame (struct frame *f)
 {
   frame_matrix_frame = f;
@@ -2763,7 +2710,7 @@ set_frame_matrix_frame (struct frame *f)
    done in frame matrices, and that we have to perform analogous
    operations in window matrices of frame_matrix_frame.  */
 
-static INLINE void
+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);
@@ -2924,7 +2871,7 @@ sync_window_with_frame_matrix_rows (struct window *w)
 /* Return the window in the window tree rooted in W containing frame
    row ROW.  Value is null if none is found.  */
 
-struct window *
+static struct window *
 frame_row_to_window (struct window *w, int row)
 {
   struct window *found = NULL;
@@ -3072,7 +3019,7 @@ mirror_line_dance (struct window *w, int unchanged_at_top, int nlines, int *copy
    matrices of leaf window agree with their frame matrices about
    glyph pointers.  */
 
-void
+static void
 check_window_matrix_pointers (struct window *w)
 {
   while (w)
@@ -3136,12 +3083,10 @@ check_matrix_pointers (struct glyph_matrix *window_matrix,
 static int
 window_to_frame_vpos (struct window *w, int vpos)
 {
-  struct frame *f = XFRAME (w->frame);
-
-  xassert (!FRAME_WINDOW_P (f));
+  xassert (!FRAME_WINDOW_P (XFRAME (w->frame)));
   xassert (vpos >= 0 && vpos <= w->desired_matrix->nrows);
   vpos += WINDOW_TOP_EDGE_LINE (w);
-  xassert (vpos >= 0 && vpos <= FRAME_LINES (f));
+  xassert (vpos >= 0 && vpos <= FRAME_LINES (XFRAME (w->frame)));
   return vpos;
 }
 
@@ -3226,21 +3171,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 (void)
-{
-  Lisp_Object tail, frame;
-
-  FOR_EACH_FRAME (tail, frame)
-    if (FRAME_VISIBLE_P (XFRAME (frame))
-       && FRAME_GARBAGED_P (XFRAME (frame)))
-      Fredraw_frame (frame);
-}
-
-
 \f
 /***********************************************************************
                             Frame Update
@@ -3562,12 +3492,12 @@ redraw_overlapping_rows (struct window *w, int 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
+static void
 check_current_matrix_flags (struct window *w)
 {
   int last_seen_p = 0;
@@ -3616,7 +3546,10 @@ update_window (struct window *w, int 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);
@@ -3669,7 +3602,7 @@ update_window (struct window *w, int 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)
        if (row->enabled_p)
          {
            int vpos = MATRIX_ROW_VPOS (row, desired_matrix);
@@ -4014,7 +3947,7 @@ update_text_area (struct window *w, int 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,
@@ -4031,11 +3964,11 @@ update_text_area (struct window *w, int vpos)
                  : (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;
        }
     }
@@ -4275,17 +4208,16 @@ static int runs_size;
 
 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 (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;
 
   entry = row_table[i];
-  while (entry && !row_equal_p (w, entry->row, row, 1))
+  while (entry && !row_equal_p (entry->row, row, 1))
     entry = entry->next;
 
   if (entry == NULL)
@@ -4336,7 +4268,8 @@ scrolling_window (struct window *w, int header_line_p)
   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;
+  int nruns, n, run_idx;
+  ptrdiff_t nbytes;
   struct row_entry *entry;
   struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
 
@@ -4352,7 +4285,7 @@ scrolling_window (struct window *w, int 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;
@@ -4367,23 +4300,29 @@ scrolling_window (struct window *w, int header_line_p)
 
   first_old = first_new = i;
 
-  /* Set last_new to the index + 1 of the last enabled row in the
-     desired matrix.  */
+  /* Set last_new to the index + 1 of the row that reaches the
+     bottom boundary in the desired matrix.  Give up if we find a
+     disabled row before we reach the bottom boundary.  */
   i = first_new + 1;
-  while (i < desired_matrix->nrows - 1
-        && MATRIX_ROW (desired_matrix, i)->enabled_p
-        && MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (desired_matrix, i)) <= yb)
-    ++i;
+  while (i < desired_matrix->nrows - 1)
+    {
+      int bottom;
 
-  if (!MATRIX_ROW (desired_matrix, i)->enabled_p)
-    return 0;
+      if (!MATRIX_ROW (desired_matrix, i)->enabled_p)
+       return 0;
+      bottom = MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (desired_matrix, i));
+      if (bottom <= yb)
+       ++i;
+      if (bottom >= yb)
+       break;
+    }
 
   last_new = i;
 
-  /* Set last_old to the index + 1 of the last enabled row in the
-     current matrix.  We don't look at the enabled flag here because
-     we plan to reuse part of the display even if other parts are
-     disabled.  */
+  /* Set last_old to the index + 1 of the row that reaches the bottom
+     boundary in the current matrix.  We don't look at the enabled
+     flag here because we plan to reuse part of the display even if
+     other parts are disabled.  */
   i = first_old + 1;
   while (i < current_matrix->nrows - 1)
     {
@@ -4405,8 +4344,7 @@ scrolling_window (struct window *w, int header_line_p)
         && (MATRIX_ROW (current_matrix, i - 1)->y
             == MATRIX_ROW (desired_matrix, j - 1)->y)
         && !MATRIX_ROW (desired_matrix, j - 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;
@@ -4467,7 +4405,7 @@ scrolling_window (struct window *w, int 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;
        }
@@ -4478,7 +4416,7 @@ scrolling_window (struct window *w, int 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));
+      entry = add_row_entry (MATRIX_ROW (desired_matrix, i));
       ++entry->new_uses;
       entry->new_line_number = i;
       new_lines[i] = entry;
@@ -4491,7 +4429,7 @@ scrolling_window (struct window *w, int 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++;
 
@@ -4504,33 +4442,33 @@ scrolling_window (struct window *w, int 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
@@ -4538,11 +4476,11 @@ scrolling_window (struct window *w, int 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;
@@ -4572,6 +4510,7 @@ scrolling_window (struct window *w, int header_line_p)
        /* Copy on the display.  */
        if (r->current_y != r->desired_y)
          {
+           rif->clear_window_mouse_face (w);
            rif->scroll_run_hook (w, r);
 
            /* Invalidate runs that copy from where we copied to.  */
@@ -4597,13 +4536,7 @@ scrolling_window (struct window *w, int header_line_p)
            to = MATRIX_ROW (current_matrix, r->desired_vpos + j);
            from = MATRIX_ROW (desired_matrix, r->desired_vpos + j);
            to_overlapped_p = to->overlapped_p;
-           if (!from->mode_line_p && !w->pseudo_window_p
-               && (to->left_fringe_bitmap != from->left_fringe_bitmap
-                   || to->right_fringe_bitmap != from->right_fringe_bitmap
-                   || to->left_fringe_face_id != from->left_fringe_face_id
-                   || to->right_fringe_face_id != from->right_fringe_face_id
-                   || to->overlay_arrow_bitmap != from->overlay_arrow_bitmap))
-             from->redraw_fringe_bitmaps_p = 1;
+           from->redraw_fringe_bitmaps_p = from->fringe_bitmap_periodic_p;
            assign_row (to, from);
            to->enabled_p = 1, from->enabled_p = 0;
            to->overlapped_p = to_overlapped_p;
@@ -4614,8 +4547,8 @@ scrolling_window (struct window *w, int 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;
 }
 
 
@@ -4639,7 +4572,7 @@ update_frame_1 (struct frame *f, int force_p, int inhibit_id_p)
   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;
 
   xassert (current_matrix && desired_matrix);
@@ -4653,7 +4586,7 @@ update_frame_1 (struct frame *f, int force_p, int inhibit_id_p)
 #if !PERIODIC_PREEMPTION_CHECKING
   if (!force_p && detect_input_pending_ignore_squeezables ())
     {
-      pause = 1;
+      pause_p = 1;
       goto do_pause;
     }
 #endif
@@ -4733,10 +4666,10 @@ update_frame_1 (struct frame *f, int force_p, int 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,
@@ -4837,13 +4770,13 @@ update_frame_1 (struct frame *f, int force_p, int inhibit_id_p)
 #endif
 
   clear_desired_matrices (f);
-  return pause;
+  return pause_p;
 }
 
 
 /* Do line insertions/deletions on frame F for frame-based redisplay.  */
 
-int
+static int
 scrolling (struct frame *frame)
 {
   int unchanged_at_top, unchanged_at_bottom;
@@ -5594,7 +5527,7 @@ marginal_area_string (struct window *w, enum window_part part,
 
 #ifdef SIGWINCH
 
-SIGTYPE
+static void
 window_change_signal (int signalnum) /* If we don't have an argument, */
                                /* some compilers complain in signal calls.  */
 {
@@ -5749,24 +5682,7 @@ change_frame_size_1 (register struct frame *f, int newheight, int newwidth, int
 
   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.  */
@@ -5776,9 +5692,7 @@ change_frame_size_1 (register struct frame *f, int newheight, int newwidth, int
 
   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.  */
@@ -6111,7 +6025,7 @@ pass nil for VARIABLE.  */)
     state = frame_and_buffer_state;
 
   vecp = XVECTOR (state)->contents;
-  end = vecp + XVECTOR (state)->size;
+  end = vecp + ASIZE (state);
 
   FOR_EACH_FRAME (tail, frame)
     {
@@ -6129,7 +6043,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;
@@ -6137,7 +6051,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;
@@ -6162,8 +6076,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 (state)->size
-      || n + 20 < XVECTOR (state)->size / 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);
@@ -6184,20 +6098,20 @@ 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;
       *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 (state)->size)
+        < ASIZE (state))
     *vecp++ = Qlambda;
   /* Make sure we didn't overflow the vector.  */
   if (vecp - XVECTOR (state)->contents
-      > XVECTOR (state)->size)
+      > ASIZE (state))
     abort ();
   return Qt;
 }
@@ -6267,11 +6181,7 @@ init_display (void)
        }
     }
 
-  if (!inhibit_window_system && display_arg
-#ifndef CANNOT_DUMP
-     && initialized
-#endif
-     )
+  if (!inhibit_window_system && display_arg)
     {
       Vinitial_window_system = Qx;
 #ifdef HAVE_X11
@@ -6384,11 +6294,14 @@ init_display (void)
     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);
   }
 
@@ -6496,10 +6409,8 @@ syms_of_display (void)
   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.