* emacs-lisp/lisp-mode.el (emacs-lisp-mode-syntax-table): Unnest `let'.
[bpt/emacs.git] / lisp / window.el
index 0372a2f..f693077 100644 (file)
@@ -63,25 +63,26 @@ are not altered by this macro (unless they are altered in BODY)."
         (when (window-live-p save-selected-window-window)
           (select-window save-selected-window-window 'norecord))))))
 
-;; The following two functions are like `window-next' and `window-prev'
-;; but the WINDOW argument is _not_ optional (so they don't substitute
-;; the selected window for nil), and they return nil when WINDOW doesn't
-;; have a parent (like a frame's root window or a minibuffer window).
+;; The following two functions are like `window-next-sibling' and
+;; `window-prev-sibling' but the WINDOW argument is _not_ optional (so
+;; they don't substitute the selected window for nil), and they return
+;; nil when WINDOW doesn't have a parent (like a frame's root window or
+;; a minibuffer window).
 (defsubst window-right (window)
   "Return WINDOW's right sibling.
 Return nil if WINDOW is the root window of its frame.  WINDOW can
 be any window."
-  (and window (window-parent window) (window-next window)))
+  (and window (window-parent window) (window-next-sibling window)))
 
 (defsubst window-left (window)
   "Return WINDOW's left sibling.
 Return nil if WINDOW is the root window of its frame.  WINDOW can
 be any window."
-  (and window (window-parent window) (window-prev window)))
+  (and window (window-parent window) (window-prev-sibling window)))
 
 (defsubst window-child (window)
   "Return WINDOW's first child window."
-  (or (window-vchild window) (window-hchild window)))
+  (or (window-top-child window) (window-left-child window)))
 
 (defun window-child-count (window)
   "Return number of WINDOW's child windows."
@@ -89,14 +90,14 @@ be any window."
     (when (and (windowp window) (setq window (window-child window)))
       (while window
        (setq count (1+ count))
-       (setq window (window-next window))))
+       (setq window (window-next-sibling window))))
     count))
 
 (defun window-last-child (window)
   "Return last child window of WINDOW."
   (when (and (windowp window) (setq window (window-child window)))
-    (while (window-next window)
-      (setq window (window-next window))))
+    (while (window-next-sibling window)
+      (setq window (window-next-sibling window))))
   window)
 
 (defsubst window-any-p (object)
@@ -169,7 +170,7 @@ of this variable is honored when windows are resized or split.
 
 Applications should never rebind this variable.  To resize a
 window to a height less than the one specified here, an
-application should instead call `resize-window' with a non-nil
+application should instead call `window-resize' with a non-nil
 IGNORE argument.  In order to have `split-window' make a window
 shorter, explictly specify the SIZE argument of that function."
   :type 'integer
@@ -189,7 +190,7 @@ split.
 
 Applications should never rebind this variable.  To resize a
 window to a width less than the one specified here, an
-application should instead call `resize-window' with a non-nil
+application should instead call `window-resize' with a non-nil
 IGNORE argument.  In order to have `split-window' make a window
 narrower, explictly specify the SIZE argument of that function."
   :type 'integer
@@ -203,8 +204,8 @@ Optional argument HORIZONTAL non-nil means return WINDOW's first
 child if WINDOW is a horizontal combination."
   (setq window (normalize-any-window window))
   (if horizontal
-      (window-hchild window)
-    (window-vchild window)))
+      (window-left-child window)
+    (window-top-child window)))
 
 (defsubst window-iso-combined-p (&optional window horizontal)
   "Return non-nil if and only if WINDOW is vertically combined.
@@ -258,9 +259,9 @@ number of horizontally arranged subwindows of WINDOW."
        (funcall proc walk-window-tree-window))
       (unless walk-window-tree-buffer
        (walk-window-tree-1
-        proc (window-hchild walk-window-tree-window) any)
+        proc (window-left-child walk-window-tree-window) any)
        (walk-window-tree-1
-        proc (window-vchild walk-window-tree-window) any))
+        proc (window-top-child walk-window-tree-window) any))
       (if sub-only
          (setq walk-window-tree-window nil)
        (setq walk-window-tree-window
@@ -375,8 +376,8 @@ WINDOW must be an internal window.  Return WINDOW."
             window t)))
       ;; Check children.
       (unless (window-buffer window)
-       (window-atom-check-1 (window-hchild window))
-       (window-atom-check-1 (window-vchild window))))
+       (window-atom-check-1 (window-left-child window))
+       (window-atom-check-1 (window-top-child window))))
     ;; Check right sibling
     (window-atom-check-1 (window-right window))))
 
@@ -1165,13 +1166,20 @@ IGNORE, when non-nil means a window can be returned even if its
      (window-frame window))
     (or best best-2)))
 
