changeset 1149:a123f88fa975

[xemacs-hg @ 2002-12-08 10:24:33 by michaels] 2002-12-02 Mike Sperber <mike@xemacs.org> * The Great Window Configuration rewrite: Re-implement window configuration functionality in Emacs Lisp. * window.h (Fcurrent_window_configuration): Don't export anymore. (Qcurrent_window_configuration): Declare. (Qset_window_configuration): Declare. * event-stream.c (execute_help_form): * bytecode.c (execute_rare_opcode): Call out to Lisp to save window excursion. * window.c (Qcurrent_window_configuration): Declare. (Qwindow_configurationp): (Vwindow_configuration_free_list): (Qset_window_configuration): (Qtemp_buffer_show_hook): (struct saved_window): (struct window_config): (SAVED_WINDOW_N): (XWINDOW_CONFIGURATION): (wrap_window_configuration): (WINDOW_CONFIGURATIONP): (CHECK_WINDOW_CONFIGURATION): (mark_window_config): (sizeof_window_config_for_n_windows): (sizeof_window_config): (print_window_config): (saved_window_equal): (window_config_equal): (Fwindow_configuration_p): (mark_windows_in_use_closure): (mark_windows_in_use): (free_window_configuration): (Fset_window_configuration): (count_windows): (saved_window_index): (save_window_save): (Fcurrent_window_configuration): (Fsave_window_excursion): Remove. (mark_window_as_deleted): Rectify comment about `set-window-configuration'. (Fset_window_buffer): Reinstate code not activated because of old implementation of window configurations. (temp_output_buffer_show): Don't run `temp-buffer-show-hook' anymore---this wasn't supposed to happen anyway according to the documentation of `temp-buffer-show-function'. (reinit_vars_of_window): Don't do the window configuration stuff no more (vars_of_window): Don't set up `temp-buffer-show-hook' any more. 2002-12-02 Mike Sperber <mike@xemacs.org> * The Great Window Configuration rewrite: Re-implement window configuration functionality in Emacs Lisp. * window-xemacs.el (current-window-configuration): (set-window-configuration): (plus many functions they depend on) Re-implement window configurations in Emacs Lisp.
author michaels
date Sun, 08 Dec 2002 10:25:14 +0000
parents 1649f1fb3177
children 9be96a92631d
files lisp/ChangeLog lisp/window-xemacs.el src/ChangeLog src/bytecode.c src/event-stream.c src/window.c src/window.h
diffstat 7 files changed, 389 insertions(+), 1046 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Sat Dec 07 22:54:03 2002 +0000
+++ b/lisp/ChangeLog	Sun Dec 08 10:25:14 2002 +0000
@@ -1,3 +1,12 @@
+2002-12-02  Mike Sperber <mike@xemacs.org>
+
+	* The Great Window Configuration rewrite: Re-implement window
+	configuration functionality in Emacs Lisp.
+
+	* window-xemacs.el (current-window-configuration): 
+	(set-window-configuration): (plus many functions they depend on)
+	Re-implement window configurations in Emacs Lisp.
+
 2002-12-03  Didier Verna  <didier@xemacs.org>
 
 	* faces.el (set-face-background-pixmap-file): Ensure default value
--- a/lisp/window-xemacs.el	Sat Dec 07 22:54:03 2002 +0000
+++ b/lisp/window-xemacs.el	Sun Dec 08 10:25:14 2002 +0000
@@ -104,7 +104,324 @@
   (if (bufferp buffer)
       (set-window-buffer window (get-buffer-create buffer)))
   (set-window-dedicated-p window (not (null buffer))))
+
+;; Window configurations
 
+(defstruct saved-window
+  currentp minibufferp minibuffer-scrollp
+  buffer mark-marker
+  start-marker
+  point-marker
+  pixel-left pixel-top pixel-right pixel-bottom
+  hscroll modeline-hscroll
+  dedicatedp
+  first-hchild first-vchild next-child)
+
+(defstruct window-configuration
+  frame
+  frame-pixel-width frame-pixel-height
+  current-buffer
+  minibuffer-pixel-height
+  min-width min-height
+  saved-root-window)
+
+(defun window-configuration-equal (conf-1 conf-2)
+  "Returns a boolean indicating whether the two given configurations
+are identical."
+  (or (eq conf-1 conf-2)
+      (and (eq (window-configuration-frame conf-1)
+	       (window-configuration-frame conf-2))
+	   (= (window-configuration-frame-pixel-width conf-1)
+	      (window-configuration-frame-pixel-width conf-2))
+	   (= (window-configuration-frame-pixel-height conf-1)
+	      (window-configuration-frame-pixel-height conf-2))
+	   (eq (window-configuration-current-buffer conf-1)
+	       (window-configuration-current-buffer conf-2))
+	   (saved-window-equal (window-configuration-saved-root-window conf-1)
+			       (window-configuration-saved-root-window conf-2)))))
+
+(defun saved-window-equal (saved-1 saved-2)
+  "Returns a boolean indicating whether the two given saved windows
+are identical."
+  (or (eq saved-1 saved-2)
+      (and (eq (saved-window-currentp saved-1)
+	       (saved-window-currentp saved-2))
+	   (eq (saved-window-minibuffer-scrollp saved-1)
+	       (saved-window-minibuffer-scrollp saved-2))
+	   (eq (saved-window-buffer saved-1)
+	       (saved-window-buffer saved-2))
+	   (equal (saved-window-mark-marker saved-1)
+		  (saved-window-mark-marker saved-2))
+	   (or (and (saved-window-currentp saved-1)
+		    (saved-window-currentp saved-2))
+	       (equal (saved-window-start-marker saved-1)
+		      (saved-window-start-marker saved-2)))
+	   (or (and (saved-window-currentp saved-1)
+		    (saved-window-currentp saved-2))
+	       (equal (saved-window-point-marker saved-1)
+		      (saved-window-point-marker saved-2)))
+	   (= (saved-window-pixel-left saved-1)
+	      (saved-window-pixel-left saved-2))
+	   (= (saved-window-pixel-top saved-1)
+	      (saved-window-pixel-top saved-2))
+	   (= (saved-window-pixel-right saved-1)
+	      (saved-window-pixel-right saved-2))
+	   (= (saved-window-pixel-bottom saved-1)
+	      (saved-window-pixel-bottom saved-2))
+	   (= (saved-window-hscroll saved-1)
+	      (saved-window-hscroll saved-2))
+	   (= (saved-window-modeline-hscroll saved-1)
+	      (saved-window-modeline-hscroll saved-2))
+	   (eq (saved-window-dedicatedp saved-1)
+	       (saved-window-dedicatedp saved-2))
+	   (maybe-saved-window-equal (saved-window-first-hchild saved-1)
+				     (saved-window-first-hchild saved-2))
+	   (maybe-saved-window-equal (saved-window-first-vchild saved-1)
+				     (saved-window-first-vchild saved-2))
+	   (maybe-saved-window-equal (saved-window-next-child saved-1)
+				     (saved-window-next-child saved-2)))))
+
+(defun maybe-saved-window-equal (maybe-saved-1 maybe-saved-2)
+  "Returns a boolean indicating whether the two given saved windows
+or NILs are identical."
+  (cond
+   ((and (not maybe-saved-1) (not maybe-saved-2)) t)
+   ((not maybe-saved-1) (not maybe-saved-2))
+   ((not maybe-saved-2) (not maybe-saved-1))
+   (t (saved-window-equal maybe-saved-1 maybe-saved-2))))
+
+(defun current-window-configuration (&optional frame)
+  "Return an object representing the current window configuration of FRAME.
+If FRAME is nil or omitted, use the selected frame.
+This describes the number of windows, their sizes and current buffers,
+and for each window on FRAME the displayed buffer, where display
+starts, and the positions of point and mark.
+An exception is made for point in the current buffer:
+its value is -not- saved."
+  (let ((frame (or frame (selected-frame))))
+    ;; The original C code used complicated but still incomplete logic
+    ;; to decide if and how to restore the size of the minibuffer.  It
+    ;; goes something like this:
+;     (let ((real-font-height
+; 	   (font-height (face-font 'default) frame))
+; 	  (minibuffer-height
+; 	   (if (and (minibuffer-window frame)
+; 		    (not (frame-minibuffer-only-p frame)))
+; 	       (window-pixel-height (minibuffer-window frame))
+; 	     0)))
+;       ...)
+	      
+    (make-window-configuration
+     :frame frame
+     :frame-pixel-width (frame-pixel-width frame)
+     :frame-pixel-height (frame-pixel-height frame)
+     :current-buffer (current-buffer)
+     :min-width window-min-width :min-height window-min-height
+     :minibuffer-pixel-height (window-pixel-height (minibuffer-window frame))
+     ;; this tries to do what the old code did:
+;        :minibuffer-height (if (zerop (% minibuffer-height real-font-height))
+; 			      (- (/ minibuffer-height real-font-height)) ; lines
+; 			    minibuffer-height) ; pixels
+     :saved-root-window (root-window->saved-window (frame-root-window frame)))))
+
+(defun root-window->saved-window (window)
+  "Converts a root window into a tree of saved-window structures."
+  (let ((buffer (window-buffer window))
+	(edges (window-pixel-edges window)))
+    (let ((left (nth 0 edges))
+	  (top (nth 1 edges))
+	  (right (nth 2 edges))
+	  (bottom (nth 3 edges)))
+      (let ((saved-window
+	     (make-saved-window
+	      :currentp (eq window (selected-window (window-frame window)))
+	      :minibufferp (eq window (minibuffer-window (window-frame window)))
+	      :minibuffer-scrollp (eq window minibuffer-scroll-window)
+	      :buffer buffer
+	      :pixel-left left :pixel-top top :pixel-right right :pixel-bottom bottom
+	      :hscroll (window-hscroll window)
+	      :modeline-hscroll (modeline-hscroll window)
+	      :dedicatedp (window-dedicated-p window)
+	      :first-hchild (if (window-first-hchild window)
+				(root-window->saved-window (window-first-hchild window))
+			      nil)
+	      :first-vchild (if (window-first-vchild window)
+				(root-window->saved-window (window-first-vchild window))
+			      nil)
+	      :next-child (if (window-next-child window)
+			      (root-window->saved-window (window-next-child window))
+			    nil))))
+	(if buffer
+	    (progn
+	      (let ((marker (make-marker)))
+		(set-marker marker (window-start window) buffer)
+		(setf (saved-window-start-marker saved-window) marker))
+	      (let ((marker (make-marker)))
+		(if (eq window (selected-window))
+		    (set-marker marker (point buffer) buffer)
+		  (set-marker marker (window-point window) buffer))
+		(setf (saved-window-point-marker saved-window) marker))
+	      (setf (saved-window-mark-marker saved-window)
+		    (copy-marker (mark-marker t buffer)))))
+	saved-window))))
+
+(defun set-window-configuration (configuration)
+  "Set the configuration of windows and buffers as specified by CONFIGURATION.
+CONFIGURATION must be a value previously returned
+by `current-window-configuration'."
+  (let ((frame (window-configuration-frame configuration)))
+    (if (and (frame-live-p frame)
+	     (not (window-configuration-equal configuration
+					      (current-window-configuration))))
+	(really-set-window-configuration frame configuration))))
+
+(defun really-set-window-configuration (frame configuration)
+  "Set the window configuration CONFIGURATION on live frame FRAME."
+  ;; avoid potential temporary problems
+  (setq window-min-width 0)
+  (setq window-min-height 0)
+  (setq minibuffer-scroll-window nil)
+
+  (frame-reduce-to-one-window frame)
+  (set-window-configuration-frame-size configuration)
+
+  ;; these may have changed because of the delete
+  (let ((root-window (frame-root-window frame)))
+    (enlarge-window-pixels 
+     (- (window-configuration-minibuffer-pixel-height configuration)
+	(window-pixel-height (minibuffer-window frame)))
+     nil
+     (minibuffer-window frame))
+
+    ;; avoid that `set-window-point' will set the buffer's point for
+    ;; the selected window
+    (select-window (minibuffer-window frame))
+
+    (let ((window-configuration-current-window nil))
+      (restore-saved-window configuration
+			    root-window
+			    (window-configuration-saved-root-window configuration)
+			    'vertical) 
+      (if window-configuration-current-window
+	  (select-window window-configuration-current-window))))
+
+  (setq window-min-width (window-configuration-min-width configuration))
+  (setq window-min-height (window-configuration-min-height configuration))
+
+  (set-buffer (window-configuration-current-buffer configuration)))
+
+(defun set-window-configuration-frame-size (configuration)
+  "Restore the frame size of a window configuration."
+  (set-frame-pixel-size
+   (window-configuration-frame configuration)
+   (window-configuration-frame-pixel-width configuration)
+   (window-configuration-frame-pixel-height configuration)))
+
+(defun frame-reduce-to-one-window (frame)
+  "Delete all windows except the minibuffer and one other in FRAME."
+  (let* ((root-window (frame-root-window frame))
+	 (combination-start (or (window-first-hchild root-window)
+				(window-first-vchild root-window))))
+    (if combination-start
+	(window-reduce-to-one combination-start))))
+
+(defun window-reduce-to-one (window)
+  "Make sure only one subwindow of WINDOW is left."
+  (let ((window (window-next-child window)))
+    (while window
+      (if (window-live-p window)
+	  (let ((next (window-next-child window)))
+	    (delete-window window)
+	    (setq window next)))))
+  (cond
+   ((window-first-hchild window)
+    (window-reduce-to-one (window-first-hchild window)))
+   ((window-first-vchild window)
+    (window-reduce-to-one (window-first-vchild window)))))
+
+(defun restore-saved-window (configuration window saved-window direction)
+  "Within CONFIGURATION, restore WINDOW to the state of SAVED-WINDOW."
+  (if (saved-window-next-child saved-window)
+      (progn
+	(if (not (saved-window-minibufferp (saved-window-next-child saved-window)))
+	    (progn
+	      (cond ((eq direction 'vertical)
+		     (split-window window nil nil))
+		    ((eq direction 'horizontal)
+		     (split-window window nil t)))
+	      (restore-saved-window configuration
+				    (window-next-child window)
+				    (saved-window-next-child saved-window)
+				    direction)))
+
+	(if (saved-window-first-hchild saved-window)
+	    (restore-saved-window configuration
+				  window
+				  (saved-window-first-hchild saved-window)
+				  'horizontal))
+	(if (saved-window-first-vchild saved-window)
+	    (restore-saved-window configuration
+				  window
+				  (saved-window-first-vchild saved-window)
+				  'vertical))))
+
+  (if (not (saved-window-minibufferp saved-window))
+      (restore-saved-window-parameters configuration window saved-window)))
+
+(defun restore-saved-window-parameters (configuration window saved-window)
+  "Restore the window parameters stored in SAVED-WINDOW on WINDOW."
+  (let ((buffer (saved-window-buffer saved-window)))
+    (if (and buffer (buffer-live-p buffer))
+	(progn
+	  (set-window-buffer window
+			     (saved-window-buffer saved-window))
+	  (set-window-start window
+			    (marker-position (saved-window-start-marker saved-window)))
+	  (set-window-point window
+			    (marker-position (saved-window-point-marker saved-window)))
+	  (set-marker (mark-marker t buffer)
+		      (marker-position (saved-window-mark-marker saved-window))
+		      buffer)
+	  (if (not (eq buffer (window-configuration-current-buffer configuration)))
+	      (goto-char (window-point window) buffer)))))
+
+  (if (and (not (saved-window-first-hchild saved-window))
+	   (not (saved-window-first-vchild saved-window)))
+      ;; only set size for non-container windows
+      (progn
+	;; If this is the root window, it may be the only window.
+	;; Because of mismatches between actual and reported frame
+	;; size, it may not let us actually set the size of the root
+	;; window to what we want. --Mike
+	(if (not (eq window (frame-root-window (window-frame window))))
+	    (progn
+	      (enlarge-window-pixels (- (saved-window-pixel-width saved-window)
+					(window-pixel-width window))
+				     t
+				     window)
+	      (enlarge-window-pixels (- (saved-window-pixel-height saved-window)
+					(window-pixel-height window))
+				     nil
+				     window)))
+	(set-window-hscroll window (saved-window-hscroll saved-window))
+	(set-modeline-hscroll window
+			      (saved-window-modeline-hscroll saved-window))
+	(set-window-dedicated-p window (saved-window-dedicatedp saved-window))))
+
+  (if (saved-window-currentp saved-window)
+      (setq window-configuration-current-window window))
+  (if (saved-window-minibuffer-scrollp saved-window)
+      (setq minibuffer-scroll-window window)))
+
+(defun saved-window-pixel-width (saved-window)
+  "Compute the pixel width of SAVED-WINDOW."
+  (- (saved-window-pixel-right saved-window)
+     (saved-window-pixel-left saved-window)))
+
+(defun saved-window-pixel-height (saved-window)
+  "Compute the pixel height of SAVED-WINDOW."
+  (- (saved-window-pixel-bottom saved-window)
+     (saved-window-pixel-top saved-window)))
 
 ;; The window-config stack is stored as a list in frame property
 ;; 'window-config-stack, with the most recent element at the front.
--- a/src/ChangeLog	Sat Dec 07 22:54:03 2002 +0000
+++ b/src/ChangeLog	Sun Dec 08 10:25:14 2002 +0000
@@ -1,3 +1,53 @@
+2002-12-02  Mike Sperber <mike@xemacs.org>
+
+	* The Great Window Configuration rewrite: Re-implement window
+	configuration functionality in Emacs Lisp.
+
+	* window.h (Fcurrent_window_configuration): Don't export anymore.
+	(Qcurrent_window_configuration): Declare.
+	(Qset_window_configuration): Declare.
+	* event-stream.c (execute_help_form): 
+	* bytecode.c (execute_rare_opcode): Call out to Lisp to save
+	window excursion.
+	* window.c (Qcurrent_window_configuration): Declare.
+	(Qwindow_configurationp):
+	(Vwindow_configuration_free_list):
+	(Qset_window_configuration):
+	(Qtemp_buffer_show_hook):
+	(struct saved_window): 
+	(struct window_config): 
+	(SAVED_WINDOW_N): 
+	(XWINDOW_CONFIGURATION): 
+	(wrap_window_configuration): 
+	(WINDOW_CONFIGURATIONP): 
+	(CHECK_WINDOW_CONFIGURATION): 
+	(mark_window_config): 
+	(sizeof_window_config_for_n_windows): 
+	(sizeof_window_config): 
+	(print_window_config): 
+	(saved_window_equal): 
+	(window_config_equal): 
+	(Fwindow_configuration_p): 
+	(mark_windows_in_use_closure): 
+	(mark_windows_in_use): 
+	(free_window_configuration): 
+	(Fset_window_configuration): 
+	(count_windows): 
+	(saved_window_index): 
+	(save_window_save): 
+	(Fcurrent_window_configuration): 
+	(Fsave_window_excursion): Remove.
+	(mark_window_as_deleted): Rectify comment about
+	`set-window-configuration'.
+	(Fset_window_buffer): Reinstate code not activated because of old
+	implementation of window configurations.
+	(temp_output_buffer_show): Don't run `temp-buffer-show-hook'
+	anymore---this wasn't supposed to happen anyway according to the
+	documentation of `temp-buffer-show-function'.
+	(reinit_vars_of_window): Don't do the window configuration stuff
+	no more
+	(vars_of_window): Don't set up `temp-buffer-show-hook' any more.
+
 2002-12-02  Greg Allen  <greg_allen@westlb-systems.co.uk>
 
 	* database.c: Fix open_database. Berkeley DB API has changed in
--- a/src/bytecode.c	Sat Dec 07 22:54:03 2002 +0000
+++ b/src/bytecode.c	Sun Dec 08 10:25:14 2002 +0000
@@ -1098,7 +1098,7 @@
       {
 	int count = specpdl_depth ();
 	record_unwind_protect (save_window_excursion_unwind,
-			       Fcurrent_window_configuration (Qnil));
+			       call1 (Qcurrent_window_configuration, Qnil));
 	TOP = Fprogn (TOP);
 	unbind_to (count);
 	break;
--- a/src/event-stream.c	Sat Dec 07 22:54:03 2002 +0000
+++ b/src/event-stream.c	Sun Dec 08 10:25:14 2002 +0000
@@ -1061,7 +1061,7 @@
   GCPRO2 (echo, help);
 
   record_unwind_protect (save_window_excursion_unwind,
-			 Fcurrent_window_configuration (Qnil));
+			 call1 (Qcurrent_window_configuration, Qnil));
   reset_key_echo (command_builder, 1);
 
   help = Feval (Vhelp_form);
--- a/src/window.c	Sat Dec 07 22:54:03 2002 +0000
+++ b/src/window.c	Sun Dec 08 10:25:14 2002 +0000
@@ -51,7 +51,7 @@
 #include "redisplay.h"
 #include "window-impl.h"
 
-Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configurationp;
+Lisp_Object Qwindowp, Qwindow_live_p;
 Lisp_Object Qdisplay_buffer;
 
 #ifdef MEMORY_USAGE_STATS
@@ -119,20 +119,14 @@
 /* Non-nil means it's the function to call to display temp buffers.  */
 Lisp_Object Vtemp_buffer_show_function;
 
-Lisp_Object Vtemp_buffer_show_hook;
-
 /* If a window gets smaller than either of these, it is removed. */
 Fixnum window_min_height;
 Fixnum window_min_width;
 
-/* Hook run at end of temp_output_buffer_show.  */
-Lisp_Object Qtemp_buffer_show_hook;
-
 /* Number of lines of continuity in scrolling by screenfuls.  */
 Fixnum next_screen_context_lines;
 
-/* List of freed window configurations with 1 - 10 windows. */
-static Lisp_Object Vwindow_configuration_free_list[10];
+Lisp_Object Qcurrent_window_configuration, Qset_window_configuration;
 
 Lisp_Object Qtruncate_partial_width_windows;
 
@@ -2029,15 +2023,7 @@
      reinitialized by the window-configuration code as necessary. */
   finalize_window ((void *) w, 0);
 
-  /* "Nobody should be accessing anything in this object any more...",
-     I said, but unfortunately that's not quite true.
-     set-window-configuration undeletes the window and relies on
-     certain items to be there already.  Fuckme!  we really should
-     rewrite it in Lisp and just recreate the windows. (But does any
-     code depend on the pointers being the same?  At the very least,
-     we should reinit everything in the window.)
-
-     Nobody should be accessing anything in this object any more,
+  /* Nobody should be accessing anything in this object any more,
      and making them Qnil allows for better GC'ing in case a pointer
      to the dead window continues to hang around.  Zero all other
      structs in case someone tries to access something through them.
@@ -2055,12 +2041,7 @@
      through the `next' slot.  This might not seem so bad, as they're
      deleted, and will presumably be GCed - but if even *one* of those
      windows is still being pointed to, by the user, or by a window
-     configuration, then *all* of those windows stick around.
-
-     Since the window-configuration code doesn't need any of the
-     pointers to other windows (they are all recreated from the
-     window-config data), we set them all to nil so that we
-     are able to collect more actual garbage. */
+     configuration, then *all* of those windows stick around. */
 
 #define WINDOW_SLOT(slot)
 #define WINDOW_SAVED_SLOT(slot, compare) w->slot = Qnil;
@@ -2195,9 +2176,7 @@
       unchain_marker (w->start[DESIRED_DISP]);
       unchain_marker (w->start[CMOTION_DISP]);
       unchain_marker (w->sb_point);
-      /* This breaks set-window-configuration if windows in the saved
-	 configuration get deleted and multiple frames are in use. */
-      /* w->buffer = Qnil; */
+      w->buffer = Qnil;
     }
 
   /* close up the hole in the sibling list */
