changeset 39449:e0fb6798db26

(make_cursor_line_fully_visible): Return 0 and set fonts_changed_p if need larger matrices due to vscrolling. (try_scrolling, try_cursor_movement, redisplay_window): Give up on this round of redisplay if make_cursor_line_fully_visible fails. (CURSOR_MOVEMENT_*, SCROLLING_*): New enumerators. (try_cursor_movement, try_scrolling): Use them instead of integers.
author Gerd Moellmann <gerd@gnu.org>
date Wed, 26 Sep 2001 11:27:06 +0000
parents b74c165ef22f
children 3ffa3a6c42e2
files src/xdisp.c
diffstat 1 files changed, 117 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/src/xdisp.c	Wed Sep 26 11:15:40 2001 +0000
+++ b/src/xdisp.c	Wed Sep 26 11:27:06 2001 +0000
@@ -708,7 +708,7 @@
 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
 static void extend_face_to_end_of_line P_ ((struct it *));
 static int append_space P_ ((struct it *, int));
-static void make_cursor_line_fully_visible P_ ((struct window *));
+static int make_cursor_line_fully_visible P_ ((struct window *));
 static int try_scrolling P_ ((Lisp_Object, int, int, int, int));
 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
 static int trailing_whitespace_p P_ ((int));
@@ -9284,9 +9284,11 @@
 
 
 /* Modify the desired matrix of window W and W->vscroll so that the
-   line containing the cursor is fully visible.  */
-
-static void
+   line containing the cursor is fully visible.  If this requires
+   larger matrices than are allocated, set fonts_changed_p and return
+   0.  */
+
+static int
 make_cursor_line_fully_visible (w)
      struct window *w;
 {
@@ -9297,7 +9299,7 @@
   /* It's not always possible to find the cursor, e.g, when a window
      is full of overlay strings.  Don't do anything in that case.  */
   if (w->cursor.vpos < 0)
-    return;
+    return 1;
   
   matrix = w->desired_matrix;
   row = MATRIX_ROW (matrix, w->cursor.vpos);
@@ -9305,13 +9307,13 @@
   /* If the cursor row is not partially visible, there's nothing
      to do.  */
   if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
-    return;
+    return 1;
 
   /* If the row the cursor is in is taller than the window's height,
      it's not clear what to do, so do nothing.  */
   window_height = window_box_height (w);
   if (row->height >= window_height)
-    return;
+    return 1;
 
   if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
     {
@@ -9334,6 +9336,16 @@
      the correct y-position.  */
   if (w == XWINDOW (selected_window))
     this_line_y = w->cursor.y;
+
+  /* If vscrolling requires a larger glyph matrix, arrange for a fresh
+     redisplay with larger matrices.  */
+  if (matrix->nrows < required_matrix_height (w))
+    {
+      fonts_changed_p = 1;
+      return 0;
+    }
+
+  return 1;
 }
 
 
@@ -9352,6 +9364,13 @@
    -1	if new fonts have been loaded so that we must interrupt
    redisplay, adjust glyph matrices, and try again.  */
 
+enum
+{
+  SCROLLING_SUCCESS,
+  SCROLLING_FAILED,
+  SCROLLING_NEED_LARGER_MATRICES
+};
+
 static int
 try_scrolling (window, just_this_one_p, scroll_conservatively,
 	       scroll_step, temp_scroll_step)
@@ -9441,7 +9460,7 @@
       dy = 1 + it.current_y - y0;
       
       if (dy > scroll_max)
-	return 0;
+	return SCROLLING_FAILED;
       
       /* Move the window start down.  If scrolling conservatively,
 	 move it just enough down to make point visible.  If
@@ -9464,7 +9483,7 @@
 	}
 
       if (amount_to_scroll <= 0)
-	return 0;
+	return SCROLLING_FAILED;
 
       move_it_vertically (&it, amount_to_scroll);
       startp = it.current.pos;
@@ -9498,7 +9517,7 @@
 		      MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
 	  dy = it.current_y - y0;
 	  if (dy > scroll_max)
-	    return 0;
+	    return SCROLLING_FAILED;
 	  
 	  /* Compute new window start.  */
 	  start_display (&it, w, startp);
@@ -9518,7 +9537,7 @@
 	    }
 
 	  if (amount_to_scroll <= 0)
