Use common memory management functions for lwlib and refactor users.
[bpt/emacs.git] / src / window.c
index 0ec1aa9..919cc7b 100644 (file)
@@ -55,6 +55,7 @@ static Lisp_Object Qwindow_pixel_to_total;
 static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
 static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of;
 static Lisp_Object Qfloor, Qceiling;
+static Lisp_Object Qwindow_point_insertion_type;
 
 static int displayed_window_lines (struct window *);
 static int count_windows (struct window *);
@@ -118,13 +119,10 @@ static Lisp_Object Qtemp_buffer_show_hook;
 /* Incremented for each window created.  */
 static int sequence_number;
 
-/* Nonzero after init_window_once has finished.  */
-static int window_initialized;
-
 /* Hook to run when window config changes.  */
 static Lisp_Object Qwindow_configuration_change_hook;
 
-/* Used by the function window_scroll_pixel_based */
+/* Used by the function window_scroll_pixel_based */
 static int window_scroll_pixel_based_preserve_x;
 static int window_scroll_pixel_based_preserve_y;
 
@@ -559,7 +557,7 @@ select_window_1 (Lisp_Object window, bool inhibit_point_swap)
 DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0,
        doc: /* Select WINDOW which must be a live window.
 Also make WINDOW's frame the selected frame and WINDOW that frame's
-selected window.  In addition, make WINDOW's buffer current and set that
+selected window.  In addition, make WINDOW's buffer current and set its
 buffer's value of `point' to the value of WINDOW's `window-point'.
 Return WINDOW.
 
@@ -567,8 +565,17 @@ Optional second arg NORECORD non-nil means do not put this buffer at the
 front of the buffer list and do not make this window the most recently
 selected one.
 
-Note that the main editor command loop sets the current buffer to the
-buffer of the selected window before each command.  */)
+Run `buffer-list-update-hook' unless NORECORD is non-nil.  Note that
+applications and internal routines often select a window temporarily for
+various purposes; mostly, to simplify coding.  As a rule, such
+selections should be not recorded and therefore will not pollute
+`buffer-list-update-hook'.  Selections that "really count" are those
+causing a visible change in the next redisplay of WINDOW's frame and
+should be always recorded.  So if you think of running a function each
+time a window gets selected put it on `buffer-list-update-hook'.
+
+Also note that the main editor command loop sets the current buffer to
+the buffer of the selected window before each command.  */)
   (register Lisp_Object window, Lisp_Object norecord)
 {
   return select_window (window, norecord, 0);
@@ -699,9 +706,9 @@ DEFUN ("window-pixel-height", Fwindow_pixel_height, Swindow_pixel_height, 0, 1,
        doc: /* Return the height of window WINDOW in pixels.
 WINDOW must be a valid window and defaults to the selected one.
 
-The return value includes the mode line and header line, if any.  If
-WINDOW is an internal window, its pixel height is the height of the
-screen areas spanned by its children.  */)
+The return value includes the mode line and header line and the bottom
+divider, if any.  If WINDOW is an internal window, its pixel height is
+the height of the screen areas spanned by its children.  */)
   (Lisp_Object window)
 {
   return make_number (decode_valid_window (window)->pixel_height);
@@ -1266,18 +1273,18 @@ coordinates_in_window (register struct window *w, int x, int y)
   if (y < top_y || y >= bottom_y || x < left_x || x >= right_x)
     return ON_NOTHING;
 
-  /* On vertical window divider (which prevails horizontal
-     dividers)?  */
-  if (!WINDOW_RIGHTMOST_P (w)
-      && WINDOW_RIGHT_DIVIDER_WIDTH (w)
-      && x >= right_x - WINDOW_RIGHT_DIVIDER_WIDTH (w)
-      && x <= right_x)
-    return ON_RIGHT_DIVIDER;
-  /* On the horizontal window divider?  */
-  else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w)
-          && y >= (bottom_y - WINDOW_BOTTOM_DIVIDER_WIDTH (w))
-          && y <= bottom_y)
+  /* On the horizontal window divider (which prevails the vertical
+     divider)?  */
+  if (WINDOW_BOTTOM_DIVIDER_WIDTH (w) > 0
+      && y >= (bottom_y - WINDOW_BOTTOM_DIVIDER_WIDTH (w))
+      && y <= bottom_y)
     return ON_BOTTOM_DIVIDER;
+  /* On vertical window divider?  */
+  else if (!WINDOW_RIGHTMOST_P (w)
+          && WINDOW_RIGHT_DIVIDER_WIDTH (w) > 0
+          && x >= right_x - WINDOW_RIGHT_DIVIDER_WIDTH (w)
+          && x <= right_x)
+    return ON_RIGHT_DIVIDER;
   /* On the mode or header line?   */
   else if ((WINDOW_WANTS_MODELINE_P (w)
            && y >= (bottom_y
@@ -1294,12 +1301,13 @@ coordinates_in_window (register struct window *w, int x, int y)
         resize windows horizontally in case we're using toolkit scroll
         bars.  Note: If scrollbars are on the left, the window that
         must be eventually resized is that on the left of WINDOW.  */
-      if ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
-          && !WINDOW_LEFTMOST_P (w)
-          && eabs (x - left_x) < grabbable_width)
-         || (!WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
-             && !WINDOW_RIGHTMOST_P (w)
-             && eabs (x - right_x) < grabbable_width))
+      if ((WINDOW_RIGHT_DIVIDER_WIDTH (w) == 0)
+         && ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
+              && !WINDOW_LEFTMOST_P (w)
+              && eabs (x - left_x) < grabbable_width)
+             || (!WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
+                 && !WINDOW_RIGHTMOST_P (w)
+                 && eabs (x - right_x) < grabbable_width)))
        return ON_VERTICAL_BORDER;
       else
        return part;
@@ -1331,6 +1339,7 @@ coordinates_in_window (register struct window *w, int x, int y)
   if (FRAME_WINDOW_P (f))
     {
       if (!w->pseudo_window_p
+         && WINDOW_RIGHT_DIVIDER_WIDTH (w) == 0
          && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
          && !WINDOW_RIGHTMOST_P (w)
          && (eabs (x - right_x) < grabbable_width))
@@ -1339,6 +1348,7 @@ coordinates_in_window (register struct window *w, int x, int y)
   /* Need to say "x > right_x" rather than >=, since on character
      terminals, the vertical line's x coordinate is right_x.  */
   else if (!w->pseudo_window_p
+          && WINDOW_RIGHT_DIVIDER_WIDTH (w) == 0
           && !WINDOW_RIGHTMOST_P (w)
           /* Why check ux if we are not the rightmost window?  Also
              shouldn't a pseudo window always be rightmost?  */
@@ -1352,8 +1362,8 @@ coordinates_in_window (register struct window *w, int x, int y)
              ? (x >= left_x + WINDOW_LEFT_FRINGE_WIDTH (w))
              : (x < left_x + lmargin_width)))
        return ON_LEFT_MARGIN;
-
-      return ON_LEFT_FRINGE;
+      else
+       return ON_LEFT_FRINGE;
     }
 
   if (x >= text_right)
@@ -1363,8 +1373,8 @@ coordinates_in_window (register struct window *w, int x, int y)
              ? (x < right_x - WINDOW_RIGHT_FRINGE_WIDTH (w))
              : (x >= right_x - rmargin_width)))
        return ON_RIGHT_MARGIN;
-
-      return ON_RIGHT_FRINGE;
+      else
+       return ON_RIGHT_FRINGE;
     }
 
   /* Everything special ruled out - must be on text area */
@@ -1383,6 +1393,8 @@ window_relative_x_coord (struct window *w, enum window_part part, int x)
     case ON_TEXT:
       return x - window_box_left (w, TEXT_AREA);
 
+    case ON_HEADER_LINE:
+    case ON_MODE_LINE:
     case ON_LEFT_FRINGE:
       return x - left_x;
 
@@ -1419,8 +1431,10 @@ measured in characters from the upper-left corner of the frame.
 frame.
 If COORDINATES are in the text portion of WINDOW,
    the coordinates relative to the window are returned.
+If they are in the bottom divider of WINDOW, `bottom-divider' is returned.
+If they are in the right divider of WINDOW, `right-divider' is returned.
 If they are in the mode line of WINDOW, `mode-line' is returned.
