Fix bug #9221 with memory leak in bidi display.
[bpt/emacs.git] / src / window.c
index dd8cdab..8df4a85 100644 (file)
@@ -54,13 +54,11 @@ Lisp_Object Qwindowp, Qwindow_live_p;
 static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer;
 static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
 static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
-static Lisp_Object Qresize_root_window, Qresize_root_window_vertically;
+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;
 
-static Lisp_Object Qwindow_size_fixed;
-
 static int displayed_window_lines (struct window *);
 static struct window *decode_window (Lisp_Object);
 static int count_windows (struct window *);
@@ -68,13 +66,7 @@ static int get_leaf_windows (struct window *, struct window **, int);
 static void window_scroll (Lisp_Object, int, int, int);
 static void window_scroll_pixel_based (Lisp_Object, int, int, int);
 static void window_scroll_line_based (Lisp_Object, int, int, int);
-static int window_min_size_1 (struct window *, int, int);
-static int window_min_size_2 (struct window *, int, int);
-static int window_min_size (struct window *, int, int, int, int *);
-static void size_window (Lisp_Object, int, int, int, int, int);
 static int freeze_window_start (struct window *, void *);
-static int window_fixed_size_p (struct window *, int, int);
-static void enlarge_window (Lisp_Object, int, int);
 static Lisp_Object window_list (void);
 static int add_window_to_list (struct window *, void *);
 static int candidate_window_p (Lisp_Object, Lisp_Object, Lisp_Object,
@@ -90,7 +82,8 @@ 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 void resize_window_apply (struct window *, int);
+static int window_resize_check (struct window *, int);
+static void window_resize_apply (struct window *, int);
 static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
 
 /* This is the window in which the terminal's cursor should
@@ -129,9 +122,6 @@ static int window_initialized;
 /* Hook to run when window config changes.  */
 static Lisp_Object Qwindow_configuration_change_hook;
 
-/* Incremented by 1 whenever a window is deleted.  */
-static int window_deletion_count;
-
 /* Used by the function window_scroll_pixel_based */
 static int window_scroll_pixel_based_preserve_x;
 static int window_scroll_pixel_based_preserve_y;
@@ -320,6 +310,8 @@ selected windows appears and to which many commands apply.  */)
   return selected_window;
 }
 
+int window_select_count;
+
 /* 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
@@ -416,14 +408,6 @@ buffer of the selected window before each command.  */)
   return select_window (window, norecord, 0);
 }
 \f
-DEFUN ("window-clone-number", Fwindow_clone_number, Swindow_clone_number, 0, 1, 0,
-       doc: /* Return WINDOW's clone number.
-WINDOW can be any window and defaults to the selected one.  */)
-     (Lisp_Object window)
-{
-  return decode_any_window (window)->clone_number;
-}
-
 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.
@@ -442,37 +426,37 @@ Return nil if WINDOW has no parent.  */)
   return decode_any_window (window)->parent;
 }
 
-DEFUN ("window-vchild", Fwindow_vchild, Swindow_vchild, 0, 1, 0,
-       doc: /* Return WINDOW's first vertical child window.
+DEFUN ("window-top-child", Fwindow_top_child, Swindow_top_child, 0, 1, 0,
+       doc: /* Return WINDOW's topmost child window.
 WINDOW can be any window and defaults to the selected one.
-Return nil if WINDOW has no vertical child.  */)
+Return nil if WINDOW is not a vertical combination.  */)
   (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.
+DEFUN ("window-left-child", Fwindow_left_child, Swindow_left_child, 0, 1, 0,
+       doc: /* Return WINDOW's leftmost child window.
 WINDOW can be any window and defaults to the selected one.
-Return nil if WINDOW has no horizontal child.  */)
+Return nil if WINDOW is not a horizontal combination.  */)
   (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.
+DEFUN ("window-next-sibling", Fwindow_next_sibling, Swindow_next_sibling, 0, 1, 0,
+       doc: /* Return WINDOW's next sibling window.
 WINDOW can be any window and defaults to the selected one.
-Return nil if WINDOW has no right sibling.  */)
+Return nil if WINDOW has no next 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.
+DEFUN ("window-prev-sibling", Fwindow_prev_sibling, Swindow_prev_sibling, 0, 1, 0,
+       doc: /* Return WINDOW's previous sibling window.
 WINDOW can be any window and defaults to the selected one.
-Return nil if WINDOW has no left sibling.  */)
+Return nil if WINDOW has no previous sibling.  */)
   (Lisp_Object window)
 {
   return decode_any_window (window)->prev;
@@ -622,7 +606,7 @@ WINDOW can be any window and defaults to the selected one.  */)
 /* Return the number of lines of W's body.  Don't count any mode or
    header line of W.  */
 
-int
+static int
 window_body_lines (struct window *w)
 {
   int height = XFASTINT (w->total_lines);
@@ -699,6 +683,7 @@ WINDOW must be a live window and defaults to the selected one.  */)
 
 DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0,
        doc: /* Set number of columns WINDOW is scrolled from left margin to NCOL.
+If WINDOW is nil, the selected window is used.
 Return NCOL.  NCOL should be zero or positive.
 
 Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
@@ -1366,6 +1351,7 @@ if it isn't already recorded.  */)
       struct text_pos startp;
       struct it it;
       struct buffer *old_buffer = NULL;
+      void *itdata = NULL;
 
       /* Cannot use Fvertical_motion because that function doesn't
         cope with variable-height lines.  */
@@ -1387,11 +1373,13 @@ if it isn't already recorded.  */)
       else
        SET_TEXT_POS_FROM_MARKER (startp, w->start);
 
+      itdata = bidi_shelve_cache ();
       start_display (&it, w, startp);
       move_it_vertically (&it, window_box_height (w));
       if (it.current_y < it.last_visible_y)
        move_it_past_eol (&it);
       value = make_number (IT_CHARPOS (it));
+      bidi_unshelve_cache (itdata, 0);
 
       if (old_buffer)
        set_buffer_internal (old_buffer);
@@ -1426,7 +1414,7 @@ Return POS.  */)
 
 DEFUN ("set-window-start", Fset_window_start, Sset_window_start, 2, 3, 0,
        doc: /* Make display in WINDOW start at position POS in WINDOW's buffer.
-WINDOW defaults to the selected window.  Return POS.
+If WINDOW is nil, the selected window is used.  Return POS.
 Optional third arg NOFORCE non-nil inhibits next redisplay from
 overriding motion of point in order to display at this exact start.  */)
   (Lisp_Object window, Lisp_Object pos, Lisp_Object noforce)
@@ -1803,9 +1791,7 @@ DEFUN ("set-window-display-table", Fset_window_display_table, Sset_window_displa
   return table;
 }
 \f
-static void delete_window (Lisp_Object);
-
-/* Record info on buffer window w is displaying
+/* Record info on buffer window W is displaying
    when it is about to cease to display that buffer.  */
 static void
 unshow_buffer (register struct window *w)
@@ -1891,7 +1877,6 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag)
       XSETFASTINT (n->window_end_pos, 0);
       n->window_end_valid = Qnil;
       n->frozen_window_start_p = 0;
-      n->orig_top_line = n->orig_total_lines = Qnil;
     }
 
   n->next = tem = o->next;
@@ -1987,239 +1972,13 @@ recombine_windows (Lisp_Object window)
 }
 
 /* If WINDOW can be deleted, delete it.  */
-Lisp_Object
+static void
 delete_deletable_window (Lisp_Object window)
 {
   if (!NILP (call1 (Qwindow_deletable_p, window)))
     call1 (Qdelete_window, window);
 }
 \f
-DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "",
-       doc: /* Remove WINDOW from its frame.
-WINDOW defaults to the selected window.  Return nil.
-Signal an error when WINDOW is the only window on its frame.  */)
-  (register Lisp_Object window)
-{
-  struct frame *f;
-  if (NILP (window))
-    window = selected_window;
-  else
-    CHECK_LIVE_WINDOW (window);
-
-  f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
-  delete_window (window);
-
-  run_window_configuration_change_hook (f);
-
-  return Qnil;
-}
-
-static void
-delete_window (register Lisp_Object window)
-{
-  register Lisp_Object tem, parent, sib;
-  register struct window *p;
-  register struct window *par;
-  struct frame *f;
-
-  /* Because this function is called by other C code on non-leaf
-     windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
-     so we can't decode_window here.  */
-  CHECK_WINDOW (window);
-  p = XWINDOW (window);
-
-  /* It's a no-op to delete an already-deleted window.  */
-  if (NILP (p->buffer)
-      && NILP (p->hchild)
-      && NILP (p->vchild))
-    return;
-
-  parent = p->parent;
-  if (NILP (parent))
-    error ("Attempt to delete minibuffer or sole ordinary window");
-  par = XWINDOW (parent);
-
-  windows_or_buffers_changed++;
-  Vwindow_list = Qnil;
-  f = XFRAME (WINDOW_FRAME (p));
-  FRAME_WINDOW_SIZES_CHANGED (f) = 1;
-
-  /* Are we trying to delete any frame's selected window?  */
-  {
-    Lisp_Object swindow, pwindow;
-
-    /* See if the frame's selected window is either WINDOW
-       or any subwindow of it, by finding all that window's parents
-       and comparing each one with WINDOW.  */
-    swindow = FRAME_SELECTED_WINDOW (f);
-
-    while (1)
-      {
-       pwindow = swindow;
-       while (!NILP (pwindow))
-         {
-           if (EQ (window, pwindow))
-             break;
-           pwindow = XWINDOW (pwindow)->parent;
-         }
-
-       /* If the window being deleted is not a parent of SWINDOW,
-          then SWINDOW is ok as the new selected window.  */
-       if (!EQ (window, pwindow))
-         break;
-       /* Otherwise, try another window for SWINDOW.  */
-       swindow = Fnext_window (swindow, Qlambda, Qnil);
-
-       /* If we get back to the frame's selected window,
-          it means there was no acceptable alternative,
-          so we cannot delete.  */
-       if (EQ (swindow, FRAME_SELECTED_WINDOW (f)))
-         error ("Cannot delete window");
-      }
-
-    /* If we need to change SWINDOW, do it.  */
-    if (! EQ (swindow, FRAME_SELECTED_WINDOW (f)))
-      {
-       /* If we're about to delete the selected window on the
-          selected frame, then we should use Fselect_window to select
-          the new window.  On the other hand, if we're about to
-          delete the selected window on any other frame, we shouldn't do
-          anything but set the frame's selected_window slot.  */
-       if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
-         Fselect_window (swindow, Qnil);
-       else
-         FRAME_SELECTED_WINDOW (f) = swindow;
-      }
-  }
-
-  /* Now we know we can delete this one.  */
-  window_deletion_count++;
-
-  tem = p->buffer;
-  /* tem is null for dummy parent windows
-     (which have inferiors but not any contents themselves) */
-  if (!NILP (tem))
-    {
-      unshow_buffer (p);
-      unchain_marker (XMARKER (p->pointm));
-      unchain_marker (XMARKER (p->start));
-    }
-
-  /* Free window glyph matrices.  It is sure that they are allocated
-     again when ADJUST_GLYPHS is called.  Block input so that expose
-     events and other events that access glyph matrices are not
-     processed while we are changing them.  */
-  BLOCK_INPUT;
-  free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)));
-
-  tem = p->next;
-  if (!NILP (tem))
-    XWINDOW (tem)->prev = p->prev;
-
-  tem = p->prev;
-  if (!NILP (tem))
-    XWINDOW (tem)->next = p->next;
-
-  if (EQ (window, par->hchild))
-    par->hchild = p->next;
-  if (EQ (window, par->vchild))
-    par->vchild = p->next;
-
-  /* Find one of our siblings to give our space to.  */
-  sib = p->prev;
-  if (NILP (sib))
-    {
-      /* If p gives its space to its next sibling, that sibling needs
-        to have its top/left side pulled back to where p's is.
-        set_window_{height,width} will re-position the sibling's
-        children.  */
-      sib = p->next;
-      XWINDOW (sib)->top_line = p->top_line;
-      XWINDOW (sib)->left_col = p->left_col;
-    }
-
-  /* Stretch that sibling.  */
-  if (!NILP (par->vchild))
-    set_window_height (sib,
-                      XFASTINT (XWINDOW (sib)->total_lines) + XFASTINT (p->total_lines),
-                      1);
-  if (!NILP (par->hchild))
-    set_window_width (sib,
-                     XFASTINT (XWINDOW (sib)->total_cols) + XFASTINT (p->total_cols),
-                     1);
-
-  /* If parent now has only one child,
-     put the child into the parent's place.  */
-  tem = par->hchild;
-  if (NILP (tem))
-    tem = par->vchild;
-  if (NILP (XWINDOW (tem)->next)) {
-    replace_window (parent, tem, 1);
-    par = XWINDOW (tem);
-  }
-
-  /* Since we may be deleting combination windows, we must make sure that
-     not only p but all its children have been marked as deleted.  */
-  if (! NILP (p->hchild))
-    delete_all_subwindows (p->hchild);
-  else if (! NILP (p->vchild))
-    delete_all_subwindows (p->vchild);
-
-  /* Mark this window as deleted.  */
-  p->buffer = p->hchild = p->vchild = Qnil;
-
-  if (! NILP (par->parent))
-    par = XWINDOW (par->parent);
-
-  /* Check if we have a v/hchild with a v/hchild.  In that case remove
-     one of them.  */
-
-  if (! NILP (par->vchild) && ! NILP (XWINDOW (par->vchild)->vchild))
-    {
-      p = XWINDOW (par->vchild);
-      par->vchild = p->vchild;
-      tem = p->vchild;
-    }
-  else if (! NILP (par->hchild) && ! NILP (XWINDOW (par->hchild)->hchild))
-    {
-      p = XWINDOW (par->hchild);
-      par->hchild = p->hchild;
-      tem = p->hchild;
-    }
-  else
-    p = 0;
-
-  if (p)
-    {
-      while (! NILP (tem)) {
-        XWINDOW (tem)->parent = p->parent;
-        if (NILP (XWINDOW (tem)->next))
-          break;
-        tem = XWINDOW (tem)->next;
-      }
-      if (! NILP (tem)) {
-        /* The next of the v/hchild we are removing is now the next of the
-           last child for the v/hchild:
-           Before v/hchild -> v/hchild -> next1 -> next2
-                    |
-                     -> next3
-           After:  v/hchild -> next1 -> next2 -> next3
-        */
-        XWINDOW (tem)->next = p->next;
-        if (! NILP (p->next))
-          XWINDOW (p->next)->prev = tem;
-      }
-      p->next = p->prev = p->vchild = p->hchild = p->buffer = Qnil;
-    }
-
-
-  /* Adjust glyph matrices. */
-  adjust_glyphs (f);
-  UNBLOCK_INPUT;
-}
-
-
-\f
 /***********************************************************************
                             Window List
  ***********************************************************************/
@@ -2457,35 +2216,32 @@ next_window (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames, in
 
 DEFUN ("next-window", Fnext_window, Snext_window, 0, 3, 0,
        doc: /* Return window following WINDOW in cyclic ordering of windows.
-WINDOW defaults to the selected window. The optional arguments
-MINIBUF and ALL-FRAMES specify the set of windows to consider.
-
-MINIBUF t means consider the minibuffer window even if the
-minibuffer is not active.  MINIBUF nil or omitted means consider
-the minibuffer window only if the minibuffer is active.  Any
-other value means do not consider the minibuffer window even if
-the minibuffer is active.
-
-Several frames may share a single minibuffer; if the minibuffer
-is active, all windows on all frames that share that minibuffer
-are considered too.  Therefore, if you are using a separate
-minibuffer frame and the minibuffer is active and MINIBUF says it
-counts, `next-window' considers the windows in the frame from
-which you entered the minibuffer, as well as the minibuffer
-window.
+WINDOW must be a live window and defaults to the selected one. The
+optional arguments MINIBUF and ALL-FRAMES specify the set of windows to
+consider.
+
+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.
+
+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.
 
-ALL-FRAMES nil or omitted means consider all windows on WINDOW's
- frame, plus the minibuffer window if specified by the MINIBUF
- argument, see above.  If the minibuffer counts, consider all
- 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 on the current terminal.
-ALL-FRAMES 0 means consider all windows on all visible and
- 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.
+others.
 
 If you use consistent values for MINIBUF and ALL-FRAMES, you can use
 `next-window' to iterate through the entire cycle of acceptable
@@ -2499,9 +2255,32 @@ windows, eventually ending up back at the window you started with.
 
 DEFUN ("previous-window", Fprevious_window, Sprevious_window, 0, 3, 0,
        doc: /* Return window preceding WINDOW in cyclic ordering of windows.
-WINDOW defaults to the selected window. The optional arguments
-MINIBUF and ALL-FRAMES specify the set of windows to consider.
-For the precise meaning of these arguments see `next-window'.
+WINDOW must be a live window and defaults to the selected one.  The
+optional arguments MINIBUF and ALL-FRAMES specify the set of windows to
+consider.
+
+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.
+
+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 you use consistent values for MINIBUF and ALL-FRAMES, you can
 use `previous-window' to iterate through the entire cycle of
@@ -2514,37 +2293,6 @@ reverse order.  */)
 }
 
 
