comparison 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
comparison
equal deleted inserted replaced
271:c7b7086b0a39 272:c5d627a313b1
38 Third: It Is Better To Be Fast Than Not To Be 38 Third: It Is Better To Be Fast Than Not To Be
39 ****************************************************************************/ 39 ****************************************************************************/
40 40
41 #include <config.h> 41 #include <config.h>
42 #include "lisp.h" 42 #include "lisp.h"
43 #include <limits.h>
43 44
44 #include "buffer.h" 45 #include "buffer.h"
45 #include "commands.h" 46 #include "commands.h"
46 #include "debug.h" 47 #include "debug.h"
47 #include "device.h" 48 #include "device.h"
61 #include "file-coding.h" 62 #include "file-coding.h"
62 #endif 63 #endif
63 64
64 #ifdef HAVE_TTY 65 #ifdef HAVE_TTY
65 #include "console-tty.h" 66 #include "console-tty.h"
67 #ifdef HAVE_UNISTD_H
68 #include <unistd.h> /* for isatty() */
66 #endif 69 #endif
70 #endif /* HAVE_TTY */
67 71
68 /* Note: We have to be careful throughout this code to properly handle 72 /* Note: We have to be careful throughout this code to properly handle
69 and differentiate between Bufbytes and Emchars. 73 and differentiate between Bufbytes and Emchars.
70 74
71 Since strings are generally composed of Bufbytes, I've taken the tack 75 Since strings are generally composed of Bufbytes, I've taken the tack
203 struct prop_block 207 struct prop_block
204 { 208 {
205 enum prop_type type; 209 enum prop_type type;
206 210
207 union data 211 union data
208 { 212 {
209 struct 213 struct
210 { 214 {
211 Bufbyte *str; 215 Bufbyte *str;
212 Bytecount len; /* length of the string. */ 216 Bytecount len; /* length of the string. */
213 } p_string; 217 } p_string;
214 218
215 struct 219 struct
216 { 220 {
217 Emchar ch; 221 Emchar ch;
218 Bytind bi_cursor_bufpos; /* NOTE: is in Bytinds */ 222 Bytind bi_cursor_bufpos; /* NOTE: is in Bytinds */
219 unsigned int cursor_type :3; 223 unsigned int cursor_type :3;
220 } p_char; 224 } p_char;
221 225
222 struct 226 struct
223 { 227 {
224 int width; 228 int width;
225 face_index findex; 229 face_index findex;
226 } p_blank; 230 } p_blank;
227 } data; 231 } data;
228 }; 232 };
229 233
230 typedef struct 234 typedef struct
231 { 235 {
232 Dynarr_declare (prop_block); 236 Dynarr_declare (prop_block);
233 } prop_block_dynarr; 237 } prop_block_dynarr;
234 238
235 239
236 /*
237 * Prototypes for all functions defined in redisplay.c.
238 */
239 struct display_block *get_display_block_from_line (struct display_line *dl,
240 enum display_type type);
241 layout_bounds calculate_display_line_boundaries (struct window *w,
242 int modeline);
243 static Bufpos generate_display_line (struct window *w, struct display_line *dl,
244 int bounds, Bufpos start_pos,
245 int start_col, prop_block_dynarr **prop,
246 int type);
247 static void generate_modeline (struct window *w, struct display_line *dl,
248 int type);
249 static int ensure_modeline_generated (struct window *w, int type);
250 #ifdef MODELINE_IS_SCROLLABLE
251 static void generate_formatted_string_db (Lisp_Object format_str, 240 static void generate_formatted_string_db (Lisp_Object format_str,
252 Lisp_Object result_str, 241 Lisp_Object result_str,
253 struct window *w, 242 struct window *w,
254 struct display_line *dl, 243 struct display_line *dl,
255 struct display_block *db, 244 struct display_block *db,
256 face_index findex, int min_pixpos, 245 face_index findex, int min_pixpos,
257 int max_pixpos, int type, 246 int max_pixpos, int type
258 int modeline); 247 #ifdef MODELINE_IS_SCROLLABLE
248 ,int modeline
249 #endif
250 );
259 static Charcount generate_fstring_runes (struct window *w, pos_data *data, 251 static Charcount generate_fstring_runes (struct window *w, pos_data *data,
260 Charcount pos, Charcount min_pos, 252 Charcount pos, Charcount min_pos,
261 Charcount max_pos, int no_limit, 253 Charcount max_pos,
254 #ifdef MODELINE_IS_SCROLLABLE
255 int no_limit,
256 #endif
262 Lisp_Object elt, 257 Lisp_Object elt,
263 int depth, int max_pixsize, 258 int depth, int max_pixsize,
264 face_index findex, int type); 259 face_index findex, int type);
265 #else /* MODELINE_IS_SCROLLABLE */
266 static void generate_formatted_string_db (Lisp_Object format_str,
267 Lisp_Object result_str,
268 struct window *w,
269 struct display_line *dl,
270 struct display_block *db,
271 face_index findex, int min_pixpos,
272 int max_pixpos, int type);
273 static Charcount generate_fstring_runes (struct window *w, pos_data *data,
274 Charcount pos, Charcount min_pos,
275 Charcount max_pos, Lisp_Object elt,
276 int depth, int max_pixsize,
277 face_index findex, int type);
278 #endif /* not MODELINE_IS_SCROLLABLE */
279 static prop_block_dynarr *add_emchar_rune (pos_data *data);
280 static prop_block_dynarr *add_bufbyte_string_runes (pos_data *data,
281 Bufbyte *c_string,
282 Bytecount c_length,
283 int no_prop);
284 static prop_block_dynarr *add_blank_rune (pos_data *data, struct window *w,
285 int char_tab_width);
286 static prop_block_dynarr *add_octal_runes (pos_data *data);
287 static prop_block_dynarr *add_control_char_runes (pos_data *data,
288 struct buffer *b);
289 static prop_block_dynarr *add_disp_table_entry_runes (pos_data *data,
290 Lisp_Object entry);
291 static prop_block_dynarr *add_propagation_runes (prop_block_dynarr **prop,
292 pos_data *data);
293 static prop_block_dynarr *add_glyph_rune (pos_data *data, 260 static prop_block_dynarr *add_glyph_rune (pos_data *data,
294 struct glyph_block *gb, 261 struct glyph_block *gb,
295 int pos_type, int allow_cursor, 262 int pos_type, int allow_cursor,
296 struct glyph_cachel *cachel); 263 struct glyph_cachel *cachel);
297 static prop_block_dynarr *add_glyph_runes (pos_data *data,
298 int pos_type);
299 /* NOTE: Bytinds not Bufpos's here. */
300 static Bytind create_text_block (struct window *w, struct display_line *dl, 264 static Bytind create_text_block (struct window *w, struct display_line *dl,
301 Bytind bi_start_pos, int start_col, 265 Bytind bi_start_pos, int start_col,
302 prop_block_dynarr **prop, int type); 266 prop_block_dynarr **prop, int type);
303 static int create_overlay_glyph_block (struct window *w, 267 static int create_overlay_glyph_block (struct window *w,
304 struct display_line *dl); 268 struct display_line *dl);
305 static void create_left_glyph_block (struct window *w, 269 static void create_left_glyph_block (struct window *w,
306 struct display_line *dl, 270 struct display_line *dl,
307 int overlay_width); 271 int overlay_width);
308 static void create_right_glyph_block (struct window *w, 272 static void create_right_glyph_block (struct window *w,
309 struct display_line *dl); 273 struct display_line *dl);
310 static void regenerate_window (struct window *w, Bufpos start_pos,
311 Bufpos point, int type);
312 static Bufpos regenerate_window_point_center (struct window *w, Bufpos point,
313 int type);
314 int window_half_pixpos (struct window *w);
315 int line_at_center (struct window *w, int type, Bufpos start, Bufpos point);
316 Bufpos point_at_center (struct window *w, int type, Bufpos start,
317 Bufpos point);
318 static void redisplay_window (Lisp_Object window, int skip_selected);
319 static void redisplay_windows (Lisp_Object window, int skip_selected); 274 static void redisplay_windows (Lisp_Object window, int skip_selected);
320 static int redisplay_frame (struct frame *f, int preemption_check);
321 void redisplay (void);
322 static void decode_mode_spec (struct window *w, Emchar spec, int type); 275 static void decode_mode_spec (struct window *w, Emchar spec, int type);
323 static void free_display_line (struct display_line *dl); 276 static void free_display_line (struct display_line *dl);
324 void free_display_structs (struct window_mirror *mir);
325 static int point_visible (struct window *w, Bufpos point, int type);
326 static void update_line_start_cache (struct window *w, Bufpos from, Bufpos to, 277 static void update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
327 Bufpos point, int no_regen); 278 Bufpos point, int no_regen);
328 static Bufpos line_start_cache_start (struct window *w); 279 static int point_visible (struct window *w, Bufpos point, int type);
329 static Bufpos line_start_cache_end (struct window *w);
330 280
331 /* This used to be 10 but 30 seems to give much better performance. */ 281 /* This used to be 10 but 30 seems to give much better performance. */
332 #define INIT_MAX_PREEMPTS 30 282 #define INIT_MAX_PREEMPTS 30
333 static int max_preempts; 283 static int max_preempts;
334 284
335 #define REDISPLAY_PREEMPTION_CHECK \ 285 #define REDISPLAY_PREEMPTION_CHECK \
336 do { \ 286 ((void) \
337 preempted = 0; \ 287 (preempted = \
338 if (!disable_preemption && \ 288 (!disable_preemption && \
339 ((preemption_count < max_preempts) || !NILP (Vexecuting_macro))) \ 289 ((preemption_count < max_preempts) || !NILP (Vexecuting_macro)) && \
340 if (!INTERACTIVE || detect_input_pending ()) { \ 290 (!INTERACTIVE || detect_input_pending ()))))
341 preempted = 1; \
342 } \
343 } while (0)
344 291
345 /* 292 /*
346 * Redisplay global variables. 293 * Redisplay global variables.
347 */ 294 */
348 295
528 static int 475 static int
529 redisplay_text_width_emchar_string (struct window *w, int findex, 476 redisplay_text_width_emchar_string (struct window *w, int findex,
530 Emchar *str, Charcount len) 477 Emchar *str, Charcount len)
531 { 478 {
532 unsigned char charsets[NUM_LEADING_BYTES]; 479 unsigned char charsets[NUM_LEADING_BYTES];
533 Lisp_Object window = Qnil; 480 Lisp_Object window;
534 481
535 find_charsets_in_emchar_string (charsets, str, len); 482 find_charsets_in_emchar_string (charsets, str, len);
536 XSETWINDOW (window, w); 483 XSETWINDOW (window, w);
537 ensure_face_cachel_complete (WINDOW_FACE_CACHEL (w, findex), window, 484 ensure_face_cachel_complete (WINDOW_FACE_CACHEL (w, findex), window,
538 charsets); 485 charsets);
565 redisplay_frame_text_width_string (struct frame *f, Lisp_Object face, 512 redisplay_frame_text_width_string (struct frame *f, Lisp_Object face,
566 Bufbyte *nonreloc, Lisp_Object reloc, 513 Bufbyte *nonreloc, Lisp_Object reloc,
567 Bytecount offset, Bytecount len) 514 Bytecount offset, Bytecount len)
568 { 515 {
569 unsigned char charsets[NUM_LEADING_BYTES]; 516 unsigned char charsets[NUM_LEADING_BYTES];
570 Lisp_Object frame = Qnil; 517 Lisp_Object frame;
571 struct face_cachel cachel; 518 struct face_cachel cachel;
572 519
573 if (!rtw_emchar_dynarr) 520 if (!rtw_emchar_dynarr)
574 rtw_emchar_dynarr = Dynarr_new (Emchar); 521 rtw_emchar_dynarr = Dynarr_new (Emchar);
575 Dynarr_reset (rtw_emchar_dynarr); 522 Dynarr_reset (rtw_emchar_dynarr);
629 dl->display_blocks = Dynarr_new (display_block); 576 dl->display_blocks = Dynarr_new (display_block);
630 } 577 }
631 578
632 /* The line doesn't have a block of the desired type so go ahead and create 579 /* The line doesn't have a block of the desired type so go ahead and create
633 one and add it to the line. */ 580 one and add it to the line. */
634 memset (&db, 0, sizeof (struct display_block)); 581 xzero (db);
635 db.type = type; 582 db.type = type;
636 db.runes = Dynarr_new (rune); 583 db.runes = Dynarr_new (rune);
637 Dynarr_add (dl->display_blocks, db); 584 Dynarr_add (dl->display_blocks, db);
638 585
639 /* Return the newly added display block. */ 586 /* Return the newly added display block. */
1900 symbol_value_in_buffer (Qsynchronize_minibuffers, w->buffer); 1847 symbol_value_in_buffer (Qsynchronize_minibuffers, w->buffer);
1901 1848
1902 dl->used_prop_data = 0; 1849 dl->used_prop_data = 0;
1903 dl->num_chars = 0; 1850 dl->num_chars = 0;
1904 1851
1905 memset (&data, 0, sizeof (data)); 1852 xzero (data);
1906 data.ef = extent_fragment_new (w->buffer, f); 1853 data.ef = extent_fragment_new (w->buffer, f);
1907 1854
1908 /* These values are used by all of the rune addition routines. We add 1855 /* These values are used by all of the rune addition routines. We add
1909 them to this structure for ease of passing. */ 1856 them to this structure for ease of passing. */
1910 data.d = d; 1857 data.d = d;
2669 2616
2670 /* If Voverlay_arrow_string isn't valid then just fail silently. */ 2617 /* If Voverlay_arrow_string isn't valid then just fail silently. */
2671 if (!STRINGP (Voverlay_arrow_string) && !GLYPHP (Voverlay_arrow_string)) 2618 if (!STRINGP (Voverlay_arrow_string) && !GLYPHP (Voverlay_arrow_string))
2672 return 0; 2619 return 0;
2673 2620
2674 memset (&data, 0, sizeof (data)); 2621 xzero (data);
2675 data.ef = NULL; 2622 data.ef = NULL;
2676 data.d = d; 2623 data.d = d;
2677 XSETWINDOW (data.window, w); 2624 XSETWINDOW (data.window, w);
2678 data.db = get_display_block_from_line (dl, OVERWRITE); 2625 data.db = get_display_block_from_line (dl, OVERWRITE);
2679 data.dl = dl; 2626 data.dl = dl;
2728 2675
2729 /* Add a type of glyph to a margin display block. */ 2676 /* Add a type of glyph to a margin display block. */
2730 2677
2731 static int 2678 static int
2732 add_margin_runes (struct display_line *dl, struct display_block *db, int start, 2679 add_margin_runes (struct display_line *dl, struct display_block *db, int start,
2733 int count, int glyph_type, int side, Lisp_Object window) 2680 int count, enum glyph_layout layout, int side, Lisp_Object window)
2734 { 2681 {
2735 glyph_block_dynarr *gbd = (side == LEFT_GLYPHS 2682 glyph_block_dynarr *gbd = (side == LEFT_GLYPHS
2736 ? dl->left_glyphs 2683 ? dl->left_glyphs
2737 : dl->right_glyphs); 2684 : dl->right_glyphs);
2738 int elt, end; 2685 int elt, end;
2739 int xpos = start; 2686 int xpos = start;
2740 int reverse; 2687 int reverse;
2741 2688
2742 if ((glyph_type == GL_WHITESPACE && side == LEFT_GLYPHS) 2689 if ((layout == GL_WHITESPACE && side == LEFT_GLYPHS)
2743 || (glyph_type == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS)) 2690 || (layout == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS))
2744 { 2691 {
2745 reverse = 1; 2692 reverse = 1;
2746 elt = Dynarr_length (gbd) - 1; 2693 elt = Dynarr_length (gbd) - 1;
2747 end = 0; 2694 end = 0;
2748 } 2695 }
2760 if (NILP (gb->extent)) 2707 if (NILP (gb->extent))
2761 abort (); /* these should have been handled in add_glyph_rune */ 2708 abort (); /* these should have been handled in add_glyph_rune */
2762 2709
2763 if (gb->active && 2710 if (gb->active &&
2764 ((side == LEFT_GLYPHS && 2711 ((side == LEFT_GLYPHS &&
2765 extent_begin_glyph_layout (XEXTENT (gb->extent)) == glyph_type) 2712 extent_begin_glyph_layout (XEXTENT (gb->extent)) == layout)
2766 || (side == RIGHT_GLYPHS && 2713 || (side == RIGHT_GLYPHS &&
2767 extent_end_glyph_layout (XEXTENT (gb->extent)) == glyph_type))) 2714 extent_end_glyph_layout (XEXTENT (gb->extent)) == layout)))
2768 { 2715 {
2769 struct rune rb; 2716 struct rune rb;
2770 2717
2771 rb.width = gb->width; 2718 rb.width = gb->width;
2772 rb.findex = gb->findex; 2719 rb.findex = gb->findex;
3578 max_pixpos -= shadow_thickness; 3525 max_pixpos -= shadow_thickness;
3579 } 3526 }
3580 else 3527 else
3581 ypos_adj = 0; 3528 ypos_adj = 0;
3582 3529
3583 #ifdef MODELINE_IS_SCROLLABLE
3584 generate_formatted_string_db (b->modeline_format, 3530 generate_formatted_string_db (b->modeline_format,
3585 b->generated_modeline_string, w, dl, db, 3531 b->generated_modeline_string, w, dl, db,
3586 MODELINE_INDEX, min_pixpos, max_pixpos, type, 3532 MODELINE_INDEX, min_pixpos, max_pixpos, type
3587 1 /* generate a modeline */); 3533 #ifdef MODELINE_IS_SCROLLABLE
3588 #else 3534 , 1 /* generate a modeline */
3589 generate_formatted_string_db (b->modeline_format,
3590 b->generated_modeline_string, w, dl, db,
3591 MODELINE_INDEX, min_pixpos, max_pixpos, type);
3592 #endif /* not MODELINE_IS_SCROLLABLE */ 3535 #endif /* not MODELINE_IS_SCROLLABLE */
3536 );
3593 3537
3594 /* The modeline is at the bottom of the gutters. We have to wait to 3538 /* The modeline is at the bottom of the gutters. We have to wait to
3595 set this until we've generated teh modeline in order to account 3539 set this until we've generated teh modeline in order to account
3596 for any embedded faces. */ 3540 for any embedded faces. */
3597 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj; 3541 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj;
3598 } 3542 }
3599 3543
3600 /* This define is for the experimental horizontal modeline scrolling. It's not 3544 /* This define is for the experimental horizontal modeline scrolling. It's not
3601 functionnal for 20.5, but might be for 21.1 */ 3545 functional for 21.0, but might be for 21.1 */
3602 #ifdef MODELINE_IS_SCROLLABLE 3546 #ifdef MODELINE_IS_SCROLLABLE
3603 static void 3547 static void
3604 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str, 3548 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str,
3605 struct window *w, struct display_line *dl, 3549 struct window *w, struct display_line *dl,
3606 struct display_block *db, face_index findex, 3550 struct display_block *db, face_index findex,
3607 int min_pixpos, int max_pixpos, int type, 3551 int min_pixpos, int max_pixpos, int type,
3608 int modeline) 3552 int modeline)
3609 { 3553 {
3610 struct frame *f = XFRAME (w->frame); 3554 struct frame *f = XFRAME (w->frame);
3611 struct device *d = XDEVICE (f->device); 3555 struct device *d = XDEVICE (f->device);
3612 3556
3613 pos_data data; 3557 pos_data data;
3614 int c_pixpos; 3558 int c_pixpos;
3615 3559
3616 memset (&data, 0, sizeof (data)); 3560 xzero (data);
3617 data.d = d; 3561 data.d = d;
3618 data.db = db; 3562 data.db = db;
3619 data.dl = dl; 3563 data.dl = dl;
3620 data.findex = findex; 3564 data.findex = findex;
3621 data.pixpos = min_pixpos; 3565 data.pixpos = min_pixpos;
3633 3577
3634 /* D. Verna Feb. 1998. 3578 /* D. Verna Feb. 1998.
3635 This recursively builds up the modeline or the title/icon string. 3579 This recursively builds up the modeline or the title/icon string.
3636 In case of a modeline, we use a negative start position to indicate 3580 In case of a modeline, we use a negative start position to indicate
3637 the current modeline horizontal scroll. */ 3581 the current modeline horizontal scroll. */
3638 generate_fstring_runes 3582 generate_fstring_runes
3639 (w, &data, 3583 (w, &data,
3640 (modeline && WINDOW_HAS_MODELINE_P (w)) ? - w->modeline_hscroll : 0, 3584 (modeline && WINDOW_HAS_MODELINE_P (w)) ? - w->modeline_hscroll : 0,
3641 (modeline && WINDOW_HAS_MODELINE_P (w)) ? - w->modeline_hscroll : 0, 3585 (modeline && WINDOW_HAS_MODELINE_P (w)) ? - w->modeline_hscroll : 0,
3642 0, /* no limit */ 1, format_str, 0, max_pixpos - min_pixpos, findex, 3586 0, /* no limit */ 1, format_str, 0, max_pixpos - min_pixpos, findex,
3643 type); 3587 type);
3644 3588
3645 if (Dynarr_length (db->runes)) 3589 if (Dynarr_length (db->runes))
3646 { 3590 {
3647 struct rune *rb = 3591 struct rune *rb =
3648 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1); 3592 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
3649 c_pixpos = rb->xpos + rb->width; 3593 c_pixpos = rb->xpos + rb->width;
3689 } 3633 }
3690 3634
3691 for (elt = 0; elt < Dynarr_length (formatted_string_extent_dynarr); 3635 for (elt = 0; elt < Dynarr_length (formatted_string_extent_dynarr);
3692 elt++) 3636 elt++)
3693 { 3637 {
3694 Lisp_Object extent = Qnil; 3638 Lisp_Object extent;
3695 Lisp_Object child; 3639 Lisp_Object child;
3696 3640
3697 XSETEXTENT (extent, Dynarr_at (formatted_string_extent_dynarr, elt)); 3641 XSETEXTENT (extent, Dynarr_at (formatted_string_extent_dynarr, elt));
3698 child = Fgethash (extent, buf->modeline_extent_table, Qnil); 3642 child = Fgethash (extent, buf->modeline_extent_table, Qnil);
3699 if (NILP (child)) 3643 if (NILP (child))
3709 result_str); 3653 result_str);
3710 } 3654 }
3711 } 3655 }
3712 } 3656 }
3713 3657
3714 /* D. Verna Feb. 1998. Rewrote this function to handle the case of a 3658 /* D. Verna Feb. 1998. Rewrote this function to handle the case of a
3715 scrolled modeline */ 3659 scrolled modeline */
3716 static Charcount 3660 static Charcount
3717 add_string_to_fstring_db_runes (pos_data *data, CONST Bufbyte *str, 3661 add_string_to_fstring_db_runes (pos_data *data, CONST Bufbyte *str,
3718 Charcount pos, Charcount min_pos, 3662 Charcount pos, Charcount min_pos,
3719 Charcount max_pos, int no_limit) 3663 Charcount max_pos, int no_limit)
3721 /* This function has been Mule-ized. */ 3665 /* This function has been Mule-ized. */
3722 Charcount initial_pos = pos; 3666 Charcount initial_pos = pos;
3723 CONST Bufbyte *cur_pos = str; 3667 CONST Bufbyte *cur_pos = str;
3724 struct display_block *db = data->db; 3668 struct display_block *db = data->db;
3725 int add_something; 3669 int add_something;
3726 3670
3727 data->blank_width = space_width (XWINDOW (data->window)); 3671 data->blank_width = space_width (XWINDOW (data->window));
3728 add_something = ((pos < min_pos) 3672 add_something = ((pos < min_pos)
3729 || ((*cur_pos) && no_limit) 3673 || ((*cur_pos) && no_limit)
3730 || ((*cur_pos) && (pos < max_pos))); 3674 || ((*cur_pos) && (pos < max_pos)));
3731 while (add_something) 3675 while (add_something)
3732 { 3676 {
3733 if ((initial_pos >= 0) && (pos == initial_pos)) 3677 if ((initial_pos >= 0) && (pos == initial_pos))
3734 while (Dynarr_length (db->runes) < pos) 3678 while (Dynarr_length (db->runes) < pos)
3735 add_blank_rune (data, NULL, 0); 3679 add_blank_rune (data, NULL, 0);
3736 3680
3737 if (pos < 0) /* just pretend we're adding something */ 3681 if (pos < 0) /* just pretend we're adding something */
3738 { 3682 {
3739 if (*cur_pos) 3683 if (*cur_pos)
3740 INC_CHARPTR (cur_pos); 3684 INC_CHARPTR (cur_pos);
3741 pos += 1; 3685 pos += 1;
3744 { 3688 {
3745 if (*cur_pos) /* some stuff to add */ 3689 if (*cur_pos) /* some stuff to add */
3746 { 3690 {
3747 CONST Bufbyte *old_cur_pos = cur_pos; 3691 CONST Bufbyte *old_cur_pos = cur_pos;
3748 int succeeded; 3692 int succeeded;
3749 3693
3750 data->ch = charptr_emchar (cur_pos); 3694 data->ch = charptr_emchar (cur_pos);
3751 succeeded = (add_emchar_rune (data) != ADD_FAILED); 3695 succeeded = (add_emchar_rune (data) != ADD_FAILED);
3752 INC_CHARPTR (cur_pos); 3696 INC_CHARPTR (cur_pos);
3753 if (succeeded) 3697 if (succeeded)
3754 { 3698 {
3770 if (*cur_pos) 3714 if (*cur_pos)
3771 INC_CHARPTR (cur_pos); 3715 INC_CHARPTR (cur_pos);
3772 pos += 1; 3716 pos += 1;
3773 } 3717 }
3774 } 3718 }
3775 add_something = ((pos < min_pos) 3719 add_something = ((pos < min_pos)
3776 || ((*cur_pos) && no_limit) 3720 || ((*cur_pos) && no_limit)
3777 || ((*cur_pos) && (pos < max_pos))); 3721 || ((*cur_pos) && (pos < max_pos)));
3778 } 3722 }
3779 3723
3780 return pos; 3724 return pos;
3782 3726
3783 /* #### Urk! Should also handle begin-glyphs and end-glyphs in 3727 /* #### Urk! Should also handle begin-glyphs and end-glyphs in
3784 modeline extents. */ 3728 modeline extents. */
3785 static Charcount 3729 static Charcount
3786 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph, 3730 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph,
3787 Charcount pos, Charcount min_pos, 3731 Charcount pos, Charcount min_pos,
3788 Charcount max_pos, int no_limit) 3732 Charcount max_pos, int no_limit)
3789 { 3733 {
3790 /* This function has been Mule-ized. */ 3734 /* This function has been Mule-ized. */
3791 Charcount end; 3735 Charcount end;
3792 struct display_block *db = data->db; 3736 struct display_block *db = data->db;
3793 struct glyph_block gb; 3737 struct glyph_block gb;
3794 3738
3795 /* D. Verna Feb. 1998. 3739 /* D. Verna Feb. 1998.
3796 If pos < 0, we're building a scrolled modeline. 3740 If pos < 0, we're building a scrolled modeline.
3797 The glyph should be hidden. So just skip it. */ 3741 The glyph should be hidden. So just skip it. */
3798 if (pos < 0) 3742 if (pos < 0)
3799 return (pos + 1); 3743 return (pos + 1);
3800 3744
3801 data->blank_width = space_width (XWINDOW (data->window)); 3745 data->blank_width = space_width (XWINDOW (data->window));
3802 while (Dynarr_length (db->runes) < pos) 3746 while (Dynarr_length (db->runes) < pos)
3803 add_blank_rune (data, NULL, 0); 3747 add_blank_rune (data, NULL, 0);
3804 3748
3805 end = Dynarr_length (db->runes) + 1; 3749 end = Dynarr_length (db->runes) + 1;
3806 if (!no_limit) 3750 if (!no_limit)
3807 end = min (max_pos, end); 3751 end = min (max_pos, end);
3808 3752
3809 gb.glyph = glyph; 3753 gb.glyph = glyph;
3810 gb.extent = Qnil; 3754 gb.extent = Qnil;
3811 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0); 3755 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
3812 pos++; 3756 pos++;
3813 3757
3852 3796
3853 if (STRINGP (elt)) 3797 if (STRINGP (elt))
3854 { 3798 {
3855 /* A string. Add to the display line and check for %-constructs 3799 /* A string. Add to the display line and check for %-constructs
3856 within it. */ 3800 within it. */
3857 3801
3858 Bufbyte *this = XSTRING_DATA (elt); 3802 Bufbyte *this = XSTRING_DATA (elt);
3859 3803
3860 while ((no_limit || pos < max_pos) && *this) 3804 while ((no_limit || pos < max_pos) && *this)
3861 { 3805 {
3862 Bufbyte *last = this; 3806 Bufbyte *last = this;
3863 3807
3864 while (*this && *this != '%') 3808 while (*this && *this != '%')
3865 this++; 3809 this++;
3866 3810
3867 if (this != last) 3811 if (this != last)
3868 { 3812 {
3869 /* The string is just a string. */ 3813 /* The string is just a string. */
3870 Charcount size = 3814 Charcount size =
3871 bytecount_to_charcount (last, this - last) + pos; 3815 bytecount_to_charcount (last, this - last) + pos;
3872 Charcount tmp_max = (no_limit ? size : min (size, max_pos)); 3816 Charcount tmp_max = (no_limit ? size : min (size, max_pos));
3873 3817
3874 pos = add_string_to_fstring_db_runes (data, last, pos, pos, 3818 pos = add_string_to_fstring_db_runes (data, last, pos, pos,
3875 tmp_max, /* limit */0); 3819 tmp_max, /* limit */0);
3876 } 3820 }
3877 else /* *this == '%' */ 3821 else /* *this == '%' */
3878 { 3822 {
3923 num_to_add++; 3867 num_to_add++;
3924 } 3868 }
3925 3869
3926 while (num_to_add--) 3870 while (num_to_add--)
3927 pos = add_string_to_fstring_db_runes 3871 pos = add_string_to_fstring_db_runes
3928 (data, (CONST Bufbyte *) "-", 3872 (data, (CONST Bufbyte *) "-",
3929 pos, pos, max_pos, no_limit); 3873 pos, pos, max_pos, no_limit);
3930 } 3874 }
3931 else if (*this != 0) 3875 else if (*this != 0)
3932 { 3876 {
3933 Bufbyte *str; 3877 Bufbyte *str;
4065 { 4009 {
4066 int limit = 50; 4010 int limit = 50;
4067 /* LIMIT is to protect against circular lists. */ 4011 /* LIMIT is to protect against circular lists. */
4068 while (CONSP (elt) && --limit > 0 && (no_limit || pos < max_pos)) 4012 while (CONSP (elt) && --limit > 0 && (no_limit || pos < max_pos))
4069 { 4013 {
4070 pos = generate_fstring_runes (w, data, pos, pos, max_pos, 4014 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4071 no_limit, 4015 no_limit,
4072 XCAR (elt), depth, 4016 XCAR (elt), depth,
4073 max_pixsize, findex, type); 4017 max_pixsize, findex, type);
4074 elt = XCDR (elt); 4018 elt = XCDR (elt);
4075 } 4019 }
4105 } 4049 }
4106 else 4050 else
4107 new_findex = old_findex; 4051 new_findex = old_findex;
4108 4052
4109 data->findex = new_findex; 4053 data->findex = new_findex;
4110 pos = generate_fstring_runes (w, data, pos, pos, max_pos, 4054 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4111 no_limit, 4055 no_limit,
4112 XCDR (elt), depth - 1, 4056 XCDR (elt), depth - 1,
4113 max_pixsize, new_findex, type); 4057 max_pixsize, new_findex, type);
4114 data->findex = old_findex; 4058 data->findex = old_findex;
4115 Dynarr_add (formatted_string_extent_dynarr, ext); 4059 Dynarr_add (formatted_string_extent_dynarr, ext);
4118 } 4062 }
4119 } 4063 }
4120 } 4064 }
4121 else if (GLYPHP (elt)) 4065 else if (GLYPHP (elt))
4122 { 4066 {
4123 pos = add_glyph_to_fstring_db_runes 4067 pos = add_glyph_to_fstring_db_runes
4124 (data, elt, pos, pos, max_pos, no_limit); 4068 (data, elt, pos, pos, max_pos, no_limit);
4125 } 4069 }
4126 else 4070 else
4127 { 4071 {
4128 invalid: 4072 invalid:
4151 struct device *d = XDEVICE (f->device); 4095 struct device *d = XDEVICE (f->device);
4152 4096
4153 pos_data data; 4097 pos_data data;
4154 int c_pixpos; 4098 int c_pixpos;
4155 4099
4156 memset (&data, 0, sizeof (data)); 4100 xzero (data);
4157 data.d = d; 4101 data.d = d;
4158 data.db = db; 4102 data.db = db;
4159 data.dl = dl; 4103 data.dl = dl;
4160 data.findex = findex; 4104 data.findex = findex;
4161 data.pixpos = min_pixpos; 4105 data.pixpos = min_pixpos;
4648 db = get_display_block_from_line (dl, TEXT); 4592 db = get_display_block_from_line (dl, TEXT);
4649 Dynarr_reset (db->runes); 4593 Dynarr_reset (db->runes);
4650 4594
4651 #ifdef MODELINE_IS_SCROLLABLE 4595 #ifdef MODELINE_IS_SCROLLABLE
4652 /* D. Verna Feb. 1998. 4596 /* D. Verna Feb. 1998.
4653 Currently, only update_frame_title can make us come here. This is not 4597 Currently, only update_frame_title can make us come here. This is not
4654 to build a modeline */ 4598 to build a modeline */
4655 generate_formatted_string_db (format_str, result_str, w, dl, db, findex, 0, 4599 generate_formatted_string_db (format_str, result_str, w, dl, db, findex, 0,
4656 -1, type, 0 /* not a modeline */); 4600 -1, type, 0 /* not a modeline */);
4657 #else /* not MODELINE_IS_SCROLLABLE */ 4601 #else /* not MODELINE_IS_SCROLLABLE */
4658 generate_formatted_string_db (format_str, result_str, w, dl, db, findex, 0, 4602 generate_formatted_string_db (format_str, result_str, w, dl, db, findex, 0,
4729 Dynarr_add (dla, *mlp); 4673 Dynarr_add (dla, *mlp);
4730 } 4674 }
4731 else 4675 else
4732 { 4676 {
4733 struct display_line modeline; 4677 struct display_line modeline;
4734 memset (&modeline, 0, sizeof (struct display_line)); 4678 xzero (modeline);
4735 Dynarr_add (dla, modeline); 4679 Dynarr_add (dla, modeline);
4736 } 4680 }
4737 } 4681 }
4738 4682
4739 /* If we're adding a new place marker go ahead and generate the 4683 /* If we're adding a new place marker go ahead and generate the
4850 dlp = Dynarr_atp (dla, Dynarr_length (dla)); 4794 dlp = Dynarr_atp (dla, Dynarr_length (dla));
4851 local = 0; 4795 local = 0;
4852 } 4796 }
4853 else 4797 else
4854 { 4798 {
4799 xzero (dl);
4855 dlp = &dl; 4800 dlp = &dl;
4856 memset (dlp, 0, sizeof (struct display_line));
4857 local = 1; 4801 local = 1;
4858 } 4802 }
4859 4803
4860 dlp->bounds = bounds; 4804 dlp->bounds = bounds;
4861 dlp->offset = 0; 4805 dlp->offset = 0;
5905 return 0; 5849 return 0;
5906 } 5850 }
5907 5851
5908 if (lrpos >= pos) 5852 if (lrpos >= pos)
5909 { 5853 {
5910 Lisp_Object window = Qnil; 5854 Lisp_Object window;
5911 XSETWINDOW (window, w); 5855 XSETWINDOW (window, w);
5912 va_run_hook_with_args_in_buffer (XBUFFER (w->buffer), 5856 va_run_hook_with_args_in_buffer (XBUFFER (w->buffer),
5913 Qredisplay_end_trigger_functions, 5857 Qredisplay_end_trigger_functions,
5914 2, window, 5858 2, window,
5915 w->redisplay_end_trigger); 5859 w->redisplay_end_trigger);
6386 #ifdef HAVE_TTY 6330 #ifdef HAVE_TTY
6387 { 6331 {
6388 struct frame *f = XFRAME (w->frame); 6332 struct frame *f = XFRAME (w->frame);
6389 if (FRAME_TTY_P (f) && f->order_count > 1) 6333 if (FRAME_TTY_P (f) && f->order_count > 1)
6390 { 6334 {
6391 str = (CONST char *) alloca (10); 6335 char * writable_str = alloca_array (char, 10);
6392 sprintf (str, "-%d", f->order_count); 6336 sprintf (writable_str, "-%d", f->order_count);
6337 str = writable_str;
6393 } 6338 }
6394 } 6339 }
6395 #endif /* HAVE_TTY */ 6340 #endif /* HAVE_TTY */
6396 break; 6341 break;
6397 6342
7392 if (cur_elt + new_line >= Dynarr_length (w->line_start_cache)) 7337 if (cur_elt + new_line >= Dynarr_length (w->line_start_cache))
7393 { 7338 {
7394 /* Hit the bottom of the buffer. */ 7339 /* Hit the bottom of the buffer. */
7395 int adjustment = 7340 int adjustment =
7396 (cur_elt + new_line) - Dynarr_length (w->line_start_cache) + 1; 7341 (cur_elt + new_line) - Dynarr_length (w->line_start_cache) + 1;
7397 Lisp_Object window = Qnil; 7342 Lisp_Object window;
7398 int defheight; 7343 int defheight;
7399 7344
7400 XSETWINDOW (window, w); 7345 XSETWINDOW (window, w);
7401 default_face_height_and_width (window, &defheight, 0); 7346 default_face_height_and_width (window, &defheight, 0);
7402 7347
7601 int old_lb = low_bound; 7546 int old_lb = low_bound;
7602 7547
7603 while (startp < old_lb || low_bound == -1) 7548 while (startp < old_lb || low_bound == -1)
7604 { 7549 {
7605 int ic_elt; 7550 int ic_elt;
7551 Bufpos new_startp;
7606 7552
7607 regenerate_window (w, startp, point, CMOTION_DISP); 7553 regenerate_window (w, startp, point, CMOTION_DISP);
7608 update_internal_cache_list (w, CMOTION_DISP); 7554 update_internal_cache_list (w, CMOTION_DISP);
7609 7555
7610 /* If this assert is triggered then regenerate_window failed 7556 /* If this assert is triggered then regenerate_window failed
7638 ic_elt--; 7584 ic_elt--;
7639 } 7585 }
7640 } 7586 }
7641 assert (ic_elt >= 0); 7587 assert (ic_elt >= 0);
7642 7588
7643 Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0), 7589 new_startp = Dynarr_atp (internal_cache, ic_elt)->end + 1;
7644 ic_elt + 1, marker); 7590
7645 marker += (ic_elt + 1); 7591 /*
7592 * Handle invisible text properly:
7593 * If the last line we're inserting has the same end as the
7594 * line before which it will be added, merge the two lines.
7595 */
7596 if (Dynarr_length (cache) &&
7597 Dynarr_atp (internal_cache, ic_elt)->end ==
7598 Dynarr_atp (cache, marker)->end)
7599 {
7600 Dynarr_atp (cache, marker)->start
7601 = Dynarr_atp (internal_cache, ic_elt)->start;
7602 Dynarr_atp (cache, marker)->height
7603 = Dynarr_atp (internal_cache, ic_elt)->height;
7604 ic_elt--;
7605 }
7606
7607 if (ic_elt >= 0) /* we still have lines to add.. */
7608 {
7609 Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0),
7610 ic_elt + 1, marker);
7611 marker += (ic_elt + 1);
7612 }
7646 7613
7647 if (startp < low_bound || low_bound == -1) 7614 if (startp < low_bound || low_bound == -1)
7648 low_bound = startp; 7615 low_bound = startp;
7649 startp = Dynarr_atp (internal_cache, ic_elt)->end + 1; 7616 startp = new_startp;
7650 if (startp > BUF_ZV (b)) 7617 if (startp > BUF_ZV (b))
7651 { 7618 {
7652 updating_line_start_cache = 0; 7619 updating_line_start_cache = 0;
7653 w->line_cache_validation_override--; 7620 w->line_cache_validation_override--;
7654 return; 7621 return;
7701 glyph_to_pixel_translation (struct window *w, int char_x, int char_y, 7668 glyph_to_pixel_translation (struct window *w, int char_x, int char_y,
7702 int *pix_x, int *pix_y) 7669 int *pix_x, int *pix_y)
7703 { 7670 {
7704 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP); 7671 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
7705 int num_disp_lines, modeline; 7672 int num_disp_lines, modeline;
7706 Lisp_Object window = Qnil; 7673 Lisp_Object window;
7707 int defheight, defwidth; 7674 int defheight, defwidth;
7708 7675
7709 XSETWINDOW (window, w); 7676 XSETWINDOW (window, w);
7710 default_face_height_and_width (window, &defheight, &defwidth); 7677 default_face_height_and_width (window, &defheight, &defwidth);
7711 7678
8354 8321
8355 if (bot_elt >= 0) 8322 if (bot_elt >= 0)
8356 { 8323 {
8357 struct display_line *dl = Dynarr_atp (dla, bot_elt); 8324 struct display_line *dl = Dynarr_atp (dla, bot_elt);
8358 int adj_area = y_coord - (dl->ypos + dl->descent); 8325 int adj_area = y_coord - (dl->ypos + dl->descent);
8359 Lisp_Object lwin = Qnil; 8326 Lisp_Object lwin;
8360 int defheight; 8327 int defheight;
8361 8328
8362 XSETWINDOW (lwin, *w); 8329 XSETWINDOW (lwin, *w);
8363 default_face_height_and_width (lwin, 0, &defheight); 8330 default_face_height_and_width (lwin, 0, &defheight);
8364 8331
8732 formatted_string_emchar_dynarr = Dynarr_new (Emchar); 8699 formatted_string_emchar_dynarr = Dynarr_new (Emchar);
8733 formatted_string_extent_dynarr = Dynarr_new (EXTENT); 8700 formatted_string_extent_dynarr = Dynarr_new (EXTENT);
8734 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount); 8701 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount);
8735 formatted_string_extent_end_dynarr = Dynarr_new (Bytecount); 8702 formatted_string_extent_end_dynarr = Dynarr_new (Bytecount);
8736 internal_cache = Dynarr_new (line_start_cache); 8703 internal_cache = Dynarr_new (line_start_cache);
8737 memset (&formatted_string_display_line, 0, sizeof (struct display_line)); 8704 xzero (formatted_string_display_line);
8738 } 8705 }
8739 8706
8740 /* window system is nil when in -batch mode */ 8707 /* window system is nil when in -batch mode */
8741 if (!initialized || noninteractive) 8708 if (!initialized || noninteractive)
8742 return; 8709 return;
8830 8797
8831 updating_line_start_cache = 0; 8798 updating_line_start_cache = 0;
8832 8799
8833 /* #### Probably temporary */ 8800 /* #### Probably temporary */
8834 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /* 8801 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /*
8835 (Temporary) Setting this will impact the performance of the internal 8802 \(Temporary) Setting this will impact the performance of the internal
8836 line start cache. 8803 line start cache.
8837 */ ); 8804 */ );
8838 cache_adjustment = 2; 8805 cache_adjustment = 2;
8839 8806
8840 DEFVAR_INT_MAGIC ("pixel-vertical-clip-threshold", &vertical_clip /* 8807 DEFVAR_INT_MAGIC ("pixel-vertical-clip-threshold", &vertical_clip /*