*** empty log message ***
[bpt/emacs.git] / src / window.c
index e50a9bc..9ea7866 100644 (file)
@@ -480,9 +480,13 @@ DEFUN ("window-end", Fwindow_end, Swindow_end, 0, 1, 0,
 {
   Lisp_Object value;
   struct window *w = decode_window (window);
-  
+  Lisp_Object buf;
+
+  buf = w->buffer;
+  CHECK_BUFFER (buf, 0);
+
   XSET (value, Lisp_Int,
-       BUF_Z (current_buffer) - XFASTINT (w->window_end_pos));
+       BUF_Z (XBUFFER (buf)) - XFASTINT (w->window_end_pos));
 
   return value;
 }
@@ -700,9 +704,22 @@ DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "",
 
   /* Are we trying to delete any frame's selected window?  */
   {
-    FRAME_PTR frame = WINDOW_FRAME (XWINDOW (window));
+    Lisp_Object frame, pwindow;
 
-    if (EQ (window, FRAME_SELECTED_WINDOW (frame)))
+    /* See if the frame's selected window is either WINDOW
+       or any subwindow of it, by finding all that window's parents
+       and comparing each one with WINDOW.  */
+    frame = WINDOW_FRAME (XWINDOW (window));
+    pwindow = FRAME_SELECTED_WINDOW (XFRAME (frame));
+
+    while (!NILP (pwindow))
+      {
+       if (EQ (window, pwindow))
+         break;
+       pwindow = XWINDOW (pwindow)->parent;
+      }
+
+    if (EQ (window, pwindow))
       {
        Lisp_Object alternative = Fnext_window (window, Qlambda, Qnil);
 
@@ -714,7 +731,7 @@ DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "",
        if (EQ (window, selected_window))
          Fselect_window (alternative);
        else
-         FRAME_SELECTED_WINDOW (frame) = alternative;
+         FRAME_SELECTED_WINDOW (XFRAME (frame)) = alternative;
       }
   }
 
@@ -788,7 +805,11 @@ DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "",
 
 extern Lisp_Object next_frame (), prev_frame ();
 
