]> code.delx.au - gnu-emacs/blobdiff - src/window.c
*** empty log message ***
[gnu-emacs] / src / window.c
index 562b69604dc572dc9e5d3f7d9f6da996f8b47492..83440f440cc52f44e7e43ee0340926ec5926b797 100644 (file)
@@ -1,6 +1,6 @@
 /* Window creation, deletion and examination for GNU Emacs.
    Does not include redisplay.
-   Copyright (C) 1985,86,87,93,94,95,96,97,1998,2000, 2001
+   Copyright (C) 1985,86,87,93,94,95,96,97,1998,2000, 2001, 2002
    Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -44,7 +44,7 @@ Boston, MA 02111-1307, USA.  */
 #ifdef MSDOS
 #include "msdos.h"
 #endif
-#ifdef macintosh
+#ifdef MAC_OS
 #include "macterm.h"
 #endif
 
@@ -58,12 +58,15 @@ enum window_part
   ON_VERTICAL_BORDER,
   ON_HEADER_LINE,
   ON_LEFT_FRINGE,
-  ON_RIGHT_FRINGE
+  ON_RIGHT_FRINGE,
+  ON_LEFT_MARGIN,
+  ON_RIGHT_MARGIN
 };
 
 
 Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configuration_p;
 Lisp_Object Qwindow_size_fixed;
+extern Lisp_Object Qleft_margin, Qright_margin;
 extern Lisp_Object Qheight, Qwidth;
 
 static int displayed_window_lines P_ ((struct window *));
@@ -145,8 +148,8 @@ int mode_line_in_non_selected_windows;
 
 /* If a window gets smaller than either of these, it is removed. */
 
-int window_min_height;
-int window_min_width;
+EMACS_INT window_min_height;
+EMACS_INT window_min_width;
 
 /* Nonzero implies Fdisplay_buffer should create windows. */
 
@@ -199,11 +202,11 @@ Lisp_Object Qtemp_buffer_show_hook;
 /* Fdisplay_buffer always splits the largest window
    if that window is more than this high.  */
 
-int split_height_threshold;
+EMACS_INT split_height_threshold;
 
 /* Number of lines of continuity in scrolling by screenfuls.  */
 
-int next_screen_context_lines;
+EMACS_INT next_screen_context_lines;
 
 /* Incremented for each window created.  */
 
@@ -228,7 +231,7 @@ Lisp_Object Vscroll_preserve_screen_position;
 static int inhibit_frame_unsplittable;
 #endif /* 0 */
 
-extern int scroll_margin;
+extern EMACS_INT scroll_margin;
 
 extern Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
 \f
@@ -275,6 +278,7 @@ make_window ()
   bzero (&p->phys_cursor, sizeof (p->phys_cursor));
   p->desired_matrix = p->current_matrix = 0;
   p->phys_cursor_type = -1;
+  p->phys_cursor_width = -1;
   p->must_be_updated_p = 0;
   XSETFASTINT (p->window_end_vpos, 0);
   XSETFASTINT (p->window_end_pos, 0);
@@ -283,6 +287,8 @@ make_window ()
   XSETWINDOW (val, p);
   XSETFASTINT (p->last_point, 0);
   p->frozen_window_start_p = 0;
+  p->height_fixed_p = 0;
+  p->last_cursor_off_p = p->cursor_off_p = 0;
 
   Vwindow_list = Qnil;
   return val;
@@ -433,7 +439,10 @@ DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
 
 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.