-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
-selected window, before making the selection.  If COUNT is
-positive, skip COUNT windows forwards.  If COUNT is negative,
-skip -COUNT windows backwards.  COUNT zero means do not skip any
-window, so select the selected window.  In an interactive call,
-COUNT is the numeric prefix argument.  Return nil.
-
-This function uses `next-window' for finding the window to select.
-The argument ALL-FRAMES has the same meaning as in `next-window',
-but the MINIBUF argument of `next-window' is always effectively
-nil.  */)
-  (Lisp_Object count, Lisp_Object all_frames)
-{
-  Lisp_Object window;
-  int i;
-
-  CHECK_NUMBER (count);
-  window = selected_window;
-
-  for (i = XINT (count); i > 0; --i)
-    window = Fnext_window (window, Qnil, all_frames);
-  for (; i < 0; ++i)
-    window = Fprevious_window (window, Qnil, all_frames);
-
-  Fselect_window (window, Qnil);
-  return Qnil;
-}
-
-
 /* Return a list of windows in cyclic ordering.  Arguments are like
    for `next-window'.  */
 
@@ -2644,11 +2392,9 @@ be listed first but no error is signalled.  */)
 enum window_loop
 {
   WINDOW_LOOP_UNUSED,
-  GET_BUFFER_WINDOW,           /* Arg is buffer */
-  DELETE_OTHER_WINDOWS,                /* Arg is window not to delete */
-  DELETE_BUFFER_WINDOWS,       /* Arg is buffer */
-  UNSHOW_BUFFER,               /* Arg is buffer */
-  REDISPLAY_BUFFER_WINDOWS,    /* Arg is buffer */
+  GET_BUFFER_WINDOW,               /* Arg is buffer */
+  REPLACE_BUFFER_IN_WINDOWS_SAFELY, /* Arg is buffer */
+  REDISPLAY_BUFFER_WINDOWS,        /* Arg is buffer */
   CHECK_ALL_WINDOWS
 };
 
@@ -2656,6 +2402,7 @@ static Lisp_Object
 window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frames)
 {
   Lisp_Object window, windows, best_window, frame_arg;
+  int frame_best_window_flag = 0;
   struct frame *f;
   struct gcpro gcpro1;
 
@@ -2705,115 +2452,51 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
         is visible, since Fwindow_list skips non-visible frames if
         that is desired, under the control of frame_arg.  */
       if (!MINI_WINDOW_P (w)
-         /* For UNSHOW_BUFFER, we must always consider all windows.  */
-         || type == UNSHOW_BUFFER
+         /* For REPLACE_BUFFER_IN_WINDOWS_SAFELY, we must always
+            consider all windows.  */
+         || type == REPLACE_BUFFER_IN_WINDOWS_SAFELY
          || (mini && minibuf_level > 0))
        switch (type)
          {
          case GET_BUFFER_WINDOW:
            if (EQ (w->buffer, obj)
-               /* Don't find any minibuffer window
-                  except the one that is currently in use.  */
-               && (MINI_WINDOW_P (w)
-                   ? EQ (window, minibuf_window)
-                   : 1))
+               /* Don't find any minibuffer window except the one that
+                  is currently in use.  */
+               && (MINI_WINDOW_P (w) ? EQ (window, minibuf_window) : 1))
              {
-               if (NILP (best_window))
-                 best_window = window;
-               else if (EQ (window, selected_window))
-                 /* Prefer to return selected-window.  */
+               if (EQ (window, selected_window))
+                 /* Preferably return the selected window.  */
                  RETURN_UNGCPRO (window);
-               else if (EQ (Fwindow_frame (window), selected_frame))
-                 /* Prefer windows on the current frame.  */
-                 best_window = window;
-             }
-           break;
-
-         case DELETE_OTHER_WINDOWS:
-           if (!EQ (window, obj))
-             Fdelete_window (window);
-           break;
-
-         case DELETE_BUFFER_WINDOWS:
-           if (EQ (w->buffer, obj))
-             {
-               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 (fr))
-                   && !NILP (w->dedicated)
-                   && other_visible_frames (fr))
+               else if (EQ (XWINDOW (window)->frame, selected_frame)
+                        && !frame_best_window_flag)
+                 /* Prefer windows on the current frame (but don't
+                    choose another one if we have one already).  */
                  {
-                   /* Skip the other windows on this frame.
-                      There might be one, the minibuffer!  */
-                   while (CONSP (XCDR (windows))
-                          && EQ (XWINDOW (XCAR (windows))->frame,
-                                 XWINDOW (XCAR (XCDR (windows)))->frame))
-                     windows = XCDR (windows);
-
-                   /* Now we can safely delete the frame.  */
-                   delete_frame (w->frame, Qnil);
+                   best_window = window;
+                   frame_best_window_flag = 1;
                  }
-               else if (NILP (w->parent))
-                 {
-                   /* If we're deleting the buffer displayed in the
-                      only window on the frame, find a new buffer to
-                      display there.  */
-                   Lisp_Object buffer;
-                   buffer = Fother_buffer (obj, Qnil, w->frame);
-                   /* Reset dedicated state of window.  */
-                   w->dedicated = Qnil;
-                   Fset_window_buffer (window, buffer, Qnil);
-                   if (EQ (window, selected_window))
-                     Fset_buffer (w->buffer);
-                 }
-               else
-                 Fdelete_window (window);
+               else if (NILP (best_window))
+                 best_window = window;
              }
            break;
 
-         case UNSHOW_BUFFER:
+         case REPLACE_BUFFER_IN_WINDOWS_SAFELY:
+           /* We could simply check whether the buffer shown by window
+              is live, and show another buffer in case it isn't.  */
            if (EQ (w->buffer, obj))
              {
-               Lisp_Object buffer;
-               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 (fr))
-                   && !NILP (w->dedicated)
-                   && other_visible_frames (fr))
-                 {
-                   /* Skip the other windows on this frame.
-                      There might be one, the minibuffer!  */
-                   while (CONSP (XCDR (windows))
-                          && EQ (XWINDOW (XCAR (windows))->frame,
-                                 XWINDOW (XCAR (XCDR (windows)))->frame))
-                     windows = XCDR (windows);
-
-                   /* Now we can safely delete the frame.  */
-                   delete_frame (w->frame, Qnil);
-                 }
-               else if (!NILP (w->dedicated) && !NILP (w->parent))
-                 {
-                   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_to_delete);
-                 }
-               else
-                 {
-                   /* Otherwise show a different buffer in the window.  */
-                   w->dedicated = Qnil;
-                   Fset_window_buffer (window, buffer, Qnil);
-                   if (EQ (window, selected_window))
-                     Fset_buffer (w->buffer);
-                 }
+               /* Undedicate WINDOW.  */
+               w->dedicated = Qnil;
+               /* Make WINDOW show the buffer returned by
+                  other_buffer_safely, don't run any hooks.  */
+               set_window_buffer
+                 (window, other_buffer_safely (w->buffer), 0, 0);
+               /* If WINDOW is the selected window, make its buffer
+                  current.  But do so only if the window shows the
+                  current buffer (Bug#6454).  */
+               if (EQ (window, selected_window)
+                   && XBUFFER (w->buffer) == current_buffer)
+                 Fset_buffer (w->buffer);
              }
            break;
 
@@ -2886,10 +2569,10 @@ selected frame and no others.  */)
     return Qnil;
 }
 
-Lisp_Object
+static Lisp_Object
 resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore)
 {
-  return call4 (Qresize_root_window, window, delta, horizontal, ignore);
+  return call4 (Qwindow_resize_root_window, window, delta, horizontal, ignore);
 }
 
 
@@ -2912,9 +2595,9 @@ window-start value is reasonable when this function is called.  */)
 {
   struct window *w, *r, *s;
   struct frame *f;
-  Lisp_Object sibling, pwindow, swindow, delta;
-  EMACS_INT startpos;
-  int top, new_top, resize_failed;
+  Lisp_Object sibling, pwindow, swindow IF_LINT (= Qnil), delta;
+  EMACS_INT startpos IF_LINT (= 0);
+  int top IF_LINT (= 0), new_top, resize_failed;
 
   w = decode_any_window (window);
   XSETWINDOW (window, w);
@@ -3000,21 +2683,21 @@ window-start value is reasonable when this function is called.  */)
   windows_or_buffers_changed++;
   Vwindow_list = Qnil;
   FRAME_WINDOW_SIZES_CHANGED (f) = 1;
+  resize_failed = 0;
 
   if (NILP (w->buffer))
     {
-      resize_failed = 0;
       /* Resize subwindows vertically.  */
       XSETINT (delta, XINT (r->total_lines) - XINT (w->total_lines));
       w->top_line = r->top_line;
       resize_root_window (window, delta, Qnil, Qnil);
-      if (resize_window_check (w, 0))
-       resize_window_apply (w, 0);
+      if (window_resize_check (w, 0))
+       window_resize_apply (w, 0);
       else
        {
          resize_root_window (window, delta, Qnil, Qt);
-         if (resize_window_check (w, 0))
-           resize_window_apply (w, 0);
+         if (window_resize_check (w, 0))
+           window_resize_apply (w, 0);
          else
            resize_failed = 1;
        }
@@ -3026,13 +2709,13 @@ window-start value is reasonable when this function is called.  */)
          XSETINT (delta, XINT (r->total_cols) - XINT (w->total_cols));
          w->left_col = r->left_col;
          resize_root_window (window, delta, Qt, Qnil);
-         if (resize_window_check (w, 1))
-           resize_window_apply (w, 1);
+         if (window_resize_check (w, 1))
+           window_resize_apply (w, 1);
          else
            {
              resize_root_window (window, delta, Qt, Qt);
-             if (resize_window_check (w, 1))
-               resize_window_apply (w, 1);
+             if (window_resize_check (w, 1))
+               window_resize_apply (w, 1);
              else
                resize_failed = 1;
            }
@@ -3128,151 +2811,28 @@ window-start value is reasonable when this function is called.  */)
 }
 
 
-DEFUN ("delete-other-windows", Fdelete_other_windows, Sdelete_other_windows,
-       0, 1, "",
-       doc: /* Make WINDOW (or the selected window) fill its frame.
-Only the frame WINDOW is on is affected.
-This function tries to reduce display jumps by keeping the text
-previously visible in WINDOW in the same place on the frame.  Doing this
-depends on the value of (window-start WINDOW), so if calling this
-function in a program gives strange scrolling, make sure the
-window-start value is reasonable when this function is called.  */)
-  (Lisp_Object window)
-{
-  struct window *w;
-  EMACS_INT startpos;
-  int top, new_top;
-
-  if (NILP (window))
-    window = selected_window;
-  else
-    CHECK_LIVE_WINDOW (window);
-  w = XWINDOW (window);
-
-  startpos = marker_position (w->start);
-  top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
-
-  if (MINI_WINDOW_P (w) && top > 0)
-    error ("Can't expand minibuffer to full frame");
-
-  window_loop (DELETE_OTHER_WINDOWS, window, 0, WINDOW_FRAME (w));
-
-  /* Try to minimize scrolling, by setting the window start to the point
-     will cause the text at the old window start to be at the same place
-     on the frame.  But don't try to do this if the window start is
-     outside the visible portion (as might happen when the display is
-     not current, due to typeahead).  */
-  new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
-  if (new_top != top
-      && startpos >= BUF_BEGV (XBUFFER (w->buffer))
-      && startpos <= BUF_ZV (XBUFFER (w->buffer)))
-    {
-      struct position pos;
-      struct buffer *obuf = current_buffer;
-
-      Fset_buffer (w->buffer);
-      /* This computation used to temporarily move point, but that can
-        have unwanted side effects due to text properties.  */
-      pos = *vmotion (startpos, -top, w);
-
-      set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
-      w->window_end_valid = Qnil;
-      w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE
-                              || FETCH_BYTE (pos.bytepos - 1) == '\n') ? Qt
-                             : Qnil);
-      /* We need to do this, so that the window-scroll-functions
-        get called.  */
-      w->optional_new_start = Qt;
-
-      set_buffer_internal (obuf);
-    }
-
-  return Qnil;
-}
-
-DEFUN ("delete-windows-on", Fdelete_windows_on, Sdelete_windows_on,
-       0, 2, "bDelete windows on (buffer): ",
-       doc: /* Delete all windows showing BUFFER-OR-NAME.
-BUFFER-OR-NAME may be a buffer or the name of an existing buffer and
-defaults to the current buffer.
-
-Optional second argument FRAME controls which frames are affected.
-If optional argument FRAME is `visible', search all visible frames.
-If FRAME is 0, search all visible and iconified frames.
-If FRAME is nil, search all frames.
-If FRAME is t, search only the selected frame.
-If FRAME is a frame, search only that frame.
-When a window showing BUFFER-OR-NAME is dedicated and the only window of
-its frame, that frame is deleted when there are other frames left.  */)
-  (Lisp_Object buffer_or_name, Lisp_Object frame)
+void
+replace_buffer_in_windows (Lisp_Object buffer)
 {
-  Lisp_Object buffer;
-
-  /* FRAME uses t and nil to mean the opposite of what window_loop
-     expects.  */
-  if (NILP (frame))
-    frame = Qt;
-  else if (EQ (frame, Qt))
-    frame = Qnil;
-
-  if (NILP (buffer_or_name))
-    buffer = Fcurrent_buffer ();
-  else
-    {
-      buffer = Fget_buffer (buffer_or_name);
-      CHECK_BUFFER (buffer);
-    }
-
-  window_loop (DELETE_BUFFER_WINDOWS, buffer, 0, frame);
-
-  return Qnil;
+  call1 (Qreplace_buffer_in_windows, buffer);
 }
 
-DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows,
-       Sreplace_buffer_in_windows,
-       0, 1, "bReplace buffer in windows: ",
-       doc: /* Replace BUFFER-OR-NAME with some other buffer in all windows showing it.
-BUFFER-OR-NAME may be a buffer or the name of an existing buffer and
-defaults to the current buffer.
-
-When a window showing BUFFER-OR-NAME is dedicated that window is
-deleted.  If that window is the only window on its frame, that frame is
-deleted too when there are other frames left.  If there are no other
-frames left, some other buffer is displayed in that window.  */)
-  (Lisp_Object buffer_or_name)
-{
-  Lisp_Object buffer;
-
-  if (NILP (buffer_or_name))
-    buffer = Fcurrent_buffer ();
-  else
-    {
-      buffer = Fget_buffer (buffer_or_name);
-      CHECK_BUFFER (buffer);
-    }
-
-  window_loop (UNSHOW_BUFFER, buffer, 0, Qt);
-
-  return Qnil;
-}
 
-/* Replace BUFFER with some other buffer in all windows
-   of all frames, even those on other keyboards.  */
+/* Safely replace BUFFER with some other buffer in all windows of all
+   frames, even those on other keyboards.  */
 
 void
-replace_buffer_in_all_windows (Lisp_Object buffer)
+replace_buffer_in_windows_safely (Lisp_Object buffer)
 {
   Lisp_Object tail, frame;
 
-  /* A single call to window_loop won't do the job
-     because it only considers frames on the current keyboard.
-     So loop manually over frames, and handle each one.  */
+  /* A single call to window_loop won't do the job because it only
+     considers frames on the current keyboard.  So loop manually over
+     frames, and handle each one.  */
   FOR_EACH_FRAME (tail, frame)
-    window_loop (UNSHOW_BUFFER, buffer, 1, frame);
+    window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, 1, frame);
 }
 \f
-/* Set the height of WINDOW and all its inferiors.  */
-
 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
    minimum allowable size.  */
 
@@ -3296,684 +2856,41 @@ check_frame_size (FRAME_PTR frame, int *rows, int *cols)
     *cols = MIN_SAFE_WINDOW_WIDTH;
 }
 
-/* Value is non-zero if window W is fixed-size.  WIDTH_P non-zero means
-   check if W's width can be changed, otherwise check W's height.
-   CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
-   siblings, too.  If none of the siblings is resizable, WINDOW isn't
-   either.  */
+/* Adjust the margins of window W if text area is too small.
+   Return 1 if window width is ok after adjustment; 0 if window
+   is still too narrow.  */
 
 static int
