diff src/window.c @ 404:2f8bb876ab1d r21-2-32

Import from CVS: tag r21-2-32
author cvs
date Mon, 13 Aug 2007 11:16:07 +0200
parents a86b2b5e0111
children 501cfd01ee6d
line wrap: on
line diff
--- a/src/window.c	Mon Aug 13 11:15:00 2007 +0200
+++ b/src/window.c	Mon Aug 13 11:16:07 2007 +0200
@@ -290,6 +290,11 @@
   INIT_DISP_VARIABLE (window_end_pos, 0);
   p->redisplay_end_trigger = Qnil;
 
+  p->gutter_extent_modiff[0] = 0;
+  p->gutter_extent_modiff[1] = 0;
+  p->gutter_extent_modiff[2] = 0;
+  p->gutter_extent_modiff[3] = 0;
+
 #define WINDOW_SLOT(slot, compare) p->slot = Qnil
 #include "winslots.h"
 
@@ -1010,31 +1015,35 @@
  relative to the frame, not the window.
  ****************************************************************************/
 
+static int
+window_top_window_gutter_height (struct window *w)
+{
+  if (!NILP (w->hchild) || !NILP (w->vchild))
+    return 0;
+  
+#ifdef HAVE_SCROLLBARS
+  if (!NILP (w->scrollbar_on_top_p))
+    return window_scrollbar_height (w);
+  else
+#endif
+    return 0;
+}
+
 int
 window_top_gutter_height (struct window *w)
 {
-  int gutter = WINDOW_REAL_TOP_GUTTER_BOUNDS (w);
+  return window_top_window_gutter_height (w);
+}
+
+static int
+window_bottom_window_gutter_height (struct window *w)
+{
+  int gutter;
 
   if (!NILP (w->hchild) || !NILP (w->vchild))
     return 0;
 
-#ifdef HAVE_SCROLLBARS
-  if (!NILP (w->scrollbar_on_top_p))
-    return window_scrollbar_height (w) + gutter;
-  else
-#endif
-    return gutter;
-}
-
-int
-window_bottom_gutter_height (struct window *w)
-{
-  int gutter = WINDOW_REAL_BOTTOM_GUTTER_BOUNDS (w);
-
-  if (!NILP (w->hchild) || !NILP (w->vchild))
-    return 0;
-
-  gutter += window_modeline_height (w);
+  gutter = window_modeline_height (w);
 
 #ifdef HAVE_SCROLLBARS
   if (NILP (w->scrollbar_on_top_p))
@@ -1045,25 +1054,35 @@
 }
 
 int
