Widely used frame validity and checking functions.
[bpt/emacs.git] / src / window.c
index 140b925..c32234b 100644 (file)
@@ -19,8 +19,10 @@ You should have received a copy of the GNU General Public License
 along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
+
+#define WINDOW_INLINE EXTERN_INLINE
+
 #include <stdio.h>
-#include <setjmp.h>
 
 #include "lisp.h"
 #include "character.h"
@@ -41,7 +43,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #ifdef HAVE_X_WINDOWS
 #include "xterm.h"
 #endif /* HAVE_X_WINDOWS */
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
 #include "w32term.h"
 #endif
 #ifdef MSDOS
@@ -51,14 +53,14 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "nsterm.h"
 #endif
 
-Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_valid_p;
+Lisp_Object Qwindowp, Qwindow_live_p;
+static Lisp_Object Qwindow_valid_p;
 static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer;
 static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
 static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
 static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically;
 static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
-static Lisp_Object Qsafe, Qabove, Qbelow;
-static Lisp_Object Qauto_buffer_name, Qclone_of;
+static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of;
 
 static int displayed_window_lines (struct window *);
 static int count_windows (struct window *);
@@ -130,6 +132,108 @@ static int window_scroll_pixel_based_preserve_y;
 static EMACS_INT window_scroll_preserve_hpos;
 static EMACS_INT window_scroll_preserve_vpos;
 \f
+/* These setters are used only in this file, so they can be private.  */
+static void
+wset_combination_limit (struct window *w, Lisp_Object val)
+{
+  w->combination_limit = val;
+}
+static void
+wset_dedicated (struct window *w, Lisp_Object val)
+{
+  w->dedicated = val;
+}
+static void
+wset_display_table (struct window *w, Lisp_Object val)
+{
+  w->display_table = val;
+}
+static void
+wset_hchild (struct window *w, Lisp_Object val)
+{
+  w->hchild = val;
+}
+static void
+wset_left_fringe_width (struct window *w, Lisp_Object val)
+{
+  w->left_fringe_width = val;
+}
+static void
+wset_left_margin_cols (struct window *w, Lisp_Object val)
+{
+  w->left_margin_cols = val;
+}
+static void
+wset_new_normal (struct window *w, Lisp_Object val)
+{
+  w->new_normal = val;
+}
+static void
+wset_new_total (struct window *w, Lisp_Object val)
+{
+  w->new_total = val;
+}
+static void
+wset_normal_cols (struct window *w, Lisp_Object val)
+{
+  w->normal_cols = val;
+}
+static void
+wset_normal_lines (struct window *w, Lisp_Object val)
+{
+  w->normal_lines = val;
+}
+static void
+wset_parent (struct window *w, Lisp_Object val)
+{
+  w->parent = val;
+}
+static void
+wset_pointm (struct window *w, Lisp_Object val)
+{
+  w->pointm = val;
+}
+static void
+wset_right_fringe_width (struct window *w, Lisp_Object val)
+{
+  w->right_fringe_width = val;
+}
+static void
+wset_right_margin_cols (struct window *w, Lisp_Object val)
+{
+  w->right_margin_cols = val;
+}
+static void
+wset_scroll_bar_width (struct window *w, Lisp_Object val)
+{
+  w->scroll_bar_width = val;
+}
+static void
+wset_start (struct window *w, Lisp_Object val)
+{
+  w->start = val;
+}
+static void
+wset_temslot (struct window *w, Lisp_Object val)
+{
+  w->temslot = val;
+}
+static void
+wset_vchild (struct window *w, Lisp_Object val)
+{
+  w->vchild = val;
+}
+static void
+wset_vertical_scroll_bar_type (struct window *w, Lisp_Object val)
+{
+  w->vertical_scroll_bar_type = val;
+}
+static void
+wset_window_parameters (struct window *w, Lisp_Object val)
+{
+  w->window_parameters = val;
+}
+
 struct window *
 decode_live_window (register Lisp_Object window)
 {
@@ -140,7 +244,7 @@ decode_live_window (register Lisp_Object window)
   return XWINDOW (window);
 }
 
-static struct window *
+struct window *
 decode_any_window (register Lisp_Object window)
 {
   struct window *w;
@@ -153,7 +257,7 @@ decode_any_window (register Lisp_Object window)
   return w;
 }
 
-struct window *
+static struct window *
 decode_valid_window (register Lisp_Object window)
 {
   struct window *w;
@@ -166,6 +270,15 @@ decode_valid_window (register Lisp_Object window)
   return w;
 }
 
+/* Build a frequently used 4-integer (X Y W H) list.  */
+
+static Lisp_Object
+quad (ptrdiff_t x, ptrdiff_t y, ptrdiff_t w, ptrdiff_t h)
+{
+  return list4 (make_number (x), make_number (y),
+               make_number (w), make_number (h));
+}
+
 DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0,
        doc: /* Return t if OBJECT is a window and nil otherwise.  */)
   (Lisp_Object object)
@@ -192,7 +305,7 @@ Internal windows and deleted windows are not live.  */)
 }
 \f
 /* Frames and windows.  */
-DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
+DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 0, 1, 0,
        doc: /* Return the frame that window WINDOW is on.
 WINDOW must be a valid window and defaults to the selected one.  */)
   (Lisp_Object window)
@@ -227,10 +340,7 @@ DEFUN ("minibuffer-window", Fminibuffer_window, Sminibuffer_window, 0, 1, 0,
 If FRAME is omitted or nil, it defaults to the selected frame.  */)
   (Lisp_Object frame)
 {
-  if (NILP (frame))
-    frame = selected_frame;
-  CHECK_LIVE_FRAME (frame);
-  return FRAME_MINIBUF_WINDOW (XFRAME (frame));
+  return FRAME_MINIBUF_WINDOW (decode_live_frame (frame));
 }
 
 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p,
@@ -270,7 +380,7 @@ the first window of that frame.  */)
       else if (! NILP (XWINDOW (window)->vchild))
        window = XWINDOW (window)->vchild;
       else
-       abort ();
+       emacs_abort ();
     }
 
   return window;
@@ -362,6 +472,9 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
       record_buffer (w->buffer);
     }
 
+  /* Make the selected window's buffer current.  */
+  Fset_buffer (w->buffer);
+
   if (EQ (window, selected_window) && !inhibit_point_swap)
     return window;
 
@@ -381,9 +494,9 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
   else
     fset_selected_window (sf, window);
 
-  /* Store the current buffer's actual point into the
-     old selected window.  It belongs to that window,
-     and when the window is not selected, must be in the window.  */
+  /* Store the old selected window's buffer's point in pointm of the old
+     selected window.  It belongs to that window, and when the window is
+     not selected, must be in the window.  */
   if (!inhibit_point_swap)
     {
       ow = XWINDOW (selected_window);
@@ -394,10 +507,7 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
     }
 
   selected_window = window;
-
-  Fset_buffer (w->buffer);
-
-  BSET (XBUFFER (w->buffer), last_selected_window, window);
+  bset_last_selected_window (XBUFFER (w->buffer), window);
 
   /* Go to the point recorded in the window.
      This is important when the buffer is in more
@@ -452,7 +562,7 @@ Return nil for a window with no parent (e.g. a root window).  */)
   return decode_valid_window (window)->parent;
 }
 
-DEFUN ("window-top-child", Fwindow_top_child, Swindow_top_child, 1, 1, 0,
+DEFUN ("window-top-child", Fwindow_top_child, Swindow_top_child, 0, 1, 0,
        doc: /* Return the topmost child window of window WINDOW.
 WINDOW must be a valid window and defaults to the selected one.
 Return nil if WINDOW is a live window (live windows have no children).
@@ -460,11 +570,10 @@ Return nil if WINDOW is an internal window whose children form a
 horizontal combination.  */)
   (Lisp_Object window)
 {
-  CHECK_WINDOW (window);
   return decode_valid_window (window)->vchild;
 }
 
-DEFUN ("window-left-child", Fwindow_left_child, Swindow_left_child, 1, 1, 0,
+DEFUN ("window-left-child", Fwindow_left_child, Swindow_left_child, 0, 1, 0,
        doc: /* Return the leftmost child window of window WINDOW.
 WINDOW must be a valid window and defaults to the selected one.
 Return nil if WINDOW is a live window (live windows have no children).
@@ -472,7 +581,6 @@ Return nil if WINDOW is an internal window whose children form a
 vertical combination.  */)
   (Lisp_Object window)
 {
-  CHECK_WINDOW (window);
   return decode_valid_window (window)->hchild;
 }
 
@@ -494,7 +602,7 @@ Return nil if WINDOW has no previous sibling.  */)
   return decode_valid_window (window)->prev;
 }
 