-window_fixed_size_p (struct window *w, int width_p, int check_siblings_p)
+adjust_window_margins (struct window *w)
 {
-  int fixed_p;
-  struct window *c;
+  int box_cols = (WINDOW_TOTAL_COLS (w)
+                 - WINDOW_FRINGE_COLS (w)
+                 - WINDOW_SCROLL_BAR_COLS (w));
+  int margin_cols = (WINDOW_LEFT_MARGIN_COLS (w)
+                    + WINDOW_RIGHT_MARGIN_COLS (w));
 
-  if (!NILP (w->hchild))
-    {
-      c = XWINDOW (w->hchild);
+  if (box_cols - margin_cols >= MIN_SAFE_WINDOW_WIDTH)
+    return 1;
 
-      if (width_p)
-       {
-         /* A horizontal combination is fixed-width if all of if its
-            children are.  */
-         while (c && window_fixed_size_p (c, width_p, 0))
-           c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
-         fixed_p = c == NULL;
-       }
-      else
-       {
-         /* A horizontal combination is fixed-height if one of if its
-            children is.  */
-         while (c && !window_fixed_size_p (c, width_p, 0))
-           c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
-         fixed_p = c != NULL;
-       }
-    }
-  else if (!NILP (w->vchild))
-    {
-      c = XWINDOW (w->vchild);
+  if (margin_cols < 0 || box_cols < MIN_SAFE_WINDOW_WIDTH)
+    return 0;
 
-      if (width_p)
-       {
-         /* A vertical combination is fixed-width if one of if its
-            children is.  */
-         while (c && !window_fixed_size_p (c, width_p, 0))
-           c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
-         fixed_p = c != NULL;
-       }
+  /* Window's text area is too narrow, but reducing the window
+     margins will fix that.  */
+  margin_cols = box_cols - MIN_SAFE_WINDOW_WIDTH;
+  if (WINDOW_RIGHT_MARGIN_COLS (w) > 0)
+    {
+      if (WINDOW_LEFT_MARGIN_COLS (w) > 0)
+       w->left_margin_cols = w->right_margin_cols
+         = make_number (margin_cols/2);
       else
-       {
-         /* A vertical combination is fixed-height if all of if its
-            children are.  */
-         while (c && window_fixed_size_p (c, width_p, 0))
-           c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
-         fixed_p = c == NULL;
-       }
-    }
-  else if (BUFFERP (w->buffer))
-    {
-      struct buffer *old = current_buffer;
-      Lisp_Object val;
-
-      current_buffer = XBUFFER (w->buffer);
-      val = find_symbol_value (Qwindow_size_fixed);
-      current_buffer = old;
-
-      fixed_p = 0;
-      if (!EQ (val, Qunbound))
-       {
-         fixed_p = !NILP (val);
-
-         if (fixed_p
-             && ((EQ (val, Qheight) && width_p)
-                 || (EQ (val, Qwidth) && !width_p)))
-           fixed_p = 0;
-       }
-
-      /* Can't tell if this one is resizable without looking at
-        siblings.  If all siblings are fixed-size this one is too.  */
-      if (!fixed_p && check_siblings_p && WINDOWP (w->parent))
-       {
-         Lisp_Object child;
-
-         for (child = w->prev; WINDOWP (child); child = XWINDOW (child)->prev)
-           if (!window_fixed_size_p (XWINDOW (child), width_p, 0))
-             break;
-
-         if (NILP (child))
-           for (child = w->next; WINDOWP (child); child = XWINDOW (child)->next)
-             if (!window_fixed_size_p (XWINDOW (child), width_p, 0))
-               break;
-
-         if (NILP (child))
-           fixed_p = 1;
-       }
-    }
-  else
-    fixed_p = 1;
-
-  return fixed_p;
-}
-
-/* Return minimum size of leaf window W.  WIDTH_P non-zero means return
-   the minimum width of W, WIDTH_P zero means return the minimum height
-   of W.  SAFE_P non-zero means ignore window-min-height|width but just
-   return values that won't crash Emacs and don't hide components like
-   fringes, scrollbars, or modelines.  If WIDTH_P is zero and W is the
-   minibuffer window, always return 1.  */
-
-static int
-window_min_size_2 (struct window *w, int width_p, int safe_p)
-{
-  /* We should consider buffer-local values of window_min_height and
-     window_min_width here.  */
-  if (width_p)
-    {
-      int safe_size = (MIN_SAFE_WINDOW_WIDTH
-                      + WINDOW_FRINGE_COLS (w)
-                      + WINDOW_SCROLL_BAR_COLS (w));
-
-      return safe_p ? safe_size : max (window_min_width, safe_size);
-    }
-  else if (MINI_WINDOW_P (w))
-    return 1;
-  else
-    {
-      int safe_size = (MIN_SAFE_WINDOW_HEIGHT
-                      + ((BUFFERP (w->buffer)
-                          && !NILP (BVAR (XBUFFER (w->buffer), mode_line_format)))
-                         ? 1 : 0));
-
-      return safe_p ? safe_size : max (window_min_height, safe_size);
-    }
-}
-
-/* Return minimum size of window W, not taking fixed-width windows into
-   account.  WIDTH_P non-zero means return the minimum width, otherwise
-   return the minimum height.  SAFE_P non-zero means ignore
-   window-min-height|width but just return values that won't crash Emacs
-   and don't hide components like fringes, scrollbars, or modelines.  If
-   W is a combination window, compute the minimum size from the minimum
-   sizes of W's children.  */
-
-static int
-window_min_size_1 (struct window *w, int width_p, int safe_p)
-{
-  struct window *c;
-  int size;
-
-  if (!NILP (w->hchild))
-    {
-      /* W is a horizontal combination.  */
-      c = XWINDOW (w->hchild);
-      size = 0;
-
-      if (width_p)
-       {
-         /* The minimum width of a horizontal combination is the sum of
-            the minimum widths of its children.  */
-         while (c)
-           {
-             size += window_min_size_1 (c, 1, safe_p);
-             c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
-           }
-       }
-      else
-       {
-         /* The minimum height of a horizontal combination is the
-            maximum of the minimum heights of its children.  */
-         while (c)
-           {
-             size = max (window_min_size_1 (c, 0, safe_p), size);
-             c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
-           }
-       }
-    }
-  else if (!NILP (w->vchild))
-    {
-      /* W is a vertical combination.  */
-      c = XWINDOW (w->vchild);
-      size = 0;
-
-      if (width_p)
-       {
-         /* The minimum width of a vertical combination is the maximum
-            of the minimum widths of its children.  */
-         while (c)
-           {
-             size = max (window_min_size_1 (c, 1, safe_p), size);
-             c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
-           }
-       }
-      else
-       {
-         /* The minimum height of a vertical combination is the sum of
-            the minimum height of its children.  */
-         while (c)
-           {
-             size += window_min_size_1 (c, 0, safe_p);
-             c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
-           }
-       }
-    }
-  else
-    /* W is a leaf window.  */
-    size = window_min_size_2 (w, width_p, safe_p);
-
-  return size;
-}
-
-/* Return the minimum size of window W, taking fixed-size windows into
-   account.  WIDTH_P non-zero means return the minimum width, otherwise
-   return the minimum height.  SAFE_P non-zero means ignore
-   window-min-height|width but just return values that won't crash Emacs
-   and don't hide components like fringes, scrollbars, or modelines.
-   IGNORE_FIXED_P non-zero means ignore if W is fixed-size.  Set *FIXED
-   to 1 if W is fixed-size unless FIXED is null.  */
-
-static int
-window_min_size (struct window *w, int width_p, int safe_p, int ignore_fixed_p, int *fixed)
-{
-  int size, fixed_p;
-
-  if (ignore_fixed_p)
-    fixed_p = 0;
-  else
-    fixed_p = window_fixed_size_p (w, width_p, 1);
-
-  if (fixed)
-    *fixed = fixed_p;
-
-  if (fixed_p)
-    size = WINDOW_TOTAL_SIZE (w, width_p);
-  else
-    size = window_min_size_1 (w, width_p, safe_p);
-
-  return size;
-}
-
-
-/* Adjust the margins of window W if text area is too small.
-   Return 1 if window width is ok after adjustment; 0 if window
-   is still too narrow.  */
-
-static int
-adjust_window_margins (struct window *w)
-{
-  int box_cols = (WINDOW_TOTAL_COLS (w)
-                 - WINDOW_FRINGE_COLS (w)
-                 - WINDOW_SCROLL_BAR_COLS (w));
-  int margin_cols = (WINDOW_LEFT_MARGIN_COLS (w)
-                    + WINDOW_RIGHT_MARGIN_COLS (w));
-
-  if (box_cols - margin_cols >= MIN_SAFE_WINDOW_WIDTH)
-    return 1;
-
-  if (margin_cols < 0 || box_cols < MIN_SAFE_WINDOW_WIDTH)
-    return 0;
-
-  /* Window's text area is too narrow, but reducing the window
-     margins will fix that.  */
-  margin_cols = box_cols - MIN_SAFE_WINDOW_WIDTH;
-  if (WINDOW_RIGHT_MARGIN_COLS (w) > 0)
-    {
-      if (WINDOW_LEFT_MARGIN_COLS (w) > 0)
-       w->left_margin_cols = w->right_margin_cols
-         = make_number (margin_cols/2);
-      else
-       w->right_margin_cols = make_number (margin_cols);
+       w->right_margin_cols = make_number (margin_cols);
     }
   else
     w->left_margin_cols = make_number (margin_cols);
   return 1;
 }
-
-/* Calculate new sizes for windows in the list FORWARD when their
-   compound size goes from TOTAL to SIZE.  TOTAL must be greater than
-   SIZE.  The number of windows in FORWARD is NCHILDREN, and the number
-   that can shrink is SHRINKABLE.  Fixed-size windows may be shrunk if
-   and only if RESIZE_FIXED_P is non-zero.  WIDTH_P non-zero means
-   shrink columns, otherwise shrink lines.
-
-   SAFE_P zero means windows may be sized down to window-min-height
-   lines (window-min-window columns for WIDTH_P non-zero).  SAFE_P
-   non-zero means windows may be sized down to their minimum safe sizes
-   taking into account the space needed to display modelines, fringes,
-   and scrollbars.
-
-   This function returns an allocated array of new sizes that the caller
-   must free.  A size -1 means the window is fixed and RESIZE_FIXED_P is
-   zero.  A size zero means the window shall be deleted.  Array index 0
-   refers to the first window in FORWARD, 1 to the second, and so on.
-
-   This function resizes windows proportionally to their size.  It also
-   tries to preserve smaller windows by resizing larger windows before
-   resizing any window to zero.  If resize_proportionally is non-nil for
-   a specific window, it will attempt to strictly resize that window
-   proportionally, even at the expense of deleting smaller windows.  */
-static int *
-shrink_windows (int total, int size, int nchildren, int shrinkable,
-               int resize_fixed_p, Lisp_Object forward, int width_p, int safe_p)
-{
-  int available_resize = 0;
-  int *new_sizes, *min_sizes;
-  struct window *c;
-  Lisp_Object child;
-  int smallest = total;
-  int total_removed = 0;
-  int total_shrink = total - size;
-  int i;
-
-  new_sizes = xmalloc (sizeof (*new_sizes) * nchildren);
-  min_sizes = xmalloc (sizeof (*min_sizes) * nchildren);
-
-  for (i = 0, child = forward; !NILP (child); child = c->next, ++i)
-    {
-      int child_size;
-
-      c = XWINDOW (child);
-      child_size = WINDOW_TOTAL_SIZE (c, width_p);
-
-      if (!resize_fixed_p && window_fixed_size_p (c, width_p, 0))
-        new_sizes[i] = -1;
-      else
-        {
-          new_sizes[i] = child_size;
-          min_sizes[i] = window_min_size_1 (c, width_p, safe_p);
-          if (child_size > min_sizes[i]
-             && NILP (c->resize_proportionally))
-            available_resize += child_size - min_sizes[i];
-        }
-    }
-  /* We might need to shrink some windows to zero.  Find the smallest
-     windows and set them to 0 until we can fulfil the new size.  */
-
-  while (shrinkable > 1 && size + available_resize < total)
-    {
-      for (i = 0; i < nchildren; ++i)
-        if (new_sizes[i] > 0 && smallest > new_sizes[i])
-          smallest = new_sizes[i];
-
-      for (i = 0; i < nchildren; ++i)
-        if (new_sizes[i] == smallest)
-          {
-            /* Resize this window down to zero.  */
-            new_sizes[i] = 0;
-            if (smallest > min_sizes[i])
-              available_resize -= smallest - min_sizes[i];
-            available_resize += smallest;
-            --shrinkable;
-            total_removed += smallest;
-
-            /* We don't know what the smallest is now.  */
-            smallest = total;
-
-            /* Out of for, just remove one window at the time and
-               check again if we have enough space.  */
-            break;
-          }
-    }
-
-  /* Now, calculate the new sizes.  Try to shrink each window
-     proportional to its size.  */
-  for (i = 0; i < nchildren; ++i)
-    {
-      if (new_sizes[i] > min_sizes[i])
-        {
-          int to_shrink = total_shrink * new_sizes[i] / total;
-
-          if (new_sizes[i] - to_shrink < min_sizes[i])
-            to_shrink = new_sizes[i] - min_sizes[i];
-          new_sizes[i] -= to_shrink;
-          total_removed += to_shrink;
-        }
-    }
-
-  /* Any reminder due to rounding, we just subtract from windows
-     that are left and still can be shrunk.  */
-  while (total_shrink > total_removed)
-    {
-      int nonzero_sizes = 0;
-
-      for (i = 0; i < nchildren; ++i)
-        if (new_sizes[i] > 0)
-         ++nonzero_sizes;
-
-      for (i = 0; i < nchildren; ++i)
-        if (new_sizes[i] > min_sizes[i])
-          {
-            --new_sizes[i];
-            ++total_removed;
-
-            /* Out of for, just shrink one window at the time and
-               check again if we have enough space.  */
-            break;
-          }
-
-      /* Special case, only one window left.  */
-      if (nonzero_sizes == 1)
-        break;
-    }
-
-  /* Any surplus due to rounding, we add to windows that are left.  */
-  while (total_shrink < total_removed)
-    {
-      for (i = 0; i < nchildren; ++i)
-        {
-          if (new_sizes[i] != 0 && total_shrink < total_removed)
-            {
-              ++new_sizes[i];
-              --total_removed;
-              break;
-            }
-        }
-    }
-
-  xfree (min_sizes);
-
-  return new_sizes;
-}
-
-/* Set WINDOW's height or width to SIZE.  WIDTH_P non-zero means set
-   WINDOW's width.  Resize WINDOW's children, if any, so that they keep
-   their proportionate size relative to WINDOW.
-
-   If FIRST_ONLY is 1, change only the first of WINDOW's children when
-   they are in series.  If LAST_ONLY is 1, change only the last of
-   WINDOW's children when they are in series.
-
-   Propagate WINDOW's top or left edge position to children.  Delete
-   windows that become too small unless NODELETE_P is 1.  When
-   NODELETE_P equals 2 do not honor settings for window-min-height and
-   window-min-width when resizing windows but use safe defaults instead.
-   This should give better behavior when resizing frames.  */
-
-static void
-size_window (Lisp_Object window, int size, int width_p, int nodelete_p, int first_only, int last_only)
-{
-  struct window *w = XWINDOW (window);
-  struct window *c;
-  Lisp_Object child, *forward, *sideward;
-  int old_size = WINDOW_TOTAL_SIZE (w, width_p);
-
-  size = max (0, size);
-
-  /* Delete WINDOW if it's too small.  */
-  if (nodelete_p != 1 && !NILP (w->parent)
-      && size < window_min_size_1 (w, width_p, nodelete_p == 2))
-    {
-      delete_window (window);
-      return;
-    }
-
-  /* Set redisplay hints.  */
-  w->last_modified = make_number (0);
-  w->last_overlay_modified = make_number (0);
-  windows_or_buffers_changed++;
-  FRAME_WINDOW_SIZES_CHANGED (XFRAME (w->frame)) = 1;
-
-  if (width_p)
-    {
-      sideward = &w->vchild;
-      forward = &w->hchild;
-      w->total_cols = make_number (size);
-      adjust_window_margins (w);
-    }
-  else
-    {
-      sideward = &w->hchild;
-      forward = &w->vchild;
-      w->total_lines = make_number (size);
-      w->orig_total_lines = Qnil;
-    }
-
-  if (!NILP (*sideward))
-    {
-      /* We have a chain of parallel siblings whose size should all change.  */
-      for (child = *sideward; !NILP (child); child = c->next)
-       {
-         c = XWINDOW (child);
-         if (width_p)
-           c->left_col = w->left_col;
-         else
-           c->top_line = w->top_line;
-         size_window (child, size, width_p, nodelete_p,
-                      first_only, last_only);
-       }
-    }
-  else if (!NILP (*forward) && last_only)
-    {
-      /* Change the last in a series of siblings.  */
-      Lisp_Object last_child;
-      int child_size;
-
-      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,
-                  width_p, nodelete_p, first_only, last_only);
-    }
-  else if (!NILP (*forward) && first_only)
-    {
-      /* Change the first in a series of siblings.  */
-      int child_size;
-
-      child = *forward;
-      c = XWINDOW (child);
-
-      if (width_p)
-       c->left_col = w->left_col;
-      else
-       c->top_line = w->top_line;
-
-      child_size = WINDOW_TOTAL_SIZE (c, width_p);
-      size_window (child, size - old_size + child_size,
-                  width_p, nodelete_p, first_only, last_only);
-    }
-  else if (!NILP (*forward))
-    {
-      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;
-
-      /* Determine the fixed-size portion of this window, and the
-        number of child windows.  */
-      fixed_size = nchildren = nfixed = total = 0;
-      for (child = *forward; !NILP (child); child = c->next, ++nchildren)
-       {
-         int child_size;
-
-         c = XWINDOW (child);
-         child_size = WINDOW_TOTAL_SIZE (c, width_p);
-         total += child_size;
-
-         if (window_fixed_size_p (c, width_p, 0))
-           {
-             fixed_size += child_size;
-             ++nfixed;
-           }
-       }
-
-      /* If the new size is smaller than fixed_size, or if there
-        aren't any resizable windows, allow resizing fixed-size
-        windows.  */
-      resize_fixed_p = nfixed == nchildren || size < fixed_size;
-
-      /* Compute how many lines/columns to add/remove to each child.  The
-        value of extra takes care of rounding errors.  */
-      n = resize_fixed_p ? nchildren : nchildren - nfixed;
-      if (size < total && n > 1)
-        new_sizes = shrink_windows (total, size, nchildren, n,
-                                    resize_fixed_p, *forward, width_p,
-                                   nodelete_p == 2);
-      else
-        {
-          each = (size - total) / n;
-          extra = (size - total) - n * each;
-        }
-
-      /* Compute new children heights and edge positions.  */
-      first_pos = width_p ? XINT (w->left_col) : XINT (w->top_line);
-      last_pos = first_pos;
-      for (n = 0, child = *forward; !NILP (child); child = c->next, ++n)
-       {
-         int new_child_size, old_child_size;
-
-         c = XWINDOW (child);
-         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.  */
-         if (width_p)
-           c->left_col = make_number (last_pos);
-         else
-           c->top_line = make_number (last_pos);
-
-         /* If this child can be resized, do it.  */
-         if (resize_fixed_p || !window_fixed_size_p (c, width_p, 0))
-           {
-             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_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_child_size;
-       }
-
-      xfree (new_sizes);
-
-      /* We should have covered the parent exactly with child windows.  */
-      xassert (size == last_pos - first_pos);
-
-      /* Now delete any children that became too small.  */
-      if (nodelete_p != 1)
-       for (child = *forward; !NILP (child); child = c->next)
-         {
-           int child_size;
-
-           c = XWINDOW (child);
-           child_size = WINDOW_TOTAL_SIZE (c, width_p);
-           size_window (child, child_size, width_p, nodelete_p,
-                        first_only, last_only);
-         }
-    }
-}
-
-/* Set WINDOW's height to HEIGHT, and recursively change the height of
-   WINDOW's children.  NODELETE zero means windows that have become
-   smaller than window-min-height in the process may be deleted.
-   NODELETE 1 means never delete windows that become too small in the
-   process.  (The caller should check later and do so if appropriate.)
-   NODELETE 2 means delete only windows that have become too small to be
-   displayed correctly.  */
-
-void
-set_window_height (Lisp_Object window, int height, int nodelete)
-{
-  size_window (window, height, 0, nodelete, 0, 0);
-}
-
-/* Set WINDOW's width to WIDTH, and recursively change the width of
-   WINDOW's children.  NODELETE zero means windows that have become
-   smaller than window-min-width in the process may be deleted.
-   NODELETE 1 means never delete windows that become too small in the
-   process.  (The caller should check later and do so if appropriate.)
-   NODELETE 2 means delete only windows that have become too small to be
-   displayed correctly.  */
-
-void
-set_window_width (Lisp_Object window, int width, int nodelete)
-{
-  size_window (window, width, 1, nodelete, 0, 0);
-}
-
-/* Change window heights in windows rooted in WINDOW by N lines.  */
-
-void
-change_window_heights (Lisp_Object window, int n)
-{
-  struct window *w = XWINDOW (window);
-
-  XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n);
-  XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n);
-
-  if (INTEGERP (w->orig_top_line))
-    XSETFASTINT (w->orig_top_line, XFASTINT (w->orig_top_line) + n);
-  if (INTEGERP (w->orig_total_lines))
-    XSETFASTINT (w->orig_total_lines, XFASTINT (w->orig_total_lines) - n);
-
-  /* Handle just the top child in a vertical split.  */
-  if (!NILP (w->vchild))
-    change_window_heights (w->vchild, n);
-
-  /* Adjust all children in a horizontal split.  */
-  for (window = w->hchild; !NILP (window); window = w->next)
-    {
-      w = XWINDOW (window);
-      change_window_heights (window, n);
-    }
-}
-
 \f
