* window.c (run_window_configuration_change_hook): New function.
[bpt/emacs.git] / src / window.c
index f1c3a6e..5b0d8f4 100644 (file)
@@ -1,7 +1,8 @@
 /* Window creation, deletion and examination for GNU Emacs.
    Does not include redisplay.
    Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
-                 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+                 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+                 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -21,6 +22,8 @@ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 Boston, MA 02110-1301, USA.  */
 
 #include <config.h>
+#include <stdio.h>
+
 #include "lisp.h"
 #include "buffer.h"
 #include "keyboard.h"
@@ -34,6 +37,7 @@ Boston, MA 02110-1301, USA.  */
 #include "dispextern.h"
 #include "blockinput.h"
 #include "intervals.h"
+#include "termhooks.h"         /* For FRAME_TERMINAL.  */
 
 #ifdef HAVE_X_WINDOWS
 #include "xterm.h"
@@ -190,6 +194,10 @@ Lisp_Object Qtemp_buffer_show_hook;
 
 EMACS_INT split_height_threshold;
 
+/* How to split windows (horizontally/vertically/hybrid).  */
+
+Lisp_Object Vsplit_window_preferred_function;
+
 /* Number of lines of continuity in scrolling by screenfuls.  */
 
 EMACS_INT next_screen_context_lines;
@@ -557,6 +565,15 @@ use  (let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))).  */)
   return make_number (window_box_text_cols (decode_any_window (window)));
 }
 
+DEFUN ("window-full-width-p", Fwindow_full_width_p, Swindow_full_width_p, 0, 1, 0,
+       doc: /* Return t if WINDOW is as wide as its frame.
+WINDOW defaults to the selected window.  */)
+     (window)
+     Lisp_Object window;
+{
+  return WINDOW_FULL_WIDTH_P (decode_any_window (window)) ? Qt : Qnil;
+}
+
 DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
        doc: /* Return the number of columns by which WINDOW is scrolled from left margin.
 WINDOW defaults to the selected window.  */)
