]> code.delx.au - gnu-emacs/blobdiff - src/window.c
Port documentation to Texinfo 5.0.
[gnu-emacs] / src / window.c
index 330636efed93dd9e5d7477797544fb043d3bdcf6..467c0861044c669aa80500e21e6e154599048685 100644 (file)
@@ -1,7 +1,7 @@
 /* Window creation, deletion and examination for GNU Emacs.
    Does not include redisplay.
-   Copyright (C) 1985-1987, 1993-1998, 2000-2012
-                 Free Software Foundation, Inc.
+   Copyright (C) 1985-1987, 1993-1998, 2000-2013 Free Software
+   Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -23,7 +23,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #define WINDOW_INLINE EXTERN_INLINE
 
 #include <stdio.h>
-#include <setjmp.h>
 
 #include "lisp.h"
 #include "character.h"
@@ -44,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
@@ -61,8 +60,7 @@ 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 *);
@@ -135,112 +133,102 @@ 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 inline void
+static void
 wset_combination_limit (struct window *w, Lisp_Object val)
 {
   w->combination_limit = val;
 }
-static inline void
+static void
 wset_dedicated (struct window *w, Lisp_Object val)
 {
   w->dedicated = val;
 }
-static inline void
+static void
 wset_display_table (struct window *w, Lisp_Object val)
 {
   w->display_table = val;
 }
-static inline void
+static void
 wset_hchild (struct window *w, Lisp_Object val)
 {
   w->hchild = val;
 }
-static inline void
+static void
 wset_left_fringe_width (struct window *w, Lisp_Object val)
 {
   w->left_fringe_width = val;
 }
-static inline void
+static void
 wset_left_margin_cols (struct window *w, Lisp_Object val)
 {
   w->left_margin_cols = val;
 }
-static inline void
+static void
 wset_new_normal (struct window *w, Lisp_Object val)
 {
   w->new_normal = val;
 }
-static inline void
+static void
 wset_new_total (struct window *w, Lisp_Object val)
 {
   w->new_total = val;
 }
-static inline void
-wset_next_buffers (struct window *w, Lisp_Object val)
-{
-  w->next_buffers = val;
-}
-static inline void
+static void
 wset_normal_cols (struct window *w, Lisp_Object val)
 {
   w->normal_cols = val;
 }
-static inline void
+static void
 wset_normal_lines (struct window *w, Lisp_Object val)
 {
   w->normal_lines = val;
 }
-static inline void
+static void
 wset_parent (struct window *w, Lisp_Object val)
 {
   w->parent = val;
 }
-static inline void
+static void
 wset_pointm (struct window *w, Lisp_Object val)
 {
   w->pointm = val;
 }
-static inline void
-wset_prev_buffers (struct window *w, Lisp_Object val)
-{
-  w->prev_buffers = val;
-}
-static inline void
+static void
 wset_right_fringe_width (struct window *w, Lisp_Object val)
 {
   w->right_fringe_width = val;
 }
-static inline void
+static void
 wset_right_margin_cols (struct window *w, Lisp_Object val)
 {
   w->right_margin_cols = val;
 }
-static inline void
+static void
 wset_scroll_bar_width (struct window *w, Lisp_Object val)
 {
   w->scroll_bar_width = val;
 }
-static inline void
+static void
 wset_start (struct window *w, Lisp_Object val)
 {
   w->start = val;
 }
-static inline void
+static void
 wset_temslot (struct window *w, Lisp_Object val)
 {
   w->temslot = val;
 }
-static inline void
+static void
 wset_vchild (struct window *w, Lisp_Object val)
 {
   w->vchild = val;
 }
-static inline void
+static void
 wset_vertical_scroll_bar_type (struct window *w, Lisp_Object val)
 {
   w->vertical_scroll_bar_type = val;
 }
-static inline void
+static void
 wset_window_parameters (struct window *w, Lisp_Object val)
 {
   w->window_parameters = val;
@@ -386,7 +374,7 @@ the first window of that frame.  */)
       else if (! NILP (XWINDOW (window)->vchild))
        window = XWINDOW (window)->vchild;
       else
-       abort ();
+       emacs_abort ();
     }
 
   return window;
@@ -535,9 +523,11 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
 }
 
 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.
