error: Print 32- and 64-bit integers portably (Bug#8435).
[bpt/emacs.git] / src / xdisp.c
index 68f7835..a296fb3 100644 (file)
@@ -483,15 +483,6 @@ int buffer_shared;
 
 static Lisp_Object default_invis_vector[3];
 
-/* Prompt to display in front of the mini-buffer contents.  */
-
-Lisp_Object minibuf_prompt;
-
-/* Width of current mini-buffer prompt.  Only set after display_line
-   of the line that contains the prompt.  */
-
-int minibuf_prompt_width;
-
 /* This is the window where the echo area message was displayed.  It
    is always a mini-buffer window, but it may not be the same window
    currently active as a mini-buffer.  */
@@ -763,7 +754,7 @@ static void setup_for_ellipsis (struct it *, int);
 static void mark_window_display_accurate_1 (struct window *, int);
 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
 static int display_prop_string_p (Lisp_Object, Lisp_Object);
-static int cursor_row_p (struct window *, struct glyph_row *);
+static int cursor_row_p (struct glyph_row *);
 static int redisplay_mode_lines (Lisp_Object, int);
 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
 
@@ -771,7 +762,7 @@ static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
 
 static void handle_line_prefix (struct it *);
 
-static void pint2str (char *, int, int);
+static void pint2str (char *, int, EMACS_INT);
 static void pint2hrstr (char *, int, int);
 static struct text_pos run_window_scroll_functions (Lisp_Object,
                                                     struct text_pos);
@@ -783,6 +774,7 @@ static int store_mode_line_noprop (const char *, int, int);
 static void handle_stop (struct it *);
 static void handle_stop_backwards (struct it *, EMACS_INT);
 static int single_display_spec_intangible_p (Lisp_Object);
+static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
 static void ensure_echo_area_buffers (void);
 static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
@@ -811,13 +803,12 @@ static int cursor_row_fully_visible_p (struct window *, int, int);
 static int try_scrolling (Lisp_Object, int, EMACS_INT, EMACS_INT, int, int);
 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
 static int trailing_whitespace_p (EMACS_INT);
-static int message_log_check_duplicate (EMACS_INT, EMACS_INT,
-                                       EMACS_INT, EMACS_INT);
+static unsigned long int message_log_check_duplicate (EMACS_INT, EMACS_INT);
 static void push_it (struct it *);
 static void pop_it (struct it *);
 static void sync_frame_with_window_matrix_rows (struct window *);
 static void select_frame_for_redisplay (Lisp_Object);
-static void redisplay_internal (int);
+static void redisplay_internal (void);
 static int echo_area_display (int);
 static void redisplay_windows (Lisp_Object);
 static void redisplay_window (Lisp_Object, int);
@@ -832,11 +823,9 @@ static int display_mode_lines (struct window *);
 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
-static const char *decode_mode_spec (struct window *, int, int, int,
-                                    Lisp_Object *);
+static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
 static void display_menu_bar (struct window *);
-static int display_count_lines (EMACS_INT, EMACS_INT, EMACS_INT, int,
-                               EMACS_INT *);
+static int display_count_lines (EMACS_INT, EMACS_INT, int, EMACS_INT *);
 static int display_string (const char *, Lisp_Object, Lisp_Object,
                            EMACS_INT, EMACS_INT, struct it *, int, int, int, int);
 static void compute_line_metrics (struct it *);
@@ -1156,7 +1145,7 @@ line_bottom_y (struct it *it)
        line_height = last_height;
       else if (IT_CHARPOS (*it) < ZV)
        {
-         move_it_by_lines (it, 1, 1);
+         move_it_by_lines (it, 1);
          line_height = (it->max_ascent || it->max_descent
                         ? it->max_ascent + it->max_descent
                         : last_height);
@@ -1210,12 +1199,12 @@ pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
   if (WINDOW_WANTS_MODELINE_P (w))
     current_mode_line_height
       = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
-                          B_ (current_buffer, mode_line_format));
+                          BVAR (current_buffer, mode_line_format));
 
   if (WINDOW_WANTS_HEADER_LINE_P (w))
     current_header_line_height
       = display_mode_line (w, HEADER_LINE_FACE_ID,
-                              B_ (current_buffer, header_line_format));
+                              BVAR (current_buffer, header_line_format));
 
   start_display (&it, w, top);
   move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
@@ -1280,7 +1269,7 @@ pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
 
       it2 = it;
       if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