@@ -783,7 +800,7 @@ coordinates_in_window (w, x, y)
       if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
          || WINDOW_RIGHTMOST_P (w))
        {
-         if (!WINDOW_LEFTMOST_P (w) && abs (*x - x0) < grabbable_width)
+         if (!WINDOW_LEFTMOST_P (w) && eabs (*x - x0) < grabbable_width)
            {
              /* Convert X and Y to window relative coordinates.
                 Vertical border is at the left edge of window.  */
@@ -794,7 +811,7 @@ coordinates_in_window (w, x, y)
        }
       else
        {
-         if (abs (*x - x1) < grabbable_width)
+         if (eabs (*x - x1) < grabbable_width)
            {
              /* Convert X and Y to window relative coordinates.
                 Vertical border is at the right edge of window.  */
@@ -842,7 +859,7 @@ coordinates_in_window (w, x, y)
       if (!w->pseudo_window_p
          && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
          && !WINDOW_RIGHTMOST_P (w)
-         && (abs (*x - right_x) < grabbable_width))
+         && (eabs (*x - right_x) < grabbable_width))
        {
          /* Convert X and Y to window relative coordinates.
             Vertical border is at the right edge of window.  */
@@ -1779,12 +1796,28 @@ candidate_window_p (window, owindow, minibuf, all_frames)
   else if (EQ (all_frames, Qvisible))
     {
       FRAME_SAMPLE_VISIBILITY (f);
-      candidate_p = FRAME_VISIBLE_P (f);
+      candidate_p = FRAME_VISIBLE_P (f)
+       && (FRAME_TERMINAL (XFRAME (w->frame))
+           == FRAME_TERMINAL (XFRAME (selected_frame)));
+
     }
   else if (INTEGERP (all_frames) && XINT (all_frames) == 0)
     {
       FRAME_SAMPLE_VISIBILITY (f);
-      candidate_p = FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f);
+      candidate_p = (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)
+#ifdef HAVE_X_WINDOWS
+                    /* Yuck!!  If we've just created the frame and the
+                       window-manager requested the user to place it
+                       manually, the window may still not be considered
+                       `visible'.  I'd argue it should be at least
+                       something like `iconified', but don't know how to do
+                       that yet.  --Stef  */
+                    || (FRAME_X_P (f) && f->output_data.x->asked_for_visible
+                        && !f->output_data.x->has_been_visible)
+#endif
+                    )
+       && (FRAME_TERMINAL (XFRAME (w->frame))
+           == FRAME_TERMINAL (XFRAME (selected_frame)));
     }
   else if (WINDOWP (all_frames))
     candidate_p = (EQ (FRAME_MINIBUF_WINDOW (f), all_frames)
@@ -2153,8 +2186,10 @@ window_loop (type, obj, mini, frames)
                if (NILP (best_window))
                  best_window = window;
                else if (EQ (window, selected_window))
-                 /* For compatibility with 20.x, prefer to return
-                    selected-window.  */
+                 /* Prefer to return selected-window.  */
+                 RETURN_UNGCPRO (window);
+               else if (EQ (Fwindow_frame (window), selected_frame))
+                 /* Prefer windows on the current frame.  */
                  best_window = window;
              }
            break;
@@ -2636,12 +2671,12 @@ window_fixed_size_p (w, width_p, check_siblings_p)
        {
          Lisp_Object child;
 
-         for (child = w->prev; !NILP (child); child = XWINDOW (child)->prev)
+         for (child = w->prev; WINDOWP (child); child = XWINDOW (child)->prev)
            if (!window_fixed_size_p (XWINDOW (child), width_p, 0))
              break;
 
          if (NILP (child))
-           for (child = w->next; !NILP (child); child = XWINDOW (child)->next)
+           for (child = w->next; WINDOWP (child); child = XWINDOW (child)->next)
              if (!window_fixed_size_p (XWINDOW (child), width_p, 0))
                break;
 
@@ -2656,9 +2691,8 @@ window_fixed_size_p (w, width_p, check_siblings_p)
 }
 
 /* Return the minimum size for leaf window W.  WIDTH_P non-zero means
-   take into account fringes and the scrollbar of W.  WIDTH_P zero
-   means take into account mode-line and header-line of W.  Return 1
-   for the minibuffer.  */
+   take into account fringes and the scrollbar of W.  WIDTH_P zero means
+   take into account mode-line of W.  Return 1 for the minibuffer.  */
 
 static int
 window_min_size_2 (w, width_p)
@@ -2677,8 +2711,11 @@ window_min_size_2 (w, width_p)
   else
     size = max (window_min_height,
                (MIN_SAFE_WINDOW_HEIGHT
-                + (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)
-                + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0 )));
+                /* Don't count the header-line here.  It would break
+                   splitting a window with a header-line when the new
+                   window shall have a height of two (calculator does
+                   that). */
+                + (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
 
   return size;
 }
@@ -3270,6 +3307,25 @@ Fset_window_buffer_unwind (obuf)
 EXFUN (Fset_window_fringes, 4);
 EXFUN (Fset_window_scroll_bars, 4);
 