+       doc: /* Select WINDOW which must be a live window.
+Also make WINDOW's frame the selected frame and WINDOW that frame's
+selected window.  In addition, make WINDOW's buffer current and set that
+buffer's value of `point' to the value of WINDOW's `window-point'.
+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
@@ -612,10 +602,12 @@ Return nil if WINDOW has no previous sibling.  */)
 
 DEFUN ("window-combination-limit", Fwindow_combination_limit, Swindow_combination_limit, 1, 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
-WINDOW's siblings.  A return value of t means that child windows of
-WINDOW are never \(re-)combined with WINDOW's siblings.  */)
+If the return value is nil, child windows of WINDOW can be recombined
+with WINDOW's siblings.  A return value of t means that child windows of
+WINDOW are never \(re-)combined with WINDOW's siblings.
+
+WINDOW must be a valid window.  The return value is meaningful for
+internal windows only.  */)
   (Lisp_Object window)
 {
   return decode_valid_window (window)->combination_limit;
@@ -623,11 +615,13 @@ 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.
+
+WINDOW must be a valid window.  Setting the combination limit is
+meaningful for internal windows only.  */)
   (Lisp_Object window, Lisp_Object limit)
 {
   wset_combination_limit (decode_valid_window (window), limit);
@@ -1289,7 +1283,7 @@ If they are in the windows's left or right marginal areas, `left-margin'\n\
       return Qnil;
 
     default:
-      abort ();
+      emacs_abort ();
     }
 }
 
@@ -1476,9 +1470,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;
@@ -1866,23 +1858,23 @@ 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);
@@ -1948,7 +1940,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)
@@ -2668,8 +2660,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:
@@ -2831,7 +2823,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);
@@ -2973,7 +2965,7 @@ window-start value is reasonable when this function is called.  */)
     }
 
   adjust_glyphs (f);
-  UNBLOCK_INPUT;
+  unblock_input ();
 
   run_window_configuration_change_hook (f);
 
@@ -3101,7 +3093,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));
     }
 
@@ -3205,7 +3197,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);
     }
 
@@ -3273,7 +3265,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;
@@ -3338,7 +3330,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.  */
@@ -3353,7 +3345,7 @@ displaying that buffer.  */)
   return Qnil;
 }
 
-
+/* Obsolete since 24.3.  */
 void
 temp_output_buffer_show (register Lisp_Object buf)
 {
@@ -3406,16 +3398,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
@@ -3473,6 +3455,10 @@ make_window (void)
   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.  */
@@ -3704,14 +3690,14 @@ be applied on the Elisp level.  */)
               (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);
 
@@ -3803,6 +3789,8 @@ resize_frame_windows (struct frame *f, int size, int horflag)
            (m, make_number (XINT (r->top_line) + XINT (r->total_lines)));
        }
     }
+
+  windows_or_buffers_changed++;
 }
 
 
@@ -3855,7 +3843,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)
@@ -3910,9 +3898,10 @@ 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_combination_limit (p, Vwindow_combination_limit);
+      if (EQ (Vwindow_combination_limit, Qt))
+       /* 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_new_total (p, horflag ? o->total_cols : o->total_lines);
       wset_new_normal (p, new_normal);
@@ -3981,13 +3970,13 @@ set correctly.  See the code of `split-window' for how this is done.  */)
   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).  */
@@ -4068,7 +4057,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
@@ -4140,7 +4129,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);
@@ -4155,7 +4144,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);  */
@@ -4205,7 +4194,7 @@ 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.  */
@@ -4216,8 +4205,9 @@ grow_mini_window (struct window *w, int delta)
       w->last_modified = 0;
       w->last_overlay_modified = 0;
 
+      windows_or_buffers_changed++;
       adjust_glyphs (f);
-      UNBLOCK_INPUT;
+      unblock_input ();
     }
 }
 
@@ -4242,7 +4232,7 @@ 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.  */
@@ -4253,8 +4243,9 @@ shrink_mini_window (struct window *w)
          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
@@ -4286,7 +4277,7 @@ 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_total_lines (w, w->new_total);
@@ -4296,7 +4287,7 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
       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;
@@ -5540,7 +5531,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;
 
@@ -5550,7 +5540,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
     {
@@ -5616,9 +5606,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)
@@ -5760,7 +5765,7 @@ the return value is nil.  Otherwise the value is t.  */)
          if (NILP (p->buffer))
            /* An internal window.  */
            wset_buffer (w, p->buffer);
-         else if (!NILP (BVAR (XBUFFER (p->buffer), name)))
+         else if (BUFFER_LIVE_P (XBUFFER (p->buffer)))
            /* If saved buffer is alive, install it.  */
            {
              wset_buffer (w, p->buffer);
@@ -5779,7 +5784,7 @@ the return value is nil.  Otherwise the value is t.  */)
                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.  */
             {
@@ -5794,18 +5799,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
-                   && (wset_buffer (w, Fget_buffer_create (auto_buffer_name)),
-                       !NILP (w->buffer)))
-           {
-             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.  */
            {
@@ -5881,7 +5874,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))
@@ -6427,15 +6420,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)
@@ -6459,18 +6445,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;
@@ -6574,15 +6553,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;
@@ -6708,10 +6689,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);
@@ -6804,23 +6785,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.
@@ -6912,7 +6906,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);