changeset 95590:9a4b27c8feec

* window.el (display-buffer-function, special-display-p) (special-display-buffer-names, special-display-regexps) (special-display-function, same-window-p, same-window-buffer-names) (same-window-regexps, pop-up-frames, display-buffer-reuse-frames) (pop-up-frame-function, pop-up-windows) (split-window-preferred-function, split-height-threshold) (split-width-threshold, window--splittable-p) (window--try-to-split-window, window--frame-usable-p) (even-window-heights, window--even-window-heights) (window--display-buffer-1, window--display-buffer-2, display-buffer) (pop-to-buffer): Move from window.c and buffer.c. (split-window-preferred-horizontally): Remove. * cus-start.el: Remove corresponding declarations. * window.c (pop_up_windows, pop_up_frames) (display_buffer_reuse_frames, Vpop_up_frame_function) (Vdisplay_buffer_function, Veven_window_heights) (Vspecial_display_buffer_names, Vspecial_display_regexps) (Vspecial_display_function, Vsame_window_buffer_names) (Vsame_window_regexps, split_height_threshold) (Vsplit_window_preferred_function): Move those vars to window.el. (display_buffer_1, Fspecial_display_p, Fsame_window_p) (Fdisplay_buffer): Move those functions to window.el. (syms_of_window): Remove corresponding declarations. (display_buffer): New function. (temp_output_buffer_show, Fother_window_for_scrolling): Use it. * dispnew.c (Flast_nonminibuf_frame): New function. * buffer.c (Fpop_to_buffer): Move to window.el.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Thu, 05 Jun 2008 18:00:36 +0000
parents 4f530a89d1ee
children fff438dcde9e
files lisp/ChangeLog lisp/cus-start.el lisp/window.el src/ChangeLog src/buffer.c src/dispnew.c src/lisp.h src/window.c src/window.h
diffstat 9 files changed, 592 insertions(+), 664 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Thu Jun 05 17:31:55 2008 +0000
+++ b/lisp/ChangeLog	Thu Jun 05 18:00:36 2008 +0000
@@ -1,3 +1,19 @@
+2008-06-05  Martin Rudalics  <rudalics@gmx.at>
+
+	* window.el (display-buffer-function, special-display-p)
+	(special-display-buffer-names, special-display-regexps)
+	(special-display-function, same-window-p, same-window-buffer-names)
+	(same-window-regexps, pop-up-frames, display-buffer-reuse-frames)
+	(pop-up-frame-function, pop-up-windows)
+	(split-window-preferred-function, split-height-threshold)
+	(split-width-threshold, window--splittable-p)
+	(window--try-to-split-window, window--frame-usable-p)
+	(even-window-heights, window--even-window-heights)
+	(window--display-buffer-1, window--display-buffer-2, display-buffer)
+	(pop-to-buffer): Move from window.c and buffer.c.
+	(split-window-preferred-horizontally): Remove.
+	* cus-start.el: Remove corresponding declarations.
+
 2008-06-05  Sam Steingold  <sds@gnu.org>
 
 	* vc.el (vc-update): Use `save-some-buffers' instead of signaling
--- a/lisp/cus-start.el	Thu Jun 05 17:31:55 2008 +0000
+++ b/lisp/cus-start.el	Thu Jun 05 18:00:36 2008 +0000
@@ -302,51 +302,7 @@
 			       "22.1")
 	     ;; window.c
 	     (temp-buffer-show-function windows (choice (const nil) function))
-	     (display-buffer-function windows (choice (const nil) function))
-	     (pop-up-frames frames boolean)
-	     (pop-up-frame-function frames function)
-	     (special-display-buffer-names
-	      frames
-	      (repeat (choice :tag "Buffer"
-			      :value ""
-			      (string :format "%v")
-			      (cons :tag "With attributes"
-				    :format "%v"
-				    :value ("" . nil)
-				    (string :format "%v")
-				    (repeat :tag "Attributes"
-					    (cons :format "%v"
-						  (symbol :tag "Parameter")
-						  (sexp :tag "Value")))))))
-	     (special-display-regexps
-	      frames
-	      (repeat (choice :tag "Buffer"
-			      :value ""
-			      (regexp :format "%v")
-			      (cons :tag "With attributes"
-				    :format "%v"
-				    :value ("" . nil)
-				    (regexp :format "%v")
-				    (repeat :tag "Attributes"
-					    (cons :format "%v"
-						  (symbol :tag "Parameter")
-						  (sexp :tag "Value")))))))
-	     (special-display-function frames function)
-	     (same-window-buffer-names windows (repeat (string :format "%v")))
-	     (same-window-regexps windows (repeat (regexp :format "%v")))
-	     (pop-up-windows windows boolean)
-	     (even-window-heights windows boolean)
 	     (next-screen-context-lines windows integer)
-	     (split-height-threshold windows integer)
-             (split-window-preferred-function
-              windows
-              (choice (const :tag "vertically" nil)
-                      ;; FIXME: Add `sensibly' which chooses between
-                      ;; vertical or horizontal splits depending on the size
-                      ;; and shape of the window.
-                      (const :tag "horizontally"
-                             split-window-preferred-horizontally))
-	      "23.1")
 	     (window-min-height windows integer)
 	     (window-min-width windows integer)
  	     (scroll-preserve-screen-position
@@ -354,7 +310,6 @@
  		       (const :tag "Off (nil)" :value nil)
  		       (const :tag "Full screen (t)" :value t)
  		       (other :tag "Always" 1)) "22.1")
-	     (display-buffer-reuse-frames windows boolean "21.1")
 	     ;; xdisp.c
 	     (scroll-step windows integer)
 	     (scroll-conservatively windows integer)
