Simplify and avoid signal-handling races.
[bpt/emacs.git] / src / xdisp.c
index 36196e8..423ecab 100644 (file)
@@ -273,9 +273,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <config.h>
 #include <stdio.h>
 #include <limits.h>
-#include <setjmp.h>
 
 #include "lisp.h"
+#include "atimer.h"
 #include "keyboard.h"
 #include "frame.h"
 #include "window.h"
@@ -365,6 +365,28 @@ Lisp_Object Qcenter;
 static Lisp_Object Qmargin, Qpointer;
 static Lisp_Object Qline_height;
 
+/* These setters are used only in this file, so they can be private.  */
+static inline void
+wset_base_line_number (struct window *w, Lisp_Object val)
+{
+  w->base_line_number = val;
+}
+static inline void
+wset_base_line_pos (struct window *w, Lisp_Object val)
+{
+  w->base_line_pos = val;
+}
+static inline void
+wset_column_number_displayed (struct window *w, Lisp_Object val)
+{
+  w->column_number_displayed = val;
+}
+static inline void
+wset_region_showing (struct window *w, Lisp_Object val)
+{
+  w->region_showing = val;
+}
+
 #ifdef HAVE_WINDOW_SYSTEM
 
 /* Test if overflow newline into fringe.  Called with iterator IT
@@ -746,9 +768,9 @@ static int clear_image_cache_count;
 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
 #endif
 
-/* Non-zero while redisplay_internal is in progress.  */
+/* True while redisplay_internal is in progress.  */
 
-int redisplaying_p;
+bool redisplaying_p;
 
 static Lisp_Object Qinhibit_free_realized_faces;
 static Lisp_Object Qmode_line_default_help_echo;
@@ -838,7 +860,6 @@ static int string_char_and_length (const unsigned char *, int *);
 static struct text_pos display_prop_end (struct it *, Lisp_Object,
                                          struct text_pos);
 static int compute_window_start_on_continuation_line (struct window *);
-static Lisp_Object safe_eval_handler (Lisp_Object);
 static void insert_left_trunc_glyphs (struct it *);
 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
                                                       Lisp_Object);
