]> code.delx.au - gnu-emacs/blobdiff - src/window.c
Remove undefined behavior in OS X dumper.
[gnu-emacs] / src / window.c
index bbe47c7255a302d493e72ff496178ae211ec5bc4..733cf75d1321b87ced5a51767c496f7fdbcedbce 100644 (file)
@@ -7,8 +7,8 @@ This file is part of GNU Emacs.
 
 GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 
 GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -35,6 +35,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "dispextern.h"
 #include "blockinput.h"
 #include "termhooks.h"         /* For FRAME_TERMINAL.  */
 #include "dispextern.h"
 #include "blockinput.h"
 #include "termhooks.h"         /* For FRAME_TERMINAL.  */
+#include "xwidget.h"
 #ifdef HAVE_WINDOW_SYSTEM
 #include TERM_HEADER
 #endif /* HAVE_WINDOW_SYSTEM */
 #ifdef HAVE_WINDOW_SYSTEM
 #include TERM_HEADER
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -669,7 +670,7 @@ DEFUN ("set-window-combination-limit", Fset_window_combination_limit, Sset_windo
 WINDOW must be a valid window used in horizontal or vertical combination.
 If LIMIT is nil, child windows of WINDOW can be recombined with WINDOW's
 siblings.  LIMIT t means that child windows of WINDOW are never
 WINDOW must be a valid window used in horizontal or vertical combination.
 If LIMIT is nil, child windows of WINDOW can be recombined with WINDOW's
 siblings.  LIMIT t means that child windows of WINDOW are never
-(re-)combined with WINDOW's siblings.  Other values are reserved for
+\(re-)combined with WINDOW's siblings.  Other values are reserved for
 future use.  */)
   (Lisp_Object window, Lisp_Object limit)
 {
 future use.  */)
   (Lisp_Object window, Lisp_Object limit)
 {
@@ -1323,7 +1324,7 @@ DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p,
 WINDOW must be a live window and defaults to the selected one.
 COORDINATES is a cons of the form (X . Y), X and Y being distances
 measured in characters from the upper-left corner of the frame.
 WINDOW must be a live window and defaults to the selected one.
 COORDINATES is a cons of the form (X . Y), X and Y being distances
 measured in characters from the upper-left corner of the frame.
-(0 . 0) denotes the character in the upper left corner of the
+\(0 . 0) denotes the character in the upper left corner of the
 frame.
 If COORDINATES are in the text portion of WINDOW,
    the coordinates relative to the window are returned.
 frame.
 If COORDINATES are in the text portion of WINDOW,
    the coordinates relative to the window are returned.
@@ -1709,7 +1710,7 @@ of the window.  The remaining elements are omitted if the character after
 POS is fully visible; otherwise, RTOP and RBOT are the number of pixels
 off-window at the top and bottom of the screen line ("row") containing
 POS, ROWH is the visible height of that row, and VPOS is the row number
 POS is fully visible; otherwise, RTOP and RBOT are the number of pixels
 off-window at the top and bottom of the screen line ("row") containing
 POS, ROWH is the visible height of that row, and VPOS is the row number
-(zero-based).  */)
+\(zero-based).  */)
   (Lisp_Object pos, Lisp_Object window, Lisp_Object partially)
 {
   struct window *w;
   (Lisp_Object pos, Lisp_Object window, Lisp_Object partially)
 {
   struct window *w;
@@ -4370,6 +4371,7 @@ Signal an error when WINDOW is the only window on its frame.  */)
 
       /* Block input.  */
       block_input ();
 
       /* Block input.  */
       block_input ();
+      xwidget_view_delete_all_in_window (w);
       window_resize_apply (p, horflag);
       /* If this window is referred to by the dpyinfo's mouse
         highlight, invalidate that slot to be safe (Bug#9904).  */
       window_resize_apply (p, horflag);
       /* If this window is referred to by the dpyinfo's mouse
         highlight, invalidate that slot to be safe (Bug#9904).  */
@@ -4981,27 +4983,34 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
 
   if (n > 0)
     {
 
   if (n > 0)
     {
+      int last_y = it.last_visible_y - this_scroll_margin - 1;
+
       /* We moved the window start towards ZV, so PT may be now
         in the scroll margin at the top.  */
       move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
       /* We moved the window start towards ZV, so PT may be now
         in the scroll margin at the top.  */
       move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
-      if (IT_CHARPOS (it) == PT && it.current_y >= this_scroll_margin
+      if (IT_CHARPOS (it) == PT
+         && it.current_y >= this_scroll_margin
+         && it.current_y <= last_y - WINDOW_HEADER_LINE_HEIGHT (w)
           && (NILP (Vscroll_preserve_screen_position)
              || EQ (Vscroll_preserve_screen_position, Qt)))
        /* We found PT at a legitimate height.  Leave it alone.  */
        ;
           && (NILP (Vscroll_preserve_screen_position)
              || EQ (Vscroll_preserve_screen_position, Qt)))
        /* We found PT at a legitimate height.  Leave it alone.  */
        ;
-      else if (window_scroll_pixel_based_preserve_y >= 0)
-       {
-         /* If we have a header line, take account of it.
-            This is necessary because we set it.current_y to 0, above.  */
-         move_it_to (&it, -1,
-                     window_scroll_pixel_based_preserve_x,
-                     (window_scroll_pixel_based_preserve_y
-                      - WINDOW_WANTS_HEADER_LINE_P (w)),
-                     -1, MOVE_TO_Y | MOVE_TO_X);
-         SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
-       }
       else
        {
       else
        {
+         if (window_scroll_pixel_based_preserve_y >= 0)
+           {
+             /* Don't enter the scroll margin at the end of the window.  */
+             int goal_y = min (last_y, window_scroll_pixel_based_preserve_y);
+
+             /* If we have a header line, take account of it.  This
+                is necessary because we set it.current_y to 0, above.  */
+             move_it_to (&it, -1,
+                         window_scroll_pixel_based_preserve_x,
+                         goal_y - WINDOW_HEADER_LINE_HEIGHT (w),
+                         -1, MOVE_TO_Y | MOVE_TO_X);
+           }
+
+         /* Get out of the scroll margin at the top of the window.  */
          while (it.current_y < this_scroll_margin)
            {
              int prev = it.current_y;
          while (it.current_y < this_scroll_margin)
            {
              int prev = it.current_y;
@@ -5025,7 +5034,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
       /* We moved the window start towards BEGV, so PT may be now
         in the scroll margin at the bottom.  */
       move_it_to (&it, PT, -1,
       /* We moved the window start towards BEGV, so PT may be now
         in the scroll margin at the bottom.  */
       move_it_to (&it, PT, -1,
-                 (it.last_visible_y - CURRENT_HEADER_LINE_HEIGHT (w)
+                 (it.last_visible_y - WINDOW_HEADER_LINE_HEIGHT (w)
                   - this_scroll_margin - 1),
                  -1,
                  MOVE_TO_POS | MOVE_TO_Y);
                   - this_scroll_margin - 1),
                  -1,
                  MOVE_TO_POS | MOVE_TO_Y);
@@ -5076,14 +5085,20 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
        ;
       else if (window_scroll_pixel_based_preserve_y >= 0)
        {
        ;
       else if (window_scroll_pixel_based_preserve_y >= 0)
        {
+         int goal_y = min (it.last_visible_y - this_scroll_margin - 1,
+                           window_scroll_pixel_based_preserve_y);
+
+         /* Don't let the preserved screen Y coordinate put us inside
+            any of the two margins.  */
+         if (goal_y < this_scroll_margin)
+           goal_y = this_scroll_margin;
          SET_TEXT_POS_FROM_MARKER (start, w->start);
          start_display (&it, w, start);
          /* It would be wrong to subtract CURRENT_HEADER_LINE_HEIGHT
             here because we called start_display again and did not
             alter it.current_y this time.  */
          move_it_to (&it, -1, window_scroll_pixel_based_preserve_x,
          SET_TEXT_POS_FROM_MARKER (start, w->start);
          start_display (&it, w, start);
          /* It would be wrong to subtract CURRENT_HEADER_LINE_HEIGHT
             here because we called start_display again and did not
             alter it.current_y this time.  */
          move_it_to (&it, -1, window_scroll_pixel_based_preserve_x,
-                     window_scroll_pixel_based_preserve_y, -1,
-                     MOVE_TO_Y | MOVE_TO_X);
+                     goal_y, -1, MOVE_TO_Y | MOVE_TO_X);
          SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
        }
       else
          SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
        }
       else
@@ -5199,6 +5214,7 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror)
       w->force_start = true;
 
       if (!NILP (Vscroll_preserve_screen_position)
       w->force_start = true;
 
       if (!NILP (Vscroll_preserve_screen_position)
+         && this_scroll_margin == 0
          && (whole || !EQ (Vscroll_preserve_screen_position, Qt)))
        {
          SET_PT_BOTH (pos, pos_byte);
          && (whole || !EQ (Vscroll_preserve_screen_position, Qt)))
        {
          SET_PT_BOTH (pos, pos_byte);
@@ -5224,8 +5240,16 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror)
                         marker_byte_position (opoint_marker));
          else if (!NILP (Vscroll_preserve_screen_position))
            {
                         marker_byte_position (opoint_marker));
          else if (!NILP (Vscroll_preserve_screen_position))
            {
+             int nlines = window_scroll_preserve_vpos;
+
              SET_PT_BOTH (pos, pos_byte);
              SET_PT_BOTH (pos, pos_byte);
-             Fvertical_motion (original_pos, window, Qnil);
+             if (window_scroll_preserve_vpos < this_scroll_margin)
+               nlines = this_scroll_margin;
+             else if (window_scroll_preserve_vpos
+                      >= w->total_lines - this_scroll_margin)
+               nlines = w->total_lines - this_scroll_margin - 1;
+             Fvertical_motion (Fcons (make_number (window_scroll_preserve_hpos),
+                                      make_number (nlines)), window, Qnil);
            }
          else
            SET_PT (top_margin);
            }
          else
            SET_PT (top_margin);
@@ -5251,8 +5275,16 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror)
            {
              if (!NILP (Vscroll_preserve_screen_position))
                {
            {
              if (!NILP (Vscroll_preserve_screen_position))
                {
+                 int nlines = window_scroll_preserve_vpos;
+
                  SET_PT_BOTH (pos, pos_byte);
                  SET_PT_BOTH (pos, pos_byte);
-                 Fvertical_motion (original_pos, window, Qnil);
+                 if (window_scroll_preserve_vpos < this_scroll_margin)
+                   nlines = this_scroll_margin;
+                 else if (window_scroll_preserve_vpos
+                          >= ht - this_scroll_margin)
+                   nlines = ht - this_scroll_margin - 1;
+                 Fvertical_motion (Fcons (make_number (window_scroll_preserve_hpos),
+                                          make_number (nlines)), window, Qnil);
                }
              else
                Fvertical_motion (make_number (-1), window, Qnil);
                }
              else
                Fvertical_motion (make_number (-1), window, Qnil);
@@ -7231,7 +7263,7 @@ resizing a window preferably resizes one adjacent window only.
 
 If this variable is t, splitting a window tries to get the space
 proportionally from all windows in the same combination.  This also
 
 If this variable is t, splitting a window tries to get the space
 proportionally from all windows in the same combination.  This also
-allows to split a window that is otherwise too small or of fixed size.
+allows splitting a window that is otherwise too small or of fixed size.
 Resizing and deleting a window proportionally resize all windows in the
 same combination.
 
 Resizing and deleting a window proportionally resize all windows in the
 same combination.