-DEFUN ("next-window", Fnext_window, Snext_window, 0, 3, 0,
+/* This comment supplies the doc string for `next-window',
+   for make-docfile to see.  We cannot put this in the real DEFUN
+   due to limits in the Unix cpp.
+
+DEFUN ("next-window", Ffoo, Sfoo, 0, 3, 0,
   "Return next window after WINDOW in canonical ordering of windows.\n\
 If omitted, WINDOW defaults to the selected window.\n\
 \n\
@@ -811,6 +832,10 @@ If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
 `next-window' to iterate through the entire cycle of acceptable\n\
 windows, eventually ending up back at the window you started with.\n\
 `previous-window' traverses the same cycle, in the reverse order.")
+  (window, minibuf, all_frames) */
+
+DEFUN ("next-window", Fnext_window, Snext_window, 0, 3, 0,
+       0)
   (window, minibuf, all_frames)
      register Lisp_Object window, minibuf, all_frames;
 {
@@ -892,7 +917,11 @@ windows, eventually ending up back at the window you started with.\n\
   return window;
 }
 
-DEFUN ("previous-window", Fprevious_window, Sprevious_window, 0, 3, 0,
+/* This comment supplies the doc string for `previous-window',
+   for make-docfile to see.  We cannot put this in the real DEFUN
+   due to limits in the Unix cpp.
+
+DEFUN ("previous-window", Ffoo, Sfoo, 0, 3, 0,
   "Return the window preceeding WINDOW in canonical ordering of windows.\n\
 If omitted, WINDOW defaults to the selected window.\n\
 \n\
@@ -916,6 +945,11 @@ If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
 `previous-window' to iterate through the entire cycle of acceptable\n\
 windows, eventually ending up back at the window you started with.\n\
 `next-window' traverses the same cycle, in the reverse order.")
+  (window, minibuf, all_frames)  */
+
+
+DEFUN ("previous-window", Fprevious_window, Sprevious_window, 0, 3, 0,
+       0)
   (window, minibuf, all_frames)
      register Lisp_Object window, minibuf, all_frames;
 {
@@ -1044,8 +1078,9 @@ argument ALL_FRAMES is non-nil, cycle through all frames.")
 \f
 /* Look at all windows, performing an operation specified by TYPE
    with argument OBJ.
-   If FRAMES is Qt, look at all frames, if Qnil, look at just the selected
-   frame.  If FRAMES is a frame, just look at windows on that frame.
+   If FRAMES is Qt, look at all frames;
+                Qnil, look at just the selected frame;
+               a frame, just look at windows on that frame.
    If MINI is non-zero, perform the operation on minibuffer windows too.
 */
 
@@ -1057,7 +1092,7 @@ enum window_loop
   DELETE_OTHER_WINDOWS,                /* Arg is window not to delete */
   DELETE_BUFFER_WINDOWS,       /* Arg is buffer */
   GET_LARGEST_WINDOW,
-  UNSHOW_BUFFER,               /* Arg is buffer */
+  UNSHOW_BUFFER                /* Arg is buffer */
 };
 
 static Lisp_Object
@@ -1113,6 +1148,8 @@ window_loop (type, obj, mini, frames)
   best_window = Qnil;
   for (;;)
     {
+      FRAME_PTR w_frame = XFRAME (WINDOW_FRAME (XWINDOW (w)));
+
       /* Pick the next window now, since some operations will delete
         the current window.  */
 #ifdef MULTI_FRAME
@@ -1124,17 +1161,15 @@ window_loop (type, obj, mini, frames)
           Or we know this isn't a MULTI_FRAME Emacs, so who cares?  */
        next_window = Fnext_window (w, mini ? Qt : Qnil, Qt);
 
-      if (!MINI_WINDOW_P (XWINDOW (w))
+      if (! MINI_WINDOW_P (XWINDOW (w))
          || (mini && minibuf_level > 0))
        switch (type)
          {
          case GET_BUFFER_WINDOW:
-#if 0
            /* Ignore invisible and iconified frames.  */
-           if (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (w))))
-               || FRAME_ICONIFIED_P (XFRAME (WINDOW_FRAME (XWINDOW (w)))))
+           if (! FRAME_VISIBLE_P (w_frame)
+               || FRAME_ICONIFIED_P (w_frame))
              break;
-#endif
            if (XBUFFER (XWINDOW (w)->buffer) == XBUFFER (obj))
              return w;
            break;
@@ -1259,8 +1294,9 @@ frame, search only that frame.\n")
 
 DEFUN ("get-buffer-window", Fget_buffer_window, Sget_buffer_window, 1, 2, 0,
   "Return a window currently displaying BUFFER, or nil if none.\n\
-If optional argument FRAMES is t, search all frames.  If FRAME is a\n\
-frame, search only that frame.\n")
+If optional argument FRAME is t, search all visible frames.\n\
+If FRAME is nil, search only the selected frame.\n\
+If FRAME is a frame, search only that frame.\n")
   (buffer, frame)
     Lisp_Object buffer, frame;
 {
@@ -1274,13 +1310,19 @@ frame, search only that frame.\n")
 DEFUN ("delete-other-windows", Fdelete_other_windows, Sdelete_other_windows,
   0, 1, "",
   "Make WINDOW (or the selected window) fill its frame.\n\
-Only the frame WINDOW is on is affected.")
+Only the frame WINDOW is on is affected.\n\
+This function tries to reduce display jumps\n\
+by keeping the text previously visible in WINDOW\n\
+in the same place on the frame.  Doing this depends on\n\
+the value of (window-start WINDOW), so if calling this function\n\
+in a program gives strange scrolling, make sure the window-start\n\
+value is reasonable when this function is called.")
   (window)
      Lisp_Object window;
 {
   struct window *w;
-  int opoint = point;
   struct buffer *obuf = current_buffer;
+  int opoint;
   int top;
 
   if (NILP (window))
@@ -1294,25 +1336,39 @@ Only the frame WINDOW is on is affected.")
   window_loop (DELETE_OTHER_WINDOWS, window, 0, WINDOW_FRAME (w));
 
   Fset_buffer (w->buffer);
+  opoint = point;
   SET_PT (marker_position (w->start));
   Frecenter (make_number (top - FRAME_MENU_BAR_LINES (XFRAME (WINDOW_FRAME (w)))));
 
-  set_buffer_internal (obuf);
   SET_PT (opoint);
+  set_buffer_internal (obuf);
   return Qnil;
 }
 
 DEFUN ("delete-windows-on", Fdelete_windows_on, Sdelete_windows_on,
   1, 1, "bDelete windows on (buffer): ",
-  "Delete all windows showing BUFFER.")
-  (buffer)
-     Lisp_Object buffer;
+  "Delete all windows showing BUFFER.\n\
+Optional second argument FRAME controls which frames are affected.\n\
+If nil or omitted, delete all windows showing BUFFER in any frame.\n\
+If t, delete only windows showing BUFFER in the selected frame.\n\
+If a frame, delete only windows showing BUFFER in that frame.")
+  (buffer, frame)
+     Lisp_Object buffer, frame;
 {
+#ifdef MULTI_FRAME
+  /* FRAME uses t and nil to mean the opposite of what window_loop
+     expects.  */
+  if (! FRAMEP (frame))
+    frame = NILP (frame) ? Qt : Qnil;
+#else
+  frame = Qt;
+#endif
+
   if (!NILP (buffer))
     {
       buffer = Fget_buffer (buffer);
       CHECK_BUFFER (buffer, 0);
-      window_loop (DELETE_BUFFER_WINDOWS, buffer, 0, Qt);
+      window_loop (DELETE_BUFFER_WINDOWS, buffer, 0, frame);
     }
   return Qnil;
 }
@@ -1360,13 +1416,16 @@ check_frame_size (frame, rows, cols)
      FRAME_PTR frame;
      int *rows, *cols;
 {
-  /* For height, we have to see whether the frame has a minibuffer, and
-     whether it wants a mode line.  */
+  /* For height, we have to see:
+     whether the frame has a minibuffer, 
+     whether it wants a mode line, and
+     whether it has a menu bar.  */
   int min_height =
-    ((FRAME_MINIBUF_ONLY_P (frame)
-      || ! FRAME_HAS_MINIBUF_P (frame))
-     ? MIN_SAFE_WINDOW_HEIGHT
+    (FRAME_MINIBUF_ONLY_P (frame) ? MIN_SAFE_WINDOW_HEIGHT - 1
+     : (! FRAME_HAS_MINIBUF_P (frame)) ? MIN_SAFE_WINDOW_HEIGHT
      : 2 * MIN_SAFE_WINDOW_HEIGHT - 1);
+  if (FRAME_MENU_BAR_LINES (frame) > 0)
+    min_height += FRAME_MENU_BAR_LINES (frame);
 
   if (*rows < min_height)
     *rows = min_height;
@@ -1531,6 +1590,8 @@ BUFFER can be a buffer or buffer name.")
     }
 
   w->buffer = buffer;
+  w->window_end_pos = 0;
+  w->window_end_valid = Qnil;
   w->hscroll = 0;
   Fset_marker (w->pointm,
               make_number (BUF_PT (XBUFFER (buffer))),