-DEFUN ("window-combination-limit", Fwindow_combination_limit, Swindow_combination_limit, 1, 1, 0,
+DEFUN ("window-combination-limit", Fwindow_combination_limit, Swindow_combination_limit, 0, 1, 0,
        doc: /* Return combination limit of window WINDOW.
 WINDOW must be a valid window and defaults to the selected one.
 If the return value is nil, child windows of WINDOW can be recombined with
@@ -508,13 +616,14 @@ WINDOW are never \(re-)combined with WINDOW's siblings.  */)
 DEFUN ("set-window-combination-limit", Fset_window_combination_limit, Sset_window_combination_limit, 2, 2, 0,
        doc: /* Set combination limit of window WINDOW to LIMIT; return LIMIT.
 WINDOW must be a valid window and defaults to the selected one.
-If LIMIT is nil, child windows of WINDOW can be recombined with
-WINDOW's siblings.  LIMIT t means that child windows of WINDOW are
-never \(re-)combined with WINDOW's siblings.  Other values are reserved
-for future use.  */)
+If LIMIT is nil, child windows of WINDOW can be recombined with WINDOW's
+siblings.  LIMIT t means that child windows of WINDOW are never
+\(re-)combined with WINDOW's siblings.  Other values are reserved for
+future use.  */)
   (Lisp_Object window, Lisp_Object limit)
 {
-  return WSET (decode_valid_window (window), combination_limit, limit);
+  wset_combination_limit (decode_valid_window (window), limit);
+  return limit;
 }
 
 DEFUN ("window-use-time", Fwindow_use_time, Swindow_use_time, 0, 1, 0,
@@ -669,8 +778,7 @@ area is only partially visible, that counts as a whole line; to
 exclude partially-visible lines, use `window-text-height'.  */)
   (Lisp_Object window)
 {
-  struct window *w = decode_live_window (window);
-  return make_number (window_body_lines (w));
+  return make_number (window_body_lines (decode_live_window (window)));
 }
 
 DEFUN ("window-body-width", Fwindow_body_width, Swindow_body_width, 0, 1, 0,
@@ -682,8 +790,7 @@ marginal areas, or scroll bars.  On a graphical display, the width is
 expressed as an integer multiple of the default character width.  */)
   (Lisp_Object window)
 {
-  struct window *w = decode_live_window (window);
-  return make_number (window_body_cols (w));
+  return make_number (window_body_cols (decode_live_window (window)));
 }
 
 DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
@@ -726,10 +833,8 @@ Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
 window so that the location of point moves off-window.  */)
   (Lisp_Object window, Lisp_Object ncol)
 {
-  struct window *w = decode_live_window (window);
-
   CHECK_NUMBER (ncol);
-  return set_window_hscroll (w, XINT (ncol));
+  return set_window_hscroll (decode_live_window (window), XINT (ncol));
 }
 
 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger,
@@ -753,7 +858,8 @@ with two arguments: WINDOW, and the end trigger value.  Afterwards the
 end-trigger value is reset to nil.  */)
   (register Lisp_Object window, Lisp_Object value)
 {
-  return WSET (decode_live_window (window), redisplay_end_trigger, value);
+  wset_redisplay_end_trigger (decode_live_window (window), value);
+  return value;
 }
 
 DEFUN ("window-edges", Fwindow_edges, Swindow_edges, 0, 1, 0,
@@ -773,11 +879,8 @@ header line, and/or mode line.  For the edges of just the text area, use
 {
   register struct window *w = decode_valid_window (window);
 
-  return Fcons (make_number (WINDOW_LEFT_EDGE_COL (w)),
-        Fcons (make_number (WINDOW_TOP_EDGE_LINE (w)),
-        Fcons (make_number (WINDOW_RIGHT_EDGE_COL (w)),
-        Fcons (make_number (WINDOW_BOTTOM_EDGE_LINE (w)),
-               Qnil))));
+  return quad (WINDOW_LEFT_EDGE_COL (w), WINDOW_TOP_EDGE_LINE (w),
+              WINDOW_RIGHT_EDGE_COL (w), WINDOW_BOTTOM_EDGE_LINE (w));
 }
 
 DEFUN ("window-pixel-edges", Fwindow_pixel_edges, Swindow_pixel_edges, 0, 1, 0,
@@ -796,11 +899,8 @@ of just the text area, use `window-inside-pixel-edges'.  */)
 {
   register struct window *w = decode_valid_window (window);
 
-  return Fcons (make_number (WINDOW_LEFT_EDGE_X (w)),
-        Fcons (make_number (WINDOW_TOP_EDGE_Y (w)),
-        Fcons (make_number (WINDOW_RIGHT_EDGE_X (w)),
-        Fcons (make_number (WINDOW_BOTTOM_EDGE_Y (w)),
-               Qnil))));
+  return quad (WINDOW_LEFT_EDGE_X (w), WINDOW_TOP_EDGE_Y (w),
+              WINDOW_RIGHT_EDGE_X (w), WINDOW_BOTTOM_EDGE_Y (w));
 }
 
 static void
@@ -842,13 +942,13 @@ of just the text area, use `window-inside-absolute-pixel-edges'.  */)
 {
   register struct window *w = decode_valid_window (window);
   int add_x, add_y;
+
   calc_absolute_offset (w, &add_x, &add_y);
 
-  return Fcons (make_number (WINDOW_LEFT_EDGE_X (w) + add_x),
-         Fcons (make_number (WINDOW_TOP_EDGE_Y (w) + add_y),
-        Fcons (make_number (WINDOW_RIGHT_EDGE_X (w) + add_x),
-        Fcons (make_number (WINDOW_BOTTOM_EDGE_Y (w) + add_y),
-               Qnil))));
+  return quad (WINDOW_LEFT_EDGE_X (w) + add_x,
+              WINDOW_TOP_EDGE_Y (w) + add_y,
+              WINDOW_RIGHT_EDGE_X (w) + add_x,
+              WINDOW_BOTTOM_EDGE_Y (w) + add_y);
 }
 
 DEFUN ("window-inside-edges", Fwindow_inside_edges, Swindow_inside_edges, 0, 1, 0,
@@ -867,16 +967,16 @@ display margins, fringes, header line, and/or mode line.  */)
 {
   register struct window *w = decode_live_window (window);
 
-  return list4 (make_number (WINDOW_BOX_LEFT_EDGE_COL (w)
-                            + WINDOW_LEFT_MARGIN_COLS (w)
-                            + WINDOW_LEFT_FRINGE_COLS (w)),
-               make_number (WINDOW_TOP_EDGE_LINE (w)
-                            + WINDOW_HEADER_LINE_LINES (w)),
-               make_number (WINDOW_BOX_RIGHT_EDGE_COL (w)
-                            - WINDOW_RIGHT_MARGIN_COLS (w)
-                            - WINDOW_RIGHT_FRINGE_COLS (w)),
-               make_number (WINDOW_BOTTOM_EDGE_LINE (w)
-                            - WINDOW_MODE_LINE_LINES (w)));
+  return quad (WINDOW_BOX_LEFT_EDGE_COL (w)
+              + WINDOW_LEFT_MARGIN_COLS (w)
+              + WINDOW_LEFT_FRINGE_COLS (w),
+              WINDOW_TOP_EDGE_LINE (w)
+              + WINDOW_HEADER_LINE_LINES (w),
+              WINDOW_BOX_RIGHT_EDGE_COL (w)
+              - WINDOW_RIGHT_MARGIN_COLS (w)
+              - WINDOW_RIGHT_FRINGE_COLS (w),
+              WINDOW_BOTTOM_EDGE_LINE (w)
+              - WINDOW_MODE_LINE_LINES (w));
 }
 
 DEFUN ("window-inside-pixel-edges", Fwindow_inside_pixel_edges, Swindow_inside_pixel_edges, 0, 1, 0,
@@ -894,16 +994,16 @@ display margins, fringes, header line, and/or mode line.  */)
 {
   register struct window *w = decode_live_window (window);
 
-  return list4 (make_number (WINDOW_BOX_LEFT_EDGE_X (w)
-                            + WINDOW_LEFT_MARGIN_WIDTH (w)
-                            + WINDOW_LEFT_FRINGE_WIDTH (w)),
-               make_number (WINDOW_TOP_EDGE_Y (w)
-                            + WINDOW_HEADER_LINE_HEIGHT (w)),
-               make_number (WINDOW_BOX_RIGHT_EDGE_X (w)
-                            - WINDOW_RIGHT_MARGIN_WIDTH (w)
-                            - WINDOW_RIGHT_FRINGE_WIDTH (w)),
-               make_number (WINDOW_BOTTOM_EDGE_Y (w)
-                            - WINDOW_MODE_LINE_HEIGHT (w)));
+  return quad (WINDOW_BOX_LEFT_EDGE_X (w)
+              + WINDOW_LEFT_MARGIN_WIDTH (w)
+              + WINDOW_LEFT_FRINGE_WIDTH (w),
+              WINDOW_TOP_EDGE_Y (w)
+              + WINDOW_HEADER_LINE_HEIGHT (w),
+              WINDOW_BOX_RIGHT_EDGE_X (w)
+              - WINDOW_RIGHT_MARGIN_WIDTH (w)
+              - WINDOW_RIGHT_FRINGE_WIDTH (w),
+              WINDOW_BOTTOM_EDGE_Y (w)
+              - WINDOW_MODE_LINE_HEIGHT (w));
 }
 
 DEFUN ("window-inside-absolute-pixel-edges",
@@ -923,18 +1023,19 @@ display margins, fringes, header line, and/or mode line.  */)
 {
   register struct window *w = decode_live_window (window);
   int add_x, add_y;
+
   calc_absolute_offset (w, &add_x, &add_y);
 
-  return list4 (make_number (WINDOW_BOX_LEFT_EDGE_X (w)
-                            + WINDOW_LEFT_MARGIN_WIDTH (w)
-                            + WINDOW_LEFT_FRINGE_WIDTH (w) + add_x),
-               make_number (WINDOW_TOP_EDGE_Y (w)
-                            + WINDOW_HEADER_LINE_HEIGHT (w) + add_y),
-               make_number (WINDOW_BOX_RIGHT_EDGE_X (w)
-                            - WINDOW_RIGHT_MARGIN_WIDTH (w)
-                            - WINDOW_RIGHT_FRINGE_WIDTH (w) + add_x),
-               make_number (WINDOW_BOTTOM_EDGE_Y (w)
-                            - WINDOW_MODE_LINE_HEIGHT (w) + add_y));
+  return quad (WINDOW_BOX_LEFT_EDGE_X (w)
+              + WINDOW_LEFT_MARGIN_WIDTH (w)
+              + WINDOW_LEFT_FRINGE_WIDTH (w) + add_x,
+              WINDOW_TOP_EDGE_Y (w)
+              + WINDOW_HEADER_LINE_HEIGHT (w) + add_y,
+              WINDOW_BOX_RIGHT_EDGE_X (w)
+              - WINDOW_RIGHT_MARGIN_WIDTH (w)
+              - WINDOW_RIGHT_FRINGE_WIDTH (w) + add_x,
+              WINDOW_BOTTOM_EDGE_Y (w)
+              - WINDOW_MODE_LINE_HEIGHT (w) + add_y);
 }
 
 /* Test if the character at column X, row Y is within window W.
@@ -1171,7 +1272,7 @@ If they are in the windows's left or right marginal areas, `left-margin'\n\
       return Qnil;
 
     default:
-      abort ();
+      emacs_abort ();
     }
 }
 