-(defun get-window-with-predicate (predicate &optional minibuf
-                                           all-frames default)
+(defun get-window-with-predicate (predicate &optional minibuf all-frames default)
   "Return a live window satisfying PREDICATE.
 More precisely, cycle through all windows calling the function
 PREDICATE on each one of them with the window as its sole
 argument.  Return the first window for which PREDICATE returns
-non-nil.  If no window satisfies PREDICATE, return DEFAULT.
+non-nil.  Windows are scanned starting with the window following
+the selcted window.  If no window satisfies PREDICATE, return
+DEFAULT.
+
+MINIBUF t means include the minibuffer window even if the
+minibuffer is not active.  MINIBUF nil or omitted means include
+the minibuffer window only if the minibuffer is active.  Any
+other value means do not include the minibuffer window even if
+the minibuffer is active.
 
 ALL-FRAMES nil or omitted means consider all windows on the selected
 frame, plus the minibuffer window if specified by the MINIBUF
@@ -1192,7 +1200,9 @@ values of ALL-FRAMES have special meanings:
 Anything else means consider all windows on the selected frame
 and no others."
   (catch 'found
-    (dolist (window (window-list-1 nil minibuf all-frames))
+    (dolist (window (window-list-1
+                    (next-window nil minibuf all-frames)
+                    minibuf all-frames))
       (when (funcall predicate window)
        (throw 'found window)))
     default))
@@ -1222,7 +1232,7 @@ have special meanings:
 Any other value of ALL-FRAMES means consider all windows on the
 selected frame and no others."
    (let (best-window best-time second-best-window second-best-time time)
-    (dolist (window (window-list-1 nil nil all-frames))
+    (dolist (window (window-list-1 nil 'nomini all-frames))
       (when (or dedicated (not (window-dedicated-p window)))
        (setq time (window-use-time window))
        (if (or (eq window (selected-window))
@@ -1255,7 +1265,7 @@ have special meanings:
 Any other value of ALL-FRAMES means consider all windows on the
 selected frame and no others."
    (let (best-window best-time time)
-    (dolist (window (window-list-1 nil nil all-frames))
+    (dolist (window (window-list-1 nil 'nomini all-frames))
       (setq time (window-use-time window))
       (when (or (not best-time) (> time best-time))
        (setq best-time time)
@@ -1285,7 +1295,7 @@ Any other value of ALL-FRAMES means consider all windows on the
 selected frame and no others."
   (let ((best-size 0)
        best-window size)
-    (dolist (window (window-list-1 nil nil all-frames))
+    (dolist (window (window-list-1 nil 'nomini all-frames))
       (when (or dedicated (not (window-dedicated-p window)))
        (setq size (* (window-total-size window)
                      (window-total-size window t)))
@@ -1297,10 +1307,8 @@ selected frame and no others."
 (defun get-buffer-window-list (&optional buffer-or-name minibuf all-frames)
   "Return list of all windows displaying BUFFER-OR-NAME, or nil if none.
 BUFFER-OR-NAME may be a buffer or the name of an existing buffer
-and defaults to the current buffer.
-
-Any windows showing BUFFER-OR-NAME on the selected frame are listed
-first.
+and defaults to the current buffer.  Windows are scanned starting
+with the selected window.
 
 MINIBUF t means include the minibuffer window even if the
 minibuffer is not active.  MINIBUF nil or omitted means include
@@ -1328,7 +1336,7 @@ Anything else means consider all windows on the selected frame
 and no others."
   (let ((buffer (normalize-live-buffer buffer-or-name))
        windows)
-    (dolist (window (window-list-1 (frame-first-window) minibuf all-frames))
+    (dolist (window (window-list-1 (selected-window) minibuf all-frames))
       (when (eq (window-buffer window) buffer)
        (setq windows (cons window windows))))
     (nreverse windows)))
@@ -1345,7 +1353,7 @@ meaning of this argument."
    (length (window-list-1 nil minibuf)))
 \f
 ;;; Resizing windows.
-(defun resize-window-reset (&optional frame horizontal)
+(defun window-resize-reset (&optional frame horizontal)
   "Reset resize values for all windows on FRAME.
 FRAME defaults to the selected frame.
 
@@ -1353,19 +1361,19 @@ This function stores the current value of `window-total-size' applied
 with argument HORIZONTAL in the new total size of all windows on
 FRAME.  It also resets the new normal size of each of these
 windows."
-  (resize-window-reset-1
+  (window-resize-reset-1
    (frame-root-window (normalize-live-frame frame)) horizontal))
 
-(defun resize-window-reset-1 (window horizontal)
-  "Internal function of `resize-window-reset'."
+(defun window-resize-reset-1 (window horizontal)
+  "Internal function of `window-resize-reset'."
   ;; Register old size in the new total size.
   (set-window-new-total window (window-total-size window horizontal))
   ;; Reset new normal size.
   (set-window-new-normal window)
   (when (window-child window)
-    (resize-window-reset-1 (window-child window) horizontal))
+    (window-resize-reset-1 (window-child window) horizontal))
   (when (window-right window)
-    (resize-window-reset-1 (window-right window) horizontal)))
+    (window-resize-reset-1 (window-right window) horizontal)))
 
 ;; The following routine is used to manually resize the minibuffer
 ;; window and is currently used, for example, by ispell.el.
@@ -1388,7 +1396,7 @@ as small) as possible but don't signal an error."
        (setq delta min-delta)))
 
       ;; Resize now.
-      (resize-window-reset frame)
+      (window-resize-reset frame)
       ;; Ideally we should be able to resize just the last subwindow of
       ;; root here.  See the comment in `resize-root-window-vertically'
       ;; for why we do not do that.
@@ -1398,7 +1406,7 @@ as small) as possible but don't signal an error."
       ;; a minibuffer-only frame.
       (resize-mini-window-internal window))))
 
-(defun resize-window (window delta &optional horizontal ignore)
+(defun window-resize (window delta &optional horizontal ignore)
   "Resize WINDOW vertically by DELTA lines.
 WINDOW can be an arbitrary window and defaults to the selected
 one.  An attempt to resize the root window of a frame will raise
@@ -1433,7 +1441,7 @@ instead."
      ((window-minibuffer-p window)
       (resize-mini-window window delta))
      ((window-resizable-p window delta horizontal ignore)
-      (resize-window-reset frame horizontal)
+      (window-resize-reset frame horizontal)
       (resize-this-window window delta horizontal ignore t)
       (if (and (not (window-splits window))
               (window-iso-combined-p window horizontal)
@@ -1454,7 +1462,7 @@ instead."
                        normal-delta)))
        ;; Otherwise, resize all other windows in the same combination.
        (resize-other-windows window delta horizontal ignore))
-      (resize-window-apply frame horizontal))
+      (window-resize-apply frame horizontal))
      (t
       (error "Cannot resize window %s" window)))))
 
@@ -1718,7 +1726,7 @@ already set by this routine."
        (while sub
          (when (or (consp (window-new-normal sub))
                    (numberp (window-new-normal sub)))
-           ;; Reset new normal size fields so `resize-window-apply'
+           ;; Reset new normal size fields so `window-resize-apply'
            ;; won't use them to apply new sizes.
            (set-window-new-normal sub))
 
@@ -1859,7 +1867,7 @@ This function recursively resizes WINDOW's subwindows to fit the
 new size.  Make sure that WINDOW is `window-resizable' before
 calling this function.  Note that this function does not resize
 siblings of WINDOW or WINDOW's parent window.  You have to
-eventually call `resize-window-apply' in order to make resizing
+eventually call `window-resize-apply' in order to make resizing
 actually take effect."
   (when add
     ;; Add DELTA to the new total size of WINDOW.
@@ -1890,7 +1898,7 @@ This function is only called by the frame resizing routines.  It
 resizes windows proportionally and never deletes any windows."
   (when (and (windowp window) (numberp delta)
             (window-sizable-p window delta horizontal ignore))
-    (resize-window-reset (window-frame window) horizontal)
+    (window-resize-reset (window-frame window) horizontal)
     (resize-this-window window delta horizontal ignore t)))
 
 (defun resize-root-window-vertically (window delta)
@@ -1914,7 +1922,7 @@ any windows."
        (unless (window-sizable window delta)
          (setq ignore t))))
 
-      (resize-window-reset (window-frame window))
+      (window-resize-reset (window-frame window))
       ;; Ideally, we would resize just the last window in a combination
       ;; but that's not feasible for the following reason: If we grow
       ;; the minibuffer window and the last window cannot be shrunk any
@@ -1992,7 +2000,7 @@ move it as far as possible in the desired direction."
          (setq delta (min max-delta (- min-delta))))
        (unless (zerop delta)
          ;; Start resizing.
-         (resize-window-reset frame horizontal)
+         (window-resize-reset frame horizontal)
          ;; Try to enlarge LEFT first.
          (setq this-delta (window-resizable left delta horizontal))
          (unless (zerop this-delta)
@@ -2015,7 +2023,7 @@ move it as far as possible in the desired direction."
          (setq delta (max (- max-delta) min-delta)))
        (unless (zerop delta)
          ;; Start resizing.
-         (resize-window-reset frame horizontal)
+         (window-resize-reset frame horizontal)
          ;; Try to enlarge RIGHT.
          (setq this-delta (window-resizable right (- delta) horizontal))
          (unless (zerop this-delta)
@@ -2032,7 +2040,7 @@ move it as far as possible in the desired direction."
             (+ (window-top-line left) (window-total-size left)))))))
       (unless (zerop delta)
        ;; Don't report an error in the standard case.
-       (unless (resize-window-apply frame horizontal)
+       (unless (window-resize-apply frame horizontal)
          ;; But do report an error if applying the changes fails.
          (error "Failed adjusting window %s" window)))))))
 
@@ -2049,9 +2057,9 @@ Return nil."
    ((window-size-fixed-p nil horizontal)
     (error "Selected window has fixed size"))
    ((window-resizable-p nil delta horizontal)
-    (resize-window nil delta horizontal))
+    (window-resize nil delta horizontal))
    (t
-    (resize-window
+    (window-resize
      nil (if (> delta 0)
             (window-max-delta nil horizontal)
           (- (window-min-delta nil horizontal)))
@@ -2070,9 +2078,9 @@ Return nil."
    ((window-size-fixed-p nil horizontal)
     (error "Selected window has fixed size"))
    ((window-resizable-p nil (- delta) horizontal)
-    (resize-window nil (- delta) horizontal))
+    (window-resize nil (- delta) horizontal))
    (t
-    (resize-window
+    (window-resize
      nil (if (> delta 0)
             (- (window-min-delta nil horizontal))
           (window-max-delta nil horizontal))
@@ -2084,8 +2092,8 @@ Make WINDOW as large as possible without deleting any windows.
 WINDOW can be any window and defaults to the selected window."
   (interactive)
   (setq window (normalize-any-window window))
-  (resize-window window (window-max-delta window))
-  (resize-window window (window-max-delta window t) t))
+  (window-resize window (window-max-delta window))
+  (window-resize window (window-max-delta window t) t))
 
 (defun minimize-window (&optional window)
   "Minimize WINDOW.
@@ -2093,8 +2101,8 @@ Make WINDOW as small as possible without deleting any windows.
 WINDOW can be any window and defaults to the selected window."
   (interactive)
   (setq window (normalize-any-window window))
-  (resize-window window (- (window-min-delta window)))
-  (resize-window window (- (window-min-delta window t)) t))
+  (window-resize window (- (window-min-delta window)))
+  (window-resize window (- (window-min-delta window t)) t))
 \f
 (defsubst frame-root-window-p (window)
   "Return non-nil if WINDOW is the root window of its frame."
@@ -2112,15 +2120,15 @@ return value."
       (setq list
            (cons
             (cond
-             ((window-vchild window)
+             ((window-top-child window)
               (cons t (cons (window-edges window)
-                            (window-tree-1 (window-vchild window) t))))
-             ((window-hchild window)
+                            (window-tree-1 (window-top-child window) t))))
+             ((window-left-child window)
               (cons nil (cons (window-edges window)
-                              (window-tree-1 (window-hchild window) t))))
+                              (window-tree-1 (window-left-child window) t))))
              (t window))
             list))
-      (setq window (when next (window-next window))))
+      (setq window (when next (window-next-sibling window))))
     (nreverse list)))
 
 (defun window-tree (&optional frame)
@@ -2244,6 +2252,28 @@ and no others."
        (next-window base-window (if nomini 'arg) all-frames))))
 \f
 ;;; Deleting windows.
+(defcustom frame-auto-delete 'automatic
+  "If non-nil, quitting a window can delete it's frame.
+If this variable is nil, functions that quit a window never
+delete the associated frame.  If this variable equals the symbol
+`automatic', a frame is deleted only if it the window is
+dedicated or was created by `display-buffer'.  If this variable
+is t, a frame can be always deleted, even if it was created by
+`make-frame-command'.  Other values should not be used.
+
+Note that a frame will be effectively deleted if and only if
+another frame still exists.
+
+Functions quitting a window and consequently affected by this
+variable are `switch-to-prev-buffer', `delete-windows-on',
+`replace-buffer-in-windows' and `quit-restore-window'."
+  :type '(choice
+         (const :tag "Never" nil)
+         (const :tag "Automatic" automatic)
+         (const :tag "Always" t))
+  :group 'windows
+  :group 'frames)
+
 (defun window-deletable-p (&optional window)
   "Return t if WINDOW can be safely deleted from its frame.
 Return `frame' if deleting WINDOW should delete its frame
@@ -2259,9 +2289,12 @@ instead."
        (quit-restore (window-parameter window 'quit-restore)))
     (cond
      ((frame-root-window-p window)
-      (when (and (or dedicated
-                    (and (eq (car-safe quit-restore) 'new-frame)
-                         (eq (nth 1 quit-restore) (window-buffer window))))
+      (when (and (or (eq frame-auto-delete t)
+                    (and (eq frame-auto-delete 'automatic)
+                         (or dedicated
+                             (and (eq (car-safe quit-restore) 'new-frame)
+                                  (eq (nth 1 quit-restore)
+                                      (window-buffer window))))))
                 (other-visible-frames-p frame))
        ;; WINDOW is the root window of its frame.  Return `frame' but
        ;; only if WINDOW is (1) either dedicated or quit-restore's car
@@ -2331,14 +2364,14 @@ non-side window, signal an error."
        ((not parent)
        (error "Attempt to delete minibuffer or sole ordinary window")))
 
-      (let* ((horizontal (window-hchild parent))
+      (let* ((horizontal (window-left-child parent))
             (size (window-total-size window horizontal))
             (frame-selected
              (window-or-subwindow-p (frame-selected-window frame) window))
             ;; Emacs 23 preferably gives WINDOW's space to its left
             ;; sibling.
             (sibling (or (window-left window) (window-right window))))
-       (resize-window-reset frame horizontal)
+       (window-resize-reset frame horizontal)
        (cond
         ((and (not (window-splits window))
               sibling (window-sizable-p sibling size))
@@ -2912,7 +2945,7 @@ buffer list.  Interactively, KILL is the prefix argument."
       (set-window-start window (nth 1 quit-restore))
       (set-window-point window (nth 2 quit-restore))
       (when (and resize (/= (nth 4 quit-restore) (window-total-size window)))
-       (resize-window
+       (window-resize
         window (- (nth 4 quit-restore) (window-total-size window))))
       ;; Reset the quit-restore parameter.
       (set-window-parameter window 'quit-restore nil)
@@ -2982,7 +3015,11 @@ new window are inherited from the window selected on WINDOW's
 frame.  The selected window is not changed by this function."
   (interactive "i")
   (setq window (normalize-any-window window))
-  (let* ((horizontal (not (memq side '(nil below above))))
+  (let* ((side (cond
+               ((not side) 'below)
+               ((memq side '(below above right left)) side)
+               (t 'right)))
+        (horizontal (not (memq side '(nil below above))))
         (frame (window-frame window))
         (parent (window-parent window))
         (function (window-parameter window 'split-window))
@@ -3104,7 +3141,7 @@ frame.  The selected window is not changed by this function."
          ;; SIZE specification violates minimum size restrictions.
          (error "Window %s too small for splitting" window)))
 
-       (resize-window-reset frame horizontal)
+       (window-resize-reset frame horizontal)
 
        (setq new-parent
              ;; Make new-parent non-nil if we need a new parent window;
@@ -3359,13 +3396,13 @@ window."
            (error "Not a window or frame %s" window-or-frame))))
         (frame (window-frame window)))
     ;; Balance vertically.
-    (resize-window-reset (window-frame window))
+    (window-resize-reset (window-frame window))
     (balance-windows-1 window)
-    (resize-window-apply frame)
+    (window-resize-apply frame)
     ;; Balance horizontally.
-    (resize-window-reset (window-frame window) t)
+    (window-resize-reset (window-frame window) t)
     (balance-windows-1 window t)
-    (resize-window-apply frame t)))
+    (window-resize-apply frame t)))
 
 (defun window-fixed-size-p (&optional window direction)
   "Return t if WINDOW cannot be resized in DIRECTION.
@@ -3385,13 +3422,13 @@ Changing this globally has no effect.")
 (make-variable-buffer-local 'window-area-factor)
 
 (defun balance-windows-area-adjust (window delta horizontal)
-  "Wrapper around `resize-window' with error checking.
+  "Wrapper around `window-resize' with error checking.
 Arguments WINDOW, DELTA and HORIZONTAL are passed on to that function."
-  ;; `resize-window' may fail if delta is too large.
+  ;; `window-resize' may fail if delta is too large.
   (while (>= (abs delta) 1)
     (condition-case nil
         (progn
-          (resize-window window delta horizontal)
+          (window-resize window delta horizontal)
           (setq delta 0))
       (error
        ;;(message "adjust: %s" (error-message-string err))
@@ -3459,7 +3496,7 @@ specific buffers."
               ;; become significant.
               (setq carry (+ carry areadiff))
            ;; This used `adjust-window-trailing-edge' before and uses
-           ;; `resize-window' now.  Error wrapping is still needed.
+           ;; `window-resize' now.  Error wrapping is still needed.
            (balance-windows-area-adjust win diff horiz)
             ;; (sit-for 0.5)
             (let ((change (cons win (window-edges win))))
@@ -3475,15 +3512,321 @@ specific buffers."
     ;; (bw-finetune wins)
     ;; (message "Done in %d rounds" round)
     ))
+
+;;; Window states, how to get them and how to put them in a window.
+(defsubst window-list-no-nils (&rest args)
+  "Like LIST but do not add nil elements of ARGS."
+  (delq nil (apply 'list args)))
+
+(defvar window-state-ignored-parameters '(quit-restore)
+  "List of window parameters ignored by `window-state-get'.")
+
+(defun window-state-get-1 (window &optional markers)
+  "Helper function for `window-state-get'."
+  (let* ((type
+         (cond
+          ((window-top-child window) 'vc)
+          ((window-left-child window) 'hc)
+          (t 'leaf)))
+        (buffer (window-buffer window))
+        (selected (eq window (selected-window)))
+        (head
+         (window-list-no-nils
+          type
+          (unless (window-next-sibling window) (cons 'last t))
+          (cons 'clone-number (window-clone-number window))
+          (cons 'total-height (window-total-size window))
+          (cons 'total-width (window-total-size window t))
+          (cons 'normal-height (window-normal-size window))
+          (cons 'normal-width (window-normal-size window t))
+          (cons 'splits (window-splits window))
+          (cons 'nest (window-nest window))
+          (let (list)
+            (dolist (parameter (window-parameters window))
+              (unless (memq (car parameter)
+                            window-state-ignored-parameters)
+                (setq list (cons parameter list))))
+            (when list
+              (cons 'parameters list)))
+          (when buffer
+            ;; All buffer related things go in here - make the buffer
+            ;; current when retrieving `point' and `mark'.
+            (with-current-buffer (window-buffer window)
+              (let ((point (if selected (point) (window-point window)))
+                    (start (window-start window))
+                    (mark (mark)))
+                (window-list-no-nils
+                 'buffer (buffer-name buffer)
+                 (cons 'selected selected)
+                 (when window-size-fixed (cons 'size-fixed window-size-fixed))
+                 (cons 'hscroll (window-hscroll window))
+                 (cons 'fringes (window-fringes window))
+                 (cons 'margins (window-margins window))
+                 (cons 'scroll-bars (window-scroll-bars window))
+                 (cons 'vscroll (window-vscroll window))
+                 (cons 'dedicated (window-dedicated-p window))
+                 (cons 'point (if markers (copy-marker point) point))
+                 (cons 'start (if markers (copy-marker start) start))
+                 (when mark
+                   (cons 'mark (if markers (copy-marker mark) mark)))))))))
+        (tail
+         (when (memq type '(vc hc))
+           (let (list)
+             (setq window (window-child window))
+             (while window
+               (setq list (cons (window-state-get-1 window markers) list))
+               (setq window (window-right window)))
+             (nreverse list)))))
+    (append head tail)))
+
+(defun window-state-get (&optional window markers)
+  "Return state of WINDOW as a Lisp object.
+WINDOW can be any window and defaults to the root window of the
+selected frame.
+
+Optional argument MARKERS non-nil means use markers for sampling
+positions like `window-point' or `window-start'.  MARKERS should
+be non-nil only if the value is used for putting the state back
+in the same session (note that markers slow down processing).
+
+The return value can be used as argument for `window-state-put'
+to put the state recorded here into an arbitrary window.  The
+value can be also stored on disk and read back in a new session."
+  (setq window
+       (if window
+           (if (window-any-p window)
+               window
+             (error "%s is not a live or internal window" window))
+         (frame-root-window)))
+  ;; The return value is a cons whose car specifies some constraints on
+  ;; the size of WINDOW.  The cdr lists the states of the subwindows of
+  ;; WINDOW.
+  (cons
+   ;; Frame related things would go into a function, say `frame-state',
+   ;; calling `window-state-get' to insert the frame's root window.
+   (window-list-no-nils
+    (cons 'min-height (window-min-size window))
+    (cons 'min-width (window-min-size window t))
+    (cons 'min-height-ignore (window-min-size window nil t))
+    (cons 'min-width-ignore (window-min-size window t t))
+    (cons 'min-height-safe (window-min-size window nil 'safe))
+    (cons 'min-width-safe (window-min-size window t 'safe))
+    ;; These are probably not needed.
+    (when (window-size-fixed-p window) (cons 'fixed-height t))
+    (when (window-size-fixed-p window t) (cons 'fixed-width t)))
+   (window-state-get-1 window markers)))
+
+(defvar window-state-put-list nil
+  "Helper variable for `window-state-put'.")
+
+(defun window-state-put-1 (state &optional window ignore totals)
+  "Helper function for `window-state-put'."
+  (let ((type (car state)))
+    (setq state (cdr state))
+    (cond
+     ((eq type 'leaf)
+      ;; For a leaf window just add unprocessed entries to
+      ;; `window-state-put-list'.
+      (setq window-state-put-list
+           (cons (cons window state) window-state-put-list)))
+     ((memq type '(vc hc))
+      (let* ((horizontal (eq type 'hc))
+            (total (window-total-size window horizontal))
+            (first t)
+            size new)
+       (dolist (item state)
+         ;; Find the next child window.  WINDOW always points to the
+         ;; real window that we want to fill with what we find here.
+         (when (memq (car item) '(leaf vc hc))
+           (if (assq 'last item)
+               ;; The last child window.  Below `window-state-put-1'
+               ;; will put into it whatever ITEM has in store.
+               (setq new nil)
+             ;; Not the last child window, prepare for splitting
+             ;; WINDOW.  SIZE is the new (and final) size of the old
+             ;; window.
+             (setq size
+                   (if totals
+                       ;; Use total size.
+                       (cdr (assq (if horizontal 'total-width 'total-height) item))
+                     ;; Use normalized size and round.
+                     (round (* total
+                               (cdr (assq
+                                     (if horizontal 'normal-width 'normal-height)
+                                     item))))))
+
+             ;; Use safe sizes, we try to resize later.
+             (setq size (max size (if horizontal
+                                      window-safe-min-height
+                                    window-safe-min-width)))
+
+             (if (window-sizable-p window (- size) horizontal 'safe)
+                 (let* ((window-nest (assq 'nest item)))
+                   ;; We must inherit the nesting, otherwise we might mess
+                   ;; up handling of atomic and side window.
+                   (setq new (split-window window size horizontal)))
+               ;; Give up if we can't resize window down to safe sizes.
+               (error "Cannot resize window %s" window))
+
+             (when first
+               (setq first nil)
+               ;; When creating the first child window add for parent
+               ;; unprocessed entries to `window-state-put-list'.
+               (setq window-state-put-list
+                     (cons (cons (window-parent window) state)
+                           window-state-put-list))))
+
+           ;; Now process the current window (either the one we've just
+           ;; split or the last child of its parent).
+           (window-state-put-1 item window ignore totals)
+           ;; Continue with the last window split off.
+           (setq window new))))))))
+
+(defun window-state-put-2 (ignore)
+  "Helper function for `window-state-put'."
+  (dolist (item window-state-put-list)
+    (let ((window (car item))
+         (clone-number (cdr (assq 'clone-number item)))
+         (splits (cdr (assq 'splits item)))
+         (nest (cdr (assq 'nest item)))
+         (parameters (cdr (assq 'parameters item)))
+         (state (cdr (assq 'buffer item))))
+      ;; Put in clone-number.
+      (when clone-number (set-window-clone-number window clone-number))
+      (when splits (set-window-splits window splits))
+      (when nest (set-window-nest window nest))
+      ;; Process parameters.
+      (when parameters
+       (dolist (parameter parameters)
+         (set-window-parameter window (car parameter) (cdr parameter))))
+      ;; Process buffer related state.
+      (when state
+       ;; We don't want to raise an error here so we create a buffer if
+       ;; there's none.
+       (set-window-buffer window (get-buffer-create (car state)))
+       (with-current-buffer (window-buffer window)
+         (set-window-hscroll window (cdr (assq 'hscroll state)))
+         (apply 'set-window-fringes
+                (cons window (cdr (assq 'fringes state))))
+         (let ((margins (cdr (assq 'margins state))))
+           (set-window-margins window (car margins) (cdr margins)))
+         (let ((scroll-bars (cdr (assq 'scroll-bars state))))
+           (set-window-scroll-bars
+            window (car scroll-bars) (nth 2 scroll-bars) (nth 3 scroll-bars)))
+         (set-window-vscroll window (cdr (assq 'vscroll state)))
+         ;; Adjust vertically.
+         (if (memq window-size-fixed '(t height))
+             ;; A fixed height window, try to restore the original size.
+             (let ((delta (- (cdr (assq 'total-height item))
+                             (window-total-height window)))
+                   window-size-fixed)
+               (when (window-resizable-p window delta)
+                 (window-resize window delta)))
+           ;; Else check whether the window is not high enough.
+           (let* ((min-size (window-min-size window nil ignore))
+                  (delta (- min-size (window-total-size window))))
+             (when (and (> delta 0)
+                        (window-resizable-p window delta nil ignore))
+               (window-resize window delta nil ignore))))
+         ;; Adjust horizontally.
+         (if (memq window-size-fixed '(t width))
+             ;; A fixed width window, try to restore the original size.
+             (let ((delta (- (cdr (assq 'total-width item))
+                             (window-total-width window)))
+                   window-size-fixed)
+               (when (window-resizable-p window delta)
+                 (window-resize window delta)))
+           ;; Else check whether the window is not wide enough.
+           (let* ((min-size (window-min-size window t ignore))
+                  (delta (- min-size (window-total-size window t))))
+             (when (and (> delta 0)
+                        (window-resizable-p window delta t ignore))
+               (window-resize window delta t ignore))))
+         ;; Set dedicated status.
+         (set-window-dedicated-p window (cdr (assq 'dedicated state)))
+         ;; Install positions (maybe we should do this after all windows
+         ;; have been created and sized).
+         (ignore-errors
+           (set-window-start window (cdr (assq 'start state)))
+           (set-window-point window (cdr (assq 'point state)))
+           ;; I'm not sure whether we should set the mark here, but maybe
+           ;; it can be used.
+           (let ((mark (cdr (assq 'mark state))))
+             (when mark (set-mark mark))))
+         ;; Select window if it's the selected one.
+         (when (cdr (assq 'selected state))
+           (select-window window)))))))
+
+(defun window-state-put (state &optional window ignore)
+  "Put window state STATE into WINDOW.
+STATE should be the state of a window returned by an earlier
+invocation of `window-state-get'.  Optional argument WINDOW must
+specify a live window and defaults to the selected one.
+
+Optional argument IGNORE non-nil means ignore minimum window
+sizes and fixed size restrictions.  IGNORE equal `safe' means
+subwindows can get as small as `window-safe-min-height' and
+`window-safe-min-width'."
+  (setq window (normalize-live-window window))
+  (let* ((frame (window-frame window))
+        (head (car state))
+        ;; We check here (1) whether the total sizes of root window of
+        ;; STATE and that of WINDOW are equal so we can avoid
+        ;; calculating new sizes, and (2) if we do have to resize
+        ;; whether we can do so without violating size restrictions.
+        (totals
+         (and (= (window-total-size window)
+                 (cdr (assq 'total-height state)))
+              (= (window-total-size window t)
+                 (cdr (assq 'total-width state)))))
+        (min-height (cdr (assq 'min-height head)))
+        (min-width (cdr (assq 'min-width head)))
+        window-splits selected)
+    (if (and (not totals)
+            (or (> min-height (window-total-size window))
+                (> min-width (window-total-size window t)))
+            (or (not ignore)
+                (and (setq min-height
+                           (cdr (assq 'min-height-ignore head)))
+                     (setq min-width
+                           (cdr (assq 'min-width-ignore head)))
+                     (or (> min-height (window-total-size window))
+                         (> min-width (window-total-size window t)))
+                     (or (not (eq ignore 'safe))
+                         (and (setq min-height
+                                    (cdr (assq 'min-height-safe head)))
+                              (setq min-width
+                                    (cdr (assq 'min-width-safe head)))
+                              (or (> min-height
+                                     (window-total-size window))
+                                  (> min-width
+                                     (window-total-size window t))))))))
+       ;; The check above might not catch all errors due to rounding
+       ;; issues - so IGNORE equal 'safe might not always produce the
+       ;; minimum possible state.  But such configurations hardly make
+       ;; sense anyway.
+       (error "Window %s too small to accomodate state" window)
+      (setq state (cdr state))
+      (setq window-state-put-list nil)
+      ;; Work on the windows of a temporary buffer to make sure that
+      ;; splitting proceeds regardless of any buffer local values of
+      ;; `window-size-fixed'.  Release that buffer after the buffers of
+      ;; all live windows have been set by `window-state-put-2'.
+      (with-temp-buffer
+       (set-window-buffer window (current-buffer))
+       (window-state-put-1 state window nil totals)
+       (window-state-put-2 ignore))
+      (window-check frame))))
 \f
 ;;; Displaying buffers.
 (defconst display-buffer-default-specifiers
   '((reuse-window nil same visible)
     (pop-up-window (largest . nil) (lru . nil))
-    (pop-up-frame)
-    (pop-up-frame-alist
-     (height . 24) (width . 80) (unsplittable . t))
+    (pop-up-window-min-height . 40)
+    (pop-up-window-min-width . 80)
+    (reuse-window other nil nil)
     (reuse-window nil other visible)
+    (reuse-window nil nil t)
     (reuse-window-even-sizes . t))
   "Buffer display default specifiers.
 The value specified here is used when no other specifiers have
@@ -3500,12 +3843,11 @@ buffer display specifiers.")
      (reuse-window nil same nil)
      (pop-up-window (largest . nil) (lru . nil))
      (reuse-window nil other nil))
-    (other-window
-     ;; Avoid selected window.
-     (reuse-window other same visible)
-     (pop-up-window (largest . nil) (lru . nil))
-     (pop-up-frame)
-     (reuse-window other other visible))
+    ;; (other-window
+    ;;  ;; Avoid selected window.
+    ;;  (reuse-window other same visible)
+    ;;  (pop-up-window (largest . nil) (lru . nil))
+    ;;  (reuse-window other other visible))
     (same-frame-other-window
      ;; Avoid other frames and selected window.
      (reuse-window other same nil)
@@ -3523,10 +3865,16 @@ buffer display specifiers.")
 
 (defcustom display-buffer-alist
   '((((regexp . ".*"))
-     reuse-window (reuse-window nil same visible)
+     ;; Reuse window showing same buffer on same frame.
+     reuse-window (reuse-window nil same nil)
+     ;; Pop up window.
      pop-up-window
+     ;; Split largest or lru window.
      (pop-up-window (largest . nil) (lru . nil))
-     reuse-window (reuse-window other other nil)
+     (pop-up-window-min-height . 40) ; split-height-threshold / 2
+     (pop-up-window-min-width . 80) ; split-width-threshold / 2
+     ;; Reuse any but selected window on same frame.
+     reuse-window (reuse-window other nil nil)
      (reuse-window-even-sizes . t)))
   "List associating buffer identifiers with display specifiers.
 The car of each element of this list is built from a set of cons
@@ -3787,6 +4135,14 @@ supported:
 
 - t to strongly dedicate the window to the buffer.
 
+A cons cell whose car is `other-window-means-other-frame' and
+whose cdr is non-nil means that you want calls of
+`display-buffer' with the second argument t or the symbol
+`other-window' to display the buffer in another frame.  This
+means, for example, that you prefer functions like
+`find-file-other-window' or `switch-to-buffer-other-window' to
+make a new frame instead of a new window on the selected frame.
+
 Usually, applications are free to override the specifiers of
 `display-buffer-alist' by passing their own specifiers as second
 argument of `display-buffer'.  For every `display-buffer-alist'
@@ -3827,7 +4183,7 @@ using the location specifiers `same-window' or `other-frame'."
        :tag "Label"
        :format "%v"
        :help-echo "A symbol equalling the buffer display label."
-       (const :format "" symbol)
+       (const :format "" label)
        (symbol :format "Label: %v\n" :size 32))))
 
      ;; Display specifiers.
@@ -4018,9 +4374,7 @@ using the location specifiers `same-window' or `other-frame'."
        (list
         :tag "Pop-up frame"
         :value (pop-up-frame
-                (pop-up-frame)
-                (pop-up-frame-alist
-                 (height . 24) (width . 80) (unsplittable . t)))
+                (pop-up-frame))
         :format "%t\n%v"
         :inline t
         (const :format "" pop-up-frame)
@@ -4184,7 +4538,12 @@ using the location specifiers `same-window' or `other-frame'."
 
        ;; Macro specifiers.
        (list
-        :tag "Same frame only"
+        :tag "Same window"
+        :format "%t%v"
+        :inline t
+        (const :format "\n" same-window))
+       (list
+        :tag "Same frame"
         :format "%t%v"
         :inline t
         (const :format "\n" same-frame))
@@ -4199,7 +4558,7 @@ using the location specifiers `same-window' or `other-frame'."
         :inline t
         (const :format "\n" same-frame-other-window))
        (list
-        :tag "Other frame only"
+        :tag "Other frame"
         :format "%t%v"
         :inline t
         (const :format "\n" other-frame))
@@ -4231,6 +4590,15 @@ using the location specifiers `same-window' or `other-frame'."
        :format "%[No other window%] %v\n" :size 15
        (const :tag "Off" :format "%t" nil)
        (const :tag "Ignore" :format "%t" t)))
+      ;; Other window means other frame.
+      (cons
+       :format "%v"
+       (const :format "" other-window-means-other-frame)
+       (choice
+       :help-echo "Whether other window means same or other frame."
+       :format "%[Same or other frame%] %v\n" :size 15
+       (const :tag "Same frame" :format "%t" nil)
+       (const :tag "Other frame" :format "%t" t)))
       ;; Overriding.
       (cons
        :format "%v\n"
@@ -4299,8 +4667,8 @@ larger than WINDOW."
        ;; Don't resize minibuffer windows.
        (window-minibuffer-p)
        ;; WINDOW must be adjacent to the selected one.
-       (not (or (eq window (window-prev))
-                (eq window (window-next))))))
+       (not (or (eq window (window-prev-sibling))
+                (eq window (window-next-sibling))))))
    ((and (window-iso-combined-p window)
         ;; Resize iff the selected window is higher than WINDOW.
         (> (window-total-height) (window-total-height window)))
@@ -4310,7 +4678,7 @@ larger than WINDOW."
     ;; WINDOW and the selected one.  But for a simple two windows
     ;; configuration the present behavior is good enough so why care?
     (ignore-errors
-      (resize-window
+      (window-resize
        window (/ (- (window-total-height) (window-total-height window))
                 2))))
    ((and (window-iso-combined-p window t)
@@ -4319,7 +4687,7 @@ larger than WINDOW."
     ;; Don't throw an error if we can't even window widths, see
     ;; comment above.
     (ignore-errors
-      (resize-window
+      (window-resize
        window (/ (- (window-total-width) (window-total-width window))
                 2) t)))))
 
@@ -4338,7 +4706,7 @@ documentation of `display-buffer-alist' for a description."
             (delta (- height (window-total-size window))))
        (when (and (window-resizable-p window delta nil 'safe)
                   (window-iso-combined-p window))
-         (resize-window window delta nil 'safe))))
+         (window-resize window delta nil 'safe))))
      ((functionp set-height)
       (ignore-errors (funcall set-height window))))))
 
@@ -4357,26 +4725,10 @@ documentation of `display-buffer-alist' for a description."
             (delta (- width (window-total-size window t))))
        (when (and (window-resizable-p window delta t 'safe)
                   (window-iso-combined-p window t))
-         (resize-window window delta t 'safe))))
+         (window-resize window delta t 'safe))))
      ((functionp set-width)
       (ignore-errors (funcall set-width window))))))
 
-;; We have to work around the deficiency that the command loop does not
-;; preserve the selected window when it is on a frame that hasn't been
-;; raised or given input focus.  So we have to (1) select the window
-;; used for displaying a buffer and (2) raise its frame if necessary,
-;; thus defeating one primary principle of `display-buffer' namely to
-;; _not_ select the window chosen for displaying the buffer :-(
-(defun display-buffer-select-window (window &optional norecord)
-  "Select WINDOW and raise its frame if necessary."
-  (let ((old-frame (selected-frame))
-       (new-frame (window-frame window)))
-    ;; Select WINDOW _before_ raising the frame to assure that the mouse
-    ;; cursor moves into the correct window.
-    (select-window window norecord)
-    (unless (eq old-frame new-frame)
-      (select-frame-set-input-focus new-frame))))
-
 (defun display-buffer-in-window (buffer window specifiers)
   "Display BUFFER in WINDOW and raise its frame if needed.
 WINDOW must be a live window and defaults to the selected one.
@@ -4391,14 +4743,24 @@ documentation of `display-buffer-alist' for a description."
         (dedicated (cdr (assq 'dedicated specifiers)))
         (no-other-window (cdr (assq 'no-other-window specifiers))))
     ;; Show BUFFER in WINDOW.
-    (set-window-dedicated-p window nil)
+    (unless (eq buffer (window-buffer window))
+      ;; If we show another buffer in WINDOW, undedicate it first.
+      (set-window-dedicated-p window nil))
     (set-window-buffer window buffer)
     (when dedicated
       (set-window-dedicated-p window dedicated))
     (when no-other-window
       (set-window-parameter window 'no-other-window t))
-    (unless (eq old-frame new-frame)
-      (display-buffer-select-window window))
+    (unless (or (eq old-frame new-frame)
+               (not (frame-visible-p new-frame))
+               ;; Assume the selected frame is already visible enough.
+               (eq new-frame (selected-frame))
+               ;; Assume the frame from which we invoked the minibuffer
+               ;; is visible.
+               (and (minibuffer-window-active-p (selected-window))
+                    (eq new-frame
+                        (window-frame (minibuffer-selected-window)))))
+      (raise-frame new-frame))
     ;; Return window.
     window))
 
@@ -4419,7 +4781,7 @@ none was found."
   (let* ((method-window (nth 0 method))
         (method-buffer (nth 1 method))
         (method-frame (nth 2 method))
-        (reuse-dedicated (assq 'reuse-window-dedicated specifiers))
+        (reuse-dedicated (cdr (assq 'reuse-window-dedicated specifiers)))
         windows other-frame dedicated time best-window best-time)
     (when (eq method-frame 'other)
       ;; `other' is not handled by `window-list-1'.
@@ -4658,65 +5020,69 @@ specifiers, see the doc-string of `display-buffer-alist' for a
 description."
   (let* ((frame (display-buffer-frame))
         (selected-window (frame-selected-window frame))
-        window side atomic)
+        cand window side atomic)
     (unless (and (cdr (assq 'unsplittable (frame-parameters frame)))
                 ;; Don't split an unsplittable frame unless
                 ;; SPECIFIERS allow it.
                 (not (cdr (assq 'split-unsplittable-frame specifiers))))
       (catch 'done
        (dolist (method methods)
-         (setq window (car method))
+         (setq cand (car method))
          (setq side (cdr method))
-         (and (setq window
-                    (cond
-                     ((eq window 'largest)
-                      (get-largest-window frame t))
-                     ((eq window 'lru)
-                      (get-lru-window frame t))
-                     ((eq window 'selected)
-                      (frame-selected-window frame))
-                     ((eq window 'root)
-                      ;; If there are side windows, split the main
-                      ;; window else the frame root window.
-                      (or (window-with-parameter 'window-side 'none nil t)
-                          (frame-root-window frame)))
-                     ((memq window window-sides)
-                      ;; This should gets us the "root" side
-                      ;; window if there exists more than one.
-                      (window-with-parameter 'window-side window nil t))
-                     ((windowp window)
-                      ;; A window, directly specified.
-                      window)))
-              ;; The window must be on the selected frame,
-              (eq (window-frame window) frame)
-              ;; and must be neither a minibuffer window,
-              (not (window-minibuffer-p window))
-              ;; nor a side window.
-              (not (eq (window-parameter window 'window-side) 'side))
-              (setq window
-                    (cond
-                     ((memq side display-buffer-side-specifiers)
-                      (if (and (window-buffer window)
-                               (setq atomic (cdr (assq 'atomic specifiers))))
-                          (display-buffer-split-atom-window
-                           window side (eq atomic 'nest) specifiers)
-                      (display-buffer-split-window window side specifiers)))
-                     ((functionp side)
-                      (ignore-errors
-                        ;; Don't pass any specifiers to this function.
-                        (funcall side window)))))
-              (throw 'done window))))
-
-      (when window
-       ;; Adjust sizes if asked for.
-       (display-buffer-set-height window specifiers)
-       (display-buffer-set-width window specifiers)
-       (set-window-parameter
-        window 'quit-restore (list 'new-window buffer selected-window))
-       (setq display-buffer-window (cons window 'new-window))
-       (display-buffer-in-window buffer window specifiers)
-       (set-window-prev-buffers window nil)
-       window))))
+         (setq window
+               (cond
+                ((eq cand 'largest)
+                 ;; The largest window. 
+                 (get-largest-window frame t))
+                ((eq cand 'lru)
+                 ;; The least recently used window.
+                 (get-lru-window frame t))
+                ((eq cand 'selected)
+                 ;; The selected window.
+                 (frame-selected-window frame))
+                ((eq cand 'root)
+                 ;; If there are side windows, split the main window
+                 ;; else the frame's root window.
+                 (or (window-with-parameter 'window-side 'none nil t)
+                     (frame-root-window frame)))
+                ((memq cand window-sides)
+                 ;; This should gets us the "root" side window if there
+                 ;; exists more than one window on that side.
+                 (window-with-parameter 'window-side cand nil t))
+                ((windowp cand)
+                 ;; A window, directly specified.
+                 cand)))
+
+         (when (and (window-live-p window)
+                    ;; The window must be on the correct frame,
+                    (eq (window-frame window) frame)
+                    ;; and must be neither a minibuffer window
+                    (not (window-minibuffer-p window))
+                    ;; nor a side window.
+                    (not (eq (window-parameter window 'window-side) 'side)))
+           (setq window
+                 (cond
+                  ((memq side display-buffer-side-specifiers)
+                   (if (and (window-buffer window)
+                            (setq atomic (cdr (assq 'atomic specifiers))))
+                       (display-buffer-split-atom-window
+                        window side (eq atomic 'nest) specifiers)
+                     (display-buffer-split-window window side specifiers)))
+                  ((functionp side)
+                   (ignore-errors
+                     ;; Don't pass any specifiers to this function.
+                     (funcall side window)))))
+
+           (when window
+             ;; Adjust sizes if asked for.
+             (display-buffer-set-height window specifiers)
+             (display-buffer-set-width window specifiers)
+             (set-window-parameter
+              window 'quit-restore (list 'new-window buffer selected-window))
+             (setq display-buffer-window (cons window 'new-window))
+             (display-buffer-in-window buffer window specifiers)
+             (set-window-prev-buffers window nil)
+             (throw 'done window))))))))
 
 (defun display-buffer-pop-up-frame (buffer &optional graphic-only specifiers)
   "Make a new frame for displaying BUFFER.
@@ -4928,51 +5294,113 @@ BUFFER-OR-NAME and return that buffer."
            buffer))
     (current-buffer)))
 
-(defun display-buffer-normalize-specifiers-1 (specifiers)
-  "Subroutine of `display-buffer-normalize-specifiers'.
-SPECIFIERS is the SPECIFIERS argument of `display-buffer'."
-  (let (normalized entry)
+(defun display-buffer-other-window-means-other-frame (buffer-or-name &optional label)
+  "Return non-nil if BUFFER shall be preferably displayed in another frame.
+BUFFER must be a live buffer or the name of a live buffer.
+
+Return nil if BUFFER shall be preferably displayed in another
+window on the selected frame.  Return non-nil if BUFFER shall be
+preferably displayed in a window on any but the selected frame.
+
+Optional argument LABEL is like the same argument of
+`display-buffer'.
+
+The calculation of the return value is exclusively based on the
+user preferences expressed in `display-buffer-alist'."
+  (let* ((buffer (normalize-live-buffer buffer-or-name))
+        (list (display-buffer-normalize-alist (buffer-name buffer) label))
+        (value (assq 'other-window-means-other-frame
+                     (or (car list) (cdr list)))))
+    (when value (cdr value))))
+
+(defun display-buffer-normalize-arguments (buffer-name specifiers label other-frame)
+  "Normalize second and third argument of `display-buffer'.
+BUFFER-NAME is the name of the buffer that shall be displayed,
+SPECIFIERS is the second argument of `display-buffer'.  LABEL is
+the same argument of `display-buffer'.  OTHER-FRAME non-nil means
+use other-frame for other-window."
+  (let (normalized entry specifier pars)
+    (setq specifier
+         (cond
+          ((not specifiers)
+           nil)
+          ((listp specifiers)
+           ;; If SPECIFIERS is a list, we assume it is a list of specifiers.
+           (dolist (specifier specifiers)
+             (cond
+              ((consp specifier)
+               (setq normalized (cons specifier normalized)))
+              ((eq specifier 'other-window)
+               ;; `other-window' must be treated separately.
+               (let ((entry (assq (if other-frame
+                                      'other-frame
+                                    'same-frame-other-window)
+                                  display-buffer-macro-specifiers)))
+                 (dolist (item (cdr entry))
+                   (setq normalized (cons item normalized)))))
+              ((symbolp specifier)
+               ;; Might be a macro specifier, try to expand it (the cdr is a
+               ;; list and we have to reverse it later, so do it one at a
+               ;; time).
+               (let ((entry (assq specifier display-buffer-macro-specifiers)))
+                 (dolist (item (cdr entry))
+                   (setq normalized (cons item normalized)))))))
+           ;; Reverse list.
+           (nreverse normalized))
+          ((setq entry (assq specifiers display-buffer-macro-specifiers))
+           ;; A macro specifier.
+           (cdr entry))
+          ((or other-frame (with-no-warnings pop-up-frames))
+           ;; `special-display-p' group.
+           (if (and (with-no-warnings special-display-function)
+                    ;; `special-display-p' returns either t or a list
+                    ;; of frame parameters to pass to
+                    ;; `special-display-function'.
+                    (setq pars (with-no-warnings
+                                 (special-display-p buffer-name))))
+               (list (list 'fun-with-args
+                           (with-no-warnings special-display-function)
+                           (when (listp pars) pars)))
+             ;; Pop up another frame.
+             (cddr (assq 'other-frame display-buffer-macro-specifiers))))
+          (t
+           ;; In any other case pop up a new window.
+           (cdr (assq 'same-frame-other-window
+                      display-buffer-macro-specifiers)))))
+
+    ;; Handle the old meaning of the LABEL argument of `display-buffer'.
     (cond
-     ((not specifiers)
-      nil)
-     ((listp specifiers)
-      ;; If SPECIFIERS is a list, we assume it is a list of specifiers.
-      (dolist (specifier specifiers)
-       (cond
-        ((consp specifier)
-         (setq normalized (cons specifier normalized)))
-        ((symbolp specifier)
-         ;; Might be a macro specifier, try to expand it (the cdr is a
-         ;; list and we have to reverse it later, so do it one at a
-         ;; time).
-         (let ((entry (assq specifier display-buffer-macro-specifiers)))
-           (dolist (item (cdr entry))
-             (setq normalized (cons item normalized)))))))
-      ;; Reverse list.
-      (nreverse normalized))
-     ((and (not (eq specifiers 'other-window))
-          (setq entry (assq specifiers display-buffer-macro-specifiers)))
-      ;; A macro specifier.
-      (cdr entry))
-     ((with-no-warnings (memq pop-up-frames '(nil unset)))
-      ;; Pop up a new window.
-      (cdr (assq 'other-window display-buffer-macro-specifiers)))
+     ((or (memq label '(visible 0 t)) (frame-live-p label))
+      ;; LABEL must be one of visible (and visible frame), 0 (any
+      ;; visible or iconfied frame), t (any frame), or a live frame.
+      (cons `(reuse-window nil same ,label) specifier))
+     ((or other-frame
+         (with-no-warnings pop-up-frames)
+         (with-no-warnings display-buffer-reuse-frames))
+      (cons '(reuse-window nil same 0) specifier))
      (t
-      ;; Pop up a new frame.
-      (cdr (assq 'other-frame display-buffer-macro-specifiers))))))
+      specifier))))
 
-(defun display-buffer-normalize-specifiers-2 (&optional buffer-or-name)
+(defun display-buffer-normalize-options (buffer-or-name)
   "Subroutine of `display-buffer-normalize-specifiers'.
 BUFFER-OR-NAME is the buffer to display.  This routine provides a
 compatibility layer for the now obsolete Emacs 23 buffer display
 options."
-  (let* ((buffer (normalize-live-buffer buffer-or-name))
-        (buffer-name (buffer-name buffer))
-        specifiers)
-    ;; Disable warnings, there are too many obsolete options here.
-    (with-no-warnings
+  (with-no-warnings
+    (let* ((buffer (normalize-live-buffer buffer-or-name))
+          (buffer-name (buffer-name buffer))
+          (use-pop-up-frames
+           (or (and (eq pop-up-frames 'graphic-only)
+                    (display-graphic-p))
+               pop-up-frames))
+          specifiers)
+      ;; `even-window-heights', unless nil or unset.
+      (unless (memq even-window-heights '(nil unset))
+       (setq specifiers
+             (cons (cons 'reuse-window-even-sizes t) specifiers)))
+
       ;; `display-buffer-mark-dedicated'
-      (unless (memq display-buffer-mark-dedicated '(nil unset))
+      (when display-buffer-mark-dedicated
        (setq specifiers
              (cons (cons 'dedicate display-buffer-mark-dedicated)
                    specifiers)))
@@ -4989,25 +5417,31 @@ options."
            (min-width (if (numberp split-width-threshold)
                           (/ split-width-threshold 2)
                         1.0)))
-       (when pop-up-window
-         ;; `split-height-threshold'
+       ;; Create an entry only if a default value was changed.
+       (when (or pop-up-window
+                 (not (equal split-height-threshold 80))
+                 (not (equal split-width-threshold 160)))
+         ;; `reuse-window' (needed as fallback when popping up the new
+         ;; window fails).
          (setq specifiers
-               (cons (cons 'pop-up-window-min-height min-height)
+               (cons (list 'reuse-window 'other nil nil)
                      specifiers))
          ;; `split-width-threshold'
          (setq specifiers
                (cons (cons 'pop-up-window-min-width min-width)
                      specifiers))
+         ;; `split-height-threshold'
+         (setq specifiers
+               (cons (cons 'pop-up-window-min-height min-height)
+                     specifiers))
          ;; `pop-up-window'
          (setq specifiers
                (cons (list 'pop-up-window
                            (cons 'largest fun) (cons 'lru fun))
                      specifiers))))
 
-      ;; `pop-up-frame' group.  Anything is added here iff
-      ;; `pop-up-frames' is neither nil nor unset (we ignore the problem
-      ;; that callers usually don't care about graphic-only).
-      (unless (memq pop-up-frames '(nil unset))
+      ;; `pop-up-frame' group.
+      (when use-pop-up-frames
        ;; `pop-up-frame-function'.  If `pop-up-frame-function' uses the
        ;; now obsolete `pop-up-frame-alist' it will continue to do so.
        (setq specifiers
@@ -5015,165 +5449,90 @@ options."
                    specifiers))
        ;; `pop-up-frame'
        (setq specifiers
-             (cons (list 'pop-up-frame pop-up-frames) specifiers)))
+             (cons (list 'pop-up-frame t) specifiers)))
 
-      ;; `special-display-regexps'
-      (dolist (entry special-display-regexps)
-       (cond
-        ((stringp entry)
-         ;; Plain string.
-         (when (string-match-p entry buffer-name)
-           (setq specifiers
-                 (cons
-                  (list 'fun-with-args special-display-function
-                        special-display-frame-alist)
-                  specifiers))))
-        ((consp entry)
-         (let ((name (car entry))
-               (rest (cdr entry)))
-           (cond
-            ((not (string-match-p name buffer-name)))
-            ((functionp (car rest))
-             ;; A function.
-             (setq specifiers
-                   (cons (list 'fun-with-args (car rest) (cadr rest))
-                         specifiers)))
-            ((listp rest)
-             ;; A list of parameters.
-             (cond
-              ((assq 'same-window rest)
-               (setq specifiers
-                     (cons (list 'reuse-window 'same) specifiers))
-               (setq specifiers
-                     (cons (list 'reuse-window-dedicated 'weak)
-                           specifiers)))
-              ((assq 'same-frame rest)
-               (setq specifiers
-                     (setq specifiers
-                           (cons (list 'same-frame) specifiers))))
-              (t
-               (setq specifiers
-                     (cons (list 'fun-with-args special-display-function
-                                 special-display-frame-alist)
-                           specifiers))))))))))
-
-      ;; `special-display-buffer-names'
-      (dolist (entry special-display-buffer-names)
-       (cond
-        ((stringp entry)
-         ;; Plain string.
-         (when (string-equal entry buffer-name)
-           (setq specifiers
-                 (cons
-                  (list 'fun-with-args special-display-function
-                        special-display-frame-alist)
-                  specifiers))))
-        ((consp entry)
-         (let ((name (car entry))
-               (rest (cdr entry)))
-           (cond
-            ((not (string-equal name buffer-name)))
-            ((functionp (car rest))
-             ;; A function.
-             (setq specifiers
-                   (cons (list 'fun-with-args (car rest) (cadr rest))
-                         specifiers)))
-            ((listp rest)
-             ;; A list of parameters.
-             (cond
-              ((assq 'same-window rest)
-               (setq specifiers
-                     (cons (list 'reuse-window 'same) specifiers))
-               (setq specifiers
-                     (cons (list 'reuse-window-dedicated 'weak)
-                           specifiers)))
-              ((assq 'same-frame rest)
-               (setq specifiers
-                     (setq specifiers
-                           (cons (list 'same-frame) specifiers))))
-              (t
-               (setq specifiers
-                     (cons (list 'fun-with-args special-display-function
-                                 special-display-frame-alist)
-                           specifiers))))))))))
-
-      ;; `same-window-regexps'
-      (dolist (entry same-window-regexps)
-       (cond
-        ((stringp entry)
-         (when (string-match-p entry buffer-name)
-           (setq specifiers
-                 (cons (list 'reuse-window 'same) specifiers))))
-        ((consp entry)
-         (when (string-match-p (car entry) buffer-name)
-           (setq specifiers
-                 (cons (list 'reuse-window 'same) specifiers))))))
-
-      ;; `same-window-buffer-names'
-      (dolist (entry same-window-buffer-names)
-       (cond
-        ((stringp entry)
-         (when (string-equal entry buffer-name)
-           (setq specifiers
-                 (cons (list 'reuse-window 'same) specifiers))))
-        ((consp entry)
-         (when (string-equal (car entry) buffer-name)
-           (setq specifiers
-                 (cons (list 'reuse-window 'same) specifiers))))))
-
-      ;; `pop-up-windows' and `pop-up-frames' nil means means we
-      ;; are supposed to reuse any window (unless we find one showing
-      ;; the same buffer already).
-
-      ;; This clause is needed because Emacs 23 options can be used to
-      ;; suppress a certain behavior while `display-buffer-alist' can be
-      ;; only used to enforce some behavior.
-      (when (and (not pop-up-windows) (memq pop-up-frames '(nil unset)))
-       ;; `even-window-heights'
-       (when even-window-heights
-         (setq specifiers
-               (cons (cons 'reuse-window-even-sizes t) specifiers)))
+      ;; `pop-up-windows' and `use-pop-up-frames' both nil means means
+      ;; we are supposed to reuse any window on the same frame (unless
+      ;; we find one showing the same buffer already).
+      (unless (or pop-up-windows use-pop-up-frames)
        ;; `reuse-window' showing any buffer on same frame.
        (setq specifiers
              (cons (list 'reuse-window nil nil nil)
                    specifiers)))
 
-      ;; `display-buffer-reuse-frames' or `pop-up-frames' set means we
-      ;; are supposed to reuse a window showing the same buffer.
-      (unless (and (memq display-buffer-reuse-frames '(nil unset))
-                  (memq pop-up-frames '(nil unset)))
-       ;; `even-window-heights'
-       (when even-window-heights
+      ;; `special-display-p' group.
+      (when 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 buffer-name)))
+         (when pars
+           (setq specifiers
+                 (cons (list 'fun-with-args special-display-function
+                             (when (listp pars) pars))
+                       specifiers)))))
+
+      ;; `pop-up-frames', `display-buffer-reuse-frames' means search for
+      ;; a window showing the buffer on some visible or iconfied frame.
+      ;; `last-nonminibuffer-frame' set and not the same frame means
+      ;; search that frame.
+      (let ((frames (or (and (or use-pop-up-frames
+                                display-buffer-reuse-frames
+                                (not (last-nonminibuffer-frame)))
+                            ;; All visible or iconfied frames.
+                            0)
+                       ;; Same frame.
+                       (last-nonminibuffer-frame))))
+       (when frames
          (setq specifiers
-               (cons (cons 'reuse-window-even-sizes t) specifiers)))
-       ;; `reuse-window' showing same buffer on visible frame.
+               (cons (list 'reuse-window 'other 'same frames)
+                     specifiers))))
+
+      ;; `same-window-p' group.
+      (when (same-window-p buffer-name)
+       ;; Try to reuse the same (selected) window.
        (setq specifiers
-             (cons (list 'reuse-window nil 'same 0)
+             (cons (list 'reuse-window 'same nil nil)
                    specifiers)))
 
-      specifiers)))
+      ;; Prepend "reuse window on same frame if showing the buffer
+      ;; already" specifier.  It will be overriden by the application
+      ;; supplied 'other-window specifier.
+      (setq specifiers (cons (list 'reuse-window nil 'same nil)
+                            specifiers))
 
-(defun display-buffer-normalize-specifiers (buffer-name specifiers label)
-  "Return normalized specifiers for a buffer matching BUFFER-NAME or LABEL.
-BUFFER-NAME must be a string specifying a valid buffer name.
-SPECIFIERS and LABEL are the homonymous arguments of
-`display-buffer'.
-
-The method for displaying the buffer specified by BUFFER-NAME or
-LABEL is established by appending the following four lists of
-specifiers:
-
-- The specifiers in `display-buffer-alist' whose buffer
-  identifier matches BUFFER-NAME or LABEL and whose 'override
-  component is set.
-
-- SPECIFIERS.
+      specifiers)))
 
-- The specifiers in `display-buffer-alist' whose buffer
-  identifier matches BUFFER-NAME or LABEL and whose 'override
-  component is not set.
+(defun display-buffer-normalize-alist-1 (specifiers label)
+  "Subroutine of `display-buffer-normalize-alist'.
+SPECIFIERS is a list of buffer display specfiers.  LABEL is the
+same argument of `display-buffer'."
+  (let (normalized entry)
+    (cond
+     ((not specifiers)
+      nil)
+     ((listp specifiers)
+      ;; If SPECIFIERS is a list, we assume it is a list of specifiers.
+      (dolist (specifier specifiers)
+       (cond
+        ((consp specifier)
+         (setq normalized (cons specifier normalized)))
+        ((symbolp specifier)
+         ;; Might be a macro specifier, try to expand it (the cdr is a
+         ;; list and we have to reverse it later, so do it one at a
+         ;; time).
+         (let ((entry (assq specifier display-buffer-macro-specifiers)))
+           (dolist (item (cdr entry))
+             (setq normalized (cons item normalized)))))))
+      ;; Reverse list.
+      (nreverse normalized))
+     ((setq entry (assq specifiers display-buffer-macro-specifiers))
+      ;; A macro specifier.
+      (cdr entry)))))
 
-- `display-buffer-default-specifiers'."
+(defun display-buffer-normalize-alist (buffer-name label)
+  "Normalize `display-buffer-alist'.
+BUFFER-NAME must be the name of the buffer that shall be displayed.
+LABEL the corresponding argument of `display-buffer'."
   (let (list-1 list-2)
     (dolist (entry display-buffer-alist)
       (when (and (listp entry)
@@ -5188,9 +5547,10 @@ specifiers:
                                        (string-match-p value buffer-name))
                                   (and (eq type 'label) (eq value label)))
                           (throw 'match t)))))))
-       (let* ((raw (cdr entry))
-              (normalized (display-buffer-normalize-specifiers-1 raw)))
-         (if (assq 'override raw)
+       (let* ((specifiers (cdr entry))
+              (normalized
+               (display-buffer-normalize-alist-1 specifiers label)))
+         (if (assq 'override specifiers)
              (setq list-1
                    (if list-1
                        (append list-1 normalized)
@@ -5200,15 +5560,46 @@ specifiers:
                      (append list-2 normalized)
                    normalized))))))
 
+    (cons list-1 list-2)))
+
+(defvar display-buffer-normalize-options-inhibit nil
+  "If non-nil, `display-buffer' doesn't process obsolete options.")
+
+(defun display-buffer-normalize-specifiers (buffer-name specifiers label)
+  "Return normalized specifiers for a buffer matching BUFFER-NAME or LABEL.
+BUFFER-NAME must be a string specifying a valid buffer name.
+SPECIFIERS and LABEL are the homonymous arguments of
+`display-buffer'.
+
+The method for displaying the buffer specified by BUFFER-NAME or
+LABEL is established by appending the following four lists of
+specifiers:
+
+- The specifiers in `display-buffer-alist' whose buffer
+  identifier matches BUFFER-NAME or LABEL and whose 'override
+  component is set.
+
+- SPECIFIERS.
+
+- The specifiers in `display-buffer-alist' whose buffer
+  identifier matches BUFFER-NAME or LABEL and whose 'override
+  component is not set.
+
+- `display-buffer-default-specifiers'."
+  (let* ((list (display-buffer-normalize-alist buffer-name label))
+        (other-frame (assq 'other-window-means-other-frame
+                           (or (car list) (cdr list)))))
     (append
      ;; Overriding user specifiers.
-     list-1
+     (car list)
      ;; Application specifiers.
-     (display-buffer-normalize-specifiers-1 specifiers)
+     (display-buffer-normalize-arguments
+      buffer-name specifiers label other-frame)
      ;; Emacs 23 compatibility specifiers.
-     (display-buffer-normalize-specifiers-2 buffer-name)
+     (unless display-buffer-normalize-options-inhibit
+       (display-buffer-normalize-options buffer-name))
      ;; Non-overriding user specifiers.
-     list-2
+     (cdr list)
      ;; Default specifiers.
      display-buffer-default-specifiers)))
 
@@ -5265,6 +5656,21 @@ override SPECIFIERS by adding an entry to `display-buffer-alist'
 whose car contains LABEL and whose cdr specifies the preferred
 alternative display method.
 
+The following values of LABEL have a special meaning and allow to
+specify the set of frames to investigate when the buffer already
+appears in a window:
+
+`visible' - the set of visible frames.
+
+0 - the set of visible or iconified frames.
+
+t - the set of all frames.
+
+A live frame - the set containing that frame as its only element.
+
+If the buffer is already displayed in a window on a frame in the
+specified set, return that window.
+
 The method to display the buffer is derived by combining the
 values of `display-buffer-alist' and SPECIFIERS.  Highest
 priority is given to overriding elements of
@@ -5278,7 +5684,7 @@ this list as arguments."
   (interactive "BDisplay buffer:\nP")
   (let* ((buffer (normalize-buffer-to-display buffer-or-name))
         (buffer-name (buffer-name buffer))
-        (specifiers
+        (normalized
          ;; Normalize specifiers.
          (display-buffer-normalize-specifiers buffer-name specifiers label))
         ;; Don't use a minibuffer frame.
@@ -5292,24 +5698,24 @@ this list as arguments."
        (funcall display-buffer-function buffer specifiers)
       ;; Retrieve the next location specifier while there a specifiers
       ;; left and we don't have a valid window.
-      (while (and specifiers (not (window-live-p window)))
-       (setq specifier (car specifiers))
-       (setq specifiers (cdr specifiers))
+      (while (and normalized (not (window-live-p window)))
+       (setq specifier (car normalized))
+       (setq normalized (cdr normalized))
        (setq method (car specifier))
        (setq window
              (cond
               ((eq method 'reuse-window)
                (display-buffer-reuse-window
-                buffer (cdr specifier) specifiers))
+                buffer (cdr specifier) normalized))
               ((eq method 'pop-up-window)
                (display-buffer-pop-up-window
-                buffer (cdr specifier) specifiers))
+                buffer (cdr specifier) normalized))
               ((eq method 'pop-up-frame)
                (display-buffer-pop-up-frame
-                buffer (cdr specifier) specifiers))
+                buffer (cdr specifier) normalized))
               ((eq method 'use-side-window)
                (display-buffer-in-side-window
-                buffer (nth 1 specifier) (nth 2 specifier) specifiers))
+                buffer (nth 1 specifier) (nth 2 specifier) normalized))
               ((eq method 'fun-with-args)
                (apply (cadr specifier) buffer (cddr specifier))))))
 
@@ -5318,12 +5724,12 @@ this list as arguments."
       (or (and (window-live-p window) window)
          ;; Try reusing a window showing BUFFER on any visible or
          ;; iconfied frame.
-         (display-buffer-reuse-window buffer '(nil buffer 0))
+         (display-buffer-reuse-window buffer `(nil ,buffer 0))
          ;; Try reusing a window not showing BUFFER on any visible or
          ;; iconified frame.
          (display-buffer-reuse-window buffer '(nil other 0))
-         ;; Try making a new frame.
-         (display-buffer-pop-up-frame buffer)
+         ;; Eli says it's better to never try making a new frame.
+         ;; (display-buffer-pop-up-frame buffer)
          ;; Try using a weakly dedicated window.
          (display-buffer-reuse-window
           buffer '(nil nil t) '((reuse-window-dedicated . weak)))
@@ -5409,11 +5815,21 @@ documentations of `display-buffer' and `display-buffer-alist' for
 additional information."
   (interactive "BPop to buffer:\nP")
   (let ((buffer (normalize-buffer-to-display buffer-or-name))
-       window)
+       (old-window (selected-window))
+       (old-frame (selected-frame))
+       new-window new-frame)
     (set-buffer buffer)
-    (when (setq window (display-buffer buffer specifiers label))
-      (select-window window norecord)
-      buffer)))
+    (setq new-window (display-buffer buffer specifiers label))
+    (unless (eq new-window old-window)
+      ;; `display-buffer' has chosen another window, select it.
+      (select-window new-window norecord)
+      (setq new-frame (window-frame new-window))
+      (unless (eq new-frame old-frame)
+       ;; `display-buffer' has chosen another frame, make sure it gets
+       ;; input focus and is risen.
+       (select-frame-set-input-focus new-frame)))
+
+    buffer))
 
 (defsubst pop-to-buffer-same-window (&optional buffer-or-name norecord label)
   "Pop to buffer specified by BUFFER-OR-NAME in the selected window.
@@ -5695,7 +6111,7 @@ and (cdr ARGS) as second."
        ;; Reuse the current window if the user requested it.
        (when (cdr (assq 'same-window args))
         (display-buffer-reuse-window
-         buffer '(same nil nil) '((reuse-dedicated . 'weak))))
+         buffer '(same nil nil) '((reuse-dedicated . weak))))
        ;; Stay on the same frame if requested.
        (when (or (cdr (assq 'same-frame args))
                 (cdr (assq 'same-window args)))
@@ -5937,32 +6353,28 @@ frame.  The default value calls `make-frame' with the argument
  'pop-up-frame-function
  "use 2nd arg of `display-buffer' instead." "24.1")
 
-(defcustom pop-up-frames 'unset ; nil
+(defcustom pop-up-frames nil
   "Whether `display-buffer' should make a separate frame.
 If nil, never make a separate frame.
 If the value is `graphic-only', make a separate frame
 on graphic displays only.
-If this is the symbol unset, the option was not set and is
-ignored.
 Any other non-nil value means always make a separate frame."
   :type '(choice
-         (const :tag "Unset" unset)
          (const :tag "Never" nil)
          (const :tag "On graphic displays only" graphic-only)
          (const :tag "Always" t))
-  :version "24.1"
   :group 'windows
   :group 'frames)
 (make-obsolete-variable
  'pop-up-frames
  "use 2nd arg of `display-buffer' instead." "24.1")
 
-(defcustom display-buffer-reuse-frames 'unset ; nil
+(defcustom display-buffer-reuse-frames nil
   "Set and 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 "24.1"
+  :version "21.1"
   :group 'windows
   :group 'frames)
 (make-obsolete-variable
@@ -6033,20 +6445,20 @@ is nil, `display-buffer' cannot split windows horizontally."
  'split-width-threshold
  "use 2nd arg of `display-buffer' instead." "24.1")
 
-(defcustom even-window-heights t
-  "If non-nil `display-buffer' will try to even window heights.
+(defcustom even-window-heights 'unset ; t
+  "If set and 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' reuses a
 window that appears above or below the selected window."
   :type 'boolean
-  :version "23.1"
+  :version "24.1"
   :group 'windows)
 (make-obsolete-variable
  'even-window-heights
  "use 2nd arg of `display-buffer' instead." "24.1")
 
-(defvar display-buffer-mark-dedicated 'unset ; nil
-  "Set and non-nil means `display-buffer' marks the windows it creates as dedicated.
+(defvar display-buffer-mark-dedicated nil
+  "Non-nil means `display-buffer' marks the windows it creates as dedicated.
 The actual non-nil value of this variable will be copied to the
 `window-dedicated-p' flag.")
 (make-obsolete-variable
@@ -6223,7 +6635,7 @@ value of `display-buffer-alist'."
      nil
      (list
       'pop-up-frame
-      (unless (memq pop-up-frames '(nil unset))
+      (when pop-up-frames
        (list 'pop-up-frame pop-up-frames))
       (when pop-up-frame-function
        (cons 'pop-up-frame-function pop-up-frame-function))
@@ -6359,17 +6771,16 @@ value of `display-buffer-alist'."
      (list
       'reuse-window
       (list 'reuse-window nil 'same
-           (unless (and (memq display-buffer-reuse-frames '(nil unset))
-                        (memq pop-up-frames '(nil unset)))
+           (when (or display-buffer-reuse-frames pop-up-frames)
              ;; "0" (all visible and iconified frames) is hardcoded in
              ;; Emacs 23.
-               0))
-      (when even-window-heights
+             0))
+      (unless (memq even-window-heights '(nil unset))
        (cons 'reuse-window-even-sizes t)))
      no-custom)
 
     ;; `display-buffer-mark-dedicated'
-    (unless (memq display-buffer-mark-dedicated '(nil unset))
+    (when display-buffer-mark-dedicated
       (display-buffer-alist-add
        nil
        (list
@@ -6396,7 +6807,7 @@ where some error may be present."
       ;; windows 1-line tall, which means that there's no more space for
       ;; the modeline.
       (let ((window-min-height (min 2 height))) ; One text line plus a modeline.
-       (resize-window window delta)))))
+       (window-resize window delta)))))
 
 (defun enlarge-window-horizontally (delta)
   "Make selected window DELTA columns wider.
@@ -6539,8 +6950,8 @@ WINDOW was scrolled."
                ;; It's silly to put `point' at the end of the previous
                ;; line and so maybe force horizontal scrolling.
                (set-window-point window (line-beginning-position 0)))
-             ;; Call `resize-window' with OVERRIDE argument equal WINDOW.
-             (resize-window window delta nil window)
+             ;; Call `window-resize' with OVERRIDE argument equal WINDOW.
+             (window-resize window delta nil window)
              ;; Check if the last line is surely fully visible.  If
              ;; not, enlarge the window.
              (let ((end (save-excursion
@@ -6563,7 +6974,7 @@ WINDOW was scrolled."
                (while (and (< desired-height max-height)
                            (= desired-height (window-total-size))
                            (not (pos-visible-in-window-p end)))
-                 (resize-window window 1 nil window)
+                 (window-resize window 1 nil window)
                  (setq desired-height (1+ desired-height)))))
          (error (setq delta nil)))
        delta))))