(set_window_cursor_after_update): Fix code
[bpt/emacs.git] / src / dispnew.c
index 04532d4..abc41ad 100644 (file)
@@ -1,5 +1,5 @@
 /* Updating of data structures for redisplay.
-   Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 98, 1999, 2000
+   Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 98, 1999, 2000, 2001
        Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -104,7 +104,7 @@ Boston, MA 02111-1307, USA.  */
 #endif
 #endif /* not __GNU_LIBRARY__ */
 
-#if defined (LINUX) && defined (HAVE_LIBNCURSES)
+#if defined(HAVE_TERM_H) && defined (LINUX) && defined (HAVE_LIBNCURSES)
 #include <term.h>              /* for tgetent */
 #endif
 \f
@@ -790,18 +790,23 @@ adjust_glyph_matrix (w, matrix, x, y, dim)
             upper window).  Invalidate all rows that are no longer part
             of the window.  */
          if (!marginal_areas_changed_p
+             && !header_line_changed_p
+             && new_rows == 0
+             && dim.width == matrix->matrix_w
              && matrix->window_left_x == XFASTINT (w->left)
              && matrix->window_top_y == XFASTINT (w->top)
-             && matrix->window_width == window_box_width (w, -1))
+             && matrix->window_width == window_width)
            {
-             i = 0;
-             while (matrix->rows[i].enabled_p
-                    && (MATRIX_ROW_BOTTOM_Y (matrix->rows + i)
-                        < matrix->window_height))
-               ++i;
+             /* Find the last row in the window.  */
+             for (i = 0; i < matrix->nrows && matrix->rows[i].enabled_p; ++i)
+               if (MATRIX_ROW_BOTTOM_Y (matrix->rows + i) >= window_height)
+                 {
+                   ++i;
+                   break;
+                 }
 
              /* Window end is invalid, if inside of the rows that
-                are invalidated.  */
+                are invalidated below.  */
              if (INTEGERP (w->window_end_vpos)
                  && XFASTINT (w->window_end_vpos) >= i)
                w->window_end_valid = Qnil;
@@ -989,13 +994,12 @@ shift_glyph_matrix (w, matrix, start, end, dy)
       struct glyph_row *row = &matrix->rows[start];
       
       row->y += dy;
+      row->visible_height = row->height;
       
       if (row->y < min_y)
-       row->visible_height = row->height - (min_y - row->y);
-      else if (row->y + row->height > max_y)
-       row->visible_height = row->height - (row->y + row->height - max_y);
-      else
-       row->visible_height = row->height;
+       row->visible_height -= min_y - row->y;
+      if (row->y + row->height > max_y)
+       row->visible_height -= row->y + row->height - max_y;
     }
 }
 
@@ -1149,13 +1153,12 @@ blank_row (w, row, y)
   row->y = y;
   row->ascent = row->phys_ascent = 0;
   row->height = row->phys_height = CANON_Y_UNIT (XFRAME (w->frame));
-  
+  row->visible_height = row->height;
+      
   if (row->y < min_y)
-    row->visible_height = row->height - (min_y - row->y);
-  else if (row->y + row->height > max_y)
-    row->visible_height = row->height - (row->y + row->height - max_y);
-  else
-    row->visible_height = row->height;
+    row->visible_height -= min_y - row->y;
+  if (row->y + row->height > max_y)
+    row->visible_height -= row->y + row->height - max_y;
 
   row->enabled_p = 1;
 }
@@ -3416,6 +3419,10 @@ direct_output_for_insert (g)
       || g == '\r'
       /* Give up if unable to display the cursor in the window.  */
       || w->cursor.vpos < 0
+      /* Give up if we are showing a message or just cleared the message
+        because we might need to resize the echo area window.  */
+      || !NILP (echo_area_buffer[0])
+      || !NILP (echo_area_buffer[1])
       || (glyph_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos),
          /* Can't do it in a continued line because continuation
             lines would change.  */
@@ -3475,6 +3482,7 @@ direct_output_for_insert (g)
   it.current_y = w->cursor.y;
   it.end_charpos = PT;
   it.stop_charpos = min (PT, it.stop_charpos);
+  it.stop_charpos = max (IT_CHARPOS (it), it.stop_charpos);
 
   /* More than one display element may be returned for PT - 1 if
      (i) it's a control character which is translated into `\003' or
@@ -3579,12 +3587,16 @@ direct_output_for_insert (g)
      implemented for X frames.  The implementation uses updated_window
      and updated_row.  */
   updated_row = glyph_row;
