emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r104543: Final preparations for new w


From: martin rudalics
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r104543: Final preparations for new window resize code.
Date: Thu, 09 Jun 2011 08:35:02 +0200
User-agent: Bazaar (2.3.1)

------------------------------------------------------------
revno: 104543
committer: martin rudalics <address@hidden>
branch nick: trunk
timestamp: Thu 2011-06-09 08:35:02 +0200
message:
  Final preparations for new window resize code.
  
  * window.c (replace_window): Rename second argument REPLACEMENT to
  NEW.  New third argument SETFLAG.  Rewrite.
  (delete_window, make_dummy_parent): Call replace_window with
  third argument 1.
  (window_list_1): Move down in code.
  (run_window_configuration_change_hook): Move set_buffer part
  before select_frame_norecord part in order to unwind correctly.
  Rename count1 to count.
  (recombine_windows, delete_deletable_window, resize_root_window)
  (Fdelete_other_windows_internal)
  (Frun_window_configuration_change_hook, make_parent_window)
  (resize_window_check, resize_window_apply, Fresize_window_apply)
  (resize_frame_windows, Fsplit_window_internal)
  (Fdelete_window_internal, Fresize_mini_window_internal): New
  functions.
  (syms_of_window): New variables Vwindow_splits and Vwindow_nest.
modified:
  src/ChangeLog
  src/window.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2011-06-08 13:00:51 +0000
+++ b/src/ChangeLog     2011-06-09 06:35:02 +0000
@@ -1,3 +1,22 @@
+2011-06-09  Martin Rudalics  <address@hidden>
+
+       * window.c (replace_window): Rename second argument REPLACEMENT to
+       NEW.  New third argument SETFLAG.  Rewrite.
+       (delete_window, make_dummy_parent): Call replace_window with
+       third argument 1.
+       (window_list_1): Move down in code.
+       (run_window_configuration_change_hook): Move set_buffer part
+       before select_frame_norecord part in order to unwind correctly.
+       Rename count1 to count.
+       (recombine_windows, delete_deletable_window, resize_root_window)
+       (Fdelete_other_windows_internal)
+       (Frun_window_configuration_change_hook, make_parent_window)
+       (resize_window_check, resize_window_apply, Fresize_window_apply)
+       (resize_frame_windows, Fsplit_window_internal)
+       (Fdelete_window_internal, Fresize_mini_window_internal): New
+       functions.
+       (syms_of_window): New variables Vwindow_splits and Vwindow_nest.
+
 2011-06-08  Martin Rudalics  <address@hidden>
 
        * window.h (window): Add some new members to window structure -

=== modified file 'src/window.c'
--- a/src/window.c      2011-06-08 13:00:51 +0000
+++ b/src/window.c      2011-06-09 06:35:02 +0000
@@ -90,6 +90,7 @@
                              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 Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
 
 /* This is the window in which the terminal's cursor should
@@ -1853,60 +1854,146 @@
     BVAR (b, last_selected_window) = Qnil;
 }
 
-/* Put replacement into the window structure in place of old. */
+/* Put NEW into the window structure in place of OLD.  SETFLAG zero
+   means change window structure only.  Otherwise store geometry and
+   other settings as well.  */
 static void
-replace_window (Lisp_Object old, Lisp_Object replacement)
+replace_window (Lisp_Object old, Lisp_Object new, int setflag)
 {
   register Lisp_Object tem;
-  register struct window *o = XWINDOW (old), *p = XWINDOW (replacement);
-
-  /* If OLD is its frame's root_window, then replacement is the new
-     root_window for that frame.  */
-
+  register struct window *o = XWINDOW (old), *n = XWINDOW (new);
+
+  /* If OLD is its frame's root window, then NEW is the new
+     root window for that frame.  */
   if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame))))
