Install some window-size related functions and window-list-1.
[bpt/emacs.git] / src / window.c
index 69dc8c7..43635fe 100644 (file)
@@ -1,7 +1,6 @@
 /* Window creation, deletion and examination for GNU Emacs.
    Does not include redisplay.
-   Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
-                 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+   Copyright (C) 1985-1987, 1993-1998, 2000-2011
                  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -51,10 +50,11 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "nsterm.h"
 #endif
 
-Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configuration_p;
-Lisp_Object Qdisplay_buffer;
-Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
-Lisp_Object Qwindow_size_fixed;
+Lisp_Object Qwindowp, Qwindow_live_p;
+static Lisp_Object Qwindow_configuration_p;
+static Lisp_Object Qdisplay_buffer;
+static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
+static Lisp_Object Qwindow_size_fixed;
 
 static int displayed_window_lines (struct window *);
 static struct window *decode_window (Lisp_Object);
@@ -79,12 +79,13 @@ static Lisp_Object next_window (Lisp_Object, Lisp_Object,
 static void decode_next_window_args (Lisp_Object *, Lisp_Object *,
                                      Lisp_Object *);
 static void foreach_window (struct frame *,
-                            int (* fn) (struct window *, void *),
+                                int (* fn) (struct window *, void *),
                             void *);
 static int foreach_window_1 (struct window *,
                              int (* fn) (struct window *, void *),
                              void *);
 static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object);
+static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
 
 /* This is the window in which the terminal's cursor should
    be left when nothing is being done with it.  This must
@@ -93,134 +94,376 @@ static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object);
 
    This value is always the same as
    FRAME_SELECTED_WINDOW (selected_frame).  */
-
 Lisp_Object selected_window;
 
 /* A list of all windows for use by next_window and Fwindow_list.
    Functions creating or deleting windows should invalidate this cache
    by setting it to nil.  */
-
 Lisp_Object Vwindow_list;
 
 /* The mini-buffer window of the selected frame.
    Note that you cannot test for mini-bufferness of an arbitrary window
    by comparing against this; but you can test for mini-bufferness of
    the selected window.  */
-
 Lisp_Object minibuf_window;
 
 /* Non-nil means it is the window whose mode line should be
    shown as the selected window when the minibuffer is selected.  */
-
 Lisp_Object minibuf_selected_window;
 
-/* Non-nil means it is the window for C-M-v to scroll
-   when the mini-buffer is selected.  */
+/* Hook run at end of temp_output_buffer_show.  */
+static Lisp_Object Qtemp_buffer_show_hook;
 
-Lisp_Object Vminibuf_scroll_window;
+/* Incremented for each window created.  */
+static int sequence_number;
 
-/* Non-nil means this is the buffer whose window C-M-v should scroll.  */
+/* Nonzero after init_window_once has finished.  */
+static int window_initialized;
 
-Lisp_Object Vother_window_scroll_buffer;
+/* Hook to run when window config changes.  */
+static Lisp_Object Qwindow_configuration_change_hook;
 
-/* Non-nil means it's function to call to display temp buffers.  */
+/* Incremented by 1 whenever a window is deleted.  */
+static int window_deletion_count;
 
-Lisp_Object Vtemp_buffer_show_function;
+/* Used by the function window_scroll_pixel_based */
+static int window_scroll_pixel_based_preserve_x;
+static int window_scroll_pixel_based_preserve_y;
 
-/* Non-zero means line and page scrolling on tall lines (with images)
-   does partial scrolling by modifying window-vscroll.  */
+/* Same for window_scroll_line_based.  */
+static int window_scroll_preserve_hpos;
+static int window_scroll_preserve_vpos;
+\f
+static struct window *
+decode_window (register Lisp_Object window)
+{
+  if (NILP (window))
+    return XWINDOW (selected_window);
 
-int auto_window_vscroll_p;
+  CHECK_LIVE_WINDOW (window);
+  return XWINDOW (window);
+}
 
-/* Non-zero means to use mode-line-inactive face in all windows but the
-   selected-window and the minibuffer-scroll-window when the
-   minibuffer is active.  */
-int mode_line_in_non_selected_windows;
+static struct window *
+decode_any_window (register Lisp_Object window)
+{
+  if (NILP (window))
+    return XWINDOW (selected_window);
 
-/* If a window gets smaller than either of these, it is removed. */
+  CHECK_WINDOW (window);
+  return XWINDOW (window);
+}
 
-EMACS_INT window_min_height;
-EMACS_INT window_min_width;
+DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0,
+       doc: /* Return t if OBJECT is a window and nil otherwise.  */)
+  (Lisp_Object object)
+{
+  return WINDOWP (object) ? Qt : Qnil;
+}
 
-/* Hook run at end of temp_output_buffer_show.  */
+DEFUN ("window-live-p", Fwindow_live_p, Swindow_live_p, 1, 1, 0,
+       doc: /* Return t if OBJECT is a live window and nil otherwise.
+A live window is a window that displays a buffer.  */)
+  (Lisp_Object object)
+{
+  return WINDOW_LIVE_P (object) ? Qt : Qnil;
+}
+\f
+/* Frames and windows.  */
+DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
+       doc: /* Return the frame that window WINDOW is on.
+WINDOW can be any window and defaults to the selected one.  */)
+  (Lisp_Object window)
+{
+  return decode_any_window (window)->frame;
+}
 
-Lisp_Object Qtemp_buffer_show_hook;
+DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
+       doc: /* Return the root window of FRAME_OR_WINDOW.
+If omitted, FRAME_OR_WINDOW defaults to the currently selected frame.
+Else if FRAME_OR_WINDOW denotes any window, return the root window of
+that window's frame.  If FRAME_OR_WINDOW denotes a live frame, return
+the root window of that frame.  */)
+  (Lisp_Object frame_or_window)
+{
+  Lisp_Object window;
 
-/* Number of lines of continuity in scrolling by screenfuls.  */
+  if (NILP (frame_or_window))
+    window = SELECTED_FRAME ()->root_window;
+  else if (WINDOWP (frame_or_window))
+    window = XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window)))->root_window;
+  else
+    {
+      CHECK_LIVE_FRAME (frame_or_window);
+      window = XFRAME (frame_or_window)->root_window;
+    }
 
-EMACS_INT next_screen_context_lines;
+  return window;
+}
 
-/* Incremented for each window created.  */
+DEFUN ("minibuffer-window", Fminibuffer_window, Sminibuffer_window, 0, 1, 0,
+       doc: /* Return the window used now for minibuffers.
+If the optional argument FRAME is specified, return the minibuffer window
+used by that frame.  */)
+  (Lisp_Object frame)
+{
+  if (NILP (frame))
+    frame = selected_frame;
+  CHECK_LIVE_FRAME (frame);
+  return FRAME_MINIBUF_WINDOW (XFRAME (frame));
+}
 
-static int sequence_number;
+DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p,
+       Swindow_minibuffer_p, 0, 1, 0,
+       doc: /* Return non-nil if WINDOW is a minibuffer window.
+WINDOW can be any window and defaults to the selected one.  */)
+  (Lisp_Object window)
+{
+  return MINI_WINDOW_P (decode_any_window (window)) ? Qt : Qnil;
+}
 
-/* Nonzero after init_window_once has finished.  */
+/* Don't move this to window.el - this must be a safe routine.  */
+DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
+       doc: /* Return the topmost, leftmost live window on FRAME_OR_WINDOW.
+If omitted, FRAME_OR_WINDOW defaults to the currently selected frame.
+Else if FRAME_OR_WINDOW denotes any window, return the first window of
+that window's frame.  If FRAME_OR_WINDOW denotes a live frame, return
+the first window of that frame.  */)
+  (Lisp_Object frame_or_window)
+{
+  Lisp_Object window;
 
-static int window_initialized;
+  if (NILP (frame_or_window))
+    window = SELECTED_FRAME ()->root_window;
+  else if (WINDOWP (frame_or_window))
+    window = XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window)))->root_window;
+  else
+    {
+      CHECK_LIVE_FRAME (frame_or_window);
+      window = XFRAME (frame_or_window)->root_window;
+    }
 
-/* Set in `set-window-configuration' to prevent "swapping out point"
-   in the old selected window.  */
+  while (NILP (XWINDOW (window)->buffer))
+    {
+      if (! NILP (XWINDOW (window)->hchild))
+       window = XWINDOW (window)->hchild;
+      else if (! NILP (XWINDOW (window)->vchild))
+       window = XWINDOW (window)->vchild;
+      else
+       abort ();
+    }
 
-static int inhibit_point_swap;
+  return window;
+}
 