@@ -1267,12 +1368,7 @@ The top left corner of the frame is considered to be row 0,
 column 0.  */)
   (Lisp_Object x, Lisp_Object y, Lisp_Object frame)
 {
-  struct frame *f;
-
-  if (NILP (frame))
-    frame = selected_frame;
-  CHECK_LIVE_FRAME (frame);
-  f = XFRAME (frame);
+  struct frame *f = decode_live_frame (frame);
 
   /* Check that arguments are integers or floats.  */
   CHECK_NUMBER_OR_FLOAT (x);
@@ -1290,22 +1386,21 @@ DEFUN ("window-point", Fwindow_point, Swindow_point, 0, 1, 0,
        doc: /* Return current value of point in WINDOW.
 WINDOW must be a live window and defaults to the selected one.
 
-For a nonselected window, this is the value point would have
-if that window were selected.
+For a nonselected window, this is the value point would have if that
+window were selected.
 
-Note that, when WINDOW is the selected window and its buffer
-is also currently selected, the value returned is the same as (point).
-It would be more strictly correct to return the `top-level' value
-of point, outside of any save-excursion forms.
-But that is hard to define.  */)
+Note that, when WINDOW is selected, the value returned is the same as
+that returned by `point' for WINDOW's buffer.  It would be more strictly
+correct to return the `top-level' value of `point', outside of any
+`save-excursion' forms.  But that is hard to define.  */)
   (Lisp_Object window)
 {
   register struct window *w = decode_live_window (window);
 
-  if (w == XWINDOW (selected_window)
-      && current_buffer == XBUFFER (w->buffer))
-    return Fpoint ();
-  return Fmarker_position (w->pointm);
+  if (w == XWINDOW (selected_window))
+    return make_number (BUF_PT (XBUFFER (w->buffer)));
+  else
+    return Fmarker_position (w->pointm);
 }
 
 DEFUN ("window-start", Fwindow_start, Swindow_start, 0, 1, 0,
@@ -1359,9 +1454,7 @@ if it isn't already recorded.  */)
 #endif
 
   if (! NILP (update)
-      && ! (! NILP (w->window_end_valid)
-           && w->last_modified >= BUF_MODIFF (b)
-           && w->last_overlay_modified >= BUF_OVERLAY_MODIFF (b))
+      && (windows_or_buffers_changed || NILP (w->window_end_valid))
       && !noninteractive)
     {
       struct text_pos startp;
@@ -1415,16 +1508,27 @@ Return POS.  */)
   register struct window *w = decode_live_window (window);
 
   CHECK_NUMBER_COERCE_MARKER (pos);
-  if (w == XWINDOW (selected_window)
-      && XBUFFER (w->buffer) == current_buffer)
-    Fgoto_char (pos);
-  else
-    set_marker_restricted (w->pointm, pos, w->buffer);
 
-  /* We have to make sure that redisplay updates the window to show
-     the new value of point.  */
-  if (!EQ (window, selected_window))
-    ++windows_or_buffers_changed;
+  if (w == XWINDOW (selected_window))
+    {
+      if (XBUFFER (w->buffer) == current_buffer)
+       Fgoto_char (pos);
+      else
+       {
+         struct buffer *old_buffer = current_buffer;
+
+         set_buffer_internal (XBUFFER (w->buffer));
+         Fgoto_char (pos);
+         set_buffer_internal (old_buffer);
+       }
+    }
+  else
+    {
+      set_marker_restricted (w->pointm, pos, w->buffer);
+      /* We have to make sure that redisplay updates the window to show
+        the new value of point.  */
+      ++windows_or_buffers_changed;
+    }
 
   return pos;
 }
@@ -1512,8 +1616,7 @@ display row, and VPOS is the row number (0-based) containing POS.  */)
     {
       Lisp_Object part = Qnil;
       if (!fully_p)
-       part = list4 (make_number (rtop), make_number (rbot),
-                       make_number (rowh), make_number (vpos));
+       part = quad (rtop, rbot, rowh, vpos);
       in_window = Fcons (make_number (x),
                         Fcons (make_number (y), part));
     }
@@ -1579,23 +1682,18 @@ Return nil if window display is not up-to-date.  In that case, use
       if (!WINDOW_WANTS_HEADER_LINE_P (w))
        return Qnil;
       row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
-      if (!row->enabled_p)
-       return Qnil;
-      return list4 (make_number (row->height),
-                   make_number (0), make_number (0),
-                   make_number (0));
+      return row->enabled_p ? quad (row->height, 0, 0, 0) : Qnil;
     }
 
   if (EQ (line, Qmode_line))
     {
       row = MATRIX_MODE_LINE_ROW (w->current_matrix);
-      if (!row->enabled_p)
-       return Qnil;
-      return list4 (make_number (row->height),
-                   make_number (0), /* not accurate */
-                   make_number (WINDOW_HEADER_LINE_HEIGHT (w)
-                                + window_text_bottom_y (w)),
-                   make_number (0));
+      return (row->enabled_p ?
+             quad (row->height,
+                   0, /* not accurate */
+                   WINDOW_HEADER_LINE_HEIGHT (w)
+                   + window_text_bottom_y (w), 0)
+             : Qnil);
     }
 
   CHECK_NUMBER (line);
@@ -1624,10 +1722,7 @@ Return nil if window display is not up-to-date.  In that case, use
 
  found_row:
   crop = max (0, (row->y + row->height) - max_y);
-  return list4 (make_number (row->height + min (0, row->y) - crop),
-               make_number (i),
-               make_number (row->y),
-               make_number (crop));
+  return quad (row->height + min (0, row->y) - crop, i, row->y, crop);
 }
 
 DEFUN ("window-dedicated-p", Fwindow_dedicated_p, Swindow_dedicated_p,
@@ -1674,7 +1769,8 @@ buffer.  If and when `set-window-buffer' displays another buffer in a
 window, it also makes sure that the window is no more dedicated.  */)
   (Lisp_Object window, Lisp_Object flag)
 {
-  return WSET (decode_live_window (window), dedicated, flag);
+  wset_dedicated (decode_live_window (window), flag);
+  return flag;
 }
 
 DEFUN ("window-prev-buffers", Fwindow_prev_buffers, Swindow_prev_buffers,
@@ -1700,7 +1796,8 @@ where BUFFER is a buffer, WINDOW-START is the start position of the
 window for that buffer, and POS is a window-specific point value.  */)
      (Lisp_Object window, Lisp_Object prev_buffers)
 {
-  return WSET (decode_live_window (window), prev_buffers, prev_buffers);
+  wset_prev_buffers (decode_live_window (window), prev_buffers);
+  return prev_buffers;
 }
 
 DEFUN ("window-next-buffers", Fwindow_next_buffers, Swindow_next_buffers,
@@ -1719,7 +1816,8 @@ WINDOW must be a live window and defaults to the selected one.
 NEXT-BUFFERS should be a list of buffers.  */)
      (Lisp_Object window, Lisp_Object next_buffers)
 {
-  return WSET (decode_live_window (window), next_buffers, next_buffers);
+  wset_next_buffers (decode_live_window (window), next_buffers);
+  return next_buffers;
 }
 
 DEFUN ("window-parameters", Fwindow_parameters, Swindow_parameters,
@@ -1735,29 +1833,29 @@ return value is a list of elements of the form (PARAMETER . VALUE).  */)
 DEFUN ("window-parameter", Fwindow_parameter, Swindow_parameter,
        2, 2, 0,
        doc:  /* Return WINDOW's value for PARAMETER.
-WINDOW must be a valid window and defaults to the selected one.  */)
+WINDOW can be any window and defaults to the selected one.  */)
   (Lisp_Object window, Lisp_Object parameter)
 {
   Lisp_Object result;
 
-  result = Fassq (parameter, decode_valid_window (window)->window_parameters);
+  result = Fassq (parameter, decode_any_window (window)->window_parameters);
   return CDR_SAFE (result);
 }
 
 DEFUN ("set-window-parameter", Fset_window_parameter,
        Sset_window_parameter, 3, 3, 0,
        doc: /* Set WINDOW's value of PARAMETER to VALUE.
-WINDOW must be a valid window and defaults to the selected one.
+WINDOW can be any window and defaults to the selected one.
 Return VALUE.  */)
   (Lisp_Object window, Lisp_Object parameter, Lisp_Object value)
 {
-  register struct window *w = decode_valid_window (window);
+  register struct window *w = decode_any_window (window);
   Lisp_Object old_alist_elt;
 
   old_alist_elt = Fassq (parameter, w->window_parameters);
   if (NILP (old_alist_elt))
-    WSET (w, window_parameters,
-         Fcons (Fcons (parameter, value), w->window_parameters));
+    wset_window_parameters
+      (w, Fcons (Fcons (parameter, value), w->window_parameters));
   else
     Fsetcdr (old_alist_elt, value);
   return value;
@@ -1802,7 +1900,8 @@ DEFUN ("set-window-display-table", Fset_window_display_table, Sset_window_displa
 WINDOW must be a live window and defaults to the selected one.  */)
   (register Lisp_Object window, Lisp_Object table)
 {
-  return WSET (decode_live_window (window), display_table, table);
+  wset_display_table (decode_live_window (window), table);
+  return table;
 }
 \f
 /* Record info on buffer window W is displaying
@@ -1816,7 +1915,7 @@ unshow_buffer (register struct window *w)
   buf = w->buffer;
   b = XBUFFER (buf);
   if (b != XMARKER (w->pointm)->buffer)
-    abort ();
+    emacs_abort ();
 
 #if 0
   if (w == XWINDOW (selected_window)
@@ -1837,6 +1936,9 @@ unshow_buffer (register struct window *w)
      is actually stored in that buffer, and the window's pointm isn't used.
      So don't clobber point in that buffer.  */
   if (! EQ (buf, XWINDOW (selected_window)->buffer)
+      /* Don't clobber point in current buffer either (this could be
+        useful in connection with bug#12208).
+      && XBUFFER (buf) != current_buffer  */
       /* This line helps to fix Horsley's testbug.el bug.  */
       && !(WINDOWP (BVAR (b, last_selected_window))
           && w != XWINDOW (BVAR (b, last_selected_window))
@@ -1851,7 +1953,7 @@ unshow_buffer (register struct window *w)
 
   if (WINDOWP (BVAR (b, last_selected_window))
       && w == XWINDOW (BVAR (b, last_selected_window)))
-    BSET (b, last_selected_window, Qnil);
+    bset_last_selected_window (b, Qnil);
 }
 
 /* Put NEW into the window structure in place of OLD.  SETFLAG zero
@@ -1870,14 +1972,14 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag)
 
    if (setflag)
      {
-      WSET (n, left_col, o->left_col);
-      WSET (n, top_line, o->top_line);
-      WSET (n, total_cols, o->total_cols);
-      WSET (n, total_lines, o->total_lines);
-      WSET (n, normal_cols, o->normal_cols);
-      WSET (o, normal_cols, make_float (1.0));
-      WSET (n, normal_lines, o->normal_lines);
-      WSET (o, normal_lines, make_float (1.0));
+      wset_left_col (n, o->left_col);
+      wset_top_line (n, o->top_line);
+      wset_total_cols (n, o->total_cols);
+      wset_total_lines (n, o->total_lines);
+      wset_normal_cols (n, o->normal_cols);
+      wset_normal_cols (o, make_float (1.0));
+      wset_normal_lines (n, o->normal_lines);
+      wset_normal_lines (o, make_float (1.0));
       n->desired_matrix = n->current_matrix = 0;
       n->vscroll = 0;
       memset (&n->cursor, 0, sizeof (n->cursor));
@@ -1887,30 +1989,30 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag)
       n->phys_cursor_width = -1;
       n->must_be_updated_p = 0;
       n->pseudo_window_p = 0;
-      WSET (n, window_end_vpos, make_number (0));
-      WSET (n, window_end_pos, make_number (0));
-      WSET (n, window_end_valid, Qnil);
+      wset_window_end_vpos (n, make_number (0));
+      wset_window_end_pos (n, make_number (0));
+      wset_window_end_valid (n, Qnil);
       n->frozen_window_start_p = 0;
     }
 
   tem = o->next;
-  WSET (n, next, tem);
+  wset_next (n, tem);
   if (!NILP (tem))
-    WSET (XWINDOW (tem), prev, new);
+    wset_prev (XWINDOW (tem), new);
 
   tem = o->prev;
-  WSET (n, prev, tem);
+  wset_prev (n, tem);
   if (!NILP (tem))
-    WSET (XWINDOW (tem), next, new);
+    wset_next (XWINDOW (tem), new);
 
   tem = o->parent;
-  WSET (n, parent, tem);
+  wset_parent (n, tem);
   if (!NILP (tem))
     {
       if (EQ (XWINDOW (tem)->vchild, old))
-       WSET (XWINDOW (tem), vchild, new);
+       wset_vchild (XWINDOW (tem), new);
       if (EQ (XWINDOW (tem)->hchild, old))
-       WSET (XWINDOW (tem), hchild, new);
+       wset_hchild (XWINDOW (tem), new);
     }
 }
 
@@ -1943,34 +2045,34 @@ recombine_windows (Lisp_Object window)
             assign new normal sizes.  */
          if (NILP (w->prev))
            if (horflag)
-             WSET (p, hchild, child);
+             wset_hchild (p, child);
            else
-             WSET (p, vchild, child);
+             wset_vchild (p, child);
          else
            {
-             WSET (c, prev, w->prev);
-             WSET (XWINDOW (w->prev), next, child);
+             wset_prev (c, w->prev);
+             wset_next (XWINDOW (w->prev), child);
            }
 
          while (c)
            {
-             WSET (c, parent, parent);
+             wset_parent (c, parent);
 
              if (horflag)
-               WSET (c, normal_cols,
-                     make_float (XFLOATINT (c->total_cols)
-                                 / XFLOATINT (p->total_cols)));
+               wset_normal_cols (c,
+                                 make_float (XFLOATINT (c->total_cols)
+                                             / XFLOATINT (p->total_cols)));
              else
-               WSET (c, normal_lines,
-                     make_float (XFLOATINT (c->total_lines)
-                                 / XFLOATINT (p->total_lines)));
+               wset_normal_lines (c,
+                                  make_float (XFLOATINT (c->total_lines)
+                                              / XFLOATINT (p->total_lines)));
 
              if (NILP (c->next))
                {
                  if (!NILP (w->next))
                    {
-                     WSET (c, next, w->next);
-                     WSET (XWINDOW (c->next), prev, child);
+                     wset_next (c, w->next);
+                     wset_prev (XWINDOW (c->next), child);
                    }
 
                  c = 0;
@@ -1983,8 +2085,8 @@ recombine_windows (Lisp_Object window)
            }
 
          /* WINDOW can be deleted now.  */
-         WSET (w, vchild, Qnil);
-         WSET (w, hchild, Qnil);
+         wset_vchild (w, Qnil);
+         wset_hchild (w, Qnil);
        }
     }
 }