--- a/lisp/window.el	Thu Jun 05 17:31:55 2008 +0000
+++ b/lisp/window.el	Thu Jun 05 18:00:36 2008 +0000
@@ -193,15 +193,15 @@
 (defalias 'some-window 'get-window-with-predicate)
 
 ;; This should probably be written in C (i.e., without using `walk-windows').
-(defun get-buffer-window-list (buffer &optional minibuf frame)
+(defun get-buffer-window-list (buffer &optional minibuf all-frames)
   "Return list of all windows displaying BUFFER, or nil if none.
 BUFFER can be a buffer or a buffer name.
-See `walk-windows' for the meaning of MINIBUF and FRAME."
+See `walk-windows' for the meaning of MINIBUF and ALL-FRAMES."
   (let ((buffer (if (bufferp buffer) buffer (get-buffer buffer))) windows)
     (walk-windows (function (lambda (window)
 			      (if (eq (window-buffer window) buffer)
 				  (setq windows (cons window windows)))))
-		  minibuf frame)
+		  minibuf all-frames)
     windows))
 
 (defun minibuffer-window-active-p (window)
@@ -517,8 +517,538 @@
     ;; (message "Done in %d rounds" round)
     ))
 
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+(defcustom display-buffer-function nil
+  "If non-nil, function to call to handle `display-buffer'.
+It will receive two args, the buffer and a flag which if non-nil
+means that the currently selected window is not acceptable.  It
+should choose or create a window, display the specified buffer in
+it, and return the window.
+
+Commands such as `switch-to-buffer-other-window' and
+`find-file-other-window' work using this function."
+  :type '(choice
+	  (const nil)
+	  (function :tag "function"))
+  :group 'windows)
+
+(defun special-display-p (buffer-name)
+  "Return non-nil if a buffer named BUFFER-NAME gets a special frame.
+If the value is t, `display-buffer' or `pop-to-buffer' would
+create a special frame for that buffer using the default frame
+parameters.
+
+If the value is a list, it is a list of frame parameters that
+would be used to make a frame for that buffer.  The variables
+`special-display-buffer-names' and `special-display-regexps'
+control this."
+  (cond
+   ((not (stringp buffer-name)))
+   ;; Make sure to return t in the following two cases.
+   ((member buffer-name special-display-buffer-names) t)
+   ((assoc buffer-name special-display-buffer-names) t)
+   ((catch 'found
+      (dolist (regexp special-display-regexps)
+	(cond
+	 ((stringp regexp)
+	  (when (string-match-p regexp buffer-name)
+	    (throw 'found t)))
+	 ((and (consp regexp) (stringp (car regexp))
+	       (string-match-p (car regexp) buffer-name))
+	  (throw 'found (cdr regexp)))))))))
+
+(defcustom special-display-buffer-names nil
+  "List of buffer names that should have their own special frames.
+Displaying a buffer with `display-buffer' or `pop-to-buffer', if
+its name is in this list, makes a special frame for it using
+`special-display-function'.  See also `special-display-regexps'.
+
+An element of the list can be a list instead of just a string.
+There are two ways to use a list as an element:
+  (BUFFER FRAME-PARAMETERS...)  (BUFFER FUNCTION OTHER-ARGS...)
+In the first case, the FRAME-PARAMETERS are pairs of the form
+\(PARAMETER . VALUE); these parameter values are used to create
+the frame.  In the second case, FUNCTION is called with BUFFER as
+the first argument, followed by the OTHER-ARGS--it can display
+BUFFER in any way it likes.  All this is done by the function
+found in `special-display-function'.
+
+If the specified frame parameters include (same-buffer . t), the
+buffer is displayed in the currently selected window.  Otherwise, if
+they include (same-frame . t), the buffer is displayed in a new window
+in the currently selected frame.
+
+If this variable appears \"not to work\", because you add a name to it
+but that buffer still appears in the selected window, look at the
+values of `same-window-buffer-names' and `same-window-regexps'.
+Those variables take precedence over this one."
+  :type '(repeat (choice :tag "Buffer"
+			 :value ""
+			 (string :format "%v")
+			 (cons :tag "With attributes"
+			       :format "%v"
+			       :value ("" . nil)
+			       (string :format "%v")
+			       (repeat :tag "Attributes"
+				       (cons :format "%v"
+					     (symbol :tag "Parameter")
+					     (sexp :tag "Value"))))))
+  :group 'frames)
+
+(defcustom special-display-regexps nil
+  "List of regexps saying which buffers should have their own special frames.
+When displaying a buffer with `display-buffer' or
+`pop-to-buffer', if any regexp in this list matches the buffer
+name, it makes a special frame for the buffer by calling
+`special-display-function'.
+
+An element of the list can be a list instead of just a string.
+There are two ways to use a list as an element:
+  (REGEXP FRAME-PARAMETERS...)  (REGEXP FUNCTION OTHER-ARGS...)
+In the first case, the FRAME-PARAMETERS are pairs of the form
+\(PARAMETER . VALUE); these parameter values are used to create
+the frame.  In the second case, FUNCTION is called with BUFFER as
+the first argument, followed by the OTHER-ARGS--it can display
+the buffer in any way it likes.  All this is done by the function
+found in `special-display-function'.
+
+If the specified frame parameters include (same-buffer . t), the
+buffer is displayed in the currently selected window.  Otherwise,
+if they include (same-frame . t), the buffer is displayed in a
+new window in the currently selected frame.
+
+If this variable appears \"not to work\", because you add a
+regexp to it but the matching buffers still appear in the
+selected window, look at the values of `same-window-buffer-names'
+and `same-window-regexps'.  Those variables take precedence over
+this one."
+  :type '(repeat (choice :tag "Buffer"
+			 :value ""
+			 (regexp :format "%v")
+			 (cons :tag "With attributes"
+			       :format "%v"
+			       :value ("" . nil)
+			       (regexp :format "%v")
+			       (repeat :tag "Attributes"
+				       (cons :format "%v"
+					     (symbol :tag "Parameter")
+					     (sexp :tag "Value"))))))
+  :group 'frames)
+
+(defcustom special-display-function 'special-display-popup-frame
+  "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 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'."
+  :type 'function
+  :group 'frames)
+
+(defun same-window-p (buffer-name)
+  "Return non-nil if a buffer named BUFFER-NAME would be shown in the \"same\" window.
+This function returns non-nil if `display-buffer' or
+`pop-to-buffer' would show a buffer named BUFFER-NAME in the
+selected rather than \(as usual\) some other window.  See
+`same-window-buffer-names' and `same-window-regexps'."
+  (cond
+   ((not (stringp buffer-name)))
+   ;; The elements of `same-window-buffer-names' can be buffer
+   ;; names or cons cells whose cars are buffer names.
+   ((member buffer-name same-window-buffer-names))
+   ((assoc buffer-name same-window-buffer-names))
+   ((catch 'found
+      (dolist (regexp same-window-regexps)
+	;; The elements of `same-window-regexps' can be regexps
+	;; or cons cells whose cars are regexps.
+	(when (or (and (stringp regexp)
+		       (string-match regexp buffer-name))
+		  (and (consp regexp) (stringp (car regexp))
+		       (string-match-p (car regexp) buffer-name)))
+	  (throw 'found t)))))))
+
+(defcustom same-window-buffer-names nil
+  "List of names of buffers that should appear in the \"same\" window.
+`display-buffer' and `pop-to-buffer' show a buffer whose name is
+on this list in the selected rather than some other window.
+
+An element of this list can be a cons cell instead of just a
+string.  In that case the car must be a string specifying the
+buffer name.  This is for compatibility with
+`special-display-buffer-names'; the cdr of the cons cell is
+ignored.
+
+See also `same-window-regexps'."
+ :type '(repeat (string :format "%v"))
+ :group 'windows)
+
+(defcustom same-window-regexps nil
+  "List of regexps saying which buffers should appear in the \"same\" window.
+`display-buffer' and `pop-to-buffer' show a buffer whose name
+matches a regexp on this list in the selected rather than some
+other window.
+
+An element of this list can be a cons cell instead of just a
+string.  In that case the car must be a string, which specifies
+the buffer name.  This is for compatibility with
+`special-display-buffer-names'; the cdr of the cons cell is
+ignored.
+
+See also `same-window-buffer-names'."
+  :type '(repeat (regexp :format "%v"))
+  :group 'windows)
+
+(defcustom pop-up-frames nil
+  "Non-nil means `display-buffer' should make a separate frame."
+  :type 'boolean
+  :group 'windows)
+
+(defcustom display-buffer-reuse-frames nil
+  "Non-nil means `display-buffer' should reuse frames.
+If the buffer in question is already displayed in a frame, raise
+that frame."
+  :type 'boolean
+  :version "21.1"
+  :group 'windows)
+
+(defcustom pop-up-frame-function nil
+  "Function to call to handle automatic new frame creation.
+It is called with no arguments and should return a newly created frame.
+
+A typical value might be
+
+`(lambda () (new-frame pop-up-frame-alist))'
+
+where `pop-up-frame-alist' would hold the default frame
+parameters."
+  :type '(choice
+	  (const nil)
+	  (function :tag "function"))
+  :group 'windows)
+
+(defcustom pop-up-windows t
+  "Non-nil means `display-buffer' should make a new window."
+  :type 'boolean
+  :group 'windows)
+
+(defcustom split-window-preferred-function nil
+  "How `display-buffer' shall split windows.
+Choices are `Vertically', `Horizontally', and `Sensibly' where
+the latter attempts to split wide windows horizontally, narrow
+ones vertically.  Alternatively, you can set this to a function
+called with a window as single argument to split that window in
+two and return the new window."
+  :type '(choice
+	  (const :tag "Vertically" nil)
+	  (const :tag "Horizontally" horizontally)
+	  (const :tag "Sensibly" sensibly)
+	  (function :tag "Function"))
+  :version "23.1"
+  :group 'windows)
+
+(defcustom split-height-threshold 80
+  "Minimum height of window to be split vertically by `display-buffer'.
+If there is only one window, it can be split regardless of this."
+  :type 'number
+  :version "23.1"
+  :group 'windows)
+
+(defcustom split-width-threshold 160
+  "Minimum width of window to be split horizontally by `display-buffer'.
+If there is only one window, it can be split regardless of this."
+  :type 'number
+  :version "23.1"
+  :group 'windows)
+
+(defun window--splittable-p (window &optional horizontal)
+  "Return non-nil if window WINDOW can be split evenly.
+Optional argument HORIZONTAL non-nil means check whether WINDOW
+can be split horizontally.
+
+WINDOW can be split vertically when the following conditions
+hold:
+
+- `window-size-fixed' is either nil or equals `width' for the buffer of
+  WINDOW.
+
+- WINDOW is at least as high as `split-height-threshold' or it is
+  the only window on its frame.
+
+- When WINDOW is split evenly, the emanating windows are at least
+  `window-min-height' lines tall and can accomodate at least one
+  line plus - if WINDOW has one - a modeline.
+
+WINDOW can be split horizontally when the following conditions
+hold:
+
+- `window-size-fixed' is either nil or equals `height' for the
+  buffer of WINDOW.
+
+- WINDOW is at least as wide as `split-width-threshold'.
+
+- When WINDOW is split evenly, the emanating windows are at least
+  `window-min-width' or two (whichever is larger) columns wide."
+  (when (window-live-p window)
+    (with-selected-window window
+      (if horizontal
+	  ;; A window can be split horizontally when its width is not
+	  ;; fixed, it is at least `split-width-threshold' columns wide
+	  ;; and at least twice as wide as `window-min-width' and 2 (the
+	  ;; latter value is hardcoded).
+	  (and (memq window-size-fixed '(nil height))
+	       (>= (window-width window)
+		   (max split-width-threshold
+			(* 2 (max window-min-width 2)))))
+	;; A window can be split vertically when its height is not
+	;; fixed, it is at least `split-height-threshold' lines high or
+	;; the only window on its frame, and it is at least twice as
+	;; high as `window-min-height' and 2 if it has a modeline or 1.
+	(and (memq window-size-fixed '(nil width))
+	     (>= (window-height window)
+		 (max (if (one-window-p 'nomini) 0 split-height-threshold)
+		      (* 2 (max window-min-height
+				(if mode-line-format 2 1))))))))))
+
+(defun window--try-to-split-window (window)
+  "Split window WINDOW if it is splittable.
+See `split-window-preferred-function' for how WINDOW shall be
+split.  See `window--splittable-p' for how to determine whether a
+window is splittable.  If WINDOW can be split, return the value
+returned by `split-window' or `split-window-preferred-function'."
+  (when (and (window-live-p window)
+	     ;; Testing `window-full-width-p' here hardly makes any
+	     ;; sense nowadays.  This can be done more intuitively by
+	     ;; setting up `split-width-threshold' appropriately.
+	     (not (frame-parameter (window-frame window) 'unsplittable)))
+    (or (and (not split-window-preferred-function)
+	     (window--splittable-p window)
+	     (split-window window))
+	(and (eq split-window-preferred-function 'horizontally)
+	     (window--splittable-p window t)
+	     (split-window window nil t))
+	(and (eq split-window-preferred-function 'sensibly)
+	     ;; The following naive aspect-ratio test should become
+	     ;; more sensible.
+	     (or (and (> (window-width window) (window-height window))
+		      (window--splittable-p window t)
+		      (split-window window nil t))
+		 (and (window--splittable-p window)
+		      (split-window window))))
+	(and (functionp split-window-preferred-function)
+	     (funcall split-window-preferred-function window)))))
+
+(defun window--frame-usable-p (frame)
+  "Return frame FRAME if it can be used to display another buffer."
+  (let ((window (frame-root-window frame)))
+    (when (or (not (window-live-p window))
+	      (and (not (window-minibuffer-p window))
+		   (not (window-dedicated-p window))))
+      frame)))
+
+(defcustom even-window-heights t
+  "If non-nil `display-buffer' will try to even window heights.
+Otherwise `display-buffer' will leave the window configuration
+alone.  Heights are evened only when `display-buffer' chooses a
+window that appears above or below the selected window."
+  :type 'boolean
+  :group 'windows)
+
+(defun window--even-window-heights (window)
+  "Even heights of window WINDOW and selected window.
+Do this only if these windows are vertically adjacent to each
+other and `even-window-heights' is non-nil."
+  (when (and even-window-heights
+	     (not (eq window (selected-window)))
+	     ;; Don't resize minibuffer windows.
+	     (not (window-minibuffer-p (selected-window)))
+	     (/= (window-height (selected-window)) (window-height window)) 
+	     (eq (window-frame window) (window-frame (selected-window)))
+	     (let ((sel-edges (window-edges (selected-window)))
+		   (win-edges (window-edges window)))
+	       (and (= (nth 0 sel-edges) (nth 0 win-edges))
+		    (= (nth 2 sel-edges) (nth 2 win-edges))
+		    (or (= (nth 1 sel-edges) (nth 3 win-edges))
+			(= (nth 3 sel-edges) (nth 1 win-edges))))))
+    (let ((window-min-height 1))
+      ;; Don't throw an error if we can't even window heights for
+      ;; whatever reason.
+      (condition-case nil
+	  (enlarge-window (/ (- (window-height window) (window-height)) 2))
+	(error nil)))))
+
+(defun window--display-buffer-1 (window)
+  "Deiconify the frame containing the window WINDOW.
+Do not deiconify the selected frame.  Return WINDOW."
+  (let* ((frame (window-frame window))
+	 (visible (frame-visible-p frame)))
+    (unless (or (not visible)
+		;; Assume the selected frame is already visible enough.
+		(eq frame (selected-frame))
+		;; Assume the frame from which we invoked the minibuffer
+		;; is visible.
+		(and (minibuffer-window-active-p (selected-window))
+		     (eq frame (window-frame (minibuffer-selected-window)))))
+      (when (eq visible 'icon)
+	(make-frame-visible frame))
+      (raise-frame frame))
+    window))
+
+(defun window--display-buffer-2 (buffer window)
+  "Display buffer BUFFER in window WINDOW and make its frame visible.
+Return WINDOW."
+  (when (and (buffer-live-p buffer) (window-live-p window))
+    (set-window-buffer window buffer)
+    (window--display-buffer-1 window)))
+
+(defun display-buffer (buffer-or-name &optional not-this-window frame)
+  "Make buffer BUFFER-OR-NAME appear in some window but don't select it.
+BUFFER-OR-NAME must be a buffer or the name of an existing
+buffer.  Return the window chosen to display BUFFER-OR-NAME or
+nil is no such window is found.
+
+Optional argument NOT-THIS-WINDOW non-nil means display the
+buffer in a window other than the selected one, even if it is
+already displayed in the selected window.
+
+Optional argument FRAME specifies which frames to investigate
+when the specified buffer is already displayed.  If the buffer is
+already displayed in some window on one of these frames simply
+return that window.  Possible values of FRAME are:
+
+`visible' - consider windows on all visible frames.
+
+0 - consider windows on all visible or iconified frames.
+
+`t' - consider windows on all frames.
+
+A specific frame - consider windows on that frame only.
+
+`nil' - consider windows on the selected frame \(actually the
+last non-minibuffer frame\) only.  If, however, either
+`display-buffer-reuse-frames' or `pop-up-frames' is non-nil,
+consider all visible or iconified frames."
+  (interactive "BDisplay buffer:\nP")
+  (let* ((can-use-selected-window
+	  ;; The selected window is usable unless either NOT-THIS-WINDOW
+	  ;; is non-nil, it is dedicated to its buffer, or it is the
+	  ;; `minibuffer-window'.
+	  (not (or not-this-window
+		   (window-dedicated-p (selected-window))
+		   (window-minibuffer-p))))
+	 (buffer (if (bufferp buffer-or-name)
+		     buffer-or-name
+		   (get-buffer buffer-or-name)))
+	 (name-of-buffer (buffer-name buffer))
+	 ;; `frame-to-use' is the frame where to show `buffer' - either
+	 ;; the selected frame or the last nonminibuffer frame.
+	 (frame-to-use
+	  (or (window--frame-usable-p (selected-frame))
+	      (window--frame-usable-p (last-nonminibuffer-frame))))
+	 ;; `window-to-use' is the window we use for showing `buffer'.
+	 window-to-use)
+    (cond
+     ((not (buffer-live-p buffer))
+      (error "No such buffer %s" buffer))
+     (display-buffer-function
+      ;; Let `display-buffer-function' do the job.
+      (funcall display-buffer-function buffer not-this-window))
+     ((and (not not-this-window)
+	   (eq (window-buffer (selected-window)) buffer))
+      ;; The selected window already displays BUFFER and
+      ;; `not-this-window' is nil, so use it.
+      (window--display-buffer-1 (selected-window)))
+     ((and can-use-selected-window (same-window-p name-of-buffer))
+      ;; If the buffer's name tells us to use the selected window do so.
+      (window--display-buffer-2 buffer (selected-window)))
+     ((let ((frames (or frame
+			(and (or pop-up-frames display-buffer-reuse-frames
+				 (not (last-nonminibuffer-frame)))
+			     0)
+			(last-nonminibuffer-frame))))
+	(and (setq window-to-use (get-buffer-window buffer frames))
+	     (or can-use-selected-window
+		 (not (eq (selected-window) window-to-use)))))
+      ;; If the buffer is already displayed in some window use that.
+      (window--display-buffer-1 window-to-use))
+     ((and special-display-function
+	   ;; `special-display-p' returns either t or a list of frame
+	   ;; parameters to pass to `special-display-function'.
+	   (let ((pars (special-display-p name-of-buffer)))
+	     (when pars
+	       (funcall special-display-function
+			(if (eq pars t) buffer pars))))))
+     ((or pop-up-frames (not frame-to-use))
+      ;; We want or need a new frame.
+      (window--display-buffer-2
+       buffer (frame-selected-window (funcall pop-up-frame-function))))
+     ((and pop-up-windows
+	   ;; Make a new window.
+	   (or (not (frame-parameter frame-to-use 'unsplittable))
+	       ;; If the selected frame cannot be split look at
+	       ;; `last-nonminibuffer-frame'.
+	       (and (eq frame-to-use (selected-frame))
+		    (setq frame-to-use (last-nonminibuffer-frame))
+		    (window--frame-usable-p frame-to-use)
+		    (not (frame-parameter frame-to-use 'unsplittable))))
+	   ;; Attempt to split largest or most recently used window.
+	   (setq window-to-use
+		 (or (window--try-to-split-window
+		      (get-largest-window frame-to-use t))
+		     (window--try-to-split-window
+		      (get-lru-window frame-to-use t))))
+	   (window--display-buffer-2 buffer window-to-use)))
+     ((setq window-to-use
+	    ;; Reuse an existing window.
+	    (or (get-buffer-window buffer 'visible)
+		(get-largest-window 'visible nil)
+		(get-buffer-window buffer 0)
+		(get-largest-window 0 nil)
+		(frame-selected-window (funcall pop-up-frame-function))
+		(get-lru-window t t)))
+      (window--even-window-heights window-to-use)
+      (window--display-buffer-2 buffer window-to-use)))))
+
+(defun pop-to-buffer (buffer-or-name &optional other-window norecord)
+  "Select buffer BUFFER-OR-NAME in some window, preferably a different one.
+BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
+nil.  If BUFFER-OR-NAME is a string not naming an existent
+buffer, create a buffer with that name.  If BUFFER-OR-NAME is
+nil, choose some other buffer.
+
+If `pop-up-windows' is non-nil, windows can be split to display
+the buffer.  If optional second arg OTHER-WINDOW is non-nil,
+insist on finding another window even if the specified buffer is
+already visible in the selected window, and ignore
+`same-window-regexps' and `same-window-buffer-names'.
+
+This function returns the buffer it switched to.  This uses the
+function `display-buffer' as a subroutine; see the documentation
+of `display-buffer' for additional customization information.
+
+Optional third arg NORECORD non-nil means do not put this buffer
+at the front of the list of recently selected ones."
+  (let ((buffer
+         ;; FIXME: This behavior is carried over from the previous C version
+         ;; of pop-to-buffer, but really we should use just
+         ;; `get-buffer' here.
+         (if (null buffer-or-name) (other-buffer (current-buffer))
+           (or (get-buffer buffer-or-name)
+               (let ((buf (get-buffer-create buffer-or-name)))
+                 (set-buffer-major-mode buf)
+                 buf)))))
+    (set-buffer buffer)
+    (select-window (display-buffer buffer other-window) norecord)
+    buffer))
+
 ;; I think this should be the default; I think people will prefer it--rms.
 (defcustom split-window-keep-point t
   "*If non-nil, \\[split-window-vertically] keeps the original point \
@@ -614,43 +1144,6 @@
 	 (setq size (+ (window-width) size)))
     (split-window-save-restore-data (split-window nil size t) old-w)))
 
-(defun split-window-preferred-horizontally (window)
-  "Split WINDOW horizontally or select an appropriate existing window.
-It is called by `display-buffer' to split windows horizontally
-when the option `split-window-preferred-function' is set to \"horizontally\".
-This function tries to match the implementation of vertical splitting
-in `display-buffer' as close as possible but with the logic of
-horizontal splitting.  It returns a new window or an appropriate
-existing window if splitting is not eligible."
-  (interactive)
-  ;; If the largest window is wide enough, eligible for splitting,
-  ;; and the only window, split it horizontally.
-  (if (and window
-           (not (frame-parameter (window-frame window) 'unsplittable))
-           (one-window-p (window-frame window))
-           (>= (window-width window) (* 2 window-min-width)))
-      (split-window window nil t)
-    ;; Otherwise, if the LRU window is wide enough, eligible for
-    ;; splitting and selected or the only window, split it horizontally.
-    (setq window (get-lru-window nil t))
-    (if (and window
-             (not (frame-parameter (window-frame window) 'unsplittable))
-             (or (eq window (selected-window))
-                 (one-window-p (window-frame window)))
-             (>= (window-width window) (* 2 window-min-width)))
-        (split-window window nil t)
-      ;; Otherwise, if get-lru-window returns nil, try other approaches.
-      (or
-       (get-lru-window nil nil)
-       ;; Try visible frames first.
-       (get-buffer-window (current-buffer) 'visible)
-       (get-largest-window 'visible)
-       ;; If that didn't work, try iconified frames.
-       (get-buffer-window (current-buffer) 0)
-       (get-largest-window 0)
-       ;; As a last resort, make a new frame.
-       (frame-selected-window (funcall pop-up-frame-function))))))
-
 
 (defun set-window-text-height (window height)
   "Sets the height in lines of the text display area of WINDOW to HEIGHT.
--- a/src/ChangeLog	Thu Jun 05 17:31:55 2008 +0000
+++ b/src/ChangeLog	Thu Jun 05 18:00:36 2008 +0000
@@ -1,3 +1,20 @@
+2008-06-05  Martin Rudalics  <rudalics@gmx.at>
+
+	* window.c (pop_up_windows, pop_up_frames)
+	(display_buffer_reuse_frames, Vpop_up_frame_function)
+	(Vdisplay_buffer_function, Veven_window_heights)
+	(Vspecial_display_buffer_names, Vspecial_display_regexps)
+	(Vspecial_display_function, Vsame_window_buffer_names)
+	(Vsame_window_regexps, split_height_threshold)
+	(Vsplit_window_preferred_function): Move those vars to window.el.
+	(display_buffer_1, Fspecial_display_p, Fsame_window_p)
+	(Fdisplay_buffer): Move those functions to window.el.
+	(syms_of_window): Remove corresponding declarations.
+	(display_buffer): New function.
+	(temp_output_buffer_show, Fother_window_for_scrolling): Use it.
+	* dispnew.c (Flast_nonminibuf_frame): New function.
+	* buffer.c (Fpop_to_buffer): Move to window.el.
+
 2008-06-05  Stefan Monnier  <monnier@iro.umontreal.ca>
 
 	* data.c (set_internal): Fix up call to let_shadows_buffer_binding_p.
--- a/src/buffer.c	Thu Jun 05 17:31:55 2008 +0000
+++ b/src/buffer.c	Thu Jun 05 18:00:36 2008 +0000
@@ -1811,42 +1811,6 @@
   return switch_to_buffer_1 (buffer, norecord);
 }
 
-DEFUN ("pop-to-buffer", Fpop_to_buffer, Spop_to_buffer, 1, 3, 0,
-       doc: /* Select buffer BUFFER in some window, preferably a different one.
-BUFFER may be a buffer, a string \(a buffer name), or nil.
-If BUFFER is a string which is not the name of an existing buffer,
-then this function creates a buffer with that name.
-If BUFFER is nil, then it chooses some other buffer.
-If `pop-up-windows' is non-nil, windows can be split to do this.
-If optional second arg OTHER-WINDOW is non-nil, insist on finding another
-window even if BUFFER is already visible in the selected window,
-and ignore `same-window-regexps' and `same-window-buffer-names'.
-This function returns the buffer it switched to.
-This uses the function `display-buffer' as a subroutine; see the documentation
-of `display-buffer' for additional customization information.
-
-Optional third arg NORECORD non-nil means
-do not put this buffer at the front of the list of recently selected ones.  */)
-     (buffer, other_window, norecord)
-     Lisp_Object buffer, other_window, norecord;
-{
-  register Lisp_Object buf;
-  if (NILP (buffer))
-    buf = Fother_buffer (Fcurrent_buffer (), Qnil, Qnil);
-  else
-    {
-      buf = Fget_buffer (buffer);
-      if (NILP (buf))
-	{
-	  buf = Fget_buffer_create (buffer);
-	  Fset_buffer_major_mode (buf);
-	}
-    }
-  Fset_buffer (buf);
-  Fselect_window (Fdisplay_buffer (buf, other_window, Qnil), norecord);
-  return buf;
-}
-
 DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0,
        doc: /* Return the current buffer as a Lisp object.  */)
      ()
@@ -6269,7 +6233,6 @@
   defsubr (&Skill_buffer);
   defsubr (&Sset_buffer_major_mode);
   defsubr (&Sswitch_to_buffer);
-  defsubr (&Spop_to_buffer);
   defsubr (&Scurrent_buffer);
   defsubr (&Sset_buffer);
   defsubr (&Sbarf_if_buffer_read_only);
--- a/src/dispnew.c	Thu Jun 05 17:31:55 2008 +0000
+++ b/src/dispnew.c	Thu Jun 05 18:00:36 2008 +0000
@@ -7061,6 +7061,17 @@
   return w->cursor_off_p ? Qnil : Qt;
 }
 
+DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
+       Slast_nonminibuf_frame, 0, 0, 0,
+       doc: /* Value is last nonminibuffer frame. */)
+     ()
+{
+  Lisp_Object frame;
+
+  XSETFRAME (frame, last_nonminibuf_frame);
+
+  return frame;
+}
 
 /***********************************************************************
 			    Initialization
@@ -7079,6 +7090,7 @@
   defsubr (&Ssend_string_to_terminal);
   defsubr (&Sinternal_show_cursor);
   defsubr (&Sinternal_show_cursor_p);
+  defsubr (&Slast_nonminibuf_frame);
 
 #if GLYPH_DEBUG
   defsubr (&Sdump_redisplay_history);
--- a/src/lisp.h	Thu Jun 05 17:31:55 2008 +0000
+++ b/src/lisp.h	Thu Jun 05 18:00:36 2008 +0000
@@ -2865,7 +2865,6 @@
 EXFUN (Fbarf_if_buffer_read_only, 0);
 EXFUN (Fcurrent_buffer, 0);
 EXFUN (Fswitch_to_buffer, 2);
-EXFUN (Fpop_to_buffer, 3);
 EXFUN (Fother_buffer, 3);
 EXFUN (Foverlay_get, 2);
 EXFUN (Fbuffer_modified_p, 1);
--- a/src/window.c	Thu Jun 05 17:31:55 2008 +0000
+++ b/src/window.c	Thu Jun 05 18:00:36 2008 +0000
@@ -52,8 +52,10 @@
 
 
 Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configuration_p;
+Lisp_Object Qdisplay_buffer;
 Lisp_Object Qscroll_up, Qscroll_down;
 Lisp_Object Qwindow_size_fixed;
+
 extern Lisp_Object Qleft_margin, Qright_margin;
 
 static int displayed_window_lines P_ ((struct window *));
@@ -139,63 +141,10 @@
 EMACS_INT window_min_height;
 EMACS_INT window_min_width;
 
-/* Nonzero implies Fdisplay_buffer should create windows. */
-
-int pop_up_windows;
-
-/* Nonzero implies make new frames for Fdisplay_buffer.  */
-
-int pop_up_frames;
-
-/* Nonzero means reuse existing frames for displaying buffers.  */
-
-int display_buffer_reuse_frames;
-
-/* Non-nil means use this function instead of default */
-
-Lisp_Object Vpop_up_frame_function;
-
-/* Function to call to handle Fdisplay_buffer.  */
-
-Lisp_Object Vdisplay_buffer_function;
-
-/* Non-nil means that Fdisplay_buffer should even the heights of windows.  */
-
-Lisp_Object Veven_window_heights;
-
-/* List of buffer *names* for buffers that should have their own frames.  */
-
-Lisp_Object Vspecial_display_buffer_names;
-
-/* List of regexps for buffer names that should have their own frames.  */
-
-Lisp_Object Vspecial_display_regexps;
-
-/* Function to pop up a special frame.  */
-
-Lisp_Object Vspecial_display_function;
-
-/* List of buffer *names* for buffers to appear in selected window.  */
-
-Lisp_Object Vsame_window_buffer_names;
-
-/* List of regexps for buffer names to appear in selected window.  */
-
-Lisp_Object Vsame_window_regexps;
-
 /* Hook run at end of temp_output_buffer_show.  */
 
 Lisp_Object Qtemp_buffer_show_hook;
 
-/* Fdisplay_buffer always splits the largest window
-   if that window is more than this high.  */
-
-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;
@@ -3639,338 +3588,12 @@
   return Fselect_window (window, Qt);
 }
 
-/* Deiconify the frame containing the window WINDOW,
-   unless it is the selected frame;
-   then return WINDOW.
-
-   The reason for the exception for the selected frame
-   is that it seems better not to change the selected frames visibility
-   merely because of displaying a different buffer in it.
-   The deiconification is useful when a buffer gets shown in
-   another frame that you were not using lately.  */
-
-static Lisp_Object
-display_buffer_1 (window)
-     Lisp_Object window;
-{
-  Lisp_Object frame = XWINDOW (window)->frame;
-  FRAME_PTR f = XFRAME (frame);
-
-  FRAME_SAMPLE_VISIBILITY (f);
-
-  if (EQ (frame, selected_frame))
-    ; /* Assume the selected frame is already visible enough.  */
-  else if (minibuf_level > 0
-	   && MINI_WINDOW_P (XWINDOW (selected_window))
-	   && WINDOW_LIVE_P (minibuf_selected_window)
-	   && EQ (frame, WINDOW_FRAME (XWINDOW (minibuf_selected_window))))
-    ; /* Assume the frame from which we invoked the minibuffer is visible.  */
-  else
-    {
-      if (FRAME_ICONIFIED_P (f))
-	Fmake_frame_visible (frame);
-      else if (FRAME_VISIBLE_P (f))
-	Fraise_frame (frame);
-    }
-
-  return window;
-}
-
-DEFUN ("special-display-p", Fspecial_display_p, Sspecial_display_p, 1, 1, 0,
-       doc: /* Returns non-nil if a buffer named BUFFER-NAME gets a special frame.
-If the value is t, `display-buffer' or `pop-to-buffer' would create a
-special frame for that buffer using the default frame parameters.
-
-If the value is a list, it is a list of frame parameters that would be used
-to make a frame for that buffer.
-The variables `special-display-buffer-names'
-and `special-display-regexps' control this.  */)
-     (buffer_name)
-     Lisp_Object buffer_name;
-{
-  Lisp_Object tem;
-
-  CHECK_STRING (buffer_name);
-
-  tem = Fmember (buffer_name, Vspecial_display_buffer_names);
-  if (!NILP (tem))
-    return Qt;
-
-  tem = Fassoc (buffer_name, Vspecial_display_buffer_names);
-  if (!NILP (tem))
-    return XCDR (tem);
-
-  for (tem = Vspecial_display_regexps; CONSP (tem); tem = XCDR (tem))
-    {
-      Lisp_Object car = XCAR (tem);
-      if (STRINGP (car)
-	  && fast_string_match (car, buffer_name) >= 0)
-	return Qt;
-      else if (CONSP (car)
-	       && STRINGP (XCAR (car))
-	       && fast_string_match (XCAR (car), buffer_name) >= 0)
-	return XCDR (car);
-    }
-  return Qnil;
-}
-
-DEFUN ("same-window-p", Fsame_window_p, Ssame_window_p, 1, 1, 0,
-       doc: /* Returns non-nil if a buffer named BUFFER-NAME would use the same window.
-More precisely, if `display-buffer' or `pop-to-buffer' would display
-that buffer in the selected window rather than (as usual) in some other window.
-See `same-window-buffer-names' and `same-window-regexps'.  */)
-     (buffer_name)
-     Lisp_Object buffer_name;
-{
-  Lisp_Object tem;
-
-  CHECK_STRING (buffer_name);
-
-  tem = Fmember (buffer_name, Vsame_window_buffer_names);
-  if (!NILP (tem))
-    return Qt;
-
-  tem = Fassoc (buffer_name, Vsame_window_buffer_names);
-  if (!NILP (tem))
-    return Qt;
-
-  for (tem = Vsame_window_regexps; CONSP (tem); tem = XCDR (tem))
-    {
-      Lisp_Object car = XCAR (tem);
-      if (STRINGP (car)
-	  && fast_string_match (car, buffer_name) >= 0)
-	return Qt;
-      else if (CONSP (car)
-	       && STRINGP (XCAR (car))
-	       && fast_string_match (XCAR (car), buffer_name) >= 0)
-	return Qt;
-    }
-  return Qnil;
-}
-
-/* Use B so the default is (other-buffer).  */
-DEFUN ("display-buffer", Fdisplay_buffer, Sdisplay_buffer, 1, 3,
-       "BDisplay buffer: \nP",
-       doc: /* Make BUFFER appear in some window but don't select it.
-BUFFER must be the name of an existing buffer, or, when called from Lisp,
-a buffer.
-If BUFFER is shown already in some window, just use that one,
-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-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', `same-window-buffer-names', and
-`same-window-regexps' customize how certain buffer names are handled.
-The latter two take effect only if NOT-THIS-WINDOW is nil.
-
-If optional argument FRAME is `visible', check all visible frames
-for a window to use.
-If FRAME is 0, check all visible and iconified frames.
-If FRAME is t, check all frames.
-If FRAME is a frame, check only that frame.
-If FRAME is nil, check only the selected frame
- (actually the last nonminibuffer frame),
- unless `pop-up-frames' or `display-buffer-reuse-frames' is non-nil,
- which means search visible and iconified frames.
-
-If a full-width window on a splittable frame is available to display
-the buffer, it may be split, subject to the value of the variable
-`split-height-threshold'.
-
-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)
-     Lisp_Object buffer, not_this_window, frame;
-{
-  register Lisp_Object window, tem, swp;
-  struct frame *f;
-
-  swp = Qnil;
-  buffer = Fget_buffer (buffer);
-  CHECK_BUFFER (buffer);
-
-  if (!NILP (Vdisplay_buffer_function))
-    return call2 (Vdisplay_buffer_function, buffer, not_this_window);
-
-  if (NILP (not_this_window)
-      && XBUFFER (XWINDOW (selected_window)->buffer) == XBUFFER (buffer))
-    return display_buffer_1 (selected_window);
-
-  /* See if the user has specified this buffer should appear
-     in the selected window.  */
-  if (NILP (not_this_window))
-    {
-      swp = Fsame_window_p (XBUFFER (buffer)->name);
-      if (!NILP (swp) && !no_switch_window (selected_window))
-	{
-	  Fswitch_to_buffer (buffer, Qnil);
-	  return display_buffer_1 (selected_window);
-	}
-    }
-
-  /* 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))
-    tem = frame;
-  else if (pop_up_frames
-	   || display_buffer_reuse_frames
-	   || last_nonminibuf_frame == 0)
-    XSETFASTINT (tem, 0);
-  else
-    XSETFRAME (tem, last_nonminibuf_frame);
-
-  window = Fget_buffer_window (buffer, tem);
-  if (!NILP (window)
-      && (NILP (not_this_window) || !EQ (window, selected_window)))
-    return display_buffer_1 (window);
-
-  /* Certain buffer names get special handling.  */
-  if (!NILP (Vspecial_display_function) && NILP (swp))
-    {
-      tem = Fspecial_display_p (XBUFFER (buffer)->name);
-      if (EQ (tem, Qt))
-	return call1 (Vspecial_display_function, buffer);
-      if (CONSP (tem))
-	return call2 (Vspecial_display_function, buffer, tem);
-    }
-
-  /* If there are no frames open that have more than a minibuffer,
-     we need to create a new frame.  */
-  if (pop_up_frames || last_nonminibuf_frame == 0)
-    {
-      window = Fframe_selected_window (call0 (Vpop_up_frame_function));
-      Fset_window_buffer (window, buffer, Qnil);
-      return display_buffer_1 (window);
-    }
-
-  f = SELECTED_FRAME ();
-  if (pop_up_windows
-      || FRAME_MINIBUF_ONLY_P (f)
-      /* If the current frame is a special display frame,
-	 don't try to reuse its windows.  */
-      || !NILP (XWINDOW (FRAME_ROOT_WINDOW (f))->dedicated))
-    {
-      Lisp_Object frames;
-      struct gcpro gcpro1;
-      GCPRO1 (buffer);
-
-      frames = Qnil;
-      if (FRAME_MINIBUF_ONLY_P (f))
-	XSETFRAME (frames, last_nonminibuf_frame);
-
-      /* Note that both Fget_largest_window and Fget_lru_window
-	 ignore minibuffers and dedicated windows.
-	 This means they can return nil.  */
-
-      /* If the frame we would try to split cannot be split,
-	 try other frames.  */
-      if (FRAME_NO_SPLIT_P (NILP (frames) ? f : last_nonminibuf_frame))
-	{
-	  /* Try visible frames first.  */
-	  window = Fget_largest_window (Qvisible, Qt);
-	  /* If that didn't work, try iconified frames.  */
-	  if (NILP (window))
-	    window = Fget_largest_window (make_number (0), Qt);
-#if 0     /* Don't try windows on other displays.  */
-	  if (NILP (window))
-	    window = Fget_largest_window (Qt, Qt);
-#endif
-	}
-      else
-	window = Fget_largest_window (frames, Qt);
-
-      tem = Qnil;
-      if (!NILP (Vsplit_window_preferred_function))
-	tem = call1 (Vsplit_window_preferred_function, window);
-
-      if (!NILP (tem))
-	window = tem;
-      else
-	/* If the largest window is tall enough, full-width, and either eligible
-	   for splitting or the only window, split it.  */
-	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)
-		>= (2 * window_min_size_2 (XWINDOW (window), 0, 0))))
-	  window = Fsplit_window (window, Qnil, Qnil);
-      else
-	{
-	  Lisp_Object upper, 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 (!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, 0))))
-	    window = Fsplit_window (window, Qnil, Qnil);
-	  else
-	    window = Fget_lru_window (frames, Qnil);
-	  /* If Fget_lru_window returned nil, try other approaches.  */
-
-	  /* Try visible frames first.  */
-	  if (NILP (window))
-	    window = Fget_buffer_window (buffer, Qvisible);
-	  if (NILP (window))
-	    window = Fget_largest_window (Qvisible, Qnil);
-	  /* If that didn't work, try iconified frames.  */
-	  if (NILP (window))
-	    window = Fget_buffer_window (buffer, make_number (0));
-	  if (NILP (window))
-	    window = Fget_largest_window (make_number (0), Qnil);
-
-#if 0     /* Don't try frames on other displays.  */
-	  if (NILP (window))
-	    window = Fget_buffer_window (buffer, Qt);
-	  if (NILP (window))
-	    window = Fget_largest_window (Qt, Qnil);
-#endif
-	  /* As a last resort, make a new frame.  */
-	  if (NILP (window))
-	    window = Fframe_selected_window (call0 (Vpop_up_frame_function));
-	  /* If window appears above or below another,
-	     even out their heights.  */
-	  other = upper = Qnil;
-	  if (!NILP (XWINDOW (window)->prev))
-	    other = upper = XWINDOW (window)->prev;
-	  if (!NILP (XWINDOW (window)->next))
-	    other = XWINDOW (window)->next, upper = window;
-	  if (!NILP (other)
-	      && !NILP (Veven_window_heights)
-	      /* Check that OTHER and WINDOW are vertically arrayed.  */
-	      && !EQ (XWINDOW (other)->top_line, XWINDOW (window)->top_line)
-	      && (XFASTINT (XWINDOW (other)->total_lines)
-		  > XFASTINT (XWINDOW (window)->total_lines)))
-	    {
-	      int total = (XFASTINT (XWINDOW (other)->total_lines)
-			   + XFASTINT (XWINDOW (window)->total_lines));
-	      enlarge_window (upper,
-			      total / 2 - XFASTINT (XWINDOW (upper)->total_lines),
-			      0);
-	    }
-	}
-      UNGCPRO;
-    }
-  else
-    window = Fget_lru_window (Qnil, Qnil);
-
-  Fset_window_buffer (window, buffer, Qnil);
-  return display_buffer_1 (window);
-}
-
+Lisp_Object
+display_buffer (buffer, not_this_window_p, override_frame)
+     Lisp_Object buffer, not_this_window_p, override_frame;
+{
+  return call3 (Qdisplay_buffer, buffer, not_this_window_p, override_frame);
+}
 
 DEFUN ("force-window-update", Fforce_window_update, Sforce_window_update,
        0, 1, 0,
@@ -4041,7 +3664,7 @@
     call1 (Vtemp_buffer_show_function, buf);
   else
     {
-      window = Fdisplay_buffer (buf, Qnil, Qnil);
+      window = display_buffer (buf, Qnil, Qnil);
 
       if (!EQ (XWINDOW (window)->frame, selected_frame))
 	Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window)));
@@ -5692,7 +5315,7 @@
     {
       window = Fget_buffer_window (Vother_window_scroll_buffer, Qnil);
       if (NILP (window))
-	window = Fdisplay_buffer (Vother_window_scroll_buffer, Qt, Qnil);
+	window = display_buffer (Vother_window_scroll_buffer, Qt, Qnil);
     }
   else
     {
@@ -7453,6 +7076,9 @@
   Qwindow_live_p = intern ("window-live-p");
   staticpro (&Qwindow_live_p);
 
+  Qdisplay_buffer = intern ("display-buffer");
+  staticpro (&Qdisplay_buffer);
+
   Qtemp_buffer_show_hook = intern ("temp-buffer-show-hook");
   staticpro (&Qtemp_buffer_show_hook);
 
@@ -7474,21 +7100,6 @@
 the buffer; `temp-buffer-show-hook' is not run unless this function runs it.  */);
   Vtemp_buffer_show_function = Qnil;
 
-  DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function,
-	       doc: /* If non-nil, function to call to handle `display-buffer'.
-It will receive two args, the buffer and a flag which if non-nil means
-that the currently selected window is not acceptable.
-It should choose or create a window, display the specified buffer in it,
-and return the window.
-Commands such as `switch-to-buffer-other-window' and `find-file-other-window'
-work using this function.  */);
-  Vdisplay_buffer_function = Qnil;
-
-  DEFVAR_LISP ("even-window-heights", &Veven_window_heights,
-	       doc: /* *If non-nil, `display-buffer' should even the window heights.
-If nil, `display-buffer' will leave the window configuration alone.  */);
-  Veven_window_heights = Qt;
-
   DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window,
 	       doc: /* Non-nil means it is the window that C-M-v in minibuffer should scroll.  */);
   Vminibuf_scroll_window = Qnil;
@@ -7503,148 +7114,14 @@
 	       doc: /* If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window.  */);
   Vother_window_scroll_buffer = Qnil;
 
-  DEFVAR_BOOL ("pop-up-frames", &pop_up_frames,
-	       doc: /* *Non-nil means `display-buffer' should make a separate frame.  */);
-  pop_up_frames = 0;
-
   DEFVAR_BOOL ("auto-window-vscroll", &auto_window_vscroll_p,
 	       doc: /* *Non-nil means to automatically adjust `window-vscroll' to view tall lines.  */);
   auto_window_vscroll_p = 1;
 
-  DEFVAR_BOOL ("display-buffer-reuse-frames", &display_buffer_reuse_frames,
-	       doc: /* *Non-nil means `display-buffer' should reuse frames.
-If the buffer in question is already displayed in a frame, raise that frame.  */);
-  display_buffer_reuse_frames = 0;
-
-  DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function,
-	       doc: /* Function to call to handle automatic new frame creation.
-It is called with no arguments and should return a newly created frame.
-
-A typical value might be `(lambda () (new-frame pop-up-frame-alist))'
-where `pop-up-frame-alist' would hold the default frame parameters.  */);
-  Vpop_up_frame_function = Qnil;
-
-  DEFVAR_LISP ("special-display-buffer-names", &Vspecial_display_buffer_names,
-	       doc: /* *List of buffer names that should have their own special frames.
-Displaying a buffer with `display-buffer' or `pop-to-buffer',
-if its name is in this list, makes a special frame for it
-using `special-display-function'.  See also `special-display-regexps'.
-
-An element of the list can be a list instead of just a string.
-There are two ways to use a list as an element:
-  (BUFFER FRAME-PARAMETERS...)   (BUFFER FUNCTION OTHER-ARGS...)
-In the first case, the FRAME-PARAMETERS are pairs of the form
-\(PARAMETER . VALUE); these parameter values are used to create the frame.
-In the second case, FUNCTION is called with BUFFER as the first argument,
-followed by the OTHER-ARGS--it can display BUFFER in any way it likes.
-All this is done by the function found in `special-display-function'.
-
-If the specified frame parameters include (same-buffer . t), the
-buffer is displayed in the currently selected window.  Otherwise, if
-they include (same-frame . t), the buffer is displayed in a new window
-in the currently selected frame.
-
-If this variable appears \"not to work\", because you add a name to it
-but that buffer still appears in the selected window, look at the
-values of `same-window-buffer-names' and `same-window-regexps'.
-Those variables take precedence over this one.  */);
-  Vspecial_display_buffer_names = Qnil;
-
-  DEFVAR_LISP ("special-display-regexps", &Vspecial_display_regexps,
-	       doc: /* *List of regexps saying which buffers should have their own special frames.
-When displaying a buffer with `display-buffer' or `pop-to-buffer',
-if any regexp in this list matches the buffer name, it makes a
-special frame for the buffer by calling `special-display-function'.
-
-An element of the list can be a list instead of just a string.
-There are two ways to use a list as an element:
-  (REGEXP FRAME-PARAMETERS...)   (REGEXP FUNCTION OTHER-ARGS...)
-In the first case, the FRAME-PARAMETERS are pairs of the form
-\(PARAMETER . VALUE); these parameter values are used to create the frame.
-In the second case, FUNCTION is called with BUFFER as the first argument,
-followed by the OTHER-ARGS--it can display the buffer in any way it likes.
-All this is done by the function found in `special-display-function'.
-
-If the specified frame parameters include (same-buffer . t), the
-buffer is displayed in the currently selected window.  Otherwise, if
-they include (same-frame . t), the buffer is displayed in a new window
-in the currently selected frame.
-
-If this variable appears \"not to work\", because you add a regexp to it
-but the matching buffers still appear in the selected window, look at the
-values of `same-window-buffer-names' and `same-window-regexps'.
-Those variables take precedence over this one.  */);
-  Vspecial_display_regexps = Qnil;
-
-  DEFVAR_LISP ("special-display-function", &Vspecial_display_function,
-	       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 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;
-
-  DEFVAR_LISP ("same-window-buffer-names", &Vsame_window_buffer_names,
-	       doc: /* *List of buffer names that should appear in the selected window.
-Displaying one of these buffers using `display-buffer' or `pop-to-buffer'
-switches to it in the selected window, rather than making it appear
-in some other window.
-
-An element of the list can be a cons cell instead of just a string.
-Then the car must be a string, which specifies the buffer name.
-This is for compatibility with `special-display-buffer-names';
-the cdr of the cons cell is ignored.
-
-See also `same-window-regexps'.  */);
-  Vsame_window_buffer_names = Qnil;
-
-  DEFVAR_LISP ("same-window-regexps", &Vsame_window_regexps,
-	       doc: /* *List of regexps saying which buffers should appear in the selected window.
-If a buffer name matches one of these regexps, then displaying it
-using `display-buffer' or `pop-to-buffer' switches to it
-in the selected window, rather than making it appear in some other window.
-
-An element of the list can be a cons cell instead of just a string.
-Then the car must be a string, which specifies the buffer name.
-This is for compatibility with `special-display-buffer-names';
-the cdr of the cons cell is ignored.
-
-See also `same-window-buffer-names'.  */);
-  Vsame_window_regexps = Qnil;
-
-  DEFVAR_BOOL ("pop-up-windows", &pop_up_windows,
-	       doc: /* *Non-nil means display-buffer should make new windows.  */);
-  pop_up_windows = 1;
-
   DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines,
 	      doc: /* *Number of lines of continuity when scrolling by screenfuls.  */);
   next_screen_context_lines = 2;
 
-  DEFVAR_INT ("split-height-threshold", &split_height_threshold,
-	      doc: /* *A window must be at least this tall to be eligible for splitting
-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.
-When this variable is nil, `display-buffer' splits windows vertically.
-Otherwise, `display-buffer' calls this function to split a window.
-It is called with a window as single argument and should split it in two
-and return the new window, or return an appropriate existing window
-if splitting is not eligible.  */);
-  Vsplit_window_preferred_function = Qnil;
-
   DEFVAR_INT ("window-min-height", &window_min_height,
 	      doc: /* Allow deleting windows less than this tall.
 The value is measured in line units.  If a window wants a modeline it
@@ -7724,9 +7201,6 @@
   defsubr (&Sdelete_window);
   defsubr (&Sset_window_buffer);
   defsubr (&Sselect_window);
-  defsubr (&Sspecial_display_p);
-  defsubr (&Ssame_window_p);
-  defsubr (&Sdisplay_buffer);
   defsubr (&Sforce_window_update);
   defsubr (&Ssplit_window);
   defsubr (&Senlarge_window);
--- a/src/window.h	Thu Jun 05 17:31:55 2008 +0000
+++ b/src/window.h	Thu Jun 05 18:00:36 2008 +0000
@@ -760,7 +760,6 @@
 
 EXFUN (Fnext_window, 3);
 EXFUN (Fselect_window, 2);
-EXFUN (Fdisplay_buffer, 3);
 EXFUN (Fset_window_buffer, 3);
 EXFUN (Fset_window_hscroll, 2);
 EXFUN (Fwindow_hscroll, 1);