-/* Hook to run when window config changes.  */
+DEFUN ("frame-selected-window", Fframe_selected_window,
+       Sframe_selected_window, 0, 1, 0,
+       doc: /* Return the selected window of FRAME_OR_WINDOW.
+If omitted, FRAME_OR_WINDOW defaults to the currently selected frame.
+Else if FRAME_OR_WINDOW denotes any window, return the selected window
+of that window's frame.  If FRAME_OR_WINDOW denotes a live frame, return
+the selected window of that frame.  */)
+  (Lisp_Object frame_or_window)
+{
+  Lisp_Object window;
 
-static Lisp_Object Qwindow_configuration_change_hook;
-static Lisp_Object Vwindow_configuration_change_hook;
+  if (NILP (frame_or_window))
+    window = SELECTED_FRAME ()->selected_window;
+  else if (WINDOWP (frame_or_window))
+    window = XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window)))->selected_window;
+  else
+    {
+      CHECK_LIVE_FRAME (frame_or_window);
+      window = XFRAME (frame_or_window)->selected_window;
+    }
 
-/* Non-nil means scroll commands try to put point
-   at the same screen height as previously.  */
+  return window;
+}
 
-Lisp_Object Vscroll_preserve_screen_position;
+DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
+       Sset_frame_selected_window, 2, 3, 0,
+       doc: /* Set selected window of FRAME to WINDOW.
+FRAME must be a live frame and defaults to the selected one.  If FRAME
+is the selected frame, this makes WINDOW the selected window.  Optional
+argument NORECORD non-nil means to neither change the order of recently
+selected windows nor the buffer list.  WINDOW must denote a live window.
+Return WINDOW.  */)
+  (Lisp_Object frame, Lisp_Object window, Lisp_Object norecord)
+{
+  if (NILP (frame))
+    frame = selected_frame;
 
-/* Non-nil means that text is inserted before window's markers.  */
+  CHECK_LIVE_FRAME (frame);
+  CHECK_LIVE_WINDOW (window);
 
-Lisp_Object Vwindow_point_insertion_type;
+  if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
+    error ("In `set-frame-selected-window', WINDOW is not on FRAME");
 
-/* Incremented by 1 whenever a window is deleted.  */
+  if (EQ (frame, selected_frame))
+    return Fselect_window (window, norecord);
+  else
+    return XFRAME (frame)->selected_window = window;
+}
 
-int window_deletion_count;
+DEFUN ("selected-window", Fselected_window, Sselected_window, 0, 0, 0,
+       doc: /* Return the selected window.
+The selected window is the window in which the standard cursor for
+selected windows appears and to which many commands apply.  */)
+  (void)
+{
+  return selected_window;
+}
 
-/* Used by the function window_scroll_pixel_based */
+/* If select_window is called with inhibit_point_swap non-zero it will
+   not store point of the old selected window's buffer back into that
+   window's pointm slot.  This is needed by Fset_window_configuration to
+   avoid that the display routine is called with selected_window set to
+   Qnil causing a subsequent crash.  */
+static Lisp_Object
+select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
+{
+  register struct window *w;
+  register struct window *ow;
+  struct frame *sf;
 
-static int window_scroll_pixel_based_preserve_x;
-static int window_scroll_pixel_based_preserve_y;
+  CHECK_LIVE_WINDOW (window);
 
-/* Same for window_scroll_line_based.  */
+  w = XWINDOW (window);
+  w->frozen_window_start_p = 0;
 
-static int window_scroll_preserve_hpos;
-static int window_scroll_preserve_vpos;
+  if (NILP (norecord))
+    {
+      ++window_select_count;
+      XSETFASTINT (w->use_time, window_select_count);
+      record_buffer (w->buffer);
+    }
 
-#if 0 /* This isn't used anywhere.  */
-/* Nonzero means we can split a frame even if it is "unsplittable".  */
-static int inhibit_frame_unsplittable;
-#endif /* 0 */
+  if (EQ (window, selected_window) && !inhibit_point_swap)
+    return window;
 
-extern EMACS_INT scroll_margin;
+  sf = SELECTED_FRAME ();
+  if (XFRAME (WINDOW_FRAME (w)) != sf)
+    {
+      XFRAME (WINDOW_FRAME (w))->selected_window = window;
+      /* Use this rather than Fhandle_switch_frame
+        so that FRAME_FOCUS_FRAME is moved appropriately as we
+        move around in the state where a minibuffer in a separate
+        frame is active.  */
+      Fselect_frame (WINDOW_FRAME (w), norecord);
+      /* Fselect_frame called us back so we've done all the work already.  */
+      eassert (EQ (window, selected_window));
+      return window;
+    }
+  else
+    sf->selected_window = window;
 
-extern Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
+  /* 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.  */
+  if (!inhibit_point_swap)
+    {
+      ow = XWINDOW (selected_window);
+      if (! NILP (ow->buffer))
+       set_marker_both (ow->pointm, ow->buffer,
+                        BUF_PT (XBUFFER (ow->buffer)),
+                        BUF_PT_BYTE (XBUFFER (ow->buffer)));
+    }
 
-/* If non-nil, then the `recenter' command with a nil argument
-   the entire frame to be redrawn; the special value `tty' causes the
-   frame to be redrawn only if it is a tty frame.  */
+  selected_window = window;
+
+  Fset_buffer (w->buffer);
+
+  BVAR (XBUFFER (w->buffer), last_selected_window) = window;
+
+  /* Go to the point recorded in the window.
+     This is important when the buffer is in more
+     than one window.  It also matters when
+     redisplay_window has altered point after scrolling,
+     because it makes the change only in the window.  */
+  {
+    register EMACS_INT new_point = marker_position (w->pointm);
+    if (new_point < BEGV)
+      SET_PT (BEGV);
+    else if (new_point > ZV)
+      SET_PT (ZV);
+    else
+      SET_PT (new_point);
+  }
 
-static Lisp_Object Vrecenter_redisplay;
+  windows_or_buffers_changed++;
+  return window;
+}
 
+DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0,
+       doc: /* Select WINDOW.  Most editing will apply to WINDOW's buffer.
+Also make WINDOW's buffer current and make WINDOW the frame's selected
+window.  Return WINDOW.
+
+Optional second arg NORECORD non-nil means do not put this buffer at the
+front of the buffer list and do not make this window the most recently
+selected one.
+
+Note that the main editor command loop sets the current buffer to the
+buffer of the selected window before each command.  */)
+  (register Lisp_Object window, Lisp_Object norecord)
+{
+  return select_window (window, norecord, 0);
+}
 \f
-DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0,
-       doc: /* Return t if OBJECT is a window.  */)
-  (Lisp_Object object)
+DEFUN ("window-buffer", Fwindow_buffer, Swindow_buffer, 0, 1, 0,
+       doc: /* Return the buffer that WINDOW is displaying.
+WINDOW can be any window and defaults to the selected one.
+If WINDOW is an internal window return nil.  */)
+  (Lisp_Object window)
 {
-  return WINDOWP (object) ? Qt : Qnil;
+  return decode_any_window (window)->buffer;
 }
 
-DEFUN ("window-live-p", Fwindow_live_p, Swindow_live_p, 1, 1, 0,
-       doc: /* Return t if OBJECT is a window which is currently visible.  */)
-  (Lisp_Object object)
+DEFUN ("window-parent", Fwindow_parent, Swindow_parent, 0, 1, 0,
+       doc: /* Return WINDOW's parent window.
+WINDOW can be any window and defaults to the selected one.
+Return nil if WINDOW has no parent.  */)
+  (Lisp_Object window)
 {
-  return WINDOW_LIVE_P (object) ? Qt : Qnil;
+  return decode_any_window (window)->parent;
+}
+
+DEFUN ("window-vchild", Fwindow_vchild, Swindow_vchild, 0, 1, 0,
+       doc: /* Return WINDOW's first vertical child window.
+WINDOW can be any window and defaults to the selected one.
+Return nil if WINDOW has no vertical child.  */)
+  (Lisp_Object window)
+{
+  return decode_any_window (window)->vchild;
 }
 
+DEFUN ("window-hchild", Fwindow_hchild, Swindow_hchild, 0, 1, 0,
+       doc: /* Return WINDOW's first horizontal child window.
+WINDOW can be any window and defaults to the selected one.
+Return nil if WINDOW has no horizontal child.  */)
+  (Lisp_Object window)
+{
+  return decode_any_window (window)->hchild;
+}
+
+DEFUN ("window-next", Fwindow_next, Swindow_next, 0, 1, 0,
+       doc: /* Return WINDOW's right sibling window.
+WINDOW can be any window and defaults to the selected one.
+Return nil if WINDOW has no right sibling.  */)
+  (Lisp_Object window)
+{
+  return decode_any_window (window)->next;
+}
+
+DEFUN ("window-prev", Fwindow_prev, Swindow_prev, 0, 1, 0,
+       doc: /* Return WINDOW's left sibling window.
+WINDOW can be any window and defaults to the selected one.
+Return nil if WINDOW has no left sibling.  */)
+  (Lisp_Object window)
+{
+  return decode_any_window (window)->prev;
+}
+\f
 Lisp_Object
 make_window (void)
 {
@@ -274,35 +517,6 @@ make_window (void)
   return val;
 }
 
