Merge from emacs-23; up to 2010-05-26T14:19:15Z!monnier@iro.umontreal.ca.
[bpt/emacs.git] / src / window.c
index a2a0c79..abf0175 100644 (file)
@@ -1,7 +1,6 @@
 /* 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, 2007, 2008, 2009, 2010
+   Copyright (C) 1985-1987, 1993-1998, 2000-2011
                  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -78,10 +77,14 @@ static Lisp_Object next_window (Lisp_Object, Lisp_Object,
                                 Lisp_Object, int);
 static void decode_next_window_args (Lisp_Object *, Lisp_Object *,
                                      Lisp_Object *);
+static void foreach_window (struct frame *,
+                                int (* fn) (struct window *, void *),
+                            void *);
 static int foreach_window_1 (struct window *,
                              int (* fn) (struct window *, void *),
                              void *);
 static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object);
+static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
 
 /* This is the window in which the terminal's cursor should
    be left when nothing is being done with it.  This must
@@ -111,42 +114,10 @@ Lisp_Object minibuf_window;
 
 Lisp_Object minibuf_selected_window;
 
-/* Non-nil means it is the window for C-M-v to scroll
-   when the mini-buffer is selected.  */
-
-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;
-
-/* Non-nil means it's function to call to display temp buffers.  */
-
-Lisp_Object Vtemp_buffer_show_function;
-
-/* Non-zero means line and page scrolling on tall lines (with images)
-   does partial scrolling by modifying window-vscroll.  */
-
-int auto_window_vscroll_p;
-
-/* Non-zero means to use mode-line-inactive face in all windows but the
-   selected-window and the minibuffer-scroll-window when the
-   minibuffer is active.  */
-int mode_line_in_non_selected_windows;
-
-/* If a window gets smaller than either of these, it is removed. */
-
-EMACS_INT window_min_height;
-EMACS_INT window_min_width;
-
 /* Hook run at end of temp_output_buffer_show.  */
 
 Lisp_Object Qtemp_buffer_show_hook;
 
-/* Number of lines of continuity in scrolling by screenfuls.  */
-
-EMACS_INT next_screen_context_lines;
-
 /* Incremented for each window created.  */
 
 static int sequence_number;
@@ -158,17 +129,6 @@ static int window_initialized;
 /* Hook to run when window config changes.  */
 
 static Lisp_Object Qwindow_configuration_change_hook;
-static Lisp_Object Vwindow_configuration_change_hook;
-
-/* Non-nil means scroll commands try to put point
-   at the same screen height as previously.  */
-
-Lisp_Object Vscroll_preserve_screen_position;
-
-/* Non-nil means that text is inserted before window's markers.  */
-
-Lisp_Object Vwindow_point_insertion_type;
-
 /* Incremented by 1 whenever a window is deleted.  */
 
 int window_deletion_count;
@@ -186,13 +146,7 @@ static int window_scroll_preserve_vpos;
 #if 0 /* This isn't used anywhere.  */
 /* Nonzero means we can split a frame even if it is "unsplittable".  */
 static int inhibit_frame_unsplittable;
-#endif /* 0 */
-
-/* If non-nil, then the `recenter' command with a nil argument
-   the entire frame to be redrawn; the special value `tty' causes the
-   frame to be redrawn only if it is a tty frame.  */
-
-static Lisp_Object Vrecenter_redisplay;
+#endif
 
 \f
 DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0,
@@ -1425,6 +1379,8 @@ DEFUN ("set-window-display-table", Fset_window_display_table, Sset_window_displa
   return table;
 }
 \f
+static void delete_window (Lisp_Object);
+
 /* Record info on buffer window w is displaying
    when it is about to cease to display that buffer.  */
 static void
@@ -1548,7 +1504,7 @@ Signal an error when WINDOW is the only window on its frame.  */)
   return Qnil;
 }
 
