Mercurial > hg > xemacs-beta
comparison src/redisplay.c @ 424:11054d720c21 r21-2-20
Import from CVS: tag r21-2-20
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:26:11 +0200 |
parents | 95016f13131a |
children |
comparison
equal
deleted
inserted
replaced
423:28d9c139be4c | 424:11054d720c21 |
---|---|
152 need to be skipped. This is used for horizontal | 152 need to be skipped. This is used for horizontal |
153 scrolling, where a certain number of columns | 153 scrolling, where a certain number of columns |
154 (those off the left side of the screen) need | 154 (those off the left side of the screen) need |
155 to be skipped before anything is displayed. */ | 155 to be skipped before anything is displayed. */ |
156 Bytind bi_start_col_enabled; | 156 Bytind bi_start_col_enabled; |
157 int start_col_xoffset; /* Number of pixels that still need to | |
158 be skipped. This is used for | |
159 horizontal scrolling of glyphs, where we want | |
160 to be able to scroll over part of the glyph. */ | |
157 | 161 |
158 int hscroll_glyph_width_adjust; /* how much the width of the hscroll | 162 int hscroll_glyph_width_adjust; /* how much the width of the hscroll |
159 glyph differs from space_width (w). | 163 glyph differs from space_width (w). |
160 0 if no hscroll glyph was used, | 164 0 if no hscroll glyph was used, |
161 i.e. the window is not scrolled | 165 i.e. the window is not scrolled |
257 static prop_block_dynarr *add_glyph_rune (pos_data *data, | 261 static prop_block_dynarr *add_glyph_rune (pos_data *data, |
258 struct glyph_block *gb, | 262 struct glyph_block *gb, |
259 int pos_type, int allow_cursor, | 263 int pos_type, int allow_cursor, |
260 struct glyph_cachel *cachel); | 264 struct glyph_cachel *cachel); |
261 static Bytind create_text_block (struct window *w, struct display_line *dl, | 265 static Bytind create_text_block (struct window *w, struct display_line *dl, |
262 Bytind bi_start_pos, int start_col, | 266 Bytind bi_start_pos, prop_block_dynarr **prop, |
263 prop_block_dynarr **prop, | |
264 int type); | 267 int type); |
265 static int create_overlay_glyph_block (struct window *w, | 268 static int create_overlay_glyph_block (struct window *w, |
266 struct display_line *dl); | 269 struct display_line *dl); |
267 static void create_left_glyph_block (struct window *w, | 270 static void create_left_glyph_block (struct window *w, |
268 struct display_line *dl, | 271 struct display_line *dl, |
273 static void decode_mode_spec (struct window *w, Emchar spec, int type); | 276 static void decode_mode_spec (struct window *w, Emchar spec, int type); |
274 static void free_display_line (struct display_line *dl); | 277 static void free_display_line (struct display_line *dl); |
275 static void update_line_start_cache (struct window *w, Bufpos from, Bufpos to, | 278 static void update_line_start_cache (struct window *w, Bufpos from, Bufpos to, |
276 Bufpos point, int no_regen); | 279 Bufpos point, int no_regen); |
277 static int point_visible (struct window *w, Bufpos point, int type); | 280 static int point_visible (struct window *w, Bufpos point, int type); |
278 extern Bytind bi_find_next_emchar_in_string (struct Lisp_String* str, Emchar target, | |
279 Bytind st, EMACS_INT count); | |
280 extern int string_column_at_point (struct Lisp_String* s, Bufpos init_pos, int tab_width); | |
281 | 281 |
282 /* This used to be 10 but 30 seems to give much better performance. */ | 282 /* This used to be 10 but 30 seems to give much better performance. */ |
283 #define INIT_MAX_PREEMPTS 30 | 283 #define INIT_MAX_PREEMPTS 30 |
284 static int max_preempts; | 284 static int max_preempts; |
285 | 285 |
300 isn't any reason we need more than a single set. */ | 300 isn't any reason we need more than a single set. */ |
301 display_line_dynarr *cmotion_display_lines; | 301 display_line_dynarr *cmotion_display_lines; |
302 | 302 |
303 /* Used by generate_formatted_string. Global because they get used so | 303 /* Used by generate_formatted_string. Global because they get used so |
304 much that the dynamic allocation time adds up. */ | 304 much that the dynamic allocation time adds up. */ |
305 Emchar_dynarr *formatted_string_emchar_dynarr; | 305 static Emchar_dynarr *formatted_string_emchar_dynarr; |
306 struct display_line formatted_string_display_line; | 306 static struct display_line formatted_string_display_line; |
307 /* We store the extents that we need to generate in a Dynarr and then | 307 /* We store the extents that we need to generate in a Dynarr and then |
308 frob them all on at the end of generating the string. We do it | 308 frob them all on at the end of generating the string. We do it |
309 this way rather than adding them as we generate the string because | 309 this way rather than adding them as we generate the string because |
310 we don't store the text into the resulting string until we're done | 310 we don't store the text into the resulting string until we're done |
311 (to avoid having to resize the string multiple times), and we don't | 311 (to avoid having to resize the string multiple times), and we don't |
312 want to go around adding extents to a string when the extents might | 312 want to go around adding extents to a string when the extents might |
313 stretch off the end of the string. */ | 313 stretch off the end of the string. */ |
314 EXTENT_dynarr *formatted_string_extent_dynarr; | 314 static EXTENT_dynarr *formatted_string_extent_dynarr; |
315 Bytecount_dynarr *formatted_string_extent_start_dynarr; | 315 static Bytecount_dynarr *formatted_string_extent_start_dynarr; |
316 Bytecount_dynarr *formatted_string_extent_end_dynarr; | 316 static Bytecount_dynarr *formatted_string_extent_end_dynarr; |
317 | 317 |
318 | 318 |
319 /* #### probably temporary */ | 319 /* #### probably temporary */ |
320 int cache_adjustment; | 320 int cache_adjustment; |
321 | 321 |
336 | 336 |
337 /* Minimum visible pixel width of clipped glyphs at right margin. */ | 337 /* Minimum visible pixel width of clipped glyphs at right margin. */ |
338 int horizontal_clip; | 338 int horizontal_clip; |
339 | 339 |
340 /* Set if currently inside update_line_start_cache. */ | 340 /* Set if currently inside update_line_start_cache. */ |
341 int updating_line_start_cache; | 341 static int updating_line_start_cache; |
342 | 342 |
343 /* Nonzero means reading single-character input with prompt | 343 /* Nonzero means reading single-character input with prompt |
344 so put cursor on minibuffer after the prompt. */ | 344 so put cursor on minibuffer after the prompt. */ |
345 int cursor_in_echo_area; | 345 int cursor_in_echo_area; |
346 Lisp_Object Qcursor_in_echo_area; | 346 Lisp_Object Qcursor_in_echo_area; |
376 /* non-zero if any displayed subwindow is in need of updating | 376 /* non-zero if any displayed subwindow is in need of updating |
377 somewhere. */ | 377 somewhere. */ |
378 int subwindows_changed; | 378 int subwindows_changed; |
379 int subwindows_changed_set; | 379 int subwindows_changed_set; |
380 | 380 |
381 /* non-zero if any displayed subwindow is in need of updating | |
382 somewhere. */ | |
383 int subwindows_state_changed; | |
384 int subwindows_state_changed_set; | |
385 | |
381 /* This variable is 1 if the icon has to be updated. | 386 /* This variable is 1 if the icon has to be updated. |
382 It is set to 1 when `frame-icon-glyph' changes. */ | 387 It is set to 1 when `frame-icon-glyph' changes. */ |
383 int icon_changed; | 388 int icon_changed; |
384 int icon_changed_set; | 389 int icon_changed_set; |
385 | 390 |
451 Lisp_Object Voverlay_arrow_position; | 456 Lisp_Object Voverlay_arrow_position; |
452 /* String to display for the arrow. */ | 457 /* String to display for the arrow. */ |
453 Lisp_Object Voverlay_arrow_string; | 458 Lisp_Object Voverlay_arrow_string; |
454 | 459 |
455 Lisp_Object Vwindow_size_change_functions; | 460 Lisp_Object Vwindow_size_change_functions; |
456 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions; | 461 Lisp_Object Vwindow_scroll_functions; |
457 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions; | 462 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions; |
458 | 463 |
459 #define INHIBIT_REDISPLAY_HOOKS /* #### Until we've thought about | 464 #define INHIBIT_REDISPLAY_HOOKS /* #### Until we've thought about |
460 this more. */ | 465 this more. */ |
461 #ifndef INHIBIT_REDISPLAY_HOOKS | 466 #ifndef INHIBIT_REDISPLAY_HOOKS |
463 Think about this for 19.14. */ | 468 Think about this for 19.14. */ |
464 Lisp_Object Vpre_redisplay_hook, Vpost_redisplay_hook; | 469 Lisp_Object Vpre_redisplay_hook, Vpost_redisplay_hook; |
465 Lisp_Object Qpre_redisplay_hook, Qpost_redisplay_hook; | 470 Lisp_Object Qpre_redisplay_hook, Qpost_redisplay_hook; |
466 #endif /* INHIBIT_REDISPLAY_HOOKS */ | 471 #endif /* INHIBIT_REDISPLAY_HOOKS */ |
467 | 472 |
468 int last_display_warning_tick, display_warning_tick; | 473 static int last_display_warning_tick, display_warning_tick; |
469 Lisp_Object Qdisplay_warning_buffer; | 474 Lisp_Object Qdisplay_warning_buffer; |
470 int inhibit_warning_display; | 475 int inhibit_warning_display; |
471 | 476 |
472 Lisp_Object Vleft_margin_width, Vright_margin_width; | 477 Lisp_Object Vleft_margin_width, Vright_margin_width; |
473 Lisp_Object Vminimum_line_ascent, Vminimum_line_descent; | 478 Lisp_Object Vminimum_line_ascent, Vminimum_line_descent; |
474 Lisp_Object Vuse_left_overflow, Vuse_right_overflow; | 479 Lisp_Object Vuse_left_overflow, Vuse_right_overflow; |
475 Lisp_Object Vtext_cursor_visible_p; | 480 Lisp_Object Vtext_cursor_visible_p; |
476 | 481 |
477 int column_number_start_at_one; | 482 int column_number_start_at_one; |
483 | |
484 #define WINDOW_SCROLLED(w) \ | |
485 (w->hscroll > 0 || w->left_xoffset) | |
486 | |
478 | 487 |
479 /***************************************************************************/ | 488 /***************************************************************************/ |
480 /* */ | 489 /* */ |
481 /* low-level interfaces onto device routines */ | 490 /* low-level interfaces onto device routines */ |
482 /* */ | 491 /* */ |
642 { | 651 { |
643 int n_pos = left_pixpos; | 652 int n_pos = left_pixpos; |
644 int pix_tab_width = tab_pix_width (w); | 653 int pix_tab_width = tab_pix_width (w); |
645 | 654 |
646 /* Adjust n_pos for any hscrolling which has happened. */ | 655 /* Adjust n_pos for any hscrolling which has happened. */ |
647 if (w->hscroll > 1) | 656 if (WINDOW_SCROLLED (w)) |
648 n_pos -= space_width (w) * (w->hscroll - 1); | 657 n_pos -= space_width (w) * (w->hscroll - 1) + w->left_xoffset; |
649 | 658 |
650 while (n_pos <= start_pixpos) | 659 while (n_pos <= start_pixpos) |
651 n_pos += pix_tab_width; | 660 n_pos += pix_tab_width; |
652 | 661 |
653 return n_pos; | 662 return n_pos; |
695 when the contents of the line reach the right boundary of the given | 704 when the contents of the line reach the right boundary of the given |
696 window. */ | 705 window. */ |
697 | 706 |
698 static Bufpos | 707 static Bufpos |
699 generate_display_line (struct window *w, struct display_line *dl, int bounds, | 708 generate_display_line (struct window *w, struct display_line *dl, int bounds, |
700 Bufpos start_pos, int start_col, | 709 Bufpos start_pos, prop_block_dynarr **prop, |
701 prop_block_dynarr **prop, | |
702 int type) | 710 int type) |
703 { | 711 { |
704 Bufpos ret_bufpos; | 712 Bufpos ret_bufpos; |
705 int overlay_width; | 713 int overlay_width; |
706 struct buffer *b = XBUFFER (WINDOW_BUFFER (w)); | 714 struct buffer *b = XBUFFER (WINDOW_BUFFER (w)); |
729 /* Create a display block for the text region of the line. */ | 737 /* Create a display block for the text region of the line. */ |
730 { | 738 { |
731 /* #### urk urk urk!!! Chuck fix this shit! */ | 739 /* #### urk urk urk!!! Chuck fix this shit! */ |
732 Bytind hacked_up_bytind = | 740 Bytind hacked_up_bytind = |
733 create_text_block (w, dl, bufpos_to_bytind (b, start_pos), | 741 create_text_block (w, dl, bufpos_to_bytind (b, start_pos), |
734 start_col, prop, type); | 742 prop, type); |
735 if (hacked_up_bytind > BI_BUF_ZV (b)) | 743 if (hacked_up_bytind > BI_BUF_ZV (b)) |
736 ret_bufpos = BUF_ZV (b) + 1; | 744 ret_bufpos = BUF_ZV (b) + 1; |
737 else | 745 else |
738 ret_bufpos = bytind_to_bufpos (b, hacked_up_bytind); | 746 ret_bufpos = bytind_to_bufpos (b, hacked_up_bytind); |
739 } | 747 } |
1546 width = glyph_width (gb->glyph, Qnil, data->findex, data->window); | 1554 width = glyph_width (gb->glyph, Qnil, data->findex, data->window); |
1547 | 1555 |
1548 if (!width) | 1556 if (!width) |
1549 return NULL; | 1557 return NULL; |
1550 | 1558 |
1551 if (data->start_col) | 1559 if (data->start_col || data->start_col_xoffset) |
1552 { | 1560 { |
1553 prop_block_dynarr *retval; | 1561 prop_block_dynarr *retval; |
1554 int glyph_char_width = width / space_width (w); | 1562 int glyph_char_width = width / space_width (w); |
1555 | 1563 |
1556 /* If we still have not fully scrolled horizontally after | 1564 /* If we still have not fully scrolled horizontally after |
1780 NOTE NOTE NOTE NOTE: This function works with and returns Bytinds. | 1788 NOTE NOTE NOTE NOTE: This function works with and returns Bytinds. |
1781 You must do appropriate conversion. */ | 1789 You must do appropriate conversion. */ |
1782 | 1790 |
1783 static Bytind | 1791 static Bytind |
1784 create_text_block (struct window *w, struct display_line *dl, | 1792 create_text_block (struct window *w, struct display_line *dl, |
1785 Bytind bi_start_pos, int start_col, | 1793 Bytind bi_start_pos, prop_block_dynarr **prop, |
1786 prop_block_dynarr **prop, | |
1787 int type) | 1794 int type) |
1788 { | 1795 { |
1789 struct frame *f = XFRAME (w->frame); | 1796 struct frame *f = XFRAME (w->frame); |
1790 struct buffer *b = XBUFFER (w->buffer); | 1797 struct buffer *b = XBUFFER (w->buffer); |
1791 struct device *d = XDEVICE (f->device); | 1798 struct device *d = XDEVICE (f->device); |
1925 else | 1932 else |
1926 data.cursor_type = NO_CURSOR; | 1933 data.cursor_type = NO_CURSOR; |
1927 data.cursor_x = -1; | 1934 data.cursor_x = -1; |
1928 | 1935 |
1929 data.start_col = w->hscroll; | 1936 data.start_col = w->hscroll; |
1937 data.start_col_xoffset = w->left_xoffset; | |
1930 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0); | 1938 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0); |
1931 data.hscroll_glyph_width_adjust = 0; | 1939 data.hscroll_glyph_width_adjust = 0; |
1932 | 1940 |
1933 /* We regenerate the line from the very beginning. */ | 1941 /* We regenerate the line from the very beginning. */ |
1934 Dynarr_reset (db->runes); | 1942 Dynarr_reset (db->runes); |
2244 that the cursor shows up properly. */ | 2252 that the cursor shows up properly. */ |
2245 data.ch = '\n'; | 2253 data.ch = '\n'; |
2246 data.blank_width = DEVMETH (d, eol_cursor_width, ()); | 2254 data.blank_width = DEVMETH (d, eol_cursor_width, ()); |
2247 data.findex = DEFAULT_INDEX; | 2255 data.findex = DEFAULT_INDEX; |
2248 data.start_col = 0; | 2256 data.start_col = 0; |
2257 data.start_col_xoffset = 0; | |
2249 data.bi_start_col_enabled = 0; | 2258 data.bi_start_col_enabled = 0; |
2250 | 2259 |
2251 add_emchar_rune (&data); | 2260 add_emchar_rune (&data); |
2252 } | 2261 } |
2253 | 2262 |
2277 int next_tab_start; | 2286 int next_tab_start; |
2278 int char_tab_width; | 2287 int char_tab_width; |
2279 int prop_width = 0; | 2288 int prop_width = 0; |
2280 | 2289 |
2281 if (data.start_col > 1) | 2290 if (data.start_col > 1) |
2282 tab_start_pixpos -= (space_width (w) * (data.start_col - 1)); | 2291 tab_start_pixpos -= (space_width (w) * (data.start_col - 1)) |
2292 + data.start_col_xoffset; | |
2283 | 2293 |
2284 next_tab_start = | 2294 next_tab_start = |
2285 next_tab_position (w, tab_start_pixpos, | 2295 next_tab_position (w, tab_start_pixpos, |
2286 dl->bounds.left_in + | 2296 dl->bounds.left_in + |
2287 data.hscroll_glyph_width_adjust); | 2297 data.hscroll_glyph_width_adjust); |
2484 | 2494 |
2485 data.ch = '\n'; | 2495 data.ch = '\n'; |
2486 data.blank_width = DEVMETH (d, eol_cursor_width, ()); | 2496 data.blank_width = DEVMETH (d, eol_cursor_width, ()); |
2487 data.findex = DEFAULT_INDEX; | 2497 data.findex = DEFAULT_INDEX; |
2488 data.start_col = 0; | 2498 data.start_col = 0; |
2499 data.start_col_xoffset = 0; | |
2489 data.bi_start_col_enabled = 0; | 2500 data.bi_start_col_enabled = 0; |
2490 | 2501 |
2491 data.max_pixpos += data.blank_width; | 2502 data.max_pixpos += data.blank_width; |
2492 add_emchar_rune (&data); | 2503 add_emchar_rune (&data); |
2493 data.max_pixpos -= data.blank_width; | 2504 data.max_pixpos -= data.blank_width; |
4232 face_index default_face) | 4243 face_index default_face) |
4233 { | 4244 { |
4234 struct frame *f = XFRAME (w->frame); | 4245 struct frame *f = XFRAME (w->frame); |
4235 /* Note that a lot of the buffer controlled stuff has been left in | 4246 /* Note that a lot of the buffer controlled stuff has been left in |
4236 because you might well want to make use of it (selective display | 4247 because you might well want to make use of it (selective display |
4237 etc), its just the buffer text that we do not use. */ | 4248 etc), its just the buffer text that we do not use. However, it |
4238 struct buffer *b = XBUFFER (w->buffer); | 4249 seems to be possible for buffer to be nil sometimes so protect |
4250 against this case. */ | |
4251 struct buffer *b = BUFFERP (w->buffer) ? XBUFFER (w->buffer) : 0; | |
4239 struct device *d = XDEVICE (f->device); | 4252 struct device *d = XDEVICE (f->device); |
4240 struct Lisp_String* s = XSTRING (disp_string); | 4253 struct Lisp_String* s = XSTRING (disp_string); |
4241 | 4254 |
4242 /* we're working with these a lot so precalculate them */ | 4255 /* we're working with these a lot so precalculate them */ |
4243 Bytecount slen = XSTRING_LENGTH (disp_string); | 4256 Bytecount slen = XSTRING_LENGTH (disp_string); |
4244 Bytecount bi_string_zv = slen; | 4257 Bytecount bi_string_zv = slen; |
4245 Bytind bi_start_pos = charcount_to_bytecount (string_data (s), start_pos); | 4258 Bytind bi_start_pos = charcount_to_bytecount (string_data (s), start_pos); |
4246 | 4259 |
4247 pos_data data; | 4260 pos_data data; |
4248 | 4261 |
4249 int truncate_win = window_truncation_on (w); | 4262 int truncate_win = b ? window_truncation_on (w) : 0; |
4250 int end_glyph_width = 0; | 4263 int end_glyph_width = 0; |
4251 | 4264 |
4252 /* we're going to ditch selective display for static text, its an | 4265 /* we're going to ditch selective display for static text, its an |
4253 FSF thing and invisble extents are the way to go | 4266 FSF thing and invisble extents are the way to go |
4254 here. Implementing it also relies on a number of buffer-specific | 4267 here. Implementing it also relies on a number of buffer-specific |
4294 | 4307 |
4295 #s(range-table data ((256 524288) (format "%x"))) | 4308 #s(range-table data ((256 524288) (format "%x"))) |
4296 | 4309 |
4297 Since more than one display table is possible, you have | 4310 Since more than one display table is possible, you have |
4298 great flexibility in mapping ranges of characters. */ | 4311 great flexibility in mapping ranges of characters. */ |
4299 Emchar printable_min = (CHAR_OR_CHAR_INTP (b->ctl_arrow) | 4312 Emchar printable_min = b ? (CHAR_OR_CHAR_INTP (b->ctl_arrow) |
4300 ? XCHAR_OR_CHAR_INT (b->ctl_arrow) | 4313 ? XCHAR_OR_CHAR_INT (b->ctl_arrow) |
4301 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil)) | 4314 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil)) |
4302 ? 255 : 160)); | 4315 ? 255 : 160)) : 255; |
4303 | 4316 |
4304 Lisp_Object face_dt, window_dt; | 4317 Lisp_Object face_dt, window_dt; |
4305 | 4318 |
4306 /* The text display block for this display line. */ | 4319 /* The text display block for this display line. */ |
4307 struct display_block *db = get_display_block_from_line (dl, TEXT); | 4320 struct display_block *db = get_display_block_from_line (dl, TEXT); |
4728 } | 4741 } |
4729 } | 4742 } |
4730 } | 4743 } |
4731 else if (data.bi_bufpos == bi_string_zv) | 4744 else if (data.bi_bufpos == bi_string_zv) |
4732 { | 4745 { |
4733 /* We need to add a marker to the end of the line since there is no | 4746 /* create_text_block () adds a bogus \n marker here which screws |
4734 newline character in order for the cursor to get drawn. We label | 4747 up subwindow display. Since we never have a cursor in the |
4735 it as a newline so that it gets handled correctly by the | 4748 gutter we can safely ignore it. */ |
4736 whitespace routines below. */ | 4749 } |
4737 | |
4738 data.ch = '\n'; | |
4739 data.blank_width = DEVMETH (d, eol_cursor_width, ()); | |
4740 data.findex = default_face; | |
4741 data.start_col = 0; | |
4742 data.bi_start_col_enabled = 0; | |
4743 | |
4744 data.max_pixpos += data.blank_width; | |
4745 add_emchar_rune (&data); | |
4746 data.max_pixpos -= data.blank_width; | |
4747 | |
4748 /* #### urk! Chuck, this shit is bad news. Going around | |
4749 manipulating invalid positions is guaranteed to result in | |
4750 trouble sooner or later. */ | |
4751 data.bi_bufpos = bi_string_zv + 1; | |
4752 } | |
4753 | |
4754 /* Calculate left whitespace boundary. */ | 4750 /* Calculate left whitespace boundary. */ |
4755 { | 4751 { |
4756 int elt = 0; | 4752 int elt = 0; |
4757 | 4753 |
4758 /* Whitespace past a newline is considered right whitespace. */ | 4754 /* Whitespace past a newline is considered right whitespace. */ |
4852 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, bi_string_zv); | 4848 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, bi_string_zv); |
4853 else | 4849 else |
4854 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, data.bi_bufpos) - 1; | 4850 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, data.bi_bufpos) - 1; |
4855 if (truncate_win) | 4851 if (truncate_win) |
4856 data.dl->num_chars = | 4852 data.dl->num_chars = |
4857 string_column_at_point (s, dl->end_bufpos, XINT (b->tab_width)); | 4853 string_column_at_point (s, dl->end_bufpos, b ? XINT (b->tab_width) : 8); |
4858 else | 4854 else |
4859 /* This doesn't correctly take into account tabs and control | 4855 /* This doesn't correctly take into account tabs and control |
4860 characters but if the window isn't being truncated then this | 4856 characters but if the window isn't being truncated then this |
4861 value isn't going to end up being used anyhow. */ | 4857 value isn't going to end up being used anyhow. */ |
4862 data.dl->num_chars = dl->end_bufpos - dl->bufpos; | 4858 data.dl->num_chars = dl->end_bufpos - dl->bufpos; |
4907 face_index default_face) | 4903 face_index default_face) |
4908 { | 4904 { |
4909 Bufpos ret_bufpos; | 4905 Bufpos ret_bufpos; |
4910 | 4906 |
4911 /* you must set bounds before calling this. */ | 4907 /* you must set bounds before calling this. */ |
4912 | 4908 |
4913 /* Reset what this line is using. */ | 4909 /* Reset what this line is using. */ |
4914 if (dl->display_blocks) | 4910 if (dl->display_blocks) |
4915 Dynarr_reset (dl->display_blocks); | 4911 Dynarr_reset (dl->display_blocks); |
4916 if (dl->left_glyphs) | 4912 if (dl->left_glyphs) |
4917 { | 4913 { |
4968 /* if there's nothing to do then do nothing. code after this assumes | 4964 /* if there's nothing to do then do nothing. code after this assumes |
4969 there is something to do. */ | 4965 there is something to do. */ |
4970 if (NILP (disp_string)) | 4966 if (NILP (disp_string)) |
4971 return; | 4967 return; |
4972 | 4968 |
4973 s_zv = XSTRING_CHAR_LENGTH (disp_string) - 1; | 4969 s_zv = XSTRING_CHAR_LENGTH (disp_string); |
4974 | 4970 |
4975 bounds.left_out = xpos; | 4971 bounds.left_out = xpos; |
4976 bounds.right_out = xpos + width; | 4972 bounds.right_out = xpos + width; |
4977 /* The inner boundaries mark where the glyph margins are located. */ | 4973 /* The inner boundaries mark where the glyph margins are located. */ |
4978 bounds.left_in = bounds.left_out + window_left_margin_width (w); | 4974 bounds.left_in = bounds.left_out + window_left_margin_width (w); |
5064 { | 5060 { |
5065 struct frame *f = XFRAME (w->frame); | 5061 struct frame *f = XFRAME (w->frame); |
5066 struct buffer *b = XBUFFER (w->buffer); | 5062 struct buffer *b = XBUFFER (w->buffer); |
5067 int ypos = WINDOW_TEXT_TOP (w); | 5063 int ypos = WINDOW_TEXT_TOP (w); |
5068 int yend; /* set farther down */ | 5064 int yend; /* set farther down */ |
5065 int yclip = WINDOW_TEXT_TOP_CLIP (w); | |
5069 | 5066 |
5070 prop_block_dynarr *prop; | 5067 prop_block_dynarr *prop; |
5071 layout_bounds bounds; | 5068 layout_bounds bounds; |
5072 display_line_dynarr *dla; | 5069 display_line_dynarr *dla; |
5073 int need_modeline; | 5070 int need_modeline; |
5138 local = 1; | 5135 local = 1; |
5139 } | 5136 } |
5140 | 5137 |
5141 dlp->bounds = bounds; | 5138 dlp->bounds = bounds; |
5142 dlp->offset = 0; | 5139 dlp->offset = 0; |
5143 start_pos = generate_display_line (w, dlp, 1, start_pos, | 5140 start_pos = generate_display_line (w, dlp, 1, start_pos, &prop, type); |
5144 w->hscroll, &prop, type); | 5141 |
5145 dlp->ypos = ypos + dlp->ascent; | 5142 if (yclip > dlp->ascent) |
5143 { | |
5144 /* this should never happen, but if it does just display the | |
5145 whole line */ | |
5146 yclip = 0; | |
5147 } | |
5148 | |
5149 dlp->ypos = (ypos + dlp->ascent) - yclip; | |
5146 ypos = dlp->ypos + dlp->descent; | 5150 ypos = dlp->ypos + dlp->descent; |
5147 | 5151 |
5152 /* See if we've been asked to start midway through a line, for | |
5153 partial display line scrolling. */ | |
5154 if (yclip) | |
5155 { | |
5156 dlp->top_clip = yclip; | |
5157 yclip = 0; | |
5158 } | |
5159 else | |
5160 dlp->top_clip = 0; | |
5161 | |
5148 if (ypos > yend) | 5162 if (ypos > yend) |
5149 { | 5163 { |
5150 int visible_height = dlp->ascent + dlp->descent; | 5164 int visible_height = dlp->ascent + dlp->descent; |
5151 | 5165 |
5152 dlp->clip = (ypos - yend); | 5166 dlp->clip = (ypos - yend); |
5153 visible_height -= dlp->clip; | 5167 /* Although this seems strange we could have a single very |
5168 tall line visible for which we need to account for both | |
5169 the top clip and the bottom clip. */ | |
5170 visible_height -= (dlp->clip + dlp->top_clip); | |
5154 | 5171 |
5155 if (visible_height < VERTICAL_CLIP (w, 1)) | 5172 if (visible_height < VERTICAL_CLIP (w, 1)) |
5156 { | 5173 { |
5157 if (local) | 5174 if (local) |
5158 free_display_line (dlp); | 5175 free_display_line (dlp); |
5391 we'll have the necessary propagation data. */ | 5408 we'll have the necessary propagation data. */ |
5392 if (line == first_line && ddl->used_prop_data) | 5409 if (line == first_line && ddl->used_prop_data) |
5393 return 0; | 5410 return 0; |
5394 | 5411 |
5395 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset, | 5412 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset, |
5396 w->hscroll, &prop, DESIRED_DISP); | 5413 &prop, DESIRED_DISP); |
5397 ddl->offset = 0; | 5414 ddl->offset = 0; |
5398 | 5415 |
5399 /* #### If there is propagated stuff the fail. We could | 5416 /* #### If there is propagated stuff the fail. We could |
5400 probably actually deal with this if the line had propagated | 5417 probably actually deal with this if the line had propagated |
5401 information when originally created by a full | 5418 information when originally created by a full |
5410 cursor has disappeared or disappeared, fail. */ | 5427 cursor has disappeared or disappeared, fail. */ |
5411 db = get_display_block_from_line (ddl, TEXT); | 5428 db = get_display_block_from_line (ddl, TEXT); |
5412 if (cdl->ypos != ddl->ypos | 5429 if (cdl->ypos != ddl->ypos |
5413 || cdl->ascent != ddl->ascent | 5430 || cdl->ascent != ddl->ascent |
5414 || cdl->descent != ddl->descent | 5431 || cdl->descent != ddl->descent |
5432 || cdl->top_clip != ddl->top_clip | |
5415 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1) | 5433 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1) |
5416 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1) | 5434 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1) |
5417 || old_start != ddl->bufpos | 5435 || old_start != ddl->bufpos |
5418 || old_end != ddl->end_bufpos | 5436 || old_end != ddl->end_bufpos |
5419 || initial_size != Dynarr_length (db->runes)) | 5437 || initial_size != Dynarr_length (db->runes)) |
5553 /* If the line was generated using propagation data, fail. */ | 5571 /* If the line was generated using propagation data, fail. */ |
5554 if (ddl->used_prop_data) | 5572 if (ddl->used_prop_data) |
5555 return 0; | 5573 return 0; |
5556 | 5574 |
5557 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset, | 5575 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset, |
5558 w->hscroll, &prop, DESIRED_DISP); | 5576 &prop, DESIRED_DISP); |
5559 ddl->offset = 0; | 5577 ddl->offset = 0; |
5560 | 5578 |
5561 /* If there is propagated stuff then it is pretty much a | 5579 /* If there is propagated stuff then it is pretty much a |
5562 guarantee that more than just the one line is affected. */ | 5580 guarantee that more than just the one line is affected. */ |
5563 if (prop) | 5581 if (prop) |
5583 /* If any line position parameters have changed or a | 5601 /* If any line position parameters have changed or a |
5584 cursor has disappeared or disappeared, fail. */ | 5602 cursor has disappeared or disappeared, fail. */ |
5585 if (cdl->ypos != ddl->ypos | 5603 if (cdl->ypos != ddl->ypos |
5586 || cdl->ascent != ddl->ascent | 5604 || cdl->ascent != ddl->ascent |
5587 || cdl->descent != ddl->descent | 5605 || cdl->descent != ddl->descent |
5606 || cdl->top_clip != ddl->top_clip | |
5588 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1) | 5607 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1) |
5589 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1)) | 5608 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1)) |
5590 { | 5609 { |
5591 return 0; | 5610 return 0; |
5592 } | 5611 } |
5875 || f->faces_changed) | 5894 || f->faces_changed) |
5876 reset_face_cachels (w); | 5895 reset_face_cachels (w); |
5877 else | 5896 else |
5878 mark_face_cachels_as_not_updated (w); | 5897 mark_face_cachels_as_not_updated (w); |
5879 | 5898 |
5880 /* Ditto the glyph cache elements. */ | 5899 /* Ditto the glyph cache elements, although we do *not* invalidate |
5900 the cache purely because glyphs have changed - this is now | |
5901 handled by the dirty flag.*/ | |
5881 if ((!echo_active && b != window_display_buffer (w)) | 5902 if ((!echo_active && b != window_display_buffer (w)) |
5882 || !Dynarr_length (w->glyph_cachels) | 5903 || !Dynarr_length (w->glyph_cachels)) |
5883 || f->glyphs_changed) | |
5884 reset_glyph_cachels (w); | 5904 reset_glyph_cachels (w); |
5885 else | 5905 else |
5886 mark_glyph_cachels_as_not_updated (w); | 5906 mark_glyph_cachels_as_not_updated (w); |
5887 | 5907 |
5888 /* If the marker's buffer is not the window's buffer, then we need | 5908 /* If the marker's buffer is not the window's buffer, then we need |
5964 && !f->clip_changed | 5984 && !f->clip_changed |
5965 && !f->extents_changed | 5985 && !f->extents_changed |
5966 && !f->faces_changed | 5986 && !f->faces_changed |
5967 && !f->glyphs_changed | 5987 && !f->glyphs_changed |
5968 && !f->subwindows_changed | 5988 && !f->subwindows_changed |
5989 && !f->subwindows_state_changed | |
5969 && !f->point_changed | 5990 && !f->point_changed |
5970 && !f->windows_structure_changed) | 5991 && !f->windows_structure_changed) |
5971 { | 5992 { |
5972 /* If not, we're done. */ | 5993 /* If not, we're done. */ |
5973 if (f->modeline_changed) | 5994 if (f->modeline_changed) |
5985 && !f->clip_changed | 6006 && !f->clip_changed |
5986 && !f->extents_changed | 6007 && !f->extents_changed |
5987 && !f->faces_changed | 6008 && !f->faces_changed |
5988 && !f->glyphs_changed | 6009 && !f->glyphs_changed |
5989 && !f->subwindows_changed | 6010 && !f->subwindows_changed |
6011 && !f->subwindows_state_changed | |
5990 && !f->windows_structure_changed) | 6012 && !f->windows_structure_changed) |
5991 { | 6013 { |
5992 if (point_visible (w, pointm, CURRENT_DISP) | 6014 if (point_visible (w, pointm, CURRENT_DISP) |
5993 && w->last_point_x[CURRENT_DISP] != -1 | 6015 && w->last_point_x[CURRENT_DISP] != -1 |
5994 && w->last_point_y[CURRENT_DISP] != -1) | 6016 && w->last_point_y[CURRENT_DISP] != -1) |
6043 else if (!w->windows_changed | 6065 else if (!w->windows_changed |
6044 && !f->clip_changed | 6066 && !f->clip_changed |
6045 && !f->faces_changed | 6067 && !f->faces_changed |
6046 && !f->glyphs_changed | 6068 && !f->glyphs_changed |
6047 && !f->subwindows_changed | 6069 && !f->subwindows_changed |
6070 && !f->subwindows_state_changed | |
6048 && !f->windows_structure_changed | 6071 && !f->windows_structure_changed |
6049 && !f->frame_changed | 6072 && !f->frame_changed |
6050 && !truncation_changed | 6073 && !truncation_changed |
6051 && pointm >= startp | 6074 && pointm >= startp |
6052 && regenerate_window_incrementally (w, startp, pointm)) | 6075 && regenerate_window_incrementally (w, startp, pointm)) |
6139 | 6162 |
6140 /* #### This should be dependent on face changes and will need to be | 6163 /* #### This should be dependent on face changes and will need to be |
6141 somewhere else once tty updates occur on a per-frame basis. */ | 6164 somewhere else once tty updates occur on a per-frame basis. */ |
6142 mark_face_cachels_as_clean (w); | 6165 mark_face_cachels_as_clean (w); |
6143 | 6166 |
6167 /* The glyph cachels only get dirty if someone changed something. */ | |
6168 if (glyphs_changed) | |
6169 mark_glyph_cachels_as_clean (w); | |
6170 | |
6144 w->windows_changed = 0; | 6171 w->windows_changed = 0; |
6145 } | 6172 } |
6146 | 6173 |
6147 /* Call buffer_reset_changes for all buffers present in any window | 6174 /* Call buffer_reset_changes for all buffers present in any window |
6148 currently visible in all frames on all devices. #### There has to | 6175 currently visible in all frames on all devices. #### There has to |
6260 the menubar's visibility. This way we avoid having flashing | 6287 the menubar's visibility. This way we avoid having flashing |
6261 caused by an Expose event generated by the visibility change | 6288 caused by an Expose event generated by the visibility change |
6262 being handled. */ | 6289 being handled. */ |
6263 update_frame_menubars (f); | 6290 update_frame_menubars (f); |
6264 #endif /* HAVE_MENUBARS */ | 6291 #endif /* HAVE_MENUBARS */ |
6265 update_frame_gutters (f); | |
6266 /* widgets are similar to menus in that they can call lisp to | 6292 /* widgets are similar to menus in that they can call lisp to |
6267 determine activation etc. Therefore update them before we get | 6293 determine activation etc. Therefore update them before we get |
6268 into redisplay. This is primarily for connected widgets such as | 6294 into redisplay. This is primarily for connected widgets such as |
6269 radio buttons. */ | 6295 radio buttons. */ |
6270 update_frame_subwindows (f); | 6296 update_frame_subwindows (f); |
6271 #ifdef HAVE_TOOLBARS | 6297 #ifdef HAVE_TOOLBARS |
6272 /* Update the toolbars. */ | 6298 /* Update the toolbars. */ |
6273 update_frame_toolbars (f); | 6299 update_frame_toolbars (f); |
6274 #endif /* HAVE_TOOLBARS */ | 6300 #endif /* HAVE_TOOLBARS */ |
6275 | 6301 |
6302 /* If we clear the frame we have to force its contents to be redrawn. */ | |
6303 if (f->clear) | |
6304 f->frame_changed = 1; | |
6305 | |
6306 /* invalidate the subwindow cache. We use subwindows_changed here to | |
6307 cause subwindows to get instantiated. This is because | |
6308 subwindows_state_changed is less strict - dealing with things | |
6309 like the clicked state of button. We have to do this before | |
6310 redisplaying the gutters as subwindows get unmapped in the | |
6311 process.*/ | |
6312 if (!Dynarr_length (f->subwindow_cachels) | |
6313 || f->subwindows_changed | |
6314 || f->frame_changed) | |
6315 { | |
6316 reset_subwindow_cachels (f); | |
6317 /* we have to do this so the gutter gets regenerated. */ | |
6318 reset_gutter_display_lines (f); | |
6319 } | |
6320 else | |
6321 mark_subwindow_cachels_as_not_updated (f); | |
6322 /* We can now update the gutters, safe in the knowledge that our | |
6323 efforts won't get undone. */ | |
6324 update_frame_gutters (f); | |
6325 | |
6276 hold_frame_size_changes (); | 6326 hold_frame_size_changes (); |
6277 | 6327 |
6278 /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */ | 6328 /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */ |
6279 /* Within this section, we are defenseless and assume that the | 6329 /* Within this section, we are defenseless and assume that the |
6280 following cannot happen: | 6330 following cannot happen: |
6297 we simply return. #### We should abort instead. | 6347 we simply return. #### We should abort instead. |
6298 | 6348 |
6299 #### If a frame-size change does occur we should probably | 6349 #### If a frame-size change does occur we should probably |
6300 actually be preempting redisplay. */ | 6350 actually be preempting redisplay. */ |
6301 | 6351 |
6302 /* If we clear the frame we have to force its contents to be redrawn. */ | |
6303 if (f->clear) | |
6304 f->frame_changed = 1; | |
6305 | |
6306 /* Erase the frame before outputting its contents. */ | 6352 /* Erase the frame before outputting its contents. */ |
6307 if (f->clear) | 6353 if (f->clear) |
6308 { | 6354 { |
6309 DEVMETH (d, clear_frame, (f)); | 6355 DEVMETH (d, clear_frame, (f)); |
6310 } | 6356 } |
6311 | |
6312 /* invalidate the subwindow cache. we are going to reuse the glyphs | |
6313 flag here to cause subwindows to get instantiated. This is | |
6314 because subwindows changed is less strict - dealing with things | |
6315 like the clicked state of button. */ | |
6316 if (!Dynarr_length (f->subwindow_cachels) | |
6317 || f->glyphs_changed | |
6318 || f->frame_changed) | |
6319 reset_subwindow_cachels (f); | |
6320 else | |
6321 mark_subwindow_cachels_as_not_updated (f); | |
6322 | 6357 |
6323 /* Do the selected window first. */ | 6358 /* Do the selected window first. */ |
6324 redisplay_window (FRAME_SELECTED_WINDOW (f), 0); | 6359 redisplay_window (FRAME_SELECTED_WINDOW (f), 0); |
6325 | 6360 |
6326 /* Then do the rest. */ | 6361 /* Then do the rest. */ |
6332 if (FRAME_TTY_P (f)) | 6367 if (FRAME_TTY_P (f)) |
6333 DEVMETH (d, output_end, (d)); | 6368 DEVMETH (d, output_end, (d)); |
6334 | 6369 |
6335 update_frame_title (f); | 6370 update_frame_title (f); |
6336 | 6371 |
6337 f->buffers_changed = 0; | 6372 CLASS_RESET_CHANGED_FLAGS (f); |
6338 f->clip_changed = 0; | |
6339 f->extents_changed = 0; | |
6340 f->faces_changed = 0; | |
6341 f->frame_changed = 0; | |
6342 f->glyphs_changed = 0; | |
6343 f->subwindows_changed = 0; | |
6344 f->icon_changed = 0; | |
6345 f->menubar_changed = 0; | |
6346 f->modeline_changed = 0; | |
6347 f->point_changed = 0; | |
6348 f->toolbar_changed = 0; | |
6349 f->gutter_changed = 0; | |
6350 f->windows_changed = 0; | |
6351 f->windows_structure_changed = 0; | |
6352 f->window_face_cache_reset = 0; | 6373 f->window_face_cache_reset = 0; |
6353 f->echo_area_garbaged = 0; | 6374 f->echo_area_garbaged = 0; |
6354 | |
6355 f->clear = 0; | 6375 f->clear = 0; |
6356 | 6376 |
6357 if (!f->size_change_pending) | 6377 if (!f->size_change_pending) |
6358 f->size_changed = 0; | 6378 f->size_changed = 0; |
6359 | 6379 |
6399 if (f->icon_changed || f->windows_changed) | 6419 if (f->icon_changed || f->windows_changed) |
6400 update_frame_icon (f); | 6420 update_frame_icon (f); |
6401 | 6421 |
6402 if (FRAME_REPAINT_P (f)) | 6422 if (FRAME_REPAINT_P (f)) |
6403 { | 6423 { |
6404 if (f->buffers_changed || f->clip_changed || f->extents_changed || | 6424 if (CLASS_REDISPLAY_FLAGS_CHANGEDP(f)) |
6405 f->faces_changed || f->frame_changed || f->menubar_changed || | |
6406 f->modeline_changed || f->point_changed || f->size_changed || | |
6407 f->toolbar_changed || f->windows_changed || f->size_slipped || | |
6408 f->windows_structure_changed || f->glyphs_changed || | |
6409 f->subwindows_changed || f->gutter_changed) | |
6410 { | 6425 { |
6411 preempted = redisplay_frame (f, 0); | 6426 preempted = redisplay_frame (f, 0); |
6412 } | 6427 } |
6413 | 6428 |
6414 if (preempted) | 6429 if (preempted) |
6434 if (f->icon_changed || f->windows_changed) | 6449 if (f->icon_changed || f->windows_changed) |
6435 update_frame_icon (f); | 6450 update_frame_icon (f); |
6436 | 6451 |
6437 if (FRAME_REPAINT_P (f)) | 6452 if (FRAME_REPAINT_P (f)) |
6438 { | 6453 { |
6439 if (f->buffers_changed || f->clip_changed || f->extents_changed || | 6454 if (CLASS_REDISPLAY_FLAGS_CHANGEDP(f) |
6440 f->faces_changed || f->frame_changed || f->menubar_changed || | 6455 || f->size_changed) |
6441 f->modeline_changed || f->point_changed || f->size_changed || | |
6442 f->toolbar_changed || f->windows_changed || | |
6443 f->windows_structure_changed || f->gutter_changed || | |
6444 f->glyphs_changed || f->subwindows_changed) | |
6445 { | 6456 { |
6446 preempted = redisplay_frame (f, 0); | 6457 preempted = redisplay_frame (f, 0); |
6447 } | 6458 } |
6448 | 6459 |
6449 if (preempted) | 6460 if (preempted) |
6454 } | 6465 } |
6455 } | 6466 } |
6456 | 6467 |
6457 /* If we get here then we redisplayed all of our frames without | 6468 /* If we get here then we redisplayed all of our frames without |
6458 getting preempted so mark ourselves as clean. */ | 6469 getting preempted so mark ourselves as clean. */ |
6459 d->buffers_changed = 0; | 6470 CLASS_RESET_CHANGED_FLAGS (d); |
6460 d->clip_changed = 0; | |
6461 d->extents_changed = 0; | |
6462 d->faces_changed = 0; | |
6463 d->frame_changed = 0; | |
6464 d->glyphs_changed = 0; | |
6465 d->subwindows_changed = 0; | |
6466 d->icon_changed = 0; | |
6467 d->menubar_changed = 0; | |
6468 d->modeline_changed = 0; | |
6469 d->point_changed = 0; | |
6470 d->toolbar_changed = 0; | |
6471 d->gutter_changed = 0; | |
6472 d->windows_changed = 0; | |
6473 d->windows_structure_changed = 0; | |
6474 | 6471 |
6475 if (!size_change_failed) | 6472 if (!size_change_failed) |
6476 d->size_changed = 0; | 6473 d->size_changed = 0; |
6477 | 6474 |
6478 return 0; | 6475 return 0; |
6503 } | 6500 } |
6504 | 6501 |
6505 if (asynch_device_change_pending) | 6502 if (asynch_device_change_pending) |
6506 handle_asynch_device_change (); | 6503 handle_asynch_device_change (); |
6507 | 6504 |
6508 if (!buffers_changed && !clip_changed && !extents_changed && | 6505 if (!GLOBAL_REDISPLAY_FLAGS_CHANGEDP && |
6509 !faces_changed && !frame_changed && !icon_changed && | 6506 !size_changed && !disable_preemption && preemption_count < max_preempts) |
6510 !menubar_changed && !modeline_changed && !point_changed && | |
6511 !size_changed && !toolbar_changed && !windows_changed && | |
6512 !glyphs_changed && !subwindows_changed && | |
6513 !gutter_changed && !windows_structure_changed && | |
6514 !disable_preemption && preemption_count < max_preempts) | |
6515 goto done; | 6507 goto done; |
6516 | 6508 |
6517 DEVICE_LOOP_NO_BREAK (devcons, concons) | 6509 DEVICE_LOOP_NO_BREAK (devcons, concons) |
6518 { | 6510 { |
6519 struct device *d = XDEVICE (XCAR (devcons)); | 6511 struct device *d = XDEVICE (XCAR (devcons)); |
6520 int preempted; | 6512 int preempted; |
6521 | 6513 |
6522 if (d->buffers_changed || d->clip_changed || d->extents_changed || | 6514 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (d) |
6523 d->faces_changed || d->frame_changed || d->icon_changed || | 6515 || d->size_changed) |
6524 d->menubar_changed || d->modeline_changed || d->point_changed || | |
6525 d->size_changed || d->toolbar_changed || d->windows_changed || | |
6526 d->windows_structure_changed || d->gutter_changed || | |
6527 d->glyphs_changed || d->subwindows_changed) | |
6528 { | 6516 { |
6529 preempted = redisplay_device (d); | 6517 preempted = redisplay_device (d); |
6530 | 6518 |
6531 if (preempted) | 6519 if (preempted) |
6532 { | 6520 { |
6541 } | 6529 } |
6542 } | 6530 } |
6543 preemption_count = 0; | 6531 preemption_count = 0; |
6544 | 6532 |
6545 /* Mark redisplay as accurate */ | 6533 /* Mark redisplay as accurate */ |
6546 buffers_changed = 0; | 6534 GLOBAL_RESET_CHANGED_FLAGS; |
6547 clip_changed = 0; | |
6548 extents_changed = 0; | |
6549 frame_changed = 0; | |
6550 glyphs_changed = 0; | |
6551 subwindows_changed = 0; | |
6552 icon_changed = 0; | |
6553 menubar_changed = 0; | |
6554 modeline_changed = 0; | |
6555 point_changed = 0; | |
6556 toolbar_changed = 0; | |
6557 gutter_changed = 0; | |
6558 windows_changed = 0; | |
6559 windows_structure_changed = 0; | |
6560 RESET_CHANGED_SET_FLAGS; | 6535 RESET_CHANGED_SET_FLAGS; |
6561 | 6536 |
6562 if (faces_changed) | 6537 if (faces_changed) |
6563 { | 6538 { |
6564 mark_all_faces_as_clean (); | 6539 mark_all_faces_as_clean (); |
6785 | 6760 |
6786 /* print percent of buffer above top of window, or Top, Bot or All */ | 6761 /* print percent of buffer above top of window, or Top, Bot or All */ |
6787 case 'p': | 6762 case 'p': |
6788 { | 6763 { |
6789 Bufpos pos = marker_position (w->start[type]); | 6764 Bufpos pos = marker_position (w->start[type]); |
6790 Charcount total = BUF_ZV (b) - BUF_BEGV (b); | |
6791 | 6765 |
6792 /* This had better be while the desired lines are being done. */ | 6766 /* This had better be while the desired lines are being done. */ |
6793 if (w->window_end_pos[type] <= BUF_Z (b) - BUF_ZV (b)) | 6767 if (w->window_end_pos[type] <= BUF_Z (b) - BUF_ZV (b)) |
6794 { | 6768 { |
6795 if (pos <= BUF_BEGV (b)) | 6769 if (pos <= BUF_BEGV (b)) |
6802 else | 6776 else |
6803 { | 6777 { |
6804 /* This hard limit is ok since the string it will hold has a | 6778 /* This hard limit is ok since the string it will hold has a |
6805 fixed maximum length of 3. But just to be safe... */ | 6779 fixed maximum length of 3. But just to be safe... */ |
6806 char buf[10]; | 6780 char buf[10]; |
6807 | 6781 Charcount chars = pos - BUF_BEGV (b); |
6808 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total; | 6782 Charcount total = BUF_ZV (b) - BUF_BEGV (b); |
6783 | |
6784 /* Avoid overflow on big buffers */ | |
6785 int percent = total > LONG_MAX/200 ? | |
6786 (chars + total/200) / (total / 100) : | |
6787 (chars * 100 + total/2) / total; | |
6809 | 6788 |
6810 /* We can't normally display a 3-digit number, so get us a | 6789 /* We can't normally display a 3-digit number, so get us a |
6811 2-digit number that is close. */ | 6790 2-digit number that is close. */ |
6812 if (total == 100) | 6791 if (percent == 100) |
6813 total = 99; | 6792 percent = 99; |
6814 | 6793 |
6815 sprintf (buf, "%2d%%", total); | 6794 sprintf (buf, "%d%%", percent); |
6816 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf, | 6795 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf, |
6817 strlen (buf)); | 6796 strlen (buf)); |
6818 | 6797 |
6819 goto decode_mode_spec_done; | 6798 goto decode_mode_spec_done; |
6820 } | 6799 } |
6825 Top, or print Bottom or All */ | 6804 Top, or print Bottom or All */ |
6826 case 'P': | 6805 case 'P': |
6827 { | 6806 { |
6828 Bufpos toppos = marker_position (w->start[type]); | 6807 Bufpos toppos = marker_position (w->start[type]); |
6829 Bufpos botpos = BUF_Z (b) - w->window_end_pos[type]; | 6808 Bufpos botpos = BUF_Z (b) - w->window_end_pos[type]; |
6830 Charcount total = BUF_ZV (b) - BUF_BEGV (b); | |
6831 | 6809 |
6832 /* botpos is only accurate as of the last redisplay, so we can | 6810 /* botpos is only accurate as of the last redisplay, so we can |
6833 only treat it as a hint. In particular, after erase-buffer, | 6811 only treat it as a hint. In particular, after erase-buffer, |
6834 botpos may be negative. */ | 6812 botpos may be negative. */ |
6835 if (botpos < toppos) | 6813 if (botpos < toppos) |
6845 else | 6823 else |
6846 { | 6824 { |
6847 /* This hard limit is ok since the string it will hold has a | 6825 /* This hard limit is ok since the string it will hold has a |
6848 fixed maximum length of around 6. But just to be safe... */ | 6826 fixed maximum length of around 6. But just to be safe... */ |
6849 char buf[10]; | 6827 char buf[10]; |
6850 | 6828 Charcount chars = botpos - BUF_BEGV (b); |
6851 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total; | 6829 Charcount total = BUF_ZV (b) - BUF_BEGV (b); |
6830 | |
6831 /* Avoid overflow on big buffers */ | |
6832 int percent = total > LONG_MAX/200 ? | |
6833 (chars + total/200) / (total / 100) : | |
6834 (chars * 100 + total/2) / max (total, 1); | |
6852 | 6835 |
6853 /* We can't normally display a 3-digit number, so get us a | 6836 /* We can't normally display a 3-digit number, so get us a |
6854 2-digit number that is close. */ | 6837 2-digit number that is close. */ |
6855 if (total == 100) | 6838 if (percent == 100) |
6856 total = 99; | 6839 percent = 99; |
6857 | 6840 |
6858 if (toppos <= BUF_BEGV (b)) | 6841 if (toppos <= BUF_BEGV (b)) |
6859 sprintf (buf, "Top%2d%%", total); | 6842 sprintf (buf, "Top%d%%", percent); |
6860 else | 6843 else |
6861 sprintf (buf, "%2d%%", total); | 6844 sprintf (buf, "%d%%", percent); |
6862 | 6845 |
6863 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf, | 6846 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf, |
6864 strlen (buf)); | 6847 strlen (buf)); |
6865 | 6848 |
6866 goto decode_mode_spec_done; | 6849 goto decode_mode_spec_done; |
6959 | 6942 |
6960 | 6943 |
6961 /* Given an array of display lines, free them and all data structures | 6944 /* Given an array of display lines, free them and all data structures |
6962 contained within them. */ | 6945 contained within them. */ |
6963 | 6946 |
6964 static void | 6947 void |
6965 free_display_lines (display_line_dynarr *dla) | 6948 free_display_lines (display_line_dynarr *dla) |
6966 { | 6949 { |
6967 int line; | 6950 int line; |
6968 | 6951 |
6969 for (line = 0; line < Dynarr_largest (dla); line++) | 6952 for (line = 0; line < Dynarr_largest (dla); line++) |
6992 } | 6975 } |
6993 } | 6976 } |
6994 | 6977 |
6995 | 6978 |
6996 static void | 6979 static void |
6997 mark_glyph_block_dynarr (glyph_block_dynarr *gba, void (*markobj) (Lisp_Object)) | 6980 mark_glyph_block_dynarr (glyph_block_dynarr *gba) |
6998 { | 6981 { |
6999 if (gba) | 6982 if (gba) |
7000 { | 6983 { |
7001 glyph_block *gb = Dynarr_atp (gba, 0); | 6984 glyph_block *gb = Dynarr_atp (gba, 0); |
7002 glyph_block *gb_last = Dynarr_atp (gba, Dynarr_length (gba)); | 6985 glyph_block *gb_last = Dynarr_atp (gba, Dynarr_length (gba)); |
7003 | 6986 |
7004 for (; gb < gb_last; gb++) | 6987 for (; gb < gb_last; gb++) |
7005 { | 6988 { |
7006 if (!NILP (gb->glyph)) | 6989 if (!NILP (gb->glyph)) |
7007 markobj (gb->glyph); | 6990 mark_object (gb->glyph); |
7008 if (!NILP (gb->extent)) | 6991 if (!NILP (gb->extent)) |
7009 markobj (gb->extent); | 6992 mark_object (gb->extent); |
7010 } | 6993 } |
7011 } | 6994 } |
7012 } | 6995 } |
7013 | 6996 |
7014 static void | 6997 static void |
7015 mark_redisplay_structs (display_line_dynarr *dla, void (*markobj) (Lisp_Object)) | 6998 mark_redisplay_structs (display_line_dynarr *dla) |
7016 { | 6999 { |
7017 display_line *dl = Dynarr_atp (dla, 0); | 7000 display_line *dl = Dynarr_atp (dla, 0); |
7018 display_line *dl_last = Dynarr_atp (dla, Dynarr_length (dla)); | 7001 display_line *dl_last = Dynarr_atp (dla, Dynarr_length (dla)); |
7019 | 7002 |
7020 for (; dl < dl_last; dl++) | 7003 for (; dl < dl_last; dl++) |
7032 for (; r < r_last; r++) | 7015 for (; r < r_last; r++) |
7033 { | 7016 { |
7034 if (r->type == RUNE_DGLYPH) | 7017 if (r->type == RUNE_DGLYPH) |
7035 { | 7018 { |
7036 if (!NILP (r->object.dglyph.glyph)) | 7019 if (!NILP (r->object.dglyph.glyph)) |
7037 markobj (r->object.dglyph.glyph); | 7020 mark_object (r->object.dglyph.glyph); |
7038 if (!NILP (r->object.dglyph.extent)) | 7021 if (!NILP (r->object.dglyph.extent)) |
7039 markobj (r->object.dglyph.extent); | 7022 mark_object (r->object.dglyph.extent); |
7040 } | 7023 } |
7041 } | 7024 } |
7042 } | 7025 } |
7043 | 7026 |
7044 mark_glyph_block_dynarr (dl->left_glyphs, markobj); | 7027 mark_glyph_block_dynarr (dl->left_glyphs); |
7045 mark_glyph_block_dynarr (dl->right_glyphs, markobj); | 7028 mark_glyph_block_dynarr (dl->right_glyphs); |
7046 } | 7029 } |
7047 } | 7030 } |
7048 | 7031 |
7049 static void | 7032 static void |
7050 mark_window_mirror (struct window_mirror *mir, void (*markobj)(Lisp_Object)) | 7033 mark_window_mirror (struct window_mirror *mir) |
7051 { | 7034 { |
7052 mark_redisplay_structs (mir->current_display_lines, markobj); | 7035 mark_redisplay_structs (mir->current_display_lines); |
7053 mark_redisplay_structs (mir->desired_display_lines, markobj); | 7036 mark_redisplay_structs (mir->desired_display_lines); |
7054 | 7037 |
7055 if (mir->next) | 7038 if (mir->next) |
7056 mark_window_mirror (mir->next, markobj); | 7039 mark_window_mirror (mir->next); |
7057 | 7040 |
7058 if (mir->hchild) | 7041 if (mir->hchild) |
7059 mark_window_mirror (mir->hchild, markobj); | 7042 mark_window_mirror (mir->hchild); |
7060 else if (mir->vchild) | 7043 else if (mir->vchild) |
7061 mark_window_mirror (mir->vchild, markobj); | 7044 mark_window_mirror (mir->vchild); |
7062 } | 7045 } |
7063 | 7046 |
7064 void | 7047 void |
7065 mark_redisplay (void (*markobj)(Lisp_Object)) | 7048 mark_redisplay (void) |
7066 { | 7049 { |
7067 Lisp_Object frmcons, devcons, concons; | 7050 Lisp_Object frmcons, devcons, concons; |
7068 | 7051 |
7069 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons) | 7052 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons) |
7070 { | 7053 { |
7071 struct frame *f = XFRAME (XCAR (frmcons)); | 7054 struct frame *f = XFRAME (XCAR (frmcons)); |
7072 update_frame_window_mirror (f); | 7055 update_frame_window_mirror (f); |
7073 mark_window_mirror (f->root_mirror, markobj); | 7056 mark_window_mirror (f->root_mirror); |
7074 } | 7057 } |
7075 } | 7058 } |
7076 | 7059 |
7077 /***************************************************************************** | 7060 /***************************************************************************** |
7078 Line Start Cache Description and Rationale | 7061 Line Start Cache Description and Rationale |
7132 applicable. | 7115 applicable. |
7133 ****************************************************************************/ | 7116 ****************************************************************************/ |
7134 | 7117 |
7135 /* This will get used quite a bit so we don't want to be constantly | 7118 /* This will get used quite a bit so we don't want to be constantly |
7136 allocating and freeing it. */ | 7119 allocating and freeing it. */ |
7137 line_start_cache_dynarr *internal_cache; | 7120 static line_start_cache_dynarr *internal_cache; |
7138 | 7121 |
7139 /* Makes internal_cache represent the TYPE display structs and only | 7122 /* Makes internal_cache represent the TYPE display structs and only |
7140 the TYPE display structs. */ | 7123 the TYPE display structs. */ |
7141 | 7124 |
7142 static void | 7125 static void |
7651 else | 7634 else |
7652 return cur_pos; | 7635 return cur_pos; |
7653 } | 7636 } |
7654 | 7637 |
7655 cur_elt--; | 7638 cur_elt--; |
7656 if (cur_elt < 0) | 7639 while (cur_elt < 0) |
7657 { | 7640 { |
7658 Bufpos from, to; | 7641 Bufpos from, to; |
7659 int win_char_height; | 7642 int win_char_height; |
7660 | 7643 |
7661 if (cur_pos <= BUF_BEGV (b)) | 7644 if (cur_pos <= BUF_BEGV (b)) |
7671 from = find_next_newline_no_quit (b, cur_pos, -win_char_height); | 7654 from = find_next_newline_no_quit (b, cur_pos, -win_char_height); |
7672 to = line_start_cache_end (w); | 7655 to = line_start_cache_end (w); |
7673 update_line_start_cache (w, from, to, point, 0); | 7656 update_line_start_cache (w, from, to, point, 0); |
7674 | 7657 |
7675 cur_elt = point_in_line_start_cache (w, cur_pos, 2) - 1; | 7658 cur_elt = point_in_line_start_cache (w, cur_pos, 2) - 1; |
7676 assert (cur_elt >= 0); | 7659 assert (cur_elt >= -1); |
7660 /* This used to be cur_elt>=0 under the assumption that if | |
7661 point is in the top line and not at BUF_BEGV, then | |
7662 setting the window_start to a newline before the start of | |
7663 the first line will always cause scrolling. | |
7664 | |
7665 However in my (jv) opinion this is wrong. That new line | |
7666 can be hidden in various ways: invisible extents, an | |
7667 explicit window-start not at a newline character etc. | |
7668 The existence of those are indeed known to create crashes | |
7669 on that assert. So we have no option but to continue the | |
7670 search if we found point at the top of the line_start_cache | |
7671 again. */ | |
7672 cur_pos = Dynarr_atp (w->line_start_cache,0)->start; | |
7677 } | 7673 } |
7678 prev_pos = cur_pos; | 7674 prev_pos = cur_pos; |
7679 } | 7675 } |
7680 } | 7676 } |
7681 | 7677 |
8967 global_redisplay_change. */ | 8963 global_redisplay_change. */ |
8968 MARK_CLIP_CHANGED; | 8964 MARK_CLIP_CHANGED; |
8969 return 0; | 8965 return 0; |
8970 } | 8966 } |
8971 | 8967 |
8968 /* This is called if the built-in glyphs have their properties | |
8969 changed. */ | |
8972 void | 8970 void |
8973 redisplay_glyph_changed (Lisp_Object glyph, Lisp_Object property, | 8971 redisplay_glyph_changed (Lisp_Object glyph, Lisp_Object property, |
8974 Lisp_Object locale) | 8972 Lisp_Object locale) |
8975 { | 8973 { |
8976 if (WINDOWP (locale)) | 8974 if (WINDOWP (locale)) |
9089 { | 9087 { |
9090 disable_preemption = 0; | 9088 disable_preemption = 0; |
9091 preemption_count = 0; | 9089 preemption_count = 0; |
9092 max_preempts = INIT_MAX_PREEMPTS; | 9090 max_preempts = INIT_MAX_PREEMPTS; |
9093 | 9091 |
9092 #ifndef PDUMP | |
9094 if (!initialized) | 9093 if (!initialized) |
9094 #endif | |
9095 { | 9095 { |
9096 cmotion_display_lines = Dynarr_new (display_line); | 9096 cmotion_display_lines = Dynarr_new (display_line); |
9097 mode_spec_bufbyte_string = Dynarr_new (Bufbyte); | 9097 mode_spec_bufbyte_string = Dynarr_new (Bufbyte); |
9098 formatted_string_emchar_dynarr = Dynarr_new (Emchar); | 9098 formatted_string_emchar_dynarr = Dynarr_new (Emchar); |
9099 formatted_string_extent_dynarr = Dynarr_new (EXTENT); | 9099 formatted_string_extent_dynarr = Dynarr_new (EXTENT); |
9169 defsymbol (&Qpre_redisplay_hook, "pre-redisplay-hook"); | 9169 defsymbol (&Qpre_redisplay_hook, "pre-redisplay-hook"); |
9170 defsymbol (&Qpost_redisplay_hook, "post-redisplay-hook"); | 9170 defsymbol (&Qpost_redisplay_hook, "post-redisplay-hook"); |
9171 #endif /* INHIBIT_REDISPLAY_HOOKS */ | 9171 #endif /* INHIBIT_REDISPLAY_HOOKS */ |
9172 defsymbol (&Qdisplay_warning_buffer, "display-warning-buffer"); | 9172 defsymbol (&Qdisplay_warning_buffer, "display-warning-buffer"); |
9173 defsymbol (&Qbar_cursor, "bar-cursor"); | 9173 defsymbol (&Qbar_cursor, "bar-cursor"); |
9174 defsymbol (&Qwindow_scroll_functions, "window-scroll-functions"); | |
9175 defsymbol (&Qredisplay_end_trigger_functions, | 9174 defsymbol (&Qredisplay_end_trigger_functions, |
9176 "redisplay-end-trigger-functions"); | 9175 "redisplay-end-trigger-functions"); |
9177 | 9176 |
9178 DEFSUBR (Fredisplay_echo_area); | 9177 DEFSUBR (Fredisplay_echo_area); |
9179 DEFSUBR (Fredraw_frame); | 9178 DEFSUBR (Fredraw_frame); |
9183 DEFSUBR (Fredraw_modeline); | 9182 DEFSUBR (Fredraw_modeline); |
9184 DEFSUBR (Fforce_cursor_redisplay); | 9183 DEFSUBR (Fforce_cursor_redisplay); |
9185 } | 9184 } |
9186 | 9185 |
9187 void | 9186 void |
9187 reinit_vars_of_redisplay (void) | |
9188 { | |
9189 updating_line_start_cache = 0; | |
9190 } | |
9191 | |
9192 void | |
9188 vars_of_redisplay (void) | 9193 vars_of_redisplay (void) |
9189 { | 9194 { |
9195 reinit_vars_of_redisplay (); | |
9196 | |
9190 #if 0 | 9197 #if 0 |
9191 staticpro (&last_arrow_position); | 9198 staticpro (&last_arrow_position); |
9192 staticpro (&last_arrow_string); | 9199 staticpro (&last_arrow_string); |
9193 last_arrow_position = Qnil; | 9200 last_arrow_position = Qnil; |
9194 last_arrow_string = Qnil; | 9201 last_arrow_string = Qnil; |
9195 #endif /* 0 */ | 9202 #endif /* 0 */ |
9196 | |
9197 updating_line_start_cache = 0; | |
9198 | 9203 |
9199 /* #### Probably temporary */ | 9204 /* #### Probably temporary */ |
9200 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /* | 9205 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /* |
9201 \(Temporary) Setting this will impact the performance of the internal | 9206 \(Temporary) Setting this will impact the performance of the internal |
9202 line start cache. | 9207 line start cache. |
9278 instead. | 9283 instead. |
9279 */ ); | 9284 */ ); |
9280 Vwindow_system = Qnil; | 9285 Vwindow_system = Qnil; |
9281 | 9286 |
9282 /* #### Temporary shit until window-system is eliminated. */ | 9287 /* #### Temporary shit until window-system is eliminated. */ |
9283 DEFVAR_LISP ("initial-window-system", &Vinitial_window_system /* | 9288 DEFVAR_CONST_LISP ("initial-window-system", &Vinitial_window_system /* |
9284 DON'T TOUCH | 9289 DON'T TOUCH |
9285 */ ); | 9290 */ ); |
9286 Vinitial_window_system = Qnil; | 9291 Vinitial_window_system = Qnil; |
9287 | 9292 |
9288 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area /* | 9293 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area /* |