-DEFUN ("selected-window", Fselected_window, Sselected_window, 0, 0, 0,
-       doc: /* Return the window that the cursor now appears in and commands apply to.  */)
-  (void)
-{
-  return selected_window;
-}
-
-DEFUN ("minibuffer-window", Fminibuffer_window, Sminibuffer_window, 0, 1, 0,
-       doc: /* Return the window used now for minibuffers.
-If the optional argument FRAME is specified, return the minibuffer window
-used by that frame.  */)
-  (Lisp_Object frame)
-{
-  if (NILP (frame))
-    frame = selected_frame;
-  CHECK_LIVE_FRAME (frame);
-  return FRAME_MINIBUF_WINDOW (XFRAME (frame));
-}
-
-DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p, Swindow_minibuffer_p, 0, 1, 0,
-       doc: /* Return non-nil if WINDOW is a minibuffer window.
-WINDOW defaults to the selected window.  */)
-  (Lisp_Object window)
-{
-  struct window *w = decode_window (window);
-  return MINI_WINDOW_P (w) ? Qt : Qnil;
-}
-
-
 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p,
        Spos_visible_in_window_p, 0, 3, 0,
        doc: /* Return non-nil if position POS is currently on the frame in WINDOW.
@@ -477,35 +691,113 @@ Return nil if window display is not up-to-date.  In that case, use
                make_number (row->y),
                make_number (crop));
 }
+\f
+DEFUN ("window-total-size", Fwindow_total_size, Swindow_total_size, 0, 2, 0,
+       doc: /* Return the total number of lines of WINDOW.
+WINDOW can be any window and defaults to the selected one.  The return
+value includes WINDOW's mode line and header line, if any.  If WINDOW
+is internal, the return value is the sum of the total number of lines
+of WINDOW's child windows if these are vertically combined and the
+height of WINDOW's first child otherwise.
+
+Optional argument HORIZONTAL non-nil means return the total number of
+columns of WINDOW.  In this case the return value includes any vertical
+dividers or scrollbars of WINDOW.  If WINDOW is internal, the return
+value is the sum of the total number of columns of WINDOW's child
+windows if they are horizontally combined and the width of WINDOW's
+first child otherwise.  */)
+  (Lisp_Object window, Lisp_Object horizontal)
+{
+  if (NILP (horizontal))
+    return decode_any_window (window)->total_lines;
+  else
+    return decode_any_window (window)->total_cols;
+}
 
+DEFUN ("window-left-column", Fwindow_left_column, Swindow_left_column, 0, 1, 0,
+       doc: /* Return left column of WINDOW.
+WINDOW can be any window and defaults to the selected one.  */)
+  (Lisp_Object window)
+{
+  return decode_any_window (window)->left_col;
+}
 
-\f
-static struct window *
-decode_window (register Lisp_Object window)
+DEFUN ("window-top-line", Fwindow_top_line, Swindow_top_line, 0, 1, 0,
+       doc: /* Return top line of WINDOW.
+WINDOW can be any window and defaults to the selected one.  */)
+  (Lisp_Object window)
 {
-  if (NILP (window))
-    return XWINDOW (selected_window);
+  return decode_any_window (window)->top_line;
+}
 
-  CHECK_LIVE_WINDOW (window);
-  return XWINDOW (window);
+/* Return the number of lines of W's body.  Don't count any mode or
+   header line of W.  */
+
+int
+window_body_lines (struct window *w)
+{
+  int height = XFASTINT (w->total_lines);
+
+  if (!MINI_WINDOW_P (w))
+    {
+      if (WINDOW_WANTS_MODELINE_P (w))
+       --height;
+      if (WINDOW_WANTS_HEADER_LINE_P (w))
+       --height;
+    }
+
+  return height;
 }
 
-static struct window *
-decode_any_window (register Lisp_Object window)
+/* Return the number of columns of W's body.  Don't count columns
+   occupied by the scroll bar or the vertical bar separating W from its
+   right sibling.  On window-systems don't count fringes or display
+   margins either.  */
+
+int
+window_body_cols (struct window *w)
 {
-  if (NILP (window))
-    return XWINDOW (selected_window);
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  int width = XINT (w->total_cols);
 
-  CHECK_WINDOW (window);
-  return XWINDOW (window);
+  if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
+    /* Scroll bars occupy a few columns.  */
+    width -= WINDOW_CONFIG_SCROLL_BAR_COLS (w);
+  else if (!FRAME_WINDOW_P (f)
+          && !WINDOW_RIGHTMOST_P (w) && !WINDOW_FULL_WIDTH_P (w))
+    /* The column of `|' characters separating side-by-side windows
+       occupies one column only.  */
+    width -= 1;
+
+  if (FRAME_WINDOW_P (f))
+    /* On window-systems, fringes and display margins cannot be
+       used for normal text.  */
+    width -= (WINDOW_FRINGE_COLS (w)
+             + WINDOW_LEFT_MARGIN_COLS (w)
+             + WINDOW_RIGHT_MARGIN_COLS (w));
+
+  return width;
 }
 
-DEFUN ("window-buffer", Fwindow_buffer, Swindow_buffer, 0, 1, 0,
-       doc: /* Return the buffer that WINDOW is displaying.
-WINDOW defaults to the selected window.  */)
-  (Lisp_Object window)
+DEFUN ("window-body-size", Fwindow_body_size, Swindow_body_size, 0, 2, 0,
+       doc: /* Return the number of lines of WINDOW's body.
+WINDOW must be a live window and defaults to the selected one.  The
+return value does not include WINDOW's mode line and header line, if
+any.
+
+Optional argument HORIZONTAL non-nil means return the number of columns
+of WINDOW's body.  In this case, the return value does not include any
+vertical dividers or scroll bars owned by WINDOW.  On a window-system
+the return value does not include the number of columns used for
+WINDOW's fringes or display margins either.  */)
+  (Lisp_Object window, Lisp_Object horizontal)
 {
-  return decode_window (window)->buffer;
+  struct window *w = decode_any_window (window);
+
+  if (NILP (horizontal))
+    return make_number (window_body_lines (w));
+  else
+    return make_number (window_body_cols (w));
 }
 
 DEFUN ("window-height", Fwindow_height, Swindow_height, 0, 1, 0,
@@ -530,7 +822,7 @@ WINDOW.  If you want to find out how many columns WINDOW takes up, use
 (let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))).  */)
   (Lisp_Object window)
 {
-  return make_number (window_box_text_cols (decode_any_window (window)));
+  return make_number (window_body_cols (decode_any_window (window)));
 }
 
 DEFUN ("window-full-width-p", Fwindow_full_width_p, Swindow_full_width_p, 0, 1, 0,
@@ -1417,8 +1709,8 @@ window_display_table (struct window *w)
     {
       struct buffer *b = XBUFFER (w->buffer);
 
-      if (DISP_TABLE_P (b->display_table))
-       dp = XCHAR_TABLE (b->display_table);
+      if (DISP_TABLE_P (BVAR (b, display_table)))
+       dp = XCHAR_TABLE (BVAR (b, display_table));
       else if (DISP_TABLE_P (Vstandard_display_table))
        dp = XCHAR_TABLE (Vstandard_display_table);
     }
@@ -1472,9 +1764,9 @@ unshow_buffer (register struct window *w)
      So don't clobber point in that buffer.  */
   if (! EQ (buf, XWINDOW (selected_window)->buffer)
       /* This line helps to fix Horsley's testbug.el bug.  */
-      && !(WINDOWP (b->last_selected_window)
-          && w != XWINDOW (b->last_selected_window)
-          && EQ (buf, XWINDOW (b->last_selected_window)->buffer)))
+      && !(WINDOWP (BVAR (b, last_selected_window))
+          && w != XWINDOW (BVAR (b, last_selected_window))
+          && EQ (buf, XWINDOW (BVAR (b, last_selected_window))->buffer)))
     temp_set_point_both (b,
                         clip_to_bounds (BUF_BEGV (b),
                                         XMARKER (w->pointm)->charpos,
@@ -1483,9 +1775,9 @@ unshow_buffer (register struct window *w)
                                         marker_byte_position (w->pointm),
                                         BUF_ZV_BYTE (b)));
 
-  if (WINDOWP (b->last_selected_window)
-      && w == XWINDOW (b->last_selected_window))
-    b->last_selected_window = Qnil;
+  if (WINDOWP (BVAR (b, last_selected_window))
+      && w == XWINDOW (BVAR (b, last_selected_window)))
+    BVAR (b, last_selected_window) = Qnil;
 }
 
 /* Put replacement into the window structure in place of old. */
@@ -1827,8 +2119,10 @@ window_list (void)
 
    ALL_FRAMES  t means search all frames,
                nil means search just current frame,
-               `visible' means search just visible frames,
-               0 means search visible and iconified frames,
+               `visible' means search just visible frames on the
+                current terminal,
+               0 means search visible and iconified frames on the
+                current terminal,
                a window means search the frame that window belongs to,
                a frame means consider windows on that frame, only.  */
 
@@ -1894,8 +2188,8 @@ candidate_window_p (Lisp_Object window, Lisp_Object owindow, Lisp_Object minibuf
 
 
 /* Decode arguments as allowed by Fnext_window, Fprevious_window, and
-   Fwindow_list.  See there for the meaning of WINDOW, MINIBUF, and
-   ALL_FRAMES.  */
+   Fwindow_list.  See candidate_window_p for the meaning of WINDOW,
+   MINIBUF, and ALL_FRAMES.  */
 
 static void
 decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object *all_frames)