-NCOL should be zero or positive.  */)
+NCOL should be zero or positive.
+
+Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
+window so that the location of point becomes invisible.  */)
      (window, ncol)
      Lisp_Object window, ncol;
 {
@@ -508,7 +517,9 @@ and BOTTOM is one more than the bottommost row used by WINDOW
       return 3.
    if it is on the window's top line, return 4;
    if it is in left or right fringe of the window,
-   return 5 or 6, and convert *X and *Y to window-relative corrdinates.
+   return 5 or 6, and convert *X and *Y to window-relative coordinates;
+   if it is in the marginal area to the left/right of the window,
+   return 7 or 8, and convert *X and *Y to window-relative coordinates.
 
    X and Y are frame relative pixel coordinates.  */
 
@@ -528,6 +539,7 @@ coordinates_in_window (w, x, y)
   /* The width of the area where the vertical line can be dragged.
      (Between mode lines for instance.  */
   int grabbable_width = ux;
+  int lmargin_width = 0, rmargin_width = 0;
 
   if (*x < x0 || *x >= x1)
     return ON_NOTHING;
@@ -622,9 +634,21 @@ coordinates_in_window (w, x, y)
        }
       else
        {
-         *x -= left_x;
-         *y -= top_y;
-         part = ON_TEXT;
+         lmargin_width = window_box_width (w, LEFT_MARGIN_AREA);
+         rmargin_width = window_box_width (w, RIGHT_MARGIN_AREA);
+         /* You can never be on a margin area if its width is zero.  */
+         if (lmargin_width
+             && *x <= window_box_right (w, LEFT_MARGIN_AREA))
+           part = ON_LEFT_MARGIN;
+         else if (rmargin_width
+                  && *x >= window_box_left (w, RIGHT_MARGIN_AREA))
+           part = ON_RIGHT_MARGIN;
+         else
+           {
+             part = ON_TEXT;
+             *x -= left_x;
+             *y -= top_y;
+           }
        }
     }
   else
@@ -652,10 +676,23 @@ coordinates_in_window (w, x, y)
        }
       else
        {
-         /* Convert X and Y to window-relative pixel coordinates.  */
-         *x -= left_x;
-         *y -= top_y;
-         part = ON_TEXT;
+         lmargin_width = window_box_width (w, LEFT_MARGIN_AREA);
+         rmargin_width = window_box_width (w, RIGHT_MARGIN_AREA);
+         /* You can never be on a margin area if its width is zero.
+            This is especially important for character terminals.  */
+         if (lmargin_width
+             && *x <= window_box_right (w, LEFT_MARGIN_AREA))
+           part = ON_LEFT_MARGIN;
+         else if (rmargin_width
+                  && *x >= window_box_left (w, RIGHT_MARGIN_AREA))
+           part = ON_RIGHT_MARGIN;
+         else
+           {
+             part = ON_TEXT;
+             /* Convert X and Y to window-relative pixel coordinates.  */
+             *x -= left_x;
+             *y -= top_y;
+           }
        }
     }
 
@@ -677,7 +714,9 @@ If they are in the top mode line of WINDOW, `header-line' is returned.
 If they are in the left fringe of WINDOW, `left-fringe' is returned.
 If they are in the right fringe of WINDOW, `right-fringe' is returned.
 If they are on the border between WINDOW and its right sibling,
-  `vertical-line' is returned.  */)
+  `vertical-line' is returned.
+If they are in the windows's left or right marginal areas, `left-margin'\n\
+  or `right-margin' is returned.  */)
      (coordinates, window)
      register Lisp_Object coordinates, window;
 {
@@ -723,6 +762,12 @@ If they are on the border between WINDOW and its right sibling,
     case ON_RIGHT_FRINGE:
       return Qright_fringe;
 
+    case ON_LEFT_MARGIN:
+      return Qleft_margin;
+      
+    case ON_RIGHT_MARGIN:
+      return Qright_margin;
+
     default:
       abort ();
     }
@@ -913,7 +958,7 @@ if it isn't already recorded.  */)
       struct buffer *old_buffer = NULL, *b = XBUFFER (buf);
 
       /* In case W->start is out of the range, use something
-         reasonable.  This situation occured when loading a file with
+         reasonable.  This situation occurred when loading a file with
          `-l' containing a call to `rmail' with subsequent other
          commands.  At the end, W->start happened to be BEG, while
          rmail had already narrowed the buffer.  */
@@ -1144,6 +1189,7 @@ replace_window (old, replacement)
   bzero (&p->last_cursor, sizeof (p->last_cursor));
   bzero (&p->phys_cursor, 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);
@@ -1815,7 +1861,7 @@ window_loop (type, obj, mini, frames)
            if (!NILP (obj) && !WINDOW_FULL_WIDTH_P (w))
              break;
            /* Ignore dedicated windows and minibuffers.  */