@@ -1310,7 +1331,7 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
   if (WINDOW_WANTS_HEADER_LINE_P (w))
     current_header_line_height
       = display_mode_line (w, HEADER_LINE_FACE_ID,
-                              BVAR (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,
@@ -2397,9 +2418,10 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
 /* Error handler for safe_eval and safe_call.  */
 
 static Lisp_Object
-safe_eval_handler (Lisp_Object arg)
+safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
 {
-  add_to_log ("Error during redisplay: %S", arg, Qnil);
+  add_to_log ("Error during redisplay: %S signaled %S",
+             Flist (nargs, args), arg);
   return Qnil;
 }
 
@@ -2420,7 +2442,7 @@ safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
       ptrdiff_t i;
       ptrdiff_t count = SPECPDL_INDEX ();
       struct gcpro gcpro1;
-      Lisp_Object *args = alloca (nargs * sizeof (Lisp_Object));
+      Lisp_Object *args = alloca (nargs * word_size);
 
       args[0] = func;
       va_start (ap, func);
@@ -2591,7 +2613,8 @@ init_iterator (struct it *it, struct window *w,
 
   /* Perhaps remap BASE_FACE_ID to a user-specified alternative.  */
   if (! NILP (Vface_remapping_alist))
-    remapped_base_face_id = lookup_basic_face (XFRAME (w->frame), base_face_id);
+    remapped_base_face_id
+      = lookup_basic_face (XFRAME (w->frame), base_face_id);
 
   /* Use one of the mode line rows of W's desired matrix if
      appropriate.  */
@@ -2659,9 +2682,9 @@ init_iterator (struct it *it, struct window *w,
      is invisible.  >0 means lines indented more than this value are
      invisible.  */
   it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
-                  ? clip_to_bounds (-1, XINT (BVAR (current_buffer,
-                                                    selective_display)),
-                                    PTRDIFF_MAX)
+                  ? (clip_to_bounds
+                     (-1, XINT (BVAR (current_buffer, selective_display)),
+                      PTRDIFF_MAX))
                   : (!NILP (BVAR (current_buffer, selective_display))
                      ? -1 : 0));
   it->selective_display_ellipsis_p
@@ -3320,7 +3343,7 @@ compute_stop_pos (struct it *it)
      interval if there isn't such an interval.  */
   position = make_number (charpos);
   iv = validate_interval_range (object, &position, &position, 0);
-  if (!NULL_INTERVAL_P (iv))
+  if (iv)
     {
       Lisp_Object values_here[LAST_PROP_IDX];
       struct props *p;
@@ -3332,7 +3355,7 @@ compute_stop_pos (struct it *it)
       /* Look for an interval following iv that has different
         properties.  */
       for (next_iv = next_interval (iv);
-          (!NULL_INTERVAL_P (next_iv)
+          (next_iv
            && (NILP (limit)
                || XFASTINT (limit) > next_iv->position));
           next_iv = next_interval (next_iv))
@@ -3350,7 +3373,7 @@ compute_stop_pos (struct it *it)
            break;
        }
 
-      if (!NULL_INTERVAL_P (next_iv))
+      if (next_iv)
        {
          if (INTEGERP (limit)
              && next_iv->position >= XFASTINT (limit))
@@ -3643,7 +3666,7 @@ handle_fontified_prop (struct it *it)
        }
       /* 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)))
+      else if (BUFFER_LIVE_P (obuf))
        set_buffer_internal_1 (obuf);
 
       /* The fontification code may have added/removed text.
@@ -4046,38 +4069,54 @@ static enum prop_handled
 handle_invisible_prop (struct it *it)
 {
   enum prop_handled handled = HANDLED_NORMALLY;
+  int invis_p;
+  Lisp_Object prop;
 
   if (STRINGP (it->string))
     {
-      Lisp_Object prop, end_charpos, limit, charpos;
+      Lisp_Object end_charpos, limit, charpos;
 
       /* Get the value of the invisible text property at the
         current position.  Value will be nil if there is no such
         property.  */
       charpos = make_number (IT_STRING_CHARPOS (*it));
       prop = Fget_text_property (charpos, Qinvisible, it->string);
+      invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
 
-      if (!NILP (prop)
-         && IT_STRING_CHARPOS (*it) < it->end_charpos)
+      if (invis_p && IT_STRING_CHARPOS (*it) < it->end_charpos)
        {
-         ptrdiff_t endpos;
+         /* Record whether we have to display an ellipsis for the
+            invisible text.  */
+         int display_ellipsis_p = (invis_p == 2);
+         ptrdiff_t len, endpos;
 
          handled = HANDLED_RECOMPUTE_PROPS;
 
-         /* Get the position at which the next change of the
-            invisible text property can be found in IT->string.
-            Value will be nil if the property value is the same for
-            all the rest of IT->string.  */
-         XSETINT (limit, SCHARS (it->string));
-         end_charpos = Fnext_single_property_change (charpos, Qinvisible,
-                                                     it->string, limit);
-
-         /* Text at current position is invisible.  The next
-            change in the property is at position end_charpos.
-            Move IT's current position to that position.  */
-         if (INTEGERP (end_charpos)
-             && (endpos = XFASTINT (end_charpos)) < XFASTINT (limit))
+         /* Get the position at which the next visible text can be
+            found in IT->string, if any.  */
+         endpos = len = SCHARS (it->string);
+         XSETINT (limit, len);
+         do
+           {
+             end_charpos = Fnext_single_property_change (charpos, Qinvisible,
+                                                         it->string, limit);
+             if (INTEGERP (end_charpos))
+               {
+                 endpos = XFASTINT (end_charpos);
+                 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
+                 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
+                 if (invis_p == 2)
+                   display_ellipsis_p = 1;
+               }
+           }
+         while (invis_p && endpos < len);
+
+         if (display_ellipsis_p)
+           it->ellipsis_p = 1;
+
+         if (endpos < len)
            {
+             /* Text at END_CHARPOS is visible.  Move IT there.  */
              struct text_pos old;
              ptrdiff_t oldpos;
 
@@ -4113,7 +4152,8 @@ handle_invisible_prop (struct it *it)
              /* The rest of the string is invisible.  If this is an
                 overlay string, proceed with the next overlay string
                 or whatever comes and return a character from there.  */
-             if (it->current.overlay_string_index >= 0)
+             if (it->current.overlay_string_index >= 0
+                 && !display_ellipsis_p)
                {
                  next_overlay_string (it);
                  /* Don't check for overlay strings when we just
@@ -4130,9 +4170,8 @@ handle_invisible_prop (struct it *it)
     }
   else
     {
-      int invis_p;
       ptrdiff_t newpos, next_stop, start_charpos, tem;
-      Lisp_Object pos, prop, overlay;
+      Lisp_Object pos, overlay;
 
       /* First of all, is there invisible text at this position?  */
       tem = start_charpos = IT_CHARPOS (*it);
@@ -5308,6 +5347,7 @@ next_overlay_string (struct it *it)
       SET_TEXT_POS (it->current.string_pos, 0, 0);
       it->method = GET_FROM_STRING;
       it->stop_charpos = 0;
+      it->end_charpos = SCHARS (it->string);
       if (it->cmp_it.stop_pos >= 0)
        it->cmp_it.stop_pos = 0;
       it->prev_stop = 0;
@@ -6009,7 +6049,7 @@ back_to_previous_visible_line_start (struct it *it)
       {
        Lisp_Object prop;
        prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
-                                    Qinvisible, it->window);
+                                  Qinvisible, it->window);
        if (TEXT_PROP_MEANS_INVISIBLE (prop))
          continue;
       }
@@ -7267,7 +7307,7 @@ set_iterator_to_next (struct it *it, int reseat_p)
 
     default:
       /* There are no other methods defined, so this should be a bug.  */
-      abort ();
+      emacs_abort ();
     }
 
   eassert (it->method != GET_FROM_STRING
@@ -7717,12 +7757,12 @@ compute_stop_pos_backwards (struct it *it)
     {
       it->end_charpos = min (charpos + 1, ZV);
       charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
-      SET_TEXT_POS (pos, charpos, BYTE_TO_CHAR (charpos));
+      SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
       reseat_1 (it, pos, 0);
       compute_stop_pos (it);
       /* We must advance forward, right?  */
       if (it->stop_charpos <= charpos)
-       abort ();
+       emacs_abort ();
     }
   while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
 
@@ -7771,7 +7811,7 @@ handle_stop_backwards (struct it *it, ptrdiff_t charpos)
       compute_stop_pos (it);
       /* We must advance forward, right?  */
       if (it->stop_charpos <= it->prev_stop)
-       abort ();
+       emacs_abort ();
       charpos = it->stop_charpos;
     }
   while (charpos <= where_we_are);
@@ -7980,7 +8020,7 @@ run_redisplay_end_trigger_hook (struct it *it)
 
   /* Since we are *trying* to run these functions, don't try to run
      them again, even if they get an error.  */
-  it->w->redisplay_end_trigger = Qnil;
+  wset_redisplay_end_trigger (it->w, Qnil);
   Frun_hook_with_args (3, args);
 
   /* Notice if it changed the face of the character we are on.  */
@@ -8859,7 +8899,7 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
          break;
 
        default:
-         abort ();
+         emacs_abort ();
        }
 
       /* Reset/increment for the next run.  */
@@ -9252,12 +9292,6 @@ add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
   USE_SAFE_ALLOCA;
 
-  /* Do nothing if called asynchronously.  Inserting text into
-     a buffer may call after-change-functions and alike and
-     that would means running Lisp asynchronously.  */
-  if (handling_signal)
-    return;
-
   fmt = msg = Qnil;
   GCPRO4 (fmt, msg, arg1, arg2);
 
@@ -9267,7 +9301,7 @@ add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
   msg = Fformat (3, args);
 
   len = SBYTES (msg) + 1;
-  SAFE_ALLOCA (buffer, char *, len);
+  buffer = SAFE_ALLOCA (len);
   memcpy (buffer, SDATA (msg), len);
 
   message_dolog (buffer, len - 1, 1, 0);
@@ -9317,7 +9351,7 @@ message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte)
       old_deactivate_mark = Vdeactivate_mark;
       oldbuf = current_buffer;
       Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
-      BVAR (current_buffer, undo_list) = Qt;
+      bset_undo_list (current_buffer, Qt);
 
       oldpoint = message_dolog_marker1;
       set_marker_restricted (oldpoint, make_number (PT), Qnil);
@@ -9594,10 +9628,8 @@ message3 (Lisp_Object m, ptrdiff_t nbytes, int multibyte)
   message_log_maybe_newline ();
   if (STRINGP (m))
     {
-      char *buffer;
       USE_SAFE_ALLOCA;
-
-      SAFE_ALLOCA (buffer, char *, nbytes);
+      char *buffer = SAFE_ALLOCA (nbytes);
       memcpy (buffer, SDATA (m), nbytes);
       message_dolog (buffer, nbytes, 1, multibyte);
       SAFE_FREE ();
@@ -9872,7 +9904,7 @@ ensure_echo_area_buffers (void)
 
   for (i = 0; i < 2; ++i)
     if (!BUFFERP (echo_buffer[i])
-       || NILP (BVAR (XBUFFER (echo_buffer[i]), name)))
+       || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
       {
        char name[30];
        Lisp_Object old_buffer;
@@ -9881,7 +9913,7 @@ ensure_echo_area_buffers (void)
        old_buffer = echo_buffer[i];
        echo_buffer[i] = Fget_buffer_create
          (make_formatted_string (name, " *Echo Area %d*", i));
-       BVAR (XBUFFER (echo_buffer[i]), truncate_lines) = Qnil;
+       bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
        /* to force word wrap in echo area -
           it was decided to postpone this*/
        /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
@@ -9970,12 +10002,12 @@ with_echo_area_buffer (struct window *w, int which,
   set_buffer_internal_1 (XBUFFER (buffer));
   if (w)
     {
-      w->buffer = buffer;
+      wset_buffer (w, buffer);
       set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
     }
 
-  BVAR (current_buffer, undo_list) = Qt;
-  BVAR (current_buffer, read_only) = Qnil;
+  bset_undo_list (current_buffer, Qt);
+  bset_read_only (current_buffer, Qnil);
   specbind (Qinhibit_read_only, Qt);
   specbind (Qinhibit_modification_hooks, Qt);
 
@@ -10055,7 +10087,7 @@ unwind_with_echo_area_buffer (Lisp_Object vector)
       charpos = AREF (vector, 5);
       bytepos = AREF (vector, 6);
 
-      w->buffer = buffer;
+      wset_buffer (w, buffer);
       set_marker_both (w->pointm, buffer,
                       XFASTINT (charpos), XFASTINT (bytepos));
     }
@@ -10088,7 +10120,7 @@ setup_echo_area_for_printing (int multibyte_p)
 
       /* Switch to that buffer and clear it.  */
       set_buffer_internal (XBUFFER (echo_area_buffer[0]));
-      BVAR (current_buffer, truncate_lines) = Qnil;
+      bset_truncate_lines (current_buffer, Qnil);
 
       if (Z > BEG)
        {
@@ -10131,7 +10163,7 @@ setup_echo_area_for_printing (int multibyte_p)
        {
          /* Someone switched buffers between print requests.  */
          set_buffer_internal (XBUFFER (echo_area_buffer[0]));
-         BVAR (current_buffer, truncate_lines) = Qnil;
+         bset_truncate_lines (current_buffer, Qnil);
        }
     }
 }
@@ -10443,11 +10475,10 @@ current_message_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
    empty.  This is a relatively infrequent operation, so it's not
    worth optimizing.  */
 
-int
+bool
 push_message (void)
 {
-  Lisp_Object msg;
-  msg = current_message ();
+  Lisp_Object msg = current_message ();
   Vmessage_stack = Fcons (msg, Vmessage_stack);
   return STRINGP (msg);
 }
@@ -10496,7 +10527,7 @@ void
 check_message_stack (void)
 {
   if (!NILP (Vmessage_stack))
-    abort ();
+    emacs_abort ();
 }
 
 
@@ -10535,7 +10566,6 @@ truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4
   return 0;
 }
 
-
 /* Set the current message to a substring of S or STRING.
 
    If STRING is a Lisp string, set the message to the first NBYTES
@@ -10562,6 +10592,10 @@ set_message (const char *s, Lisp_Object string,
                         (intptr_t) s, string, nbytes, multibyte_p);
   message_buf_print = 0;
   help_echo_showing_p = 0;
+
+  if (STRINGP (Vdebug_on_message)
+      && fast_string_match (Vdebug_on_message, string) >= 0)
+    call_debugger (list2 (Qerror, string));
 }
 
 
@@ -10583,9 +10617,9 @@ set_message_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t nbytes, ptrdiff_t multiby
       != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
     Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
 
-  BVAR (current_buffer, truncate_lines) = message_truncate_lines ? Qt : Qnil;
+  bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
   if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
-    BVAR (current_buffer, bidi_paragraph_direction) = Qleft_to_right;
+    bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
 
   /* Insert new message at BEG.  */
   TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
@@ -10892,7 +10926,7 @@ format_mode_line_unwind_data (struct frame *target_frame,
       /* Similarly to `with-selected-window', if the operation selects
         a window on another frame, we must restore that frame's
         selected window, and (for a tty) the top-frame.  */
-      ASET (vector, 8, FVAR (target_frame, selected_window));
+      ASET (vector, 8, target_frame->selected_window);
       if (FRAME_TERMCAP_P (target_frame))
        ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
     }
@@ -11052,13 +11086,14 @@ x_consider_frame_title (Lisp_Object frame)
                             format_mode_line_unwind_data
                               (f, current_buffer, selected_window, 0));
 
-      Fselect_window (FVAR (f, selected_window), Qt);
-      set_buffer_internal_1 (XBUFFER (XWINDOW (FVAR (f, selected_window))->buffer));
+      Fselect_window (f->selected_window, Qt);
+      set_buffer_internal_1
+       (XBUFFER (XWINDOW (f->selected_window)->buffer));
       fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
 
       mode_line_target = MODE_LINE_TITLE;
       title_start = MODE_LINE_NOPROP_LEN (0);
-      init_iterator (&it, XWINDOW (FVAR (f, selected_window)), -1, -1,
+      init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
                     NULL, DEFAULT_FACE_ID);
       display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
       len = MODE_LINE_NOPROP_LEN (title_start);
@@ -11070,9 +11105,9 @@ x_consider_frame_title (Lisp_Object frame)
         already wasted too much time by walking through the list with
         display_mode_element, then we might need to optimize at a
         higher level than this.)  */