@@ -1929,12 +2223,6 @@ decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object
     ;
   else if (!EQ (*all_frames, Qt))
     *all_frames = Qnil;
-
-  /* Now *ALL_FRAMES is t meaning search all frames, nil meaning
-     search just current frame, `visible' meaning search just visible
-     frames, 0 meaning search visible and iconified frames, or a
-     window, meaning search the frame that window belongs to, or a
-     frame, meaning consider windows on that frame, only.  */
 }
 
 
@@ -2032,9 +2320,9 @@ ALL-FRAMES nil or omitted means consider all windows on WINDOW's
  windows on all frames that share that minibuffer too.
 ALL-FRAMES t means consider all windows on all existing frames.
 ALL-FRAMES `visible' means consider all windows on all visible
- frames.
+ frames on the current terminal.
 ALL-FRAMES 0 means consider all windows on all visible and
- iconified frames.
+ iconified frames on the current terminal.
 ALL-FRAMES a frame means consider all windows on that frame only.
 Anything else means consider all windows on WINDOW's frame and no
  others.
@@ -2066,6 +2354,43 @@ reverse order.  */)
 }
 
 
+DEFUN ("window-list-1", Fwindow_list_1, Swindow_list_1, 0, 3, 0,
+       doc: /* Return a list of all live windows.
+WINDOW specifies the first window to list and defaults to the selected
+window.
+
+Optional argument MINIBUF nil or omitted means consider the minibuffer
+window only if the minibuffer is active.  MINIBUF t means consider the
+minibuffer window even if the minibuffer is not active.  Any other value
+means do not consider the minibuffer window even if the minibuffer is
+active.
+
+Optional argument ALL-FRAMES nil or omitted means consider all windows
+on WINDOW's frame, plus the minibuffer window if specified by the
+MINIBUF argument.  If the minibuffer counts, consider all windows on all
+frames that share that minibuffer too.  The following non-nil values of
+ALL-FRAMES have special meanings:
+
+- t means consider all windows on all existing frames.
+
+- `visible' means consider all windows on all visible frames.
+
+- 0 (the number zero) means consider all windows on all visible and
+  iconified frames.
+
+- A frame means consider all windows on that frame only.
+
+Anything else means consider all windows on WINDOW's frame and no
+others.
+
+If WINDOW is not on the list of windows returned, some other window will
+be listed first but no error is signalled.  */)
+  (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames)
+{
+  return window_list_1 (window, minibuf, all_frames);
+}
+
+
 DEFUN ("other-window", Fother_window, Sother_window, 1, 2, "p",
        doc: /* Select another window in cyclic ordering of windows.
 COUNT specifies the number of windows to skip, starting with the
@@ -2097,29 +2422,6 @@ nil.  */)
 }
 
 
-DEFUN ("window-list", Fwindow_list, Swindow_list, 0, 3, 0,
-       doc: /* Return a list of windows on FRAME, starting with WINDOW.
-FRAME nil or omitted means use the selected frame.
-WINDOW nil or omitted means use the selected window.
-MINIBUF t means include the minibuffer window, even if it isn't active.
-MINIBUF nil or omitted means include the minibuffer window only
-if it's active.
-MINIBUF neither nil nor t means never include the minibuffer window.  */)
-  (Lisp_Object frame, Lisp_Object minibuf, Lisp_Object window)
-{
-  if (NILP (window))
-    window = FRAMEP (frame) ? XFRAME (frame)->selected_window : selected_window;
-  CHECK_WINDOW (window);
-  if (NILP (frame))
-    frame = selected_frame;
-
-  if (!EQ (frame, XWINDOW (window)->frame))
-    error ("Window is on a different frame");
-
-  return window_list_1 (window, minibuf, frame);
-}
-
-
 /* Return a list of windows in cyclic ordering.  Arguments are like
    for `next-window'.  */
 
@@ -2149,6 +2451,29 @@ window_list_1 (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames)
 }
 
 
+DEFUN ("window-list", Fwindow_list, Swindow_list, 0, 3, 0,
+       doc: /* Return a list of windows on FRAME, starting with WINDOW.
+FRAME nil or omitted means use the selected frame.
+WINDOW nil or omitted means use the selected window.
+MINIBUF t means include the minibuffer window, even if it isn't active.
+MINIBUF nil or omitted means include the minibuffer window only
+if it's active.
+MINIBUF neither nil nor t means never include the minibuffer window.  */)
+  (Lisp_Object frame, Lisp_Object minibuf, Lisp_Object window)
+{
+  if (NILP (window))
+    window = FRAMEP (frame) ? XFRAME (frame)->selected_window : selected_window;
+  CHECK_WINDOW (window);
+  if (NILP (frame))
+    frame = selected_frame;
+
+  if (!EQ (frame, XWINDOW (window)->frame))
+    error ("Window is on a different frame");
+
+  return window_list_1 (window, minibuf, frame);
+}
+
+
 \f
 /* Look at all windows, performing an operation specified by TYPE
    with argument OBJ.
@@ -2271,13 +2596,13 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
          case DELETE_BUFFER_WINDOWS:
            if (EQ (w->buffer, obj))
              {
-               struct frame *f = XFRAME (WINDOW_FRAME (w));
+               struct frame *fr = XFRAME (WINDOW_FRAME (w));
 
                /* If this window is dedicated, and in a frame of its own,
                   kill the frame.  */