-           if (MINI_WINDOW_P (w) || !NILP (w->dedicated))
+           if (MINI_WINDOW_P (w) || EQ (w->dedicated, Qt))
              break;
            if (NILP (best_window)
                || (XFASTINT (XWINDOW (best_window)->use_time)
@@ -1868,7 +1914,7 @@ window_loop (type, obj, mini, frames)
          case GET_LARGEST_WINDOW:
            {
              /* Ignore dedicated windows and minibuffers.  */
-             if (MINI_WINDOW_P (w) || !NILP (w->dedicated))
+             if (MINI_WINDOW_P (w) || EQ (w->dedicated, Qt))
                break;
              
              if (NILP (best_window))
@@ -1908,6 +1954,14 @@ window_loop (type, obj, mini, frames)
                    /* Now we can safely delete the frame.  */
                    Fdelete_frame (w->frame, Qnil);
                  }
+               else if (!NILP (w->dedicated) && !NILP (w->parent))
+                 {
+                   Lisp_Object window;
+                   XSETWINDOW (window, w);
+                   /* If this window is dedicated and not the only window
+                      in its frame, then kill it.  */
+                   Fdelete_window (window);
+                 }
                else
                  {
                    /* Otherwise show a different buffer in the window.  */
@@ -2618,7 +2672,7 @@ set_window_buffer (window, buffer, run_hooks_p)
 {
   struct window *w = XWINDOW (window);
   struct buffer *b = XBUFFER (buffer);
-  int count = specpdl_ptr - specpdl;
+  int count = SPECPDL_INDEX ();
 
   w->buffer = buffer;
 
@@ -2701,7 +2755,7 @@ BUFFER can be a buffer or buffer name.  */)
     {
       if (!NILP (w->dedicated) && !EQ (tem, buffer))
        error ("Window is dedicated to `%s'",
-              XSTRING (XBUFFER (tem)->name)->data);
+              SDATA (XBUFFER (tem)->name));
 
       unshow_buffer (w);
     }
@@ -2713,6 +2767,8 @@ BUFFER can be a buffer or buffer name.  */)
 DEFUN ("select-window", Fselect_window, Sselect_window, 1, 1, 0,
        doc: /* Select WINDOW.  Most editing will apply to WINDOW's buffer.
 If WINDOW is not already selected, also make WINDOW's buffer current.
+Also make WINDOW the frame's selected window.
+
 Note that the main editor command loop
 selects the buffer of the selected window before each command.  */)
      (window)
@@ -2896,7 +2952,7 @@ unless the window is the selected window and the optional second
 argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).
 If `pop-up-frames' is non-nil, make a new frame if no window shows BUFFER.
 Returns the window displaying BUFFER.
-If `display-reuse-frames' is non-nil, and another frame is currently
+If `display-buffer-reuse-frames' is non-nil, and another frame is currently
 displaying BUFFER, then simply raise that frame.
 
 The variables `special-display-buffer-names', `special-display-regexps',
@@ -2944,7 +3000,7 @@ displayed.  */)
        }
     }
 
-  /* If the user wants pop-up-frames or display-reuse-frames, then
+  /* If the user wants pop-up-frames or display-buffer-reuse-frames,
      look for a window showing BUFFER on any visible or iconified frame.
      Otherwise search only the current frame.  */
   if (! NILP (frame))
@@ -2992,7 +3048,7 @@ displayed.  */)
       frames = Qnil;
       if (FRAME_MINIBUF_ONLY_P (f))
        XSETFRAME (frames, last_nonminibuf_frame);
-      /* Don't try to create a window if would get an error */
+      /* Don't try to create a window if we would get an error.  */
       if (split_height_threshold < window_min_height << 1)
        split_height_threshold = window_min_height << 1;
 
@@ -3099,7 +3155,9 @@ temp_output_buffer_show (buf)
   BEGV = BEG;
   ZV = Z;
   SET_PT (BEG);
+#if 0  /* rms: there should be no reason for this.  */
   XBUFFER (buf)->prevent_redisplay_optimizations_p = 1;
