Don't have previous and next buffers deal with internal windows.
[bpt/emacs.git] / src / window.c
index 959c1c3..0473ed4 100644 (file)
@@ -54,7 +54,7 @@ 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;
@@ -82,8 +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 int resize_window_check (struct window *, int);
-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
@@ -408,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.
@@ -434,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;
@@ -691,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
@@ -1358,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.  */
@@ -1379,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);
@@ -1418,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)
@@ -1686,7 +1682,7 @@ PREV-BUFFERS should be either nil or a list of <buffer, window-start,
 window-point> triples where buffer was previously shown in WINDOW.  */)
      (Lisp_Object window, Lisp_Object prev_buffers)
 {
-  return decode_any_window (window)->prev_buffers = prev_buffers;
+  return decode_window (window)->prev_buffers = prev_buffers;
 }
 
 DEFUN ("window-next-buffers", Fwindow_next_buffers, Swindow_next_buffers,
@@ -1708,7 +1704,7 @@ NEXT-BUFFERS should be either nil or a list of buffers that have been
 recently re-shown in WINDOW.  */)
      (Lisp_Object window, Lisp_Object next_buffers)
 {
-  return decode_any_window (window)->next_buffers = next_buffers;
+  return decode_window (window)->next_buffers = next_buffers;
 }
 
 DEFUN ("window-parameters", Fwindow_parameters, Swindow_parameters,
@@ -1974,6 +1970,14 @@ recombine_windows (Lisp_Object window)
        }
     }
 }
+
+/* If WINDOW can be deleted, delete it.  */
+static void
+delete_deletable_window (Lisp_Object window)
+{
+  if (!NILP (call1 (Qwindow_deletable_p, window)))
+    call1 (Qdelete_window, window);
+}
 \f
 /***********************************************************************
                             Window List
@@ -2568,7 +2572,7 @@ selected frame and no others.  */)
 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);
 }
 
 
@@ -2687,13 +2691,13 @@ window-start value is reasonable when this function is called.  */)
       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;
        }
@@ -2705,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;
            }
@@ -3079,18 +3083,6 @@ 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 has to be a live window and defaults to the selected one.
@@ -3216,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)));
@@ -3278,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);
 
@@ -3324,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;
@@ -3404,7 +3397,7 @@ Note: This function does not operate on any subwindows of WINDOW.  */)
    `window-min-height' or `window-min-width'.  It does check that window
    sizes do not drop below one line (two columns). */
 static int
-resize_window_check (struct window *w, int horflag)
+window_resize_check (struct window *w, int horflag)
 {
   struct window *c;
 
@@ -3418,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);
            }
@@ -3431,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);
@@ -3450,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);
@@ -3463,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);
            }
@@ -3483,9 +3476,9 @@ 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.  */
+   run window_resize_check on W before applying this function.  */
 static void
-resize_window_apply (struct window *w, int horflag)
+window_resize_apply (struct window *w, int horflag)
 {
   struct window *c;
   int pos;
@@ -3519,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);
@@ -3535,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);
@@ -3548,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.
@@ -3573,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;
@@ -3630,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
@@ -3754,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.  */
@@ -3762,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))
@@ -3850,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.  */
@@ -3934,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;
@@ -4062,11 +4055,12 @@ grow_mini_window (struct window *w, int delta)
 
   root = FRAME_ROOT_WINDOW (f);
   r = XWINDOW (root);