-If they are in the top mode line of WINDOW, `header-line' is returned.
+If they are in the header line of WINDOW, `header-line' is returned.
 If they are in the left fringe of WINDOW, `left-fringe' is returned.
 If they are in the right fringe of WINDOW, `right-fringe' is returned.
 If they are on the border between WINDOW and its right sibling,
@@ -3422,14 +3436,10 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
   wset_redisplay (w);
   w->update_mode_line = true;
 
-  /* We must select BUFFER for running the window-scroll-functions.  */
-  /* We can't check ! NILP (Vwindow_scroll_functions) here
-     because that might itself be a local variable.  */
-  if (window_initialized)
-    {
-      record_unwind_current_buffer ();
-      Fset_buffer (buffer);
-    }
+  /* We must select BUFFER to run the window-scroll-functions and to look up
+     the buffer-local value of Vwindow_point_insertion_type.  */
+  record_unwind_current_buffer ();
+  Fset_buffer (buffer);
 
   XMARKER (w->pointm)->insertion_type = !NILP (Vwindow_point_insertion_type);
 
@@ -5422,8 +5432,10 @@ specifies the window.  This takes precedence over
   if (MINI_WINDOW_P (XWINDOW (selected_window))
       && !NILP (Vminibuf_scroll_window))
     window = Vminibuf_scroll_window;