+void
+run_window_configuration_change_hook (struct frame *f)
+{
+  if (! NILP (Vwindow_configuration_change_hook)
+      && ! NILP (Vrun_hooks))
+    {
+      int count = SPECPDL_INDEX ();
+      if (SELECTED_FRAME () != f)
+       {
+         Lisp_Object frame;
+         XSETFRAME (frame, f);
+         record_unwind_protect (Fselect_frame, Fselected_frame ());
+         Fselect_frame (frame);
+       }
+      call1 (Vrun_hooks, Qwindow_configuration_change_hook);
+      unbind_to (count, 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
@@ -3284,6 +3340,7 @@ set_window_buffer (window, buffer, run_hooks_p, keep_margins_p)
   struct window *w = XWINDOW (window);
   struct buffer *b = XBUFFER (buffer);
   int count = SPECPDL_INDEX ();
+  int samebuf = EQ (buffer, w->buffer);
 
   w->buffer = buffer;
 
@@ -3302,16 +3359,28 @@ set_window_buffer (window, buffer, run_hooks_p, keep_margins_p)
   XSETFASTINT (w->window_end_vpos, 0);
   bzero (&w->last_cursor, sizeof w->last_cursor);
   w->window_end_valid = Qnil;
-  w->hscroll = w->min_hscroll = make_number (0);
-  w->vscroll = 0;
-  set_marker_both (w->pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
-  set_marker_restricted (w->start,
-                        make_number (b->last_window_start),
-                        buffer);
-  w->start_at_line_beg = Qnil;
-  w->force_start = Qnil;
-  XSETFASTINT (w->last_modified, 0);
-  XSETFASTINT (w->last_overlay_modified, 0);
+  if (!(keep_margins_p && samebuf))
+    { /* If we're not actually changing the buffer, Don't reset hscroll and
+        vscroll.  This case happens for example when called from
+        change_frame_size_1, where we use a dummy call to
+        Fset_window_buffer on the frame's selected window (and no other)
+        just in order to run window-configuration-change-hook.
+        Resetting hscroll and vscroll here is problematic for things like
+        image-mode and doc-view-mode since it resets the image's position
+        whenever we resize the frame.  */
+      w->hscroll = w->min_hscroll = make_number (0);
+      w->vscroll = 0;
+      set_marker_both (w->pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
+      set_marker_restricted (w->start,
+                            make_number (b->last_window_start),
+                            buffer);
+      w->start_at_line_beg = Qnil;
+      w->force_start = Qnil;
+      XSETFASTINT (w->last_modified, 0);
+      XSETFASTINT (w->last_overlay_modified, 0);
+    }
+  /* Maybe we could move this into the `if' but it's not obviously safe and
+     I doubt it's worth the trouble.  */
   windows_or_buffers_changed++;
 
   /* We must select BUFFER for running the window-scroll-functions.
@@ -3358,10 +3427,7 @@ set_window_buffer (window, buffer, run_hooks_p, keep_margins_p)
       if (! NILP (Vwindow_scroll_functions))
        run_hook_with_args_2 (Qwindow_scroll_functions, window,
                              Fmarker_position (w->start));
-
-      if (! NILP (Vwindow_configuration_change_hook)
-         && ! NILP (Vrun_hooks))
-       call1 (Vrun_hooks, Qwindow_configuration_change_hook);
+      run_window_configuration_change_hook (XFRAME (WINDOW_FRAME (w)));
     }
 
   unbind_to (count, Qnil);
@@ -3436,6 +3502,22 @@ selects the buffer of the selected window before each command.  */)
   if (EQ (window, selected_window))
     return window;
 
+  sf = SELECTED_FRAME ();
+  if (XFRAME (WINDOW_FRAME (w)) != sf)
+    {
+      XFRAME (WINDOW_FRAME (w))->selected_window = window;
+      /* Use this rather than Fhandle_switch_frame
+        so that FRAME_FOCUS_FRAME is moved appropriately as we
+        move around in the state where a minibuffer in a separate
+        frame is active.  */
+      Fselect_frame (WINDOW_FRAME (w));
+      /* Fselect_frame called us back so we've done all the work already.  */
+      eassert (EQ (window, selected_window));
+      return window;
+    }
+  else
+    sf->selected_window = window;
+
   /* Store the current buffer's actual point into the
      old selected window.  It belongs to that window,
      and when the window is not selected, must be in the window.  */
@@ -3449,18 +3531,6 @@ selects the buffer of the selected window before each command.  */)
     }
 
   selected_window = window;
-  sf = SELECTED_FRAME ();
-  if (XFRAME (WINDOW_FRAME (w)) != sf)
-    {
-      XFRAME (WINDOW_FRAME (w))->selected_window = window;
-      /* Use this rather than Fhandle_switch_frame
-        so that FRAME_FOCUS_FRAME is moved appropriately as we
-        move around in the state where a minibuffer in a separate
-        frame is active.  */
-      Fselect_frame (WINDOW_FRAME (w));
-    }
-  else
-    sf->selected_window = window;
 
   if (NILP (norecord))
     record_buffer (w->buffer);
@@ -3640,7 +3710,7 @@ If `even-window-heights' is non-nil, window heights will be evened out
 if displaying the buffer causes two vertically adjacent windows to be
 displayed.  */)
      (buffer, not_this_window, frame)
-     register Lisp_Object buffer, not_this_window, frame;
+     Lisp_Object buffer, not_this_window, frame;
 {
   register Lisp_Object window, tem, swp;
   struct frame *f;
@@ -3712,6 +3782,8 @@ displayed.  */)
       || !NILP (XWINDOW (FRAME_ROOT_WINDOW (f))->dedicated))
     {
       Lisp_Object frames;
+      struct gcpro gcpro1;
+      GCPRO1 (buffer);
 
       frames = Qnil;
       if (FRAME_MINIBUF_ONLY_P (f))
@@ -3743,26 +3815,26 @@ displayed.  */)
       if (!NILP (window)
          && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window)->frame))
          && WINDOW_FULL_WIDTH_P (XWINDOW (window))
-         && (window_height (window) >= split_height_threshold
-             || (NILP (XWINDOW (window)->parent)))
+              && (window_height (window) >= split_height_threshold
+                  || (NILP (XWINDOW (window)->parent)))
          && (window_height (window)
              >= (2 * window_min_size_2 (XWINDOW (window), 0))))
-       window = Fsplit_window (window, Qnil, Qnil);
+       window = call1 (Vsplit_window_preferred_function, window);
       else
        {
          Lisp_Object upper, lower, other;
 
          window = Fget_lru_window (frames, Qt);
-         /* If the LRU window is tall enough, and either eligible for splitting
-         and selected or the only window, split it.  */
+         /* If the LRU window is tall enough, and either eligible for
+            splitting and selected or the only window, split it.  */
          if (!NILP (window)
              && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window)->frame))
-             && ((EQ (window, selected_window)
-                  && window_height (window) >= split_height_threshold)
-                 || (NILP (XWINDOW (window)->parent)))
-             && (window_height (window)
-                 >= (2 * window_min_size_2 (XWINDOW (window), 0))))
-           window = Fsplit_window (window, Qnil, Qnil);
+                  && ((EQ (window, selected_window)
+                       && window_height (window) >= split_height_threshold)
+                      || (NILP (XWINDOW (window)->parent)))
+                  && (window_height (window)
+                      >= (2 * window_min_size_2 (XWINDOW (window), 0))))
+           window = call1 (Vsplit_window_preferred_function, window);
          else
            window = Fget_lru_window (frames, Qnil);
          /* If Fget_lru_window returned nil, try other approaches.  */
@@ -3808,6 +3880,7 @@ displayed.  */)
                              0);
            }
        }
+      UNGCPRO;
     }
   else
     window = Fget_lru_window (Qnil, Qnil);
@@ -4250,10 +4323,10 @@ enlarge_window (window, delta, horiz_flag)
 
   /* Find the total we can get from other siblings without deleting them.  */
   maximum = 0;
-  for (next = p->next; ! NILP (next); next = XWINDOW (next)->next)
+  for (next = p->next; WINDOWP (next); next = XWINDOW (next)->next)
     maximum += (*sizefun) (next) - window_min_size (XWINDOW (next),
                                                    horiz_flag, 0, 0);
-  for (prev = p->prev; ! NILP (prev); prev = XWINDOW (prev)->prev)
+  for (prev = p->prev; WINDOWP (prev); prev = XWINDOW (prev)->prev)
     maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev),
                                                    horiz_flag, 0, 0);
 
@@ -4401,10 +4474,10 @@ enlarge_window (window, delta, horiz_flag)
          Lisp_Object s;
          int n = 1;
 
-         for (s = w->next; !NILP (s); s = XWINDOW (s)->next)
+         for (s = w->next; WINDOWP (s); s = XWINDOW (s)->next)
            if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
              ++n;
-         for (s = w->prev; !NILP (s); s = XWINDOW (s)->prev)
+         for (s = w->prev; WINDOWP (s); s = XWINDOW (s)->prev)
            if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
              ++n;
 
@@ -4660,7 +4733,7 @@ shrink_window_lowest_first (w, height)
       /* Find the last child.  We are taking space from lowest windows
         first, so we iterate over children from the last child
         backwards.  */
-      for (child = w->vchild; !NILP (child); child = XWINDOW (child)->next)
+      for (child = w->vchild; WINDOWP (child); child = XWINDOW (child)->next)
        last_child = child;
 
       /* Assign new heights.  We leave only MIN_SAFE_WINDOW_HEIGHT.  */
@@ -5456,7 +5529,7 @@ scroll_command (n, direction)
 {
   int count = SPECPDL_INDEX ();
 
-  xassert (abs (direction) == 1);
+  xassert (eabs (direction) == 1);
 
   /* If selected window's buffer isn't current, make it current for
      the moment.  But don't screw up if window_scroll gets an error.  */
@@ -6008,10 +6081,8 @@ zero means top of window, negative means relative to bottom of window.  */)
 
 struct save_window_data
   {
-    EMACS_INT size_from_Lisp_Vector_struct;
+    EMACS_UINT size;
     struct Lisp_Vector *next_from_Lisp_Vector_struct;
-    Lisp_Object frame_cols, frame_lines, frame_menu_bar_lines;
-    Lisp_Object frame_tool_bar_lines;
     Lisp_Object selected_frame;
     Lisp_Object current_window;
     Lisp_Object current_buffer;
@@ -6019,19 +6090,25 @@ struct save_window_data
     Lisp_Object minibuf_selected_window;
     Lisp_Object root_window;
     Lisp_Object focus_frame;
-    /* Record the values of window-min-width and window-min-height
-       so that window sizes remain consistent with them.  */
-    Lisp_Object min_width, min_height;
     /* A vector, each of whose elements is a struct saved_window
        for one window.  */
     Lisp_Object saved_windows;
+
+    /* All fields above are traced by the GC.
+       From `fame-cols' down, the fields are ignored by the GC.  */
+
+    int frame_cols, frame_lines, frame_menu_bar_lines;
+    int frame_tool_bar_lines;
+    /* Record the values of window-min-width and window-min-height
+       so that window sizes remain consistent with them.  */
+    int min_width, min_height;
   };
 
 /* This is saved as a Lisp_Vector  */
 struct saved_window
 {
   /* these first two must agree with struct Lisp_Vector in lisp.h */
-  EMACS_INT size_from_Lisp_Vector_struct;
+  EMACS_UINT size;
   struct Lisp_Vector *next_from_Lisp_Vector_struct;
 
   Lisp_Object window;
@@ -6164,18 +6241,20 @@ the return value is nil.  Otherwise the value is t.  */)
         if it runs during this.  */
       BLOCK_INPUT;
 
-      if (XFASTINT (data->frame_lines) != previous_frame_lines
-         || XFASTINT (data->frame_cols) != previous_frame_cols)
-       change_frame_size (f, XFASTINT (data->frame_lines),
-                          XFASTINT (data->frame_cols), 0, 0, 0);
+      if (data->frame_lines != previous_frame_lines
+         || data->frame_cols != previous_frame_cols)
+       change_frame_size (f, data->frame_lines,
+                          data->frame_cols, 0, 0, 0);
 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
-      if (XFASTINT (data->frame_menu_bar_lines)
+      if (data->frame_menu_bar_lines
          != previous_frame_menu_bar_lines)
-       x_set_menu_bar_lines (f, data->frame_menu_bar_lines, make_number (0));
+       x_set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines),
+                             make_number (0));
 #ifdef HAVE_WINDOW_SYSTEM