-int window_select_count;
-
 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);
@@ -3981,6 +2898,8 @@ 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);
 
+/* The following three routines are needed for running a window's
+   configuration change hook.  */
 static void
 run_funs (Lisp_Object funs)
 {
@@ -3989,8 +2908,19 @@ run_funs (Lisp_Object funs)
       call0 (XCAR (funs));
 }
 
-static Lisp_Object select_window_norecord (Lisp_Object window);
-static Lisp_Object select_frame_norecord (Lisp_Object frame);
+static Lisp_Object
+select_window_norecord (Lisp_Object window)
+{
+  return WINDOW_LIVE_P (window)
+    ? Fselect_window (window, Qt) : selected_window;
+}
+
+static Lisp_Object
+select_frame_norecord (Lisp_Object frame)
+{
+  return FRAME_LIVE_P (XFRAME (frame))
+    ? Fselect_frame (frame, Qt) : selected_frame;
+}
 
 void
 run_window_configuration_change_hook (struct frame *f)
@@ -4026,12 +2956,12 @@ run_window_configuration_change_hook (struct frame *f)
        if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook,
                                      buffer)))
          {
-           int count = SPECPDL_INDEX ();
+           int inner_count = 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 (inner_count, Qnil);
          }
       }
   }
@@ -4153,25 +3083,15 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int
   unbind_to (count, Qnil);
 }
 
-DEFUN ("set-window-clone-number", Fset_window_clone_number, Sset_window_clone_number, 2, 2, 0,
-       doc: /* Set WINDOW's clone number to CLONE-NUMBER.
-WINDOW can be any window and defaults to the selected one.  */)
-     (Lisp_Object window, Lisp_Object clone_number)
-{
-  register struct window *w = decode_any_window (window);
-
-  CHECK_NUMBER (clone_number);
-  w->clone_number = clone_number;
-  return w->clone_number;
-}
-
 DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0,
        doc: /* Make WINDOW display BUFFER-OR-NAME as its contents.
-WINDOW defaults to the selected window.  BUFFER-OR-NAME must be a buffer
-or the name of an existing buffer.  Optional third argument KEEP-MARGINS
-non-nil means that WINDOW's current display margins, fringe widths, and
-scroll bar settings are preserved; the default is to reset these from
-the local settings for BUFFER-OR-NAME or the frame defaults.  Return nil.
+WINDOW has to be a live window and defaults to the selected one.
+BUFFER-OR-NAME must be a buffer or the name of an existing buffer.
+
+Optional third argument KEEP-MARGINS non-nil means that WINDOW's current
+display margins, fringe widths, and scroll bar settings are preserved;
+the default is to reset these from the local settings for BUFFER-OR-NAME
+or the frame defaults.  Return nil.
 
 This function throws an error when WINDOW is strongly dedicated to its
 buffer (that is `window-dedicated-p' returns t for WINDOW) and does not
@@ -4196,32 +3116,26 @@ This function runs `window-scroll-functions' before running
   else if (!EQ (tem, Qt))
     /* w->buffer is t when the window is first being set up.  */
     {
-      if (EQ (tem, buffer))
-       return Qnil;
-      else if (EQ (w->dedicated, Qt))
-       error ("Window is dedicated to `%s'", SDATA (BVAR (XBUFFER (tem), name)));
-      else
-       w->dedicated = Qnil;
+      if (!EQ (tem, buffer))
+       {
+         if (EQ (w->dedicated, Qt))
+           /* WINDOW is strongly dedicated to its buffer, signal an
+              error.  */
+           error ("Window is dedicated to `%s'", SDATA (BVAR (XBUFFER (tem), name)));
+         else
+           /* WINDOW is weakly dedicated to its buffer, reset
+              dedicatedness.  */
+           w->dedicated = Qnil;
+
+         call1 (Qrecord_window_buffer, window);
+       }
 
       unshow_buffer (w);
     }
 
   set_window_buffer (window, buffer, 1, !NILP (keep_margins));
-  return Qnil;
-}
-
-static Lisp_Object
-select_window_norecord (Lisp_Object window)
-{
-  return WINDOW_LIVE_P (window)
-    ? Fselect_window (window, Qt) : selected_window;
-}
 
-static Lisp_Object
-select_frame_norecord (Lisp_Object frame)
-{
-  return FRAME_LIVE_P (XFRAME (frame))
-    ? Fselect_frame (frame, Qt) : selected_frame;
+  return Qnil;
 }
 \f
 static Lisp_Object
@@ -4294,7 +3208,10 @@ temp_output_buffer_show (register Lisp_Object buf)
     call1 (Vtemp_buffer_show_function, buf);
   else
     {
-      window = display_buffer (buf, Qnil, Qnil);
+      window = display_buffer (buf, Vtemp_buffer_show_specifiers, Qnil);
+      /* Reset Vtemp_buffer_show_specifiers immediately so it won't
+        affect subsequent calls.  */
+      Vtemp_buffer_show_specifiers = Qnil;
 
       if (!EQ (XWINDOW (window)->frame, selected_frame))
        Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window)));
@@ -4337,43 +3254,6 @@ DEFUN ("internal-temp-output-buffer-show",
   return Qnil;
 }
 \f
-static void
-make_dummy_parent (Lisp_Object window)
-{
-  Lisp_Object new;
-  register struct window *o, *p;
-  int i;
-
-  o = XWINDOW (window);
-  p = allocate_window ();
-  for (i = 0; i < VECSIZE (struct window); ++i)
-    ((struct Lisp_Vector *) p)->contents[i]
-      = ((struct Lisp_Vector *)o)->contents[i];
-  XSETWINDOW (new, p);
-
-  ++sequence_number;
-  XSETFASTINT (p->sequence_number, sequence_number);
-  XSETFASTINT (p->clone_number, sequence_number);
-
-  /* Put new into window structure in place of window */
-  replace_window (window, new, 1);
-
-  o->next = Qnil;
-  o->prev = Qnil;
-  o->vchild = Qnil;
-  o->hchild = Qnil;
-  o->parent = new;
-
-  p->start = Qnil;
-  p->pointm = Qnil;
-  p->buffer = Qnil;
-
-  p->splits = Qnil;
-  p->nest = Qnil;
-  p->window_parameters = Qnil;
-
-}
-
 /* Make new window, have it replace WINDOW in window-tree, and make
    WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only
    horizontal child).   */
@@ -4393,7 +3273,6 @@ make_parent_window (Lisp_Object window, int horflag)
 
   ++sequence_number;
   XSETFASTINT (p->sequence_number, sequence_number);
-  XSETFASTINT (p->clone_number, sequence_number);
 
   replace_window (window, parent, 1);
 
@@ -4439,7 +3318,6 @@ make_window (void)
   XSETFASTINT (w->use_time, 0);
   ++sequence_number;
   XSETFASTINT (w->sequence_number, sequence_number);
-  XSETFASTINT (w->clone_number, sequence_number);
   w->temslot = w->last_modified = w->last_overlay_modified = Qnil;
   XSETFASTINT (w->last_point, 0);
   w->last_had_star = w->vertical_scroll_bar = Qnil;
@@ -4470,7 +3348,6 @@ make_window (void)
   w->pseudo_window_p = 0;
   w->frozen_window_start_p = 0;
   w->vscroll = 0;
-  w->resize_proportionally = Qnil;
   /* Reset window_list.  */
   Vwindow_list = Qnil;
   /* Return window.  */
@@ -4519,8 +3396,8 @@ Note: This function does not operate on any subwindows of WINDOW.  */)
    Note: This function does not check any of `window-fixed-size-p',
    `window-min-height' or `window-min-width'.  It does check that window
    sizes do not drop below one line (two columns). */
-int
-resize_window_check (struct window *w, int horflag)
+static int
+window_resize_check (struct window *w, int horflag)
 {
   struct window *c;
 
@@ -4534,7 +3411,7 @@ resize_window_check (struct window *w, int horflag)
          while (c)
            {
              if ((XINT (c->new_total) != XINT (w->new_total))
-                 || !resize_window_check (c, horflag))
+                 || !window_resize_check (c, horflag))
                return 0;
              c = NILP (c->next) ? 0 : XWINDOW (c->next);
            }
