(START_FILES, LIB_STANDARD): Adjust value according to HAVE_X86_64_LIB64_DIR.
[bpt/emacs.git] / src / window.c
index adb384b..57452b3 100644 (file)
@@ -1,13 +1,14 @@
 /* Window creation, deletion and examination for GNU Emacs.
    Does not include redisplay.
    Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
-                 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+                 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -62,6 +63,7 @@ static void window_scroll P_ ((Lisp_Object, int, int, int));
 static void window_scroll_pixel_based P_ ((Lisp_Object, int, int, int));
 static void window_scroll_line_based P_ ((Lisp_Object, int, int, int));
 static int window_min_size_1 P_ ((struct window *, int));
+static int window_min_size_2 P_ ((struct window *, int));
 static int window_min_size P_ ((struct window *, int, int, int *));
 static void size_window P_ ((Lisp_Object, int, int, int, int, int));
 static int freeze_window_start P_ ((struct window *, void *));
@@ -333,6 +335,7 @@ Return nil if that position is scrolled vertically out of view.
 If a character is only partially visible, nil is returned, unless the
 optional argument PARTIALLY is non-nil.
 If POS is only out of view because of horizontal scrolling, return non-nil.
+If POS is t, it specifies the position of the last visible glyph in WINDOW.
 POS defaults to point in WINDOW; WINDOW defaults to the selected window.
 
 If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil,
@@ -340,7 +343,7 @@ return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]),
 where X and Y are the pixel coordinates relative to the top left corner
 of the window.  The remaining elements are omitted if the character after
 POS is fully visible; otherwise, RTOP and RBOT are the number of pixels
-off-screen at the top and bottom of the row, ROWH is the height of the
+off-window at the top and bottom of the row, ROWH is the height of the
 display row, and VPOS is the row number (0-based) containing POS.  */)
      (pos, window, partially)
      Lisp_Object pos, window, partially;
@@ -357,7 +360,9 @@ display row, and VPOS is the row number (0-based) containing POS.  */)
   buf = XBUFFER (w->buffer);
   SET_TEXT_POS_FROM_MARKER (top, w->start);
 
-  if (!NILP (pos))
+  if (EQ (pos, Qt))
+    posint = -1;
+  else if (!NILP (pos))
     {
       CHECK_NUMBER_COERCE_MARKER (pos);
       posint = XINT (pos);
@@ -369,8 +374,8 @@ display row, and VPOS is the row number (0-based) containing POS.  */)
 
   /* If position is above window start or outside buffer boundaries,
      or if window start is out of range, position is not visible.  */
