(wait_reading_process_input): If wait_for_cell, do call
[bpt/emacs.git] / src / window.c
index a14599b..a9ab938 100644 (file)
@@ -1,6 +1,6 @@
 /* Window creation, deletion and examination for GNU Emacs.
    Does not include redisplay.
-   Copyright (C) 1985, 1986, 1987, 1992, 1993 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1993 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -29,7 +29,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "disptab.h"
 #include "keyboard.h"
 
-Lisp_Object Qwindowp, Qlive_window_p;
+Lisp_Object Qwindowp, Qwindow_live_p;
 
 Lisp_Object Fnext_window (), Fdelete_window (), Fselect_window ();
 Lisp_Object Fset_window_buffer (), Fsplit_window (), Frecenter ();
@@ -60,12 +60,6 @@ Lisp_Object Vminibuf_scroll_window;
 /* Non-nil means this is the buffer whose window C-M-v should scroll.  */
 Lisp_Object Vother_window_scroll_buffer;
 
-/* Window that the mouse is over (nil if no mouse support).  */
-Lisp_Object Vmouse_window;
-
-/* Last mouse click data structure (nil if no mouse support).  */
-Lisp_Object Vmouse_event;
-
 /* Non-nil means it's function to call to display temp buffers.  */
 Lisp_Object Vtemp_buffer_show_function;
 
@@ -105,7 +99,7 @@ DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0,
   return XTYPE (obj) == Lisp_Window ? Qt : Qnil;
 }
 
-DEFUN ("live-window-p", Flive_window_p, Slive_window_p, 1, 1, 0,
+DEFUN ("window-live-p", Fwindow_live_p, Swindow_live_p, 1, 1, 0,
   "Returns t if OBJ is a window which is currently visible.")
      (obj)
      Lisp_Object obj;
@@ -534,7 +528,7 @@ from overriding motion of point in order to display at this exact start.")
 DEFUN ("window-dedicated-p", Fwindow_dedicated_p, Swindow_dedicated_p,
        1, 1, 0,
   "Return WINDOW's dedicated object, usually t or nil.\n\
-See also `set-window-buffer-dedicated'.")
+See also `set-window-dedicated-p'.")
   (window)
      Lisp_Object window;
 {
@@ -706,9 +700,22 @@ DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "",
 
   /* Are we trying to delete any frame's selected window?  */
   {
-    Lisp_Object frame = WINDOW_FRAME (XWINDOW (window));
+    Lisp_Object frame, pwindow;
+
+    /* 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, FRAME_SELECTED_WINDOW (XFRAME (frame))))
+    if (EQ (window, pwindow))
       {
        Lisp_Object alternative = Fnext_window (window, Qlambda, Qnil);
 
@@ -811,7 +818,12 @@ minibuffer does not count, only windows from WINDOW's frame count.\n\
 \n\
 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
-above.  If neither nil nor t, restrict to WINDOW's frame.")
+above.  If neither nil nor t, restrict to WINDOW's frame.\n\
+\n\
+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)
      register Lisp_Object window, minibuf, all_frames;
 {
@@ -841,6 +853,9 @@ above.  If neither nil nor t, restrict to WINDOW's frame.")
                   : Qnil);
   else if (! EQ (all_frames, Qt))
     all_frames = Qnil;
+  /* Now all_frames is t meaning search all frames,
+     nil meaning search just current frame,
+     or a window, meaning search the frame that window belongs to.  */
 
   /* Do this loop at least once, to get the next window, and perhaps
      again, if we hit the minibuffer and that is not acceptable.  */
@@ -908,7 +923,12 @@ count.\n\
 \n\
 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
-above.  If neither nil nor t, restrict to WINDOW's frame.")
+above.  If neither nil nor t, restrict to WINDOW's frame.\n\
+\n\
+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)
      register Lisp_Object window, minibuf, all_frames;
 {
@@ -938,6 +958,9 @@ above.  If neither nil nor t, restrict to WINDOW's frame.")
                   : Qnil);
   else if (! EQ (all_frames, Qt))
     all_frames = Qnil;
+  /* Now all_frames is t meaning search all frames,
+     nil meaning search just current frame,
+     or a window, meaning search the frame that window belongs to.  */
 
   /* Do this loop at least once, to get the previous window, and perhaps
      again, if we hit the minibuffer and that is not acceptable.  */
@@ -955,9 +978,23 @@ above.  If neither nil nor t, restrict to WINDOW's frame.")
            tem = WINDOW_FRAME (XWINDOW (window));
 #ifdef MULTI_FRAME
            if (! NILP (all_frames))
-             tem = next_frame (tem, all_frames);
+             /* It's actually important that we use prev_frame here,
+                rather than next_frame.  All the windows acceptable
+                according to the given parameters should form a ring;
+                Fnext_window and Fprevious_window should go back and
+                forth around the ring.  If we use next_frame here,
+                then Fnext_window and Fprevious_window take different
+                paths through the set of acceptable windows.
+                window_loop assumes that these `ring' requirement are
+                met.  */
+             tem = prev_frame (tem, all_frames);
 #endif
-           tem = FRAME_ROOT_WINDOW (XFRAME (tem));
+           /* If this frame has a minibuffer, find that window first,
+              because it is conceptually the last window in that frame.  */
+           if (FRAME_HAS_MINIBUF_P (XFRAME (tem)))
+             tem = FRAME_MINIBUF_WINDOW (XFRAME (tem));
+           else
+             tem = FRAME_ROOT_WINDOW (XFRAME (tem));
 
            break;
          }