-               if (EQ (window, FRAME_ROOT_WINDOW (f))
+               if (EQ (window, FRAME_ROOT_WINDOW (fr))
                    && !NILP (w->dedicated)
-                   && other_visible_frames (f))
+                   && other_visible_frames (fr))
                  {
                    /* Skip the other windows on this frame.
                       There might be one, the minibuffer!  */
@@ -2329,16 +2654,16 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
            if (EQ (w->buffer, obj))
              {
                Lisp_Object buffer;
-               struct frame *f = XFRAME (w->frame);
+               struct frame *fr = XFRAME (w->frame);
 
                /* Find another buffer to show in this window.  */
                buffer = Fother_buffer (obj, Qnil, w->frame);
 
                /* If this window is dedicated, and in a frame of its own,
                   kill the frame.  */
-               if (EQ (window, FRAME_ROOT_WINDOW (f))
+               if (EQ (window, FRAME_ROOT_WINDOW (fr))
                    && !NILP (w->dedicated)
-                   && other_visible_frames (f))
+                   && other_visible_frames (fr))
                  {
                    /* Skip the other windows on this frame.
                       There might be one, the minibuffer!  */
@@ -2352,11 +2677,11 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
                  }
                else if (!NILP (w->dedicated) && !NILP (w->parent))
                  {
-                   Lisp_Object window;
-                   XSETWINDOW (window, w);
+                   Lisp_Object window_to_delete;
+                   XSETWINDOW (window_to_delete, w);
                    /* If this window is dedicated and not the only window
                       in its frame, then kill it.  */
-                   Fdelete_window (window);
+                   Fdelete_window (window_to_delete);
                  }
                else
                  {
@@ -2383,7 +2708,7 @@ 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 (XBUFFER (w->buffer)->name))
+               && NILP (BVAR (XBUFFER (w->buffer), name)))
              abort ();
            break;
 
@@ -2398,6 +2723,7 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
 
 /* Used for debugging.  Abort if any window has a dead buffer.  */
 
+extern void check_all_windows (void) EXTERNALLY_VISIBLE;
 void
 check_all_windows (void)
 {
@@ -2787,7 +3113,7 @@ window_min_size_2 (struct window *w, int width_p, int safe_p)
     {
       int safe_size = (MIN_SAFE_WINDOW_HEIGHT
                       + ((BUFFERP (w->buffer)
-                          && !NILP (XBUFFER (w->buffer)->mode_line_format))
+                          && !NILP (BVAR (XBUFFER (w->buffer), mode_line_format)))
                          ? 1 : 0));
 
       return safe_p ? safe_size : max (window_min_height, safe_size);
@@ -3040,14 +3366,10 @@ shrink_windows (int total, int size, int nchildren, int shrinkable,
   while (total_shrink > total_removed)
     {
       int nonzero_sizes = 0;
-      int nonzero_idx = -1;
 
       for (i = 0; i < nchildren; ++i)
         if (new_sizes[i] > 0)
-          {
-            ++nonzero_sizes;
-            nonzero_idx = i;
-          }
+         ++nonzero_sizes;
 
       for (i = 0; i < nchildren; ++i)
         if (new_sizes[i] > min_sizes[i])
@@ -3157,11 +3479,14 @@ size_window (Lisp_Object window, int size, int width_p, int nodelete_p, int firs
       Lisp_Object last_child;
       int child_size;
 
-      for (child = *forward; !NILP (child); child = c->next)
+      child = *forward;
+      do
        {
          c = XWINDOW (child);
          last_child = child;
+         child = c->next;
        }
+      while (!NILP (child));
 
       child_size = WINDOW_TOTAL_SIZE (c, width_p);
       size_window (last_child, size - old_size + child_size,
@@ -3186,7 +3511,7 @@ size_window (Lisp_Object window, int size, int width_p, int nodelete_p, int firs
     }
   else if (!NILP (*forward))
     {
-      int fixed_size, each, extra, n;
+      int fixed_size, each IF_LINT (= 0), extra IF_LINT (= 0), n;
       int resize_fixed_p, nfixed;
       int last_pos, first_pos, nchildren, total;
       int *new_sizes = NULL;
@@ -3232,11 +3557,11 @@ size_window (Lisp_Object window, int size, int width_p, int nodelete_p, int firs
       last_pos = first_pos;
       for (n = 0, child = *forward; !NILP (child); child = c->next, ++n)
        {
-         int new_size, old_size;
+         int new_child_size, old_child_size;
 
          c = XWINDOW (child);
-         old_size = WINDOW_TOTAL_SIZE (c, width_p);
-         new_size = old_size;
+         old_child_size = WINDOW_TOTAL_SIZE (c, width_p);
+         new_child_size = old_child_size;
 
          /* The top or left edge position of this child equals the
             bottom or right edge of its predecessor.  */
@@ -3248,18 +3573,20 @@ size_window (Lisp_Object window, int size, int width_p, int nodelete_p, int firs
          /* If this child can be resized, do it.  */
          if (resize_fixed_p || !window_fixed_size_p (c, width_p, 0))
            {
-             new_size = new_sizes ? new_sizes[n] : old_size + each + extra;
+             new_child_size =
+               new_sizes ? new_sizes[n] : old_child_size + each + extra;
              extra = 0;
            }
 
          /* Set new size.  Note that size_window also propagates
             edge positions to children, so it's not a no-op if we
             didn't change the child's size.  */
-         size_window (child, new_size, width_p, 1, first_only, last_only);
+         size_window (child, new_child_size, width_p, 1,
+                      first_only, last_only);
 
          /* Remember the bottom/right edge position of this child; it
             will be used to set the top/left edge of the next child.  */
-          last_pos += new_size;
+          last_pos += new_child_size;
        }
 
       xfree (new_sizes);
@@ -3339,8 +3666,12 @@ change_window_heights (Lisp_Object window, int n)
 \f
 int window_select_count;
 
-EXFUN (Fset_window_fringes, 4);
-EXFUN (Fset_window_scroll_bars, 4);
+static Lisp_Object Fset_window_margins (Lisp_Object, Lisp_Object, Lisp_Object);
+static Lisp_Object Fset_window_fringes (Lisp_Object, Lisp_Object, Lisp_Object,
+                                       Lisp_Object);
+static Lisp_Object Fset_window_scroll_bars (Lisp_Object, Lisp_Object,
+                                           Lisp_Object, Lisp_Object);
+static Lisp_Object Fset_window_vscroll (Lisp_Object, Lisp_Object, Lisp_Object);
 
 static void
 run_funs (Lisp_Object funs)
@@ -3387,12 +3718,12 @@ run_window_configuration_change_hook (struct frame *f)
        if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook,
                                      buffer)))
          {
-           int count = SPECPDL_INDEX ();
+           int count1 = SPECPDL_INDEX ();
            record_unwind_protect (select_window_norecord, Fselected_window ());
            select_window_norecord (window);
            run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook,
                                           buffer));
-           unbind_to (count, Qnil);
+           unbind_to (count1, Qnil);
          }
       }
   }
@@ -3418,15 +3749,15 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int
   w->buffer = buffer;
 
   if (EQ (window, selected_window))
-    b->last_selected_window = window;
+    BVAR (b, last_selected_window) = window;
 
   /* Let redisplay errors through.  */
   b->display_error_modiff = 0;
 
   /* Update time stamps of buffer display.  */
-  if (INTEGERP (b->display_count))
-    XSETINT (b->display_count, XINT (b->display_count) + 1);
-  b->display_time = Fcurrent_time ();
+  if (INTEGERP (BVAR (b, display_count)))
+    XSETINT (BVAR (b, display_count), XINT (BVAR (b, display_count)) + 1);
+  BVAR (b, display_time) = Fcurrent_time ();
 
   XSETFASTINT (w->window_end_pos, 0);
   XSETFASTINT (w->window_end_vpos, 0);
@@ -3479,18 +3810,18 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int
       w->left_margin_cols = w->right_margin_cols = Qnil;
 
       Fset_window_fringes (window,
-                          b->left_fringe_width, b->right_fringe_width,
-                          b->fringes_outside_margins);
+                          BVAR (b, left_fringe_width), BVAR (b, right_fringe_width),
+                          BVAR (b, fringes_outside_margins));
 
       Fset_window_scroll_bars (window,
-                              b->scroll_bar_width,
-                              b->vertical_scroll_bar_type, Qnil);
+                              BVAR (b, scroll_bar_width),
+                              BVAR (b, vertical_scroll_bar_type), Qnil);
 
       w->left_margin_cols = save_left;
       w->right_margin_cols = save_right;
 
       Fset_window_margins (window,
-                          b->left_margin_cols, b->right_margin_cols);
+                          BVAR (b, left_margin_cols), BVAR (b, right_margin_cols));
     }
 
   if (run_hooks_p)
@@ -3527,7 +3858,7 @@ This function runs `window-scroll-functions' before running
   XSETWINDOW (window, w);
   buffer = Fget_buffer (buffer_or_name);
   CHECK_BUFFER (buffer);
-  if (NILP (XBUFFER (buffer)->name))
+  if (NILP (BVAR (XBUFFER (buffer), name)))
     error ("Attempt to display deleted buffer");
 
   tem = w->buffer;
@@ -3539,7 +3870,7 @@ This function runs `window-scroll-functions' before running
       if (EQ (tem, buffer))
        return Qnil;
       else if (EQ (w->dedicated, Qt))
-       error ("Window is dedicated to `%s'", SDATA (XBUFFER (tem)->name));
+       error ("Window is dedicated to `%s'", SDATA (BVAR (XBUFFER (tem), name)));
       else
        w->dedicated = Qnil;
 