-      if (XFASTINT (data->frame_tool_bar_lines)
+      if (data->frame_tool_bar_lines
          != previous_frame_tool_bar_lines)
-       x_set_tool_bar_lines (f, data->frame_tool_bar_lines, make_number (0));
+       x_set_tool_bar_lines (f, make_number (data->frame_tool_bar_lines),
+                             make_number (0));
 #endif
 #endif
 
@@ -6409,8 +6488,8 @@ the return value is nil.  Otherwise the value is t.  */)
     Fset_buffer (new_current_buffer);
 
   /* Restore the minimum heights recorded in the configuration.  */
-  window_min_height = XINT (data->min_height);
-  window_min_width = XINT (data->min_width);
+  window_min_height = data->min_height;
+  window_min_width = data->min_width;
 
   Vminibuf_scroll_window = data->minibuf_scroll_window;
   minibuf_selected_window = data->minibuf_selected_window;
@@ -6611,7 +6690,6 @@ redirection (see `redirect-frame-focus').  */)
   register Lisp_Object tem;
   register int n_windows;
   register struct save_window_data *data;
-  register struct Lisp_Vector *vec;
   register int i;
   FRAME_PTR f;
 
@@ -6621,13 +6699,13 @@ redirection (see `redirect-frame-focus').  */)
   f = XFRAME (frame);
 
   n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f)));