-void
+static void
 delete_window (register Lisp_Object window)
 {
   register Lisp_Object tem, parent, sib;
@@ -3522,11 +3478,12 @@ This function runs `window-scroll-functions' before running
   else if (!EQ (tem, Qt))
     /* w->buffer is t when the window is first being set up.  */
     {
-      if (!EQ (tem, buffer))
-       if (EQ (w->dedicated, Qt))
-         error ("Window is dedicated to `%s'", SDATA (XBUFFER (tem)->name));
-       else
-         w->dedicated = Qnil;
+      if (EQ (tem, buffer))
+       return Qnil;
+      else if (EQ (w->dedicated, Qt))
+       error ("Window is dedicated to `%s'", SDATA (XBUFFER (tem)->name));
+      else
+       w->dedicated = Qnil;
 
       unshow_buffer (w);
     }
@@ -3535,20 +3492,14 @@ This function runs `window-scroll-functions' before running
   return Qnil;
 }
 
-/* Note that selected_window can be nil when this is called from
-   Fset_window_configuration.  */
-
-DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0,
-       doc: /* Select WINDOW.  Most editing will apply to WINDOW's buffer.
-If WINDOW is not already selected, make WINDOW's buffer current
-and make WINDOW the frame's selected window.  Return WINDOW.
-Optional second arg NORECORD non-nil means do not put this buffer
-at the front of the list of recently selected ones and do not
-make this window the most recently selected one.
+/* If select_window is called with inhibit_point_swap non-zero it will
+   not store point of the old selected window's buffer back into that
+   window's pointm slot.  This is needed by Fset_window_configuration to
+   avoid that the display routine is called with selected_window set to
+   Qnil causing a subsequent crash.  */
 
-Note that the main editor command loop selects the buffer of the
-selected window before each command.  */)
-  (register Lisp_Object window, Lisp_Object norecord)
+static Lisp_Object
+select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
 {
   register struct window *w;
   register struct window *ow;
@@ -3588,7 +3539,7 @@ selected window before each command.  */)
   /* Store the current buffer's actual point into the
      old selected window.  It belongs to that window,
      and when the window is not selected, must be in the window.  */
-  if (!NILP (selected_window))
+  if (!inhibit_point_swap)
     {
       ow = XWINDOW (selected_window);
       if (! NILP (ow->buffer))
@@ -3622,6 +3573,25 @@ selected window before each command.  */)
   return window;
 }
 
+
+/* Note that selected_window can be nil when this is called from
+   Fset_window_configuration.  */
+
+DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0,
+       doc: /* Select WINDOW.  Most editing will apply to WINDOW's buffer.
+If WINDOW is not already selected, make WINDOW's buffer current
+and make WINDOW the frame's selected window.  Return WINDOW.
+Optional second arg NORECORD non-nil means do not put this buffer
+at the front of the list of recently selected ones and do not
+make this window the most recently selected one.
+
+Note that the main editor command loop selects the buffer of the
+selected window before each command.  */)
+     (register Lisp_Object window, Lisp_Object norecord)
+{
+  return select_window (window, norecord, 0);
+}
+
 static Lisp_Object
 select_window_norecord (Lisp_Object window)
 {
@@ -3957,14 +3927,14 @@ fixed size windows is not altered by this function. */)
   return Qnil;
 }
 
-int
+static int
 window_height (Lisp_Object window)
 {
   register struct window *p = XWINDOW (window);
   return WINDOW_TOTAL_LINES (p);
 }
 
-int
+static int
 window_width (Lisp_Object window)
 {
   register struct window *p = XWINDOW (window);
@@ -5756,6 +5726,12 @@ zero means top of window, negative means relative to bottom of window.  */)
   int this_scroll_margin;
 #endif
 
+  if (!(BUFFERP (w->buffer)
+       && XBUFFER (w->buffer) == current_buffer))
+    /* This test is needed to make sure PT/PT_BYTE make sense in w->buffer
+       when passed below to set_marker_both.  */
+    error ("move-to-window-line called from unrelated buffer");
+
   window = selected_window;
   start = marker_position (w->start);
   if (start < BEGV || start > ZV)
@@ -6132,10 +6108,6 @@ the return value is nil.  Otherwise the value is t.  */)
        }
 
       FRAME_ROOT_WINDOW (f) = data->root_window;
-      /* Prevent "swapping out point" in the old selected window
-        using the buffer that has been restored into it.
-        We already swapped out point that from that window's old buffer.  */
-      selected_window = Qnil;
 
       /* Arrange *not* to restore point in the buffer that was
         current when the window configuration was saved.  */
@@ -6144,7 +6116,11 @@ the return value is nil.  Otherwise the value is t.  */)
                               make_number (old_point),
                               XWINDOW (data->current_window)->buffer);
 
-      Fselect_window (data->current_window, Qnil);
+      /* In the following call to `select-window, prevent "swapping
+        out point" in the old selected window using the buffer that
+        has been restored into it.  We already swapped out that point
+        from that window's old buffer.  */
+      select_window (data->current_window, Qnil, 1);
       XBUFFER (XWINDOW (selected_window)->buffer)->last_selected_window
        = selected_window;
 