@@ -4547,7 +3424,7 @@ resize_window_check (struct window *w, int horflag)
          int sum_of_sizes = 0;
          while (c)
            {
-             if (!resize_window_check (c, horflag))
+             if (!window_resize_check (c, horflag))
                return 0;
              sum_of_sizes = sum_of_sizes + XINT (c->new_total);
              c = NILP (c->next) ? 0 : XWINDOW (c->next);
@@ -4566,7 +3443,7 @@ resize_window_check (struct window *w, int horflag)
          int sum_of_sizes = 0;
          while (c)
            {
-             if (!resize_window_check (c, horflag))
+             if (!window_resize_check (c, horflag))
                return 0;
              sum_of_sizes = sum_of_sizes + XINT (c->new_total);
              c = NILP (c->next) ? 0 : XWINDOW (c->next);
@@ -4579,7 +3456,7 @@ resize_window_check (struct window *w, int horflag)
          while (c)
            {
              if ((XINT (c->new_total) != XINT (w->new_total))
-                 || !resize_window_check (c, horflag))
+                 || !window_resize_check (c, horflag))
                return 0;
              c = NILP (c->next) ? 0 : XWINDOW (c->next);
            }
@@ -4599,11 +3476,11 @@ resize_window_check (struct window *w, int horflag)
    each of these windows.
 
    This function does not perform any error checks.  Make sure you have
-   run resize_window_check on W before applying this function.  */
-void
-resize_window_apply (struct window *w, int horflag)
+   run window_resize_check on W before applying this function.  */
+static void
+window_resize_apply (struct window *w, int horflag)
 {
-  struct window *c, *p;
+  struct window *c;
   int pos;
 
   /* Note: Assigning new_normal requires that the new total size of the
@@ -4635,7 +3512,7 @@ resize_window_apply (struct window *w, int horflag)
            XSETFASTINT (c->left_col, pos);
          else
            XSETFASTINT (c->top_line, pos);
-         resize_window_apply (c, horflag);
+         window_resize_apply (c, horflag);
          if (!horflag)
            pos = pos + XINT (c->total_lines);
          c = NILP (c->next) ? 0 : XWINDOW (c->next);
@@ -4651,7 +3528,7 @@ resize_window_apply (struct window *w, int horflag)
            XSETFASTINT (c->left_col, pos);
          else
            XSETFASTINT (c->top_line, pos);
-         resize_window_apply (c, horflag);
+         window_resize_apply (c, horflag);
          if (horflag)
            pos = pos + XINT (c->total_cols);
          c = NILP (c->next) ? 0 : XWINDOW (c->next);
@@ -4664,7 +3541,7 @@ resize_window_apply (struct window *w, int horflag)
 }
 
 
-DEFUN ("resize-window-apply", Fresize_window_apply, Sresize_window_apply, 1, 2, 0,
+DEFUN ("window-resize-apply", Fwindow_resize_apply, Swindow_resize_apply, 1, 2, 0,
        doc: /* Apply requested size values for window-tree of FRAME.
 Optional argument HORIZONTAL omitted or nil means apply requested height
 values.  HORIZONTAL non-nil means apply requested width values.
@@ -4689,12 +3566,12 @@ be applied on the Elisp level.  */)
   f = XFRAME (frame);
   r = XWINDOW (FRAME_ROOT_WINDOW (f));
 
-  if (!resize_window_check (r, horflag)
+  if (!window_resize_check (r, horflag)
       || ! EQ (r->new_total, (horflag ? r->total_cols : r->total_lines)))
     return Qnil;
 
   BLOCK_INPUT;
-  resize_window_apply (r, horflag);
+  window_resize_apply (r, horflag);
 
   windows_or_buffers_changed++;
   FRAME_WINDOW_SIZES_CHANGED (f) = 1;
@@ -4746,22 +3623,22 @@ resize_frame_windows (struct frame *f, int size, int horflag)
       XSETINT (delta, new_size - old_size);
       /* Try a "normal" resize first.  */
       resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil);
-      if (resize_window_check (r, horflag) && new_size == XINT (r->new_total))
-       resize_window_apply (r, horflag);
+      if (window_resize_check (r, horflag) && new_size == XINT (r->new_total))
+       window_resize_apply (r, horflag);
       else
        {
          /* Try with "reasonable" minimum sizes next.  */
          resize_root_window (root, delta, horflag ? Qt : Qnil, Qt);
-         if (resize_window_check (r, horflag)
+         if (window_resize_check (r, horflag)
              && new_size == XINT (r->new_total))
-           resize_window_apply (r, horflag);
+           window_resize_apply (r, horflag);
          else
            {
              /* Finally, try with "safe" minimum sizes.  */
              resize_root_window (root, delta, horflag ? Qt : Qnil, Qsafe);
-             if (resize_window_check (r, horflag)
+             if (window_resize_check (r, horflag)
                  && new_size == XINT (r->new_total))
-               resize_window_apply (r, horflag);
+               window_resize_apply (r, horflag);
              else
                {
                  /* We lost.  Delete all windows but the frame's
@@ -4795,7 +3672,7 @@ resize_frame_windows (struct frame *f, int size, int horflag)
 DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0,
        doc: /* Split window OLD.
 Second argument TOTAL-SIZE specifies the number of lines or columns of the
-new window.  In any case TOTAL-SIZE must be a positive integer 
+new window.  In any case TOTAL-SIZE must be a positive integer.
 
 Third argument SIDE nil (or `below') specifies that the new window shall
 be located below WINDOW.  SIDE `above' means the new window shall be
@@ -4870,7 +3747,7 @@ set correctly.  See the code of `split-window' for how this is done.  */)
       XSETINT (p->new_total,
               XINT (horflag ? p->total_cols : p->total_lines)
               - XINT (total_size));
-      if (!resize_window_check (p, horflag))
+      if (!window_resize_check (p, horflag))
        error ("Window sizes don't fit");
       else
        /* Undo the temporary pretension.  */
@@ -4878,7 +3755,7 @@ set correctly.  See the code of `split-window' for how this is done.  */)
     }
   else
     {
-      if (!resize_window_check (o, horflag))
+      if (!window_resize_check (o, horflag))
        error ("Resizing old window failed");
       else if (XINT (total_size) + XINT (o->new_total)
               != XINT (horflag ? o->total_cols : o->total_lines))
@@ -4966,13 +3843,13 @@ set correctly.  See the code of `split-window' for how this is done.  */)
       n->total_cols = o->total_cols;
     }
 
-  /* Iso-coordinates and sizes are assigned by resize_window_apply,
+  /* Iso-coordinates and sizes are assigned by window_resize_apply,
      get them ready here.  */
   n->new_total = total_size;
   n->new_normal = normal_size;
 
   BLOCK_INPUT;
-  resize_window_apply (p, horflag);
+  window_resize_apply (p, horflag);
   adjust_glyphs (f);
   /* Set buffer of NEW to buffer of reference window.  Don't run
      any hooks.  */
@@ -5050,13 +3927,13 @@ when WINDOW is the only window on its frame.  */)
        XWINDOW (s->next)->prev = sibling;
     }
 
-  if (resize_window_check (r, horflag)
+  if (window_resize_check (r, horflag)
       && EQ (r->new_total, (horflag ? r->total_cols : r->total_lines)))
     /* We can delete WINDOW now.  */
     {
       /* Block input.  */
       BLOCK_INPUT;
-      resize_window_apply (p, horflag);
+      window_resize_apply (p, horflag);
 
       windows_or_buffers_changed++;
       Vwindow_list = Qnil;
@@ -5114,958 +3991,168 @@ when WINDOW is the only window on its frame.  */)
          - promote the first window _without recording it_ first.  */
          if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
            Fselect_window (new_selected_window, Qt);
-         else
-           FRAME_SELECTED_WINDOW (f) = new_selected_window;
-
-         UNBLOCK_INPUT;
-
-         /* Now look whether `get-mru-window' gets us something.  */
-         mru_window = call1 (Qget_mru_window, frame);
-         if (WINDOW_LIVE_P (mru_window)
-             && EQ (XWINDOW (mru_window)->frame, frame))
-           new_selected_window = mru_window;
-
-         /* If all ended up well, we now promote the mru window.  */
-         if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
-           Fselect_window (new_selected_window, Qnil);
-         else
-           FRAME_SELECTED_WINDOW (f) = new_selected_window;
-       }
-      else
-       UNBLOCK_INPUT;
-
-      /* Must be run by the caller:
-        run_window_configuration_change_hook (f);  */
-    }
-  else
-    /* We failed: Relink WINDOW into window tree.  */
-    {
-      if (before_sibling)
-       {
-         s->prev = window;
-         if (horflag)
-           p->hchild = window;
-         else
-           p->vchild = window;
-       }
-      else
-       {
-         s->next = window;
-         if (!NILP (w->next))
-           XWINDOW (w->next)->prev = window;
-       }
-      error ("Deletion failed");
-    }
-
-  return Qnil;
-}
-
-DEFUN ("split-window", Fsplit_window, Ssplit_window, 0, 3, "",
-       doc: /* Split WINDOW, putting SIZE lines in the first of the pair.
-WINDOW defaults to selected one and SIZE to half its size.
-If optional third arg HORIZONTAL is non-nil, split side by side and put
-SIZE columns in the first of the pair.  In that case, SIZE includes that
-window's scroll bar, or the divider column to its right.
-Interactively, all arguments are nil.
-Returns the newly created window (which is the lower or rightmost one).
-The upper or leftmost window is the original one, and remains selected
-if it was selected before.
-
-See Info node `(elisp)Splitting Windows' for more details and examples.  */)
-  (Lisp_Object window, Lisp_Object size, Lisp_Object horizontal)
-{
-  register Lisp_Object new;
-  register struct window *o, *p;
-  FRAME_PTR fo;
-  register int size_int;
-
-  if (NILP (window))
-    window = selected_window;
-  else
-    CHECK_LIVE_WINDOW (window);
-
-  o = XWINDOW (window);
-  fo = XFRAME (WINDOW_FRAME (o));
-
-  if (NILP (size))
-    {
-      if (!NILP (horizontal))
-       /* Calculate the size of the left-hand window, by dividing
-          the usable space in columns by two.
-          We round up, since the left-hand window may include
-          a dividing line, while the right-hand may not.  */
-       size_int = (XFASTINT (o->total_cols) + 1) >> 1;
-      else
-       size_int = XFASTINT (o->total_lines) >> 1;
-    }
-  else
-    {
-      CHECK_NUMBER (size);
-      size_int = XINT (size);
-    }
-
-  if (MINI_WINDOW_P (o))
-    error ("Attempt to split minibuffer window");
-  else if (window_fixed_size_p (o, !NILP (horizontal), 0))
-    error ("Attempt to split fixed-size window");
-
-  if (NILP (horizontal))
-    {
-      int window_safe_height = window_min_size_2 (o, 0, 0);
-
-      if (size_int < window_safe_height)
-       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)",
-              (int) (XFASTINT (o->total_lines) - size_int));
-      if (NILP (o->parent)
-         || NILP (XWINDOW (o->parent)->vchild))
-       {
-         make_dummy_parent (window);
-         new = o->parent;
-         XWINDOW (new)->vchild = window;
-       }
-    }
-  else
-    {
-      int window_safe_width = window_min_size_2 (o, 1, 0);
-
-      if (size_int < window_safe_width)
-       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)",
-              (int) (XFASTINT (o->total_cols) - size_int));
-      if (NILP (o->parent)
-         || NILP (XWINDOW (o->parent)->hchild))
-       {
-         make_dummy_parent (window);
-         new = o->parent;
-         XWINDOW (new)->hchild = window;
-       }
-    }
-
-  /* Now we know that window's parent is a vertical combination
-     if we are dividing vertically, or a horizontal combination
-     if we are making side-by-side windows */
-
-  windows_or_buffers_changed++;
-  FRAME_WINDOW_SIZES_CHANGED (fo) = 1;
-  new = make_window ();
-  p = XWINDOW (new);
-
-  p->frame = o->frame;
-  p->next = o->next;
-  if (!NILP (p->next))
-    XWINDOW (p->next)->prev = new;
-  p->prev = window;
-  o->next = new;
-  p->parent = o->parent;
-  p->buffer = Qt;
-  p->window_end_valid = Qnil;
-  memset (&p->last_cursor, 0, sizeof p->last_cursor);
-
-  /* Duplicate special geometry settings.  */
-
-  p->left_margin_cols = o->left_margin_cols;
-  p->right_margin_cols = o->right_margin_cols;
-  p->left_fringe_width = o->left_fringe_width;
-  p->right_fringe_width = o->right_fringe_width;
-  p->fringes_outside_margins = o->fringes_outside_margins;
-  p->scroll_bar_width = o->scroll_bar_width;
-  p->vertical_scroll_bar_type = o->vertical_scroll_bar_type;
-
-  /* Apportion the available frame space among the two new windows */
-
-  if (!NILP (horizontal))
-    {
-      p->total_lines = o->total_lines;
-      p->top_line = o->top_line;
-      XSETFASTINT (p->total_cols, XFASTINT (o->total_cols) - size_int);
-      XSETFASTINT (o->total_cols, size_int);
-      XSETFASTINT (p->left_col, XFASTINT (o->left_col) + size_int);
-      adjust_window_margins (p);
-      adjust_window_margins (o);
-    }
-  else
-    {
-      p->left_col = o->left_col;
-      p->total_cols = o->total_cols;
-      XSETFASTINT (p->total_lines, XFASTINT (o->total_lines) - size_int);
-      XSETFASTINT (o->total_lines, size_int);
-      XSETFASTINT (p->top_line, XFASTINT (o->top_line) + size_int);
-    }
-
-  /* Adjust glyph matrices.  */
-  adjust_glyphs (fo);
-
-  Fset_window_buffer (new, o->buffer, Qt);
-  return new;
-}
-
-DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini_window_internal, 1, 1, 0,
-       doc: /* Resize minibuffer window WINDOW.  */)
-     (Lisp_Object window)
-{
-  struct window *w = XWINDOW (window);
-  struct window *r;
-  struct frame *f;
-  int height;
-
-  CHECK_WINDOW (window);
-  f = XFRAME (w->frame);
-
-  if (!EQ (FRAME_MINIBUF_WINDOW (XFRAME (w->frame)), window))
-    error ("Not a valid minibuffer window");
-  else if (FRAME_MINIBUF_ONLY_P (f))
-    error ("Cannot resize a minibuffer-only frame");
-
-  r = XWINDOW (FRAME_ROOT_WINDOW (f));
-  height = XINT (r->total_lines) + XINT (w->total_lines);
-  if (resize_window_check (r, 0)
-      && XINT (w->new_total) > 0
-      && height == XINT (r->new_total) + XINT (w->new_total))
-    {
-      BLOCK_INPUT;
-      resize_window_apply (r, 0);
-
-      w->total_lines = w->new_total;
-      XSETFASTINT (w->top_line, XINT (r->top_line) + XINT (r->total_lines));
-
-      windows_or_buffers_changed++;
-      FRAME_WINDOW_SIZES_CHANGED (f) = 1;
-      adjust_glyphs (f);
-      UNBLOCK_INPUT;
-
-      run_window_configuration_change_hook (f);
-      return Qt;
-    }
-  else error ("Failed to resize minibuffer window");
-}
-\f
-DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 2, "p",
-       doc: /* Make selected window SIZE lines taller.
-Interactively, if no argument is given, make the selected window one
-line taller.  If optional argument HORIZONTAL is non-nil, make selected
-window wider by SIZE columns.  If SIZE is negative, shrink the window by
--SIZE lines or columns.  Return nil.
-
-This function can delete windows if they get too small.  The size of
-fixed size windows is not altered by this function.  */)
-  (Lisp_Object size, Lisp_Object horizontal)
-{
-  CHECK_NUMBER (size);
-  enlarge_window (selected_window, XINT (size), !NILP (horizontal));
-
-  run_window_configuration_change_hook (SELECTED_FRAME ());
-
-  return Qnil;
-}
-
-DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 2, "p",
-       doc: /* Make selected window SIZE lines smaller.
-Interactively, if no argument is given, make the selected window one
-line smaller.  If optional argument HORIZONTAL is non-nil, make the
-window narrower by SIZE columns.  If SIZE is negative, enlarge selected
-window by -SIZE lines or columns.  Return nil.
-
-This function can delete windows if they get too small.  The size of
-fixed size windows is not altered by this function. */)
-  (Lisp_Object size, Lisp_Object horizontal)
-{
-  CHECK_NUMBER (size);
-  enlarge_window (selected_window, -XINT (size), !NILP (horizontal));
-
-  run_window_configuration_change_hook (SELECTED_FRAME ());
-
-  return Qnil;
-}
-
-static int
-window_height (Lisp_Object window)
-{
-  register struct window *p = XWINDOW (window);
-  return WINDOW_TOTAL_LINES (p);
-}
-
-static int
-window_width (Lisp_Object window)
-{
-  register struct window *p = XWINDOW (window);
-  return WINDOW_TOTAL_COLS (p);
-}
-
-
-#define CURBEG(w) \
-  *(horiz_flag ? &(XWINDOW (w)->left_col) : &(XWINDOW (w)->top_line))
-
-#define CURSIZE(w) \
-  *(horiz_flag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
-
-
-/* Enlarge WINDOW by DELTA.  HORIZ_FLAG nonzero means enlarge it
-   horizontally; zero means do it vertically.
-
-   Siblings of the selected window are resized to fulfill the size
-   request.  If they become too small in the process, they may be
-   deleted.  */
-
-static void
-enlarge_window (Lisp_Object window, int delta, int horiz_flag)
-{
-  Lisp_Object parent, next, prev;
-  struct window *p;
-  Lisp_Object *sizep;
-  int maximum;
-  int (*sizefun) (Lisp_Object)
-    = horiz_flag ? window_width : window_height;
-  void (*setsizefun) (Lisp_Object, int, int)
-    = (horiz_flag ? set_window_width : set_window_height);
-
-  /* Give up if this window cannot be resized.  */
-  if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1))
-    error ("Window is not resizable");
-
-  /* Find the parent of the selected window.  */
-  while (1)
-    {
-      p = XWINDOW (window);
-      parent = p->parent;
-
-      if (NILP (parent))
-       {
-         if (horiz_flag)
-           error ("No other window to side of this one");
-         break;
-       }
-
-      if (horiz_flag
-         ? !NILP (XWINDOW (parent)->hchild)
-         : !NILP (XWINDOW (parent)->vchild))
-       break;
-
-      window = parent;
-    }
-
-  sizep = &CURSIZE (window);
-
-  {
-    register int maxdelta;
-
-    /* Compute the maximum size increment this window can have.  */
-
-    maxdelta = (!NILP (parent) ? (*sizefun) (parent) - XINT (*sizep)
-               /* This is a main window followed by a minibuffer.  */
-               : !NILP (p->next) ? ((*sizefun) (p->next)
-                                    - window_min_size (XWINDOW (p->next),
-                                                       horiz_flag, 0, 0, 0))
-               /* This is a minibuffer following a main window.  */
-               : !NILP (p->prev) ? ((*sizefun) (p->prev)
-                                    - window_min_size (XWINDOW (p->prev),
-                                                       horiz_flag, 0, 0, 0))
-               /* This is a frame with only one window, a minibuffer-only
-                  or a minibufferless frame.  */
-               : (delta = 0));
-
-    if (delta > maxdelta)
-      /* This case traps trying to make the minibuffer
-        the full frame, or make the only window aside from the
-        minibuffer the full frame.  */
-      delta = maxdelta;
-  }
-
-  if (XINT (*sizep) + delta < window_min_size (XWINDOW (window),
-                                              horiz_flag, 0, 0, 0))
-    {
-      delete_window (window);
-      return;
-    }
-
-  if (delta == 0)
-    return;
-
-  /* Find the total we can get from other siblings without deleting them.  */
-  maximum = 0;
-  for (next = p->next; WINDOWP (next); next = XWINDOW (next)->next)
-    maximum += (*sizefun) (next) - window_min_size (XWINDOW (next),
-                                                   horiz_flag, 0, 0, 0);
-  for (prev = p->prev; WINDOWP (prev); prev = XWINDOW (prev)->prev)
-    maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev),
-                                                   horiz_flag, 0, 0, 0);
-
-  /* If we can get it all from them without deleting them, do so.  */
-  if (delta <= maximum)
-    {
-      Lisp_Object first_unaffected;
-      Lisp_Object first_affected;
-      int fixed_p;
-
-      next = p->next;
-      prev = p->prev;
-      first_affected = window;
-      /* Look at one sibling at a time,
-        moving away from this window in both directions alternately,
-        and take as much as we can get without deleting that sibling.  */
-      while (delta != 0
-            && (!NILP (next) || !NILP (prev)))
-       {
-         if (! NILP (next))
-           {
-             int this_one = ((*sizefun) (next)
-                             - window_min_size (XWINDOW (next), horiz_flag,
-                                                0, 0, &fixed_p));
-             if (!fixed_p)
-               {
-                 if (this_one > delta)
-                   this_one = delta;
-
-                 (*setsizefun) (next, (*sizefun) (next) - this_one, 0);
-                 (*setsizefun) (window, XINT (*sizep) + this_one, 0);
-
-                 delta -= this_one;
-               }
-
-             next = XWINDOW (next)->next;
-           }
-
-         if (delta == 0)
-           break;
-
-         if (! NILP (prev))
-           {
-             int this_one = ((*sizefun) (prev)
-                             - window_min_size (XWINDOW (prev), horiz_flag,
-                                                0, 0, &fixed_p));
-             if (!fixed_p)
-               {
-                 if (this_one > delta)
-                   this_one = delta;
-
-                 first_affected = prev;
-
-                 (*setsizefun) (prev, (*sizefun) (prev) - this_one, 0);
-                 (*setsizefun) (window, XINT (*sizep) + this_one, 0);
-
-                 delta -= this_one;
-               }
-
-             prev = XWINDOW (prev)->prev;
-           }
-       }
-
-      xassert (delta == 0);
-
-      /* Now recalculate the edge positions of all the windows affected,
-        based on the new sizes.  */
-      first_unaffected = next;
-      prev = first_affected;
-      for (next = XWINDOW (prev)->next; ! EQ (next, first_unaffected);
-          prev = next, next = XWINDOW (next)->next)
-       {
-         XSETINT (CURBEG (next), XINT (CURBEG (prev)) + (*sizefun) (prev));
-         /* This does not change size of NEXT,
-            but it propagates the new top edge to its children */
-         (*setsizefun) (next, (*sizefun) (next), 0);
-       }
-    }
-  else
-    {
-      register int delta1;
-      register int opht = (*sizefun) (parent);
-
-      if (opht <= XINT (*sizep) + delta)
-       {
-         /* If trying to grow this window to or beyond size of the parent,
-            just delete all the sibling windows.  */
-         Lisp_Object start, tem;
-
-         start = XWINDOW (parent)->vchild;
-         if (NILP (start))
-           start = XWINDOW (parent)->hchild;
-
-         /* Delete any siblings that come after WINDOW.  */
-         tem = XWINDOW (window)->next;
-         while (! NILP (tem))
-           {
-             Lisp_Object next1 = XWINDOW (tem)->next;
-             delete_window (tem);
-             tem = next1;
-           }
-
-         /* Delete any siblings that come after WINDOW.
-            Note that if START is not WINDOW, then WINDOW still
-            has siblings, so WINDOW has not yet replaced its parent.  */
-         tem = start;
-         while (! EQ (tem, window))
-           {
-             Lisp_Object next1 = XWINDOW (tem)->next;
-             delete_window (tem);
-             tem = next1;
-           }
-       }
-      else
-       {
-         /* Otherwise, make delta1 just right so that if we add
-            delta1 lines to this window and to the parent, and then
-            shrink the parent back to its original size, the new
-            proportional size of this window will increase by delta.
-
-            The function size_window will compute the new height h'
-            of the window from delta1 as:
-
-            e = delta1/n
-            x = delta1 - delta1/n * n for the 1st resizable child
-            h' = h + e + x
-
-            where n is the number of children that can be resized.
-            We can ignore x by choosing a delta1 that is a multiple of
-            n.  We want the height of this window to come out as
-
-            h' = h + delta
-
-            So, delta1 must be
-
-            h + e = h + delta
-            delta1/n = delta
-            delta1 = n * delta.
-
-            The number of children n equals the number of resizable
-            children of this window + 1 because we know window itself
-            is resizable (otherwise we would have signaled an error).
-
-            This reasoning is not correct when other windows become too
-            small and shrink_windows refuses to delete them.  Below we
-            use resize_proportionally to work around this problem.  */
-
-         struct window *w = XWINDOW (window);
-         Lisp_Object s;
-         int n = 1;
-
-         for (s = w->next; WINDOWP (s); s = XWINDOW (s)->next)
-           if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
-             ++n;
-         for (s = w->prev; WINDOWP (s); s = XWINDOW (s)->prev)
-           if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
-             ++n;
-
-         delta1 = n * delta;
-
-         /* Add delta1 lines or columns to this window, and to the parent,
-            keeping things consistent while not affecting siblings.  */
-         XSETINT (CURSIZE (parent), opht + delta1);
-         (*setsizefun) (window, XINT (*sizep) + delta1, 0);
-
-         /* Squeeze out delta1 lines or columns from our parent,
-            shrinking this window and siblings proportionately.  This
-            brings parent back to correct size.  Delta1 was calculated
-            so this makes this window the desired size, taking it all
-            out of the siblings.
-
-            Temporarily set resize_proportionally to Qt to assure that,
-            if necessary, shrink_windows deletes smaller windows rather
-            than shrink this window.  */
-         w->resize_proportionally = Qt;
-         (*setsizefun) (parent, opht, 0);
-         w->resize_proportionally = Qnil;
-       }
-    }
-
-  XSETFASTINT (p->last_modified, 0);
-  XSETFASTINT (p->last_overlay_modified, 0);
-
-  /* Adjust glyph matrices. */
-  adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window))));
-}
-
-
-/* Adjust the size of WINDOW by DELTA, moving only its trailing edge.
-   HORIZ_FLAG nonzero means adjust the width, moving the right edge.
-   zero means adjust the height, moving the bottom edge.
-
-   Following siblings of the selected window are resized to fulfill
-   the size request.  If they become too small in the process, they
-   are not deleted; instead, we signal an error.  */
-
-static void
-adjust_window_trailing_edge (Lisp_Object window, int delta, int horiz_flag)
-{
-  Lisp_Object parent, child;
-  struct window *p;
-  Lisp_Object old_config = Fcurrent_window_configuration (Qnil);
-  int delcount = window_deletion_count;
-
-  CHECK_WINDOW (window);
-
-  /* Give up if this window cannot be resized.  */
-  if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1))
-    error ("Window is not resizable");
-
-  while (1)
-    {
-      Lisp_Object first_parallel = Qnil;
-
-      if (NILP (window))
-       {
-         /* This happens if WINDOW on the previous iteration was
-            at top level of the window tree.  */
-         Fset_window_configuration (old_config);
-         error ("Specified window edge is fixed");
-       }
-
-      p = XWINDOW (window);
-      parent = p->parent;
-
-      /* See if this level has windows in parallel in the specified
-        direction.  If so, set FIRST_PARALLEL to the first one.  */
-      if (horiz_flag)
-       {
-         if (! NILP (parent) && !NILP (XWINDOW (parent)->vchild))
-           first_parallel = XWINDOW (parent)->vchild;
-         else if (NILP (parent) && !NILP (p->next))
-           {
-             /* Handle the vertical chain of main window and minibuffer
-                which has no parent.  */
-             first_parallel = window;
-             while (! NILP (XWINDOW (first_parallel)->prev))
-               first_parallel = XWINDOW (first_parallel)->prev;
-           }
-       }
-      else
-       {
-         if (! NILP (parent) && !NILP (XWINDOW (parent)->hchild))
-           first_parallel = XWINDOW (parent)->hchild;
-       }
-
-      /* If this level's succession is in the desired dimension,
-        and this window is the last one, and there is no higher level,
-        its trailing edge is fixed.  */
-      if (NILP (XWINDOW (window)->next) && NILP (first_parallel)
-         && NILP (parent))
-       {
-         Fset_window_configuration (old_config);
-         error ("Specified window edge is fixed");
-       }
-
-      /* Don't make this window too small.  */
-      if (XINT (CURSIZE (window)) + delta
-         < window_min_size_2 (XWINDOW (window), horiz_flag, 0))
-       {
-         Fset_window_configuration (old_config);
-         error ("Cannot adjust window size as specified");
-       }
-
-      /* Clear out some redisplay caches.  */
-      XSETFASTINT (p->last_modified, 0);
-      XSETFASTINT (p->last_overlay_modified, 0);
-
-      /* Adjust this window's edge.  */
-      XSETINT (CURSIZE (window),
-              XINT (CURSIZE (window)) + delta);
-
-      /* If this window has following siblings in the desired dimension,
-        make them smaller, and exit the loop.
-
-        (If we reach the top of the tree and can never do this,
-        we will fail and report an error, above.)  */
-      if (NILP (first_parallel))
-       {
-         if (!NILP (p->next))
-           {
-              /* This may happen for the minibuffer.  In that case
-                 the window_deletion_count check below does not work.  */
-              if (XINT (CURSIZE (p->next)) - delta <= 0)
-                {
-                  Fset_window_configuration (old_config);
-                  error ("Cannot adjust window size as specified");
-                }
-
-             XSETINT (CURBEG (p->next),
-                      XINT (CURBEG (p->next)) + delta);
-             size_window (p->next, XINT (CURSIZE (p->next)) - delta,
-                          horiz_flag, 0, 1, 0);
-             break;
-           }
-       }
-      else
-       /* Here we have a chain of parallel siblings, in the other dimension.
-          Change the size of the other siblings.  */
-       for (child = first_parallel;
-            ! NILP (child);
-            child = XWINDOW (child)->next)
-         if (! EQ (child, window))
-           size_window (child, XINT (CURSIZE (child)) + delta,
-                        horiz_flag, 0, 0, 1);
-
-      window = parent;
-    }
-
-  /* If we made a window so small it got deleted,
-     we failed.  Report failure.  */
-  if (delcount != window_deletion_count)
-    {
-      Fset_window_configuration (old_config);
-      error ("Cannot adjust window size as specified");
-    }
-
-  /* Adjust glyph matrices. */
-  adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window))));
-}
-
-#undef CURBEG
-#undef CURSIZE
-
-DEFUN ("adjust-window-trailing-edge", Fadjust_window_trailing_edge,
-       Sadjust_window_trailing_edge, 3, 3, 0,
-       doc: /* Adjust the bottom or right edge of WINDOW by DELTA.
-If HORIZONTAL is non-nil, that means adjust the width, moving the right edge.
-Otherwise, adjust the height, moving the bottom edge.
-
-Following siblings of the selected window are resized to fulfill
-the size request.  If they become too small in the process, they
-are not deleted; instead, we signal an error.  */)
-  (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal)
-{
-  CHECK_NUMBER (delta);
-  if (NILP (window))
-    window = selected_window;
-  adjust_window_trailing_edge (window, XINT (delta), !NILP (horizontal));
-
-  run_window_configuration_change_hook
-    (XFRAME (WINDOW_FRAME (XWINDOW (window))));
-
-  return Qnil;
-}
-
-
-\f
-/***********************************************************************
-                       Resizing Mini-Windows
- ***********************************************************************/
-
-static void shrink_window_lowest_first (struct window *, int);
-
-enum save_restore_action
-{
-    CHECK_ORIG_SIZES,
-    SAVE_ORIG_SIZES,
-    RESTORE_ORIG_SIZES
-};
-
-static int save_restore_orig_size (struct window *,
-                                   enum save_restore_action);
-
-/* Shrink windows rooted in window W to HEIGHT.  Take the space needed
-   from lowest windows first.  */
-
-static void
-shrink_window_lowest_first (struct window *w, int height)
-{
-  struct window *c;
-  Lisp_Object child;
-  int old_height;
-
-  xassert (!MINI_WINDOW_P (w));
-
-  /* Set redisplay hints.  */
-  XSETFASTINT (w->last_modified, 0);
-  XSETFASTINT (w->last_overlay_modified, 0);
-  windows_or_buffers_changed++;
-  FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w))) = 1;
-
-  old_height = XFASTINT (w->total_lines);
-  XSETFASTINT (w->total_lines, height);
-
-  if (!NILP (w->hchild))
-    {
-      for (child = w->hchild; !NILP (child); child = c->next)
-       {
-         c = XWINDOW (child);
-         c->top_line = w->top_line;
-         shrink_window_lowest_first (c, height);
-       }
-    }
-  else if (!NILP (w->vchild))
-    {
-      Lisp_Object last_child;
-      int delta = old_height - height;
-      int last_top;
-
-      last_child = Qnil;
-
-      /* Find the last child.  We are taking space from lowest windows
-        first, so we iterate over children from the last child
-        backwards.  */
-      for (child = w->vchild; WINDOWP (child); child = XWINDOW (child)->next)
-       last_child = child;
-
-      /* Size children down to their safe heights.  */
-      for (child = last_child; delta && !NILP (child); child = c->prev)
-       {
-         int this_one;
-
-         c = XWINDOW (child);
-         this_one = XFASTINT (c->total_lines) - window_min_size_1 (c, 0, 1);
-
-         if (this_one > delta)
-           this_one = delta;
-
-         shrink_window_lowest_first (c, XFASTINT (c->total_lines) - this_one);
-         delta -= this_one;
-       }
-
-      /* Compute new positions.  */
-      last_top = XINT (w->top_line);
-      for (child = w->vchild; !NILP (child); child = c->next)
-       {
-         c = XWINDOW (child);
-         c->top_line = make_number (last_top);
-         shrink_window_lowest_first (c, XFASTINT (c->total_lines));
-         last_top += XFASTINT (c->total_lines);
-       }
-    }
-}
-
-
-/* Save, restore, or check positions and sizes in the window tree
-   rooted at W.  ACTION says what to do.
-
-   If ACTION is CHECK_ORIG_SIZES, check if orig_top_line and
-   orig_total_lines members are valid for all windows in the window
-   tree.  Value is non-zero if they are valid.
+         else
+           FRAME_SELECTED_WINDOW (f) = new_selected_window;
 
-   If ACTION is SAVE_ORIG_SIZES, save members top and height in
-   orig_top_line and orig_total_lines for all windows in the tree.
+         UNBLOCK_INPUT;
 
-   If ACTION is RESTORE_ORIG_SIZES, restore top and height from values
-   stored in orig_top_line and orig_total_lines for all windows.  */
+         /* Now look whether `get-mru-window' gets us something.  */
+         mru_window = call1 (Qget_mru_window, frame);
+         if (WINDOW_LIVE_P (mru_window)
+             && EQ (XWINDOW (mru_window)->frame, frame))
+           new_selected_window = mru_window;
 