@@ -3551,20 +3530,8 @@
   tem = w->buffer;
   if (NILP (tem))
     invalid_operation ("Window is deleted", Qunbound);
-
-  /* While this seems like a logical thing to do, it causes problems
-     because of saved window configurations.  It is possible for a
-     buffer to get restored into a window in which it is already being
-     displayed, but start and point are actually at completely
-     different locations.  So we let this function complete fully and
-     it will then make sure redisplay correctly updates things.
-
-     #### This is a kludge.  The correct approach is not to do this
-     but to fix set-window-configuration. */
-#if 0
   else if (EQ (tem, buffer))
     return Qnil;
-#endif
   else if (! EQ (tem, Qt))	/* w->buffer is t when the window
 				   is first being set up.  */
     {
@@ -3743,30 +3710,6 @@
       set_marker_restricted (w->start[CURRENT_DISP], make_int (1), buf);
       set_marker_restricted (w->pointm[CURRENT_DISP], make_int (1), buf);
       set_marker_restricted (w->sb_point, make_int (1), buf);
-
-      /* Run temp-buffer-show-hook, with the chosen window selected.  */
-      if (!preparing_for_armageddon)
-	{
-	  Lisp_Object tem;
-	  tem = Fboundp (Qtemp_buffer_show_hook);
-	  if (!NILP (tem))
-	    {
-	      tem = Fsymbol_value (Qtemp_buffer_show_hook);
-	      if (!NILP (tem))
-		{
-		  int count = specpdl_depth ();
-
-		  /* Select the window that was chosen, for running
-                     the hook.  */
-		  record_unwind_protect (save_window_excursion_unwind,
-					 Fcurrent_window_configuration (Qnil));
-
-		  Fselect_window (window, Qnil);
-		  run_hook (Qtemp_buffer_show_hook);
-		  unbind_to (count);
-		}
-	    }
-	}
     }
 }
 