-      if (! STRINGP (FVAR (f, name))
-         || SBYTES (FVAR (f, name)) != len
-         || memcmp (title, SDATA (FVAR (f, name)), len) != 0)
+      if (! STRINGP (f->name)
+         || SBYTES (f->name) != len
+         || memcmp (title, SDATA (f->name), len) != 0)
        x_implicitly_set_name (f, make_string (title, len), Qnil);
     }
 }
@@ -11171,8 +11206,8 @@ prepare_menu_bars (void)
 #ifdef HAVE_NS
           if (windows_or_buffers_changed
              && FRAME_NS_P (f))
-            ns_set_doc_edited (f, Fbuffer_modified_p
-                              (XWINDOW (FVAR (f, selected_window))->buffer));
+            ns_set_doc_edited
+             (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->buffer));
 #endif
          UNGCPRO;
        }
@@ -11274,7 +11309,7 @@ update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
            }
 
          XSETFRAME (Vmenu_updating_frame, f);
-         FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
+         fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
 
          /* Redisplay the menu bar in case we changed it.  */
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
@@ -11368,11 +11403,11 @@ x_cursor_to (int vpos, int hpos, int y, int x)
      This will also set the cursor position of W.  */
   if (updated_window == NULL)
     {
-      BLOCK_INPUT;
+      block_input ();
       display_and_set_cursor (w, 1, hpos, vpos, x, y);
       if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
        FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
-      UNBLOCK_INPUT;
+      unblock_input ();
     }
 }
 
@@ -11413,8 +11448,8 @@ update_tool_bar (struct frame *f, int save_match_data)
 #if defined (USE_GTK) || defined (HAVE_NS)
   int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
 #else
-  int do_update = WINDOWP (FVAR (f, tool_bar_window))
-    && WINDOW_TOTAL_LINES (XWINDOW (FVAR (f, tool_bar_window))) > 0;
+  int do_update = WINDOWP (f->tool_bar_window)
+    && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
 #endif
 
   if (do_update)
@@ -11475,21 +11510,22 @@ update_tool_bar (struct frame *f, int save_match_data)
          selected_frame = frame;
 
          /* Build desired tool-bar items from keymaps.  */
-          new_tool_bar = tool_bar_items 
-           (Fcopy_sequence (FVAR (f, tool_bar_items)), &new_n_tool_bar);
+          new_tool_bar
+           = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
+                             &new_n_tool_bar);
 
          /* Redisplay the tool-bar if we changed it.  */
          if (new_n_tool_bar != f->n_tool_bar_items
-             || NILP (Fequal (new_tool_bar, FVAR (f, tool_bar_items))))
+             || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
             {
               /* Redisplay that happens asynchronously due to an expose event
                  may access f->tool_bar_items.  Make sure we update both
                  variables within BLOCK_INPUT so no such event interrupts.  */
-              BLOCK_INPUT;
-              FVAR (f, tool_bar_items) = new_tool_bar;
+              block_input ();
+              fset_tool_bar_items (f, new_tool_bar);
               f->n_tool_bar_items = new_n_tool_bar;
               w->update_mode_line = 1;
-              UNBLOCK_INPUT;
+              unblock_input ();
             }
 
          UNGCPRO;
@@ -11519,22 +11555,22 @@ build_desired_tool_bar_string (struct frame *f)
      Otherwise, make a new string.  */
 
   /* The size of the string we might be able to reuse.  */
-  size = (STRINGP (FVAR (f, desired_tool_bar_string))
-         ? SCHARS (FVAR (f, desired_tool_bar_string))
+  size = (STRINGP (f->desired_tool_bar_string)
+         ? SCHARS (f->desired_tool_bar_string)
          : 0);
 
   /* We need one space in the string for each image.  */
   size_needed = f->n_tool_bar_items;
 
   /* Reuse f->desired_tool_bar_string, if possible.  */
-  if (size < size_needed || NILP (FVAR (f, desired_tool_bar_string)))
-    FVAR (f, desired_tool_bar_string)
-      = Fmake_string (make_number (size_needed), make_number (' '));
+  if (size < size_needed || NILP (f->desired_tool_bar_string))
+    fset_desired_tool_bar_string
+      (f, Fmake_string (make_number (size_needed), make_number (' ')));
   else
     {
       props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
       Fremove_text_properties (make_number (0), make_number (size),
-                              props, FVAR (f, desired_tool_bar_string));
+                              props, f->desired_tool_bar_string);
     }
 
   /* Put a `display' property on the string for the images to display,
@@ -11543,7 +11579,7 @@ build_desired_tool_bar_string (struct frame *f)
   for (i = 0; i < f->n_tool_bar_items; ++i)
     {
 #define PROP(IDX) \
-  AREF (FVAR (f, tool_bar_items), i * TOOL_BAR_ITEM_NSLOTS + (IDX))
+  AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
 
       int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
       int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
@@ -11652,11 +11688,11 @@ build_desired_tool_bar_string (struct frame *f)
          string.  The string can be longer than needed when we reuse a
          previous string.  */
       if (i + 1 == f->n_tool_bar_items)
-       end = SCHARS (FVAR (f, desired_tool_bar_string));
+       end = SCHARS (f->desired_tool_bar_string);
       else
        end = i + 1;
       Fadd_text_properties (make_number (i), make_number (end),
-                           props, FVAR (f, desired_tool_bar_string));
+                           props, f->desired_tool_bar_string);
 #undef PROP
     }
 