-  value = call2 (Qresize_root_window_vertically, root, make_number (- delta));
-  if (INTEGERP (value) && resize_window_check (r, 0))
+  value = call2 (Qwindow_resize_root_window_vertically,
+                root, make_number (- delta));
+  if (INTEGERP (value) && window_resize_check (r, 0))
     {
       BLOCK_INPUT;
-      resize_window_apply (r, 0);
+      window_resize_apply (r, 0);
 
       /* Grow the mini-window.  */
       XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
@@ -4096,12 +4090,12 @@ shrink_mini_window (struct window *w)
     {
       root = FRAME_ROOT_WINDOW (f);
       r = XWINDOW (root);
-      value = call2 (Qresize_root_window_vertically,
+      value = call2 (Qwindow_resize_root_window_vertically,
                     root, make_number (size - 1));
-      if (INTEGERP (value) && resize_window_check (r, 0))
+      if (INTEGERP (value) && window_resize_check (r, 0))
        {
          BLOCK_INPUT;
-         resize_window_apply (r, 0);
+         window_resize_apply (r, 0);
 
          /* Shrink the mini-window.  */
          XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
@@ -4139,12 +4133,12 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
 
   r = XWINDOW (FRAME_ROOT_WINDOW (f));
   height = XINT (r->total_lines) + XINT (w->total_lines);
-  if (resize_window_check (r, 0)
+  if (window_resize_check (r, 0)
       && XINT (w->new_total) > 0
       && height == XINT (r->new_total) + XINT (w->new_total))
     {
       BLOCK_INPUT;
-      resize_window_apply (r, 0);
+      window_resize_apply (r, 0);
 
       w->total_lines = w->new_total;
       XSETFASTINT (w->top_line, XINT (r->top_line) + XINT (r->total_lines));
@@ -4247,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);
 
@@ -4257,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.  */
@@ -4277,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)
     {
@@ -4339,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))
@@ -4417,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
        {
@@ -4430,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.  */
@@ -4577,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);
 }
 
 
@@ -4655,14 +4662,9 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
 
   if (pos < ZV)
     {
-      int this_scroll_margin = scroll_margin;
-
       /* Don't use a scroll margin that is negative or too large.  */
-      if (this_scroll_margin < 0)
-       this_scroll_margin = 0;
-
-      if (XINT (w->total_lines) < 4 * scroll_margin)
-       this_scroll_margin = XINT (w->total_lines) / 4;
+      int this_scroll_margin =
+       max (0, min (scroll_margin, XINT (w->total_lines) / 4));
 
       set_marker_restricted_both (w->start, w->buffer, pos, pos_byte);
       w->start_at_line_beg = bolp;
@@ -4979,6 +4981,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)
     {
@@ -4998,9 +5001,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
@@ -5047,7 +5052,7 @@ and redisplay normally--don't erase and redraw the frame.  */)
   struct buffer *obuf = current_buffer;
   int center_p = 0;
   EMACS_INT charpos, bytepos;
-  int iarg IF_LINT (= 0);
+  EMACS_INT iarg IF_LINT (= 0);
   int this_scroll_margin;
 
   /* If redisplay is suppressed due to an error, try again.  */
@@ -5059,7 +5064,7 @@ and redisplay normally--don't erase and redraw the frame.  */)
          && (!EQ (Vrecenter_redisplay, Qtty)
              || !NILP (Ftty_type (selected_frame))))
        {
-         int i;
+         ptrdiff_t i;
 
          /* Invalidate pixel data calculated for all compositions.  */
          for (i = 0; i < n_compositions; i++)
@@ -5086,9 +5091,8 @@ and redisplay normally--don't erase and redraw the frame.  */)
 
   /* Do this after making BUF current
      in case scroll_margin is buffer-local.  */
-  this_scroll_margin = max (0, scroll_margin);
-  this_scroll_margin = min (this_scroll_margin,
-                           XFASTINT (w->total_lines) / 4);
+  this_scroll_margin =
+    max (0, min (scroll_margin, XFASTINT (w->total_lines) / 4));
 
   /* Handle centering on a graphical frame specially.  Such frames can
      have variable-height lines and centering point on the basis of
@@ -5099,20 +5103,23 @@ 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)
        {
          struct it it;
          struct text_pos pt;
-         int nlines = -iarg;
+         int nlines = min (INT_MAX, -iarg);
          int extra_line_spacing;
          int h = window_box_height (w);
+         void *itdata = bidi_shelve_cache ();
 
          iarg = - max (-iarg, this_scroll_margin);
 
@@ -5150,7 +5157,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);
@@ -5170,6 +5180,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
        {
@@ -5270,15 +5282,14 @@ zero means top of window, negative means relative to bottom of window.  */)
   lines = displayed_window_lines (w);
 
 #if 0
-  this_scroll_margin = max (0, scroll_margin);
-  this_scroll_margin = min (this_scroll_margin, lines / 4);
+  this_scroll_margin = max (0, min (scroll_margin, lines / 4));
 #endif
 
   if (NILP (arg))
     XSETFASTINT (arg, lines / 2);
   else
     {
-      int iarg = XINT (Fprefix_numeric_value (arg));
+      EMACS_INT iarg = XINT (Fprefix_numeric_value (arg));
 
       if (iarg < 0)
        iarg = iarg + lines;
@@ -5336,8 +5347,7 @@ 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;
@@ -5388,6 +5398,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;
 
@@ -5443,12 +5454,15 @@ 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;
       struct window **leaf_windows;
       int n_leaf_windows;
-      int k, i, n;
+      ptrdiff_t k;
+      int i, n;
 
       /* If the frame has been resized since this window configuration was
         made, we change the frame to the size specified in the
@@ -5519,7 +5533,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))
@@ -5552,7 +5567,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))
@@ -5582,55 +5596,70 @@ the return value is nil.  Otherwise the value is t.  */)
 
          /* Reinstall the saved buffer and pointers into it.  */
          if (NILP (p->buffer))
+           /* An internal window.  */
            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))
@@ -5638,10 +5667,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;
@@ -5682,9 +5711,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
@@ -5813,7 +5849,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;
@@ -5930,82 +5965,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
@@ -6365,116 +6324,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;
-  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))
+  struct Lisp_Vector *sws1, *sws2;
+  ptrdiff_t i;
+
+  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;
 
-  /* Verify that the two confis have the same number of windows.  */
-  if (sw1->header.size != sw2->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;
     }
 
@@ -6515,69 +6439,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);
 
-  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);
 
@@ -6597,6 +6482,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;
@@ -6612,16 +6507,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_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
@@ -6698,13 +6593,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);
@@ -6718,7 +6612,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);
@@ -6748,7 +6642,6 @@ function `window-nest' and altered by the function `set-window-nest'.  */);
   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);
@@ -6768,7 +6661,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);