@@ -2131,11 +2233,9 @@ candidate_window_p (Lisp_Object window, Lisp_Object owindow, Lisp_Object minibuf
 static void
 decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object *all_frames)
 {
-  if (NILP (*window))
-    *window = selected_window;
-  else
-    CHECK_LIVE_WINDOW (*window);
+  struct window *w = decode_live_window (*window);
 
+  XSETWINDOW (*window, w);
   /* MINIBUF nil may or may not include minibuffers.  Decide if it
      does.  */
   if (NILP (*minibuf))
@@ -2151,7 +2251,7 @@ decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object
   if (NILP (*all_frames))
     *all_frames
       = (!EQ (*minibuf, Qlambda)
-        ? FRAME_MINIBUF_WINDOW (XFRAME (XWINDOW (*window)->frame))
+        ? FRAME_MINIBUF_WINDOW (XFRAME (w->frame))
         : Qnil);
   else if (EQ (*all_frames, Qvisible))
     ;
@@ -2505,7 +2605,7 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
            if (EQ (w->buffer, obj))
              {
                /* Undedicate WINDOW.  */
-               WSET (w, dedicated, Qnil);
+               wset_dedicated (w, Qnil);
                /* Make WINDOW show the buffer returned by
                   other_buffer_safely, don't run any hooks.  */
                set_window_buffer
@@ -2533,8 +2633,8 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
            /* Check for a window that has a killed buffer.  */
          case CHECK_ALL_WINDOWS:
            if (! NILP (w->buffer)
-               && NILP (BVAR (XBUFFER (w->buffer), name)))
-             abort ();
+               && !BUFFER_LIVE_P (XBUFFER (w->buffer)))
+             emacs_abort ();
            break;
 
          case WINDOW_LOOP_UNUSED:
@@ -2696,7 +2796,7 @@ window-start value is reasonable when this function is called.  */)
        }
     }
 
-  BLOCK_INPUT;
+  block_input ();
   if (!FRAME_INITIAL_P (f))
     {
         Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
@@ -2727,7 +2827,7 @@ window-start value is reasonable when this function is called.  */)
       /* Resize child windows vertically.  */
       XSETINT (delta, XINT (r->total_lines)
               - XINT (w->total_lines));
-      WSET (w, top_line, r->top_line);
+      wset_top_line (w, r->top_line);
       resize_root_window (window, delta, Qnil, Qnil);
       if (window_resize_check (w, 0))
        window_resize_apply (w, 0);
@@ -2743,10 +2843,10 @@ window-start value is reasonable when this function is called.  */)
       /* Resize child windows horizontally.  */
       if (!resize_failed)
        {
-         WSET (w, left_col, r->left_col);
+         wset_left_col (w, r->left_col);
          XSETINT (delta,
                   XINT (r->total_cols) - XINT (w->total_cols));
-         WSET (w, left_col, r->left_col);
+         wset_left_col (w, r->left_col);
          resize_root_window (window, delta, Qt, Qnil);
          if (window_resize_check (w, 1))
            window_resize_apply (w, 1);
@@ -2774,32 +2874,32 @@ window-start value is reasonable when this function is called.  */)
     {
       sibling = w->prev;
       s = XWINDOW (sibling);
-      WSET (s, next, w->next);
+      wset_next (s, w->next);
       if (!NILP (s->next))
-       WSET (XWINDOW (s->next), prev, sibling);
+       wset_prev (XWINDOW (s->next), sibling);
     }
   else
     /* Get SIBLING below (on the right of) WINDOW.  */
     {
       sibling = w->next;
       s = XWINDOW (sibling);
-      WSET (s, prev, Qnil);
+      wset_prev (s, Qnil);
       if (!NILP (XWINDOW (w->parent)->vchild))
-       WSET (XWINDOW (w->parent), vchild, sibling);
+       wset_vchild (XWINDOW (w->parent), sibling);
       else
-       WSET (XWINDOW (w->parent), hchild, sibling);
+       wset_hchild (XWINDOW (w->parent), sibling);
     }
 
   /* Delete ROOT and all child windows of ROOT.  */
   if (!NILP (r->vchild))
     {
       delete_all_child_windows (r->vchild);
-      WSET (r, vchild, Qnil);
+      wset_vchild (r, Qnil);
     }
   else if (!NILP (r->hchild))
     {
       delete_all_child_windows (r->hchild);
-      WSET (r, hchild, Qnil);
+      wset_hchild (r, Qnil);
     }
 
   replace_window (root, window, 1);
@@ -2826,7 +2926,7 @@ window-start value is reasonable when this function is called.  */)
          pos = *vmotion (startpos, -top, w);
 
          set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
-         WSET (w, window_end_valid, Qnil);
+         wset_window_end_valid (w, Qnil);
          w->start_at_line_beg = (pos.bytepos == BEGV_BYTE
                                    || FETCH_BYTE (pos.bytepos - 1) == '\n');
          /* We need to do this, so that the window-scroll-functions
@@ -2838,7 +2938,7 @@ window-start value is reasonable when this function is called.  */)
     }
 
   adjust_glyphs (f);
-  UNBLOCK_INPUT;
+  unblock_input ();
 
   run_window_configuration_change_hook (f);
 
@@ -2917,14 +3017,14 @@ adjust_window_margins (struct window *w)
     {
       if (WINDOW_LEFT_MARGIN_COLS (w) > 0)
        {
-         WSET (w, left_margin_cols, make_number (margin_cols / 2));
-         WSET (w, right_margin_cols, make_number (margin_cols / 2));
+         wset_left_margin_cols (w, make_number (margin_cols / 2));
+         wset_right_margin_cols (w, make_number (margin_cols / 2));
        }
       else
-       WSET (w, right_margin_cols, make_number (margin_cols));
+       wset_right_margin_cols (w, make_number (margin_cols));
     }
   else
-    WSET (w, left_margin_cols, make_number (margin_cols));
+    wset_left_margin_cols (w, make_number (margin_cols));
   return 1;
 }
 \f
@@ -2966,7 +3066,7 @@ run_window_configuration_change_hook (struct frame *f)
   /* Use the right buffer.  Matters when running the local hooks.  */
   if (current_buffer != XBUFFER (Fwindow_buffer (Qnil)))
     {
-      record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
+      record_unwind_current_buffer ();
       Fset_buffer (Fwindow_buffer (Qnil));
     }
 
@@ -3001,12 +3101,12 @@ run_window_configuration_change_hook (struct frame *f)
 }
 
 DEFUN ("run-window-configuration-change-hook", Frun_window_configuration_change_hook,
-       Srun_window_configuration_change_hook, 1, 1, 0,
-       doc: /* Run `window-configuration-change-hook' for FRAME.  */)
-     (Lisp_Object frame)
+       Srun_window_configuration_change_hook, 0, 1, 0,
+       doc: /* Run `window-configuration-change-hook' for FRAME. 
+If FRAME is omitted or nil, it defaults to the selected frame.  */)
+  (Lisp_Object frame)
 {
-  CHECK_LIVE_FRAME (frame);
-  run_window_configuration_change_hook (XFRAME (frame));
+  run_window_configuration_change_hook (decode_live_frame (frame));
   return Qnil;
 }
 
@@ -3024,23 +3124,23 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int
   ptrdiff_t count = SPECPDL_INDEX ();
   int samebuf = EQ (buffer, w->buffer);
 
-  WSET (w, buffer, buffer);
+  wset_buffer (w, buffer);
 
   if (EQ (window, selected_window))
-    BSET (b, last_selected_window, window);
+    bset_last_selected_window (b, window);
 
   /* Let redisplay errors through.  */
   b->display_error_modiff = 0;
 
   /* Update time stamps of buffer display.  */
   if (INTEGERP (BVAR (b, display_count)))
-    BSET (b, display_count, make_number (XINT (BVAR (b, display_count)) + 1));
-  BSET (b, display_time, Fcurrent_time ());
+    bset_display_count (b, make_number (XINT (BVAR (b, display_count)) + 1));
+  bset_display_time (b, Fcurrent_time ());
 
-  WSET (w, window_end_pos, make_number (0));
-  WSET (w, window_end_vpos, make_number (0));
+  wset_window_end_pos (w, make_number (0));
+  wset_window_end_vpos (w, make_number (0));
   memset (&w->last_cursor, 0, sizeof w->last_cursor);
-  WSET (w, window_end_valid, Qnil);
+  wset_window_end_valid (w, Qnil);
   if (!(keep_margins_p && samebuf))
     { /* If we're not actually changing the buffer, don't reset hscroll and
         vscroll.  This case happens for example when called from
@@ -3070,7 +3170,7 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int
      because that might itself be a local variable.  */
   if (window_initialized)
     {
-      record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
+      record_unwind_current_buffer ();
       Fset_buffer (buffer);
     }
 
@@ -3085,8 +3185,8 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int
       Lisp_Object save_left = w->left_margin_cols;
       Lisp_Object save_right = w->right_margin_cols;
 
-      WSET (w, left_margin_cols, Qnil);
-      WSET (w, right_margin_cols, Qnil);
+      wset_left_margin_cols (w, Qnil);
+      wset_right_margin_cols (w, Qnil);
 
       Fset_window_fringes (window,
                           BVAR (b, left_fringe_width), BVAR (b, right_fringe_width),
@@ -3096,8 +3196,8 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int
                               BVAR (b, scroll_bar_width),
                               BVAR (b, vertical_scroll_bar_type), Qnil);
 
-      WSET (w, left_margin_cols, save_left);
-      WSET (w, right_margin_cols, save_right);
+      wset_left_margin_cols (w, save_left);
+      wset_right_margin_cols (w, save_right);
 
       Fset_window_margins (window,
                           BVAR (b, left_margin_cols), BVAR (b, right_margin_cols));
@@ -3138,7 +3238,7 @@ This function runs `window-scroll-functions' before running
   XSETWINDOW (window, w);
   buffer = Fget_buffer (buffer_or_name);
   CHECK_BUFFER (buffer);
-  if (NILP (BVAR (XBUFFER (buffer), name)))
+  if (!BUFFER_LIVE_P (XBUFFER (buffer)))
     error ("Attempt to display deleted buffer");
 
   tem = w->buffer;
@@ -3156,7 +3256,7 @@ This function runs `window-scroll-functions' before running
          else
            /* WINDOW is weakly dedicated to its buffer, reset
               dedication.  */
-           WSET (w, dedicated, Qnil);
+           wset_dedicated (w, Qnil);
 
          call1 (Qrecord_window_buffer, window);
        }
@@ -3203,7 +3303,7 @@ displaying that buffer.  */)
 
   if (STRINGP (object))
     object = Fget_buffer (object);
