changeset 2729:76afd3322533

Arrange to tell redisplay about changes in overlays. * xdisp.c (redisplay_region): New function. * buffer.c (Fmove_overlay): Call redisplay_region on the areas the overlay has enclosed or left. (Fdelete_overlay): Call redisplay_region on the area the overlay used to occupy. (Foverlay_put): Call redisplay_region on the area the overlay now occupies; we may have put a face property on it. * xdisp.c (redisplay): If we're doing a thorough redisplay (all windows on all frames involved), go ahead and flush the GC cache - call clear_face_vector. * xdisp.c (display_text_line): Apply faces to characters according to overlays and text properties; use compute_char_face and compute_glyph_face to figure out what face to use, and where a new face starts. * xterm.c (dumpglyphs): Use the upper bits of the glyphs to decide which frame face to use. Call GLYPH_FOLLOW_ALIASES to make sure we're implementing the glyph table properly. If we're not using the default or mode line face, call intern_face to find a display face for the frame face selected by the glyph code. Implement underlining. Remove the `font' argument; we have to derive this from the frame and face anyway. Change all callers. * disptab.h (GLYPH_FOLLOW_ALIASES): New macro.
author Jim Blandy <jimb@redhat.com>
date Mon, 10 May 1993 00:23:47 +0000
parents 93c9529b2b69
children 139740855fa6
files src/xdisp.c
diffstat 1 files changed, 136 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/src/xdisp.c	Mon May 10 00:17:55 1993 +0000
+++ b/src/xdisp.c	Mon May 10 00:23:47 1993 +0000
@@ -516,6 +516,12 @@
     {
       Lisp_Object tail, frame;
 
+#ifdef HAVE_X_WINDOWS
+      /* Since we're doing a thorough redisplay, we might as well
+	 recompute all our display faces.  */
+      clear_face_vector ();
+#endif
+
       /* Recompute # windows showing selected buffer.
 	 This will be incremented each time such a window is displayed.  */
       buffer_shared = 0;
@@ -1473,6 +1479,68 @@
   return 1;
 }
 
+/* Mark a section of BUF as modified, but only for the sake of redisplay.
+   This is useful for recording changes to overlays.
+
+   We increment the buffer's modification timestamp and set the
+   redisplay caches (windows_or_buffers_changed, beg_unchanged, etc)
+   as if the region of text between START and END had been modified;
+   the redisplay code will check this against the windows' timestamps,
+   and redraw the appropriate area of the buffer.
+
+   However, if the buffer is unmodified, we bump the last-save
+   timestamp as well, so that incrementing the timestamp doesn't fool
+   Emacs into thinking that the buffer's text has been modified. 
+
+   Tweaking the timestamps shouldn't hurt the first-modification
+   timestamps recorded in the undo records; those values aren't
+   written until just before a real text modification is made, so they
+   will never catch the timestamp value just before this function gets
+   called.  */
+
+void
+redisplay_region (buf, start, end)
+     struct buffer *buf;
+     int start, end;
+{
+  if (start == end)
+    return;
+
+  if (start > end)
+    {
+      int temp = start;
+      start = end; end = temp;
+    }
+
+  if (buf != current_buffer)
+    windows_or_buffers_changed = 1;
+  else
+    {
+      if (unchanged_modified == MODIFF)
+	{
+	  beg_unchanged = start - BEG;
+	  end_unchanged = Z - end;
+	}
+      else
+	{
+	  if (Z - end < end_unchanged)
+	    end_unchanged = Z - end;
+	  if (start - BEG < beg_unchanged)
+	    beg_unchanged = start - BEG;
+	}
+    }
+
+  /* Increment the buffer's time stamp, but also increment the save
+     and autosave timestamps, so as not to screw up that timekeeping. */
+  if (BUF_MODIFF (buf) == buf->save_modified)
+    buf->save_modified++;
+  if (BUF_MODIFF (buf) == buf->auto_save_modified)
+    buf->auto_save_modified++;
+
+  BUF_MODIFF (buf) ++;
+}
+
+
 /* Copy glyphs from the vector FROM to the rope T.
    But don't actually copy the parts that would come in before S.
    Value is T, advanced past the copied data.  */
@@ -1581,6 +1649,13 @@
   GLYPH continuer = (dp == 0 || XTYPE (DISP_CONTINUE_GLYPH (dp)) != Lisp_Int
 		    ? '\\' : XINT (DISP_CONTINUE_GLYPH (dp)));
 
+  /* The next buffer location at which the face should change, due
+     to overlays or text property changes.  */
+  int next_face_change;
+
+  /* The face we're currently using.  */
+  int current_face;
+
   hpos += XFASTINT (w->left);
   get_display_line (f, vpos, XFASTINT (w->left));
   if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
@@ -1603,16 +1678,21 @@
 
   /* Loop generating characters.
      Stop at end of buffer, before newline,
-     or if reach or pass continuation column.  */
-
+     if reach or pass continuation column,
+     or at face change.  */
   pause = pos;