@@ -5146,790 +5089,7 @@
 }
 
 #endif /* MEMORY_USAGE_STATS */
-
 
-/************************************************************************/
-/*                         Window configurations                        */
-/************************************************************************/
-
-/* #### This window configuration stuff has had serious bugs lurking in it
-   for years; it would be a -huge- win if this was reimplemented in lisp.
- */
-
-/* If you add anything to this structure make sure saved_window_equal
-   knows about it. */
-struct saved_window
-{
-  Lisp_Object window;         /* window */
-  Lisp_Object buffer;         /* buffer */
-  Lisp_Object start;          /* copied marker */
-  Lisp_Object pointm;         /* copied marker */
-  Lisp_Object sb_point;	      /* copied marker */
-  Lisp_Object mark;           /* copied marker */
-  int pixel_left;
-  int pixel_top;
-  int pixel_width;
-  int pixel_height;
-  int hscroll;
-  Charcount modeline_hscroll;
-  int parent_index;           /* index into saved_windows */
-  int prev_index;             /* index into saved_windows */
-  char start_at_line_beg; /* boolean */
-
-#define WINDOW_SLOT_DECLARATION
-#define WINDOW_SLOT(slot)
-#define WINDOW_SAVED_SLOT(slot, compare) Lisp_Object slot;
-#include "winslots.h"
-};
-
-/* If you add anything to this structure make sure window_config_equal
-   knows about it. */
-struct window_config
-{
-  struct lcrecord_header header;
-  /*  int frame_width; No longer needed, JV
-      int frame_height; */
-#if 0 /* FSFmacs */
-  Lisp_Object selected_frame;
-#endif
-  Lisp_Object current_window;
-  Lisp_Object current_buffer;
-  Lisp_Object minibuffer_scroll_window;
-  Lisp_Object root_window;
-  int minibuf_height; /* 0 = no minibuffer, <0, size in lines, >0 in pixels */
-  /* Record the values of window-min-width and window-min-height
-     so that window sizes remain consistent with them.  */
-  int min_width, min_height;
-  int saved_windows_count;
-  /* Zero-sized arrays aren't ANSI C */
-  struct saved_window saved_windows[1];
-};
-
-#define SAVED_WINDOW_N(conf, n) (&((conf)->saved_windows[(n)]))
-#define XWINDOW_CONFIGURATION(x) XRECORD (x, window_configuration, struct window_config)
-#define wrap_window_configuration(p) wrap_record (p, window_configuration)
-#define WINDOW_CONFIGURATIONP(x) RECORDP (x, window_configuration)
-#define CHECK_WINDOW_CONFIGURATION(x) CHECK_RECORD (x, window_configuration)
-
-#ifdef USE_KKCC
-static const struct struct_description saved_window_description = {
-};
-
-static const struct lrecord_description window_config_description [] = {
-  { XD_LISP_OBJECT, offsetof (struct window_config, current_window) },
-  { XD_LISP_OBJECT, offsetof (struct window_config, current_buffer) },
-  { XD_LISP_OBJECT, offsetof (struct window_config, minibuffer_scroll_window) },
-  { XD_LISP_OBJECT, offsetof (struct window_config, root_window) },
-  { XD_END }
-};
-#endif /* USE_KKCC */
-
-static Lisp_Object
-mark_window_config (Lisp_Object obj)
-{
-  struct window_config *config = XWINDOW_CONFIGURATION (obj);
-  int i;
-  mark_object (config->current_window);
-  mark_object (config->current_buffer);
-  mark_object (config->minibuffer_scroll_window);
-  mark_object (config->root_window);
-
-  for (i = 0; i < config->saved_windows_count; i++)
-    {
-      struct saved_window *s = SAVED_WINDOW_N (config, i);
-      mark_object (s->window);
-      mark_object (s->buffer);
-      mark_object (s->start);
-      mark_object (s->pointm);
-      mark_object (s->sb_point);
-      mark_object (s->mark);
-#if 0
-      /* #### This looked like this. I do not see why specifier cached
-	 values should not be marked, as such specifiers as toolbars
-	 might have GC-able instances. Freed configs are not marked,
-	 aren't they?  -- kkm */
-      mark_object (s->dedicated);
-#else
-#define WINDOW_SLOT(slot)
-#define WINDOW_SAVED_SLOT(slot, compare) mark_object (s->slot);
-#include "winslots.h"
-#endif
-    }
-  return Qnil;
-}
-
-inline static Bytecount
-sizeof_window_config_for_n_windows (int n)
-{
-  return FLEXIBLE_ARRAY_STRUCT_SIZEOF (struct window_config,
-				       struct saved_window, saved_windows, n);
-}
-
-static Bytecount
-sizeof_window_config (const void *h)
-{
-  const struct window_config *c = (const struct window_config *) h;
-  return sizeof_window_config_for_n_windows (c->saved_windows_count);
-}
-
-static void
-print_window_config (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
-{
-  struct window_config *config = XWINDOW_CONFIGURATION (obj);
-  if (print_readably)
-    printing_unreadable_object ("#<window-configuration 0x%x>",
-				config->header.uid);
-  write_c_string (printcharfun, "#<window-configuration ");
-  write_fmt_string (printcharfun, "0x%x>", config->header.uid);
-}
-
-#ifdef USE_KKCC
-DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("window-configuration",
-					window_configuration,
-					0, /*dumpable-flag*/
-					mark_window_config,
-					print_window_config,
-					0, 0, 0, 
-					0/*window_config_description*/, sizeof_window_config,
-					struct window_config);
-#else /* not USE_KKCC */
-DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("window-configuration",
-					window_configuration,
-					mark_window_config,
-					print_window_config,
-					0, 0, 0, 0, sizeof_window_config,
-					struct window_config);
-#endif /* not USE_KKCC */
-
-/* Returns a boolean indicating whether the two saved windows are
-   identical. */
-static int
-saved_window_equal (struct saved_window *win1, struct saved_window *win2)
-{
-#define WINDOW_SLOT(slot)
-#define WINDOW_SAVED_SLOT(slot, compare)	\
-  if (!compare (win1->slot, win2->slot))	\
-    return 0;
-#include "winslots.h"
-
-  return
-    EQ (win1->window, win2->window) &&
-    EQ (win1->buffer, win2->buffer) &&
-    internal_equal (win1->start,    win2->start, 0) &&
-    internal_equal (win1->pointm,   win2->pointm, 0) &&
-    internal_equal (win1->sb_point, win2->sb_point, 0) &&
-    internal_equal (win1->mark,     win2->mark, 0) &&
-    win1->pixel_left   == win2->pixel_left &&
-    win1->pixel_top    == win2->pixel_top &&
-    win1->pixel_width  == win2->pixel_width &&
-    win1->pixel_height == win2->pixel_height &&
-    win1->hscroll      == win2->hscroll &&
-    win1->modeline_hscroll == win2->modeline_hscroll &&
-    win1->parent_index == win2->parent_index &&
-    win1->prev_index   == win2->prev_index &&
-    win1->start_at_line_beg == win2->start_at_line_beg;
-}
-
-/* Returns a boolean indicating whether the two given configurations
-   are identical. */
-static int
-window_config_equal (Lisp_Object conf1, Lisp_Object conf2)
-{
-  struct window_config *fig1, *fig2;
-  int i;
-
-  /* First check if they are truly the same. */
-  if (EQ (conf1, conf2))
-    return 1;
-
-  fig1 = XWINDOW_CONFIGURATION (conf1);
-  fig2 = XWINDOW_CONFIGURATION (conf2);
-
-  if (!((fig1->saved_windows_count == fig2->saved_windows_count) &&
-	EQ (fig1->current_window,	    fig2->current_window) &&
-	EQ (fig1->current_buffer,	    fig2->current_buffer) &&
-	EQ (fig1->root_window,		    fig2->root_window) &&
-	EQ (fig1->minibuffer_scroll_window, fig2->minibuffer_scroll_window)))
-	/* &&
-	fig1->frame_width  == fig2->frame_width &&
-	fig1->frame_height == fig2->frame_height)) */
-    return 0;
-
-  for (i = 0; i < fig1->saved_windows_count; i++)
-    {
-      if (!saved_window_equal (SAVED_WINDOW_N (fig1, i),
-			       SAVED_WINDOW_N (fig2, i)))
-	return 0;
-    }
-
-  return 1;
-}
-
-DEFUN ("window-configuration-p", Fwindow_configuration_p, 1, 1, 0, /*
-Return t if OBJECT is a window-configuration object.
-*/
-       (object))
-{
-  return WINDOW_CONFIGURATIONP (object) ? Qt : Qnil;
-}
-
-static int
-mark_windows_in_use_closure (struct window *w, void *closure)
-{
-  int mark = *(int *)closure;
-  w->config_mark = mark;
-  return 0;
-}
-
-static void
-mark_windows_in_use (struct frame *f, int mark)
-{
-  map_windows (f, mark_windows_in_use_closure, &mark);
-}
-
-/* Lisp_Object return value so it can be used in record_unwind_protect() */
-static Lisp_Object
-free_window_configuration (Lisp_Object window_config)
-{
-  int i;
-  struct window_config *config = XWINDOW_CONFIGURATION (window_config);
-
-  /* Free all the markers.  It's not completely necessary that
-     we do this (window configs sitting in a free list aren't
-     marked normally so the markers wouldn't be marked anyway)
-     but it's more efficient. */
-  for (i = 0; i < config->saved_windows_count; i++)
-    {
-      struct saved_window *p = SAVED_WINDOW_N (config, i);
-
-      if (!NILP (p->pointm))
-	{
-	  free_marker (XMARKER (p->pointm));
-	  p->pointm = Qnil;
-	}
-      if (!NILP (p->start))
-	{
-	  free_marker (XMARKER (p->start));
-	  p->start = Qnil;
-	}
-      if (!NILP (p->sb_point))
-	{
-	  free_marker (XMARKER (p->sb_point));
-	  p->sb_point = Qnil;
-	}
-      if (!NILP (p->mark))
-	{
-	  free_marker (XMARKER (p->mark));
-	  p->mark = Qnil;
-	}
-    }
-
-  if (config->saved_windows_count <= countof (Vwindow_configuration_free_list))
-    free_managed_lcrecord (Vwindow_configuration_free_list
-			   [config->saved_windows_count - 1],
-			   window_config);
-
-  return Qnil;
-}
-
-DEFUN ("set-window-configuration", Fset_window_configuration, 1, 1, 0, /*
-Set the configuration of windows and buffers as specified by CONFIGURATION.
-CONFIGURATION must be a value previously returned
-by `current-window-configuration' (which see).
-*/
-       (configuration))
-{
-  struct window *w;
-  struct window_config *config;
-  struct saved_window *p;
-  Lisp_Object new_current_buffer;
-  int k;
-  Lisp_Object frame;
-  struct frame *f;
-  struct gcpro gcpro1;
-  Lisp_Object old_window_config;
-  /*  int previous_frame_height;
-      int previous_frame_width;*/
-  int previous_pixel_top;
-  int previous_pixel_height;
-  int previous_pixel_left;
-  int previous_pixel_width;
-  int previous_minibuf_height, previous_minibuf_top,previous_minibuf_width;
-  int real_font_height;
-  int converted_minibuf_height,target_minibuf_height;
-  int specpdl_count = specpdl_depth ();
-
-  GCPRO1 (configuration);
-
-  CHECK_WINDOW_CONFIGURATION (configuration);
-  config = XWINDOW_CONFIGURATION (configuration);
-
-  frame = XWINDOW (SAVED_WINDOW_N (config, 0)->window)->frame;
-  f = XFRAME (frame);
-
-  /* Do not signal an error here if the frame was deleted.  There are
-     reasonable cases where we could get here with a deleted frame and
-     just want to do close to nothing instead. */
-
-  if (FRAME_LIVE_P (f))
-    {
-      /* restore the frame characteristics */
-
-      new_current_buffer = config->current_buffer;
-      if (!BUFFER_LIVE_P (XBUFFER (new_current_buffer)))
-	new_current_buffer = Qnil;
-
-      /*
-       * Assumed precondition:  w->config_mark = 0 for all w
-       * This procedure should ensure this is true by the time it exits
-       * to ensure the precondition for future calls.
-       *
-       * We use w->config_mark to know whether we're modifying a
-       * window that is currently visible on the frame (#### we
-       * should just be able to check whether the window is dead
-       * or not, but this way is safer?).  As we process each
-       * window, we set its config_mark to 0.  At the end, we
-       * go through all the windows that used to be on the frame,
-       * set each one's config_mark to 0 (to maintain the
-       * assumed precondition) and delete each one that's no
-       * longer in use.
-       *
-       * #### Using a window-configuration to keep track of
-       * the current windows is wasteful.  All we need is the
-       * list of windows, so we could just use a dynarr.
-       */
-      old_window_config = Fcurrent_window_configuration (frame);
-
-      /* If the new configuration is already equal to the old, then stop
-	 right here.  This saves the work below and it also saves
-	 triggering a full redisplay of this window.  This is a huge win
-	 when using the mouse since the mode motion code uses
-	 save-window-excursion extensively but will rarely cause the
-	 configuration to actually change. */
-      if (window_config_equal (configuration, old_window_config))
-	{
-	  free_window_configuration (old_window_config);
-	  UNGCPRO;
-	  return Qnil;
-	}
-
-      /* We can't quit or even check for quit because that may cause
-	 investigation of the frame state, which may crash if the frame is
-	 in an inconsistent state. */
-      begin_dont_check_for_quit ();
-      record_unwind_protect (free_window_configuration, old_window_config);
-
-      mark_windows_in_use (f, 1);
-#ifdef BROKEN_SUBWINDOW_REDISPLAY
-      /* Force subwindows to be remapped. This is overkill but saves
-	us having to rely on the redisplay code to unmap any extant
-	subwindows.
-
-	#### It does cause some extra flashing though which we could
-	possibly avoid. So consider trying to get redisplay to work
-	correctly.
-
-	Removing the instances from the frame cache is wrong because
-	an instance is only put in the frame cache when it is
-	instantiated. So if we do this there is a chance that stuff
-	will never get put back in the frame cache. */
-      reset_frame_subwindow_instance_cache (f);
-#endif
-#if 0
-      /* JV: This is bogus,
-	 First of all, the units are inconsistent. The frame sizes are measured
-	 in characters but the window sizes are stored in pixels. So if a
-	 font size change happened between saving and restoring, the
-	 frame "sizes" maybe equal but the windows still should be
-	 resized. This is tickled a lot by the new "character size
-	 stays constant" policy in 21.0. It leads to very weird
-	 glitches (and possibly crashes when asserts are tickled).
-
-	 Just changing the units doesn't help because changing the
-	 toolbar configuration can also change the pixel positions.
-	 Luckily there is a much simpler way of doing this, see below.
-       */
-      previous_frame_width = FRAME_WIDTH (f);
-      previous_frame_height = FRAME_HEIGHT (f);
-      /* If the frame has been resized since this window configuration was
-	 made, we change the frame to the size specified in the
-	 configuration, restore the configuration, and then resize it
-	 back.  We keep track of the prevailing height in these variables.  */
-      if (config->frame_height != FRAME_HEIGHT (f)
-	  || config->frame_width != FRAME_WIDTH (f))
-	change_frame_size (f, config->frame_height, config->frame_width, 0);
-#endif
-
-      previous_pixel_top = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top;
-      previous_pixel_height = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_height;
-      previous_pixel_left = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left;
-      previous_pixel_width = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_width;
-
-      /* remember some properties of the minibuffer */
-
-      default_face_height_and_width (frame, &real_font_height, 0);
-      assert(real_font_height > 0);
-
-      if (FRAME_HAS_MINIBUF_P (f) && ! FRAME_MINIBUF_ONLY_P (f))
-	{
-	  previous_minibuf_height
-	    = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_height;
-	  previous_minibuf_top
-	    = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_top;
-	  previous_minibuf_width
-	    = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_width;
-	}
-      else
-	{
-	  previous_minibuf_height = 0;
-	  previous_minibuf_top = 0;
-	  previous_minibuf_width = 0;
-	}
-      converted_minibuf_height =
-	(previous_minibuf_height % real_font_height) == 0 ?
-	- (previous_minibuf_height / real_font_height ) :    /* lines */
-	    previous_minibuf_height;   /* pixels */
-
-      /* Temporarily avoid any problems with windows that are smaller
-	 than they are supposed to be.  */
-      window_min_height = 1;
-      window_min_width = 1;
-
-      /* OK, now restore all the windows in the window config.
-	 This may involve "undeleting" windows, since the
-	 windows in the window config may be deleted.
-	 */
-      for (k = 0; k < config->saved_windows_count; k++)
-	{
-	  p = SAVED_WINDOW_N (config, k);
-	  w = XWINDOW (p->window);
-	  w->next = Qnil;
-
-	  /* The window might be dead.  In this case, its redisplay
-	     structures were freed, so we need to reallocate them. */
-	  if (!w->face_cachels)
-	    {
-	      w->face_cachels = Dynarr_new (face_cachel);
-	      reset_face_cachels (w);
-	    }
-	  if (!w->glyph_cachels)
-	    w->glyph_cachels = Dynarr_new (glyph_cachel);
-	  if (!w->line_start_cache)
-	    w->line_start_cache = Dynarr_new (line_start_cache);
-	  w->gutter_extent_modiff[0] = 0;
-	  w->gutter_extent_modiff[1] = 0;
-	  w->gutter_extent_modiff[2] = 0;
-	  w->gutter_extent_modiff[3] = 0;
-	  w->dead = 0;
-
-	  note_object_created (p->window);
-
-	  if (p->parent_index >= 0)
-	    w->parent = SAVED_WINDOW_N (config, p->parent_index)->window;
-	  else
-	    w->parent = Qnil;
-
-	  if (p->prev_index >= 0)
-	    {
-	      w->prev = SAVED_WINDOW_N (config, p->prev_index)->window;
-
-	      /* This is true for a minibuffer-only frame. */
-	      if (!NILP (w->mini_p) && EQ (w->prev, p->window))
-		w->next = Qnil;
-	      else
-		XWINDOW (w->prev)->next = p->window;
-	    }
-	  else
-	    {
-	      w->prev = Qnil;
-	      if (!NILP (w->parent))
-		{
-		  if (WINDOW_WIDTH (p) == WINDOW_WIDTH (XWINDOW (w->parent)))
-		    {
-		      XWINDOW (w->parent)->vchild = p->window;
-		      XWINDOW (w->parent)->hchild = Qnil;
-		    }
-		  else
-		    {
-		      XWINDOW (w->parent)->hchild = p->window;
-		      XWINDOW (w->parent)->vchild = Qnil;
-		    }
-		}
-	    }
-	  if (!w->config_mark)
-	    {
-	      /* #### This should be equivalent to the window previously
-		 having been dead.  If we're brave, we'll put in an
-		 assertion to this effect. */
-	      MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f);
-	    }
-	  else /* if (!EQ (w->buffer, p->buffer)) */
-	    {
-	      /* With the new redisplay we let it know that a change has
-		 been made and it will take care of the rest.  If we don't
-		 tell it something has possibly changed it could lead to
-		 incorrect display. */
-	      MARK_WINDOWS_CHANGED (w);
-	    }
-
-	  WINDOW_LEFT (w) = WINDOW_LEFT (p);
-	  WINDOW_TOP (w) = WINDOW_TOP (p);
-	  WINDOW_WIDTH (w) = WINDOW_WIDTH (p);
-	  WINDOW_HEIGHT (w) = WINDOW_HEIGHT (p);
-	  w->hscroll = p->hscroll;
-	  w->modeline_hscroll = p->modeline_hscroll;
-	  w->line_cache_last_updated = Qzero;
-	  /* When we restore a window's configuration, the identity of
-	     the window hasn't actually changed - so there is no
-	     reason why we shouldn't preserve the instance cache for
-	     it - unless it was originally deleted. This will often
-	     buy us something as we will not have to re-instantiate
-	     all the instances. This is because this is an instance
-	     cache - not a display cache. Preserving the display cache
-	     would definitely be wrong.
-
-	     We specifically want to do this for tabs, since for some
-	     reason finding a file will cause the configuration to be
-	     set. */
-	  if (NILP (w->subwindow_instance_cache))
-	    w->subwindow_instance_cache =
-	      make_image_instance_cache_hash_table ();
-
-	  SET_LAST_MODIFIED (w, 1);
-	  SET_LAST_FACECHANGE (w);
-	  w->config_mark = 0;
-
-	  /* #### Consider making the instance cache a WINDOW_SAVED_SLOT. */
-#define WINDOW_SLOT(slot)
-#define WINDOW_SAVED_SLOT(slot, compare) w->slot = p->slot;
-#include "winslots.h"
-
-	  /* Reinstall the saved buffer and pointers into it.  */
-	  if (NILP (p->buffer))
-	    w->buffer = p->buffer;
-	  else
-	    {
-	      if (BUFFER_LIVE_P (XBUFFER (p->buffer)))
-		/* If saved buffer is alive, install it.  */
-		{
-		  w->buffer = p->buffer;
-		  w->start_at_line_beg = p->start_at_line_beg;
-		  set_marker_restricted (w->start[CURRENT_DISP],
-					 Fmarker_position (p->start),
-					 w->buffer);
-		  set_marker_restricted (w->pointm[CURRENT_DISP],
-					 Fmarker_position (p->pointm),
-					 w->buffer);
-		  set_marker_restricted (w->sb_point,
-					 Fmarker_position (p->sb_point),
-					 w->buffer);
-		  Fset_marker (XBUFFER (w->buffer)->mark,
-			       Fmarker_position (p->mark), w->buffer);
-
-		  /* As documented in Fcurrent_window_configuration, don't
-		     save the location of point in the buffer which was current
-		     when the window configuration was recorded.  */
-		  if (!EQ (p->buffer, new_current_buffer) &&
-		      XBUFFER (p->buffer) == current_buffer)
-		    Fgoto_char (w->pointm[CURRENT_DISP], Qnil);
-		}
-	      else if (NILP (w->buffer) ||
-		       !BUFFER_LIVE_P (XBUFFER (w->buffer)))
-		/* Else if window's old buffer is dead too, get a live one.  */
-		{
-		  /* #### The following line makes me nervous... */
-		  /* w->buffer = Fcdr (Fcar (XFRAME (w->frame)->buffer_alist));*/
-		  w->buffer = Fget_buffer_create (QSscratch);
-		  /* w->buffer = Fother_buffer (Qnil, w->frame, Qnil); */
-		  /* This will set the markers to beginning of visible
-                     range.  */
-		  set_marker_restricted (w->start[CURRENT_DISP], Qzero, w->buffer);
-		  set_marker_restricted (w->pointm[CURRENT_DISP], Qzero,
-					 w->buffer);
-		  set_marker_restricted (w->sb_point, Qzero, w->buffer);
-		  w->start_at_line_beg = 1;
-		}
-	      else
-		/* Keeping window's old buffer; make sure the markers
-                   are real.  */
-		{
-		  /* Set window markers at start of visible range.  */
-		  if (XMARKER (w->start[CURRENT_DISP])->buffer == 0)
-		    set_marker_restricted (w->start[CURRENT_DISP], Qzero,
-					   w->buffer);
-		  if (XMARKER (w->sb_point)->buffer == 0)
-		    set_marker_restricted (w->sb_point, Qzero, w->buffer);
-		  if (XMARKER (w->pointm[CURRENT_DISP])->buffer == 0)
-		    set_marker_restricted (w->pointm[CURRENT_DISP],
-					   make_int
-					   (BUF_PT (XBUFFER (w->buffer))),
-					   w->buffer);
-		  w->start_at_line_beg = 1;
-		}
-	    }
-	}
-
-      FRAME_ROOT_WINDOW (f) = config->root_window;
-      /* Note that FSFmacs unilaterally calls Fselect_window() here, and
-	 then calls do_switch_frame() below to select the frame that was
-	 recorded in the window config as being selected.
-
-	 Instead, we don't ever change the selected frame, and either
-	 call Fselect_window() below if the window config's frame is
-	 currently selected, or just set the selected window of the
-	 window config's frame. */
-
-#if 0
-      /* Set the frame height to the value it had before this function.  */
-      if (previous_frame_height != FRAME_HEIGHT (f)
-	  || previous_frame_width != FRAME_WIDTH (f))
-	change_frame_size (f, previous_frame_height, previous_frame_width, 0);
-#endif
-      /* We just reset the size and position of the minibuffer, to its old
-	 value, which needn't be valid. So we do some magic to see which value
-	 to actually take. Then we set it.
-
-	 The magic:
-	 We take the old value if is in the same units but differs from the
-	 current value.
-
-         #### Now we get more cases correct then ever before, but
-	 are we treating all? For instance what if the frames minibuf window
-	 is no longer the same one?
-      */
-      target_minibuf_height = previous_minibuf_height;
-      if (converted_minibuf_height &&
-	  (converted_minibuf_height * config->minibuf_height) > 0 &&
-	  (converted_minibuf_height !=  config->minibuf_height))
-	{
-	  target_minibuf_height = config->minibuf_height < 0 ?
-	    - (config->minibuf_height * real_font_height) :
-	    config->minibuf_height;
-	  target_minibuf_height =
-	    max(target_minibuf_height,real_font_height);
-	}
-      if (previous_minibuf_height)
-	{
-	  XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_top
-	    = previous_minibuf_top -
-	          (target_minibuf_height - previous_minibuf_height);
-	  set_window_pixheight (FRAME_MINIBUF_WINDOW (f),
-				target_minibuf_height, 0);
-	  set_window_pixwidth  (FRAME_MINIBUF_WINDOW (f),
-			    previous_minibuf_width, 0);
-	}
-
-      /* This is a better way to deal with frame resizing, etc.
-	 What we _actually_ want is for the old (just restored)
-	 root window to fit
-	 into the place of the new one. So we just do that. Simple! */
-      XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top = previous_pixel_top;
-      /* Note that this function also updates the subwindow
-	 "pixel_top"s */
-      set_window_pixheight (FRAME_ROOT_WINDOW (f),
-	  previous_pixel_height -
-		  (target_minibuf_height - previous_minibuf_height), 0);
-      XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left = previous_pixel_left;
-      /* Note that this function also updates the subwindow
-	 "pixel_left"s */
-      set_window_pixwidth (FRAME_ROOT_WINDOW (f), previous_pixel_width, 0);
-
-      /* If restoring in the current frame make the window current,
-	 otherwise just update the frame selected_window slot to be
-	 the restored current_window. */
-      if (f == selected_frame ())
-	{
-#if 0
-	  /* When using `pop-window-configuration', often the minibuffer
-	     ends up as the selected window even though it's not active ...
-	     I really don't know the cause of this, but it should never
-	     happen.  This kludge should fix it.
-
-	     #### Find out why this is really going wrong. */
-	  if (!minibuf_level &&
-	      MINI_WINDOW_P (XWINDOW (config->current_window)))
-	    window_to_select = Fnext_window (config->current_window,
-					     Qnil, Qnil, Qnil);
-	  else
-	    window_to_select = config->current_window;
-#endif
-	  /* Do this last so that buffer stacking is calculated
-	     correctly. */
-	  Fselect_window (config->current_window, Qnil);
-
-	  if (!NILP (new_current_buffer))
-	    {
-	      Fset_buffer (new_current_buffer);
-	      Frecord_buffer (new_current_buffer);
-	    }
-	  else
-	    {
-	      Fset_buffer (XWINDOW (config->current_window)->buffer);
-	      Frecord_buffer (XWINDOW (config->current_window)->buffer);
-	    }
-	}
-      else
-	set_frame_selected_window (f, config->current_window);
-    }
-  else
-    old_window_config = Qnil; /* Warning suppression */
-
-  /* Restore the minimum heights recorded in the configuration.  */
-  window_min_height = config->min_height;
-  window_min_width = config->min_width;
-
-#if 0 /* FSFmacs */
-  /* see above comment */
-  /* Fselect_window will have made f the selected frame, so we
-     reselect the proper frame here.  Fhandle_switch_frame will change the
-     selected window too, but that doesn't make the call to
-     Fselect_window above totally superfluous; it still sets f's
-     selected window.  */
-  if (FRAME_LIVE_P (XFRAME (config->selected_frame)))
-    do_switch_frame (config->selected_frame, Qnil, 0);
-#endif
-
-  Vminibuffer_scroll_window = config->minibuffer_scroll_window;
-
-  if (FRAME_LIVE_P (f))
-    {
-      /* Do this before calling recompute_all_cached_specifiers_in_window()
-	 so that things like redisplay_redraw_cursor() won't abort due
-	 to no window mirror present. */
-      f->mirror_dirty = 1;
-
-      config = XWINDOW_CONFIGURATION (old_window_config);
-      for (k = 0; k < config->saved_windows_count; k++)
-	{
-	  p = SAVED_WINDOW_N (config, k);
-	  w = XWINDOW (p->window);
-	  /* Remember, we set w->config_mark on all currently visible
-	     windows, and reset it on all newly visible windows.
-	     Any windows still marked need to be deleted. */
-	  if (w->config_mark)
-	    {
-	      mark_window_as_deleted (w);
-	      w->config_mark = 0;
-	    }
-	  else
-	    {
-	      /* We just potentially changed the window's buffer and
-		 potentially turned a dead window into a live one,
-		 so we need to recompute the cached specifier values. */
-	      recompute_all_cached_specifiers_in_window (w);
-	    }
-	}
-    }
-
-  /* Now restore things, when everything else if OK. */
-
-  unbind_to (specpdl_count);
-
-  UNGCPRO;
-
-  return Qnil;
-}
-
 /* Mark all subwindows of a window as deleted.  The argument
    W is actually the subwindow tree of the window in question. */
 