-  /* If buffer is specified, scroll that buffer.  */
-  else if (!NILP (Vother_window_scroll_buffer))
+  /* If buffer is specified and live, scroll that buffer.  */
+  else if (!NILP (Vother_window_scroll_buffer)
+          && BUFFERP (Vother_window_scroll_buffer)
+          && BUFFER_LIVE_P (XBUFFER (Vother_window_scroll_buffer)))
     {
       window = Fget_buffer_window (Vother_window_scroll_buffer, Qnil);
       if (NILP (window))
@@ -5941,12 +5953,12 @@ struct save_window_data
     int frame_menu_bar_height, frame_tool_bar_height;
   };
 
-/* This is saved as a Lisp_Vector  */
+/* This is saved as a Lisp_Vector.  */
 struct saved_window
 {
   struct vectorlike_header header;
 
-  Lisp_Object window, buffer, start, pointm, mark;
+  Lisp_Object window, buffer, start, pointm;
   Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width;
   Lisp_Object left_col, top_line, total_cols, total_lines;
   Lisp_Object normal_cols, normal_lines;
@@ -6248,8 +6260,6 @@ the return value is nil.  Otherwise the value is t.  */)
              set_marker_restricted (w->start, p->start, w->contents);
              set_marker_restricted (w->pointm, p->pointm,
                                     w->contents);
-             Fset_marker (BVAR (XBUFFER (w->contents), mark),
-                          p->mark, w->contents);
 
              /* As documented in Fcurrent_window_configuration, don't
                 restore the location of point in the buffer which was
@@ -6600,31 +6610,21 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
          else
            p->pointm = Fcopy_marker (w->pointm, Qnil);
          XMARKER (p->pointm)->insertion_type
-           = !NILP (Vwindow_point_insertion_type);
+           = !NILP (buffer_local_value /* Don't signal error if void.  */
+                    (Qwindow_point_insertion_type, w->contents));
 
          p->start = Fcopy_marker (w->start, Qnil);
          p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil;
