]> code.delx.au - gnu-emacs/blobdiff - src/dispnew.c
(adjust_glyph_matrix, enable_glyph_matrix_rows):
[gnu-emacs] / src / dispnew.c
index f2cd62094cfaaa848c080872007d3966347177dd..b20383dcfa91920c74ccb9937a4cade2f251092f 100644 (file)
@@ -37,6 +37,7 @@ Boston, MA 02111-1307, USA.  */
 #include "cm.h"
 #include "buffer.h"
 #include "charset.h"
+#include "keyboard.h"
 #include "frame.h"
 #include "window.h"
 #include "commands.h"
@@ -45,7 +46,6 @@ Boston, MA 02111-1307, USA.  */
 #include "intervals.h"
 #include "blockinput.h"
 #include "process.h"
-#include "keyboard.h"
 
 /* I don't know why DEC Alpha OSF1 fail to compile this file if we
    include the following file.  */
@@ -241,7 +241,7 @@ Lisp_Object Vstandard_display_table;
 
 int cursor_in_echo_area;
 
-Lisp_Object Qdisplay_table;
+Lisp_Object Qdisplay_table, Qredisplay_dont_pause;
 
 \f
 /* The currently selected frame.  In a single-frame version, this
@@ -667,6 +667,7 @@ adjust_glyph_matrix (w, matrix, x, y, dim)
   
   /* Number of rows to be used by MATRIX.  */
   matrix->nrows = dim.height;
+  xassert (matrix->nrows >= 0);
 
   /* Mark rows in a current matrix of a window as not having valid
      contents.  It's important to not do this for desired matrices.
@@ -2454,6 +2455,7 @@ build_frame_matrix_from_leaf_window (frame_matrix, w)
     {
       struct glyph_row *frame_row = frame_matrix->rows + frame_y;
       struct glyph_row *window_row = window_matrix->rows + window_y;
+      int current_row_p = window_matrix == w->current_matrix;
 
       /* Fill up the frame row with spaces up to the left margin of the
         window row.  */
@@ -2461,19 +2463,32 @@ build_frame_matrix_from_leaf_window (frame_matrix, w)
 
       /* Fill up areas in the window matrix row with spaces.  */
       fill_up_glyph_row_with_spaces (window_row);
+
+      /* If only part of W's desired matrix has been built, and
+         window_row wasn't displayed, use the corresponding current
+         row instead.  */
+      if (window_matrix == w->desired_matrix
+         && !window_row->enabled_p)
+       {
+         window_row = w->current_matrix->rows + window_y;
+         current_row_p = 1;
+       }
       
-      if (window_matrix == w->current_matrix)
+      if (current_row_p)
        {
-         /* We have to copy W's current matrix.  Copy window
-            row to frame row.  */
+         /* Copy window row to frame row.  */
          bcopy (window_row->glyphs[0],
                 frame_row->glyphs[TEXT_AREA] + window_matrix->matrix_x,
                 window_matrix->matrix_w * sizeof (struct glyph));
        }
       else
        {
-         /* Copy W's desired matrix.  */
-
+         xassert (window_row->enabled_p);
+         
+         /* Only when a desired row has been displayed, we want
+            the corresponding frame row to be updated.  */
+         frame_row->enabled_p = 1;
+         
           /* Maybe insert a vertical border between horizontally adjacent
             windows.  */
           if (right_border_glyph)
@@ -2523,8 +2538,7 @@ build_frame_matrix_from_leaf_window (frame_matrix, w)
       frame_row->used[TEXT_AREA] 
        = window_matrix->matrix_x + window_matrix->matrix_w;
 
-      /* Or in flags.  */
-      frame_row->enabled_p |= window_row->enabled_p;
+      /* Or in other flags.  */
       frame_row->inverse_p |= window_row->inverse_p;
 
       /* Next row.  */
@@ -3443,11 +3457,13 @@ direct_output_forward_char (n)
 
   row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
 
+  /* Give up if PT is outside of the last known cursor row.  */
   if (PT <= MATRIX_ROW_START_BYTEPOS (row)
       || PT >= MATRIX_ROW_END_BYTEPOS (row))
     return 0;
 
   set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
+  
   w->last_cursor = w->cursor;
   XSETFASTINT (w->last_point, PT);
 
@@ -3545,10 +3561,9 @@ update_frame (f, force_p, inhibit_hairy_id_p)
       /* Update windows.  */
       paused_p = update_window_tree (root_window, force_p);
       update_end (f);
-      display_completed = !paused_p;
-
-      /* The flush is a performance bottleneck under X.  */
-#if 0
+      
+#if 0 /* This flush is a performance bottleneck under X,
+        and it doesn't seem to be necessary anyway.  */
       rif->flush_display (f);
 #endif
     }