-	    return 0;
+	    return SCROLLING_FAILED;
 	  
 	  move_it_vertically (&it, - amount_to_scroll);
 	  startp = it.current.pos;
@@ -9531,11 +9550,11 @@
   /* Display the window.  Give up if new fonts are loaded, or if point
      doesn't appear.  */
   if (!try_window (window, startp))
-    rc = -1;
+    rc = SCROLLING_NEED_LARGER_MATRICES;
   else if (w->cursor.vpos < 0)
     {
       clear_glyph_matrix (w->desired_matrix);
-      rc = 0;
+      rc = SCROLLING_FAILED;
     }
   else
     {
@@ -9546,9 +9565,12 @@
 	w->base_line_number = Qnil;
       
       /* If cursor ends up on a partially visible line, shift display
-	 lines up or down.  */
-      make_cursor_line_fully_visible (w);
-      rc = 1;
+	 lines up or down.  If that fails because we need larger
+	 matrices, give up.  */
+      if (!make_cursor_line_fully_visible (w))
+	rc = SCROLLING_NEED_LARGER_MATRICES;
+      else
+	rc = SCROLLING_SUCCESS;
     }
 
   return rc;
@@ -9630,13 +9652,25 @@
 /* Try cursor movement in case text has not changes in window WINDOW,
    with window start STARTP.  Value is
 
-   1	if successful
-   
-   0	if this method cannot be used
+   CURSOR_MOVEMENT_SUCCESS if successful
    
-   -1	if we know we have to scroll the display.  *SCROLL_STEP is
-   set to 1, under certain circumstances, if we want to scroll as
-   if scroll-step were set to 1.  See the code.  */
+   CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
+
+   CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
+   display.  *SCROLL_STEP is set to 1, under certain circumstances, if
+   we want to scroll as if scroll-step were set to 1.  See the code.
+
+   CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
+   which case we have to abort this redisplay, and adjust matrices
+   first.  */
+
+enum 
+{
+  CURSOR_MOVEMENT_SUCCESS,
+  CURSOR_MOVEMENT_CANNOT_BE_USED,
+  CURSOR_MOVEMENT_MUST_SCROLL,
+  CURSOR_MOVEMENT_NEED_LARGER_MATRICES
+};
 
 static int
 try_cursor_movement (window, startp, scroll_step)
@@ -9646,7 +9680,7 @@
 {
   struct window *w = XWINDOW (window);
   struct frame *f = XFRAME (w->frame);
-  int rc = 0;
+  int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
   
   /* Handle case where text has not changed, only point, and it has
      not moved off the frame.  */
@@ -9704,17 +9738,17 @@
 	 not paused redisplay.  Give up if that row is not valid.  */
       if (w->last_cursor.vpos < 0
 	  || w->last_cursor.vpos >= w->current_matrix->nrows)
-	rc = -1;
+	rc = CURSOR_MOVEMENT_MUST_SCROLL;
       else
 	{
 	  row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
 	  if (row->mode_line_p)
 	    ++row;
 	  if (!row->enabled_p)
-	    rc = -1;
-	}
-
-      if (rc == 0)
+	    rc = CURSOR_MOVEMENT_MUST_SCROLL;
+	}
+
+      if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
 	{
 	  int scroll_p = 0;
 	  int last_y = window_text_bottom_y (w) - this_scroll_margin;
@@ -9797,14 +9831,14 @@
 	      || PT > MATRIX_ROW_END_CHARPOS (row))
 	    {
 	      /* if PT is not in the glyph row, give up.  */
-	      rc = -1;
+	      rc = CURSOR_MOVEMENT_MUST_SCROLL;
 	    }
 	  else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
 	    {
 	      if (PT == MATRIX_ROW_END_CHARPOS (row)
 		  && !row->ends_at_zv_p
 		  && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
-		rc = -1;
+		rc = CURSOR_MOVEMENT_MUST_SCROLL;
 	      else if (row->height > window_box_height (w))
 		{
 		  /* If we end up in a partially visible line, let's
@@ -9812,22 +9846,24 @@
 		     than the window, in which case we can't do much
 		     about it.  */
 		  *scroll_step = 1;
-		  rc = -1;
+		  rc = CURSOR_MOVEMENT_MUST_SCROLL;
 		}
 	      else
 		{
 		  set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
 		  try_window (window, startp);
-		  make_cursor_line_fully_visible (w);
-		  rc = 1;
+		  if (!make_cursor_line_fully_visible (w))
+		    rc = CURSOR_MOVEMENT_NEED_LARGER_MATRICES;
+		  else
+		    rc = CURSOR_MOVEMENT_SUCCESS;
 		}
 	    }
 	  else if (scroll_p)
-	    rc = -1;
+	    rc = CURSOR_MOVEMENT_MUST_SCROLL;
 	  else
 	    {
 	      set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
-	      rc = 1;
+	      rc = CURSOR_MOVEMENT_SUCCESS;
 	    }
 	}
     }