-
-         tem = BVAR (XBUFFER (w->contents), mark);
-         p->mark = Fcopy_marker (tem, Qnil);
        }
       else
        {
          p->pointm = Qnil;
          p->start = Qnil;
-         p->mark = Qnil;
          p->start_at_line_beg = Qnil;
        }
 
-      if (NILP (w->parent))
-       p->parent = Qnil;
-      else
-       p->parent = XWINDOW (w->parent)->temslot;
-
-      if (NILP (w->prev))
-       p->prev = Qnil;
-      else
-       p->prev = XWINDOW (w->prev)->temslot;
+      p->parent = NILP (w->parent) ? Qnil : XWINDOW (w->parent)->temslot;
+      p->prev = NILP (w->prev) ? Qnil : XWINDOW (w->prev)->temslot;
 
       if (WINDOWP (w->contents))
        i = save_window_save (w->contents, vector, i);
@@ -6638,8 +6638,8 @@ DEFUN ("current-window-configuration", Fcurrent_window_configuration,
        doc: /* Return an object representing the current window configuration of FRAME.
 If FRAME is nil or omitted, use the selected frame.
 This describes the number of windows, their sizes and current buffers,
-and for each displayed buffer, where display starts, and the positions of
-point and mark.  An exception is made for point in the current buffer:
+and for each displayed buffer, where display starts, and the position of
+point.  An exception is made for point in the current buffer:
 its value is -not- saved.
 This also records the currently selected frame, and FRAME's focus
 redirection (see `redirect-frame-focus').  The variable
@@ -7083,8 +7083,7 @@ compare_window_configurations (Lisp_Object configuration1,
                  || !EQ (sw1->min_hscroll, sw2->min_hscroll)
                  || !EQ (sw1->start_at_line_beg, sw2->start_at_line_beg)
                  || NILP (Fequal (sw1->start, sw2->start))
-                 || NILP (Fequal (sw1->pointm, sw2->pointm))
-                 || NILP (Fequal (sw1->mark, sw2->mark))))
+                 || NILP (Fequal (sw1->pointm, sw2->pointm))))
          || !EQ (sw1->left_margin_cols, sw2->left_margin_cols)
          || !EQ (sw1->right_margin_cols, sw2->right_margin_cols)
          || !EQ (sw1->left_fringe_width, sw2->left_fringe_width)
@@ -7101,7 +7100,7 @@ compare_window_configurations (Lisp_Object configuration1,
 DEFUN ("compare-window-configurations", Fcompare_window_configurations,
        Scompare_window_configurations, 2, 2, 0,
        doc: /* Compare two window configurations as regards the structure of windows.
-This function ignores details such as the values of point and mark
+This function ignores details such as the values of point
 and scrolling positions.  */)
   (Lisp_Object x, Lisp_Object y)
 {
@@ -7118,8 +7117,6 @@ init_window_once (void)
   Vterminal_frame = selected_frame;
   minibuf_window = f->minibuffer_window;
   selected_window = f->selected_window;
-
-  window_initialized = 1;
 }
 
 void
@@ -7190,7 +7187,7 @@ is displayed in the `mode-line' face.  */);
   mode_line_in_non_selected_windows = 1;
 
   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.  */);
+              doc: /* If this is a live buffer, \\[scroll-other-window] should scroll its window.  */);
   Vother_window_scroll_buffer = Qnil;
 
   DEFVAR_BOOL ("auto-window-vscroll", auto_window_vscroll_p,
@@ -7217,6 +7214,7 @@ on their symbols to be controlled by this variable.  */);
   DEFVAR_LISP ("window-point-insertion-type", Vwindow_point_insertion_type,
               doc: /* Type of marker to use for `window-point'.  */);
   Vwindow_point_insertion_type = Qnil;
+  DEFSYM (Qwindow_point_insertion_type, "window_point_insertion_type");
 
   DEFVAR_LISP ("window-configuration-change-hook",
               Vwindow_configuration_change_hook,