@@ -6153,13 +6129,6 @@ the return value is nil.  Otherwise the value is t.  */)
              && FRAME_LIVE_P (XFRAME (data->focus_frame))))
        Fredirect_frame_focus (frame, data->focus_frame);
 
-#if 0 /* I don't understand why this is needed, and it causes problems
-         when the frame's old selected window has been deleted.  */
-      if (f != selected_frame && FRAME_WINDOW_P (f))
-       do_switch_frame (WINDOW_FRAME (XWINDOW (data->root_window)),
-                        0, 0, Qnil);
-#endif
-
       /* Set the screen height to the value it had before this function.  */
       if (previous_frame_lines != FRAME_LINES (f)
          || previous_frame_cols != FRAME_COLS (f))
@@ -6816,8 +6785,9 @@ If PIXELS-P is non-nil, the return value is VSCROLL.  */)
    first argument being a pointer to the leaf window, and with
    additional argument USER_DATA.  Stops when FN returns 0.  */
 
-void
-foreach_window (struct frame *f, int (*fn) (struct window *, void *), void *user_data)
+static void
+foreach_window (struct frame *f, int (*fn) (struct window *, void *),
+               void *user_data)
 {
   /* delete_frame may set FRAME_ROOT_WINDOW (f) to Qnil.  */
   if (WINDOWP (FRAME_ROOT_WINDOW (f)))
@@ -7081,7 +7051,7 @@ syms_of_window (void)
   window_scroll_preserve_hpos = -1;
   window_scroll_preserve_vpos = -1;
 
-  DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function,
+  DEFVAR_LISP ("temp-buffer-show-function", Vtemp_buffer_show_function,
               doc: /* Non-nil means call as function to display a help buffer.
 The function is called with one argument, the buffer to be displayed.
 Used by `with-output-to-temp-buffer'.
@@ -7089,29 +7059,29 @@ If this function is used, then it must do the entire job of showing
 the buffer; `temp-buffer-show-hook' is not run unless this function runs it.  */);
   Vtemp_buffer_show_function = Qnil;
 
-  DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window,
+  DEFVAR_LISP ("minibuffer-scroll-window", Vminibuf_scroll_window,
               doc: /* Non-nil means it is the window that C-M-v in minibuffer should scroll.  */);
   Vminibuf_scroll_window = Qnil;
 
-  DEFVAR_BOOL ("mode-line-in-non-selected-windows", &mode_line_in_non_selected_windows,
+  DEFVAR_BOOL ("mode-line-in-non-selected-windows", mode_line_in_non_selected_windows,
               doc: /* Non-nil means to use `mode-line-inactive' face in non-selected windows.
 If the minibuffer is active, the `minibuffer-scroll-window' mode line
 is displayed in the `mode-line' face.  */);
   mode_line_in_non_selected_windows = 1;
 
-  DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer,
+  DEFVAR_LISP ("other-window-scroll-buffer", Vother_window_scroll_buffer,
               doc: /* If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window.  */);
   Vother_window_scroll_buffer = Qnil;
 
-  DEFVAR_BOOL ("auto-window-vscroll", &auto_window_vscroll_p,
+  DEFVAR_BOOL ("auto-window-vscroll", auto_window_vscroll_p,
               doc: /* *Non-nil means to automatically adjust `window-vscroll' to view tall lines.  */);
   auto_window_vscroll_p = 1;
 
-  DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines,
+  DEFVAR_INT ("next-screen-context-lines", next_screen_context_lines,
              doc: /* *Number of lines of continuity when scrolling by screenfuls.  */);
   next_screen_context_lines = 2;
 
-  DEFVAR_INT ("window-min-height", &window_min_height,
+  DEFVAR_INT ("window-min-height", window_min_height,
              doc: /* Allow deleting windows less than this tall.
 The value is measured in line units.  If a window wants a modeline it
 is counted as one line.
@@ -7120,7 +7090,7 @@ Emacs honors settings of this variable when enlarging or shrinking
 windows vertically.  A value less than 1 is invalid.  */);
   window_min_height = 4;
 
-  DEFVAR_INT ("window-min-width", &window_min_width,
+  DEFVAR_INT ("window-min-width", window_min_width,
              doc: /* Allow deleting windows less than this wide.
 The value is measured in characters and includes any fringes or
 the scrollbar.
@@ -7130,7 +7100,7 @@ windows horizontally.  A value less than 2 is invalid.  */);
   window_min_width = 10;
 
   DEFVAR_LISP ("scroll-preserve-screen-position",
-              &Vscroll_preserve_screen_position,
+              Vscroll_preserve_screen_position,
               doc: /* *Controls if scroll commands move point to keep its screen position unchanged.
 A value of nil means point does not keep its screen position except
 at the scroll margin or window boundary respectively.
@@ -7142,19 +7112,19 @@ Scroll commands should have the `scroll-command' property
 on their symbols to be controlled by this variable.  */);
   Vscroll_preserve_screen_position = Qnil;
 
-  DEFVAR_LISP ("window-point-insertion-type", &Vwindow_point_insertion_type,
+  DEFVAR_LISP ("window-point-insertion-type", Vwindow_point_insertion_type,
               doc: /* Type of marker to use for `window-point'.  */);
   Vwindow_point_insertion_type = Qnil;
 
   DEFVAR_LISP ("window-configuration-change-hook",
-              &Vwindow_configuration_change_hook,
+              Vwindow_configuration_change_hook,
               doc: /* Functions to call when window configuration changes.
 The buffer-local part is run once per window, with the relevant window
 selected; while the global part is run only once for the modified frame,
 with the relevant frame selected.  */);
   Vwindow_configuration_change_hook = Qnil;
 
-  DEFVAR_LISP ("recenter-redisplay", &Vrecenter_redisplay,
+  DEFVAR_LISP ("recenter-redisplay", Vrecenter_redisplay,
               doc: /* If non-nil, then the `recenter' command with a nil argument
 will redraw the entire frame; the special value `tty' causes the
 frame to be redrawn only if it is a tty frame.  */);
@@ -7197,6 +7167,7 @@ frame to be redrawn only if it is a tty frame.  */);
   defsubr (&Sprevious_window);
   defsubr (&Sother_window);
   defsubr (&Sget_lru_window);
+  defsubr (&Swindow_use_time);
   defsubr (&Sget_largest_window);
   defsubr (&Sget_buffer_window);
   defsubr (&Sdelete_other_windows);
@@ -7258,5 +7229,3 @@ keys_of_window (void)
   initial_define_key (meta_map, 'v', "scroll-down-command");
 }
 
-/* arch-tag: 90a9c576-0590-48f1-a5f1-6c96a0452d9f
-   (do not change this comment) */