diff src/redisplay.c @ 272:c5d627a313b1 r21-0b34

Import from CVS: tag r21-0b34
author cvs
date Mon, 13 Aug 2007 10:28:48 +0200
parents b2472a1930f2
children ca9a9ec9c1c1
line wrap: on
line diff
--- a/src/redisplay.c	Mon Aug 13 10:27:41 2007 +0200
+++ b/src/redisplay.c	Mon Aug 13 10:28:48 2007 +0200
@@ -40,6 +40,7 @@
 
 #include <config.h>
 #include "lisp.h"
+#include <limits.h>
 
 #include "buffer.h"
 #include "commands.h"
@@ -63,7 +64,10 @@
 
 #ifdef HAVE_TTY
 #include "console-tty.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> /* for isatty() */
 #endif
+#endif /* HAVE_TTY */
 
 /* Note: We have to be careful throughout this code to properly handle
    and differentiate between Bufbytes and Emchars.
@@ -205,26 +209,26 @@
   enum prop_type type;
 
   union data
-    {
-      struct
-	{
-	  Bufbyte *str;
-	  Bytecount len; /* length of the string. */
-	} p_string;
-
-      struct
-	{
-	  Emchar ch;
-	  Bytind bi_cursor_bufpos; /* NOTE: is in Bytinds */
-	  unsigned int cursor_type :3;
-	} p_char;
-
-      struct
-	{
-	  int width;
-	  face_index findex;
-	} p_blank;
-    } data;
+  {
+    struct
+    {
+      Bufbyte *str;
+      Bytecount len; /* length of the string. */
+    } p_string;
+
+    struct
+    {
+      Emchar ch;
+      Bytind bi_cursor_bufpos; /* NOTE: is in Bytinds */
+      unsigned int cursor_type :3;
+    } p_char;
+
+    struct
+    {
+      int width;
+      face_index findex;
+    } p_blank;
+  } data;
 };
 
 typedef struct
@@ -233,70 +237,30 @@
 } prop_block_dynarr;
 
 
-/*
- * Prototypes for all functions defined in redisplay.c.
- */
-struct display_block *get_display_block_from_line (struct display_line *dl,
-						   enum display_type type);
-layout_bounds calculate_display_line_boundaries (struct window *w,
-						 int modeline);
-static Bufpos generate_display_line (struct window *w, struct display_line *dl,
-				     int bounds, Bufpos start_pos,
-				     int start_col, prop_block_dynarr **prop,
-				     int type);
-static void generate_modeline (struct window *w, struct display_line *dl,
-			       int type);
-static int ensure_modeline_generated (struct window *w, int type);
-#ifdef MODELINE_IS_SCROLLABLE
 static void generate_formatted_string_db (Lisp_Object format_str,
 					  Lisp_Object result_str,
 					  struct window *w,
 					  struct display_line *dl,
 					  struct display_block *db,
 					  face_index findex, int min_pixpos,
-					  int max_pixpos, int type, 
-					  int modeline);
+					  int max_pixpos, int type
+#ifdef MODELINE_IS_SCROLLABLE
+					  ,int modeline
+#endif
+					  );
 static Charcount generate_fstring_runes (struct window *w, pos_data *data,
 					 Charcount pos, Charcount min_pos,
-					 Charcount max_pos, int no_limit,
+					 Charcount max_pos,
+#ifdef MODELINE_IS_SCROLLABLE
+					 int no_limit,
+#endif
 					 Lisp_Object elt,
 					 int depth, int max_pixsize,
 					 face_index findex, int type);
