Mercurial > hg > xemacs-beta
comparison src/redisplay.c @ 442:abe6d1db359e r21-2-36
Import from CVS: tag r21-2-36
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:35:02 +0200 |
parents | 8de8e3f6228a |
children | 576fb035e263 |
comparison
equal
deleted
inserted
replaced
441:72a7cfa4a488 | 442:abe6d1db359e |
---|---|
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> | |
44 | 43 |
45 #include "buffer.h" | 44 #include "buffer.h" |
46 #include "commands.h" | 45 #include "commands.h" |
47 #include "debug.h" | 46 #include "debug.h" |
48 #include "device.h" | 47 #include "device.h" |
62 #include "line-number.h" | 61 #include "line-number.h" |
63 #ifdef FILE_CODING | 62 #ifdef FILE_CODING |
64 #include "file-coding.h" | 63 #include "file-coding.h" |
65 #endif | 64 #endif |
66 | 65 |
66 #include "sysfile.h" | |
67 | |
67 #ifdef HAVE_TTY | 68 #ifdef HAVE_TTY |
68 #include "console-tty.h" | 69 #include "console-tty.h" |
69 #ifdef HAVE_UNISTD_H | |
70 #include <unistd.h> /* for isatty() */ | |
71 #endif | |
72 #endif /* HAVE_TTY */ | 70 #endif /* HAVE_TTY */ |
73 | 71 |
74 /* Note: We have to be careful throughout this code to properly handle | 72 /* Note: We have to be careful throughout this code to properly handle |
75 and differentiate between Bufbytes and Emchars. | 73 and differentiate between Bufbytes and Emchars. |
76 | 74 |
85 #define BEGIN_GLYPHS 0 | 83 #define BEGIN_GLYPHS 0 |
86 #define END_GLYPHS 1 | 84 #define END_GLYPHS 1 |
87 #define LEFT_GLYPHS 2 | 85 #define LEFT_GLYPHS 2 |
88 #define RIGHT_GLYPHS 3 | 86 #define RIGHT_GLYPHS 3 |
89 | 87 |
90 /* Set the vertical clip to 0 if we are currently updating the line | |
91 start cache. Otherwise for buffers of line height 1 it may fail to | |
92 be able to work properly because regenerate_window will not layout | |
93 a single line. */ | |
94 #define VERTICAL_CLIP(w, display) \ | 88 #define VERTICAL_CLIP(w, display) \ |
95 (updating_line_start_cache \ | 89 ((WINDOW_TTY_P (w) | (!display && scroll_on_clipped_lines)) \ |
96 ? 0 \ | |
97 : ((WINDOW_TTY_P (w) | (!display && scroll_on_clipped_lines)) \ | |
98 ? INT_MAX \ | 90 ? INT_MAX \ |
99 : vertical_clip)) | 91 : vertical_clip) |
100 | 92 |
101 /* The following structures are completely private to redisplay.c so | 93 /* The following structures are completely private to redisplay.c so |
102 we put them here instead of in a header file, for modularity. */ | 94 we put them here instead of in a header file, for modularity. */ |
103 | 95 |
104 /* NOTE: Bytinds not Bufpos's in this structure. */ | 96 /* NOTE: Bytinds not Bufpos's in this structure. */ |
326 int vertical_clip; | 318 int vertical_clip; |
327 | 319 |
328 /* Minimum visible pixel width of clipped glyphs at right margin. */ | 320 /* Minimum visible pixel width of clipped glyphs at right margin. */ |
329 int horizontal_clip; | 321 int horizontal_clip; |
330 | 322 |
331 /* Set if currently inside update_line_start_cache. */ | |
332 static int updating_line_start_cache; | |
333 | |
334 /* Nonzero means reading single-character input with prompt | 323 /* Nonzero means reading single-character input with prompt |
335 so put cursor on minibuffer after the prompt. */ | 324 so put cursor on minibuffer after the prompt. */ |
336 int cursor_in_echo_area; | 325 int cursor_in_echo_area; |
337 Lisp_Object Qcursor_in_echo_area; | 326 Lisp_Object Qcursor_in_echo_area; |
338 | 327 |
362 hscroll, control-arrow, etc) is in need of updating | 351 hscroll, control-arrow, etc) is in need of updating |
363 somewhere. */ | 352 somewhere. */ |
364 int glyphs_changed; | 353 int glyphs_changed; |
365 int glyphs_changed_set; | 354 int glyphs_changed_set; |
366 | 355 |
367 /* non-zero if any displayed subwindow is in need of updating | 356 /* non-zero if any subwindow has been deleted. */ |
368 somewhere. */ | |
369 int subwindows_changed; | 357 int subwindows_changed; |
370 int subwindows_changed_set; | 358 int subwindows_changed_set; |
371 | 359 |
372 /* non-zero if any displayed subwindow is in need of updating | 360 /* non-zero if any displayed subwindow is in need of updating |
373 somewhere. */ | 361 somewhere. */ |
417 | 405 |
418 /* If non-nil, use vertical bar cursor. */ | 406 /* If non-nil, use vertical bar cursor. */ |
419 Lisp_Object Vbar_cursor; | 407 Lisp_Object Vbar_cursor; |
420 Lisp_Object Qbar_cursor; | 408 Lisp_Object Qbar_cursor; |
421 | 409 |
422 int visible_bell; /* If true and the terminal will support it | 410 Lisp_Object Vvisible_bell; /* If true and the terminal will support it |
423 then the frame will flash instead of | 411 then the frame will flash instead of |
424 beeping when an error occurs */ | 412 beeping when an error occurs */ |
425 | 413 |
426 /* Nonzero means no need to redraw the entire frame on resuming | 414 /* Nonzero means no need to redraw the entire frame on resuming |
427 a suspended Emacs. This is useful on terminals with multiple pages, | 415 a suspended Emacs. This is useful on terminals with multiple pages, |
428 where one page is used for Emacs and another for all else. */ | 416 where one page is used for Emacs and another for all else. */ |
429 int no_redraw_on_reenter; | 417 int no_redraw_on_reenter; |
448 Lisp_Object Voverlay_arrow_string; | 436 Lisp_Object Voverlay_arrow_string; |
449 | 437 |
450 Lisp_Object Vwindow_size_change_functions; | 438 Lisp_Object Vwindow_size_change_functions; |
451 Lisp_Object Vwindow_scroll_functions; | 439 Lisp_Object Vwindow_scroll_functions; |
452 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions; | 440 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions; |
441 | |
442 Lisp_Object Qbuffer_list_changed_hook, Vbuffer_list_changed_hook; | |
443 | |
453 | 444 |
454 #define INHIBIT_REDISPLAY_HOOKS /* #### Until we've thought about | 445 #define INHIBIT_REDISPLAY_HOOKS /* #### Until we've thought about |
455 this more. */ | 446 this more. */ |
456 #ifndef INHIBIT_REDISPLAY_HOOKS | 447 #ifndef INHIBIT_REDISPLAY_HOOKS |
457 /* #### Chuck says: I think this needs more thought. | 448 /* #### Chuck says: I think this needs more thought. |
468 Lisp_Object Vminimum_line_ascent, Vminimum_line_descent; | 459 Lisp_Object Vminimum_line_ascent, Vminimum_line_descent; |
469 Lisp_Object Vuse_left_overflow, Vuse_right_overflow; | 460 Lisp_Object Vuse_left_overflow, Vuse_right_overflow; |
470 Lisp_Object Vtext_cursor_visible_p; | 461 Lisp_Object Vtext_cursor_visible_p; |
471 | 462 |
472 int column_number_start_at_one; | 463 int column_number_start_at_one; |
464 | |
465 Lisp_Object Qtop_bottom; | |
473 | 466 |
474 #define WINDOW_SCROLLED(w) \ | 467 #define WINDOW_SCROLLED(w) \ |
475 (w->hscroll > 0 || w->left_xoffset) | 468 (w->hscroll > 0 || w->left_xoffset) |
476 | 469 |
477 | 470 |
801 | 794 |
802 gb.extent = Qnil; | 795 gb.extent = Qnil; |
803 gb.glyph = Vhscroll_glyph; | 796 gb.glyph = Vhscroll_glyph; |
804 { | 797 { |
805 int oldpixpos = data->pixpos; | 798 int oldpixpos = data->pixpos; |
806 retval = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1, | 799 retval = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, |
807 GLYPH_CACHEL (XWINDOW (data->window), | 800 GLYPH_CACHEL (XWINDOW (data->window), |
808 HSCROLL_GLYPH_INDEX)); | 801 HSCROLL_GLYPH_INDEX)); |
809 data->hscroll_glyph_width_adjust = | 802 data->hscroll_glyph_width_adjust = |
810 data->pixpos - oldpixpos - space_width (XWINDOW (data->window)); | 803 data->pixpos - oldpixpos - space_width (XWINDOW (data->window)); |
811 } | 804 } |
921 bytecount_to_charcount (XSTRING_DATA (data->string), data->bi_bufpos); | 914 bytecount_to_charcount (XSTRING_DATA (data->string), data->bi_bufpos); |
922 } | 915 } |
923 else if (data->is_modeline) | 916 else if (data->is_modeline) |
924 crb->bufpos = data->modeline_charpos; | 917 crb->bufpos = data->modeline_charpos; |
925 else | 918 else |
926 /* fuckme if this shouldn't be an abort. */ | 919 /* Text but not in buffer */ |
927 /* abort (); fuckme harder, this abort gets tripped quite often, | |
928 in propagation and whatnot. #### fixme */ | |
929 crb->bufpos = 0; | 920 crb->bufpos = 0; |
930 crb->type = RUNE_CHAR; | 921 crb->type = RUNE_CHAR; |
931 crb->object.chr.ch = data->font_is_bogus ? '~' : data->ch; | 922 crb->object.chr.ch = data->font_is_bogus ? '~' : data->ch; |
932 crb->endpos = 0; | 923 crb->endpos = 0; |
933 | 924 |
1318 dst += long_to_string_base ((char *)dst, data->ch, 16); | 1309 dst += long_to_string_base ((char *)dst, data->ch, 16); |
1319 break;*/ | 1310 break;*/ |
1320 case '%': | 1311 case '%': |
1321 dst += set_charptr_emchar (dst, '%'); | 1312 dst += set_charptr_emchar (dst, '%'); |
1322 break; | 1313 break; |
1314 /* #### unimplemented */ | |
1323 } | 1315 } |
1324 } | 1316 } |
1325 } | 1317 } |
1326 prop = add_bufbyte_string_runes (data, result, dst - result, 0); | 1318 prop = add_bufbyte_string_runes (data, result, dst - result, 0); |
1327 } | 1319 } |
1526 | 1518 |
1527 /* If window faces changed, and glyph instance is text, then | 1519 /* If window faces changed, and glyph instance is text, then |
1528 glyph sizes might have changed too */ | 1520 glyph sizes might have changed too */ |
1529 invalidate_glyph_geometry_maybe (gb->glyph, w); | 1521 invalidate_glyph_geometry_maybe (gb->glyph, w); |
1530 | 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). */ | 1531 /* A nil extent indicates a special glyph (ex. truncator). */ |
1532 if (NILP (gb->extent) | 1532 if (NILP (gb->extent) |
1533 || (pos_type == BEGIN_GLYPHS && | 1533 || (pos_type == BEGIN_GLYPHS && |
1534 extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT) | 1534 extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT) |
1535 || (pos_type == END_GLYPHS && | 1535 || (pos_type == END_GLYPHS && |
1536 extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)) | 1536 extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT) |
1537 || pos_type == LEFT_GLYPHS || pos_type == RIGHT_GLYPHS) | |
1537 { | 1538 { |
1538 struct rune rb; | 1539 struct rune rb; |
1539 int width; | 1540 int width; |
1540 int xoffset = 0; | 1541 int xoffset = 0; |
1541 int ascent, descent; | 1542 int ascent, descent; |
1542 Lisp_Object baseline; | 1543 Lisp_Object baseline; |
1543 Lisp_Object face; | 1544 Lisp_Object face; |
1545 Lisp_Object instance; | |
1546 face_index findex; | |
1544 | 1547 |
1545 if (cachel) | 1548 if (cachel) |
1546 width = cachel->width; | 1549 width = cachel->width; |
1547 else | 1550 else |
1548 width = glyph_width (gb->glyph, data->window); | 1551 width = glyph_width (gb->glyph, data->window); |
1650 abort (); | 1653 abort (); |
1651 } | 1654 } |
1652 | 1655 |
1653 face = glyph_face (gb->glyph, data->window); | 1656 face = glyph_face (gb->glyph, data->window); |
1654 if (NILP (face)) | 1657 if (NILP (face)) |
1655 rb.findex = data->findex; | 1658 findex = data->findex; |
1656 else | 1659 else |
1657 rb.findex = get_builtin_face_cache_index (w, face); | 1660 findex = get_builtin_face_cache_index (w, face); |
1658 | 1661 |
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; | |
1659 rb.xpos = data->pixpos; | 1684 rb.xpos = data->pixpos; |
1660 rb.width = width; | 1685 rb.width = width; |
1661 rb.bufpos = 0; /* glyphs are never "at" anywhere */ | 1686 rb.bufpos = 0; /* glyphs are never "at" anywhere */ |
1662 if (data->bi_endpos) | 1687 if (data->bi_endpos) |
1663 /* #### is this necessary at all? */ | 1688 /* #### is this necessary at all? */ |
1664 rb.endpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)), | 1689 rb.endpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)), |
1665 data->bi_endpos); | 1690 data->bi_endpos); |
1666 else | 1691 else |
1667 rb.endpos = 0; | 1692 rb.endpos = 0; |
1668 rb.type = RUNE_DGLYPH; | 1693 rb.type = RUNE_DGLYPH; |
1669 /* #### Ben sez: this is way bogus if the glyph is a string. | |
1670 You should not make the output routines have to cope with | |
1671 this. The string could contain Mule characters, or non- | |
1672 printable characters, or characters to be passed through | |
1673 the display table, or non-character objects (when this gets | |
1674 implemented), etc. Instead, this routine here should parse | |
1675 the string into a series of runes. */ | |
1676 rb.object.dglyph.glyph = gb->glyph; | 1694 rb.object.dglyph.glyph = gb->glyph; |
1677 rb.object.dglyph.extent = gb->extent; | 1695 rb.object.dglyph.extent = gb->extent; |
1678 rb.object.dglyph.xoffset = xoffset; | 1696 rb.object.dglyph.xoffset = xoffset; |
1679 | 1697 |
1680 if (allow_cursor) | 1698 if (allow_cursor) |
1873 Lisp_Object synch_minibuffers_value = | 1891 Lisp_Object synch_minibuffers_value = |
1874 symbol_value_in_buffer (Qsynchronize_minibuffers, w->buffer); | 1892 symbol_value_in_buffer (Qsynchronize_minibuffers, w->buffer); |
1875 | 1893 |
1876 dl->used_prop_data = 0; | 1894 dl->used_prop_data = 0; |
1877 dl->num_chars = 0; | 1895 dl->num_chars = 0; |
1896 dl->line_continuation = 0; | |
1878 | 1897 |
1879 xzero (data); | 1898 xzero (data); |
1880 data.ef = extent_fragment_new (w->buffer, f); | 1899 data.ef = extent_fragment_new (w->buffer, f); |
1881 | 1900 |
1882 /* These values are used by all of the rune addition routines. We add | 1901 /* These values are used by all of the rune addition routines. We add |
2463 /* The cursor can never be on the continuation glyph. */ | 2482 /* The cursor can never be on the continuation glyph. */ |
2464 data.cursor_type = NO_CURSOR; | 2483 data.cursor_type = NO_CURSOR; |
2465 | 2484 |
2466 /* data.bi_bufpos is already at the start of the next line. */ | 2485 /* data.bi_bufpos is already at the start of the next line. */ |
2467 | 2486 |
2487 dl->line_continuation = 1; | |
2468 gb.glyph = Vcontinuation_glyph; | 2488 gb.glyph = Vcontinuation_glyph; |
2469 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX); | 2489 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX); |
2470 } | 2490 } |
2471 | 2491 |
2472 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 1, cachel); | 2492 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel); |
2473 | 2493 |
2474 if (truncate_win && data.bi_bufpos == BI_BUF_ZV (b) | 2494 if (truncate_win && data.bi_bufpos == BI_BUF_ZV (b) |
2475 && BI_BUF_FETCH_CHAR (b, prev_bytind (b, BI_BUF_ZV (b))) != '\n') | 2495 && BI_BUF_FETCH_CHAR (b, prev_bytind (b, BI_BUF_ZV (b))) != '\n') |
2476 /* #### Damn this losing shit. */ | 2496 /* #### Damn this losing shit. */ |
2477 data.bi_bufpos++; | 2497 data.bi_bufpos++; |
2715 { | 2735 { |
2716 glyph_block_dynarr *gbd = (side == LEFT_GLYPHS | 2736 glyph_block_dynarr *gbd = (side == LEFT_GLYPHS |
2717 ? dl->left_glyphs | 2737 ? dl->left_glyphs |
2718 : dl->right_glyphs); | 2738 : dl->right_glyphs); |
2719 int elt, end; | 2739 int elt, end; |
2720 int xpos = start; | |
2721 int reverse; | 2740 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; | |
2722 | 2760 |
2723 if ((layout == GL_WHITESPACE && side == LEFT_GLYPHS) | 2761 if ((layout == GL_WHITESPACE && side == LEFT_GLYPHS) |
2724 || (layout == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS)) | 2762 || (layout == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS)) |
2725 { | 2763 { |
2726 reverse = 1; | 2764 reverse = 1; |
2745 ((side == LEFT_GLYPHS && | 2783 ((side == LEFT_GLYPHS && |
2746 extent_begin_glyph_layout (XEXTENT (gb->extent)) == layout) | 2784 extent_begin_glyph_layout (XEXTENT (gb->extent)) == layout) |
2747 || (side == RIGHT_GLYPHS && | 2785 || (side == RIGHT_GLYPHS && |
2748 extent_end_glyph_layout (XEXTENT (gb->extent)) == layout))) | 2786 extent_end_glyph_layout (XEXTENT (gb->extent)) == layout))) |
2749 { | 2787 { |
2750 struct rune rb; | 2788 data.findex = gb->findex; |
2751 | 2789 data.max_pixpos = data.pixpos + gb->width; |
2752 rb.width = gb->width; | 2790 add_glyph_rune (&data, gb, side, 0, NULL); |
2753 rb.findex = gb->findex; | |
2754 rb.xpos = xpos; | |
2755 rb.bufpos = -1; | |
2756 rb.endpos = 0; | |
2757 rb.type = RUNE_DGLYPH; | |
2758 rb.object.dglyph.glyph = gb->glyph; | |
2759 rb.object.dglyph.extent = gb->extent; | |
2760 rb.object.dglyph.xoffset = 0; | |
2761 rb.cursor_type = CURSOR_OFF; | |
2762 | |
2763 Dynarr_add (db->runes, rb); | |
2764 xpos += rb.width; | |
2765 count--; | 2791 count--; |
2766 gb->active = 0; | 2792 gb->active = 0; |
2767 | |
2768 if (glyph_contrib_p (gb->glyph, window)) | |
2769 { | |
2770 unsigned short ascent, descent; | |
2771 Lisp_Object baseline = glyph_baseline (gb->glyph, window); | |
2772 | |
2773 ascent = glyph_ascent (gb->glyph, window); | |
2774 descent = glyph_descent (gb->glyph, window); | |
2775 | |
2776 /* A pixmap that has not had a baseline explicitly set. | |
2777 We use the existing ascent / descent ratio of the | |
2778 line. */ | |
2779 if (NILP (baseline)) | |
2780 { | |
2781 int gheight = ascent + descent; | |
2782 int line_height = dl->ascent + dl->descent; | |
2783 int pix_ascent, pix_descent; | |
2784 | |
2785 pix_descent = (int) (gheight * dl->descent) / line_height; | |
2786 pix_ascent = gheight - pix_descent; | |
2787 | |
2788 dl->ascent = max ((int) dl->ascent, pix_ascent); | |
2789 dl->descent = max ((int) dl->descent, pix_descent); | |
2790 } | |
2791 | |
2792 /* A string so determine contribution normally. */ | |
2793 else if (EQ (baseline, Qt)) | |
2794 { | |
2795 dl->ascent = max (dl->ascent, ascent); | |
2796 dl->descent = max (dl->descent, descent); | |
2797 } | |
2798 | |
2799 /* A pixmap with an explicitly set baseline. We determine the | |
2800 contribution here. */ | |
2801 else if (INTP (baseline)) | |
2802 { | |
2803 int height = ascent + descent; | |
2804 int pix_ascent, pix_descent; | |
2805 | |
2806 pix_ascent = height * XINT (baseline) / 100; | |
2807 pix_descent = height - pix_ascent; | |
2808 | |
2809 dl->ascent = max ((int) dl->ascent, pix_ascent); | |
2810 dl->descent = max ((int) dl->descent, pix_descent); | |
2811 } | |
2812 | |
2813 /* Otherwise something is screwed up. */ | |
2814 else | |
2815 abort (); | |
2816 } | |
2817 } | 2793 } |
2818 | 2794 |
2819 (reverse ? elt-- : elt++); | 2795 (reverse ? elt-- : elt++); |
2820 } | 2796 } |
2821 | 2797 |
2822 return xpos; | 2798 if (data.max_pixmap_height) |
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; | |
2823 } | 2813 } |
2824 | 2814 |
2825 /* Add a blank to a margin display block. */ | 2815 /* Add a blank to a margin display block. */ |
2826 | 2816 |
2827 static void | 2817 static void |
3508 Dynarr_reset (formatted_string_extent_start_dynarr); | 3498 Dynarr_reset (formatted_string_extent_start_dynarr); |
3509 Dynarr_reset (formatted_string_extent_end_dynarr); | 3499 Dynarr_reset (formatted_string_extent_end_dynarr); |
3510 | 3500 |
3511 /* result_str is nil when we're building a frame or icon title. Otherwise, | 3501 /* result_str is nil when we're building a frame or icon title. Otherwise, |
3512 we're building a modeline, so the offset starts at the modeline | 3502 we're building a modeline, so the offset starts at the modeline |
3513 horizontal scrolling ammount */ | 3503 horizontal scrolling amount */ |
3514 if (! NILP (result_str)) | 3504 if (! NILP (result_str)) |
3515 offset = w->modeline_hscroll; | 3505 offset = w->modeline_hscroll; |
3516 generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0, | 3506 generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0, |
3517 max_pixpos - min_pixpos, findex, type, &offset, | 3507 max_pixpos - min_pixpos, findex, type, &offset, |
3518 Qnil); | 3508 Qnil); |
3544 { | 3534 { |
3545 int elt; | 3535 int elt; |
3546 Bytecount len; | 3536 Bytecount len; |
3547 Bufbyte *strdata; | 3537 Bufbyte *strdata; |
3548 struct buffer *buf = XBUFFER (WINDOW_BUFFER (w)); | 3538 struct buffer *buf = XBUFFER (WINDOW_BUFFER (w)); |
3539 | |
3540 in_modeline_generation = 1; | |
3549 | 3541 |
3550 detach_all_extents (result_str); | 3542 detach_all_extents (result_str); |
3551 resize_string (XSTRING (result_str), -1, | 3543 resize_string (XSTRING (result_str), -1, |
3552 data.bytepos - XSTRING_LENGTH (result_str)); | 3544 data.bytepos - XSTRING_LENGTH (result_str)); |
3553 | 3545 |
3581 (XEXTENT (child), | 3573 (XEXTENT (child), |
3582 Dynarr_at (formatted_string_extent_start_dynarr, elt), | 3574 Dynarr_at (formatted_string_extent_start_dynarr, elt), |
3583 Dynarr_at (formatted_string_extent_end_dynarr, elt), | 3575 Dynarr_at (formatted_string_extent_end_dynarr, elt), |
3584 result_str); | 3576 result_str); |
3585 } | 3577 } |
3578 | |
3579 in_modeline_generation = 0; | |
3586 } | 3580 } |
3587 } | 3581 } |
3588 | 3582 |
3589 /* Ensure that the given display line DL accurately represents the | 3583 /* Ensure that the given display line DL accurately represents the |
3590 modeline for the given window. */ | 3584 modeline for the given window. */ |
3623 | 3617 |
3624 dl->ascent = DEVMETH (d, divider_height, ()); | 3618 dl->ascent = DEVMETH (d, divider_height, ()); |
3625 dl->descent = 0; | 3619 dl->descent = 0; |
3626 /* The modeline is at the bottom of the gutters. */ | 3620 /* The modeline is at the bottom of the gutters. */ |
3627 dl->ypos = WINDOW_BOTTOM (w); | 3621 dl->ypos = WINDOW_BOTTOM (w); |
3628 | |
3629 /* adjust for the bottom gutter */ | |
3630 if (window_is_lowest (w)) | |
3631 dl->ypos -= FRAME_BOTTOM_GUTTER_BOUNDS (f); | |
3632 | 3622 |
3633 rb.findex = MODELINE_INDEX; | 3623 rb.findex = MODELINE_INDEX; |
3634 rb.xpos = dl->bounds.left_out; | 3624 rb.xpos = dl->bounds.left_out; |
3635 rb.width = dl->bounds.right_out - dl->bounds.left_out; | 3625 rb.width = dl->bounds.right_out - dl->bounds.left_out; |
3636 rb.bufpos = 0; | 3626 rb.bufpos = 0; |
3681 | 3671 |
3682 /* The modeline is at the bottom of the gutters. We have to wait to | 3672 /* The modeline is at the bottom of the gutters. We have to wait to |
3683 set this until we've generated the modeline in order to account | 3673 set this until we've generated the modeline in order to account |
3684 for any embedded faces. */ | 3674 for any embedded faces. */ |
3685 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj; | 3675 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj; |
3686 /* adjust for the bottom gutter */ | |
3687 if (window_is_lowest (w)) | |
3688 dl->ypos -= FRAME_BOTTOM_GUTTER_BOUNDS (f); | |
3689 } | 3676 } |
3690 | 3677 |
3691 static Charcount | 3678 static Charcount |
3692 add_string_to_fstring_db_runes (pos_data *data, CONST Bufbyte *str, | 3679 add_string_to_fstring_db_runes (pos_data *data, const Bufbyte *str, |
3693 Charcount pos, Charcount min_pos, Charcount max_pos) | 3680 Charcount pos, Charcount min_pos, Charcount max_pos) |
3694 { | 3681 { |
3695 /* This function has been Mule-ized. */ | 3682 /* This function has been Mule-ized. */ |
3696 Charcount end; | 3683 Charcount end; |
3697 CONST Bufbyte *cur_pos = str; | 3684 const Bufbyte *cur_pos = str; |
3698 struct display_block *db = data->db; | 3685 struct display_block *db = data->db; |
3699 | 3686 |
3700 data->blank_width = space_width (XWINDOW (data->window)); | 3687 data->blank_width = space_width (XWINDOW (data->window)); |
3701 while (Dynarr_length (db->runes) < pos) | 3688 while (Dynarr_length (db->runes) < pos) |
3702 add_blank_rune (data, NULL, 0); | 3689 add_blank_rune (data, NULL, 0); |
3703 | 3690 |
3704 end = (Dynarr_length (db->runes) + | 3691 end = (Dynarr_length (db->runes) + |
3705 bytecount_to_charcount (str, strlen ((CONST char *) str))); | 3692 bytecount_to_charcount (str, strlen ((const char *) str))); |
3706 if (max_pos != -1) | 3693 if (max_pos != -1) |
3707 end = min (max_pos, end); | 3694 end = min (max_pos, end); |
3708 | 3695 |
3709 while (pos < end && *cur_pos) | 3696 while (pos < end && *cur_pos) |
3710 { | 3697 { |
3711 CONST Bufbyte *old_cur_pos = cur_pos; | 3698 const Bufbyte *old_cur_pos = cur_pos; |
3712 int succeeded; | 3699 int succeeded; |
3713 | 3700 |
3714 data->ch = charptr_emchar (cur_pos); | 3701 data->ch = charptr_emchar (cur_pos); |
3715 succeeded = (add_emchar_rune (data) != ADD_FAILED); | 3702 succeeded = (add_emchar_rune (data) != ADD_FAILED); |
3716 INC_CHARPTR (cur_pos); | 3703 INC_CHARPTR (cur_pos); |
3818 *offset -= size; | 3805 *offset -= size; |
3819 else | 3806 else |
3820 { | 3807 { |
3821 Charcount tmp_max = (max_pos == -1 ? pos + size - *offset : | 3808 Charcount tmp_max = (max_pos == -1 ? pos + size - *offset : |
3822 min (pos + size - *offset, max_pos)); | 3809 min (pos + size - *offset, max_pos)); |
3823 CONST Bufbyte *tmp_last = charptr_n_addr (last, *offset); | 3810 const Bufbyte *tmp_last = charptr_n_addr (last, *offset); |
3824 | 3811 |
3825 pos = add_string_to_fstring_db_runes (data, tmp_last, | 3812 pos = add_string_to_fstring_db_runes (data, tmp_last, |
3826 pos, pos, tmp_max); | 3813 pos, pos, tmp_max); |
3827 *offset = 0; | 3814 *offset = 0; |
3828 } | 3815 } |
3875 num_to_add++; | 3862 num_to_add++; |
3876 } | 3863 } |
3877 | 3864 |
3878 while (num_to_add--) | 3865 while (num_to_add--) |
3879 pos = add_string_to_fstring_db_runes | 3866 pos = add_string_to_fstring_db_runes |
3880 (data, (CONST Bufbyte *) "-", pos, pos, max_pos); | 3867 (data, (const Bufbyte *) "-", pos, pos, max_pos); |
3881 } | 3868 } |
3882 else if (*this != 0) | 3869 else if (*this != 0) |
3883 { | 3870 { |
3884 Emchar ch = charptr_emchar (this); | 3871 Emchar ch = charptr_emchar (this); |
3885 Bufbyte *str; | 3872 Bufbyte *str; |
3894 | 3881 |
3895 if (size <= *offset) | 3882 if (size <= *offset) |
3896 *offset -= size; | 3883 *offset -= size; |
3897 else | 3884 else |
3898 { | 3885 { |
3899 CONST Bufbyte *tmp_str = charptr_n_addr (str, *offset); | 3886 const Bufbyte *tmp_str = charptr_n_addr (str, *offset); |
3900 | 3887 |
3901 /* #### NOTE: I don't understand why a tmp_max is not | 3888 /* #### NOTE: I don't understand why a tmp_max is not |
3902 computed and used here as in the plain string case | 3889 computed and used here as in the plain string case |
3903 above. -- dv */ | 3890 above. -- dv */ |
3904 pos = add_string_to_fstring_db_runes (data, tmp_str, | 3891 pos = add_string_to_fstring_db_runes (data, tmp_str, |
3940 | 3927 |
3941 if (size <= *offset) | 3928 if (size <= *offset) |
3942 *offset -= size; | 3929 *offset -= size; |
3943 else | 3930 else |
3944 { | 3931 { |
3945 CONST Bufbyte *tmp_str = charptr_n_addr (str, *offset); | 3932 const Bufbyte *tmp_str = charptr_n_addr (str, *offset); |
3946 | 3933 |
3947 /* #### NOTE: I don't understand why a tmp_max is not | 3934 /* #### NOTE: I don't understand why a tmp_max is not |
3948 computed and used here as in the plain string case | 3935 computed and used here as in the plain string case |
3949 above. -- dv */ | 3936 above. -- dv */ |
3950 pos = add_string_to_fstring_db_runes (data, tmp_str, pos, | 3937 pos = add_string_to_fstring_db_runes (data, tmp_str, pos, |
3981 * at most that many characters. If positive, pad (with spaces) | 3968 * at most that many characters. If positive, pad (with spaces) |
3982 * to at least that many characters. | 3969 * to at least that many characters. |
3983 * - If first element is another symbol, process the cadr or caddr | 3970 * - If first element is another symbol, process the cadr or caddr |
3984 * recursively according to whether the symbol's value is non-nil or | 3971 * recursively according to whether the symbol's value is non-nil or |
3985 * nil. | 3972 * nil. |
3986 * - If first element is a face, process the cdr recursively | 3973 * - If first element is an extent, process the cdr recursively |
3987 * without altering the depth. | 3974 * and handle the extent's face. |
3988 */ | 3975 */ |
3989 | 3976 |
3990 Lisp_Object car, tem; | 3977 Lisp_Object car, tem; |
3991 | 3978 |
3992 car = XCAR (elt); | 3979 car = XCAR (elt); |
4134 | 4121 |
4135 if (size <= *offset) | 4122 if (size <= *offset) |
4136 *offset -= size; | 4123 *offset -= size; |
4137 else | 4124 else |
4138 { | 4125 { |
4139 CONST Bufbyte *tmp_str = | 4126 const Bufbyte *tmp_str = |
4140 charptr_n_addr ((CONST Bufbyte *) str, *offset); | 4127 charptr_n_addr ((const Bufbyte *) str, *offset); |
4141 | 4128 |
4142 /* #### NOTE: I don't understand why a tmp_max is not computed and | 4129 /* #### NOTE: I don't understand why a tmp_max is not computed and |
4143 used here as in the plain string case above. -- dv */ | 4130 used here as in the plain string case above. -- dv */ |
4144 pos = add_string_to_fstring_db_runes (data, tmp_str, pos, | 4131 pos = add_string_to_fstring_db_runes (data, tmp_str, pos, |
4145 min_pos, max_pos); | 4132 min_pos, max_pos); |
4148 } | 4135 } |
4149 } | 4136 } |
4150 | 4137 |
4151 if (min_pos > pos) | 4138 if (min_pos > pos) |
4152 { | 4139 { |
4153 add_string_to_fstring_db_runes (data, (CONST Bufbyte *) "", pos, | 4140 add_string_to_fstring_db_runes (data, (const Bufbyte *) "", pos, |
4154 min_pos, -1); | 4141 min_pos, -1); |
4155 } | 4142 } |
4156 | 4143 |
4157 return pos; | 4144 return pos; |
4158 } | 4145 } |
4295 pos_data data; | 4282 pos_data data; |
4296 | 4283 |
4297 int truncate_win = b ? window_truncation_on (w) : 0; | 4284 int truncate_win = b ? window_truncation_on (w) : 0; |
4298 int end_glyph_width = 0; | 4285 int end_glyph_width = 0; |
4299 | 4286 |
4300 /* we're going to ditch selective display for static text, its an | 4287 /* We're going to ditch selective display for static text, it's an |
4301 FSF thing and invisble extents are the way to go | 4288 FSF thing and invisible extents are the way to go here. |
4302 here. Implementing it also relies on a number of buffer-specific | 4289 Implementing it also relies on a number of buffer-specific |
4303 functions that we don't have the luxury of being able to use | 4290 functions that we don't have the luxury of being able to use |
4304 here. */ | 4291 here. */ |
4305 | 4292 |
4306 /* The variable ctl-arrow allows the user to specify what characters | 4293 /* The variable ctl-arrow allows the user to specify what characters |
4307 can actually be displayed and which octal should be used for. | 4294 can actually be displayed and which octal should be used for. |
4363 displayed. */ | 4350 displayed. */ |
4364 int no_more_frags = 0; | 4351 int no_more_frags = 0; |
4365 | 4352 |
4366 dl->used_prop_data = 0; | 4353 dl->used_prop_data = 0; |
4367 dl->num_chars = 0; | 4354 dl->num_chars = 0; |
4355 dl->line_continuation = 0; | |
4368 | 4356 |
4369 /* set up faces to use for clearing areas, used by | 4357 /* set up faces to use for clearing areas, used by |
4370 output_display_line */ | 4358 output_display_line */ |
4371 dl->default_findex = default_face; | 4359 dl->default_findex = default_face; |
4372 if (default_face) | 4360 if (default_face) |
4755 /* The cursor can never be on the continuation glyph. */ | 4743 /* The cursor can never be on the continuation glyph. */ |
4756 data.cursor_type = NO_CURSOR; | 4744 data.cursor_type = NO_CURSOR; |
4757 | 4745 |
4758 /* data.bi_bufpos is already at the start of the next line. */ | 4746 /* data.bi_bufpos is already at the start of the next line. */ |
4759 | 4747 |
4748 dl->line_continuation = 1; | |
4760 gb.glyph = Vcontinuation_glyph; | 4749 gb.glyph = Vcontinuation_glyph; |
4761 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX); | 4750 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX); |
4762 } | 4751 } |
4763 | 4752 |
4764 if (end_glyph_width) | 4753 if (end_glyph_width) |
4765 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel); | 4754 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel); |
4766 | 4755 |
4767 if (truncate_win && data.bi_bufpos == bi_string_zv) | 4756 if (truncate_win && data.bi_bufpos == bi_string_zv) |
4768 { | 4757 { |
4769 CONST Bufbyte* endb = charptr_n_addr (string_data (s), bi_string_zv); | 4758 const Bufbyte* endb = charptr_n_addr (string_data (s), bi_string_zv); |
4770 DEC_CHARPTR (endb); | 4759 DEC_CHARPTR (endb); |
4771 if (charptr_emchar (endb) != '\n') | 4760 if (charptr_emchar (endb) != '\n') |
4772 { | 4761 { |
4773 /* #### Damn this losing shit. */ | 4762 /* #### Damn this losing shit. */ |
4774 data.bi_bufpos++; | 4763 data.bi_bufpos++; |
5096 struct frame *f = XFRAME (w->frame); | 5085 struct frame *f = XFRAME (w->frame); |
5097 struct buffer *b = XBUFFER (w->buffer); | 5086 struct buffer *b = XBUFFER (w->buffer); |
5098 int ypos = WINDOW_TEXT_TOP (w); | 5087 int ypos = WINDOW_TEXT_TOP (w); |
5099 int yend; /* set farther down */ | 5088 int yend; /* set farther down */ |
5100 int yclip = WINDOW_TEXT_TOP_CLIP (w); | 5089 int yclip = WINDOW_TEXT_TOP_CLIP (w); |
5090 int force; | |
5101 | 5091 |
5102 prop_block_dynarr *prop; | 5092 prop_block_dynarr *prop; |
5103 layout_bounds bounds; | 5093 layout_bounds bounds; |
5104 display_line_dynarr *dla; | 5094 display_line_dynarr *dla; |
5105 int need_modeline; | 5095 int need_modeline; |
5149 Dynarr_add (prop, pb); | 5139 Dynarr_add (prop, pb); |
5150 } | 5140 } |
5151 else | 5141 else |
5152 prop = 0; | 5142 prop = 0; |
5153 | 5143 |
5154 while (ypos < yend) | 5144 /* When we are computing things for scrolling purposes, make |
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) | |
5155 { | 5152 { |
5156 struct display_line dl; | 5153 struct display_line dl; |
5157 struct display_line *dlp; | 5154 struct display_line *dlp; |
5158 int local; | 5155 int local; |
5159 | 5156 |
5202 /* Although this seems strange we could have a single very | 5199 /* Although this seems strange we could have a single very |
5203 tall line visible for which we need to account for both | 5200 tall line visible for which we need to account for both |
5204 the top clip and the bottom clip. */ | 5201 the top clip and the bottom clip. */ |
5205 visible_height -= (dlp->clip + dlp->top_clip); | 5202 visible_height -= (dlp->clip + dlp->top_clip); |
5206 | 5203 |
5207 if (visible_height < VERTICAL_CLIP (w, 1)) | 5204 if (visible_height < VERTICAL_CLIP (w, 1) && !force) |
5208 { | 5205 { |
5209 if (local) | 5206 if (local) |
5210 free_display_line (dlp); | 5207 free_display_line (dlp); |
5211 break; | 5208 break; |
5212 } | 5209 } |
5246 | 5243 |
5247 /* #### This type of check needs to be done down in the | 5244 /* #### This type of check needs to be done down in the |
5248 generate_display_line call. */ | 5245 generate_display_line call. */ |
5249 if (start_pos > BUF_ZV (b)) | 5246 if (start_pos > BUF_ZV (b)) |
5250 break; | 5247 break; |
5248 | |
5249 force = 0; | |
5251 } | 5250 } |
5252 | 5251 |
5253 if (prop) | 5252 if (prop) |
5254 Dynarr_free (prop); | 5253 Dynarr_free (prop); |
5255 | 5254 |
5256 /* #### More not quite right, but close enough. */ | 5255 /* #### More not quite right, but close enough. */ |
5257 /* #### Ben sez: apparently window_end_pos[] is measured | 5256 /* Ben sez: apparently window_end_pos[] is measured |
5258 as the number of characters between the window end and the | 5257 as the number of characters between the window end and the |
5259 end of the buffer? This seems rather weirdo. What's | 5258 end of the buffer? This seems rather weirdo. What's |
5260 the justification for this? */ | 5259 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 */ | |
5261 w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type]; | 5264 w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type]; |
5262 | 5265 |
5263 if (need_modeline) | 5266 if (need_modeline) |
5264 { | 5267 { |
5265 /* We know that this is the right thing to use because we put it | 5268 /* We know that this is the right thing to use because we put it |
5586 | 5589 |
5587 assert (cdl->bufpos == ddl->bufpos); | 5590 assert (cdl->bufpos == ddl->bufpos); |
5588 assert (cdl->end_bufpos == ddl->end_bufpos); | 5591 assert (cdl->end_bufpos == ddl->end_bufpos); |
5589 assert (cdl->offset == ddl->offset); | 5592 assert (cdl->offset == ddl->offset); |
5590 | 5593 |
5591 /* If the last rune is already a continuation glyph, fail. | 5594 /* If the line continues to next display line, fail. */ |
5592 #### We should be able to handle this better. */ | 5595 if (ddl->line_continuation) |
5593 { | 5596 return 0; |
5594 struct display_block *db = get_display_block_from_line (ddl, TEXT); | |
5595 if (Dynarr_length (db->runes)) | |
5596 { | |
5597 struct rune *rb = | |
5598 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1); | |
5599 | |
5600 if (rb->type == RUNE_DGLYPH | |
5601 && EQ (rb->object.dglyph.glyph, Vcontinuation_glyph)) | |
5602 return 0; | |
5603 } | |
5604 } | |
5605 | 5597 |
5606 /* If the line was generated using propagation data, fail. */ | 5598 /* If the line was generated using propagation data, fail. */ |
5607 if (ddl->used_prop_data) | 5599 if (ddl->used_prop_data) |
5608 return 0; | 5600 return 0; |
5609 | 5601 |
5617 { | 5609 { |
5618 Dynarr_free (prop); | 5610 Dynarr_free (prop); |
5619 return 0; | 5611 return 0; |
5620 } | 5612 } |
5621 | 5613 |
5622 /* If the last rune is now a continuation glyph, fail. */ | 5614 /* If the line continues to next display line, fail. */ |
5623 { | 5615 if (ddl->line_continuation) |
5624 struct display_block *db = get_display_block_from_line (ddl, TEXT); | 5616 return 0; |
5625 if (Dynarr_length (db->runes)) | |
5626 { | |
5627 struct rune *rb = | |
5628 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1); | |
5629 | |
5630 if (rb->type == RUNE_DGLYPH | |
5631 && EQ (rb->object.dglyph.glyph, Vcontinuation_glyph)) | |
5632 return 0; | |
5633 } | |
5634 } | |
5635 | 5617 |
5636 /* If any line position parameters have changed or a | 5618 /* If any line position parameters have changed or a |
5637 cursor has disappeared or disappeared, fail. */ | 5619 cursor has disappeared or disappeared, fail. */ |
5638 if (cdl->ypos != ddl->ypos | 5620 if (cdl->ypos != ddl->ypos |
5639 || cdl->ascent != ddl->ascent | 5621 || cdl->ascent != ddl->ascent |
6005 /* This check is to make sure we restore the minibuffer after a | 5987 /* This check is to make sure we restore the minibuffer after a |
6006 temporary change to the echo area. */ | 5988 temporary change to the echo area. */ |
6007 && !(MINI_WINDOW_P (w) && f->buffers_changed) | 5989 && !(MINI_WINDOW_P (w) && f->buffers_changed) |
6008 && !f->frame_changed | 5990 && !f->frame_changed |
6009 && !truncation_changed | 5991 && !truncation_changed |
6010 /* check whether start is really at the begining of a line GE */ | 5992 /* check whether start is really at the beginning of a line GE */ |
6011 && (!w->start_at_line_beg || beginning_of_line_p (b, startp)) | 5993 && (!w->start_at_line_beg || beginning_of_line_p (b, startp)) |
6012 ) | 5994 ) |
6013 { | 5995 { |
6014 /* Check if the cursor has actually moved. */ | 5996 /* Check if the cursor has actually moved. */ |
6015 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer) | 5997 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer) |
6019 && !f->clip_changed | 6001 && !f->clip_changed |
6020 && !f->extents_changed | 6002 && !f->extents_changed |
6021 && !f->faces_changed | 6003 && !f->faces_changed |
6022 && !f->glyphs_changed | 6004 && !f->glyphs_changed |
6023 && !f->subwindows_changed | 6005 && !f->subwindows_changed |
6024 && !f->subwindows_state_changed | 6006 /* && !f->subwindows_state_changed*/ |
6025 && !f->point_changed | 6007 && !f->point_changed |
6026 && !f->windows_structure_changed) | 6008 && !f->windows_structure_changed) |
6027 { | 6009 { |
6028 /* If not, we're done. */ | 6010 /* If not, we're done. */ |
6029 if (f->modeline_changed) | 6011 if (f->modeline_changed) |
6041 && !f->clip_changed | 6023 && !f->clip_changed |
6042 && !f->extents_changed | 6024 && !f->extents_changed |
6043 && !f->faces_changed | 6025 && !f->faces_changed |
6044 && !f->glyphs_changed | 6026 && !f->glyphs_changed |
6045 && !f->subwindows_changed | 6027 && !f->subwindows_changed |
6046 && !f->subwindows_state_changed | 6028 /* && !f->subwindows_state_changed*/ |
6047 && !f->windows_structure_changed) | 6029 && !f->windows_structure_changed) |
6048 { | 6030 { |
6049 if (point_visible (w, pointm, CURRENT_DISP) | 6031 if (point_visible (w, pointm, CURRENT_DISP) |
6050 && w->last_point_x[CURRENT_DISP] != -1 | 6032 && w->last_point_x[CURRENT_DISP] != -1 |
6051 && w->last_point_y[CURRENT_DISP] != -1) | 6033 && w->last_point_y[CURRENT_DISP] != -1) |
6100 else if (!w->windows_changed | 6082 else if (!w->windows_changed |
6101 && !f->clip_changed | 6083 && !f->clip_changed |
6102 && !f->faces_changed | 6084 && !f->faces_changed |
6103 && !f->glyphs_changed | 6085 && !f->glyphs_changed |
6104 && !f->subwindows_changed | 6086 && !f->subwindows_changed |
6105 && !f->subwindows_state_changed | 6087 /* && !f->subwindows_state_changed*/ |
6106 && !f->windows_structure_changed | 6088 && !f->windows_structure_changed |
6107 && !f->frame_changed | 6089 && !f->frame_changed |
6108 && !truncation_changed | 6090 && !truncation_changed |
6109 && pointm >= startp | 6091 && pointm >= startp |
6110 && regenerate_window_incrementally (w, startp, pointm)) | 6092 && regenerate_window_incrementally (w, startp, pointm)) |
6282 return 0; | 6264 return 0; |
6283 } | 6265 } |
6284 | 6266 |
6285 /* Ensure that all windows on the given frame are correctly displayed. */ | 6267 /* Ensure that all windows on the given frame are correctly displayed. */ |
6286 | 6268 |
6287 static int | 6269 int |
6288 redisplay_frame (struct frame *f, int preemption_check) | 6270 redisplay_frame (struct frame *f, int preemption_check) |
6289 { | 6271 { |
6290 struct device *d = XDEVICE (f->device); | 6272 struct device *d = XDEVICE (f->device); |
6291 | 6273 |
6292 if (preemption_check) | 6274 if (preemption_check) |
6297 int preempted; | 6279 int preempted; |
6298 | 6280 |
6299 REDISPLAY_PREEMPTION_CHECK; | 6281 REDISPLAY_PREEMPTION_CHECK; |
6300 if (preempted) | 6282 if (preempted) |
6301 return 1; | 6283 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); | |
6302 } | 6294 } |
6303 | 6295 |
6304 /* Before we put a hold on frame size changes, attempt to process | 6296 /* Before we put a hold on frame size changes, attempt to process |
6305 any which are already pending. */ | 6297 any which are already pending. */ |
6306 if (f->size_change_pending) | 6298 if (f->size_change_pending) |
6324 the menubar's visibility. This way we avoid having flashing | 6316 the menubar's visibility. This way we avoid having flashing |
6325 caused by an Expose event generated by the visibility change | 6317 caused by an Expose event generated by the visibility change |
6326 being handled. */ | 6318 being handled. */ |
6327 update_frame_menubars (f); | 6319 update_frame_menubars (f); |
6328 #endif /* HAVE_MENUBARS */ | 6320 #endif /* HAVE_MENUBARS */ |
6329 /* widgets are similar to menus in that they can call lisp to | |
6330 determine activation etc. Therefore update them before we get | |
6331 into redisplay. This is primarily for connected widgets such as | |
6332 radio buttons. */ | |
6333 update_frame_subwindows (f); | |
6334 #ifdef HAVE_TOOLBARS | 6321 #ifdef HAVE_TOOLBARS |
6335 /* Update the toolbars. */ | 6322 /* Update the toolbars. */ |
6336 update_frame_toolbars (f); | 6323 update_frame_toolbars (f); |
6337 #endif /* HAVE_TOOLBARS */ | 6324 #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); | |
6338 | 6329 |
6339 /* If we clear the frame we have to force its contents to be redrawn. */ | 6330 /* If we clear the frame we have to force its contents to be redrawn. */ |
6340 if (f->clear) | 6331 if (f->clear) |
6341 f->frame_changed = 1; | 6332 f->frame_changed = 1; |
6342 | 6333 |
6343 /* invalidate the subwindow cache. We use subwindows_changed here to | 6334 /* Invalidate the subwindow caches. We use subwindows_changed here |
6344 cause subwindows to get instantiated. This is because | 6335 to cause subwindows to get instantiated. This is because |
6345 subwindows_state_changed is less strict - dealing with things | 6336 subwindows_state_changed is less strict - dealing with things |
6346 like the clicked state of button. We have to do this before | 6337 like the clicked state of button. We have to do this before |
6347 redisplaying the gutters as subwindows get unmapped in the | 6338 redisplaying the gutters as subwindows get unmapped in the |
6348 process.*/ | 6339 process.*/ |
6349 if (!Dynarr_length (f->subwindow_cachels) | 6340 if (f->frame_changed) |
6350 || f->subwindows_changed | 6341 reset_frame_subwindow_instance_cache (f); |
6351 || f->faces_changed | 6342 |
6352 || f->frame_changed) | 6343 if (f->frame_changed || f->subwindows_changed) |
6353 { | 6344 { |
6354 reset_subwindow_cachels (f); | |
6355 /* we have to do this so the gutter gets regenerated. */ | 6345 /* we have to do this so the gutter gets regenerated. */ |
6356 reset_gutter_display_lines (f); | 6346 reset_gutter_display_lines (f); |
6357 } | 6347 } |
6358 else | |
6359 mark_subwindow_cachels_as_not_updated (f); | |
6360 /* We can now update the gutters, safe in the knowledge that our | |
6361 efforts won't get undone. */ | |
6362 update_frame_gutters (f); | |
6363 | 6348 |
6364 hold_frame_size_changes (); | 6349 hold_frame_size_changes (); |
6365 | 6350 |
6366 /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */ | 6351 /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */ |
6367 /* Within this section, we are defenseless and assume that the | 6352 /* Within this section, we are defenseless and assume that the |
6385 we simply return. #### We should abort instead. | 6370 we simply return. #### We should abort instead. |
6386 | 6371 |
6387 #### If a frame-size change does occur we should probably | 6372 #### If a frame-size change does occur we should probably |
6388 actually be preempting redisplay. */ | 6373 actually be preempting redisplay. */ |
6389 | 6374 |
6375 MAYBE_DEVMETH (d, frame_output_begin, (f)); | |
6376 | |
6377 /* We can now update the gutters, safe in the knowledge that our | |
6378 efforts won't get undone. */ | |
6379 | |
6380 /* This can call lisp, but redisplay is protected by binding | |
6381 inhibit_quit. More importantly the code involving display lines | |
6382 *assumes* that GC will not happen and so does not GCPRO | |
6383 anything. Since we use this code the whole time with the gutters | |
6384 we cannot allow GC to happen when manipulating the gutters. */ | |
6385 update_frame_gutters (f); | |
6386 | |
6390 /* Erase the frame before outputting its contents. */ | 6387 /* Erase the frame before outputting its contents. */ |
6391 if (f->clear) | 6388 if (f->clear) |
6392 { | 6389 { |
6393 DEVMETH (d, clear_frame, (f)); | 6390 MAYBE_DEVMETH (d, clear_frame, (f)); |
6394 } | 6391 } |
6395 | 6392 |
6396 /* Do the selected window first. */ | 6393 /* Do the selected window first. */ |
6397 redisplay_window (FRAME_SELECTED_WINDOW (f), 0); | 6394 redisplay_window (FRAME_SELECTED_WINDOW (f), 0); |
6398 | 6395 |
6399 /* Then do the rest. */ | 6396 /* Then do the rest. */ |
6400 redisplay_windows (f->root_window, 1); | 6397 redisplay_windows (f->root_window, 1); |
6401 | 6398 |
6402 /* We now call the output_end routine for tty frames. We delay | 6399 MAYBE_DEVMETH (d, frame_output_end, (f)); |
6403 doing so in order to avoid cursor flicker. So much for 100% | |
6404 encapsulation. */ | |
6405 if (FRAME_TTY_P (f)) | |
6406 DEVMETH (d, output_end, (d)); | |
6407 | 6400 |
6408 update_frame_title (f); | 6401 update_frame_title (f); |
6409 | 6402 |
6410 CLASS_RESET_CHANGED_FLAGS (f); | 6403 CLASS_RESET_CHANGED_FLAGS (f); |
6411 f->window_face_cache_reset = 0; | 6404 f->window_face_cache_reset = 0; |
6673 | 6666 |
6674 static void | 6667 static void |
6675 decode_mode_spec (struct window *w, Emchar spec, int type) | 6668 decode_mode_spec (struct window *w, Emchar spec, int type) |
6676 { | 6669 { |
6677 Lisp_Object obj = Qnil; | 6670 Lisp_Object obj = Qnil; |
6678 CONST char *str = NULL; | 6671 const char *str = NULL; |
6679 struct buffer *b = XBUFFER (w->buffer); | 6672 struct buffer *b = XBUFFER (w->buffer); |
6680 | 6673 |
6681 Dynarr_reset (mode_spec_bufbyte_string); | 6674 Dynarr_reset (mode_spec_bufbyte_string); |
6682 | 6675 |
6683 switch (spec) | 6676 switch (spec) |
6702 char buf[32]; | 6695 char buf[32]; |
6703 | 6696 |
6704 long_to_string (buf, col); | 6697 long_to_string (buf, col); |
6705 | 6698 |
6706 Dynarr_add_many (mode_spec_bufbyte_string, | 6699 Dynarr_add_many (mode_spec_bufbyte_string, |
6707 (CONST Bufbyte *) buf, strlen (buf)); | 6700 (const Bufbyte *) buf, strlen (buf)); |
6708 | 6701 |
6709 goto decode_mode_spec_done; | 6702 goto decode_mode_spec_done; |
6710 } | 6703 } |
6711 /* print the file coding system */ | 6704 /* print the file coding system */ |
6712 case 'C': | 6705 case 'C': |
7039 mark_object (gb->extent); | 7032 mark_object (gb->extent); |
7040 } | 7033 } |
7041 } | 7034 } |
7042 } | 7035 } |
7043 | 7036 |
7044 static void | 7037 /* See the comment in image_instantiate_cache_result as to why marking |
7038 the glyph will also mark the image_instance. */ | |
7039 void | |
7045 mark_redisplay_structs (display_line_dynarr *dla) | 7040 mark_redisplay_structs (display_line_dynarr *dla) |
7046 { | 7041 { |
7047 display_line *dl = Dynarr_atp (dla, 0); | 7042 display_line *dl = Dynarr_atp (dla, 0); |
7048 display_line *dl_last = Dynarr_atp (dla, Dynarr_length (dla)); | 7043 display_line *dl_last = Dynarr_atp (dla, Dynarr_length (dla)); |
7049 | 7044 |
7099 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons) | 7094 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons) |
7100 { | 7095 { |
7101 struct frame *f = XFRAME (XCAR (frmcons)); | 7096 struct frame *f = XFRAME (XCAR (frmcons)); |
7102 update_frame_window_mirror (f); | 7097 update_frame_window_mirror (f); |
7103 mark_window_mirror (f->root_mirror); | 7098 mark_window_mirror (f->root_mirror); |
7099 mark_gutters (f); | |
7104 } | 7100 } |
7105 } | 7101 } |
7106 | 7102 |
7107 /***************************************************************************** | 7103 /***************************************************************************** |
7108 Line Start Cache Description and Rationale | 7104 Line Start Cache Description and Rationale |
7535 /* For the given window W, if display starts at STARTP, what will be | 7531 /* For the given window W, if display starts at STARTP, what will be |
7536 the buffer position at the beginning or end of the last line | 7532 the buffer position at the beginning or end of the last line |
7537 displayed. The end of the last line is also know as the window end | 7533 displayed. The end of the last line is also know as the window end |
7538 position. | 7534 position. |
7539 | 7535 |
7536 WARNING: It is possible that redisplay failed to layout any lines for the | |
7537 windows. Under normal circumstances this is rare. However it seems that it | |
7538 does occur in the following situation: A mouse event has come in and we | |
7539 need to compute its location in a window. That code (in | |
7540 pixel_to_glyph_translation) already can handle 0 as an error return value. | |
7541 | |
7540 #### With a little work this could probably be reworked as just a | 7542 #### With a little work this could probably be reworked as just a |
7541 call to start_with_line_at_pixpos. */ | 7543 call to start_with_line_at_pixpos. */ |
7542 | 7544 |
7543 static Bufpos | 7545 static Bufpos |
7544 start_end_of_last_line (struct window *w, Bufpos startp, int end) | 7546 start_end_of_last_line (struct window *w, Bufpos startp, int end, |
7547 int may_error) | |
7545 { | 7548 { |
7546 struct buffer *b = XBUFFER (w->buffer); | 7549 struct buffer *b = XBUFFER (w->buffer); |
7547 line_start_cache_dynarr *cache = w->line_start_cache; | 7550 line_start_cache_dynarr *cache = w->line_start_cache; |
7548 int pixpos = 0; | 7551 int pixpos = 0; |
7549 int bottom = WINDOW_TEXT_HEIGHT (w); | 7552 int bottom = WINDOW_TEXT_HEIGHT (w); |
7559 startp = BUF_ZV (b); | 7562 startp = BUF_ZV (b); |
7560 cur_start = startp; | 7563 cur_start = startp; |
7561 | 7564 |
7562 start_elt = point_in_line_start_cache (w, cur_start, 0); | 7565 start_elt = point_in_line_start_cache (w, cur_start, 0); |
7563 if (start_elt == -1) | 7566 if (start_elt == -1) |
7564 abort (); /* this had better never happen */ | 7567 return may_error ? 0 : startp; |
7565 | 7568 |
7566 while (1) | 7569 while (1) |
7567 { | 7570 { |
7568 int height = Dynarr_atp (cache, start_elt)->height; | 7571 int height = Dynarr_atp (cache, start_elt)->height; |
7569 | 7572 |
7623 the buffer position at the beginning of the last line displayed. */ | 7626 the buffer position at the beginning of the last line displayed. */ |
7624 | 7627 |
7625 Bufpos | 7628 Bufpos |
7626 start_of_last_line (struct window *w, Bufpos startp) | 7629 start_of_last_line (struct window *w, Bufpos startp) |
7627 { | 7630 { |
7628 return start_end_of_last_line (w, startp, 0); | 7631 return start_end_of_last_line (w, startp, 0 , 0); |
7629 } | 7632 } |
7630 | 7633 |
7631 /* For the given window W, if display starts at STARTP, what will be | 7634 /* 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 | 7635 the buffer position at the end of the last line displayed. This is |
7633 also know as the window end position. */ | 7636 also know as the window end position. */ |
7634 | 7637 |
7635 Bufpos | 7638 Bufpos |
7636 end_of_last_line (struct window *w, Bufpos startp) | 7639 end_of_last_line (struct window *w, Bufpos startp) |
7637 { | 7640 { |
7638 return start_end_of_last_line (w, startp, 1); | 7641 return start_end_of_last_line (w, startp, 1, 0); |
7639 } | 7642 } |
7643 | |
7644 static Bufpos | |
7645 end_of_last_line_may_error (struct window *w, Bufpos startp) | |
7646 { | |
7647 return start_end_of_last_line (w, startp, 1, 1); | |
7648 } | |
7649 | |
7640 | 7650 |
7641 /* For window W, what does the starting position have to be so that | 7651 /* For window W, what does the starting position have to be so that |
7642 the line containing POINT will cover pixel position PIXPOS. */ | 7652 the line containing POINT will cover pixel position PIXPOS. */ |
7643 | 7653 |
7644 Bufpos | 7654 Bufpos |
7819 line_start_cache_dynarr *cache = w->line_start_cache; | 7829 line_start_cache_dynarr *cache = w->line_start_cache; |
7820 Bufpos low_bound, high_bound; | 7830 Bufpos low_bound, high_bound; |
7821 | 7831 |
7822 validate_line_start_cache (w); | 7832 validate_line_start_cache (w); |
7823 w->line_cache_validation_override++; | 7833 w->line_cache_validation_override++; |
7824 updating_line_start_cache = 1; | |
7825 | 7834 |
7826 if (from < BUF_BEGV (b)) | 7835 if (from < BUF_BEGV (b)) |
7827 from = BUF_BEGV (b); | 7836 from = BUF_BEGV (b); |
7828 if (to > BUF_ZV (b)) | 7837 if (to > BUF_ZV (b)) |
7829 to = BUF_ZV (b); | 7838 to = BUF_ZV (b); |
7830 | 7839 |
7831 if (from > to) | 7840 if (from > to) |
7832 { | 7841 { |
7833 updating_line_start_cache = 0; | |
7834 w->line_cache_validation_override--; | 7842 w->line_cache_validation_override--; |
7835 return; | 7843 return; |
7836 } | 7844 } |
7837 | 7845 |
7838 if (Dynarr_length (cache)) | 7846 if (Dynarr_length (cache)) |
7841 high_bound = line_start_cache_end (w); | 7849 high_bound = line_start_cache_end (w); |
7842 | 7850 |
7843 /* Check to see if the desired range is already in the cache. */ | 7851 /* Check to see if the desired range is already in the cache. */ |
7844 if (from >= low_bound && to <= high_bound) | 7852 if (from >= low_bound && to <= high_bound) |
7845 { | 7853 { |
7846 updating_line_start_cache = 0; | |
7847 w->line_cache_validation_override--; | 7854 w->line_cache_validation_override--; |
7848 return; | 7855 return; |
7849 } | 7856 } |
7850 | 7857 |
7851 /* Check to make sure that the desired range is adjacent to the | 7858 /* Check to make sure that the desired range is adjacent to the |
7870 Bufpos start, end; | 7877 Bufpos start, end; |
7871 | 7878 |
7872 update_internal_cache_list (w, DESIRED_DISP); | 7879 update_internal_cache_list (w, DESIRED_DISP); |
7873 if (!Dynarr_length (internal_cache)) | 7880 if (!Dynarr_length (internal_cache)) |
7874 { | 7881 { |
7875 updating_line_start_cache = 0; | |
7876 w->line_cache_validation_override--; | 7882 w->line_cache_validation_override--; |
7877 return; | 7883 return; |
7878 } | 7884 } |
7879 | 7885 |
7880 start = Dynarr_atp (internal_cache, 0)->start; | 7886 start = Dynarr_atp (internal_cache, 0)->start; |
7898 | 7904 |
7899 if (!Dynarr_length (cache)) | 7905 if (!Dynarr_length (cache)) |
7900 { | 7906 { |
7901 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0), | 7907 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0), |
7902 Dynarr_length (internal_cache)); | 7908 Dynarr_length (internal_cache)); |
7903 updating_line_start_cache = 0; | |
7904 w->line_cache_validation_override--; | 7909 w->line_cache_validation_override--; |
7905 return; | 7910 return; |
7906 } | 7911 } |
7907 | 7912 |
7908 /* An extra check just in case the calling function didn't pass in | 7913 /* An extra check just in case the calling function didn't pass in |
7909 the bounds of the DESIRED structs in the first place. */ | 7914 the bounds of the DESIRED structs in the first place. */ |
7910 if (start >= low_bound && end <= high_bound) | 7915 if (start >= low_bound && end <= high_bound) |
7911 { | 7916 { |
7912 updating_line_start_cache = 0; | |
7913 w->line_cache_validation_override--; | 7917 w->line_cache_validation_override--; |
7914 return; | 7918 return; |
7915 } | 7919 } |
7916 | 7920 |
7917 /* At this point we know that the internal cache partially overlaps | 7921 /* At this point we know that the internal cache partially overlaps |
7930 if (!(ic_elt >= 0)) | 7934 if (!(ic_elt >= 0)) |
7931 { | 7935 { |
7932 Dynarr_reset (cache); | 7936 Dynarr_reset (cache); |
7933 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0), | 7937 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0), |
7934 Dynarr_length (internal_cache)); | 7938 Dynarr_length (internal_cache)); |
7935 updating_line_start_cache = 0; | |
7936 w->line_cache_validation_override--; | 7939 w->line_cache_validation_override--; |
7937 return; | 7940 return; |
7938 } | 7941 } |
7939 | 7942 |
7940 Dynarr_insert_many_at_start (cache, Dynarr_atp (internal_cache, 0), | 7943 Dynarr_insert_many_at_start (cache, Dynarr_atp (internal_cache, 0), |
7956 if (!(ic_elt < Dynarr_length (internal_cache))) | 7959 if (!(ic_elt < Dynarr_length (internal_cache))) |
7957 { | 7960 { |
7958 Dynarr_reset (cache); | 7961 Dynarr_reset (cache); |
7959 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0), | 7962 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0), |
7960 Dynarr_length (internal_cache)); | 7963 Dynarr_length (internal_cache)); |
7961 updating_line_start_cache = 0; | |
7962 w->line_cache_validation_override--; | 7964 w->line_cache_validation_override--; |
7963 return; | 7965 return; |
7964 } | 7966 } |
7965 | 7967 |
7966 Dynarr_add_many (cache, Dynarr_atp (internal_cache, ic_elt), | 7968 Dynarr_add_many (cache, Dynarr_atp (internal_cache, ic_elt), |
7967 Dynarr_length (internal_cache) - ic_elt); | 7969 Dynarr_length (internal_cache) - ic_elt); |
7968 } | 7970 } |
7969 | 7971 |
7970 updating_line_start_cache = 0; | |
7971 w->line_cache_validation_override--; | 7972 w->line_cache_validation_override--; |
7972 return; | 7973 return; |
7973 } | 7974 } |
7974 | 7975 |
7975 if (!Dynarr_length (cache) || from < low_bound) | 7976 if (!Dynarr_length (cache) || from < low_bound) |
7985 | 7986 |
7986 regenerate_window (w, startp, point, CMOTION_DISP); | 7987 regenerate_window (w, startp, point, CMOTION_DISP); |
7987 update_internal_cache_list (w, CMOTION_DISP); | 7988 update_internal_cache_list (w, CMOTION_DISP); |
7988 | 7989 |
7989 /* If this assert is triggered then regenerate_window failed | 7990 /* If this assert is triggered then regenerate_window failed |
7990 to layout a single line. That is not supposed to be | 7991 to layout a single line. This is not possible since we |
7991 possible because we impose a minimum height on the buffer | 7992 force at least a single line to be layout for CMOTION_DISP */ |
7992 and override vertical clip when we are in here. */ | 7993 assert (Dynarr_length (internal_cache)); |
7993 /* #### Ah, but it is because the window may temporarily | |
7994 exist but not have any lines at all if the minibuffer is | |
7995 real big. Look into that situation better. */ | |
7996 if (!Dynarr_length (internal_cache)) | |
7997 { | |
7998 if (old_lb == -1 && low_bound == -1) | |
7999 { | |
8000 updating_line_start_cache = 0; | |
8001 w->line_cache_validation_override--; | |
8002 return; | |
8003 } | |
8004 | |
8005 assert (Dynarr_length (internal_cache)); | |
8006 } | |
8007 assert (startp == Dynarr_atp (internal_cache, 0)->start); | 7994 assert (startp == Dynarr_atp (internal_cache, 0)->start); |
8008 | 7995 |
8009 ic_elt = Dynarr_length (internal_cache) - 1; | 7996 ic_elt = Dynarr_length (internal_cache) - 1; |
8010 if (low_bound != -1) | 7997 if (low_bound != -1) |
8011 { | 7998 { |
8047 if (startp < low_bound || low_bound == -1) | 8034 if (startp < low_bound || low_bound == -1) |
8048 low_bound = startp; | 8035 low_bound = startp; |
8049 startp = new_startp; | 8036 startp = new_startp; |
8050 if (startp > BUF_ZV (b)) | 8037 if (startp > BUF_ZV (b)) |
8051 { | 8038 { |
8052 updating_line_start_cache = 0; | |
8053 w->line_cache_validation_override--; | 8039 w->line_cache_validation_override--; |
8054 return; | 8040 return; |
8055 } | 8041 } |
8056 } | 8042 } |
8057 } | 8043 } |
8081 startp = high_bound + 1; | 8067 startp = high_bound + 1; |
8082 } | 8068 } |
8083 while (to > high_bound); | 8069 while (to > high_bound); |
8084 } | 8070 } |
8085 | 8071 |
8086 updating_line_start_cache = 0; | |
8087 w->line_cache_validation_override--; | 8072 w->line_cache_validation_override--; |
8088 assert (to <= high_bound); | 8073 assert (to <= high_bound); |
8089 } | 8074 } |
8090 | 8075 |
8091 | 8076 |
8789 /* #### This should be checked out some more to determine what | 8774 /* #### This should be checked out some more to determine what |
8790 should really be going on. */ | 8775 should really be going on. */ |
8791 if (!MARKERP ((*w)->start[CURRENT_DISP])) | 8776 if (!MARKERP ((*w)->start[CURRENT_DISP])) |
8792 *closest = 0; | 8777 *closest = 0; |
8793 else | 8778 else |
8794 *closest = end_of_last_line (*w, | 8779 *closest = end_of_last_line_may_error (*w, |
8795 marker_position ((*w)->start[CURRENT_DISP])); | 8780 marker_position ((*w)->start[CURRENT_DISP])); |
8796 *col = 0; | 8781 *col = 0; |
8797 UPDATE_CACHE_RETURN; | 8782 UPDATE_CACHE_RETURN; |
8798 } | 8783 } |
8799 #undef UPDATE_CACHE_RETURN | 8784 #undef UPDATE_CACHE_RETURN |
8822 struct frame *f = XFRAME (XCAR (frmcons)); | 8807 struct frame *f = XFRAME (XCAR (frmcons)); |
8823 | 8808 |
8824 if (FRAME_REPAINT_P (f) && FRAME_HAS_MINIBUF_P (f)) | 8809 if (FRAME_REPAINT_P (f) && FRAME_HAS_MINIBUF_P (f)) |
8825 { | 8810 { |
8826 Lisp_Object window = FRAME_MINIBUF_WINDOW (f); | 8811 Lisp_Object window = FRAME_MINIBUF_WINDOW (f); |
8812 | |
8813 MAYBE_DEVMETH (d, frame_output_begin, (f)); | |
8814 | |
8827 /* | 8815 /* |
8828 * If the frame size has changed, there may be random | 8816 * If the frame size has changed, there may be random |
8829 * chud on the screen left from previous messages | 8817 * chud on the screen left from previous messages |
8830 * because redisplay_frame hasn't been called yet. | 8818 * because redisplay_frame hasn't been called yet. |
8831 * Clear the screen to get rid of the potential mess. | 8819 * Clear the screen to get rid of the potential mess. |
8832 */ | 8820 */ |
8833 if (f->echo_area_garbaged) | 8821 if (f->echo_area_garbaged) |
8834 { | 8822 { |
8835 DEVMETH (d, clear_frame, (f)); | 8823 MAYBE_DEVMETH (d, clear_frame, (f)); |
8836 f->echo_area_garbaged = 0; | 8824 f->echo_area_garbaged = 0; |
8837 } | 8825 } |
8838 redisplay_window (window, 0); | 8826 redisplay_window (window, 0); |
8827 MAYBE_DEVMETH (d, frame_output_end, (f)); | |
8828 | |
8839 call_redisplay_end_triggers (XWINDOW (window), 0); | 8829 call_redisplay_end_triggers (XWINDOW (window), 0); |
8840 } | 8830 } |
8841 } | 8831 } |
8842 | |
8843 /* We now call the output_end routine for tty frames. We delay | |
8844 doing so in order to avoid cursor flicker. So much for 100% | |
8845 encapsulation. */ | |
8846 if (DEVICE_TTY_P (d)) | |
8847 DEVMETH (d, output_end, (d)); | |
8848 } | 8832 } |
8849 | 8833 |
8850 return Qnil; | 8834 return Qnil; |
8851 } | 8835 } |
8852 | 8836 |
8876 disable_preemption++; | 8860 disable_preemption++; |
8877 } | 8861 } |
8878 | 8862 |
8879 f->clear = 1; | 8863 f->clear = 1; |
8880 redisplay_frame (f, 1); | 8864 redisplay_frame (f, 1); |
8865 | |
8866 /* See the comment in Fredisplay_frame. */ | |
8867 RESET_CHANGED_SET_FLAGS; | |
8881 | 8868 |
8882 return unbind_to (count, Qnil); | 8869 return unbind_to (count, Qnil); |
8883 } | 8870 } |
8884 | 8871 |
8885 DEFUN ("redisplay-frame", Fredisplay_frame, 0, 2, 0, /* | 8872 DEFUN ("redisplay-frame", Fredisplay_frame, 0, 2, 0, /* |
8904 disable_preemption++; | 8891 disable_preemption++; |
8905 } | 8892 } |
8906 | 8893 |
8907 redisplay_frame (f, 1); | 8894 redisplay_frame (f, 1); |
8908 | 8895 |
8896 /* If we don't reset the global redisplay flags here, subsequent | |
8897 changes to the display will not get registered by redisplay | |
8898 because it thinks it already has registered changes. If you | |
8899 really knew what you were doing you could confuse redisplay by | |
8900 calling Fredisplay_frame while updating another frame. We assume | |
8901 that if you know what you are doing you will not be that | |
8902 stupid. */ | |
8903 RESET_CHANGED_SET_FLAGS; | |
8904 | |
8909 return unbind_to (count, Qnil); | 8905 return unbind_to (count, Qnil); |
8910 } | 8906 } |
8911 | 8907 |
8912 DEFUN ("redraw-device", Fredraw_device, 0, 2, 0, /* | 8908 DEFUN ("redraw-device", Fredraw_device, 0, 2, 0, /* |
8913 Clear device DEVICE and output again what is supposed to appear on it. | 8909 Clear device DEVICE and output again what is supposed to appear on it. |
8932 DEVICE_FRAME_LOOP (frmcons, d) | 8928 DEVICE_FRAME_LOOP (frmcons, d) |
8933 { | 8929 { |
8934 XFRAME (XCAR (frmcons))->clear = 1; | 8930 XFRAME (XCAR (frmcons))->clear = 1; |
8935 } | 8931 } |
8936 redisplay_device (d, 0); | 8932 redisplay_device (d, 0); |
8933 | |
8934 /* See the comment in Fredisplay_frame. */ | |
8935 RESET_CHANGED_SET_FLAGS; | |
8937 | 8936 |
8938 return unbind_to (count, Qnil); | 8937 return unbind_to (count, Qnil); |
8939 } | 8938 } |
8940 | 8939 |
8941 DEFUN ("redisplay-device", Fredisplay_device, 0, 2, 0, /* | 8940 DEFUN ("redisplay-device", Fredisplay_device, 0, 2, 0, /* |
8959 make_int (disable_preemption)); | 8958 make_int (disable_preemption)); |
8960 disable_preemption++; | 8959 disable_preemption++; |
8961 } | 8960 } |
8962 | 8961 |
8963 redisplay_device (d, 0); | 8962 redisplay_device (d, 0); |
8963 | |
8964 /* See the comment in Fredisplay_frame. */ | |
8965 RESET_CHANGED_SET_FLAGS; | |
8964 | 8966 |
8965 return unbind_to (count, Qnil); | 8967 return unbind_to (count, Qnil); |
8966 } | 8968 } |
8967 | 8969 |
8968 /* Big lie. Big lie. This will force all modelines to be updated | 8970 /* Big lie. Big lie. This will force all modelines to be updated |
9222 #endif /* INHIBIT_REDISPLAY_HOOKS */ | 9224 #endif /* INHIBIT_REDISPLAY_HOOKS */ |
9223 defsymbol (&Qdisplay_warning_buffer, "display-warning-buffer"); | 9225 defsymbol (&Qdisplay_warning_buffer, "display-warning-buffer"); |
9224 defsymbol (&Qbar_cursor, "bar-cursor"); | 9226 defsymbol (&Qbar_cursor, "bar-cursor"); |
9225 defsymbol (&Qredisplay_end_trigger_functions, | 9227 defsymbol (&Qredisplay_end_trigger_functions, |
9226 "redisplay-end-trigger-functions"); | 9228 "redisplay-end-trigger-functions"); |
9229 defsymbol (&Qtop_bottom, "top-bottom"); | |
9230 defsymbol (&Qbuffer_list_changed_hook, "buffer-list-changed-hook"); | |
9227 | 9231 |
9228 DEFSUBR (Fredisplay_echo_area); | 9232 DEFSUBR (Fredisplay_echo_area); |
9229 DEFSUBR (Fredraw_frame); | 9233 DEFSUBR (Fredraw_frame); |
9230 DEFSUBR (Fredisplay_frame); | 9234 DEFSUBR (Fredisplay_frame); |
9231 DEFSUBR (Fredraw_device); | 9235 DEFSUBR (Fredraw_device); |
9233 DEFSUBR (Fredraw_modeline); | 9237 DEFSUBR (Fredraw_modeline); |
9234 DEFSUBR (Fforce_cursor_redisplay); | 9238 DEFSUBR (Fforce_cursor_redisplay); |
9235 } | 9239 } |
9236 | 9240 |
9237 void | 9241 void |
9238 reinit_vars_of_redisplay (void) | |
9239 { | |
9240 updating_line_start_cache = 0; | |
9241 } | |
9242 | |
9243 void | |
9244 vars_of_redisplay (void) | 9242 vars_of_redisplay (void) |
9245 { | 9243 { |
9246 reinit_vars_of_redisplay (); | |
9247 | 9244 |
9248 #if 0 | 9245 #if 0 |
9249 staticpro (&last_arrow_position); | 9246 staticpro (&last_arrow_position); |
9250 staticpro (&last_arrow_string); | 9247 staticpro (&last_arrow_string); |
9251 last_arrow_position = Qnil; | 9248 last_arrow_position = Qnil; |
9286 */ , | 9283 */ , |
9287 redisplay_variable_changed); | 9284 redisplay_variable_changed); |
9288 Voverlay_arrow_position = Qnil; | 9285 Voverlay_arrow_position = Qnil; |
9289 | 9286 |
9290 DEFVAR_LISP_MAGIC ("overlay-arrow-string", &Voverlay_arrow_string /* | 9287 DEFVAR_LISP_MAGIC ("overlay-arrow-string", &Voverlay_arrow_string /* |
9291 String to display as an arrow. See also `overlay-arrow-position'. | 9288 String or glyph to display as an arrow. See also `overlay-arrow-position'. |
9289 (Note that despite the name of this variable, it can be set to a glyph as | |
9290 well as a string.) | |
9292 */ , | 9291 */ , |
9293 redisplay_variable_changed); | 9292 redisplay_variable_changed); |
9294 Voverlay_arrow_string = Qnil; | 9293 Voverlay_arrow_string = Qnil; |
9295 | 9294 |
9296 DEFVAR_INT ("scroll-step", &scroll_step /* | 9295 DEFVAR_INT ("scroll-step", &scroll_step /* |
9310 *Non-nil means truncate lines in all windows less than full frame wide. | 9309 *Non-nil means truncate lines in all windows less than full frame wide. |
9311 */ , | 9310 */ , |
9312 redisplay_variable_changed); | 9311 redisplay_variable_changed); |
9313 truncate_partial_width_windows = 1; | 9312 truncate_partial_width_windows = 1; |
9314 | 9313 |
9315 DEFVAR_BOOL ("visible-bell", &visible_bell /* | 9314 DEFVAR_LISP ("visible-bell", &Vvisible_bell /* |
9316 *Non-nil means try to flash the frame to represent a bell. | 9315 *Non-nil substitutes a visual signal for the audible bell. |
9316 | |
9317 Default behavior is to flash the whole screen. On some platforms, | |
9318 special effects are available using the following values: | |
9319 | |
9320 'display Flash the whole screen (ie, the default behavior). | |
9321 'top-bottom Flash only the top and bottom lines of the selected frame. | |
9322 | |
9323 When effects are unavailable on a platform, the visual bell is the | |
9324 default, whole screen. (Currently only X supports any special effects.) | |
9317 */ ); | 9325 */ ); |
9318 visible_bell = 0; | 9326 Vvisible_bell = Qnil; |
9319 | 9327 |
9320 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter /* | 9328 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter /* |
9321 *Non-nil means no need to redraw entire frame after suspending. | 9329 *Non-nil means no need to redraw entire frame after suspending. |
9322 A non-nil value is useful if the terminal can automatically preserve | 9330 A non-nil value is useful if the terminal can automatically preserve |
9323 Emacs's frame display when you reenter Emacs. | 9331 Emacs's frame display when you reenter Emacs. |
9364 Vbar_cursor = Qnil; | 9372 Vbar_cursor = Qnil; |
9365 | 9373 |
9366 #ifndef INHIBIT_REDISPLAY_HOOKS | 9374 #ifndef INHIBIT_REDISPLAY_HOOKS |
9367 xxDEFVAR_LISP ("pre-redisplay-hook", &Vpre_redisplay_hook /* | 9375 xxDEFVAR_LISP ("pre-redisplay-hook", &Vpre_redisplay_hook /* |
9368 Function or functions to run before every redisplay. | 9376 Function or functions to run before every redisplay. |
9369 Functions on this hook must be careful to avoid signalling errors! | |
9370 */ ); | 9377 */ ); |
9371 Vpre_redisplay_hook = Qnil; | 9378 Vpre_redisplay_hook = Qnil; |
9372 | 9379 |
9373 xxDEFVAR_LISP ("post-redisplay-hook", &Vpost_redisplay_hook /* | 9380 xxDEFVAR_LISP ("post-redisplay-hook", &Vpost_redisplay_hook /* |
9374 Function or functions to run after every redisplay. | 9381 Function or functions to run after every redisplay. |
9375 Functions on this hook must be careful to avoid signalling errors! | |
9376 */ ); | 9382 */ ); |
9377 Vpost_redisplay_hook = Qnil; | 9383 Vpost_redisplay_hook = Qnil; |
9378 #endif /* INHIBIT_REDISPLAY_HOOKS */ | 9384 #endif /* INHIBIT_REDISPLAY_HOOKS */ |
9385 | |
9386 DEFVAR_LISP ("buffer-list-changed-hook", &Vbuffer_list_changed_hook /* | |
9387 Function or functions to call when a frame's buffer list has changed. | |
9388 This is called during redisplay, before redisplaying each frame. | |
9389 Functions on this hook are called with one argument, the frame. | |
9390 */ ); | |
9391 Vbuffer_list_changed_hook = Qnil; | |
9379 | 9392 |
9380 DEFVAR_INT ("display-warning-tick", &display_warning_tick /* | 9393 DEFVAR_INT ("display-warning-tick", &display_warning_tick /* |
9381 Bump this to tell the C code to call `display-warning-buffer' | 9394 Bump this to tell the C code to call `display-warning-buffer' |
9382 at next redisplay. You should not normally change this; the function | 9395 at next redisplay. You should not normally change this; the function |
9383 `display-warning' automatically does this at appropriate times. | 9396 `display-warning' automatically does this at appropriate times. |