(Qarith_error): Delete redundant definition.
[bpt/emacs.git] / src / window.c
index 4939a19..6d635a5 100644 (file)
@@ -1,6 +1,6 @@
 /* Window creation, deletion and examination for GNU Emacs.
    Does not include redisplay.
-   Copyright (C) 1985, 86, 87, 93, 94, 95 Free Software Foundation, Inc.
+   Copyright (C) 1985, 86, 87, 93, 94, 95, 96 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -98,7 +98,7 @@ Lisp_Object Vsame_window_regexps;
 /* Hook run at end of temp_output_buffer_show.  */
 Lisp_Object Qtemp_buffer_show_hook;
 
-/* Fdisplay_buffer always splits the largest window 
+/* Fdisplay_buffer always splits the largest window
    if that window is more than this high.  */
 int split_height_threshold;
 
@@ -108,6 +108,9 @@ int next_screen_context_lines;
 /* Incremented for each window created.  */
 static int sequence_number;
 
+/* Nonzero after init_window_once has finished.  */
+static int window_initialized;
+
 #define min(a, b) ((a) < (b) ? (a) : (b))
 
 extern Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
@@ -390,7 +393,7 @@ coordinates_in_window (w, x, y)
   if (*y == top + window_height - 1
       && ! MINI_WINDOW_P (w))
     return 2;
-  
+
   /* Is the character in the right border?  */
   if (*x == left + width - 1
       && left + width != FRAME_WIDTH (XFRAME (w->frame)))
@@ -433,7 +436,7 @@ If they are on the border between WINDOW and its right sibling,\n\
 
     case 2:                    /* In mode line of window. */
       return Qmode_line;
-      
+
     case 3:                    /* On right border of window.  */
       return Qvertical_line;
 
@@ -470,7 +473,7 @@ window_from_coordinates (frame, x, y, part)
       tem = Fnext_window (tem, Qt, Qlambda);
     }
   while (! EQ (tem, first));
-  
+
   return Qnil;
 }
 
@@ -1471,7 +1474,7 @@ window_loop (type, obj, mini, frames)
     }
 
   return best_window;
-}     
+}
 
 DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 1, 0,
   "Return the window least recently selected or used for display.\n\
@@ -1676,7 +1679,7 @@ check_frame_size (frame, rows, cols)
      int *rows, *cols;
 {
   /* For height, we have to see:
-     whether the frame has a minibuffer, 
+     whether the frame has a minibuffer,
      whether it wants a mode line, and
      whether it has a menu bar.  */
   int min_height =
@@ -1825,6 +1828,14 @@ set_window_width (window, width, nodelete)
 \f
 int window_select_count;
 
+Lisp_Object
+Fset_window_buffer_unwind (obuf)
+     Lisp_Object obuf;
+{
+  Fset_buffer (obuf);
+  return Qnil;
+}
+
 DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 2, 0,
   "Make WINDOW display BUFFER as its contents.\n\
 BUFFER can be a buffer or buffer name.")
@@ -1833,6 +1844,7 @@ BUFFER can be a buffer or buffer name.")
 {
   register Lisp_Object tem;
   register struct window *w = decode_window (window);
+  int count = specpdl_ptr - specpdl;
 
   buffer = Fget_buffer (buffer);
   CHECK_BUFFER (buffer, 1);
@@ -1867,12 +1879,26 @@ BUFFER can be a buffer or buffer name.")
   w->force_start = Qnil;
   XSETFASTINT (w->last_modified, 0);
   windows_or_buffers_changed++;
+
+  /* We must select BUFFER for running the window-scroll-functions.
+     If WINDOW is selected, switch permanently.
+     Otherwise, switch but go back to the ambient buffer afterward.  */
   if (EQ (window, selected_window))
     Fset_buffer (buffer);
+  /* We can't check ! NILP (Vwindow_scroll_functions) here
+     because that might itself be a local variable.  */
+  else if (window_initialized)
+    {
+      record_unwind_protect (Fset_window_buffer_unwind, Fcurrent_buffer ());
+      Fset_buffer (buffer);
+    }
+
   if (! NILP (Vwindow_scroll_functions))
     run_hook_with_args_2 (Qwindow_scroll_functions, window,
                          Fmarker_position (w->start));
 
+  unbind_to (count, Qnil);
+
   return Qnil;
 }
 
@@ -1954,9 +1980,13 @@ display_buffer_1 (window)
 #ifdef MULTI_FRAME
   FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
   FRAME_SAMPLE_VISIBILITY (f);
-  if (FRAME_ICONIFIED_P (f)
-      && f != selected_frame)
-    Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window)));
+  if (f != selected_frame)
+    {
+      if (FRAME_ICONIFIED_P (f))
+       Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window)));
+      else if (FRAME_VISIBLE_P (f))
+       Fraise_frame (WINDOW_FRAME (XWINDOW (window)));
+    }
 #endif
   return window;
 }