-window_left_gutter_width (struct window *w, int modeline)
-{
-  int gutter = WINDOW_REAL_LEFT_GUTTER_BOUNDS (w);
-
+window_bottom_gutter_height (struct window *w)
+{
+  return window_bottom_window_gutter_height (w);
+}
+
+static int
+window_left_window_gutter_width (struct window *w, int modeline)
+{
   if (!NILP (w->hchild) || !NILP (w->vchild))
     return 0;
 
 #ifdef HAVE_SCROLLBARS
   if (!modeline && !NILP (w->scrollbar_on_left_p))
-    gutter += window_scrollbar_width (w);
+    return window_scrollbar_width (w);
 #endif
 
-  return gutter;
+  return 0;
 }
 
 int
-window_right_gutter_width (struct window *w, int modeline)
-{
-  int gutter = WINDOW_REAL_RIGHT_GUTTER_BOUNDS (w);
+window_left_gutter_width (struct window *w, int modeline)
+{
+  return window_left_window_gutter_width (w, modeline);
+}
+
+static int
+window_right_window_gutter_width (struct window *w, int modeline)
+{
+  int gutter = 0;
 
   if (!NILP (w->hchild) || !NILP (w->vchild))
     return 0;
@@ -1079,6 +1098,18 @@
   return gutter;
 }
 
+int
+window_right_gutter_width (struct window *w, int modeline)
+{
+  return window_right_window_gutter_width (w, modeline);
+}
+
+static int
+window_pixel_height (struct window* w)
+{
+  return WINDOW_HEIGHT (w);
+}
+
 
 DEFUN ("windowp", Fwindowp, 1, 1, 0, /*
 Return t if OBJ is a window.
@@ -1294,6 +1325,22 @@
 Use `window-height' to get consistent results in geometry calculations.
 Use `window-displayed-height' to get the actual number of lines
 currently displayed in a window.
+
+The names are somewhat confusing; here's a table to help out:
+
+                    width                         height               
+-------------------------------------------------------------------------
+w/o gutters
+  (rows/columns)    window-width                  window-text-area-height
+  (pixels)          window-text-area-pixel-width  window-text-area-pixel-height
+
+with gutters
+  (rows/columns)    window-full-width             window-height
+  (pixels)          window-pixel-width            window-pixel-height
+
+actually displayed
+  (rows/columns)    ----                          window-displayed-height
+  (pixels)          ----                     window-displayed-text-pixel-height
 */
        (window))
 {
@@ -1320,7 +1367,20 @@
 */
        (window))
 {
-  return make_int (decode_window (window)->pixel_height);
+  return make_int (window_pixel_height (decode_window (window)));
+}
+
+DEFUN ("window-text-area-height", Fwindow_text_area_height, 0, 1, 0, /*
+Return the number of default lines in the text area of WINDOW.
+This actually works by dividing the window's text area pixel height (i.e.
+excluding the modeline and horizontal scrollbar, if any) by the height of the
+default font; therefore, the number of displayed lines will probably
+be different.
+See also `window-height' and `window-displayed-height'.
+*/
+       (window))
+{
+  return make_int (window_char_height (decode_window (window), 0));
 }
 
 DEFUN ("window-text-area-pixel-height",
@@ -1401,13 +1461,25 @@
 
 DEFUN ("window-width", Fwindow_width, 0, 1, 0, /*
 Return the number of display columns in WINDOW.
-This is the width that is usable columns available for text in WINDOW.
+This is the width that is usable columns available for text in WINDOW,
+and does not include vertical scrollbars, dividers, or the like.  See also
+`window-full-width' and `window-height'.
 */
        (window))
 {
   return make_int (window_char_width (decode_window (window), 0));
 }
 
+DEFUN ("window-full-width", Fwindow_full_width, 0, 1, 0, /*
+Return the total number of columns in WINDOW.
+This is like `window-width' but includes vertical scrollbars, dividers,
+etc.
+*/
+       (window))
+{
+  return make_int (window_char_width (decode_window (window), 1));
+}
+
 DEFUN ("window-pixel-width", Fwindow_pixel_width, 0, 1, 0, /*
 Return the width of WINDOW in pixels.  Defaults to current window.
 */
@@ -1526,15 +1598,14 @@
 DEFUN ("window-pixel-edges", Fwindow_pixel_edges, 0, 1, 0, /*
 Return a list of the pixel edge coordinates of WINDOW.
 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.
-The frame toolbars and menubars are considered to be outside of this area.
+The frame toolbars, menubars and gutters are considered to be outside of this area.
 */
        (window))
 {
   struct window *w = decode_window (window);
-  struct frame *f = XFRAME (w->frame);
-
-  int left = w->pixel_left - FRAME_LEFT_BORDER_END (f);
-  int top  = w->pixel_top  - FRAME_TOP_BORDER_END  (f);
+
+  int left = w->pixel_left;
+  int top  = w->pixel_top;
 
   return list4 (make_int (left),
 		make_int (top),
@@ -3277,8 +3348,9 @@
   /* we have already caught dead-window errors */
   if (!NILP (w->hchild) || !NILP (w->vchild))
     error ("Trying to select non-leaf window");
-
+  
   w->use_time = make_int (++window_select_count);
+
   if (EQ (window, old_selected_window))
     return window;
 
@@ -3402,6 +3474,10 @@
   p->line_start_cache = Dynarr_new (line_start_cache);
   p->face_cachels     = Dynarr_new (face_cachel);
   p->glyph_cachels    = Dynarr_new (glyph_cachel);
+  p->subwindow_instance_cache = 
+    make_lisp_hash_table (10,
+			  HASH_TABLE_KEY_WEAK,
+			  HASH_TABLE_EQ);
 
   /* Put new into window structure in place of window */
   replace_window (window, new);
@@ -3617,12 +3693,6 @@
 }
 
 static int
-window_pixel_height (Lisp_Object window)
-{
-  return WINDOW_HEIGHT (XWINDOW (window));
-}
-
-static int
 window_pixel_height_to_char_height (struct window *w, int pixel_height,
 				    int include_gutters_p)
 {
@@ -3635,8 +3705,8 @@
 
   avail_height = (pixel_height -
 		  (include_gutters_p ? 0 :
-		   window_top_gutter_height (w) +
-		   window_bottom_gutter_height (w)));
+		   window_top_window_gutter_height (w) +
+		   window_bottom_window_gutter_height (w)));
 
   default_face_height_and_width (window, &defheight, &defwidth);
 
@@ -3667,8 +3737,8 @@
   avail_height = char_height * defheight;
   pixel_height = (avail_height +
 		  (include_gutters_p ? 0 :
-		   window_top_gutter_height (w) +
-		   window_bottom_gutter_height (w)));
+		   window_top_window_gutter_height (w) +
+		   window_bottom_window_gutter_height (w)));
 
   /* It's the calling function's responsibility to check these values
      and make sure they're not out of range.
@@ -3681,11 +3751,12 @@
 /* Return number of default lines of text can fit in the window W.
    If INCLUDE_GUTTERS_P is 1, include "gutter" space (modeline plus
    horizontal scrollbar) in the space that is used for the calculation.
+   This doesn't include space used by the frame gutters.
    */
 int
 window_char_height (struct window *w, int include_gutters_p)
 {
-  return window_pixel_height_to_char_height (w, WINDOW_HEIGHT (w),
+  return window_pixel_height_to_char_height (w, window_pixel_height (w),
 					     include_gutters_p);
 }
 
@@ -3765,6 +3836,8 @@
   return WINDOW_WIDTH (XWINDOW (window));
 }
 
+/* Calculate the pixel of a window, optionally including margin space
+   but no vertical gutters. */
 static int
 window_pixel_width_to_char_width (struct window *w, int pixel_width,
 				  int include_margins_p)
@@ -3809,8 +3882,8 @@
 
   avail_width = char_width * defwidth;
   pixel_width = (avail_width +
-		 window_left_gutter_width (w, 0) +
-		 window_right_gutter_width (w, 0) +
+		 window_left_window_gutter_width (w, 0) +
+		 window_right_window_gutter_width (w, 0) +
 		 (include_margins_p ? 0 : window_left_margin_width (w)) +
 		 (include_margins_p ? 0 : window_right_margin_width (w)));
 
@@ -3849,6 +3922,12 @@
   (widthflag ? window_min_width : MINI_WINDOW_P (XWINDOW (window)) \
    ? 1 : window_min_height)
 
+static int
+window_pixheight (Lisp_Object w)
+{
+  return window_pixel_height (XWINDOW (w));
+}
+
 /* Unlike set_window_pixheight, this function
    also changes the heights of the siblings so as to
    keep everything consistent. */
@@ -3864,7 +3943,7 @@
   int *sizep;
   int (*sizefun) (Lisp_Object) = (widthflag
 				  ? window_pixel_width
-				  : window_pixel_height);
+				  : window_pixheight);
   void (*setsizefun) (Lisp_Object, int, int) = (widthflag
 						? set_window_pixwidth
 						: set_window_pixheight);
@@ -5102,7 +5181,7 @@
 	 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).
