changeset 34788:9512f05b60d1

(ensure_frame_matrix): Removed. (save_frame_matrix, restore_frame_matrix): New functions. (adjust_frame_glyphs_for_frame_redisplay): Use them.
author Gerd Moellmann <gerd@gnu.org>
date Thu, 21 Dec 2000 15:39:27 +0000
parents e77dcc645720
children 7ebf09eda05e
files src/dispnew.c
diffstat 1 files changed, 74 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/dispnew.c	Thu Dec 21 15:39:04 2000 +0000
+++ b/src/dispnew.c	Thu Dec 21 15:39:27 2000 +0000
@@ -120,6 +120,8 @@
 
 /* Function prototypes.  */
 
+static struct glyph_matrix *save_frame_matrix P_ ((struct glyph_matrix *));
+static void restore_frame_matrix P_ ((struct glyph_matrix *, struct glyph_matrix *));
 static void fake_current_matrices P_ ((Lisp_Object));
 static void redraw_overlapping_rows P_ ((struct window *, int));
 static void redraw_overlapped_rows P_ ((struct window *, int));
@@ -2054,15 +2056,55 @@
 }
 
 
-/* Make sure the current frame matrix of frame F has been built.
-   This is a no-op if F doesn't use frame-based redisplay.  */
-
-void
-ensure_frame_matrix (f)
-     struct frame *f;
+/* Return a glyph matrix that holds of copy of the glyph contents
+   of frame matrix M.  */
+
+static struct glyph_matrix *
+save_frame_matrix (m)
+     struct glyph_matrix *m;
 {
-  if (f->current_pool && display_completed)
-    build_frame_matrix (f);
+  struct glyph_matrix *copy;
+  int i;
+
+  copy = (struct glyph_matrix *) xmalloc (sizeof *copy);
+  *copy = *m;
+  copy->rows = (struct glyph_row *) xmalloc (m->nrows * sizeof (*copy->rows));
+
+  for (i = 0; i < copy->nrows; ++i)
+    {
+      struct glyph_row *from = m->rows + i;
+      struct glyph_row *to = copy->rows + i;
+      size_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
+      to->glyphs[TEXT_AREA] = (struct glyph *) xmalloc (nbytes);
+      bcopy (from->glyphs[TEXT_AREA], to->glyphs[TEXT_AREA], nbytes);
+      to->used[TEXT_AREA] = from->used[TEXT_AREA];
+    }
+  
+  return copy;
+}
+
+
+/* Restore the glyph contents of frame matrix M from the copy COPY,
+   made by save_frame_matrix.  Free memory allocated for COPY.  */
+
+static void
+restore_frame_matrix (m, copy)
+     struct glyph_matrix *m, *copy;
+{
+  int i;
+  
+  for (i = 0; i < copy->nrows; ++i)
+    {
+      struct glyph_row *from = copy->rows + i;
+      struct glyph_row *to = m->rows + i;
+      size_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
+      bcopy (from->glyphs[TEXT_AREA], to->glyphs[TEXT_AREA], nbytes);
+      to->used[TEXT_AREA] = from->used[TEXT_AREA];
+      xfree (from->glyphs[TEXT_AREA]);
+    }
+
+  xfree (copy->rows);
+  xfree (copy);
 }
 
 
@@ -2139,15 +2181,31 @@
   
       /* Resize frame matrices.  */
       adjust_glyph_matrix (NULL, f->desired_matrix, 0, 0, matrix_dim);
-      adjust_glyph_matrix (NULL, f->current_matrix, 0, 0, matrix_dim);
-
-      /* If the display hasn't been interrupted, set up windows'
-         current matrices so that they describe what's on the
-         screen.  */
-      if (display_completed)
-	fake_current_matrices (FRAME_ROOT_WINDOW (f));
+
+      /* Pointers to glyph memory in glyph rows are exchanged during
+	 the update phase of redisplay, which means in general that a
+	 frame's current matrix consists of pointers into both the
+	 desired and current glyph pool of the frame.  Adjusting a
+	 matrix sets the frame matrix up so that pointers are all into
+	 the same pool.  If we want to preserve glyph contents of the
+	 current matrix over a call to adjust_glyph_matrix, we must
+	 make a copy of the current glyphs, and restore the current
+	 matrix' contents from that copy.  */
+      if (display_completed
+	  && !FRAME_GARBAGED_P (f)
+	  && matrix_dim.width == f->current_matrix->matrix_w
+	  && matrix_dim.height == f->current_matrix->matrix_h)
+	{
+	  struct glyph_matrix *saved = save_frame_matrix (f->current_matrix);
+	  adjust_glyph_matrix (NULL, f->current_matrix, 0, 0, matrix_dim);
+	  restore_frame_matrix (f->current_matrix, saved);
+	  fake_current_matrices (FRAME_ROOT_WINDOW (f));
+	}
       else
-	SET_FRAME_GARBAGED (f);
+	{
+	  adjust_glyph_matrix (NULL, f->current_matrix, 0, 0, matrix_dim);
+	  SET_FRAME_GARBAGED (f);
+	}
     }
 }