-#else /* MODELINE_IS_SCROLLABLE */
-static void generate_formatted_string_db (Lisp_Object format_str,
-					  Lisp_Object result_str,
-					  struct window *w,
-					  struct display_line *dl,
-					  struct display_block *db,
-					  face_index findex, int min_pixpos,
-					  int max_pixpos, int type);
-static Charcount generate_fstring_runes (struct window *w, pos_data *data,
-					 Charcount pos, Charcount min_pos,
-					 Charcount max_pos, Lisp_Object elt,
-					 int depth, int max_pixsize,
-					 face_index findex, int type);
-#endif /* not MODELINE_IS_SCROLLABLE */
-static prop_block_dynarr *add_emchar_rune (pos_data *data);
-static prop_block_dynarr *add_bufbyte_string_runes (pos_data *data,
-						    Bufbyte *c_string,
-						    Bytecount c_length,
-						    int no_prop);
-static prop_block_dynarr *add_blank_rune (pos_data *data, struct window *w,
-					  int char_tab_width);
-static prop_block_dynarr *add_octal_runes (pos_data *data);
-static prop_block_dynarr *add_control_char_runes (pos_data *data,
-						  struct buffer *b);
-static prop_block_dynarr *add_disp_table_entry_runes (pos_data *data,
-						      Lisp_Object entry);
-static prop_block_dynarr *add_propagation_runes (prop_block_dynarr **prop,
-						 pos_data *data);
 static prop_block_dynarr *add_glyph_rune (pos_data *data,
 					  struct glyph_block *gb,
 					  int pos_type, int allow_cursor,
 					  struct glyph_cachel *cachel);
-static prop_block_dynarr *add_glyph_runes (pos_data *data,
-					   int pos_type);
-/* NOTE: Bytinds not Bufpos's here. */
 static Bytind create_text_block (struct window *w, struct display_line *dl,
 				 Bytind bi_start_pos, int start_col,
 				 prop_block_dynarr **prop, int type);
@@ -307,40 +271,23 @@
 				     int overlay_width);
 static void create_right_glyph_block (struct window *w,
 				      struct display_line *dl);
-static void regenerate_window (struct window *w, Bufpos start_pos,
-			       Bufpos point, int type);
-static Bufpos regenerate_window_point_center (struct window *w, Bufpos point,
-					      int type);
-int window_half_pixpos (struct window *w);
-int line_at_center (struct window *w, int type, Bufpos start, Bufpos point);
-Bufpos point_at_center (struct window *w, int type, Bufpos start,
-			Bufpos point);
-static void redisplay_window (Lisp_Object window, int skip_selected);
 static void redisplay_windows (Lisp_Object window, int skip_selected);
-static int redisplay_frame (struct frame *f, int preemption_check);
-void redisplay (void);
 static void decode_mode_spec (struct window *w, Emchar spec, int type);
 static void free_display_line (struct display_line *dl);
-void free_display_structs (struct window_mirror *mir);
-static int point_visible (struct window *w, Bufpos point, int type);
 static void update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
 				     Bufpos point, int no_regen);
-static Bufpos line_start_cache_start (struct window *w);
-static Bufpos line_start_cache_end (struct window *w);
+static int point_visible (struct window *w, Bufpos point, int type);
 
 /* This used to be 10 but 30 seems to give much better performance. */
 #define INIT_MAX_PREEMPTS	30
 static int max_preempts;
 
-#define REDISPLAY_PREEMPTION_CHECK				\
-  do {								\
-    preempted = 0;						\
-    if (!disable_preemption &&					\
-	((preemption_count < max_preempts) || !NILP (Vexecuting_macro))) \
-      if (!INTERACTIVE || detect_input_pending ()) {		\
-        preempted = 1;						\
-      }								\
-  } while (0)
+#define REDISPLAY_PREEMPTION_CHECK					\
+((void)									\
+ (preempted =								\
+  (!disable_preemption &&						\
+   ((preemption_count < max_preempts) || !NILP (Vexecuting_macro)) &&	\
+   (!INTERACTIVE || detect_input_pending ()))))
 
 /*
  * Redisplay global variables.
@@ -530,7 +477,7 @@
 				    Emchar *str, Charcount len)
 {
   unsigned char charsets[NUM_LEADING_BYTES];
-  Lisp_Object window = Qnil;
+  Lisp_Object window;
 
   find_charsets_in_emchar_string (charsets, str, len);
   XSETWINDOW (window, w);
@@ -567,7 +514,7 @@
 				   Bytecount offset, Bytecount len)
 {
   unsigned char charsets[NUM_LEADING_BYTES];
-  Lisp_Object frame = Qnil;
+  Lisp_Object frame;
   struct face_cachel cachel;
 
   if (!rtw_emchar_dynarr)
@@ -631,7 +578,7 @@
 
   /* The line doesn't have a block of the desired type so go ahead and create
      one and add it to the line. */