-  if (posint >= CHARPOS (top)
-      && posint <= BUF_ZV (buf)
+  if ((EQ (pos, Qt)
+       || (posint >= CHARPOS (top) && posint <= BUF_ZV (buf)))
       && CHARPOS (top) >= BUF_BEGV (buf)
       && CHARPOS (top) <= BUF_ZV (buf)
       && pos_visible_p (w, posint, &x, &y, &rtop, &rbot, &rowh, &vpos)
@@ -402,10 +407,10 @@ counts from the end of the window.
 
 Value is a list (HEIGHT VPOS YPOS OFFBOT), where HEIGHT is the height
 in pixels of the visible part of the line, VPOS and YPOS are the
-vertical position in lines and pixels of the row, relative to the top
-of the first text line, and OFFBOT is the number of off-screen pixels at
-the bottom of the text row.  If there are off-screen pixels at the top
-of the (first) text row, YPOS is negative.
+vertical position in lines and pixels of the line, relative to the top
+of the first text line, and OFFBOT is the number of off-window pixels at
+the bottom of the text line.  If there are off-window pixels at the top
+of the (first) text line, YPOS is negative.
 
 Return nil if window display is not up-to-date.  In that case, use
 `pos-visible-in-window-p' to obtain the information.  */)
@@ -534,7 +539,8 @@ WINDOW defaults to the selected window.  */)
 }
 
 DEFUN ("window-height", Fwindow_height, Swindow_height, 0, 1, 0,
-       doc: /* Return the number of lines in WINDOW (including its mode line).  */)
+       doc: /* Return the number of lines in WINDOW (including its mode line).
+WINDOW defaults to the selected window.  */)
      (window)
      Lisp_Object window;
 {
@@ -552,8 +558,18 @@ use  (let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))).  */)
   return make_number (window_box_text_cols (decode_any_window (window)));
 }
 
+DEFUN ("window-full-width-p", Fwindow_full_width_p, Swindow_full_width_p, 0, 1, 0,
+       doc: /* Return t if WINDOW is as wide as its frame.
+WINDOW defaults to the selected window.  */)
+     (window)
+     Lisp_Object window;
+{
+  return WINDOW_FULL_WIDTH_P (decode_any_window (window)) ? Qt : Qnil;
+}
+
 DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
-       doc: /* Return the number of columns by which WINDOW is scrolled from left margin.  */)
+       doc: /* Return the number of columns by which WINDOW is scrolled from left margin.
+WINDOW defaults to the selected window.  */)
      (window)
      Lisp_Object window;
 {
@@ -565,7 +581,7 @@ DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0,
 Return NCOL.  NCOL should be zero or positive.
 
 Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
-window so that the location of point moves off-screen.  */)
+window so that the location of point moves off-window.  */)
      (window, ncol)
      Lisp_Object window, ncol;
 {
@@ -586,6 +602,7 @@ window so that the location of point moves off-screen.  */)
 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger,
        Swindow_redisplay_end_trigger, 0, 1, 0,
        doc: /* Return WINDOW's redisplay end trigger value.
+WINDOW defaults to the selected window.
 See `set-window-redisplay-end-trigger' for more information.  */)
      (window)
      Lisp_Object window;
@@ -1108,6 +1125,8 @@ column 0.  */)
 
 DEFUN ("window-point", Fwindow_point, Swindow_point, 0, 1, 0,
        doc: /* Return current value of point in WINDOW.
+WINDOW defaults to the selected window.
+
 For a nonselected window, this is the value point would have
 if that window were selected.
 
@@ -1129,6 +1148,7 @@ But that is hard to define.  */)
 
 DEFUN ("window-start", Fwindow_start, Swindow_start, 0, 1, 0,
        doc: /* Return position at which display currently starts in WINDOW.
+WINDOW defaults to the selected window.
 This is updated by redisplay or by calling `set-window-start'.  */)
      (window)
      Lisp_Object window;
@@ -1149,6 +1169,7 @@ have been if redisplay had finished, do this:
 
 DEFUN ("window-end", Fwindow_end, Swindow_end, 0, 2, 0,
        doc: /* Return position at which display currently ends in WINDOW.
+WINDOW defaults to the selected window.
 This is updated by redisplay, when it runs to completion.
 Simply changing the buffer text or setting `window-start'
 does not update this value.
@@ -1162,7 +1183,7 @@ if it isn't already recorded.  */)
   Lisp_Object value;
   struct window *w = decode_window (window);
   Lisp_Object buf;
-  struct buffer *b = XBUFFER (buf);
+  struct buffer *b;
 
   buf = w->buffer;
   CHECK_BUFFER (buf);
@@ -1179,7 +1200,8 @@ if it isn't already recorded.  */)
 
   if (! NILP (update)
       && ! (! NILP (w->window_end_valid)
-           && XFASTINT (w->last_modified) >= BUF_MODIFF (b))
+           && XFASTINT (w->last_modified) >= BUF_MODIFF (b)
+           && XFASTINT (w->last_overlay_modified) >= BUF_OVERLAY_MODIFF (b))
       && !noninteractive)
     {
       struct text_pos startp;
@@ -1298,7 +1320,8 @@ non-nil means yes. */)
 
 DEFUN ("window-display-table", Fwindow_display_table, Swindow_display_table,
        0, 1, 0,
-       doc: /* Return the display-table that WINDOW is using.  */)
+       doc: /* Return the display-table that WINDOW is using.
+WINDOW defaults to the selected window.  */)
      (window)
      Lisp_Object window;
 {
@@ -1520,7 +1543,7 @@ delete_window (window)
        if (!EQ (window, pwindow))
          break;
        /* Otherwise, try another window for SWINDOW.  */
-       swindow = Fnext_window (swindow, Qlambda, Qnil);;
+       swindow = Fnext_window (swindow, Qlambda, Qnil);
 
        /* If we get back to the frame's selected window,
           it means there was no acceptable alternative,
@@ -2302,6 +2325,8 @@ check_all_windows ()
 
 DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 2, 0,
        doc: /* Return the window least recently selected or used for display.
+\(LRU means Least Recently Used.)
+
 Return a full-width window if possible.
 A minibuffer window is never a candidate.
 A dedicated window is never a candidate, unless DEDICATED is non-nil,
@@ -2539,7 +2564,6 @@ check_frame_size (frame, rows, cols)
     *cols = MIN_SAFE_WINDOW_WIDTH;
 }
 
-
 /* Value is non-zero if window W is fixed-size.  WIDTH_P non-zero means
    check if W's width can be changed, otherwise check W's height.
    CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
@@ -2641,6 +2665,35 @@ window_fixed_size_p (w, width_p, check_siblings_p)
   return fixed_p;
 }
 
+/* Return the minimum size for leaf window W.  WIDTH_P non-zero means
+   take into account fringes and the scrollbar of W.  WIDTH_P zero means
+   take into account mode-line of W.  Return 1 for the minibuffer.  */
+
+static int
+window_min_size_2 (w, width_p)
+     struct window *w;
+     int width_p;
+{
+  int size;
+  
+  if (width_p)
+    size = max (window_min_width,
+               (MIN_SAFE_WINDOW_WIDTH
+                + WINDOW_FRINGE_COLS (w)
+                + WINDOW_SCROLL_BAR_COLS (w)));
+  else if (MINI_WINDOW_P (w))
+    size = 1;
+  else
+    size = max (window_min_height,
+               (MIN_SAFE_WINDOW_HEIGHT
+                /* Don't count the header-line here.  It would break
+                   splitting a window with a header-line when the new
+                   window shall have a height of two (calculator does
+                   that). */
+                + (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
+
+  return size;
+}
 
 /* Return the minimum size of window W, not taking fixed-width windows
    into account.  WIDTH_P non-zero means return the minimum width,
@@ -2710,22 +2763,7 @@ window_min_size_1 (w, width_p)
        }
     }
   else
-    {
-      if (width_p)
-       size = max (window_min_width,
-                   (MIN_SAFE_WINDOW_WIDTH
-                    + WINDOW_FRINGE_COLS (w)
-                    + WINDOW_SCROLL_BAR_COLS (w)));
-      else
-       {
-         if (MINI_WINDOW_P (w)
-             || (!WINDOW_WANTS_MODELINE_P (w)
-                 && !WINDOW_WANTS_HEADER_LINE_P (w)))
-           size = 1;
-         else
-           size = window_min_height;
-       }
-    }
+    size = window_min_size_2 (w, width_p);
 
   return size;
 }
@@ -2967,11 +3005,6 @@ size_window (window, size, width_p, nodelete_p, first_only, last_only)
   Lisp_Object child, *forward, *sideward;
   int old_size, min_size, safe_min_size;
 
-  /* We test nodelete_p != 2 and nodelete_p != 1 below, so it
-     seems like it's too soon to do this here.  ++KFS.  */
-  if (nodelete_p == 2)
-    nodelete_p = 0;
-
   check_min_window_sizes ();
   size = max (0, size);
 
@@ -2982,22 +3015,23 @@ size_window (window, size, width_p, nodelete_p, first_only, last_only)
     {
       old_size = WINDOW_TOTAL_COLS (w);
       min_size = window_min_width;
-      /* Ensure that there is room for the scroll bar and fringes!
-         We may reduce display margins though.  */
-      safe_min_size = (MIN_SAFE_WINDOW_WIDTH
-                      + WINDOW_FRINGE_COLS (w)
-                      + WINDOW_SCROLL_BAR_COLS (w));
+      safe_min_size = window_min_size_2 (w, 1);
     }
   else
     {
       old_size = XINT (w->total_lines);
       min_size = window_min_height;
-      safe_min_size = MIN_SAFE_WINDOW_HEIGHT;
+      safe_min_size = window_min_size_2 (w, 0);
     }
 
   if (old_size < min_size && nodelete_p != 2)
     w->too_small_ok = Qt;
 
+  /* Move the following test here since otherwise the
+     preceding test doesn't make sense.  martin. */
+  if (nodelete_p == 2)
+    nodelete_p = 0;
+
   /* Maybe delete WINDOW if it's too small.  */
   if (nodelete_p != 1 && !NILP (w->parent))
     {
@@ -3585,7 +3619,7 @@ See `same-window-buffer-names' and `same-window-regexps'.  */)
 DEFUN ("display-buffer", Fdisplay_buffer, Sdisplay_buffer, 1, 3,
        "BDisplay buffer: \nP",
        doc: /* Make BUFFER appear in some window but don't select it.
-BUFFER must  be the name of an existing buffer, or, when called from Lisp,
+BUFFER must be the name of an existing buffer, or, when called from Lisp,
 a buffer.
 If BUFFER is shown already in some window, just use that one,
 unless the window is the selected window and the optional second
@@ -3600,11 +3634,12 @@ The variables `special-display-buffer-names',
 `same-window-regexps' customize how certain buffer names are handled.
 The latter two take effect only if NOT-THIS-WINDOW is nil.
 
-If optional argument FRAME is `visible', search all visible frames.
-If FRAME is 0, search all visible and iconified frames.
-If FRAME is t, search all frames.
-If FRAME is a frame, search only that frame.
-If FRAME is nil, search only the selected frame
+If optional argument FRAME is `visible', check all visible frames
+for a window to use.
+If FRAME is 0, check all visible and iconified frames.
+If FRAME is t, check all frames.
+If FRAME is a frame, check only that frame.
+If FRAME is nil, check only the selected frame
  (actually the last nonminibuffer frame),
  unless `pop-up-frames' or `display-buffer-reuse-frames' is non-nil,
  which means search visible and iconified frames.
@@ -3693,9 +3728,6 @@ displayed.  */)
       frames = Qnil;
       if (FRAME_MINIBUF_ONLY_P (f))
        XSETFRAME (frames, last_nonminibuf_frame);
-      /* Don't try to create a window if we would get an error.  */
-      if (split_height_threshold < window_min_height << 1)
-       split_height_threshold = window_min_height << 1;
 
       /* Note that both Fget_largest_window and Fget_lru_window
         ignore minibuffers and dedicated windows.
@@ -3718,25 +3750,30 @@ displayed.  */)
       else
        window = Fget_largest_window (frames, Qt);
 
-      /* If we got a tall enough full-width window that can be split,
-        split it.  */
+      /* If the largest window is tall enough, full-width, and either eligible
+        for splitting or the only window, split it.  */
       if (!NILP (window)
          && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window)->frame))
-         && window_height (window) >= split_height_threshold
-         && WINDOW_FULL_WIDTH_P (XWINDOW (window)))
+         && WINDOW_FULL_WIDTH_P (XWINDOW (window))
+         && (window_height (window) >= split_height_threshold
+             || (NILP (XWINDOW (window)->parent)))
+         && (window_height (window)
+             >= (2 * window_min_size_2 (XWINDOW (window), 0))))
        window = Fsplit_window (window, Qnil, Qnil);
       else
        {
          Lisp_Object upper, lower, other;
 
          window = Fget_lru_window (frames, Qt);
-         /* If the LRU window is selected, and big enough,
-            and can be split, split it.  */
+         /* If the LRU window is tall enough, and either eligible for splitting
+         and selected or the only window, split it.  */
          if (!NILP (window)
              && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window)->frame))