-  if (BUFFERP (object) && !NILP (BVAR (XBUFFER (object), name)))
+  if (BUFFERP (object) && BUFFER_LIVE_P (XBUFFER (object)))
     {
       /* Walk all windows looking for buffer, and force update
         of each of those windows.  */
@@ -3218,7 +3318,7 @@ displaying that buffer.  */)
   return Qnil;
 }
 
-
+/* Obsolete since 24.3.  */
 void
 temp_output_buffer_show (register Lisp_Object buf)
 {
@@ -3226,7 +3326,7 @@ temp_output_buffer_show (register Lisp_Object buf)
   register Lisp_Object window;
   register struct window *w;
 
-  BSET (XBUFFER (buf), directory, BVAR (current_buffer, directory));
+  bset_directory (XBUFFER (buf), BVAR (current_buffer, directory));
 
   Fset_buffer (buf);
   BUF_SAVE_MODIFF (XBUFFER (buf)) = MODIFF;
@@ -3271,16 +3371,6 @@ temp_output_buffer_show (register Lisp_Object buf)
       }
     }
 }
-
-DEFUN ("internal-temp-output-buffer-show",
-       Ftemp_output_buffer_show, Stemp_output_buffer_show,
-       1, 1, 0,
-       doc: /* Internal function for `with-output-to-temp-buffer'.  */)
-     (Lisp_Object buf)
-{
-  temp_output_buffer_show (buf);
-  return Qnil;
-}
 \f
 /* Make new window, have it replace WINDOW in window-tree, and make
    WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only
@@ -3302,17 +3392,17 @@ make_parent_window (Lisp_Object window, int horflag)
 
   replace_window (window, parent, 1);
 
-  WSET (o, next, Qnil);
-  WSET (o, prev, Qnil);
-  WSET (o, parent, parent);
+  wset_next (o, Qnil);
+  wset_prev (o, Qnil);
+  wset_parent (o, parent);
 
-  WSET (p, hchild, horflag ? window : Qnil);
-  WSET (p, vchild, horflag ? Qnil : window);
-  WSET (p, start, Qnil);
-  WSET (p, pointm, Qnil);
-  WSET (p, buffer, Qnil);
-  WSET (p, combination_limit, Qnil);
-  WSET (p, window_parameters, Qnil);
+  wset_hchild (p, horflag ? window : Qnil);
+  wset_vchild (p, horflag ? Qnil : window);
+  wset_start (p, Qnil);
+  wset_pointm (p, Qnil);
+  wset_buffer (p, Qnil);
+  wset_combination_limit (p, Qnil);
+  wset_window_parameters (p, Qnil);
 }
 
 /* Make new window from scratch.  */
@@ -3325,19 +3415,23 @@ make_window (void)
   w = allocate_window ();
   /* Initialize Lisp data.  Note that allocate_window initializes all
      Lisp data to nil, so do it only for slots which should not be nil.  */
-  WSET (w, left_col, make_number (0));
-  WSET (w, top_line, make_number (0));
-  WSET (w, total_lines, make_number (0));
-  WSET (w, total_cols, make_number (0));
-  WSET (w, normal_lines, make_float (1.0));
-  WSET (w, normal_cols, make_float (1.0));
-  WSET (w, new_total, make_number (0));
-  WSET (w, new_normal, make_number (0));
-  WSET (w, start, Fmake_marker ());
-  WSET (w, pointm, Fmake_marker ());
-  WSET (w, vertical_scroll_bar_type, Qt);
-  WSET (w, window_end_pos, make_number (0));
-  WSET (w, window_end_vpos, make_number (0));
+  wset_left_col (w, make_number (0));
+  wset_top_line (w, make_number (0));
+  wset_total_lines (w, make_number (0));
+  wset_total_cols (w, make_number (0));
+  wset_normal_lines (w, make_float (1.0));
+  wset_normal_cols (w, make_float (1.0));
+  wset_new_total (w, make_number (0));
+  wset_new_normal (w, make_number (0));
+  wset_start (w, Fmake_marker ());
+  wset_pointm (w, Fmake_marker ());
+  wset_vertical_scroll_bar_type (w, Qt);
+  wset_window_end_pos (w, make_number (0));
+  wset_window_end_vpos (w, make_number (0));
+  /* These Lisp fields are marked specially so they're not set to nil by
+     allocate_window.  */
+  wset_prev_buffers (w, Qnil);
+  wset_next_buffers (w, Qnil);
 
   /* Initialize non-Lisp data.  Note that allocate_window zeroes out all
      non-Lisp data, so do it only for slots which should not be zero.  */
@@ -3368,9 +3462,9 @@ Note: This function does not operate on any child windows of WINDOW.  */)
 
   CHECK_NUMBER (size);
   if (NILP (add))
-    WSET (w, new_total, size);
+    wset_new_total (w, size);
   else
-    WSET (w, new_total, make_number (XINT (w->new_total) + XINT (size)));
+    wset_new_total (w, make_number (XINT (w->new_total) + XINT (size)));
 
   return w->new_total;
 }
@@ -3383,7 +3477,8 @@ Return SIZE.
 Note: This function does not operate on any child windows of WINDOW.  */)
      (Lisp_Object window, Lisp_Object size)
 {
-  return WSET (decode_valid_window (window), new_normal, size);
+  wset_new_normal (decode_valid_window (window), size);
+  return size;
 }
 
 /* Return 1 if setting w->total_lines (w->total_cols if HORFLAG is
@@ -3484,17 +3579,17 @@ window_resize_apply (struct window *w, int horflag)
      parent window has been set *before*.  */
   if (horflag)
     {
-      WSET (w, total_cols, w->new_total);
+      wset_total_cols (w, w->new_total);
       if (NUMBERP (w->new_normal))
-       WSET (w, normal_cols, w->new_normal);
+       wset_normal_cols (w, w->new_normal);
 
       pos = XINT (w->left_col);
     }
   else
     {
-      WSET (w, total_lines, w->new_total);
+      wset_total_lines (w, w->new_total);
       if (NUMBERP (w->new_normal))
-       WSET (w, normal_lines, w->new_normal);
+       wset_normal_lines (w, w->new_normal);
 
       pos = XINT (w->top_line);
     }
@@ -3506,9 +3601,9 @@ window_resize_apply (struct window *w, int horflag)
       while (c)
        {
          if (horflag)
-           WSET (c, left_col, make_number (pos));
+           wset_left_col (c, make_number (pos));
          else
-           WSET (c, top_line, make_number (pos));
+           wset_top_line (c, make_number (pos));
          window_resize_apply (c, horflag);
          if (!horflag)
            pos = pos + XINT (c->total_lines);
@@ -3522,9 +3617,9 @@ window_resize_apply (struct window *w, int horflag)
       while (c)
        {
          if (horflag)
-           WSET (c, left_col, make_number (pos));
+           wset_left_col (c, make_number (pos));
          else
-           WSET (c, top_line, make_number (pos));
+           wset_top_line (c, make_number (pos));
          window_resize_apply (c, horflag);
          if (horflag)
            pos = pos + XINT (c->total_cols);
@@ -3538,10 +3633,12 @@ window_resize_apply (struct window *w, int horflag)
 }
 
 
-DEFUN ("window-resize-apply", Fwindow_resize_apply, Swindow_resize_apply, 1, 2, 0,
+DEFUN ("window-resize-apply", Fwindow_resize_apply, Swindow_resize_apply, 0, 2, 0,
        doc: /* Apply requested size values for window-tree of FRAME.
-Optional argument HORIZONTAL omitted or nil means apply requested height
-values.  HORIZONTAL non-nil means apply requested width values.
+If FRAME is omitted or nil, it defaults to the selected frame.
+
+Optional argument HORIZONTAL omitted or nil means apply requested
+height values.  HORIZONTAL non-nil means apply requested width values.
 
 This function checks whether the requested values sum up to a valid
 window layout, recursively assigns the new sizes of all child windows
@@ -3552,30 +3649,23 @@ Note: This function does not check any of `window-fixed-size-p',
 be applied on the Elisp level.  */)
      (Lisp_Object frame, Lisp_Object horizontal)
 {
-  struct frame *f;
-  struct window *r;
+  struct frame *f = decode_live_frame (frame);
+  struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
   int horflag = !NILP (horizontal);
 
-  if (NILP (frame))
-    frame = selected_frame;
-  CHECK_LIVE_FRAME (frame);
-
-  f = XFRAME (frame);
-  r = XWINDOW (FRAME_ROOT_WINDOW (f));
-
   if (!window_resize_check (r, horflag)
       || ! EQ (r->new_total,
               (horflag ? r->total_cols : r->total_lines)))
     return Qnil;
 
-  BLOCK_INPUT;
+  block_input ();
   window_resize_apply (r, horflag);
 
   windows_or_buffers_changed++;
   FRAME_WINDOW_SIZES_CHANGED (f) = 1;
 
   adjust_glyphs (f);
-  UNBLOCK_INPUT;
+  unblock_input ();
 
   run_window_configuration_change_hook (f);
 
@@ -3605,13 +3695,13 @@ resize_frame_windows (struct frame *f, int size, int horflag)
                     - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
                        ? 1 : 0)));
 
-  WSET (r, top_line, make_number (FRAME_TOP_MARGIN (f)));
+  wset_top_line (r, make_number (FRAME_TOP_MARGIN (f)));
   if (NILP (r->vchild) && NILP (r->hchild))
     /* For a leaf root window just set the size.  */
     if (horflag)
-      WSET (r, total_cols, make_number (new_size));
+      wset_total_cols (r, make_number (new_size));
     else
-      WSET (r, total_lines, make_number (new_size));
+      wset_total_lines (r, make_number (new_size));
   else
     {
       /* old_size is the old size of the frame's root window.  */
@@ -3646,9 +3736,9 @@ resize_frame_windows (struct frame *f, int size, int horflag)
                  root = f->selected_window;
                  Fdelete_other_windows_internal (root, Qnil);
                  if (horflag)
-                   WSET (XWINDOW (root), total_cols, make_number (new_size));
+                   wset_total_cols (XWINDOW (root), make_number (new_size));
                  else
-                   WSET (XWINDOW (root), total_lines, make_number (new_size));
+                   wset_total_lines (XWINDOW (root), make_number (new_size));
                }
            }
        }
@@ -3658,15 +3748,17 @@ resize_frame_windows (struct frame *f, int size, int horflag)
     {
       m = XWINDOW (mini);
       if (horflag)
-       WSET (m, total_cols, make_number (size));
+       wset_total_cols (m, make_number (size));
       else
        {
          /* Are we sure we always want 1 line here?  */
-         WSET (m, total_lines, make_number (1));
-         WSET (m, top_line,
-               make_number (XINT (r->top_line) + XINT (r->total_lines)));
+         wset_total_lines (m, make_number (1));
+         wset_top_line
+           (m, make_number (XINT (r->top_line) + XINT (r->total_lines)));
        }
     }
+
+  windows_or_buffers_changed++;
 }
 
 
@@ -3719,7 +3811,7 @@ set correctly.  See the code of `split-window' for how this is done.  */)
      We do that if either `window-combination-limit' is t, or OLD has no
      parent, or OLD is ortho-combined.  */
   combination_limit =