-static int
-save_restore_orig_size (struct window *w, enum save_restore_action action)
-{
-  int success_p = 1;
+         /* If all ended up well, we now promote the mru window.  */
+         if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
+           Fselect_window (new_selected_window, Qnil);
+         else
+           FRAME_SELECTED_WINDOW (f) = new_selected_window;
+       }
+      else
+       UNBLOCK_INPUT;
 
-  while (w)
+      /* Must be run by the caller:
+        run_window_configuration_change_hook (f);  */
+    }
+  else
+    /* We failed: Relink WINDOW into window tree.  */
     {
-      if (!NILP (w->hchild))
-       {
-         if (!save_restore_orig_size (XWINDOW (w->hchild), action))
-           success_p = 0;
-       }
-      else if (!NILP (w->vchild))
+      if (before_sibling)
        {
-         if (!save_restore_orig_size (XWINDOW (w->vchild), action))
-           success_p = 0;
+         s->prev = window;
+         if (horflag)
+           p->hchild = window;
+         else
+           p->vchild = window;
        }
-
-      switch (action)
+      else
        {
-       case CHECK_ORIG_SIZES:
-         if (!INTEGERP (w->orig_top_line) || !INTEGERP (w->orig_total_lines))
-           return 0;
-         break;
-
-       case SAVE_ORIG_SIZES:
-         w->orig_top_line = w->top_line;
-         w->orig_total_lines = w->total_lines;
-          XSETFASTINT (w->last_modified, 0);
-          XSETFASTINT (w->last_overlay_modified, 0);
-         break;
-
-       case RESTORE_ORIG_SIZES:
-         xassert (INTEGERP (w->orig_top_line) && INTEGERP (w->orig_total_lines));
-         w->top_line = w->orig_top_line;
-         w->total_lines = w->orig_total_lines;
-         w->orig_total_lines = w->orig_top_line = Qnil;
-          XSETFASTINT (w->last_modified, 0);
-          XSETFASTINT (w->last_overlay_modified, 0);
-         break;
-
-       default:
-         abort ();
+         s->next = window;
+         if (!NILP (w->next))
+           XWINDOW (w->next)->prev = window;
        }
-
-      w = NILP (w->next) ? NULL : XWINDOW (w->next);
+      error ("Deletion failed");
     }
 
-  return success_p;
+  return Qnil;
 }
+\f
+/***********************************************************************
+                       Resizing Mini-Windows
+ ***********************************************************************/
 
-
-/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can
-   without deleting other windows.  */
-
+/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we
+   can.  */
 void
 grow_mini_window (struct window *w, int delta)
 {
   struct frame *f = XFRAME (w->frame);
-  struct window *root;
+  struct window *r;
+  Lisp_Object root, value;
 
   xassert (MINI_WINDOW_P (w));
-  /* Commenting out the following assertion goes against the stated interface
-     of the function, but it currently does not seem to do anything useful.
-     See discussion of this issue in the thread for bug#4534.
-     xassert (delta >= 0); */
-
-  /* Compute how much we can enlarge the mini-window without deleting
-     other windows.  */
-  root = XWINDOW (FRAME_ROOT_WINDOW (f));
-  if (delta > 0)
-    {
-      int min_height = window_min_size (root, 0, 0, 0, 0);
-      if (XFASTINT (root->total_lines) - delta < min_height)
-       /* Note that the root window may already be smaller than
-          min_height.  */
-       delta = max (0, XFASTINT (root->total_lines) - min_height);
-    }
+  xassert (delta >= 0);
 
-  if (delta)
+  root = FRAME_ROOT_WINDOW (f);
+  r = XWINDOW (root);
+  value = call2 (Qwindow_resize_root_window_vertically,
+                root, make_number (- delta));
+  if (INTEGERP (value) && window_resize_check (r, 0))
     {
-      /* Save original window sizes and positions, if not already done.  */
-      if (!save_restore_orig_size (root, CHECK_ORIG_SIZES))
-       save_restore_orig_size (root, SAVE_ORIG_SIZES);
-
-      /* Shrink other windows.  */
-      shrink_window_lowest_first (root, XFASTINT (root->total_lines) - delta);
+      BLOCK_INPUT;
+      window_resize_apply (r, 0);
 
       /* Grow the mini-window.  */
-      w->top_line = make_number (XFASTINT (root->top_line) + XFASTINT (root->total_lines));
-      w->total_lines = make_number (XFASTINT (w->total_lines) + delta);
+      XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
+      XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - XINT (value));
       XSETFASTINT (w->last_modified, 0);
       XSETFASTINT (w->last_overlay_modified, 0);
 
       adjust_glyphs (f);
+      UNBLOCK_INPUT;
     }
 }
 
 
-/* Shrink mini-window W.  If there is recorded info about window sizes
-   before a call to grow_mini_window, restore recorded window sizes.
-   Otherwise, if the mini-window is higher than 1 line, resize it to 1
-   line.  */
-
+/* Shrink mini-window W.  */
 void
 shrink_mini_window (struct window *w)
 {
   struct frame *f = XFRAME (w->frame);
-  struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
+  struct window *r;
+  Lisp_Object root, value;
+  EMACS_INT size;
 
-  if (save_restore_orig_size (root, CHECK_ORIG_SIZES))
-    {
-      save_restore_orig_size (root, RESTORE_ORIG_SIZES);
-      adjust_glyphs (f);
-      FRAME_WINDOW_SIZES_CHANGED (f) = 1;
-      windows_or_buffers_changed = 1;
-    }
-  else if (XFASTINT (w->total_lines) > 1)
+  xassert (MINI_WINDOW_P (w));
+
+  size = XINT (w->total_lines);
+  if (size > 1)
     {
-      /* Distribute the additional lines of the mini-window
-        among the other windows.  */
-      Lisp_Object window;
-      XSETWINDOW (window, w);
-      enlarge_window (window, 1 - XFASTINT (w->total_lines), 0);
+      root = FRAME_ROOT_WINDOW (f);
+      r = XWINDOW (root);
+      value = call2 (Qwindow_resize_root_window_vertically,
+                    root, make_number (size - 1));
+      if (INTEGERP (value) && window_resize_check (r, 0))
+       {
+         BLOCK_INPUT;
+         window_resize_apply (r, 0);
+
+         /* Shrink the mini-window.  */
+         XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
+         XSETFASTINT (w->total_lines, 1);
+
+         XSETFASTINT (w->last_modified, 0);
+         XSETFASTINT (w->last_overlay_modified, 0);
+
+         adjust_glyphs (f);
+         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
+        shrinking the frame (and probably when making the initial
+        *scratch* window).  For the moment leave things as they are.  */
     }
 }
 
+DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini_window_internal, 1, 1, 0,
+       doc: /* Resize minibuffer window WINDOW.  */)
+     (Lisp_Object window)
+{
+  struct window *w = XWINDOW (window);
+  struct window *r;
+  struct frame *f;
+  int height;
+
+  CHECK_WINDOW (window);
+  f = XFRAME (w->frame);
+
+  if (!EQ (FRAME_MINIBUF_WINDOW (XFRAME (w->frame)), window))
+    error ("Not a valid minibuffer window");
+  else if (FRAME_MINIBUF_ONLY_P (f))
+    error ("Cannot resize a minibuffer-only frame");
+
+  r = XWINDOW (FRAME_ROOT_WINDOW (f));
+  height = XINT (r->total_lines) + XINT (w->total_lines);
+  if (window_resize_check (r, 0)
+      && XINT (w->new_total) > 0
+      && height == XINT (r->new_total) + XINT (w->new_total))
+    {
+      BLOCK_INPUT;
+      window_resize_apply (r, 0);
+
+      w->total_lines = w->new_total;
+      XSETFASTINT (w->top_line, XINT (r->top_line) + XINT (r->total_lines));
+
+      windows_or_buffers_changed++;
+      FRAME_WINDOW_SIZES_CHANGED (f) = 1;
+      adjust_glyphs (f);
+      UNBLOCK_INPUT;
 
+      run_window_configuration_change_hook (f);
+      return Qt;
+    }
+  else error ("Failed to resize minibuffer window");
+}
 \f
 /* Mark window cursors off for all windows in the window tree rooted
    at W by setting their phys_cursor_on_p flag to zero.  Called from
@@ -6154,6 +4241,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
   /* True if we fiddled the window vscroll field without really scrolling.  */
   int vscrolled = 0;
   int x, y, rtop, rbot, rowh, vpos;