@@ -3550,95 +3881,6 @@ This function runs `window-scroll-functions' before running
   return Qnil;
 }
 
-/* Note that selected_window can be nil when this is called from
-   Fset_window_configuration.  */
-
-DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0,
-       doc: /* Select WINDOW.  Most editing will apply to WINDOW's buffer.
-If WINDOW is not already selected, make WINDOW's buffer current
-and make WINDOW the frame's selected window.  Return WINDOW.
-Optional second arg NORECORD non-nil means do not put this buffer
-at the front of the list of recently selected ones and do not
-make this window the most recently selected one.
-
-Note that the main editor command loop selects the buffer of the
-selected window before each command.  */)
-  (register Lisp_Object window, Lisp_Object norecord)
-{
-  register struct window *w;
-  register struct window *ow;
-  struct frame *sf;
-
-  CHECK_LIVE_WINDOW (window);
-
-  w = XWINDOW (window);
-  w->frozen_window_start_p = 0;
-
-  if (NILP (norecord))
-    {
-      ++window_select_count;
-      XSETFASTINT (w->use_time, window_select_count);
-      record_buffer (w->buffer);
-    }
-
-  if (EQ (window, selected_window))
-    return window;
-
-  sf = SELECTED_FRAME ();
-  if (XFRAME (WINDOW_FRAME (w)) != sf)
-    {
-      XFRAME (WINDOW_FRAME (w))->selected_window = window;
-      /* Use this rather than Fhandle_switch_frame
-        so that FRAME_FOCUS_FRAME is moved appropriately as we
-        move around in the state where a minibuffer in a separate
-        frame is active.  */
-      Fselect_frame (WINDOW_FRAME (w), norecord);
-      /* Fselect_frame called us back so we've done all the work already.  */
-      eassert (EQ (window, selected_window));
-      return window;
-    }
-  else
-    sf->selected_window = 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.  */
-  if (inhibit_point_swap)
-    inhibit_point_swap = 0;
-  else
-    {
-      ow = XWINDOW (selected_window);
-      if (! NILP (ow->buffer))
-       set_marker_both (ow->pointm, ow->buffer,
-                        BUF_PT (XBUFFER (ow->buffer)),
-                        BUF_PT_BYTE (XBUFFER (ow->buffer)));
-    }
-
-  selected_window = window;
-
-  Fset_buffer (w->buffer);
-
-  XBUFFER (w->buffer)->last_selected_window = window;
-
-  /* Go to the point recorded in the window.
-     This is important when the buffer is in more
-     than one window.  It also matters when
-     redisplay_window has altered point after scrolling,
-     because it makes the change only in the window.  */
-  {
-    register EMACS_INT new_point = marker_position (w->pointm);
-    if (new_point < BEGV)
-      SET_PT (BEGV);
-    else if (new_point > ZV)
-      SET_PT (ZV);
-    else
-      SET_PT (new_point);
-  }
-
-  windows_or_buffers_changed++;
-  return window;
-}
-
 static Lisp_Object
 select_window_norecord (Lisp_Object window)
 {
@@ -3653,7 +3895,7 @@ select_frame_norecord (Lisp_Object frame)
     ? Fselect_frame (frame, Qt) : selected_frame;
 }
 \f
-Lisp_Object
+static Lisp_Object
 display_buffer (Lisp_Object buffer, Lisp_Object not_this_window_p, Lisp_Object override_frame)
 {
   return call3 (Qdisplay_buffer, buffer, not_this_window_p, override_frame);
@@ -3687,7 +3929,7 @@ displaying that buffer.  */)
 
   if (STRINGP (object))
     object = Fget_buffer (object);
-  if (BUFFERP (object) && !NILP (XBUFFER (object)->name))
+  if (BUFFERP (object) && !NILP (BVAR (XBUFFER (object), name)))
     {
       /* Walk all windows looking for buffer, and force update
         of each of those windows.  */
@@ -3710,16 +3952,13 @@ temp_output_buffer_show (register Lisp_Object buf)
   register Lisp_Object window;
   register struct window *w;
 
-  XBUFFER (buf)->directory = current_buffer->directory;
+  BVAR (XBUFFER (buf), directory) = BVAR (current_buffer, directory);
 
   Fset_buffer (buf);
   BUF_SAVE_MODIFF (XBUFFER (buf)) = MODIFF;
   BEGV = BEG;
   ZV = Z;
   SET_PT (BEG);
-#if 0  /* rms: there should be no reason for this.  */
-  XBUFFER (buf)->prevent_redisplay_optimizations_p = 1;
-#endif
   set_buffer_internal (old);
 
   if (!NILP (Vtemp_buffer_show_function))
@@ -3739,29 +3978,35 @@ temp_output_buffer_show (register Lisp_Object buf)
 
       /* Run temp-buffer-show-hook, with the chosen window selected
         and its buffer current.  */
-
-      if (!NILP (Vrun_hooks)
-         && !NILP (Fboundp (Qtemp_buffer_show_hook))
-         && !NILP (Fsymbol_value (Qtemp_buffer_show_hook)))
-       {
-         int count = SPECPDL_INDEX ();
-         Lisp_Object prev_window, prev_buffer;
-         prev_window = selected_window;
-         XSETBUFFER (prev_buffer, old);
-
-         /* Select the window that was chosen, for running the hook.
-            Note: Both Fselect_window and select_window_norecord may
-            set-buffer to the buffer displayed in the window,
-            so we need to save the current buffer.  --stef  */
-         record_unwind_protect (Fset_buffer, prev_buffer);
-         record_unwind_protect (select_window_norecord, prev_window);
-         Fselect_window (window, Qt);
-         Fset_buffer (w->buffer);
-         call1 (Vrun_hooks, Qtemp_buffer_show_hook);
-         unbind_to (count, Qnil);
-       }
+      {
+        int count = SPECPDL_INDEX ();
+        Lisp_Object prev_window, prev_buffer;
+        prev_window = selected_window;
+        XSETBUFFER (prev_buffer, old);
+
+        /* Select the window that was chosen, for running the hook.
+           Note: Both Fselect_window and select_window_norecord may
+           set-buffer to the buffer displayed in the window,
+           so we need to save the current buffer.  --stef  */
+        record_unwind_protect (Fset_buffer, prev_buffer);
+        record_unwind_protect (select_window_norecord, prev_window);
+        Fselect_window (window, Qt);
+        Fset_buffer (w->buffer);
+        Frun_hooks (1, &Qtemp_buffer_show_hook);
+        unbind_to (count, Qnil);
+      }
     }
 }
+
+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
 static void
 make_dummy_parent (Lisp_Object window)
@@ -3851,7 +4096,7 @@ See Info node `(elisp)Splitting Windows' for more details and examples.  */)
        error ("Window height %d too small (after splitting)", size_int);
       if (size_int + window_safe_height > XFASTINT (o->total_lines))
        error ("Window height %d too small (after splitting)",
-              XFASTINT (o->total_lines) - size_int);
+              (int) (XFASTINT (o->total_lines) - size_int));
       if (NILP (o->parent)
          || NILP (XWINDOW (o->parent)->vchild))
        {
@@ -3868,7 +4113,7 @@ See Info node `(elisp)Splitting Windows' for more details and examples.  */)
        error ("Window width %d too small (after splitting)", size_int);
       if (size_int + window_safe_width > XFASTINT (o->total_cols))
        error ("Window width %d too small (after splitting)",
-              XFASTINT (o->total_cols) - size_int);
+              (int) (XFASTINT (o->total_cols) - size_int));
       if (NILP (o->parent)
          || NILP (XWINDOW (o->parent)->hchild))
        {
@@ -4170,7 +4415,7 @@ enlarge_window (Lisp_Object window, int delta, int horiz_flag)
        {
          /* If trying to grow this window to or beyond size of the parent,
             just delete all the sibling windows.  */
-         Lisp_Object start, tem, next;
+         Lisp_Object start, tem;
 
          start = XWINDOW (parent)->vchild;
          if (NILP (start))
@@ -4180,9 +4425,9 @@ enlarge_window (Lisp_Object window, int delta, int horiz_flag)
          tem = XWINDOW (window)->next;
          while (! NILP (tem))
            {
-             next = XWINDOW (tem)->next;
+             Lisp_Object next1 = XWINDOW (tem)->next;
              delete_window (tem);
-             tem = next;
+             tem = next1;
            }
 
          /* Delete any siblings that come after WINDOW.
@@ -4191,9 +4436,9 @@ enlarge_window (Lisp_Object window, int delta, int horiz_flag)
          tem = start;
          while (! EQ (tem, window))
            {
-             next = XWINDOW (tem)->next;
+             Lisp_Object next1 = XWINDOW (tem)->next;
              delete_window (tem);
-             tem = next;
+             tem = next1;
            }
        }
       else
@@ -4706,37 +4951,6 @@ window_internal_height (struct window *w)
 
   return ht;
 }
-
-
-/* Return the number of columns in W.
-   Don't count columns occupied by scroll bars or the vertical bar
-   separating W from the sibling to its right.  */
-
-int
-window_box_text_cols (struct window *w)
-{
-  struct frame *f = XFRAME (WINDOW_FRAME (w));
-  int width = XINT (w->total_cols);
-
-  if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
-    /* Scroll bars occupy a few columns.  */
-    width -= WINDOW_CONFIG_SCROLL_BAR_COLS (w);
-  else if (!FRAME_WINDOW_P (f)
-          && !WINDOW_RIGHTMOST_P (w) && !WINDOW_FULL_WIDTH_P (w))
-    /* The column of `|' characters separating side-by-side windows
-       occupies one column only.  */
-    width -= 1;
-
-  if (FRAME_WINDOW_P (f))
-    /* On window-systems, fringes and display margins cannot be
-       used for normal text.  */
-    width -= (WINDOW_FRINGE_COLS (w)
-             + WINDOW_LEFT_MARGIN_COLS (w)
-             + WINDOW_RIGHT_MARGIN_COLS (w));
-
-  return width;
-}
-
 \f
 /************************************************************************
                           Window Scrolling
@@ -4881,8 +5095,8 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
         possibility of point becoming "stuck" on a tall line when
         scrolling by one line.  */
       if (window_scroll_pixel_based_preserve_y < 0
-         || !SYMBOLP (current_kboard->Vlast_command)
-         || NILP (Fget (current_kboard->Vlast_command, Qscroll_command)))
+         || !SYMBOLP (KVAR (current_kboard, Vlast_command))
+         || NILP (Fget (KVAR (current_kboard, Vlast_command), Qscroll_command)))
        {
          start_display (&it, w, start);
          move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
@@ -4915,7 +5129,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
             looking at an image that is taller that the window height.  */
          while (start_pos == IT_CHARPOS (it)
                 && start_pos > BEGV)
-           move_it_by_lines (&it, -1, 1);
+           move_it_by_lines (&it, -1);
        }
       else if (dy > 0)
        {
@@ -4925,11 +5139,11 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
             looking at an image that is taller that the window height.  */
          while (start_pos == IT_CHARPOS (it)
                 && start_pos < ZV)
-           move_it_by_lines (&it, 1, 1);
+           move_it_by_lines (&it, 1);
        }
     }
   else
-    move_it_by_lines (&it, n, 1);
+    move_it_by_lines (&it, n);
 
   /* We failed if we find ZV is already on the screen (scrolling up,
      means there's nothing past the end), or if we can't start any
@@ -5040,7 +5254,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
          while (it.current_y < this_scroll_margin)
            {
              int prev = it.current_y;
-             move_it_by_lines (&it, 1, 1);
+             move_it_by_lines (&it, 1);
              if (prev == it.current_y)
                break;
            }
@@ -5074,7 +5288,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
        partial_p = it.current_y + it.ascent + it.descent > it.last_visible_y;
       else
        {
-         move_it_by_lines (&it, 1, 1);
+         move_it_by_lines (&it, 1);
          partial_p = it.current_y > it.last_visible_y;
        }
 
@@ -5101,7 +5315,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
            /* The last line was only partially visible, so back up two
               lines to make sure we're on a fully visible line.  */
            {
-             move_it_by_lines (&it, -2, 0);
+             move_it_by_lines (&it, -2);
              SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
            }
          else