-       move_it_by_lines (&it, 1, 0);
+       move_it_by_lines (&it, 1);
       if (charpos < IT_CHARPOS (it)
          || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
        {
@@ -2190,7 +2179,7 @@ safe_eval_handler (Lisp_Object arg)
    redisplay during the evaluation.  */
 
 Lisp_Object
-safe_call (int nargs, Lisp_Object *args)
+safe_call (size_t nargs, Lisp_Object *args)
 {
   Lisp_Object val;
 
@@ -2405,10 +2394,10 @@ init_iterator (struct it *it, struct window *w,
   if (base_face_id == DEFAULT_FACE_ID
       && FRAME_WINDOW_P (it->f))
     {
-      if (NATNUMP (B_ (current_buffer, extra_line_spacing)))
-       it->extra_line_spacing = XFASTINT (B_ (current_buffer, extra_line_spacing));
-      else if (FLOATP (B_ (current_buffer, extra_line_spacing)))
-       it->extra_line_spacing = (XFLOAT_DATA (B_ (current_buffer, extra_line_spacing))
+      if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
+       it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
+      else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
+       it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
                                  * FRAME_LINE_HEIGHT (it->f));
       else if (it->f->extra_line_spacing > 0)
        it->extra_line_spacing = it->f->extra_line_spacing;
@@ -2431,36 +2420,36 @@ init_iterator (struct it *it, struct window *w,
   it->override_ascent = -1;
 
   /* Are control characters displayed as `^C'?  */
-  it->ctl_arrow_p = !NILP (B_ (current_buffer, ctl_arrow));
+  it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
 
   /* -1 means everything between a CR and the following line end
      is invisible.  >0 means lines indented more than this value are
      invisible.  */
-  it->selective = (INTEGERP (B_ (current_buffer, selective_display))
-                  ? XFASTINT (B_ (current_buffer, selective_display))
-                  : (!NILP (B_ (current_buffer, selective_display))
+  it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
+                  ? XFASTINT (BVAR (current_buffer, selective_display))
+                  : (!NILP (BVAR (current_buffer, selective_display))
                      ? -1 : 0));
   it->selective_display_ellipsis_p
-    = !NILP (B_ (current_buffer, selective_display_ellipses));
+    = !NILP (BVAR (current_buffer, selective_display_ellipses));
 
   /* Display table to use.  */
   it->dp = window_display_table (w);
 
   /* Are multibyte characters enabled in current_buffer?  */
-  it->multibyte_p = !NILP (B_ (current_buffer, enable_multibyte_characters));
+  it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
 
   /* Do we need to reorder bidirectional text?  Not if this is a
      unibyte buffer: by definition, none of the single-byte characters
      are strong R2L, so no reordering is needed.  And bidi.c doesn't
      support unibyte buffers anyway.  */
   it->bidi_p
-    = !NILP (B_ (current_buffer, bidi_display_reordering)) && it->multibyte_p;
+    = !NILP (BVAR (current_buffer, bidi_display_reordering)) && it->multibyte_p;
 
   /* Non-zero if we should highlight the region.  */
   highlight_region_p
     = (!NILP (Vtransient_mark_mode)
-       && !NILP (B_ (current_buffer, mark_active))
-       && XMARKER (B_ (current_buffer, mark))->buffer != 0);
+       && !NILP (BVAR (current_buffer, mark_active))
+       && XMARKER (BVAR (current_buffer, mark))->buffer != 0);
 
   /* Set IT->region_beg_charpos and IT->region_end_charpos to the
      start and end of a visible region in window IT->w.  Set both to
@@ -2477,9 +2466,9 @@ init_iterator (struct it *it, struct window *w,
              && WINDOWP (minibuf_selected_window)
              && w == XWINDOW (minibuf_selected_window))))
     {
-      EMACS_INT charpos = marker_position (B_ (current_buffer, mark));
-      it->region_beg_charpos = min (PT, charpos);
-      it->region_end_charpos = max (PT, charpos);
+      EMACS_INT markpos = marker_position (BVAR (current_buffer, mark));
+      it->region_beg_charpos = min (PT, markpos);
+      it->region_end_charpos = max (PT, markpos);
     }
   else
     it->region_beg_charpos = it->region_end_charpos = -1;
@@ -2494,7 +2483,7 @@ init_iterator (struct it *it, struct window *w,
     it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
 
   /* Correct bogus values of tab_width.  */
-  it->tab_width = XINT (B_ (current_buffer, tab_width));
+  it->tab_width = XINT (BVAR (current_buffer, tab_width));
   if (it->tab_width <= 0 || it->tab_width > 1000)
     it->tab_width = 8;
 
@@ -2508,8 +2497,8 @@ init_iterator (struct it *it, struct window *w,
                  && (WINDOW_TOTAL_COLS (it->w)
                      < XINT (Vtruncate_partial_width_windows))))))
     it->line_wrap = TRUNCATE;
-  else if (NILP (B_ (current_buffer, truncate_lines)))
-    it->line_wrap = NILP (B_ (current_buffer, word_wrap))
+  else if (NILP (BVAR (current_buffer, truncate_lines)))
+    it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
       ? WINDOW_WRAP : WORD_WRAP;
   else
     it->line_wrap = TRUNCATE;
@@ -2611,9 +2600,9 @@ init_iterator (struct it *it, struct window *w,
     {
       /* Note the paragraph direction that this buffer wants to
         use.  */
-      if (EQ (B_ (current_buffer, bidi_paragraph_direction), Qleft_to_right))
+      if (EQ (BVAR (current_buffer, bidi_paragraph_direction), Qleft_to_right))
        it->paragraph_embedding = L2R;
-      else if (EQ (B_ (current_buffer, bidi_paragraph_direction), Qright_to_left))
+      else if (EQ (BVAR (current_buffer, bidi_paragraph_direction), Qright_to_left))
        it->paragraph_embedding = R2L;
       else
        it->paragraph_embedding = NEUTRAL_DIR;
@@ -3173,6 +3162,9 @@ handle_fontified_prop (struct it *it)
     {
       int count = SPECPDL_INDEX ();
       Lisp_Object val;
+      struct buffer *obuf = current_buffer;
+      int begv = BEGV, zv = ZV;
+      int old_clip_changed = current_buffer->clip_changed;
 
       val = Vfontification_functions;
       specbind (Qfontification_functions, Qnil);
@@ -3183,11 +3175,11 @@ handle_fontified_prop (struct it *it)
        safe_call1 (val, pos);
       else
        {
-         Lisp_Object globals, fn;
+         Lisp_Object fns, fn;
          struct gcpro gcpro1, gcpro2;
 
-         globals = Qnil;
-         GCPRO2 (val, globals);
+         fns = Qnil;
+         GCPRO2 (val, fns);
 
          for (; CONSP (val); val = XCDR (val))
            {
@@ -3200,11 +3192,11 @@ handle_fontified_prop (struct it *it)
                     In a global value, t should not occur.  If it
                     does, we must ignore it to avoid an endless
                     loop.  */
-                 for (globals = Fdefault_value (Qfontification_functions);
-                      CONSP (globals);
-                      globals = XCDR (globals))
+                 for (fns = Fdefault_value (Qfontification_functions);
+                      CONSP (fns);
+                      fns = XCDR (fns))
                    {
-                     fn = XCAR (globals);
+                     fn = XCAR (fns);
                      if (!EQ (fn, Qt))
                        safe_call1 (fn, pos);
                    }
@@ -3218,6 +3210,23 @@ handle_fontified_prop (struct it *it)
 
       unbind_to (count, Qnil);
 
+      /* Fontification functions routinely call `save-restriction'.
+        Normally, this tags clip_changed, which can confuse redisplay
+        (see discussion in Bug#6671).  Since we don't perform any
+        special handling of fontification changes in the case where
+        `save-restriction' isn't called, there's no point doing so in
+        this case either.  So, if the buffer's restrictions are
+        actually left unchanged, reset clip_changed.  */
+      if (obuf == current_buffer)
+       {
+         if (begv == BEGV && zv == ZV)
+           current_buffer->clip_changed = old_clip_changed;
+       }
+      /* There isn't much we can reasonably do to protect against
+        misbehaving fontification, but here's a fig leaf.  */
+      else if (!NILP (BVAR (obuf, name)))
+       set_buffer_internal_1 (obuf);
+
       /* The fontification code may have added/removed text.
         It could do even a lot worse, but let's at least protect against
         the most obvious case where only the text past `pos' gets changed',
@@ -3989,12 +3998,12 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
          else if (NUMBERP (it->font_height))
            {
              /* Value is a multiple of the canonical char height.  */
-             struct face *face;
+             struct face *f;
 
-             face = FACE_FROM_ID (it->f,
-                                  lookup_basic_face (it->f, DEFAULT_FACE_ID));
+             f = FACE_FROM_ID (it->f,
+                               lookup_basic_face (it->f, DEFAULT_FACE_ID));
              new_height = (XFLOATINT (it->font_height)
-                           * XINT (face->lface[LFACE_HEIGHT_INDEX]));
+                           * XINT (f->lface[LFACE_HEIGHT_INDEX]));
            }
          else
            {
@@ -4409,20 +4418,18 @@ display_prop_string_p (Lisp_Object prop, Lisp_Object string)
   return 0;
 }
 
-/* Look for STRING in overlays and text properties in W's buffer,
-   between character positions FROM and TO (excluding TO).
+/* Look for STRING in overlays and text properties in the current
+   buffer, between character positions FROM and TO (excluding TO).
    BACK_P non-zero means look back (in this case, TO is supposed to be
    less than FROM).
    Value is the first character position where STRING was found, or
    zero if it wasn't found before hitting TO.
 
-   W's buffer must be current.
-
    This function may only use code that doesn't eval because it is
    called asynchronously from note_mouse_highlight.  */
 
 static EMACS_INT
-string_buffer_position_lim (struct window *w, Lisp_Object string,
+string_buffer_position_lim (Lisp_Object string,
                            EMACS_INT from, EMACS_INT to, int back_p)
 {
   Lisp_Object limit, prop, pos;
@@ -4460,27 +4467,25 @@ string_buffer_position_lim (struct window *w, Lisp_Object string,
   return found ? XINT (pos) : 0;
 }
 
-/* Determine which buffer position in W's buffer STRING comes from.
+/* Determine which buffer position in current buffer STRING comes from.
    AROUND_CHARPOS is an approximate position where it could come from.
    Value is the buffer position or 0 if it couldn't be determined.
 
-   W's buffer must be current.
-
    This function is necessary because we don't record buffer positions
    in glyphs generated from strings (to keep struct glyph small).
    This function may only use code that doesn't eval because it is
    called asynchronously from note_mouse_highlight.  */
 
-EMACS_INT
-string_buffer_position (struct window *w, Lisp_Object string, EMACS_INT around_charpos)
+static EMACS_INT
+string_buffer_position (Lisp_Object string, EMACS_INT around_charpos)
 {
   const int MAX_DISTANCE = 1000;
-  EMACS_INT found = string_buffer_position_lim (w, string, around_charpos,
+  EMACS_INT found = string_buffer_position_lim (string, around_charpos,
                                                around_charpos + MAX_DISTANCE,
                                                0);
 
   if (!found)
-    found = string_buffer_position_lim (w, string, around_charpos,
+    found = string_buffer_position_lim (string, around_charpos,
                                        around_charpos - MAX_DISTANCE, 1);
   return found;
 }
@@ -5411,7 +5416,7 @@ reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
   it->method = GET_FROM_BUFFER;
   it->object = it->w->buffer;
   it->area = TEXT_AREA;
-  it->multibyte_p = !NILP (B_ (current_buffer, enable_multibyte_characters));
+  it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
   it->sp = 0;
   it->string_from_display_prop_p = 0;
   it->face_before_selective_p = 0;
@@ -7632,7 +7637,7 @@ move_it_vertically_backward (struct it *it, int dy)
       /* DY == 0 means move to the start of the screen line.  The
         value of nlines is > 0 if continuation lines were involved.  */
       if (nlines > 0)
-       move_it_by_lines (it, nlines, 1);
+       move_it_by_lines (it, nlines);
     }
   else
     {
@@ -7676,7 +7681,7 @@ move_it_vertically_backward (struct it *it, int dy)
            {
              do
                {
-                 move_it_by_lines (it, 1, 1);
+                 move_it_by_lines (it, 1);
                }
              while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
            }
@@ -7706,7 +7711,7 @@ move_it_vertically (struct it *it, int dy)
       if (IT_CHARPOS (*it) == ZV
          && ZV > BEGV
          && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
-       move_it_by_lines (it, 0, 0);
+       move_it_by_lines (it, 0);
     }
 }
 
@@ -7726,15 +7731,14 @@ move_it_past_eol (struct it *it)
 
 /* Move IT by a specified number DVPOS of screen lines down.  DVPOS
    negative means move up.  DVPOS == 0 means move to the start of the
-   screen line.  NEED_Y_P non-zero means calculate IT->current_y.  If
-   NEED_Y_P is zero, IT->current_y will be left unchanged.
+   screen line.
 
-   Further optimization ideas: If we would know that IT->f doesn't use
+   Optimization idea: If we would know that IT->f doesn't use
    a face with proportional font, we could be faster for
    truncate-lines nil.  */
 
 void
-move_it_by_lines (struct it *it, int dvpos, int need_y_p)
+move_it_by_lines (struct it *it, int dvpos)
 {
 
   /* The commented-out optimization uses vmotion on terminals.  This
@@ -7919,7 +7923,7 @@ message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
       old_deactivate_mark = Vdeactivate_mark;
       oldbuf = current_buffer;
       Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
-      B_ (current_buffer, undo_list) = Qt;
+      BVAR (current_buffer, undo_list) = Qt;
 
       oldpoint = message_dolog_marker1;
       set_marker_restricted (oldpoint, make_number (PT), Qnil);
@@ -7943,7 +7947,7 @@ message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
       /* Insert the string--maybe converting multibyte to single byte
         or vice versa, so that all the text fits the buffer.  */
       if (multibyte
-         && NILP (B_ (current_buffer, enable_multibyte_characters)))
+         && NILP (BVAR (current_buffer, enable_multibyte_characters)))
        {
          EMACS_INT i;
          int c, char_bytes;
@@ -7956,12 +7960,12 @@ message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
              c = string_char_and_length (msg + i, &char_bytes);
              work[0] = (ASCII_CHAR_P (c)
                         ? c
-                        : multibyte_char_to_unibyte (c, Qnil));
+                        : multibyte_char_to_unibyte (c));
              insert_1_both (work, 1, 1, 1, 0, 0);
            }
        }
       else if (! multibyte
-              && ! NILP (B_ (current_buffer, enable_multibyte_characters)))
+              && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
        {
          EMACS_INT i;
          int c, char_bytes;
@@ -7982,7 +7986,7 @@ message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
       if (nlflag)
        {
          EMACS_INT this_bol, this_bol_byte, prev_bol, prev_bol_byte;
-         int dup;
+         unsigned long int dups;
          insert_1 ("\n", 1, 1, 0, 0);
 
          scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
@@ -7997,20 +8001,20 @@ message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
              prev_bol = PT;
              prev_bol_byte = PT_BYTE;
 
-             dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
-                                                this_bol, this_bol_byte);
-             if (dup)
+             dups = message_log_check_duplicate (prev_bol_byte,
+                                                  this_bol_byte);
+             if (dups)
                {
                  del_range_both (prev_bol, prev_bol_byte,
                                  this_bol, this_bol_byte, 0);
-                 if (dup > 1)
+                 if (dups > 1)
                    {
                      char dupstr[40];
                      int duplen;
 
                      /* If you change this format, don't forget to also
                         change message_log_check_duplicate.  */
-                     sprintf (dupstr, " [%d times]", dup);
+                     sprintf (dupstr, " [%lu times]", dups);
                      duplen = strlen (dupstr);
                      TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
                      insert_1 (dupstr, duplen, 1, 0, 1);
@@ -8072,9 +8076,8 @@ message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
    Return 0 if different, 1 if the new one should just replace it, or a
    value N > 1 if we should also append " [N times]".  */
 
-static int
-message_log_check_duplicate (EMACS_INT prev_bol, EMACS_INT prev_bol_byte,
-                            EMACS_INT this_bol, EMACS_INT this_bol_byte)
+static unsigned long int
+message_log_check_duplicate (EMACS_INT prev_bol_byte, EMACS_INT this_bol_byte)
 {
   EMACS_INT i;
   EMACS_INT len = Z_BYTE - 1 - this_bol_byte;
@@ -8094,10 +8097,9 @@ message_log_check_duplicate (EMACS_INT prev_bol, EMACS_INT prev_bol_byte,
     return 2;
   if (*p1++ == ' ' && *p1++ == '[')
     {
-      int n = 0;
-      while (*p1 >= '0' && *p1 <= '9')
-       n = n * 10 + *p1++ - '0';
-      if (strncmp ((char *) p1, " times]\n", 8) == 0)
+      char *pend;
+      unsigned long int n = strtoul ((char *) p1, &pend, 10);
+      if (strncmp (pend, " times]\n", 8) == 0)
        return n+1;
     }
   return 0;
@@ -8340,20 +8342,20 @@ message_with_string (const char *m, Lisp_Object string, int log)
         cmd_error, so this must be just an informative message; toss it.  */
       if (FRAME_MESSAGE_BUF (f))
        {
-         Lisp_Object args[2], message;
+         Lisp_Object args[2], msg;
          struct gcpro gcpro1, gcpro2;
 
          args[0] = build_string (m);
-         args[1] = message = string;
-         GCPRO2 (args[0], message);
+         args[1] = msg = string;
+         GCPRO2 (args[0], msg);
          gcpro1.nvars = 2;
 
-         message = Fformat (2, args);
+         msg = Fformat (2, args);
 
          if (log)
-           message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
+           message3 (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
          else
-           message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
+           message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
 
          UNGCPRO;
 
@@ -8405,10 +8407,18 @@ vmessage (const char *m, va_list ap)
        {
          if (m)
            {
-             EMACS_INT len;
-
-             len = doprnt (FRAME_MESSAGE_BUF (f),
-                           FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
+             char *buf = FRAME_MESSAGE_BUF (f);
+             size_t bufsize = FRAME_MESSAGE_BUF_SIZE (f);
+             int len = vsnprintf (buf, bufsize, m, ap);
+             if (len < 0)
+               len = 0;
+
+             /* Do any truncation at a character boundary.  */
+             if (0 < bufsize && bufsize <= len)
+               for (len = bufsize - 1;
+                    len && ! CHAR_HEAD_P (buf[len - 1]);
+                    len--)
+                 continue;
 
              message2 (FRAME_MESSAGE_BUF (f), len, 0);
            }
@@ -8432,22 +8442,6 @@ message (const char *m, ...)
 }
 
 
-/* The non-logging version of message.  */
-
-void
-message_nolog (const char *m, ...)
-{
-  Lisp_Object old_log_max;
-  va_list ap;
-  va_start (ap, m);
-  old_log_max = Vmessage_log_max;
-  Vmessage_log_max = Qnil;
-  vmessage (m, ap);
-  Vmessage_log_max = old_log_max;
-  va_end (ap);
-}
-
-
 /* Display the current message in the current mini-buffer.  This is
    only called from error handlers in process.c, and is not time
    critical.  */
@@ -8460,7 +8454,7 @@ update_echo_area (void)
       Lisp_Object string;
       string = Fcurrent_message ();
       message3 (string, SBYTES (string),
-               !NILP (B_ (current_buffer, enable_multibyte_characters)));
+               !NILP (BVAR (current_buffer, enable_multibyte_characters)));
     }
 }
 
@@ -8475,7 +8469,7 @@ ensure_echo_area_buffers (void)
 
   for (i = 0; i < 2; ++i)
     if (!BUFFERP (echo_buffer[i])
-       || NILP (B_ (XBUFFER (echo_buffer[i]), name)))
+       || NILP (BVAR (XBUFFER (echo_buffer[i]), name)))
       {
        char name[30];
        Lisp_Object old_buffer;
@@ -8484,7 +8478,7 @@ ensure_echo_area_buffers (void)
        old_buffer = echo_buffer[i];
        sprintf (name, " *Echo Area %d*", i);
        echo_buffer[i] = Fget_buffer_create (build_string (name));
-       B_ (XBUFFER (echo_buffer[i]), truncate_lines) = Qnil;
+       BVAR (XBUFFER (echo_buffer[i]), truncate_lines) = Qnil;
        /* to force word wrap in echo area -
           it was decided to postpone this*/
        /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
@@ -8577,8 +8571,8 @@ with_echo_area_buffer (struct window *w, int which,
       set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
     }
 
-  B_ (current_buffer, undo_list) = Qt;
-  B_ (current_buffer, read_only) = Qnil;
+  BVAR (current_buffer, undo_list) = Qt;
+  BVAR (current_buffer, read_only) = Qnil;
   specbind (Qinhibit_read_only, Qt);
   specbind (Qinhibit_modification_hooks, Qt);
 
@@ -8691,7 +8685,7 @@ setup_echo_area_for_printing (int multibyte_p)
 
       /* Switch to that buffer and clear it.  */
       set_buffer_internal (XBUFFER (echo_area_buffer[0]));
-      B_ (current_buffer, truncate_lines) = Qnil;
+      BVAR (current_buffer, truncate_lines) = Qnil;
 
       if (Z > BEG)
        {
@@ -8705,7 +8699,7 @@ setup_echo_area_for_printing (int multibyte_p)
 
       /* Set up the buffer for the multibyteness we need.  */
       if (multibyte_p
-         != !NILP (B_ (current_buffer, enable_multibyte_characters)))
+         != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
        Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
 
       /* Raise the frame containing the echo area.  */
@@ -8734,7 +8728,7 @@ setup_echo_area_for_printing (int multibyte_p)
        {
          /* Someone switched buffers between print requests.  */
          set_buffer_internal (XBUFFER (echo_area_buffer[0]));
-         B_ (current_buffer, truncate_lines) = Qnil;
+         BVAR (current_buffer, truncate_lines) = Qnil;
        }
     }
 }
@@ -8833,7 +8827,7 @@ resize_echo_area_exactly (void)
        {
          ++windows_or_buffers_changed;
          ++update_mode_lines;
-         redisplay_internal (0);
+         redisplay_internal ();
        }
     }
 }
@@ -9177,12 +9171,12 @@ set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multiby
 
   /* Change multibyteness of the echo buffer appropriately.  */
   if (message_enable_multibyte
-      != !NILP (B_ (current_buffer, enable_multibyte_characters)))
+      != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
     Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
 
-  B_ (current_buffer, truncate_lines) = message_truncate_lines ? Qt : Qnil;
-  if (!NILP (B_ (current_buffer, bidi_display_reordering)))
-    B_ (current_buffer, bidi_paragraph_direction) = Qleft_to_right;
+  BVAR (current_buffer, truncate_lines) = message_truncate_lines ? Qt : Qnil;
+  if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
+    BVAR (current_buffer, bidi_paragraph_direction) = Qleft_to_right;
 
   /* Insert new message at BEG.  */
   TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
@@ -9205,7 +9199,7 @@ set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multiby
       if (nbytes == 0)
        nbytes = strlen (s);
 
-      if (multibyte_p && NILP (B_ (current_buffer, enable_multibyte_characters)))
+      if (multibyte_p && NILP (BVAR (current_buffer, enable_multibyte_characters)))
        {
          /* Convert from multi-byte to single-byte.  */
          EMACS_INT i;
@@ -9218,12 +9212,12 @@ set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multiby
              c = string_char_and_length (msg + i, &n);
              work[0] = (ASCII_CHAR_P (c)
                         ? c
-                        : multibyte_char_to_unibyte (c, Qnil));
+                        : multibyte_char_to_unibyte (c));
              insert_1_both (work, 1, 1, 1, 0, 0);
            }
        }
       else if (!multibyte_p
-              && !NILP (B_ (current_buffer, enable_multibyte_characters)))
+              && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
        {
          /* Convert from single-byte to multi-byte.  */
          EMACS_INT i;
@@ -9374,7 +9368,7 @@ echo_area_display (int update_frame_p)
              int count = SPECPDL_INDEX ();
              specbind (Qredisplay_dont_pause, Qt);
              windows_or_buffers_changed = 1;
-             redisplay_internal (0);
+             redisplay_internal ();
              unbind_to (count, Qnil);
            }
          else if (FRAME_WINDOW_P (f) && n == 0)
@@ -9808,7 +9802,7 @@ update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
               < BUF_MODIFF (XBUFFER (w->buffer)))
              != !NILP (w->last_had_star))
          || ((!NILP (Vtransient_mark_mode)
-              && !NILP (B_ (XBUFFER (w->buffer), mark_active)))
+              && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
              != !NILP (w->region_showing)))
        {
          struct buffer *prev = current_buffer;
@@ -10006,7 +10000,7 @@ update_tool_bar (struct frame *f, int save_match_data)
               < BUF_MODIFF (XBUFFER (w->buffer)))
              != !NILP (w->last_had_star))
          || ((!NILP (Vtransient_mark_mode)
-              && !NILP (B_ (XBUFFER (w->buffer), mark_active)))
+              && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
              != !NILP (w->region_showing)))
        {
          struct buffer *prev = current_buffer;
@@ -10918,7 +10912,7 @@ hscroll_window_tree (Lisp_Object window)
              current_buffer = XBUFFER (w->buffer);
 
              if (w == XWINDOW (selected_window))
-               pt = BUF_PT (current_buffer);
+               pt = PT;
              else
                {
                  pt = marker_position (w->pointm);
@@ -11097,8 +11091,8 @@ text_outside_line_unchanged_p (struct window *w,
       /* If selective display, can't optimize if changes start at the
         beginning of the line.  */
       if (unchanged_p
-         && INTEGERP (B_ (current_buffer, selective_display))
-         && XINT (B_ (current_buffer, selective_display)) > 0
+         && INTEGERP (BVAR (current_buffer, selective_display))
+         && XINT (BVAR (current_buffer, selective_display)) > 0
          && (BEG_UNCHANGED < start || GPT <= start))
        unchanged_p = 0;
 
@@ -11126,8 +11120,8 @@ text_outside_line_unchanged_p (struct window *w,
         require to redisplay the whole paragraph.  It might be worthwhile
         to find the paragraph limits and widen the range of redisplayed
         lines to that, but for now just give up this optimization.  */
-      if (!NILP (B_ (XBUFFER (w->buffer), bidi_display_reordering))
-         && NILP (B_ (XBUFFER (w->buffer), bidi_paragraph_direction)))
+      if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
+         && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
        unchanged_p = 0;
     }
 
@@ -11145,7 +11139,7 @@ text_outside_line_unchanged_p (struct window *w,
 void
 redisplay (void)
 {
-  redisplay_internal (0);
+  redisplay_internal ();
 }
 
 
@@ -11356,7 +11350,7 @@ reconsider_clip_changes (struct window *w, struct buffer *b)
       EMACS_INT pt;
 
       if (w == XWINDOW (selected_window))
-       pt = BUF_PT (current_buffer);
+       pt = PT;
       else
        pt = marker_position (w->pointm);
 
@@ -11409,18 +11403,16 @@ do { if (polling_stopped_here) start_polling ();      \
        polling_stopped_here = 0; } while (0)
 
 
-/* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
-   response to any user action; therefore, we should preserve the echo
-   area.  (Actually, our caller does that job.)  Perhaps in the future
-   avoid recentering windows if it is not necessary; currently that
-   causes some problems.  */
+/* Perhaps in the future avoid recentering windows if it
+   is not necessary; currently that causes some problems.  */
 
 static void
-redisplay_internal (int preserve_echo_area)
+redisplay_internal (void)
 {
   struct window *w = XWINDOW (selected_window);
-  struct frame *f;
-  int pause;
+  struct window *sw;
+  struct frame *fr;
+  int pending;
   int must_finish = 0;
   struct text_pos tlbufpos, tlendpos;
   int number_of_visible_frames;
@@ -11445,10 +11437,10 @@ redisplay_internal (int preserve_echo_area)
   /* Don't examine these until after testing Vinhibit_redisplay.
      When Emacs is shutting down, perhaps because its connection to
      X has dropped, we should not look at them at all.  */
-  f = XFRAME (w->frame);
+  fr = XFRAME (w->frame);
   sf = SELECTED_FRAME ();
 
-  if (!f->glyphs_initialized_p)
+  if (!fr->glyphs_initialized_p)
     return;
 
 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
@@ -11479,6 +11471,9 @@ redisplay_internal (int preserve_echo_area)
   }
 
  retry:
+  /* Remember the currently selected window.  */
+  sw = w;
+
   if (!EQ (old_frame, selected_frame)
       && FRAME_LIVE_P (XFRAME (old_frame)))
     /* When running redisplay, we play a bit fast-and-loose and allow e.g.
@@ -11487,7 +11482,7 @@ redisplay_internal (int preserve_echo_area)
        may need to run Elisp code (via prepare_menu_bars).  */
     select_frame_for_redisplay (old_frame);
 
-  pause = 0;
+  pending = 0;
   reconsider_clip_changes (w, current_buffer);
   last_escape_glyph_frame = NULL;
   last_escape_glyph_face_id = (1 << FACE_ID_BITS);
@@ -11546,6 +11541,14 @@ redisplay_internal (int preserve_echo_area)
   /* Notice any pending interrupt request to change frame size.  */
   do_pending_window_change (1);
 
+  /* do_pending_window_change could change the selected_window due to
+     frame resizing which makes the selected window too small.  */
+  if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
+    {
+      sw = w;
+      reconsider_clip_changes (w, current_buffer);
+    }
+
   /* Clear frames marked as garbaged.  */
   if (frame_garbaged)
     clear_garbaged_frames ();
@@ -11576,8 +11579,7 @@ redisplay_internal (int preserve_echo_area)
       && !(PT == XFASTINT (w->last_point)
           && XFASTINT (w->last_modified) >= MODIFF
           && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
-      && (XFASTINT (w->column_number_displayed)
-          != (int) current_column ()))  /* iftc */
+      && (XFASTINT (w->column_number_displayed) != current_column ()))
     w->update_mode_line = Qt;
 
   unbind_to (count1, Qnil);
@@ -11662,11 +11664,11 @@ redisplay_internal (int preserve_echo_area)
      the whole window.  The assignment to this_line_start_pos prevents
      the optimization directly below this if-statement.  */
   if (((!NILP (Vtransient_mark_mode)
-       && !NILP (B_ (XBUFFER (w->buffer), mark_active)))
+       && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
        != !NILP (w->region_showing))
       || (!NILP (w->region_showing)
          && !EQ (w->region_showing,
-                 Fmarker_position (B_ (XBUFFER (w->buffer), mark)))))
+                 Fmarker_position (BVAR (XBUFFER (w->buffer), mark)))))
     CHARPOS (this_line_start_pos) = 0;
 
   /* Optimize the case that only the line containing the cursor in the
@@ -11815,6 +11817,10 @@ redisplay_internal (int preserve_echo_area)
          if (!must_finish)
            {
              do_pending_window_change (1);
+             /* If selected_window changed, redisplay again.  */
+             if (WINDOWP (selected_window)
+                 && (w = XWINDOW (selected_window)) != sw)
+               goto retry;
 
              /* We used to always goto end_of_redisplay here, but this
                 isn't enough if we have a blinking cursor.  */
@@ -11826,8 +11832,8 @@ redisplay_internal (int preserve_echo_area)
       /* If highlighting the region, or if the cursor is in the echo area,
         then we can't just move the cursor.  */
       else if (! (!NILP (Vtransient_mark_mode)
-                 && !NILP (B_ (current_buffer, mark_active)))
-              && (EQ (selected_window, B_ (current_buffer, last_selected_window))
+                 && !NILP (BVAR (current_buffer, mark_active)))
+              && (EQ (selected_window, BVAR (current_buffer, last_selected_window))
                   || highlight_nonselected_windows)
               && NILP (w->region_showing)
               && NILP (Vshow_trailing_whitespace)
@@ -11947,7 +11953,7 @@ redisplay_internal (int preserve_echo_area)
 
                  /* Update the display.  */
                  set_window_update_flags (XWINDOW (f->root_window), 1);
-                 pause |= update_frame (f, 0, 0);
+                 pending |= update_frame (f, 0, 0);
                  f->updated_p = 1;
                }
            }
@@ -11961,7 +11967,7 @@ redisplay_internal (int preserve_echo_area)
        select_frame_for_redisplay (old_frame);
       eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
 
-      if (!pause)
+      if (!pending)
        {
          /* Do the mark_window_display_accurate after all windows have
             been redisplayed because this call resets flags in buffers
@@ -12010,7 +12016,7 @@ redisplay_internal (int preserve_echo_area)
            goto retry;
 
          XWINDOW (selected_window)->must_be_updated_p = 1;
-         pause = update_frame (sf, 0, 0);
+         pending = update_frame (sf, 0, 0);
        }
 
       /* We may have called echo_area_display at the top of this
@@ -12024,15 +12030,15 @@ redisplay_internal (int preserve_echo_area)
       if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
        {
          XWINDOW (mini_window)->must_be_updated_p = 1;
-         pause |= update_frame (mini_frame, 0, 0);
-         if (!pause && hscroll_windows (mini_window))
+         pending |= update_frame (mini_frame, 0, 0);
+         if (!pending && hscroll_windows (mini_window))
            goto retry;
        }
     }
 
   /* If display was paused because of pending input, make sure we do a
      thorough update the next time.  */
-  if (pause)
+  if (pending)
     {
       /* Prevent the optimization at the beginning of
         redisplay_internal that tries a single-line update of the
@@ -12082,7 +12088,7 @@ redisplay_internal (int preserve_echo_area)
      redisplay constructing glyphs, so simply exposing a frame won't
      display anything in this case.  So, we have to display these
      frames here explicitly.  */
-  if (!pause)
+  if (!pending)
     {
       Lisp_Object tail, frame;
       int new_count = 0;
@@ -12109,8 +12115,9 @@ redisplay_internal (int preserve_echo_area)
   do_pending_window_change (1);
 
   /* If we just did a pending size change, or have additional
-     visible frames, redisplay again.  */
-  if (windows_or_buffers_changed && !pause)
+     visible frames, or selected_window changed, redisplay again.  */
+  if ((windows_or_buffers_changed && !pending)
+      || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
     goto retry;
 
   /* Clear the face and image caches.
@@ -12160,11 +12167,11 @@ redisplay_preserve_echo_area (int from_where)
       /* We have a previously displayed message, but no current
         message.  Redisplay the previous message.  */
       display_last_displayed_message_p = 1;
-      redisplay_internal (1);
+      redisplay_internal ();
       display_last_displayed_message_p = 0;
     }
   else
-    redisplay_internal (1);
+    redisplay_internal ();
 
   if (FRAME_RIF (SELECTED_FRAME ()) != NULL
       && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
@@ -12365,18 +12372,6 @@ redisplay_window_1 (Lisp_Object window)
 }
 \f
 
-/* Increment GLYPH until it reaches END or CONDITION fails while
-   adding (GLYPH)->pixel_width to X. */
-
-#define SKIP_GLYPHS(glyph, end, x, condition)  \
-  do                                           \
-    {                                          \
-      (x) += (glyph)->pixel_width;             \
-      ++(glyph);                               \
-    }                                          \
-  while ((glyph) < (end) && (condition))
-
-
 /* Set cursor position of W.  PT is assumed to be displayed in ROW.
    DELTA and DELTA_BYTES are the numbers of characters and bytes by
    which positions recorded in ROW differ from current buffer
@@ -12717,7 +12712,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
                  EMACS_INT tem;
 
                  str = glyph->object;
-                 tem = string_buffer_position_lim (w, str, pos, pos_after, 0);
+                 tem = string_buffer_position_lim (str, pos, pos_after, 0);
                  if (tem == 0  /* from overlay */
                      || pos <= tem)
                    {
@@ -12989,6 +12984,12 @@ enum
   SCROLLING_NEED_LARGER_MATRICES
 };
 
+/* If scroll-conservatively is more than this, never recenter.
+
+   If you change this, don't forget to update the doc string of
+   `scroll-conservatively' and the Emacs manual.  */
+#define SCROLL_LIMIT 100
+
 static int
 try_scrolling (Lisp_Object window, int just_this_one_p,
               EMACS_INT arg_scroll_conservatively, EMACS_INT scroll_step,
@@ -13002,7 +13003,8 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
   int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
   int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
   Lisp_Object aggressive;
-  int scroll_limit = INT_MAX / FRAME_LINE_HEIGHT (f);
+  /* We will never try scrolling more than this number of lines.  */
+  int scroll_limit = SCROLL_LIMIT;
 
 #if GLYPH_DEBUG
   debug_method_add (w, "try_scrolling");
@@ -13018,14 +13020,14 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
   else
     this_scroll_margin = 0;
 
-  /* Force arg_scroll_conservatively to have a reasonable value, to avoid
-     overflow while computing how much to scroll.  Note that the user
-     can supply scroll-conservatively equal to `most-positive-fixnum',
-     which can be larger than INT_MAX.  */
+  /* Force arg_scroll_conservatively to have a reasonable value, to
+     avoid scrolling too far away with slow move_it_* functions.  Note
+     that the user can supply scroll-conservatively equal to
+     `most-positive-fixnum', which can be larger than INT_MAX.  */
   if (arg_scroll_conservatively > scroll_limit)
     {
-      arg_scroll_conservatively = scroll_limit;
-      scroll_max = INT_MAX;
+      arg_scroll_conservatively = scroll_limit + 1;
+      scroll_max = scroll_limit * FRAME_LINE_HEIGHT (f);
     }
   else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
     /* Compute how much we should try to scroll maximally to bring
@@ -13033,8 +13035,8 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
     scroll_max = (max (scroll_step,
                       max (arg_scroll_conservatively, temp_scroll_step))
                  * FRAME_LINE_HEIGHT (f));
-  else if (NUMBERP (B_ (current_buffer, scroll_down_aggressively))
-          || NUMBERP (B_ (current_buffer, scroll_up_aggressively)))
+  else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
+          || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
     /* We're trying to scroll because of aggressive scrolling but no
        scroll_step is set.  Choose an arbitrary one.  */
     scroll_max = 10 * FRAME_LINE_HEIGHT (f);
@@ -13062,13 +13064,10 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
          /* Compute how many pixels below window bottom to stop searching
             for PT.  This avoids costly search for PT that is far away if
             the user limited scrolling by a small number of lines, but
-            always finds PT if arg_scroll_conservatively is set to a large
+            always finds PT if scroll_conservatively is set to a large
             number, such as most-positive-fixnum.  */
          int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
-         int y_to_move =
-           slack >= INT_MAX - it.last_visible_y
-           ? INT_MAX
-           : it.last_visible_y + slack;
+         int y_to_move = it.last_visible_y + slack;
 
          /* Compute the distance from the scroll margin to PT or to
             the scroll limit, whichever comes first.  This should
@@ -13099,7 +13098,7 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
        amount_to_scroll = scroll_max;
       else
        {
-         aggressive = B_ (current_buffer, scroll_up_aggressively);
+         aggressive = BVAR (current_buffer, scroll_up_aggressively);
          height = WINDOW_BOX_TEXT_HEIGHT (w);
          if (NUMBERP (aggressive))
            {
@@ -13107,6 +13106,10 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
              amount_to_scroll = float_amount;
              if (amount_to_scroll == 0 && float_amount > 0)
                amount_to_scroll = 1;
+             /* Don't let point enter the scroll margin near top of
+                the window.  */
+             if (amount_to_scroll > height - 2*this_scroll_margin + dy)
+               amount_to_scroll = height - 2*this_scroll_margin + dy;
            }
        }
 
@@ -13114,12 +13117,12 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
        return SCROLLING_FAILED;
 
       start_display (&it, w, startp);
-      if (scroll_max < INT_MAX)
+      if (arg_scroll_conservatively <= scroll_limit)
        move_it_vertically (&it, amount_to_scroll);
       else
        {
          /* Extra precision for users who set scroll-conservatively
-            to most-positive-fixnum: make sure the amount we scroll
+            to a large number: make sure the amount we scroll
             the window start is never less than amount_to_scroll,
             which was computed as distance from window bottom to
             point.  This matters when lines at window top and lines
@@ -13130,14 +13133,14 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
          int start_y = line_bottom_y (&it1);
 
          do {
-           move_it_by_lines (&it, 1, 1);
+           move_it_by_lines (&it, 1);
            it1 = it;
          } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
        }
 
       /* If STARTP is unchanged, move it down another screen line.  */
       if (CHARPOS (it.current.pos) == CHARPOS (startp))
-       move_it_by_lines (&it, 1, 1);
+       move_it_by_lines (&it, 1);
       startp = it.current.pos;
     }
   else
@@ -13157,16 +13160,19 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
        {
          /* Point is in the scroll margin at the top of the window or
             above what is displayed in the window.  */
-         int y0;
+         int y0, y_to_move;
 
          /* Compute the vertical distance from PT to the scroll
-            margin position.  Give up if distance is greater than
-            scroll_max.  */
+            margin position.  Move as far as scroll_max allows, or
+            one screenful, or 10 screen lines, whichever is largest.
+            Give up if distance is greater than scroll_max.  */
          SET_TEXT_POS (pos, PT, PT_BYTE);
          start_display (&it, w, pos);
          y0 = it.current_y;
+         y_to_move = max (it.last_visible_y,
+                          max (scroll_max, 10 * FRAME_LINE_HEIGHT (f)));
          move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
-                     it.last_visible_y, -1,
+                     y_to_move, -1,
                      MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
          dy = it.current_y - y0;
          if (dy > scroll_max)
@@ -13176,13 +13182,13 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
          start_display (&it, w, startp);
 
          if (arg_scroll_conservatively)
-           amount_to_scroll
-             = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
+           amount_to_scroll = max (dy, FRAME_LINE_HEIGHT (f) *
+                                   max (scroll_step, temp_scroll_step));
          else if (scroll_step || temp_scroll_step)
            amount_to_scroll = scroll_max;
          else
            {
-             aggressive = B_ (current_buffer, scroll_down_aggressively);
+             aggressive = BVAR (current_buffer, scroll_down_aggressively);
              height = WINDOW_BOX_TEXT_HEIGHT (w);
              if (NUMBERP (aggressive))
                {
@@ -13190,6 +13196,12 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
                  amount_to_scroll = float_amount;
                  if (amount_to_scroll == 0 && float_amount > 0)
                    amount_to_scroll = 1;
+                 amount_to_scroll -=
+                   this_scroll_margin - dy - FRAME_LINE_HEIGHT (f);
+                 /* Don't let point enter the scroll margin near
+                    bottom of the window.  */
+                 if (amount_to_scroll > height - 2*this_scroll_margin + dy)
+                   amount_to_scroll = height - 2*this_scroll_margin + dy;
                }
            }
 
@@ -13298,7 +13310,7 @@ compute_window_start_on_continuation_line (struct window *w)
            {
              min_distance = distance;
              pos = it.current.pos;
-             move_it_by_lines (&it, 1, 0);
+             move_it_by_lines (&it, 1);
            }
 
          /* Set the window start there.  */
@@ -13363,7 +13375,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
          region exists, cursor movement has to do more than just
          set the cursor.  */
       && !(!NILP (Vtransient_mark_mode)
-          && !NILP (B_ (current_buffer, mark_active)))
+          && !NILP (BVAR (current_buffer, mark_active)))
       && NILP (w->region_showing)
       && NILP (Vshow_trailing_whitespace)
       /* Right after splitting windows, last_point may be nil.  */
@@ -13443,7 +13455,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
                     && row < w->current_matrix->rows
                                + w->current_matrix->nrows - 1
                     && MATRIX_ROW_START_CHARPOS (row+1) == PT
-                    && !cursor_row_p (w, row))
+                    && !cursor_row_p (row))
                ++row;
 
              /* If within the scroll margin, scroll.  Note that
@@ -13495,7 +13507,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
                 skip forward over overlay strings.  */
              while (MATRIX_ROW_BOTTOM_Y (row) < last_y
                     && MATRIX_ROW_END_CHARPOS (row) == PT
-                    && !cursor_row_p (w, row))
+                    && !cursor_row_p (row))
                ++row;
 
              /* If within the scroll margin, scroll.  */
