comparison src/redisplay.c @ 412:697ef44129c6 r21-2-14

Import from CVS: tag r21-2-14
author cvs
date Mon, 13 Aug 2007 11:20:41 +0200
parents de805c49cfc1
children 95016f13131a
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
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"
48 #include "elhash.h" 49 #include "elhash.h"
49 #include "extents.h" 50 #include "extents.h"
50 #include "faces.h" 51 #include "faces.h"
51 #include "frame.h" 52 #include "frame.h"
52 #include "glyphs.h" 53 #include "glyphs.h"
53 #include "gutter.h"
54 #include "insdel.h" 54 #include "insdel.h"
55 #include "menubar.h" 55 #include "menubar.h"
56 #include "objects.h" 56 #include "objects.h"
57 #include "process.h" 57 #include "process.h"
58 #include "redisplay.h" 58 #include "redisplay.h"
61 #include "line-number.h" 61 #include "line-number.h"
62 #ifdef FILE_CODING 62 #ifdef FILE_CODING
63 #include "file-coding.h" 63 #include "file-coding.h"
64 #endif 64 #endif
65 65
66 #include "sysfile.h"
67
68 #ifdef HAVE_TTY 66 #ifdef HAVE_TTY
69 #include "console-tty.h" 67 #include "console-tty.h"
68 #ifdef HAVE_UNISTD_H
69 #include <unistd.h> /* for isatty() */
70 #endif
70 #endif /* HAVE_TTY */ 71 #endif /* HAVE_TTY */
71 72
72 /* Note: We have to be careful throughout this code to properly handle 73 /* Note: We have to be careful throughout this code to properly handle
73 and differentiate between Bufbytes and Emchars. 74 and differentiate between Bufbytes and Emchars.
74 75
83 #define BEGIN_GLYPHS 0 84 #define BEGIN_GLYPHS 0
84 #define END_GLYPHS 1 85 #define END_GLYPHS 1
85 #define LEFT_GLYPHS 2 86 #define LEFT_GLYPHS 2
86 #define RIGHT_GLYPHS 3 87 #define RIGHT_GLYPHS 3
87 88
89 /* Set the vertical clip to 0 if we are currently updating the line
90 start cache. Otherwise for buffers of line height 1 it may fail to
91 be able to work properly because regenerate_window will not layout
92 a single line. */
88 #define VERTICAL_CLIP(w, display) \ 93 #define VERTICAL_CLIP(w, display) \
89 ((WINDOW_TTY_P (w) | (!display && scroll_on_clipped_lines)) \ 94 (updating_line_start_cache \
95 ? 0 \
96 : ((WINDOW_TTY_P (w) | (!display && scroll_on_clipped_lines)) \
90 ? INT_MAX \ 97 ? INT_MAX \
91 : vertical_clip) 98 : vertical_clip))
92 99
93 /* The following structures are completely private to redisplay.c so 100 /* The following structures are completely private to redisplay.c so
94 we put them here instead of in a header file, for modularity. */ 101 we put them here instead of in a header file, for modularity. */
95 102
96 /* NOTE: Bytinds not Bufpos's in this structure. */ 103 /* NOTE: Bytinds not Bufpos's in this structure. */
98 typedef struct position_redisplay_data_type 105 typedef struct position_redisplay_data_type
99 { 106 {
100 /* This information is normally filled in by the create_*_block 107 /* This information is normally filled in by the create_*_block
101 routines and is used by the add_*_rune routines. */ 108 routines and is used by the add_*_rune routines. */
102 Lisp_Object window; 109 Lisp_Object window;
103 /* if we are working with strings rather than buffers we need a
104 handle to the string */
105 Lisp_Object string;
106 struct device *d; 110 struct device *d;
107 struct display_block *db; 111 struct display_block *db;
108 struct display_line *dl; 112 struct display_line *dl;
109 Emchar ch; /* Character that is to be added. This is 113 Emchar ch; /* Character that is to be added. This is
110 used to communicate this information to 114 used to communicate this information to
144 need to be skipped. This is used for horizontal 148 need to be skipped. This is used for horizontal
145 scrolling, where a certain number of columns 149 scrolling, where a certain number of columns
146 (those off the left side of the screen) need 150 (those off the left side of the screen) need
147 to be skipped before anything is displayed. */ 151 to be skipped before anything is displayed. */
148 Bytind bi_start_col_enabled; 152 Bytind bi_start_col_enabled;
149 int start_col_xoffset; /* Number of pixels that still need to
150 be skipped. This is used for
151 horizontal scrolling of glyphs, where we want
152 to be able to scroll over part of the glyph. */
153 153
154 int hscroll_glyph_width_adjust; /* how much the width of the hscroll 154 int hscroll_glyph_width_adjust; /* how much the width of the hscroll
155 glyph differs from space_width (w). 155 glyph differs from space_width (w).
156 0 if no hscroll glyph was used, 156 0 if no hscroll glyph was used,
157 i.e. the window is not scrolled 157 i.e. the window is not scrolled
236 { 236 {
237 Dynarr_declare (prop_block); 237 Dynarr_declare (prop_block);
238 } prop_block_dynarr; 238 } prop_block_dynarr;
239 239
240 240
241 static void generate_formatted_string_db (Lisp_Object format_str,
242 Lisp_Object result_str,
243 struct window *w,
244 struct display_line *dl,
245 struct display_block *db,
246 face_index findex, int min_pixpos,
247 int max_pixpos, int type);
241 static Charcount generate_fstring_runes (struct window *w, pos_data *data, 248 static Charcount generate_fstring_runes (struct window *w, pos_data *data,
242 Charcount pos, Charcount min_pos, 249 Charcount pos, Charcount min_pos,
243 Charcount max_pos, Lisp_Object elt, 250 Charcount max_pos, Lisp_Object elt,
244 int depth, int max_pixsize, 251 int depth, int max_pixsize,
245 face_index findex, int type, 252 face_index findex, int type);
246 Charcount *offset,
247 Lisp_Object cur_ext);
248 static prop_block_dynarr *add_glyph_rune (pos_data *data, 253 static prop_block_dynarr *add_glyph_rune (pos_data *data,
249 struct glyph_block *gb, 254 struct glyph_block *gb,
250 int pos_type, int allow_cursor, 255 int pos_type, int allow_cursor,
251 struct glyph_cachel *cachel); 256 struct glyph_cachel *cachel);
252 static Bytind create_text_block (struct window *w, struct display_line *dl, 257 static Bytind create_text_block (struct window *w, struct display_line *dl,
253 Bytind bi_start_pos, prop_block_dynarr **prop, 258 Bytind bi_start_pos, int start_col,
259 prop_block_dynarr **prop,
254 int type); 260 int type);
255 static int create_overlay_glyph_block (struct window *w, 261 static int create_overlay_glyph_block (struct window *w,
256 struct display_line *dl); 262 struct display_line *dl);
257 static void create_left_glyph_block (struct window *w, 263 static void create_left_glyph_block (struct window *w,
258 struct display_line *dl, 264 struct display_line *dl,
285 routines. We used to just give each window a third set. However, 291 routines. We used to just give each window a third set. However,
286 we always fully regenerate the structures when needed so there 292 we always fully regenerate the structures when needed so there
287 isn't any reason we need more than a single set. */ 293 isn't any reason we need more than a single set. */
288 display_line_dynarr *cmotion_display_lines; 294 display_line_dynarr *cmotion_display_lines;
289 295
296 /* Used by generate_formatted_string. Global because they get used so
297 much that the dynamic allocation time adds up. */
298 Emchar_dynarr *formatted_string_emchar_dynarr;
299 struct display_line formatted_string_display_line;
290 /* We store the extents that we need to generate in a Dynarr and then 300 /* We store the extents that we need to generate in a Dynarr and then
291 frob them all on at the end of generating the string. We do it 301 frob them all on at the end of generating the string. We do it
292 this way rather than adding them as we generate the string because 302 this way rather than adding them as we generate the string because
293 we don't store the text into the resulting string until we're done 303 we don't store the text into the resulting string until we're done
294 (to avoid having to resize the string multiple times), and we don't 304 (to avoid having to resize the string multiple times), and we don't
295 want to go around adding extents to a string when the extents might 305 want to go around adding extents to a string when the extents might
296 stretch off the end of the string. */ 306 stretch off the end of the string. */
297 static EXTENT_dynarr *formatted_string_extent_dynarr; 307 EXTENT_dynarr *formatted_string_extent_dynarr;
298 static Bytecount_dynarr *formatted_string_extent_start_dynarr; 308 Bytecount_dynarr *formatted_string_extent_start_dynarr;
299 static Bytecount_dynarr *formatted_string_extent_end_dynarr; 309 Bytecount_dynarr *formatted_string_extent_end_dynarr;
300 310
301 311
302 /* #### probably temporary */ 312 /* #### probably temporary */
303 int cache_adjustment; 313 int cache_adjustment;
304 314
317 /* Minimum pixel height of clipped bottom display line. */ 327 /* Minimum pixel height of clipped bottom display line. */
318 int vertical_clip; 328 int vertical_clip;
319 329
320 /* Minimum visible pixel width of clipped glyphs at right margin. */ 330 /* Minimum visible pixel width of clipped glyphs at right margin. */
321 int horizontal_clip; 331 int horizontal_clip;
332
333 /* Set if currently inside update_line_start_cache. */
334 int updating_line_start_cache;
322 335
323 /* Nonzero means reading single-character input with prompt 336 /* Nonzero means reading single-character input with prompt
324 so put cursor on minibuffer after the prompt. */ 337 so put cursor on minibuffer after the prompt. */
325 int cursor_in_echo_area; 338 int cursor_in_echo_area;
326 Lisp_Object Qcursor_in_echo_area; 339 Lisp_Object Qcursor_in_echo_area;
351 hscroll, control-arrow, etc) is in need of updating 364 hscroll, control-arrow, etc) is in need of updating
352 somewhere. */ 365 somewhere. */
353 int glyphs_changed; 366 int glyphs_changed;
354 int glyphs_changed_set; 367 int glyphs_changed_set;
355 368
356 /* non-zero if any subwindow has been deleted. */ 369 /* non-zero if any displayed subwindow is in need of updating
370 somewhere. */
357 int subwindows_changed; 371 int subwindows_changed;
358 int subwindows_changed_set; 372 int subwindows_changed_set;
359
360 /* non-zero if any displayed subwindow is in need of updating
361 somewhere. */
362 int subwindows_state_changed;
363 int subwindows_state_changed_set;
364 373
365 /* This variable is 1 if the icon has to be updated. 374 /* This variable is 1 if the icon has to be updated.
366 It is set to 1 when `frame-icon-glyph' changes. */ 375 It is set to 1 when `frame-icon-glyph' changes. */
367 int icon_changed; 376 int icon_changed;
368 int icon_changed_set; 377 int icon_changed_set;
390 399
391 /* non-nil if any toolbar has changed */ 400 /* non-nil if any toolbar has changed */
392 int toolbar_changed; 401 int toolbar_changed;
393 int toolbar_changed_set; 402 int toolbar_changed_set;
394 403
395 /* non-nil if any gutter has changed */
396 int gutter_changed;
397 int gutter_changed_set;
398
399 /* non-nil if any window has changed since the last time redisplay completed */ 404 /* non-nil if any window has changed since the last time redisplay completed */
400 int windows_changed; 405 int windows_changed;
401 406
402 /* non-nil if any frame's window structure has changed since the last 407 /* non-nil if any frame's window structure has changed since the last
403 time redisplay completed */ 408 time redisplay completed */
405 410
406 /* If non-nil, use vertical bar cursor. */ 411 /* If non-nil, use vertical bar cursor. */
407 Lisp_Object Vbar_cursor; 412 Lisp_Object Vbar_cursor;
408 Lisp_Object Qbar_cursor; 413 Lisp_Object Qbar_cursor;
409 414
410 Lisp_Object Vvisible_bell; /* If true and the terminal will support it 415
411 then the frame will flash instead of 416 int visible_bell; /* If true and the terminal will support it
412 beeping when an error occurs */ 417 then the frame will flash instead of
418 beeping when an error occurs */
413 419
414 /* Nonzero means no need to redraw the entire frame on resuming 420 /* Nonzero means no need to redraw the entire frame on resuming
415 a suspended Emacs. This is useful on terminals with multiple pages, 421 a suspended Emacs. This is useful on terminals with multiple pages,
416 where one page is used for Emacs and another for all else. */ 422 where one page is used for Emacs and another for all else. */
417 int no_redraw_on_reenter; 423 int no_redraw_on_reenter;
434 Lisp_Object Voverlay_arrow_position; 440 Lisp_Object Voverlay_arrow_position;
435 /* String to display for the arrow. */ 441 /* String to display for the arrow. */
436 Lisp_Object Voverlay_arrow_string; 442 Lisp_Object Voverlay_arrow_string;
437 443
438 Lisp_Object Vwindow_size_change_functions; 444 Lisp_Object Vwindow_size_change_functions;
439 Lisp_Object Vwindow_scroll_functions; 445 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
440 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions; 446 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
441
442 Lisp_Object Qbuffer_list_changed_hook, Vbuffer_list_changed_hook;
443
444 447
445 #define INHIBIT_REDISPLAY_HOOKS /* #### Until we've thought about 448 #define INHIBIT_REDISPLAY_HOOKS /* #### Until we've thought about
446 this more. */ 449 this more. */
447 #ifndef INHIBIT_REDISPLAY_HOOKS 450 #ifndef INHIBIT_REDISPLAY_HOOKS
448 /* #### Chuck says: I think this needs more thought. 451 /* #### Chuck says: I think this needs more thought.
449 Think about this for 19.14. */ 452 Think about this for 19.14. */
450 Lisp_Object Vpre_redisplay_hook, Vpost_redisplay_hook; 453 Lisp_Object Vpre_redisplay_hook, Vpost_redisplay_hook;
451 Lisp_Object Qpre_redisplay_hook, Qpost_redisplay_hook; 454 Lisp_Object Qpre_redisplay_hook, Qpost_redisplay_hook;
452 #endif /* INHIBIT_REDISPLAY_HOOKS */ 455 #endif /* INHIBIT_REDISPLAY_HOOKS */
453 456
454 static int last_display_warning_tick, display_warning_tick; 457 int last_display_warning_tick, display_warning_tick;
455 Lisp_Object Qdisplay_warning_buffer; 458 Lisp_Object Qdisplay_warning_buffer;
456 int inhibit_warning_display; 459 int inhibit_warning_display;
457 460
458 Lisp_Object Vleft_margin_width, Vright_margin_width; 461 Lisp_Object Vleft_margin_width, Vright_margin_width;
459 Lisp_Object Vminimum_line_ascent, Vminimum_line_descent; 462 Lisp_Object Vminimum_line_ascent, Vminimum_line_descent;
460 Lisp_Object Vuse_left_overflow, Vuse_right_overflow; 463 Lisp_Object Vuse_left_overflow, Vuse_right_overflow;
461 Lisp_Object Vtext_cursor_visible_p; 464 Lisp_Object Vtext_cursor_visible_p;
462 465
463 int column_number_start_at_one; 466 int column_number_start_at_one;
464
465 Lisp_Object Qtop_bottom;
466
467 #define WINDOW_SCROLLED(w) \
468 (w->hscroll > 0 || w->left_xoffset)
469
470 467
471 /***************************************************************************/ 468 /***************************************************************************/
472 /* */ 469 /* */
473 /* low-level interfaces onto device routines */ 470 /* low-level interfaces onto device routines */
474 /* */ 471 /* */
634 { 631 {
635 int n_pos = left_pixpos; 632 int n_pos = left_pixpos;
636 int pix_tab_width = tab_pix_width (w); 633 int pix_tab_width = tab_pix_width (w);
637 634
638 /* Adjust n_pos for any hscrolling which has happened. */ 635 /* Adjust n_pos for any hscrolling which has happened. */
639 if (WINDOW_SCROLLED (w)) 636 if (w->hscroll > 1)
640 n_pos -= space_width (w) * (w->hscroll - 1) + w->left_xoffset; 637 n_pos -= space_width (w) * (w->hscroll - 1);
641 638
642 while (n_pos <= start_pixpos) 639 while (n_pos <= start_pixpos)
643 n_pos += pix_tab_width; 640 n_pos += pix_tab_width;
644 641
645 return n_pos; 642 return n_pos;
687 when the contents of the line reach the right boundary of the given 684 when the contents of the line reach the right boundary of the given
688 window. */ 685 window. */
689 686
690 static Bufpos 687 static Bufpos
691 generate_display_line (struct window *w, struct display_line *dl, int bounds, 688 generate_display_line (struct window *w, struct display_line *dl, int bounds,
692 Bufpos start_pos, prop_block_dynarr **prop, 689 Bufpos start_pos, int start_col,
690 prop_block_dynarr **prop,
693 int type) 691 int type)
694 { 692 {
695 Bufpos ret_bufpos; 693 Bufpos ret_bufpos;
696 int overlay_width; 694 int overlay_width;
697 struct buffer *b = XBUFFER (WINDOW_BUFFER (w)); 695 struct buffer *b = XBUFFER (WINDOW_BUFFER (w));
720 /* Create a display block for the text region of the line. */ 718 /* Create a display block for the text region of the line. */
721 { 719 {
722 /* #### urk urk urk!!! Chuck fix this shit! */ 720 /* #### urk urk urk!!! Chuck fix this shit! */
723 Bytind hacked_up_bytind = 721 Bytind hacked_up_bytind =
724 create_text_block (w, dl, bufpos_to_bytind (b, start_pos), 722 create_text_block (w, dl, bufpos_to_bytind (b, start_pos),
725 prop, type); 723 start_col, prop, type);
726 if (hacked_up_bytind > BI_BUF_ZV (b)) 724 if (hacked_up_bytind > BI_BUF_ZV (b))
727 ret_bufpos = BUF_ZV (b) + 1; 725 ret_bufpos = BUF_ZV (b) + 1;
728 else 726 else
729 ret_bufpos = bytind_to_bufpos (b, hacked_up_bytind); 727 ret_bufpos = bytind_to_bufpos (b, hacked_up_bytind);
730 } 728 }
794 792
795 gb.extent = Qnil; 793 gb.extent = Qnil;
796 gb.glyph = Vhscroll_glyph; 794 gb.glyph = Vhscroll_glyph;
797 { 795 {
798 int oldpixpos = data->pixpos; 796 int oldpixpos = data->pixpos;
799 retval = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 797 retval = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
800 GLYPH_CACHEL (XWINDOW (data->window), 798 GLYPH_CACHEL (XWINDOW (data->window),
801 HSCROLL_GLYPH_INDEX)); 799 HSCROLL_GLYPH_INDEX));
802 data->hscroll_glyph_width_adjust = 800 data->hscroll_glyph_width_adjust =
803 data->pixpos - oldpixpos - space_width (XWINDOW (data->window)); 801 data->pixpos - oldpixpos - space_width (XWINDOW (data->window));
804 } 802 }
850 struct window *w = XWINDOW (data->window); 848 struct window *w = XWINDOW (data->window);
851 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, data->findex); 849 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, data->findex);
852 Lisp_Object font_instance = 850 Lisp_Object font_instance =
853 ensure_face_cachel_contains_charset (cachel, data->window, 851 ensure_face_cachel_contains_charset (cachel, data->window,
854 charset); 852 charset);
855 Lisp_Font_Instance *fi; 853 struct Lisp_Font_Instance *fi;
856 854
857 if (EQ (font_instance, Vthe_null_font_instance)) 855 if (EQ (font_instance, Vthe_null_font_instance))
858 { 856 {
859 font_instance = FACE_CACHEL_FONT (cachel, Vcharset_ascii); 857 font_instance = FACE_CACHEL_FONT (cachel, Vcharset_ascii);
860 data->font_is_bogus = 1; 858 data->font_is_bogus = 1;
902 900
903 crb->findex = data->findex; 901 crb->findex = data->findex;
904 crb->xpos = data->pixpos; 902 crb->xpos = data->pixpos;
905 crb->width = width; 903 crb->width = width;
906 if (data->bi_bufpos) 904 if (data->bi_bufpos)
907 { 905 crb->bufpos =
908 if (NILP (data->string)) 906 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
909 crb->bufpos = 907 data->bi_bufpos);
910 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
911 data->bi_bufpos);
912 else
913 crb->bufpos =
914 bytecount_to_charcount (XSTRING_DATA (data->string), data->bi_bufpos);
915 }
916 else if (data->is_modeline) 908 else if (data->is_modeline)
917 crb->bufpos = data->modeline_charpos; 909 crb->bufpos = data->modeline_charpos;
918 else 910 else
919 /* Text but not in buffer */ 911 /* fuckme if this shouldn't be an abort. */
912 /* abort (); fuckme harder, this abort gets tripped quite often,
913 in propagation and whatnot. #### fixme */
920 crb->bufpos = 0; 914 crb->bufpos = 0;
921 crb->type = RUNE_CHAR; 915 crb->type = RUNE_CHAR;
922 crb->object.chr.ch = data->font_is_bogus ? '~' : data->ch; 916 crb->object.chr.ch = data->font_is_bogus ? '~' : data->ch;
923 crb->endpos = 0; 917 crb->endpos = 0;
924 918
1309 dst += long_to_string_base ((char *)dst, data->ch, 16); 1303 dst += long_to_string_base ((char *)dst, data->ch, 16);
1310 break;*/ 1304 break;*/
1311 case '%': 1305 case '%':
1312 dst += set_charptr_emchar (dst, '%'); 1306 dst += set_charptr_emchar (dst, '%');
1313 break; 1307 break;
1314 /* #### unimplemented */
1315 } 1308 }
1316 } 1309 }
1317 } 1310 }
1318 prop = add_bufbyte_string_runes (data, result, dst - result, 0); 1311 prop = add_bufbyte_string_runes (data, result, dst - result, 0);
1319 } 1312 }
1331 add_disp_table_entry_runes (pos_data *data, Lisp_Object entry) 1324 add_disp_table_entry_runes (pos_data *data, Lisp_Object entry)
1332 { 1325 {
1333 prop_block_dynarr *prop = NULL; 1326 prop_block_dynarr *prop = NULL;
1334 if (VECTORP (entry)) 1327 if (VECTORP (entry))
1335 { 1328 {
1336 Lisp_Vector *de = XVECTOR (entry); 1329 struct Lisp_Vector *de = XVECTOR (entry);
1337 EMACS_INT len = vector_length (de); 1330 EMACS_INT len = vector_length (de);
1338 int elt; 1331 int elt;
1339 1332
1340 for (elt = 0; elt < len; elt++) 1333 for (elt = 0; elt < len; elt++)
1341 { 1334 {
1514 add_glyph_rune (pos_data *data, struct glyph_block *gb, int pos_type, 1507 add_glyph_rune (pos_data *data, struct glyph_block *gb, int pos_type,
1515 int allow_cursor, struct glyph_cachel *cachel) 1508 int allow_cursor, struct glyph_cachel *cachel)
1516 { 1509 {
1517 struct window *w = XWINDOW (data->window); 1510 struct window *w = XWINDOW (data->window);
1518 1511
1519 /* If window faces changed, and glyph instance is text, then
1520 glyph sizes might have changed too */
1521 invalidate_glyph_geometry_maybe (gb->glyph, w);
1522
1523 /* This makes sure the glyph is in the cachels.
1524
1525 #### We do this to make sure the glyph is in the glyph cachels,
1526 so that the dirty flag can be reset after redisplay has
1527 finished. We should do this some other way, maybe by iterating
1528 over the window cache of subwindows. */
1529 get_glyph_cachel_index (w, gb->glyph);
1530
1531 /* A nil extent indicates a special glyph (ex. truncator). */ 1512 /* A nil extent indicates a special glyph (ex. truncator). */
1532 if (NILP (gb->extent) 1513 if (NILP (gb->extent)
1533 || (pos_type == BEGIN_GLYPHS && 1514 || (pos_type == BEGIN_GLYPHS &&
1534 extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT) 1515 extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1535 || (pos_type == END_GLYPHS && 1516 || (pos_type == END_GLYPHS &&
1536 extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT) 1517 extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT))
1537 || pos_type == LEFT_GLYPHS || pos_type == RIGHT_GLYPHS)
1538 { 1518 {
1539 struct rune rb; 1519 struct rune rb;
1540 int width; 1520 int width;
1541 int xoffset = 0; 1521 int xoffset = 0;
1542 int ascent, descent; 1522 int ascent, descent;
1543 Lisp_Object baseline; 1523 Lisp_Object baseline;
1544 Lisp_Object face; 1524 Lisp_Object face;
1545 Lisp_Object instance;
1546 face_index findex;
1547 1525
1548 if (cachel) 1526 if (cachel)
1549 width = cachel->width; 1527 width = cachel->width;
1550 else 1528 else
1551 width = glyph_width (gb->glyph, data->window); 1529 width = glyph_width (gb->glyph, Qnil, data->findex, data->window);
1552 1530
1553 if (!width) 1531 if (!width)
1554 return NULL; 1532 return NULL;
1555 1533
1556 if (data->start_col || data->start_col_xoffset) 1534 if (data->start_col)
1557 { 1535 {
1558 prop_block_dynarr *retval; 1536 prop_block_dynarr *retval;
1559 int glyph_char_width = width / space_width (w); 1537 int glyph_char_width = width / space_width (w);
1560 1538
1561 /* If we still have not fully scrolled horizontally after 1539 /* If we still have not fully scrolled horizontally after
1609 ascent = cachel->ascent; 1587 ascent = cachel->ascent;
1610 descent = cachel->descent; 1588 descent = cachel->descent;
1611 } 1589 }
1612 else 1590 else
1613 { 1591 {
1614 ascent = glyph_ascent (gb->glyph, data->window); 1592 ascent = glyph_ascent (gb->glyph, Qnil, data->findex, data->window);
1615 descent = glyph_descent (gb->glyph, data->window); 1593 descent = glyph_descent (gb->glyph, Qnil, data->findex,
1594 data->window);
1616 } 1595 }
1617 1596
1618 baseline = glyph_baseline (gb->glyph, data->window); 1597 baseline = glyph_baseline (gb->glyph, data->window);
1619 1598
1620 if (glyph_contrib_p (gb->glyph, data->window)) 1599 if (glyph_contrib_p (gb->glyph, data->window))
1653 abort (); 1632 abort ();
1654 } 1633 }
1655 1634
1656 face = glyph_face (gb->glyph, data->window); 1635 face = glyph_face (gb->glyph, data->window);
1657 if (NILP (face)) 1636 if (NILP (face))
1658 findex = data->findex; 1637 rb.findex = data->findex;
1659 else 1638 else
1660 findex = get_builtin_face_cache_index (w, face); 1639 rb.findex = get_builtin_face_cache_index (w, face);
1661 1640
1662 instance = glyph_image_instance (gb->glyph, data->window,
1663 ERROR_ME_NOT, 1);
1664 if (TEXT_IMAGE_INSTANCEP (instance))
1665 {
1666 Lisp_Object string = XIMAGE_INSTANCE_TEXT_STRING (instance);
1667 face_index orig_findex = data->findex;
1668 Bytind orig_bufpos = data->bi_bufpos;
1669 Bytind orig_start_col_enabled = data->bi_start_col_enabled;
1670
1671 data->findex = findex;
1672 data->bi_start_col_enabled = 0;
1673 if (!allow_cursor)
1674 data->bi_bufpos = 0;
1675 add_bufbyte_string_runes (data, XSTRING_DATA (string),
1676 XSTRING_LENGTH (string), 0);
1677 data->findex = orig_findex;
1678 data->bi_bufpos = orig_bufpos;
1679 data->bi_start_col_enabled = orig_start_col_enabled;
1680 return NULL;
1681 }
1682
1683 rb.findex = findex;
1684 rb.xpos = data->pixpos; 1641 rb.xpos = data->pixpos;
1685 rb.width = width; 1642 rb.width = width;
1686 rb.bufpos = 0; /* glyphs are never "at" anywhere */ 1643 rb.bufpos = 0; /* glyphs are never "at" anywhere */
1687 if (data->bi_endpos) 1644 if (data->bi_endpos)
1688 /* #### is this necessary at all? */ 1645 /* #### is this necessary at all? */
1689 rb.endpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)), 1646 rb.endpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1690 data->bi_endpos); 1647 data->bi_endpos);
1691 else 1648 else
1692 rb.endpos = 0; 1649 rb.endpos = 0;
1693 rb.type = RUNE_DGLYPH; 1650 rb.type = RUNE_DGLYPH;
1651 /* #### Ben sez: this is way bogus if the glyph is a string.
1652 You should not make the output routines have to cope with
1653 this. The string could contain Mule characters, or non-
1654 printable characters, or characters to be passed through
1655 the display table, or non-character objects (when this gets
1656 implemented), etc. Instead, this routine here should parse
1657 the string into a series of runes. */
1694 rb.object.dglyph.glyph = gb->glyph; 1658 rb.object.dglyph.glyph = gb->glyph;
1695 rb.object.dglyph.extent = gb->extent; 1659 rb.object.dglyph.extent = gb->extent;
1696 rb.object.dglyph.xoffset = xoffset; 1660 rb.object.dglyph.xoffset = xoffset;
1697 1661
1698 if (allow_cursor) 1662 if (allow_cursor)
1799 NOTE NOTE NOTE NOTE: This function works with and returns Bytinds. 1763 NOTE NOTE NOTE NOTE: This function works with and returns Bytinds.
1800 You must do appropriate conversion. */ 1764 You must do appropriate conversion. */
1801 1765
1802 static Bytind 1766 static Bytind
1803 create_text_block (struct window *w, struct display_line *dl, 1767 create_text_block (struct window *w, struct display_line *dl,
1804 Bytind bi_start_pos, prop_block_dynarr **prop, 1768 Bytind bi_start_pos, int start_col,
1769 prop_block_dynarr **prop,
1805 int type) 1770 int type)
1806 { 1771 {
1807 struct frame *f = XFRAME (w->frame); 1772 struct frame *f = XFRAME (w->frame);
1808 struct buffer *b = XBUFFER (w->buffer); 1773 struct buffer *b = XBUFFER (w->buffer);
1809 struct device *d = XDEVICE (f->device); 1774 struct device *d = XDEVICE (f->device);
1824 only lines that start with less than selective_display columns of 1789 only lines that start with less than selective_display columns of
1825 space will be displayed. If selective_display is t then all text 1790 space will be displayed. If selective_display is t then all text
1826 after a ^M is invisible. */ 1791 after a ^M is invisible. */
1827 int selective = (INTP (b->selective_display) 1792 int selective = (INTP (b->selective_display)
1828 ? XINT (b->selective_display) 1793 ? XINT (b->selective_display)
1829 : (!NILP (b->selective_display) ? -1 : 0)); 1794 : ((!NILP (b->selective_display) ? -1 : 0)));
1830 1795
1831 /* The variable ctl-arrow allows the user to specify what characters 1796 /* The variable ctl-arrow allows the user to specify what characters
1832 can actually be displayed and which octal should be used for. 1797 can actually be displayed and which octal should be used for.
1833 #### This variable should probably have some rethought done to 1798 #### This variable should probably have some rethought done to
1834 it. 1799 it.
1891 Lisp_Object synch_minibuffers_value = 1856 Lisp_Object synch_minibuffers_value =
1892 symbol_value_in_buffer (Qsynchronize_minibuffers, w->buffer); 1857 symbol_value_in_buffer (Qsynchronize_minibuffers, w->buffer);
1893 1858
1894 dl->used_prop_data = 0; 1859 dl->used_prop_data = 0;
1895 dl->num_chars = 0; 1860 dl->num_chars = 0;
1896 dl->line_continuation = 0;
1897 1861
1898 xzero (data); 1862 xzero (data);
1899 data.ef = extent_fragment_new (w->buffer, f); 1863 data.ef = extent_fragment_new (w->buffer, f);
1900 1864
1901 /* These values are used by all of the rune addition routines. We add 1865 /* These values are used by all of the rune addition routines. We add
1902 them to this structure for ease of passing. */ 1866 them to this structure for ease of passing. */
1903 data.d = d; 1867 data.d = d;
1904 XSETWINDOW (data.window, w); 1868 XSETWINDOW (data.window, w);
1905 data.string = Qnil;
1906 data.db = db; 1869 data.db = db;
1907 data.dl = dl; 1870 data.dl = dl;
1908 1871
1909 data.bi_bufpos = bi_start_pos; 1872 data.bi_bufpos = bi_start_pos;
1910 data.pixpos = dl->bounds.left_in; 1873 data.pixpos = dl->bounds.left_in;
1944 else 1907 else
1945 data.cursor_type = NO_CURSOR; 1908 data.cursor_type = NO_CURSOR;
1946 data.cursor_x = -1; 1909 data.cursor_x = -1;
1947 1910
1948 data.start_col = w->hscroll; 1911 data.start_col = w->hscroll;
1949 data.start_col_xoffset = w->left_xoffset;
1950 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0); 1912 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
1951 data.hscroll_glyph_width_adjust = 0; 1913 data.hscroll_glyph_width_adjust = 0;
1952 1914
1953 /* We regenerate the line from the very beginning. */ 1915 /* We regenerate the line from the very beginning. */
1954 Dynarr_reset (db->runes); 1916 Dynarr_reset (db->runes);
2264 that the cursor shows up properly. */ 2226 that the cursor shows up properly. */
2265 data.ch = '\n'; 2227 data.ch = '\n';
2266 data.blank_width = DEVMETH (d, eol_cursor_width, ()); 2228 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2267 data.findex = DEFAULT_INDEX; 2229 data.findex = DEFAULT_INDEX;
2268 data.start_col = 0; 2230 data.start_col = 0;
2269 data.start_col_xoffset = 0;
2270 data.bi_start_col_enabled = 0; 2231 data.bi_start_col_enabled = 0;
2271 2232
2272 add_emchar_rune (&data); 2233 add_emchar_rune (&data);
2273 } 2234 }
2274 2235
2298 int next_tab_start; 2259 int next_tab_start;
2299 int char_tab_width; 2260 int char_tab_width;
2300 int prop_width = 0; 2261 int prop_width = 0;
2301 2262
2302 if (data.start_col > 1) 2263 if (data.start_col > 1)
2303 tab_start_pixpos -= (space_width (w) * (data.start_col - 1)) 2264 tab_start_pixpos -= (space_width (w) * (data.start_col - 1));
2304 + data.start_col_xoffset;
2305 2265
2306 next_tab_start = 2266 next_tab_start =
2307 next_tab_position (w, tab_start_pixpos, 2267 next_tab_position (w, tab_start_pixpos,
2308 dl->bounds.left_in + 2268 dl->bounds.left_in +
2309 data.hscroll_glyph_width_adjust); 2269 data.hscroll_glyph_width_adjust);
2482 /* The cursor can never be on the continuation glyph. */ 2442 /* The cursor can never be on the continuation glyph. */
2483 data.cursor_type = NO_CURSOR; 2443 data.cursor_type = NO_CURSOR;
2484 2444
2485 /* data.bi_bufpos is already at the start of the next line. */ 2445 /* data.bi_bufpos is already at the start of the next line. */
2486 2446
2487 dl->line_continuation = 1;
2488 gb.glyph = Vcontinuation_glyph; 2447 gb.glyph = Vcontinuation_glyph;
2489 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX); 2448 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
2490 } 2449 }
2491 2450
2492 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel); 2451 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 1, cachel);
2493 2452
2494 if (truncate_win && data.bi_bufpos == BI_BUF_ZV (b) 2453 if (truncate_win && data.bi_bufpos == BI_BUF_ZV (b)
2495 && BI_BUF_FETCH_CHAR (b, prev_bytind (b, BI_BUF_ZV (b))) != '\n') 2454 && BI_BUF_FETCH_CHAR (b, prev_bytind (b, BI_BUF_ZV (b))) != '\n')
2496 /* #### Damn this losing shit. */ 2455 /* #### Damn this losing shit. */
2497 data.bi_bufpos++; 2456 data.bi_bufpos++;
2507 2466
2508 data.ch = '\n'; 2467 data.ch = '\n';
2509 data.blank_width = DEVMETH (d, eol_cursor_width, ()); 2468 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2510 data.findex = DEFAULT_INDEX; 2469 data.findex = DEFAULT_INDEX;
2511 data.start_col = 0; 2470 data.start_col = 0;
2512 data.start_col_xoffset = 0;
2513 data.bi_start_col_enabled = 0; 2471 data.bi_start_col_enabled = 0;
2514 2472
2515 data.max_pixpos += data.blank_width; 2473 data.max_pixpos += data.blank_width;
2516 add_emchar_rune (&data); 2474 add_emchar_rune (&data);
2517 data.max_pixpos -= data.blank_width; 2475 data.max_pixpos -= data.blank_width;
2683 data.cursor_x = -1; 2641 data.cursor_x = -1;
2684 data.findex = DEFAULT_INDEX; 2642 data.findex = DEFAULT_INDEX;
2685 data.last_charset = Qunbound; 2643 data.last_charset = Qunbound;
2686 data.last_findex = DEFAULT_INDEX; 2644 data.last_findex = DEFAULT_INDEX;
2687 data.result_str = Qnil; 2645 data.result_str = Qnil;
2688 data.string = Qnil;
2689 2646
2690 Dynarr_reset (data.db->runes); 2647 Dynarr_reset (data.db->runes);
2691 2648
2692 if (STRINGP (Voverlay_arrow_string)) 2649 if (STRINGP (Voverlay_arrow_string))
2693 { 2650 {
2735 { 2692 {
2736 glyph_block_dynarr *gbd = (side == LEFT_GLYPHS 2693 glyph_block_dynarr *gbd = (side == LEFT_GLYPHS
2737 ? dl->left_glyphs 2694 ? dl->left_glyphs
2738 : dl->right_glyphs); 2695 : dl->right_glyphs);
2739 int elt, end; 2696 int elt, end;
2697 int xpos = start;
2740 int reverse; 2698 int reverse;
2741 struct window *w = XWINDOW (window);
2742 struct frame *f = XFRAME (w->frame);
2743 struct device *d = XDEVICE (f->device);
2744 pos_data data;
2745
2746 xzero (data);
2747 data.d = d;
2748 data.window = window;
2749 data.db = db;
2750 data.dl = dl;
2751 data.pixpos = start;
2752 data.cursor_type = NO_CURSOR;
2753 data.cursor_x = -1;
2754 data.last_charset = Qunbound;
2755 data.last_findex = DEFAULT_INDEX;
2756 data.result_str = Qnil;
2757 data.string = Qnil;
2758 data.new_ascent = dl->ascent;
2759 data.new_descent = dl->descent;
2760 2699
2761 if ((layout == GL_WHITESPACE && side == LEFT_GLYPHS) 2700 if ((layout == GL_WHITESPACE && side == LEFT_GLYPHS)
2762 || (layout == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS)) 2701 || (layout == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS))
2763 { 2702 {
2764 reverse = 1; 2703 reverse = 1;
2783 ((side == LEFT_GLYPHS && 2722 ((side == LEFT_GLYPHS &&
2784 extent_begin_glyph_layout (XEXTENT (gb->extent)) == layout) 2723 extent_begin_glyph_layout (XEXTENT (gb->extent)) == layout)
2785 || (side == RIGHT_GLYPHS && 2724 || (side == RIGHT_GLYPHS &&
2786 extent_end_glyph_layout (XEXTENT (gb->extent)) == layout))) 2725 extent_end_glyph_layout (XEXTENT (gb->extent)) == layout)))
2787 { 2726 {
2788 data.findex = gb->findex; 2727 struct rune rb;
2789 data.max_pixpos = data.pixpos + gb->width; 2728
2790 add_glyph_rune (&data, gb, side, 0, NULL); 2729 rb.width = gb->width;
2730 rb.findex = gb->findex;
2731 rb.xpos = xpos;
2732 rb.bufpos = -1;
2733 rb.endpos = 0;
2734 rb.type = RUNE_DGLYPH;
2735 rb.object.dglyph.glyph = gb->glyph;
2736 rb.object.dglyph.extent = gb->extent;
2737 rb.object.dglyph.xoffset = 0;
2738 rb.cursor_type = CURSOR_OFF;
2739
2740 Dynarr_add (db->runes, rb);
2741 xpos += rb.width;
2791 count--; 2742 count--;
2792 gb->active = 0; 2743 gb->active = 0;
2744
2745 if (glyph_contrib_p (gb->glyph, window))
2746 {
2747 unsigned short ascent, descent;
2748 Lisp_Object baseline = glyph_baseline (gb->glyph, window);
2749
2750 ascent = glyph_ascent (gb->glyph, Qnil, gb->findex, window);
2751 descent = glyph_descent (gb->glyph, Qnil, gb->findex, window);
2752
2753 /* A pixmap that has not had a baseline explicitly set.
2754 We use the existing ascent / descent ratio of the
2755 line. */
2756 if (NILP (baseline))
2757 {
2758 int gheight = ascent + descent;
2759 int line_height = dl->ascent + dl->descent;
2760 int pix_ascent, pix_descent;
2761
2762 pix_descent = (int) (gheight * dl->descent) / line_height;
2763 pix_ascent = gheight - pix_descent;
2764
2765 dl->ascent = max ((int) dl->ascent, pix_ascent);
2766 dl->descent = max ((int) dl->descent, pix_descent);
2767 }
2768
2769 /* A string so determine contribution normally. */
2770 else if (EQ (baseline, Qt))
2771 {
2772 dl->ascent = max (dl->ascent, ascent);
2773 dl->descent = max (dl->descent, descent);
2774 }
2775
2776 /* A pixmap with an explicitly set baseline. We determine the
2777 contribution here. */
2778 else if (INTP (baseline))
2779 {
2780 int height = ascent + descent;
2781 int pix_ascent, pix_descent;
2782
2783 pix_ascent = height * XINT (baseline) / 100;
2784 pix_descent = height - pix_ascent;
2785
2786 dl->ascent = max ((int) dl->ascent, pix_ascent);
2787 dl->descent = max ((int) dl->descent, pix_descent);
2788 }
2789
2790 /* Otherwise something is screwed up. */
2791 else
2792 abort ();
2793 }
2793 } 2794 }
2794 2795
2795 (reverse ? elt-- : elt++); 2796 (reverse ? elt-- : elt++);
2796 } 2797 }
2797 2798
2798 if (data.max_pixmap_height) 2799 return xpos;
2799 {
2800 int height = data.new_ascent + data.new_descent;
2801 int pix_ascent, pix_descent;
2802
2803 pix_descent = data.max_pixmap_height * data.new_descent / height;
2804 pix_ascent = data.max_pixmap_height - pix_descent;
2805 data.new_ascent = max (data.new_ascent, pix_ascent);
2806 data.new_descent = max (data.new_descent, pix_descent);
2807 }
2808
2809 dl->ascent = data.new_ascent;
2810 dl->descent = data.new_descent;
2811
2812 return data.pixpos;
2813 } 2800 }
2814 2801
2815 /* Add a blank to a margin display block. */ 2802 /* Add a blank to a margin display block. */
2816 2803
2817 static void 2804 static void
2873 2860
2874 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE) 2861 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
2875 { 2862 {
2876 int width; 2863 int width;
2877 2864
2878 width = glyph_width (gb->glyph, window); 2865 width = glyph_width (gb->glyph, Qnil, gb->findex, window);
2879 2866
2880 if (white_in_start - width >= left_in_end) 2867 if (white_in_start - width >= left_in_end)
2881 { 2868 {
2882 white_in_cnt++; 2869 white_in_cnt++;
2883 white_in_start -= width; 2870 white_in_start -= width;
2924 abort (); /* these should have been handled in add_glyph_rune */ 2911 abort (); /* these should have been handled in add_glyph_rune */
2925 2912
2926 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) == 2913 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
2927 GL_INSIDE_MARGIN) 2914 GL_INSIDE_MARGIN)
2928 { 2915 {
2929 gb->width = glyph_width (gb->glyph, window); 2916 gb->width = glyph_width (gb->glyph, Qnil, gb->findex, window);
2930 used_in += gb->width; 2917 used_in += gb->width;
2931 Dynarr_add (ib, *gb); 2918 Dynarr_add (ib, *gb);
2932 } 2919 }
2933 2920
2934 elt++; 2921 elt++;
2993 abort (); /* these should have been handled in add_glyph_rune */ 2980 abort (); /* these should have been handled in add_glyph_rune */
2994 2981
2995 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) == 2982 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
2996 GL_INSIDE_MARGIN) 2983 GL_INSIDE_MARGIN)
2997 { 2984 {
2998 int width = glyph_width (gb->glyph, window); 2985 int width = glyph_width (gb->glyph, Qnil, gb->findex, window);
2999 2986
3000 if (used_out) 2987 if (used_out)
3001 { 2988 {
3002 in_out_cnt++; 2989 in_out_cnt++;
3003 in_out_start -= width; 2990 in_out_start -= width;
3035 abort (); /* these should have been handled in add_glyph_rune */ 3022 abort (); /* these should have been handled in add_glyph_rune */
3036 3023
3037 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) == 3024 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3038 GL_OUTSIDE_MARGIN) 3025 GL_OUTSIDE_MARGIN)
3039 { 3026 {
3040 int width = glyph_width (gb->glyph, window); 3027 int width = glyph_width (gb->glyph, Qnil, gb->findex, window);
3041 3028
3042 if (out_end + width <= in_out_start) 3029 if (out_end + width <= in_out_start)
3043 { 3030 {
3044 out_cnt++; 3031 out_cnt++;
3045 out_end += width; 3032 out_end += width;
3192 if (NILP (gb->extent)) 3179 if (NILP (gb->extent))
3193 abort (); /* these should have been handled in add_glyph_rune */ 3180 abort (); /* these should have been handled in add_glyph_rune */
3194 3181
3195 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE) 3182 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
3196 { 3183 {
3197 int width = glyph_width (gb->glyph, window); 3184 int width = glyph_width (gb->glyph, Qnil, gb->findex, window);
3198 3185
3199 if (white_in_end + width <= dl->bounds.right_in) 3186 if (white_in_end + width <= dl->bounds.right_in)
3200 { 3187 {
3201 white_in_cnt++; 3188 white_in_cnt++;
3202 white_in_end += width; 3189 white_in_end += width;
3242 if (NILP (gb->extent)) 3229 if (NILP (gb->extent))
3243 abort (); /* these should have been handled in add_glyph_rune */ 3230 abort (); /* these should have been handled in add_glyph_rune */
3244 3231
3245 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN) 3232 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3246 { 3233 {
3247 gb->width = glyph_width (gb->glyph, window); 3234 gb->width = glyph_width (gb->glyph, Qnil, gb->findex, window);
3248 used_in += gb->width; 3235 used_in += gb->width;
3249 Dynarr_add (ib, *gb); 3236 Dynarr_add (ib, *gb);
3250 } 3237 }
3251 3238
3252 elt++; 3239 elt++;
3306 if (NILP (gb->extent)) 3293 if (NILP (gb->extent))
3307 abort (); /* these should have been handled in add_glyph_rune */ 3294 abort (); /* these should have been handled in add_glyph_rune */
3308 3295
3309 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN) 3296 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3310 { 3297 {
3311 int width = glyph_width (gb->glyph, window); 3298 int width = glyph_width (gb->glyph, Qnil, gb->findex, window);
3312 3299
3313 if (used_out) 3300 if (used_out)
3314 { 3301 {
3315 in_out_cnt++; 3302 in_out_cnt++;
3316 in_out_end += width; 3303 in_out_end += width;
3347 if (NILP (gb->extent)) 3334 if (NILP (gb->extent))
3348 abort (); /* these should have been handled in add_glyph_rune */ 3335 abort (); /* these should have been handled in add_glyph_rune */
3349 3336
3350 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_OUTSIDE_MARGIN) 3337 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_OUTSIDE_MARGIN)
3351 { 3338 {
3352 int width = glyph_width (gb->glyph, window); 3339 int width = glyph_width (gb->glyph, Qnil, gb->findex, window);
3353 3340
3354 if (out_start - width >= in_out_end) 3341 if (out_start - width >= in_out_end)
3355 { 3342 {
3356 out_cnt++; 3343 out_cnt++;
3357 out_start -= width; 3344 out_start -= width;
3463 /* */ 3450 /* */
3464 /* modeline routines */ 3451 /* modeline routines */
3465 /* */ 3452 /* */
3466 /***************************************************************************/ 3453 /***************************************************************************/
3467 3454
3468 /* This function is also used in frame.c by `generate_title_string' */ 3455 /* Ensure that the given display line DL accurately represents the
3469 void 3456 modeline for the given window. */
3457
3458 static void
3459 generate_modeline (struct window *w, struct display_line *dl, int type)
3460 {
3461 struct buffer *b = XBUFFER (w->buffer);
3462 struct frame *f = XFRAME (w->frame);
3463 struct device *d = XDEVICE (f->device);
3464
3465 /* Unlike display line and rune pointers, this one can't change underneath
3466 our feet. */
3467 struct display_block *db = get_display_block_from_line (dl, TEXT);
3468 int max_pixpos, min_pixpos, ypos_adj;
3469 Lisp_Object font_inst;
3470
3471 /* This will actually determine incorrect inside boundaries for the
3472 modeline since it ignores the margins. However being aware of this fact
3473 we never use those values anywhere so it doesn't matter. */
3474 dl->bounds = calculate_display_line_boundaries (w, 1);
3475
3476 /* We are generating a modeline. */
3477 dl->modeline = 1;
3478 dl->cursor_elt = -1;
3479
3480 /* Reset the runes on the modeline. */
3481 Dynarr_reset (db->runes);
3482
3483 if (!WINDOW_HAS_MODELINE_P (w))
3484 {
3485 struct rune rb;
3486
3487 /* If there is a horizontal scrollbar, don't add anything. */
3488 if (window_scrollbar_height (w))
3489 return;
3490
3491 dl->ascent = DEVMETH (d, divider_height, ());
3492 dl->descent = 0;
3493 /* The modeline is at the bottom of the gutters. */
3494 dl->ypos = WINDOW_BOTTOM (w);
3495
3496 rb.findex = MODELINE_INDEX;
3497 rb.xpos = dl->bounds.left_out;
3498 rb.width = dl->bounds.right_out - dl->bounds.left_out;
3499 rb.bufpos = 0;
3500 rb.endpos = 0;
3501 rb.type = RUNE_HLINE;
3502 rb.object.hline.thickness = 1;
3503 rb.object.hline.yoffset = 0;
3504 rb.cursor_type = NO_CURSOR;
3505
3506 if (!EQ (Qzero, w->modeline_shadow_thickness)
3507 && FRAME_WIN_P (f))
3508 {
3509 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3510
3511 dl->ypos -= shadow_thickness;
3512 rb.xpos += shadow_thickness;
3513 rb.width -= 2 * shadow_thickness;
3514 }
3515
3516 Dynarr_add (db->runes, rb);
3517 return;
3518 }
3519
3520 /* !!#### not right; needs to compute the max height of
3521 all the charsets */
3522 font_inst = WINDOW_FACE_CACHEL_FONT (w, MODELINE_INDEX, Vcharset_ascii);
3523
3524 dl->ascent = XFONT_INSTANCE (font_inst)->ascent;
3525 dl->descent = XFONT_INSTANCE (font_inst)->descent;
3526
3527 min_pixpos = dl->bounds.left_out;
3528 max_pixpos = dl->bounds.right_out;
3529
3530 if (!EQ (Qzero, w->modeline_shadow_thickness) && FRAME_WIN_P (f))
3531 {
3532 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3533
3534 ypos_adj = shadow_thickness;
3535 min_pixpos += shadow_thickness;
3536 max_pixpos -= shadow_thickness;
3537 }
3538 else
3539 ypos_adj = 0;
3540
3541 generate_formatted_string_db (b->modeline_format,
3542 b->generated_modeline_string, w, dl, db,
3543 MODELINE_INDEX, min_pixpos, max_pixpos, type);
3544
3545 /* The modeline is at the bottom of the gutters. We have to wait to
3546 set this until we've generated the modeline in order to account
3547 for any embedded faces. */
3548 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj;
3549 }
3550
3551 static void
3470 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str, 3552 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str,
3471 struct window *w, struct display_line *dl, 3553 struct window *w, struct display_line *dl,
3472 struct display_block *db, face_index findex, 3554 struct display_block *db, face_index findex,
3473 int min_pixpos, int max_pixpos, int type) 3555 int min_pixpos, int max_pixpos, int type)
3474 { 3556 {
3475 struct frame *f = XFRAME (w->frame); 3557 struct frame *f = XFRAME (w->frame);
3476 struct device *d = XDEVICE (f->device); 3558 struct device *d = XDEVICE (f->device);
3477 3559
3478 pos_data data; 3560 pos_data data;
3479 int c_pixpos; 3561 int c_pixpos;
3480 Charcount offset = 0;
3481 3562
3482 xzero (data); 3563 xzero (data);
3483 data.d = d; 3564 data.d = d;
3484 data.db = db; 3565 data.db = db;
3485 data.dl = dl; 3566 data.dl = dl;
3489 data.cursor_type = NO_CURSOR; 3570 data.cursor_type = NO_CURSOR;
3490 data.last_charset = Qunbound; 3571 data.last_charset = Qunbound;
3491 data.last_findex = DEFAULT_INDEX; 3572 data.last_findex = DEFAULT_INDEX;
3492 data.result_str = result_str; 3573 data.result_str = result_str;
3493 data.is_modeline = 1; 3574 data.is_modeline = 1;
3494 data.string = Qnil;
3495 XSETWINDOW (data.window, w); 3575 XSETWINDOW (data.window, w);
3496 3576
3497 Dynarr_reset (formatted_string_extent_dynarr); 3577 Dynarr_reset (formatted_string_extent_dynarr);
3498 Dynarr_reset (formatted_string_extent_start_dynarr); 3578 Dynarr_reset (formatted_string_extent_start_dynarr);
3499 Dynarr_reset (formatted_string_extent_end_dynarr); 3579 Dynarr_reset (formatted_string_extent_end_dynarr);
3500 3580
3501 /* result_str is nil when we're building a frame or icon title. Otherwise, 3581 /* This recursively builds up the modeline. */
3502 we're building a modeline, so the offset starts at the modeline
3503 horizontal scrolling ammount */
3504 if (! NILP (result_str))
3505 offset = w->modeline_hscroll;
3506 generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0, 3582 generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0,
3507 max_pixpos - min_pixpos, findex, type, &offset, 3583 max_pixpos - min_pixpos, findex, type);
3508 Qnil);
3509 3584
3510 if (Dynarr_length (db->runes)) 3585 if (Dynarr_length (db->runes))
3511 { 3586 {
3512 struct rune *rb = 3587 struct rune *rb =
3513 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1); 3588 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
3534 { 3609 {
3535 int elt; 3610 int elt;
3536 Bytecount len; 3611 Bytecount len;
3537 Bufbyte *strdata; 3612 Bufbyte *strdata;
3538 struct buffer *buf = XBUFFER (WINDOW_BUFFER (w)); 3613 struct buffer *buf = XBUFFER (WINDOW_BUFFER (w));
3539
3540 in_modeline_generation = 1;
3541 3614
3542 detach_all_extents (result_str); 3615 detach_all_extents (result_str);
3543 resize_string (XSTRING (result_str), -1, 3616 resize_string (XSTRING (result_str), -1,
3544 data.bytepos - XSTRING_LENGTH (result_str)); 3617 data.bytepos - XSTRING_LENGTH (result_str));
3545 3618
3573 (XEXTENT (child), 3646 (XEXTENT (child),
3574 Dynarr_at (formatted_string_extent_start_dynarr, elt), 3647 Dynarr_at (formatted_string_extent_start_dynarr, elt),
3575 Dynarr_at (formatted_string_extent_end_dynarr, elt), 3648 Dynarr_at (formatted_string_extent_end_dynarr, elt),
3576 result_str); 3649 result_str);
3577 } 3650 }
3578 3651 }
3579 in_modeline_generation = 0;
3580 }
3581 }
3582
3583 /* Ensure that the given display line DL accurately represents the
3584 modeline for the given window. */
3585 static void
3586 generate_modeline (struct window *w, struct display_line *dl, int type)
3587 {
3588 struct buffer *b = XBUFFER (w->buffer);
3589 struct frame *f = XFRAME (w->frame);
3590 struct device *d = XDEVICE (f->device);
3591
3592 /* Unlike display line and rune pointers, this one can't change underneath
3593 our feet. */
3594 struct display_block *db = get_display_block_from_line (dl, TEXT);
3595 int max_pixpos, min_pixpos, ypos_adj;
3596 Lisp_Object font_inst;
3597
3598 /* This will actually determine incorrect inside boundaries for the
3599 modeline since it ignores the margins. However being aware of this fact
3600 we never use those values anywhere so it doesn't matter. */
3601 dl->bounds = calculate_display_line_boundaries (w, 1);
3602
3603 /* We are generating a modeline. */
3604 dl->modeline = 1;
3605 dl->cursor_elt = -1;
3606
3607 /* Reset the runes on the modeline. */
3608 Dynarr_reset (db->runes);
3609
3610 if (!WINDOW_HAS_MODELINE_P (w))
3611 {
3612 struct rune rb;
3613
3614 /* If there is a horizontal scrollbar, don't add anything. */
3615 if (window_scrollbar_height (w))
3616 return;
3617
3618 dl->ascent = DEVMETH (d, divider_height, ());
3619 dl->descent = 0;
3620 /* The modeline is at the bottom of the gutters. */
3621 dl->ypos = WINDOW_BOTTOM (w);
3622
3623 rb.findex = MODELINE_INDEX;
3624 rb.xpos = dl->bounds.left_out;
3625 rb.width = dl->bounds.right_out - dl->bounds.left_out;
3626 rb.bufpos = 0;
3627 rb.endpos = 0;
3628 rb.type = RUNE_HLINE;
3629 rb.object.hline.thickness = 1;
3630 rb.object.hline.yoffset = 0;
3631 rb.cursor_type = NO_CURSOR;
3632
3633 if (!EQ (Qzero, w->modeline_shadow_thickness)
3634 && FRAME_WIN_P (f))
3635 {
3636 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3637
3638 dl->ypos -= shadow_thickness;
3639 rb.xpos += shadow_thickness;
3640 rb.width -= 2 * shadow_thickness;
3641 }
3642
3643 Dynarr_add (db->runes, rb);
3644 return;
3645 }
3646
3647 /* !!#### not right; needs to compute the max height of
3648 all the charsets */
3649 font_inst = WINDOW_FACE_CACHEL_FONT (w, MODELINE_INDEX, Vcharset_ascii);
3650
3651 dl->ascent = XFONT_INSTANCE (font_inst)->ascent;
3652 dl->descent = XFONT_INSTANCE (font_inst)->descent;
3653
3654 min_pixpos = dl->bounds.left_out;
3655 max_pixpos = dl->bounds.right_out;
3656
3657 if (!EQ (Qzero, w->modeline_shadow_thickness) && FRAME_WIN_P (f))
3658 {
3659 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3660
3661 ypos_adj = shadow_thickness;
3662 min_pixpos += shadow_thickness;
3663 max_pixpos -= shadow_thickness;
3664 }
3665 else
3666 ypos_adj = 0;
3667
3668 generate_formatted_string_db (b->modeline_format,
3669 b->generated_modeline_string, w, dl, db,
3670 MODELINE_INDEX, min_pixpos, max_pixpos, type);
3671
3672 /* The modeline is at the bottom of the gutters. We have to wait to
3673 set this until we've generated the modeline in order to account
3674 for any embedded faces. */
3675 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj;
3676 } 3652 }
3677 3653
3678 static Charcount 3654 static Charcount
3679 add_string_to_fstring_db_runes (pos_data *data, const Bufbyte *str, 3655 add_string_to_fstring_db_runes (pos_data *data, CONST Bufbyte *str,
3680 Charcount pos, Charcount min_pos, Charcount max_pos) 3656 Charcount pos, Charcount min_pos, Charcount max_pos)
3681 { 3657 {
3682 /* This function has been Mule-ized. */ 3658 /* This function has been Mule-ized. */
3683 Charcount end; 3659 Charcount end;
3684 const Bufbyte *cur_pos = str; 3660 CONST Bufbyte *cur_pos = str;
3685 struct display_block *db = data->db; 3661 struct display_block *db = data->db;
3686 3662
3687 data->blank_width = space_width (XWINDOW (data->window)); 3663 data->blank_width = space_width (XWINDOW (data->window));
3688 while (Dynarr_length (db->runes) < pos) 3664 while (Dynarr_length (db->runes) < pos)
3689 add_blank_rune (data, NULL, 0); 3665 add_blank_rune (data, NULL, 0);
3690 3666
3691 end = (Dynarr_length (db->runes) + 3667 end = (Dynarr_length (db->runes) +
3692 bytecount_to_charcount (str, strlen ((const char *) str))); 3668 bytecount_to_charcount (str, strlen ((CONST char *) str)));
3693 if (max_pos != -1) 3669 if (max_pos != -1)
3694 end = min (max_pos, end); 3670 end = min (max_pos, end);
3695 3671
3696 while (pos < end && *cur_pos) 3672 while (pos < end && *cur_pos)
3697 { 3673 {
3698 const Bufbyte *old_cur_pos = cur_pos; 3674 CONST Bufbyte *old_cur_pos = cur_pos;
3699 int succeeded; 3675 int succeeded;
3700 3676
3701 data->ch = charptr_emchar (cur_pos); 3677 data->ch = charptr_emchar (cur_pos);
3702 succeeded = (add_emchar_rune (data) != ADD_FAILED); 3678 succeeded = (add_emchar_rune (data) != ADD_FAILED);
3703 INC_CHARPTR (cur_pos); 3679 INC_CHARPTR (cur_pos);
3718 3694
3719 /* #### Urk! Should also handle begin-glyphs and end-glyphs in 3695 /* #### Urk! Should also handle begin-glyphs and end-glyphs in
3720 modeline extents. */ 3696 modeline extents. */
3721 static Charcount 3697 static Charcount
3722 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph, 3698 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph,
3723 Charcount pos, Charcount min_pos, 3699 Charcount pos, Charcount min_pos, Charcount max_pos)
3724 Charcount max_pos, Lisp_Object extent)
3725 { 3700 {
3726 /* This function has been Mule-ized. */ 3701 /* This function has been Mule-ized. */
3727 Charcount end; 3702 Charcount end;
3728 struct display_block *db = data->db; 3703 struct display_block *db = data->db;
3729 struct glyph_block gb; 3704 struct glyph_block gb;
3735 end = Dynarr_length (db->runes) + 1; 3710 end = Dynarr_length (db->runes) + 1;
3736 if (max_pos != -1) 3711 if (max_pos != -1)
3737 end = min (max_pos, end); 3712 end = min (max_pos, end);
3738 3713
3739 gb.glyph = glyph; 3714 gb.glyph = glyph;
3740 gb.extent = extent; 3715 gb.extent = Qnil;
3741 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0); 3716 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
3742 pos++; 3717 pos++;
3743 3718
3744 while (Dynarr_length (db->runes) < pos && 3719 while (Dynarr_length (db->runes) < pos &&
3745 (data->pixpos + data->blank_width <= data->max_pixpos)) 3720 (data->pixpos + data->blank_width <= data->max_pixpos))
3762 modeline. */ 3737 modeline. */
3763 static Charcount 3738 static Charcount
3764 generate_fstring_runes (struct window *w, pos_data *data, Charcount pos, 3739 generate_fstring_runes (struct window *w, pos_data *data, Charcount pos,
3765 Charcount min_pos, Charcount max_pos, 3740 Charcount min_pos, Charcount max_pos,
3766 Lisp_Object elt, int depth, int max_pixsize, 3741 Lisp_Object elt, int depth, int max_pixsize,
3767 face_index findex, int type, Charcount *offset, 3742 face_index findex, int type)
3768 Lisp_Object cur_ext)
3769 { 3743 {
3770 /* This function has been Mule-ized. */ 3744 /* This function has been Mule-ized. */
3771 /* #### The other losing things in this function are: 3745 /* #### The other losing things in this function are:
3772 3746
3773 -- C zero-terminated-string lossage. 3747 -- C zero-terminated-string lossage.
3795 while (*this && *this != '%') 3769 while (*this && *this != '%')
3796 this++; 3770 this++;
3797 3771
3798 if (this != last) 3772 if (this != last)
3799 { 3773 {
3800 /* No %-construct */ 3774 /* The string is just a string. */
3801 Charcount size = 3775 Charcount size =
3802 bytecount_to_charcount (last, this - last); 3776 bytecount_to_charcount (last, this - last) + pos;
3803 3777 Charcount tmp_max = (max_pos == -1 ? size : min (size, max_pos));
3804 if (size <= *offset) 3778
3805 *offset -= size; 3779 pos = add_string_to_fstring_db_runes (data, last, pos, pos,
3806 else 3780 tmp_max);
3807 {
3808 Charcount tmp_max = (max_pos == -1 ? pos + size - *offset :
3809 min (pos + size - *offset, max_pos));
3810 const Bufbyte *tmp_last = charptr_n_addr (last, *offset);
3811
3812 pos = add_string_to_fstring_db_runes (data, tmp_last,
3813 pos, pos, tmp_max);
3814 *offset = 0;
3815 }
3816 } 3781 }
3817 else /* *this == '%' */ 3782 else /* *this == '%' */
3818 { 3783 {
3819 Charcount spec_width = 0; 3784 Charcount spec_width = 0;
3820 3785
3835 if (*this == 'M') 3800 if (*this == 'M')
3836 { 3801 {
3837 pos = generate_fstring_runes (w, data, pos, spec_width, 3802 pos = generate_fstring_runes (w, data, pos, spec_width,
3838 max_pos, Vglobal_mode_string, 3803 max_pos, Vglobal_mode_string,
3839 depth, max_pixsize, findex, 3804 depth, max_pixsize, findex,
3840 type, offset, cur_ext); 3805 type);
3841 } 3806 }
3842 else if (*this == '-') 3807 else if (*this == '-')
3843 { 3808 {
3844 Charcount num_to_add; 3809 Charcount num_to_add;
3845 3810
3862 num_to_add++; 3827 num_to_add++;
3863 } 3828 }
3864 3829
3865 while (num_to_add--) 3830 while (num_to_add--)
3866 pos = add_string_to_fstring_db_runes 3831 pos = add_string_to_fstring_db_runes
3867 (data, (const Bufbyte *) "-", pos, pos, max_pos); 3832 (data, (CONST Bufbyte *) "-", pos, pos, max_pos);
3868 } 3833 }
3869 else if (*this != 0) 3834 else if (*this != 0)
3870 { 3835 {
3836 Bufbyte *str;
3871 Emchar ch = charptr_emchar (this); 3837 Emchar ch = charptr_emchar (this);
3872 Bufbyte *str;
3873 Charcount size;
3874
3875 decode_mode_spec (w, ch, type); 3838 decode_mode_spec (w, ch, type);
3876 3839
3877 str = Dynarr_atp (mode_spec_bufbyte_string, 0); 3840 str = Dynarr_atp (mode_spec_bufbyte_string, 0);
3878 size = bytecount_to_charcount 3841 pos = add_string_to_fstring_db_runes (data,str, pos, pos,
3879 /* Skip the null character added by `decode_mode_spec' */ 3842 max_pos);
3880 (str, Dynarr_length (mode_spec_bufbyte_string)) - 1;
3881
3882 if (size <= *offset)
3883 *offset -= size;
3884 else
3885 {
3886 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3887
3888 /* #### NOTE: I don't understand why a tmp_max is not
3889 computed and used here as in the plain string case
3890 above. -- dv */
3891 pos = add_string_to_fstring_db_runes (data, tmp_str,
3892 pos, pos,
3893 max_pos);
3894 *offset = 0;
3895 }
3896 } 3843 }
3897 3844
3898 /* NOT this++. There could be any sort of character at 3845 /* NOT this++. There could be any sort of character at
3899 the current position. */ 3846 the current position. */
3900 INC_CHARPTR (this); 3847 INC_CHARPTR (this);
3916 as if it appeared here directly. */ 3863 as if it appeared here directly. */
3917 Lisp_Object tem = symbol_value_in_buffer (elt, w->buffer); 3864 Lisp_Object tem = symbol_value_in_buffer (elt, w->buffer);
3918 3865
3919 if (!UNBOUNDP (tem)) 3866 if (!UNBOUNDP (tem))
3920 { 3867 {
3921 /* If value is a string, output that string literally: 3868 /* If value is a string, output that string literally:
3922 don't check for % within it. */ 3869 don't check for % within it. */
3923 if (STRINGP (tem)) 3870 if (STRINGP (tem))
3924 { 3871 {
3925 Bufbyte *str = XSTRING_DATA (tem); 3872 pos =
3926 Charcount size = XSTRING_CHAR_LENGTH (tem); 3873 add_string_to_fstring_db_runes
3927 3874 (data, XSTRING_DATA (tem), pos, min_pos, max_pos);
3928 if (size <= *offset)
3929 *offset -= size;
3930 else
3931 {
3932 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3933
3934 /* #### NOTE: I don't understand why a tmp_max is not
3935 computed and used here as in the plain string case
3936 above. -- dv */
3937 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
3938 min_pos, max_pos);
3939 *offset = 0;
3940 }
3941 } 3875 }
3942 /* Give up right away for nil or t. */ 3876 /* Give up right away for nil or t. */
3943 else if (!EQ (tem, elt)) 3877 else if (!EQ (tem, elt))
3944 { 3878 {
3945 elt = tem; 3879 elt = tem;
3960 } 3894 }
3961 } 3895 }
3962 else if (CONSP (elt)) 3896 else if (CONSP (elt))
3963 { 3897 {
3964 /* A cons cell: four distinct cases. 3898 /* A cons cell: four distinct cases.
3965 * - If first element is a string or a cons, process all the elements 3899 * If first element is a string or a cons, process all the elements
3966 * and effectively concatenate them. 3900 * and effectively concatenate them.
3967 * - If first element is a negative number, truncate displaying cdr to 3901 * If first element is a negative number, truncate displaying cdr to
3968 * at most that many characters. If positive, pad (with spaces) 3902 * at most that many characters. If positive, pad (with spaces)
3969 * to at least that many characters. 3903 * to at least that many characters.
3970 * - If first element is another symbol, process the cadr or caddr 3904 * If first element is a symbol, process the cadr or caddr recursively
3971 * recursively according to whether the symbol's value is non-nil or 3905 * according to whether the symbol's value is non-nil or nil.
3972 * nil. 3906 * If first element is a face, process the cdr recursively
3973 * - If first element is an extent, process the cdr recursively 3907 * without altering the depth.
3974 * and handle the extent's face.
3975 */ 3908 */
3976
3977 Lisp_Object car, tem; 3909 Lisp_Object car, tem;
3978 3910
3979 car = XCAR (elt); 3911 car = XCAR (elt);
3980 if (SYMBOLP (car)) 3912 if (SYMBOLP (car))
3981 { 3913 {
3982 elt = XCDR (elt); 3914 elt = XCDR (elt);
3983 if (!CONSP (elt)) 3915 if (!CONSP (elt))
3984 goto invalid; 3916 goto invalid;
3985 3917 tem = symbol_value_in_buffer (car, w->buffer);
3986 tem = symbol_value_in_buffer (car, w->buffer); 3918 /* elt is now the cdr, and we know it is a cons cell.
3987 /* elt is now the cdr, and we know it is a cons cell. 3919 Use its car if CAR has a non-nil value. */
3988 Use its car if CAR has a non-nil value. */ 3920 if (!UNBOUNDP (tem))
3989 if (!UNBOUNDP (tem)) 3921 {
3990 { 3922 if (!NILP (tem))
3991 if (!NILP (tem)) 3923 {
3992 { 3924 elt = XCAR (elt);
3993 elt = XCAR (elt); 3925 goto tail_recurse;
3994 goto tail_recurse; 3926 }
3995 } 3927 }
3996 } 3928 /* Symbol's value is nil (or symbol is unbound)
3997 /* Symbol's value is nil (or symbol is unbound) 3929 * Get the cddr of the original list
3998 * Get the cddr of the original list 3930 * and if possible find the caddr and use that.
3999 * and if possible find the caddr and use that. 3931 */
4000 */ 3932 elt = XCDR (elt);
4001 elt = XCDR (elt); 3933 if (NILP (elt))
4002 if (NILP (elt)) 3934 ;
4003 ; 3935 else if (!CONSP (elt))
4004 else if (!CONSP (elt)) 3936 goto invalid;
4005 goto invalid; 3937 else
4006 else 3938 {
4007 { 3939 elt = XCAR (elt);
4008 elt = XCAR (elt); 3940 goto tail_recurse;
4009 goto tail_recurse; 3941 }
4010 } 3942 }
4011 }
4012 else if (INTP (car)) 3943 else if (INTP (car))
4013 { 3944 {
4014 Charcount lim = XINT (car); 3945 Charcount lim = XINT (car);
4015 3946
4016 elt = XCDR (elt); 3947 elt = XCDR (elt);
4045 goto tail_recurse; 3976 goto tail_recurse;
4046 } 3977 }
4047 else if (STRINGP (car) || CONSP (car)) 3978 else if (STRINGP (car) || CONSP (car))
4048 { 3979 {
4049 int limit = 50; 3980 int limit = 50;
4050
4051 /* LIMIT is to protect against circular lists. */ 3981 /* LIMIT is to protect against circular lists. */
4052 while (CONSP (elt) && --limit > 0 3982 while (CONSP (elt) && --limit > 0
4053 && (pos < max_pos || max_pos == -1)) 3983 && (pos < max_pos || max_pos == -1))
4054 { 3984 {
4055 pos = generate_fstring_runes (w, data, pos, pos, max_pos, 3985 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4056 XCAR (elt), depth, max_pixsize, 3986 XCAR (elt), depth,
4057 findex, type, offset, cur_ext); 3987 max_pixsize, findex, type);
4058 elt = XCDR (elt); 3988 elt = XCDR (elt);
4059 } 3989 }
4060 } 3990 }
4061 else if (EXTENTP (car)) 3991 else if (EXTENTP (car))
4062 { 3992 {
4091 new_findex = old_findex; 4021 new_findex = old_findex;
4092 4022
4093 data->findex = new_findex; 4023 data->findex = new_findex;
4094 pos = generate_fstring_runes (w, data, pos, pos, max_pos, 4024 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4095 XCDR (elt), depth - 1, 4025 XCDR (elt), depth - 1,
4096 max_pixsize, new_findex, type, 4026 max_pixsize, new_findex, type);
4097 offset, car);
4098 data->findex = old_findex; 4027 data->findex = old_findex;
4099 Dynarr_add (formatted_string_extent_dynarr, ext); 4028 Dynarr_add (formatted_string_extent_dynarr, ext);
4100 Dynarr_add (formatted_string_extent_start_dynarr, start); 4029 Dynarr_add (formatted_string_extent_start_dynarr, start);
4101 Dynarr_add (formatted_string_extent_end_dynarr, data->bytepos); 4030 Dynarr_add (formatted_string_extent_end_dynarr, data->bytepos);
4102 } 4031 }
4103 } 4032 }
4104 } 4033 }
4105 else if (GLYPHP (elt)) 4034 else if (GLYPHP (elt))
4106 { 4035 {
4107 /* Glyphs are considered as one character with respect to the modeline 4036 pos = add_glyph_to_fstring_db_runes (data, elt, pos, pos, max_pos);
4108 horizontal scrolling facility. -- dv */
4109 if (*offset > 0)
4110 *offset -= 1;
4111 else
4112 pos = add_glyph_to_fstring_db_runes (data, elt, pos, pos, max_pos,
4113 cur_ext);
4114 } 4037 }
4115 else 4038 else
4116 { 4039 {
4117 invalid: 4040 invalid:
4118 { 4041 pos =
4119 char *str = GETTEXT ("*invalid*"); 4042 add_string_to_fstring_db_runes
4120 Charcount size = (Charcount) strlen (str); /* is this ok ?? -- dv */ 4043 (data, (CONST Bufbyte *) GETTEXT ("*invalid*"), pos, min_pos,
4121 4044 max_pos);
4122 if (size <= *offset)
4123 *offset -= size;
4124 else
4125 {
4126 const Bufbyte *tmp_str =
4127 charptr_n_addr ((const Bufbyte *) str, *offset);
4128
4129 /* #### NOTE: I don't understand why a tmp_max is not computed and
4130 used here as in the plain string case above. -- dv */
4131 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
4132 min_pos, max_pos);
4133 *offset = 0;
4134 }
4135 }
4136 } 4045 }
4137 4046
4138 if (min_pos > pos) 4047 if (min_pos > pos)
4139 { 4048 {
4140 add_string_to_fstring_db_runes (data, (const Bufbyte *) "", pos, 4049 add_string_to_fstring_db_runes (data, (CONST Bufbyte *) "", pos, min_pos,
4141 min_pos, -1); 4050 -1);
4142 } 4051 }
4143 4052
4144 return pos; 4053 return pos;
4054 }
4055
4056 /* The caller is responsible for freeing the returned string. */
4057 Bufbyte *
4058 generate_formatted_string (struct window *w, Lisp_Object format_str,
4059 Lisp_Object result_str, face_index findex, int type)
4060 {
4061 struct display_line *dl;
4062 struct display_block *db;
4063 int elt = 0;
4064
4065 dl = &formatted_string_display_line;
4066 db = get_display_block_from_line (dl, TEXT);
4067 Dynarr_reset (db->runes);
4068
4069 generate_formatted_string_db (format_str, result_str, w, dl, db, findex, 0,
4070 -1, type);
4071
4072 Dynarr_reset (formatted_string_emchar_dynarr);
4073 while (elt < Dynarr_length (db->runes))
4074 {
4075 if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR)
4076 Dynarr_add (formatted_string_emchar_dynarr,
4077 Dynarr_atp (db->runes, elt)->object.chr.ch);
4078 elt++;
4079 }
4080
4081 return
4082 convert_emchar_string_into_malloced_string
4083 ( Dynarr_atp (formatted_string_emchar_dynarr, 0),
4084 Dynarr_length (formatted_string_emchar_dynarr), 0);
4145 } 4085 }
4146 4086
4147 /* Update just the modeline. Assumes the desired display structs. If 4087 /* Update just the modeline. Assumes the desired display structs. If
4148 they do not have a modeline block, it does nothing. */ 4088 they do not have a modeline block, it does nothing. */
4149 static void 4089 static void
4236 return 0; 4176 return 0;
4237 } 4177 }
4238 4178
4239 4179
4240 /***************************************************************************/ 4180 /***************************************************************************/
4241 /* */
4242 /* displayable string routines */
4243 /* */
4244 /***************************************************************************/
4245
4246 /* Given a position for a string in a window, ensure that the given
4247 display line DL accurately represents the text on a line starting
4248 at the given position.
4249
4250 Yes, this is duplicating the code of create_text_block, but it
4251 looked just too hard to change create_text_block to handle strings
4252 *and* buffers. We already make a distinction between the two
4253 elsewhere in the code so I think unifying them would require a
4254 complete MULE rewrite. Besides, the other distinction is that these
4255 functions cover text that the user *cannot edit* so we can remove
4256 everything to do with cursors, minibuffers etc. Eventually the
4257 modeline routines should be modified to use this code as it copes
4258 with many more types of display situation. */
4259
4260 static Bufpos
4261 create_string_text_block (struct window *w, Lisp_Object disp_string,
4262 struct display_line *dl,
4263 Bufpos start_pos,
4264 prop_block_dynarr **prop,
4265 face_index default_face)
4266 {
4267 struct frame *f = XFRAME (w->frame);
4268 /* Note that a lot of the buffer controlled stuff has been left in
4269 because you might well want to make use of it (selective display
4270 etc), its just the buffer text that we do not use. However, it
4271 seems to be possible for buffer to be nil sometimes so protect
4272 against this case. */
4273 struct buffer *b = BUFFERP (w->buffer) ? XBUFFER (w->buffer) : 0;
4274 struct device *d = XDEVICE (f->device);
4275 Lisp_String* s = XSTRING (disp_string);
4276
4277 /* we're working with these a lot so precalculate them */
4278 Bytecount slen = XSTRING_LENGTH (disp_string);
4279 Bytecount bi_string_zv = slen;
4280 Bytind bi_start_pos = charcount_to_bytecount (string_data (s), start_pos);
4281
4282 pos_data data;
4283
4284 int truncate_win = b ? window_truncation_on (w) : 0;
4285 int end_glyph_width = 0;
4286
4287 /* we're going to ditch selective display for static text, its an
4288 FSF thing and invisble extents are the way to go
4289 here. Implementing it also relies on a number of buffer-specific
4290 functions that we don't have the luxury of being able to use
4291 here. */
4292
4293 /* The variable ctl-arrow allows the user to specify what characters
4294 can actually be displayed and which octal should be used for.
4295 #### This variable should probably have some rethought done to
4296 it.
4297
4298 #### It would also be really nice if you could specify that
4299 the characters come out in hex instead of in octal. Mule
4300 does that by adding a ctl-hexa variable similar to ctl-arrow,
4301 but that's bogus -- we need a more general solution. I
4302 think you need to extend the concept of display tables
4303 into a more general conversion mechanism. Ideally you
4304 could specify a Lisp function that converts characters,
4305 but this violates the Second Golden Rule and besides would
4306 make things way way way way slow.
4307
4308 So instead, we extend the display-table concept, which was
4309 historically limited to 256-byte vectors, to one of the
4310 following:
4311
4312 a) A 256-entry vector, for backward compatibility;
4313 b) char-table, mapping characters to values;
4314 c) range-table, mapping ranges of characters to values;
4315 d) a list of the above.
4316
4317 The (d) option allows you to specify multiple display tables
4318 instead of just one. Each display table can specify conversions
4319 for some characters and leave others unchanged. The way the
4320 character gets displayed is determined by the first display table
4321 with a binding for that character. This way, you could call a
4322 function `enable-hex-display' that adds a hex display-table to
4323 the list of display tables for the current buffer.
4324
4325 #### ...not yet implemented... Also, we extend the concept of
4326 "mapping" to include a printf-like spec. Thus you can make all
4327 extended characters show up as hex with a display table like
4328 this:
4329
4330 #s(range-table data ((256 524288) (format "%x")))
4331
4332 Since more than one display table is possible, you have
4333 great flexibility in mapping ranges of characters. */
4334 Emchar printable_min = b ? (CHAR_OR_CHAR_INTP (b->ctl_arrow)
4335 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
4336 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
4337 ? 255 : 160)) : 255;
4338
4339 Lisp_Object face_dt, window_dt;
4340
4341 /* The text display block for this display line. */
4342 struct display_block *db = get_display_block_from_line (dl, TEXT);
4343
4344 /* The first time through the main loop we need to force the glyph
4345 data to be updated. */
4346 int initial = 1;
4347
4348 /* Apparently the new extent_fragment_update returns an end position
4349 equal to the position passed in if there are no more runs to be
4350 displayed. */
4351 int no_more_frags = 0;
4352
4353 dl->used_prop_data = 0;
4354 dl->num_chars = 0;
4355 dl->line_continuation = 0;
4356
4357 /* set up faces to use for clearing areas, used by
4358 output_display_line */
4359 dl->default_findex = default_face;
4360 if (default_face)
4361 {
4362 dl->left_margin_findex = default_face;
4363 dl->right_margin_findex = default_face;
4364 }
4365 else
4366 {
4367 dl->left_margin_findex =
4368 get_builtin_face_cache_index (w, Vleft_margin_face);
4369 dl->right_margin_findex =
4370 get_builtin_face_cache_index (w, Vright_margin_face);
4371 }
4372
4373 xzero (data);
4374 data.ef = extent_fragment_new (disp_string, f);
4375
4376 /* These values are used by all of the rune addition routines. We add
4377 them to this structure for ease of passing. */
4378 data.d = d;
4379 XSETWINDOW (data.window, w);
4380 data.db = db;
4381 data.dl = dl;
4382
4383 data.bi_bufpos = bi_start_pos;
4384 data.pixpos = dl->bounds.left_in;
4385 data.last_charset = Qunbound;
4386 data.last_findex = default_face;
4387 data.result_str = Qnil;
4388 data.string = disp_string;
4389
4390 /* Set the right boundary adjusting it to take into account any end
4391 glyph. Save the width of the end glyph for later use. */
4392 data.max_pixpos = dl->bounds.right_in;
4393 #if 0
4394 if (truncate_win)
4395 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
4396 else
4397 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
4398 #endif
4399 data.max_pixpos -= end_glyph_width;
4400
4401 data.cursor_type = NO_CURSOR;
4402 data.cursor_x = -1;
4403
4404 data.start_col = 0;
4405 /* I don't think we want this, string areas should not scroll with
4406 the window
4407 data.start_col = w->hscroll;
4408 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
4409 */
4410 data.bi_start_col_enabled = 0;
4411 data.hscroll_glyph_width_adjust = 0;
4412
4413 /* We regenerate the line from the very beginning. */
4414 Dynarr_reset (db->runes);
4415
4416 /* Why is this less than or equal and not just less than? If the
4417 starting position is already equal to the maximum we can't add
4418 anything else, right? Wrong. We might still have a newline to
4419 add. A newline can use the room allocated for an end glyph since
4420 if we add it we know we aren't going to be adding any end
4421 glyph. */
4422
4423 /* #### Chuck -- I think this condition should be while (1).
4424 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
4425 and the begin-glyph ends exactly at the end of the window, the
4426 end-glyph and text might not be displayed. while (1) ensures
4427 that the loop terminates only when either (a) there is
4428 propagation data or (b) the end-of-line or end-of-buffer is hit.
4429
4430 #### Also I think you need to ensure that the operation
4431 "add begin glyphs; add end glyphs; add text" is atomic and
4432 can't get interrupted in the middle. If you run off the end
4433 of the line during that operation, then you keep accumulating
4434 propagation data until you're done. Otherwise, if the (e.g.)
4435 there's a begin glyph at a particular position and attempting
4436 to display that glyph results in window-end being hit and
4437 propagation data being generated, then the character at that
4438 position won't be displayed.
4439
4440 #### See also the comment after the end of this loop, below.
4441 */
4442 while (data.pixpos <= data.max_pixpos)
4443 {
4444 /* #### This check probably should not be necessary. */
4445 if (data.bi_bufpos > bi_string_zv)
4446 {
4447 /* #### urk! More of this lossage! */
4448 data.bi_bufpos--;
4449 goto done;
4450 }
4451
4452 /* Check for face changes. */
4453 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
4454 {
4455 /* Now compute the face and begin/end-glyph information. */
4456 data.findex =
4457 /* Remember that the extent-fragment routines deal in Bytind's. */
4458 extent_fragment_update (w, data.ef, data.bi_bufpos);
4459 /* This is somewhat cheesy but the alternative is to
4460 propagate default_face into extent_fragment_update. */
4461 if (data.findex == DEFAULT_INDEX)
4462 data.findex = default_face;
4463
4464 get_display_tables (w, data.findex, &face_dt, &window_dt);
4465
4466 if (data.bi_bufpos == data.ef->end)
4467 no_more_frags = 1;
4468 }
4469 initial = 0;
4470
4471 /* Determine what is next to be displayed. We first handle any
4472 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
4473 display then we determine what to do based on the character at the
4474 current buffer position. */
4475
4476 /* If the current position is covered by an invisible extent, do
4477 nothing (except maybe add some ellipses).
4478
4479 #### The behavior of begin and end-glyphs at the edge of an
4480 invisible extent should be investigated further. This is
4481 fairly low priority though. */
4482 if (data.ef->invisible)
4483 {
4484 /* #### Chuck, perhaps you could look at this code? I don't
4485 really know what I'm doing. */
4486 if (*prop)
4487 {
4488 Dynarr_free (*prop);
4489 *prop = 0;
4490 }
4491
4492 /* The extent fragment code only sets this when we should
4493 really display the ellipses. It makes sure the ellipses
4494 don't get displayed more than once in a row. */
4495 if (data.ef->invisible_ellipses)
4496 {
4497 struct glyph_block gb;
4498
4499 data.ef->invisible_ellipses_already_displayed = 1;
4500 data.ef->invisible_ellipses = 0;
4501 gb.extent = Qnil;
4502 gb.glyph = Vinvisible_text_glyph;
4503 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
4504 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
4505 /* Perhaps they shouldn't propagate if the very next thing
4506 is to display a newline (for compatibility with
4507 selective-display-ellipses)? Maybe that's too
4508 abstruse. */
4509 if (*prop)
4510 goto done;
4511 }
4512
4513 /* #### What if we we're dealing with a display table? */
4514 if (data.start_col)
4515 data.start_col--;
4516
4517 if (data.bi_bufpos == bi_string_zv)
4518 goto done;
4519 else
4520 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4521 }
4522
4523 /* If there is propagation data, then it represents the current
4524 buffer position being displayed. Add them and advance the
4525 position counter. This might also add the minibuffer
4526 prompt. */
4527 else if (*prop)
4528 {
4529 dl->used_prop_data = 1;
4530 *prop = add_propagation_runes (prop, &data);
4531
4532 if (*prop)
4533 goto done; /* gee, a really narrow window */
4534 else if (data.bi_bufpos == bi_string_zv)
4535 goto done;
4536 else if (data.bi_bufpos < 0)
4537 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
4538 data.bi_bufpos = 0;
4539 else
4540 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4541 }
4542
4543 /* If there are end glyphs, add them to the line. These are
4544 the end glyphs for the previous run of text. We add them
4545 here rather than doing them at the end of handling the
4546 previous run so that glyphs at the beginning and end of
4547 a line are handled correctly. */
4548 else if (Dynarr_length (data.ef->end_glyphs) > 0)
4549 {
4550 *prop = add_glyph_runes (&data, END_GLYPHS);
4551 if (*prop)
4552 goto done;
4553 }
4554
4555 /* If there are begin glyphs, add them to the line. */
4556 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
4557 {
4558 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
4559 if (*prop)
4560 goto done;
4561 }
4562
4563 /* If at end-of-buffer, we've already processed begin and
4564 end-glyphs at this point and there's no text to process,
4565 so we're done. */
4566 else if (data.bi_bufpos == bi_string_zv)
4567 goto done;
4568
4569 else
4570 {
4571 Lisp_Object entry = Qnil;
4572 /* Get the character at the current buffer position. */
4573 data.ch = string_char (s, data.bi_bufpos);
4574 if (!NILP (face_dt) || !NILP (window_dt))
4575 entry = display_table_entry (data.ch, face_dt, window_dt);
4576
4577 /* If there is a display table entry for it, hand it off to
4578 add_disp_table_entry_runes and let it worry about it. */
4579 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
4580 {
4581 *prop = add_disp_table_entry_runes (&data, entry);
4582
4583 if (*prop)
4584 goto done;
4585 }
4586
4587 /* Check if we have hit a newline character. If so, add a marker
4588 to the line and end this loop. */
4589 else if (data.ch == '\n')
4590 {
4591 /* We aren't going to be adding an end glyph so give its
4592 space back in order to make sure that the cursor can
4593 fit. */
4594 data.max_pixpos += end_glyph_width;
4595 goto done;
4596 }
4597
4598 /* If the current character is considered to be printable, then
4599 just add it. */
4600 else if (data.ch >= printable_min)
4601 {
4602 *prop = add_emchar_rune (&data);
4603 if (*prop)
4604 goto done;
4605 }
4606
4607 /* If the current character is a tab, determine the next tab
4608 starting position and add a blank rune which extends from the
4609 current pixel position to that starting position. */
4610 else if (data.ch == '\t')
4611 {
4612 int tab_start_pixpos = data.pixpos;
4613 int next_tab_start;
4614 int char_tab_width;
4615 int prop_width = 0;
4616
4617 if (data.start_col > 1)
4618 tab_start_pixpos -= (space_width (w) * (data.start_col - 1));
4619
4620 next_tab_start =
4621 next_tab_position (w, tab_start_pixpos,
4622 dl->bounds.left_in +
4623 data.hscroll_glyph_width_adjust);
4624 if (next_tab_start > data.max_pixpos)
4625 {
4626 prop_width = next_tab_start - data.max_pixpos;
4627 next_tab_start = data.max_pixpos;
4628 }
4629 data.blank_width = next_tab_start - data.pixpos;
4630 char_tab_width =
4631 (next_tab_start - tab_start_pixpos) / space_width (w);
4632
4633 *prop = add_blank_rune (&data, w, char_tab_width);
4634
4635 /* add_blank_rune is only supposed to be called with
4636 sizes guaranteed to fit in the available space. */
4637 assert (!(*prop));
4638
4639 if (prop_width)
4640 {
4641 struct prop_block pb;
4642 *prop = Dynarr_new (prop_block);
4643
4644 pb.type = PROP_BLANK;
4645 pb.data.p_blank.width = prop_width;
4646 pb.data.p_blank.findex = data.findex;
4647 Dynarr_add (*prop, pb);
4648
4649 goto done;
4650 }
4651 }
4652
4653 /* If character is a control character, pass it off to
4654 add_control_char_runes.
4655
4656 The is_*() routines have undefined results on
4657 arguments outside of the range [-1, 255]. (This
4658 often bites people who carelessly use `char' instead
4659 of `unsigned char'.)
4660 */
4661 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
4662 {
4663 *prop = add_control_char_runes (&data, b);
4664
4665 if (*prop)
4666 goto done;
4667 }
4668
4669 /* If the character is above the ASCII range and we have not
4670 already handled it, then print it as an octal number. */
4671 else if (data.ch >= 0200)
4672 {
4673 *prop = add_octal_runes (&data);
4674
4675 if (*prop)
4676 goto done;
4677 }
4678
4679 /* Assume the current character is considered to be printable,
4680 then just add it. */
4681 else
4682 {
4683 *prop = add_emchar_rune (&data);
4684 if (*prop)
4685 goto done;
4686 }
4687
4688 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4689 }
4690 }
4691
4692 done:
4693
4694 /* Determine the starting point of the next line if we did not hit the
4695 end of the buffer. */
4696 if (data.bi_bufpos < bi_string_zv)
4697 {
4698 /* #### This check is not correct. If the line terminated
4699 due to a begin-glyph or end-glyph hitting window-end, then
4700 data.ch will not point to the character at data.bi_bufpos. If
4701 you make the two changes mentioned at the top of this loop,
4702 you should be able to say '(if (*prop))'. That should also
4703 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
4704 check. */
4705
4706 /* The common case is that the line ended because we hit a newline.
4707 In that case, the next character is just the next buffer
4708 position. */
4709 if (data.ch == '\n')
4710 {
4711 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4712 }
4713
4714 /* Otherwise we have a buffer line which cannot fit on one display
4715 line. */
4716 else
4717 {
4718 struct glyph_block gb;
4719 struct glyph_cachel *cachel;
4720
4721 /* If the line is to be truncated then we actually have to look
4722 for the next newline. We also add the end-of-line glyph which
4723 we know will fit because we adjusted the right border before
4724 we starting laying out the line. */
4725 data.max_pixpos += end_glyph_width;
4726 data.findex = default_face;
4727 gb.extent = Qnil;
4728
4729 if (truncate_win)
4730 {
4731 Bytind bi_pos;
4732
4733 /* Now find the start of the next line. */
4734 bi_pos = bi_find_next_emchar_in_string (s, '\n', data.bi_bufpos, 1);
4735
4736 data.cursor_type = NO_CURSOR;
4737 data.bi_bufpos = bi_pos;
4738 gb.glyph = Vtruncation_glyph;
4739 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
4740 }
4741 else
4742 {
4743 /* The cursor can never be on the continuation glyph. */
4744 data.cursor_type = NO_CURSOR;
4745
4746 /* data.bi_bufpos is already at the start of the next line. */
4747
4748 dl->line_continuation = 1;
4749 gb.glyph = Vcontinuation_glyph;
4750 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
4751 }
4752
4753 if (end_glyph_width)
4754 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
4755
4756 if (truncate_win && data.bi_bufpos == bi_string_zv)
4757 {
4758 const Bufbyte* endb = charptr_n_addr (string_data (s), bi_string_zv);
4759 DEC_CHARPTR (endb);
4760 if (charptr_emchar (endb) != '\n')
4761 {
4762 /* #### Damn this losing shit. */
4763 data.bi_bufpos++;
4764 }
4765 }
4766 }
4767 }
4768 else if (data.bi_bufpos == bi_string_zv)
4769 {
4770 /* create_text_block () adds a bogus \n marker here which screws
4771 up subwindow display. Since we never have a cursor in the
4772 gutter we can safely ignore it. */
4773 }
4774 /* Calculate left whitespace boundary. */
4775 {
4776 int elt = 0;
4777
4778 /* Whitespace past a newline is considered right whitespace. */
4779 while (elt < Dynarr_length (db->runes))
4780 {
4781 struct rune *rb = Dynarr_atp (db->runes, elt);
4782
4783 if ((rb->type == RUNE_CHAR && rb->object.chr.ch == ' ')
4784 || rb->type == RUNE_BLANK)
4785 {
4786 dl->bounds.left_white += rb->width;
4787 elt++;
4788 }
4789 else
4790 elt = Dynarr_length (db->runes);
4791 }
4792 }
4793
4794 /* Calculate right whitespace boundary. */
4795 {
4796 int elt = Dynarr_length (db->runes) - 1;
4797 int done = 0;
4798
4799 while (!done && elt >= 0)
4800 {
4801 struct rune *rb = Dynarr_atp (db->runes, elt);
4802
4803 if (!(rb->type == RUNE_CHAR && rb->object.chr.ch < 0x100
4804 && isspace (rb->object.chr.ch))
4805 && !rb->type == RUNE_BLANK)
4806 {
4807 dl->bounds.right_white = rb->xpos + rb->width;
4808 done = 1;
4809 }
4810
4811 elt--;
4812
4813 }
4814
4815 /* The line is blank so everything is considered to be right
4816 whitespace. */
4817 if (!done)
4818 dl->bounds.right_white = dl->bounds.left_in;
4819 }
4820
4821 /* Set the display blocks bounds. */
4822 db->start_pos = dl->bounds.left_in;
4823 if (Dynarr_length (db->runes))
4824 {
4825 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
4826
4827 db->end_pos = rb->xpos + rb->width;
4828 }
4829 else
4830 db->end_pos = dl->bounds.right_white;
4831
4832 /* update line height parameters */
4833 if (!data.new_ascent && !data.new_descent)
4834 {
4835 /* We've got a blank line so initialize these values from the default
4836 face. */
4837 default_face_font_info (data.window, &data.new_ascent,
4838 &data.new_descent, 0, 0, 0);
4839 }
4840
4841 if (data.max_pixmap_height)
4842 {
4843 int height = data.new_ascent + data.new_descent;
4844 int pix_ascent, pix_descent;
4845
4846 pix_descent = data.max_pixmap_height * data.new_descent / height;
4847 pix_ascent = data.max_pixmap_height - pix_descent;
4848
4849 data.new_ascent = max (data.new_ascent, pix_ascent);
4850 data.new_descent = max (data.new_descent, pix_descent);
4851 }
4852
4853 dl->ascent = data.new_ascent;
4854 dl->descent = data.new_descent;
4855
4856 {
4857 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
4858
4859 if (dl->ascent < ascent)
4860 dl->ascent = ascent;
4861 }
4862 {
4863 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
4864
4865 if (dl->descent < descent)
4866 dl->descent = descent;
4867 }
4868
4869 dl->cursor_elt = data.cursor_x;
4870 /* #### lossage lossage lossage! Fix this shit! */
4871 if (data.bi_bufpos > bi_string_zv)
4872 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, bi_string_zv);
4873 else
4874 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, data.bi_bufpos) - 1;
4875 if (truncate_win)
4876 data.dl->num_chars =
4877 string_column_at_point (s, dl->end_bufpos, b ? XINT (b->tab_width) : 8);
4878 else
4879 /* This doesn't correctly take into account tabs and control
4880 characters but if the window isn't being truncated then this
4881 value isn't going to end up being used anyhow. */
4882 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
4883
4884 /* #### handle horizontally scrolled line with text none of which
4885 was actually laid out. */
4886
4887 /* #### handle any remainder of overlay arrow */
4888
4889 if (*prop == ADD_FAILED)
4890 *prop = NULL;
4891
4892 if (truncate_win && *prop)
4893 {
4894 Dynarr_free (*prop);
4895 *prop = NULL;
4896 }
4897
4898 extent_fragment_delete (data.ef);
4899
4900 /* #### If we started at EOB, then make sure we return a value past
4901 it so that regenerate_window will exit properly. This is bogus.
4902 The main loop should get fixed so that it isn't necessary to call
4903 this function if we are already at EOB. */
4904
4905 if (data.bi_bufpos == bi_string_zv && bi_start_pos == bi_string_zv)
4906 return bytecount_to_charcount (string_data (s), data.bi_bufpos) + 1; /* Yuck! */
4907 else
4908 return bytecount_to_charcount (string_data (s), data.bi_bufpos);
4909 }
4910
4911 /* Given a display line and a starting position, ensure that the
4912 contents of the display line accurately represent the visual
4913 representation of the buffer contents starting from the given
4914 position when displayed in the given window. The display line ends
4915 when the contents of the line reach the right boundary of the given
4916 window.
4917
4918 This is very similar to generate_display_line but with the same
4919 limitations as create_string_text_block. I have taken the liberty
4920 of fixing the bytind stuff though.*/
4921
4922 static Bufpos
4923 generate_string_display_line (struct window *w, Lisp_Object disp_string,
4924 struct display_line *dl,
4925 Bufpos start_pos,
4926 prop_block_dynarr **prop,
4927 face_index default_face)
4928 {
4929 Bufpos ret_bufpos;
4930
4931 /* you must set bounds before calling this. */
4932
4933 /* Reset what this line is using. */
4934 if (dl->display_blocks)
4935 Dynarr_reset (dl->display_blocks);
4936 if (dl->left_glyphs)
4937 {
4938 Dynarr_free (dl->left_glyphs);
4939 dl->left_glyphs = 0;
4940 }
4941 if (dl->right_glyphs)
4942 {
4943 Dynarr_free (dl->right_glyphs);
4944 dl->right_glyphs = 0;
4945 }
4946
4947 /* We aren't generating a modeline at the moment. */
4948 dl->modeline = 0;
4949
4950 /* Create a display block for the text region of the line. */
4951 ret_bufpos = create_string_text_block (w, disp_string, dl, start_pos,
4952 prop, default_face);
4953 dl->bufpos = start_pos;
4954 if (dl->end_bufpos < dl->bufpos)
4955 dl->end_bufpos = dl->bufpos;
4956
4957 /* If there are left glyphs associated with any character in the
4958 text block, then create a display block to handle them. */
4959 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
4960 create_left_glyph_block (w, dl, 0);
4961
4962 /* If there are right glyphs associated with any character in the
4963 text block, then create a display block to handle them. */
4964 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
4965 create_right_glyph_block (w, dl);
4966
4967 return ret_bufpos;
4968 }
4969
4970 /* This is ripped off from regenerate_window. All we want to do is
4971 loop through elements in the string creating display lines until we
4972 have covered the provided area. Simple really. */
4973 void
4974 generate_displayable_area (struct window *w, Lisp_Object disp_string,
4975 int xpos, int ypos, int width, int height,
4976 display_line_dynarr* dla,
4977 Bufpos start_pos,
4978 face_index default_face)
4979 {
4980 int yend = ypos + height;
4981 Charcount s_zv;
4982
4983 prop_block_dynarr *prop = 0;
4984 layout_bounds bounds;
4985 assert (dla);
4986
4987 Dynarr_reset (dla);
4988 /* if there's nothing to do then do nothing. code after this assumes
4989 there is something to do. */
4990 if (NILP (disp_string))
4991 return;
4992
4993 s_zv = XSTRING_CHAR_LENGTH (disp_string);
4994
4995 bounds.left_out = xpos;
4996 bounds.right_out = xpos + width;
4997 /* The inner boundaries mark where the glyph margins are located. */
4998 bounds.left_in = bounds.left_out + window_left_margin_width (w);
4999 bounds.right_in = bounds.right_out - window_right_margin_width (w);
5000 /* We cannot fully calculate the whitespace boundaries as they
5001 depend on the contents of the line being displayed. */
5002 bounds.left_white = bounds.left_in;
5003 bounds.right_white = bounds.right_in;
5004
5005 while (ypos < yend)
5006 {
5007 struct display_line dl;
5008 struct display_line *dlp;
5009 Bufpos next_pos;
5010 int local;
5011
5012 if (Dynarr_length (dla) < Dynarr_largest (dla))
5013 {
5014 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5015 local = 0;
5016 }
5017 else
5018 {
5019
5020 xzero (dl);
5021 dlp = &dl;
5022 local = 1;
5023 }
5024
5025 dlp->bounds = bounds;
5026 dlp->offset = 0;
5027 next_pos = generate_string_display_line (w, disp_string, dlp, start_pos,
5028 &prop, default_face);
5029 /* we need to make sure that we continue along the line if there
5030 is more left to display otherwise we just end up redisplaying
5031 the same chunk over and over again. */
5032 if (next_pos == start_pos && next_pos < s_zv)
5033 start_pos++;
5034 else
5035 start_pos = next_pos;
5036
5037 dlp->ypos = ypos + dlp->ascent;
5038 ypos = dlp->ypos + dlp->descent;
5039
5040 if (ypos > yend)
5041 {
5042 int visible_height = dlp->ascent + dlp->descent;
5043
5044 dlp->clip = (ypos - yend);
5045 visible_height -= dlp->clip;
5046
5047 if (visible_height < VERTICAL_CLIP (w, 1))
5048 {
5049 if (local)
5050 free_display_line (dlp);
5051 break;
5052 }
5053 }
5054 else
5055 dlp->clip = 0;
5056
5057 Dynarr_add (dla, *dlp);
5058
5059 /* #### This type of check needs to be done down in the
5060 generate_display_line call. */
5061 if (start_pos >= s_zv)
5062 break;
5063 }
5064
5065 if (prop)
5066 Dynarr_free (prop);
5067 }
5068
5069
5070 /***************************************************************************/
5071 /* */ 4181 /* */
5072 /* window-regeneration routines */ 4182 /* window-regeneration routines */
5073 /* */ 4183 /* */
5074 /***************************************************************************/ 4184 /***************************************************************************/
5075 4185
5084 { 4194 {
5085 struct frame *f = XFRAME (w->frame); 4195 struct frame *f = XFRAME (w->frame);
5086 struct buffer *b = XBUFFER (w->buffer); 4196 struct buffer *b = XBUFFER (w->buffer);
5087 int ypos = WINDOW_TEXT_TOP (w); 4197 int ypos = WINDOW_TEXT_TOP (w);
5088 int yend; /* set farther down */ 4198 int yend; /* set farther down */
5089 int yclip = WINDOW_TEXT_TOP_CLIP (w);
5090 int force;
5091 4199
5092 prop_block_dynarr *prop; 4200 prop_block_dynarr *prop;
5093 layout_bounds bounds; 4201 layout_bounds bounds;
5094 display_line_dynarr *dla; 4202 display_line_dynarr *dla;
5095 int need_modeline; 4203 int need_modeline;
5139 Dynarr_add (prop, pb); 4247 Dynarr_add (prop, pb);
5140 } 4248 }
5141 else 4249 else
5142 prop = 0; 4250 prop = 0;
5143 4251
5144 /* When we are computing things for scrolling purposes, make 4252 while (ypos < yend)
5145 sure at least one line is always generated */
5146 force = (type == CMOTION_DISP);
5147
5148 /* Make sure this is set always */
5149 /* Note the conversion at end */
5150 w->window_end_pos[type] = start_pos;
5151 while (ypos < yend || force)
5152 { 4253 {
5153 struct display_line dl; 4254 struct display_line dl;
5154 struct display_line *dlp; 4255 struct display_line *dlp;
5155 int local; 4256 int local;
5156 4257
5159 dlp = Dynarr_atp (dla, Dynarr_length (dla)); 4260 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5160 local = 0; 4261 local = 0;
5161 } 4262 }
5162 else 4263 else
5163 { 4264 {
5164
5165 xzero (dl); 4265 xzero (dl);
5166 dlp = &dl; 4266 dlp = &dl;
5167 local = 1; 4267 local = 1;
5168 } 4268 }
5169 4269
5170 dlp->bounds = bounds; 4270 dlp->bounds = bounds;
5171 dlp->offset = 0; 4271 dlp->offset = 0;
5172 start_pos = generate_display_line (w, dlp, 1, start_pos, &prop, type); 4272 start_pos = generate_display_line (w, dlp, 1, start_pos,
5173 4273 w->hscroll, &prop, type);
5174 if (yclip > dlp->ascent) 4274 dlp->ypos = ypos + dlp->ascent;
5175 {
5176 /* this should never happen, but if it does just display the
5177 whole line */
5178 yclip = 0;
5179 }
5180
5181 dlp->ypos = (ypos + dlp->ascent) - yclip;
5182 ypos = dlp->ypos + dlp->descent; 4275 ypos = dlp->ypos + dlp->descent;
5183 4276
5184 /* See if we've been asked to start midway through a line, for
5185 partial display line scrolling. */
5186 if (yclip)
5187 {
5188 dlp->top_clip = yclip;
5189 yclip = 0;
5190 }
5191 else
5192 dlp->top_clip = 0;
5193
5194 if (ypos > yend) 4277 if (ypos > yend)
5195 { 4278 {
5196 int visible_height = dlp->ascent + dlp->descent; 4279 int visible_height = dlp->ascent + dlp->descent;
5197 4280
5198 dlp->clip = (ypos - yend); 4281 dlp->clip = (ypos - yend);
5199 /* Although this seems strange we could have a single very 4282 visible_height -= dlp->clip;
5200 tall line visible for which we need to account for both 4283
5201 the top clip and the bottom clip. */ 4284 if (visible_height < VERTICAL_CLIP (w, 1))
5202 visible_height -= (dlp->clip + dlp->top_clip);
5203
5204 if (visible_height < VERTICAL_CLIP (w, 1) && !force)
5205 { 4285 {
5206 if (local) 4286 if (local)
5207 free_display_line (dlp); 4287 free_display_line (dlp);
5208 break; 4288 break;
5209 } 4289 }
5243 4323
5244 /* #### This type of check needs to be done down in the 4324 /* #### This type of check needs to be done down in the
5245 generate_display_line call. */ 4325 generate_display_line call. */
5246 if (start_pos > BUF_ZV (b)) 4326 if (start_pos > BUF_ZV (b))
5247 break; 4327 break;
5248
5249 force = 0;
5250 } 4328 }
5251 4329
5252 if (prop) 4330 if (prop)
5253 Dynarr_free (prop); 4331 Dynarr_free (prop);
5254 4332
5255 /* #### More not quite right, but close enough. */ 4333 /* #### More not quite right, but close enough. */
5256 /* Ben sez: apparently window_end_pos[] is measured 4334 /* #### Ben sez: apparently window_end_pos[] is measured
5257 as the number of characters between the window end and the 4335 as the number of characters between the window end and the
5258 end of the buffer? This seems rather weirdo. What's 4336 end of the buffer? This seems rather weirdo. What's
5259 the justification for this? 4337 the justification for this? */
5260
5261 JV sez: Because BUF_Z (b) would be a good initial value, however
5262 that can change. This representation allows initalizing with 0.
5263 */
5264 w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type]; 4338 w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type];
5265 4339
5266 if (need_modeline) 4340 if (need_modeline)
5267 { 4341 {
5268 /* We know that this is the right thing to use because we put it 4342 /* We know that this is the right thing to use because we put it
5446 we'll have the necessary propagation data. */ 4520 we'll have the necessary propagation data. */
5447 if (line == first_line && ddl->used_prop_data) 4521 if (line == first_line && ddl->used_prop_data)
5448 return 0; 4522 return 0;
5449 4523
5450 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset, 4524 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5451 &prop, DESIRED_DISP); 4525 w->hscroll, &prop, DESIRED_DISP);
5452 ddl->offset = 0; 4526 ddl->offset = 0;
5453 4527
5454 /* #### If there is propagated stuff the fail. We could 4528 /* #### If there is propagated stuff the fail. We could
5455 probably actually deal with this if the line had propagated 4529 probably actually deal with this if the line had propagated
5456 information when originally created by a full 4530 information when originally created by a full
5465 cursor has disappeared or disappeared, fail. */ 4539 cursor has disappeared or disappeared, fail. */
5466 db = get_display_block_from_line (ddl, TEXT); 4540 db = get_display_block_from_line (ddl, TEXT);
5467 if (cdl->ypos != ddl->ypos 4541 if (cdl->ypos != ddl->ypos
5468 || cdl->ascent != ddl->ascent 4542 || cdl->ascent != ddl->ascent
5469 || cdl->descent != ddl->descent 4543 || cdl->descent != ddl->descent
5470 || cdl->top_clip != ddl->top_clip
5471 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1) 4544 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5472 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1) 4545 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1)
5473 || old_start != ddl->bufpos 4546 || old_start != ddl->bufpos
5474 || old_end != ddl->end_bufpos 4547 || old_end != ddl->end_bufpos
5475 || initial_size != Dynarr_length (db->runes)) 4548 || initial_size != Dynarr_length (db->runes))
5589 4662
5590 assert (cdl->bufpos == ddl->bufpos); 4663 assert (cdl->bufpos == ddl->bufpos);
5591 assert (cdl->end_bufpos == ddl->end_bufpos); 4664 assert (cdl->end_bufpos == ddl->end_bufpos);
5592 assert (cdl->offset == ddl->offset); 4665 assert (cdl->offset == ddl->offset);
5593 4666
5594 /* If the line continues to next display line, fail. */ 4667 /* If the last rune is already a continuation glyph, fail.
5595 if (ddl->line_continuation) 4668 #### We should be able to handle this better. */
5596 return 0; 4669 {
4670 struct display_block *db = get_display_block_from_line (ddl, TEXT);
4671 if (Dynarr_length (db->runes))
4672 {
4673 struct rune *rb =
4674 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
4675
4676 if (rb->type == RUNE_DGLYPH
4677 && EQ (rb->object.dglyph.glyph, Vcontinuation_glyph))
4678 return 0;
4679 }
4680 }
5597 4681
5598 /* If the line was generated using propagation data, fail. */ 4682 /* If the line was generated using propagation data, fail. */
5599 if (ddl->used_prop_data) 4683 if (ddl->used_prop_data)
5600 return 0; 4684 return 0;
5601 4685
5602 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset, 4686 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5603 &prop, DESIRED_DISP); 4687 w->hscroll, &prop, DESIRED_DISP);
5604 ddl->offset = 0; 4688 ddl->offset = 0;
5605 4689
5606 /* If there is propagated stuff then it is pretty much a 4690 /* If there is propagated stuff then it is pretty much a
5607 guarantee that more than just the one line is affected. */ 4691 guarantee that more than just the one line is affected. */
5608 if (prop) 4692 if (prop)
5609 { 4693 {
5610 Dynarr_free (prop); 4694 Dynarr_free (prop);
5611 return 0; 4695 return 0;
5612 } 4696 }
5613 4697
5614 /* If the line continues to next display line, fail. */ 4698 /* If the last rune is now a continuation glyph, fail. */
5615 if (ddl->line_continuation) 4699 {
5616 return 0; 4700 struct display_block *db = get_display_block_from_line (ddl, TEXT);
4701 if (Dynarr_length (db->runes))
4702 {
4703 struct rune *rb =
4704 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
4705
4706 if (rb->type == RUNE_DGLYPH
4707 && EQ (rb->object.dglyph.glyph, Vcontinuation_glyph))
4708 return 0;
4709 }
4710 }
5617 4711
5618 /* If any line position parameters have changed or a 4712 /* If any line position parameters have changed or a
5619 cursor has disappeared or disappeared, fail. */ 4713 cursor has disappeared or disappeared, fail. */
5620 if (cdl->ypos != ddl->ypos 4714 if (cdl->ypos != ddl->ypos
5621 || cdl->ascent != ddl->ascent 4715 || cdl->ascent != ddl->ascent
5622 || cdl->descent != ddl->descent 4716 || cdl->descent != ddl->descent
5623 || cdl->top_clip != ddl->top_clip
5624 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1) 4717 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5625 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1)) 4718 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1))
5626 { 4719 {
5627 return 0; 4720 return 0;
5628 } 4721 }
5902 pointm = BUF_ZV (b); 4995 pointm = BUF_ZV (b);
5903 } 4996 }
5904 } 4997 }
5905 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm), the_buffer); 4998 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm), the_buffer);
5906 4999
5907 /* If the buffer has changed we have to invalidate all of our face 5000 /* If the buffer has changed we have to invalid all of our face
5908 cache elements. */ 5001 cache elements. */
5909 if ((!echo_active && b != window_display_buffer (w)) 5002 if ((!echo_active && b != window_display_buffer (w))
5910 || !Dynarr_length (w->face_cachels) 5003 || !Dynarr_length (w->face_cachels)
5911 || f->faces_changed) 5004 || f->faces_changed)
5912 reset_face_cachels (w); 5005 reset_face_cachels (w);
5913 else 5006 else
5914 mark_face_cachels_as_not_updated (w); 5007 mark_face_cachels_as_not_updated (w);
5915 5008
5916 /* Ditto the glyph cache elements, although we do *not* invalidate 5009 /* Ditto the glyph cache elements. */
5917 the cache purely because glyphs have changed - this is now
5918 handled by the dirty flag.*/
5919 if ((!echo_active && b != window_display_buffer (w)) 5010 if ((!echo_active && b != window_display_buffer (w))
5920 || !Dynarr_length (w->glyph_cachels) || f->faces_changed) 5011 || !Dynarr_length (w->glyph_cachels)
5012 || f->glyphs_changed)
5921 reset_glyph_cachels (w); 5013 reset_glyph_cachels (w);
5922 else 5014 else
5923 mark_glyph_cachels_as_not_updated (w); 5015 mark_glyph_cachels_as_not_updated (w);
5924 5016
5925 /* If the marker's buffer is not the window's buffer, then we need 5017 /* If the marker's buffer is not the window's buffer, then we need
6001 && !f->clip_changed 5093 && !f->clip_changed
6002 && !f->extents_changed 5094 && !f->extents_changed
6003 && !f->faces_changed 5095 && !f->faces_changed
6004 && !f->glyphs_changed 5096 && !f->glyphs_changed
6005 && !f->subwindows_changed 5097 && !f->subwindows_changed
6006 /* && !f->subwindows_state_changed*/
6007 && !f->point_changed 5098 && !f->point_changed
6008 && !f->windows_structure_changed) 5099 && !f->windows_structure_changed)
6009 { 5100 {
6010 /* If not, we're done. */ 5101 /* If not, we're done. */
6011 if (f->modeline_changed) 5102 if (f->modeline_changed)
6023 && !f->clip_changed 5114 && !f->clip_changed
6024 && !f->extents_changed 5115 && !f->extents_changed
6025 && !f->faces_changed 5116 && !f->faces_changed
6026 && !f->glyphs_changed 5117 && !f->glyphs_changed
6027 && !f->subwindows_changed 5118 && !f->subwindows_changed
6028 /* && !f->subwindows_state_changed*/
6029 && !f->windows_structure_changed) 5119 && !f->windows_structure_changed)
6030 { 5120 {
6031 if (point_visible (w, pointm, CURRENT_DISP) 5121 if (point_visible (w, pointm, CURRENT_DISP)
6032 && w->last_point_x[CURRENT_DISP] != -1 5122 && w->last_point_x[CURRENT_DISP] != -1
6033 && w->last_point_y[CURRENT_DISP] != -1) 5123 && w->last_point_y[CURRENT_DISP] != -1)
6082 else if (!w->windows_changed 5172 else if (!w->windows_changed
6083 && !f->clip_changed 5173 && !f->clip_changed
6084 && !f->faces_changed 5174 && !f->faces_changed
6085 && !f->glyphs_changed 5175 && !f->glyphs_changed
6086 && !f->subwindows_changed 5176 && !f->subwindows_changed
6087 /* && !f->subwindows_state_changed*/
6088 && !f->windows_structure_changed 5177 && !f->windows_structure_changed
6089 && !f->frame_changed 5178 && !f->frame_changed
6090 && !truncation_changed 5179 && !truncation_changed
6091 && pointm >= startp 5180 && pointm >= startp
6092 && regenerate_window_incrementally (w, startp, pointm)) 5181 && regenerate_window_incrementally (w, startp, pointm))
6179 5268
6180 /* #### This should be dependent on face changes and will need to be 5269 /* #### This should be dependent on face changes and will need to be
6181 somewhere else once tty updates occur on a per-frame basis. */ 5270 somewhere else once tty updates occur on a per-frame basis. */
6182 mark_face_cachels_as_clean (w); 5271 mark_face_cachels_as_clean (w);
6183 5272
6184 /* The glyph cachels only get dirty if someone changed something.
6185 Since redisplay has now effectively ended we can reset the dirty
6186 flag since everything must be up-to-date. */
6187 if (glyphs_changed)
6188 mark_glyph_cachels_as_clean (w);
6189
6190 w->windows_changed = 0; 5273 w->windows_changed = 0;
6191 } 5274 }
6192 5275
6193 /* Call buffer_reset_changes for all buffers present in any window 5276 /* Call buffer_reset_changes for all buffers present in any window
6194 currently visible in all frames on all devices. #### There has to 5277 currently visible in all frames on all devices. #### There has to
6264 return 0; 5347 return 0;
6265 } 5348 }
6266 5349
6267 /* Ensure that all windows on the given frame are correctly displayed. */ 5350 /* Ensure that all windows on the given frame are correctly displayed. */
6268 5351
6269 int 5352 static int
6270 redisplay_frame (struct frame *f, int preemption_check) 5353 redisplay_frame (struct frame *f, int preemption_check)
6271 { 5354 {
6272 struct device *d = XDEVICE (f->device); 5355 struct device *d = XDEVICE (f->device);
6273 5356
6274 if (preemption_check) 5357 if (preemption_check)
6279 int preempted; 5362 int preempted;
6280 5363
6281 REDISPLAY_PREEMPTION_CHECK; 5364 REDISPLAY_PREEMPTION_CHECK;
6282 if (preempted) 5365 if (preempted)
6283 return 1; 5366 return 1;
6284 }
6285
6286 if (!internal_equal (f->old_buffer_alist, f->buffer_alist, 0))
6287 {
6288 Lisp_Object frame;
6289
6290 f->old_buffer_alist = Freplace_list (f->old_buffer_alist,
6291 f->buffer_alist);
6292 XSETFRAME (frame, f);
6293 va_run_hook_with_args (Qbuffer_list_changed_hook, 1, frame);
6294 } 5367 }
6295 5368
6296 /* Before we put a hold on frame size changes, attempt to process 5369 /* Before we put a hold on frame size changes, attempt to process
6297 any which are already pending. */ 5370 any which are already pending. */
6298 if (f->size_change_pending) 5371 if (f->size_change_pending)
6316 the menubar's visibility. This way we avoid having flashing 5389 the menubar's visibility. This way we avoid having flashing
6317 caused by an Expose event generated by the visibility change 5390 caused by an Expose event generated by the visibility change
6318 being handled. */ 5391 being handled. */
6319 update_frame_menubars (f); 5392 update_frame_menubars (f);
6320 #endif /* HAVE_MENUBARS */ 5393 #endif /* HAVE_MENUBARS */
5394 /* widgets are similar to menus in that they can call lisp to
5395 determine activation etc. Therefore update them before we get
5396 into redisplay. This is primarily for connected widgets such as
5397 radio buttons. */
5398 update_frame_subwindows (f);
6321 #ifdef HAVE_TOOLBARS 5399 #ifdef HAVE_TOOLBARS
6322 /* Update the toolbars. */ 5400 /* Update the toolbars. */
6323 update_frame_toolbars (f); 5401 update_frame_toolbars (f);
6324 #endif /* HAVE_TOOLBARS */ 5402 #endif /* HAVE_TOOLBARS */
6325 /* Gutter update proper has to be done inside display when no frame
6326 size changes can occur, thus we separately update the gutter
6327 geometry here if it needs it. */
6328 update_frame_gutter_geometry (f);
6329
6330 /* If we clear the frame we have to force its contents to be redrawn. */
6331 if (f->clear)
6332 f->frame_changed = 1;
6333
6334 /* Invalidate the subwindow cache. We use subwindows_changed here to
6335 cause subwindows to get instantiated. This is because
6336 subwindows_state_changed is less strict - dealing with things
6337 like the clicked state of button. We have to do this before
6338 redisplaying the gutters as subwindows get unmapped in the
6339 process.*/
6340 if (f->frame_changed || f->subwindows_changed)
6341 {
6342 /* we have to do this so the gutter gets regenerated. */
6343 reset_gutter_display_lines (f);
6344 }
6345 5403
6346 hold_frame_size_changes (); 5404 hold_frame_size_changes ();
6347 5405
6348 /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */ 5406 /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */
6349 /* Within this section, we are defenseless and assume that the 5407 /* Within this section, we are defenseless and assume that the
6367 we simply return. #### We should abort instead. 5425 we simply return. #### We should abort instead.
6368 5426
6369 #### If a frame-size change does occur we should probably 5427 #### If a frame-size change does occur we should probably
6370 actually be preempting redisplay. */ 5428 actually be preempting redisplay. */
6371 5429
6372 MAYBE_DEVMETH (d, frame_output_begin, (f)); 5430 /* If we clear the frame we have to force its contents to be redrawn. */
6373 5431 if (f->clear)
6374 /* We can now update the gutters, safe in the knowledge that our 5432 f->frame_changed = 1;
6375 efforts won't get undone. */
6376
6377 /* This can call lisp, but redisplay is protected by binding
6378 inhibit_quit. More importantly the code involving display lines
6379 *assumes* that GC will not happen and so does not GCPRO
6380 anything. Since we use this code the whole time with the gutters
6381 we cannot allow GC to happen when manipulating the gutters. */
6382 update_frame_gutters (f);
6383 5433
6384 /* Erase the frame before outputting its contents. */ 5434 /* Erase the frame before outputting its contents. */
6385 if (f->clear) 5435 if (f->clear)
6386 { 5436 {
6387 MAYBE_DEVMETH (d, clear_frame, (f)); 5437 DEVMETH (d, clear_frame, (f));
6388 } 5438 }
5439
5440 /* invalidate the subwindow cache. we are going to reuse the glyphs
5441 flag here to cause subwindows to get instantiated. This is
5442 because subwindows changed is less strict - dealing with things
5443 like the clicked state of button. */
5444 if (!Dynarr_length (f->subwindow_cachels)
5445 || f->glyphs_changed
5446 || f->frame_changed)
5447 reset_subwindow_cachels (f);
5448 else
5449 mark_subwindow_cachels_as_not_updated (f);
6389 5450
6390 /* Do the selected window first. */ 5451 /* Do the selected window first. */
6391 redisplay_window (FRAME_SELECTED_WINDOW (f), 0); 5452 redisplay_window (FRAME_SELECTED_WINDOW (f), 0);
6392 5453
6393 /* Then do the rest. */ 5454 /* Then do the rest. */
6394 redisplay_windows (f->root_window, 1); 5455 redisplay_windows (f->root_window, 1);
6395 5456
6396 MAYBE_DEVMETH (d, frame_output_end, (f)); 5457 /* We now call the output_end routine for tty frames. We delay
5458 doing so in order to avoid cursor flicker. So much for 100%
5459 encapsulation. */
5460 if (FRAME_TTY_P (f))
5461 DEVMETH (d, output_end, (d));
6397 5462
6398 update_frame_title (f); 5463 update_frame_title (f);
6399 5464
6400 CLASS_RESET_CHANGED_FLAGS (f); 5465 f->buffers_changed = 0;
5466 f->clip_changed = 0;
5467 f->extents_changed = 0;
5468 f->faces_changed = 0;
5469 f->frame_changed = 0;
5470 f->glyphs_changed = 0;
5471 f->subwindows_changed = 0;
5472 f->icon_changed = 0;
5473 f->menubar_changed = 0;
5474 f->modeline_changed = 0;
5475 f->point_changed = 0;
5476 f->toolbar_changed = 0;
5477 f->windows_changed = 0;
5478 f->windows_structure_changed = 0;
6401 f->window_face_cache_reset = 0; 5479 f->window_face_cache_reset = 0;
6402 f->echo_area_garbaged = 0; 5480 f->echo_area_garbaged = 0;
5481
6403 f->clear = 0; 5482 f->clear = 0;
6404 5483
6405 if (!f->size_change_pending) 5484 if (!f->size_change_pending)
6406 f->size_changed = 0; 5485 f->size_changed = 0;
6407 5486
6414 5493
6415 map_windows (f, call_redisplay_end_triggers, 0); 5494 map_windows (f, call_redisplay_end_triggers, 0);
6416 return 0; 5495 return 0;
6417 } 5496 }
6418 5497
6419 /* Ensure that all frames on the given device are correctly displayed. 5498 /* Ensure that all frames on the given device are correctly displayed. */
6420 If AUTOMATIC is non-zero, and the device implementation indicates
6421 no automatic redisplay, as printers do, then the device is not
6422 redisplayed. AUTOMATIC is set to zero when called from lisp
6423 functions (redraw-device) and (redisplay-device), and to non-zero
6424 when called from "lazy" redisplay();
6425 */
6426 5499
6427 static int 5500 static int
6428 redisplay_device (struct device *d, int automatic) 5501 redisplay_device (struct device *d)
6429 { 5502 {
6430 Lisp_Object frame, frmcons; 5503 Lisp_Object frame, frmcons;
6431 int preempted = 0; 5504 int preempted = 0;
6432 int size_change_failed = 0; 5505 int size_change_failed = 0;
6433 struct frame *f; 5506 struct frame *f;
6434
6435 if (automatic
6436 && (MAYBE_INT_DEVMETH (d, device_implementation_flags, ())
6437 & XDEVIMPF_NO_AUTO_REDISPLAY))
6438 return 0;
6439 5507
6440 if (DEVICE_STREAM_P (d)) /* nothing to do */ 5508 if (DEVICE_STREAM_P (d)) /* nothing to do */
6441 return 0; 5509 return 0;
6442 5510
6443 /* It is possible that redisplay has been called before the 5511 /* It is possible that redisplay has been called before the
6458 if (f->icon_changed || f->windows_changed) 5526 if (f->icon_changed || f->windows_changed)
6459 update_frame_icon (f); 5527 update_frame_icon (f);
6460 5528
6461 if (FRAME_REPAINT_P (f)) 5529 if (FRAME_REPAINT_P (f))
6462 { 5530 {
6463 if (CLASS_REDISPLAY_FLAGS_CHANGEDP(f)) 5531 if (f->buffers_changed || f->clip_changed || f->extents_changed ||
5532 f->faces_changed || f->frame_changed || f->menubar_changed ||
5533 f->modeline_changed || f->point_changed || f->size_changed ||
5534 f->toolbar_changed || f->windows_changed || f->size_slipped ||
5535 f->windows_structure_changed || f->glyphs_changed || f->subwindows_changed)
6464 { 5536 {
6465 preempted = redisplay_frame (f, 0); 5537 preempted = redisplay_frame (f, 0);
6466 } 5538 }
6467 5539
6468 if (preempted) 5540 if (preempted)
6488 if (f->icon_changed || f->windows_changed) 5560 if (f->icon_changed || f->windows_changed)
6489 update_frame_icon (f); 5561 update_frame_icon (f);
6490 5562
6491 if (FRAME_REPAINT_P (f)) 5563 if (FRAME_REPAINT_P (f))
6492 { 5564 {
6493 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (f)) 5565 if (f->buffers_changed || f->clip_changed || f->extents_changed ||
5566 f->faces_changed || f->frame_changed || f->menubar_changed ||
5567 f->modeline_changed || f->point_changed || f->size_changed ||
5568 f->toolbar_changed || f->windows_changed ||
5569 f->windows_structure_changed ||
5570 f->glyphs_changed || f->subwindows_changed)
6494 { 5571 {
6495 preempted = redisplay_frame (f, 0); 5572 preempted = redisplay_frame (f, 0);
6496 } 5573 }
6497 5574
6498 if (preempted) 5575 if (preempted)
6503 } 5580 }
6504 } 5581 }
6505 5582
6506 /* If we get here then we redisplayed all of our frames without 5583 /* If we get here then we redisplayed all of our frames without
6507 getting preempted so mark ourselves as clean. */ 5584 getting preempted so mark ourselves as clean. */
6508 CLASS_RESET_CHANGED_FLAGS (d); 5585 d->buffers_changed = 0;
5586 d->clip_changed = 0;
5587 d->extents_changed = 0;
5588 d->faces_changed = 0;
5589 d->frame_changed = 0;
5590 d->glyphs_changed = 0;
5591 d->subwindows_changed = 0;
5592 d->icon_changed = 0;
5593 d->menubar_changed = 0;
5594 d->modeline_changed = 0;
5595 d->point_changed = 0;
5596 d->toolbar_changed = 0;
5597 d->windows_changed = 0;
5598 d->windows_structure_changed = 0;
6509 5599
6510 if (!size_change_failed) 5600 if (!size_change_failed)
6511 d->size_changed = 0; 5601 d->size_changed = 0;
6512 5602
6513 return 0; 5603 return 0;
6538 } 5628 }
6539 5629
6540 if (asynch_device_change_pending) 5630 if (asynch_device_change_pending)
6541 handle_asynch_device_change (); 5631 handle_asynch_device_change ();
6542 5632
6543 if (!GLOBAL_REDISPLAY_FLAGS_CHANGEDP && 5633 if (!buffers_changed && !clip_changed && !extents_changed &&
6544 !disable_preemption && preemption_count < max_preempts) 5634 !faces_changed && !frame_changed && !icon_changed &&
5635 !menubar_changed && !modeline_changed && !point_changed &&
5636 !size_changed && !toolbar_changed && !windows_changed &&
5637 !glyphs_changed && !subwindows_changed &&
5638 !windows_structure_changed && !disable_preemption &&
5639 preemption_count < max_preempts)
6545 goto done; 5640 goto done;
6546 5641
6547 DEVICE_LOOP_NO_BREAK (devcons, concons) 5642 DEVICE_LOOP_NO_BREAK (devcons, concons)
6548 { 5643 {
6549 struct device *d = XDEVICE (XCAR (devcons)); 5644 struct device *d = XDEVICE (XCAR (devcons));
6550 int preempted; 5645 int preempted;
6551 5646
6552 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (d)) 5647 if (d->buffers_changed || d->clip_changed || d->extents_changed ||
6553 { 5648 d->faces_changed || d->frame_changed || d->icon_changed ||
6554 preempted = redisplay_device (d, 1); 5649 d->menubar_changed || d->modeline_changed || d->point_changed ||
5650 d->size_changed || d->toolbar_changed || d->windows_changed ||
5651 d->windows_structure_changed ||
5652 d->glyphs_changed || d->subwindows_changed)
5653 {
5654 preempted = redisplay_device (d);
6555 5655
6556 if (preempted) 5656 if (preempted)
6557 { 5657 {
6558 preemption_count++; 5658 preemption_count++;
6559 RESET_CHANGED_SET_FLAGS; 5659 RESET_CHANGED_SET_FLAGS;
6566 } 5666 }
6567 } 5667 }
6568 preemption_count = 0; 5668 preemption_count = 0;
6569 5669
6570 /* Mark redisplay as accurate */ 5670 /* Mark redisplay as accurate */
6571 GLOBAL_RESET_CHANGED_FLAGS; 5671 buffers_changed = 0;
5672 clip_changed = 0;
5673 extents_changed = 0;
5674 frame_changed = 0;
5675 glyphs_changed = 0;
5676 subwindows_changed = 0;
5677 icon_changed = 0;
5678 menubar_changed = 0;
5679 modeline_changed = 0;
5680 point_changed = 0;
5681 toolbar_changed = 0;
5682 windows_changed = 0;
5683 windows_structure_changed = 0;
6572 RESET_CHANGED_SET_FLAGS; 5684 RESET_CHANGED_SET_FLAGS;
6573 5685
6574 if (faces_changed) 5686 if (faces_changed)
6575 { 5687 {
6576 mark_all_faces_as_clean (); 5688 mark_all_faces_as_clean ();
6663 5775
6664 static void 5776 static void
6665 decode_mode_spec (struct window *w, Emchar spec, int type) 5777 decode_mode_spec (struct window *w, Emchar spec, int type)
6666 { 5778 {
6667 Lisp_Object obj = Qnil; 5779 Lisp_Object obj = Qnil;
6668 const char *str = NULL; 5780 CONST char *str = NULL;
6669 struct buffer *b = XBUFFER (w->buffer); 5781 struct buffer *b = XBUFFER (w->buffer);
6670 5782
6671 Dynarr_reset (mode_spec_bufbyte_string); 5783 Dynarr_reset (mode_spec_bufbyte_string);
6672 5784
6673 switch (spec) 5785 switch (spec)
6692 char buf[32]; 5804 char buf[32];
6693 5805
6694 long_to_string (buf, col); 5806 long_to_string (buf, col);
6695 5807
6696 Dynarr_add_many (mode_spec_bufbyte_string, 5808 Dynarr_add_many (mode_spec_bufbyte_string,
6697 (const Bufbyte *) buf, strlen (buf)); 5809 (CONST Bufbyte *) buf, strlen (buf));
6698 5810
6699 goto decode_mode_spec_done; 5811 goto decode_mode_spec_done;
6700 } 5812 }
6701 /* print the file coding system */ 5813 /* print the file coding system */
6702 case 'C': 5814 case 'C':
6797 5909
6798 /* print percent of buffer above top of window, or Top, Bot or All */ 5910 /* print percent of buffer above top of window, or Top, Bot or All */
6799 case 'p': 5911 case 'p':
6800 { 5912 {
6801 Bufpos pos = marker_position (w->start[type]); 5913 Bufpos pos = marker_position (w->start[type]);
5914 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6802 5915
6803 /* This had better be while the desired lines are being done. */ 5916 /* This had better be while the desired lines are being done. */
6804 if (w->window_end_pos[type] <= BUF_Z (b) - BUF_ZV (b)) 5917 if (w->window_end_pos[type] <= BUF_Z (b) - BUF_ZV (b))
6805 { 5918 {
6806 if (pos <= BUF_BEGV (b)) 5919 if (pos <= BUF_BEGV (b))
6813 else 5926 else
6814 { 5927 {
6815 /* This hard limit is ok since the string it will hold has a 5928 /* This hard limit is ok since the string it will hold has a
6816 fixed maximum length of 3. But just to be safe... */ 5929 fixed maximum length of 3. But just to be safe... */
6817 char buf[10]; 5930 char buf[10];
6818 Charcount chars = pos - BUF_BEGV (b); 5931
6819 Charcount total = BUF_ZV (b) - BUF_BEGV (b); 5932 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
6820
6821 /* Avoid overflow on big buffers */
6822 int percent = total > LONG_MAX/200 ?
6823 (chars + total/200) / (total / 100) :
6824 (chars * 100 + total/2) / total;
6825 5933
6826 /* We can't normally display a 3-digit number, so get us a 5934 /* We can't normally display a 3-digit number, so get us a
6827 2-digit number that is close. */ 5935 2-digit number that is close. */
6828 if (percent == 100) 5936 if (total == 100)
6829 percent = 99; 5937 total = 99;
6830 5938
6831 sprintf (buf, "%d%%", percent); 5939 sprintf (buf, "%2d%%", total);
6832 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf, 5940 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6833 strlen (buf)); 5941 strlen (buf));
6834 5942
6835 goto decode_mode_spec_done; 5943 goto decode_mode_spec_done;
6836 } 5944 }
6841 Top, or print Bottom or All */ 5949 Top, or print Bottom or All */
6842 case 'P': 5950 case 'P':
6843 { 5951 {
6844 Bufpos toppos = marker_position (w->start[type]); 5952 Bufpos toppos = marker_position (w->start[type]);
6845 Bufpos botpos = BUF_Z (b) - w->window_end_pos[type]; 5953 Bufpos botpos = BUF_Z (b) - w->window_end_pos[type];
5954 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6846 5955
6847 /* botpos is only accurate as of the last redisplay, so we can 5956 /* botpos is only accurate as of the last redisplay, so we can
6848 only treat it as a hint. In particular, after erase-buffer, 5957 only treat it as a hint. In particular, after erase-buffer,
6849 botpos may be negative. */ 5958 botpos may be negative. */
6850 if (botpos < toppos) 5959 if (botpos < toppos)
6860 else 5969 else
6861 { 5970 {
6862 /* This hard limit is ok since the string it will hold has a 5971 /* This hard limit is ok since the string it will hold has a
6863 fixed maximum length of around 6. But just to be safe... */ 5972 fixed maximum length of around 6. But just to be safe... */
6864 char buf[10]; 5973 char buf[10];
6865 Charcount chars = botpos - BUF_BEGV (b); 5974
6866 Charcount total = BUF_ZV (b) - BUF_BEGV (b); 5975 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
6867
6868 /* Avoid overflow on big buffers */
6869 int percent = total > LONG_MAX/200 ?
6870 (chars + total/200) / (total / 100) :
6871 (chars * 100 + total/2) / max (total, 1);
6872 5976
6873 /* We can't normally display a 3-digit number, so get us a 5977 /* We can't normally display a 3-digit number, so get us a
6874 2-digit number that is close. */ 5978 2-digit number that is close. */
6875 if (percent == 100) 5979 if (total == 100)
6876 percent = 99; 5980 total = 99;
6877 5981
6878 if (toppos <= BUF_BEGV (b)) 5982 if (toppos <= BUF_BEGV (b))
6879 sprintf (buf, "Top%d%%", percent); 5983 sprintf (buf, "Top%2d%%", total);
6880 else 5984 else
6881 sprintf (buf, "%d%%", percent); 5985 sprintf (buf, "%2d%%", total);
6882 5986
6883 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf, 5987 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6884 strlen (buf)); 5988 strlen (buf));
6885 5989
6886 goto decode_mode_spec_done; 5990 goto decode_mode_spec_done;
6979 6083
6980 6084
6981 /* Given an array of display lines, free them and all data structures 6085 /* Given an array of display lines, free them and all data structures
6982 contained within them. */ 6086 contained within them. */
6983 6087
6984 void 6088 static void
6985 free_display_lines (display_line_dynarr *dla) 6089 free_display_lines (display_line_dynarr *dla)
6986 { 6090 {
6987 int line; 6091 int line;
6988 6092
6989 for (line = 0; line < Dynarr_largest (dla); line++) 6093 for (line = 0; line < Dynarr_largest (dla); line++)
7012 } 6116 }
7013 } 6117 }
7014 6118
7015 6119
7016 static void 6120 static void
7017 mark_glyph_block_dynarr (glyph_block_dynarr *gba) 6121 mark_glyph_block_dynarr (glyph_block_dynarr *gba, void (*markobj) (Lisp_Object))
7018 { 6122 {
7019 if (gba) 6123 if (gba)
7020 { 6124 {
7021 glyph_block *gb = Dynarr_atp (gba, 0); 6125 glyph_block *gb = Dynarr_atp (gba, 0);
7022 glyph_block *gb_last = Dynarr_atp (gba, Dynarr_length (gba)); 6126 glyph_block *gb_last = Dynarr_atp (gba, Dynarr_length (gba));
7023 6127
7024 for (; gb < gb_last; gb++) 6128 for (; gb < gb_last; gb++)
7025 { 6129 {
7026 if (!NILP (gb->glyph)) 6130 if (!NILP (gb->glyph))
7027 mark_object (gb->glyph); 6131 markobj (gb->glyph);
7028 if (!NILP (gb->extent)) 6132 if (!NILP (gb->extent))
7029 mark_object (gb->extent); 6133 markobj (gb->extent);
7030 } 6134 }
7031 } 6135 }
7032 } 6136 }
7033 6137
7034 /* See the comment in image_instantiate_cache_result as to why marking 6138 static void
7035 the glyph will also mark the image_instance. */ 6139 mark_redisplay_structs (display_line_dynarr *dla, void (*markobj) (Lisp_Object))
7036 void
7037 mark_redisplay_structs (display_line_dynarr *dla)
7038 { 6140 {
7039 display_line *dl = Dynarr_atp (dla, 0); 6141 display_line *dl = Dynarr_atp (dla, 0);
7040 display_line *dl_last = Dynarr_atp (dla, Dynarr_length (dla)); 6142 display_line *dl_last = Dynarr_atp (dla, Dynarr_length (dla));
7041 6143
7042 for (; dl < dl_last; dl++) 6144 for (; dl < dl_last; dl++)
7054 for (; r < r_last; r++) 6156 for (; r < r_last; r++)
7055 { 6157 {
7056 if (r->type == RUNE_DGLYPH) 6158 if (r->type == RUNE_DGLYPH)
7057 { 6159 {
7058 if (!NILP (r->object.dglyph.glyph)) 6160 if (!NILP (r->object.dglyph.glyph))
7059 mark_object (r->object.dglyph.glyph); 6161 markobj (r->object.dglyph.glyph);
7060 if (!NILP (r->object.dglyph.extent)) 6162 if (!NILP (r->object.dglyph.extent))
7061 mark_object (r->object.dglyph.extent); 6163 markobj (r->object.dglyph.extent);
7062 } 6164 }
7063 } 6165 }
7064 } 6166 }
7065 6167
7066 mark_glyph_block_dynarr (dl->left_glyphs); 6168 mark_glyph_block_dynarr (dl->left_glyphs, markobj);
7067 mark_glyph_block_dynarr (dl->right_glyphs); 6169 mark_glyph_block_dynarr (dl->right_glyphs, markobj);
7068 } 6170 }
7069 } 6171 }
7070 6172
7071 static void 6173 static void
7072 mark_window_mirror (struct window_mirror *mir) 6174 mark_window_mirror (struct window_mirror *mir, void (*markobj)(Lisp_Object))
7073 { 6175 {
7074 mark_redisplay_structs (mir->current_display_lines); 6176 mark_redisplay_structs (mir->current_display_lines, markobj);
7075 mark_redisplay_structs (mir->desired_display_lines); 6177 mark_redisplay_structs (mir->desired_display_lines, markobj);
7076 6178
7077 if (mir->next) 6179 if (mir->next)
7078 mark_window_mirror (mir->next); 6180 mark_window_mirror (mir->next, markobj);
7079 6181
7080 if (mir->hchild) 6182 if (mir->hchild)
7081 mark_window_mirror (mir->hchild); 6183 mark_window_mirror (mir->hchild, markobj);
7082 else if (mir->vchild) 6184 else if (mir->vchild)
7083 mark_window_mirror (mir->vchild); 6185 mark_window_mirror (mir->vchild, markobj);
7084 } 6186 }
7085 6187
7086 void 6188 void
7087 mark_redisplay (void) 6189 mark_redisplay (void (*markobj)(Lisp_Object))
7088 { 6190 {
7089 Lisp_Object frmcons, devcons, concons; 6191 Lisp_Object frmcons, devcons, concons;
7090 6192
7091 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons) 6193 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
7092 { 6194 {
7093 struct frame *f = XFRAME (XCAR (frmcons)); 6195 struct frame *f = XFRAME (XCAR (frmcons));
7094 update_frame_window_mirror (f); 6196 update_frame_window_mirror (f);
7095 mark_window_mirror (f->root_mirror); 6197 mark_window_mirror (f->root_mirror, markobj);
7096 mark_gutters (f);
7097 } 6198 }
7098 } 6199 }
7099 6200
7100 /***************************************************************************** 6201 /*****************************************************************************
7101 Line Start Cache Description and Rationale 6202 Line Start Cache Description and Rationale
7155 applicable. 6256 applicable.
7156 ****************************************************************************/ 6257 ****************************************************************************/
7157 6258
7158 /* This will get used quite a bit so we don't want to be constantly 6259 /* This will get used quite a bit so we don't want to be constantly
7159 allocating and freeing it. */ 6260 allocating and freeing it. */
7160 static line_start_cache_dynarr *internal_cache; 6261 line_start_cache_dynarr *internal_cache;
7161 6262
7162 /* Makes internal_cache represent the TYPE display structs and only 6263 /* Makes internal_cache represent the TYPE display structs and only
7163 the TYPE display structs. */ 6264 the TYPE display structs. */
7164 6265
7165 static void 6266 static void
7176 if (dl->modeline) 6277 if (dl->modeline)
7177 continue; 6278 continue;
7178 else 6279 else
7179 { 6280 {
7180 struct line_start_cache lsc; 6281 struct line_start_cache lsc;
7181 6282
7182 lsc.start = dl->bufpos; 6283 lsc.start = dl->bufpos;
7183 lsc.end = dl->end_bufpos; 6284 lsc.end = dl->end_bufpos;
7184 lsc.height = dl->ascent + dl->descent; 6285 lsc.height = dl->ascent + dl->descent;
7185 6286
7186 Dynarr_add (internal_cache, lsc); 6287 Dynarr_add (internal_cache, lsc);
7449 6550
7450 int 6551 int
7451 point_would_be_visible (struct window *w, Bufpos startp, Bufpos point) 6552 point_would_be_visible (struct window *w, Bufpos startp, Bufpos point)
7452 { 6553 {
7453 struct buffer *b = XBUFFER (w->buffer); 6554 struct buffer *b = XBUFFER (w->buffer);
7454 int pixpos = -WINDOW_TEXT_TOP_CLIP(w); 6555 int pixpos = 0;
7455 int bottom = WINDOW_TEXT_HEIGHT (w); 6556 int bottom = WINDOW_TEXT_HEIGHT (w);
7456 int start_elt; 6557 int start_elt;
7457 6558
7458 /* If point is before the intended start it obviously can't be visible. */ 6559 /* If point is before the intended start it obviously can't be visible. */
7459 if (point < startp) 6560 if (point < startp)
7528 /* For the given window W, if display starts at STARTP, what will be 6629 /* For the given window W, if display starts at STARTP, what will be
7529 the buffer position at the beginning or end of the last line 6630 the buffer position at the beginning or end of the last line
7530 displayed. The end of the last line is also know as the window end 6631 displayed. The end of the last line is also know as the window end
7531 position. 6632 position.
7532 6633
7533 WARNING: It is possible that rediplay failed to layout any lines for the
7534 windows. Under normal circumstances this is rare. However it seems that it
7535 does occur in the following situation: A mouse event has come in and we
7536 need to compute its location in a window. That code (in
7537 pixel_to_glyph_translation) already can handle 0 as an error return value.
7538
7539 #### With a little work this could probably be reworked as just a 6634 #### With a little work this could probably be reworked as just a
7540 call to start_with_line_at_pixpos. */ 6635 call to start_with_line_at_pixpos. */
7541 6636
7542 static Bufpos 6637 static Bufpos
7543 start_end_of_last_line (struct window *w, Bufpos startp, int end, 6638 start_end_of_last_line (struct window *w, Bufpos startp, int end)
7544 int may_error)
7545 { 6639 {
7546 struct buffer *b = XBUFFER (w->buffer); 6640 struct buffer *b = XBUFFER (w->buffer);
7547 line_start_cache_dynarr *cache = w->line_start_cache; 6641 line_start_cache_dynarr *cache = w->line_start_cache;
7548 int pixpos = 0; 6642 int pixpos = 0;
7549 int bottom = WINDOW_TEXT_HEIGHT (w); 6643 int bottom = WINDOW_TEXT_HEIGHT (w);
7559 startp = BUF_ZV (b); 6653 startp = BUF_ZV (b);
7560 cur_start = startp; 6654 cur_start = startp;
7561 6655
7562 start_elt = point_in_line_start_cache (w, cur_start, 0); 6656 start_elt = point_in_line_start_cache (w, cur_start, 0);
7563 if (start_elt == -1) 6657 if (start_elt == -1)
7564 return may_error ? 0 : startp; 6658 abort (); /* this had better never happen */
7565 6659
7566 while (1) 6660 while (1)
7567 { 6661 {
7568 int height = Dynarr_atp (cache, start_elt)->height; 6662 int height = Dynarr_atp (cache, start_elt)->height;
7569 6663
7623 the buffer position at the beginning of the last line displayed. */ 6717 the buffer position at the beginning of the last line displayed. */
7624 6718
7625 Bufpos 6719 Bufpos
7626 start_of_last_line (struct window *w, Bufpos startp) 6720 start_of_last_line (struct window *w, Bufpos startp)
7627 { 6721 {
7628 return start_end_of_last_line (w, startp, 0 , 0); 6722 return start_end_of_last_line (w, startp, 0);
7629 } 6723 }
7630 6724
7631 /* For the given window W, if display starts at STARTP, what will be 6725 /* For the given window W, if display starts at STARTP, what will be
7632 the buffer position at the end of the last line displayed. This is 6726 the buffer position at the end of the last line displayed. This is
7633 also know as the window end position. */ 6727 also know as the window end position. */
7634 6728
7635 Bufpos 6729 Bufpos
7636 end_of_last_line (struct window *w, Bufpos startp) 6730 end_of_last_line (struct window *w, Bufpos startp)
7637 { 6731 {
7638 return start_end_of_last_line (w, startp, 1, 0); 6732 return start_end_of_last_line (w, startp, 1);
7639 } 6733 }
7640
7641 static Bufpos
7642 end_of_last_line_may_error (struct window *w, Bufpos startp)
7643 {
7644 return start_end_of_last_line (w, startp, 1, 1);
7645 }
7646
7647 6734
7648 /* For window W, what does the starting position have to be so that 6735 /* For window W, what does the starting position have to be so that
7649 the line containing POINT will cover pixel position PIXPOS. */ 6736 the line containing POINT will cover pixel position PIXPOS. */
7650 6737
7651 Bufpos 6738 Bufpos
7688 else 6775 else
7689 return cur_pos; 6776 return cur_pos;
7690 } 6777 }
7691 6778
7692 cur_elt--; 6779 cur_elt--;
7693 while (cur_elt < 0) 6780 if (cur_elt < 0)
7694 { 6781 {
7695 Bufpos from, to; 6782 Bufpos from, to;
7696 int win_char_height; 6783 int win_char_height;
7697 6784
7698 if (cur_pos <= BUF_BEGV (b)) 6785 if (cur_pos <= BUF_BEGV (b))
7708 from = find_next_newline_no_quit (b, cur_pos, -win_char_height); 6795 from = find_next_newline_no_quit (b, cur_pos, -win_char_height);
7709 to = line_start_cache_end (w); 6796 to = line_start_cache_end (w);
7710 update_line_start_cache (w, from, to, point, 0); 6797 update_line_start_cache (w, from, to, point, 0);
7711 6798
7712 cur_elt = point_in_line_start_cache (w, cur_pos, 2) - 1; 6799 cur_elt = point_in_line_start_cache (w, cur_pos, 2) - 1;
7713 assert (cur_elt >= -1); 6800 assert (cur_elt >= 0);
7714 /* This used to be cur_elt>=0 under the assumption that if
7715 point is in the top line and not at BUF_BEGV, then
7716 setting the window_start to a newline before the start of
7717 the first line will always cause scrolling.
7718
7719 However in my (jv) opinion this is wrong. That new line
7720 can be hidden in various ways: invisible extents, an
7721 explicit window-start not at a newline character etc.
7722 The existence of those are indeed known to create crashes
7723 on that assert. So we have no option but to continue the
7724 search if we found point at the top of the line_start_cache
7725 again. */
7726 cur_pos = Dynarr_atp (w->line_start_cache,0)->start;
7727 } 6801 }
7728 prev_pos = cur_pos; 6802 prev_pos = cur_pos;
7729 } 6803 }
7730 } 6804 }
7731 6805
7826 line_start_cache_dynarr *cache = w->line_start_cache; 6900 line_start_cache_dynarr *cache = w->line_start_cache;
7827 Bufpos low_bound, high_bound; 6901 Bufpos low_bound, high_bound;
7828 6902
7829 validate_line_start_cache (w); 6903 validate_line_start_cache (w);
7830 w->line_cache_validation_override++; 6904 w->line_cache_validation_override++;
6905 updating_line_start_cache = 1;
7831 6906
7832 if (from < BUF_BEGV (b)) 6907 if (from < BUF_BEGV (b))
7833 from = BUF_BEGV (b); 6908 from = BUF_BEGV (b);
7834 if (to > BUF_ZV (b)) 6909 if (to > BUF_ZV (b))
7835 to = BUF_ZV (b); 6910 to = BUF_ZV (b);
7836 6911
7837 if (from > to) 6912 if (from > to)
7838 { 6913 {
6914 updating_line_start_cache = 0;
7839 w->line_cache_validation_override--; 6915 w->line_cache_validation_override--;
7840 return; 6916 return;
7841 } 6917 }
7842 6918
7843 if (Dynarr_length (cache)) 6919 if (Dynarr_length (cache))
7846 high_bound = line_start_cache_end (w); 6922 high_bound = line_start_cache_end (w);
7847 6923
7848 /* Check to see if the desired range is already in the cache. */ 6924 /* Check to see if the desired range is already in the cache. */
7849 if (from >= low_bound && to <= high_bound) 6925 if (from >= low_bound && to <= high_bound)
7850 { 6926 {
6927 updating_line_start_cache = 0;
7851 w->line_cache_validation_override--; 6928 w->line_cache_validation_override--;
7852 return; 6929 return;
7853 } 6930 }
7854 6931
7855 /* Check to make sure that the desired range is adjacent to the 6932 /* Check to make sure that the desired range is adjacent to the
7874 Bufpos start, end; 6951 Bufpos start, end;
7875 6952
7876 update_internal_cache_list (w, DESIRED_DISP); 6953 update_internal_cache_list (w, DESIRED_DISP);
7877 if (!Dynarr_length (internal_cache)) 6954 if (!Dynarr_length (internal_cache))
7878 { 6955 {
6956 updating_line_start_cache = 0;
7879 w->line_cache_validation_override--; 6957 w->line_cache_validation_override--;
7880 return; 6958 return;
7881 } 6959 }
7882 6960
7883 start = Dynarr_atp (internal_cache, 0)->start; 6961 start = Dynarr_atp (internal_cache, 0)->start;
7901 6979
7902 if (!Dynarr_length (cache)) 6980 if (!Dynarr_length (cache))
7903 { 6981 {
7904 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0), 6982 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7905 Dynarr_length (internal_cache)); 6983 Dynarr_length (internal_cache));
6984 updating_line_start_cache = 0;
7906 w->line_cache_validation_override--; 6985 w->line_cache_validation_override--;
7907 return; 6986 return;
7908 } 6987 }
7909 6988
7910 /* An extra check just in case the calling function didn't pass in 6989 /* An extra check just in case the calling function didn't pass in
7911 the bounds of the DESIRED structs in the first place. */ 6990 the bounds of the DESIRED structs in the first place. */
7912 if (start >= low_bound && end <= high_bound) 6991 if (start >= low_bound && end <= high_bound)
7913 { 6992 {
6993 updating_line_start_cache = 0;
7914 w->line_cache_validation_override--; 6994 w->line_cache_validation_override--;
7915 return; 6995 return;
7916 } 6996 }
7917 6997
7918 /* At this point we know that the internal cache partially overlaps 6998 /* At this point we know that the internal cache partially overlaps
7931 if (!(ic_elt >= 0)) 7011 if (!(ic_elt >= 0))
7932 { 7012 {
7933 Dynarr_reset (cache); 7013 Dynarr_reset (cache);
7934 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0), 7014 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7935 Dynarr_length (internal_cache)); 7015 Dynarr_length (internal_cache));
7016 updating_line_start_cache = 0;
7936 w->line_cache_validation_override--; 7017 w->line_cache_validation_override--;
7937 return; 7018 return;
7938 } 7019 }
7939 7020
7940 Dynarr_insert_many_at_start (cache, Dynarr_atp (internal_cache, 0), 7021 Dynarr_insert_many_at_start (cache, Dynarr_atp (internal_cache, 0),
7956 if (!(ic_elt < Dynarr_length (internal_cache))) 7037 if (!(ic_elt < Dynarr_length (internal_cache)))
7957 { 7038 {
7958 Dynarr_reset (cache); 7039 Dynarr_reset (cache);
7959 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0), 7040 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7960 Dynarr_length (internal_cache)); 7041 Dynarr_length (internal_cache));
7042 updating_line_start_cache = 0;
7961 w->line_cache_validation_override--; 7043 w->line_cache_validation_override--;
7962 return; 7044 return;
7963 } 7045 }
7964 7046
7965 Dynarr_add_many (cache, Dynarr_atp (internal_cache, ic_elt), 7047 Dynarr_add_many (cache, Dynarr_atp (internal_cache, ic_elt),
7966 Dynarr_length (internal_cache) - ic_elt); 7048 Dynarr_length (internal_cache) - ic_elt);
7967 } 7049 }
7968 7050
7051 updating_line_start_cache = 0;
7969 w->line_cache_validation_override--; 7052 w->line_cache_validation_override--;
7970 return; 7053 return;
7971 } 7054 }
7972 7055
7973 if (!Dynarr_length (cache) || from < low_bound) 7056 if (!Dynarr_length (cache) || from < low_bound)
7983 7066
7984 regenerate_window (w, startp, point, CMOTION_DISP); 7067 regenerate_window (w, startp, point, CMOTION_DISP);
7985 update_internal_cache_list (w, CMOTION_DISP); 7068 update_internal_cache_list (w, CMOTION_DISP);
7986 7069
7987 /* If this assert is triggered then regenerate_window failed 7070 /* If this assert is triggered then regenerate_window failed
7988 to layout a single line. This is not possible since we 7071 to layout a single line. That is not supposed to be
7989 force at least a single line to be layout for CMOTION_DISP */ 7072 possible because we impose a minimum height on the buffer
7990 assert (Dynarr_length (internal_cache)); 7073 and override vertical clip when we are in here. */
7074 /* #### Ah, but it is because the window may temporarily
7075 exist but not have any lines at all if the minibuffer is
7076 real big. Look into that situation better. */
7077 if (!Dynarr_length (internal_cache))
7078 {
7079 if (old_lb == -1 && low_bound == -1)
7080 {
7081 updating_line_start_cache = 0;
7082 w->line_cache_validation_override--;
7083 return;
7084 }
7085
7086 assert (Dynarr_length (internal_cache));
7087 }
7991 assert (startp == Dynarr_atp (internal_cache, 0)->start); 7088 assert (startp == Dynarr_atp (internal_cache, 0)->start);
7992 7089
7993 ic_elt = Dynarr_length (internal_cache) - 1; 7090 ic_elt = Dynarr_length (internal_cache) - 1;
7994 if (low_bound != -1) 7091 if (low_bound != -1)
7995 { 7092 {
8031 if (startp < low_bound || low_bound == -1) 7128 if (startp < low_bound || low_bound == -1)
8032 low_bound = startp; 7129 low_bound = startp;
8033 startp = new_startp; 7130 startp = new_startp;
8034 if (startp > BUF_ZV (b)) 7131 if (startp > BUF_ZV (b))
8035 { 7132 {
7133 updating_line_start_cache = 0;
8036 w->line_cache_validation_override--; 7134 w->line_cache_validation_override--;
8037 return; 7135 return;
8038 } 7136 }
8039 } 7137 }
8040 } 7138 }
8064 startp = high_bound + 1; 7162 startp = high_bound + 1;
8065 } 7163 }
8066 while (to > high_bound); 7164 while (to > high_bound);
8067 } 7165 }
8068 7166
7167 updating_line_start_cache = 0;
8069 w->line_cache_validation_override--; 7168 w->line_cache_validation_override--;
8070 assert (to <= high_bound); 7169 assert (to <= high_bound);
8071 } 7170 }
8072 7171
8073 7172
8771 /* #### This should be checked out some more to determine what 7870 /* #### This should be checked out some more to determine what
8772 should really be going on. */ 7871 should really be going on. */
8773 if (!MARKERP ((*w)->start[CURRENT_DISP])) 7872 if (!MARKERP ((*w)->start[CURRENT_DISP]))
8774 *closest = 0; 7873 *closest = 0;
8775 else 7874 else
8776 *closest = end_of_last_line_may_error (*w, 7875 *closest = end_of_last_line (*w,
8777 marker_position ((*w)->start[CURRENT_DISP])); 7876 marker_position ((*w)->start[CURRENT_DISP]));
8778 *col = 0; 7877 *col = 0;
8779 UPDATE_CACHE_RETURN; 7878 UPDATE_CACHE_RETURN;
8780 } 7879 }
8781 #undef UPDATE_CACHE_RETURN 7880 #undef UPDATE_CACHE_RETURN
8804 struct frame *f = XFRAME (XCAR (frmcons)); 7903 struct frame *f = XFRAME (XCAR (frmcons));
8805 7904
8806 if (FRAME_REPAINT_P (f) && FRAME_HAS_MINIBUF_P (f)) 7905 if (FRAME_REPAINT_P (f) && FRAME_HAS_MINIBUF_P (f))
8807 { 7906 {
8808 Lisp_Object window = FRAME_MINIBUF_WINDOW (f); 7907 Lisp_Object window = FRAME_MINIBUF_WINDOW (f);
8809
8810 MAYBE_DEVMETH (d, frame_output_begin, (f));
8811
8812 /* 7908 /*
8813 * If the frame size has changed, there may be random 7909 * If the frame size has changed, there may be random
8814 * chud on the screen left from previous messages 7910 * chud on the screen left from previous messages
8815 * because redisplay_frame hasn't been called yet. 7911 * because redisplay_frame hasn't been called yet.
8816 * Clear the screen to get rid of the potential mess. 7912 * Clear the screen to get rid of the potential mess.
8817 */ 7913 */
8818 if (f->echo_area_garbaged) 7914 if (f->echo_area_garbaged)
8819 { 7915 {
8820 MAYBE_DEVMETH (d, clear_frame, (f)); 7916 DEVMETH (d, clear_frame, (f));
8821 f->echo_area_garbaged = 0; 7917 f->echo_area_garbaged = 0;
8822 } 7918 }
8823 redisplay_window (window, 0); 7919 redisplay_window (window, 0);
8824 MAYBE_DEVMETH (d, frame_output_end, (f));
8825
8826 call_redisplay_end_triggers (XWINDOW (window), 0); 7920 call_redisplay_end_triggers (XWINDOW (window), 0);
8827 } 7921 }
8828 } 7922 }
7923
7924 /* We now call the output_end routine for tty frames. We delay
7925 doing so in order to avoid cursor flicker. So much for 100%
7926 encapsulation. */
7927 if (DEVICE_TTY_P (d))
7928 DEVMETH (d, output_end, (d));
8829 } 7929 }
8830 7930
8831 return Qnil; 7931 return Qnil;
8832 } 7932 }
8833 7933
8857 disable_preemption++; 7957 disable_preemption++;
8858 } 7958 }
8859 7959
8860 f->clear = 1; 7960 f->clear = 1;
8861 redisplay_frame (f, 1); 7961 redisplay_frame (f, 1);
8862
8863 /* See the comment in Fredisplay_frame. */
8864 RESET_CHANGED_SET_FLAGS;
8865 7962
8866 return unbind_to (count, Qnil); 7963 return unbind_to (count, Qnil);
8867 } 7964 }
8868 7965
8869 DEFUN ("redisplay-frame", Fredisplay_frame, 0, 2, 0, /* 7966 DEFUN ("redisplay-frame", Fredisplay_frame, 0, 2, 0, /*
8888 disable_preemption++; 7985 disable_preemption++;
8889 } 7986 }
8890 7987
8891 redisplay_frame (f, 1); 7988 redisplay_frame (f, 1);
8892 7989
8893 /* If we don't reset the global redisplay flafs here, subsequent
8894 changes to the display will not get registered by redisplay
8895 because it thinks it already has registered changes. If you
8896 really knew what you were doing you could confuse redisplay by
8897 calling Fredisplay_frame while updating another frame. We assume
8898 that if you know what you are doing you will not be that
8899 stupid. */
8900 RESET_CHANGED_SET_FLAGS;
8901
8902 return unbind_to (count, Qnil); 7990 return unbind_to (count, Qnil);
8903 } 7991 }
8904 7992
8905 DEFUN ("redraw-device", Fredraw_device, 0, 2, 0, /* 7993 DEFUN ("redraw-device", Fredraw_device, 0, 2, 0, /*
8906 Clear device DEVICE and output again what is supposed to appear on it. 7994 Clear device DEVICE and output again what is supposed to appear on it.
8924 8012
8925 DEVICE_FRAME_LOOP (frmcons, d) 8013 DEVICE_FRAME_LOOP (frmcons, d)
8926 { 8014 {
8927 XFRAME (XCAR (frmcons))->clear = 1; 8015 XFRAME (XCAR (frmcons))->clear = 1;
8928 } 8016 }
8929 redisplay_device (d, 0); 8017 redisplay_device (d);
8930
8931 /* See the comment in Fredisplay_frame. */
8932 RESET_CHANGED_SET_FLAGS;
8933 8018
8934 return unbind_to (count, Qnil); 8019 return unbind_to (count, Qnil);
8935 } 8020 }
8936 8021
8937 DEFUN ("redisplay-device", Fredisplay_device, 0, 2, 0, /* 8022 DEFUN ("redisplay-device", Fredisplay_device, 0, 2, 0, /*
8954 record_unwind_protect (restore_disable_preemption_value, 8039 record_unwind_protect (restore_disable_preemption_value,
8955 make_int (disable_preemption)); 8040 make_int (disable_preemption));
8956 disable_preemption++; 8041 disable_preemption++;
8957 } 8042 }
8958 8043
8959 redisplay_device (d, 0); 8044 redisplay_device (d);
8960
8961 /* See the comment in Fredisplay_frame. */
8962 RESET_CHANGED_SET_FLAGS;
8963 8045
8964 return unbind_to (count, Qnil); 8046 return unbind_to (count, Qnil);
8965 } 8047 }
8966 8048
8967 /* Big lie. Big lie. This will force all modelines to be updated 8049 /* Big lie. Big lie. This will force all modelines to be updated
9009 global_redisplay_change. */ 8091 global_redisplay_change. */
9010 MARK_CLIP_CHANGED; 8092 MARK_CLIP_CHANGED;
9011 return 0; 8093 return 0;
9012 } 8094 }
9013 8095
9014 /* This is called if the built-in glyphs have their properties
9015 changed. */
9016 void 8096 void
9017 redisplay_glyph_changed (Lisp_Object glyph, Lisp_Object property, 8097 redisplay_glyph_changed (Lisp_Object glyph, Lisp_Object property,
9018 Lisp_Object locale) 8098 Lisp_Object locale)
9019 { 8099 {
9020 if (WINDOWP (locale)) 8100 if (WINDOWP (locale))
9133 { 8213 {
9134 disable_preemption = 0; 8214 disable_preemption = 0;
9135 preemption_count = 0; 8215 preemption_count = 0;
9136 max_preempts = INIT_MAX_PREEMPTS; 8216 max_preempts = INIT_MAX_PREEMPTS;
9137 8217
9138 #ifndef PDUMP
9139 if (!initialized) 8218 if (!initialized)
9140 #endif 8219 {
9141 { 8220 cmotion_display_lines = Dynarr_new (display_line);
9142 if (!cmotion_display_lines) 8221 mode_spec_bufbyte_string = Dynarr_new (Bufbyte);
9143 cmotion_display_lines = Dynarr_new (display_line); 8222 formatted_string_emchar_dynarr = Dynarr_new (Emchar);
9144 if (!mode_spec_bufbyte_string) 8223 formatted_string_extent_dynarr = Dynarr_new (EXTENT);
9145 mode_spec_bufbyte_string = Dynarr_new (Bufbyte); 8224 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount);
9146 if (!formatted_string_extent_dynarr) 8225 formatted_string_extent_end_dynarr = Dynarr_new (Bytecount);
9147 formatted_string_extent_dynarr = Dynarr_new (EXTENT); 8226 internal_cache = Dynarr_new (line_start_cache);
9148 if (!formatted_string_extent_start_dynarr) 8227 xzero (formatted_string_display_line);
9149 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount);
9150 if (!formatted_string_extent_end_dynarr)
9151 formatted_string_extent_end_dynarr = Dynarr_new (Bytecount);
9152 if (!internal_cache)
9153 internal_cache = Dynarr_new (line_start_cache);
9154 } 8228 }
9155 8229
9156 /* window system is nil when in -batch mode */ 8230 /* window system is nil when in -batch mode */
9157 if (!initialized || noninteractive) 8231 if (!initialized || noninteractive)
9158 return; 8232 return;
9219 defsymbol (&Qpre_redisplay_hook, "pre-redisplay-hook"); 8293 defsymbol (&Qpre_redisplay_hook, "pre-redisplay-hook");
9220 defsymbol (&Qpost_redisplay_hook, "post-redisplay-hook"); 8294 defsymbol (&Qpost_redisplay_hook, "post-redisplay-hook");
9221 #endif /* INHIBIT_REDISPLAY_HOOKS */ 8295 #endif /* INHIBIT_REDISPLAY_HOOKS */
9222 defsymbol (&Qdisplay_warning_buffer, "display-warning-buffer"); 8296 defsymbol (&Qdisplay_warning_buffer, "display-warning-buffer");
9223 defsymbol (&Qbar_cursor, "bar-cursor"); 8297 defsymbol (&Qbar_cursor, "bar-cursor");
8298 defsymbol (&Qwindow_scroll_functions, "window-scroll-functions");
9224 defsymbol (&Qredisplay_end_trigger_functions, 8299 defsymbol (&Qredisplay_end_trigger_functions,
9225 "redisplay-end-trigger-functions"); 8300 "redisplay-end-trigger-functions");
9226 defsymbol (&Qtop_bottom, "top-bottom");
9227 defsymbol (&Qbuffer_list_changed_hook, "buffer-list-changed-hook");
9228 8301
9229 DEFSUBR (Fredisplay_echo_area); 8302 DEFSUBR (Fredisplay_echo_area);
9230 DEFSUBR (Fredraw_frame); 8303 DEFSUBR (Fredraw_frame);
9231 DEFSUBR (Fredisplay_frame); 8304 DEFSUBR (Fredisplay_frame);
9232 DEFSUBR (Fredraw_device); 8305 DEFSUBR (Fredraw_device);
9236 } 8309 }
9237 8310
9238 void 8311 void
9239 vars_of_redisplay (void) 8312 vars_of_redisplay (void)
9240 { 8313 {
9241
9242 #if 0 8314 #if 0
9243 staticpro (&last_arrow_position); 8315 staticpro (&last_arrow_position);
9244 staticpro (&last_arrow_string); 8316 staticpro (&last_arrow_string);
9245 last_arrow_position = Qnil; 8317 last_arrow_position = Qnil;
9246 last_arrow_string = Qnil; 8318 last_arrow_string = Qnil;
9247 #endif /* 0 */ 8319 #endif /* 0 */
8320
8321 updating_line_start_cache = 0;
9248 8322
9249 /* #### Probably temporary */ 8323 /* #### Probably temporary */
9250 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /* 8324 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /*
9251 \(Temporary) Setting this will impact the performance of the internal 8325 \(Temporary) Setting this will impact the performance of the internal
9252 line start cache. 8326 line start cache.
9280 */ , 8354 */ ,
9281 redisplay_variable_changed); 8355 redisplay_variable_changed);
9282 Voverlay_arrow_position = Qnil; 8356 Voverlay_arrow_position = Qnil;
9283 8357
9284 DEFVAR_LISP_MAGIC ("overlay-arrow-string", &Voverlay_arrow_string /* 8358 DEFVAR_LISP_MAGIC ("overlay-arrow-string", &Voverlay_arrow_string /*
9285 String or glyph to display as an arrow. See also `overlay-arrow-position'. 8359 String to display as an arrow. See also `overlay-arrow-position'.
9286 (Note that despite the name of this variable, it can be set to a glyph as
9287 well as a string.)
9288 */ , 8360 */ ,
9289 redisplay_variable_changed); 8361 redisplay_variable_changed);
9290 Voverlay_arrow_string = Qnil; 8362 Voverlay_arrow_string = Qnil;
9291 8363
9292 DEFVAR_INT ("scroll-step", &scroll_step /* 8364 DEFVAR_INT ("scroll-step", &scroll_step /*
9306 *Non-nil means truncate lines in all windows less than full frame wide. 8378 *Non-nil means truncate lines in all windows less than full frame wide.
9307 */ , 8379 */ ,
9308 redisplay_variable_changed); 8380 redisplay_variable_changed);
9309 truncate_partial_width_windows = 1; 8381 truncate_partial_width_windows = 1;
9310 8382
9311 DEFVAR_LISP ("visible-bell", &Vvisible_bell /* 8383 DEFVAR_BOOL ("visible-bell", &visible_bell /*
9312 *Non-nil substitutes a visual signal for the audible bell. 8384 *Non-nil means try to flash the frame to represent a bell.
9313
9314 Default behavior is to flash the whole screen. On some platforms,
9315 special effects are available using the following values:
9316
9317 'display Flash the whole screen (ie, the default behavior).
9318 'top-bottom Flash only the top and bottom lines of the selected frame.
9319
9320 When effects are unavailable on a platform, the visual bell is the
9321 default, whole screen. (Currently only X supports any special effects.)
9322 */ ); 8385 */ );
9323 Vvisible_bell = Qnil; 8386 visible_bell = 0;
9324 8387
9325 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter /* 8388 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter /*
9326 *Non-nil means no need to redraw entire frame after suspending. 8389 *Non-nil means no need to redraw entire frame after suspending.
9327 A non-nil value is useful if the terminal can automatically preserve 8390 A non-nil value is useful if the terminal can automatically preserve
9328 Emacs's frame display when you reenter Emacs. 8391 Emacs's frame display when you reenter Emacs.
9339 instead. 8402 instead.
9340 */ ); 8403 */ );
9341 Vwindow_system = Qnil; 8404 Vwindow_system = Qnil;
9342 8405
9343 /* #### Temporary shit until window-system is eliminated. */ 8406 /* #### Temporary shit until window-system is eliminated. */
9344 DEFVAR_CONST_LISP ("initial-window-system", &Vinitial_window_system /* 8407 DEFVAR_LISP ("initial-window-system", &Vinitial_window_system /*
9345 DON'T TOUCH 8408 DON'T TOUCH
9346 */ ); 8409 */ );
9347 Vinitial_window_system = Qnil; 8410 Vinitial_window_system = Qnil;
9348 8411
9349 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area /* 8412 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area /*
9369 Vbar_cursor = Qnil; 8432 Vbar_cursor = Qnil;
9370 8433
9371 #ifndef INHIBIT_REDISPLAY_HOOKS 8434 #ifndef INHIBIT_REDISPLAY_HOOKS
9372 xxDEFVAR_LISP ("pre-redisplay-hook", &Vpre_redisplay_hook /* 8435 xxDEFVAR_LISP ("pre-redisplay-hook", &Vpre_redisplay_hook /*
9373 Function or functions to run before every redisplay. 8436 Function or functions to run before every redisplay.
8437 Functions on this hook must be careful to avoid signalling errors!
9374 */ ); 8438 */ );
9375 Vpre_redisplay_hook = Qnil; 8439 Vpre_redisplay_hook = Qnil;
9376 8440
9377 xxDEFVAR_LISP ("post-redisplay-hook", &Vpost_redisplay_hook /* 8441 xxDEFVAR_LISP ("post-redisplay-hook", &Vpost_redisplay_hook /*
9378 Function or functions to run after every redisplay. 8442 Function or functions to run after every redisplay.
8443 Functions on this hook must be careful to avoid signalling errors!
9379 */ ); 8444 */ );
9380 Vpost_redisplay_hook = Qnil; 8445 Vpost_redisplay_hook = Qnil;
9381 #endif /* INHIBIT_REDISPLAY_HOOKS */ 8446 #endif /* INHIBIT_REDISPLAY_HOOKS */
9382
9383 DEFVAR_LISP ("buffer-list-changed-hook", &Vbuffer_list_changed_hook /*
9384 Function or functions to call when a frame's buffer list has changed.
9385 This is called during redisplay, before redisplaying each frame.
9386 Functions on this hook are called with one argument, the frame.
9387 */ );
9388 Vbuffer_list_changed_hook = Qnil;
9389 8447
9390 DEFVAR_INT ("display-warning-tick", &display_warning_tick /* 8448 DEFVAR_INT ("display-warning-tick", &display_warning_tick /*
9391 Bump this to tell the C code to call `display-warning-buffer' 8449 Bump this to tell the C code to call `display-warning-buffer'
9392 at next redisplay. You should not normally change this; the function 8450 at next redisplay. You should not normally change this; the function
9393 `display-warning' automatically does this at appropriate times. 8451 `display-warning' automatically does this at appropriate times.
9443 This is a specifier; use `set-specifier' to change it. 8501 This is a specifier; use `set-specifier' to change it.
9444 */ ); 8502 */ );
9445 Vleft_margin_width = Fmake_specifier (Qnatnum); 8503 Vleft_margin_width = Fmake_specifier (Qnatnum);
9446 set_specifier_fallback (Vleft_margin_width, list1 (Fcons (Qnil, Qzero))); 8504 set_specifier_fallback (Vleft_margin_width, list1 (Fcons (Qnil, Qzero)));
9447 set_specifier_caching (Vleft_margin_width, 8505 set_specifier_caching (Vleft_margin_width,
9448 offsetof (struct window, left_margin_width), 8506 slot_offset (struct window, left_margin_width),
9449 some_window_value_changed, 8507 some_window_value_changed,
9450 offsetof (struct frame, left_margin_width), 8508 slot_offset (struct frame, left_margin_width),
9451 margin_width_changed_in_frame); 8509 margin_width_changed_in_frame);
9452 8510
9453 DEFVAR_SPECIFIER ("right-margin-width", &Vright_margin_width /* 8511 DEFVAR_SPECIFIER ("right-margin-width", &Vright_margin_width /*
9454 *Width of right margin. 8512 *Width of right margin.
9455 This is a specifier; use `set-specifier' to change it. 8513 This is a specifier; use `set-specifier' to change it.
9456 */ ); 8514 */ );
9457 Vright_margin_width = Fmake_specifier (Qnatnum); 8515 Vright_margin_width = Fmake_specifier (Qnatnum);
9458 set_specifier_fallback (Vright_margin_width, list1 (Fcons (Qnil, Qzero))); 8516 set_specifier_fallback (Vright_margin_width, list1 (Fcons (Qnil, Qzero)));
9459 set_specifier_caching (Vright_margin_width, 8517 set_specifier_caching (Vright_margin_width,
9460 offsetof (struct window, right_margin_width), 8518 slot_offset (struct window, right_margin_width),
9461 some_window_value_changed, 8519 some_window_value_changed,
9462 offsetof (struct frame, right_margin_width), 8520 slot_offset (struct frame, right_margin_width),
9463 margin_width_changed_in_frame); 8521 margin_width_changed_in_frame);
9464 8522
9465 DEFVAR_SPECIFIER ("minimum-line-ascent", &Vminimum_line_ascent /* 8523 DEFVAR_SPECIFIER ("minimum-line-ascent", &Vminimum_line_ascent /*
9466 *Minimum ascent height of lines. 8524 *Minimum ascent height of lines.
9467 This is a specifier; use `set-specifier' to change it. 8525 This is a specifier; use `set-specifier' to change it.
9468 */ ); 8526 */ );
9469 Vminimum_line_ascent = Fmake_specifier (Qnatnum); 8527 Vminimum_line_ascent = Fmake_specifier (Qnatnum);
9470 set_specifier_fallback (Vminimum_line_ascent, list1 (Fcons (Qnil, Qzero))); 8528 set_specifier_fallback (Vminimum_line_ascent, list1 (Fcons (Qnil, Qzero)));
9471 set_specifier_caching (Vminimum_line_ascent, 8529 set_specifier_caching (Vminimum_line_ascent,
9472 offsetof (struct window, minimum_line_ascent), 8530 slot_offset (struct window, minimum_line_ascent),
9473 some_window_value_changed, 8531 some_window_value_changed,
9474 0, 0); 8532 0, 0);
9475 8533
9476 DEFVAR_SPECIFIER ("minimum-line-descent", &Vminimum_line_descent /* 8534 DEFVAR_SPECIFIER ("minimum-line-descent", &Vminimum_line_descent /*
9477 *Minimum descent height of lines. 8535 *Minimum descent height of lines.
9478 This is a specifier; use `set-specifier' to change it. 8536 This is a specifier; use `set-specifier' to change it.
9479 */ ); 8537 */ );
9480 Vminimum_line_descent = Fmake_specifier (Qnatnum); 8538 Vminimum_line_descent = Fmake_specifier (Qnatnum);
9481 set_specifier_fallback (Vminimum_line_descent, list1 (Fcons (Qnil, Qzero))); 8539 set_specifier_fallback (Vminimum_line_descent, list1 (Fcons (Qnil, Qzero)));
9482 set_specifier_caching (Vminimum_line_descent, 8540 set_specifier_caching (Vminimum_line_descent,
9483 offsetof (struct window, minimum_line_descent), 8541 slot_offset (struct window, minimum_line_descent),
9484 some_window_value_changed, 8542 some_window_value_changed,
9485 0, 0); 8543 0, 0);
9486 8544
9487 DEFVAR_SPECIFIER ("use-left-overflow", &Vuse_left_overflow /* 8545 DEFVAR_SPECIFIER ("use-left-overflow", &Vuse_left_overflow /*
9488 *Non-nil means use the left outside margin as extra whitespace when 8546 *Non-nil means use the left outside margin as extra whitespace when
9490 This is a specifier; use `set-specifier' to change it. 8548 This is a specifier; use `set-specifier' to change it.
9491 */ ); 8549 */ );
9492 Vuse_left_overflow = Fmake_specifier (Qboolean); 8550 Vuse_left_overflow = Fmake_specifier (Qboolean);
9493 set_specifier_fallback (Vuse_left_overflow, list1 (Fcons (Qnil, Qnil))); 8551 set_specifier_fallback (Vuse_left_overflow, list1 (Fcons (Qnil, Qnil)));
9494 set_specifier_caching (Vuse_left_overflow, 8552 set_specifier_caching (Vuse_left_overflow,
9495 offsetof (struct window, use_left_overflow), 8553 slot_offset (struct window, use_left_overflow),
9496 some_window_value_changed, 8554 some_window_value_changed,
9497 0, 0); 8555 0, 0);
9498 8556
9499 DEFVAR_SPECIFIER ("use-right-overflow", &Vuse_right_overflow /* 8557 DEFVAR_SPECIFIER ("use-right-overflow", &Vuse_right_overflow /*
9500 *Non-nil means use the right outside margin as extra whitespace when 8558 *Non-nil means use the right outside margin as extra whitespace when
9502 This is a specifier; use `set-specifier' to change it. 8560 This is a specifier; use `set-specifier' to change it.
9503 */ ); 8561 */ );
9504 Vuse_right_overflow = Fmake_specifier (Qboolean); 8562 Vuse_right_overflow = Fmake_specifier (Qboolean);
9505 set_specifier_fallback (Vuse_right_overflow, list1 (Fcons (Qnil, Qnil))); 8563 set_specifier_fallback (Vuse_right_overflow, list1 (Fcons (Qnil, Qnil)));
9506 set_specifier_caching (Vuse_right_overflow, 8564 set_specifier_caching (Vuse_right_overflow,
9507 offsetof (struct window, use_right_overflow), 8565 slot_offset (struct window, use_right_overflow),
9508 some_window_value_changed, 8566 some_window_value_changed,
9509 0, 0); 8567 0, 0);
9510 8568
9511 DEFVAR_SPECIFIER ("text-cursor-visible-p", &Vtext_cursor_visible_p /* 8569 DEFVAR_SPECIFIER ("text-cursor-visible-p", &Vtext_cursor_visible_p /*
9512 *Non-nil means the text cursor is visible (this is usually the case). 8570 *Non-nil means the text cursor is visible (this is usually the case).
9513 This is a specifier; use `set-specifier' to change it. 8571 This is a specifier; use `set-specifier' to change it.
9514 */ ); 8572 */ );
9515 Vtext_cursor_visible_p = Fmake_specifier (Qboolean); 8573 Vtext_cursor_visible_p = Fmake_specifier (Qboolean);
9516 set_specifier_fallback (Vtext_cursor_visible_p, list1 (Fcons (Qnil, Qt))); 8574 set_specifier_fallback (Vtext_cursor_visible_p, list1 (Fcons (Qnil, Qt)));
9517 set_specifier_caching (Vtext_cursor_visible_p, 8575 set_specifier_caching (Vtext_cursor_visible_p,
9518 offsetof (struct window, text_cursor_visible_p), 8576 slot_offset (struct window, text_cursor_visible_p),
9519 text_cursor_visible_p_changed, 8577 text_cursor_visible_p_changed,
9520 0, 0); 8578 0, 0);
9521 8579
9522 } 8580 }