@@ -1020,8 +1057,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.
 */
 
@@ -1089,6 +1127,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
@@ -1100,17 +1140,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;
@@ -1118,7 +1156,7 @@ window_loop (type, obj, mini, frames)
          case GET_LRU_WINDOW:
            /* t as arg means consider only full-width windows */
            if (!NILP (obj) && XFASTINT (XWINDOW (w)->width)
-               != FRAME_WIDTH (frame))
+               != FRAME_WIDTH (XFRAME (WINDOW_FRAME (XWINDOW (w)))))
              break;
 #if 0
            /* Ignore invisible and iconified frames.  */
@@ -1235,8 +1273,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;
 {
@@ -1267,11 +1306,11 @@ Only the frame WINDOW is on is affected.")
   w = XWINDOW (window);
   top = XFASTINT (w->top);
 
-  window_loop (DELETE_OTHER_WINDOWS, window, 0, WINDOW_FRAME(w));
+  window_loop (DELETE_OTHER_WINDOWS, window, 0, WINDOW_FRAME (w));
 
   Fset_buffer (w->buffer);
   SET_PT (marker_position (w->start));
-  Frecenter (make_number (top));
+  Frecenter (make_number (top - FRAME_MENU_BAR_LINES (XFRAME (WINDOW_FRAME (w)))));
 
   set_buffer_internal (obuf);
   SET_PT (opoint);
@@ -1339,9 +1378,8 @@ check_frame_size (frame, rows, cols)
   /* For height, we have to see whether the frame has a minibuffer, and
      whether it wants a mode line.  */
   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 (*rows < min_height)
@@ -1507,6 +1545,7 @@ BUFFER can be a buffer or buffer name.")
     }
 
   w->buffer = buffer;
+  w->hscroll = 0;
   Fset_marker (w->pointm,
               make_number (BUF_PT (XBUFFER (buffer))),
               buffer);
@@ -1514,6 +1553,7 @@ BUFFER can be a buffer or buffer name.")
                         make_number (XBUFFER (buffer)->last_window_start),
                         buffer);
   w->start_at_line_beg = Qnil;
+  w->force_start = Qnil;
   XFASTINT (w->last_modified) = 0;
   windows_or_buffers_changed++;
   if (EQ (window, selected_window))
@@ -1551,7 +1591,7 @@ before each command.")
   if (XFRAME (WINDOW_FRAME (w)) != selected_frame)
     {
       XFRAME (WINDOW_FRAME (w))->selected_window = window;
-      Fselect_frame (WINDOW_FRAME (w), Qnil);
+      Fhandle_switch_frame (WINDOW_FRAME (w), Qnil);
     }
   else
     selected_frame->selected_window = window;
@@ -1580,7 +1620,7 @@ before each command.")
 }
 
 DEFUN ("display-buffer", Fdisplay_buffer, Sdisplay_buffer, 1, 2,
-       "BDisplay buffer:\nP",
+       "BDisplay buffer: \nP",
   "Make BUFFER appear in some window but don't select it.\n\
 BUFFER can be a buffer or a buffer name.\n\
 If BUFFER is shown already in some window, just use that one,\n\
@@ -1616,7 +1656,7 @@ Returns the window displaying BUFFER.")
        = Fframe_selected_window (call0 (Vpop_up_frame_function));
       Fset_window_buffer (window, buffer);
 #if 0
-      Fselect_frame (XWINDOW (window)->frame, Qnil);
+      Fhandle_switch_frame (XWINDOW (window)->frame, Qnil);
 #endif
       return window;
     }