@@ -13518,7 +13530,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
              must_scroll = 1;
            }
          else if (rc != CURSOR_MOVEMENT_SUCCESS
-                  && !NILP (B_ (XBUFFER (w->buffer), bidi_display_reordering)))
+                  && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
            {
              /* If rows are bidi-reordered and point moved, back up
                 until we find a row that does not belong to a
@@ -13576,7 +13588,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
          else if (scroll_p)
            rc = CURSOR_MOVEMENT_MUST_SCROLL;
          else if (rc != CURSOR_MOVEMENT_SUCCESS
-                  && !NILP (B_ (XBUFFER (w->buffer), bidi_display_reordering)))
+                  && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
            {
              /* With bidi-reordered rows, there could be more than
                 one candidate row whose start and end positions
@@ -13591,7 +13603,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
                {
                  if (MATRIX_ROW_START_CHARPOS (row) <= PT
                      && PT <= MATRIX_ROW_END_CHARPOS (row)
-                     && cursor_row_p (w, row))
+                     && cursor_row_p (row))
                    rv |= set_cursor_from_row (w, row, w->current_matrix,
                                               0, 0, 0, 0);
                  /* As soon as we've found the first suitable row
@@ -13630,7 +13642,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
                }
              while (MATRIX_ROW_BOTTOM_Y (row) < last_y
                     && MATRIX_ROW_START_CHARPOS (row) == PT
-                    && cursor_row_p (w, row));
+                    && cursor_row_p (row));
            }
        }
     }
@@ -13824,8 +13836,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
       && !(PT == XFASTINT (w->last_point)
           && XFASTINT (w->last_modified) >= MODIFF
           && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
-      && (XFASTINT (w->column_number_displayed)
-          != (int) current_column ()))  /* iftc */
+      && (XFASTINT (w->column_number_displayed) != current_column ()))
     update_mode_line = 1;
 
   /* Count number of windows showing the selected buffer.  An indirect
@@ -13876,7 +13887,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
       struct Lisp_Char_Table *disptab = buffer_display_table ();
 
       if (! disptab_matches_widthtab (disptab,
-                                      XVECTOR (B_ (current_buffer, width_table))))
+                                      XVECTOR (BVAR (current_buffer, width_table))))
         {
           invalidate_region_cache (current_buffer,
                                    current_buffer->width_run_cache,
@@ -13998,7 +14009,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
          /* If we are highlighting the region, then we just changed
             the region, so redisplay to show it.  */
          if (!NILP (Vtransient_mark_mode)
-             && !NILP (B_ (current_buffer, mark_active)))
+             && !NILP (BVAR (current_buffer, mark_active)))
            {
              clear_glyph_matrix (w->desired_matrix);
              if (!try_window (window, startp, 0))
@@ -14161,19 +14172,18 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
   if ((scroll_conservatively
        || emacs_scroll_step
        || temp_scroll_step
-       || NUMBERP (B_ (current_buffer, scroll_up_aggressively))
-       || NUMBERP (B_ (current_buffer, scroll_down_aggressively)))
-      && !current_buffer->clip_changed
+       || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
+       || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
       && CHARPOS (startp) >= BEGV
       && CHARPOS (startp) <= ZV)
     {
       /* The function returns -1 if new fonts were loaded, 1 if
         successful, 0 if not successful.  */
-      int rc = try_scrolling (window, just_this_one_p,
+      int ss = try_scrolling (window, just_this_one_p,
                              scroll_conservatively,
                              emacs_scroll_step,
                              temp_scroll_step, last_line_misfit);
-      switch (rc)
+      switch (ss)
        {
        case SCROLLING_SUCCESS:
          goto done;
@@ -14189,11 +14199,10 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
        }
     }
 
-  /* Finally, just choose place to start which centers point */
+  /* Finally, just choose a place to start which positions point
+     according to user preferences.  */
 
  recenter:
-  if (centering_position < 0)
-    centering_position = window_box_height (w) / 2;
 
 #if GLYPH_DEBUG
   debug_method_add (w, "recenter");
@@ -14205,10 +14214,77 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
   if (!buffer_unchanged_p)
     w->base_line_number = Qnil;
 
-  /* Move backward half the height of the window.  */
+  /* Determine the window start relative to point.  */
   init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
   it.current_y = it.last_visible_y;
+  if (centering_position < 0)
+    {
+      int margin =
+       scroll_margin > 0
+       ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
+       : 0;
+      EMACS_INT margin_pos = CHARPOS (startp);
+      int scrolling_up;
+      Lisp_Object aggressive;
+
+      /* If there is a scroll margin at the top of the window, find
+        its character position.  */
+      if (margin)
+       {
+         struct it it1;
+
+         start_display (&it1, w, startp);
+         move_it_vertically (&it1, margin);
+         margin_pos = IT_CHARPOS (it1);
+       }
+      scrolling_up = PT > margin_pos;
+      aggressive =
+       scrolling_up
+       ? BVAR (current_buffer, scroll_up_aggressively)
+       : BVAR (current_buffer, scroll_down_aggressively);
+
+      if (!MINI_WINDOW_P (w)
+         && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
+       {
+         int pt_offset = 0;
+
+         /* Setting scroll-conservatively overrides
+            scroll-*-aggressively.  */
+         if (!scroll_conservatively && NUMBERP (aggressive))
+           {
+             double float_amount = XFLOATINT (aggressive);
+
+             pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
+             if (pt_offset == 0 && float_amount > 0)
+               pt_offset = 1;
+             if (pt_offset)
+               margin -= 1;
+           }
+         /* Compute how much to move the window start backward from
+            point so that point will be displayed where the user
+            wants it.  */
+         if (scrolling_up)
+           {
+             centering_position = it.last_visible_y;
+             if (pt_offset)
+               centering_position -= pt_offset;
+             centering_position -=
+               FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0));
+             /* Don't let point enter the scroll margin near top of
+                the window.  */
+             if (centering_position < margin * FRAME_LINE_HEIGHT (f))
+               centering_position = margin * FRAME_LINE_HEIGHT (f);
+           }
+         else
+           centering_position = margin * FRAME_LINE_HEIGHT (f) + pt_offset;
+       }
+      else
+       /* Set the window start half the height of the window backward
+          from point.  */
+       centering_position = window_box_height (w) / 2;
+    }
   move_it_vertically_backward (&it, centering_position);
+
   xassert (IT_CHARPOS (it) >= BEGV);
 
   /* The function move_it_vertically_backward may move over more
@@ -14225,8 +14301,9 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
 
   it.current_x = it.hpos = 0;
 
-  /* Set startp here explicitly in case that helps avoid an infinite loop
-     in case the window-scroll-functions functions get errors.  */
+  /* Set the window start position here explicitly, to avoid an
+     infinite loop in case the functions in window-scroll-functions
+     get errors.  */
   set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
 
   /* Run scroll hooks.  */
@@ -14262,13 +14339,13 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
          && PT >= Z - XFASTINT (w->window_end_pos))
        {
          clear_glyph_matrix (w->desired_matrix);
-         move_it_by_lines (&it, 1, 0);
+         move_it_by_lines (&it, 1);
          try_window (window, it.current.pos, 0);
        }
       else if (PT < IT_CHARPOS (it))
        {
          clear_glyph_matrix (w->desired_matrix);
-         move_it_by_lines (&it, -1, 0);
+         move_it_by_lines (&it, -1);
          try_window (window, it.current.pos, 0);
        }
       else