@@ -1969,7 +1999,11 @@ If BUFFER is shown already in some window, just use that one,\n\
 unless the window is the selected window and the optional second\n\
 argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).\n\
 If `pop-up-frames' is non-nil, make a new frame if no window shows BUFFER.\n\
-Returns the window displaying BUFFER.")
+Returns the window displaying BUFFER.\n\
+\n\
+The variables `special-display-buffer-names', `special-display-regexps',\n\
+`same-window-buffer-names', and `same-window-regexps' customize how certain\n\
+buffer names are handled.")
   (buffer, not_this_window)
      register Lisp_Object buffer, not_this_window;
 {
@@ -2049,7 +2083,7 @@ Returns the window displaying BUFFER.")
       tem = Fassoc (XBUFFER (buffer)->name, Vspecial_display_buffer_names);
       if (!NILP (tem))
        return call2 (Vspecial_display_function, buffer, XCONS (tem)->cdr);
-      
+
       for (tem = Vspecial_display_regexps; CONSP (tem); tem = XCONS (tem)->cdr)
        {
          Lisp_Object car = XCONS (tem)->car;
@@ -2088,7 +2122,7 @@ Returns the window displaying BUFFER.")
     {
       Lisp_Object frames;
 
-      frames = Qnil;      
+      frames = Qnil;
 #ifdef MULTI_FRAME
       if (FRAME_MINIBUF_ONLY_P (selected_frame))
        XSETFRAME (frames, last_nonminibuf_frame);
@@ -2220,7 +2254,7 @@ temp_output_buffer_show (buf)
       set_marker_restricted (w->start, make_number (1), buf);
       set_marker_restricted (w->pointm, make_number (1), buf);
 
-      /* Run temp-buffer-show-hook, with the chosen window selected.  */ 
+      /* Run temp-buffer-show-hook, with the chosen window selected.  */
       if (!NILP (Vrun_hooks))
        {
          Lisp_Object tem;
@@ -2331,7 +2365,7 @@ and put SIZE columns in the first of the pair.")
       if (size_int < window_min_height)
        error ("Window height %d too small (after splitting)", size_int);
       if (size_int + window_min_height > XFASTINT (o->height))
-       error ("Window height %d too small (after splitting)", 
+       error ("Window height %d too small (after splitting)",
               XFASTINT (o->height) - size_int);
       if (NILP (o->parent)
          || NILP (XWINDOW (o->parent)->vchild))
@@ -2346,7 +2380,7 @@ and put SIZE columns in the first of the pair.")
       if (size_int < window_min_width)
        error ("Window width %d too small (after splitting)", size_int);
       if (internal_width - size_int - separator_width < window_min_width)
-       error ("Window width %d too small (after splitting)", 
+       error ("Window width %d too small (after splitting)",
               internal_width - size_int - separator_width);
       if (NILP (o->parent)
          || NILP (XWINDOW (o->parent)->hchild))
@@ -3052,7 +3086,7 @@ by `current-window-configuration' (which see).")
       if (XFASTINT (data->frame_height) != previous_frame_height
          || XFASTINT (data->frame_width) != previous_frame_width)
        change_frame_size (f, data->frame_height, data->frame_width, 0, 0);
-#ifdef HAVE_WINDOW_SYSTEM
+#if defined (HAVE_WINDOW_SYSTEM) || (defined (MSDOS) && defined (MULTI_FRAME))
       if (XFASTINT (data->frame_menu_bar_lines)
          != previous_frame_menu_bar_lines)
        x_set_menu_bar_lines (f, data->frame_menu_bar_lines, 0);
@@ -3069,7 +3103,7 @@ by `current-window-configuration' (which see).")
       /* Kludge Alert!
         Mark all windows now on frame as "deleted".
         Restoring the new configuration "undeletes" any that are in it.
-        
+
         Save their current buffers in their height fields, since we may
         need it later, if a buffer saved in the configuration is now
         dead.  */
@@ -3190,7 +3224,7 @@ by `current-window-configuration' (which see).")
 #if 0 /* I don't understand why this is needed, and it causes problems
          when the frame's old selected window has been deleted.  */
 #ifdef MULTI_FRAME
-      if (f != selected_frame && ! FRAME_TERMCAP_P (f))
+      if (f != selected_frame && FRAME_WINDOW_P (f))
        do_switch_frame (WINDOW_FRAME (XWINDOW (data->root_window)),
                         Qnil, 0);
 #endif
@@ -3201,7 +3235,7 @@ by `current-window-configuration' (which see).")
          || previous_frame_width != FRAME_WIDTH (f))
        change_frame_size (f, previous_frame_height, previous_frame_width,
                           0, 0);
-#ifdef HAVE_WINDOW_SYSTEM
+#if defined (HAVE_WINDOW_SYSTEM) || (defined (MSDOS) && defined (MULTI_FRAME))
       if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f))
        x_set_menu_bar_lines (f, previous_frame_menu_bar_lines, 0);
 #endif
@@ -3464,6 +3498,8 @@ init_window_once ()
      something newer than this.  */
   XSETFASTINT (XWINDOW (selected_window)->use_time, ++window_select_count);
 #endif /* not MULTI_FRAME */
+
+  window_initialized = 1;
 }
 
 syms_of_window ()