-  vec = allocate_other_vector (VECSIZE (struct save_window_data));
-  data = (struct save_window_data *)vec;
+  data = ALLOCATE_PSEUDOVECTOR (struct save_window_data, frame_cols,
+                              PVEC_WINDOW_CONFIGURATION);
 
-  XSETFASTINT (data->frame_cols, FRAME_COLS (f));
-  XSETFASTINT (data->frame_lines, FRAME_LINES (f));
-  XSETFASTINT (data->frame_menu_bar_lines, FRAME_MENU_BAR_LINES (f));
-  XSETFASTINT (data->frame_tool_bar_lines, FRAME_TOOL_BAR_LINES (f));
+  data->frame_cols = FRAME_COLS (f);
+  data->frame_lines = FRAME_LINES (f);
+  data->frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
+  data->frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f);
   data->selected_frame = selected_frame;
   data->current_window = FRAME_SELECTED_WINDOW (f);
   XSETBUFFER (data->current_buffer, current_buffer);
@@ -6635,8 +6713,8 @@ redirection (see `redirect-frame-focus').  */)
   data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window : Qnil;
   data->root_window = FRAME_ROOT_WINDOW (f);
   data->focus_frame = FRAME_FOCUS_FRAME (f);
-  XSETINT (data->min_height, window_min_height);
-  XSETINT (data->min_width, window_min_width);
+  data->min_height = window_min_height;
+  data->min_width = window_min_width;
   tem = Fmake_vector (make_number (n_windows), Qnil);
   data->saved_windows = tem;
   for (i = 0; i < n_windows; i++)
@@ -7093,11 +7171,12 @@ freeze_window_start (w, freeze_p)
      struct window *w;
      void *freeze_p;
 {
-  if (w == XWINDOW (selected_window)
-      || MINI_WINDOW_P (w)
-      || (MINI_WINDOW_P (XWINDOW (selected_window))
-         && ! NILP (Vminibuf_scroll_window)
-         && w == XWINDOW (Vminibuf_scroll_window)))
+  if (MINI_WINDOW_P (w)
+      || (WINDOWP (selected_window) /* Can be nil in corner cases.  */
+         && (w == XWINDOW (selected_window)
+             || (MINI_WINDOW_P (XWINDOW (selected_window))
+                 && ! NILP (Vminibuf_scroll_window)
+                 && w == XWINDOW (Vminibuf_scroll_window)))))
     freeze_p = NULL;
 
   w->frozen_window_start_p = freeze_p != NULL;
@@ -7142,11 +7221,11 @@ compare_window_configurations (c1, c2, ignore_positions)
   sw1 = XVECTOR (d1->saved_windows);
   sw2 = XVECTOR (d2->saved_windows);
 
-  if (! EQ (d1->frame_cols, d2->frame_cols))
+  if (d1->frame_cols != d2->frame_cols)
     return 0;
-  if (! EQ (d1->frame_lines, d2->frame_lines))
+  if (d1->frame_lines != d2->frame_lines)
     return 0;
-  if (! EQ (d1->frame_menu_bar_lines, d2->frame_menu_bar_lines))
+  if (d1->frame_menu_bar_lines != d2->frame_menu_bar_lines)
     return 0;
   if (! EQ (d1->selected_frame, d2->selected_frame))
     return 0;
@@ -7168,9 +7247,9 @@ compare_window_configurations (c1, c2, ignore_positions)
      if everything else compares equal.  */
   if (! EQ (d1->focus_frame, d2->focus_frame))
     return 0;
-  if (! EQ (d1->min_width, d2->min_width))
+  if (d1->min_width != d2->min_width)
     return 0;
-  if (! EQ (d1->min_height, d2->min_height))
+  if (d1->min_height != d2->min_height)
     return 0;
 
   /* Verify that the two confis have the same number of windows.  */
@@ -7260,7 +7339,7 @@ and scrolling positions.  */)
 void
 init_window_once ()
 {
-  struct frame *f = make_terminal_frame ();
+  struct frame *f = make_initial_frame ();
   XSETFRAME (selected_frame, f);
   Vterminal_frame = selected_frame;
   minibuf_window = f->minibuffer_window;
@@ -7479,6 +7558,15 @@ by `display-buffer'.  The value is in line units.
 If there is only one window, it is split regardless of this value.  */);
   split_height_threshold = 500;
 
+  DEFVAR_LISP ("split-window-preferred-function",
+              &Vsplit_window_preferred_function,
+              doc: /* Function to use to split a window.
+This is used by `display-buffer' to allow the user to choose whether
+to split windows horizontally or vertically or some mix of the two.
+It is called with a window as single argument and should split it in two
+and return the new window.  */);
+  Vsplit_window_preferred_function = intern ("split-window");
+
   DEFVAR_INT ("window-min-height", &window_min_height,
              doc: /* *Delete any window less than this tall (including its mode line).
 The value is in line units. */);
@@ -7515,6 +7603,7 @@ The selected frame is the one whose configuration has changed.  */);
   defsubr (&Swindow_buffer);
   defsubr (&Swindow_height);
   defsubr (&Swindow_width);
+  defsubr (&Swindow_full_width_p);
   defsubr (&Swindow_hscroll);
   defsubr (&Sset_window_hscroll);
   defsubr (&Swindow_redisplay_end_trigger);