@@ -5119,7 +5333,12 @@ static void
 window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
 {
   register struct window *w = XWINDOW (window);
-  register EMACS_INT opoint = PT, opoint_byte = PT_BYTE;
+  /* Fvertical_motion enters redisplay, which can trigger
+     fontification, which in turn can modify buffer text (e.g., if the
+     fontification functions replace escape sequences with faces, as
+     in `grep-mode-font-lock-keywords').  So we use a marker to record
+     the old point position, to prevent crashes in SET_PT_BOTH.  */
+  Lisp_Object opoint_marker = Fpoint_marker ();
   register EMACS_INT pos, pos_byte;
   register int ht = window_internal_height (w);
   register Lisp_Object tem;
@@ -5138,8 +5357,8 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
   if (!NILP (Vscroll_preserve_screen_position))
     {
       if (window_scroll_preserve_vpos <= 0
-         || !SYMBOLP (current_kboard->Vlast_command)
-         || NILP (Fget (current_kboard->Vlast_command, Qscroll_command)))
+         || !SYMBOLP (KVAR (current_kboard, Vlast_command))
+         || NILP (Fget (KVAR (current_kboard, Vlast_command), Qscroll_command)))
        {
          struct position posit
            = *compute_motion (startpos, 0, 0, 0,
@@ -5169,7 +5388,8 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
   pos = PT;
   pos_byte = PT_BYTE;
   bolp = Fbolp ();
-  SET_PT_BOTH (opoint, opoint_byte);
+  SET_PT_BOTH (marker_position (opoint_marker),
+              marker_byte_position (opoint_marker));
 
   if (lose)
     {
@@ -5220,8 +5440,9 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
          else
            top_margin = pos;
 
-         if (top_margin <= opoint)
-           SET_PT_BOTH (opoint, opoint_byte);
+         if (top_margin <= marker_position (opoint_marker))
+           SET_PT_BOTH (marker_position (opoint_marker),
+                        marker_byte_position (opoint_marker));
          else if (!NILP (Vscroll_preserve_screen_position))
            {
              SET_PT_BOTH (pos, pos_byte);
@@ -5243,8 +5464,9 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
          else
            bottom_margin = PT + 1;
 
-         if (bottom_margin > opoint)
-           SET_PT_BOTH (opoint, opoint_byte);
+         if (bottom_margin > marker_position (opoint_marker))
+           SET_PT_BOTH (marker_position (opoint_marker),
+                        marker_byte_position (opoint_marker));
          else
            {
              if (!NILP (Vscroll_preserve_screen_position))
@@ -5437,7 +5659,7 @@ by this function.  This happens in an interactive call.  */)
   struct window *w = XWINDOW (selected_window);
 
   if (NILP (arg))
-    XSETFASTINT (arg, window_box_text_cols (w) - 2);
+    XSETFASTINT (arg, window_body_cols (w) - 2);
   else
     arg = Fprefix_numeric_value (arg);
 
@@ -5466,7 +5688,7 @@ by this function.  This happens in an interactive call.  */)
   struct window *w = XWINDOW (selected_window);
 
   if (NILP (arg))
-    XSETFASTINT (arg, window_box_text_cols (w) - 2);
+    XSETFASTINT (arg, window_body_cols (w) - 2);
   else
     arg = Fprefix_numeric_value (arg);
 
@@ -5571,7 +5793,7 @@ and redisplay normally--don't erase and redraw the frame.  */)
   struct buffer *obuf = current_buffer;
   int center_p = 0;
   EMACS_INT charpos, bytepos;
-  int iarg;
+  int iarg IF_LINT (= 0);
   int this_scroll_margin;
 
   /* If redisplay is suppressed due to an error, try again.  */
@@ -5644,14 +5866,14 @@ and redisplay normally--don't erase and redraw the frame.  */)
          start_display (&it, w, pt);
 
          /* Be sure we have the exact height of the full line containing PT.  */
-         move_it_by_lines (&it, 0, 1);
+         move_it_by_lines (&it, 0);
 
          /* The amount of pixels we have to move back is the window
             height minus what's displayed in the line containing PT,
             and the lines below.  */
          it.current_y = 0;
          it.vpos = 0;
-         move_it_by_lines (&it, nlines, 1);
+         move_it_by_lines (&it, nlines);
 
          if (it.vpos == nlines)
            h -= it.current_y;
@@ -5690,7 +5912,7 @@ and redisplay normally--don't erase and redraw the frame.  */)
          */
          h += extra_line_spacing;
          while (-it.current_y > h)
-           move_it_by_lines (&it, 1, 1);
+           move_it_by_lines (&it, 1);
 
          charpos = IT_CHARPOS (it);
          bytepos = IT_BYTEPOS (it);
@@ -5837,8 +6059,7 @@ zero means top of window, negative means relative to bottom of window.  */)
 
 struct save_window_data
   {
-    EMACS_UINT size;
-    struct Lisp_Vector *next_from_Lisp_Vector_struct;
+    struct vectorlike_header header;
     Lisp_Object selected_frame;
     Lisp_Object current_window;
     Lisp_Object current_buffer;
@@ -5860,10 +6081,7 @@ struct save_window_data
 /* This is saved as a Lisp_Vector  */
 struct saved_window
 {
-  /* these first two must agree with struct Lisp_Vector in lisp.h */
-  EMACS_UINT size;
-  struct Lisp_Vector *next_from_Lisp_Vector_struct;
-
+  struct vectorlike_header header;
   Lisp_Object window;
   Lisp_Object buffer, start, pointm, mark;
   Lisp_Object left_col, top_line, total_cols, total_lines;
@@ -5925,7 +6143,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 (XBUFFER (new_current_buffer)->name))
+  if (NILP (BVAR (XBUFFER (new_current_buffer), name)))
     new_current_buffer = Qnil;
   else
     {
@@ -6044,7 +6262,7 @@ the return value is nil.  Otherwise the value is t.  */)
         dead.  */
       delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f)));
 
-      for (k = 0; k < saved_windows->size; k++)
+      for (k = 0; k < saved_windows->header.size; k++)
        {
          p = SAVED_WINDOW_N (saved_windows, k);
          w = XWINDOW (p->window);
@@ -6110,14 +6328,14 @@ the return value is nil.  Otherwise the value is t.  */)
            w->buffer = p->buffer;
          else
            {
-             if (!NILP (XBUFFER (p->buffer)->name))
+             if (!NILP (BVAR (XBUFFER (p->buffer), name)))
                /* If saved buffer is alive, install it.  */
                {
                  w->buffer = p->buffer;
                  w->start_at_line_beg = 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 (XBUFFER (w->buffer)->mark,
+                 Fset_marker (BVAR (XBUFFER (w->buffer), mark),
                               p->mark, w->buffer);
 
                  /* As documented in Fcurrent_window_configuration, don't
@@ -6127,7 +6345,7 @@ the return value is nil.  Otherwise the value is t.  */)
                      && XBUFFER (p->buffer) == current_buffer)
                    Fgoto_char (w->pointm);
                }
-             else if (NILP (w->buffer) || NILP (XBUFFER (w->buffer)->name))
+             else if (NILP (w->buffer) || NILP (BVAR (XBUFFER (w->buffer), name)))
                /* Else unless window has a live buffer, get one.  */
                {
                  w->buffer = Fcdr (Fcar (Vbuffer_alist));
@@ -6167,9 +6385,8 @@ the return value is nil.  Otherwise the value is t.  */)
         out point" in the old selected window using the buffer that
         has been restored into it.  We already swapped out that point
         from that window's old buffer.  */
-      inhibit_point_swap = 1;
-      Fselect_window (data->current_window, Qnil);
-      XBUFFER (XWINDOW (selected_window)->buffer)->last_selected_window
+      select_window (data->current_window, Qnil, 1);
+      BVAR (XBUFFER (XWINDOW (selected_window)->buffer), last_selected_window)
        = selected_window;
 
       if (NILP (data->focus_frame)
@@ -6370,7 +6587,7 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
          p->start = Fcopy_marker (w->start, Qnil);
          p->start_at_line_beg = w->start_at_line_beg;
 
-         tem = XBUFFER (w->buffer)->mark;
+         tem = BVAR (XBUFFER (w->buffer), mark);
          p->mark = Fcopy_marker (tem, Qnil);
        }
       else
@@ -6448,28 +6665,6 @@ redirection (see `redirect-frame-focus').  */)
   return (tem);
 }
 
-DEFUN ("save-window-excursion", Fsave_window_excursion, Ssave_window_excursion,
-       0, UNEVALLED, 0,
-       doc: /* Execute BODY, preserving window sizes and contents.
-Return the value of the last form in BODY.
-Restore which buffer appears in which window, where display starts,
-and the value of point and mark for each window.
-Also restore the choice of selected window.
-Also restore which buffer is current.
-Does not restore the value of point in current buffer.
-usage: (save-window-excursion BODY...)  */)
-  (Lisp_Object args)
-{
-  register Lisp_Object val;
-  register int count = SPECPDL_INDEX ();
-
-  record_unwind_protect (Fset_window_configuration,
-                        Fcurrent_window_configuration (Qnil));
-  val = Fprogn (args);
-  return unbind_to (count, val);
-}
-
-
 \f
 /***********************************************************************
                            Window Split Tree
@@ -6680,8 +6875,8 @@ Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS).  */)
                            Scroll bars
  ***********************************************************************/
 
-DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars, Sset_window_scroll_bars,
-       2, 4, 0,
+DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars,
+       Sset_window_scroll_bars, 2, 4, 0,
        doc: /* Set width and type of scroll bars of window WINDOW.
 If window is nil, set scroll bars of the currently selected window.
 Second parameter WIDTH specifies the pixel width for the scroll bar;
@@ -6950,10 +7145,10 @@ compare_window_configurations (Lisp_Object c1, Lisp_Object c2, int ignore_positi
     return 0;
 
   /* Verify that the two confis have the same number of windows.  */
-  if (sw1->size != sw2->size)
+  if (sw1->header.size != sw2->header.size)
     return 0;
 
-  for (i = 0; i < sw1->size; i++)
+  for (i = 0; i < sw1->header.size; i++)
     {
       struct saved_window *p1, *p2;
       int w1_is_current, w2_is_current;
@@ -7099,9 +7294,7 @@ syms_of_window (void)
   window_scroll_preserve_hpos = -1;
   window_scroll_preserve_vpos = -1;
 
-  inhibit_point_swap = 0;
-
-  DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function,
+  DEFVAR_LISP ("temp-buffer-show-function", Vtemp_buffer_show_function,
               doc: /* Non-nil means call as function to display a help buffer.
 The function is called with one argument, the buffer to be displayed.
 Used by `with-output-to-temp-buffer'.
@@ -7109,29 +7302,29 @@ If this function is used, then it must do the entire job of showing
 the buffer; `temp-buffer-show-hook' is not run unless this function runs it.  */);
   Vtemp_buffer_show_function = Qnil;
 
-  DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window,
+  DEFVAR_LISP ("minibuffer-scroll-window", Vminibuf_scroll_window,
               doc: /* Non-nil means it is the window that C-M-v in minibuffer should scroll.  */);
   Vminibuf_scroll_window = Qnil;
 
-  DEFVAR_BOOL ("mode-line-in-non-selected-windows", &mode_line_in_non_selected_windows,
+  DEFVAR_BOOL ("mode-line-in-non-selected-windows", mode_line_in_non_selected_windows,
               doc: /* Non-nil means to use `mode-line-inactive' face in non-selected windows.
 If the minibuffer is active, the `minibuffer-scroll-window' mode line
 is displayed in the `mode-line' face.  */);
   mode_line_in_non_selected_windows = 1;
 
-  DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer,
+  DEFVAR_LISP ("other-window-scroll-buffer", Vother_window_scroll_buffer,
               doc: /* If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window.  */);
   Vother_window_scroll_buffer = Qnil;
 
-  DEFVAR_BOOL ("auto-window-vscroll", &auto_window_vscroll_p,
+  DEFVAR_BOOL ("auto-window-vscroll", auto_window_vscroll_p,
               doc: /* *Non-nil means to automatically adjust `window-vscroll' to view tall lines.  */);
   auto_window_vscroll_p = 1;
 
-  DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines,
+  DEFVAR_INT ("next-screen-context-lines", next_screen_context_lines,
              doc: /* *Number of lines of continuity when scrolling by screenfuls.  */);
   next_screen_context_lines = 2;
 
-  DEFVAR_INT ("window-min-height", &window_min_height,
+  DEFVAR_INT ("window-min-height", window_min_height,
              doc: /* Allow deleting windows less than this tall.
 The value is measured in line units.  If a window wants a modeline it
 is counted as one line.
@@ -7140,7 +7333,7 @@ Emacs honors settings of this variable when enlarging or shrinking
 windows vertically.  A value less than 1 is invalid.  */);
   window_min_height = 4;
 
-  DEFVAR_INT ("window-min-width", &window_min_width,
+  DEFVAR_INT ("window-min-width", window_min_width,
              doc: /* Allow deleting windows less than this wide.
 The value is measured in characters and includes any fringes or
 the scrollbar.
@@ -7150,7 +7343,7 @@ windows horizontally.  A value less than 2 is invalid.  */);
   window_min_width = 10;
 
   DEFVAR_LISP ("scroll-preserve-screen-position",
-              &Vscroll_preserve_screen_position,
+              Vscroll_preserve_screen_position,
               doc: /* *Controls if scroll commands move point to keep its screen position unchanged.
 A value of nil means point does not keep its screen position except
 at the scroll margin or window boundary respectively.
@@ -7162,19 +7355,19 @@ Scroll commands should have the `scroll-command' property
 on their symbols to be controlled by this variable.  */);
   Vscroll_preserve_screen_position = Qnil;
 
-  DEFVAR_LISP ("window-point-insertion-type", &Vwindow_point_insertion_type,
+  DEFVAR_LISP ("window-point-insertion-type", Vwindow_point_insertion_type,
               doc: /* Type of marker to use for `window-point'.  */);
   Vwindow_point_insertion_type = Qnil;
 
   DEFVAR_LISP ("window-configuration-change-hook",
-              &Vwindow_configuration_change_hook,
+              Vwindow_configuration_change_hook,
               doc: /* Functions to call when window configuration changes.
 The buffer-local part is run once per window, with the relevant window
 selected; while the global part is run only once for the modified frame,
 with the relevant frame selected.  */);
   Vwindow_configuration_change_hook = Qnil;
 
-  DEFVAR_LISP ("recenter-redisplay", &Vrecenter_redisplay,
+  DEFVAR_LISP ("recenter-redisplay", Vrecenter_redisplay,
               doc: /* If non-nil, then the `recenter' command with a nil argument
 will redraw the entire frame; the special value `tty' causes the
 frame to be redrawn only if it is a tty frame.  */);
@@ -7186,9 +7379,24 @@ frame to be redrawn only if it is a tty frame.  */);
   defsubr (&Swindow_minibuffer_p);
   defsubr (&Swindowp);
   defsubr (&Swindow_live_p);
+  defsubr (&Swindow_frame);
+  defsubr (&Sframe_root_window);
+  defsubr (&Sframe_first_window);
+  defsubr (&Sframe_selected_window);
+  defsubr (&Sset_frame_selected_window);
   defsubr (&Spos_visible_in_window_p);
   defsubr (&Swindow_line_height);
   defsubr (&Swindow_buffer);
+  defsubr (&Swindow_parent);
+  defsubr (&Swindow_vchild);
+  defsubr (&Swindow_hchild);
+  defsubr (&Swindow_next);
+  defsubr (&Swindow_prev);
+  defsubr (&Swindow_use_time);
+  defsubr (&Swindow_top_line);
+  defsubr (&Swindow_left_column);
+  defsubr (&Swindow_total_size);
+  defsubr (&Swindow_body_size);
   defsubr (&Swindow_height);
   defsubr (&Swindow_width);
   defsubr (&Swindow_full_width_p);
@@ -7217,7 +7425,6 @@ frame to be redrawn only if it is a tty frame.  */);
   defsubr (&Sprevious_window);
   defsubr (&Sother_window);
   defsubr (&Sget_lru_window);
-  defsubr (&Swindow_use_time);
   defsubr (&Sget_largest_window);
   defsubr (&Sget_buffer_window);
   defsubr (&Sdelete_other_windows);
@@ -7227,6 +7434,7 @@ frame to be redrawn only if it is a tty frame.  */);
   defsubr (&Sset_window_buffer);
   defsubr (&Sselect_window);
   defsubr (&Sforce_window_update);
+  defsubr (&Stemp_output_buffer_show);
   defsubr (&Ssplit_window);
   defsubr (&Senlarge_window);
   defsubr (&Sshrink_window);
@@ -7245,7 +7453,6 @@ frame to be redrawn only if it is a tty frame.  */);
   defsubr (&Swindow_configuration_frame);
   defsubr (&Sset_window_configuration);
   defsubr (&Scurrent_window_configuration);
-  defsubr (&Ssave_window_excursion);
   defsubr (&Swindow_tree);
   defsubr (&Sset_window_margins);
   defsubr (&Swindow_margins);
@@ -7257,10 +7464,10 @@ frame to be redrawn only if it is a tty frame.  */);
   defsubr (&Sset_window_vscroll);
   defsubr (&Scompare_window_configurations);
   defsubr (&Swindow_list);
+  defsubr (&Swindow_list_1);
   defsubr (&Swindow_parameters);
   defsubr (&Swindow_parameter);
   defsubr (&Sset_window_parameter);
-
 }
 
 void
@@ -7278,4 +7485,3 @@ keys_of_window (void)
   initial_define_key (meta_map, Ctl ('V'), "scroll-other-window");
   initial_define_key (meta_map, 'v', "scroll-down-command");
 }
-