-             && (EQ (window, selected_window)
-                 || EQ (XWINDOW (window)->parent, Qnil))
-             && window_height (window) >= window_min_height << 1)
+             && ((EQ (window, selected_window)
+                  && window_height (window) >= split_height_threshold)
+                 || (NILP (XWINDOW (window)->parent)))
+             && (window_height (window)
+                 >= (2 * window_min_size_2 (XWINDOW (window), 0))))
            window = Fsplit_window (window, Qnil, Qnil);
          else
            window = Fget_lru_window (frames, Qnil);
@@ -3985,9 +4022,11 @@ See Info node `(elisp)Splitting Windows' for more details and examples.*/)
 
   if (NILP (horflag))
     {
-      if (size_int < window_min_height)
+      int window_safe_height = window_min_size_2 (o, 0);
+      
+      if (size_int < window_safe_height)
        error ("Window height %d too small (after splitting)", size_int);
-      if (size_int + window_min_height > XFASTINT (o->total_lines))
+      if (size_int + window_safe_height > XFASTINT (o->total_lines))
        error ("Window height %d too small (after splitting)",
               XFASTINT (o->total_lines) - size_int);
       if (NILP (o->parent)
@@ -4000,10 +4039,11 @@ See Info node `(elisp)Splitting Windows' for more details and examples.*/)
     }
   else
     {
-      if (size_int < window_min_width)
+      int window_safe_width = window_min_size_2 (o, 1);
+      
+      if (size_int < window_safe_width)
        error ("Window width %d too small (after splitting)", size_int);
-
-      if (size_int + window_min_width > XFASTINT (o->total_cols))
+      if (size_int + window_safe_width > XFASTINT (o->total_cols))
        error ("Window width %d too small (after splitting)",
               XFASTINT (o->total_cols) - size_int);
       if (NILP (o->parent)
@@ -4095,8 +4135,8 @@ too small.  */)
 DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 2, "p",
        doc: /* Make current window ARG lines smaller.
 From program, optional second arg non-nil means shrink sideways arg columns.
-Interactively, if an argument is not given, make the window one line smaller.  Only
-siblings to the right or below are changed.  */)
+Interactively, if an argument is not given, make the window one line smaller.
+Only siblings to the right or below are changed.  */)
      (arg, side)
      Lisp_Object arg, side;
 {
@@ -4484,7 +4524,7 @@ adjust_window_trailing_edge (window, delta, horiz_flag)
 
       /* Don't make this window too small.  */
       if (XINT (CURSIZE (window)) + delta
-         < (horiz_flag ? window_min_width : window_min_height))
+         < window_min_size_2 (XWINDOW (window), horiz_flag))
        {
          Fset_window_configuration (old_config);
          error ("Cannot adjust window size as specified");
@@ -5711,8 +5751,10 @@ With prefix argument ARG, recenter putting point on screen line ARG
 relative to the current window.  If ARG is negative, it counts up from the
 bottom of the window.  (ARG should be less than the height of the window.)
 
-If ARG is omitted or nil, erase the entire frame and then
-redraw with point in the center of the current window.
+If ARG is omitted or nil, erase the entire frame and then redraw with point
+in the center of the current window.  If `auto-resize-tool-bars' is set to
+`grow-only', this resets the tool-bar's height to the minimum height needed.
+
 Just C-u as prefix means put point in the center of the window
 and redisplay normally--don't erase and redraw the frame.  */)
      (arg)
@@ -5737,8 +5779,10 @@ and redisplay normally--don't erase and redraw the frame.  */)
       for (i = 0; i < n_compositions; i++)
        composition_table[i]->font = NULL;
 
-      Fredraw_frame (w->frame);
-      SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w)));
+      WINDOW_XFRAME (w)->minimize_tool_bar_window_p = 1;
+
+      Fredraw_frame (WINDOW_FRAME (w));
+      SET_FRAME_GARBAGED (WINDOW_XFRAME (w));
       center_p = 1;
     }
   else if (CONSP (arg)) /* Just C-u. */