-    !NILP (Vwindow_combination_limit)
+    EQ (Vwindow_combination_limit, Qt)
     || NILP (o->parent)
     || NILP (horflag
             ? (XWINDOW (o->parent)->hchild)
@@ -3745,15 +3837,14 @@ set correctly.  See the code of `split-window' for how this is done.  */)
     {
       p = XWINDOW (o->parent);
       /* Temporarily pretend we split the parent window.  */
-      WSET (p, new_total,
-           make_number (XINT (horflag ? p->total_cols : p->total_lines)
+      wset_new_total
+       (p, make_number (XINT (horflag ? p->total_cols : p->total_lines)
                         - XINT (total_size)));
       if (!window_resize_check (p, horflag))
        error ("Window sizes don't fit");
       else
        /* Undo the temporary pretension.  */
-       WSET (p, new_total,
-             horflag ? p->total_cols : p->total_lines);
+       wset_new_total (p, horflag ? p->total_cols : p->total_lines);
     }
   else
     {
@@ -3775,12 +3866,12 @@ set correctly.  See the code of `split-window' for how this is done.  */)
 
       make_parent_window (old, horflag);
       p = XWINDOW (o->parent);
-      /* Store value of `window-combination-limit' in new parent's
-        combination_limit slot.  */
-      WSET (p, combination_limit, Vwindow_combination_limit);
+      /* Store t in the new parent's combination_limit slot to avoid
+       that its children get merged into another window.  */
+      wset_combination_limit (p, Qt);
       /* These get applied below.  */
-      WSET (p, new_total, horflag ? o->total_cols : o->total_lines);
-      WSET (p, new_normal, new_normal);
+      wset_new_total (p, horflag ? o->total_cols : o->total_lines);
+      wset_new_normal (p, new_normal);
     }
   else
     p = XWINDOW (o->parent);
@@ -3789,70 +3880,70 @@ set correctly.  See the code of `split-window' for how this is done.  */)
   FRAME_WINDOW_SIZES_CHANGED (f) = 1;
   new = make_window ();
   n = XWINDOW (new);
-  WSET (n, frame, frame);
-  WSET (n, parent, o->parent);
-  WSET (n, vchild, Qnil);
-  WSET (n, hchild, Qnil);
+  wset_frame (n, frame);
+  wset_parent (n, o->parent);
+  wset_vchild (n, Qnil);
+  wset_hchild (n, Qnil);
 
   if (EQ (side, Qabove) || EQ (side, Qleft))
     {
-      WSET (n, prev, o->prev);
+      wset_prev (n, o->prev);
       if (NILP (n->prev))
        if (horflag)
-         WSET (p, hchild, new);
+         wset_hchild (p, new);
        else
-         WSET (p, vchild, new);
+         wset_vchild (p, new);
       else
-       WSET (XWINDOW (n->prev), next, new);
-      WSET (n, next, old);
-      WSET (o, prev, new);
+       wset_next (XWINDOW (n->prev), new);
+      wset_next (n, old);
+      wset_prev (o, new);
     }
   else
     {
-      WSET (n, next, o->next);
+      wset_next (n, o->next);
       if (!NILP (n->next))
-       WSET (XWINDOW (n->next), prev, new);
-      WSET (n, prev, old);
-      WSET (o, next, new);
+       wset_prev (XWINDOW (n->next), new);
+      wset_prev (n, old);
+      wset_next (o, new);
     }
 
-  WSET (n, buffer, Qt);
-  WSET (n, window_end_valid, Qnil);
+  wset_buffer (n, Qt);
+  wset_window_end_valid (n, Qnil);
   memset (&n->last_cursor, 0, sizeof n->last_cursor);
 
   /* Get special geometry settings from reference window.  */
-  WSET (n, left_margin_cols, r->left_margin_cols);
-  WSET (n, right_margin_cols, r->right_margin_cols);
-  WSET (n, left_fringe_width, r->left_fringe_width);
-  WSET (n, right_fringe_width, r->right_fringe_width);
+  wset_left_margin_cols (n, r->left_margin_cols);
+  wset_right_margin_cols (n, r->right_margin_cols);
+  wset_left_fringe_width (n, r->left_fringe_width);
+  wset_right_fringe_width (n, r->right_fringe_width);
   n->fringes_outside_margins = r->fringes_outside_margins;
-  WSET (n, scroll_bar_width, r->scroll_bar_width);
-  WSET (n, vertical_scroll_bar_type, r->vertical_scroll_bar_type);
+  wset_scroll_bar_width (n, r->scroll_bar_width);
+  wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type);
 
   /* Directly assign orthogonal coordinates and sizes.  */
   if (horflag)
     {
-      WSET (n, top_line, o->top_line);
-      WSET (n, total_lines, o->total_lines);
+      wset_top_line (n, o->top_line);
+      wset_total_lines (n, o->total_lines);
     }
   else
     {
-      WSET (n, left_col, o->left_col);
-      WSET (n, total_cols, o->total_cols);
+      wset_left_col (n, o->left_col);
+      wset_total_cols (n, o->total_cols);
     }
 
   /* Iso-coordinates and sizes are assigned by window_resize_apply,
      get them ready here.  */
-  WSET (n, new_total, total_size);
-  WSET (n, new_normal, normal_size);
+  wset_new_total (n, total_size);
+  wset_new_normal (n, normal_size);
 
-  BLOCK_INPUT;
+  block_input ();
   window_resize_apply (p, horflag);
   adjust_glyphs (f);
   /* Set buffer of NEW to buffer of reference window.  Don't run
      any hooks.  */
   set_window_buffer (new, r->buffer, 0, 1);
-  UNBLOCK_INPUT;
+  unblock_input ();
 
   /* Maybe we should run the scroll functions in Elisp (which already
      runs the configuration change hook).  */
@@ -3910,20 +4001,20 @@ Signal an error when WINDOW is the only window on its frame.  */)
       before_sibling = 1;
       sibling = w->next;
       s = XWINDOW (sibling);
-      WSET (s, prev, Qnil);
+      wset_prev (s, Qnil);
       if (horflag)
-       WSET (p, hchild, sibling);
+       wset_hchild (p, sibling);
       else
-       WSET (p, vchild, sibling);
+       wset_vchild (p, sibling);
     }
   else
     /* Get SIBLING above (on the left of) WINDOW.  */
     {
       sibling = w->prev;
       s = XWINDOW (sibling);
-      WSET (s, next, w->next);
+      wset_next (s, w->next);
       if (!NILP (s->next))
-       WSET (XWINDOW (s->next), prev, sibling);
+       wset_prev (XWINDOW (s->next), sibling);
     }
 
   if (window_resize_check (r, horflag)
@@ -3933,7 +4024,7 @@ Signal an error when WINDOW is the only window on its frame.  */)
     {
 
       /* Block input.  */
-      BLOCK_INPUT;
+      block_input ();
       window_resize_apply (p, horflag);
 
       /* If this window is referred to by the dpyinfo's mouse
@@ -3950,25 +4041,25 @@ Signal an error when WINDOW is the only window on its frame.  */)
       Vwindow_list = Qnil;
       FRAME_WINDOW_SIZES_CHANGED (f) = 1;
 
-      WSET (w, next, Qnil);  /* Don't delete w->next too.  */
+      wset_next (w, Qnil);  /* Don't delete w->next too.  */
       free_window_matrices (w);
 
       if (!NILP (w->vchild))
        {
          delete_all_child_windows (w->vchild);
-         WSET (w, vchild, Qnil);
+         wset_vchild (w, Qnil);
        }
       else if (!NILP (w->hchild))
        {
          delete_all_child_windows (w->hchild);
-         WSET (w, hchild, Qnil);
+         wset_hchild (w, Qnil);
        }
       else if (!NILP (w->buffer))
        {
          unshow_buffer (w);
          unchain_marker (XMARKER (w->pointm));
          unchain_marker (XMARKER (w->start));
-         WSET (w, buffer, Qnil);
+         wset_buffer (w, Qnil);
        }
 
       if (NILP (s->prev) && NILP (s->next))
@@ -3979,11 +4070,11 @@ Signal an error when WINDOW is the only window on its frame.  */)
          replace_window (parent, sibling, 0);
          /* Have SIBLING inherit the following three slot values from
             PARENT (the combination_limit slot is not inherited).  */
-         WSET (s, normal_cols, p->normal_cols);
-         WSET (s, normal_lines, p->normal_lines);
+         wset_normal_cols (s, p->normal_cols);
+         wset_normal_lines (s, p->normal_lines);
          /* Mark PARENT as deleted.  */
-         WSET (p, vchild, Qnil);
-         WSET (p, hchild, Qnil);
+         wset_vchild (p, Qnil);
+         wset_hchild (p, Qnil);
          /* Try to merge SIBLING into its new parent.  */
          recombine_windows (sibling);
        }
@@ -4005,7 +4096,7 @@ Signal an error when WINDOW is the only window on its frame.  */)
          else
            fset_selected_window (f, new_selected_window);
 
-         UNBLOCK_INPUT;
+         unblock_input ();
 
          /* Now look whether `get-mru-window' gets us something.  */
          mru_window = call1 (Qget_mru_window, frame);
@@ -4020,7 +4111,7 @@ Signal an error when WINDOW is the only window on its frame.  */)
            fset_selected_window (f, new_selected_window);
        }
       else
-       UNBLOCK_INPUT;
+       unblock_input ();
 
       /* Must be run by the caller:
         run_window_configuration_change_hook (f);  */
@@ -4030,17 +4121,17 @@ Signal an error when WINDOW is the only window on its frame.  */)
     {
       if (before_sibling)
        {
-         WSET (s, prev, window);
+         wset_prev (s, window);
          if (horflag)
-           WSET (p, hchild, window);
+           wset_hchild (p, window);
          else
-           WSET (p, vchild, window);
+           wset_vchild (p, window);
        }
       else
        {
-         WSET (s, next, window);
+         wset_next (s, window);
          if (!NILP (w->next))
-           WSET (XWINDOW (w->next), prev, window);
+           wset_prev (XWINDOW (w->next), window);
        }
       error ("Deletion failed");
     }
@@ -4070,19 +4161,20 @@ grow_mini_window (struct window *w, int delta)
                 root, make_number (- delta));
   if (INTEGERP (value) && window_resize_check (r, 0))
     {
-      BLOCK_INPUT;
+      block_input ();
       window_resize_apply (r, 0);
 
       /* Grow the mini-window.  */
-      WSET (w, top_line,
-           make_number (XFASTINT (r->top_line) + XFASTINT (r->total_lines)));
-      WSET (w, total_lines,
-           make_number (XFASTINT (w->total_lines) - XINT (value)));
+      wset_top_line
+       (w, make_number (XFASTINT (r->top_line) + XFASTINT (r->total_lines)));
+      wset_total_lines
+       (w, make_number (XFASTINT (w->total_lines) - XINT (value)));
       w->last_modified = 0;
       w->last_overlay_modified = 0;
 
+      windows_or_buffers_changed++;
       adjust_glyphs (f);
-      UNBLOCK_INPUT;
+      unblock_input ();
     }
 }
 