+  void *itdata = NULL;
 
   SET_TEXT_POS_FROM_MARKER (start, w->start);
 
@@ -6164,6 +4252,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
 
   if (!pos_visible_p (w, PT, &x, &y, &rtop, &rbot, &rowh, &vpos))
     {
+      itdata = bidi_shelve_cache ();
       /* Move backward half the height of the window.  Performance note:
         vmotion used here is about 10% faster, but would give wrong
         results for variable height lines.  */
@@ -6184,6 +4273,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
        }
 
       start = it.current.pos;
+      bidi_unshelve_cache (itdata, 0);
     }
   else if (auto_window_vscroll_p)
     {
@@ -6246,6 +4336,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
       Fset_window_vscroll (window, make_number (0), Qt);
     }
 
+  itdata = bidi_shelve_cache ();
   /* If scroll_preserve_screen_position is non-nil, we try to set
      point in the same window line as it is now, so get that line.  */
   if (!NILP (Vscroll_preserve_screen_position))
@@ -6324,12 +4415,16 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
                            - it.current_y + it.max_ascent + it.max_descent);
              adjust_glyphs (it.f);
            }
-         else if (noerror)
-           return;
-         else if (n < 0)       /* could happen with empty buffers */
-           xsignal0 (Qbeginning_of_buffer);
          else
-           xsignal0 (Qend_of_buffer);
+           {
+             bidi_unshelve_cache (itdata, 0);
+             if (noerror)
+               return;
+             else if (n < 0)   /* could happen with empty buffers */
+               xsignal0 (Qbeginning_of_buffer);
+             else
+               xsignal0 (Qend_of_buffer);
+           }
        }
       else
        {
@@ -6337,10 +4432,14 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
            /* The first line was only partially visible, make it fully
               visible. */
            w->vscroll = 0;
-         else if (noerror)
-           return;
          else
-           xsignal0 (Qbeginning_of_buffer);
+           {
+             bidi_unshelve_cache (itdata, 0);
+             if (noerror)
+               return;
+             else
+               xsignal0 (Qbeginning_of_buffer);
+           }
        }
 
       /* If control gets here, then we vscrolled.  */
@@ -6484,6 +4583,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
            SET_PT_BOTH (charpos, bytepos);
        }
     }
+  bidi_unshelve_cache (itdata, 0);
 }
 
 
@@ -6886,6 +4986,7 @@ displayed_window_lines (struct window *w)
   int height = window_box_height (w);
   struct buffer *old_buffer;
   int bottom_y;
+  void *itdata = NULL;
 
   if (XBUFFER (w->buffer) != current_buffer)
     {
@@ -6905,9 +5006,11 @@ displayed_window_lines (struct window *w)
   else
     SET_TEXT_POS_FROM_MARKER (start, w->start);
 
+  itdata = bidi_shelve_cache ();
   start_display (&it, w, start);
   move_it_vertically (&it, height);
   bottom_y = line_bottom_y (&it);
+  bidi_unshelve_cache (itdata, 0);
 
   /* rms: On a non-window display,
      the value of it.vpos at the bottom of the screen
@@ -7006,12 +5109,14 @@ and redisplay normally--don't erase and redraw the frame.  */)
        {
          struct it it;
          struct text_pos pt;
+         void *itdata = bidi_shelve_cache ();
 
          SET_TEXT_POS (pt, PT, PT_BYTE);
          start_display (&it, w, pt);
          move_it_vertically_backward (&it, window_box_height (w) / 2);
          charpos = IT_CHARPOS (it);
          bytepos = IT_BYTEPOS (it);
+         bidi_unshelve_cache (itdata, 0);
        }
       else if (iarg < 0)
        {
@@ -7020,6 +5125,7 @@ and redisplay normally--don't erase and redraw the frame.  */)
          int nlines = -iarg;
          int extra_line_spacing;
          int h = window_box_height (w);
+         void *itdata = bidi_shelve_cache ();
 
          iarg = - max (-iarg, this_scroll_margin);
 
@@ -7057,7 +5163,10 @@ and redisplay normally--don't erase and redraw the frame.  */)
              h -= nlines * (FRAME_LINE_HEIGHT (it.f) + extra_line_spacing);
            }
          if (h <= 0)
-           return Qnil;
+           {
+             bidi_unshelve_cache (itdata, 0);
+             return Qnil;
+           }
 
          /* Now find the new top line (starting position) of the window.  */
          start_display (&it, w, pt);
@@ -7077,6 +5186,8 @@ and redisplay normally--don't erase and redraw the frame.  */)
 
          charpos = IT_CHARPOS (it);
          bytepos = IT_BYTEPOS (it);
+
+         bidi_unshelve_cache (itdata, 0);
        }
       else
        {
@@ -7123,7 +5234,6 @@ and redisplay normally--don't erase and redraw the frame.  */)
   return Qnil;
 }
 
-
 DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height,
        0, 1, 0,
        doc: /* Return the height in lines of the text display area of WINDOW.
@@ -7244,19 +5354,16 @@ struct saved_window
 {
   struct vectorlike_header header;
 
-  Lisp_Object window, clone_number;
-  Lisp_Object buffer, start, pointm, mark;
+  Lisp_Object window, buffer, start, pointm, mark;
   Lisp_Object left_col, top_line, total_cols, total_lines;
   Lisp_Object normal_cols, normal_lines;
   Lisp_Object hscroll, min_hscroll;
   Lisp_Object parent, prev;
   Lisp_Object start_at_line_beg;
   Lisp_Object display_table;
-  Lisp_Object orig_top_line, orig_total_lines;
   Lisp_Object left_margin_cols, right_margin_cols;
   Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins;
-  Lisp_Object scroll_bar_width, vertical_scroll_bar_type;
-  Lisp_Object dedicated, resize_proportionally;
+  Lisp_Object scroll_bar_width, vertical_scroll_bar_type, dedicated;
   Lisp_Object splits, nest, window_parameters;
 };
 
@@ -7298,6 +5405,7 @@ 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;
   EMACS_INT old_point = -1;
 
@@ -7353,6 +5461,8 @@ the return value is nil.  Otherwise the value is t.  */)
      However, there is other stuff we should still try to do below.  */
   if (FRAME_LIVE_P (f))
     {
+      Lisp_Object window;
+      Lisp_Object dead_windows = Qnil;
       register struct window *w;
       register struct saved_window *p;
       struct window *root_window;
@@ -7429,7 +5539,8 @@ the return value is nil.  Otherwise the value is t.  */)
       for (k = 0; k < saved_windows->header.size; k++)
        {
          p = SAVED_WINDOW_N (saved_windows, k);
-         w = XWINDOW (p->window);
+         window = p->window;
+         w = XWINDOW (window);
          w->next = Qnil;
 
          if (!NILP (p->parent))
@@ -7462,7 +5573,6 @@ the return value is nil.  Otherwise the value is t.  */)
                }
            }
 
-         w->clone_number = p->clone_number;
          /* If we squirreled away the buffer in the window's height,
             restore it now.  */
          if (BUFFERP (w->total_lines))
@@ -7476,8 +5586,6 @@ the return value is nil.  Otherwise the value is t.  */)
          w->hscroll = p->hscroll;
          w->min_hscroll = p->min_hscroll;
          w->display_table = p->display_table;
-         w->orig_top_line = p->orig_top_line;
-         w->orig_total_lines = p->orig_total_lines;
          w->left_margin_cols = p->left_margin_cols;
          w->right_margin_cols = p->right_margin_cols;
          w->left_fringe_width = p->left_fringe_width;
@@ -7489,61 +5597,75 @@ the return value is nil.  Otherwise the value is t.  */)
          w->splits = p->splits;
          w->nest = p->nest;
          w->window_parameters = p->window_parameters;
-         w->resize_proportionally = p->resize_proportionally;
          XSETFASTINT (w->last_modified, 0);
          XSETFASTINT (w->last_overlay_modified, 0);
 
          /* Reinstall the saved buffer and pointers into it.  */
          if (NILP (p->buffer))
+           /* An internal window.  */
            w->buffer = p->buffer;
+         else 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 (BVAR (XBUFFER (w->buffer), mark),
+                          p->mark, w->buffer);
+
+             /* As documented in Fcurrent_window_configuration, don't
+                restore the location of point in the buffer which was
+                current when the window configuration was recorded.  */
+             if (!EQ (p->buffer, new_current_buffer)
+                 && XBUFFER (p->buffer) == current_buffer)
+               Fgoto_char (w->pointm);
+           }
+         else if (!NILP (w->buffer) && !NILP (BVAR (XBUFFER (w->buffer), name)))
+           /* Keep window's old buffer; make sure the markers are
+              real.  */
+           {
+             /* Set window markers at start of visible range.  */
+             if (XMARKER (w->start)->buffer == 0)
+               set_marker_restricted (w->start, make_number (0),
+                                      w->buffer);
+             if (XMARKER (w->pointm)->buffer == 0)
+               set_marker_restricted_both (w->pointm, w->buffer,
+                                           BUF_PT (XBUFFER (w->buffer)),
+                                           BUF_PT_BYTE (XBUFFER (w->buffer)));
+             w->start_at_line_beg = Qt;
+           }
+         else if (STRINGP (auto_buffer_name =
+                           Fwindow_parameter (window, Qauto_buffer_name))
+                  && SCHARS (auto_buffer_name) != 0
+                  && !NILP (w->buffer = Fget_buffer_create (auto_buffer_name)))
+           {
+             set_marker_restricted (w->start, make_number (0), w->buffer);
+             set_marker_restricted (w->pointm, make_number (0), w->buffer);
+             w->start_at_line_beg = Qt;
+           }
          else
+           /* Window has no live buffer, get one.  */
            {
-             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 (BVAR (XBUFFER (w->buffer), mark),
-                              p->mark, w->buffer);
-
-                 /* As documented in Fcurrent_window_configuration, don't
-                    restore the location of point in the buffer which was
-                    current when the window configuration was recorded.  */
-                 if (!EQ (p->buffer, new_current_buffer)
-                     && XBUFFER (p->buffer) == current_buffer)
-                   Fgoto_char (w->pointm);
-               }
-             else if (NILP (w->buffer) || NILP (BVAR (XBUFFER (w->buffer), name)))
-               /* Else unless window has a live buffer, get one.  */
-               {
-                 w->buffer = Fcdr (Fcar (Vbuffer_alist));
-                 /* This will set the markers to beginning of visible
-                    range.  */
-                 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 = Qt;
-               }
-             else
-               /* Keeping window's old buffer; make sure the markers
-                  are real.  */
-               {
-                 /* Set window markers at start of visible range.  */
-                 if (XMARKER (w->start)->buffer == 0)
-                   set_marker_restricted (w->start, make_number (0),
-                                          w->buffer);
-                 if (XMARKER (w->pointm)->buffer == 0)
-                   set_marker_restricted_both (w->pointm, w->buffer,
-                                               BUF_PT (XBUFFER (w->buffer)),
-                                               BUF_PT_BYTE (XBUFFER (w->buffer)));
-                 w->start_at_line_beg = Qt;
-               }
+             /* Get the buffer via other_buffer_safely in order to
+             avoid showing an unimportant buffer and, if necessary, to
+             recreate *scratch* in the course (part of Juanma's bs-show
+             scenario from March 2011).  */
+             w->buffer = other_buffer_safely (Fcurrent_buffer ());
+             /* This will set the markers to beginning of visible
+                range.  */
+             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 = Qt;
+             if (!NILP (w->dedicated))
+               /* Record this window as dead.  */
+               dead_windows = Fcons (window, dead_windows);
+             /* Make sure window is no more dedicated.  */
+             w->dedicated = Qnil;
            }
        }
 
       FRAME_ROOT_WINDOW (f) = data->root_window;
-
       /* Arrange *not* to restore point in the buffer that was
         current when the window configuration was saved.  */
       if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer))
@@ -7551,10 +5673,10 @@ the return value is nil.  Otherwise the value is t.  */)
                               make_number (old_point),
                               XWINDOW (data->current_window)->buffer);
 
-      /* In the following call to `select-window, prevent "swapping
-        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.  */
+      /* In the following call to `select-window', prevent "swapping 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.  */
       select_window (data->current_window, Qnil, 1);
       BVAR (XBUFFER (XWINDOW (selected_window)->buffer), last_selected_window)
        = selected_window;
@@ -7595,9 +5717,16 @@ the return value is nil.  Otherwise the value is t.  */)
        }
 
       adjust_glyphs (f);
-
       UNBLOCK_INPUT;
 
+      /* Scan dead buffer windows.  */
+      for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
+       {
+         window = XCAR (dead_windows);
+         if (WINDOW_LIVE_P (window) && !EQ (window, FRAME_ROOT_WINDOW (f)))
+           delete_deletable_window (window);
+       }
+
       /* Fselect_window will have made f the selected frame, so we
         reselect the proper frame here.  Fhandle_switch_frame will change the
         selected window too, but that doesn't make the call to
@@ -7618,6 +5747,7 @@ the return value is nil.  Otherwise the value is t.  */)
   return (FRAME_LIVE_P (f) ? Qt : Qnil);
 }
 
+
 /* Delete all subwindows reachable via the next, vchild, and hchild
    slots of WINDOW.  */
 void
@@ -7670,7 +5800,6 @@ count_windows (register struct window *window)
 
 /* Fill vector FLAT with leaf windows under W, starting at index I.
    Value is last index + 1.  */