-    FRAME_ROOT_WINDOW (XFRAME (o->frame)) = replacement;
-
-  p->left_col = o->left_col;
-  p->top_line = o->top_line;
-  p->total_cols = o->total_cols;
-  p->total_lines = o->total_lines;
-  p->desired_matrix = p->current_matrix = 0;
-  p->vscroll = 0;
-  memset (&p->cursor, 0, sizeof (p->cursor));
-  memset (&p->last_cursor, 0, sizeof (p->last_cursor));
-  memset (&p->phys_cursor, 0, sizeof (p->phys_cursor));
-  p->phys_cursor_type = -1;
-  p->phys_cursor_width = -1;
-  p->must_be_updated_p = 0;
-  p->pseudo_window_p = 0;
-  XSETFASTINT (p->window_end_vpos, 0);
-  XSETFASTINT (p->window_end_pos, 0);
-  p->window_end_valid = Qnil;
-  p->frozen_window_start_p = 0;
-  p->orig_top_line = p->orig_total_lines = Qnil;
-
-  p->next = tem = o->next;
-  if (!NILP (tem))
-    XWINDOW (tem)->prev = replacement;
-
-  p->prev = tem = o->prev;
-  if (!NILP (tem))
-    XWINDOW (tem)->next = replacement;
-
-  p->parent = tem = o->parent;
+    FRAME_ROOT_WINDOW (XFRAME (o->frame)) = new;
+
+  if (setflag)
+    {
+      n->left_col = o->left_col;
+      n->top_line = o->top_line;
+      n->total_cols = o->total_cols;
+      n->total_lines = o->total_lines;
+      n->normal_cols = o->normal_cols;
+      o->normal_cols = make_float (1.0);
+      n->normal_lines = o->normal_lines;
+      o->normal_lines = make_float (1.0);
+      n->desired_matrix = n->current_matrix = 0;
+      n->vscroll = 0;
+      memset (&n->cursor, 0, sizeof (n->cursor));
+      memset (&n->last_cursor, 0, sizeof (n->last_cursor));
+      memset (&n->phys_cursor, 0, sizeof (n->phys_cursor));
+      n->phys_cursor_type = -1;
+      n->phys_cursor_width = -1;
+      n->must_be_updated_p = 0;
+      n->pseudo_window_p = 0;
+      XSETFASTINT (n->window_end_vpos, 0);
+      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;
+  if (!NILP (tem))
+    XWINDOW (tem)->prev = new;
+
+  n->prev = tem = o->prev;
+  if (!NILP (tem))
+    XWINDOW (tem)->next = new;
+
+  n->parent = tem = o->parent;
   if (!NILP (tem))
     {
       if (EQ (XWINDOW (tem)->vchild, old))
-       XWINDOW (tem)->vchild = replacement;
+       XWINDOW (tem)->vchild = new;
       if (EQ (XWINDOW (tem)->hchild, old))
-       XWINDOW (tem)->hchild = replacement;
-    }
-
-/*** Here, if replacement is a vertical combination
-and so is its new parent, we should make replacement's
-children be children of that parent instead.  ***/
-}
-
+       XWINDOW (tem)->hchild = new;
+    }
+}
+
+/* If window WINDOW and its parent window are iso-combined, merge
+   WINDOW's children into those of its parent window and mark WINDOW as
+   deleted.  */
+
+static void
+recombine_windows (Lisp_Object window)
+{
+  struct window *w, *p, *c;
+  Lisp_Object parent, child;
+  int horflag;
+
+  w = XWINDOW (window);
+  parent = w->parent;
+  if (!NILP (parent) && NILP (w->nest))
+    {
+      p = XWINDOW (parent);
+      if (((!NILP (p->vchild) && !NILP (w->vchild))
+          || (!NILP (p->hchild) && !NILP (w->hchild))))
+       /* WINDOW and PARENT are both either a vertical or a horizontal
+          combination.  */
+       {
+         horflag = NILP (w->vchild);
+         child = horflag ? w->hchild : w->vchild;
+         c = XWINDOW (child);
+
+         /* Splice WINDOW's children into its parent's children and
+            assign new normal sizes.  */
+         if (NILP (w->prev))
+           if (horflag)
+             p->hchild = child;
+           else
+             p->vchild = child;
+         else
+           {
+             c->prev = w->prev;
+             XWINDOW (w->prev)->next = child;
+           }
+
+         while (c)
+           {
+             c->parent = parent;
+
+             if (horflag)
+               c->normal_cols
+                 = make_float (XFLOATINT (c->total_cols)
+                               / XFLOATINT (p->total_cols));
+             else
+               c->normal_lines
+                 = make_float (XFLOATINT (c->total_lines)
+                               / XFLOATINT (p->total_lines));
+
+             if (NILP (c->next))
+               {
+                 if (!NILP (w->next))
+                   {
+                     c->next = w->next;
+                     XWINDOW (c->next)->prev = child;
+                   }
+
+                 c = 0;
+               }
+             else
+               {
+                 child = c->next;
+                 c = XWINDOW (child);
+               }
+           }
+
+         /* WINDOW can be deleted now.  */
+         w->vchild = w->hchild = Qnil;
+       }
+    }
+}
+
+/* If WINDOW can be deleted, delete it.  */
+Lisp_Object
+delete_deletable_window (Lisp_Object window)
+{
+  if (!NILP (call1 (Qwindow_deletable_p, window)))
+    call1 (Qdelete_window, window);
+}
+
 DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "",
        doc: /* Remove WINDOW from its frame.
 WINDOW defaults to the selected window.  Return nil.
@@ -2067,7 +2154,7 @@
   if (NILP (tem))
     tem = par->vchild;
   if (NILP (XWINDOW (tem)->next)) {
-    replace_window (parent, tem);
+    replace_window (parent, tem, 1);
     par = XWINDOW (tem);
   }
 
@@ -2427,43 +2514,6 @@
 }
 
 
-DEFUN ("window-list-1", Fwindow_list_1, Swindow_list_1, 0, 3, 0,
-       doc: /* Return a list of all live windows.
-WINDOW specifies the first window to list and defaults to the selected
-window.
-
-Optional argument MINIBUF nil or omitted means consider the minibuffer
-window only if the minibuffer is active.  MINIBUF t means consider the
-minibuffer window even if the minibuffer is not active.  Any other value
-means do not consider the minibuffer window even if the minibuffer is
-active.
-
-Optional argument ALL-FRAMES nil or omitted means consider all windows
-on WINDOW's frame, plus the minibuffer window if specified by the
-MINIBUF argument.  If the minibuffer counts, consider all windows on all
-frames that share that minibuffer too.  The following non-nil values of
-ALL-FRAMES have special meanings:
-
-- t means consider all windows on all existing frames.
-
-- `visible' means consider all windows on all visible frames.
-
-- 0 (the number zero) means consider all windows on all visible and
-  iconified frames.
-
-- A frame means consider all windows on that frame only.
-
-Anything else means consider all windows on WINDOW's frame and no
-others.
-
-If WINDOW is not on the list of windows returned, some other window will
-be listed first but no error is signalled.  */)
-  (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames)
-{
-  return window_list_1 (window, minibuf, all_frames);
-}
-
-
 DEFUN ("other-window", Fother_window, Sother_window, 1, 2, "p",
        doc: /* Select another window in cyclic ordering of windows.
 COUNT specifies the number of windows to skip, starting with the
@@ -2547,6 +2597,41 @@
 }
 
 
+DEFUN ("window-list-1", Fwindow_list_1, Swindow_list_1, 0, 3, 0,
+       doc: /* Return a list of all live windows.
+WINDOW specifies the first window to list and defaults to the selected
+window.
+
+Optional argument MINIBUF nil or omitted means consider the minibuffer
+window only if the minibuffer is active.  MINIBUF t means consider the
+minibuffer window even if the minibuffer is not active.  Any other value
+means do not consider the minibuffer window even if the minibuffer is
+active.
+
+Optional argument ALL-FRAMES nil or omitted means consider all windows
+on WINDOW's frame, plus the minibuffer window if specified by the
+MINIBUF argument.  If the minibuffer counts, consider all windows on all
+frames that share that minibuffer too.  The following non-nil values of
+ALL-FRAMES have special meanings:
+
+- t means consider all windows on all existing frames.
+
+- `visible' means consider all windows on all visible frames.
+
+- 0 (the number zero) means consider all windows on all visible and
+  iconified frames.
+
+- A frame means consider all windows on that frame only.
+
+Anything else means consider all windows on WINDOW's frame and no
+others.
+
+If WINDOW is not on the list of windows returned, some other window will
+be listed first but no error is signalled.  */)
+  (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames)
+{
+  return window_list_1 (window, minibuf, all_frames);
+}
 
 /* Look at all windows, performing an operation specified by TYPE
    with argument OBJ.
@@ -2801,6 +2886,248 @@
     return Qnil;
 }
 
+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);
+}
+
+
+DEFUN ("delete-other-windows-internal", Fdelete_other_windows_internal,
+       Sdelete_other_windows_internal, 0, 2, "",
+       doc: /* Make WINDOW fill its frame.
+Only the frame WINDOW is on is affected.  WINDOW may be any window and
+defaults to the selected one.
+
+Optional argument ROOT, if non-nil, must specify an internal window
+containing WINDOW as a subwindow.  If this is the case, replace ROOT by
+WINDOW and leave alone any windows not contained in ROOT.
+
+When WINDOW is live try 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, Lisp_Object root)
+{
+  struct window *w, *r, *s;
+  struct frame *f;
+  Lisp_Object sibling, pwindow, swindow, delta;
+  EMACS_INT startpos;
+  int top, new_top, resize_failed;
+
+  w = decode_any_window (window);
+  XSETWINDOW (window, w);
+  f = XFRAME (w->frame);
+
+  if (NILP (root))
+    /* ROOT is the frame's root window.  */
+    {
+      root = FRAME_ROOT_WINDOW (f);
+      r = XWINDOW (root);
+    }
+  else
+    /* ROOT must be an ancestor of WINDOW.  */
+    {
+      r = decode_any_window (root);
+      pwindow = XWINDOW (window)->parent;
+      while (!NILP (pwindow))
+       if (EQ (pwindow, root))
+         break;
+       else
+         pwindow = XWINDOW (pwindow)->parent;
+      if (!EQ (pwindow, root))
+       error ("Specified root is not an ancestor of specified window");
+    }
+
+  if (EQ (window, root))
+    /* A noop.  */
+    return Qnil;
+  /* I don't understand the "top > 0" part below.  If we deal with a
+     standalone minibuffer it would have been caught by the preceding
+     test.  */
+  else if (MINI_WINDOW_P (w)) /* && top > 0) */
+    error ("Can't expand minibuffer to full frame");
+
+  if (!NILP (w->buffer))
+    {
+      startpos = marker_position (w->start);
+      top = WINDOW_TOP_EDGE_LINE (w)
+       - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
+      /* Make sure WINDOW is the frame's selected window.  */
+      if (!EQ (window, FRAME_SELECTED_WINDOW (f)))
+       {
+         if (EQ (selected_frame, w->frame))
+           Fselect_window (window, Qnil);
+         else
+           FRAME_SELECTED_WINDOW (f) = window;
+       }
+    }
+  else
+    {
+      /* See if the frame's selected window is a subwindow of WINDOW, by
+        finding all the selected window's parents and comparing each
+        one with WINDOW.  If it isn't we need a new selected window for
+        this frame.  */
+      swindow = FRAME_SELECTED_WINDOW (f);
+      while (1)
+       {
+         pwindow = swindow;
+         while (!NILP (pwindow) && !EQ (window, pwindow))
+           pwindow = XWINDOW (pwindow)->parent;
+
+         if (EQ (window, pwindow))
+           /* If WINDOW is an ancestor of SWINDOW, then SWINDOW is ok
+              as the new selected window.  */
+           break;
+         else
+           /* Else try the previous window of SWINDOW.  */
+           swindow = Fprevious_window (swindow, Qlambda, Qnil);
+       }
+
+      if (!EQ (swindow, FRAME_SELECTED_WINDOW (f)))
+       {
+         if (EQ (selected_frame, w->frame))
+           Fselect_window (swindow, Qnil);
+         else
+           FRAME_SELECTED_WINDOW (f) = swindow;
+       }
+    }
+
+  BLOCK_INPUT;
+  free_window_matrices (r);
+
+  windows_or_buffers_changed++;
+  Vwindow_list = Qnil;
+  FRAME_WINDOW_SIZES_CHANGED (f) = 1;
+
+  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);
+      else
+       {
+         resize_root_window (window, delta, Qnil, Qt);
+         if (resize_window_check (w, 0))
+           resize_window_apply (w, 0);
+         else
+           resize_failed = 1;
+       }
+
+      /* Resize subwindows horizontally.  */
+      if (!resize_failed)
+       {
+         w->left_col = r->left_col;
+         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);
+         else
+           {
+             resize_root_window (window, delta, Qt, Qt);
+             if (resize_window_check (w, 1))
+               resize_window_apply (w, 1);
+             else
+               resize_failed = 1;
+           }
+       }
+
+      if (resize_failed)
+       /* Play safe, if we still can ...  */
+       {
+         window = swindow;
+         w = XWINDOW (window);
+       }
+    }
+
+  /* Cleanly unlink WINDOW from window-tree.  */
+  if (!NILP (w->prev))
+    /* Get SIBLING above (on the left of) WINDOW.  */
+    {
+      sibling = w->prev;
+      s = XWINDOW (sibling);
+      s->next = w->next;
+      if (!NILP (s->next))
+       XWINDOW (s->next)->prev = sibling;
+    }
+  else
+    /* Get SIBLING below (on the right of) WINDOW.  */
+    {
+      sibling = w->next;
+      s = XWINDOW (sibling);
+      s->prev = Qnil;
+      if (!NILP (XWINDOW (w->parent)->vchild))
+       XWINDOW (w->parent)->vchild = sibling;
+      else
+       XWINDOW (w->parent)->hchild = sibling;
+    }
+
+  /* Delete ROOT and all subwindows of ROOT.  */
+  if (!NILP (r->vchild))
+    {
+      delete_all_subwindows (r->vchild);
+      r->vchild = Qnil;
+    }
+  else if (!NILP (r->hchild))
+    {
+      delete_all_subwindows (r->hchild);
+      r->hchild = Qnil;
+    }
+
+  replace_window (root, window, 1);
+
+  /* Reset WINDOW's splits status.  */
+  w->splits = Qnil;
+
+  /* This must become SWINDOW anyway ....... */
+  if (!NILP (w->buffer) && !resize_failed)
+    {
+      /* 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);
+       }
+    }
+
+  adjust_glyphs (f);
+  UNBLOCK_INPUT;
+
+  run_window_configuration_change_hook (f);
+
+  return Qnil;
+}
+
+
 DEFUN ("delete-other-windows", Fdelete_other_windows, Sdelete_other_windows,
        0, 1, "",
        doc: /* Make WINDOW (or the selected window) fill its frame.
@@ -3676,12 +4003,6 @@
   if (NILP (Vrun_hooks))
     return;
 
-  if (SELECTED_FRAME () != f)
-    {
-      record_unwind_protect (select_frame_norecord, Fselected_frame ());
-      Fselect_frame (frame, Qt);
-    }
-
   /* Use the right buffer.  Matters when running the local hooks.  */
   if (current_buffer != XBUFFER (Fwindow_buffer (Qnil)))
     {
@@ -3689,6 +4010,12 @@
       Fset_buffer (Fwindow_buffer (Qnil));
     }
 
+  if (SELECTED_FRAME () != f)
+    {
+      record_unwind_protect (select_frame_norecord, Fselected_frame ());
+      select_frame_norecord (frame);
+    }
+
   /* Look for buffer-local values.  */
   {
     Lisp_Object windows = Fwindow_list (frame, Qlambda, Qnil);
@@ -3699,12 +4026,12 @@
        if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook,
                                      buffer)))
          {
-           int count1 = SPECPDL_INDEX ();
+           int 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 (count1, Qnil);
+           unbind_to (count, Qnil);
          }
       }
   }