+  updated_area = TEXT_AREA;
   update_begin (f);
   if (rif)
     {
       rif->update_window_begin_hook (w);
       
-      if (glyphs == end - n)
+      if (glyphs == end - n
+         /* In front of a space added by append_space.  */
+         || (glyphs == end - n - 1
+             && (end - n)->charpos <= 0))
        rif->write_glyphs (glyphs, n);
       else
        rif->insert_glyphs (glyphs, n);
@@ -4043,7 +4055,7 @@ update_window (w, force_p)
     {
       struct glyph_row *row, *end;
       struct glyph_row *mode_line_row;
-      struct glyph_row *header_line_row = NULL;
+      struct glyph_row *header_line_row;
       int yb, changed_p = 0, mouse_face_overwritten_p = 0, n_updated;
 
       rif->update_window_begin_hook (w);
@@ -4053,8 +4065,14 @@ update_window (w, force_p)
         Adjust y-positions of other rows by the top line height.  */
       row = desired_matrix->rows;
       end = row + desired_matrix->nrows - 1;
+      
       if (row->mode_line_p)
-       header_line_row = row++;
+       {
+         header_line_row = row;
+         ++row;
+       }
+      else
+       header_line_row = NULL;
 
       /* Update the mode line, if necessary.  */
       mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix);
@@ -4084,6 +4102,7 @@ update_window (w, force_p)
              goto set_cursor;
            }
          else if (rc > 0)
+           /* We've scrolled the display.  */
            force_p = 1;
          changed_p = 1;
        }
@@ -4157,8 +4176,11 @@ update_window (w, force_p)
       strcpy (w->current_matrix->method, w->desired_matrix->method);
 #endif
 
-      /* End of update of window W.  */
-      rif->update_window_end_hook (w, 1, mouse_face_overwritten_p);
+      /* End the update of window W.  Don't set the cursor if we
+         paused updating the display because in this case,
+         set_window_cursor_after_update hasn't been called, and
+         output_cursor doesn't contain the cursor location.  */
+      rif->update_window_end_hook (w, !paused_p, mouse_face_overwritten_p);
     }
   else
     paused_p = 1;
@@ -4518,22 +4540,21 @@ set_window_cursor_after_update (w)
          int yb = window_text_bottom_y (w);
 
          last_row = NULL;
-         for (row = MATRIX_ROW (w->current_matrix, 0);
-              row->enabled_p;
-              ++row)
+         row = w->current_matrix->rows;
+         while (row->enabled_p
+                && (last_row == NULL
+                    || MATRIX_ROW_BOTTOM_Y (row) <= yb))
            {
              if (row->used[TEXT_AREA]
                  && row->glyphs[TEXT_AREA][0].charpos >= 0)
                last_row = row;
-
-             if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
-               break;
+             ++row;
            }
          
          if (last_row)
            {
-             struct glyph *start = row->glyphs[TEXT_AREA];
-             struct glyph *last = start + row->used[TEXT_AREA] - 1;
+             struct glyph *start = last_row->glyphs[TEXT_AREA];
+             struct glyph *last = start + last_row->used[TEXT_AREA] - 1;
 
              while (last > start && last->charpos < 0)
                --last;
@@ -5678,14 +5699,17 @@ update_frame_line (f, vpos)
                   X/Y Position -> Buffer Position
  ***********************************************************************/
 
-/* Return the character position of the character at window relative
-   pixel position (*X, *Y).  *X and *Y are adjusted to character
-   boundaries.  */
+/* Determine what's under window-relative pixel position (*X, *Y).
+   Return in *OBJECT the object (string or buffer) that's there.
+   Return in *POS the position in that object. Adjust *X and *Y
+   to character boundaries.  */
 
-int
-buffer_posn_from_coords (w, x, y)
+void
+buffer_posn_from_coords (w, x, y, object, pos)
      struct window *w;
      int *x, *y;
+     Lisp_Object *object;
+     struct display_pos *pos;
 {
   struct it it;
   struct buffer *old_current_buffer = current_buffer;
@@ -5705,7 +5729,9 @@ buffer_posn_from_coords (w, x, y)
   *x = it.current_x - it.first_visible_x + left_area_width;
   *y = it.current_y;
   current_buffer = old_current_buffer;
-  return IT_CHARPOS (it);
+
+  *object = STRINGP (it.string) ? it.string : w->buffer;
+  *pos = it.current;
 }
 
 
@@ -6621,8 +6647,9 @@ If not nil, this is a vector indexed by glyph code to define the glyph.\n\
 Each element can be:\n\
  integer: a glyph code which this glyph is an alias for.\n\
  string: output this glyph using that string (not impl. in X windows).\n\
- nil: this glyph mod 256 is char code to output,\n\
-    and this glyph / 256 is face code for X windows (see `face-id').");
+ nil: this glyph mod 524288 is the code of a character to output,\n\
+    and this glyph / 524288 is the face number (see `face-id') to use\n\
+    while outputting it.");
   Vglyph_table = Qnil;
 
   DEFVAR_LISP ("standard-display-table", &Vstandard_display_table,