@@ -2022,7 +2062,7 @@ window_internal_height (w)
 
 
 /* Return the number of columns in W.
-   Don't count columns occupied by scrollbars or the vertical bar
+   Don't count columns occupied by scroll bars or the vertical bar
    separating W from the sibling to its right.  */
 int
 window_internal_width (w)
@@ -2040,9 +2080,9 @@ window_internal_width (w)
   /* If we are not flush right, then our rightmost columns are
      occupied by some sort of separator.  */
 
-  /* Scrollbars occupy a few columns.  */
-  if (FRAME_HAS_VERTICAL_SCROLLBARS (f))
-    return width - VERTICAL_SCROLLBAR_WIDTH;
+  /* Scroll bars occupy a few columns.  */
+  if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
+    return width - VERTICAL_SCROLL_BAR_WIDTH;
 
   /* The column of `|' characters separating side-by-side windows
      occupies one column only.  */
@@ -2205,8 +2245,20 @@ showing that buffer, popping the buffer up if necessary.")
        window = Fdisplay_buffer (Vother_window_scroll_buffer, Qt);
     }
   else
-    /* Nothing specified; pick a neighboring window.  */
-    window = Fnext_window (selected_window, Qnil, Qt);
+    {
+      /* Nothing specified; look for a neighboring window on the same
+        frame.  */
+      window = Fnext_window (selected_window, Qnil, Qnil);
+
+      if (EQ (window, selected_window))
+       /* That didn't get us anywhere; look for a window on another
+           visible frame.  */
+       do
+         window = Fnext_window (window, Qnil, Qt);
+       while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window))))
+              && ! EQ (window, selected_window));
+    }
+
   CHECK_LIVE_WINDOW (window, 0);
 
   if (EQ (window, selected_window))
@@ -2234,12 +2286,12 @@ showing that buffer, popping the buffer up if necessary.")
     }
 
   Fset_marker (w->pointm, make_number (point), Qnil);
-  unbind_to (count);
+  unbind_to (count, Qnil);
 
   return Qnil;
 }
 \f
-DEFUN ("scroll-left", Fscroll_left, Sscroll_left, 1, 1, "P",
+DEFUN ("scroll-left", Fscroll_left, Sscroll_left, 0, 1, "P",
   "Scroll selected window display ARG columns left.\n\
 Default for ARG is window width minus 2.")
   (arg)
@@ -2247,7 +2299,7 @@ Default for ARG is window width minus 2.")
 {
 
   if (NILP (arg))
-    XFASTINT (arg) = window_internal_width (selected_window) - 2;
+    XFASTINT (arg) = window_internal_width (XWINDOW (selected_window)) - 2;
   else
     arg = Fprefix_numeric_value (arg);
 
@@ -2257,14 +2309,14 @@ Default for ARG is window width minus 2.")
                                      + XINT (arg)));
 }
 