@@ -3713,6 +4040,16 @@
   unbind_to (count, Qnil);
 }
 
+DEFUN ("run-window-configuration-change-hook", 
Frun_window_configuration_change_hook,
+       Srun_window_configuration_change_hook, 1, 1, 0,
+       doc: /* Run `window-configuration-change-hook' for FRAME.  */)
+     (Lisp_Object frame)
+{
+  CHECK_LIVE_FRAME (frame);
+  run_window_configuration_change_hook (XFRAME (frame));
+  return Qnil;
+}
+
 /* Make WINDOW display BUFFER as its contents.  RUN_HOOKS_P non-zero
    means it's allowed to run hooks.  See make_frame for a case where
    it's not allowed.  KEEP_MARGINS_P non-zero means that the current
@@ -4019,7 +4356,7 @@
   XSETFASTINT (p->clone_number, sequence_number);
 
   /* Put new into window structure in place of window */
-  replace_window (window, new);
+  replace_window (window, new, 1);
 
   o->next = Qnil;
   o->prev = Qnil;
@@ -4037,6 +4374,43 @@
 
 }
 
+/* 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).   */
+static void
+make_parent_window (Lisp_Object window, int horflag)
+{
+  Lisp_Object parent;
+  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 (parent, p);
+
+  ++sequence_number;
+  XSETFASTINT (p->sequence_number, sequence_number);
+  XSETFASTINT (p->clone_number, sequence_number);
+
+  replace_window (window, parent, 1);
+
+  o->next = Qnil;
+  o->prev = Qnil;
+  o->parent = parent;
+
+  p->hchild = horflag ? window : Qnil;
+  p->vchild = horflag ? Qnil : window;
+  p->start = Qnil;
+  p->pointm = Qnil;
+  p->buffer = Qnil;
+  p->splits = Qnil;
+  p->nest = Qnil;
+  p->window_parameters = Qnil;
+}
+
 /* Make new window from scratch.  */
 Lisp_Object
 make_window (void)