@@ -11806,7 +11842,7 @@ display_tool_bar_line (struct it *it, int height)
 static int
 tool_bar_lines_needed (struct frame *f, int *n_rows)
 {
-  struct window *w = XWINDOW (FVAR (f, tool_bar_window));
+  struct window *w = XWINDOW (f->tool_bar_window);
   struct it it;
   /* tool_bar_lines_needed is called from redisplay_tool_bar after building
      the desired matrix, so use (unused) mode-line row as temporary row to
@@ -11818,7 +11854,7 @@ tool_bar_lines_needed (struct frame *f, int *n_rows)
   init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
   it.first_visible_x = 0;
   it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
-  reseat_to_string (&it, NULL, FVAR (f, desired_tool_bar_string), 0, 0, 0, -1);
+  reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
   it.paragraph_embedding = L2R;
 
   while (!ITERATOR_AT_END_P (&it))
@@ -11852,8 +11888,8 @@ DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
     CHECK_FRAME (frame);
   f = XFRAME (frame);
 
-  if (WINDOWP (FVAR (f, tool_bar_window))
-      && (w = XWINDOW (FVAR (f, tool_bar_window)),
+  if (WINDOWP (f->tool_bar_window)
+      && (w = XWINDOW (f->tool_bar_window),
          WINDOW_TOTAL_LINES (w) > 0))
     {
       update_tool_bar (f, 1);
@@ -11888,8 +11924,8 @@ redisplay_tool_bar (struct frame *f)
      do anything.  This means you must start with tool-bar-lines
      non-zero to get the auto-sizing effect.  Or in other words, you
      can turn off tool-bars by specifying tool-bar-lines zero.  */
-  if (!WINDOWP (FVAR (f, tool_bar_window))
-      || (w = XWINDOW (FVAR (f, tool_bar_window)),
+  if (!WINDOWP (f->tool_bar_window)
+      || (w = XWINDOW (f->tool_bar_window),
           WINDOW_TOTAL_LINES (w) == 0))
     return 0;
 
@@ -11901,7 +11937,7 @@ redisplay_tool_bar (struct frame *f)
 
   /* Build a string that represents the contents of the tool-bar.  */
   build_desired_tool_bar_string (f);
-  reseat_to_string (&it, NULL, FVAR (f, desired_tool_bar_string), 0, 0, 0, -1);
+  reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
   /* FIXME: This should be controlled by a user option.  But it
      doesn't make sense to have an R2L tool bar if the menu bar cannot
      be drawn also R2L, and making the menu bar R2L is tricky due
@@ -12058,14 +12094,14 @@ tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
   /* This function can be called asynchronously, which means we must
      exclude any possibility that Fget_text_property signals an
      error.  */
-  charpos = min (SCHARS (FVAR (f, current_tool_bar_string)), glyph->charpos);
+  charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
   charpos = max (0, charpos);
 
   /* Get the text property `menu-item' at pos. The value of that
      property is the start index of this item's properties in
      F->tool_bar_items.  */
   prop = Fget_text_property (make_number (charpos),
-                            Qmenu_item, FVAR (f, current_tool_bar_string));
+                            Qmenu_item, f->current_tool_bar_string);
   if (INTEGERP (prop))
     {
       *prop_idx = XINT (prop);
@@ -12093,7 +12129,7 @@ get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
                   int *hpos, int *vpos, int *prop_idx)
 {
   Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
-  struct window *w = XWINDOW (FVAR (f, tool_bar_window));
+  struct window *w = XWINDOW (f->tool_bar_window);
   int area;
 
   /* Find the glyph under X/Y.  */
@@ -12107,7 +12143,7 @@ get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
     return -1;
 
   /* Is mouse on the highlighted item?  */
-  if (EQ (FVAR (f, tool_bar_window), hlinfo->mouse_face_window)
+  if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
       && *vpos >= hlinfo->mouse_face_beg_row
       && *vpos <= hlinfo->mouse_face_end_row
       && (*vpos > hlinfo->mouse_face_beg_row
@@ -12132,7 +12168,7 @@ handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
                       int modifiers)
 {
   Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
-  struct window *w = XWINDOW (FVAR (f, tool_bar_window));
+  struct window *w = XWINDOW (f->tool_bar_window);
   int hpos, vpos, prop_idx;
   struct glyph *glyph;
   Lisp_Object enabled_p;
@@ -12143,7 +12179,7 @@ handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
     return;
 
   /* If item is disabled, do nothing.  */
-  enabled_p = AREF (FVAR (f, tool_bar_items), prop_idx + TOOL_BAR_ITEM_ENABLED_P);
+  enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
   if (NILP (enabled_p))
     return;
 
@@ -12164,7 +12200,7 @@ handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
       show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
       hlinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
 
-      key = AREF (FVAR (f, tool_bar_items), prop_idx + TOOL_BAR_ITEM_KEY);
+      key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
 
       XSETFRAME (frame, f);
       event.kind = TOOL_BAR_EVENT;
@@ -12189,7 +12225,7 @@ handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
 static void
 note_tool_bar_highlight (struct frame *f, int x, int y)
 {
-  Lisp_Object window = FVAR (f, tool_bar_window);
+  Lisp_Object window = f->tool_bar_window;
   struct window *w = XWINDOW (window);
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
@@ -12235,7 +12271,7 @@ note_tool_bar_highlight (struct frame *f, int x, int y)
   draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
 
   /* If tool-bar item is not enabled, don't highlight it.  */
-  enabled_p = AREF (FVAR (f, tool_bar_items), prop_idx + TOOL_BAR_ITEM_ENABLED_P);
+  enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
   if (!NILP (enabled_p))
     {
       /* Compute the x-position of the glyph.  In front and past the
@@ -12269,9 +12305,9 @@ note_tool_bar_highlight (struct frame *f, int x, int y)
      XTread_socket does the rest.  */
   help_echo_object = help_echo_window = Qnil;
   help_echo_pos = -1;
-  help_echo_string = AREF (FVAR (f, tool_bar_items), prop_idx + TOOL_BAR_ITEM_HELP);
+  help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
   if (NILP (help_echo_string))
-    help_echo_string = AREF (FVAR (f, tool_bar_items), prop_idx + TOOL_BAR_ITEM_CAPTION);
+    help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
 }
 
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -12751,7 +12787,7 @@ overlay_arrow_at_row (struct it *it, struct glyph_row *row)
                    return make_number (fringe_bitmap);
                }
 #endif
-             return make_number (-1); /* Use default arrow bitmap */
+             return make_number (-1); /* Use default arrow bitmap */
            }
          return overlay_arrow_string_or_property (var);
        }
@@ -12852,7 +12888,7 @@ select_frame_for_redisplay (Lisp_Object frame)
   selected_frame = frame;
 
   do {
-    for (tail = FVAR (XFRAME (frame), param_alist);
+    for (tail = XFRAME (frame)->param_alist;
         CONSP (tail); tail = XCDR (tail))
       if (CONSP (XCAR (tail))
          && (tem = XCAR (XCAR (tail)),
@@ -12928,12 +12964,11 @@ redisplay_internal (void)
   if (redisplaying_p)
     return;
 
-  /* Record a function that resets redisplaying_p to its old value
+  /* Record a function that clears redisplaying_p
      when we leave this function.  */
   count = SPECPDL_INDEX ();
-  record_unwind_protect (unwind_redisplay,
-                        Fcons (make_number (redisplaying_p), selected_frame));
-  ++redisplaying_p;
+  record_unwind_protect (unwind_redisplay, selected_frame);
+  redisplaying_p = 1;
   specbind (Qinhibit_free_realized_faces, Qnil);
 
   {
@@ -13265,12 +13300,12 @@ redisplay_internal (void)
              if ((it.glyph_row - 1)->displays_text_p)
                {
                  if (XFASTINT (w->window_end_vpos) < this_line_vpos)
-                   XSETINT (w->window_end_vpos, this_line_vpos);
+                   wset_window_end_vpos (w, make_number (this_line_vpos));
                }
              else if (XFASTINT (w->window_end_vpos) == this_line_vpos
                       && this_line_vpos > 0)
-               XSETINT (w->window_end_vpos, this_line_vpos - 1);
-             w->window_end_valid = Qnil;
+               wset_window_end_vpos (w, make_number (this_line_vpos - 1));
+             wset_window_end_valid (w, Qnil);
 
              /* Update hint: No need to try to scroll in update_window.  */
              w->desired_matrix->no_scrolling_p = 1;
@@ -13426,7 +13461,7 @@ redisplay_internal (void)
                  if (!f->already_hscrolled_p)
                    {
                      f->already_hscrolled_p = 1;
-                     if (hscroll_windows (FVAR (f, root_window)))
+                     if (hscroll_windows (f->root_window))
                        goto retry;
                    }
 
@@ -13439,7 +13474,7 @@ redisplay_internal (void)
                  STOP_POLLING;
 
                  /* Update the display.  */
-                 set_window_update_flags (XWINDOW (FVAR (f, root_window)), 1);
+                 set_window_update_flags (XWINDOW (f->root_window), 1);
                  pending |= update_frame (f, 0, 0);
                  f->updated_p = 1;
                }
@@ -13452,7 +13487,7 @@ redisplay_internal (void)
           and selected_window to be temporarily out-of-sync but let's make
           sure this stays contained.  */
        select_frame_for_redisplay (old_frame);
-      eassert (EQ (FVAR (XFRAME (selected_frame), selected_window),
+      eassert (EQ (XFRAME (selected_frame)->selected_window,
                   selected_window));
 
       if (!pending)
@@ -13465,7 +13500,7 @@ redisplay_internal (void)
              struct frame *f = XFRAME (frame);
               if (f->updated_p)
                 {
-                  mark_window_display_accurate (FVAR (f, root_window), 1);
+                  mark_window_display_accurate (f->root_window, 1);
                   if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
                     FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
                 }
@@ -13671,21 +13706,15 @@ redisplay_preserve_echo_area (int from_where)
 }
 
 
-/* Function registered with record_unwind_protect in
-   redisplay_internal.  Reset redisplaying_p to the value it had
-   before redisplay_internal was called, and clear
-   prevent_freeing_realized_faces_p.  It also selects the previously
+/* Function registered with record_unwind_protect in redisplay_internal.
+   Clear redisplaying_p.  Also, select the previously
    selected frame, unless it has been deleted (by an X connection
    failure during redisplay, for example).  */
 
 static Lisp_Object
-unwind_redisplay (Lisp_Object val)
+unwind_redisplay (Lisp_Object old_frame)
 {
-  Lisp_Object old_redisplaying_p, old_frame;
-
-  old_redisplaying_p = XCAR (val);
-  redisplaying_p = XFASTINT (old_redisplaying_p);
-  old_frame = XCDR (val);
+  redisplaying_p = 0;
   if (! EQ (old_frame, selected_frame)
       && FRAME_LIVE_P (XFRAME (old_frame)))
     select_frame_for_redisplay (old_frame);
@@ -13736,7 +13765,7 @@ mark_window_display_accurate_1 (struct window *w, int accurate_p)
 
   if (accurate_p)
     {
-      w->window_end_valid = w->buffer;
+      wset_window_end_valid (w, w->buffer);
       w->update_mode_line = 0;
     }
 }
@@ -14384,7 +14413,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
       for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
        {
          if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
-           abort ();
+           emacs_abort ();
          x += g->pixel_width;
        }
     }
@@ -14505,7 +14534,7 @@ run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
   SET_MARKER_FROM_TEXT_POS (w->start, startp);
 
   if (current_buffer != XBUFFER (w->buffer))
-    abort ();
+    emacs_abort ();
 
   if (!NILP (Vwindow_scroll_functions))
     {
@@ -14513,8 +14542,7 @@ run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
                            make_number (CHARPOS (startp)));
       SET_TEXT_POS_FROM_MARKER (startp, w->start);
       /* In case the hook functions switch buffers.  */
-      if (current_buffer != XBUFFER (w->buffer))
-       set_buffer_internal_1 (XBUFFER (w->buffer));
+      set_buffer_internal (XBUFFER (w->buffer));
     }
 
   return startp;
@@ -14844,7 +14872,7 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
       if (!just_this_one_p
          || current_buffer->clip_changed
          || BEG_UNCHANGED < CHARPOS (startp))
-       w->base_line_number = Qnil;
+       wset_base_line_number (w, Qnil);
 
       /* If cursor ends up on a partially visible line,
         treat that as being off the bottom of the screen.  */
@@ -15342,7 +15370,7 @@ set_vertical_scroll_bar (struct window *w)
    selected_window is redisplayed.
 
    We can return without actually redisplaying the window if
-   fonts_changed_p is nonzero.  In that case, redisplay_internal will
+   fonts_changed_p.  In that case, redisplay_internal will
    retry.  */
 
 static void
@@ -15469,15 +15497,15 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
       if (XMARKER (w->start)->buffer == current_buffer)
        compute_window_start_on_continuation_line (w);
 
-      w->window_end_valid = Qnil;
+      wset_window_end_valid (w, Qnil);
     }
 
   /* Some sanity checks.  */
   CHECK_WINDOW_END (w);
   if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
-    abort ();
+    emacs_abort ();
   if (BYTEPOS (opoint) < CHARPOS (opoint))
-    abort ();
+    emacs_abort ();
 
   /* If %c is in mode line, update it if needed.  */
   if (!NILP (w->column_number_displayed)
@@ -15536,8 +15564,8 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
     {
       struct Lisp_Char_Table *disptab = buffer_display_table ();
 
-      if (! disptab_matches_widthtab (disptab,
-                                      XVECTOR (BVAR (current_buffer, width_table))))
+      if (! disptab_matches_widthtab
+         (disptab, XVECTOR (BVAR (current_buffer, width_table))))
         {
           invalidate_region_cache (current_buffer,
                                    current_buffer->width_run_cache,
@@ -15580,11 +15608,11 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
 
       w->force_start = 0;
       w->vscroll = 0;
-      w->window_end_valid = Qnil;
+      wset_window_end_valid (w, Qnil);
 
       /* Forget any recorded base line for line number display.  */
       if (!buffer_unchanged_p)
-       w->base_line_number = Qnil;
+       wset_base_line_number (w, Qnil);
 
       /* Redisplay the mode line.  Select the buffer properly for that.
         Also, run the hook window-scroll-functions
@@ -15689,7 +15717,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
          goto try_to_scroll;
 
        default:
-         abort ();
+         emacs_abort ();
        }
     }
   /* If current starting point was originally the beginning of a line
@@ -15798,7 +15826,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
              || current_buffer->clip_changed
              || BEG_UNCHANGED < CHARPOS (startp))
            /* Forget any recorded base line for line number display.  */
-           w->base_line_number = Qnil;
+           wset_base_line_number (w, Qnil);
 
          if (!cursor_row_fully_visible_p (w, 1, 0))
            {
@@ -15852,7 +15880,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
          break;
 
        default:
-         abort ();
+         emacs_abort ();
        }
     }
 
@@ -15869,7 +15897,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
 
   /* Forget any previously recorded base line for line number display.  */
   if (!buffer_unchanged_p)
-    w->base_line_number = Qnil;
+    wset_base_line_number (w, Qnil);
 
   /* Determine the window start relative to point.  */
   init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
@@ -16127,8 +16155,8 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
   if (!line_number_displayed
       && !BUFFERP (w->base_line_pos))
     {
-      w->base_line_pos = Qnil;
-      w->base_line_number = Qnil;
+      wset_base_line_pos (w, Qnil);
+      wset_base_line_number (w, Qnil);
     }
 
  finish_menu_bars:
@@ -16161,7 +16189,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
          if (FRAME_EXTERNAL_TOOL_BAR (f))
            redisplay_tool_bar (f);
 #else
-         if (WINDOWP (FVAR (f, tool_bar_window))
+         if (WINDOWP (f->tool_bar_window)
              && (FRAME_TOOL_BAR_LINES (f) > 0
                  || !NILP (Vauto_resize_tool_bars))
              && redisplay_tool_bar (f))
@@ -16178,15 +16206,15 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
                                    || w->pseudo_window_p)))
     {
       update_begin (f);
-      BLOCK_INPUT;
+      block_input ();
       if (draw_window_fringes (w, 1))
        x_draw_vertical_border (w);
-      UNBLOCK_INPUT;
+      unblock_input ();
       update_end (f);
     }
 #endif /* HAVE_WINDOW_SYSTEM */
 
-  /* We go to this label, with fonts_changed_p nonzero,
+  /* We go to this label, with fonts_changed_p set,
      if it is necessary to try again using larger glyph matrices.
      We have to redeem the scroll bar even in this case,
      because the loop in redisplay_internal expects that.  */
@@ -16305,22 +16333,23 @@ try_window (Lisp_Object window, struct text_pos pos, int flags)
       eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
       w->window_end_bytepos
        = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
-      w->window_end_pos
-       = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
-      w->window_end_vpos
-       = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
-      eassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
-              ->displays_text_p);
+      wset_window_end_pos
+       (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
+      wset_window_end_vpos
+       (w, make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix)));
+      eassert
+       (MATRIX_ROW (w->desired_matrix,
+                    XFASTINT (w->window_end_vpos))->displays_text_p);
     }
   else
     {
       w->window_end_bytepos = Z_BYTE - ZV_BYTE;
-      w->window_end_pos = make_number (Z - ZV);
-      w->window_end_vpos = make_number (0);
+      wset_window_end_pos (w, make_number (Z - ZV));
+      wset_window_end_vpos (w, make_number (0));
     }
 
   /* But that is not valid info until redisplay finishes.  */
-  w->window_end_valid = Qnil;
+  wset_window_end_valid (w, Qnil);
   return 1;
 }
 
@@ -16544,29 +16573,31 @@ try_window_reusing_current_matrix (struct window *w)
        {
          w->window_end_bytepos
            = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
-         w->window_end_pos
-           = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
-         w->window_end_vpos
-           = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
-                                           w->current_matrix));
+         wset_window_end_pos
+           (w, make_number (Z
+                            - MATRIX_ROW_END_CHARPOS (last_reused_text_row)));
+         wset_window_end_vpos
+           (w, make_number (MATRIX_ROW_VPOS (last_reused_text_row,
+                                             w->current_matrix)));
        }
       else if (last_text_row)
        {
          w->window_end_bytepos
            = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
-         w->window_end_pos
-           = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
-         w->window_end_vpos
-           = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
+         wset_window_end_pos
+           (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
+         wset_window_end_vpos
+           (w, make_number (MATRIX_ROW_VPOS (last_text_row,
+                                             w->desired_matrix)));
        }
       else
        {
          /* This window must be completely empty.  */
          w->window_end_bytepos = Z_BYTE - ZV_BYTE;
-         w->window_end_pos = make_number (Z - ZV);
-         w->window_end_vpos = make_number (0);
+         wset_window_end_pos (w, make_number (Z - ZV));
+         wset_window_end_vpos (w, make_number (0));
        }
-      w->window_end_valid = Qnil;
+      wset_window_end_valid (w, Qnil);
 
       /* Update hint: don't try scrolling again in update_window.  */
       w->desired_matrix->no_scrolling_p = 1;
@@ -16715,28 +16746,33 @@ try_window_reusing_current_matrix (struct window *w)
            }
          if (row < bottom_row)
            {
-             struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
-             struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
-
-             /* Can't use this optimization with bidi-reordered glyph
-                rows, unless cursor is already at point. */
+             /* Can't simply scan the row for point with
+                bidi-reordered glyph rows.  Let set_cursor_from_row
+                figure out where to put the cursor, and if it fails,
+                give up.  */
              if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
                {
-                 if (!(w->cursor.hpos >= 0
-                       && w->cursor.hpos < row->used[TEXT_AREA]
-                       && BUFFERP (glyph->object)
-                       && glyph->charpos == PT))
-                   return 0;
+                 if (!set_cursor_from_row (w, row, w->current_matrix,
+                                           0, 0, 0, 0))
+                   {
+                     clear_glyph_matrix (w->desired_matrix);
+                     return 0;
+                   }
                }
              else
-               for (; glyph < end
-                      && (!BUFFERP (glyph->object)
-                          || glyph->charpos < PT);
-                    glyph++)
-                 {
-                   w->cursor.hpos++;
-                   w->cursor.x += glyph->pixel_width;
-                 }
+               {
+                 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
+                 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
+
+                 for (; glyph < end
+                        && (!BUFFERP (glyph->object)
+                            || glyph->charpos < PT);
+                      glyph++)
+                   {
+                     w->cursor.hpos++;
+                     w->cursor.x += glyph->pixel_width;
+                   }
+               }
            }
        }
 