@@ -14330,11 +14407,10 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
        || INTEGERP (w->base_line_pos)
        /* Column number is displayed and different from the one displayed.  */
        || (!NILP (w->column_number_displayed)
-          && (XFASTINT (w->column_number_displayed)
-               != (int) current_column ()))) /* iftc */
-       /* This means that the window has a mode line.  */
-       && (WINDOW_WANTS_MODELINE_P (w)
-          || WINDOW_WANTS_HEADER_LINE_P (w)))
+          && (XFASTINT (w->column_number_displayed) != current_column ())))
+      /* This means that the window has a mode line.  */
+      && (WINDOW_WANTS_MODELINE_P (w)
+         || WINDOW_WANTS_HEADER_LINE_P (w)))
     {
       display_mode_lines (w);
 
@@ -14580,7 +14656,7 @@ static int
 try_window_reusing_current_matrix (struct window *w)
 {
   struct frame *f = XFRAME (w->frame);
-  struct glyph_row *row, *bottom_row;
+  struct glyph_row *bottom_row;
   struct it it;
   struct run run;
   struct text_pos start, new_start;
@@ -14605,7 +14681,7 @@ try_window_reusing_current_matrix (struct window *w)
 
   /* Can't do this if region may have changed.  */
   if ((!NILP (Vtransient_mark_mode)
-       && !NILP (B_ (current_buffer, mark_active)))
+       && !NILP (BVAR (current_buffer, mark_active)))
       || !NILP (w->region_showing)
       || !NILP (Vshow_trailing_whitespace))
     return 0;
@@ -14632,8 +14708,6 @@ try_window_reusing_current_matrix (struct window *w)
 
   if (CHARPOS (new_start) <= CHARPOS (start))
     {
-      int first_row_y;
-
       /* Don't use this method if the display starts with an ellipsis
         displayed for invisible text.  It's not easy to handle that case
         below, and it's certainly not worth the effort since this is
@@ -14648,7 +14722,6 @@ try_window_reusing_current_matrix (struct window *w)
         text.  Note that it.vpos == 0 if or if not there is a
          header-line; it's not the same as the MATRIX_ROW_VPOS!  */
       start_display (&it, w, new_start);
-      first_row_y = it.current_y;
       w->cursor.vpos = -1;
       last_text_row = last_reused_text_row = NULL;
 
@@ -14689,6 +14762,8 @@ try_window_reusing_current_matrix (struct window *w)
         have at least one reusable row.  */
       if (it.current_y < it.last_visible_y)
        {
+         struct glyph_row *row;
+
          /* IT.vpos always starts from 0; it counts text lines.  */
          nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
 
@@ -14948,7 +15023,7 @@ try_window_reusing_current_matrix (struct window *w)
 
              /* Can't use this optimization with bidi-reordered glyph
                 rows, unless cursor is already at point. */
-             if (!NILP (B_ (XBUFFER (w->buffer), bidi_display_reordering)))
+             if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
                {
                  if (!(w->cursor.hpos >= 0
                        && w->cursor.hpos < row->used[TEXT_AREA]
@@ -15262,7 +15337,7 @@ row_containing_pos (struct window *w, EMACS_INT charpos,
        {
          struct glyph *g;
 
-         if (NILP (B_ (XBUFFER (w->buffer), bidi_display_reordering))
+         if (NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
              || (!best_row && !row->continued_p))
            return row;
          /* In bidi-reordered rows, there could be several rows
@@ -15409,7 +15484,7 @@ try_window_id (struct window *w)
   /* Can't use this if highlighting a region because a cursor movement
      will do more than just set the cursor.  */
   if (!NILP (Vtransient_mark_mode)
-      && !NILP (B_ (current_buffer, mark_active)))
+      && !NILP (BVAR (current_buffer, mark_active)))
     GIVE_UP (9);
 
   /* Likewise if highlighting trailing whitespace.  */
@@ -15429,7 +15504,7 @@ try_window_id (struct window *w)
      wrapped line can change the wrap position, altering the line
      above it.  It might be worthwhile to handle this more
      intelligently, but for now just redisplay from scratch.  */
-  if (!NILP (B_ (XBUFFER (w->buffer), word_wrap)))
+  if (!NILP (BVAR (XBUFFER (w->buffer), word_wrap)))
     GIVE_UP (21);
 
   /* Under bidi reordering, adding or deleting a character in the
@@ -15440,8 +15515,8 @@ try_window_id (struct window *w)
      to find the paragraph limits and widen the range of redisplayed
      lines to that, but for now just give up this optimization and
      redisplay from scratch.  */
-  if (!NILP (B_ (XBUFFER (w->buffer), bidi_display_reordering))
-      && NILP (B_ (XBUFFER (w->buffer), bidi_paragraph_direction)))
+  if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
+      && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
     GIVE_UP (22);
 
   /* Make sure beg_unchanged and end_unchanged are up to date.  Do it
@@ -15474,41 +15549,41 @@ try_window_id (struct window *w)
          || (last_changed_charpos < CHARPOS (start) - 1
              && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
     {
-      EMACS_INT Z_old, delta, Z_BYTE_old, delta_bytes;
+      EMACS_INT Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
       struct glyph_row *r0;
 
       /* Compute how many chars/bytes have been added to or removed
         from the buffer.  */
       Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
       Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
-      delta = Z - Z_old;
-      delta_bytes = Z_BYTE - Z_BYTE_old;
+      Z_delta = Z - Z_old;
+      Z_delta_bytes = Z_BYTE - Z_BYTE_old;
 
       /* Give up if PT is not in the window.  Note that it already has
         been checked at the start of try_window_id that PT is not in
         front of the window start.  */
-      if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
+      if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
        GIVE_UP (13);
 
       /* If window start is unchanged, we can reuse the whole matrix
         as is, after adjusting glyph positions.  No need to compute
         the window end again, since its offset from Z hasn't changed.  */
       r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
-      if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
-         && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
+      if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
+         && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
          /* PT must not be in a partially visible line.  */
-         && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
+         && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
               && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
        {
          /* Adjust positions in the glyph matrix.  */
-         if (delta || delta_bytes)
+         if (Z_delta || Z_delta_bytes)
            {
              struct glyph_row *r1
                = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
              increment_matrix_positions (w->current_matrix,
                                          MATRIX_ROW_VPOS (r0, current_matrix),
                                          MATRIX_ROW_VPOS (r1, current_matrix),
-                                         delta, delta_bytes);
+                                         Z_delta, Z_delta_bytes);
            }
 
          /* Set the cursor.  */
@@ -15824,9 +15899,9 @@ try_window_id (struct window *w)
        {
          /* Terminal frame.  In this case, dvpos gives the number of
             lines to scroll by; dvpos < 0 means scroll up.  */
-         int first_unchanged_at_end_vpos
+         int from_vpos
            = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
-         int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
+         int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
          int end = (WINDOW_TOP_EDGE_LINE (w)
                     + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
                     + window_internal_height (w));
@@ -16375,7 +16450,7 @@ With ARG, turn tracing on if and only if ARG is positive.  */)
 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
        doc: /* Like `format', but print result to stderr.
 usage: (trace-to-stderr STRING &rest OBJECTS)  */)
-  (int nargs, Lisp_Object *args)
+  (size_t nargs, Lisp_Object *args)
 {
   Lisp_Object s = Fformat (nargs, args);
   fprintf (stderr, "%s", SDATA (s));
@@ -16412,7 +16487,7 @@ get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
   it.glyph_row->used[TEXT_AREA] = 0;
   SET_TEXT_POS (it.position, 0, 0);
 
-  multibyte_p = !NILP (B_ (buffer, enable_multibyte_characters));
+  multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
   p = arrow_string;
   while (p < arrow_end)
     {
@@ -16557,7 +16632,6 @@ static void
 compute_line_metrics (struct it *it)
 {
   struct glyph_row *row = it->glyph_row;
-  int area, i;
 
   if (FRAME_WINDOW_P (it->f))
     {
@@ -16622,14 +16696,17 @@ compute_line_metrics (struct it *it)
     }
 
   /* Compute a hash code for this row.  */
-  row->hash = 0;
-  for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
-    for (i = 0; i < row->used[area]; ++i)
-      row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
-                  + row->glyphs[area][i].u.val
-                  + row->glyphs[area][i].face_id
-                  + row->glyphs[area][i].padding_p
-                  + (row->glyphs[area][i].type << 2));
+  {
+    int area, i;
+    row->hash = 0;
+    for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
+      for (i = 0; i < row->used[area]; ++i)
+       row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
+                    + row->glyphs[area][i].u.val
+                    + row->glyphs[area][i].face_id
+                    + row->glyphs[area][i].padding_p
+                    + (row->glyphs[area][i].type << 2));
+  }
 
   it->max_ascent = it->max_descent = 0;
   it->max_phys_ascent = it->max_phys_descent = 0;
@@ -16956,13 +17033,13 @@ highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
 }
 
 
-/* Value is non-zero if glyph row ROW in window W should be
+/* Value is non-zero if glyph row ROW should be
    used to hold the cursor.  */
 
 static int
-cursor_row_p (struct window *w, struct glyph_row *row)
+cursor_row_p (struct glyph_row *row)
 {
-  int cursor_row_p = 1;
+  int result = 1;
 
   if (PT == CHARPOS (row->end.pos))
     {
@@ -16975,7 +17052,7 @@ cursor_row_p (struct window *w, struct glyph_row *row)
       if (CHARPOS (row->end.string_pos) >= 0)
        {
          if (row->continued_p)
-           cursor_row_p = 1;
+           result = 1;
          else
            {
              /* Check for `display' property.  */
@@ -16983,14 +17060,14 @@ cursor_row_p (struct window *w, struct glyph_row *row)
              struct glyph *end = beg + row->used[TEXT_AREA] - 1;
              struct glyph *glyph;
 
-             cursor_row_p = 0;
+             result = 0;
              for (glyph = end; glyph >= beg; --glyph)
                if (STRINGP (glyph->object))
                  {
                    Lisp_Object prop
                      = Fget_char_property (make_number (PT),
                                            Qdisplay, Qnil);
-                   cursor_row_p =
+                   result =
                      (!NILP (prop)
                       && display_prop_string_p (prop, glyph->object));
                    break;
@@ -17004,23 +17081,23 @@ cursor_row_p (struct window *w, struct glyph_row *row)
             That's because CHARPOS (ROW->end.pos) would equal
             PT if PT is before the character.  */
          if (!row->ends_in_ellipsis_p)
-           cursor_row_p = row->continued_p;
+           result = row->continued_p;
          else
          /* If the row ends in an ellipsis, then
             CHARPOS (ROW->end.pos) will equal point after the
             invisible text.  We want that position to be displayed
             after the ellipsis.  */
-           cursor_row_p = 0;
+           result = 0;
        }
       /* If the row ends at ZV, display the cursor at the end of that
         row instead of at the start of the row below.  */
       else if (row->ends_at_zv_p)
-       cursor_row_p = 1;
+       result = 1;
       else
-       cursor_row_p = 0;
+       result = 0;
     }
 
-  return cursor_row_p;
+  return result;
 }
 
 \f
@@ -17232,14 +17309,16 @@ display_line (struct it *it)
   struct glyph_row *row = it->glyph_row;
   Lisp_Object overlay_arrow_string;
   struct it wrap_it;
-  int may_wrap = 0, wrap_x;
-  int wrap_row_used = -1, wrap_row_ascent, wrap_row_height;
-  int wrap_row_phys_ascent, wrap_row_phys_height;
-  int wrap_row_extra_line_spacing;
-  EMACS_INT wrap_row_min_pos, wrap_row_min_bpos;
-  EMACS_INT wrap_row_max_pos, wrap_row_max_bpos;
+  int may_wrap = 0, wrap_x IF_LINT (= 0);
+  int wrap_row_used = -1;
+  int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
+  int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
+  int wrap_row_extra_line_spacing IF_LINT (= 0);
+  EMACS_INT wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
+  EMACS_INT wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
   int cvpos;
-  EMACS_INT min_pos = ZV + 1, min_bpos, max_pos = 0, max_bpos;
+  EMACS_INT min_pos = ZV + 1, max_pos = 0;
+  EMACS_INT min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
 
   /* We always start displaying at hpos zero even if hscrolled.  */
   xassert (it->hpos == 0 && it->current_x == 0);
@@ -17277,7 +17356,7 @@ display_line (struct it *it)
      if the first glyph is partially visible or if we hit a line end.  */
   if (it->current_x < it->first_visible_x)
     {
-      SET_TEXT_POS (this_line_min_pos, ZV + 1, ZV_BYTE + 1);
+      this_line_min_pos = row->start.pos;
       move_it_in_display_line_to (it, ZV, it->first_visible_x,
                                  MOVE_TO_POS | MOVE_TO_X);
       /* Record the smallest positions seen while we moved over
@@ -17328,7 +17407,7 @@ display_line (struct it *it)
   while (1)
     {
       int n_glyphs_before, hpos_before, x_before;
-      int x, i, nglyphs;
+      int x, nglyphs;
       int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
 
       /* Retrieve the next thing to display.  Value is zero if end of
@@ -17347,7 +17426,7 @@ display_line (struct it *it)
              row->glyphs[TEXT_AREA]->charpos = -1;
              row->displays_text_p = 0;
 
-             if (!NILP (B_ (XBUFFER (it->w->buffer), indicate_empty_lines))
+             if (!NILP (BVAR (XBUFFER (it->w->buffer), indicate_empty_lines))
                  && (!MINI_WINDOW_P (it->w)
                      || (minibuf_level && EQ (it->window, minibuf_window))))
                row->indicate_empty_line_p = 1;
@@ -17453,7 +17532,7 @@ display_line (struct it *it)
        }
       else
        {
-         int new_x;
+         int i, new_x;
          struct glyph *glyph;
 
          for (i = 0; i < nglyphs; ++i, x = new_x)
@@ -17871,7 +17950,7 @@ display_line (struct it *it)
           && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
       && PT >= MATRIX_ROW_START_CHARPOS (row)
       && PT <= MATRIX_ROW_END_CHARPOS (row)
-      && cursor_row_p (it->w, row))
+      && cursor_row_p (row))
     set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
 
   /* Highlight trailing whitespace.  */
@@ -17913,22 +17992,19 @@ paragraphs, text begins at the right margin and is read from right to left.
 See also `bidi-paragraph-direction'.  */)
   (Lisp_Object buffer)
 {
-  struct buffer *buf;
-  struct buffer *old;
+  struct buffer *buf = current_buffer;
+  struct buffer *old = buf;
 
-  if (NILP (buffer))
-    buf = current_buffer;
-  else
+  if (! NILP (buffer))
     {
       CHECK_BUFFER (buffer);
       buf = XBUFFER (buffer);
-      old = current_buffer;
     }
 
-  if (NILP (B_ (buf, bidi_display_reordering)))
+  if (NILP (BVAR (buf, bidi_display_reordering)))
     return Qleft_to_right;
-  else if (!NILP (B_ (buf, bidi_paragraph_direction)))
-    return B_ (buf, bidi_paragraph_direction);
+  else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
+    return BVAR (buf, bidi_paragraph_direction);
   else
     {
       /* Determine the direction from buffer text.  We could try to
@@ -17939,8 +18015,7 @@ See also `bidi-paragraph-direction'.  */)
       EMACS_INT bytepos = BUF_PT_BYTE (buf);
       int c;
 
-      if (buf != current_buffer)
-       set_buffer_temp (buf);
+      set_buffer_temp (buf);
       /* bidi_paragraph_init finds the base direction of the paragraph
         by searching forward from paragraph start.  We need the base
         direction of the current or _previous_ paragraph, so we need
@@ -17968,8 +18043,7 @@ See also `bidi-paragraph-direction'.  */)
       itb.paragraph_dir = NEUTRAL_DIR;
 
       bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
-      if (buf != current_buffer)
-       set_buffer_temp (old);
+      set_buffer_temp (old);
       switch (itb.paragraph_dir)
        {
        case L2R:
@@ -18187,14 +18261,14 @@ display_mode_lines (struct window *w)
 
       /* Select mode line face based on the real selected window.  */
       display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
-                        B_ (current_buffer, mode_line_format));
+                        BVAR (current_buffer, mode_line_format));
       ++n;
     }
 
   if (WINDOW_WANTS_HEADER_LINE_P (w))
     {
       display_mode_line (w, HEADER_LINE_FACE_ID,
-                        B_ (current_buffer, header_line_format));
+                        BVAR (current_buffer, header_line_format));
       ++n;
     }
 
@@ -18528,7 +18602,7 @@ display_mode_element (struct it *it, int depth, int field_width, int precision,
                    charpos = (STRING_MULTIBYTE (elt)
                               ? string_byte_to_char (elt, bytepos)
                               : bytepos);
-                   spec = decode_mode_spec (it->w, c, field, prec, &string);
+                   spec = decode_mode_spec (it->w, c, field, &string);
                    multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
 
                    switch (mode_line_target)
@@ -18981,7 +19055,7 @@ are the selected window and the WINDOW's buffer).  */)
    the positive integer D to BUF using a minimal field width WIDTH.  */
 
 static void
-pint2str (register char *buf, register int width, register int d)
+pint2str (register char *buf, register int width, register EMACS_INT d)
 {
   register char *p = buf;
 
@@ -19013,7 +19087,7 @@ pint2str (register char *buf, register int width, register int d)
 
 static const char power_letter[] =
   {
-    0,  /* not used */
+    0,  /* no letter */
     'k', /* kilo */
     'M', /* mega */
     'G', /* giga */
@@ -19095,8 +19169,7 @@ pint2hrstr (char *buf, int width, int d)
   p = psuffix = buf + max (width, length);
 
   /* Print EXPONENT. */
-  if (exponent)
-    *psuffix++ = power_letter[exponent];
+  *psuffix++ = power_letter[exponent];
   *psuffix = '\0';
 
   /* Print TENTHS. */
@@ -19129,7 +19202,7 @@ static char *
 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
 {
   Lisp_Object val;
-  int multibyte = !NILP (B_ (current_buffer, enable_multibyte_characters));
+  int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
   const unsigned char *eol_str;
   int eol_str_len;
   /* The EOL conversion we are using.  */
@@ -19200,9 +19273,8 @@ decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_
 }
 
 /* Return a string for the output of a mode line %-spec for window W,
-   generated by character C.  PRECISION >= 0 means don't return a
-   string longer than that value.  FIELD_WIDTH > 0 means pad the
-   string returned with spaces to that value.  Return a Lisp string in
+   generated by character C.  FIELD_WIDTH > 0 means pad the string
+   returned with spaces to that value.  Return a Lisp string in
    *STRING if the resulting string is taken from that Lisp string.
 
    Note we operate on the current buffer for most purposes,
@@ -19212,7 +19284,7 @@ static char lots_of_dashes[] = "------------------------------------------------
 
 static const char *
 decode_mode_spec (struct window *w, register int c, int field_width,
-                 int precision, Lisp_Object *string)
+                 Lisp_Object *string)
 {
   Lisp_Object obj;
   struct frame *f = XFRAME (WINDOW_FRAME (w));
@@ -19225,7 +19297,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
   switch (c)
     {
     case '*':
-      if (!NILP (B_ (b, read_only)))
+      if (!NILP (BVAR (b, read_only)))
        return "%";
       if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
        return "*";
@@ -19235,7 +19307,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
       /* This differs from %* only for a modified read-only buffer.  */
       if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
        return "*";
-      if (!NILP (B_ (b, read_only)))
+      if (!NILP (BVAR (b, read_only)))
        return "%";
       return "-";
 
@@ -19297,7 +19369,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
       }
 
     case 'b':
-      obj = B_ (b, name);
+      obj = BVAR (b, name);
       break;
 
     case 'c':
@@ -19310,7 +19382,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
        return "";
       else
        {
-         int col = (int) current_column (); /* iftc */
+         EMACS_INT col = current_column ();
          w->column_number_displayed = make_number (col);
          pint2str (decode_mode_spec_buf, field_width, col);
          return decode_mode_spec_buf;
@@ -19337,7 +19409,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
       return "Emacs";
 
     case 'f':
-      obj = B_ (b, filename);
+      obj = BVAR (b, filename);
       break;
 
     case 'i':
@@ -19401,7 +19473,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
          }
 
        /* Count lines from base line to window start position.  */
-       nlines = display_count_lines (linepos, linepos_byte,
+       nlines = display_count_lines (linepos_byte,
                                      startpos_byte,
                                      startpos, &junk);
 
@@ -19430,7 +19502,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
                limit_byte = CHAR_TO_BYTE (limit);
              }
 
-           nlines = display_count_lines (startpos, startpos_byte,
+           nlines = display_count_lines (startpos_byte,
                                          limit_byte,
                                          - (height * 2 + 30),
                                          &position);
@@ -19449,7 +19521,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
          }
 
        /* Now count lines from the start pos to point.  */
-       nlines = display_count_lines (startpos, startpos_byte,
+       nlines = display_count_lines (startpos_byte,
                                      PT_BYTE, PT, &junk);
 
        /* Record that we did display the line number.  */
@@ -19473,7 +19545,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
       break;
 
     case 'm':
-      obj = B_ (b, mode_name);
+      obj = BVAR (b, mode_name);
       break;
 
     case 'n':
@@ -19558,7 +19630,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
       {
        int count = inhibit_garbage_collection ();
        Lisp_Object val = call1 (intern ("file-remote-p"),
-                                B_ (current_buffer, directory));
+                                BVAR (current_buffer, directory));
        unbind_to (count, Qnil);
 
        if (NILP (val))
@@ -19568,11 +19640,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
       }
 
     case 't':                  /* indicate TEXT or BINARY */
-#ifdef MODE_LINE_BINARY_TEXT
-      return MODE_LINE_BINARY_TEXT (b);
-#else
       return "T";
-#endif
 
     case 'z':
       /* coding-system (not including end-of-line format) */
@@ -19593,7 +19661,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
                                         (FRAME_TERMINAL_CODING (f)->id),
                                         p, 0);
          }
-       p = decode_mode_spec_coding (B_ (b, buffer_file_coding_system),
+       p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
                                     p, eol_flag);
 
 #if 0 /* This proves to be annoying; I think we can do without.  -- rms.  */
@@ -19623,14 +19691,14 @@ decode_mode_spec (struct window *w, register int c, int field_width,
 }
 
 
-/* Count up to COUNT lines starting from START / START_BYTE.
+/* Count up to COUNT lines starting from START_BYTE.
    But don't go beyond LIMIT_BYTE.
    Return the number of lines thus found (always nonnegative).
 
    Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT.  */
 
 static int
-display_count_lines (EMACS_INT start, EMACS_INT start_byte,
+display_count_lines (EMACS_INT start_byte,
                     EMACS_INT limit_byte, int count,
                     EMACS_INT *byte_pos_ptr)
 {
@@ -19643,8 +19711,8 @@ display_count_lines (EMACS_INT start, EMACS_INT start_byte,
 
   /* If we are not in selective display mode,
      check only for newlines.  */
-  int selective_display = (!NILP (B_ (current_buffer, selective_display))
-                          && !INTEGERP (B_ (current_buffer, selective_display)));
+  int selective_display = (!NILP (BVAR (current_buffer, selective_display))
+                          && !INTEGERP (BVAR (current_buffer, selective_display)));
 
   if (count > 0)
     {
@@ -19911,16 +19979,16 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st
            {
              if (!FRAME_WINDOW_P (it->f))
                {
-                 int i, n;
+                 int ii, n;
 
                  if (it->current_x > it->last_visible_x)
                    {
-                     for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
-                       if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
+                     for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
+                       if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
                          break;
-                     for (n = row->used[TEXT_AREA]; i < n; ++i)
+                     for (n = row->used[TEXT_AREA]; ii < n; ++ii)
                        {
-                         row->used[TEXT_AREA] = i;
+                         row->used[TEXT_AREA] = ii;
                          produce_special_glyphs (it, IT_TRUNCATION);
                        }
                    }
@@ -20394,16 +20462,15 @@ append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
 }
 
 
-/* Get face and two-byte form of character C in face FACE_ID on frame
-   F.  The encoding of C is returned in *CHAR2B.  MULTIBYTE_P non-zero
-   means we want to display multibyte text.  DISPLAY_P non-zero means
+/* Get face and two-byte form of character C in face FACE_ID on frame F.
+   The encoding of C is returned in *CHAR2B.  DISPLAY_P non-zero means
    make sure that X resources for the face returned are allocated.
    Value is a pointer to a realized face that is ready for display if
    DISPLAY_P is non-zero.  */
 
 static INLINE struct face *
 get_char_face_and_encoding (struct frame *f, int c, int face_id,
-                           XChar2b *char2b, int multibyte_p, int display_p)
+                           XChar2b *char2b, int display_p)
 {
   struct face *face = FACE_FROM_ID (f, face_id);
 
@@ -20523,7 +20590,7 @@ fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
                                       -1, Qnil);
 
          face = get_char_face_and_encoding (s->f, c, face_id,
-                                            s->char2b + i, 1, 1);
+                                            s->char2b + i, 1);
          if (face)
            {
              if (! s->face)
@@ -20722,15 +20789,13 @@ fill_image_glyph_string (struct glyph_string *s)
 
 /* Fill glyph string S from a sequence of stretch glyphs.
 
-   ROW is the glyph row in which the glyphs are found, AREA is the
-   area within the row.  START is the index of the first glyph to
-   consider, END is the index of the last + 1.
+   START is the index of the first glyph to consider,
+   END is the index of the last + 1.
 
    Value is the index of the first glyph not in S.  */
 
 static int
-fill_stretch_glyph_string (struct glyph_string *s, struct glyph_row *row,
-                          enum glyph_row_area area, int start, int end)
+fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
 {
   struct glyph *glyph, *last;
   int voffset, face_id;
@@ -20764,7 +20829,7 @@ fill_stretch_glyph_string (struct glyph_string *s, struct glyph_row *row,
 }
 
 static struct font_metrics *
-get_per_char_metric (struct frame *f, struct font *font, XChar2b *char2b)
+get_per_char_metric (struct font *font, XChar2b *char2b)
 {
   static struct font_metrics metrics;
   unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
@@ -20792,7 +20857,7 @@ x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *rig
       struct font_metrics *pcm;
 
       face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
-      if (face->font && (pcm = get_per_char_metric (f, face->font, &char2b)))
+      if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
        {
          if (pcm->rbearing > pcm->width)
            *right = pcm->rbearing - pcm->width;
@@ -21026,7 +21091,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
        {                                                                   \
         s = (struct glyph_string *) alloca (sizeof *s);                    \
         INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL);              \
-        START = fill_stretch_glyph_string (s, row, area, START, END);      \
+        START = fill_stretch_glyph_string (s, START, END);                 \
         append_glyph_string (&HEAD, &TAIL, s);                             \
          s->x = (X);                                                       \
        }                                                                   \
@@ -21097,7 +21162,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
     int cmp_id = (row)->glyphs[area][START].u.cmp.id;                      \
     struct composition *cmp = composition_table[cmp_id];                   \
     XChar2b *char2b;                                                       \
-    struct glyph_string *first_s;                                          \
+    struct glyph_string *first_s IF_LINT (= NULL);                         \
     int n;                                                                 \
                                                                            \
     char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len);       \
@@ -21152,7 +21217,6 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
   do                                                                       \
     {                                                                      \
       int face_id;                                                         \
-      XChar2b *char2b;                                                     \
                                                                            \
       face_id = (row)->glyphs[area][START].face_id;                        \
                                                                            \
@@ -21302,7 +21366,8 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
     {
       struct glyph_string *h, *t;
       Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
-      int mouse_beg_col, mouse_end_col, check_mouse_face = 0;
+      int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
+      int check_mouse_face = 0;
       int dummy_x = 0;
 
       /* If mouse highlighting is on, we may need to draw adjacent
@@ -22249,7 +22314,8 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
     }
   else
     {
-      char buf[7], *str;
+      char buf[7];
+      const char *str;
       unsigned int code[6];
       int upper_len;
       int ascent, descent;
@@ -22297,7 +22363,13 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
          if (metrics_upper.width >= metrics_lower.width)
            lower_xoff = (width - metrics_lower.width) / 2;
          else
-           upper_xoff = (width - metrics_upper.width) / 2;
+           {
+             /* FIXME: This code doesn't look right.  It formerly was
+                missing the "lower_xoff = 0;", which couldn't have
+                been right since it left lower_xoff uninitialized.  */
+             lower_xoff = 0;
+             upper_xoff = (width - metrics_upper.width) / 2;
+           }
        }
 
       /* +5 is for horizontal bars of a box plus 1-pixel spaces at
@@ -22392,7 +22464,7 @@ x_produce_glyphs (struct it *it)
 
          if (get_char_glyph_code (it->char_to_display, font, &char2b))
            {
-             pcm = get_per_char_metric (it->f, font, &char2b);
+             pcm = get_per_char_metric (font, &char2b);
              if (pcm->width == 0
                  && pcm->rbearing == 0 && pcm->lbearing == 0)
                pcm = NULL;
@@ -22694,8 +22766,8 @@ x_produce_glyphs (struct it *it)
          if (! font_not_found_p)
            {
              get_char_face_and_encoding (it->f, c, it->face_id,
-                                         &char2b, it->multibyte_p, 0);
-             pcm = get_per_char_metric (it->f, font, &char2b);
+                                         &char2b, 0);
+             pcm = get_per_char_metric (font, &char2b);
            }
 
          /* Initialize the bounding box.  */
@@ -22743,7 +22815,6 @@ x_produce_glyphs (struct it *it)
              int ch = COMPOSITION_GLYPH (cmp, i);
              int face_id;
              struct face *this_face;
-             int this_boff;
 
              if (ch == '\t')
                ch = ' ';
@@ -22755,12 +22826,9 @@ x_produce_glyphs (struct it *it)
                pcm = NULL;
              else
                {
-                 this_boff = font->baseline_offset;
-                 if (font->vertical_centering)
-                   this_boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
                  get_char_face_and_encoding (it->f, ch, face_id,
-                                             &char2b, it->multibyte_p, 0);
-                 pcm = get_per_char_metric (it->f, font, &char2b);
+                                             &char2b, 0);
+                 pcm = get_per_char_metric (font, &char2b);
                }
              if (! pcm)
                cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
@@ -23239,7 +23307,7 @@ get_specified_cursor_type (Lisp_Object arg, int *width)
 void
 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
 {
-  int width;
+  int width = 1;
   Lisp_Object tem;
 
   FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
@@ -23291,13 +23359,13 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
     {
       if (w == XWINDOW (echo_area_window))
        {
-         if (EQ (B_ (b, cursor_type), Qt) || NILP (B_ (b, cursor_type)))
+         if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
            {
              *width = FRAME_CURSOR_WIDTH (f);
              return FRAME_DESIRED_CURSOR (f);
            }
          else
-           return get_specified_cursor_type (B_ (b, cursor_type), width);
+           return get_specified_cursor_type (BVAR (b, cursor_type), width);
        }
 
       *active_cursor = 0;
@@ -23317,23 +23385,23 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
     }
 
   /* Never display a cursor in a window in which cursor-type is nil.  */
-  if (NILP (B_ (b, cursor_type)))
+  if (NILP (BVAR (b, cursor_type)))
     return NO_CURSOR;
 
   /* Get the normal cursor type for this window.  */
-  if (EQ (B_ (b, cursor_type), Qt))
+  if (EQ (BVAR (b, cursor_type), Qt))
     {
       cursor_type = FRAME_DESIRED_CURSOR (f);
       *width = FRAME_CURSOR_WIDTH (f);
     }
   else
-    cursor_type = get_specified_cursor_type (B_ (b, cursor_type), width);
+    cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
 
   /* Use cursor-in-non-selected-windows instead
      for non-selected window or frame.  */
   if (non_selected)
     {
-      alt_cursor = B_ (b, cursor_in_non_selected_windows);
+      alt_cursor = BVAR (b, cursor_in_non_selected_windows);
       if (!EQ (Qt, alt_cursor))
        return get_specified_cursor_type (alt_cursor, width);
       /* t means modify the normal cursor type.  */
@@ -23380,7 +23448,7 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
   /* Cursor is blinked off, so determine how to "toggle" it.  */
 
   /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist.  */
-  if ((alt_cursor = Fassoc (B_ (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
+  if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
     return get_specified_cursor_type (XCDR (alt_cursor), width);
 
   /* Then see if frame has specified a specific blink off cursor type.  */
@@ -23770,7 +23838,7 @@ display_and_set_cursor (struct window *w, int on,
 /* Switch the display of W's cursor on or off, according to the value
    of ON.  */
 
-void
+static void
 update_window_cursor (struct window *w, int on)
 {
   /* Don't update cursor in windows whose frame is in the process
@@ -24184,7 +24252,7 @@ rows_from_pos_range (struct window *w,
    for the overlay or run of text properties specifying the mouse
    face.  BEFORE_STRING and AFTER_STRING, if non-nil, are a
    before-string and after-string that must also be highlighted.
-   DISPLAY_STRING, if non-nil, is a display string that may cover some
+   COVER_STRING, if non-nil, is a display string that may cover some
    or all of the highlighted text.  */
 
 static void
@@ -24195,7 +24263,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
                            EMACS_INT end_charpos,
                            Lisp_Object before_string,
                            Lisp_Object after_string,
-                           Lisp_Object display_string)
+                           Lisp_Object cover_string)
 {
   struct window *w = XWINDOW (window);
   struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
@@ -24204,7 +24272,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
   EMACS_INT ignore, pos;
   int x;
 
-  xassert (NILP (display_string) || STRINGP (display_string));
+  xassert (NILP (cover_string) || STRINGP (cover_string));
   xassert (NILP (before_string) || STRINGP (before_string));
   xassert (NILP (after_string) || STRINGP (after_string));
 
@@ -24214,7 +24282,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
     r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
   /* If the before-string or display-string contains newlines,
      rows_from_pos_range skips to its last row.  Move back.  */
-  if (!NILP (before_string) || !NILP (display_string))
+  if (!NILP (before_string) || !NILP (cover_string))
     {
       struct glyph_row *prev;
       while ((prev = r1 - 1, prev >= first)
@@ -24226,7 +24294,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
          while (--glyph >= beg && INTEGERP (glyph->object));
          if (glyph < beg
              || !(EQ (glyph->object, before_string)
-                  || EQ (glyph->object, display_string)))
+                  || EQ (glyph->object, cover_string)))
            break;
          r1 = prev;
        }
@@ -24269,7 +24337,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
   hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
 
   /* For a bidi-reordered row, the positions of BEFORE_STRING,
-     AFTER_STRING, DISPLAY_STRING, START_CHARPOS, and END_CHARPOS
+     AFTER_STRING, COVER_STRING, START_CHARPOS, and END_CHARPOS
      could be anywhere in the row and in any order.  The strategy
      below is to find the leftmost and the rightmost glyph that
      belongs to either of these 3 strings, or whose position is
@@ -24295,11 +24363,11 @@ mouse_face_from_buffer_pos (Lisp_Object window,
          x += glyph->pixel_width;
 
       /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
-        or DISPLAY_STRING, and the first glyph from buffer whose
+        or COVER_STRING, and the first glyph from buffer whose
         position is between START_CHARPOS and END_CHARPOS.  */
       for (; glyph < end
             && !INTEGERP (glyph->object)
-            && !EQ (glyph->object, display_string)
+            && !EQ (glyph->object, cover_string)
             && !(BUFFERP (glyph->object)
                  && (glyph->charpos >= start_charpos
                      && glyph->charpos < end_charpos));
@@ -24310,7 +24378,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
             END_CHARPOS, or if they come from an overlay.  */
          if (EQ (glyph->object, before_string))
            {
-             pos = string_buffer_position (w, before_string,
+             pos = string_buffer_position (before_string,
                                            start_charpos);
              /* If pos == 0, it means before_string came from an
                 overlay, not from a buffer position.  */
@@ -24319,7 +24387,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
            }
          else if (EQ (glyph->object, after_string))
            {
-             pos = string_buffer_position (w, after_string, end_charpos);
+             pos = string_buffer_position (after_string, end_charpos);
              if (!pos || (pos >= start_charpos && pos < end_charpos))
                break;
            }
@@ -24346,11 +24414,11 @@ mouse_face_from_buffer_pos (Lisp_Object window,
          ;
 
       /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
-        or DISPLAY_STRING, and the first glyph from buffer whose
+        or COVER_STRING, and the first glyph from buffer whose
         position is between START_CHARPOS and END_CHARPOS.  */
       for (; glyph > end
             && !INTEGERP (glyph->object)
-            && !EQ (glyph->object, display_string)
+            && !EQ (glyph->object, cover_string)
             && !(BUFFERP (glyph->object)
                  && (glyph->charpos >= start_charpos
                      && glyph->charpos < end_charpos));
@@ -24361,7 +24429,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
             END_CHARPOS, or if they come from an overlay.  */
          if (EQ (glyph->object, before_string))
            {
-             pos = string_buffer_position (w, before_string, start_charpos);
+             pos = string_buffer_position (before_string, start_charpos);
              /* If pos == 0, it means before_string came from an
                 overlay, not from a buffer position.  */
              if (!pos || (pos >= start_charpos && pos < end_charpos))
@@ -24369,7 +24437,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
            }
          else if (EQ (glyph->object, after_string))
            {
-             pos = string_buffer_position (w, after_string, end_charpos);
+             pos = string_buffer_position (after_string, end_charpos);
              if (!pos || (pos >= start_charpos && pos < end_charpos))
                break;
            }
@@ -24411,12 +24479,12 @@ mouse_face_from_buffer_pos (Lisp_Object window,
        --end;
       /* Scan the rest of the glyph row from the end, looking for the
         first glyph that comes from BEFORE_STRING, AFTER_STRING, or
-        DISPLAY_STRING, or whose position is between START_CHARPOS
+        COVER_STRING, or whose position is between START_CHARPOS
         and END_CHARPOS */
       for (--end;
             end > glyph
             && !INTEGERP (end->object)
-            && !EQ (end->object, display_string)
+            && !EQ (end->object, cover_string)
             && !(BUFFERP (end->object)
                  && (end->charpos >= start_charpos
                      && end->charpos < end_charpos));
@@ -24427,13 +24495,13 @@ mouse_face_from_buffer_pos (Lisp_Object window,
             END_CHARPOS, or if they come from an overlay.  */
          if (EQ (end->object, before_string))
            {
-             pos = string_buffer_position (w, before_string, start_charpos);
+             pos = string_buffer_position (before_string, start_charpos);
              if (!pos || (pos >= start_charpos && pos < end_charpos))
                break;
            }
          else if (EQ (end->object, after_string))
            {
-             pos = string_buffer_position (w, after_string, end_charpos);
+             pos = string_buffer_position (after_string, end_charpos);
              if (!pos || (pos >= start_charpos && pos < end_charpos))
                break;
            }
@@ -24461,12 +24529,12 @@ mouse_face_from_buffer_pos (Lisp_Object window,
        }
       /* Scan the rest of the glyph row from the end, looking for the
         first glyph that comes from BEFORE_STRING, AFTER_STRING, or
-        DISPLAY_STRING, or whose position is between START_CHARPOS
+        COVER_STRING, or whose position is between START_CHARPOS
         and END_CHARPOS */
       for ( ;
             end < glyph
             && !INTEGERP (end->object)
-            && !EQ (end->object, display_string)
+            && !EQ (end->object, cover_string)
             && !(BUFFERP (end->object)
                  && (end->charpos >= start_charpos
                      && end->charpos < end_charpos));
@@ -24477,13 +24545,13 @@ mouse_face_from_buffer_pos (Lisp_Object window,
             END_CHARPOS, or if they come from an overlay.  */
          if (EQ (end->object, before_string))
            {
-             pos = string_buffer_position (w, before_string, start_charpos);
+             pos = string_buffer_position (before_string, start_charpos);
              if (!pos || (pos >= start_charpos && pos < end_charpos))
                break;
            }
          else if (EQ (end->object, after_string))
            {
-             pos = string_buffer_position (w, after_string, end_charpos);
+             pos = string_buffer_position (after_string, end_charpos);
              if (!pos || (pos >= start_charpos && pos < end_charpos))
                break;
            }
@@ -24960,10 +25028,9 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
              CONSP (hotspot))
          && (hotspot = XCDR (hotspot), CONSP (hotspot)))
        {
-         Lisp_Object area_id, plist;
+         Lisp_Object plist;
 
-         area_id = XCAR (hotspot);
-         /* Could check AREA_ID to see if we enter/leave this hot-spot.
+         /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
             If so, we could look for mouse-enter, mouse-leave
             properties in PLIST (and do something...).  */
          hotspot = XCDR (hotspot);
@@ -25272,7 +25339,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
       EMACS_INT pos;
       struct glyph *glyph;
       Lisp_Object object;
-      Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
+      Lisp_Object mouse_face = Qnil, position;
       Lisp_Object *overlay_vec = NULL;
       int noverlays;
       struct buffer *obuf;
@@ -25298,10 +25365,10 @@ note_mouse_highlight (struct frame *f, int x, int y)
                      CONSP (hotspot))
                  && (hotspot = XCDR (hotspot), CONSP (hotspot)))
                {
-                 Lisp_Object area_id, plist;
+                 Lisp_Object plist;
 
-                 area_id = XCAR (hotspot);
-                 /* Could check AREA_ID to see if we enter/leave this hot-spot.
+                 /* Could check XCAR (hotspot) to see if we enter/leave
+                    this hot-spot.
                     If so, we could look for mouse-enter, mouse-leave
                     properties in PLIST (and do something...).  */
                  hotspot = XCDR (hotspot);
@@ -25405,7 +25472,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
              && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
        {
          /* Find the highest priority overlay with a mouse-face.  */
-         overlay = Qnil;
+         Lisp_Object overlay = Qnil;
          for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
            {
              mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
@@ -25433,19 +25500,19 @@ note_mouse_highlight (struct frame *f, int x, int y)
            {
              /* The mouse-highlighting comes from a display string
                 with a mouse-face.  */
-             Lisp_Object b, e;
+             Lisp_Object s, e;
              EMACS_INT ignore;
 
-             b = Fprevious_single_property_change
+             s = Fprevious_single_property_change
                (make_number (pos + 1), Qmouse_face, object, Qnil);
              e = Fnext_single_property_change
                (position, Qmouse_face, object, Qnil);
-             if (NILP (b))
-               b = make_number (0);
+             if (NILP (s))
+               s = make_number (0);
              if (NILP (e))
                e = make_number (SCHARS (object) - 1);
              mouse_face_from_string_pos (w, hlinfo, object,
-                                         XINT (b), XINT (e));
+                                         XINT (s), XINT (e));
              hlinfo->mouse_face_past_end = 0;
              hlinfo->mouse_face_window = window;
              hlinfo->mouse_face_face_id
@@ -25458,7 +25525,8 @@ note_mouse_highlight (struct frame *f, int x, int y)
            {
              /* The mouse-highlighting, if any, comes from an overlay
                 or text property in the buffer.  */
-             Lisp_Object buffer, display_string;
+             Lisp_Object buffer IF_LINT (= Qnil);
+             Lisp_Object cover_string IF_LINT (= Qnil);
 
              if (STRINGP (object))
                {
@@ -25466,19 +25534,19 @@ note_mouse_highlight (struct frame *f, int x, int y)
                     check if the text under it has one.  */
                  struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
                  EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
-                 pos = string_buffer_position (w, object, start);
+                 pos = string_buffer_position (object, start);
                  if (pos > 0)
                    {
                      mouse_face = get_char_property_and_overlay
                        (make_number (pos), Qmouse_face, w->buffer, &overlay);
                      buffer = w->buffer;
-                     display_string = object;
+                     cover_string = object;
                    }
                }
              else
                {
                  buffer = object;
-                 display_string = Qnil;
+                 cover_string = Qnil;
                }
 
              if (!NILP (mouse_face))
@@ -25496,11 +25564,11 @@ note_mouse_highlight (struct frame *f, int x, int y)
                     necessarily display the character whose position
                     is the smallest.  */
                  Lisp_Object lim1 =
-                   NILP (B_ (XBUFFER (buffer), bidi_display_reordering))
+                   NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
                    ? Fmarker_position (w->start)
                    : Qnil;
                  Lisp_Object lim2 =
-                   NILP (B_ (XBUFFER (buffer), bidi_display_reordering))
+                   NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
                    ? make_number (BUF_Z (XBUFFER (buffer))
                                   - XFASTINT (w->window_end_pos))
                    : Qnil;
@@ -25530,7 +25598,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
                                              XFASTINT (before),
                                              XFASTINT (after),
                                              before_string, after_string,
-                                             display_string);
+                                             cover_string);
                  cursor = No_Cursor;
                }
            }
@@ -25559,16 +25627,16 @@ note_mouse_highlight (struct frame *f, int x, int y)
          }
        else
          {
-           Lisp_Object object = glyph->object;
+           Lisp_Object obj = glyph->object;
            EMACS_INT charpos = glyph->charpos;
 
            /* Try text properties.  */
-           if (STRINGP (object)
+           if (STRINGP (obj)
                && charpos >= 0
-               && charpos < SCHARS (object))
+               && charpos < SCHARS (obj))
              {
                help = Fget_text_property (make_number (charpos),
-                                          Qhelp_echo, object);
+                                          Qhelp_echo, obj);
                if (NILP (help))
                  {
                    /* If the string itself doesn't specify a help-echo,
@@ -25576,30 +25644,30 @@ note_mouse_highlight (struct frame *f, int x, int y)
                    struct glyph_row *r
                      = MATRIX_ROW (w->current_matrix, vpos);
                    EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
-                   EMACS_INT pos = string_buffer_position (w, object, start);
-                   if (pos > 0)
+                   EMACS_INT p = string_buffer_position (obj, start);
+                   if (p > 0)
                      {
-                       help = Fget_char_property (make_number (pos),
+                       help = Fget_char_property (make_number (p),
                                                   Qhelp_echo, w->buffer);
                        if (!NILP (help))
                          {
-                           charpos = pos;
-                           object = w->buffer;
+                           charpos = p;
+                           obj = w->buffer;
                          }
                      }
                  }
              }
-           else if (BUFFERP (object)
+           else if (BUFFERP (obj)
                     && charpos >= BEGV
                     && charpos < ZV)
              help = Fget_text_property (make_number (charpos), Qhelp_echo,
-                                        object);
+                                        obj);
 
            if (!NILP (help))
              {
                help_echo_string = help;
                help_echo_window = window;
-               help_echo_object = object;
+               help_echo_object = obj;
                help_echo_pos = charpos;
              }
          }
@@ -25615,16 +25683,16 @@ note_mouse_highlight (struct frame *f, int x, int y)
 
          if (NILP (pointer))
            {
-             Lisp_Object object = glyph->object;
+             Lisp_Object obj = glyph->object;
              EMACS_INT charpos = glyph->charpos;
 
              /* Try text properties.  */
-             if (STRINGP (object)
+             if (STRINGP (obj)
                  && charpos >= 0
-                 && charpos < SCHARS (object))
+                 && charpos < SCHARS (obj))
                {
                  pointer = Fget_text_property (make_number (charpos),
-                                               Qpointer, object);
+                                               Qpointer, obj);
                  if (NILP (pointer))
                    {
                      /* If the string itself doesn't specify a pointer,
@@ -25632,18 +25700,17 @@ note_mouse_highlight (struct frame *f, int x, int y)
                      struct glyph_row *r
                        = MATRIX_ROW (w->current_matrix, vpos);
                      EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
-                     EMACS_INT pos = string_buffer_position (w, object,
-                                                             start);
-                     if (pos > 0)
-                       pointer = Fget_char_property (make_number (pos),
+                     EMACS_INT p = string_buffer_position (obj, start);
+                     if (p > 0)
+                       pointer = Fget_char_property (make_number (p),
                                                      Qpointer, w->buffer);
                    }
                }
-             else if (BUFFERP (object)
+             else if (BUFFERP (obj)
                       && charpos >= BEGV
                       && charpos < ZV)
                pointer = Fget_text_property (make_number (charpos),
-                                             Qpointer, object);
+                                             Qpointer, obj);
            }
        }
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -26164,10 +26231,10 @@ expose_frame (struct frame *f, int x, int y, int w, int h)
       Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
       if (f == hlinfo->mouse_face_mouse_frame)
        {
-         int x = hlinfo->mouse_face_mouse_x;
-         int y = hlinfo->mouse_face_mouse_y;
+         int mouse_x = hlinfo->mouse_face_mouse_x;
+         int mouse_y = hlinfo->mouse_face_mouse_y;
          clear_mouse_face (hlinfo);
-         note_mouse_highlight (f, x, y);
+         note_mouse_highlight (f, mouse_x, mouse_y);
        }
     }
 }
@@ -26510,6 +26577,10 @@ If point moves off-screen, redisplay will scroll by up to
 onto the screen again.  If that cannot be done, then redisplay
 recenters point as usual.
 
+If the value is greater than 100, redisplay will never recenter point,
+but will always scroll just enough text to bring point into view, even
+if you move far away.
+
 A value of zero means always recenter point if it moves off screen.  */);
   scroll_conservatively = 0;