@@ -3558,21 +3573,26 @@ update_frame (f, force_p, inhibit_hairy_id_p)
         frame matrix we operate.  */
       set_frame_matrix_frame (f);
 
-      /* Build F's desired matrix from window matrices.  For windows
-        whose must_be_updated_p flag is set, desired matrices are
-        made part of the desired frame matrix.  For other windows,
-        the current matrix is copied.  */
+      /* Build F's desired matrix from window matrices.  */
       build_frame_matrix (f);
       
-      /* Do the update on the frame desired matrix.  */
+      /* Update the display  */
+      update_begin (f);
       paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p);
-      
+      update_end (f);
+
+      if (termscript)
+       fflush (termscript);
+      fflush (stdout);
+
       /* Check window matrices for lost pointers.  */
       IF_DEBUG (check_window_matrix_pointers (root_window));
     }
 
   /* Reset flags indicating that a window should be updated.  */
   set_window_update_flags (root_window, 0);
+  
+  display_completed = !paused_p;
   return paused_p;
 }
 
@@ -3793,7 +3813,7 @@ update_window (w, force_p)
       while (row < end && !row->enabled_p)
        ++row;
       
-      /* Try reusing part of the display by inserting/deleting lines.  */
+      /* Try reusing part of the display by copying.  */
       if (row < end && !desired_matrix->no_scrolling_p)
        {
          int rc = scrolling_window (w, header_line_row != NULL);
@@ -3820,11 +3840,7 @@ update_window (w, force_p)
 
       /* Update the rest of the lines.  */
       for (; row < end && (force_p || !input_pending); ++row)
-       if (row->enabled_p
-           /* A row can be completely invisible in case a desired
-              matrix was built with a vscroll and then
-              make_cursor_line_fully_visible shifts the matrix.  */
-           && row->visible_height > 0)
+       if (row->enabled_p)
          {
            int vpos = MATRIX_ROW_VPOS (row, desired_matrix);
            int i;
@@ -4110,51 +4126,59 @@ update_window_line (w, vpos, mouse_face_overwritten_p)
   struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
   int changed_p = 0;
 
-  xassert (desired_row->enabled_p);
-
   /* Set the row being updated.  This is important to let xterm.c
      know what line height values are in effect.  */
   updated_row = desired_row;
 
-  /* Update display of the left margin area, if there is one.  */
-  if (!desired_row->full_width_p
-      && !NILP (w->left_margin_width))
-    {
-      changed_p = 1;
-      update_marginal_area (w, LEFT_MARGIN_AREA, vpos);
-    }
-  
-  /* Update the display of the text area.  */
-  if (update_text_area (w, vpos))
+  /* A row can be completely invisible in case a desired matrix was 
+     built with a vscroll and then make_cursor_line_fully_visible shifts 
+     the matrix.  Make sure to make such rows current anyway, since
+     we need the correct y-position, for example, in the current matrix.  */
+  if (desired_row->mode_line_p
+      || desired_row->visible_height > 0)
     {
-      changed_p = 1;
-      if (current_row->mouse_face_p)
-       *mouse_face_overwritten_p = 1;
-    }
-  
-  /* Update display of the right margin area, if there is one.  */
-  if (!desired_row->full_width_p
-      && !NILP (w->right_margin_width))
-    {
-      changed_p = 1;
-      update_marginal_area (w, RIGHT_MARGIN_AREA, vpos);
+      xassert (desired_row->enabled_p);
+
+      /* Update display of the left margin area, if there is one.  */
+      if (!desired_row->full_width_p
+         && !NILP (w->left_margin_width))
+       {
+         changed_p = 1;
+         update_marginal_area (w, LEFT_MARGIN_AREA, vpos);
+       }
+      
+      /* Update the display of the text area.  */
+      if (update_text_area (w, vpos))
+       {
+         changed_p = 1;
+         if (current_row->mouse_face_p)
+           *mouse_face_overwritten_p = 1;
+       }
+      
+      /* Update display of the right margin area, if there is one.  */
+      if (!desired_row->full_width_p
+         && !NILP (w->right_margin_width))
+       {
+         changed_p = 1;
+         update_marginal_area (w, RIGHT_MARGIN_AREA, vpos);
+       }
+      
+      /* Draw truncation marks etc.  */
+      if (!current_row->enabled_p
+         || desired_row->y != current_row->y
+         || desired_row->visible_height != current_row->visible_height
+         || desired_row->overlay_arrow_p != current_row->overlay_arrow_p
+         || desired_row->truncated_on_left_p != current_row->truncated_on_left_p
+         || desired_row->truncated_on_right_p != current_row->truncated_on_right_p
+         || desired_row->continued_p != current_row->continued_p
+         || desired_row->mode_line_p != current_row->mode_line_p
+         || (desired_row->indicate_empty_line_p
+             != current_row->indicate_empty_line_p)
+         || (MATRIX_ROW_CONTINUATION_LINE_P (desired_row)
+             != MATRIX_ROW_CONTINUATION_LINE_P (current_row)))
+       rif->after_update_window_line_hook (desired_row);
     }
   
-  /* Draw truncation marks etc.  */
-  if (!current_row->enabled_p
-      || desired_row->y != current_row->y
-      || desired_row->visible_height != current_row->visible_height
-      || desired_row->overlay_arrow_p != current_row->overlay_arrow_p
-      || desired_row->truncated_on_left_p != current_row->truncated_on_left_p
-      || desired_row->truncated_on_right_p != current_row->truncated_on_right_p
-      || desired_row->continued_p != current_row->continued_p
-      || desired_row->mode_line_p != current_row->mode_line_p
-      || (desired_row->indicate_empty_line_p
-         != current_row->indicate_empty_line_p)
-      || (MATRIX_ROW_CONTINUATION_LINE_P (desired_row)
-         != MATRIX_ROW_CONTINUATION_LINE_P (current_row)))
-    rif->after_update_window_line_hook (desired_row);
-  
   /* Update current_row from desired_row.  */
   make_current (w->desired_matrix, w->current_matrix, vpos);
   updated_row = NULL;
@@ -4400,20 +4424,23 @@ scrolling_window (w, header_line_p)
   struct row_entry *entry;
 
   /* Skip over rows equal at the start.  */
-  i = header_line_p ? 1 : 0;
-  while (i < current_matrix->nrows - 1
-         && MATRIX_ROW_ENABLED_P (current_matrix, i)
-        && MATRIX_ROW_ENABLED_P (desired_matrix, i)
-        && MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (desired_matrix, i)) <= yb
-        && MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (current_matrix, i)) <= yb
-         && row_equal_p (w,
-                        MATRIX_ROW (desired_matrix, i),
-                         MATRIX_ROW (current_matrix, i), 1))
+  for (i = header_line_p ? 1 : 0; i < current_matrix->nrows - 1; ++i)
     {
-      assign_row (MATRIX_ROW (current_matrix, i),
-                 MATRIX_ROW (desired_matrix, i));
-      MATRIX_ROW (desired_matrix, i)->enabled_p = 0;
-      ++i;
+      struct glyph_row *d = MATRIX_ROW (desired_matrix, i);
+      struct glyph_row *c = MATRIX_ROW (current_matrix, i);
+
+      if (c->enabled_p
+         && d->enabled_p
+         && c->y == d->y
+         && MATRIX_ROW_BOTTOM_Y (c) <= yb
+         && MATRIX_ROW_BOTTOM_Y (d) <= yb
+         && row_equal_p (w, c, d, 1))
+       {
+         assign_row (c, d);
+         d->enabled_p = 0;
+       }
+      else
+       break;
     }
 
   /* Give up if some rows in the desired matrix are not enabled.  */