-DEFUN ("scroll-right", Fscroll_right, Sscroll_right, 1, 1, "P",
+DEFUN ("scroll-right", Fscroll_right, Sscroll_right, 0, 1, "P",
   "Scroll selected window display ARG columns right.\n\
 Default for ARG is window width minus 2.")
   (arg)
      register Lisp_Object arg;
 {
   if (NILP (arg))
-    XFASTINT (arg) = window_internal_width (selected_window) - 2;
+    XFASTINT (arg) = window_internal_width (XWINDOW (selected_window)) - 2;
   else
     arg = Fprefix_numeric_value (arg);
 
@@ -2408,9 +2460,8 @@ DEFUN ("window-configuration-p", Fwindow_configuration_p, Swindow_configuration_
 }
 
 
-DEFUN ("set-window-configuration",
-       Fset_window_configuration, Sset_window_configuration,
-       1, 1, 0,
+DEFUN ("set-window-configuration", Fset_window_configuration,
+  Sset_window_configuration, 1, 1, 0,
   "Set the configuration of windows and buffers as specified by CONFIGURATION.\n\
 CONFIGURATION must be a value previously returned\n\
 by `current-window-configuration' (which see).")
@@ -2543,8 +2594,8 @@ by `current-window-configuration' (which see).")
                      XBUFFER (p->buffer) == current_buffer)
                    Fgoto_char (w->pointm);
                }
-             else if (NILP (XBUFFER (w->buffer)->name))
-               /* Else if window's old buffer is dead too, get a live one.  */
+             else if (NILP (w->buffer) || NILP (XBUFFER (w->buffer)->name))
+               /* Else unless window has a live buffer, get one.  */
                {
                  w->buffer = Fcdr (Fcar (Vbuffer_alist));
                  /* This will set the markers to beginning of visible
@@ -2555,8 +2606,7 @@ by `current-window-configuration' (which see).")
                }
              else
                /* Keeping window's old buffer; make sure the markers
-                  are real.  Else if window's old buffer is dead too,
-                  get a live one.  */
+                  are real.  */
                {
                  /* Set window markers at start of visible range.  */
                  if (XMARKER (w->start)->buffer == 0)
@@ -2586,7 +2636,7 @@ by `current-window-configuration' (which see).")
          when the frame's old selected window has been deleted.  */
 #ifdef MULTI_FRAME
       if (f != selected_frame && ! FRAME_TERMCAP_P (f))
-       Fselect_frame (WINDOW_FRAME (XWINDOW (data->root_window)), Qnil);
+       Fhandle_switch_frame (WINDOW_FRAME (XWINDOW (data->root_window)), Qnil);
 #endif
 #endif
 
@@ -2599,12 +2649,12 @@ by `current-window-configuration' (which see).")
 
 #ifdef MULTI_FRAME
   /* Fselect_window will have made f the selected frame, so we
-     reselect the proper frame here.  Fselect_frame will change the
+     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 (data->selected_frame)))
-    Fselect_frame (data->selected_frame);
+    Fhandle_switch_frame (data->selected_frame, Qnil);
 #endif
 
   if (!NILP (new_current_buffer))
@@ -2845,8 +2895,8 @@ syms_of_window ()
   Qwindowp = intern ("windowp");
   staticpro (&Qwindowp);
 
-  Qlive_window_p = intern ("live-window-p");
-  staticpro (&Qlive_window_p);
+  Qwindow_live_p = intern ("window-live-p");
+  staticpro (&Qwindow_live_p);
 
 #ifndef MULTI_FRAME
   /* Make sure all windows get marked */
@@ -2866,25 +2916,6 @@ Commands such as `switch-to-buffer-other-window' and `find-file-other-window'\n\
 work using this function.");
   Vdisplay_buffer_function = Qnil;
 
-  DEFVAR_LISP ("mouse-window", &Vmouse_window,
-     "Window that the last mouse click occurred on.");
-  Vmouse_window = Qnil;
-
-  DEFVAR_LISP ("mouse-event", &Vmouse_event,
-     "The last mouse-event object.  A list of four elements:\n\
-  ((X-POS Y-POS) WINDOW FRAME-PART KEYSEQ).\n\
-KEYSEQ is a string, the key sequence to be looked up in the mouse maps.\n\
-WINDOW is the window that the click applies do.\n\
-If FRAME-PART is non-nil, the event was on a scrollbar;\n\
-then Y-POS is really the total length of the scrollbar, while X-POS is\n\
-the relative position of the scrollbar's value within that total length.\n\
-FRAME-PART is one of the following symbols:\n\
- `vertical-scrollbar', `vertical-slider',\n\
- `vertical-thumbup', `vertical-thumbdown',\n\
- `horizontal-scrollbar', `horizontal-slider',\n\
- `horizontal-thumbleft', `horizontal-thumbright'");
-  Vmouse_event = Qnil;
-
   DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window,
     "Non-nil means it is the window that C-M-v in minibuffer should scroll.");
   Vminibuf_scroll_window = Qnil;
@@ -2893,7 +2924,6 @@ FRAME-PART is one of the following symbols:\n\
     "If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window.");
   Vother_window_scroll_buffer = Qnil;
 
-#ifdef MULTI_FRAME
   DEFVAR_BOOL ("pop-up-frames", &pop_up_frames,
     "*Non-nil means `display-buffer' should make a separate frame.");
   pop_up_frames = 0;
@@ -2905,7 +2935,6 @@ It is called with no arguments and should return a newly created frame.\n\
 A typical value might be `(lambda () (new-frame pop-up-frame-alist))'\n\
 where `pop-up-frame-alist' would hold the default frame parameters.");
   Vpop_up_frame_function = Qnil;
-#endif
 
   DEFVAR_BOOL ("pop-up-windows", &pop_up_windows,
     "*Non-nil means display-buffer should make new windows.");
@@ -2932,7 +2961,7 @@ If there is only one window, it is split regardless of this value.");
   defsubr (&Sminibuffer_window);
   defsubr (&Swindow_minibuffer_p);
   defsubr (&Swindowp);
-  defsubr (&Slive_window_p);
+  defsubr (&Swindow_live_p);
   defsubr (&Spos_visible_in_window_p);
   defsubr (&Swindow_buffer);
   defsubr (&Swindow_height);