-  memset (&db, 0, sizeof (struct display_block));
+  xzero (db);
   db.type = type;
   db.runes = Dynarr_new (rune);
   Dynarr_add (dl->display_blocks, db);
@@ -1902,7 +1849,7 @@
   dl->used_prop_data = 0;
   dl->num_chars = 0;
 
-  memset (&data, 0, sizeof (data));
+  xzero (data);
   data.ef = extent_fragment_new (w->buffer, f);
 
   /* These values are used by all of the rune addition routines.  We add
@@ -2671,7 +2618,7 @@
   if (!STRINGP (Voverlay_arrow_string) && !GLYPHP (Voverlay_arrow_string))
     return 0;
 
-  memset (&data, 0, sizeof (data));
+  xzero (data);
   data.ef = NULL;
   data.d = d;
   XSETWINDOW (data.window, w);
@@ -2730,7 +2677,7 @@
 
 static int
 add_margin_runes (struct display_line *dl, struct display_block *db, int start,
-		  int count, int glyph_type, int side, Lisp_Object window)
+		  int count, enum glyph_layout layout, int side, Lisp_Object window)
 {
   glyph_block_dynarr *gbd = (side == LEFT_GLYPHS
 			     ? dl->left_glyphs
@@ -2739,8 +2686,8 @@
   int xpos = start;
   int reverse;
 
-  if ((glyph_type == GL_WHITESPACE && side == LEFT_GLYPHS)
-      || (glyph_type == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS))
+  if ((layout == GL_WHITESPACE && side == LEFT_GLYPHS)
+      || (layout == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS))
     {
       reverse = 1;
       elt = Dynarr_length (gbd) - 1;
@@ -2762,9 +2709,9 @@
 
       if (gb->active &&
 	  ((side == LEFT_GLYPHS &&
-	    extent_begin_glyph_layout (XEXTENT (gb->extent)) == glyph_type)
+	    extent_begin_glyph_layout (XEXTENT (gb->extent)) == layout)
 	   || (side == RIGHT_GLYPHS &&
-	       extent_end_glyph_layout (XEXTENT (gb->extent)) == glyph_type)))
+	       extent_end_glyph_layout (XEXTENT (gb->extent)) == layout)))
 	{
 	  struct rune rb;
 
@@ -3580,16 +3527,13 @@
   else
     ypos_adj = 0;
 
-#ifdef MODELINE_IS_SCROLLABLE
   generate_formatted_string_db (b->modeline_format,
 				b->generated_modeline_string, w, dl, db,
-				MODELINE_INDEX, min_pixpos, max_pixpos, type,
-				1 /* generate a modeline */);
-#else
-  generate_formatted_string_db (b->modeline_format,
-                                b->generated_modeline_string, w, dl, db,
-                                MODELINE_INDEX, min_pixpos, max_pixpos, type);
+				MODELINE_INDEX, min_pixpos, max_pixpos, type
+#ifdef MODELINE_IS_SCROLLABLE
+				, 1 /* generate a modeline */
 #endif /* not MODELINE_IS_SCROLLABLE */
+				);
 
   /* The modeline is at the bottom of the gutters.  We have to wait to
      set this until we've generated teh modeline in order to account
@@ -3598,13 +3542,13 @@
 }
 
 /* This define is for the experimental horizontal modeline scrolling. It's not
-   functionnal for 20.5, but might be for 21.1 */
+   functional for 21.0, but might be for 21.1 */
 #ifdef MODELINE_IS_SCROLLABLE
 static void
 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str,
 			      struct window *w, struct display_line *dl,
 			      struct display_block *db, face_index findex,