@@ -4107,19 +4199,20 @@ shrink_mini_window (struct window *w)
                     root, make_number (size - 1));
       if (INTEGERP (value) && window_resize_check (r, 0))
        {
-         BLOCK_INPUT;
+         block_input ();
          window_resize_apply (r, 0);
 
          /* Shrink the mini-window.  */
-         WSET (w, top_line,
-               make_number (XFASTINT (r->top_line) + XFASTINT (r->total_lines)));
-         WSET (w, total_lines, make_number (1));
+         wset_top_line (w, make_number (XFASTINT (r->top_line)
+                                        + XFASTINT (r->total_lines)));
+         wset_total_lines (w, make_number (1));
 
          w->last_modified = 0;
          w->last_overlay_modified = 0;
 
+         windows_or_buffers_changed++;
          adjust_glyphs (f);
-         UNBLOCK_INPUT;
+         unblock_input ();
        }
       /* If the above failed for whatever strange reason we must make a
         one window frame here.  The same routine will be needed when
@@ -4151,17 +4244,17 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
       && XINT (w->new_total) > 0
       && height == XINT (r->new_total) + XINT (w->new_total))
     {
-      BLOCK_INPUT;
+      block_input ();
       window_resize_apply (r, 0);
 
-      WSET (w, total_lines, w->new_total);
-      WSET (w, top_line,
-           make_number (XINT (r->top_line) + XINT (r->total_lines)));
+      wset_total_lines (w, w->new_total);
+      wset_top_line (w, make_number (XINT (r->top_line)
+                                    + XINT (r->total_lines)));
 
       windows_or_buffers_changed++;
       FRAME_WINDOW_SIZES_CHANGED (f) = 1;
       adjust_glyphs (f);
-      UNBLOCK_INPUT;
+      unblock_input ();
 
       run_window_configuration_change_hook (f);
       return Qt;
@@ -5224,7 +5317,7 @@ and redisplay normally--don't erase and redraw the frame.  */)
 
   /* Set the new window start.  */
   set_marker_both (w->start, w->buffer, charpos, bytepos);
-  WSET (w, window_end_valid, Qnil);
+  wset_window_end_valid (w, Qnil);
 
   w->optional_new_start = 1;
 
@@ -5405,7 +5498,6 @@ the return value is nil.  Otherwise the value is t.  */)
   struct Lisp_Vector *saved_windows;
   Lisp_Object new_current_buffer;
   Lisp_Object frame;
-  Lisp_Object auto_buffer_name;
   FRAME_PTR f;
   ptrdiff_t old_point = -1;
 
@@ -5415,7 +5507,7 @@ the return value is nil.  Otherwise the value is t.  */)
   saved_windows = XVECTOR (data->saved_windows);
 
   new_current_buffer = data->current_buffer;
-  if (NILP (BVAR (XBUFFER (new_current_buffer), name)))
+  if (!BUFFER_LIVE_P (XBUFFER (new_current_buffer)))
     new_current_buffer = Qnil;
   else
     {
@@ -5481,9 +5573,24 @@ the return value is nil.  Otherwise the value is t.  */)
       int previous_frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
       int previous_frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f);
 
+      /* Don't do this within the main loop below: This may call Lisp
+        code and is thus potentially unsafe while input is blocked.  */
+      for (k = 0; k < saved_windows->header.size; k++)
+       {
+         p = SAVED_WINDOW_N (saved_windows, k);
+         window = p->window;
+         w = XWINDOW (window);
+         if (!NILP (w->buffer)
+             && !EQ (w->buffer, p->buffer)
+             && BUFFER_LIVE_P (XBUFFER (p->buffer)))
+           /* If a window we restore gets another buffer, record the
+              window's old buffer.  */
+           call1 (Qrecord_window_buffer, window);
+       }
+
       /* The mouse highlighting code could get screwed up
         if it runs during this.  */
-      BLOCK_INPUT;
+      block_input ();
 
       if (data->frame_lines != previous_frame_lines
          || data->frame_cols != previous_frame_cols)
@@ -5542,34 +5649,34 @@ the return value is nil.  Otherwise the value is t.  */)
          p = SAVED_WINDOW_N (saved_windows, k);
          window = p->window;
          w = XWINDOW (window);
-         WSET (w, next, Qnil);
+         wset_next (w, Qnil);
 
          if (!NILP (p->parent))
-           WSET (w, parent, SAVED_WINDOW_N
-                 (saved_windows, XFASTINT (p->parent))->window);
+           wset_parent
+             (w, SAVED_WINDOW_N (saved_windows, XFASTINT (p->parent))->window);
          else
-           WSET (w, parent, Qnil);
+           wset_parent (w, Qnil);
 
          if (!NILP (p->prev))
            {
-             WSET (w, prev, SAVED_WINDOW_N
-                   (saved_windows, XFASTINT (p->prev))->window);
-             WSET (XWINDOW (w->prev), next, p->window);
+             wset_prev
+               (w, SAVED_WINDOW_N (saved_windows, XFASTINT (p->prev))->window);
+             wset_next (XWINDOW (w->prev), p->window);
            }
          else
            {
-             WSET (w, prev, Qnil);
+             wset_prev (w, Qnil);
              if (!NILP (w->parent))
                {
                  if (EQ (p->total_cols, XWINDOW (w->parent)->total_cols))
                    {
-                     WSET (XWINDOW (w->parent), vchild, p->window);
-                     WSET (XWINDOW (w->parent), hchild, Qnil);
+                     wset_vchild (XWINDOW (w->parent), p->window);
+                     wset_hchild (XWINDOW (w->parent), Qnil);
                    }
                  else
                    {
-                     WSET (XWINDOW (w->parent), hchild, p->window);
-                     WSET (XWINDOW (w->parent), vchild, Qnil);
+                     wset_hchild (XWINDOW (w->parent), p->window);
+                     wset_vchild (XWINDOW (w->parent), Qnil);
                    }
                }
            }
@@ -5577,25 +5684,25 @@ the return value is nil.  Otherwise the value is t.  */)
          /* If we squirreled away the buffer in the window's height,
             restore it now.  */
          if (BUFFERP (w->total_lines))
-           WSET (w, buffer, w->total_lines);
-         WSET (w, left_col, p->left_col);
-         WSET (w, top_line, p->top_line);
-         WSET (w, total_cols, p->total_cols);
-         WSET (w, total_lines, p->total_lines);
-         WSET (w, normal_cols, p->normal_cols);
-         WSET (w, normal_lines, p->normal_lines);
+           wset_buffer (w, w->total_lines);
+         wset_left_col (w, p->left_col);
+         wset_top_line (w, p->top_line);
+         wset_total_cols (w, p->total_cols);
+         wset_total_lines (w, p->total_lines);
+         wset_normal_cols (w, p->normal_cols);
+         wset_normal_lines (w, p->normal_lines);
          w->hscroll = XFASTINT (p->hscroll);
          w->min_hscroll = XFASTINT (p->min_hscroll);
-         WSET (w, display_table, p->display_table);
-         WSET (w, left_margin_cols, p->left_margin_cols);
-         WSET (w, right_margin_cols, p->right_margin_cols);
-         WSET (w, left_fringe_width, p->left_fringe_width);
-         WSET (w, right_fringe_width, p->right_fringe_width);
+         wset_display_table (w, p->display_table);
+         wset_left_margin_cols (w, p->left_margin_cols);
+         wset_right_margin_cols (w, p->right_margin_cols);
+         wset_left_fringe_width (w, p->left_fringe_width);
+         wset_right_fringe_width (w, p->right_fringe_width);
          w->fringes_outside_margins = !NILP (p->fringes_outside_margins);
-         WSET (w, scroll_bar_width, p->scroll_bar_width);
-         WSET (w, vertical_scroll_bar_type, p->vertical_scroll_bar_type);
-         WSET (w, dedicated, p->dedicated);
-         WSET (w, combination_limit, p->combination_limit);
+         wset_scroll_bar_width (w, p->scroll_bar_width);
+         wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type);
+         wset_dedicated (w, p->dedicated);
+         wset_combination_limit (w, p->combination_limit);
          /* Restore any window parameters that have been saved.
             Parameters that have not been saved are left alone.  */
          for (tem = p->window_parameters; CONSP (tem); tem = XCDR (tem))
@@ -5624,27 +5731,27 @@ the return value is nil.  Otherwise the value is t.  */)
          /* Reinstall the saved buffer and pointers into it.  */
          if (NILP (p->buffer))
            /* An internal window.  */
-           WSET (w, buffer, p->buffer);
-         else if (!NILP (BVAR (XBUFFER (p->buffer), name)))
+           wset_buffer (w, p->buffer);
+         else if (BUFFER_LIVE_P (XBUFFER (p->buffer)))
            /* If saved buffer is alive, install it.  */
            {
-             WSET (w, buffer, p->buffer);
-              w->start_at_line_beg = !NILP (p->start_at_line_beg);
-              set_marker_restricted (w->start, p->start, w->buffer);
-              set_marker_restricted (w->pointm, p->pointm,
-                                     w->buffer);
-              Fset_marker (BVAR (XBUFFER (w->buffer), mark),
-                           p->mark, w->buffer);
-
-              /* As documented in Fcurrent_window_configuration, don't
-                 restore the location of point in the buffer which was
-                 current when the window configuration was recorded.  */
-              if (!EQ (p->buffer, new_current_buffer)
-                  && XBUFFER (p->buffer) == current_buffer)
-                Fgoto_char (w->pointm);
+             wset_buffer (w, p->buffer);
+             w->start_at_line_beg = !NILP (p->start_at_line_beg);
+             set_marker_restricted (w->start, p->start, w->buffer);
+             set_marker_restricted (w->pointm, p->pointm,
+                                    w->buffer);
+             Fset_marker (BVAR (XBUFFER (w->buffer), mark),
+                          p->mark, w->buffer);
+
+             /* As documented in Fcurrent_window_configuration, don't
+                restore the location of point in the buffer which was
+                current when the window configuration was recorded.  */
+             if (!EQ (p->buffer, new_current_buffer)
+                 && XBUFFER (p->buffer) == current_buffer)
+               Fgoto_char (w->pointm);
             }
           else if (!NILP (w->buffer)
-                   && !NILP (BVAR (XBUFFER (w->buffer), name)))
+                   && BUFFER_LIVE_P (XBUFFER (w->buffer)))
             /* Keep window's old buffer; make sure the markers are
                real.  */
             {
@@ -5659,17 +5766,6 @@ the return value is nil.  Otherwise the value is t.  */)
                    BUF_PT_BYTE (XBUFFER (w->buffer)));
               w->start_at_line_beg = 1;
             }
-          else if (STRINGP (auto_buffer_name =
-                            Fwindow_parameter (window, Qauto_buffer_name))
-                   && SCHARS (auto_buffer_name) != 0
-                   && !NILP (WSET (w, buffer, Fget_buffer_create (auto_buffer_name))))
-           {
-             set_marker_restricted (w->start,
-                                    make_number (0), w->buffer);
-             set_marker_restricted (w->pointm,
-                                    make_number (0), w->buffer);
-             w->start_at_line_beg = 1;
-           }
          else
            /* Window has no live buffer, get one.  */
            {
@@ -5677,7 +5773,7 @@ the return value is nil.  Otherwise the value is t.  */)
              avoid showing an unimportant buffer and, if necessary, to
              recreate *scratch* in the course (part of Juanma's bs-show
              scenario from March 2011).  */
-             WSET (w, buffer, other_buffer_safely (Fcurrent_buffer ()));
+             wset_buffer (w, other_buffer_safely (Fcurrent_buffer ()));
              /* This will set the markers to beginning of visible
                 range.  */
              set_marker_restricted (w->start,
@@ -5689,7 +5785,7 @@ the return value is nil.  Otherwise the value is t.  */)
                /* Record this window as dead.  */
                dead_windows = Fcons (window, dead_windows);
              /* Make sure window is no more dedicated.  */
-             WSET (w, dedicated, Qnil);
+             wset_dedicated (w, Qnil);
            }
        }
 
@@ -5745,7 +5841,7 @@ the return value is nil.  Otherwise the value is t.  */)
        }
 
       adjust_glyphs (f);
-      UNBLOCK_INPUT;
+      unblock_input ();
 
       /* Scan dead buffer windows.  */
       for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
