Contents in latest XEmacs 21.2 at 1999-06-24-19.
[chise/xemacs-chise.git.1] / src / window.c
index 63a9aca..90c1be3 100644 (file)
@@ -36,6 +36,7 @@ Boston, MA 02111-1307, USA.  */
 #include "glyphs.h"
 #include "redisplay.h"
 #include "window.h"
+#include "elhash.h"
 #include "commands.h"
 
 Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configurationp;
@@ -136,36 +137,38 @@ do {                                              \
 
 \f
 #define MARK_DISP_VARIABLE(field)              \
-  ((markobj) (window->field[CURRENT_DISP]));   \
-  ((markobj) (window->field[DESIRED_DISP]));   \
-  ((markobj) (window->field[CMOTION_DISP]));
+  markobj (window->field[CURRENT_DISP]);       \
+  markobj (window->field[DESIRED_DISP]);       \
+  markobj (window->field[CMOTION_DISP]);
 
 static Lisp_Object
 mark_window (Lisp_Object obj, void (*markobj) (Lisp_Object))
 {
   struct window *window = XWINDOW (obj);
-  ((markobj) (window->frame));
-  ((markobj) (window->mini_p));
-  ((markobj) (window->next));
-  ((markobj) (window->prev));
-  ((markobj) (window->hchild));
-  ((markobj) (window->vchild));
-  ((markobj) (window->parent));
-  ((markobj) (window->buffer));
+  markobj (window->frame);
+  markobj (window->mini_p);
+  markobj (window->next);
+  markobj (window->prev);
+  markobj (window->hchild);
+  markobj (window->vchild);
+  markobj (window->parent);
+  markobj (window->buffer);
   MARK_DISP_VARIABLE (start);
   MARK_DISP_VARIABLE (pointm);
-  ((markobj) (window->sb_point));      /* #### move to scrollbar.c? */
-  ((markobj) (window->use_time));
+  markobj (window->sb_point);  /* #### move to scrollbar.c? */
+  markobj (window->use_time);
   MARK_DISP_VARIABLE (last_modified);
   MARK_DISP_VARIABLE (last_point);
   MARK_DISP_VARIABLE (last_start);
   MARK_DISP_VARIABLE (last_facechange);
-  ((markobj) (window->line_cache_last_updated));
-  ((markobj) (window->redisplay_end_trigger));
+  markobj (window->line_cache_last_updated);
+  markobj (window->redisplay_end_trigger);
+  markobj (window->subwindow_instance_cache);
+
   mark_face_cachels (window->face_cachels, markobj);
   mark_glyph_cachels (window->glyph_cachels, markobj);
 
-#define WINDOW_SLOT(slot, compare) ((markobj) (window->slot))
+#define WINDOW_SLOT(slot, compare) ((void) (markobj (window->slot)))
 #include "winslots.h"
 
   return Qnil;
@@ -228,7 +231,7 @@ finalize_window (void *header, int for_disksave)
 
 DEFINE_LRECORD_IMPLEMENTATION ("window", window,
                                mark_window, print_window, finalize_window,
-                              0, 0, struct window);
+                              0, 0, 0, struct window);
 
 
 #define INIT_DISP_VARIABLE(field, initialization)      \
@@ -249,7 +252,7 @@ Lisp_Object
 allocate_window (void)
 {
   Lisp_Object val;
-  struct window *p = alloc_lcrecord_type (struct window, lrecord_window);
+  struct window *p = alloc_lcrecord_type (struct window, &lrecord_window);
 
   zero_lcrecord (p);
   XSETWINDOW (val, p);
@@ -274,6 +277,9 @@ allocate_window (void)
   p->face_cachels     = Dynarr_new (face_cachel);
   p->glyph_cachels    = Dynarr_new (glyph_cachel);
   p->line_start_cache = Dynarr_new (line_start_cache);
+  p->subwindow_instance_cache = make_lisp_hash_table (10,
+                                                     HASH_TABLE_KEY_WEAK,
+                                                     HASH_TABLE_EQ);
   p->line_cache_last_updated = Qzero;
   INIT_DISP_VARIABLE (last_point_x, 0);
   INIT_DISP_VARIABLE (last_point_y, 0);
@@ -385,23 +391,21 @@ static Lisp_Object
 real_window_internal (Lisp_Object win, struct window_mirror *rmir,
                      struct window_mirror *mir)
 {
-  Lisp_Object retval;
-
   for (; !NILP (win) && rmir ; win = XWINDOW (win)->next, rmir = rmir->next)
     {
       if (mir == rmir)
        return win;
       if (!NILP (XWINDOW (win)->vchild))
        {
-         retval = real_window_internal (XWINDOW (win)->vchild, rmir->vchild,
-                                        mir);
+         Lisp_Object retval =
+           real_window_internal (XWINDOW (win)->vchild, rmir->vchild, mir);
          if (!NILP (retval))
            return retval;
        }
       if (!NILP (XWINDOW (win)->hchild))
        {
-         retval = real_window_internal (XWINDOW (win)->hchild, rmir->hchild,
-                                        mir);
+         Lisp_Object retval =
+           real_window_internal (XWINDOW (win)->hchild, rmir->hchild, mir);
          if (!NILP (retval))
            return retval;
        }
@@ -746,7 +750,7 @@ window_needs_vertical_divider_1 (struct window *w)
     return 1;
 
 #ifdef HAVE_SCROLLBARS
-  /* Our right scrollabr is enough to separate us at the right */
+  /* Our right scrollbar is enough to separate us at the right */
   if (NILP (w->scrollbar_on_left_p)
       && !NILP (w->vertical_scrollbar_visible_p)
       && !ZEROP (w->scrollbar_width))
@@ -785,7 +789,7 @@ invalidate_vertical_divider_cache_in_window (struct window *w,
 /* Calculate width of vertical divider, including its shadows
    and spacing. The returned value is effectively the distance
    between adjacent window edges. This function does not check
-   whether a windows needs vertival divider, so the returned 
+   whether a window needs a vertical divider, so the returned
    value is a "theoretical" one */
 int
 window_divider_width (struct window *w)
@@ -794,7 +798,7 @@ window_divider_width (struct window *w)
      will have a depressed look */
 
   if (FRAME_WIN_P (XFRAME (WINDOW_FRAME (w))))
-    return 
+    return
       XINT (w->vertical_divider_line_width)
       + 2 * XINT (w->vertical_divider_spacing)
       + 2 * abs (XINT (w->vertical_divider_shadow_thickness));
@@ -893,7 +897,7 @@ window_modeline_height (struct window *w)
                /* This should be an abort except I'm not yet 100%
                    confident that it won't ever get hit (though I
                    haven't been able to trigger it).  It is extremely
-                   unlikely to cause any noticable problem and even if
+                   unlikely to cause any noticeable problem and even if
                    it does it will be a minor display glitch. */
                /* #### Bullshit alert.  It does get hit and it causes
                    noticeable glitches.  real_current_modeline_height
@@ -1051,7 +1055,7 @@ int
 window_left_gutter_width (struct window *w, int modeline)
 {
   int gutter = window_left_toolbar_width (w);
-  
+
   if (!NILP (w->hchild) || !NILP (w->vchild))
     return 0;
 
@@ -1067,8 +1071,8 @@ window_left_gutter_width (struct window *w, int modeline)
 int
 window_right_gutter_width (struct window *w, int modeline)
 {
-  int gutter = window_left_toolbar_width (w);
-  
+  int gutter = window_right_toolbar_width (w);
+
   if (!NILP (w->hchild) || !NILP (w->vchild))
     return 0;
 
@@ -1341,7 +1345,7 @@ is non-nil, do not include space occupied by clipped lines.
   if (NILP (window))
     window = Fselected_window (Qnil);
 
-  CHECK_WINDOW (window);
+  CHECK_LIVE_WINDOW (window);
   w = XWINDOW (window);
 
   start  = marker_position (w->start[CURRENT_DISP]);
@@ -1404,7 +1408,7 @@ DEFUN ("window-text-area-pixel-width",
        Fwindow_text_area_pixel_width, 0, 1, 0, /*
 Return the width in pixels of the text-displaying portion of WINDOW.
 Unlike `window-pixel-width', the space occupied by the vertical
-scrollbar or divider, if any, is not counted.  
+scrollbar or divider, if any, is not counted.
 */
      (window))
 {
@@ -1635,7 +1639,8 @@ from overriding motion of point in order to display at this exact start.
   /* this is not right, but much easier than doing what is right. */
   /* w->start_at_line_beg = 0; */
   /* WTF is the above supposed to mean?  GE */
-  w->start_at_line_beg = beginning_of_line_p (XBUFFER (w->buffer), XINT (pos));
+  w->start_at_line_beg = beginning_of_line_p (XBUFFER (w->buffer),
+                                             marker_position (w->start[CURRENT_DISP]));
   if (NILP (noforce))
     w->force_start = 1;
   w->redo_modeline = 1;
@@ -3167,7 +3172,7 @@ BUFFER can be a buffer or buffer name.
   Fset_marker (w->sb_point, w->start[CURRENT_DISP], buffer);
   /* set start_at_line_beg correctly. GE */
   w->start_at_line_beg = beginning_of_line_p (XBUFFER (buffer),
-                                             XBUFFER (buffer)->last_window_start);  
+                                             marker_position (w->start[CURRENT_DISP]));
   w->force_start = 0;           /* Lucid fix */
   SET_LAST_MODIFIED (w, 1);
   SET_LAST_FACECHANGE (w);
@@ -3314,7 +3319,7 @@ make_dummy_parent (Lisp_Object window)
 {
   Lisp_Object new;
   struct window *o = XWINDOW (window);
-  struct window *p = alloc_lcrecord_type (struct window, lrecord_window);
+  struct window *p = alloc_lcrecord_type (struct window, &lrecord_window);
 
   XSETWINDOW (new, p);
   copy_lcrecord (p, o);
@@ -3361,7 +3366,7 @@ and put SIZE columns in the first of the pair.
   if (NILP (window))
     window = Fselected_window (Qnil);
   else
-    CHECK_WINDOW (window);
+    CHECK_LIVE_WINDOW (window);
 
   o = XWINDOW (window);
   f = XFRAME (WINDOW_FRAME (o));
@@ -3483,9 +3488,9 @@ and put SIZE columns in the first of the pair.
 \f
 
 DEFUN ("enlarge-window", Fenlarge_window, 1, 3, "_p", /*
-Make the selected window ARG lines bigger.
-From program, optional second arg non-nil means grow sideways ARG columns,
-and optional third ARG specifies the window to change instead of the
+Make the selected window N lines bigger.
+From program, optional second arg SIDE non-nil means grow sideways N columns,
+and optional third arg WINDOW specifies the window to change instead of the
 selected window.
 */
        (n, side, window))
@@ -3497,9 +3502,9 @@ selected window.
 }
 
 DEFUN ("enlarge-window-pixels", Fenlarge_window_pixels, 1, 3, "_p", /*
-Make the selected window ARG pixels bigger.
-From program, optional second arg non-nil means grow sideways ARG pixels,
-and optional third ARG specifies the window to change instead of the
+Make the selected window N pixels bigger.
+From program, optional second arg SIDE non-nil means grow sideways N pixels,
+and optional third arg WINDOW specifies the window to change instead of the
 selected window.
 */
        (n, side, window))
@@ -3511,9 +3516,9 @@ selected window.
 }
 
 DEFUN ("shrink-window", Fshrink_window, 1, 3, "_p", /*
-Make the selected window ARG lines smaller.
-From program, optional second arg non-nil means shrink sideways ARG columns,
-and optional third ARG specifies the window to change instead of the
+Make the selected window N lines smaller.
+From program, optional second arg SIDE non-nil means shrink sideways N columns,
+and optional third arg WINDOW specifies the window to change instead of the
 selected window.
 */
        (n, side, window))
@@ -3525,9 +3530,9 @@ selected window.
 }
 
 DEFUN ("shrink-window-pixels", Fshrink_window_pixels, 1, 3, "_p", /*
-Make the selected window ARG pixels smaller.
-From program, optional second arg non-nil means shrink sideways ARG pixels,
-and optional third ARG specifies the window to change instead of the
+Make the selected window N pixels smaller.
+From program, optional second arg SIDE non-nil means shrink sideways N pixels,
+and optional third arg WINDOW specifies the window to change instead of the
 selected window.
 */
        (n, side, window))
@@ -3911,7 +3916,7 @@ change_window_height (struct window *win, int delta, int widthflag,
       (*setsizefun) (window, *sizep + delta1, 0);
 
       /* Squeeze out delta1 lines or columns from our parent,
-        shriking this window and siblings proportionately.
+        shrinking this window and siblings proportionately.
         This brings parent back to correct size.
         Delta1 was calculated so this makes this window the desired size,
         taking it all out of the siblings.  */
@@ -3956,7 +3961,7 @@ window_scroll (Lisp_Object window, Lisp_Object n, int direction,
     }
 
   /* Always set force_start so that redisplay_window will run
-     thw window-scroll-functions.  */
+     the window-scroll-functions.  */
   w->force_start = 1;
 
   /* #### When the fuck does this happen?  I'm so glad that history has
@@ -4129,10 +4134,10 @@ window_scroll (Lisp_Object window, Lisp_Object n, int direction,
 }
 \f
 DEFUN ("scroll-up", Fscroll_up, 0, 1, "_P", /*
-Scroll text of current window upward ARG lines; or near full screen if no ARG.
+Scroll text of current window upward N lines; or near full screen if no arg.
 A near full screen is `next-screen-context-lines' less than a full screen.
-Negative ARG means scroll downward.
-When calling from a program, supply a number as argument or nil.
+Negative N means scroll downward.
+When calling from a program, supply an integer as argument or nil.
 On attempt to scroll past end of buffer, `end-of-buffer' is signaled.
 On attempt to scroll past beginning of buffer, `beginning-of-buffer' is
 signaled.
@@ -4144,9 +4149,9 @@ signaled.
 }
 
 DEFUN ("scroll-down", Fscroll_down, 0, 1, "_P", /*
-Scroll text of current window downward ARG lines; or near full screen if no ARG.
+Scroll text of current window downward N lines; or near full screen if no arg.
 A near full screen is `next-screen-context-lines' less than a full screen.
-Negative ARG means scroll upward.
+Negative N means scroll upward.
 When calling from a program, supply a number as argument or nil.
 On attempt to scroll past end of buffer, `end-of-buffer' is signaled.
 On attempt to scroll past beginning of buffer, `beginning-of-buffer' is
@@ -4204,9 +4209,9 @@ showing that buffer is used.
  }
 
 DEFUN ("scroll-other-window", Fscroll_other_window, 0, 1, "_P", /*
-Scroll next window upward ARG lines; or near full frame if no ARG.
+Scroll next window upward N lines; or near full frame if no arg.
 The next window is the one below the current one; or the one at the top
-if the current one is at the bottom.  Negative ARG means scroll downward.
+if the current one is at the bottom.  Negative N means scroll downward.
 When calling from a program, supply a number as argument or nil.
 
 If in the minibuffer, `minibuffer-scroll-window' if non-nil
@@ -4221,37 +4226,33 @@ showing that buffer, popping the buffer up if necessary.
 }
 \f
 DEFUN ("scroll-left", Fscroll_left, 0, 1, "_P", /*
-Scroll selected window display ARG columns left.
-Default for ARG is window width minus 2.
+Scroll selected window display N columns left.
+Default for N is window width minus 2.
 */
-       (arg))
+       (n))
 {
   Lisp_Object window = Fselected_window (Qnil);
   struct window *w = XWINDOW (window);
+  int count = (NILP (n) ?
+              window_char_width (w, 0) - 2 :
+              XINT (Fprefix_numeric_value (n)));
 
-  if (NILP (arg))
-    arg = make_int (window_char_width (w, 0) - 2);
-  else
-    arg = Fprefix_numeric_value (arg);
-
-  return Fset_window_hscroll (window, make_int (w->hscroll + XINT (arg)));
+  return Fset_window_hscroll (window, make_int (w->hscroll + count));
 }
 
 DEFUN ("scroll-right", Fscroll_right, 0, 1, "_P", /*
-Scroll selected window display ARG columns right.
-Default for ARG is window width minus 2.
+Scroll selected window display N columns right.
+Default for N is window width minus 2.
 */
-       (arg))
+       (n))
 {
   Lisp_Object window = Fselected_window (Qnil);
   struct window *w = XWINDOW (window);
+  int count = (NILP (n) ?
+              window_char_width (w, 0) - 2 :
+              XINT (Fprefix_numeric_value (n)));
 
-  if (NILP (arg))
-    arg = make_int (window_char_width (w, 0) - 2);
-  else
-    arg = Fprefix_numeric_value (arg);
-
-  return Fset_window_hscroll (window, make_int (w->hscroll - XINT (arg)));
+  return Fset_window_hscroll (window, make_int (w->hscroll - count));
 }
 \f
 DEFUN ("center-to-window-line", Fcenter_to_window_line, 0, 2, "_P", /*
@@ -4303,7 +4304,7 @@ If WINDOW is nil, the selected window is used.
   if (NILP (window))
     window = Fselected_window (Qnil);
   else
-    CHECK_WINDOW (window);
+    CHECK_LIVE_WINDOW (window);
   w = XWINDOW (window);
   b = XBUFFER (w->buffer);
 
@@ -4430,7 +4431,7 @@ map_windows_1 (Lisp_Object window,
    non-zero, the mapping is halted.  Otherwise, map_windows() maps
    over all windows in F.
 
-   If MAPFUN creates or deletes windows, the behaviour is undefined.  */
+   If MAPFUN creates or deletes windows, the behavior is undefined.  */
 
 int
 map_windows (struct frame *f, int (*mapfun) (struct window *w, void *closure),
@@ -4446,7 +4447,7 @@ map_windows (struct frame *f, int (*mapfun) (struct window *w, void *closure),
        {
          int v = map_windows_1 (FRAME_ROOT_WINDOW (XFRAME (XCAR (frmcons))),
                                 mapfun, closure);
-         if (v)     
+         if (v)
            return v;
        }
     }
@@ -4464,8 +4465,8 @@ modeline_shadow_thickness_changed (Lisp_Object specifier, struct window *w,
 }
 
 static void
-vertical_divider_changed_in_window (Lisp_Object specifier, 
-                                   struct window *w, 
+vertical_divider_changed_in_window (Lisp_Object specifier,
+                                   struct window *w,
                                    Lisp_Object oldval)
 {
   MARK_WINDOWS_CHANGED (w);
@@ -4620,8 +4621,8 @@ struct saved_window
 struct window_config
 {
   struct lcrecord_header header;
-  int frame_width;
-  int frame_height;
+  /*  int frame_width; No longer needed, JV
+      int frame_height; */
 #if 0 /* FSFmacs */
   Lisp_Object selected_frame;
 #endif
@@ -4629,6 +4630,7 @@ struct window_config
   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;
@@ -4649,28 +4651,28 @@ mark_window_config (Lisp_Object obj, void (*markobj) (Lisp_Object))
 {
   struct window_config *config = XWINDOW_CONFIGURATION (obj);
   int i;
-  ((markobj) (config->current_window));
-  ((markobj) (config->current_buffer));
-  ((markobj) (config->minibuffer_scroll_window));
-  ((markobj) (config->root_window));
+  markobj (config->current_window);
+  markobj (config->current_buffer);
+  markobj (config->minibuffer_scroll_window);
+  markobj (config->root_window);
 
   for (i = 0; i < config->saved_windows_count; i++)
     {
       struct saved_window *s = SAVED_WINDOW_N (config, i);
-      ((markobj) (s->window));
-      ((markobj) (s->buffer));
-      ((markobj) (s->start));
-      ((markobj) (s->pointm));
-      ((markobj) (s->sb_point));
-      ((markobj) (s->mark));
+      markobj (s->window);
+      markobj (s->buffer);
+      markobj (s->start);
+      markobj (s->pointm);
+      markobj (s->sb_point);
+      markobj (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 */
-      ((markobj) (s->dedicated));
+      markobj (s->dedicated);
 #else
-#define WINDOW_SLOT(slot, compare) ((markobj) (s->slot))
+#define WINDOW_SLOT(slot, compare) ((void) (markobj (s->slot)))
 #include "winslots.h"
 #endif
     }
@@ -4709,7 +4711,7 @@ DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("window-configuration",
                                        window_configuration,
                                        mark_window_config,
                                        print_window_config,
-                                       0, 0, 0, sizeof_window_config,
+                                       0, 0, 0, 0, sizeof_window_config,
                                        struct window_config);
 
 
@@ -4760,9 +4762,10 @@ window_config_equal (Lisp_Object conf1, Lisp_Object conf2)
        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) &&
+       EQ (fig1->minibuffer_scroll_window, fig2->minibuffer_scroll_window)))
+       /* &&
        fig1->frame_width  == fig2->frame_width &&
-       fig1->frame_height == fig2->frame_height))
+       fig1->frame_height == fig2->frame_height)) */
     return 0;
 
   for (i = 0; i < fig1->saved_windows_count; i++)
@@ -4858,8 +4861,15 @@ by `current-window-configuration' (which see).
   struct frame *f;
   struct gcpro gcpro1;
   Lisp_Object old_window_config;
-  int previous_frame_height;
-  int previous_frame_width;
+  /*  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);
@@ -4924,6 +4934,20 @@ by `current-window-configuration' (which see).
 
       mark_windows_in_use (f, 1);
 
+#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 alot by the new "character size
+        stays constant" policy in 21.0. It leads to very wierd
+        glitches (and possibly craches when asserts are tickled).
+
+        Just changing the units doens'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
@@ -4933,7 +4957,37 @@ by `current-window-configuration' (which see).
       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_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;
@@ -5099,11 +5153,61 @@ by `current-window-configuration' (which see).
         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. */
@@ -5318,6 +5422,8 @@ its value is -not- saved.
   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
@@ -5327,11 +5433,11 @@ its value is -not- saved.
     /* More than ten windows; just allocate directly */
     config = (struct window_config *)
       alloc_lcrecord (sizeof_window_config_for_n_windows (n_windows),
-                     lrecord_window_configuration);
+                     &lrecord_window_configuration);
   XSETWINDOW_CONFIGURATION (result, config);
-
+  /*
   config->frame_width = FRAME_WIDTH (f);
-  config->frame_height = FRAME_HEIGHT (f);
+  config->frame_height = FRAME_HEIGHT (f); */
   config->current_window = FRAME_SELECTED_WINDOW (f);
   XSETBUFFER (config->current_buffer, current_buffer);
   config->minibuffer_scroll_window = Vminibuffer_scroll_window;
@@ -5340,6 +5446,22 @@ its value is -not- saved.
   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 */
+  
+  XSETFRAME (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;
 }
 
@@ -5576,7 +5698,7 @@ If non-nil, this is a buffer and \\[scroll-other-window] should scroll its windo
       {
        Vwindow_configuration_free_list[i] =
          make_lcrecord_list (sizeof_window_config_for_n_windows (i + 1),
-                             lrecord_window_configuration);
+                             &lrecord_window_configuration);
        staticpro (&Vwindow_configuration_free_list[i]);
       }
   }
@@ -5604,7 +5726,7 @@ This is a specifier; use `set-specifier' to change it.
                                      modeline_shadow_thickness),
                         modeline_shadow_thickness_changed,
                         0, 0);
-  
+
   DEFVAR_SPECIFIER ("has-modeline-p", &Vhas_modeline_p /*
 *Whether the modeline should be displayed.
 This is a specifier; use `set-specifier' to change it.
@@ -5642,7 +5764,7 @@ This is a specifier; use `set-specifier' to change it.
                         0, 0);
 
   DEFVAR_SPECIFIER ("vertical-divider-shadow-thickness", &Vvertical_divider_shadow_thickness /*
-*How thick to draw 3D shadows around vertical dividers. 
+*How thick to draw 3D shadows around vertical dividers.
 This is a specifier; use `set-specifier' to change it.
 */ );
   Vvertical_divider_shadow_thickness = Fmake_specifier (Qinteger);
@@ -5670,7 +5792,7 @@ This is a specifier; use `set-specifier' to change it.
   {
     Lisp_Object fb = Qnil;
 #ifdef HAVE_TTY
-    fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
+    fb = Fcons (Fcons (list1 (Qtty), make_int (1)), fb);
 #endif
 #ifdef HAVE_X_WINDOWS
     fb = Fcons (Fcons (list1 (Qx), make_int (3)), fb);