@@ -5888,6 +5932,7 @@ and redisplay normally--don't erase and redraw the frame.  */)
 DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height,
        0, 1, 0,
        doc: /* Return the height in lines of the text display area of WINDOW.
+WINDOW defaults to the selected window.
 This doesn't include the mode-line (or header-line if any) or any
 partial-height lines in the text display area.  */)
      (window)
@@ -6623,7 +6668,7 @@ and the value of point and mark for each window.
 Also restore the choice of selected window.
 Also restore which buffer is current.
 Does not restore the value of point in current buffer.
-usage: (save-window-excursion BODY ...)  */)
+usage: (save-window-excursion BODY...)  */)
      (args)
      Lisp_Object args;
 {
@@ -6877,7 +6922,7 @@ Fourth parameter HORIZONTAL-TYPE is currently unused.  */)
        vertical_type = Qnil;
     }
 
-  if (!(EQ (vertical_type, Qnil)
+  if (!(NILP (vertical_type)
        || EQ (vertical_type, Qleft)
        || EQ (vertical_type, Qright)
        || EQ (vertical_type, Qt)))
@@ -7482,6 +7527,7 @@ The selected frame is the one whose configuration has changed.  */);
   defsubr (&Swindow_buffer);
   defsubr (&Swindow_height);
   defsubr (&Swindow_width);
+  defsubr (&Swindow_full_width_p);
   defsubr (&Swindow_hscroll);
   defsubr (&Sset_window_hscroll);
   defsubr (&Swindow_redisplay_end_trigger);