-			      int min_pixpos, int max_pixpos, int type, 
+			      int min_pixpos, int max_pixpos, int type,
 			      int modeline)
 {
   struct frame *f = XFRAME (w->frame);
@@ -3613,7 +3557,7 @@
   pos_data data;
   int c_pixpos;
 
-  memset (&data, 0, sizeof (data));
+  xzero (data);
   data.d = d;
   data.db = db;
   data.dl = dl;
@@ -3635,13 +3579,13 @@
      This recursively builds up the modeline or the title/icon string.
      In case of a modeline, we use a negative start position to indicate
      the current modeline horizontal scroll. */
-  generate_fstring_runes 
-    (w, &data, 
+  generate_fstring_runes
+    (w, &data,
      (modeline && WINDOW_HAS_MODELINE_P (w)) ? - w->modeline_hscroll : 0,
      (modeline && WINDOW_HAS_MODELINE_P (w)) ? - w->modeline_hscroll : 0,
-     0, /* no limit */ 1, format_str, 0, max_pixpos - min_pixpos, findex, 
+     0, /* no limit */ 1, format_str, 0, max_pixpos - min_pixpos, findex,
      type);
-  
+
   if (Dynarr_length (db->runes))
     {
       struct rune *rb =
@@ -3691,7 +3635,7 @@
       for (elt = 0; elt < Dynarr_length (formatted_string_extent_dynarr);
 	   elt++)
 	{
-	  Lisp_Object extent = Qnil;
+	  Lisp_Object extent;
 	  Lisp_Object child;
 
 	  XSETEXTENT (extent, Dynarr_at (formatted_string_extent_dynarr, elt));
@@ -3711,7 +3655,7 @@
     }
 }
 
-/* D. Verna Feb. 1998. Rewrote this function to handle the case of a 
+/* D. Verna Feb. 1998. Rewrote this function to handle the case of a
    scrolled modeline */
 static Charcount
 add_string_to_fstring_db_runes (pos_data *data, CONST Bufbyte *str,
@@ -3723,9 +3667,9 @@
   CONST Bufbyte *cur_pos = str;
   struct display_block *db = data->db;
   int add_something;
-  
+
   data->blank_width = space_width (XWINDOW (data->window));
-  add_something = ((pos < min_pos) 
+  add_something = ((pos < min_pos)
 		   || ((*cur_pos) && no_limit)
 		   || ((*cur_pos) && (pos < max_pos)));
   while (add_something)
@@ -3733,7 +3677,7 @@
       if ((initial_pos >= 0) && (pos == initial_pos))
 	while (Dynarr_length (db->runes) < pos)
 	  add_blank_rune (data, NULL, 0);
-      
+
       if (pos < 0) /* just pretend we're adding something */
 	{
 	  if (*cur_pos)
@@ -3746,7 +3690,7 @@
 	    {
 	      CONST Bufbyte *old_cur_pos = cur_pos;
 	      int succeeded;
-	      
+
 	      data->ch = charptr_emchar (cur_pos);
 	      succeeded = (add_emchar_rune (data) != ADD_FAILED);
 	      INC_CHARPTR (cur_pos);
@@ -3772,7 +3716,7 @@
 	      pos += 1;
 	    }
 	}
-      add_something = ((pos < min_pos) 
+      add_something = ((pos < min_pos)
 		       || ((*cur_pos) && no_limit)
 		       || ((*cur_pos) && (pos < max_pos)));
     }
@@ -3784,7 +3728,7 @@
    modeline extents. */
 static Charcount
 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph,
-			       Charcount pos, Charcount min_pos, 
+			       Charcount pos, Charcount min_pos,
 			       Charcount max_pos, int no_limit)
 {
   /* This function has been Mule-ized. */
@@ -3793,19 +3737,19 @@
   struct glyph_block gb;
 
   /* D. Verna Feb. 1998.
-     If pos < 0, we're building a scrolled modeline. 
+     If pos < 0, we're building a scrolled modeline.
      The glyph should be hidden. So just skip it. */
   if (pos < 0)
     return (pos + 1);
-  
+
   data->blank_width = space_width (XWINDOW (data->window));
   while (Dynarr_length (db->runes) < pos)
     add_blank_rune (data, NULL, 0);
-  
+
   end = Dynarr_length (db->runes) + 1;
   if (!no_limit)
     end = min (max_pos, end);
-  
+
   gb.glyph = glyph;
   gb.extent = Qnil;
   add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
@@ -3854,23 +3798,23 @@
     {
       /* A string.  Add to the display line and check for %-constructs
          within it. */
-      
+
       Bufbyte *this = XSTRING_DATA (elt);
-      
+
       while ((no_limit || pos < max_pos) && *this)
 	{
 	  Bufbyte *last = this;
-	  
+
 	  while (*this && *this != '%')
 	    this++;
-	  
+
 	  if (this != last)
 	    {
 	      /* The string is just a string. */
 	      Charcount size =
 		bytecount_to_charcount (last, this - last) + pos;
 	      Charcount tmp_max = (no_limit ? size : min (size, max_pos));
-	      
+
 	      pos = add_string_to_fstring_db_runes (data, last, pos, pos,
 						    tmp_max, /* limit */0);
 	    }
@@ -3925,7 +3869,7 @@
 
 		  while (num_to_add--)
 		    pos = add_string_to_fstring_db_runes
-		      (data, (CONST Bufbyte *) "-", 
+		      (data, (CONST Bufbyte *) "-",
 		       pos, pos, max_pos, no_limit);
 		}
 	      else if (*this != 0)
@@ -4067,7 +4011,7 @@
           /* LIMIT is to protect against circular lists.  */
           while (CONSP (elt) && --limit > 0 && (no_limit || pos < max_pos))
             {
-	      pos = generate_fstring_runes (w, data, pos, pos, max_pos, 
+	      pos = generate_fstring_runes (w, data, pos, pos, max_pos,
 					    no_limit,
 					    XCAR (elt), depth,
 					    max_pixsize, findex, type);
@@ -4107,7 +4051,7 @@
 		new_findex = old_findex;
 
 	      data->findex = new_findex;
-	      pos = generate_fstring_runes (w, data, pos, pos, max_pos, 
+	      pos = generate_fstring_runes (w, data, pos, pos, max_pos,
 					    no_limit,
 					    XCDR (elt), depth - 1,
 					    max_pixsize, new_findex, type);
@@ -4120,7 +4064,7 @@
     }
   else if (GLYPHP (elt))
     {
-      pos = add_glyph_to_fstring_db_runes 
+      pos = add_glyph_to_fstring_db_runes
 	(data, elt, pos, pos, max_pos, no_limit);
     }
   else
@@ -4153,7 +4097,7 @@
   pos_data data;
   int c_pixpos;
 
-  memset (&data, 0, sizeof (data));
+  xzero (data);
   data.d = d;
   data.db = db;
   data.dl = dl;
@@ -4650,7 +4594,7 @@
 
 #ifdef MODELINE_IS_SCROLLABLE
   /* D. Verna Feb. 1998.
-     Currently, only update_frame_title can make us come here. This is not 
+     Currently, only update_frame_title can make us come here. This is not
      to build a modeline */
   generate_formatted_string_db (format_str, result_str, w, dl, db, findex, 0,
 				-1, type, 0 /* not a modeline */);
@@ -4731,7 +4675,7 @@
 	  else
 	    {
 	      struct display_line modeline;
-	      memset (&modeline, 0, sizeof (struct display_line));
+	      xzero (modeline);
 	      Dynarr_add (dla, modeline);
 	    }
 	}
@@ -4852,8 +4796,8 @@
 	}
       else
 	{
+	  xzero (dl);
 	  dlp = &dl;
-	  memset (dlp, 0, sizeof (struct display_line));
 	  local = 1;
 	}
 
@@ -5907,7 +5851,7 @@
 
       if (lrpos >= pos)
 	{
-	  Lisp_Object window = Qnil;
+	  Lisp_Object window;
 	  XSETWINDOW (window, w);
 	  va_run_hook_with_args_in_buffer (XBUFFER (w->buffer),
 					   Qredisplay_end_trigger_functions,
@@ -6388,8 +6332,9 @@
 	struct frame *f = XFRAME (w->frame);
 	if (FRAME_TTY_P (f) && f->order_count > 1)
 	  {
-	    str = (CONST char *) alloca (10);
-	    sprintf (str, "-%d", f->order_count);
+	    char * writable_str = alloca_array (char, 10);
+	    sprintf (writable_str, "-%d", f->order_count);
+	    str = writable_str;
 	  }
       }
 #endif /* HAVE_TTY */
@@ -7394,7 +7339,7 @@
 	  /* Hit the bottom of the buffer. */
 	  int adjustment =
 	    (cur_elt + new_line) - Dynarr_length (w->line_start_cache) + 1;
-	  Lisp_Object window = Qnil;
+	  Lisp_Object window;
 	  int defheight;
 
 	  XSETWINDOW (window, w);
@@ -7603,6 +7548,7 @@
       while (startp < old_lb || low_bound == -1)
 	{
 	  int ic_elt;
+          Bufpos new_startp;
 
 	  regenerate_window (w, startp, point, CMOTION_DISP);
 	  update_internal_cache_list (w, CMOTION_DISP);
@@ -7640,13 +7586,34 @@
 	    }
 	  assert (ic_elt >= 0);
 
-	  Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0),
-			      ic_elt + 1, marker);
-	  marker += (ic_elt + 1);
+	  new_startp = Dynarr_atp (internal_cache, ic_elt)->end + 1;
+
+          /*
+           * Handle invisible text properly:
+           * If the last line we're inserting has the same end as the 
+           * line before which it will be added, merge the two lines.
+           */
+          if (Dynarr_length (cache)  &&
+              Dynarr_atp (internal_cache, ic_elt)->end ==
+              Dynarr_atp (cache, marker)->end)
+            {
+              Dynarr_atp (cache, marker)->start
+                = Dynarr_atp (internal_cache, ic_elt)->start;
+              Dynarr_atp (cache, marker)->height
+                = Dynarr_atp (internal_cache, ic_elt)->height;
+              ic_elt--;
+            }
+
+          if (ic_elt >= 0)       /* we still have lines to add.. */
+            {
+              Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0),
+                                  ic_elt + 1, marker);
+              marker += (ic_elt + 1);
+            }
 
 	  if (startp < low_bound || low_bound == -1)
 	    low_bound = startp;
-	  startp = Dynarr_atp (internal_cache, ic_elt)->end + 1;
+	  startp = new_startp;
 	  if (startp > BUF_ZV (b))
 	    {
 	      updating_line_start_cache = 0;
@@ -7703,7 +7670,7 @@
 {
   display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
   int num_disp_lines, modeline;
-  Lisp_Object window = Qnil;
+  Lisp_Object window;
   int defheight, defwidth;
 
   XSETWINDOW (window, w);
@@ -8356,7 +8323,7 @@
 	{
 	  struct display_line *dl = Dynarr_atp (dla, bot_elt);
 	  int adj_area = y_coord - (dl->ypos + dl->descent);
-	  Lisp_Object lwin = Qnil;
+	  Lisp_Object lwin;
 	  int defheight;
 
 	  XSETWINDOW (lwin, *w);
@@ -8734,7 +8701,7 @@
       formatted_string_extent_start_dynarr = Dynarr_new (Bytecount);
       formatted_string_extent_end_dynarr = Dynarr_new (Bytecount);
       internal_cache = Dynarr_new (line_start_cache);
-      memset (&formatted_string_display_line, 0, sizeof (struct display_line));
+      xzero (formatted_string_display_line);
     }
 
   /* window system is nil when in -batch mode */
@@ -8832,7 +8799,7 @@
 
   /* #### Probably temporary */
   DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /*
-(Temporary) Setting this will impact the performance of the internal
+\(Temporary) Setting this will impact the performance of the internal
 line start cache.
 */ );
   cache_adjustment = 2;