@@ -16747,18 +16783,19 @@ try_window_reusing_current_matrix (struct window *w)
        {
          w->window_end_bytepos
            = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
-         w->window_end_pos
-           = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
-         w->window_end_vpos
-           = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
+         wset_window_end_pos
+           (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
+         wset_window_end_vpos
+           (w, make_number (MATRIX_ROW_VPOS (last_text_row,
+                                             w->desired_matrix)));
        }
       else
        {
-         w->window_end_vpos
-           = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
+         wset_window_end_vpos
+           (w, make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled));
        }
 
-      w->window_end_valid = Qnil;
+      wset_window_end_valid (w, Qnil);
       w->desired_matrix->no_scrolling_p = 1;
 
 #ifdef GLYPH_DEBUG
@@ -17296,7 +17333,7 @@ try_window_id (struct window *w)
          if (row)
            set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
          else
-           abort ();
+           emacs_abort ();
          return 1;
        }
     }
@@ -17330,8 +17367,8 @@ try_window_id (struct window *w)
        {
          /* We have to compute the window end anew since text
             could have been added/removed after it.  */
-         w->window_end_pos
-           = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
+         wset_window_end_pos
+           (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
          w->window_end_bytepos
            = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
 
@@ -17340,7 +17377,7 @@ try_window_id (struct window *w)
          if (row)
            set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
          else
-           abort ();
+           emacs_abort ();
          return 2;
        }
     }