@@ -5943,185 +5103,10 @@
   mark_window_as_deleted (w);
 }
 
-
-static int
-count_windows (struct window *window)
-{
-  return 1 +
-    (!NILP (window->next)   ? count_windows (XWINDOW (window->next))   : 0) +
-    (!NILP (window->vchild) ? count_windows (XWINDOW (window->vchild)) : 0) +
-    (!NILP (window->hchild) ? count_windows (XWINDOW (window->hchild)) : 0);
-}
-
-static int
-saved_window_index (Lisp_Object window, struct window_config *config, int lim)
-{
-  int j;
-  for (j = 0; j < lim; j++)
-    {
-      if (EQ (SAVED_WINDOW_N (config, j)->window, window))
-	return j;
-    }
-  abort ();
-  return 0;	/* suppress compiler warning */
-}
-
-static int
-save_window_save (Lisp_Object window, struct window_config *config, int i)
-{
-  struct window *w;
-
-  for (; !NILP (window); window = w->next)
-    {
-      struct saved_window *p = SAVED_WINDOW_N (config, i);
-
-      w = XWINDOW (window);
-      i++;
-      p->window = window;
-      p->buffer = w->buffer;
-      WINDOW_LEFT (p) = WINDOW_LEFT (w);
-      WINDOW_TOP (p) = WINDOW_TOP (w);
-      WINDOW_WIDTH (p) = WINDOW_WIDTH (w);
-      WINDOW_HEIGHT (p) = WINDOW_HEIGHT (w);
-      p->hscroll = w->hscroll;
-      p->modeline_hscroll = w->modeline_hscroll;
-
-#define WINDOW_SLOT(slot)
-#define WINDOW_SAVED_SLOT(slot, compare) p->slot = w->slot;
-#include "winslots.h"
-
-      if (!NILP (w->buffer))
-	{
-	  /* Save w's value of point in the window configuration.
-	     If w is the selected window, then get the value of point
-	     from the buffer; pointm is garbage in the selected window.  */
-	  if (EQ (window, Fselected_window (Qnil)))
-	    {
-	      p->pointm = noseeum_make_marker ();
-	      Fset_marker (p->pointm,
-			   make_int (BUF_PT (XBUFFER (w->buffer))),
-			   w->buffer);
-	    }
-	  else
-	    p->pointm = noseeum_copy_marker (w->pointm[CURRENT_DISP], Qnil);
-
-	  p->start = noseeum_copy_marker (w->start[CURRENT_DISP], Qnil);
-	  p->sb_point = noseeum_copy_marker (w->sb_point, Qnil);
-	  p->start_at_line_beg = w->start_at_line_beg;
-
-	  p->mark = noseeum_copy_marker (XBUFFER (w->buffer)->mark, Qnil);
-	}
-      else
-	{
-	  p->pointm = Qnil;
-	  p->start = Qnil;
-	  p->sb_point = Qnil;
-	  p->mark = Qnil;
-	  p->start_at_line_beg = 0;
-	}
-
-      if (NILP (w->parent))
-	p->parent_index = -1;
-      else
-        p->parent_index = saved_window_index (w->parent, config, i);
-      if (NILP (w->prev))
-	p->prev_index = -1;
-      else
-        p->prev_index = saved_window_index (w->prev, config, i);
-      if (!NILP (w->vchild))
-	i = save_window_save (w->vchild, config, i);
-      if (!NILP (w->hchild))
-	i = save_window_save (w->hchild, config, i);
-    }
-
-  return i;
-}
-
-#if 0 /* FSFmacs */
-/* Added to doc string:
-
-This also records the currently selected frame, and FRAME's focus
-redirection (see `redirect-frame-focus').
-
-*/
-#endif
-
-DEFUN ("current-window-configuration", Fcurrent_window_configuration, 0, 1, 0, /*
-Return an object representing the current window configuration of FRAME.
-If FRAME is nil or omitted, use the selected frame.
-This describes the number of windows, their sizes and current buffers,
-and for each window on FRAME the displayed buffer, where display
-starts, and the positions of point and mark.
-An exception is made for point in the current buffer:
-its value is -not- saved.
-*/
-       (frame))
-{
-  Lisp_Object result;
-  struct frame *f = decode_frame (frame);
-  struct window_config *config;
-  int n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f)));
-  int minibuf_height;
-  int real_font_height;
-
-  if (n_windows <= countof (Vwindow_configuration_free_list))
-    config = XWINDOW_CONFIGURATION (allocate_managed_lcrecord
-				    (Vwindow_configuration_free_list
-				     [n_windows - 1]));
-  else
-    /* More than ten windows; just allocate directly */
-    config = (struct window_config *)
-      alloc_lcrecord (sizeof_window_config_for_n_windows (n_windows),
-		      &lrecord_window_configuration);
-  result = wrap_window_configuration (config);
-  /*
-  config->frame_width = FRAME_WIDTH (f);
-  config->frame_height = FRAME_HEIGHT (f); */
-  /* #### When using `push-window-configuration', often the minibuffer ends
-     up as the selected window because functions run as the result of
-     user interaction e.g. hyper-apropos. It seems to me the sensible
-     thing to do is not record the minibuffer here. 
-
-     #### Unfortunately this is a change to previous behaviour, however logical
-     it may be, so revert for the moment. */
-#if 0
-  if (FRAME_MINIBUF_ONLY_P (f) || minibuf_level)
-    config->current_window = FRAME_SELECTED_WINDOW (f);
-  else
-    config->current_window = FRAME_LAST_NONMINIBUF_WINDOW (f);
-#endif
-  config->current_window = FRAME_SELECTED_WINDOW (f);
-  config->current_buffer = wrap_buffer (current_buffer);
-  config->minibuffer_scroll_window = Vminibuffer_scroll_window;
-  config->root_window = FRAME_ROOT_WINDOW (f);
-  config->min_height = window_min_height;
-  config->min_width = window_min_width;
-  config->saved_windows_count = n_windows;
-  save_window_save (FRAME_ROOT_WINDOW (f), config, 0);
-
-  /* save the minibuffer height using the heuristics from
-     change_frame_size_1 */
-
-  frame = wrap_frame (f); /* frame could have been nil ! */
-  default_face_height_and_width (frame, &real_font_height, 0);
-  assert(real_font_height > 0);
-
-  if (FRAME_HAS_MINIBUF_P (f) && ! FRAME_MINIBUF_ONLY_P (f))
-    minibuf_height = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_height;
-  else
-    minibuf_height = 0;
-  config->minibuf_height = (minibuf_height % real_font_height) == 0 ?
-    - (minibuf_height / real_font_height ) :    /* lines */
-    minibuf_height;   /* pixels */
-
-  return result;
-}
-
 Lisp_Object
 save_window_excursion_unwind (Lisp_Object window_config)
 {
-  Lisp_Object val = Fset_window_configuration (window_config);
-  free_window_configuration (window_config);
+  Lisp_Object val = call1 (Qset_window_configuration, window_config);
   return val;
 }
 