+#endif
   set_buffer_internal (old);
 
   if (!EQ (Vtemp_buffer_show_function, Qnil))
@@ -3118,7 +3176,7 @@ temp_output_buffer_show (buf)
       set_marker_restricted_both (w->pointm, buf, 1, 1);
 
       /* Run temp-buffer-show-hook, with the chosen window selected
-        and it sbuffer current.  */
+        and itbuffer current.  */
       if (!NILP (Vrun_hooks))
        {
          Lisp_Object tem;
@@ -3128,11 +3186,14 @@ temp_output_buffer_show (buf)
              tem = Fsymbol_value (Qtemp_buffer_show_hook);
              if (!NILP (tem))
                {
-                 int count = specpdl_ptr - specpdl;
+                 int count = SPECPDL_INDEX ();
                  Lisp_Object prev_window;
                  prev_window = selected_window;
 
                  /* Select the window that was chosen, for running the hook.  */
+                 /* Both this Fselect_window and the select_window_1
+                    below will (may) incorrectly set-buffer to the buffer
+                    displayed in the window.  --stef  */
                  record_unwind_protect (Fselect_window, prev_window);
                  select_window_1 (window, 0);
                  Fset_buffer (w->buffer);
@@ -3320,15 +3381,20 @@ siblings to the right or below are changed.  */)
   return Qnil;
 }
 
-DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 2, "p",
+DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 3, "p",
        doc: /* Make current window ARG lines smaller.
 From program, optional second arg non-nil means shrink sideways arg columns.
-Interactively, if an argument is not given, make the window one line smaller.  */)
-     (arg, side)
-     register Lisp_Object arg, side;
+Interactively, if an argument is not given, make the window one line smaller.
+
+Optional third arg PRESERVE-BEFORE, if non-nil, means do not change the size
+of the siblings above or to the left of the selected window.  Only
+siblings to the right or below are changed.  */)
+     (arg, side, preserve_before)
+     register Lisp_Object arg, side, preserve_before;
 {
   CHECK_NUMBER (arg);
-  enlarge_window (selected_window, -XINT (arg), !NILP (side), 0);
+  enlarge_window (selected_window, -XINT (arg), !NILP (side),
+                 !NILP (preserve_before));
 
   if (! NILP (Vwindow_configuration_change_hook))
     call1 (Vrun_hooks, Qwindow_configuration_change_hook);
@@ -3608,7 +3674,7 @@ enlarge_window (window, delta, widthflag, preserve_before)
             delta1/n = delta
             delta1 = n * delta.
 
-            The number of children n rquals the number of resizable
+            The number of children n equals the number of resizable
             children of this window + 1 because we know window itself
             is resizable (otherwise we would have signalled an error.  */
 
@@ -3985,12 +4051,16 @@ window_scroll (window, n, whole, noerror)
      int whole;
      int noerror;
 {
+  immediate_quit = 1;
+
   /* If we must, use the pixel-based version which is much slower than
      the line-based one but can handle varying line heights.  */
   if (FRAME_WINDOW_P (XFRAME (XWINDOW (window)->frame)))
     window_scroll_pixel_based (window, n, whole, noerror);
   else
     window_scroll_line_based (window, n, whole, noerror);
+
+  immediate_quit = 0;
 }
 
 
@@ -4077,14 +4147,17 @@ window_scroll_pixel_based (window, n, whole, noerror)
   else
     move_it_by_lines (&it, n, 1);
 
-  /* End if we end up at ZV or BEGV.  */
+  /* We failed if we find ZV is already on the screen (scrolling up,
+     means there's nothing past the end), or if we can't start any
+     earlier (scrolling down, means there's nothing past the top).  */
   if ((n > 0 && IT_CHARPOS (it) == ZV)
       || (n < 0 && IT_CHARPOS (it) == CHARPOS (start)))
     {
       if (IT_CHARPOS (it) == ZV)
        {
-         if (it.current_y + it.max_ascent + it.max_descent
-             > it.last_visible_y)
+         if (it.current_y < it.last_visible_y
+             && (it.current_y + it.max_ascent + it.max_descent
+                 >= it.last_visible_y))
            {
              /* The last line was only partially visible, make it fully
                 visible.  */
@@ -4119,10 +4192,14 @@ window_scroll_pixel_based (window, n, whole, noerror)
 
   if (! vscrolled)
     {
+      int pos = IT_CHARPOS (it);
+      int bytepos;
       /* Set the window start, and set up the window for redisplay.  */
-      set_marker_restricted (w->start, make_number (IT_CHARPOS (it)),
+      set_marker_restricted (w->start, make_number (pos),
                             w->buffer);
-      w->start_at_line_beg = Fbolp ();
+      bytepos = XMARKER (w->start)->bytepos;
+      w->start_at_line_beg = ((pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n')
+                             ? Qt : Qnil);
       w->update_mode_line = Qt;
       XSETFASTINT (w->last_modified, 0);
       XSETFASTINT (w->last_overlay_modified, 0);
@@ -4152,7 +4229,12 @@ window_scroll_pixel_based (window, n, whole, noerror)
             in the scroll margin at the top.  */
          move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
          while (it.current_y < this_scroll_margin)
-           move_it_by_lines (&it, 1, 1);
+           {
+             int prev = it.current_y;
+             move_it_by_lines (&it, 1, 1);
+             if (prev == it.current_y)
+               break;
+           }
          SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
        }
       else if (n < 0)
@@ -4343,7 +4425,7 @@ scroll_command (n, direction)
      Lisp_Object n;
      int direction;
 {
-  int count = BINDING_STACK_SIZE ();
+  int count = SPECPDL_INDEX ();
 
   xassert (abs (direction) == 1);
 
@@ -4457,7 +4539,7 @@ showing that buffer, popping the buffer up if necessary.  */)
 {
   Lisp_Object window;
   struct window *w;
-  int count = BINDING_STACK_SIZE ();
+  int count = SPECPDL_INDEX ();
 
   window = Fother_window_for_scrolling ();
   w = XWINDOW (window);
@@ -4547,6 +4629,20 @@ by this function.  */)
   return result;
 }
 
+DEFUN ("minibuffer-selected-window", Fminibuffer_selected_window, Sminibuffer_selected_window, 0, 0, 0,
+       doc: /* Return the window which was selected when entering the minibuffer.
+Returns nil, if current window is not a minibuffer window.  */)
+     ()
+{
+  if (minibuf_level > 0
+      && MINI_WINDOW_P (XWINDOW (selected_window))
+      && !NILP (minibuf_selected_window)
+      && WINDOW_LIVE_P (minibuf_selected_window))
+    return minibuf_selected_window;
+
+  return Qnil;
+}
+
 /* Value is the number of lines actually displayed in window W,
    as opposed to its height.  */
 
@@ -4582,6 +4678,15 @@ displayed_window_lines (w)
   move_it_vertically (&it, height);
   bottom_y = line_bottom_y (&it);
 
+  /* rms: On a non-window display,
+     the value of it.vpos at the bottom of the screen
+     seems to be 1 larger than window_box_height (w).
+     This kludge fixes a bug whereby (move-to-window-line -1)
+     when ZV is on the last screen line
+     moves to the previous screen line instead of the last one.  */
+  if (! FRAME_WINDOW_P (XFRAME (w->frame)))
+    height++;
+
   /* Add in empty lines at the bottom of the window.  */
   if (bottom_y < height)
     {
@@ -4712,7 +4817,9 @@ and redisplay normally--don't erase and redraw the frame.  */)
   /* Set the new window start.  */
   set_marker_both (w->start, w->buffer, charpos, bytepos);
   w->window_end_valid = Qnil;
-  w->force_start = Qt;
+  
+  w->optional_new_start = Qt;
+
   if (bytepos == BEGV_BYTE || FETCH_BYTE (bytepos - 1) == '\n')
     w->start_at_line_beg = Qt;
   else
@@ -4887,6 +4994,8 @@ the return value is nil.  Otherwise the value is t.  */)
     {
       if (XBUFFER (new_current_buffer) == current_buffer)
        old_point = PT;
+      else
+       old_point = BUF_PT (XBUFFER (new_current_buffer));
     }
 
   frame = XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame;
@@ -5039,8 +5148,8 @@ the return value is nil.  Otherwise the value is t.  */)
                               p->mark, w->buffer);
 
                  /* As documented in Fcurrent_window_configuration, don't
-                    save the location of point in the buffer which was current
-                    when the window configuration was recorded.  */
+                    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);
@@ -5075,9 +5184,15 @@ the return value is nil.  Otherwise the value is t.  */)
       FRAME_ROOT_WINDOW (f) = data->root_window;
       /* Prevent "swapping out point" in the old selected window
         using the buffer that has been restored into it.
-        That swapping out has already been done,
-        near the beginning of this function.  */
+        Use the point value from the beginning of this function
+        since unshow_buffer (called from delete_all_subwindows)
+        could have altered it.  */
       selected_window = Qnil;
+      if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer))
+       set_marker_restricted (XWINDOW (data->current_window)->pointm,
+                              make_number (old_point),
+                              XWINDOW (data->current_window)->buffer);
+                 
       Fselect_window (data->current_window);
       XBUFFER (XWINDOW (selected_window)->buffer)->last_selected_window
        = selected_window;