@@ -17663,15 +17700,15 @@ try_window_id (struct window *w)
     {
       rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
                     bottom_vpos, dvpos);
-      enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
-                               bottom_vpos, 0);
+      clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
+                              bottom_vpos);
     }
   else if (dvpos > 0)
     {
       rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
                     bottom_vpos, dvpos);
-      enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
-                               first_unchanged_at_end_vpos + dvpos, 0);
+      clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
+                              first_unchanged_at_end_vpos + dvpos);
     }
 
   /* For frame-based redisplay, make sure that current frame and window
@@ -17765,21 +17802,22 @@ try_window_id (struct window *w)
                                           first_unchanged_at_end_row);
       eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
 
-      w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
+      wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
       w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
-      w->window_end_vpos
-       = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
+      wset_window_end_vpos
+       (w, make_number (MATRIX_ROW_VPOS (row, w->current_matrix)));
       eassert (w->window_end_bytepos >= 0);
       IF_DEBUG (debug_method_add (w, "A"));
     }
   else if (last_text_row_at_end)
     {
-      w->window_end_pos
-       = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
+      wset_window_end_pos
+       (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end)));
       w->window_end_bytepos
        = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
-      w->window_end_vpos
-       = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
+      wset_window_end_vpos
+       (w, make_number (MATRIX_ROW_VPOS (last_text_row_at_end,
+                                         desired_matrix)));
       eassert (w->window_end_bytepos >= 0);
       IF_DEBUG (debug_method_add (w, "B"));
     }
@@ -17788,12 +17826,12 @@ try_window_id (struct window *w)
       /* We have displayed either to the end of the window or at the
         end of the window, i.e. the last row with text is to be found
         in the desired matrix.  */
-      w->window_end_pos
-       = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
+      wset_window_end_pos
+       (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
       w->window_end_bytepos
        = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
-      w->window_end_vpos
-       = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
+      wset_window_end_vpos
+       (w, make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix)));
       eassert (w->window_end_bytepos >= 0);
     }
   else if (first_unchanged_at_end_row == NULL
@@ -17821,20 +17859,20 @@ try_window_id (struct window *w)
        }
 
       eassert (row != NULL);
-      w->window_end_vpos = make_number (vpos + 1);
-      w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
+      wset_window_end_vpos (w, make_number (vpos + 1));
+      wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
       w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
       eassert (w->window_end_bytepos >= 0);
       IF_DEBUG (debug_method_add (w, "C"));
     }
   else
-    abort ();
+    emacs_abort ();
 
   IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
            debug_end_vpos = XFASTINT (w->window_end_vpos));
 
   /* Record that display has not been completed.  */
-  w->window_end_valid = Qnil;
+  wset_window_end_valid (w, Qnil);
   w->desired_matrix->no_scrolling_p = 1;
   return 3;
 
@@ -18116,7 +18154,7 @@ GLYPH > 1 or omitted means dump glyphs in long form.  */)
   (Lisp_Object row, Lisp_Object glyphs)
 {
   struct frame *sf = SELECTED_FRAME ();
-  struct glyph_matrix *m = XWINDOW (FVAR (sf, tool_bar_window))->current_matrix;
+  struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
   EMACS_INT vpos;
 
   CHECK_NUMBER (row);
@@ -19205,7 +19243,7 @@ find_row_edges (struct it *it, struct glyph_row *row,
        /* A line that is entirely from a string/image/stretch...  */
        row->maxpos = row->minpos;
       else
-       abort ();
+       emacs_abort ();
     }
   else
     row->maxpos = it->current.pos;
@@ -19247,7 +19285,7 @@ display_line (struct it *it)
     }
 
   /* Is IT->w showing the region?  */