@@ -4138,6 +4512,654 @@
   return w->new_normal;
 }
 
+/* Return 1 if setting w->total_lines (w->total_cols if HORFLAG is
+   non-zero) to w->new_total would result in correct heights (widths)
+   for window W and recursively all subwindows of W.
+
+   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)
+{
+  struct window *c;
+
+  if (!NILP (w->vchild))
+    /* W is a vertical combination.  */
+    {
+      c = XWINDOW (w->vchild);
+      if (horflag)
+       /* All subwindows of W must have the same width as W.  */
+       {
+         while (c)
+           {
+             if ((XINT (c->new_total) != XINT (w->new_total))
+                 || !resize_window_check (c, horflag))
+               return 0;
+             c = NILP (c->next) ? 0 : XWINDOW (c->next);
+           }
+         return 1;
+       }
+      else
+       /* The sum of the heights of the subwindows of W must equal W's
+          height.  */
+       {
+         int sum_of_sizes = 0;
+         while (c)
+           {
+             if (!resize_window_check (c, horflag))
+               return 0;
+             sum_of_sizes = sum_of_sizes + XINT (c->new_total);
+             c = NILP (c->next) ? 0 : XWINDOW (c->next);
+           }
+         return (sum_of_sizes == XINT (w->new_total));
+       }
+    }
+  else if (!NILP (w->hchild))
+    /* W is a horizontal combination.  */
+    {
+      c = XWINDOW (w->hchild);
+      if (horflag)
+       /* The sum of the widths of the subwindows of W must equal W's
+          width.  */
+       {
+         int sum_of_sizes = 0;
+         while (c)
+           {
+             if (!resize_window_check (c, horflag))
+               return 0;
+             sum_of_sizes = sum_of_sizes + XINT (c->new_total);
+             c = NILP (c->next) ? 0 : XWINDOW (c->next);
+           }
+         return (sum_of_sizes == XINT (w->new_total));
+       }
+      else
+       /* All subwindows of W must have the same height as W.  */
+       {
+         while (c)
+           {
+             if ((XINT (c->new_total) != XINT (w->new_total))
+                 || !resize_window_check (c, horflag))
+               return 0;
+             c = NILP (c->next) ? 0 : XWINDOW (c->next);
+           }
+         return 1;
+       }
+    }
+  else
+    /* A leaf window.  Make sure it's not too small.  The following
+       hardcodes the values of `window-safe-min-width' (2) and
+       `window-safe-min-height' (1) which are defined in window.el.  */
+    return XINT (w->new_total) >= (horflag ? 2 : 1);
+}
+
+/* Set w->total_lines (w->total_cols if HORIZONTAL is non-zero) to
+   w->new_total for window W and recursively all subwindows of W.  Also
+   calculate and assign the new vertical (horizontal) start positions of
+   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)
+{
+  struct window *c, *p;
+  int pos;
+
+  /* Note: Assigning new_normal requires that the new total size of the
+     parent window has been set *before*.  */
+  if (horflag)
+    {
+      w->total_cols = w->new_total;
+      if (NUMBERP (w->new_normal))
+       w->normal_cols = w->new_normal;
+
+      pos = XINT (w->left_col);
+    }
+  else
+    {
+      w->total_lines = w->new_total;
+      if (NUMBERP (w->new_normal))
+       w->normal_lines = w->new_normal;
+
+      pos = XINT (w->top_line);
+    }
+
+  if (!NILP (w->vchild))
+    /* W is a vertical combination.  */
+    {
+      c = XWINDOW (w->vchild);
+      while (c)
+       {
+         if (horflag)
+           XSETFASTINT (c->left_col, pos);
+         else
+           XSETFASTINT (c->top_line, pos);
+         resize_window_apply (c, horflag);
+         if (!horflag)
+           pos = pos + XINT (c->total_lines);
+         c = NILP (c->next) ? 0 : XWINDOW (c->next);
+       }
+    }
+  else if (!NILP (w->hchild))
+    /* W is a horizontal combination.  */
+    {
+      c = XWINDOW (w->hchild);
+      while (c)
+       {
+         if (horflag)
+           XSETFASTINT (c->left_col, pos);
+         else
+           XSETFASTINT (c->top_line, pos);
+         resize_window_apply (c, horflag);
+         if (horflag)
+           pos = pos + XINT (c->total_cols);
+         c = NILP (c->next) ? 0 : XWINDOW (c->next);
+       }
+    }
+
+  /* Clear out some redisplay caches.  */
+  XSETFASTINT (w->last_modified, 0);
+  XSETFASTINT (w->last_overlay_modified, 0);
+}
+
+
+DEFUN ("resize-window-apply", Fresize_window_apply, Sresize_window_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.
+
+This function checks whether the requested values sum up to a valid
+window layout, recursively assigns the new sizes of all subwindows and
+calculates and assigns the new start positions of these windows.
+
+Note: This function does not check any of `window-fixed-size-p',
+`window-min-height' or `window-min-width'.  All these checks have to
+be applied on the Elisp level.  */)
+     (Lisp_Object frame, Lisp_Object horizontal)
+{
+  struct frame *f;
+  struct window *r;
+  int horflag = !NILP (horizontal);
+
+  if (NILP (frame))
+    frame = selected_frame;
+  CHECK_LIVE_FRAME (frame);
+
+  f = XFRAME (frame);
+  r = XWINDOW (FRAME_ROOT_WINDOW (f));
+
+  if (!resize_window_check (r, horflag)
+      || ! EQ (r->new_total, (horflag ? r->total_cols : r->total_lines)))
+    return Qnil;
+
+  BLOCK_INPUT;
+  resize_window_apply (r, horflag);
+
+  windows_or_buffers_changed++;
+  FRAME_WINDOW_SIZES_CHANGED (f) = 1;
+
+  adjust_glyphs (f);
+  UNBLOCK_INPUT;
+
+  run_window_configuration_change_hook (f);
+
+  return Qt;
+}
+
+
+/* Resize frame F's windows when number of lines of F is set to SIZE.
+   HORFLAG 1 means resize windows when number of columns of F is set to
+   SIZE.
+
+   This function can delete all windows but the selected one in order to
+   satisfy the request.  The result will be meaningful if and only if
+   F's windows have meaningful sizes when you call this.  */
+void
+resize_frame_windows (struct frame *f, int size, int horflag)
+{
+  Lisp_Object root = f->root_window;
+  struct window *r = XWINDOW (root);
+  Lisp_Object mini = f->minibuffer_window;
+  struct window *m;
+  /* new_size is the new size of the frame's root window.  */
+  int new_size = (horflag
+                 ? size
+                 : (size
+                    - FRAME_TOP_MARGIN (f)
+                    - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
+                       ? 1 : 0)));
+
+  XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f));
+  if (NILP (r->vchild) && NILP (r->hchild))
+    /* For a leaf root window just set the size.  */
+    if (horflag)
+      XSETFASTINT (r->total_cols, new_size);
+    else
+      XSETFASTINT (r->total_lines, new_size);
+  else
+    {
+      /* old_size is the old size of the frame's root window.  */
+      int old_size = XFASTINT (horflag ? r->total_cols : r->total_lines);
+      Lisp_Object delta;
+
+      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);
+      else
+       {
+         /* Try with "reasonable" minimum sizes next.  */
+         resize_root_window (root, delta, horflag ? Qt : Qnil, Qt);
+         if (resize_window_check (r, horflag)
+             && new_size == XINT (r->new_total))
+           resize_window_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)
+                 && new_size == XINT (r->new_total))
+               resize_window_apply (r, horflag);
+             else
+               {
+                 /* We lost.  Delete all windows but the frame's
+                    selected one.  */
+                 root = f->selected_window;
+                 Fdelete_other_windows_internal (root, Qnil);
+                 if (horflag)
+                   XSETFASTINT (XWINDOW (root)->total_cols, new_size);
+                 else
+                   XSETFASTINT (XWINDOW (root)->total_lines, new_size);
+               }
+           }
+       }
+    }
+
+  if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
+    {
+      m = XWINDOW (mini);
+      if (horflag)
+       XSETFASTINT (m->total_cols, size);
+      else
+       {
+         /* Are we sure we always want 1 line here?  */
+         XSETFASTINT (m->total_lines, 1);
+         XSETFASTINT (m->top_line, XINT (r->top_line) + XINT (r->total_lines));
+       }
+    }
+}
+
+
+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 
+
+Third argument SIDE nil (or `below') specifies that the new window shall
+be located below WINDOW.  SIDE `above' means the new window shall be
+located above WINDOW.  In both cases TOTAL-SIZE specifies the number of
+lines of the new window including space reserved for the mode and/or
+header line.
+
+SIDE t (or `right') specifies that the new window shall be located on
+the right side of WINDOW.  SIDE `left' means the new window shall be
+located on the left of WINDOW.  In both cases TOTAL-SIZE specifies the
+number of columns of the new window including space reserved for fringes
+and the scrollbar or a divider column.
+
+Fourth argument NORMAL-SIZE specifies the normal size of the new window
+according to the SIDE argument.
+
+The new total and normal sizes of all involved windows must have been
+set correctly.  See the code of `split-window' for how this is done.  */)
+  (Lisp_Object old, Lisp_Object total_size, Lisp_Object side, Lisp_Object 
normal_size)
+{
+  /* OLD (*o) is the window we have to split.  (*p) is either OLD's
+     parent window or an internal window we have to install as OLD's new
+     parent.  REFERENCE (*r) must denote a live window, or is set to OLD
+     provided OLD is a leaf window, or to the frame's selected window.
+     NEW (*n) is the new window created with some parameters taken from
+     REFERENCE (*r).  */
+  register Lisp_Object new, frame, reference;
+  register struct window *o, *p, *n, *r;
+  struct frame *f;
+  int horflag
+    /* HORFLAG is 1 when we split side-by-side, 0 otherwise.  */
+    = EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright);
+  int do_nest = 0;
+
+  CHECK_WINDOW (old);
+  o = XWINDOW (old);
+  frame = WINDOW_FRAME (o);
+  f = XFRAME (frame);
+
+  CHECK_NUMBER (total_size);
+
+  /* Set do_nest to 1 if we have to make a new parent window.  We do
+     that if either `window-nest' is non-nil, or OLD has no parent, or
+     OLD is ortho-combined.  */
+  do_nest =
+    !NILP (Vwindow_nest)
+    || NILP (o->parent)
+    || NILP (horflag
+            ? (XWINDOW (o->parent)->hchild)
+            : (XWINDOW (o->parent)->vchild));
+
+  /* We need a live reference window to initialize some parameters.  */
+  if (WINDOW_LIVE_P (old))
+    /* OLD is live, use it as reference window.  */
+    reference = old;
+  else
+    /* Use the frame's selected window as reference window.  */
+    reference = FRAME_SELECTED_WINDOW (f);
+  r = XWINDOW (reference);
+
+  /* The following bugs are caught by `split-window'.  */
+  if (MINI_WINDOW_P (o))
+    error ("Attempt to split minibuffer window");
+  else if (XINT (total_size) < (horflag ? 2 : 1))
+    error ("Size of new window too small (after split)");
+  else if (!do_nest && !NILP (Vwindow_splits))
+    /* `window-splits' non-nil means try to resize OLD's siblings
+       proportionally.  */
+    {
+      p = XWINDOW (o->parent);
+      /* Temporarily pretend we split the parent window.  */
+      XSETINT (p->new_total,
+              XINT (horflag ? p->total_cols : p->total_lines)
+              - XINT (total_size));
+      if (!resize_window_check (p, horflag))
+       error ("Window sizes don't fit");
+      else
+       /* Undo the temporary pretension.  */
+       p->new_total = horflag ? p->total_cols : p->total_lines;
+    }
+  else
+    {
+      if (!resize_window_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))
+       error ("Sum of sizes of old and new window don't fit");
+    }
+
+  /* This is our point of no return. */
+  if (do_nest)
+    {
+      /* Save the old value of o->normal_cols/lines.  It gets corrupted
+        by make_parent_window and we need it below for assigning it to
+        p->new_normal.  */
+      Lisp_Object new_normal = horflag ? o->normal_cols : o->normal_lines;
+
+      make_parent_window (old, horflag);
+      p = XWINDOW (o->parent);
+      /* Store value of `window-nest' in new parent's nest slot.  */
+      p->nest = Vwindow_nest;
+      /* Have PARENT inherit splits slot value from OLD.  */
+      p->splits = o->splits;
+      /* Store value of `window-splits' in OLD's splits slot.  */
+      o->splits = Vwindow_splits;
+      /* These get applied below.  */
+      p->new_total = horflag ? o->total_cols : o->total_lines;
+      p->new_normal = new_normal;
+    }
+  else
+    p = XWINDOW (o->parent);
+
+  windows_or_buffers_changed++;
+  FRAME_WINDOW_SIZES_CHANGED (f) = 1;
+  new = make_window ();
+  n = XWINDOW (new);
+  n->frame = frame;
+  n->parent = o->parent;
+  n->vchild = n->hchild = Qnil;
+
+  if (EQ (side, Qabove) || EQ (side, Qleft))
+    {
+      n->prev = o->prev;
+      if (NILP (n->prev))
+       if (horflag)
+         p->hchild = new;
+       else
+         p->vchild = new;
+      else
+       XWINDOW (n->prev)->next = new;
+      n->next = old;
+      o->prev = new;
+    }
+  else
+    {
+      n->next = o->next;
+      if (!NILP (n->next))
+       XWINDOW (n->next)->prev = new;
+      n->prev = old;
+      o->next = new;
+    }
+
+  n->buffer = Qt;
+  n->window_end_valid = Qnil;
+  memset (&n->last_cursor, 0, sizeof n->last_cursor);
+
+  /* Get special geometry settings from reference window.  */
+  n->left_margin_cols = r->left_margin_cols;
+  n->right_margin_cols = r->right_margin_cols;
+  n->left_fringe_width = r->left_fringe_width;
+  n->right_fringe_width = r->right_fringe_width;
+  n->fringes_outside_margins = r->fringes_outside_margins;
+  n->scroll_bar_width = r->scroll_bar_width;
+  n->vertical_scroll_bar_type = r->vertical_scroll_bar_type;
+
+  /* Store `window-splits' in NEW's splits slot.  */
+  n->splits = Vwindow_splits;
+
+  /* Directly assign orthogonal coordinates and sizes.  */
+  if (horflag)
+    {
+      n->top_line = o->top_line;
+      n->total_lines = o->total_lines;
+    }
+  else
+    {
+      n->left_col = o->left_col;
+      n->total_cols = o->total_cols;
+    }
+
+  /* Iso-coordinates and sizes are assigned by resize_window_apply,
+     get them ready here.  */
+  n->new_total = total_size;
+  n->new_normal = normal_size;
+
+  BLOCK_INPUT;
+  resize_window_apply (p, horflag);
+  adjust_glyphs (f);
+  /* Set buffer of NEW to buffer of reference window.  Don't run
+     any hooks.  */
+  set_window_buffer (new, r->buffer, 0, 1);
+  UNBLOCK_INPUT;
+
+  /* Maybe we should run the scroll functions in Elisp (which already
+     runs the configuration change hook).  */
+  if (! NILP (Vwindow_scroll_functions))
+    run_hook_with_args_2 (Qwindow_scroll_functions, new,
+                         Fmarker_position (n->start));
+  /* Return NEW.  */
+  return new;
+}
+
+
+DEFUN ("delete-window-internal", Fdelete_window_internal, 
Sdelete_window_internal, 1, 1, 0,
+       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)
+{
+  register Lisp_Object parent, sibling, frame, root;
+  struct window *w, *p, *s, *r;
+  struct frame *f;
+  int horflag;
+  int before_sibling = 0;
+
+  w = decode_any_window (window);
+  XSETWINDOW (window, w);
+  if (NILP (w->buffer) && NILP (w->hchild) && NILP (w->vchild))
+    /* It's a no-op to delete an already deleted window.  */
+    return Qnil;
+
+  parent = w->parent;
+  if (NILP (parent))
+    /* Never delete a minibuffer or frame root window.  */
+    error ("Attempt to delete minibuffer or sole ordinary window");
+  else if (NILP (w->prev) && NILP (w->next))
+    /* Rather bow out here, this case should be handled on the Elisp
+       level.  */
+    error ("Attempt to delete sole window of parent");
+
+  p = XWINDOW (parent);
+  horflag = NILP (p->vchild);
+
+  frame = WINDOW_FRAME (w);
+  f = XFRAME (frame);
+
+  root = FRAME_ROOT_WINDOW (f);
+  r = XWINDOW (root);
+
+  /* Unlink WINDOW from window tree.  */
+  if (NILP (w->prev))
+    /* Get SIBLING below (on the right of) WINDOW.  */
+    {
+      /* before_sibling 1 means WINDOW is the first child of its
+        parent and thus before the sibling.  */
+      before_sibling = 1;
+      sibling = w->next;
+      s = XWINDOW (sibling);
+      s->prev = Qnil;
+      if (horflag)
+       p->hchild = sibling;
+      else
+       p->vchild = sibling;
+    }
+  else
+    /* Get SIBLING above (on the left of) WINDOW.  */
+    {
+      sibling = w->prev;
+      s = XWINDOW (sibling);
+      s->next = w->next;
+      if (!NILP (s->next))
+       XWINDOW (s->next)->prev = sibling;
+    }
+
+  if (resize_window_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);
+
+      windows_or_buffers_changed++;
+      Vwindow_list = Qnil;
+      FRAME_WINDOW_SIZES_CHANGED (f) = 1;
+
+      w->next = Qnil;  /* Don't delete w->next too.  */
+      free_window_matrices (w);
+
+      if (!NILP (w->vchild))
+       {
+         delete_all_subwindows (w->vchild);
+         w->vchild = Qnil;
+       }
+      else if (!NILP (w->hchild))
+       {
+         delete_all_subwindows (w->hchild);
+         w->hchild = Qnil;
+       }
+      else if (!NILP (w->buffer))
+       {
+         unshow_buffer (w);
+         unchain_marker (XMARKER (w->pointm));
+         unchain_marker (XMARKER (w->start));
+         w->buffer = Qnil;
+       }
+
+      if (NILP (s->prev) && NILP (s->next))
+         /* A matrjoshka where SIBLING has become the only child of
+            PARENT.  */
+       {
+         /* Put SIBLING into PARENT's place.  */
+         replace_window (parent, sibling, 0);
+         /* Have SIBLING inherit the following three slot values from
+            PARENT (the nest slot is not inherited).  */
+         s->normal_cols = p->normal_cols;
+         s->normal_lines = p->normal_lines;
+         s->splits = p->splits;
+         /* Mark PARENT as deleted.  */
+         p->vchild = p->hchild = Qnil;
+         /* Try to merge SIBLING into its new parent.  */
+         recombine_windows (sibling);
+       }
+
+      adjust_glyphs (f);
+
+      if (!WINDOW_LIVE_P (FRAME_SELECTED_WINDOW (f)))
+       /* We deleted the frame's selected window.  */
+       {
+         /* Use the frame's first window as fallback ...  */
+         Lisp_Object new_selected_window = Fframe_first_window (frame);
+         /* ... but preferably use its most recently used window.  */
+         Lisp_Object mru_window;
+
+         /* `get-mru-window' might fail for some reason so play it safe
+         - 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.
@@ -4279,6 +5301,46 @@
   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");
+}
 
 DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 2, "p",
        doc: /* Make selected window SIZE lines taller.
@@ -7527,6 +8589,41 @@
 frame to be redrawn only if it is a tty frame.  */);
   Vrecenter_redisplay = Qtty;
 
+  DEFVAR_LISP ("window-splits", Vwindow_splits,
+              doc: /* Non-nil means splitting windows is handled specially.
+If this variable is nil, splitting a window gets the entire screen space
+for displaying the new window from the window to split.  If this
+variable is non-nil, splitting a window may resize all windows in the
+same combination.  This also allows to split a window that is otherwise
+too small or of fixed size.
+
+The value of this variable is also assigned to the split status of the
+new window and, provided the old and new window form a new combination,
+to the window that was split as well.  The split status of a window can
+be retrieved with the function `window-splits' and altered by the
+function `set-window-splits'.
+
+If the value of the variable `window-nest' is non-nil, the space for the
+new window is exclusively taken from the window that shall be split, but
+the split status of the window that is split as well as that of the new
+window are still set to the value of this variable.  */);
+  Vwindow_splits = Qnil;
+
+  DEFVAR_LISP ("window-nest", Vwindow_nest,
+              doc: /* Non-nil means splitting a window makes a new parent 
window.
+If this variable is nil, splitting a window will create a new parent
+window only if the window has no parent window or the window shall
+become a combination orthogonal to the one it it is part of.
+
+If this variable is non-nil, splitting a window always creates a new
+parent window.  If all splits behave this way, each frame's window tree
+is a binary tree and every window but the frame's root window has
+exactly one sibling.
+
+The value of this variable is also assigned to the nest status of the
+new parent window.  The nest status of a window can be retrieved via the
+function `window-nest' and altered by the function `set-window-nest'.  */);
+  Vwindow_nest = Qnil;
 
   defsubr (&Sselected_window);
   defsubr (&Sminibuffer_window);
@@ -7560,6 +8657,7 @@
   defsubr (&Swindow_new_normal);
   defsubr (&Sset_window_new_total);
   defsubr (&Sset_window_new_normal);
+  defsubr (&Sresize_window_apply);
   defsubr (&Swindow_body_size);
   defsubr (&Swindow_hscroll);
   defsubr (&Sset_window_hscroll);
@@ -7590,12 +8688,17 @@
   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);


reply via email to

[Prev in Thread] Current Thread [Next in Thread]