@@ -5767,7 +5863,13 @@ the return value is nil.  Otherwise the value is t.  */)
     }
 
   if (!NILP (new_current_buffer))
-    Fset_buffer (new_current_buffer);
+    {
+      Fset_buffer (new_current_buffer);
+      /* If the new current buffer doesn't appear in the selected
+        window, go to its old point (see bug#12208).  */
+      if (!EQ (XWINDOW (data->current_window)->buffer, new_current_buffer))
+       Fgoto_char (make_number (old_point));
+    }
 
   Vminibuf_scroll_window = data->minibuf_scroll_window;
   minibuf_selected_window = data->minibuf_selected_window;
@@ -5789,24 +5891,25 @@ delete_all_child_windows (Lisp_Object window)
     /* Delete WINDOW's siblings (we traverse postorderly).  */
     delete_all_child_windows (w->next);
 
-  WSET (w, total_lines, w->buffer);       /* See Fset_window_configuration for excuse.  */
+  /* See Fset_window_configuration for excuse.  */
+  wset_total_lines (w, w->buffer);
 
   if (!NILP (w->vchild))
     {
       delete_all_child_windows (w->vchild);
-      WSET (w, vchild, Qnil);
+      wset_vchild (w, Qnil);
     }
   else if (!NILP (w->hchild))
     {
       delete_all_child_windows (w->hchild);
-      WSET (w, hchild, Qnil);
+      wset_hchild (w, Qnil);
     }
   else if (!NILP (w->buffer))
     {
       unshow_buffer (w);
       unchain_marker (XMARKER (w->pointm));
       unchain_marker (XMARKER (w->start));
-      WSET (w, buffer, Qnil);
+      wset_buffer (w, Qnil);
     }
 
   Vwindow_list = Qnil;
@@ -5898,7 +6001,7 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
       p = SAVED_WINDOW_N (vector, i);
       w = XWINDOW (window);
 
-      WSET (w, temslot, make_number (i)); i++;
+      wset_temslot (w, make_number (i)); i++;
       p->window = window;
       p->buffer = w->buffer;
       p->left_col = w->left_col;
@@ -6032,12 +6135,7 @@ saved by this function.  */)
   register int n_windows;
   register struct save_window_data *data;
   register int i;
-  FRAME_PTR f;
-
-  if (NILP (frame))
-    frame = selected_frame;
-  CHECK_LIVE_FRAME (frame);
-  f = XFRAME (frame);
+  struct frame *f = decode_live_frame (frame);
 
   n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f)));
   data = ALLOCATE_PSEUDOVECTOR (struct save_window_data, frame_cols,
@@ -6101,8 +6199,8 @@ means no margin.  */)
   if (!EQ (w->left_margin_cols, left_width)
       || !EQ (w->right_margin_cols, right_width))
     {
-      WSET (w, left_margin_cols, left_width);
-      WSET (w, right_margin_cols, right_width);
+      wset_left_margin_cols (w, left_width);
+      wset_right_margin_cols (w, right_width);
 
       adjust_window_margins (w);
 
@@ -6163,14 +6261,14 @@ display marginal areas and the text area.  */)
          || !EQ (w->right_fringe_width, right_width)
          || w->fringes_outside_margins != outside))
     {
-      WSET (w, left_fringe_width, left_width);
-      WSET (w, right_fringe_width, right_width);
+      wset_left_fringe_width (w, left_width);
+      wset_right_fringe_width (w, right_width);
       w->fringes_outside_margins = outside;
 
       adjust_window_margins (w);
 
       clear_glyph_matrix (w->current_matrix);
-      WSET (w, window_end_valid, Qnil);
+      wset_window_end_valid (w, Qnil);
 
       ++windows_or_buffers_changed;
       adjust_glyphs (XFRAME (WINDOW_FRAME (w)));
@@ -6190,10 +6288,9 @@ Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS).  */)
 {
   struct window *w = decode_live_window (window);
 
-  return Fcons (make_number (WINDOW_LEFT_FRINGE_WIDTH (w)),
-               Fcons (make_number (WINDOW_RIGHT_FRINGE_WIDTH (w)),
-                      Fcons ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
-                              ? Qt : Qnil), Qnil)));
+  return list3 (make_number (WINDOW_LEFT_FRINGE_WIDTH (w)),
+               make_number (WINDOW_RIGHT_FRINGE_WIDTH (w)),
+               WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) ? Qt : Qnil);
 }
 
 
@@ -6235,13 +6332,13 @@ Fourth parameter HORIZONTAL-TYPE is currently unused.  */)
   if (!EQ (w->scroll_bar_width, width)
       || !EQ (w->vertical_scroll_bar_type, vertical_type))
     {
-      WSET (w, scroll_bar_width, width);
-      WSET (w, vertical_scroll_bar_type, vertical_type);
+      wset_scroll_bar_width (w, width);
+      wset_vertical_scroll_bar_type (w, vertical_type);
 
       adjust_window_margins (w);
 
       clear_glyph_matrix (w->current_matrix);
-      WSET (w, window_end_valid, Qnil);
+      wset_window_end_valid (w, Qnil);
 
       ++windows_or_buffers_changed;
       adjust_glyphs (XFRAME (WINDOW_FRAME (w)));
@@ -6262,12 +6359,12 @@ value.  */)
   (Lisp_Object window)
 {
   struct window *w = decode_live_window (window);
-  return Fcons (make_number ((WINDOW_CONFIG_SCROLL_BAR_WIDTH (w)
+
+  return list4 (make_number ((WINDOW_CONFIG_SCROLL_BAR_WIDTH (w)
                              ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w)
                              : WINDOW_SCROLL_BAR_AREA_WIDTH (w))),
-               Fcons (make_number (WINDOW_SCROLL_BAR_COLS (w)),
-                      Fcons (w->vertical_scroll_bar_type,
-                             Fcons (Qnil, Qnil))));
+               make_number (WINDOW_SCROLL_BAR_COLS (w)),
+               w->vertical_scroll_bar_type, Qnil);
 }
 
 
@@ -6284,15 +6381,8 @@ optional second arg PIXELS-P means value is measured in pixels.  */)
   (Lisp_Object window, Lisp_Object pixels_p)
 {
   Lisp_Object result;
-  struct frame *f;
-  struct window *w;
-
-  if (NILP (window))
-    window = selected_window;
-  else
-    CHECK_WINDOW (window);
-  w = XWINDOW (window);
-  f = XFRAME (w->frame);
+  struct window *w = decode_live_window (window);
+  struct frame *f = XFRAME (w->frame);
 
   if (FRAME_WINDOW_P (f))
     result = (NILP (pixels_p)
@@ -6316,18 +6406,11 @@ result of this rounding.
 If PIXELS-P is non-nil, the return value is VSCROLL.  */)
   (Lisp_Object window, Lisp_Object vscroll, Lisp_Object pixels_p)
 {
-  struct window *w;
-  struct frame *f;
+  struct window *w = decode_live_window (window);
+  struct frame *f = XFRAME (w->frame);
 
-  if (NILP (window))
-    window = selected_window;
-  else
-    CHECK_WINDOW (window);
   CHECK_NUMBER_OR_FLOAT (vscroll);
 
-  w = XWINDOW (window);
-  f = XFRAME (w->frame);
-
   if (FRAME_WINDOW_P (f))
     {
       int old_dy = w->vscroll;
@@ -6431,15 +6514,17 @@ freeze_window_starts (struct frame *f, int freeze_p)
 /* Return 1 if window configurations CONFIGURATION1 and CONFIGURATION2
    describe the same state of affairs.  This is used by Fequal.
 
-   ignore_positions non-zero means ignore non-matching scroll positions
+   IGNORE_POSITIONS means ignore non-matching scroll positions
    and the like.
 
    This ignores a couple of things like the dedication status of
    window, combination_limit and the like.  This might have to be
    fixed.  */
 
-int
-compare_window_configurations (Lisp_Object configuration1, Lisp_Object configuration2, int ignore_positions)
+bool
+compare_window_configurations (Lisp_Object configuration1,
+                              Lisp_Object configuration2,
+                              bool ignore_positions)
 {
   register struct save_window_data *d1, *d2;
   struct Lisp_Vector *sws1, *sws2;
@@ -6565,10 +6650,10 @@ syms_of_window (void)
   DEFSYM (Qreplace_buffer_in_windows, "replace-buffer-in-windows");
   DEFSYM (Qrecord_window_buffer, "record-window-buffer");
   DEFSYM (Qget_mru_window, "get-mru-window");
+  DEFSYM (Qwindow_size, "window-size");
   DEFSYM (Qtemp_buffer_show_hook, "temp-buffer-show-hook");
   DEFSYM (Qabove, "above");
   DEFSYM (Qbelow, "below");
-  DEFSYM (Qauto_buffer_name, "auto-buffer-name");
   DEFSYM (Qclone_of, "clone-of");
 
   staticpro (&Vwindow_list);
@@ -6661,23 +6746,36 @@ This variable takes no effect if `window-combination-limit' is non-nil.  */);
   Vwindow_combination_resize = Qnil;
 
   DEFVAR_LISP ("window-combination-limit", Vwindow_combination_limit,
-              doc: /* If t, splitting a window makes a new parent window.
-If this variable is nil, splitting a window will create a new parent
-window only if the window has no parent window or the window shall
-become a combination orthogonal to the one it is part of.
+              doc: /* If non-nil, splitting a window makes a new parent window.
+The following values are recognized:
 
-If this variable is t, splitting a window always creates a new parent
-window.  If all splits behave this way, each frame's window tree is a
-binary tree and every window but the frame's root window has exactly one
-sibling.
+nil means splitting a window will create a new parent window only if the
+    window has no parent window or the window shall become part of a
+    combination orthogonal to the one it is part of.
 
-Other values are reserved for future use.
+`window-size' means that splitting a window for displaying a buffer
+    makes a new parent window provided `display-buffer' is supposed to
+    explicitly set the window's size due to the presence of a
+    `window-height' or `window-width' entry in the alist used by
+    `display-buffer'.  Otherwise, this value is handled like nil.
+
+`temp-buffer' means that splitting a window for displaying a temporary
+    buffer always makes a new parent window.  Otherwise, this value is
+    handled like nil.
+
+`display-buffer' means that splitting a window for displaying a buffer
+    always makes a new parent window.  Since temporary buffers are
+    displayed by the function `display-buffer', this value is stronger
+    than `temp-buffer'.  Splitting a window for other purpose makes a
+    new parent window only if needed.
+
+t means that splitting a window always creates a new parent window.  If
+    all splits behave this way, each frame's window tree is a binary
+    tree and every window but the frame's root window has exactly one
+    sibling.
 
-The value of this variable is also assigned to the combination limit of
-the new parent window.  The combination limit of a window can be
-retrieved via the function `window-combination-limit' and altered by the
-function `set-window-combination-limit'.  */);
-  Vwindow_combination_limit = Qnil;
+Other values are reserved for future use.  */);
+  Vwindow_combination_limit = Qwindow_size;
 
   DEFVAR_LISP ("window-persistent-parameters", Vwindow_persistent_parameters,
               doc: /* Alist of persistent window parameters.
@@ -6769,7 +6867,6 @@ respectively are not installed by `window-state-put'.  */);
   defsubr (&Srun_window_configuration_change_hook);
   defsubr (&Sselect_window);
   defsubr (&Sforce_window_update);
-  defsubr (&Stemp_output_buffer_show);
   defsubr (&Ssplit_window_internal);
   defsubr (&Sscroll_up);
   defsubr (&Sscroll_down);