-  it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
+  wset_region_showing (it->w, it->region_beg_charpos > 0 ? Qt : Qnil);
 
   /* Clear the result glyph row and enable it.  */
   prepare_desired_row (row);
@@ -20046,7 +20084,7 @@ See also `bidi-paragraph-direction'.  */)
          return Qright_to_left;
          break;
        default:
-         abort ();
+         emacs_abort ();
        }
     }
 }
@@ -20101,8 +20139,8 @@ display_menu_bar (struct window *w)
       /* Menu bar lines are displayed in the desired matrix of the
         dummy window menu_bar_window.  */
       struct window *menu_w;
-      eassert (WINDOWP (FVAR (f, menu_bar_window)));
-      menu_w = XWINDOW (FVAR (f, menu_bar_window));
+      eassert (WINDOWP (f->menu_bar_window));
+      menu_w = XWINDOW (f->menu_bar_window);
       init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
                     MENU_FACE_ID);
       it.first_visible_x = 0;
@@ -20251,7 +20289,7 @@ display_mode_lines (struct window *w)
 
   /* These will be set while the mode line specs are processed.  */
   line_number_displayed = 0;
-  w->column_number_displayed = Qnil;
+  wset_column_number_displayed (w, Qnil);
 
   if (WINDOW_WANTS_MODELINE_P (w))
     {
@@ -21001,8 +21039,7 @@ are the selected window and the WINDOW's buffer).  */)
     : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
     : DEFAULT_FACE_ID;
 
-  if (XBUFFER (buffer) != current_buffer)
-    old_buffer = current_buffer;
+  old_buffer = current_buffer;
 
   /* Save things including mode_line_proptrans_alist,
      and set that to nil so that we don't alter the outer value.  */
@@ -21013,8 +21050,7 @@ are the selected window and the WINDOW's buffer).  */)
   mode_line_proptrans_alist = Qnil;
 
   Fselect_window (window, Qt);
-  if (old_buffer)
-    set_buffer_internal_1 (XBUFFER (buffer));
+  set_buffer_internal_1 (XBUFFER (buffer));
 
   init_iterator (&it, w, -1, -1, NULL, face_id);
 
@@ -21387,7 +21423,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
       else
        {
          ptrdiff_t col = current_column ();
-         w->column_number_displayed = make_number (col);
+         wset_column_number_displayed (w, make_number (col));
          pint2str (decode_mode_spec_buf, field_width, col);
          return decode_mode_spec_buf;
        }
@@ -21406,10 +21442,10 @@ decode_mode_spec (struct window *w, register int c, int field_width,
 
     case 'F':
       /* %F displays the frame name.  */
-      if (!NILP (FVAR (f, title)))
-       return SSDATA (FVAR (f, title));
+      if (!NILP (f->title))
+       return SSDATA (f->title);
       if (f->explicit_name || ! FRAME_WINDOW_P (f))
-       return SSDATA (FVAR (f, name));
+       return SSDATA (f->name);
       return "Emacs";
 
     case 'f':
@@ -21450,14 +21486,14 @@ decode_mode_spec (struct window *w, register int c, int field_width,
          goto no_value;
        /* But do forget it, if the window shows a different buffer now.  */
        else if (BUFFERP (w->base_line_pos))
-         w->base_line_pos = Qnil;
+         wset_base_line_pos (w, Qnil);
 
        /* If the buffer is very big, don't waste time.  */
        if (INTEGERP (Vline_number_display_limit)
            && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
          {
-           w->base_line_pos = Qnil;
-           w->base_line_number = Qnil;
+           wset_base_line_pos (w, Qnil);
+           wset_base_line_number (w, Qnil);
            goto no_value;
          }
 
@@ -21489,8 +21525,8 @@ decode_mode_spec (struct window *w, register int c, int field_width,
           go back past it.  */
        if (startpos == BUF_BEGV (b))
          {
-           w->base_line_number = make_number (topline);
-           w->base_line_pos = make_number (BUF_BEGV (b));
+           wset_base_line_number (w, make_number (topline));
+           wset_base_line_pos (w, make_number (BUF_BEGV (b)));
          }
        else if (nlines < height + 25 || nlines > height * 3 + 50
                 || linepos == BUF_BEGV (b))
@@ -21516,13 +21552,13 @@ decode_mode_spec (struct window *w, register int c, int field_width,
               give up on line numbers for this window.  */
            if (position == limit_byte && limit == startpos - distance)
              {
-               w->base_line_pos = w->buffer;
-               w->base_line_number = Qnil;
+               wset_base_line_pos (w, w->buffer);
+               wset_base_line_number (w, Qnil);
                goto no_value;
              }
 
-           w->base_line_number = make_number (topline - nlines);
-           w->base_line_pos = make_number (BYTE_TO_CHAR (position));
+           wset_base_line_number (w, make_number (topline - nlines));
+           wset_base_line_pos (w, make_number (BYTE_TO_CHAR (position)));
          }
 
        /* Now count lines from the start pos to point.  */
@@ -21674,10 +21710,10 @@ decode_mode_spec (struct window *w, register int c, int field_width,
        obj = Fget_buffer_process (Fcurrent_buffer ());
        if (PROCESSP (obj))
          {
-           p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
-                                        p, eol_flag);
-           p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
-                                        p, eol_flag);
+           p = decode_mode_spec_coding
+             (XPROCESS (obj)->decode_coding_system, p, eol_flag);
+           p = decode_mode_spec_coding
+             (XPROCESS (obj)->encode_coding_system, p, eol_flag);
          }
 #endif /* subprocesses */
 #endif /* 0 */
@@ -21959,7 +21995,7 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st
            {
              /* Glyph is off the left margin of the display area.
                 Should not happen.  */
-             abort ();
+             emacs_abort ();
            }
 
          row->ascent = max (row->ascent, it->max_ascent);
@@ -23004,7 +23040,8 @@ right_overwritten (struct glyph_string *s)
     {
       int x = 0, i;
       struct glyph *glyphs = s->row->glyphs[s->area];
-      int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
+      int first = (s->first_glyph - glyphs
+                  + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
       int end = s->row->used[s->area];
 
       for (i = first; i < end && s->right_overhang > x; ++i)
@@ -23027,7 +23064,8 @@ right_overwriting (struct glyph_string *s)
   int i, k, x;
   int end = s->row->used[s->area];
   struct glyph *glyphs = s->row->glyphs[s->area];
-  int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
+  int first = (s->first_glyph - glyphs
+              + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
 
   k = -1;
   x = 0;
@@ -23324,7 +23362,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
              break;                                                    \
                                                                        \
            default:                                                    \
-             abort ();                                                 \
+             emacs_abort ();                                                   \
            }                                                           \
                                                                        \
          if (s)                                                        \
@@ -23665,7 +23703,7 @@ append_glyph (struct it *it)
        {
          glyph->resolved_level = it->bidi_it.resolved_level;
          if ((it->bidi_it.type & 7) != it->bidi_it.type)
-           abort ();
+           emacs_abort ();
          glyph->bidi_type = it->bidi_it.type;
        }
       else
@@ -23739,7 +23777,7 @@ append_composite_glyph (struct it *it)
        {
          glyph->resolved_level = it->bidi_it.resolved_level;
          if ((it->bidi_it.type & 7) != it->bidi_it.type)
-           abort ();
+           emacs_abort ();
          glyph->bidi_type = it->bidi_it.type;
        }
       ++it->glyph_row->used[area];
@@ -23918,7 +23956,7 @@ produce_image_glyph (struct it *it)
            {
              glyph->resolved_level = it->bidi_it.resolved_level;
              if ((it->bidi_it.type & 7) != it->bidi_it.type)
-               abort ();
+               emacs_abort ();
              glyph->bidi_type = it->bidi_it.type;
            }
          ++it->glyph_row->used[area];
@@ -23979,7 +24017,7 @@ append_stretch_glyph (struct it *it, Lisp_Object object,
        {
          glyph->resolved_level = it->bidi_it.resolved_level;
          if ((it->bidi_it.type & 7) != it->bidi_it.type)
-           abort ();
+           emacs_abort ();
          glyph->bidi_type = it->bidi_it.type;
        }
       else
@@ -24234,7 +24272,7 @@ produce_special_glyphs (struct it *it, enum display_element_type what)
        }
     }
   else
-    abort ();
+    emacs_abort ();
 
 #ifdef HAVE_WINDOW_SYSTEM
   /* On a GUI frame, when the right fringe (left fringe for R2L rows)
@@ -24431,7 +24469,7 @@ append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
        {
          glyph->resolved_level = it->bidi_it.resolved_level;
          if ((it->bidi_it.type & 7) != it->bidi_it.type)
-           abort ();
+           emacs_abort ();
          glyph->bidi_type = it->bidi_it.type;
        }
       ++it->glyph_row->used[area];
@@ -24952,7 +24990,7 @@ x_produce_glyphs (struct it *it)
          font_descent = FONT_DESCENT (font) - boff;
          font_height = FONT_HEIGHT (font);
 
-         cmp->font = (void *) font;
+         cmp->font = font;
 
          pcm = NULL;
          if (! font_not_found_p)
@@ -25290,7 +25328,7 @@ x_write_glyphs (struct glyph *start, int len)
   if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
     chpos = updated_row->used[TEXT_AREA] - 1;
 
-  BLOCK_INPUT;
+  block_input ();
 
   /* Write glyphs.  */
 
@@ -25308,7 +25346,7 @@ x_write_glyphs (struct glyph *start, int len)
       && chpos < hpos + len)
     updated_window->phys_cursor_on_p = 0;
 
-  UNBLOCK_INPUT;
+  unblock_input ();
 
   /* Advance the output cursor.  */
   output_cursor.hpos += len;
@@ -25331,7 +25369,7 @@ x_insert_glyphs (struct glyph *start, int len)
   ptrdiff_t hpos;
 
   eassert (updated_window && updated_row);
-  BLOCK_INPUT;
+  block_input ();
   w = updated_window;
   f = XFRAME (WINDOW_FRAME (w));
 
@@ -25365,7 +25403,7 @@ x_insert_glyphs (struct glyph *start, int len)
   /* Advance the output cursor.  */
   output_cursor.hpos += len;
   output_cursor.x += shift_by_width;
-  UNBLOCK_INPUT;
+  unblock_input ();
 }
 
 
@@ -25434,10 +25472,10 @@ x_clear_end_of_line (int to_x)
   /* Prevent inadvertently clearing to end of the X window.  */
   if (to_x > from_x && to_y > from_y)
     {
-      BLOCK_INPUT;
+      block_input ();
       FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
                                        to_x - from_x, to_y - from_y);
-      UNBLOCK_INPUT;
+      unblock_input ();
     }
 }
 
@@ -25573,7 +25611,7 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
     }
 
   /* Detect a nonselected window or nonselected frame.  */
-  else if (w != XWINDOW (FVAR (f, selected_window))
+  else if (w != XWINDOW (f->selected_window)
           || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
     {
       *active_cursor = 0;
@@ -25764,7 +25802,7 @@ x_fix_overlapping_area (struct window *w, struct glyph_row *row,
 {
   int i, x;
 
-  BLOCK_INPUT;
+  block_input ();
 
   x = 0;
   for (i = 0; i < row->used[area];)
@@ -25792,7 +25830,7 @@ x_fix_overlapping_area (struct window *w, struct glyph_row *row,
        }
     }
 
-  UNBLOCK_INPUT;
+  unblock_input ();
 }
 
 
@@ -26010,7 +26048,7 @@ display_and_set_cursor (struct window *w, int on,
       || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
     glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
 
-  eassert (interrupt_input_blocked);
+  eassert (input_blocked_p ());
 
   /* Set new_cursor_type to the cursor we want to be displayed.  */
   new_cursor_type = get_window_cursor_type (w, glyph,
@@ -26080,10 +26118,10 @@ update_window_cursor (struct window *w, int on)
       if (row->reversed_p && hpos >= row->used[TEXT_AREA])
        hpos = row->used[TEXT_AREA] - 1;
 
-      BLOCK_INPUT;
+      block_input ();
       display_and_set_cursor (w, on, hpos, vpos,
                              w->phys_cursor.x, w->phys_cursor.y);
-      UNBLOCK_INPUT;
+      unblock_input ();
     }
 }
 
@@ -26115,7 +26153,7 @@ update_cursor_in_window_tree (struct window *w, int on_p)
 void
 x_update_cursor (struct frame *f, int on_p)
 {
-  update_cursor_in_window_tree (XWINDOW (FVAR (f, root_window)), on_p);
+  update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
 }
 
 
@@ -26261,10 +26299,10 @@ show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
          if (row->reversed_p && hpos >= row->used[TEXT_AREA])
            hpos = row->used[TEXT_AREA] - 1;
 
-         BLOCK_INPUT;
+         block_input ();
          display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
                                  w->phys_cursor.x, w->phys_cursor.y);
-         UNBLOCK_INPUT;
+         unblock_input ();
        }
 #endif /* HAVE_WINDOW_SYSTEM */
     }
@@ -26274,7 +26312,7 @@ show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
   if (FRAME_WINDOW_P (f))
     {
       if (draw == DRAW_NORMAL_TEXT
-         && !EQ (hlinfo->mouse_face_window, FVAR (f, tool_bar_window)))
+         && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
        FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
       else if (draw == DRAW_MOUSE_FACE)
        FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
@@ -27630,7 +27668,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
 #ifdef HAVE_WINDOW_SYSTEM
   /* Handle tool-bar window differently since it doesn't display a
      buffer.  */
-  if (EQ (window, FVAR (f, tool_bar_window)))
+  if (EQ (window, f->tool_bar_window))
     {
       note_tool_bar_highlight (f, x, y);
       return;
@@ -28079,11 +28117,11 @@ x_clear_window_mouse_face (struct window *w)
   Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
   Lisp_Object window;
 
-  BLOCK_INPUT;
+  block_input ();
   XSETWINDOW (window, w);
   if (EQ (window, hlinfo->mouse_face_window))
     clear_mouse_face (hlinfo);
-  UNBLOCK_INPUT;
+  unblock_input ();
 }
 
 
@@ -28540,18 +28578,18 @@ expose_frame (struct frame *f, int x, int y, int w, int h)
     }
 
   TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
-  mouse_face_overwritten_p = expose_window_tree (XWINDOW (FVAR (f, root_window)), &r);
+  mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
 
-  if (WINDOWP (FVAR (f, tool_bar_window)))
+  if (WINDOWP (f->tool_bar_window))
     mouse_face_overwritten_p
-      |= expose_window (XWINDOW (FVAR (f, tool_bar_window)), &r);
+      |= expose_window (XWINDOW (f->tool_bar_window), &r);
 
 #ifdef HAVE_X_WINDOWS
 #ifndef MSDOS
 #ifndef USE_X_TOOLKIT
-  if (WINDOWP (FVAR (f, menu_bar_window)))
+  if (WINDOWP (f->menu_bar_window))
     mouse_face_overwritten_p
-      |= expose_window (XWINDOW (FVAR (f, menu_bar_window)), &r);
+      |= expose_window (XWINDOW (f->menu_bar_window), &r);
 #endif /* not USE_X_TOOLKIT */
 #endif
 #endif
@@ -29264,6 +29302,10 @@ Its value should be an ASCII acronym string, `hex-code', `empty-box', or
   Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
   Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
                              Qempty_box);
+
+  DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
+              doc: /* If non-nil, debug if a message matching this regexp is displayed.  */);
+  Vdebug_on_message = Qnil;
 }
 
 
@@ -29287,12 +29329,13 @@ init_xdisp (void)
 
       echo_area_window = minibuf_window;
 
-      XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f));
-      XSETFASTINT (r->total_lines, FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f));
-      XSETFASTINT (r->total_cols, FRAME_COLS (f));
-      XSETFASTINT (m->top_line, FRAME_LINES (f) - 1);
-      XSETFASTINT (m->total_lines, 1);
-      XSETFASTINT (m->total_cols, FRAME_COLS (f));
+      wset_top_line (r, make_number (FRAME_TOP_MARGIN (f)));
+      wset_total_lines
+       (r, make_number (FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f)));
+      wset_total_cols (r, make_number (FRAME_COLS (f)));
+      wset_top_line (m, make_number (FRAME_LINES (f) - 1));
+      wset_total_lines (m, make_number (1));
+      wset_total_cols (m, make_number (FRAME_COLS (f)));
 
       scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
       scratch_glyph_row.glyphs[TEXT_AREA + 1]