@@ -6137,10 +5122,10 @@
   int speccount = specpdl_depth ();
 
   record_unwind_protect (save_window_excursion_unwind,
-			 Fcurrent_window_configuration (Qnil));
+			 call1 (Qcurrent_window_configuration, Qnil));
   return unbind_to_1 (speccount, Fprogn (args));
 }
-
+
 DEFUN ("current-pixel-column", Fcurrent_pixel_column, 0, 2, 0, /*
 Return the horizontal pixel position of POS in window.
 Beginning of line is column 0. This is calculated using the redisplay
@@ -6263,13 +5248,10 @@
 syms_of_window (void)
 {
   INIT_LRECORD_IMPLEMENTATION (window);
-  INIT_LRECORD_IMPLEMENTATION (window_configuration);
   INIT_LRECORD_IMPLEMENTATION (window_mirror);
 
   DEFSYMBOL (Qwindowp);
   DEFSYMBOL (Qwindow_live_p);
-  DEFSYMBOL_MULTIWORD_PREDICATE (Qwindow_configurationp);
-  DEFSYMBOL (Qtemp_buffer_show_hook);
   DEFSYMBOL (Qdisplay_buffer);
 
 #ifdef MEMORY_USAGE_STATS
@@ -6284,6 +5266,8 @@
 #endif
 
   DEFSYMBOL (Qtruncate_partial_width_windows);
+  DEFSYMBOL (Qcurrent_window_configuration);
+  DEFSYMBOL (Qset_window_configuration);
   
   DEFSUBR (Fselected_window);
   DEFSUBR (Flast_nonminibuf_window);
@@ -6363,9 +5347,6 @@
 #ifdef MEMORY_USAGE_STATS
   DEFSUBR (Fwindow_memory_usage);
 #endif
-  DEFSUBR (Fwindow_configuration_p);
-  DEFSUBR (Fset_window_configuration);
-  DEFSUBR (Fcurrent_window_configuration);
   DEFSUBR (Fsave_window_excursion);
   DEFSUBR (Fcurrent_pixel_column);
 }
@@ -6373,18 +5354,9 @@
 void
 reinit_vars_of_window (void)
 {
-  int i;
   /* Make sure all windows get marked */
   minibuf_window = Qnil;
   staticpro_nodump (&minibuf_window);
-
-  for (i = 0; i < countof (Vwindow_configuration_free_list); i++)
-    {
-      Vwindow_configuration_free_list[i] =
-	make_lcrecord_list (sizeof_window_config_for_n_windows (i + 1),
-			    &lrecord_window_configuration);
-      staticpro_nodump (&Vwindow_configuration_free_list[i]);
-    }
 }
 
 void
@@ -6397,11 +5369,6 @@
 */ );
   scroll_on_clipped_lines = 1;
 
-  DEFVAR_LISP ("temp-buffer-show-hook", &Vtemp_buffer_show_hook /*
-See `temp-buffer-show-function'.
-*/ );
-  Vtemp_buffer_show_hook = Qnil;
-
   DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function /*
 Non-nil means call as function to display a help buffer.
 The function is called with one argument, the buffer to be displayed.
--- a/src/window.h	Sat Dec 07 22:54:03 2002 +0000
+++ b/src/window.h	Sun Dec 08 10:25:14 2002 +0000
@@ -104,9 +104,9 @@
 EXFUN (Fwindow_highest_p, 1);
 EXFUN (Fwindow_point, 1);
 EXFUN (Fwindow_start, 1);
-EXFUN (Fcurrent_window_configuration, 1);
 
 Lisp_Object save_window_excursion_unwind (Lisp_Object);
+extern Lisp_Object Qcurrent_window_configuration, Qset_window_configuration;
 Lisp_Object display_buffer (Lisp_Object, Lisp_Object, Lisp_Object);
 
 /* The minibuffer window of the selected frame.