-
 static int
 get_leaf_windows (struct window *w, struct window **flat, int i)
 {
@@ -7693,7 +5822,6 @@ get_leaf_windows (struct window *w, struct window **flat, int i)
 /* Return a pointer to the glyph W's physical cursor is on.  Value is
    null if W's current matrix is invalid, so that no meaningfull glyph
    can be returned.  */
-
 struct glyph *
 get_phys_cursor_glyph (struct window *w)
 {
@@ -7727,7 +5855,6 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
 
       XSETFASTINT (w->temslot, i); i++;
       p->window = window;
-      p->clone_number = w->clone_number;
       p->buffer = w->buffer;
       p->left_col = w->left_col;
       p->top_line = w->top_line;
@@ -7738,8 +5865,6 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
       p->hscroll = w->hscroll;
       p->min_hscroll = w->min_hscroll;
       p->display_table = w->display_table;
-      p->orig_top_line = w->orig_top_line;
-      p->orig_total_lines = w->orig_total_lines;
       p->left_margin_cols = w->left_margin_cols;
       p->right_margin_cols = w->right_margin_cols;
       p->left_fringe_width = w->left_fringe_width;
@@ -7750,7 +5875,6 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
       p->dedicated = w->dedicated;
       p->splits = w->splits;
       p->nest = w->nest;
-      p->resize_proportionally = w->resize_proportionally;
       p->window_parameters = w->window_parameters;
       if (!NILP (w->buffer))
        {
@@ -7847,82 +5971,6 @@ redirection (see `redirect-frame-focus').  */)
   XSETWINDOW_CONFIGURATION (tem, data);
   return (tem);
 }
-
-\f
-/***********************************************************************
-                           Window Split Tree
- ***********************************************************************/
-
-static Lisp_Object
-window_tree (struct window *w)
-{
-  Lisp_Object tail = Qnil;
-  Lisp_Object result = Qnil;
-
-  while (w)
-    {
-      Lisp_Object wn;
-
-      XSETWINDOW (wn, w);
-      if (!NILP (w->hchild))
-       wn = Fcons (Qnil, Fcons (Fwindow_edges (wn),
-                                window_tree (XWINDOW (w->hchild))));
-      else if (!NILP (w->vchild))
-       wn = Fcons (Qt, Fcons (Fwindow_edges (wn),
-                              window_tree (XWINDOW (w->vchild))));
-
-      if (NILP (result))
-       {
-         result = tail = Fcons (wn, Qnil);
-       }
-      else
-       {
-         XSETCDR (tail, Fcons (wn, Qnil));
-         tail = XCDR (tail);
-       }
-
-      w = NILP (w->next) ? 0 : XWINDOW (w->next);
-    }
-
-  return result;
-}
-
-
-
-DEFUN ("window-tree", Fwindow_tree, Swindow_tree,
-       0, 1, 0,
-       doc: /* Return the window tree for frame FRAME.
-
-The return value is a list of the form (ROOT MINI), where ROOT
-represents the window tree of the frame's root window, and MINI
-is the frame's minibuffer window.
-
-If the root window is not split, ROOT is the root window itself.
-Otherwise, ROOT is a list (DIR EDGES W1 W2 ...) where DIR is nil for a
-horizontal split, and t for a vertical split, EDGES gives the combined
-size and position of the subwindows in the split, and the rest of the
-elements are the subwindows in the split.  Each of the subwindows may
-again be a window or a list representing a window split, and so on.
-EDGES is a list \(LEFT TOP RIGHT BOTTOM) as returned by `window-edges'.
-
-If FRAME is nil or omitted, return information on the currently
-selected frame.  */)
-  (Lisp_Object frame)
-{
-  FRAME_PTR f;
-
-  if (NILP (frame))
-    frame = selected_frame;
-
-  CHECK_FRAME (frame);
-  f = XFRAME (frame);
-
-  if (!FRAME_LIVE_P (f))
-    return Qnil;
-
-  return window_tree (XWINDOW (FRAME_ROOT_WINDOW (f)));
-}
-
 \f
 /***********************************************************************
                            Marginal Areas
@@ -8282,116 +6330,81 @@ freeze_window_starts (struct frame *f, int freeze_p)
                            Initialization
  ***********************************************************************/
 
-/* Return 1 if window configurations C1 and C2
-   describe the same state of affairs.  This is used by Fequal.  */
+/* 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
+   and the like.
+
+   This ignores a couple of things like the dedicatedness status of
+   window, splits, nest and the like.  This might have to be fixed.  */
 
 int
-compare_window_configurations (Lisp_Object c1, Lisp_Object c2, int ignore_positions)
+compare_window_configurations (Lisp_Object configuration1, Lisp_Object configuration2, int ignore_positions)
 {
   register struct save_window_data *d1, *d2;
-  struct Lisp_Vector *sw1, *sw2;
+  struct Lisp_Vector *sws1, *sws2;
   int i;
 
-  CHECK_WINDOW_CONFIGURATION (c1);
-  CHECK_WINDOW_CONFIGURATION (c2);
-
-  d1 = (struct save_window_data *) XVECTOR (c1);
-  d2 = (struct save_window_data *) XVECTOR (c2);
-  sw1 = XVECTOR (d1->saved_windows);
-  sw2 = XVECTOR (d2->saved_windows);
-
-  if (d1->frame_cols != d2->frame_cols)
-    return 0;
-  if (d1->frame_lines != d2->frame_lines)
-    return 0;
-  if (d1->frame_menu_bar_lines != d2->frame_menu_bar_lines)
-    return 0;
-  if (! EQ (d1->selected_frame, d2->selected_frame))
-    return 0;
-  /* Don't compare the current_window field directly.
-     Instead see w1_is_current and w2_is_current, below.  */
-  if (! EQ (d1->current_buffer, d2->current_buffer))
-    return 0;
-  if (! ignore_positions)
-    {
-      if (! EQ (d1->minibuf_scroll_window, d2->minibuf_scroll_window))
-       return 0;
-      if (! EQ (d1->minibuf_selected_window, d2->minibuf_selected_window))
-       return 0;
-    }
-  /* Don't compare the root_window field.
-     We don't require the two configurations
-     to use the same window object,
-     and the two root windows must be equivalent
-     if everything else compares equal.  */
-  if (! EQ (d1->focus_frame, d2->focus_frame))
-    return 0;
-
-  /* Verify that the two confis have the same number of windows.  */
-  if (sw1->header.size != sw2->header.size)
+  CHECK_WINDOW_CONFIGURATION (configuration1);
+  CHECK_WINDOW_CONFIGURATION (configuration2);
+
+  d1 = (struct save_window_data *) XVECTOR (configuration1);
+  d2 = (struct save_window_data *) XVECTOR (configuration2);
+  sws1 = XVECTOR (d1->saved_windows);
+  sws2 = XVECTOR (d2->saved_windows);
+
+  /* Frame settings must match.  */
+  if (d1->frame_cols != d2->frame_cols
+      || d1->frame_lines != d2->frame_lines
+      || d1->frame_menu_bar_lines != d2->frame_menu_bar_lines
+      || !EQ (d1->selected_frame, d2->selected_frame)
+      || !EQ (d1->current_buffer, d2->current_buffer)
+      || (!ignore_positions
+         && (!EQ (d1->minibuf_scroll_window, d2->minibuf_scroll_window)
+             || !EQ (d1->minibuf_selected_window, d2->minibuf_selected_window)))
+      || !EQ (d1->focus_frame, d2->focus_frame)
+      /* Verify that the two configurations have the same number of windows.  */
+      || sws1->header.size != sws2->header.size)
     return 0;
 
-  for (i = 0; i < sw1->header.size; i++)
-    {
-      struct saved_window *p1, *p2;
-      int w1_is_current, w2_is_current;
-
-      p1 = SAVED_WINDOW_N (sw1, i);
-      p2 = SAVED_WINDOW_N (sw2, i);
-
-      /* Verify that the current windows in the two
-        configurations correspond to each other.  */
-      w1_is_current = EQ (d1->current_window, p1->window);
-      w2_is_current = EQ (d2->current_window, p2->window);
-
-      if (w1_is_current != w2_is_current)
-       return 0;
-
-      /* Verify that the corresponding windows do match.  */
-      if (! EQ (p1->buffer, p2->buffer))
-       return 0;
-      if (! EQ (p1->left_col, p2->left_col))
-       return 0;
-      if (! EQ (p1->top_line, p2->top_line))
-       return 0;
-      if (! EQ (p1->total_cols, p2->total_cols))
-       return 0;
-      if (! EQ (p1->total_lines, p2->total_lines))
-       return 0;
-      if (! EQ (p1->display_table, p2->display_table))
-       return 0;
-      if (! EQ (p1->parent, p2->parent))
-       return 0;
-      if (! EQ (p1->prev, p2->prev))
-       return 0;
-      if (! ignore_positions)
-       {
-         if (! EQ (p1->hscroll, p2->hscroll))
-           return 0;
-         if (!EQ (p1->min_hscroll, p2->min_hscroll))
-           return 0;
-         if (! EQ (p1->start_at_line_beg, p2->start_at_line_beg))
-           return 0;
-         if (NILP (Fequal (p1->start, p2->start)))
-           return 0;
-         if (NILP (Fequal (p1->pointm, p2->pointm)))
-           return 0;
-         if (NILP (Fequal (p1->mark, p2->mark)))
-           return 0;
-       }
-      if (! EQ (p1->left_margin_cols, p2->left_margin_cols))
-       return 0;
-      if (! EQ (p1->right_margin_cols, p2->right_margin_cols))
-       return 0;
-      if (! EQ (p1->left_fringe_width, p2->left_fringe_width))
-       return 0;
-      if (! EQ (p1->right_fringe_width, p2->right_fringe_width))
-       return 0;
-      if (! EQ (p1->fringes_outside_margins, p2->fringes_outside_margins))
-       return 0;
-      if (! EQ (p1->scroll_bar_width, p2->scroll_bar_width))
-       return 0;
-      if (! EQ (p1->vertical_scroll_bar_type, p2->vertical_scroll_bar_type))
+  for (i = 0; i < sws1->header.size; i++)
+    {
+      struct saved_window *sw1, *sw2;
+
+      sw1 = SAVED_WINDOW_N (sws1, i);
+      sw2 = SAVED_WINDOW_N (sws2, i);
+
+      if (
+          /* The "current" windows in the two configurations must
+             correspond to each other.  */
+         EQ (d1->current_window, sw1->window)
+         != EQ (d2->current_window, sw2->window)
+         /* Windows' buffers must match.  */
+         || !EQ (sw1->buffer, sw2->buffer)
+         || !EQ (sw1->left_col, sw2->left_col)
+         || !EQ (sw1->top_line, sw2->top_line)
+         || !EQ (sw1->total_cols, sw2->total_cols)
+         || !EQ (sw1->total_lines, sw2->total_lines)
+         || !EQ (sw1->display_table, sw2->display_table)
+         /* The next two disjuncts check the window structure for
+            equality.  */
+         || !EQ (sw1->parent, sw2->parent)
+         || !EQ (sw1->prev, sw2->prev)
+         || (!ignore_positions
+             && (!EQ (sw1->hscroll, sw2->hscroll)
+                 || !EQ (sw1->min_hscroll, sw2->min_hscroll)
+                 || !EQ (sw1->start_at_line_beg, sw2->start_at_line_beg)
+                 || NILP (Fequal (sw1->start, sw2->start))
+                 || NILP (Fequal (sw1->pointm, sw2->pointm))
+                 || NILP (Fequal (sw1->mark, sw2->mark))))
+         || !EQ (sw1->left_margin_cols, sw2->left_margin_cols)
+         || !EQ (sw1->right_margin_cols, sw2->right_margin_cols)
+         || !EQ (sw1->left_fringe_width, sw2->left_fringe_width)
+         || !EQ (sw1->right_fringe_width, sw2->right_fringe_width)
+         || !EQ (sw1->fringes_outside_margins, sw2->fringes_outside_margins)
+         || !EQ (sw1->scroll_bar_width, sw2->scroll_bar_width)
+         || !EQ (sw1->vertical_scroll_bar_type, sw2->vertical_scroll_bar_type))
        return 0;
     }
 
@@ -8432,73 +6445,30 @@ init_window (void)
 void
 syms_of_window (void)
 {
-  Qscroll_up = intern_c_string ("scroll-up");
-  staticpro (&Qscroll_up);
-
-  Qscroll_down = intern_c_string ("scroll-down");
-  staticpro (&Qscroll_down);
-
-  Qscroll_command = intern_c_string ("scroll-command");
-  staticpro (&Qscroll_command);
+  DEFSYM (Qscroll_up, "scroll-up");
+  DEFSYM (Qscroll_down, "scroll-down");
+  DEFSYM (Qscroll_command, "scroll-command");
 
   Fput (Qscroll_up, Qscroll_command, Qt);
   Fput (Qscroll_down, Qscroll_command, Qt);
 
-  Qwindow_size_fixed = intern_c_string ("window-size-fixed");
-  staticpro (&Qwindow_size_fixed);
-  Fset (Qwindow_size_fixed, Qnil);
-
-  staticpro (&Qwindow_configuration_change_hook);
-  Qwindow_configuration_change_hook
-    = intern_c_string ("window-configuration-change-hook");
-
-  Qwindowp = intern_c_string ("windowp");
-  staticpro (&Qwindowp);
-
-  Qwindow_configuration_p = intern_c_string ("window-configuration-p");
-  staticpro (&Qwindow_configuration_p);
-
-  Qwindow_live_p = intern_c_string ("window-live-p");
-  staticpro (&Qwindow_live_p);
-
-  Qwindow_deletable_p = intern_c_string ("window-deletable-p");
-  staticpro (&Qwindow_deletable_p);
-
-  Qdelete_window = intern_c_string ("delete-window");
-  staticpro (&Qdelete_window);
-
-  Qresize_root_window = intern_c_string ("resize-root-window");
-  staticpro (&Qresize_root_window);
-
-  Qresize_root_window_vertically = intern_c_string ("resize-root-window-vertically");
-  staticpro (&Qresize_root_window_vertically);
-
-  Qsafe = intern_c_string ("safe");
-  staticpro (&Qsafe);
-
-  Qdisplay_buffer = intern_c_string ("display-buffer");
-  staticpro (&Qdisplay_buffer);
-
-  Qreplace_buffer_in_windows = intern_c_string ("replace-buffer-in-windows");
-  staticpro (&Qreplace_buffer_in_windows);
-
-  Qrecord_window_buffer = intern_c_string ("record-window-buffer");
-  staticpro (&Qrecord_window_buffer);
-
-  Qget_mru_window = intern_c_string ("get-mru-window");
-  staticpro (&Qget_mru_window);
-
-  Qtemp_buffer_show_hook = intern_c_string ("temp-buffer-show-hook");
-  staticpro (&Qtemp_buffer_show_hook);
-
-  Qabove = intern_c_string ("above");
-  staticpro (&Qabove);
-
-  Qbelow = intern_c_string ("below");
-  staticpro (&Qbelow);
-
-  Qauto_buffer_name = intern_c_string ("auto-buffer-name");
-  staticpro (&Qauto_buffer_name);
+  DEFSYM (Qwindow_configuration_change_hook, "window-configuration-change-hook");
+  DEFSYM (Qwindowp, "windowp");
+  DEFSYM (Qwindow_configuration_p, "window-configuration-p");
+  DEFSYM (Qwindow_live_p, "window-live-p");
+  DEFSYM (Qwindow_deletable_p, "window-deletable-p");
+  DEFSYM (Qdelete_window, "delete-window");
+  DEFSYM (Qwindow_resize_root_window, "window--resize-root-window");
+  DEFSYM (Qwindow_resize_root_window_vertically, "window--resize-root-window-vertically");
+  DEFSYM (Qsafe, "safe");
+  DEFSYM (Qdisplay_buffer, "display-buffer");
+  DEFSYM (Qreplace_buffer_in_windows, "replace-buffer-in-windows");
+  DEFSYM (Qrecord_window_buffer, "record-window-buffer");
+  DEFSYM (Qget_mru_window, "get-mru-window");
+  DEFSYM (Qtemp_buffer_show_hook, "temp-buffer-show-hook");
+  DEFSYM (Qabove, "above");
+  DEFSYM (Qbelow, "below");
+  DEFSYM (Qauto_buffer_name, "auto-buffer-name");
 
   staticpro (&Vwindow_list);
 
@@ -8518,6 +6488,16 @@ 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 ("temp-buffer-show-specifiers", Vtemp_buffer_show_specifiers,
+              doc: /* Buffer display specifiers used by `with-output-to-temp-buffer'.
+These specifiers are passed by `with-output-to-temp-buffer' as second
+argument to `display-buffer'.  Applications should only let-bind this
+around a call to `with-output-to-temp-buffer'.
+
+For a description of buffer display specifiers see the variable
+`display-buffer-alist'.  */);
+  Vtemp_buffer_show_specifiers = Qnil;
+
   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;
@@ -8533,34 +6513,16 @@ is displayed in the `mode-line' face.  */);
   Vother_window_scroll_buffer = Qnil;
 
   DEFVAR_BOOL ("auto-window-vscroll", auto_window_vscroll_p,
-              doc: /* *Non-nil means to automatically adjust `window-vscroll' to view tall lines.  */);
+              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,
-             doc: /* *Number of lines of continuity when scrolling by screenfuls.  */);
+             doc: /* Number of lines of continuity when scrolling by screenfuls.  */);
   next_screen_context_lines = 2;
 
-  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.
-
-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,
-             doc: /* Allow deleting windows less than this wide.
-The value is measured in characters and includes any fringes or
-the scrollbar.
-
-Emacs honors settings of this variable when enlarging or shrinking
-windows horizontally.  A value less than 2 is invalid.  */);
-  window_min_width = 10;
-
   DEFVAR_LISP ("scroll-preserve-screen-position",
               Vscroll_preserve_screen_position,
-              doc: /* *Controls if scroll commands move point to keep its screen position unchanged.
+              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.
 A value of t means point keeps its screen position if the scroll
@@ -8637,13 +6599,12 @@ function `window-nest' and altered by the function `set-window-nest'.  */);
   defsubr (&Sset_frame_selected_window);
   defsubr (&Spos_visible_in_window_p);
   defsubr (&Swindow_line_height);
-  defsubr (&Swindow_clone_number);
   defsubr (&Swindow_buffer);
   defsubr (&Swindow_parent);
-  defsubr (&Swindow_vchild);
-  defsubr (&Swindow_hchild);
-  defsubr (&Swindow_next);
-  defsubr (&Swindow_prev);
+  defsubr (&Swindow_top_child);
+  defsubr (&Swindow_left_child);
+  defsubr (&Swindow_next_sibling);
+  defsubr (&Swindow_prev_sibling);
   defsubr (&Swindow_splits);
   defsubr (&Sset_window_splits);
   defsubr (&Swindow_nest);
@@ -8657,7 +6618,7 @@ function `window-nest' and altered by the function `set-window-nest'.  */);
   defsubr (&Swindow_new_normal);
   defsubr (&Sset_window_new_total);
   defsubr (&Sset_window_new_normal);
-  defsubr (&Sresize_window_apply);
+  defsubr (&Swindow_resize_apply);
   defsubr (&Swindow_body_size);
   defsubr (&Swindow_hscroll);
   defsubr (&Sset_window_hscroll);
@@ -8682,26 +6643,16 @@ function `window-nest' and altered by the function `set-window-nest'.  */);
   defsubr (&Sset_window_display_table);
   defsubr (&Snext_window);
   defsubr (&Sprevious_window);
-  defsubr (&Sother_window);
   defsubr (&Sget_buffer_window);
-  defsubr (&Sdelete_other_windows);
-  defsubr (&Sdelete_windows_on);
-  defsubr (&Sreplace_buffer_in_windows);
-  defsubr (&Sdelete_window);
   defsubr (&Sdelete_other_windows_internal);
   defsubr (&Sdelete_window_internal);
   defsubr (&Sresize_mini_window_internal);
   defsubr (&Sset_window_buffer);
-  defsubr (&Sset_window_clone_number);
   defsubr (&Srun_window_configuration_change_hook);
   defsubr (&Sselect_window);
   defsubr (&Sforce_window_update);
   defsubr (&Stemp_output_buffer_show);
-  defsubr (&Ssplit_window);
   defsubr (&Ssplit_window_internal);
-  defsubr (&Senlarge_window);
-  defsubr (&Sshrink_window);
-  defsubr (&Sadjust_window_trailing_edge);
   defsubr (&Sscroll_up);
   defsubr (&Sscroll_down);
   defsubr (&Sscroll_left);
@@ -8716,7 +6667,6 @@ function `window-nest' and altered by the function `set-window-nest'.  */);
   defsubr (&Swindow_configuration_frame);
   defsubr (&Sset_window_configuration);
   defsubr (&Scurrent_window_configuration);
-  defsubr (&Swindow_tree);
   defsubr (&Sset_window_margins);
   defsubr (&Swindow_margins);
   defsubr (&Sset_window_fringes);
@@ -8740,11 +6690,6 @@ function `window-nest' and altered by the function `set-window-nest'.  */);
 void
 keys_of_window (void)
 {
-  initial_define_key (control_x_map, '1', "delete-other-windows");
-  initial_define_key (control_x_map, '2', "split-window");
-  initial_define_key (control_x_map, '0', "delete-window");
-  initial_define_key (control_x_map, 'o', "other-window");
-  initial_define_key (control_x_map, '^', "enlarge-window");
   initial_define_key (control_x_map, '<', "scroll-left");
   initial_define_key (control_x_map, '>', "scroll-right");