@@ -5123,11 +5238,6 @@ the return value is nil.  Otherwise the value is t.  */)
          else if (EQ (leaf_windows[i]->buffer, new_current_buffer))
            ++n;
        }
-
-      /* If more than one window shows the new and old current buffer,
-        don't try to preserve point in that buffer.  */
-      if (old_point > 0 && n > 1)
-       old_point = -1;
       
       adjust_glyphs (f);
 
@@ -5147,15 +5257,7 @@ the return value is nil.  Otherwise the value is t.  */)
     }
 
   if (!NILP (new_current_buffer))
-    {
-      Fset_buffer (new_current_buffer);
-
-      /* If the buffer that is current now is the same
-        that was current before setting the window configuration,
-        don't alter its PT.  */
-      if (old_point >= 0)
-       SET_PT (old_point);
-    }
+    Fset_buffer (new_current_buffer);
 
   /* Restore the minimum heights recorded in the configuration.  */
   window_min_height = XINT (data->min_height);
@@ -5401,7 +5503,7 @@ usage: (save-window-excursion BODY ...)  */)
      Lisp_Object args;
 {
   register Lisp_Object val;
-  register int count = specpdl_ptr - specpdl;
+  register int count = SPECPDL_INDEX ();
 
   record_unwind_protect (Fset_window_configuration,
                         Fcurrent_window_configuration (Qnil));
@@ -5787,6 +5889,8 @@ syms_of_window ()
   staticpro (&Qtemp_buffer_show_hook);
 
   staticpro (&Vwindow_list);
+
+  minibuf_selected_window = Qnil;
   staticpro (&minibuf_selected_window);
 
   DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function,
@@ -5884,10 +5988,14 @@ Those variables take precedence over this one.  */);
               doc: /* Function to call to make a new frame for a special buffer.
 It is called with two arguments, the buffer and optional buffer specific
 data, and should return a window displaying that buffer.
-The default value makes a separate frame for the buffer,
-using `special-display-frame-alist' to specify the frame parameters.
-
-A buffer is special if its is listed in `special-display-buffer-names'
+The default value normally makes a separate frame for the buffer,
+  using `special-display-frame-alist' to specify the frame parameters.
+But if the buffer specific data includes (same-buffer . t) then the
+  buffer is displayed in the current selected window.
+Otherwise if it includes (same-frame . t) then the buffer is displayed in
+  a new window in the currently selected frame.
+
+A buffer is special if it is listed in `special-display-buffer-names'
 or matches a regexp in `special-display-regexps'.  */);
   Vspecial_display_function = Qnil;
 
@@ -6008,6 +6116,7 @@ This variable automatically becomes buffer-local when set.  */);
   defsubr (&Sscroll_right);
   defsubr (&Sother_window_for_scrolling);
   defsubr (&Sscroll_other_window);
+  defsubr (&Sminibuffer_selected_window);
   defsubr (&Srecenter);
   defsubr (&Swindow_text_height);
   defsubr (&Smove_to_window_line);