@@ -4695,15 +4722,14 @@ update_frame_1 (f, force_p, inhibit_id_p)
   if (preempt_count <= 0)
     preempt_count = 1;
 
-  detect_input_pending ();
-  if (input_pending && !force_p)
+  if (redisplay_dont_pause)
+    force_p = 1;
+  else if (!force_p && detect_input_pending ())
     {
       pause = 1;
       goto do_pause;
     }
 
-  update_begin (f);
-
   /* If we cannot insert/delete lines, it's no use trying it.  */
   if (!line_ins_del_ok)
     inhibit_id_p = 1;
@@ -4859,15 +4885,8 @@ update_frame_1 (f, force_p, inhibit_id_p)
        }
     }
 
-  update_end (f);
-
-  if (termscript)
-    fflush (termscript);
-  fflush (stdout);
-
  do_pause:
 
-  display_completed = !pause;
   clear_desired_matrices (f);
   return pause;
 }
@@ -5426,7 +5445,9 @@ window_change_signal (signalnum) /* If we don't have an argument, */
      int signalnum;            /* some compilers complain in signal calls.  */
 {
   int width, height;
+#ifndef USE_CRT_DLL
   extern int errno;
+#endif
   int old_errno = errno;
 
   get_frame_size (&width, &height);
@@ -6225,6 +6246,8 @@ syms_of_display ()
 
   Qdisplay_table = intern ("display-table");
   staticpro (&Qdisplay_table);
+  Qredisplay_dont_pause = intern ("redisplay-dont-pause");
+  staticpro (&Qredisplay_dont_pause);
 
   DEFVAR_INT ("baud-rate", &baud_rate,
     "*The output baud rate of the terminal.\n\