@@ -10101,11 +10137,12 @@
 	    {
 	      clear_glyph_matrix (w->desired_matrix);
 	      if (!try_window (window, startp))
-		goto finish_scroll_bars;
-	    }
-	}
-
-      make_cursor_line_fully_visible (w);
+		goto need_larger_matrices;
+	    }
+	}
+
+      if (!make_cursor_line_fully_visible (w))
+	goto need_larger_matrices;
 #if GLYPH_DEBUG
       debug_method_add (w, "forced window start");
 #endif
@@ -10116,12 +10153,22 @@
      not moved off the frame.  */
   if (current_matrix_up_to_date_p
       && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
-	  rc != 0))
-    {
-      if (rc == -1)
-	goto try_to_scroll;
-      else
-	goto done;
+	  rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
+    {
+      switch (rc)
+	{
+	case CURSOR_MOVEMENT_SUCCESS:
+	  goto done;
+	  
+	case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
+	  goto need_larger_matrices;
+	  
+	case CURSOR_MOVEMENT_MUST_SCROLL:
+	  goto try_to_scroll;
+	  
+	default:
+	  abort ();
+	}
     }
   /* If current starting point was originally the beginning of a line
      but no longer is, find a new starting point.  */
@@ -10145,7 +10192,7 @@
 #endif
 
       if (fonts_changed_p)
-	goto finish_scroll_bars;
+	goto need_larger_matrices;
       if (tem > 0)
 	goto done;
 
@@ -10180,7 +10227,7 @@
 	}
 
       if (fonts_changed_p)
-	goto finish_scroll_bars;
+	goto need_larger_matrices;
       
       if (w->cursor.vpos >= 0)
 	{
@@ -10190,7 +10237,8 @@
 	    /* Forget any recorded base line for line number display.  */
 	    w->base_line_number = Qnil;
 	  
-	  make_cursor_line_fully_visible (w);
+	  if (!make_cursor_line_fully_visible (w))
+	    goto need_larger_matrices;
 	  goto done;
 	}
       else
@@ -10225,10 +10273,20 @@
 			      scroll_conservatively,
 			      scroll_step,
 			      temp_scroll_step);
-      if (rc > 0)
-	goto done;
-      else if (rc < 0)
-	goto finish_scroll_bars;
+      switch (rc)
+	{
+	case SCROLLING_SUCCESS:
+	  goto done;
+	  
+	case SCROLLING_NEED_LARGER_MATRICES:
+	  goto need_larger_matrices;
+	  
+	case SCROLLING_FAILED:
+	  break;
+	  
+	default:
+	  abort ();
+	}
     }
 
   /* Finally, just choose place to start which centers point */
@@ -10289,7 +10347,7 @@
      have to start a new redisplay since we need to re-adjust glyph
      matrices.  */
   if (fonts_changed_p)
-    goto finish_scroll_bars;
+    goto need_larger_matrices;
 
   /* If cursor did not appear assume that the middle of the window is
      in the first line of the window.  Do it again with the next line.
@@ -10329,7 +10387,8 @@
       set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
     }
   
-  make_cursor_line_fully_visible (w);
+  if (!make_cursor_line_fully_visible (w))
+    goto need_larger_matrices;
 
  done:
 
@@ -10379,7 +10438,7 @@
 	}
 
       if (fonts_changed_p)
-	goto finish_scroll_bars;
+	goto need_larger_matrices;
     }
 
   if (!line_number_displayed
@@ -10419,6 +10478,8 @@
 #endif
     }
 
+ need_larger_matrices:
+  ;
  finish_scroll_bars:
 
   if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))