+  next_face_change = pos;
   while (p1 < endp)
     {
       p1prev = p1;
-      if (pos == pause)
+      if (pos >= pause)
 	{
-	  if (pos == end)
+	  /* Did we hit the end of the visible region of the buffer?
+	     Stop here.  */
+	  if (pos >= end)
 	    break;
+
+	  /* Did we reach point?  Record the cursor location.  */
 	  if (pos == point && cursor_vpos < 0)
 	    {
 	      cursor_vpos = vpos;
@@ -1620,6 +1700,19 @@
 	    }
 
 	  pause = end;
+
+	  /* Did we hit a face change?  Figure out what face we should
+	     use now.  We also hit this the first time through the
+	     loop, to see what face we should start with.  */
+	  if (pos == next_face_change)
+	    {
+	      current_face = compute_char_face (f, w, pos, &next_face_change);
+	      if (pos < next_face_change && next_face_change < pause)
+		pause = next_face_change;
+	    }
+
+	  /* Wouldn't you hate to read the next line to someone over
+             the phone?  */
 	  if (pos < point && point < pause)
 	    pause = point;
 	  if (pos < GPT && GPT < pause)
@@ -1632,7 +1725,7 @@
 	  && (dp == 0 || XTYPE (DISP_CHAR_VECTOR (dp, c)) != Lisp_Vector))
 	{
 	  if (p1 >= startp)
-	    *p1 = c;
+	    *p1 = MAKE_GLYPH (c, 0);
 	  p1++;
 	}
       else if (c == '\n')
@@ -1656,7 +1749,11 @@
 				 XVECTOR (DISP_INVIS_VECTOR (dp))->contents,
 				 (p1 - p1prev));
 	    }
-	  break;
+
+	  /* This assures we'll exit the loop, but still gives us a chance to
+	     apply current_face to the glyphs we've laid down.  */
+	  end = pos;
+	  pause = end;
 	}
       else if (c == '\t')
 	{
@@ -1683,7 +1780,8 @@
 				 XVECTOR(DISP_INVIS_VECTOR (dp))->contents,
 				 (p1 - p1prev));
 	    }
-	  break;
+	  end = pos;
+	  pause = end;
 	}
       else if (dp != 0 && XTYPE (DISP_CHAR_VECTOR (dp, c)) == Lisp_Vector)
 	{
@@ -1692,29 +1790,50 @@
       else if (c < 0200 && ctl_arrow)
 	{
 	  if (p1 >= startp)
-	    *p1 = (dp && XTYPE (DISP_CTRL_GLYPH (dp)) == Lisp_Int
-		   ? XINT (DISP_CTRL_GLYPH (dp)) : '^');
+	    *p1 = MAKE_GLYPH ((dp && XTYPE (DISP_CTRL_GLYPH (dp)) == Lisp_Int
+			       ? XINT (DISP_CTRL_GLYPH (dp)) : '^'),
+			      0);
 	  p1++;
 	  if (p1 >= startp && p1 < endp)
-	    *p1 = c ^ 0100;
+	    *p1 = MAKE_GLYPH (c ^ 0100, 0);
 	  p1++;
 	}
       else
 	{
 	  if (p1 >= startp)
-	    *p1 = (dp && XTYPE (DISP_ESCAPE_GLYPH (dp)) == Lisp_Int
-		   ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\');
+	    *p1 = MAKE_GLYPH ((dp && XTYPE (DISP_ESCAPE_GLYPH (dp)) == Lisp_Int
+			       ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\'),
+			      0);
 	  p1++;
 	  if (p1 >= startp && p1 < endp)
-	    *p1 = (c >> 6) + '0';
+	    *p1 = MAKE_GLYPH ((c >> 6) + '0', 0);
+	  p1++;
+	  if (p1 >= startp && p1 < endp)
+	    *p1 = MAKE_GLYPH ((7 & (c >> 3)) + '0', 0);
 	  p1++;
 	  if (p1 >= startp && p1 < endp)
-	    *p1 = (7 & (c >> 3)) + '0';
-	  p1++;
-	  if (p1 >= startp && p1 < endp)
-	    *p1 = (7 & c) + '0';
+	    *p1 = MAKE_GLYPH ((7 & c) + '0', 0);
 	  p1++;
 	}
+
+      /* Now we've laid down some characters between p1prev and p1.
+	 Let's apply current_face to those who have a face of zero
+	 (the default), and apply Vglyph_table to the result.  */
+      if (current_face)
+	{
+	  GLYPH *gstart, *gp, *gend;
+
+	  gstart = (p1prev > startp) ? p1prev : startp;
+	  gend   = (p1     < endp)   ? p1     : endp;
+
+	  for (gp = gstart; gp < gend; gp++)
+	    *gp = MAKE_GLYPH (GLYPH_CHAR (*gp),
+			      (GLYPH_FACE (*gp) == 0
+			       ? current_face
+			       : compute_glyph_face (f, FRAME_DEFAULT_FACE (f),
+						     GLYPH_FACE (*gp))));
+	}
+
       pos++;
     }