+	 glitches (and possibly crashes when asserts are tickled).
 
 	 Just changing the units doens't help because changing the
 	 toolbar configuration can also change the pixel positions.
@@ -5175,6 +5254,10 @@
 	    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;
 
 	  if (p->parent_index >= 0)
@@ -5374,6 +5457,7 @@
 	 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
@@ -5382,15 +5466,25 @@
 	     #### Find out why this is really going wrong. */
 	  if (!minibuf_level &&
 	      MINI_WINDOW_P (XWINDOW (config->current_window)))
-	    Fselect_window (Fnext_window (config->current_window,
-					  Qnil, Qnil, Qnil),
-                            Qnil);
+	    window_to_select = Fnext_window (config->current_window,
+					     Qnil, Qnil, Qnil);
 	  else
-	    Fselect_window (config->current_window, Qnil);
+	    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);
+	    {
+	      Fset_buffer (new_current_buffer);
+	      Frecord_buffer (new_current_buffer);
+	    }
 	  else
-	    Fset_buffer (XWINDOW (Fselected_window (Qnil))->buffer);
+	    {
+	      Fset_buffer (XWINDOW (config->current_window)->buffer);
+	      Frecord_buffer (XWINDOW (config->current_window)->buffer);
+	    }
 	}
       else
 	set_frame_selected_window (f, config->current_window);
@@ -5599,7 +5693,14 @@
   /*
   config->frame_width = FRAME_WIDTH (f);
   config->frame_height = FRAME_HEIGHT (f); */
-  config->current_window = FRAME_SELECTED_WINDOW (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-apropros. It seems to me the sensible
+     thing to do is not record the minibuffer here. */
+  if (FRAME_MINIBUF_ONLY_P (f) || minibuf_level)
+    config->current_window = FRAME_SELECTED_WINDOW (f);
+  else
+    config->current_window = FRAME_LAST_NONMINIBUF_WINDOW (f);
   XSETBUFFER (config->current_buffer, current_buffer);
   config->minibuffer_scroll_window = Vminibuffer_scroll_window;
   config->root_window = FRAME_ROOT_WINDOW (f);
@@ -5739,15 +5840,15 @@
     child = Fwindow_first_hchild (window);
 
   for (i = level; i > 0; i--)
-    putc ('\t', stderr);
-
-  fputs ("#<window", stderr);
+    stderr_out ("\t");
+
+  stderr_out ("#<window");
   {
     Lisp_Object buffer = XWINDOW (window)->buffer;
     if (!NILP (buffer) && BUFFERP (buffer))
-      fprintf (stderr, " on %s", XSTRING_DATA (XBUFFER (buffer)->name));
+      stderr_out (" on %s", XSTRING_DATA (XBUFFER (buffer)->name));
   }
-  fprintf (stderr, " 0x%x>", XWINDOW (window)->header.uid);
+  stderr_out (" 0x%x>", XWINDOW (window)->header.uid);
 
   while (!NILP (child))
     {
@@ -5815,8 +5916,10 @@
   DEFSUBR (Fwindow_height);
   DEFSUBR (Fwindow_displayed_height);
   DEFSUBR (Fwindow_width);
+  DEFSUBR (Fwindow_full_width);
   DEFSUBR (Fwindow_pixel_height);
   DEFSUBR (Fwindow_pixel_width);
+  DEFSUBR (Fwindow_text_area_height);
   DEFSUBR (Fwindow_text_area_pixel_height);
   DEFSUBR (Fwindow_displayed_text_pixel_height);
   DEFSUBR (Fwindow_text_area_pixel_width);