1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1994, 1995, 1996 Board of Trustees, University of Illinois.
3 Copyright (C) 1995 Free Software Foundation, Inc.
4 Copyright (C) 1995, 1996 Ben Wing.
5 Copyright (C) 1995 Sun Microsystems, Inc.
6 Copyright (C) 1996 Chuck Thompson.
8 This file is part of XEmacs.
10 XEmacs is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
15 XEmacs is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with XEmacs; see the file COPYING. If not, write to
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
25 /* Synched up with: Not in FSF. */
27 /* Author: Chuck Thompson */
29 /* Fixed up by Ben Wing for Mule */
31 /* This file has been Mule-ized. */
33 /*****************************************************************************
34 The Golden Rules of Redisplay
36 First: It Is Better To Be Correct Than Fast
37 Second: Thou Shalt Not Run Elisp From Within Redisplay
38 Third: It Is Better To Be Fast Than Not To Be
39 ****************************************************************************/
58 #include "redisplay.h"
61 #include "line-number.h"
63 #include "file-coding.h"
69 #include "console-tty.h"
72 /* Note: We have to be careful throughout this code to properly handle
73 and differentiate between Bufbytes and Emchars.
75 Since strings are generally composed of Bufbytes, I've taken the tack
76 that any contiguous set of Bufbytes is called a "string", while
77 any contiguous set of Emchars is called an "array". */
79 /* Return value to indicate a failure by an add_*_rune routine to add
80 a rune, but no propagation information needs to be returned. */
81 #define ADD_FAILED (prop_block_dynarr *) 1
83 #define BEGIN_GLYPHS 0
86 #define RIGHT_GLYPHS 3
88 #define VERTICAL_CLIP(w, display) \
89 ((WINDOW_TTY_P (w) | (!display && scroll_on_clipped_lines)) \
93 /* The following structures are completely private to redisplay.c so
94 we put them here instead of in a header file, for modularity. */
96 /* NOTE: Bytinds not Bufpos's in this structure. */
98 typedef struct position_redisplay_data_type
100 /* This information is normally filled in by the create_*_block
101 routines and is used by the add_*_rune routines. */
103 /* if we are working with strings rather than buffers we need a
104 handle to the string */
107 struct display_block *db;
108 struct display_line *dl;
109 Emchar ch; /* Character that is to be added. This is
110 used to communicate this information to
111 add_emchar_rune(). */
112 Lisp_Object last_charset; /* The charset of the previous character.
113 Used to optimize some lookups -- we
114 only have to do some things when
115 the charset changes. */
116 face_index last_findex; /* The face index of the previous character.
117 Needed to ensure the validity of the
118 last_charset optimization. */
120 int last_char_width; /* The width of the previous character. */
121 int font_is_bogus; /* If true, it means we couldn't instantiate
122 the font for this charset, so we substitute
123 ~'s from the ASCII charset. */
128 int blank_width; /* Width of the blank that is to be added.
129 This is used to communicate this information
132 This is also used rather cheesily to
133 communicate the width of the eol-cursor-size
134 blank that exists at the end of the line.
135 add_emchar_rune() is called cheesily with
136 the non-printing char '\n', which is stuck
137 in the output routines with its width being
139 Bytind bi_cursor_bufpos;/* This stores the buffer position of the cursor. */
140 unsigned int cursor_type :3;
141 int cursor_x; /* rune block cursor is at */
142 int start_col; /* Number of character columns (each column has
143 a width of the default char width) that still
144 need to be skipped. This is used for horizontal
145 scrolling, where a certain number of columns
146 (those off the left side of the screen) need
147 to be skipped before anything is displayed. */
148 Bytind bi_start_col_enabled;
149 int start_col_xoffset; /* Number of pixels that still need to
150 be skipped. This is used for
151 horizontal scrolling of glyphs, where we want
152 to be able to scroll over part of the glyph. */
154 int hscroll_glyph_width_adjust; /* how much the width of the hscroll
155 glyph differs from space_width (w).
156 0 if no hscroll glyph was used,
157 i.e. the window is not scrolled
158 horizontally. Used in tab
161 /* Information about the face the text should be displayed in and
162 any begin-glyphs and end-glyphs. */
163 struct extent_fragment *ef;
166 /* The height of a pixmap may either be predetermined if the user has set a
167 baseline value, or it may be dependent on whatever the line ascent and
168 descent values end up being, based just on font and pixmap-ascent
169 information. In the first case we can immediately update the values, thus
170 their inclusion here. In the last case we cannot determine the actual
171 contribution to the line height until we have finished laying out all text
172 on the line. Thus we propagate the max height of such pixmaps and do a
173 final calculation (in calculate_baseline()) after all text has been added
177 int max_pixmap_height;
178 int need_baseline_computation;
179 int end_glyph_width; /* Well, it is the kitchen sink after all ... */
181 Lisp_Object result_str; /* String where we put the result of
182 generating a formatted string in the modeline. */
183 int is_modeline; /* Non-zero if we're generating the modeline. */
184 Charcount modeline_charpos; /* Number of chars used in result_str so far;
185 corresponds to bytepos. */
186 Bytecount bytepos; /* Number of bytes used in result_str so far.
187 We don't actually copy the bytes into result_str
188 until the end because we don't know how big the
189 string is going to be until then. */
201 /* Data that should be propagated to the next line. Either a single
202 Emchar, a string of Bufbyte's or a glyph.
204 The actual data that is propagated ends up as a Dynarr of these
207 prop_blocks are used to indicate that data that was supposed to go
208 on the previous line couldn't actually be displayed. Generally this
209 shouldn't happen if we are clipping the end of lines. If we are
210 wrapping then we need to display the propagation data before moving
211 on. Its questionable whether we should wrap or clip glyphs in this
212 instance. Most e-lisp relies on clipping so we preserve this
215 #### It's unclean that both Emchars and Bufbytes are here.
218 typedef struct prop_block prop_block;
228 Bytecount len; /* length of the string. */
234 Bytind bi_cursor_bufpos; /* NOTE: is in Bytinds */
235 unsigned int cursor_type :3;
246 /* Not used as yet, but could be used to wrap rather than clip glyphs. */
256 Dynarr_declare (prop_block);
260 static Charcount generate_fstring_runes (struct window *w, pos_data *data,
261 Charcount pos, Charcount min_pos,
262 Charcount max_pos, Lisp_Object elt,
263 int depth, int max_pixsize,
264 face_index findex, int type,
266 Lisp_Object cur_ext);
267 static prop_block_dynarr *add_glyph_rune (pos_data *data,
268 struct glyph_block *gb,
269 int pos_type, int allow_cursor,
270 struct glyph_cachel *cachel);
271 static Bytind create_text_block (struct window *w, struct display_line *dl,
272 Bytind bi_start_pos, prop_block_dynarr **prop,
274 static int create_overlay_glyph_block (struct window *w,
275 struct display_line *dl);
276 static void create_left_glyph_block (struct window *w,
277 struct display_line *dl,
279 static void create_right_glyph_block (struct window *w,
280 struct display_line *dl);
281 static void redisplay_windows (Lisp_Object window, int skip_selected);
282 static void decode_mode_spec (struct window *w, Emchar spec, int type);
283 static void free_display_line (struct display_line *dl);
284 static void update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
285 Bufpos point, int no_regen);
286 static int point_visible (struct window *w, Bufpos point, int type);
287 static void calculate_yoffset (struct display_line *dl,
288 struct display_block *fixup);
289 static void calculate_baseline (pos_data *data);
291 /* This used to be 10 but 30 seems to give much better performance. */
292 #define INIT_MAX_PREEMPTS 30
293 static int max_preempts;
295 #define REDISPLAY_PREEMPTION_CHECK \
298 (!disable_preemption && \
299 ((preemption_count < max_preempts) || !NILP (Vexecuting_macro)) && \
300 (!INTERACTIVE || detect_input_pending ()))))
303 * Redisplay global variables.
306 /* We need a third set of display structures for the cursor motion
307 routines. We used to just give each window a third set. However,
308 we always fully regenerate the structures when needed so there
309 isn't any reason we need more than a single set. */
310 display_line_dynarr *cmotion_display_lines;
312 /* We store the extents that we need to generate in a Dynarr and then
313 frob them all on at the end of generating the string. We do it
314 this way rather than adding them as we generate the string because
315 we don't store the text into the resulting string until we're done
316 (to avoid having to resize the string multiple times), and we don't
317 want to go around adding extents to a string when the extents might
318 stretch off the end of the string. */
319 static EXTENT_dynarr *formatted_string_extent_dynarr;
320 static Bytecount_dynarr *formatted_string_extent_start_dynarr;
321 static Bytecount_dynarr *formatted_string_extent_end_dynarr;
324 /* #### probably temporary */
325 Fixnum cache_adjustment;
327 /* This holds a string representing the text corresponding to a single
329 static Bufbyte_dynarr *mode_spec_bufbyte_string;
331 int in_display; /* 1 if in redisplay. */
333 int disable_preemption; /* Used for debugging redisplay and for
336 /* We only allow max_preempts preemptions before we force a redisplay. */
337 static int preemption_count;
339 /* Minimum pixel height of clipped bottom display line. */
340 Fixnum vertical_clip;
342 /* Minimum visible pixel width of clipped glyphs at right margin. */
343 Fixnum horizontal_clip;
345 /* Nonzero means reading single-character input with prompt
346 so put cursor on minibuffer after the prompt. */
347 int cursor_in_echo_area;
348 Lisp_Object Qcursor_in_echo_area;
350 /* Nonzero means truncate lines in all windows less wide than the frame */
351 int truncate_partial_width_windows;
353 /* non-nil if a buffer has changed since the last time redisplay completed */
355 int buffers_changed_set;
357 /* non-nil if hscroll has changed somewhere or a buffer has been
358 narrowed or widened */
360 int clip_changed_set;
362 /* non-nil if any extent has changed since the last time redisplay completed */
364 int extents_changed_set;
366 /* non-nil if any face has changed since the last time redisplay completed */
369 /* Nonzero means some frames have been marked as garbaged */
372 /* non-zero if any of the builtin display glyphs (continuation,
373 hscroll, control-arrow, etc) is in need of updating
376 int glyphs_changed_set;
378 /* non-zero if any subwindow has been deleted. */
379 int subwindows_changed;
380 int subwindows_changed_set;
382 /* non-zero if any displayed subwindow is in need of updating
384 int subwindows_state_changed;
385 int subwindows_state_changed_set;
387 /* This variable is 1 if the icon has to be updated.
388 It is set to 1 when `frame-icon-glyph' changes. */
390 int icon_changed_set;
392 /* This variable is 1 if the menubar widget has to be updated.
393 It is set to 1 by set-menubar-dirty-flag and cleared when the widget
396 int menubar_changed_set;
398 /* true iff we should redraw the modelines on the next redisplay */
399 int modeline_changed;
400 int modeline_changed_set;
402 /* non-nil if point has changed in some buffer since the last time
403 redisplay completed */
405 int point_changed_set;
407 /* non-nil if some frame has changed its size */
410 /* non-nil if some device has signaled that it wants to change size */
411 int asynch_device_change_pending;
413 /* non-nil if any toolbar has changed */
415 int toolbar_changed_set;
417 /* Nonzero if some frame has changed the layout of internal elements
418 (gutters or toolbars). */
419 int frame_layout_changed;
421 /* non-nil if any gutter has changed */
423 int gutter_changed_set;
425 /* non-nil if any window has changed since the last time redisplay completed */
428 /* non-nil if any frame's window structure has changed since the last
429 time redisplay completed */
430 int windows_structure_changed;
432 /* If non-nil, use vertical bar cursor. */
433 Lisp_Object Vbar_cursor;
434 Lisp_Object Qbar_cursor;
436 Lisp_Object Vvisible_bell; /* If true and the terminal will support it
437 then the frame will flash instead of
438 beeping when an error occurs */
440 /* Nonzero means no need to redraw the entire frame on resuming
441 a suspended Emacs. This is useful on terminals with multiple pages,
442 where one page is used for Emacs and another for all else. */
443 int no_redraw_on_reenter;
445 Lisp_Object Vwindow_system; /* nil or a symbol naming the window system
446 under which emacs is running
447 ('x is the only current possibility) */
448 Lisp_Object Vinitial_window_system;
450 Lisp_Object Vglobal_mode_string;
452 /* The number of lines scroll a window by when point leaves the window; if
453 it is <=0 then point is centered in the window */
456 /* Scroll up to this many lines, to bring point back on screen. */
457 Fixnum scroll_conservatively;
459 /* Marker for where to display an arrow on top of the buffer text. */
460 Lisp_Object Voverlay_arrow_position;
461 /* String to display for the arrow. */
462 Lisp_Object Voverlay_arrow_string;
464 Lisp_Object Vwindow_size_change_functions;
465 Lisp_Object Vwindow_scroll_functions;
466 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
468 Lisp_Object Qbuffer_list_changed_hook, Vbuffer_list_changed_hook;
471 #define INHIBIT_REDISPLAY_HOOKS /* #### Until we've thought about
473 #ifndef INHIBIT_REDISPLAY_HOOKS
474 /* #### Chuck says: I think this needs more thought.
475 Think about this for 19.14. */
476 Lisp_Object Vpre_redisplay_hook, Vpost_redisplay_hook;
477 Lisp_Object Qpre_redisplay_hook, Qpost_redisplay_hook;
478 #endif /* INHIBIT_REDISPLAY_HOOKS */
480 static Fixnum last_display_warning_tick;
481 static Fixnum display_warning_tick;
482 Lisp_Object Qdisplay_warning_buffer;
483 int inhibit_warning_display;
485 Lisp_Object Vleft_margin_width, Vright_margin_width;
486 Lisp_Object Vminimum_line_ascent, Vminimum_line_descent;
487 Lisp_Object Vuse_left_overflow, Vuse_right_overflow;
488 Lisp_Object Vtext_cursor_visible_p;
490 int column_number_start_at_one;
492 Lisp_Object Qtop_bottom;
494 #define WINDOW_SCROLLED(w) ((w)->hscroll > 0 || (w)->left_xoffset)
497 /***************************************************************************/
499 /* low-level interfaces onto device routines */
501 /***************************************************************************/
504 redisplay_text_width_charc_string (struct window *w, int findex,
505 Charc *str, Charcount len)
507 Charset_ID charsets[NUM_LEADING_BYTES];
510 find_charsets_in_charc_string (charsets, str, len);
511 XSETWINDOW (window, w);
512 ensure_face_cachel_complete (WINDOW_FACE_CACHEL (w, findex), window,
514 return DEVMETH (XDEVICE (FRAME_DEVICE (XFRAME (WINDOW_FRAME (w)))),
515 text_width, (XFRAME (WINDOW_FRAME (w)),
516 WINDOW_FACE_CACHEL (w, findex), str, len));
519 static Charc_dynarr *rtw_charc_dynarr;
522 redisplay_text_width_string (struct window *w, int findex,
523 Bufbyte *nonreloc, Lisp_Object reloc,
524 Bytecount offset, Bytecount len)
526 if (!rtw_charc_dynarr)
527 rtw_charc_dynarr = Dynarr_new (Charc);
528 Dynarr_reset (rtw_charc_dynarr);
530 fixup_internal_substring (nonreloc, reloc, offset, &len);
532 nonreloc = XSTRING_DATA (reloc);
533 convert_bufbyte_string_into_charc_dynarr (nonreloc, len, rtw_charc_dynarr);
534 return redisplay_text_width_charc_string
535 (w, findex, Dynarr_atp (rtw_charc_dynarr, 0),
536 Dynarr_length (rtw_charc_dynarr));
540 redisplay_frame_text_width_string (struct frame *f, Lisp_Object face,
541 Bufbyte *nonreloc, Lisp_Object reloc,
542 Bytecount offset, Bytecount len)
544 Charset_ID charsets[NUM_LEADING_BYTES];
546 struct face_cachel cachel;
548 if (!rtw_charc_dynarr)
549 rtw_charc_dynarr = Dynarr_new (Charc);
550 Dynarr_reset (rtw_charc_dynarr);
552 fixup_internal_substring (nonreloc, reloc, offset, &len);
554 nonreloc = XSTRING_DATA (reloc);
555 convert_bufbyte_string_into_charc_dynarr (nonreloc, len, rtw_charc_dynarr);
556 find_charsets_in_bufbyte_string (charsets, nonreloc, len);
557 reset_face_cachel (&cachel);
559 XSETFRAME (frame, f);
560 ensure_face_cachel_complete (&cachel, frame, charsets);
561 return DEVMETH (XDEVICE (FRAME_DEVICE (f)),
562 text_width, (f, &cachel, Dynarr_atp (rtw_charc_dynarr, 0),
563 Dynarr_length (rtw_charc_dynarr)));
566 /* Return the display block from DL of the given TYPE. A display line
567 can have only one display block of each possible type. If DL does
568 not have a block of type TYPE, one will be created and added to DL. */
570 struct display_block *
571 get_display_block_from_line (struct display_line *dl, enum display_type type)
574 struct display_block db;
576 /* Check if this display line already has a block of the desired type and
578 if (dl->display_blocks)
580 for (elt = 0; elt < Dynarr_length (dl->display_blocks); elt++)
582 if (Dynarr_at (dl->display_blocks, elt).type == type)
583 return Dynarr_atp (dl->display_blocks, elt);
586 /* There isn't an active block of the desired type, but there
587 might still be allocated blocks we need to reuse. */
588 if (elt < Dynarr_largest (dl->display_blocks))
590 struct display_block *dbp = Dynarr_atp (dl->display_blocks, elt);
592 /* 'add' the block to the list */
593 Dynarr_increment (dl->display_blocks);
595 /* initialize and return */
602 /* This line doesn't have any display blocks, so initialize the display
604 dl->display_blocks = Dynarr_new (display_block);
607 /* The line doesn't have a block of the desired type so go ahead and create
608 one and add it to the line. */
611 db.runes = Dynarr_new (rune);
612 Dynarr_add (dl->display_blocks, db);
614 /* Return the newly added display block. */
615 elt = Dynarr_length (dl->display_blocks) - 1;
617 return Dynarr_atp (dl->display_blocks, elt);
621 tab_char_width (struct window *w)
623 struct buffer *b = XBUFFER (w->buffer);
624 int char_tab_width = XINT (b->tab_width);
626 if (char_tab_width <= 0 || char_tab_width > 1000) char_tab_width = 8;
628 return char_tab_width;
632 space_width (struct window *w)
634 /* While tabs are traditional composed of spaces, for variable-width
635 fonts the space character tends to give too narrow a value. So
636 we use 'n' instead. Except that we don't. We use the default
637 character width for the default face. If this is actually
638 defined by the font then it is probably the best thing to
639 actually use. If it isn't, we have assumed it is 'n' and have
640 already calculated its width. Thus we can avoid a call to
641 XTextWidth on X frames by just querying the default width. */
642 return XFONT_INSTANCE
643 (WINDOW_FACE_CACHEL_FONT (w, DEFAULT_INDEX, Vcharset_ascii))->width;
647 tab_pix_width (struct window *w)
649 return space_width (w) * tab_char_width (w);
652 /* Given a pixel position in a window, return the pixel location of
653 the next tabstop. Tabs are calculated from the left window edge in
654 terms of spaces displayed in the default face. Formerly the space
655 width was determined using the currently active face. That method
656 leads to tabstops which do not line up. */
659 next_tab_position (struct window *w, int start_pixpos, int left_pixpos)
661 int n_pos = left_pixpos;
662 int pix_tab_width = tab_pix_width (w);
664 /* Adjust n_pos for any hscrolling which has happened. */
665 if (WINDOW_SCROLLED (w))
666 n_pos -= space_width (w) * (w->hscroll - 1) + w->left_xoffset;
668 while (n_pos <= start_pixpos)
669 n_pos += pix_tab_width;
674 /* For the given window, calculate the outside and margin boundaries for a
675 display line. The whitespace boundaries must be calculated by the text
679 calculate_display_line_boundaries (struct window *w, int modeline)
681 layout_bounds bounds;
683 /* Set the outermost boundaries which are the boundaries of the
684 window itself minus the gutters (and minus the scrollbars if this
685 is for the modeline). */
688 bounds.left_out = WINDOW_TEXT_LEFT (w);
689 bounds.right_out = WINDOW_TEXT_RIGHT (w);
693 bounds.left_out = WINDOW_MODELINE_LEFT (w);
694 bounds.right_out = WINDOW_MODELINE_RIGHT (w);
697 /* The inner boundaries mark where the glyph margins are located. */
698 bounds.left_in = bounds.left_out + window_left_margin_width (w);
699 bounds.right_in = bounds.right_out - window_right_margin_width (w);
701 /* We cannot fully calculate the whitespace boundaries as they
702 depend on the contents of the line being displayed. */
703 bounds.left_white = bounds.left_in;
704 bounds.right_white = bounds.right_in;
709 /* This takes a display_block and its containing line and corrects the yoffset
710 of each glyph in the block to cater for the ascent of the line as a
711 whole. Must be called *after* the line-ascent is known! */
714 calculate_yoffset (struct display_line *dl, struct display_block *fixup)
717 for (i=0; i<Dynarr_length (fixup->runes); i++)
719 struct rune *r = Dynarr_atp (fixup->runes,i);
720 if (r->type == RUNE_DGLYPH)
722 if (r->object.dglyph.ascent < dl->ascent)
723 r->object.dglyph.yoffset = dl->ascent - r->object.dglyph.ascent +
724 r->object.dglyph.descent;
729 /* Calculate the textual baseline (the ascent and descent values for the
730 display_line as a whole).
732 If the baseline is completely blank, or contains no manually positioned
733 glyphs, then the textual baseline is simply the baseline of the default font.
734 (The `contains no manually positioned glyphs' part is actually done for
735 us by `add_emchar_rune'.)
737 If the baseline contains pixmaps, and they're all manually positioned, then
738 the textual baseline location is constrained that way, and we need do no
741 If the baseline contains pixmaps, and at least one is automatically
742 positioned, then the textual ascent is the largest ascent on the line, and
743 the textual descent is the largest descent (which is how things are set up at
744 entry to this function anyway): except that if the max_ascent + max_descent
745 is too small for the height of the line (say you've adjusted the baseline of
746 a short glyph, and there's a tall one next to it), then take the ascent and
747 descent for the line individually from the largest of the explicitly set
748 ascent/descent, and the rescaled ascent/descent of the default font, scaled
749 such that the largest glyph will fit.
751 This means that if you have a short glyph (but taller than the default
752 font's descent) forced right under the baseline, and a really tall
753 automatically positioned glyph, that the descent for the line is just big
754 enough for the manually positioned short glyph, and the tall one uses as
755 much of that space as the default font would were it as tall as the tall
756 glyph; but that the ascent is big enough for the tall glyph to fit.
758 This behaviour means that under no circumstances will changing the baseline
759 of a short glyph cause a tall glyph to move around; nor will it move the
760 textual baseline more than necessary. (Changing a tall glyph's baseline
761 might move the text's baseline arbitrarily, of course.) */
764 calculate_baseline (pos_data *data)
766 /* Blank line: baseline is default font's baseline. */
768 if (!data->new_ascent && !data->new_descent)
770 /* We've got a blank line so initialize these values from the default
772 default_face_font_info (data->window, &data->new_ascent,
773 &data->new_descent, 0, 0, 0);
776 /* No automatically positioned glyphs? Return at once. */
777 if (!data->need_baseline_computation)
780 /* Is the tallest glyph on the line automatically positioned?
781 If it's manually positioned, or it's automatically positioned
782 and there's enough room for it anyway, we need do no more work. */
783 if (data->max_pixmap_height > data->new_ascent + data->new_descent)
785 int default_font_ascent, default_font_descent, default_font_height;
786 int scaled_default_font_ascent, scaled_default_font_descent;
788 default_face_font_info (data->window, &default_font_ascent,
789 &default_font_descent, &default_font_height,
792 scaled_default_font_ascent = data->max_pixmap_height *
793 default_font_ascent / default_font_height;
795 data->new_ascent = max (data->new_ascent, scaled_default_font_ascent);
797 /* The ascent may have expanded now. Do we still need to grow the descent,
798 or are things big enough?
800 The +1 caters for the baseline row itself. */
801 if (data->max_pixmap_height > data->new_ascent + data->new_descent)
803 scaled_default_font_descent = (data->max_pixmap_height *
804 default_font_descent / default_font_height) + 1;
806 data->new_descent = max (data->new_descent, scaled_default_font_descent);
811 /* Given a display line and a starting position, ensure that the
812 contents of the display line accurately represent the visual
813 representation of the buffer contents starting from the given
814 position when displayed in the given window. The display line ends
815 when the contents of the line reach the right boundary of the given
819 generate_display_line (struct window *w, struct display_line *dl, int bounds,
820 Bufpos start_pos, prop_block_dynarr **prop,
825 struct buffer *b = XBUFFER (WINDOW_BUFFER (w));
827 /* If our caller hasn't already set the boundaries, then do so now. */
829 dl->bounds = calculate_display_line_boundaries (w, 0);
831 /* Reset what this line is using. */
832 if (dl->display_blocks)
833 Dynarr_reset (dl->display_blocks);
836 Dynarr_free (dl->left_glyphs);
839 if (dl->right_glyphs)
841 Dynarr_free (dl->right_glyphs);
842 dl->right_glyphs = 0;
845 /* We aren't generating a modeline at the moment. */
848 /* Create a display block for the text region of the line. */
850 /* #### urk urk urk!!! Chuck fix this shit! */
851 Bytind hacked_up_bytind =
852 create_text_block (w, dl, bufpos_to_bytind (b, start_pos),
854 if (hacked_up_bytind > BI_BUF_ZV (b))
855 ret_bufpos = BUF_ZV (b) + 1;
857 ret_bufpos = bytind_to_bufpos (b, hacked_up_bytind);
859 dl->bufpos = start_pos;
860 if (dl->end_bufpos < dl->bufpos)
861 dl->end_bufpos = dl->bufpos;
863 if (MARKERP (Voverlay_arrow_position)
864 && EQ (w->buffer, Fmarker_buffer (Voverlay_arrow_position))
865 && start_pos == marker_position (Voverlay_arrow_position)
866 && (STRINGP (Voverlay_arrow_string)
867 || GLYPHP (Voverlay_arrow_string)))
869 overlay_width = create_overlay_glyph_block (w, dl);
874 /* If there are left glyphs associated with any character in the
875 text block, then create a display block to handle them. */
876 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
877 create_left_glyph_block (w, dl, overlay_width);
879 /* If there are right glyphs associated with any character in the
880 text block, then create a display block to handle them. */
881 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
882 create_right_glyph_block (w, dl);
884 /* In the future additional types of display blocks may be generated
887 w->last_redisplay_pos = ret_bufpos;
892 /* Adds an hscroll glyph to a display block. If this is called, then
893 the block had better be empty.
895 Yes, there are multiple places where this function is called but
896 that is the way it has to be. Each calling function has to deal
897 with bi_start_col_enabled a little differently depending on the
898 object being worked with. */
900 static prop_block_dynarr *
901 add_hscroll_rune (pos_data *data)
903 struct glyph_block gb;
904 prop_block_dynarr *retval;
905 Bytind bi_old_cursor_bufpos = data->bi_cursor_bufpos;
906 unsigned int old_cursor_type = data->cursor_type;
907 Bytind bi_old_bufpos = data->bi_bufpos;
909 if (data->cursor_type == CURSOR_ON
910 && data->bi_cursor_bufpos >= data->bi_start_col_enabled
911 && data->bi_cursor_bufpos <= data->bi_bufpos)
913 data->bi_cursor_bufpos = data->bi_start_col_enabled;
917 data->cursor_type = NO_CURSOR;
920 data->bi_endpos = data->bi_bufpos;
921 data->bi_bufpos = data->bi_start_col_enabled;
924 gb.glyph = Vhscroll_glyph;
926 int oldpixpos = data->pixpos;
927 retval = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0,
928 GLYPH_CACHEL (XWINDOW (data->window),
929 HSCROLL_GLYPH_INDEX));
930 data->hscroll_glyph_width_adjust =
931 data->pixpos - oldpixpos - space_width (XWINDOW (data->window));
934 data->bi_cursor_bufpos = bi_old_cursor_bufpos;
935 data->cursor_type = old_cursor_type;
936 data->bi_bufpos = bi_old_bufpos;
938 data->bi_start_col_enabled = 0;
942 /* Adds a character rune to a display block. If there is not enough room
943 to fit the rune on the display block (as determined by the MAX_PIXPOS)
944 then it adds nothing and returns ADD_FAILED. If
945 NO_CONTRIBUTE_TO_LINE_HEIGHT is non-zero, don't allow the char's height
946 to affect the total line height. (See add_intbyte_string_runes()). */
948 static prop_block_dynarr *
949 add_emchar_rune_1 (pos_data *data, int no_contribute_to_line_height)
951 struct rune rb, *crb;
963 if (data->bi_start_col_enabled)
965 return add_hscroll_rune (data);
968 if (data->ch == '\n')
970 char_glyph = ASCII_TO_CHARC ('\n');
971 data->font_is_bogus = 0;
972 /* Cheesy end-of-line pseudo-character. */
973 width = data->blank_width;
979 char_glyph = CHAR_TO_CHARC (data->ch);
980 charset = CHARC_CHARSET (char_glyph);
981 if (!EQ (charset, data->last_charset) ||
982 data->findex != data->last_findex)
984 /* OK, we need to do things the hard way. */
985 struct window *w = XWINDOW (data->window);
986 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, data->findex);
987 Lisp_Object font_instance =
988 ensure_face_cachel_contains_charset (cachel, data->window,
990 Lisp_Font_Instance *fi;
992 if (EQ (font_instance, Vthe_null_font_instance))
994 font_instance = FACE_CACHEL_FONT (cachel, Vcharset_ascii);
995 data->font_is_bogus = 1;
998 data->font_is_bogus = 0;
1000 fi = XFONT_INSTANCE (font_instance);
1001 if (!fi->proportional_p)
1002 /* sweetness and light. */
1003 data->last_char_width = fi->width;
1005 data->last_char_width = -1;
1007 if (!no_contribute_to_line_height)
1009 data->new_ascent = max (data->new_ascent, (int) fi->ascent);
1010 data->new_descent = max (data->new_descent, (int) fi->descent);
1013 data->last_charset = charset;
1014 data->last_findex = data->findex;
1017 width = data->last_char_width;
1020 /* bummer. Proportional fonts. */
1021 width = redisplay_text_width_charc_string (XWINDOW (data->window),
1027 if (data->max_pixpos != -1 && (data->pixpos + width > data->max_pixpos))
1032 if (Dynarr_length (data->db->runes) < Dynarr_largest (data->db->runes))
1034 crb = Dynarr_atp (data->db->runes, Dynarr_length (data->db->runes));
1043 crb->findex = data->findex;
1044 crb->xpos = data->pixpos;
1046 if (data->bi_bufpos)
1048 if (NILP (data->string))
1050 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
1054 bytecount_to_charcount (XSTRING_DATA (data->string),
1057 else if (data->is_modeline)
1058 crb->bufpos = data->modeline_charpos;
1060 /* Text but not in buffer */
1062 crb->type = RUNE_CHAR;
1063 crb->object.cglyph = data->font_is_bogus
1064 ? ASCII_TO_CHARC ('~')
1068 if (data->cursor_type == CURSOR_ON)
1070 if (data->bi_bufpos == data->bi_cursor_bufpos)
1072 crb->cursor_type = CURSOR_ON;
1073 data->cursor_x = Dynarr_length (data->db->runes);
1076 crb->cursor_type = CURSOR_OFF;
1078 else if (data->cursor_type == NEXT_CURSOR)
1080 crb->cursor_type = CURSOR_ON;
1081 data->cursor_x = Dynarr_length (data->db->runes);
1082 data->cursor_type = NO_CURSOR;
1084 else if (data->cursor_type == IGNORE_CURSOR)
1085 crb->cursor_type = IGNORE_CURSOR;
1087 crb->cursor_type = CURSOR_OFF;
1090 Dynarr_add (data->db->runes, *crb);
1092 Dynarr_increment (data->db->runes);
1094 data->pixpos += width;
1099 static prop_block_dynarr *
1100 add_emchar_rune (pos_data *data)
1102 return add_emchar_rune_1 (data, 0);
1105 /* Given a string C_STRING of length C_LENGTH, call add_emchar_rune for
1106 each character in the string. Propagate any left-over data unless
1107 NO_PROP is non-zero. If NO_CONTRIBUTE_TO_LINE_HEIGHT is non-zero, don't
1108 allow this character to increase the total height of the line. (This is
1109 used when the character is part of a text glyph. In that case, the
1110 glyph code itself adjusts the line height as necessary, depending on
1111 whether glyph-contrib-p is true.) */
1113 static prop_block_dynarr *
1114 add_bufbyte_string_runes (pos_data *data, Bufbyte *c_string,
1115 Bytecount c_length, int no_prop,
1116 int no_contribute_to_line_height)
1118 Bufbyte *pos, *end = c_string + c_length;
1119 prop_block_dynarr *prop;
1121 /* #### This function is too simplistic. It needs to do the same
1122 sort of character interpretation (display-table lookup,
1123 ctl-arrow checking), etc. that create_text_block() does.
1124 The functionality to do this in that routine needs to be
1127 for (pos = c_string; pos < end;)
1129 Bufbyte *old_pos = pos;
1131 data->ch = charptr_emchar (pos);
1133 prop = add_emchar_rune_1 (data, no_contribute_to_line_height);
1141 struct prop_block pb;
1142 Bytecount len = end - pos;
1143 prop = Dynarr_new (prop_block);
1145 pb.type = PROP_STRING;
1146 pb.data.p_string.str = xnew_array (Bufbyte, len);
1147 strncpy ((char *) pb.data.p_string.str, (char *) pos, len);
1148 pb.data.p_string.len = len;
1150 Dynarr_add (prop, pb);
1155 assert (pos <= end);
1156 /* #### Duplicate code from add_string_to_fstring_db_runes
1157 should we do more?*/
1158 data->bytepos += pos - old_pos;
1164 /* Add a single rune of the specified width. The area covered by this
1165 rune will be displayed in the foreground color of the associated
1168 static prop_block_dynarr *
1169 add_blank_rune (pos_data *data, struct window *w, int char_tab_width)
1173 /* If data->start_col is not 0 then this call to add_blank_rune must have
1174 been to add it as a tab. */
1175 if (data->start_col)
1177 /* assert (w != NULL) */
1178 prop_block_dynarr *retval;
1180 /* If we have still not fully scrolled horizontally, subtract
1181 the width of this tab and return. */
1182 if (char_tab_width < data->start_col)
1184 data->start_col -= char_tab_width;
1187 else if (char_tab_width == data->start_col)
1188 data->blank_width = 0;
1191 int spcwid = space_width (w);
1193 if (spcwid >= data->blank_width)
1194 data->blank_width = 0;
1196 data->blank_width -= spcwid;
1199 data->start_col = 0;
1200 retval = add_hscroll_rune (data);
1202 /* Could be caused by the handling of the hscroll rune. */
1203 if (retval != NULL || !data->blank_width)
1207 /* Blank runes are always calculated to fit. */
1208 assert (data->pixpos + data->blank_width <= data->max_pixpos);
1210 rb.findex = data->findex;
1211 rb.xpos = data->pixpos;
1212 rb.width = data->blank_width;
1213 if (data->bi_bufpos)
1215 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
1218 /* #### and this is really correct too? */
1221 rb.type = RUNE_BLANK;
1223 if (data->cursor_type == CURSOR_ON)
1225 if (data->bi_bufpos == data->bi_cursor_bufpos)
1227 rb.cursor_type = CURSOR_ON;
1228 data->cursor_x = Dynarr_length (data->db->runes);
1231 rb.cursor_type = CURSOR_OFF;
1233 else if (data->cursor_type == NEXT_CURSOR)
1235 rb.cursor_type = CURSOR_ON;
1236 data->cursor_x = Dynarr_length (data->db->runes);
1237 data->cursor_type = NO_CURSOR;
1240 rb.cursor_type = CURSOR_OFF;
1242 Dynarr_add (data->db->runes, rb);
1243 data->pixpos += data->blank_width;
1248 /* Add runes representing a character in octal. */
1250 #define ADD_NEXT_OCTAL_RUNE_CHAR do \
1252 if (add_failed || (add_failed = add_emchar_rune (data))) \
1254 struct prop_block pb; \
1256 prop = Dynarr_new (prop_block); \
1258 pb.type = PROP_CHAR; \
1259 pb.data.p_char.ch = data->ch; \
1260 pb.data.p_char.cursor_type = data->cursor_type; \
1261 Dynarr_add (prop, pb); \
1265 static prop_block_dynarr *
1266 add_octal_runes (pos_data *data)
1268 prop_block_dynarr *add_failed, *prop = 0;
1269 Emchar orig_char = data->ch;
1270 unsigned int orig_cursor_type = data->cursor_type;
1275 if (data->start_col)
1278 if (!data->start_col)
1280 if (data->bi_start_col_enabled)
1282 add_failed = add_hscroll_rune (data);
1286 struct glyph_block gb;
1287 struct window *w = XWINDOW (data->window);
1290 gb.glyph = Voctal_escape_glyph;
1292 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1293 GLYPH_CACHEL (w, OCT_ESC_GLYPH_INDEX));
1297 /* We only propagate information if the glyph was partially
1302 data->cursor_type = IGNORE_CURSOR;
1304 if (data->ch >= 0x100)
1306 /* If the character is an extended Mule character, it could have
1307 up to 19 bits. For the moment, we treat it as a seven-digit
1308 octal number. This is not that pretty, but whatever. */
1309 data->ch = (7 & (orig_char >> 18)) + '0';
1310 ADD_NEXT_OCTAL_RUNE_CHAR;
1312 data->ch = (7 & (orig_char >> 15)) + '0';
1313 ADD_NEXT_OCTAL_RUNE_CHAR;
1315 data->ch = (7 & (orig_char >> 12)) + '0';
1316 ADD_NEXT_OCTAL_RUNE_CHAR;
1318 data->ch = (7 & (orig_char >> 9)) + '0';
1319 ADD_NEXT_OCTAL_RUNE_CHAR;
1322 data->ch = (7 & (orig_char >> 6)) + '0';
1323 ADD_NEXT_OCTAL_RUNE_CHAR;
1325 data->ch = (7 & (orig_char >> 3)) + '0';
1326 ADD_NEXT_OCTAL_RUNE_CHAR;
1328 data->ch = (7 & orig_char) + '0';
1329 ADD_NEXT_OCTAL_RUNE_CHAR;
1331 data->cursor_type = orig_cursor_type;
1335 #undef ADD_NEXT_OCTAL_RUNE_CHAR
1337 /* Add runes representing a control character to a display block. */
1339 static prop_block_dynarr *
1340 add_control_char_runes (pos_data *data, struct buffer *b)
1342 if (!NILP (b->ctl_arrow))
1344 prop_block_dynarr *prop;
1345 Emchar orig_char = data->ch;
1346 unsigned int old_cursor_type = data->cursor_type;
1351 if (data->start_col)
1354 if (!data->start_col)
1356 if (data->bi_start_col_enabled)
1358 prop_block_dynarr *retval;
1360 retval = add_hscroll_rune (data);
1366 struct glyph_block gb;
1367 struct window *w = XWINDOW (data->window);
1370 gb.glyph = Vcontrol_arrow_glyph;
1372 /* We only propagate information if the glyph was partially
1374 if (add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1375 GLYPH_CACHEL (w, CONTROL_GLYPH_INDEX)))
1380 if (orig_char == 0177)
1383 data->ch = orig_char ^ 0100;
1384 data->cursor_type = IGNORE_CURSOR;
1386 if (add_emchar_rune (data))
1388 struct prop_block pb;
1390 prop = Dynarr_new (prop_block);
1392 pb.type = PROP_CHAR;
1393 pb.data.p_char.ch = data->ch;
1394 pb.data.p_char.cursor_type = data->cursor_type;
1395 Dynarr_add (prop, pb);
1398 data->cursor_type = old_cursor_type;
1403 return add_octal_runes (data);
1407 static prop_block_dynarr *
1408 add_disp_table_entry_runes_1 (pos_data *data, Lisp_Object entry)
1410 prop_block_dynarr *prop = NULL;
1412 if (STRINGP (entry))
1414 prop = add_bufbyte_string_runes (data,
1415 XSTRING_DATA (entry),
1416 XSTRING_LENGTH (entry),
1419 else if (GLYPHP (entry))
1421 if (data->start_col)
1424 if (!data->start_col && data->bi_start_col_enabled)
1426 prop = add_hscroll_rune (data);
1430 struct glyph_block gb;
1434 prop = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
1437 else if (CHAR_OR_CHAR_INTP (entry))
1439 data->ch = XCHAR_OR_CHAR_INT (entry);
1440 prop = add_emchar_rune (data);
1442 else if (CONSP (entry))
1444 if (EQ (XCAR (entry), Qformat)
1445 && CONSP (XCDR (entry))
1446 && STRINGP (XCAR (XCDR (entry))))
1448 Lisp_Object format = XCAR (XCDR (entry));
1449 Bytind len = XSTRING_LENGTH (format);
1450 Bufbyte *src = XSTRING_DATA (format), *end = src + len;
1451 Bufbyte *result = alloca_array (Bufbyte, len);
1452 Bufbyte *dst = result;
1456 Emchar c = charptr_emchar (src);
1458 if (c != '%' || src == end)
1459 dst += set_charptr_emchar (dst, c);
1462 c = charptr_emchar (src);
1467 dst += long_to_string_base ((char *)dst, data->ch, 16);
1470 dst += set_charptr_emchar (dst, '%');
1472 /* #### unimplemented */
1476 prop = add_bufbyte_string_runes (data, result, dst - result, 0, 0);
1480 /* Else blow it off because someone added a bad entry and we don't
1481 have any safe way of signaling an error. */
1485 /* Given a display table entry, call the appropriate functions to
1486 display each element of the entry. */
1488 static prop_block_dynarr *
1489 add_disp_table_entry_runes (pos_data *data, Lisp_Object entry)
1491 prop_block_dynarr *prop = NULL;
1492 if (VECTORP (entry))
1494 Lisp_Vector *de = XVECTOR (entry);
1495 EMACS_INT len = vector_length (de);
1498 for (elt = 0; elt < len; elt++)
1500 if (NILP (vector_data (de)[elt]))
1503 prop = add_disp_table_entry_runes_1 (data, vector_data (de)[elt]);
1504 /* Else blow it off because someone added a bad entry and we
1505 don't have any safe way of signaling an error. Hey, this
1506 comment sounds familiar. */
1508 /* #### Still need to add any remaining elements to the
1509 propagation information. */
1515 prop = add_disp_table_entry_runes_1 (data, entry);
1519 /* Add runes which were propagated from the previous line. */
1521 static prop_block_dynarr *
1522 add_propagation_runes (prop_block_dynarr **prop, pos_data *data)
1524 /* #### Remember to handle start_col parameter of data when the rest of
1525 this is finished. */
1526 /* #### Chuck -- I've redone this function a bit. It looked like the
1527 case of not all the propagation blocks being added was not handled
1529 /* #### Chuck -- I also think the double indirection of PROP is kind
1530 of bogus. A cleaner solution is just to check for
1531 Dynarr_length (prop) > 0. */
1532 /* #### This function also doesn't even pay attention to ADD_FAILED!
1533 This is seriously fucked! Seven ####'s in 130 lines -- is that a
1536 prop_block_dynarr *add_failed;
1537 Bytind bi_old_cursor_bufpos = data->bi_cursor_bufpos;
1538 unsigned int old_cursor_type = data->cursor_type;
1540 for (elt = 0; elt < Dynarr_length (*prop); elt++)
1542 struct prop_block *pb = Dynarr_atp (*prop, elt);
1547 data->ch = pb->data.p_char.ch;
1548 data->bi_cursor_bufpos = pb->data.p_char.bi_cursor_bufpos;
1549 data->cursor_type = pb->data.p_char.cursor_type;
1550 add_failed = add_emchar_rune (data);
1553 goto oops_no_more_space;
1556 if (pb->data.p_string.str)
1557 xfree (pb->data.p_string.str);
1558 /* #### bogus bogus -- this doesn't do anything!
1559 Should probably call add_bufbyte_string_runes(),
1560 once that function is fixed. */
1562 case PROP_MINIBUF_PROMPT:
1564 face_index old_findex = data->findex;
1565 Bytind bi_old_bufpos = data->bi_bufpos;
1567 data->findex = DEFAULT_INDEX;
1568 data->bi_bufpos = 0;
1569 data->cursor_type = NO_CURSOR;
1571 while (pb->data.p_string.len > 0)
1573 data->ch = charptr_emchar (pb->data.p_string.str);
1574 add_failed = add_emchar_rune (data);
1578 data->findex = old_findex;
1579 data->bi_bufpos = bi_old_bufpos;
1580 goto oops_no_more_space;
1584 /* Complicated equivalent of ptr++, len-- */
1585 Bufbyte *oldpos = pb->data.p_string.str;
1586 INC_CHARPTR (pb->data.p_string.str);
1587 pb->data.p_string.len -= pb->data.p_string.str - oldpos;
1591 data->findex = old_findex;
1592 /* ##### FIXME FIXME FIXME -- Upon successful return from
1593 this function, data->bi_bufpos is automatically incremented.
1594 However, we don't want that to happen if we were adding
1595 the minibuffer prompt. */
1597 struct buffer *buf =
1598 XBUFFER (WINDOW_BUFFER (XWINDOW (data->window)));
1599 /* #### Chuck fix this shit or I'm gonna scream! */
1600 if (bi_old_bufpos > BI_BUF_BEGV (buf))
1601 data->bi_bufpos = prev_bytind (buf, bi_old_bufpos);
1603 /* #### is this correct? Does anyone know?
1604 Does anyone care? Is this a cheesy hack or what? */
1605 data->bi_bufpos = BI_BUF_BEGV (buf) - 1;
1611 /* #### I think it's unnecessary and misleading to preserve
1612 the blank_width, as it implies that the value carries
1613 over from one rune to the next, which is wrong. */
1614 int old_width = data->blank_width;
1615 face_index old_findex = data->findex;
1617 data->findex = pb->data.p_blank.findex;
1618 data->blank_width = pb->data.p_blank.width;
1619 data->bi_cursor_bufpos = 0;
1620 data->cursor_type = IGNORE_CURSOR;
1622 if (data->pixpos + data->blank_width > data->max_pixpos)
1623 data->blank_width = data->max_pixpos - data->pixpos;
1625 /* We pass a bogus value of char_tab_width. It shouldn't
1626 matter because unless something is really screwed up
1627 this call won't cause that arg to be used. */
1628 add_failed = add_blank_rune (data, XWINDOW (data->window), 0);
1630 /* This can happen in the case where we have a tab which
1631 is wider than the window. */
1632 if (data->blank_width != pb->data.p_blank.width)
1634 pb->data.p_blank.width -= data->blank_width;
1635 add_failed = ADD_FAILED;
1638 data->findex = old_findex;
1639 data->blank_width = old_width;
1642 goto oops_no_more_space;
1652 data->bi_cursor_bufpos = bi_old_cursor_bufpos;
1653 data->cursor_type = old_cursor_type;
1654 if (elt < Dynarr_length (*prop))
1656 Dynarr_delete_many (*prop, 0, elt);
1661 Dynarr_free (*prop);
1666 /* Add 'text layout glyphs at position POS_TYPE that are contained to
1667 the display block, but add all other types to the appropriate list
1668 of the display line. They will be added later by different
1671 static prop_block_dynarr *
1672 add_glyph_rune (pos_data *data, struct glyph_block *gb, int pos_type,
1673 int allow_cursor, struct glyph_cachel *cachel)
1675 struct window *w = XWINDOW (data->window);
1677 /* If window faces changed, and glyph instance is text, then
1678 glyph sizes might have changed too */
1679 invalidate_glyph_geometry_maybe (gb->glyph, w);
1681 /* This makes sure the glyph is in the cachels.
1683 #### We do this to make sure the glyph is in the glyph cachels,
1684 so that the dirty flag can be reset after redisplay has
1685 finished. We should do this some other way, maybe by iterating
1686 over the window cache of subwindows. */
1687 get_glyph_cachel_index (w, gb->glyph);
1689 /* A nil extent indicates a special glyph (ex. truncator). */
1690 if (NILP (gb->extent)
1691 || (pos_type == BEGIN_GLYPHS &&
1692 extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1693 || (pos_type == END_GLYPHS &&
1694 extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1695 || pos_type == LEFT_GLYPHS || pos_type == RIGHT_GLYPHS)
1700 int ascent, descent;
1701 Lisp_Object baseline;
1703 Lisp_Object instance;
1705 prop_block_dynarr *retval = 0;
1708 width = cachel->width;
1710 width = glyph_width (gb->glyph, data->window);
1715 if (data->start_col || data->start_col_xoffset)
1717 int glyph_char_width = width / space_width (w);
1719 /* If we still have not fully scrolled horizontally after
1720 taking into account the width of the glyph, subtract its
1721 width and return. */
1722 if (glyph_char_width < data->start_col)
1724 data->start_col -= glyph_char_width;
1727 else if (glyph_char_width == data->start_col)
1731 xoffset = space_width (w) * data->start_col;
1734 /* #### Can this happen? */
1739 data->start_col = 0;
1740 retval = add_hscroll_rune (data);
1742 /* Could be caused by the handling of the hscroll rune. */
1743 if (retval != NULL || !width)
1749 if (data->pixpos + width > data->max_pixpos)
1751 /* If this is the first object we are attempting to add to
1752 the line then we ignore the horizontal_clip threshold.
1753 Otherwise we will loop until the bottom of the window
1754 continually failing to add this glyph because it is wider
1755 than the window. We could alternatively just completely
1756 ignore the glyph and proceed from there but I think that
1757 this is a better solution.
1759 This does, however, create a different problem in that we
1760 can end up adding the object to every single line, never
1761 getting any further - for instance an extent with a long
1762 start-glyph that covers multitple following
1764 if (Dynarr_length (data->db->runes)
1765 && data->max_pixpos - data->pixpos < horizontal_clip)
1768 struct prop_block pb;
1770 /* We need to account for the width of the end-of-line
1771 glyph if there is nothing more in the line to display,
1772 since we will not display it in this instance. It seems
1773 kind of gross doing it here, but otherwise we have to
1774 search the runes in create_text_block(). */
1775 if (data->ch == '\n')
1776 data->max_pixpos += data->end_glyph_width;
1777 width = data->max_pixpos - data->pixpos;
1778 /* Add the glyph we are displaying, but clipping, to the
1779 propagation data so that we don't try and do it
1781 retval = Dynarr_new (prop_block);
1782 pb.type = PROP_GLYPH;
1783 pb.data.p_glyph.glyph = gb->glyph;
1784 pb.data.p_glyph.width = width;
1785 Dynarr_add (retval, pb);
1791 ascent = cachel->ascent;
1792 descent = cachel->descent;
1796 ascent = glyph_ascent (gb->glyph, data->window);
1797 descent = glyph_descent (gb->glyph, data->window);
1800 baseline = glyph_baseline (gb->glyph, data->window);
1802 rb.object.dglyph.descent = 0; /* Gets reset lower down, if it is known. */
1804 if (glyph_contrib_p (gb->glyph, data->window))
1806 /* A pixmap that has not had a baseline explicitly set. Its
1807 contribution will be determined later. */
1808 if (NILP (baseline))
1810 int height = ascent + descent;
1811 data->need_baseline_computation = 1;
1812 data->max_pixmap_height = max (data->max_pixmap_height, height);
1815 /* A string so determine contribution normally. */
1816 else if (EQ (baseline, Qt))
1818 data->new_ascent = max (data->new_ascent, ascent);
1819 data->new_descent = max (data->new_descent, descent);
1822 /* A pixmap with an explicitly set baseline. We determine the
1823 contribution here. */
1824 else if (INTP (baseline))
1826 int height = ascent + descent;
1827 int pix_ascent, pix_descent;
1829 pix_ascent = height * XINT (baseline) / 100;
1830 pix_descent = height - pix_ascent;
1832 data->new_ascent = max (data->new_ascent, pix_ascent);
1833 data->new_descent = max (data->new_descent, pix_descent);
1834 data->max_pixmap_height = max (data->max_pixmap_height, height);
1836 rb.object.dglyph.descent = pix_descent;
1839 /* Otherwise something is screwed up. */
1844 face = glyph_face (gb->glyph, data->window);
1846 findex = data->findex;
1848 findex = get_builtin_face_cache_index (w, face);
1850 instance = glyph_image_instance (gb->glyph, data->window,
1852 if (TEXT_IMAGE_INSTANCEP (instance))
1854 Lisp_Object string = XIMAGE_INSTANCE_TEXT_STRING (instance);
1855 face_index orig_findex = data->findex;
1856 Bytind orig_bufpos = data->bi_bufpos;
1857 Bytind orig_start_col_enabled = data->bi_start_col_enabled;
1859 data->findex = findex;
1860 data->bi_start_col_enabled = 0;
1862 data->bi_bufpos = 0;
1863 add_bufbyte_string_runes (data, XSTRING_DATA (string),
1864 XSTRING_LENGTH (string), 0, 1);
1865 data->findex = orig_findex;
1866 data->bi_bufpos = orig_bufpos;
1867 data->bi_start_col_enabled = orig_start_col_enabled;
1872 rb.xpos = data->pixpos;
1874 rb.bufpos = 0; /* glyphs are never "at" anywhere */
1875 if (data->bi_endpos)
1876 /* #### is this necessary at all? */
1877 rb.endpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1881 rb.type = RUNE_DGLYPH;
1882 rb.object.dglyph.glyph = gb->glyph;
1883 rb.object.dglyph.extent = gb->extent;
1884 rb.object.dglyph.xoffset = xoffset;
1885 rb.object.dglyph.ascent = ascent;
1886 rb.object.dglyph.yoffset = 0; /* Until we know better, assume that it has
1887 a normal (textual) baseline. */
1891 rb.bufpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1894 if (data->cursor_type == CURSOR_ON)
1896 if (data->bi_bufpos == data->bi_cursor_bufpos)
1898 rb.cursor_type = CURSOR_ON;
1899 data->cursor_x = Dynarr_length (data->db->runes);
1902 rb.cursor_type = CURSOR_OFF;
1904 else if (data->cursor_type == NEXT_CURSOR)
1906 rb.cursor_type = CURSOR_ON;
1907 data->cursor_x = Dynarr_length (data->db->runes);
1908 data->cursor_type = NO_CURSOR;
1910 else if (data->cursor_type == IGNORE_CURSOR)
1911 rb.cursor_type = IGNORE_CURSOR;
1912 else if (data->cursor_type == NO_CURSOR)
1913 rb.cursor_type = NO_CURSOR;
1915 rb.cursor_type = CURSOR_OFF;
1918 rb.cursor_type = CURSOR_OFF;
1920 Dynarr_add (data->db->runes, rb);
1921 data->pixpos += width;
1927 if (!NILP (glyph_face (gb->glyph, data->window)))
1929 get_builtin_face_cache_index (w, glyph_face (gb->glyph,
1932 gb->findex = data->findex;
1934 if (pos_type == BEGIN_GLYPHS)
1936 if (!data->dl->left_glyphs)
1937 data->dl->left_glyphs = Dynarr_new (glyph_block);
1938 Dynarr_add (data->dl->left_glyphs, *gb);
1941 else if (pos_type == END_GLYPHS)
1943 if (!data->dl->right_glyphs)
1944 data->dl->right_glyphs = Dynarr_new (glyph_block);
1945 Dynarr_add (data->dl->right_glyphs, *gb);
1949 abort (); /* there are no unknown types */
1955 /* Add all glyphs at position POS_TYPE that are contained in the given
1958 static prop_block_dynarr *
1959 add_glyph_runes (pos_data *data, int pos_type)
1961 /* #### This still needs to handle the start_col parameter. Duh, Chuck,
1962 why didn't you just modify add_glyph_rune in the first place? */
1964 glyph_block_dynarr *glyph_arr = (pos_type == BEGIN_GLYPHS
1965 ? data->ef->begin_glyphs
1966 : data->ef->end_glyphs);
1967 prop_block_dynarr *prop;
1969 for (elt = 0; elt < Dynarr_length (glyph_arr); elt++)
1971 prop = add_glyph_rune (data, Dynarr_atp (glyph_arr, elt), pos_type, 0,
1976 /* #### Add some propagation information. */
1981 Dynarr_reset (glyph_arr);
1986 /* Given a position for a buffer in a window, ensure that the given
1987 display line DL accurately represents the text on a line starting
1988 at the given position.
1990 NOTE NOTE NOTE NOTE: This function works with and returns Bytinds.
1991 You must do appropriate conversion. */
1994 create_text_block (struct window *w, struct display_line *dl,
1995 Bytind bi_start_pos, prop_block_dynarr **prop,
1998 struct frame *f = XFRAME (w->frame);
1999 struct buffer *b = XBUFFER (w->buffer);
2000 struct device *d = XDEVICE (f->device);
2004 /* Don't display anything in the minibuffer if this window is not on
2005 a selected frame. We consider all other windows to be active
2006 minibuffers as it simplifies the coding. */
2007 int active_minibuffer = (!MINI_WINDOW_P (w) ||
2008 (f == device_selected_frame (d)) ||
2009 is_surrogate_for_selected_frame (f));
2011 int truncate_win = window_truncation_on (w);
2013 /* If the buffer's value of selective_display is an integer then
2014 only lines that start with less than selective_display columns of
2015 space will be displayed. If selective_display is t then all text
2016 after a ^M is invisible. */
2017 int selective = (INTP (b->selective_display)
2018 ? XINT (b->selective_display)
2019 : (!NILP (b->selective_display) ? -1 : 0));
2021 /* The variable ctl-arrow allows the user to specify what characters
2022 can actually be displayed and which octal should be used for.
2023 #### This variable should probably have some rethought done to
2026 #### It would also be really nice if you could specify that
2027 the characters come out in hex instead of in octal. Mule
2028 does that by adding a ctl-hexa variable similar to ctl-arrow,
2029 but that's bogus -- we need a more general solution. I
2030 think you need to extend the concept of display tables
2031 into a more general conversion mechanism. Ideally you
2032 could specify a Lisp function that converts characters,
2033 but this violates the Second Golden Rule and besides would
2034 make things way way way way slow.
2036 So instead, we extend the display-table concept, which was
2037 historically limited to 256-byte vectors, to one of the
2040 a) A 256-entry vector, for backward compatibility;
2041 b) char-table, mapping characters to values;
2042 c) range-table, mapping ranges of characters to values;
2043 d) a list of the above.
2045 The (d) option allows you to specify multiple display tables
2046 instead of just one. Each display table can specify conversions
2047 for some characters and leave others unchanged. The way the
2048 character gets displayed is determined by the first display table
2049 with a binding for that character. This way, you could call a
2050 function `enable-hex-display' that adds a hex display-table to
2051 the list of display tables for the current buffer.
2053 #### ...not yet implemented... Also, we extend the concept of
2054 "mapping" to include a printf-like spec. Thus you can make all
2055 extended characters show up as hex with a display table like
2058 #s(range-table data ((256 524288) (format "%x")))
2060 Since more than one display table is possible, you have
2061 great flexibility in mapping ranges of characters. */
2062 Emchar printable_min = (CHAR_OR_CHAR_INTP (b->ctl_arrow)
2063 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
2064 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
2067 Lisp_Object face_dt, window_dt;
2069 /* The text display block for this display line. */
2070 struct display_block *db = get_display_block_from_line (dl, TEXT);
2072 /* The first time through the main loop we need to force the glyph
2073 data to be updated. */
2076 /* Apparently the new extent_fragment_update returns an end position
2077 equal to the position passed in if there are no more runs to be
2079 int no_more_frags = 0;
2081 Lisp_Object synch_minibuffers_value =
2082 symbol_value_in_buffer (Qsynchronize_minibuffers, w->buffer);
2084 dl->used_prop_data = 0;
2086 dl->line_continuation = 0;
2089 data.ef = extent_fragment_new (w->buffer, f);
2091 /* These values are used by all of the rune addition routines. We add
2092 them to this structure for ease of passing. */
2094 XSETWINDOW (data.window, w);
2099 data.bi_bufpos = bi_start_pos;
2100 data.pixpos = dl->bounds.left_in;
2101 data.last_charset = Qunbound;
2102 data.last_findex = DEFAULT_INDEX;
2103 data.result_str = Qnil;
2105 /* Set the right boundary adjusting it to take into account any end
2106 glyph. Save the width of the end glyph for later use. */
2107 data.max_pixpos = dl->bounds.right_in;
2109 data.end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
2111 data.end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
2112 data.max_pixpos -= data.end_glyph_width;
2114 if (cursor_in_echo_area && MINI_WINDOW_P (w) && echo_area_active (f))
2116 data.bi_cursor_bufpos = BI_BUF_ZV (b);
2117 data.cursor_type = CURSOR_ON;
2119 else if (MINI_WINDOW_P (w) && !active_minibuffer)
2120 data.cursor_type = NO_CURSOR;
2121 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)) &&
2122 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
2123 d == XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d))))&&
2124 f == XFRAME(DEVICE_SELECTED_FRAME(d)))
2126 data.bi_cursor_bufpos = BI_BUF_PT (b);
2127 data.cursor_type = CURSOR_ON;
2129 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)))
2131 data.bi_cursor_bufpos = bi_marker_position (w->pointm[type]);
2132 data.cursor_type = CURSOR_ON;
2135 data.cursor_type = NO_CURSOR;
2138 data.start_col = w->hscroll;
2139 data.start_col_xoffset = w->left_xoffset;
2140 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
2141 data.hscroll_glyph_width_adjust = 0;
2143 /* We regenerate the line from the very beginning. */
2144 Dynarr_reset (db->runes);
2146 /* Why is this less than or equal and not just less than? If the
2147 starting position is already equal to the maximum we can't add
2148 anything else, right? Wrong. We might still have a newline to
2149 add. A newline can use the room allocated for an end glyph since
2150 if we add it we know we aren't going to be adding any end
2153 /* #### Chuck -- I think this condition should be while (1).
2154 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
2155 and the begin-glyph ends exactly at the end of the window, the
2156 end-glyph and text might not be displayed. while (1) ensures
2157 that the loop terminates only when either (a) there is
2158 propagation data or (b) the end-of-line or end-of-buffer is hit.
2160 #### Also I think you need to ensure that the operation
2161 "add begin glyphs; add end glyphs; add text" is atomic and
2162 can't get interrupted in the middle. If you run off the end
2163 of the line during that operation, then you keep accumulating
2164 propagation data until you're done. Otherwise, if the (e.g.)
2165 there's a begin glyph at a particular position and attempting
2166 to display that glyph results in window-end being hit and
2167 propagation data being generated, then the character at that
2168 position won't be displayed.
2170 #### See also the comment after the end of this loop, below.
2172 while (data.pixpos <= data.max_pixpos
2173 && (active_minibuffer || !NILP (synch_minibuffers_value)))
2175 /* #### This check probably should not be necessary. */
2176 if (data.bi_bufpos > BI_BUF_ZV (b))
2178 /* #### urk! More of this lossage! */
2183 /* If selective display was an integer and we aren't working on
2184 a continuation line then find the next line we are actually
2185 supposed to display. */
2187 && (data.bi_bufpos == BI_BUF_BEGV (b)
2188 || BUF_FETCH_CHAR (b, prev_bytind (b, data.bi_bufpos)) == '\n'))
2190 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2193 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2194 if (data.bi_bufpos >= BI_BUF_ZV (b))
2196 data.bi_bufpos = BI_BUF_ZV (b);
2202 /* Check for face changes. */
2203 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
2205 Lisp_Object last_glyph = Qnil;
2207 /* Deal with glyphs that we have already displayed. The
2208 theory is that if we end up with a PROP_GLYPH in the
2209 propagation data then we are clipping the glyph and there
2210 can be no propagation data before that point. The theory
2211 works because we always recalculate the extent-fragments
2212 for propagated data, we never actually propagate the
2213 fragments that still need to be displayed. */
2214 if (*prop && Dynarr_atp (*prop, 0)->type == PROP_GLYPH)
2216 last_glyph = Dynarr_atp (*prop, 0)->data.p_glyph.glyph;
2217 Dynarr_free (*prop);
2220 /* Now compute the face and begin/end-glyph information. */
2222 /* Remember that the extent-fragment routines deal in Bytind's. */
2223 extent_fragment_update (w, data.ef, data.bi_bufpos, last_glyph);
2225 get_display_tables (w, data.findex, &face_dt, &window_dt);
2227 if (data.bi_bufpos == data.ef->end)
2232 /* Determine what is next to be displayed. We first handle any
2233 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
2234 display then we determine what to do based on the character at the
2235 current buffer position. */
2237 /* If the current position is covered by an invisible extent, do
2238 nothing (except maybe add some ellipses).
2240 #### The behavior of begin and end-glyphs at the edge of an
2241 invisible extent should be investigated further. This is
2242 fairly low priority though. */
2243 if (data.ef->invisible)
2245 /* #### Chuck, perhaps you could look at this code? I don't
2246 really know what I'm doing. */
2249 Dynarr_free (*prop);
2253 /* The extent fragment code only sets this when we should
2254 really display the ellipses. It makes sure the ellipses
2255 don't get displayed more than once in a row. */
2256 if (data.ef->invisible_ellipses)
2258 struct glyph_block gb;
2260 data.ef->invisible_ellipses_already_displayed = 1;
2261 data.ef->invisible_ellipses = 0;
2263 gb.glyph = Vinvisible_text_glyph;
2264 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2265 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2266 /* Perhaps they shouldn't propagate if the very next thing
2267 is to display a newline (for compatibility with
2268 selective-display-ellipses)? Maybe that's too
2274 /* If point is in an invisible region we place it on the
2275 next visible character. */
2276 if (data.cursor_type == CURSOR_ON
2277 && data.bi_bufpos == data.bi_cursor_bufpos)
2279 data.cursor_type = NEXT_CURSOR;
2282 /* #### What if we we're dealing with a display table? */
2286 if (data.bi_bufpos == BI_BUF_ZV (b))
2289 INC_BYTIND (b, data.bi_bufpos);
2292 /* If there is propagation data, then it represents the current
2293 buffer position being displayed. Add them and advance the
2294 position counter. This might also add the minibuffer
2298 dl->used_prop_data = 1;
2299 *prop = add_propagation_runes (prop, &data);
2302 goto done; /* gee, a really narrow window */
2303 else if (data.bi_bufpos == BI_BUF_ZV (b))
2305 else if (data.bi_bufpos < BI_BUF_BEGV (b))
2306 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
2307 data.bi_bufpos = BI_BUF_BEGV (b);
2309 INC_BYTIND (b, data.bi_bufpos);
2312 /* If there are end glyphs, add them to the line. These are
2313 the end glyphs for the previous run of text. We add them
2314 here rather than doing them at the end of handling the
2315 previous run so that glyphs at the beginning and end of
2316 a line are handled correctly. */
2317 else if (Dynarr_length (data.ef->end_glyphs) > 0
2318 || Dynarr_length (data.ef->begin_glyphs) > 0)
2320 glyph_block_dynarr* tmpglyphs = 0;
2321 /* #### I think this is safe, but could be wrong. */
2322 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2324 if (Dynarr_length (data.ef->end_glyphs) > 0)
2326 *prop = add_glyph_runes (&data, END_GLYPHS);
2327 tmpglyphs = data.ef->end_glyphs;
2330 /* If there are begin glyphs, add them to the line. */
2331 if (!*prop && Dynarr_length (data.ef->begin_glyphs) > 0)
2333 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
2334 tmpglyphs = data.ef->begin_glyphs;
2339 /* If we just clipped a glyph and we are at the end of a
2340 line and there are more glyphs to display then do
2341 appropriate processing to not get a continuation
2343 if (*prop != ADD_FAILED
2344 && Dynarr_atp (*prop, 0)->type == PROP_GLYPH
2347 /* If there are no more glyphs then do the normal
2350 #### This doesn't actually work if the same glyph is
2351 present more than once in the block. To solve
2352 this we would have to carry the index around
2353 which might be problematic since the fragment is
2354 recalculated for each line. */
2355 if (EQ (Dynarr_end (tmpglyphs)->glyph,
2356 Dynarr_atp (*prop, 0)->data.p_glyph.glyph))
2358 Dynarr_free (*prop);
2362 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2363 add_emchar_rune (&data); /* discard prop data. */
2372 /* If at end-of-buffer, we've already processed begin and
2373 end-glyphs at this point and there's no text to process,
2375 else if (data.bi_bufpos == BI_BUF_ZV (b))
2380 Lisp_Object entry = Qnil;
2381 /* Get the character at the current buffer position. */
2382 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2383 if (!NILP (face_dt) || !NILP (window_dt))
2384 entry = display_table_entry (data.ch, face_dt, window_dt);
2386 /* If there is a display table entry for it, hand it off to
2387 add_disp_table_entry_runes and let it worry about it. */
2388 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
2390 *prop = add_disp_table_entry_runes (&data, entry);
2396 /* Check if we have hit a newline character. If so, add a marker
2397 to the line and end this loop. */
2398 else if (data.ch == '\n')
2400 /* We aren't going to be adding an end glyph so give its
2401 space back in order to make sure that the cursor can
2403 data.max_pixpos += data.end_glyph_width;
2406 && (bi_spaces_at_point
2407 (b, next_bytind (b, data.bi_bufpos))
2410 if (!NILP (b->selective_display_ellipses))
2412 struct glyph_block gb;
2415 gb.glyph = Vinvisible_text_glyph;
2416 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2417 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2421 /* Cheesy, cheesy, cheesy. We mark the end of the
2422 line with a special "character rune" whose width
2423 is the EOL cursor width and whose character is
2424 the non-printing character '\n'. */
2425 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2426 *prop = add_emchar_rune (&data);
2429 /* We need to set data.bi_bufpos to the start of the
2430 next visible region in order to make this line
2431 appear to contain all of the invisible area.
2432 Otherwise, the line cache won't work
2434 INC_BYTIND (b, data.bi_bufpos);
2435 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2438 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2439 if (data.bi_bufpos >= BI_BUF_ZV (b))
2441 data.bi_bufpos = BI_BUF_ZV (b);
2445 if (BI_BUF_FETCH_CHAR
2446 (b, prev_bytind (b, data.bi_bufpos)) == '\n')
2447 DEC_BYTIND (b, data.bi_bufpos);
2451 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2452 *prop = add_emchar_rune (&data);
2458 /* If the current character is ^M, and selective display is
2459 enabled, then add the invisible-text-glyph if
2460 selective-display-ellipses is set. In any case, this
2462 else if (data.ch == (('M' & 037)) && selective == -1)
2464 Bytind bi_next_bufpos;
2466 /* Find the buffer position at the end of the line. */
2468 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2469 if (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_next_bufpos))
2471 DEC_BYTIND (b, bi_next_bufpos);
2473 /* If the cursor is somewhere in the elided text make
2474 sure that the cursor gets drawn appropriately. */
2475 if (data.cursor_type == CURSOR_ON
2476 && (data.bi_cursor_bufpos >= data.bi_bufpos &&
2477 data.bi_cursor_bufpos < bi_next_bufpos))
2479 data.cursor_type = NEXT_CURSOR;
2482 /* We won't be adding a truncation or continuation glyph
2483 so give up the room allocated for them. */
2484 data.max_pixpos += data.end_glyph_width;
2486 if (!NILP (b->selective_display_ellipses))
2488 /* We don't propagate anything from the invisible
2489 text glyph if it fails to fit. This is
2491 struct glyph_block gb;
2494 gb.glyph = Vinvisible_text_glyph;
2495 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 1,
2496 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2499 /* Set the buffer position to the end of the line. We
2500 need to do this before potentially adding a newline
2501 so that the cursor flag will get set correctly (if
2503 data.bi_bufpos = bi_next_bufpos;
2505 if (NILP (b->selective_display_ellipses)
2506 || data.bi_cursor_bufpos == bi_next_bufpos)
2508 /* We have to at least add a newline character so
2509 that the cursor shows up properly. */
2511 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2512 data.findex = DEFAULT_INDEX;
2514 data.start_col_xoffset = 0;
2515 data.bi_start_col_enabled = 0;
2517 add_emchar_rune (&data);
2520 /* This had better be a newline but doing it this way
2521 we'll see obvious incorrect results if it isn't. No
2522 need to abort here. */
2523 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2528 /* If the current character is considered to be printable, then
2530 else if (data.ch >= printable_min)
2532 *prop = add_emchar_rune (&data);
2537 /* If the current character is a tab, determine the next tab
2538 starting position and add a blank rune which extends from the
2539 current pixel position to that starting position. */
2540 else if (data.ch == '\t')
2542 int tab_start_pixpos = data.pixpos;
2547 if (data.start_col > 1)
2548 tab_start_pixpos -= (space_width (w) * (data.start_col - 1))
2549 + data.start_col_xoffset;
2552 next_tab_position (w, tab_start_pixpos,
2553 dl->bounds.left_in +
2554 data.hscroll_glyph_width_adjust);
2555 if (next_tab_start > data.max_pixpos)
2557 prop_width = next_tab_start - data.max_pixpos;
2558 next_tab_start = data.max_pixpos;
2560 data.blank_width = next_tab_start - data.pixpos;
2562 (next_tab_start - tab_start_pixpos) / space_width (w);
2564 *prop = add_blank_rune (&data, w, char_tab_width);
2566 /* add_blank_rune is only supposed to be called with
2567 sizes guaranteed to fit in the available space. */
2572 struct prop_block pb;
2573 *prop = Dynarr_new (prop_block);
2575 pb.type = PROP_BLANK;
2576 pb.data.p_blank.width = prop_width;
2577 pb.data.p_blank.findex = data.findex;
2578 Dynarr_add (*prop, pb);
2584 /* If character is a control character, pass it off to
2585 add_control_char_runes.
2587 The is_*() routines have undefined results on
2588 arguments outside of the range [-1, 255]. (This
2589 often bites people who carelessly use `char' instead
2590 of `unsigned char'.)
2592 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
2594 *prop = add_control_char_runes (&data, b);
2600 /* If the character is above the ASCII range and we have not
2601 already handled it, then print it as an octal number. */
2602 else if (data.ch >= 0200)
2604 *prop = add_octal_runes (&data);
2610 /* Assume the current character is considered to be printable,
2611 then just add it. */
2614 *prop = add_emchar_rune (&data);
2619 INC_BYTIND (b, data.bi_bufpos);
2625 /* Determine the starting point of the next line if we did not hit the
2626 end of the buffer. */
2627 if (data.bi_bufpos < BI_BUF_ZV (b)
2628 && (active_minibuffer || !NILP (synch_minibuffers_value)))
2630 /* #### This check is not correct. If the line terminated
2631 due to a begin-glyph or end-glyph hitting window-end, then
2632 data.ch will not point to the character at data.bi_bufpos. If
2633 you make the two changes mentioned at the top of this loop,
2634 you should be able to say '(if (*prop))'. That should also
2635 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
2638 /* The common case is that the line ended because we hit a newline.
2639 In that case, the next character is just the next buffer
2641 if (data.ch == '\n')
2643 /* If data.start_col_enabled is still true, then the window is
2644 scrolled far enough so that nothing on this line is visible.
2645 We need to stick a truncation glyph at the beginning of the
2646 line in that case unless the line is completely blank. */
2647 if (data.bi_start_col_enabled)
2649 if (data.cursor_type == CURSOR_ON)
2651 if (data.bi_cursor_bufpos >= bi_start_pos
2652 && data.bi_cursor_bufpos <= data.bi_bufpos)
2653 data.bi_cursor_bufpos = data.bi_bufpos;
2655 data.findex = DEFAULT_INDEX;
2657 data.bi_start_col_enabled = 0;
2659 if (data.bi_bufpos != bi_start_pos)
2661 struct glyph_block gb;
2664 gb.glyph = Vhscroll_glyph;
2665 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2666 GLYPH_CACHEL (w, HSCROLL_GLYPH_INDEX));
2670 /* This duplicates code down below to add a newline to
2671 the end of an otherwise empty line.*/
2673 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2675 add_emchar_rune (&data);
2679 INC_BYTIND (b, data.bi_bufpos);
2682 /* Otherwise we have a buffer line which cannot fit on one display
2686 struct glyph_block gb;
2687 struct glyph_cachel *cachel;
2689 /* If the line is to be truncated then we actually have to look
2690 for the next newline. We also add the end-of-line glyph which
2691 we know will fit because we adjusted the right border before
2692 we starting laying out the line. */
2693 data.max_pixpos += data.end_glyph_width;
2694 data.findex = DEFAULT_INDEX;
2701 /* Now find the start of the next line. */
2702 bi_pos = bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2704 /* If the cursor is past the truncation line then we
2705 make it appear on the truncation glyph. If we've hit
2706 the end of the buffer then we also make the cursor
2707 appear unless eob is immediately preceded by a
2708 newline. In that case the cursor should actually
2709 appear on the next line. */
2710 if (data.cursor_type == CURSOR_ON
2711 && data.bi_cursor_bufpos >= data.bi_bufpos
2712 && (data.bi_cursor_bufpos < bi_pos ||
2713 (bi_pos == BI_BUF_ZV (b)
2714 && (bi_pos == BI_BUF_BEGV (b)
2715 || (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_pos))
2717 data.bi_cursor_bufpos = bi_pos;
2719 data.cursor_type = NO_CURSOR;
2721 data.bi_bufpos = bi_pos;
2722 gb.glyph = Vtruncation_glyph;
2723 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
2727 /* The cursor can never be on the continuation glyph. */
2728 data.cursor_type = NO_CURSOR;
2730 /* data.bi_bufpos is already at the start of the next line. */
2732 dl->line_continuation = 1;
2733 gb.glyph = Vcontinuation_glyph;
2734 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
2737 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
2739 if (truncate_win && data.bi_bufpos == BI_BUF_ZV (b)
2740 && BI_BUF_FETCH_CHAR (b, prev_bytind (b, BI_BUF_ZV (b))) != '\n')
2741 /* #### Damn this losing shit. */
2745 else if ((active_minibuffer || !NILP (synch_minibuffers_value))
2746 && (!echo_area_active (f) || data.bi_bufpos == BI_BUF_ZV (b)))
2748 /* We need to add a marker to the end of the line since there is no
2749 newline character in order for the cursor to get drawn. We label
2750 it as a newline so that it gets handled correctly by the
2751 whitespace routines below. */
2754 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2755 data.findex = DEFAULT_INDEX;
2757 data.start_col_xoffset = 0;
2758 data.bi_start_col_enabled = 0;
2760 data.max_pixpos += data.blank_width;
2761 add_emchar_rune (&data);
2762 data.max_pixpos -= data.blank_width;
2764 /* #### urk! Chuck, this shit is bad news. Going around
2765 manipulating invalid positions is guaranteed to result in
2766 trouble sooner or later. */
2767 data.bi_bufpos = BI_BUF_ZV (b) + 1;
2770 /* Calculate left whitespace boundary. */
2774 /* Whitespace past a newline is considered right whitespace. */
2775 while (elt < Dynarr_length (db->runes))
2777 struct rune *rb = Dynarr_atp (db->runes, elt);
2779 if ((rb->type == RUNE_CHAR && CHARC_ASCII_EQ (rb->object.cglyph, ' '))
2780 || rb->type == RUNE_BLANK)
2782 dl->bounds.left_white += rb->width;
2786 elt = Dynarr_length (db->runes);
2790 /* Calculate right whitespace boundary. */
2792 int elt = Dynarr_length (db->runes) - 1;
2795 while (!done && elt >= 0)
2797 struct rune *rb = Dynarr_atp (db->runes, elt);
2799 if (!(rb->type == RUNE_CHAR && CHARC_IS_SPACE (rb->object.cglyph))
2800 && !rb->type == RUNE_BLANK)
2802 dl->bounds.right_white = rb->xpos + rb->width;
2810 /* The line is blank so everything is considered to be right
2813 dl->bounds.right_white = dl->bounds.left_in;
2816 /* Set the display blocks bounds. */
2817 db->start_pos = dl->bounds.left_in;
2818 if (Dynarr_length (db->runes))
2820 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
2822 db->end_pos = rb->xpos + rb->width;
2825 db->end_pos = dl->bounds.right_white;
2827 calculate_baseline (&data);
2829 dl->ascent = data.new_ascent;
2830 dl->descent = data.new_descent;
2833 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
2835 if (dl->ascent < ascent)
2836 dl->ascent = ascent;
2839 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
2841 if (dl->descent < descent)
2842 dl->descent = descent;
2845 calculate_yoffset (dl, db);
2847 dl->cursor_elt = data.cursor_x;
2848 /* #### lossage lossage lossage! Fix this shit! */
2849 if (data.bi_bufpos > BI_BUF_ZV (b))
2850 dl->end_bufpos = BUF_ZV (b);
2852 dl->end_bufpos = bytind_to_bufpos (b, data.bi_bufpos) - 1;
2854 data.dl->num_chars = column_at_point (b, dl->end_bufpos, 0);
2856 /* This doesn't correctly take into account tabs and control
2857 characters but if the window isn't being truncated then this
2858 value isn't going to end up being used anyhow. */
2859 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
2861 /* #### handle horizontally scrolled line with text none of which
2862 was actually laid out. */
2864 /* #### handle any remainder of overlay arrow */
2866 if (*prop == ADD_FAILED)
2869 if (truncate_win && *prop)
2871 Dynarr_free (*prop);
2875 extent_fragment_delete (data.ef);
2877 /* #### If we started at EOB, then make sure we return a value past
2878 it so that regenerate_window will exit properly. This is bogus.
2879 The main loop should get fixed so that it isn't necessary to call
2880 this function if we are already at EOB. */
2882 if (data.bi_bufpos == BI_BUF_ZV (b) && bi_start_pos == BI_BUF_ZV (b))
2883 return data.bi_bufpos + 1; /* Yuck! */
2885 return data.bi_bufpos;
2888 /* Display the overlay arrow at the beginning of the given line. */
2891 create_overlay_glyph_block (struct window *w, struct display_line *dl)
2893 struct frame *f = XFRAME (w->frame);
2894 struct device *d = XDEVICE (f->device);
2897 /* If Voverlay_arrow_string isn't valid then just fail silently. */
2898 if (!STRINGP (Voverlay_arrow_string) && !GLYPHP (Voverlay_arrow_string))
2904 XSETWINDOW (data.window, w);
2905 data.db = get_display_block_from_line (dl, OVERWRITE);
2907 data.pixpos = dl->bounds.left_in;
2908 data.max_pixpos = dl->bounds.right_in;
2909 data.cursor_type = NO_CURSOR;
2911 data.findex = DEFAULT_INDEX;
2912 data.last_charset = Qunbound;
2913 data.last_findex = DEFAULT_INDEX;
2914 data.result_str = Qnil;
2917 Dynarr_reset (data.db->runes);
2919 if (STRINGP (Voverlay_arrow_string))
2921 add_bufbyte_string_runes
2923 XSTRING_DATA (Voverlay_arrow_string),
2924 XSTRING_LENGTH (Voverlay_arrow_string),
2927 else if (GLYPHP (Voverlay_arrow_string))
2929 struct glyph_block gb;
2931 gb.glyph = Voverlay_arrow_string;
2933 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, 0);
2936 calculate_baseline (&data);
2938 dl->ascent = data.new_ascent;
2939 dl->descent = data.new_descent;
2941 data.db->start_pos = dl->bounds.left_in;
2942 data.db->end_pos = data.pixpos;
2944 calculate_yoffset (dl, data.db);
2946 return data.pixpos - dl->bounds.left_in;
2949 /* Add a type of glyph to a margin display block. */
2952 add_margin_runes (struct display_line *dl, struct display_block *db, int start,
2953 int count, enum glyph_layout layout, int side, Lisp_Object window)
2955 glyph_block_dynarr *gbd = (side == LEFT_GLYPHS
2957 : dl->right_glyphs);
2960 struct window *w = XWINDOW (window);
2961 struct frame *f = XFRAME (w->frame);
2962 struct device *d = XDEVICE (f->device);
2967 data.window = window;
2970 data.pixpos = start;
2971 data.cursor_type = NO_CURSOR;
2973 data.last_charset = Qunbound;
2974 data.last_findex = DEFAULT_INDEX;
2975 data.result_str = Qnil;
2977 data.new_ascent = dl->ascent;
2978 data.new_descent = dl->descent;
2980 if ((layout == GL_WHITESPACE && side == LEFT_GLYPHS)
2981 || (layout == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS))
2984 elt = Dynarr_length (gbd) - 1;
2991 end = Dynarr_length (gbd);
2994 while (count && ((!reverse && elt < end) || (reverse && elt >= end)))
2996 struct glyph_block *gb = Dynarr_atp (gbd, elt);
2998 if (NILP (gb->extent))
2999 abort (); /* these should have been handled in add_glyph_rune */
3002 ((side == LEFT_GLYPHS &&
3003 extent_begin_glyph_layout (XEXTENT (gb->extent)) == layout)
3004 || (side == RIGHT_GLYPHS &&
3005 extent_end_glyph_layout (XEXTENT (gb->extent)) == layout)))
3007 data.findex = gb->findex;
3008 data.max_pixpos = data.pixpos + gb->width;
3009 add_glyph_rune (&data, gb, side, 0, NULL);
3014 (reverse ? elt-- : elt++);
3017 calculate_baseline (&data);
3019 dl->ascent = data.new_ascent;
3020 dl->descent = data.new_descent;
3022 calculate_yoffset (dl, data.db);
3027 /* Add a blank to a margin display block. */
3030 add_margin_blank (struct display_line *dl, struct display_block *db,
3031 struct window *w, int xpos, int width, int side)
3035 rb.findex = (side == LEFT_GLYPHS
3036 ? get_builtin_face_cache_index (w, Vleft_margin_face)
3037 : get_builtin_face_cache_index (w, Vright_margin_face));
3042 rb.type = RUNE_BLANK;
3043 rb.cursor_type = CURSOR_OFF;
3045 Dynarr_add (db->runes, rb);
3048 /* Display glyphs in the left outside margin, left inside margin and
3049 left whitespace area. */
3052 create_left_glyph_block (struct window *w, struct display_line *dl,
3057 int use_overflow = (NILP (w->use_left_overflow) ? 0 : 1);
3059 int out_end, in_out_start, in_in_end, white_out_start, white_in_start;
3060 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
3061 int left_in_start = dl->bounds.left_in;
3062 int left_in_end = dl->bounds.left_in + overlay_width;
3064 struct display_block *odb, *idb;
3066 XSETWINDOW (window, w);
3068 /* We have to add the glyphs to the line in the order outside,
3069 inside, whitespace. However the precedence dictates that we
3070 determine how many will fit in the reverse order. */
3072 /* Determine how many whitespace glyphs we can display and where
3073 they should start. */
3074 white_in_start = dl->bounds.left_white;
3075 white_out_start = left_in_start;
3076 white_out_cnt = white_in_cnt = 0;
3079 while (elt < Dynarr_length (dl->left_glyphs))
3081 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3083 if (NILP (gb->extent))
3084 abort (); /* these should have been handled in add_glyph_rune */
3086 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
3090 width = glyph_width (gb->glyph, window);
3092 if (white_in_start - width >= left_in_end)
3095 white_in_start -= width;
3099 else if (use_overflow
3100 && (white_out_start - width > dl->bounds.left_out))
3103 white_out_start -= width;
3114 /* Determine how many inside margin glyphs we can display and where
3115 they should start. The inside margin glyphs get whatever space
3116 is left after the whitespace glyphs have been displayed. These
3117 are tricky to calculate since if we decide to use the overflow
3118 area we basically have to start over. So for these we build up a
3119 list of just the inside margin glyphs and manipulate it to
3120 determine the needed info. */
3122 glyph_block_dynarr *ib;
3123 int avail_in, avail_out;
3126 int used_in, used_out;
3129 used_in = used_out = 0;
3130 ib = Dynarr_new (glyph_block);
3131 while (elt < Dynarr_length (dl->left_glyphs))
3133 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3135 if (NILP (gb->extent))
3136 abort (); /* these should have been handled in add_glyph_rune */
3138 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3141 gb->width = glyph_width (gb->glyph, window);
3142 used_in += gb->width;
3143 Dynarr_add (ib, *gb);
3153 avail_in = white_in_start - left_in_end;
3161 avail_out = white_out_start - dl->bounds.left_out;
3164 while (!done && marker < Dynarr_length (ib))
3166 int width = Dynarr_atp (ib, marker)->width;
3168 /* If everything now fits in the available inside margin
3169 space, we're done. */
3170 if (used_in <= avail_in)
3174 /* Otherwise see if we have room to move a glyph to the
3176 if (used_out + width <= avail_out)
3189 /* At this point we now know that everything from marker on goes in
3190 the inside margin and everything before it goes in the outside
3191 margin. The stuff going into the outside margin is guaranteed
3192 to fit, but we may have to trim some stuff from the inside. */
3194 in_in_end = left_in_end;
3195 in_out_start = white_out_start;
3196 in_out_cnt = in_in_cnt = 0;
3200 while (elt < Dynarr_length (dl->left_glyphs))
3202 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3204 if (NILP (gb->extent))
3205 abort (); /* these should have been handled in add_glyph_rune */
3207 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3210 int width = glyph_width (gb->glyph, window);
3215 in_out_start -= width;
3220 else if (in_in_end + width < white_in_start)
3235 /* Determine how many outside margin glyphs we can display. They
3236 always start at the left outside margin and can only use the
3237 outside margin space. */
3238 out_end = dl->bounds.left_out;
3242 while (elt < Dynarr_length (dl->left_glyphs))
3244 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3246 if (NILP (gb->extent))
3247 abort (); /* these should have been handled in add_glyph_rune */
3249 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3252 int width = glyph_width (gb->glyph, window);
3254 if (out_end + width <= in_out_start)
3268 /* Now that we know where everything goes, we add the glyphs as
3269 runes to the appropriate display blocks. */
3270 if (out_cnt || in_out_cnt || white_out_cnt)
3272 odb = get_display_block_from_line (dl, LEFT_OUTSIDE_MARGIN);
3273 odb->start_pos = dl->bounds.left_out;
3274 /* #### We should stop adding a blank to account for the space
3275 between the end of the glyphs and the margin and instead set
3276 this accordingly. */
3277 odb->end_pos = dl->bounds.left_in;
3278 Dynarr_reset (odb->runes);
3283 if (in_in_cnt || white_in_cnt)
3285 idb = get_display_block_from_line (dl, LEFT_INSIDE_MARGIN);
3286 idb->start_pos = dl->bounds.left_in;
3287 /* #### See above comment for odb->end_pos */
3288 idb->end_pos = dl->bounds.left_white;
3289 Dynarr_reset (idb->runes);
3294 /* First add the outside margin glyphs. */
3296 end_xpos = add_margin_runes (dl, odb, dl->bounds.left_out, out_cnt,
3297 GL_OUTSIDE_MARGIN, LEFT_GLYPHS, window);
3299 end_xpos = dl->bounds.left_out;
3301 /* There may be blank space between the outside margin glyphs and
3302 the inside margin glyphs. If so, add a blank. */
3303 if (in_out_cnt && (in_out_start - end_xpos))
3305 add_margin_blank (dl, odb, w, end_xpos, in_out_start - end_xpos,
3309 /* Next add the inside margin glyphs which are actually in the
3313 end_xpos = add_margin_runes (dl, odb, in_out_start, in_out_cnt,
3314 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3317 /* If we didn't add any inside margin glyphs to the outside margin,
3318 but are adding whitespace glyphs, then we need to add a blank
3320 if (!in_out_cnt && white_out_cnt && (white_out_start - end_xpos))
3322 add_margin_blank (dl, odb, w, end_xpos, white_out_start - end_xpos,
3326 /* Next add the whitespace margin glyphs which are actually in the
3330 end_xpos = add_margin_runes (dl, odb, white_out_start, white_out_cnt,
3331 GL_WHITESPACE, LEFT_GLYPHS, window);
3334 /* We take care of clearing between the end of the glyphs and the
3335 start of the inside margin for lines which have glyphs. */
3336 if (odb && (left_in_start - end_xpos))
3338 add_margin_blank (dl, odb, w, end_xpos, left_in_start - end_xpos,
3342 /* Next add the inside margin glyphs which are actually in the
3346 end_xpos = add_margin_runes (dl, idb, left_in_end, in_in_cnt,
3347 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3350 end_xpos = left_in_end;
3352 /* Make sure that the area between the end of the inside margin
3353 glyphs and the whitespace glyphs is cleared. */
3354 if (idb && (white_in_start - end_xpos > 0))
3356 add_margin_blank (dl, idb, w, end_xpos, white_in_start - end_xpos,
3360 /* Next add the whitespace margin glyphs which are actually in the
3364 add_margin_runes (dl, idb, white_in_start, white_in_cnt, GL_WHITESPACE,
3365 LEFT_GLYPHS, window);
3368 /* Whitespace glyphs always end right next to the text block so
3369 there is nothing we have to make sure is cleared after them. */
3372 /* Display glyphs in the right outside margin, right inside margin and
3373 right whitespace area. */
3376 create_right_glyph_block (struct window *w, struct display_line *dl)
3380 int use_overflow = (NILP (w->use_right_overflow) ? 0 : 1);
3382 int out_start, in_out_end, in_in_start, white_out_end, white_in_end;
3383 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
3385 struct display_block *odb, *idb;
3387 XSETWINDOW (window, w);
3389 /* We have to add the glyphs to the line in the order outside,
3390 inside, whitespace. However the precedence dictates that we
3391 determine how many will fit in the reverse order. */
3393 /* Determine how many whitespace glyphs we can display and where
3394 they should start. */
3395 white_in_end = dl->bounds.right_white;
3396 white_out_end = dl->bounds.right_in;
3397 white_out_cnt = white_in_cnt = 0;
3400 while (elt < Dynarr_length (dl->right_glyphs))
3402 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3404 if (NILP (gb->extent))
3405 abort (); /* these should have been handled in add_glyph_rune */
3407 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
3409 int width = glyph_width (gb->glyph, window);
3411 if (white_in_end + width <= dl->bounds.right_in)
3414 white_in_end += width;
3418 else if (use_overflow
3419 && (white_out_end + width <= dl->bounds.right_out))
3422 white_out_end += width;
3433 /* Determine how many inside margin glyphs we can display and where
3434 they should start. The inside margin glyphs get whatever space
3435 is left after the whitespace glyphs have been displayed. These
3436 are tricky to calculate since if we decide to use the overflow
3437 area we basically have to start over. So for these we build up a
3438 list of just the inside margin glyphs and manipulate it to
3439 determine the needed info. */
3441 glyph_block_dynarr *ib;
3442 int avail_in, avail_out;
3445 int used_in, used_out;
3448 used_in = used_out = 0;
3449 ib = Dynarr_new (glyph_block);
3450 while (elt < Dynarr_length (dl->right_glyphs))
3452 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3454 if (NILP (gb->extent))
3455 abort (); /* these should have been handled in add_glyph_rune */
3457 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3459 gb->width = glyph_width (gb->glyph, window);
3460 used_in += gb->width;
3461 Dynarr_add (ib, *gb);
3470 avail_in = dl->bounds.right_in - white_in_end;
3475 avail_out = dl->bounds.right_out - white_out_end;
3478 while (!done && marker < Dynarr_length (ib))
3480 int width = Dynarr_atp (ib, marker)->width;
3482 /* If everything now fits in the available inside margin
3483 space, we're done. */
3484 if (used_in <= avail_in)
3488 /* Otherwise see if we have room to move a glyph to the
3490 if (used_out + width <= avail_out)
3503 /* At this point we now know that everything from marker on goes in
3504 the inside margin and everything before it goes in the outside
3505 margin. The stuff going into the outside margin is guaranteed
3506 to fit, but we may have to trim some stuff from the inside. */
3508 in_in_start = dl->bounds.right_in;
3509 in_out_end = dl->bounds.right_in;
3510 in_out_cnt = in_in_cnt = 0;
3514 while (elt < Dynarr_length (dl->right_glyphs))
3516 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3518 if (NILP (gb->extent))
3519 abort (); /* these should have been handled in add_glyph_rune */
3521 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3523 int width = glyph_width (gb->glyph, window);
3528 in_out_end += width;
3533 else if (in_in_start - width >= white_in_end)
3536 in_in_start -= width;
3548 /* Determine how many outside margin glyphs we can display. They
3549 always start at the right outside margin and can only use the
3550 outside margin space. */
3551 out_start = dl->bounds.right_out;
3555 while (elt < Dynarr_length (dl->right_glyphs))
3557 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3559 if (NILP (gb->extent))
3560 abort (); /* these should have been handled in add_glyph_rune */
3562 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_OUTSIDE_MARGIN)
3564 int width = glyph_width (gb->glyph, window);
3566 if (out_start - width >= in_out_end)
3580 /* Now that we now where everything goes, we add the glyphs as runes
3581 to the appropriate display blocks. */
3582 if (out_cnt || in_out_cnt || white_out_cnt)
3584 odb = get_display_block_from_line (dl, RIGHT_OUTSIDE_MARGIN);
3585 /* #### See comments before odb->start_pos init in
3586 create_left_glyph_block */
3587 odb->start_pos = dl->bounds.right_in;
3588 odb->end_pos = dl->bounds.right_out;
3589 Dynarr_reset (odb->runes);
3594 if (in_in_cnt || white_in_cnt)
3596 idb = get_display_block_from_line (dl, RIGHT_INSIDE_MARGIN);
3597 idb->start_pos = dl->bounds.right_white;
3598 /* #### See comments before odb->start_pos init in
3599 create_left_glyph_block */
3600 idb->end_pos = dl->bounds.right_in;
3601 Dynarr_reset (idb->runes);
3606 /* First add the whitespace margin glyphs which are actually in the
3610 end_xpos = add_margin_runes (dl, idb, dl->bounds.right_white,
3611 white_in_cnt, GL_WHITESPACE, RIGHT_GLYPHS,
3615 end_xpos = dl->bounds.right_white;
3617 /* Make sure that the area between the end of the whitespace glyphs
3618 and the inside margin glyphs is cleared. */
3619 if (in_in_cnt && (in_in_start - end_xpos))
3621 add_margin_blank (dl, idb, w, end_xpos, in_in_start - end_xpos,
3625 /* Next add the inside margin glyphs which are actually in the
3629 end_xpos = add_margin_runes (dl, idb, in_in_start, in_in_cnt,
3630 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3633 /* If we didn't add any inside margin glyphs then make sure the rest
3634 of the inside margin area gets cleared. */
3635 if (idb && (dl->bounds.right_in - end_xpos))
3637 add_margin_blank (dl, idb, w, end_xpos, dl->bounds.right_in - end_xpos,
3641 /* Next add any whitespace glyphs in the outside margin. */
3644 end_xpos = add_margin_runes (dl, odb, dl->bounds.right_in, white_out_cnt,
3645 GL_WHITESPACE, RIGHT_GLYPHS, window);
3648 end_xpos = dl->bounds.right_in;
3650 /* Next add any inside margin glyphs in the outside margin. */
3653 end_xpos = add_margin_runes (dl, odb, end_xpos, in_out_cnt,
3654 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3657 /* There may be space between any whitespace or inside margin glyphs
3658 in the outside margin and the actual outside margin glyphs. */
3659 if (odb && (out_start - end_xpos))
3661 add_margin_blank (dl, odb, w, end_xpos, out_start - end_xpos,
3665 /* Finally, add the outside margin glyphs. */
3668 add_margin_runes (dl, odb, out_start, out_cnt, GL_OUTSIDE_MARGIN,
3669 RIGHT_GLYPHS, window);
3674 /***************************************************************************/
3676 /* modeline routines */
3678 /***************************************************************************/
3680 /* This function is also used in frame.c by `generate_title_string' */
3682 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str,
3683 struct window *w, struct display_line *dl,
3684 struct display_block *db, face_index findex,
3685 int min_pixpos, int max_pixpos, int type)
3687 struct frame *f = XFRAME (w->frame);
3688 struct device *d = XDEVICE (f->device);
3692 Charcount offset = 0;
3698 data.findex = findex;
3699 data.pixpos = min_pixpos;
3700 data.max_pixpos = max_pixpos;
3701 data.cursor_type = NO_CURSOR;
3702 data.last_charset = Qunbound;
3703 data.last_findex = DEFAULT_INDEX;
3704 data.result_str = result_str;
3705 data.is_modeline = 1;
3707 XSETWINDOW (data.window, w);
3709 Dynarr_reset (formatted_string_extent_dynarr);
3710 Dynarr_reset (formatted_string_extent_start_dynarr);
3711 Dynarr_reset (formatted_string_extent_end_dynarr);
3713 /* result_str is nil when we're building a frame or icon title. Otherwise,
3714 we're building a modeline, so the offset starts at the modeline
3715 horizontal scrolling amount */
3716 if (! NILP (result_str))
3717 offset = w->modeline_hscroll;
3718 generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0,
3719 max_pixpos - min_pixpos, findex, type, &offset,
3722 if (Dynarr_length (db->runes))
3725 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
3726 c_pixpos = rb->xpos + rb->width;
3729 c_pixpos = min_pixpos;
3731 /* If we don't reach the right side of the window, add a blank rune
3732 to make up the difference. This usually only occurs if the
3733 modeline face is using a proportional width font or a fixed width
3734 font of a different size from the default face font. */
3736 if (c_pixpos < max_pixpos)
3738 data.pixpos = c_pixpos;
3739 data.blank_width = max_pixpos - data.pixpos;
3741 add_blank_rune (&data, NULL, 0);
3744 /* Now create the result string and frob the extents into it. */
3745 if (!NILP (result_str))
3750 struct buffer *buf = XBUFFER (WINDOW_BUFFER (w));
3752 in_modeline_generation = 1;
3754 detach_all_extents (result_str);
3755 resize_string (XSTRING (result_str), -1,
3756 data.bytepos - XSTRING_LENGTH (result_str));
3758 strdata = XSTRING_DATA (result_str);
3760 for (elt = 0, len = 0; elt < Dynarr_length (db->runes); elt++)
3762 if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR)
3764 len += (set_charptr_emchar
3766 CHARC_TO_CHAR (Dynarr_atp (db->runes,
3767 elt)->object.cglyph)));
3771 for (elt = 0; elt < Dynarr_length (formatted_string_extent_dynarr);
3774 Lisp_Object extent = Qnil;
3777 XSETEXTENT (extent, Dynarr_at (formatted_string_extent_dynarr, elt));
3778 child = Fgethash (extent, buf->modeline_extent_table, Qnil);
3781 child = Fmake_extent (Qnil, Qnil, result_str);
3782 Fputhash (extent, child, buf->modeline_extent_table);
3784 Fset_extent_parent (child, extent);
3785 set_extent_endpoints
3787 Dynarr_at (formatted_string_extent_start_dynarr, elt),
3788 Dynarr_at (formatted_string_extent_end_dynarr, elt),
3792 in_modeline_generation = 0;
3796 /* Ensure that the given display line DL accurately represents the
3797 modeline for the given window. */
3799 generate_modeline (struct window *w, struct display_line *dl, int type)
3801 struct buffer *b = XBUFFER (w->buffer);
3802 struct frame *f = XFRAME (w->frame);
3803 struct device *d = XDEVICE (f->device);
3805 /* Unlike display line and rune pointers, this one can't change underneath
3807 struct display_block *db = get_display_block_from_line (dl, TEXT);
3808 int max_pixpos, min_pixpos, ypos_adj;
3809 Lisp_Object font_inst;
3811 /* This will actually determine incorrect inside boundaries for the
3812 modeline since it ignores the margins. However being aware of this fact
3813 we never use those values anywhere so it doesn't matter. */
3814 dl->bounds = calculate_display_line_boundaries (w, 1);
3816 /* We are generating a modeline. */
3818 dl->cursor_elt = -1;
3820 /* Reset the runes on the modeline. */
3821 Dynarr_reset (db->runes);
3823 if (!WINDOW_HAS_MODELINE_P (w))
3827 /* If there is a horizontal scrollbar, don't add anything. */
3828 if (window_scrollbar_height (w))
3831 dl->ascent = DEVMETH (d, divider_height, ());
3833 /* The modeline is at the bottom of the gutters. */
3834 dl->ypos = WINDOW_BOTTOM (w);
3836 rb.findex = MODELINE_INDEX;
3837 rb.xpos = dl->bounds.left_out;
3838 rb.width = dl->bounds.right_out - dl->bounds.left_out;
3841 rb.type = RUNE_HLINE;
3842 rb.object.hline.thickness = 1;
3843 rb.object.hline.yoffset = 0;
3844 rb.cursor_type = NO_CURSOR;
3846 if (!EQ (Qzero, w->modeline_shadow_thickness)
3849 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3851 dl->ypos -= shadow_thickness;
3852 rb.xpos += shadow_thickness;
3853 rb.width -= 2 * shadow_thickness;
3856 Dynarr_add (db->runes, rb);
3860 /* !!#### not right; needs to compute the max height of
3862 font_inst = WINDOW_FACE_CACHEL_FONT (w, MODELINE_INDEX, Vcharset_ascii);
3864 dl->ascent = XFONT_INSTANCE (font_inst)->ascent;
3865 dl->descent = XFONT_INSTANCE (font_inst)->descent;
3867 min_pixpos = dl->bounds.left_out;
3868 max_pixpos = dl->bounds.right_out;
3870 if (!EQ (Qzero, w->modeline_shadow_thickness) && FRAME_WIN_P (f))
3872 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3874 ypos_adj = shadow_thickness;
3875 min_pixpos += shadow_thickness;
3876 max_pixpos -= shadow_thickness;
3881 generate_formatted_string_db (b->modeline_format,
3882 b->generated_modeline_string, w, dl, db,
3883 MODELINE_INDEX, min_pixpos, max_pixpos, type);
3885 /* The modeline is at the bottom of the gutters. We have to wait to
3886 set this until we've generated the modeline in order to account
3887 for any embedded faces. */
3888 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj;
3892 add_string_to_fstring_db_runes (pos_data *data, const Bufbyte *str,
3893 Charcount pos, Charcount min_pos, Charcount max_pos)
3895 /* This function has been Mule-ized. */
3897 const Bufbyte *cur_pos = str;
3898 struct display_block *db = data->db;
3900 data->blank_width = space_width (XWINDOW (data->window));
3901 while (Dynarr_length (db->runes) < pos)
3902 add_blank_rune (data, NULL, 0);
3904 end = (Dynarr_length (db->runes) +
3905 bytecount_to_charcount (str, strlen ((const char *) str)));
3907 end = min (max_pos, end);
3909 while (pos < end && *cur_pos)
3911 const Bufbyte *old_cur_pos = cur_pos;
3914 data->ch = charptr_emchar (cur_pos);
3915 succeeded = (add_emchar_rune (data) != ADD_FAILED);
3916 INC_CHARPTR (cur_pos);
3920 data->modeline_charpos++;
3921 data->bytepos += cur_pos - old_cur_pos;
3925 while (Dynarr_length (db->runes) < min_pos &&
3926 (data->pixpos + data->blank_width <= data->max_pixpos))
3927 add_blank_rune (data, NULL, 0);
3929 return Dynarr_length (db->runes);
3932 /* #### Urk! Should also handle begin-glyphs and end-glyphs in
3933 modeline extents. */
3935 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph,
3936 Charcount pos, Charcount min_pos,
3937 Charcount max_pos, Lisp_Object extent)
3939 /* This function has been Mule-ized. */
3941 struct display_block *db = data->db;
3942 struct glyph_block gb;
3944 data->blank_width = space_width (XWINDOW (data->window));
3945 while (Dynarr_length (db->runes) < pos)
3946 add_blank_rune (data, NULL, 0);
3948 end = Dynarr_length (db->runes) + 1;
3950 end = min (max_pos, end);
3954 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
3957 while (Dynarr_length (db->runes) < pos &&
3958 (data->pixpos + data->blank_width <= data->max_pixpos))
3959 add_blank_rune (data, NULL, 0);
3961 return Dynarr_length (db->runes);
3964 /* If max_pos is == -1, it is considered to be infinite. The same is
3965 true of max_pixsize. */
3966 #define SET_CURRENT_MODE_CHARS_PIXSIZE \
3967 if (Dynarr_length (data->db->runes)) \
3968 cur_pixsize = data->pixpos - Dynarr_atp (data->db->runes, 0)->xpos; \
3972 /* Note that this function does "positions" in terms of characters and
3973 not in terms of columns. This is necessary to make the formatting
3974 work correctly when proportional width fonts are used in the
3977 generate_fstring_runes (struct window *w, pos_data *data, Charcount pos,
3978 Charcount min_pos, Charcount max_pos,
3979 Lisp_Object elt, int depth, int max_pixsize,
3980 face_index findex, int type, Charcount *offset,
3981 Lisp_Object cur_ext)
3983 /* This function has been Mule-ized. */
3984 /* #### The other losing things in this function are:
3986 -- C zero-terminated-string lossage.
3987 -- Non-printable characters should be converted into something
3988 appropriate (e.g. ^F) instead of blindly being printed anyway.
3999 /* A string. Add to the display line and check for %-constructs
4002 Bufbyte *this = XSTRING_DATA (elt);
4004 while ((pos < max_pos || max_pos == -1) && *this)
4006 Bufbyte *last = this;
4008 while (*this && *this != '%')
4013 /* No %-construct */
4015 bytecount_to_charcount (last, this - last);
4017 if (size <= *offset)
4021 Charcount tmp_max = (max_pos == -1 ? pos + size - *offset :
4022 min (pos + size - *offset, max_pos));
4023 const Bufbyte *tmp_last = charptr_n_addr (last, *offset);
4025 pos = add_string_to_fstring_db_runes (data, tmp_last,
4030 else /* *this == '%' */
4032 Charcount spec_width = 0;
4034 this++; /* skip over '%' */
4036 /* We can't allow -ve args due to the "%-" construct.
4037 * Argument specifies minwidth but not maxwidth
4038 * (maxwidth can be specified by
4039 * (<negative-number> . <stuff>) modeline elements)
4041 while (isdigit (*this))
4043 spec_width = spec_width * 10 + (*this - '0');
4050 pos = generate_fstring_runes (w, data, pos, spec_width,
4051 max_pos, Vglobal_mode_string,
4052 depth, max_pixsize, findex,
4053 type, offset, cur_ext);
4055 else if (*this == '-')
4057 Charcount num_to_add;
4059 if (max_pixsize < 0)
4061 else if (max_pos != -1)
4062 num_to_add = max_pos - pos;
4068 SET_CURRENT_MODE_CHARS_PIXSIZE;
4071 redisplay_text_width_string (w, findex, &ch, Qnil, 0,
4074 num_to_add = (max_pixsize - cur_pixsize) / dash_pixsize;
4078 while (num_to_add--)
4079 pos = add_string_to_fstring_db_runes
4080 (data, (const Bufbyte *) "-", pos, pos, max_pos);
4082 else if (*this != 0)
4084 Emchar ch = charptr_emchar (this);
4088 decode_mode_spec (w, ch, type);
4090 str = Dynarr_atp (mode_spec_bufbyte_string, 0);
4091 size = bytecount_to_charcount
4092 /* Skip the null character added by `decode_mode_spec' */
4093 (str, Dynarr_length (mode_spec_bufbyte_string)) - 1;
4095 if (size <= *offset)
4099 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
4101 /* #### NOTE: I don't understand why a tmp_max is not
4102 computed and used here as in the plain string case
4104 pos = add_string_to_fstring_db_runes (data, tmp_str,
4111 /* NOT this++. There could be any sort of character at
4112 the current position. */
4116 if (max_pixsize > 0)
4119 SET_CURRENT_MODE_CHARS_PIXSIZE;
4121 if (cur_pixsize >= max_pixsize)
4126 else if (SYMBOLP (elt))
4128 /* A symbol: process the value of the symbol recursively
4129 as if it appeared here directly. */
4130 Lisp_Object tem = symbol_value_in_buffer (elt, w->buffer);
4132 if (!UNBOUNDP (tem))
4134 /* If value is a string, output that string literally:
4135 don't check for % within it. */
4138 Bufbyte *str = XSTRING_DATA (tem);
4139 Charcount size = XSTRING_CHAR_LENGTH (tem);
4141 if (size <= *offset)
4145 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
4147 /* #### NOTE: I don't understand why a tmp_max is not
4148 computed and used here as in the plain string case
4150 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
4155 /* Give up right away for nil or t. */
4156 else if (!EQ (tem, elt))
4163 else if (GENERIC_SPECIFIERP (elt))
4165 Lisp_Object window, tem;
4166 XSETWINDOW (window, w);
4167 tem = specifier_instance_no_quit (elt, Qunbound, window,
4168 ERROR_ME_NOT, 0, Qzero);
4169 if (!UNBOUNDP (tem))
4175 else if (CONSP (elt))
4177 /* A cons cell: four distinct cases.
4178 * - If first element is a string or a cons, process all the elements
4179 * and effectively concatenate them.
4180 * - If first element is a negative number, truncate displaying cdr to
4181 * at most that many characters. If positive, pad (with spaces)
4182 * to at least that many characters.
4183 * - If first element is another symbol, process the cadr or caddr
4184 * recursively according to whether the symbol's value is non-nil or
4186 * - If first element is an extent, process the cdr recursively
4187 * and handle the extent's face.
4190 Lisp_Object car, tem;
4199 tem = symbol_value_in_buffer (car, w->buffer);
4200 /* elt is now the cdr, and we know it is a cons cell.
4201 Use its car if CAR has a non-nil value. */
4202 if (!UNBOUNDP (tem))
4210 /* Symbol's value is nil (or symbol is unbound)
4211 * Get the cddr of the original list
4212 * and if possible find the caddr and use that.
4217 else if (!CONSP (elt))
4225 else if (INTP (car))
4227 Charcount lim = XINT (car);
4233 /* Negative int means reduce maximum width.
4234 * DO NOT change MIN_PIXPOS here!
4235 * (20 -10 . foo) should truncate foo to 10 col
4236 * and then pad to 20.
4239 max_pos = pos - lim;
4241 max_pos = min (max_pos, pos - lim);
4245 /* Padding specified. Don't let it be more than
4249 if (max_pos != -1 && lim > max_pos)
4251 /* If that's more padding than already wanted, queue it.
4252 * But don't reduce padding already specified even if
4253 * that is beyond the current truncation point.
4260 else if (STRINGP (car) || CONSP (car))
4264 /* LIMIT is to protect against circular lists. */
4265 while (CONSP (elt) && --limit > 0
4266 && (pos < max_pos || max_pos == -1))
4268 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4269 XCAR (elt), depth, max_pixsize,
4270 findex, type, offset, cur_ext);
4274 else if (EXTENTP (car))
4276 struct extent *ext = XEXTENT (car);
4278 if (EXTENT_LIVE_P (ext))
4280 face_index old_findex = data->findex;
4282 Lisp_Object font_inst;
4283 face_index new_findex;
4284 Bytecount start = data->bytepos;
4286 face = extent_face (ext);
4289 /* #### needs to merge faces, sigh */
4290 /* #### needs to handle list of faces */
4291 new_findex = get_builtin_face_cache_index (w, face);
4292 /* !!#### not right; needs to compute the max height of
4294 font_inst = WINDOW_FACE_CACHEL_FONT (w, new_findex,
4297 data->dl->ascent = max (data->dl->ascent,
4298 XFONT_INSTANCE (font_inst)->ascent);
4299 data->dl->descent = max (data->dl->descent,
4300 XFONT_INSTANCE (font_inst)->
4304 new_findex = old_findex;
4306 data->findex = new_findex;
4307 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4308 XCDR (elt), depth - 1,
4309 max_pixsize, new_findex, type,
4311 data->findex = old_findex;
4312 Dynarr_add (formatted_string_extent_dynarr, ext);
4313 Dynarr_add (formatted_string_extent_start_dynarr, start);
4314 Dynarr_add (formatted_string_extent_end_dynarr, data->bytepos);
4318 else if (GLYPHP (elt))
4320 /* Glyphs are considered as one character with respect to the modeline
4321 horizontal scrolling facility. -- dv */
4325 pos = add_glyph_to_fstring_db_runes (data, elt, pos, pos, max_pos,
4332 char *str = GETTEXT ("*invalid*");
4333 Charcount size = (Charcount) strlen (str); /* is this ok ?? -- dv */
4335 if (size <= *offset)
4339 const Bufbyte *tmp_str =
4340 charptr_n_addr ((const Bufbyte *) str, *offset);
4342 /* #### NOTE: I don't understand why a tmp_max is not computed and
4343 used here as in the plain string case above. -- dv */
4344 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
4353 add_string_to_fstring_db_runes (data, (const Bufbyte *) "", pos,
4360 /* Update just the modeline. Assumes the desired display structs. If
4361 they do not have a modeline block, it does nothing. */
4363 regenerate_modeline (struct window *w)
4365 display_line_dynarr *dla = window_display_lines (w, DESIRED_DISP);
4367 if (!Dynarr_length (dla) || !Dynarr_atp (dla, 0)->modeline)
4371 generate_modeline (w, Dynarr_atp (dla, 0), DESIRED_DISP);
4372 redisplay_update_line (w, 0, 0, 0);
4376 /* Make sure that modeline display line is present in the given
4377 display structs if the window has a modeline and update that
4378 line. Returns true if a modeline was needed. */
4380 ensure_modeline_generated (struct window *w, int type)
4384 /* minibuffer windows don't have modelines */
4385 if (MINI_WINDOW_P (w))
4387 /* windows which haven't had it turned off do */
4388 else if (WINDOW_HAS_MODELINE_P (w))
4390 /* windows which have it turned off don't have a divider if there is
4391 a horizontal scrollbar */
4392 else if (window_scrollbar_height (w))
4394 /* and in this case there is none */
4400 display_line_dynarr *dla;
4402 dla = window_display_lines (w, type);
4404 /* We don't care if there is a display line which is not
4405 currently a modeline because it is definitely going to become
4406 one if we have gotten to this point. */
4407 if (Dynarr_length (dla) == 0)
4409 if (Dynarr_largest (dla) > 0)
4411 struct display_line *mlp = Dynarr_atp (dla, 0);
4412 Dynarr_add (dla, *mlp);
4416 struct display_line modeline;
4418 Dynarr_add (dla, modeline);
4422 /* If we're adding a new place marker go ahead and generate the
4423 modeline so that it is available for use by
4424 window_modeline_height. */
4425 generate_modeline (w, Dynarr_atp (dla, 0), type);
4428 return need_modeline;
4431 /* #### Kludge or not a kludge. I tend towards the former. */
4433 real_current_modeline_height (struct window *w)
4435 Fset_marker (w->start[CMOTION_DISP], w->start[CURRENT_DISP], w->buffer);
4436 Fset_marker (w->pointm[CMOTION_DISP], w->pointm[CURRENT_DISP], w->buffer);
4438 if (ensure_modeline_generated (w, CMOTION_DISP))
4440 display_line_dynarr *dla = window_display_lines (w, CMOTION_DISP);
4442 if (Dynarr_length (dla))
4444 if (Dynarr_atp (dla, 0)->modeline)
4445 return (Dynarr_atp (dla, 0)->ascent +
4446 Dynarr_atp (dla, 0)->descent);
4453 /***************************************************************************/
4455 /* displayable string routines */
4457 /***************************************************************************/
4459 /* Given a position for a string in a window, ensure that the given
4460 display line DL accurately represents the text on a line starting
4461 at the given position.
4463 Yes, this is duplicating the code of create_text_block, but it
4464 looked just too hard to change create_text_block to handle strings
4465 *and* buffers. We already make a distinction between the two
4466 elsewhere in the code so I think unifying them would require a
4467 complete MULE rewrite. Besides, the other distinction is that these
4468 functions cover text that the user *cannot edit* so we can remove
4469 everything to do with cursors, minibuffers etc. Eventually the
4470 modeline routines should be modified to use this code as it copes
4471 with many more types of display situation. */
4474 create_string_text_block (struct window *w, Lisp_Object disp_string,
4475 struct display_line *dl,
4477 prop_block_dynarr **prop,
4478 face_index default_face)
4480 struct frame *f = XFRAME (w->frame);
4481 /* Note that a lot of the buffer controlled stuff has been left in
4482 because you might well want to make use of it (selective display
4483 etc), its just the buffer text that we do not use. However, it
4484 seems to be possible for buffer to be nil sometimes so protect
4485 against this case. */
4486 struct buffer *b = BUFFERP (w->buffer) ? XBUFFER (w->buffer) : 0;
4487 struct device *d = XDEVICE (f->device);
4488 Lisp_String* s = XSTRING (disp_string);
4490 /* we're working with these a lot so precalculate them */
4491 Bytecount slen = XSTRING_LENGTH (disp_string);
4492 Bytecount bi_string_zv = slen;
4493 Bytind bi_start_pos = charcount_to_bytecount (string_data (s), start_pos);
4497 int truncate_win = b ? window_truncation_on (w) : 0;
4499 /* We're going to ditch selective display for static text, it's an
4500 FSF thing and invisible extents are the way to go here.
4501 Implementing it also relies on a number of buffer-specific
4502 functions that we don't have the luxury of being able to use
4505 /* The variable ctl-arrow allows the user to specify what characters
4506 can actually be displayed and which octal should be used for.
4507 #### This variable should probably have some rethought done to
4510 #### It would also be really nice if you could specify that
4511 the characters come out in hex instead of in octal. Mule
4512 does that by adding a ctl-hexa variable similar to ctl-arrow,
4513 but that's bogus -- we need a more general solution. I
4514 think you need to extend the concept of display tables
4515 into a more general conversion mechanism. Ideally you
4516 could specify a Lisp function that converts characters,
4517 but this violates the Second Golden Rule and besides would
4518 make things way way way way slow.
4520 So instead, we extend the display-table concept, which was
4521 historically limited to 256-byte vectors, to one of the
4524 a) A 256-entry vector, for backward compatibility;
4525 b) char-table, mapping characters to values;
4526 c) range-table, mapping ranges of characters to values;
4527 d) a list of the above.
4529 The (d) option allows you to specify multiple display tables
4530 instead of just one. Each display table can specify conversions
4531 for some characters and leave others unchanged. The way the
4532 character gets displayed is determined by the first display table
4533 with a binding for that character. This way, you could call a
4534 function `enable-hex-display' that adds a hex display-table to
4535 the list of display tables for the current buffer.
4537 #### ...not yet implemented... Also, we extend the concept of
4538 "mapping" to include a printf-like spec. Thus you can make all
4539 extended characters show up as hex with a display table like
4542 #s(range-table data ((256 524288) (format "%x")))
4544 Since more than one display table is possible, you have
4545 great flexibility in mapping ranges of characters. */
4546 Emchar printable_min = b ? (CHAR_OR_CHAR_INTP (b->ctl_arrow)
4547 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
4548 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
4549 ? 255 : 160)) : 255;
4551 Lisp_Object face_dt, window_dt;
4553 /* The text display block for this display line. */
4554 struct display_block *db = get_display_block_from_line (dl, TEXT);
4556 /* The first time through the main loop we need to force the glyph
4557 data to be updated. */
4560 /* Apparently the new extent_fragment_update returns an end position
4561 equal to the position passed in if there are no more runs to be
4563 int no_more_frags = 0;
4565 dl->used_prop_data = 0;
4567 dl->line_continuation = 0;
4569 /* set up faces to use for clearing areas, used by
4570 output_display_line */
4571 dl->default_findex = default_face;
4574 dl->left_margin_findex = default_face;
4575 dl->right_margin_findex = default_face;
4579 dl->left_margin_findex =
4580 get_builtin_face_cache_index (w, Vleft_margin_face);
4581 dl->right_margin_findex =
4582 get_builtin_face_cache_index (w, Vright_margin_face);
4586 data.ef = extent_fragment_new (disp_string, f);
4588 /* These values are used by all of the rune addition routines. We add
4589 them to this structure for ease of passing. */
4591 XSETWINDOW (data.window, w);
4595 data.bi_bufpos = bi_start_pos;
4596 data.pixpos = dl->bounds.left_in;
4597 data.last_charset = Qunbound;
4598 data.last_findex = default_face;
4599 data.result_str = Qnil;
4600 data.string = disp_string;
4602 /* Set the right boundary adjusting it to take into account any end
4603 glyph. Save the width of the end glyph for later use. */
4604 data.max_pixpos = dl->bounds.right_in;
4605 data.max_pixpos -= data.end_glyph_width;
4607 data.cursor_type = NO_CURSOR;
4611 /* I don't think we want this, string areas should not scroll with
4613 data.start_col = w->hscroll;
4614 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
4616 data.bi_start_col_enabled = 0;
4617 data.hscroll_glyph_width_adjust = 0;
4619 /* We regenerate the line from the very beginning. */
4620 Dynarr_reset (db->runes);
4622 /* Why is this less than or equal and not just less than? If the
4623 starting position is already equal to the maximum we can't add
4624 anything else, right? Wrong. We might still have a newline to
4625 add. A newline can use the room allocated for an end glyph since
4626 if we add it we know we aren't going to be adding any end
4629 /* #### Chuck -- I think this condition should be while (1).
4630 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
4631 and the begin-glyph ends exactly at the end of the window, the
4632 end-glyph and text might not be displayed. while (1) ensures
4633 that the loop terminates only when either (a) there is
4634 propagation data or (b) the end-of-line or end-of-buffer is hit.
4636 #### Also I think you need to ensure that the operation
4637 "add begin glyphs; add end glyphs; add text" is atomic and
4638 can't get interrupted in the middle. If you run off the end
4639 of the line during that operation, then you keep accumulating
4640 propagation data until you're done. Otherwise, if the (e.g.)
4641 there's a begin glyph at a particular position and attempting
4642 to display that glyph results in window-end being hit and
4643 propagation data being generated, then the character at that
4644 position won't be displayed.
4646 #### See also the comment after the end of this loop, below.
4648 while (data.pixpos <= data.max_pixpos)
4650 /* #### This check probably should not be necessary. */
4651 if (data.bi_bufpos > bi_string_zv)
4653 /* #### urk! More of this lossage! */
4658 /* Check for face changes. */
4659 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
4661 Lisp_Object last_glyph = Qnil;
4662 /* Deal with clipped glyphs that we have already displayed. */
4663 if (*prop && Dynarr_atp (*prop, 0)->type == PROP_GLYPH)
4665 last_glyph = Dynarr_atp (*prop, 0)->data.p_glyph.glyph;
4666 Dynarr_free (*prop);
4669 /* Now compute the face and begin/end-glyph information. */
4671 /* Remember that the extent-fragment routines deal in Bytind's. */
4672 extent_fragment_update (w, data.ef, data.bi_bufpos, last_glyph);
4673 /* This is somewhat cheesy but the alternative is to
4674 propagate default_face into extent_fragment_update. */
4675 if (data.findex == DEFAULT_INDEX)
4676 data.findex = default_face;
4678 get_display_tables (w, data.findex, &face_dt, &window_dt);
4680 if (data.bi_bufpos == data.ef->end)
4685 /* Determine what is next to be displayed. We first handle any
4686 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
4687 display then we determine what to do based on the character at the
4688 current buffer position. */
4690 /* If the current position is covered by an invisible extent, do
4691 nothing (except maybe add some ellipses).
4693 #### The behavior of begin and end-glyphs at the edge of an
4694 invisible extent should be investigated further. This is
4695 fairly low priority though. */
4696 if (data.ef->invisible)
4698 /* #### Chuck, perhaps you could look at this code? I don't
4699 really know what I'm doing. */
4702 Dynarr_free (*prop);
4706 /* The extent fragment code only sets this when we should
4707 really display the ellipses. It makes sure the ellipses
4708 don't get displayed more than once in a row. */
4709 if (data.ef->invisible_ellipses)
4711 struct glyph_block gb;
4713 data.ef->invisible_ellipses_already_displayed = 1;
4714 data.ef->invisible_ellipses = 0;
4716 gb.glyph = Vinvisible_text_glyph;
4717 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
4718 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
4719 /* Perhaps they shouldn't propagate if the very next thing
4720 is to display a newline (for compatibility with
4721 selective-display-ellipses)? Maybe that's too
4727 /* #### What if we're dealing with a display table? */
4731 if (data.bi_bufpos == bi_string_zv)
4734 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4737 /* If there is propagation data, then it represents the current
4738 buffer position being displayed. Add them and advance the
4739 position counter. This might also add the minibuffer
4743 dl->used_prop_data = 1;
4744 *prop = add_propagation_runes (prop, &data);
4747 goto done; /* gee, a really narrow window */
4748 else if (data.bi_bufpos == bi_string_zv)
4750 else if (data.bi_bufpos < 0)
4751 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
4754 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4757 /* If there are end glyphs, add them to the line. These are
4758 the end glyphs for the previous run of text. We add them
4759 here rather than doing them at the end of handling the
4760 previous run so that glyphs at the beginning and end of
4761 a line are handled correctly. */
4762 else if (Dynarr_length (data.ef->end_glyphs) > 0)
4764 data.ch = string_char (s, data.bi_bufpos);
4765 *prop = add_glyph_runes (&data, END_GLYPHS);
4772 /* If there are begin glyphs, add them to the line. */
4773 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
4775 data.ch = string_char (s, data.bi_bufpos);
4776 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
4783 /* If at end-of-buffer, we've already processed begin and
4784 end-glyphs at this point and there's no text to process,
4786 else if (data.bi_bufpos == bi_string_zv)
4791 Lisp_Object entry = Qnil;
4792 /* Get the character at the current buffer position. */
4793 data.ch = string_char (s, data.bi_bufpos);
4794 if (!NILP (face_dt) || !NILP (window_dt))
4795 entry = display_table_entry (data.ch, face_dt, window_dt);
4797 /* If there is a display table entry for it, hand it off to
4798 add_disp_table_entry_runes and let it worry about it. */
4799 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
4801 *prop = add_disp_table_entry_runes (&data, entry);
4807 /* Check if we have hit a newline character. If so, add a marker
4808 to the line and end this loop. */
4809 else if (data.ch == '\n')
4811 /* We aren't going to be adding an end glyph so give its
4812 space back in order to make sure that the cursor can
4814 data.max_pixpos += data.end_glyph_width;
4818 /* If the current character is considered to be printable, then
4820 else if (data.ch >= printable_min)
4822 *prop = add_emchar_rune (&data);
4827 /* If the current character is a tab, determine the next tab
4828 starting position and add a blank rune which extends from the
4829 current pixel position to that starting position. */
4830 else if (data.ch == '\t')
4832 int tab_start_pixpos = data.pixpos;
4837 if (data.start_col > 1)
4838 tab_start_pixpos -= (space_width (w) * (data.start_col - 1));
4841 next_tab_position (w, tab_start_pixpos,
4842 dl->bounds.left_in +
4843 data.hscroll_glyph_width_adjust);
4844 if (next_tab_start > data.max_pixpos)
4846 prop_width = next_tab_start - data.max_pixpos;
4847 next_tab_start = data.max_pixpos;
4849 data.blank_width = next_tab_start - data.pixpos;
4851 (next_tab_start - tab_start_pixpos) / space_width (w);
4853 *prop = add_blank_rune (&data, w, char_tab_width);
4855 /* add_blank_rune is only supposed to be called with
4856 sizes guaranteed to fit in the available space. */
4861 struct prop_block pb;
4862 *prop = Dynarr_new (prop_block);
4864 pb.type = PROP_BLANK;
4865 pb.data.p_blank.width = prop_width;
4866 pb.data.p_blank.findex = data.findex;
4867 Dynarr_add (*prop, pb);
4873 /* If character is a control character, pass it off to
4874 add_control_char_runes.
4876 The is_*() routines have undefined results on
4877 arguments outside of the range [-1, 255]. (This
4878 often bites people who carelessly use `char' instead
4879 of `unsigned char'.)
4881 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
4883 *prop = add_control_char_runes (&data, b);
4889 /* If the character is above the ASCII range and we have not
4890 already handled it, then print it as an octal number. */
4891 else if (data.ch >= 0200)
4893 *prop = add_octal_runes (&data);
4899 /* Assume the current character is considered to be printable,
4900 then just add it. */
4903 *prop = add_emchar_rune (&data);
4908 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4914 /* Determine the starting point of the next line if we did not hit the
4915 end of the buffer. */
4916 if (data.bi_bufpos < bi_string_zv)
4918 /* #### This check is not correct. If the line terminated
4919 due to a begin-glyph or end-glyph hitting window-end, then
4920 data.ch will not point to the character at data.bi_bufpos. If
4921 you make the two changes mentioned at the top of this loop,
4922 you should be able to say '(if (*prop))'. That should also
4923 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
4926 /* The common case is that the line ended because we hit a newline.
4927 In that case, the next character is just the next buffer
4929 if (data.ch == '\n')
4931 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4934 /* Otherwise we have a buffer line which cannot fit on one display
4938 struct glyph_block gb;
4939 struct glyph_cachel *cachel;
4941 /* If the line is to be truncated then we actually have to look
4942 for the next newline. We also add the end-of-line glyph which
4943 we know will fit because we adjusted the right border before
4944 we starting laying out the line. */
4945 data.max_pixpos += data.end_glyph_width;
4946 data.findex = default_face;
4953 /* Now find the start of the next line. */
4954 bi_pos = bi_find_next_emchar_in_string (s, '\n', data.bi_bufpos, 1);
4956 data.cursor_type = NO_CURSOR;
4957 data.bi_bufpos = bi_pos;
4958 gb.glyph = Vtruncation_glyph;
4959 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
4963 /* The cursor can never be on the continuation glyph. */
4964 data.cursor_type = NO_CURSOR;
4966 /* data.bi_bufpos is already at the start of the next line. */
4968 dl->line_continuation = 1;
4969 gb.glyph = Vcontinuation_glyph;
4970 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
4973 if (data.end_glyph_width)
4974 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
4976 if (truncate_win && data.bi_bufpos == bi_string_zv)
4978 const Bufbyte* endb = charptr_n_addr (string_data (s), bi_string_zv);
4980 if (charptr_emchar (endb) != '\n')
4982 /* #### Damn this losing shit. */
4988 else if (data.bi_bufpos == bi_string_zv)
4990 /* create_text_block () adds a bogus \n marker here which screws
4991 up subwindow display. Since we never have a cursor in the
4992 gutter we can safely ignore it. */
4994 /* Calculate left whitespace boundary. */
4998 /* Whitespace past a newline is considered right whitespace. */
4999 while (elt < Dynarr_length (db->runes))
5001 struct rune *rb = Dynarr_atp (db->runes, elt);
5003 if ((rb->type == RUNE_CHAR && CHARC_ASCII_EQ (rb->object.cglyph, ' '))
5004 || rb->type == RUNE_BLANK)
5006 dl->bounds.left_white += rb->width;
5010 elt = Dynarr_length (db->runes);
5014 /* Calculate right whitespace boundary. */
5016 int elt = Dynarr_length (db->runes) - 1;
5019 while (!done && elt >= 0)
5021 struct rune *rb = Dynarr_atp (db->runes, elt);
5023 if (!(rb->type == RUNE_CHAR && CHARC_IS_SPACE (rb->object.cglyph))
5024 && !rb->type == RUNE_BLANK)
5026 dl->bounds.right_white = rb->xpos + rb->width;
5034 /* The line is blank so everything is considered to be right
5037 dl->bounds.right_white = dl->bounds.left_in;
5040 /* Set the display blocks bounds. */
5041 db->start_pos = dl->bounds.left_in;
5042 if (Dynarr_length (db->runes))
5044 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
5046 db->end_pos = rb->xpos + rb->width;
5049 db->end_pos = dl->bounds.right_white;
5051 calculate_baseline (&data);
5053 dl->ascent = data.new_ascent;
5054 dl->descent = data.new_descent;
5057 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
5059 if (dl->ascent < ascent)
5060 dl->ascent = ascent;
5063 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
5065 if (dl->descent < descent)
5066 dl->descent = descent;
5069 calculate_yoffset (dl, db);
5071 dl->cursor_elt = data.cursor_x;
5072 /* #### lossage lossage lossage! Fix this shit! */
5073 if (data.bi_bufpos > bi_string_zv)
5074 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, bi_string_zv);
5076 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, data.bi_bufpos) - 1;
5078 data.dl->num_chars =
5079 string_column_at_point (s, dl->end_bufpos, b ? XINT (b->tab_width) : 8);
5081 /* This doesn't correctly take into account tabs and control
5082 characters but if the window isn't being truncated then this
5083 value isn't going to end up being used anyhow. */
5084 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
5086 /* #### handle horizontally scrolled line with text none of which
5087 was actually laid out. */
5089 /* #### handle any remainder of overlay arrow */
5091 if (*prop == ADD_FAILED)
5094 if (truncate_win && *prop)
5096 Dynarr_free (*prop);
5100 extent_fragment_delete (data.ef);
5102 /* #### If we started at EOB, then make sure we return a value past
5103 it so that regenerate_window will exit properly. This is bogus.
5104 The main loop should get fixed so that it isn't necessary to call
5105 this function if we are already at EOB. */
5107 if (data.bi_bufpos == bi_string_zv && bi_start_pos == bi_string_zv)
5108 return bytecount_to_charcount (string_data (s), data.bi_bufpos) + 1; /* Yuck! */
5110 return bytecount_to_charcount (string_data (s), data.bi_bufpos);
5113 /* Given a display line and a starting position, ensure that the
5114 contents of the display line accurately represent the visual
5115 representation of the buffer contents starting from the given
5116 position when displayed in the given window. The display line ends
5117 when the contents of the line reach the right boundary of the given
5120 This is very similar to generate_display_line but with the same
5121 limitations as create_string_text_block. I have taken the liberty
5122 of fixing the bytind stuff though.*/
5125 generate_string_display_line (struct window *w, Lisp_Object disp_string,
5126 struct display_line *dl,
5128 prop_block_dynarr **prop,
5129 face_index default_face)
5133 /* you must set bounds before calling this. */
5135 /* Reset what this line is using. */
5136 if (dl->display_blocks)
5137 Dynarr_reset (dl->display_blocks);
5138 if (dl->left_glyphs)
5140 Dynarr_free (dl->left_glyphs);
5141 dl->left_glyphs = 0;
5143 if (dl->right_glyphs)
5145 Dynarr_free (dl->right_glyphs);
5146 dl->right_glyphs = 0;
5149 /* We aren't generating a modeline at the moment. */
5152 /* Create a display block for the text region of the line. */
5153 ret_bufpos = create_string_text_block (w, disp_string, dl, start_pos,
5154 prop, default_face);
5155 dl->bufpos = start_pos;
5156 if (dl->end_bufpos < dl->bufpos)
5157 dl->end_bufpos = dl->bufpos;
5159 /* If there are left glyphs associated with any character in the
5160 text block, then create a display block to handle them. */
5161 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
5162 create_left_glyph_block (w, dl, 0);
5164 /* If there are right glyphs associated with any character in the
5165 text block, then create a display block to handle them. */
5166 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
5167 create_right_glyph_block (w, dl);
5172 /* This is ripped off from regenerate_window. All we want to do is
5173 loop through elements in the string creating display lines until we
5174 have covered the provided area. Simple really. */
5176 generate_displayable_area (struct window *w, Lisp_Object disp_string,
5177 int xpos, int ypos, int width, int height,
5178 display_line_dynarr* dla,
5180 face_index default_face)
5182 int yend = ypos + height;
5185 prop_block_dynarr *prop = 0;
5186 layout_bounds bounds;
5190 /* if there's nothing to do then do nothing. code after this assumes
5191 there is something to do. */
5192 if (NILP (disp_string))
5195 s_zv = XSTRING_CHAR_LENGTH (disp_string);
5197 bounds.left_out = xpos;
5198 bounds.right_out = xpos + width;
5199 /* The inner boundaries mark where the glyph margins are located. */
5200 bounds.left_in = bounds.left_out + window_left_margin_width (w);
5201 bounds.right_in = bounds.right_out - window_right_margin_width (w);
5202 /* We cannot fully calculate the whitespace boundaries as they
5203 depend on the contents of the line being displayed. */
5204 bounds.left_white = bounds.left_in;
5205 bounds.right_white = bounds.right_in;
5209 struct display_line dl;
5210 struct display_line *dlp;
5214 if (Dynarr_length (dla) < Dynarr_largest (dla))
5216 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5227 dlp->bounds = bounds;
5229 next_pos = generate_string_display_line (w, disp_string, dlp, start_pos,
5230 &prop, default_face);
5231 /* we need to make sure that we continue along the line if there
5232 is more left to display otherwise we just end up redisplaying
5233 the same chunk over and over again. */
5234 if (next_pos == start_pos && next_pos < s_zv)
5237 start_pos = next_pos;
5239 dlp->ypos = ypos + dlp->ascent;
5240 ypos = dlp->ypos + dlp->descent;
5244 int visible_height = dlp->ascent + dlp->descent;
5246 dlp->clip = (ypos - yend);
5247 visible_height -= dlp->clip;
5249 if (visible_height < VERTICAL_CLIP (w, 1))
5252 free_display_line (dlp);
5259 Dynarr_add (dla, *dlp);
5261 /* #### This type of check needs to be done down in the
5262 generate_display_line call. */
5263 if (start_pos >= s_zv)
5272 /***************************************************************************/
5274 /* window-regeneration routines */
5276 /***************************************************************************/
5278 /* For a given window and starting position in the buffer it contains,
5279 ensure that the TYPE display lines accurately represent the
5280 presentation of the window. We pass the buffer instead of getting
5281 it from the window since redisplay_window may have temporarily
5282 changed it to the echo area buffer. */
5285 regenerate_window (struct window *w, Bufpos start_pos, Bufpos point, int type)
5287 struct frame *f = XFRAME (w->frame);
5288 struct buffer *b = XBUFFER (w->buffer);
5289 int ypos = WINDOW_TEXT_TOP (w);
5290 int yend; /* set farther down */
5291 int yclip = WINDOW_TEXT_TOP_CLIP (w);
5294 prop_block_dynarr *prop;
5295 layout_bounds bounds;
5296 display_line_dynarr *dla;
5299 /* The lines had better exist by this point. */
5300 if (!(dla = window_display_lines (w, type)))
5303 w->max_line_len = 0;
5305 /* Normally these get updated in redisplay_window but it is possible
5306 for this function to get called from some other points where that
5307 update may not have occurred. This acts as a safety check. */
5308 if (!Dynarr_length (w->face_cachels))
5309 reset_face_cachels (w);
5310 if (!Dynarr_length (w->glyph_cachels))
5311 reset_glyph_cachels (w);
5313 Fset_marker (w->start[type], make_int (start_pos), w->buffer);
5314 Fset_marker (w->pointm[type], make_int (point), w->buffer);
5315 w->last_point_x[type] = -1;
5316 w->last_point_y[type] = -1;
5318 /* Make sure a modeline is in the structs if needed. */
5319 need_modeline = ensure_modeline_generated (w, type);
5321 /* Wait until here to set this so that the structs have a modeline
5322 generated in the case where one didn't exist. */
5323 yend = WINDOW_TEXT_BOTTOM (w);
5325 bounds = calculate_display_line_boundaries (w, 0);
5327 /* 97/3/14 jhod: stuff added here to support pre-prompts (used for input systems) */
5328 if (MINI_WINDOW_P (w)
5329 && (!NILP (Vminibuf_prompt) || !NILP (Vminibuf_preprompt))
5330 && !echo_area_active (f)
5331 && start_pos == BUF_BEGV (b))
5333 struct prop_block pb;
5335 prop = Dynarr_new (prop_block);
5337 string = concat2(Vminibuf_preprompt, Vminibuf_prompt);
5338 pb.type = PROP_MINIBUF_PROMPT;
5339 pb.data.p_string.str = XSTRING_DATA(string);
5340 pb.data.p_string.len = XSTRING_LENGTH(string);
5341 Dynarr_add (prop, pb);
5346 /* When we are computing things for scrolling purposes, make
5347 sure at least one line is always generated */
5348 force = (type == CMOTION_DISP);
5350 /* Make sure this is set always */
5351 /* Note the conversion at end */
5352 w->window_end_pos[type] = start_pos;
5353 while (ypos < yend || force)
5355 struct display_line dl;
5356 struct display_line *dlp;
5359 if (Dynarr_length (dla) < Dynarr_largest (dla))
5361 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5372 dlp->bounds = bounds;
5374 start_pos = generate_display_line (w, dlp, 1, start_pos, &prop, type);
5376 if (yclip > dlp->ascent)
5378 /* this should never happen, but if it does just display the
5383 dlp->ypos = (ypos + dlp->ascent) - yclip;
5384 ypos = dlp->ypos + dlp->descent;
5386 /* See if we've been asked to start midway through a line, for
5387 partial display line scrolling. */
5390 dlp->top_clip = yclip;
5398 int visible_height = dlp->ascent + dlp->descent;
5400 dlp->clip = (ypos - yend);
5401 /* Although this seems strange we could have a single very
5402 tall line visible for which we need to account for both
5403 the top clip and the bottom clip. */
5404 visible_height -= (dlp->clip + dlp->top_clip);
5406 if (visible_height < VERTICAL_CLIP (w, 1) && !force)
5409 free_display_line (dlp);
5416 if (dlp->cursor_elt != -1)
5418 /* #### This check is steaming crap. Have to get things
5419 fixed so when create_text_block hits EOB, we're done,
5421 if (w->last_point_x[type] == -1)
5423 w->last_point_x[type] = dlp->cursor_elt;
5424 w->last_point_y[type] = Dynarr_length (dla);
5428 /* #### This means that we've added a cursor at EOB
5429 twice. Yuck oh yuck. */
5430 struct display_block *db =
5431 get_display_block_from_line (dlp, TEXT);
5433 Dynarr_atp (db->runes, dlp->cursor_elt)->cursor_type = NO_CURSOR;
5434 dlp->cursor_elt = -1;
5438 if (dlp->num_chars > w->max_line_len)
5439 w->max_line_len = dlp->num_chars;
5441 Dynarr_add (dla, *dlp);
5443 /* #### This isn't right, but it is close enough for now. */
5444 w->window_end_pos[type] = start_pos;
5446 /* #### This type of check needs to be done down in the
5447 generate_display_line call. */
5448 if (start_pos > BUF_ZV (b))
5457 /* #### More not quite right, but close enough. */
5458 /* Ben sez: apparently window_end_pos[] is measured
5459 as the number of characters between the window end and the
5460 end of the buffer? This seems rather weirdo. What's
5461 the justification for this?
5463 JV sez: Because BUF_Z (b) would be a good initial value, however
5464 that can change. This representation allows initalizing with 0.
5466 w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type];
5470 /* We know that this is the right thing to use because we put it
5471 there when we first started working in this function. */
5472 generate_modeline (w, Dynarr_atp (dla, 0), type);
5476 #define REGEN_INC_FIND_START_END \
5478 /* Determine start and end of lines. */ \
5479 if (!Dynarr_length (cdla)) \
5483 if (Dynarr_atp (cdla, 0)->modeline && Dynarr_atp (ddla, 0)->modeline) \
5487 else if (!Dynarr_atp (cdla, 0)->modeline \
5488 && !Dynarr_atp (ddla, 0)->modeline) \
5493 abort (); /* structs differ */ \
5495 dla_end = Dynarr_length (cdla) - 1; \
5498 start_pos = (Dynarr_atp (cdla, dla_start)->bufpos \
5499 + Dynarr_atp (cdla, dla_start)->offset); \
5500 /* If this isn't true, then startp has changed and we need to do a \
5502 if (startp != start_pos) \
5505 /* Point is outside the visible region so give up. */ \
5506 if (pointm < start_pos) \
5511 /* This attempts to incrementally update the display structures. It
5512 returns a boolean indicating success or failure. This function is
5513 very similar to regenerate_window_incrementally and is in fact only
5514 called from that function. However, because of the nature of the
5515 changes it deals with it sometimes makes different assumptions
5516 which can lead to success which are much more difficult to make
5517 when dealing with buffer changes. */
5520 regenerate_window_extents_only_changed (struct window *w, Bufpos startp,
5522 Charcount beg_unchanged,
5523 Charcount end_unchanged)
5525 struct buffer *b = XBUFFER (w->buffer);
5526 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5527 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5531 int first_line, last_line;
5533 /* Don't define this in the loop where it is used because we
5534 definitely want its value to survive between passes. */
5535 prop_block_dynarr *prop = NULL;
5537 /* If we don't have any buffer change recorded but the modiff flag has
5538 been incremented, then fail. I'm not sure of the exact circumstances
5539 under which this can happen, but I believe that it is probably a
5540 reasonable happening. */
5541 if (!point_visible (w, pointm, CURRENT_DISP)
5542 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b))
5545 /* If the cursor is moved we attempt to update it. If we succeed we
5546 go ahead and proceed with the optimization attempt. */
5547 if (!EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5548 || pointm != marker_position (w->last_point[CURRENT_DISP]))
5550 struct frame *f = XFRAME (w->frame);
5551 struct device *d = XDEVICE (f->device);
5552 struct frame *sel_f = device_selected_frame (d);
5555 if (w->last_point_x[CURRENT_DISP] != -1
5556 && w->last_point_y[CURRENT_DISP] != -1)
5559 if (redisplay_move_cursor (w, pointm, WINDOW_TTY_P (w)))
5561 /* Always regenerate the modeline in case it is
5562 displaying the current line or column. */
5563 regenerate_modeline (w);
5567 else if (w != XWINDOW (FRAME_SELECTED_WINDOW (sel_f)))
5569 if (f->modeline_changed)
5570 regenerate_modeline (w);
5578 if (beg_unchanged == -1 && end_unchanged == -1)
5581 /* assert: There are no buffer modifications or they are all below the
5582 visible region. We assume that regenerate_window_incrementally has
5583 not called us unless this is true. */
5585 REGEN_INC_FIND_START_END;
5587 /* If the changed are starts before the visible area, give up. */
5588 if (beg_unchanged < startp)
5591 /* Find what display line the extent changes first affect. */
5593 while (line <= dla_end)
5595 struct display_line *dl = Dynarr_atp (cdla, line);
5596 Bufpos lstart = dl->bufpos + dl->offset;
5597 Bufpos lend = dl->end_bufpos + dl->offset;
5599 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5605 /* If the changes are below the visible area then if point hasn't
5606 moved return success otherwise fail in order to be safe. */
5609 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5610 && pointm == marker_position (w->last_point[CURRENT_DISP]))
5616 /* At this point we know what line the changes first affect. We now
5617 begin redrawing lines as long as we are still in the affected
5618 region and the line's size and positioning don't change.
5619 Otherwise we fail. If we fail we will have altered the desired
5620 structs which could lead to an assertion failure. However, if we
5621 fail the next thing that is going to happen is a full regen so we
5622 will actually end up being safe. */
5623 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5624 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5625 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
5626 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
5628 first_line = last_line = line;
5629 while (line <= dla_end)
5631 Bufpos old_start, old_end, new_start;
5632 struct display_line *cdl = Dynarr_atp (cdla, line);
5633 struct display_line *ddl = Dynarr_atp (ddla, line);
5634 struct display_block *db;
5637 assert (cdl->bufpos == ddl->bufpos);
5638 assert (cdl->end_bufpos == ddl->end_bufpos);
5639 assert (cdl->offset == ddl->offset);
5641 db = get_display_block_from_line (ddl, TEXT);
5642 initial_size = Dynarr_length (db->runes);
5643 old_start = ddl->bufpos + ddl->offset;
5644 old_end = ddl->end_bufpos + ddl->offset;
5646 /* If this is the first line being updated and it used
5647 propagation data, fail. Otherwise we'll be okay because
5648 we'll have the necessary propagation data. */
5649 if (line == first_line && ddl->used_prop_data)
5652 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5653 &prop, DESIRED_DISP);
5656 /* #### If there is propagated stuff the fail. We could
5657 probably actually deal with this if the line had propagated
5658 information when originally created by a full
5666 /* If any line position parameters have changed or a
5667 cursor has disappeared or disappeared, fail. */
5668 db = get_display_block_from_line (ddl, TEXT);
5669 if (cdl->ypos != ddl->ypos
5670 || cdl->ascent != ddl->ascent
5671 || cdl->descent != ddl->descent
5672 || cdl->top_clip != ddl->top_clip
5673 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5674 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1)
5675 || old_start != ddl->bufpos
5676 || old_end != ddl->end_bufpos
5677 || initial_size != Dynarr_length (db->runes))
5682 if (ddl->cursor_elt != -1)
5684 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5685 w->last_point_y[DESIRED_DISP] = line;
5690 /* If the extent changes end on the line we just updated then
5691 we're done. Otherwise go on to the next line. */
5692 if (end_unchanged <= ddl->end_bufpos)
5698 redisplay_update_line (w, first_line, last_line, 1);
5702 /* Attempt to update the display data structures based on knowledge of
5703 the changed region in the buffer. Returns a boolean indicating
5704 success or failure. If this function returns a failure then a
5705 regenerate_window _must_ be performed next in order to maintain
5706 invariants located here. */
5709 regenerate_window_incrementally (struct window *w, Bufpos startp,
5712 struct buffer *b = XBUFFER (w->buffer);
5713 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5714 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5715 Charcount beg_unchanged, end_unchanged;
5716 Charcount extent_beg_unchanged, extent_end_unchanged;
5722 /* If this function is called, the current and desired structures
5723 had better be identical. If they are not, then that is a bug. */
5724 assert (Dynarr_length (cdla) == Dynarr_length (ddla));
5726 /* We don't handle minibuffer windows yet. The minibuffer prompt
5728 if (MINI_WINDOW_P (w))
5731 extent_beg_unchanged = BUF_EXTENT_BEGIN_UNCHANGED (b);
5732 extent_end_unchanged = (BUF_EXTENT_END_UNCHANGED (b) == -1
5734 : BUF_Z (b) - BUF_EXTENT_END_UNCHANGED (b));
5736 /* If nothing has changed in the buffer, then make sure point is ok
5738 if (BUF_BEGIN_UNCHANGED (b) == -1 && BUF_END_UNCHANGED (b) == -1)
5739 return regenerate_window_extents_only_changed (w, startp, pointm,
5740 extent_beg_unchanged,
5741 extent_end_unchanged);
5743 /* We can't deal with deleted newlines. */
5744 if (BUF_NEWLINE_WAS_DELETED (b))
5747 beg_unchanged = BUF_BEGIN_UNCHANGED (b);
5748 end_unchanged = (BUF_END_UNCHANGED (b) == -1
5750 : BUF_Z (b) - BUF_END_UNCHANGED (b));
5752 REGEN_INC_FIND_START_END;
5754 /* If the changed area starts before the visible area, give up. */
5755 if (beg_unchanged < startp)
5758 /* Find what display line the buffer changes first affect. */
5760 while (line <= dla_end)
5762 struct display_line *dl = Dynarr_atp (cdla, line);
5763 Bufpos lstart = dl->bufpos + dl->offset;
5764 Bufpos lend = dl->end_bufpos + dl->offset;
5766 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5772 /* If the changes are below the visible area then if point hasn't
5773 moved return success otherwise fail in order to be safe. */
5775 return regenerate_window_extents_only_changed (w, startp, pointm,
5776 extent_beg_unchanged,
5777 extent_end_unchanged);
5779 /* At this point we know what line the changes first affect. We
5780 now redraw that line. If the changes are contained within it
5781 we are going to succeed and can update just that one line.
5782 Otherwise we fail. If we fail we will have altered the desired
5783 structs which could lead to an assertion failure. However, if
5784 we fail the next thing that is going to happen is a full regen
5785 so we will actually end up being safe. */
5788 prop_block_dynarr *prop = NULL;
5789 struct display_line *cdl = Dynarr_atp (cdla, line);
5790 struct display_line *ddl = Dynarr_atp (ddla, line);
5792 assert (cdl->bufpos == ddl->bufpos);
5793 assert (cdl->end_bufpos == ddl->end_bufpos);
5794 assert (cdl->offset == ddl->offset);
5796 /* If the line continues to next display line, fail. */
5797 if (ddl->line_continuation)
5800 /* If the line was generated using propagation data, fail. */
5801 if (ddl->used_prop_data)
5804 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5805 &prop, DESIRED_DISP);
5808 /* If there is propagated stuff then it is pretty much a
5809 guarantee that more than just the one line is affected. */
5816 /* If the line continues to next display line, fail. */
5817 if (ddl->line_continuation)
5820 /* If any line position parameters have changed or a
5821 cursor has disappeared or disappeared, fail. */
5822 if (cdl->ypos != ddl->ypos
5823 || cdl->ascent != ddl->ascent
5824 || cdl->descent != ddl->descent
5825 || cdl->top_clip != ddl->top_clip
5826 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5827 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1))
5832 /* If the changed area also ends on this line, then we may be in
5833 business. Update everything and return success. */
5834 if (end_unchanged >= ddl->bufpos && end_unchanged <= ddl->end_bufpos)
5836 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5837 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5838 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp),
5840 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm),
5843 if (ddl->cursor_elt != -1)
5845 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5846 w->last_point_y[DESIRED_DISP] = line;
5849 redisplay_update_line (w, line, line, 1);
5850 regenerate_modeline (w);
5852 /* #### For now we just flush the cache until this has been
5853 tested. After that is done, this should correct the
5855 Dynarr_reset (w->line_start_cache);
5857 /* Adjust the extent changed boundaries to remove any
5858 overlap with the buffer changes since we've just
5859 successfully updated that area. */
5860 if (extent_beg_unchanged != -1
5861 && extent_beg_unchanged >= beg_unchanged
5862 && extent_beg_unchanged < end_unchanged)
5863 extent_beg_unchanged = end_unchanged;
5865 if (extent_end_unchanged != -1
5866 && extent_end_unchanged >= beg_unchanged
5867 && extent_end_unchanged < end_unchanged)
5868 extent_end_unchanged = beg_unchanged - 1;
5870 if (extent_end_unchanged <= extent_beg_unchanged)
5871 extent_beg_unchanged = extent_end_unchanged = -1;
5873 /* This could lead to odd results if it fails, but since the
5874 buffer changes update succeeded this probably will to.
5875 We already know that the extent changes start at or after
5876 the line because we checked before entering the loop. */
5877 if (extent_beg_unchanged != -1
5878 && extent_end_unchanged != -1
5879 && ((extent_beg_unchanged < ddl->bufpos)
5880 || (extent_end_unchanged > ddl->end_bufpos)))
5881 return regenerate_window_extents_only_changed (w, startp, pointm,
5882 extent_beg_unchanged,
5883 extent_end_unchanged);
5893 /* Given a window and a point, update the given display lines such
5894 that point is displayed in the middle of the window.
5895 Return the window's new start position. */
5898 regenerate_window_point_center (struct window *w, Bufpos point, int type)
5902 /* We need to make sure that the modeline is generated so that the
5903 window height can be calculated correctly. */
5904 ensure_modeline_generated (w, type);
5906 startp = start_with_line_at_pixpos (w, point, window_half_pixpos (w));
5907 regenerate_window (w, startp, point, type);
5908 Fset_marker (w->start[type], make_int (startp), w->buffer);
5913 /* Given a window and a set of display lines, return a boolean
5914 indicating whether the given point is contained within. */
5917 point_visible (struct window *w, Bufpos point, int type)
5919 struct buffer *b = XBUFFER (w->buffer);
5920 display_line_dynarr *dla = window_display_lines (w, type);
5923 if (Dynarr_length (dla) && Dynarr_atp (dla, 0)->modeline)
5928 if (Dynarr_length (dla) > first_line)
5931 struct display_line *dl = Dynarr_atp (dla, first_line);
5934 end = BUF_Z (b) - w->window_end_pos[type] - 1;
5936 if (point >= start && point <= end)
5938 if (!MINI_WINDOW_P (w) && scroll_on_clipped_lines)
5940 dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
5942 if (point >= (dl->bufpos + dl->offset)
5943 && point <= (dl->end_bufpos + dl->offset))
5958 /* Return pixel position the middle of the window, not including the
5959 modeline and any potential horizontal scrollbar. */
5962 window_half_pixpos (struct window *w)
5964 return WINDOW_TEXT_TOP (w) + (WINDOW_TEXT_HEIGHT (w) >> 1);
5967 /* Return the display line which is currently in the middle of the
5968 window W for display lines TYPE. */
5971 line_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5973 display_line_dynarr *dla;
5976 int first_elt = (MINI_WINDOW_P (w) ? 0 : 1);
5978 if (type == CMOTION_DISP)
5979 regenerate_window (w, start, point, type);
5981 dla = window_display_lines (w, type);
5982 half = window_half_pixpos (w);
5984 for (elt = first_elt; elt < Dynarr_length (dla); elt++)
5986 struct display_line *dl = Dynarr_atp (dla, elt);
5987 int line_bot = dl->ypos + dl->descent;
5989 if (line_bot > half)
5993 /* We may not have a line at the middle if the end of the buffer is
5998 /* Return a value for point that would place it at the beginning of
5999 the line which is in the middle of the window. */
6002 point_at_center (struct window *w, int type, Bufpos start, Bufpos point)
6004 /* line_at_center will regenerate the display structures, if necessary. */
6005 int line = line_at_center (w, type, start, point);
6008 return BUF_ZV (XBUFFER (w->buffer));
6011 display_line_dynarr *dla = window_display_lines (w, type);
6012 struct display_line *dl = Dynarr_atp (dla, line);
6018 /* For a given window, ensure that the current visual representation
6022 redisplay_window (Lisp_Object window, int skip_selected)
6024 struct window *w = XWINDOW (window);
6025 struct frame *f = XFRAME (w->frame);
6026 struct device *d = XDEVICE (f->device);
6027 Lisp_Object old_buffer = w->buffer;
6028 Lisp_Object the_buffer = w->buffer;
6030 int echo_active = 0;
6035 int selected_in_its_frame;
6036 int selected_globally;
6037 int skip_output = 0;
6038 int truncation_changed;
6039 int inactive_minibuffer =
6040 (MINI_WINDOW_P (w) &&
6041 (f != device_selected_frame (d)) &&
6042 !is_surrogate_for_selected_frame (f));
6044 /* #### In the new world this function actually does a bunch of
6045 optimizations such as buffer-based scrolling, but none of that is
6048 /* If this is a combination window, do its children; that's all.
6049 The selected window is always a leaf so we don't check for
6050 skip_selected here. */
6051 if (!NILP (w->vchild))
6053 redisplay_windows (w->vchild, skip_selected);
6056 if (!NILP (w->hchild))
6058 redisplay_windows (w->hchild, skip_selected);
6062 /* Is this window the selected window on its frame? */
6063 selected_in_its_frame = (w == XWINDOW (FRAME_SELECTED_WINDOW (f)));
6065 selected_in_its_frame &&
6066 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
6067 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d &&
6068 XFRAME(DEVICE_SELECTED_FRAME(d)) == f;
6069 if (skip_selected && selected_in_its_frame)
6072 /* It is possible that the window is not fully initialized yet. */
6073 if (NILP (w->buffer))
6076 if (MINI_WINDOW_P (w) && echo_area_active (f))
6078 w->buffer = the_buffer = Vecho_area_buffer;
6082 b = XBUFFER (w->buffer);
6086 old_pointm = selected_globally
6088 : marker_position (w->pointm[CURRENT_DISP]);
6093 if (selected_globally)
6095 pointm = BUF_PT (b);
6099 pointm = marker_position (w->pointm[CURRENT_DISP]);
6101 if (pointm < BUF_BEGV (b))
6102 pointm = BUF_BEGV (b);
6103 else if (pointm > BUF_ZV (b))
6104 pointm = BUF_ZV (b);
6107 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm), the_buffer);
6109 /* If the buffer has changed we have to invalidate all of our face
6111 if ((!echo_active && b != window_display_buffer (w))
6112 || !Dynarr_length (w->face_cachels)
6113 || f->faces_changed)
6114 reset_face_cachels (w);
6116 mark_face_cachels_as_not_updated (w);
6118 /* Ditto the glyph cache elements, although we do *not* invalidate
6119 the cache purely because glyphs have changed - this is now
6120 handled by the dirty flag.*/
6121 if ((!echo_active && b != window_display_buffer (w))
6122 || !Dynarr_length (w->glyph_cachels) || f->faces_changed)
6123 reset_glyph_cachels (w);
6125 mark_glyph_cachels_as_not_updated (w);
6127 /* If the marker's buffer is not the window's buffer, then we need
6128 to find a new starting position. */
6129 if (!MINI_WINDOW_P (w)
6130 && !EQ (Fmarker_buffer (w->start[CURRENT_DISP]), w->buffer))
6132 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6134 goto regeneration_done;
6139 old_startp = marker_position (w->start[CURRENT_DISP]);
6144 startp = marker_position (w->start[CURRENT_DISP]);
6145 if (startp < BUF_BEGV (b))
6146 startp = BUF_BEGV (b);
6147 else if (startp > BUF_ZV (b))
6148 startp = BUF_ZV (b);
6150 Fset_marker (w->start[DESIRED_DISP], make_int (startp), the_buffer);
6152 truncation_changed = (find_window_mirror (w)->truncate_win !=
6153 window_truncation_on (w));
6155 /* If w->force_start is set, then some function set w->start and we
6156 should display from there and change point, if necessary, to
6157 ensure that it is visible. */
6158 if (w->force_start || inactive_minibuffer)
6161 w->last_modified[DESIRED_DISP] = Qzero;
6162 w->last_facechange[DESIRED_DISP] = Qzero;
6164 regenerate_window (w, startp, pointm, DESIRED_DISP);
6166 if (!point_visible (w, pointm, DESIRED_DISP) && !inactive_minibuffer)
6168 pointm = point_at_center (w, DESIRED_DISP, 0, 0);
6170 if (selected_globally)
6171 BUF_SET_PT (b, pointm);
6173 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm),
6176 /* #### BUFU amounts of overkill just to get the cursor
6177 location marked properly. FIX ME FIX ME FIX ME */
6178 regenerate_window (w, startp, pointm, DESIRED_DISP);
6181 goto regeneration_done;
6184 /* If nothing has changed since the last redisplay, then we just
6185 need to make sure that point is still visible. */
6186 if (XINT (w->last_modified[CURRENT_DISP]) >= BUF_MODIFF (b)
6187 && XINT (w->last_facechange[CURRENT_DISP]) >= BUF_FACECHANGE (b)
6189 /* This check is to make sure we restore the minibuffer after a
6190 temporary change to the echo area. */
6191 && !(MINI_WINDOW_P (w) && f->buffers_changed)
6192 && !f->frame_changed
6193 && !truncation_changed
6194 /* check whether start is really at the beginning of a line GE */
6195 && (!w->start_at_line_beg || beginning_of_line_p (b, startp))
6198 /* Check if the cursor has actually moved. */
6199 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
6200 && pointm == marker_position (w->last_point[CURRENT_DISP])
6201 && selected_globally
6202 && !w->windows_changed
6204 && !f->extents_changed
6205 && !f->faces_changed
6206 && !f->glyphs_changed
6207 && !f->subwindows_changed
6208 /* && !f->subwindows_state_changed*/
6209 && !f->point_changed
6210 && !f->windows_structure_changed)
6212 /* If not, we're done. */
6213 if (f->modeline_changed)
6214 regenerate_modeline (w);
6217 goto regeneration_done;
6221 /* If the new point is visible in the redisplay structures,
6222 then let the output update routines handle it, otherwise
6223 do things the hard way. */
6224 if (!w->windows_changed
6226 && !f->extents_changed
6227 && !f->faces_changed
6228 && !f->glyphs_changed
6229 && !f->subwindows_changed
6230 /* && !f->subwindows_state_changed*/
6231 && !f->windows_structure_changed)
6233 if (point_visible (w, pointm, CURRENT_DISP)
6234 && w->last_point_x[CURRENT_DISP] != -1
6235 && w->last_point_y[CURRENT_DISP] != -1)
6237 if (redisplay_move_cursor (w, pointm, FRAME_TTY_P (f)))
6239 /* Always regenerate in case it is displaying
6240 the current line or column. */
6241 regenerate_modeline (w);
6244 goto regeneration_done;
6247 else if (!selected_in_its_frame && !f->point_changed)
6249 if (f->modeline_changed)
6250 regenerate_modeline (w);
6253 goto regeneration_done;
6257 /* If we weren't able to take the shortcut method, then use
6258 the brute force method. */
6259 regenerate_window (w, startp, pointm, DESIRED_DISP);
6261 if (point_visible (w, pointm, DESIRED_DISP))
6262 goto regeneration_done;
6266 /* Check if the starting point is no longer at the beginning of a
6267 line, in which case find a new starting point. We also recenter
6268 if our start position is equal to point-max. Otherwise we'll end
6269 up with a blank window. */
6270 else if (((w->start_at_line_beg || MINI_WINDOW_P (w))
6271 && !(startp == BUF_BEGV (b)
6272 || BUF_FETCH_CHAR (b, startp - 1) == '\n'))
6273 || (pointm == startp &&
6274 EQ (Fmarker_buffer (w->last_start[CURRENT_DISP]), w->buffer) &&
6275 startp < marker_position (w->last_start[CURRENT_DISP]))
6276 || (startp == BUF_ZV (b)))
6278 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6280 goto regeneration_done;
6282 /* See if we can update the data structures locally based on
6283 knowledge of what changed in the buffer. */
6284 else if (!w->windows_changed
6286 && !f->faces_changed
6287 && !f->glyphs_changed
6288 && !f->subwindows_changed
6289 /* && !f->subwindows_state_changed*/
6290 && !f->windows_structure_changed
6291 && !f->frame_changed
6292 && !truncation_changed
6294 && regenerate_window_incrementally (w, startp, pointm))
6296 if (f->modeline_changed
6297 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b)
6298 || XINT (w->last_facechange[CURRENT_DISP]) < BUF_FACECHANGE (b))
6299 regenerate_modeline (w);
6302 goto regeneration_done;
6304 /* #### This is where a check for structure based scrolling would go. */
6305 /* If all else fails, try just regenerating and see what happens. */
6308 regenerate_window (w, startp, pointm, DESIRED_DISP);
6310 if (point_visible (w, pointm, DESIRED_DISP))
6311 goto regeneration_done;
6314 /* We still haven't gotten the window regenerated with point
6315 visible. Next we try scrolling a little and see if point comes
6316 back onto the screen. */
6317 if (scroll_step > 0)
6319 int scrolled = scroll_conservatively;
6320 for (; scrolled >= 0; scrolled -= scroll_step)
6322 startp = vmotion (w, startp,
6323 (pointm < startp) ? -scroll_step : scroll_step, 0);
6324 regenerate_window (w, startp, pointm, DESIRED_DISP);
6326 if (point_visible (w, pointm, DESIRED_DISP))
6327 goto regeneration_done;
6331 /* We still haven't managed to get the screen drawn with point on
6332 the screen, so just center it and be done with it. */
6333 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6338 /* If the window's frame is changed then reset the current display
6339 lines in order to force a full repaint. */
6340 if (f->frame_changed)
6342 display_line_dynarr *cla = window_display_lines (w, CURRENT_DISP);
6347 /* Must do this before calling redisplay_output_window because it
6348 sets some markers on the window. */
6351 w->buffer = old_buffer;
6352 Fset_marker (w->pointm[DESIRED_DISP], make_int (old_pointm), old_buffer);
6353 Fset_marker (w->start[DESIRED_DISP], make_int (old_startp), old_buffer);
6356 /* These also have to be set before calling redisplay_output_window
6357 since it sets the CURRENT_DISP values based on them. */
6358 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
6359 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
6360 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
6361 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
6365 Bufpos start = marker_position (w->start[DESIRED_DISP]);
6366 Bufpos end = (w->window_end_pos[DESIRED_DISP] == -1
6368 : BUF_Z (b) - w->window_end_pos[DESIRED_DISP] - 1);
6369 /* Don't pollute the cache if not sure if we are correct */
6370 if (w->start_at_line_beg)
6371 update_line_start_cache (w, start, end, pointm, 1);
6372 redisplay_output_window (w);
6374 * If we just displayed the echo area, the line start cache is
6375 * no longer valid, because the minibuffer window is associated
6376 * with the window now.
6379 w->line_cache_last_updated = make_int (-1);
6382 /* #### This should be dependent on face changes and will need to be
6383 somewhere else once tty updates occur on a per-frame basis. */
6384 mark_face_cachels_as_clean (w);
6386 /* The glyph cachels only get dirty if someone changed something.
6387 Since redisplay has now effectively ended we can reset the dirty
6388 flag since everything must be up-to-date. */
6390 mark_glyph_cachels_as_clean (w);
6392 w->windows_changed = 0;
6395 /* Call buffer_reset_changes for all buffers present in any window
6396 currently visible in all frames on all devices. #### There has to
6397 be a better way to do this. */
6400 reset_buffer_changes_mapfun (struct window *w, void *ignored_closure)
6402 buffer_reset_changes (XBUFFER (w->buffer));
6407 reset_buffer_changes (void)
6409 Lisp_Object frmcons, devcons, concons;
6411 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
6413 struct frame *f = XFRAME (XCAR (frmcons));
6415 if (FRAME_REPAINT_P (f))
6416 map_windows (f, reset_buffer_changes_mapfun, 0);
6420 /* Ensure that all windows underneath the given window in the window
6421 hierarchy are correctly displayed. */
6424 redisplay_windows (Lisp_Object window, int skip_selected)
6426 for (; !NILP (window) ; window = XWINDOW (window)->next)
6428 redisplay_window (window, skip_selected);
6433 call_redisplay_end_triggers (struct window *w, void *closure)
6435 Bufpos lrpos = w->last_redisplay_pos;
6436 w->last_redisplay_pos = 0;
6437 if (!NILP (w->buffer)
6438 && !NILP (w->redisplay_end_trigger)
6443 if (MARKERP (w->redisplay_end_trigger)
6444 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
6445 pos = marker_position (w->redisplay_end_trigger);
6446 else if (INTP (w->redisplay_end_trigger))
6447 pos = XINT (w->redisplay_end_trigger);
6450 w->redisplay_end_trigger = Qnil;
6457 XSETWINDOW (window, w);
6458 va_run_hook_with_args_in_buffer (XBUFFER (w->buffer),
6459 Qredisplay_end_trigger_functions,
6461 w->redisplay_end_trigger);
6462 w->redisplay_end_trigger = Qnil;
6469 /* Ensure that all windows on the given frame are correctly displayed. */
6472 redisplay_frame (struct frame *f, int preemption_check)
6474 struct device *d = XDEVICE (f->device);
6476 if (preemption_check
6477 && !DEVICE_IMPL_FLAG (d, XDEVIMPF_DONT_PREEMPT_REDISPLAY))
6479 /* The preemption check itself takes a lot of time,
6480 so normally don't do it here. We do it if called
6481 from Lisp, though (`redisplay-frame'). */
6484 REDISPLAY_PREEMPTION_CHECK;
6489 if (!internal_equal (f->old_buffer_alist, f->buffer_alist, 0))
6493 f->old_buffer_alist = Freplace_list (f->old_buffer_alist,
6495 XSETFRAME (frame, f);
6496 va_run_hook_with_args (Qbuffer_list_changed_hook, 1, frame);
6499 /* Before we put a hold on frame size changes, attempt to process
6500 any which are already pending. */
6501 if (f->size_change_pending)
6502 change_frame_size (f, f->new_height, f->new_width, 0);
6504 /* If frame size might need to be changed, due to changed size
6505 of toolbars, scrollbars etc, change it now */
6506 if (f->size_slipped)
6508 adjust_frame_size (f);
6509 assert (!f->size_slipped);
6512 /* The menubar, toolbar, and icon updates must be done before
6513 hold_frame_size_changes is called and we are officially
6514 'in_display'. They may eval lisp code which may call Fsignal.
6515 If in_display is set Fsignal will abort. */
6517 #ifdef HAVE_MENUBARS
6518 /* Update the menubar. It is done first since it could change
6519 the menubar's visibility. This way we avoid having flashing
6520 caused by an Expose event generated by the visibility change
6522 update_frame_menubars (f);
6523 #endif /* HAVE_MENUBARS */
6524 #ifdef HAVE_TOOLBARS
6525 /* Update the toolbars geometry. We don't update the toolbars
6526 themselves at this point since the space they are trying to
6527 occupy may currently by occupied by gutter elements. Instead we
6528 update the geometry, then update the gutter geometry, then update
6529 the gutters - which will cause mapped windows to be repositioned
6530 - and finally update the toolbars. */
6531 update_frame_toolbars_geometry (f);
6532 #endif /* HAVE_TOOLBARS */
6533 /* Gutter update proper has to be done inside display when no frame
6534 size changes can occur, thus we separately update the gutter
6535 geometry here if it needs it. */
6536 update_frame_gutter_geometry (f);
6538 /* If we clear the frame we have to force its contents to be redrawn. */
6540 f->frame_changed = 1;
6542 /* Invalidate the subwindow caches. We use subwindows_changed here
6543 to cause subwindows to get instantiated. This is because
6544 subwindows_state_changed is less strict - dealing with things
6545 like the clicked state of button. We have to do this before
6546 redisplaying the gutters as subwindows get unmapped in the
6548 if (f->frame_changed)
6549 reset_frame_subwindow_instance_cache (f);
6551 if (f->frame_changed || f->subwindows_changed)
6553 /* we have to do this so the gutter gets regenerated. */
6554 reset_gutter_display_lines (f);
6557 hold_frame_size_changes ();
6559 /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */
6560 /* Within this section, we are defenseless and assume that the
6561 following cannot happen:
6563 1) garbage collection
6564 2) Lisp code evaluation
6565 3) frame size changes
6567 We ensure (3) by calling hold_frame_size_changes(), which
6568 will cause any pending frame size changes to get put on hold
6569 till after the end of the critical section. (1) follows
6570 automatically if (2) is met. #### Unfortunately, there are
6571 some places where Lisp code can be called within this section.
6572 We need to remove them.
6574 If Fsignal() is called during this critical section, we
6577 If garbage collection is called during this critical section,
6578 we simply return. #### We should abort instead.
6580 #### If a frame-size change does occur we should probably
6581 actually be preempting redisplay. */
6583 MAYBE_DEVMETH (d, frame_output_begin, (f));
6585 /* We can now update the gutters, safe in the knowledge that our
6586 efforts won't get undone. */
6588 /* This can call lisp, but redisplay is protected by binding
6589 inhibit_quit. More importantly the code involving display lines
6590 *assumes* that GC will not happen and so does not GCPRO
6591 anything. Since we use this code the whole time with the gutters
6592 we cannot allow GC to happen when manipulating the gutters. */
6593 update_frame_gutters (f);
6595 /* Erase the frame before outputting its contents. */
6598 MAYBE_DEVMETH (d, clear_frame, (f));
6601 /* Do the selected window first. */
6602 redisplay_window (FRAME_SELECTED_WINDOW (f), 0);
6604 /* Then do the rest. */
6605 redisplay_windows (f->root_window, 1);
6607 MAYBE_DEVMETH (d, frame_output_end, (f));
6609 update_frame_title (f);
6611 #ifdef HAVE_TOOLBARS
6612 /* Finally update the toolbars. It seems its possible to get in a
6613 cycle between updating the gutter and the toolbars. Basically we
6614 want to end up with both being up-to-date and this doesn't seem
6615 possible in a single pass. */
6616 update_frame_toolbars (f);
6617 #endif /* HAVE_TOOLBARS */
6619 CLASS_RESET_CHANGED_FLAGS (f);
6620 f->window_face_cache_reset = 0;
6621 f->echo_area_garbaged = 0;
6624 if (!f->size_change_pending)
6625 f->size_changed = 0;
6627 /* ----------------- END CRITICAL REDISPLAY SECTION ---------------- */
6629 /* Allow frame size changes to occur again.
6631 #### what happens if changes to other frames happen? */
6632 unhold_one_frame_size_changes (f);
6634 map_windows (f, call_redisplay_end_triggers, 0);
6638 /* Ensure that all frames on the given device are correctly displayed.
6639 If AUTOMATIC is non-zero, and the device implementation indicates
6640 no automatic redisplay, as printers do, then the device is not
6641 redisplayed. AUTOMATIC is set to zero when called from lisp
6642 functions (redraw-device) and (redisplay-device), and to non-zero
6643 when called from "lazy" redisplay();
6647 redisplay_device (struct device *d, int automatic)
6649 Lisp_Object frame, frmcons;
6650 int size_change_failed = 0;
6653 if (automatic && DEVICE_IMPL_FLAG (d, XDEVIMPF_NO_AUTO_REDISPLAY))
6656 if (DEVICE_STREAM_P (d)) /* nothing to do */
6659 /* It is possible that redisplay has been called before the
6660 device is fully initialized, or that the console implementation
6661 allows frameless devices. If so then continue with the next
6663 if (NILP (DEVICE_SELECTED_FRAME (d)))
6666 if (!DEVICE_IMPL_FLAG (d, XDEVIMPF_DONT_PREEMPT_REDISPLAY))
6669 REDISPLAY_PREEMPTION_CHECK;
6674 /* Always do the selected frame first. */
6675 frame = DEVICE_SELECTED_FRAME (d);
6679 if (f->icon_changed || f->windows_changed)
6680 update_frame_icon (f);
6682 if (FRAME_REPAINT_P (f))
6684 if (CLASS_REDISPLAY_FLAGS_CHANGEDP(f))
6686 int preempted = redisplay_frame (f, 0);
6691 /* If the frame redisplay did not get preempted, then this flag
6692 should have gotten set to 0. It might be possible for that
6693 not to happen if a size change event were to occur at an odd
6694 time. To make sure we don't miss anything we simply don't
6695 reset the top level flags until the condition ends up being
6696 in the right state. */
6697 if (f->size_changed)
6698 size_change_failed = 1;
6701 DEVICE_FRAME_LOOP (frmcons, d)
6703 f = XFRAME (XCAR (frmcons));
6705 if (f == XFRAME (DEVICE_SELECTED_FRAME (d)))
6708 if (f->icon_changed || f->windows_changed)
6709 update_frame_icon (f);
6711 if (FRAME_REPAINT_P (f))
6713 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (f))
6715 int preempted = redisplay_frame (f, 0);
6720 if (f->size_change_pending)
6721 size_change_failed = 1;
6725 /* If we get here then we redisplayed all of our frames without
6726 getting preempted so mark ourselves as clean. */
6727 CLASS_RESET_CHANGED_FLAGS (d);
6729 if (!size_change_failed)
6730 d->size_changed = 0;
6736 restore_profiling_redisplay_flag (Lisp_Object val)
6738 profiling_redisplay_flag = XINT (val);
6742 /* Ensure that all windows on all frames on all devices are displaying
6743 the current contents of their respective buffers. */
6746 redisplay_without_hooks (void)
6748 Lisp_Object devcons, concons;
6749 int size_change_failed = 0;
6750 int count = specpdl_depth ();
6752 if (profiling_active)
6754 record_unwind_protect (restore_profiling_redisplay_flag,
6755 make_int (profiling_redisplay_flag));
6756 profiling_redisplay_flag = 1;
6759 if (asynch_device_change_pending)
6760 handle_asynch_device_change ();
6762 if (!GLOBAL_REDISPLAY_FLAGS_CHANGEDP &&
6763 !disable_preemption && preemption_count < max_preempts)
6766 DEVICE_LOOP_NO_BREAK (devcons, concons)
6768 struct device *d = XDEVICE (XCAR (devcons));
6771 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (d))
6773 preempted = redisplay_device (d, 1);
6778 RESET_CHANGED_SET_FLAGS;
6782 /* See comment in redisplay_device. */
6783 if (d->size_changed)
6784 size_change_failed = 1;
6787 preemption_count = 0;
6789 /* Mark redisplay as accurate */
6790 GLOBAL_RESET_CHANGED_FLAGS;
6791 RESET_CHANGED_SET_FLAGS;
6795 mark_all_faces_as_clean ();
6799 if (!size_change_failed)
6802 reset_buffer_changes ();
6805 unbind_to (count, Qnil);
6811 if (last_display_warning_tick != display_warning_tick &&
6812 !inhibit_warning_display)
6814 /* If an error occurs during this function, oh well.
6815 If we report another warning, we could get stuck in an
6816 infinite loop reporting warnings. */
6817 call0_trapping_errors (0, Qdisplay_warning_buffer);
6818 last_display_warning_tick = display_warning_tick;
6820 /* The run_hook_trapping_errors functions are smart enough not
6821 to do any evalling if the hook function is empty, so there
6822 should not be any significant time loss. All places in the
6823 C code that call redisplay() are prepared to handle GCing,
6824 so we should be OK. */
6825 #ifndef INHIBIT_REDISPLAY_HOOKS
6826 run_hook_trapping_errors ("Error in pre-redisplay-hook",
6827 Qpre_redisplay_hook);
6828 #endif /* INHIBIT_REDISPLAY_HOOKS */
6830 redisplay_without_hooks ();
6832 #ifndef INHIBIT_REDISPLAY_HOOKS
6833 run_hook_trapping_errors ("Error in post-redisplay-hook",
6834 Qpost_redisplay_hook);
6835 #endif /* INHIBIT_REDISPLAY_HOOKS */
6839 static char window_line_number_buf[32];
6841 /* Efficiently determine the window line number, and return a pointer
6842 to its printed representation. Do this regardless of whether
6843 line-number-mode is on. The first line in the buffer is counted as
6844 1. If narrowing is in effect, the lines are counted from the
6845 beginning of the visible portion of the buffer. */
6847 window_line_number (struct window *w, int type)
6849 struct device *d = XDEVICE (XFRAME (w->frame)->device);
6850 struct buffer *b = XBUFFER (w->buffer);
6851 /* Be careful in the order of these tests. The first clause will
6852 fail if DEVICE_SELECTED_FRAME == Qnil (since w->frame cannot be).
6853 This can occur when the frame title is computed really early */
6855 ((EQ(DEVICE_SELECTED_FRAME(d), w->frame) &&
6856 (w == XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame(d)))) &&
6857 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
6858 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d )
6860 : marker_position (w->pointm[type]));
6863 line = buffer_line_number (b, pos, 1);
6865 long_to_string (window_line_number_buf, line + 1);
6867 return window_line_number_buf;
6871 /* Given a character representing an object in a modeline
6872 specification, return a string (stored into the global array
6873 `mode_spec_bufbyte_string') with the information that object
6876 This function is largely unchanged from previous versions of the
6879 Warning! This code is also used for frame titles and can be called
6880 very early in the device/frame update process! JV
6884 decode_mode_spec (struct window *w, Emchar spec, int type)
6886 Lisp_Object obj = Qnil;
6887 const char *str = NULL;
6888 struct buffer *b = XBUFFER (w->buffer);
6890 Dynarr_reset (mode_spec_bufbyte_string);
6894 /* print buffer name */
6899 /* print visited file name */
6904 /* print the current column */
6907 Bufpos pt = (w == XWINDOW (Fselected_window (Qnil)))
6909 : marker_position (w->pointm[type]);
6910 int col = column_at_point (b, pt, 1) + !!column_number_start_at_one;
6913 long_to_string (buf, col);
6915 Dynarr_add_many (mode_spec_bufbyte_string,
6916 (const Bufbyte *) buf, strlen (buf));
6918 goto decode_mode_spec_done;
6920 /* print the file coding system */
6924 Lisp_Object codesys = b->buffer_file_coding_system;
6925 /* Be very careful here not to get an error. */
6926 if (NILP (codesys) || SYMBOLP (codesys) || CODING_SYSTEMP (codesys))
6928 codesys = Ffind_coding_system (codesys);
6929 if (CODING_SYSTEMP (codesys))
6930 obj = XCODING_SYSTEM_MNEMONIC (codesys);
6933 #endif /* FILE_CODING */
6936 /* print the current line number */
6938 str = window_line_number (w, type);
6941 /* print value of mode-name (obsolete) */
6946 /* print hyphen and frame number, if != 1 */
6950 struct frame *f = XFRAME (w->frame);
6951 if (FRAME_TTY_P (f) && f->order_count > 1 && f->order_count <= 99999999)
6953 /* Naughty, naughty */
6954 char * writable_str = alloca_array (char, 10);
6955 sprintf (writable_str, "-%d", f->order_count);
6959 #endif /* HAVE_TTY */
6962 /* print Narrow if appropriate */
6964 if (BUF_BEGV (b) > BUF_BEG (b)
6965 || BUF_ZV (b) < BUF_Z (b))
6969 /* print %, * or hyphen, if buffer is read-only, modified or neither */
6971 str = (!NILP (b->read_only)
6973 : ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6978 /* print * or hyphen -- XEmacs change to allow a buffer to be
6979 read-only but still indicate whether it is modified. */
6981 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6983 : (!NILP (b->read_only)
6988 /* #### defined in 19.29 decode_mode_spec, but not in
6989 modeline-format doc string. */
6990 /* This differs from %* in that it ignores read-only-ness. */
6992 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6997 /* print process status */
6999 obj = Fget_buffer_process (w->buffer);
7001 str = GETTEXT ("no process");
7003 obj = Fsymbol_name (Fprocess_status (obj));
7006 /* Print name of selected frame. */
7008 obj = XFRAME (w->frame)->name;
7011 /* indicate TEXT or BINARY */
7013 /* #### NT does not use this any more. Now what? */
7017 /* print percent of buffer above top of window, or Top, Bot or All */
7020 Bufpos pos = marker_position (w->start[type]);
7022 /* This had better be while the desired lines are being done. */
7023 if (w->window_end_pos[type] <= BUF_Z (b) - BUF_ZV (b))
7025 if (pos <= BUF_BEGV (b))
7030 else if (pos <= BUF_BEGV (b))
7034 /* This hard limit is ok since the string it will hold has a
7035 fixed maximum length of 3. But just to be safe... */
7037 Charcount chars = pos - BUF_BEGV (b);
7038 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
7040 /* Avoid overflow on big buffers */
7041 int percent = total > LONG_MAX/200 ?
7042 (chars + total/200) / (total / 100) :
7043 (chars * 100 + total/2) / total;
7045 /* We can't normally display a 3-digit number, so get us a
7046 2-digit number that is close. */
7050 sprintf (buf, "%d%%", percent);
7051 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
7054 goto decode_mode_spec_done;
7059 /* print percent of buffer above bottom of window, perhaps plus
7060 Top, or print Bottom or All */
7063 Bufpos toppos = marker_position (w->start[type]);
7064 Bufpos botpos = BUF_Z (b) - w->window_end_pos[type];
7066 /* botpos is only accurate as of the last redisplay, so we can
7067 only treat it as a hint. In particular, after erase-buffer,
7068 botpos may be negative. */
7069 if (botpos < toppos)
7072 if (botpos >= BUF_ZV (b))
7074 if (toppos <= BUF_BEGV (b))
7081 /* This hard limit is ok since the string it will hold has a
7082 fixed maximum length of around 6. But just to be safe... */
7084 Charcount chars = botpos - BUF_BEGV (b);
7085 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
7087 /* Avoid overflow on big buffers */
7088 int percent = total > LONG_MAX/200 ?
7089 (chars + total/200) / (total / 100) :
7090 (chars * 100 + total/2) / max (total, 1);
7092 /* We can't normally display a 3-digit number, so get us a
7093 2-digit number that is close. */
7097 if (toppos <= BUF_BEGV (b))
7098 sprintf (buf, "Top%d%%", percent);
7100 sprintf (buf, "%d%%", percent);
7102 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
7105 goto decode_mode_spec_done;
7115 /* print one [ for each recursive editing level. */
7120 if (command_loop_level > 5)
7126 for (i = 0; i < command_loop_level; i++)
7127 Dynarr_add (mode_spec_bufbyte_string, '[');
7129 goto decode_mode_spec_done;
7132 /* print one ] for each recursive editing level. */
7137 if (command_loop_level > 5)
7143 for (i = 0; i < command_loop_level; i++)
7144 Dynarr_add (mode_spec_bufbyte_string, ']');
7146 goto decode_mode_spec_done;
7149 /* print infinitely many dashes -- handle at top level now */
7156 Dynarr_add_many (mode_spec_bufbyte_string,
7158 XSTRING_LENGTH (obj));
7160 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) str, strlen (str));
7162 decode_mode_spec_done:
7163 Dynarr_add (mode_spec_bufbyte_string, '\0');
7166 /* Given a display line, free all of its data structures. */
7169 free_display_line (struct display_line *dl)
7173 if (dl->display_blocks)
7175 for (block = 0; block < Dynarr_largest (dl->display_blocks); block++)
7177 struct display_block *db = Dynarr_atp (dl->display_blocks, block);
7179 Dynarr_free (db->runes);
7182 Dynarr_free (dl->display_blocks);
7183 dl->display_blocks = NULL;
7186 if (dl->left_glyphs)
7188 Dynarr_free (dl->left_glyphs);
7189 dl->left_glyphs = NULL;
7192 if (dl->right_glyphs)
7194 Dynarr_free (dl->right_glyphs);
7195 dl->right_glyphs = NULL;
7200 /* Given an array of display lines, free them and all data structures
7201 contained within them. */
7204 free_display_lines (display_line_dynarr *dla)
7208 for (line = 0; line < Dynarr_largest (dla); line++)
7210 free_display_line (Dynarr_atp (dla, line));
7216 /* Call internal free routine for each set of display lines. */
7219 free_display_structs (struct window_mirror *mir)
7221 if (mir->current_display_lines)
7223 free_display_lines (mir->current_display_lines);
7224 mir->current_display_lines = 0;
7227 if (mir->desired_display_lines)
7229 free_display_lines (mir->desired_display_lines);
7230 mir->desired_display_lines = 0;
7236 mark_glyph_block_dynarr (glyph_block_dynarr *gba)
7240 glyph_block *gb = Dynarr_atp (gba, 0);
7241 glyph_block *gb_last = Dynarr_atp (gba, Dynarr_length (gba));
7243 for (; gb < gb_last; gb++)
7245 if (!NILP (gb->glyph))
7246 mark_object (gb->glyph);
7247 if (!NILP (gb->extent))
7248 mark_object (gb->extent);
7253 /* See the comment in image_instantiate_cache_result as to why marking
7254 the glyph will also mark the image_instance. */
7256 mark_redisplay_structs (display_line_dynarr *dla)
7258 display_line *dl = Dynarr_atp (dla, 0);
7259 display_line *dl_last = Dynarr_atp (dla, Dynarr_length (dla));
7261 for (; dl < dl_last; dl++)
7263 display_block_dynarr *dba = dl->display_blocks;
7264 display_block *db = Dynarr_atp (dba, 0);
7265 display_block *db_last = Dynarr_atp (dba, Dynarr_length (dba));
7267 for (; db < db_last; db++)
7269 rune_dynarr *ra = db->runes;
7270 rune *r = Dynarr_atp (ra, 0);
7271 rune *r_last = Dynarr_atp (ra, Dynarr_length (ra));
7273 for (; r < r_last; r++)
7275 if (r->type == RUNE_DGLYPH)
7277 if (!NILP (r->object.dglyph.glyph))
7278 mark_object (r->object.dglyph.glyph);
7279 if (!NILP (r->object.dglyph.extent))
7280 mark_object (r->object.dglyph.extent);
7285 mark_glyph_block_dynarr (dl->left_glyphs);
7286 mark_glyph_block_dynarr (dl->right_glyphs);
7291 mark_window_mirror (struct window_mirror *mir)
7293 mark_redisplay_structs (mir->current_display_lines);
7294 mark_redisplay_structs (mir->desired_display_lines);
7297 mark_window_mirror (mir->next);
7300 mark_window_mirror (mir->hchild);
7301 else if (mir->vchild)
7302 mark_window_mirror (mir->vchild);
7306 mark_redisplay (void)
7308 Lisp_Object frmcons, devcons, concons;
7310 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
7312 struct frame *f = XFRAME (XCAR (frmcons));
7313 mark_window_mirror (f->root_mirror);
7318 /*****************************************************************************
7319 Line Start Cache Description and Rationale
7321 The traditional scrolling code in Emacs breaks in a variable height world.
7322 It depends on the key assumption that the number of lines that can be
7323 displayed at any given time is fixed. This led to a complete separation
7324 of the scrolling code from the redisplay code. In order to fully support
7325 variable height lines, the scrolling code must actually be tightly
7326 integrated with redisplay. Only redisplay can determine how many lines
7327 will be displayed on a screen for any given starting point.
7329 What is ideally wanted is a complete list of the starting buffer position
7330 for every possible display line of a buffer along with the height of that
7331 display line. Maintaining such a full list would be very expensive. We
7332 settle for having it include information for all areas which we happen to
7333 generate anyhow (i.e. the region currently being displayed) and for those
7334 areas we need to work with.
7336 In order to ensure that the cache accurately represents what redisplay
7337 would actually show, it is necessary to invalidate it in many situations.
7338 If the buffer changes, the starting positions may no longer be correct.
7339 If a face or an extent has changed then the line heights may have altered.
7340 These events happen frequently enough that the cache can end up being
7341 constantly disabled. With this potentially constant invalidation when is
7342 the cache ever useful?
7344 Even if the cache is invalidated before every single usage, it is
7345 necessary. Scrolling often requires knowledge about display lines which
7346 are actually above or below the visible region. The cache provides a
7347 convenient light-weight method of storing this information for multiple
7348 display regions. This knowledge is necessary for the scrolling code to
7349 always obey the First Golden Rule of Redisplay.
7351 If the cache already contains all of the information that the scrolling
7352 routines happen to need so that it doesn't have to go generate it, then we
7353 are able to obey the Third Golden Rule of Redisplay. The first thing we
7354 do to help out the cache is to always add the displayed region. This
7355 region had to be generated anyway, so the cache ends up getting the
7356 information basically for free. In those cases where a user is simply
7357 scrolling around viewing a buffer there is a high probability that this is
7358 sufficient to always provide the needed information. The second thing we
7359 can do is be smart about invalidating the cache.
7361 TODO -- Be smart about invalidating the cache. Potential places:
7363 + Insertions at end-of-line which don't cause line-wraps do not alter the
7364 starting positions of any display lines. These types of buffer
7365 modifications should not invalidate the cache. This is actually a large
7366 optimization for redisplay speed as well.
7368 + Buffer modifications frequently only affect the display of lines at and
7369 below where they occur. In these situations we should only invalidate
7370 the part of the cache starting at where the modification occurs.
7372 In case you're wondering, the Second Golden Rule of Redisplay is not
7374 ****************************************************************************/
7376 /* This will get used quite a bit so we don't want to be constantly
7377 allocating and freeing it. */
7378 static line_start_cache_dynarr *internal_cache;
7380 /* Makes internal_cache represent the TYPE display structs and only
7381 the TYPE display structs. */
7384 update_internal_cache_list (struct window *w, int type)
7387 display_line_dynarr *dla = window_display_lines (w, type);
7389 Dynarr_reset (internal_cache);
7390 for (line = 0; line < Dynarr_length (dla); line++)
7392 struct display_line *dl = Dynarr_atp (dla, line);
7398 struct line_start_cache lsc;
7400 lsc.start = dl->bufpos;
7401 lsc.end = dl->end_bufpos;
7402 lsc.height = dl->ascent + dl->descent;
7404 Dynarr_add (internal_cache, lsc);
7409 /* Reset the line cache if necessary. This should be run at the
7410 beginning of any function which access the cache. */
7413 validate_line_start_cache (struct window *w)
7415 struct buffer *b = XBUFFER (w->buffer);
7416 struct frame *f = XFRAME (w->frame);
7418 if (!w->line_cache_validation_override)
7420 /* f->extents_changed used to be in here because extent face and
7421 size changes can cause text shifting. However, the extent
7422 covering the region is constantly having its face set and
7423 priority altered by the mouse code. This means that the line
7424 start cache is constantly being invalidated. This is bad
7425 since the mouse code also triggers heavy usage of the cache.
7426 Since it is an unlikely that f->extents being changed
7427 indicates that the cache really needs to be updated and if it
7428 does redisplay will catch it pretty quickly we no longer
7429 invalidate the cache if it is set. This greatly speeds up
7430 dragging out regions with the mouse. */
7431 if (XINT (w->line_cache_last_updated) < BUF_MODIFF (b)
7435 Dynarr_reset (w->line_start_cache);
7440 /* Return the very first buffer position contained in the given
7441 window's cache, or -1 if the cache is empty. Assumes that the
7445 line_start_cache_start (struct window *w)
7447 line_start_cache_dynarr *cache = w->line_start_cache;
7449 if (!Dynarr_length (cache))
7452 return Dynarr_atp (cache, 0)->start;
7455 /* Return the very last buffer position contained in the given
7456 window's cache, or -1 if the cache is empty. Assumes that the
7460 line_start_cache_end (struct window *w)
7462 line_start_cache_dynarr *cache = w->line_start_cache;
7464 if (!Dynarr_length (cache))
7467 return Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
7470 /* Return the index of the line POINT is contained within in window
7471 W's line start cache. It will enlarge the cache or move the cache
7472 window in order to have POINT be present in the cache. MIN_PAST is
7473 a guarantee of the number of entries in the cache present on either
7474 side of POINT (unless a buffer boundary is hit). If MIN_PAST is -1
7475 then it will be treated as 0, but the cache window will not be
7476 allowed to shift. Returns -1 if POINT cannot be found in the cache
7480 point_in_line_start_cache (struct window *w, Bufpos point, int min_past)
7482 struct buffer *b = XBUFFER (w->buffer);
7483 line_start_cache_dynarr *cache = w->line_start_cache;
7484 unsigned int top, bottom;
7487 validate_line_start_cache (w);
7488 w->line_cache_validation_override++;
7490 /* Let functions pass in negative values, but we still treat -1
7492 /* #### bogosity alert */
7493 if (min_past < 0 && min_past != -1)
7494 min_past = -min_past;
7496 if (!Dynarr_length (cache) || line_start_cache_start (w) > point
7497 || line_start_cache_end (w) < point)
7500 int win_char_height = window_char_height (w, 1);
7502 /* Occasionally we get here with a 0 height
7503 window. find_next_newline_no_quit will abort if we pass it a
7504 count of 0 so handle that case. */
7505 if (!win_char_height)
7506 win_char_height = 1;
7508 if (!Dynarr_length (cache))
7510 Bufpos from = find_next_newline_no_quit (b, point, -1);
7511 Bufpos to = find_next_newline_no_quit (b, from, win_char_height);
7513 update_line_start_cache (w, from, to, point, 0);
7515 if (!Dynarr_length (cache))
7517 w->line_cache_validation_override--;
7522 assert (Dynarr_length (cache));
7525 while (line_start_cache_start (w) > point
7526 && (loop < cache_adjustment || min_past == -1))
7530 from = line_start_cache_start (w);
7531 if (from <= BUF_BEGV (b))
7534 from = find_next_newline_no_quit (b, from, -win_char_height);
7535 to = line_start_cache_end (w);
7537 update_line_start_cache (w, from, to, point, 0);
7541 if (line_start_cache_start (w) > point)
7545 from = find_next_newline_no_quit (b, point, -1);
7546 if (from >= BUF_ZV (b))
7548 to = find_next_newline_no_quit (b, from, -win_char_height);
7553 to = find_next_newline_no_quit (b, from, win_char_height);
7555 update_line_start_cache (w, from, to, point, 0);
7559 while (line_start_cache_end (w) < point
7560 && (loop < cache_adjustment || min_past == -1))
7564 to = line_start_cache_end (w);
7565 if (to >= BUF_ZV (b))
7568 from = line_start_cache_end (w);
7569 to = find_next_newline_no_quit (b, from, win_char_height);
7571 update_line_start_cache (w, from, to, point, 0);
7575 if (line_start_cache_end (w) < point)
7579 from = find_next_newline_no_quit (b, point, -1);
7580 if (from >= BUF_ZV (b))
7582 to = find_next_newline_no_quit (b, from, -win_char_height);
7587 to = find_next_newline_no_quit (b, from, win_char_height);
7589 update_line_start_cache (w, from, to, point, 0);
7593 assert (Dynarr_length (cache));
7598 /* This could happen if the buffer is narrowed. */
7599 if (line_start_cache_start (w) > point
7600 || line_start_cache_end (w) < point)
7602 w->line_cache_validation_override--;
7608 top = Dynarr_length (cache) - 1;
7616 pos = (bottom + top + 1) >> 1;
7617 start = Dynarr_atp (cache, pos)->start;
7618 end = Dynarr_atp (cache, pos)->end;
7620 if (point >= start && point <= end)
7622 if (pos < min_past && line_start_cache_start (w) > BUF_BEGV (b))
7625 find_next_newline_no_quit (b, line_start_cache_start (w),
7627 Bufpos to = line_start_cache_end (w);
7629 update_line_start_cache (w, from, to, point, 0);
7630 goto find_point_loop;
7632 else if ((Dynarr_length (cache) - pos - 1) < min_past
7633 && line_start_cache_end (w) < BUF_ZV (b))
7635 Bufpos from = line_start_cache_end (w);
7636 Bufpos to = find_next_newline_no_quit (b, from,
7641 update_line_start_cache (w, from, to, point, 0);
7642 goto find_point_loop;
7646 w->line_cache_validation_override--;
7650 else if (point > end)
7652 else if (point < start)
7657 new_pos = (bottom + top + 1) >> 1;
7660 w->line_cache_validation_override--;
7666 /* Return a boolean indicating if POINT would be visible in window W
7667 if display of the window was to begin at STARTP. */
7670 point_would_be_visible (struct window *w, Bufpos startp, Bufpos point)
7672 struct buffer *b = XBUFFER (w->buffer);
7673 int pixpos = -WINDOW_TEXT_TOP_CLIP(w);
7674 int bottom = WINDOW_TEXT_HEIGHT (w);
7677 /* If point is before the intended start it obviously can't be visible. */
7681 /* If point or start are not in the accessible buffer range, then
7683 if (startp < BUF_BEGV (b) || startp > BUF_ZV (b)
7684 || point < BUF_BEGV (b) || point > BUF_ZV (b))
7687 validate_line_start_cache (w);
7688 w->line_cache_validation_override++;
7690 start_elt = point_in_line_start_cache (w, startp, 0);
7691 if (start_elt == -1)
7693 w->line_cache_validation_override--;
7697 assert (line_start_cache_start (w) <= startp
7698 && line_start_cache_end (w) >= startp);
7704 /* Expand the cache if necessary. */
7705 if (start_elt == Dynarr_length (w->line_start_cache))
7708 Dynarr_atp (w->line_start_cache, start_elt - 1)->start;
7710 start_elt = point_in_line_start_cache (w, old_startp,
7711 window_char_height (w, 0));
7713 /* We've already actually processed old_startp, so increment
7717 /* If this happens we didn't add any extra elements. Bummer. */
7718 if (start_elt == Dynarr_length (w->line_start_cache))
7720 w->line_cache_validation_override--;
7725 height = Dynarr_atp (w->line_start_cache, start_elt)->height;
7727 if (pixpos + height > bottom)
7729 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7731 w->line_cache_validation_override--;
7737 if (point <= Dynarr_atp (w->line_start_cache, start_elt)->end)
7739 w->line_cache_validation_override--;
7747 /* For the given window W, if display starts at STARTP, what will be
7748 the buffer position at the beginning or end of the last line
7749 displayed. The end of the last line is also know as the window end
7752 WARNING: It is possible that redisplay failed to layout any lines for the
7753 windows. Under normal circumstances this is rare. However it seems that it
7754 does occur in the following situation: A mouse event has come in and we
7755 need to compute its location in a window. That code (in
7756 pixel_to_glyph_translation) already can handle 0 as an error return value.
7758 #### With a little work this could probably be reworked as just a
7759 call to start_with_line_at_pixpos. */
7762 start_end_of_last_line (struct window *w, Bufpos startp, int end,
7765 struct buffer *b = XBUFFER (w->buffer);
7766 line_start_cache_dynarr *cache = w->line_start_cache;
7768 int bottom = WINDOW_TEXT_HEIGHT (w);
7772 validate_line_start_cache (w);
7773 w->line_cache_validation_override++;
7775 if (startp < BUF_BEGV (b))
7776 startp = BUF_BEGV (b);
7777 else if (startp > BUF_ZV (b))
7778 startp = BUF_ZV (b);
7781 start_elt = point_in_line_start_cache (w, cur_start, 0);
7782 if (start_elt == -1)
7783 return may_error ? 0 : startp;
7787 int height = Dynarr_atp (cache, start_elt)->height;
7789 cur_start = Dynarr_atp (cache, start_elt)->start;
7791 if (pixpos + height > bottom)
7793 /* Adjust for any possible clip. */
7794 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7799 w->line_cache_validation_override--;
7803 return BUF_BEGV (b);
7807 w->line_cache_validation_override--;
7809 return Dynarr_atp (cache, start_elt)->end;
7811 return Dynarr_atp (cache, start_elt)->start;
7817 if (start_elt == Dynarr_length (cache))
7819 Bufpos from = line_start_cache_end (w);
7820 int win_char_height = window_char_height (w, 0);
7821 Bufpos to = find_next_newline_no_quit (b, from,
7826 /* We've hit the end of the bottom so that's what it is. */
7827 if (from >= BUF_ZV (b))
7829 w->line_cache_validation_override--;
7833 update_line_start_cache (w, from, to, BUF_PT (b), 0);
7835 /* Updating the cache invalidates any current indexes. */
7836 start_elt = point_in_line_start_cache (w, cur_start, -1) + 1;
7841 /* For the given window W, if display starts at STARTP, what will be
7842 the buffer position at the beginning of the last line displayed. */
7845 start_of_last_line (struct window *w, Bufpos startp)
7847 return start_end_of_last_line (w, startp, 0 , 0);
7850 /* For the given window W, if display starts at STARTP, what will be
7851 the buffer position at the end of the last line displayed. This is
7852 also know as the window end position. */
7855 end_of_last_line (struct window *w, Bufpos startp)
7857 return start_end_of_last_line (w, startp, 1, 0);
7861 end_of_last_line_may_error (struct window *w, Bufpos startp)
7863 return start_end_of_last_line (w, startp, 1, 1);
7867 /* For window W, what does the starting position have to be so that
7868 the line containing POINT will cover pixel position PIXPOS. */
7871 start_with_line_at_pixpos (struct window *w, Bufpos point, int pixpos)
7873 struct buffer *b = XBUFFER (w->buffer);
7875 Bufpos cur_pos, prev_pos = point;
7876 int point_line_height;
7877 int pixheight = pixpos - WINDOW_TEXT_TOP (w);
7879 validate_line_start_cache (w);
7880 w->line_cache_validation_override++;
7882 cur_elt = point_in_line_start_cache (w, point, 0);
7883 /* #### See comment in update_line_start_cache about big minibuffers. */
7886 w->line_cache_validation_override--;
7890 point_line_height = Dynarr_atp (w->line_start_cache, cur_elt)->height;
7894 cur_pos = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7896 pixheight -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7898 /* Do not take into account the value of vertical_clip here.
7899 That is the responsibility of the calling functions. */
7902 w->line_cache_validation_override--;
7903 if (-pixheight > point_line_height)
7904 /* We can't make the target line cover pixpos, so put it
7905 above pixpos. That way it will at least be visible. */
7915 int win_char_height;
7917 if (cur_pos <= BUF_BEGV (b))
7919 w->line_cache_validation_override--;
7920 return BUF_BEGV (b);
7923 win_char_height = window_char_height (w, 0);
7924 if (!win_char_height)
7925 win_char_height = 1;
7927 from = find_next_newline_no_quit (b, cur_pos, -win_char_height);
7928 to = line_start_cache_end (w);
7929 update_line_start_cache (w, from, to, point, 0);
7931 cur_elt = point_in_line_start_cache (w, cur_pos, 2) - 1;
7932 assert (cur_elt >= -1);
7933 /* This used to be cur_elt>=0 under the assumption that if
7934 point is in the top line and not at BUF_BEGV, then
7935 setting the window_start to a newline before the start of
7936 the first line will always cause scrolling.
7938 However in my (jv) opinion this is wrong. That new line
7939 can be hidden in various ways: invisible extents, an
7940 explicit window-start not at a newline character etc.
7941 The existence of those are indeed known to create crashes
7942 on that assert. So we have no option but to continue the
7943 search if we found point at the top of the line_start_cache
7945 cur_pos = Dynarr_atp (w->line_start_cache,0)->start;
7951 /* For window W, what does the starting position have to be so that
7952 the line containing point is on display line LINE. If LINE is
7953 positive it is considered to be the number of lines from the top of
7954 the window (0 is the top line). If it is negative the number is
7955 considered to be the number of lines from the bottom (-1 is the
7959 start_with_point_on_display_line (struct window *w, Bufpos point, int line)
7961 validate_line_start_cache (w);
7962 w->line_cache_validation_override++;
7966 int cur_elt = point_in_line_start_cache (w, point, line);
7968 if (cur_elt - line < 0)
7969 cur_elt = 0; /* Hit the top */
7973 w->line_cache_validation_override--;
7974 return Dynarr_atp (w->line_start_cache, cur_elt)->start;
7978 /* The calculated value of pixpos is correct for the bottom line
7979 or what we want when line is -1. Therefore we subtract one
7980 because we have already handled one line. */
7981 int new_line = -line - 1;
7982 int cur_elt = point_in_line_start_cache (w, point, new_line);
7983 int pixpos = WINDOW_TEXT_BOTTOM (w);
7984 Bufpos retval, search_point;
7986 /* If scroll_on_clipped_lines is false, the last "visible" line of
7987 the window covers the pixel at WINDOW_TEXT_BOTTOM (w) - 1.
7988 If s_o_c_l is true, then we don't want to count a clipped
7989 line, so back up from the bottom by the height of the line
7990 containing point. */
7991 if (scroll_on_clipped_lines)
7992 pixpos -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7996 if (cur_elt + new_line >= Dynarr_length (w->line_start_cache))
7998 /* Hit the bottom of the buffer. */
8000 (cur_elt + new_line) - Dynarr_length (w->line_start_cache) + 1;
8004 XSETWINDOW (window, w);
8005 default_face_height_and_width (window, &defheight, 0);
8007 cur_elt = Dynarr_length (w->line_start_cache) - 1;
8009 pixpos -= (adjustment * defheight);
8010 if (pixpos < WINDOW_TEXT_TOP (w))
8011 pixpos = WINDOW_TEXT_TOP (w);
8014 cur_elt = cur_elt + new_line;
8016 search_point = Dynarr_atp (w->line_start_cache, cur_elt)->start;
8018 retval = start_with_line_at_pixpos (w, search_point, pixpos);
8019 w->line_cache_validation_override--;
8024 /* This is used to speed up vertical scrolling by caching the known
8025 buffer starting positions for display lines. This allows the
8026 scrolling routines to avoid costly calls to regenerate_window. If
8027 NO_REGEN is true then it will only add the values in the DESIRED
8028 display structs which are in the given range.
8030 Note also that the FROM/TO values are minimums. It is possible
8031 that this function will actually add information outside of the
8032 lines containing those positions. This can't hurt but it could
8035 #### We currently force the cache to have only 1 contiguous region.
8036 It might help to make the cache a dynarr of caches so that we can
8037 cover more areas. This might, however, turn out to be a lot of
8038 overhead for too little gain. */
8041 update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
8042 Bufpos point, int no_regen)
8044 struct buffer *b = XBUFFER (w->buffer);
8045 line_start_cache_dynarr *cache = w->line_start_cache;
8046 Bufpos low_bound, high_bound;
8048 validate_line_start_cache (w);
8049 w->line_cache_validation_override++;
8051 if (from < BUF_BEGV (b))
8052 from = BUF_BEGV (b);
8053 if (to > BUF_ZV (b))
8058 w->line_cache_validation_override--;
8062 if (Dynarr_length (cache))
8064 low_bound = line_start_cache_start (w);
8065 high_bound = line_start_cache_end (w);
8067 /* Check to see if the desired range is already in the cache. */
8068 if (from >= low_bound && to <= high_bound)
8070 w->line_cache_validation_override--;
8074 /* Check to make sure that the desired range is adjacent to the
8075 current cache. If not, invalidate the cache. */
8076 if (to < low_bound || from > high_bound)
8078 Dynarr_reset (cache);
8079 low_bound = high_bound = -1;
8084 low_bound = high_bound = -1;
8087 w->line_cache_last_updated = make_int (BUF_MODIFF (b));
8089 /* This could be integrated into the next two sections, but it is easier
8090 to follow what's going on by having it separate. */
8095 update_internal_cache_list (w, DESIRED_DISP);
8096 if (!Dynarr_length (internal_cache))
8098 w->line_cache_validation_override--;
8102 start = Dynarr_atp (internal_cache, 0)->start;
8104 Dynarr_atp (internal_cache, Dynarr_length (internal_cache) - 1)->end;
8106 /* We aren't allowed to generate additional information to fill in
8107 gaps, so if the DESIRED structs don't overlap the cache, reset the
8109 if (Dynarr_length (cache))
8111 if (end < low_bound || start > high_bound)
8112 Dynarr_reset (cache);
8114 /* #### What should really happen if what we are doing is
8115 extending a line (the last line)? */
8116 if (Dynarr_length (cache) == 1
8117 && Dynarr_length (internal_cache) == 1)
8118 Dynarr_reset (cache);
8121 if (!Dynarr_length (cache))
8123 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
8124 Dynarr_length (internal_cache));
8125 w->line_cache_validation_override--;
8129 /* An extra check just in case the calling function didn't pass in
8130 the bounds of the DESIRED structs in the first place. */
8131 if (start >= low_bound && end <= high_bound)
8133 w->line_cache_validation_override--;
8137 /* At this point we know that the internal cache partially overlaps
8139 if (start < low_bound)
8141 int ic_elt = Dynarr_length (internal_cache) - 1;
8144 if (Dynarr_atp (internal_cache, ic_elt)->start < low_bound)
8152 Dynarr_reset (cache);
8153 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
8154 Dynarr_length (internal_cache));
8155 w->line_cache_validation_override--;
8159 Dynarr_insert_many_at_start (cache, Dynarr_atp (internal_cache, 0),
8163 if (end > high_bound)
8167 while (ic_elt < Dynarr_length (internal_cache))
8169 if (Dynarr_atp (internal_cache, ic_elt)->start > high_bound)
8175 if (!(ic_elt < Dynarr_length (internal_cache)))
8177 Dynarr_reset (cache);
8178 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
8179 Dynarr_length (internal_cache));
8180 w->line_cache_validation_override--;
8184 Dynarr_add_many (cache, Dynarr_atp (internal_cache, ic_elt),
8185 Dynarr_length (internal_cache) - ic_elt);
8188 w->line_cache_validation_override--;
8192 if (!Dynarr_length (cache) || from < low_bound)
8194 Bufpos startp = find_next_newline_no_quit (b, from, -1);
8196 int old_lb = low_bound;
8198 while (startp < old_lb || low_bound == -1)
8203 regenerate_window (w, startp, point, CMOTION_DISP);
8204 update_internal_cache_list (w, CMOTION_DISP);
8206 /* If this assert is triggered then regenerate_window failed
8207 to layout a single line. This is not possible since we
8208 force at least a single line to be layout for CMOTION_DISP */
8209 assert (Dynarr_length (internal_cache));
8210 assert (startp == Dynarr_atp (internal_cache, 0)->start);
8212 ic_elt = Dynarr_length (internal_cache) - 1;
8213 if (low_bound != -1)
8217 if (Dynarr_atp (internal_cache, ic_elt)->start < old_lb)
8223 assert (ic_elt >= 0);
8225 new_startp = Dynarr_atp (internal_cache, ic_elt)->end + 1;
8228 * Handle invisible text properly:
8229 * If the last line we're inserting has the same end as the
8230 * line before which it will be added, merge the two lines.
8232 if (Dynarr_length (cache) &&
8233 Dynarr_atp (internal_cache, ic_elt)->end ==
8234 Dynarr_atp (cache, marker)->end)
8236 Dynarr_atp (cache, marker)->start
8237 = Dynarr_atp (internal_cache, ic_elt)->start;
8238 Dynarr_atp (cache, marker)->height
8239 = Dynarr_atp (internal_cache, ic_elt)->height;
8243 if (ic_elt >= 0) /* we still have lines to add.. */
8245 Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0),
8246 ic_elt + 1, marker);
8247 marker += (ic_elt + 1);
8250 if (startp < low_bound || low_bound == -1)
8252 startp = new_startp;
8253 if (startp > BUF_ZV (b))
8255 w->line_cache_validation_override--;
8261 assert (Dynarr_length (cache));
8262 assert (from >= low_bound);
8264 /* Readjust the high_bound to account for any changes made while
8265 correcting the low_bound. */
8266 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8268 if (to > high_bound)
8270 Bufpos startp = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end + 1;
8274 regenerate_window (w, startp, point, CMOTION_DISP);
8275 update_internal_cache_list (w, CMOTION_DISP);
8277 /* See comment above about regenerate_window failing. */
8278 assert (Dynarr_length (internal_cache));
8280 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
8281 Dynarr_length (internal_cache));
8282 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8283 startp = high_bound + 1;
8285 while (to > high_bound);
8288 w->line_cache_validation_override--;
8289 assert (to <= high_bound);
8293 /* Given x and y coordinates in characters, relative to a window,
8294 return the pixel location corresponding to those coordinates. The
8295 pixel location returned is the center of the given character
8296 position. The pixel values are generated relative to the window,
8299 The modeline is considered to be part of the window. */
8302 glyph_to_pixel_translation (struct window *w, int char_x, int char_y,
8303 int *pix_x, int *pix_y)
8305 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
8306 int num_disp_lines, modeline;
8308 int defheight, defwidth;
8310 XSETWINDOW (window, w);
8311 default_face_height_and_width (window, &defheight, &defwidth);
8313 /* If we get a bogus value indicating somewhere above or to the left of
8314 the window, use the first window line or character position
8321 num_disp_lines = Dynarr_length (dla);
8325 if (Dynarr_atp (dla, 0)->modeline)
8332 /* First check if the y position intersects the display lines. */
8333 if (char_y < num_disp_lines)
8335 struct display_line *dl = Dynarr_atp (dla, char_y + modeline);
8336 struct display_block *db = get_display_block_from_line (dl, TEXT);
8338 *pix_y = (dl->ypos - dl->ascent +
8339 ((unsigned int) (dl->ascent + dl->descent - dl->clip) >> 1));
8341 if (char_x < Dynarr_length (db->runes))
8343 struct rune *rb = Dynarr_atp (db->runes, char_x);
8345 *pix_x = rb->xpos + (rb->width >> 1);
8349 int last_rune = Dynarr_length (db->runes) - 1;
8350 struct rune *rb = Dynarr_atp (db->runes, last_rune);
8352 char_x -= last_rune;
8354 *pix_x = rb->xpos + rb->width;
8355 *pix_x += ((char_x - 1) * defwidth);
8356 *pix_x += (defwidth >> 1);
8361 /* It didn't intersect, so extrapolate. #### For now, we include the
8362 modeline in this since we don't have true character positions in
8365 if (!Dynarr_length (w->face_cachels))
8366 reset_face_cachels (w);
8368 char_y -= num_disp_lines;
8370 if (Dynarr_length (dla))
8372 struct display_line *dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
8373 *pix_y = dl->ypos + dl->descent - dl->clip;
8376 *pix_y = WINDOW_TEXT_TOP (w);
8378 *pix_y += (char_y * defheight);
8379 *pix_y += (defheight >> 1);
8381 *pix_x = WINDOW_TEXT_LEFT (w);
8382 /* Don't adjust by one because this is still the unadjusted value. */
8383 *pix_x += (char_x * defwidth);
8384 *pix_x += (defwidth >> 1);
8387 if (*pix_x > w->pixel_left + w->pixel_width)
8388 *pix_x = w->pixel_left + w->pixel_width;
8389 if (*pix_y > w->pixel_top + w->pixel_height)
8390 *pix_y = w->pixel_top + w->pixel_height;
8392 *pix_x -= w->pixel_left;
8393 *pix_y -= w->pixel_top;
8396 /* Given a display line and a position, determine if there is a glyph
8397 there and return information about it if there is. */
8400 get_position_object (struct display_line *dl, Lisp_Object *obj1,
8401 Lisp_Object *obj2, int x_coord, int *low_x_coord,
8404 struct display_block *db;
8407 get_next_display_block (dl->bounds, dl->display_blocks, x_coord, 0);
8409 /* We use get_next_display_block to get the actual display block
8410 that would be displayed at x_coord. */
8412 if (block == NO_BLOCK)
8415 db = Dynarr_atp (dl->display_blocks, block);
8417 for (elt = 0; elt < Dynarr_length (db->runes); elt++)
8419 struct rune *rb = Dynarr_atp (db->runes, elt);
8421 if (rb->xpos <= x_coord && x_coord < (rb->xpos + rb->width))
8423 if (rb->type == RUNE_DGLYPH)
8425 *obj1 = rb->object.dglyph.glyph;
8426 *obj2 = rb->object.dglyph.extent;
8435 *low_x_coord = rb->xpos;
8437 *high_x_coord = rb->xpos + rb->width;
8444 #define UPDATE_CACHE_RETURN \
8446 d->pixel_to_glyph_cache.valid = 1; \
8447 d->pixel_to_glyph_cache.low_x_coord = low_x_coord; \
8448 d->pixel_to_glyph_cache.high_x_coord = high_x_coord; \
8449 d->pixel_to_glyph_cache.low_y_coord = low_y_coord; \
8450 d->pixel_to_glyph_cache.high_y_coord = high_y_coord; \
8451 d->pixel_to_glyph_cache.frame = f; \
8452 d->pixel_to_glyph_cache.col = *col; \
8453 d->pixel_to_glyph_cache.row = *row; \
8454 d->pixel_to_glyph_cache.obj_x = *obj_x; \
8455 d->pixel_to_glyph_cache.obj_y = *obj_y; \
8456 d->pixel_to_glyph_cache.w = *w; \
8457 d->pixel_to_glyph_cache.bufpos = *bufpos; \
8458 d->pixel_to_glyph_cache.closest = *closest; \
8459 d->pixel_to_glyph_cache.modeline_closest = *modeline_closest; \
8460 d->pixel_to_glyph_cache.obj1 = *obj1; \
8461 d->pixel_to_glyph_cache.obj2 = *obj2; \
8462 d->pixel_to_glyph_cache.retval = position; \
8463 RETURN_SANS_WARNINGS position; \
8466 /* Given x and y coordinates in pixels relative to a frame, return
8467 information about what is located under those coordinates.
8469 The return value will be one of:
8471 OVER_TOOLBAR: over one of the 4 frame toolbars
8472 OVER_MODELINE: over a modeline
8473 OVER_BORDER: over an internal border
8474 OVER_NOTHING: over the text area, but not over text
8475 OVER_OUTSIDE: outside of the frame border
8476 OVER_TEXT: over text in the text area
8482 -- nil if the coordinates are not over a glyph or a toolbar button.
8486 -- an extent, if the coordinates are over a glyph in the text area
8489 If the coordinates are over a glyph, OBJ_X and OBJ_Y give the
8490 equivalent coordinates relative to the upper-left corner of the glyph.
8492 If the coordinates are over a character, OBJ_X and OBJ_Y give the
8493 equivalent coordinates relative to the upper-left corner of the character.
8495 Otherwise, OBJ_X and OBJ_Y are undefined.
8499 pixel_to_glyph_translation (struct frame *f, int x_coord, int y_coord,
8500 int *col, int *row, int *obj_x, int *obj_y,
8501 struct window **w, Bufpos *bufpos,
8502 Bufpos *closest, Charcount *modeline_closest,
8503 Lisp_Object *obj1, Lisp_Object *obj2)
8506 struct pixel_to_glyph_translation_cache *cache;
8508 int frm_left, frm_right, frm_top, frm_bottom;
8509 int low_x_coord, high_x_coord, low_y_coord, high_y_coord;
8510 int position = OVER_NOTHING;
8511 int device_check_failed = 0;
8512 display_line_dynarr *dla;
8514 /* This is a safety valve in case this got called with a frame in
8515 the middle of being deleted. */
8516 if (!DEVICEP (f->device) || !DEVICE_LIVE_P (XDEVICE (f->device)))
8518 device_check_failed = 1;
8519 d = NULL, cache = NULL; /* Warning suppression */
8523 d = XDEVICE (f->device);
8524 cache = &d->pixel_to_glyph_cache;
8527 if (!device_check_failed
8529 && cache->frame == f
8530 && cache->low_x_coord <= x_coord
8531 && cache->high_x_coord > x_coord
8532 && cache->low_y_coord <= y_coord
8533 && cache->high_y_coord > y_coord)
8537 *obj_x = cache->obj_x;
8538 *obj_y = cache->obj_y;
8540 *bufpos = cache->bufpos;
8541 *closest = cache->closest;
8542 *modeline_closest = cache->modeline_closest;
8543 *obj1 = cache->obj1;
8544 *obj2 = cache->obj2;
8546 return cache->retval;
8557 *modeline_closest = -1;
8561 low_x_coord = x_coord;
8562 high_x_coord = x_coord + 1;
8563 low_y_coord = y_coord;
8564 high_y_coord = y_coord + 1;
8567 if (device_check_failed)
8568 return OVER_NOTHING;
8570 frm_left = FRAME_LEFT_BORDER_END (f);
8571 frm_right = FRAME_RIGHT_BORDER_START (f);
8572 frm_top = FRAME_TOP_BORDER_END (f);
8573 frm_bottom = FRAME_BOTTOM_BORDER_START (f);
8575 /* Check if the mouse is outside of the text area actually used by
8577 if (y_coord < frm_top)
8579 if (y_coord >= FRAME_TOP_BORDER_START (f))
8581 low_y_coord = FRAME_TOP_BORDER_START (f);
8582 high_y_coord = frm_top;
8583 position = OVER_BORDER;
8585 else if (y_coord >= 0)
8588 high_y_coord = FRAME_TOP_BORDER_START (f);
8589 position = OVER_TOOLBAR;
8593 low_y_coord = y_coord;
8595 position = OVER_OUTSIDE;
8598 else if (y_coord >= frm_bottom)
8600 if (y_coord < FRAME_BOTTOM_BORDER_END (f))
8602 low_y_coord = frm_bottom;
8603 high_y_coord = FRAME_BOTTOM_BORDER_END (f);
8604 position = OVER_BORDER;
8606 else if (y_coord < FRAME_PIXHEIGHT (f))
8608 low_y_coord = FRAME_BOTTOM_BORDER_END (f);
8609 high_y_coord = FRAME_PIXHEIGHT (f);
8610 position = OVER_TOOLBAR;
8614 low_y_coord = FRAME_PIXHEIGHT (f);
8615 high_y_coord = y_coord;
8616 position = OVER_OUTSIDE;
8620 if (position != OVER_TOOLBAR && position != OVER_BORDER)
8622 if (x_coord < frm_left)
8624 if (x_coord >= FRAME_LEFT_BORDER_START (f))
8626 low_x_coord = FRAME_LEFT_BORDER_START (f);
8627 high_x_coord = frm_left;
8628 position = OVER_BORDER;
8630 else if (x_coord >= 0)
8633 high_x_coord = FRAME_LEFT_BORDER_START (f);
8634 position = OVER_TOOLBAR;
8638 low_x_coord = x_coord;
8640 position = OVER_OUTSIDE;
8643 else if (x_coord >= frm_right)
8645 if (x_coord < FRAME_RIGHT_BORDER_END (f))
8647 low_x_coord = frm_right;
8648 high_x_coord = FRAME_RIGHT_BORDER_END (f);
8649 position = OVER_BORDER;
8651 else if (x_coord < FRAME_PIXWIDTH (f))
8653 low_x_coord = FRAME_RIGHT_BORDER_END (f);
8654 high_x_coord = FRAME_PIXWIDTH (f);
8655 position = OVER_TOOLBAR;
8659 low_x_coord = FRAME_PIXWIDTH (f);
8660 high_x_coord = x_coord;
8661 position = OVER_OUTSIDE;
8666 #ifdef HAVE_TOOLBARS
8667 if (position == OVER_TOOLBAR)
8669 *obj1 = toolbar_button_at_pixpos (f, x_coord, y_coord);
8672 UPDATE_CACHE_RETURN;
8674 #endif /* HAVE_TOOLBARS */
8676 /* We still have to return the window the pointer is next to and its
8677 relative y position even if it is outside the x boundary. */
8678 if (x_coord < frm_left)
8680 else if (x_coord > frm_right)
8681 x_coord = frm_right;
8683 /* Same in reverse. */
8684 if (y_coord < frm_top)
8686 else if (y_coord > frm_bottom)
8687 y_coord = frm_bottom;
8689 /* Find what window the given coordinates are actually in. */
8690 window = f->root_window;
8691 *w = find_window_by_pixel_pos (x_coord, y_coord, window);
8693 /* If we didn't find a window, we're done. */
8696 UPDATE_CACHE_RETURN;
8698 else if (position != OVER_NOTHING)
8701 *modeline_closest = -1;
8703 if (high_y_coord <= frm_top || high_y_coord >= frm_bottom)
8706 UPDATE_CACHE_RETURN;
8710 /* Check if the window is a minibuffer but isn't active. */
8711 if (MINI_WINDOW_P (*w) && !minibuf_level)
8713 /* Must reset the window value since some callers will ignore
8714 the return value if it is set. */
8716 UPDATE_CACHE_RETURN;
8719 /* See if the point is over window vertical divider */
8720 if (window_needs_vertical_divider (*w))
8722 int div_x_high = WINDOW_RIGHT (*w);
8723 int div_x_low = div_x_high - window_divider_width (*w);
8724 int div_y_high = WINDOW_BOTTOM (*w);
8725 int div_y_low = WINDOW_TOP (*w);
8727 if (div_x_low < x_coord && x_coord <= div_x_high &&
8728 div_y_low < y_coord && y_coord <= div_y_high)
8730 low_x_coord = div_x_low;
8731 high_x_coord = div_x_high;
8732 low_y_coord = div_y_low;
8733 high_y_coord = div_y_high;
8734 position = OVER_V_DIVIDER;
8735 UPDATE_CACHE_RETURN;
8739 dla = window_display_lines (*w, CURRENT_DISP);
8741 for (*row = 0; *row < Dynarr_length (dla); (*row)++)
8743 int really_over_nothing = 0;
8744 struct display_line *dl = Dynarr_atp (dla, *row);
8746 if ((int) (dl->ypos - dl->ascent) <= y_coord
8747 && y_coord <= (int) (dl->ypos + dl->descent))
8749 int check_margin_glyphs = 0;
8750 struct display_block *db = get_display_block_from_line (dl, TEXT);
8751 struct rune *rb = 0;
8753 if (x_coord < dl->bounds.left_white
8754 || x_coord >= dl->bounds.right_white)
8755 check_margin_glyphs = 1;
8757 low_y_coord = dl->ypos - dl->ascent;
8758 high_y_coord = dl->ypos + dl->descent + 1;
8760 if (position == OVER_BORDER
8761 || position == OVER_OUTSIDE
8762 || check_margin_glyphs)
8764 int x_check, left_bound;
8766 if (check_margin_glyphs)
8769 left_bound = dl->bounds.left_white;
8773 x_check = high_x_coord;
8774 left_bound = frm_left;
8777 if (Dynarr_length (db->runes))
8779 if (x_check <= left_bound)
8782 *modeline_closest = Dynarr_atp (db->runes, 0)->bufpos;
8784 *closest = Dynarr_atp (db->runes, 0)->bufpos;
8790 Dynarr_atp (db->runes,
8791 Dynarr_length (db->runes) - 1)->bufpos;
8794 Dynarr_atp (db->runes,
8795 Dynarr_length (db->runes) - 1)->bufpos;
8799 *modeline_closest += dl->offset;
8801 *closest += dl->offset;
8805 /* #### What should be here. */
8807 *modeline_closest = 0;
8812 if (check_margin_glyphs)
8814 if (x_coord < dl->bounds.left_in
8815 || x_coord >= dl->bounds.right_in)
8817 /* If we are over the outside margins then we
8818 know the loop over the text block isn't going
8819 to accomplish anything. So we go ahead and
8820 set what information we can right here and
8823 *obj_y = y_coord - (dl->ypos - dl->ascent);
8824 get_position_object (dl, obj1, obj2, x_coord,
8825 &low_x_coord, &high_x_coord);
8827 UPDATE_CACHE_RETURN;
8831 UPDATE_CACHE_RETURN;
8834 for (*col = 0; *col <= Dynarr_length (db->runes); (*col)++)
8836 int past_end = (*col == Dynarr_length (db->runes));
8839 rb = Dynarr_atp (db->runes, *col);
8842 (rb->xpos <= x_coord && x_coord < rb->xpos + rb->width))
8847 rb = Dynarr_atp (db->runes, *col);
8850 *bufpos = rb->bufpos + dl->offset;
8851 low_x_coord = rb->xpos;
8852 high_x_coord = rb->xpos + rb->width;
8854 if (rb->type == RUNE_DGLYPH)
8858 /* Find the first character after the glyph. */
8859 while (elt < Dynarr_length (db->runes))
8861 if (Dynarr_atp (db->runes, elt)->type != RUNE_DGLYPH)
8865 (Dynarr_atp (db->runes, elt)->bufpos +
8869 (Dynarr_atp (db->runes, elt)->bufpos +
8877 /* In this case we failed to find a non-glyph
8878 character so we return the last position
8879 displayed on the line. */
8880 if (elt == Dynarr_length (db->runes))
8883 *modeline_closest = dl->end_bufpos + dl->offset;
8885 *closest = dl->end_bufpos + dl->offset;
8886 really_over_nothing = 1;
8892 *modeline_closest = rb->bufpos + dl->offset;
8894 *closest = rb->bufpos + dl->offset;
8899 *row = window_displayed_height (*w);
8901 if (position == OVER_NOTHING)
8902 position = OVER_MODELINE;
8904 if (rb->type == RUNE_DGLYPH)
8906 *obj1 = rb->object.dglyph.glyph;
8907 *obj2 = rb->object.dglyph.extent;
8909 else if (rb->type == RUNE_CHAR)
8920 UPDATE_CACHE_RETURN;
8923 || (rb->type == RUNE_CHAR
8924 && CHARC_ASCII_EQ (rb->object.cglyph, '\n')))
8927 /* At this point we may have glyphs in the right
8929 if (check_margin_glyphs)
8930 get_position_object (dl, obj1, obj2, x_coord,
8931 &low_x_coord, &high_x_coord);
8932 UPDATE_CACHE_RETURN;
8937 if (rb->type == RUNE_DGLYPH)
8939 *obj1 = rb->object.dglyph.glyph;
8940 *obj2 = rb->object.dglyph.extent;
8942 else if (rb->type == RUNE_CHAR)
8953 *obj_x = x_coord - rb->xpos;
8954 *obj_y = y_coord - (dl->ypos - dl->ascent);
8956 /* At this point we may have glyphs in the left
8958 if (check_margin_glyphs)
8959 get_position_object (dl, obj1, obj2, x_coord, 0, 0);
8961 if (position == OVER_NOTHING && !really_over_nothing)
8962 position = OVER_TEXT;
8964 UPDATE_CACHE_RETURN;
8971 *row = Dynarr_length (dla) - 1;
8972 if (FRAME_WIN_P (f))
8974 int bot_elt = Dynarr_length (dla) - 1;
8978 struct display_line *dl = Dynarr_atp (dla, bot_elt);
8979 int adj_area = y_coord - (dl->ypos + dl->descent);
8983 XSETWINDOW (lwin, *w);
8984 default_face_height_and_width (lwin, 0, &defheight);
8986 *row += (adj_area / defheight);
8990 /* #### This should be checked out some more to determine what
8991 should really be going on. */
8992 if (!MARKERP ((*w)->start[CURRENT_DISP]))
8995 *closest = end_of_last_line_may_error (*w,
8996 marker_position ((*w)->start[CURRENT_DISP]));
8998 UPDATE_CACHE_RETURN;
9000 #undef UPDATE_CACHE_RETURN
9003 /***************************************************************************/
9005 /* Lisp functions */
9007 /***************************************************************************/
9009 DEFUN ("redisplay-echo-area", Fredisplay_echo_area, 0, 0, 0, /*
9010 Ensure that all minibuffers are correctly showing the echo area.
9014 Lisp_Object devcons, concons;
9016 DEVICE_LOOP_NO_BREAK (devcons, concons)
9018 struct device *d = XDEVICE (XCAR (devcons));
9019 Lisp_Object frmcons;
9021 DEVICE_FRAME_LOOP (frmcons, d)
9023 struct frame *f = XFRAME (XCAR (frmcons));
9025 if (FRAME_REPAINT_P (f) && FRAME_HAS_MINIBUF_P (f))
9027 Lisp_Object window = FRAME_MINIBUF_WINDOW (f);
9029 MAYBE_DEVMETH (d, frame_output_begin, (f));
9032 * If the frame size has changed, there may be random
9033 * chud on the screen left from previous messages
9034 * because redisplay_frame hasn't been called yet.
9035 * Clear the screen to get rid of the potential mess.
9037 if (f->echo_area_garbaged)
9039 MAYBE_DEVMETH (d, clear_frame, (f));
9040 f->echo_area_garbaged = 0;
9042 redisplay_window (window, 0);
9043 MAYBE_DEVMETH (d, frame_output_end, (f));
9045 call_redisplay_end_triggers (XWINDOW (window), 0);
9054 restore_disable_preemption_value (Lisp_Object value)
9056 disable_preemption = XINT (value);
9060 DEFUN ("redraw-frame", Fredraw_frame, 0, 2, 0, /*
9061 Clear frame FRAME and output again what is supposed to appear on it.
9062 FRAME defaults to the selected frame if omitted.
9063 Normally, redisplay is preempted as normal if input arrives. However,
9064 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
9065 input and is guaranteed to proceed to completion.
9067 (frame, no_preempt))
9069 struct frame *f = decode_frame (frame);
9070 int count = specpdl_depth ();
9072 if (!NILP (no_preempt))
9074 record_unwind_protect (restore_disable_preemption_value,
9075 make_int (disable_preemption));
9076 disable_preemption++;
9080 redisplay_frame (f, 1);
9082 /* See the comment in Fredisplay_frame. */
9083 RESET_CHANGED_SET_FLAGS;
9085 return unbind_to (count, Qnil);
9088 DEFUN ("redisplay-frame", Fredisplay_frame, 0, 2, 0, /*
9089 Ensure that FRAME's contents are correctly displayed.
9090 This differs from `redraw-frame' in that it only redraws what needs to
9091 be updated, as opposed to unconditionally clearing and redrawing
9093 FRAME defaults to the selected frame if omitted.
9094 Normally, redisplay is preempted as normal if input arrives. However,
9095 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
9096 input and is guaranteed to proceed to completion.
9098 (frame, no_preempt))
9100 struct frame *f = decode_frame (frame);
9101 int count = specpdl_depth ();
9103 if (!NILP (no_preempt))
9105 record_unwind_protect (restore_disable_preemption_value,
9106 make_int (disable_preemption));
9107 disable_preemption++;
9110 redisplay_frame (f, 1);
9112 /* If we don't reset the global redisplay flags here, subsequent
9113 changes to the display will not get registered by redisplay
9114 because it thinks it already has registered changes. If you
9115 really knew what you were doing you could confuse redisplay by
9116 calling Fredisplay_frame while updating another frame. We assume
9117 that if you know what you are doing you will not be that
9119 RESET_CHANGED_SET_FLAGS;
9121 return unbind_to (count, Qnil);
9124 DEFUN ("redraw-device", Fredraw_device, 0, 2, 0, /*
9125 Clear device DEVICE and output again what is supposed to appear on it.
9126 DEVICE defaults to the selected device if omitted.
9127 Normally, redisplay is preempted as normal if input arrives. However,
9128 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
9129 input and is guaranteed to proceed to completion.
9131 (device, no_preempt))
9133 struct device *d = decode_device (device);
9134 Lisp_Object frmcons;
9135 int count = specpdl_depth ();
9137 if (!NILP (no_preempt))
9139 record_unwind_protect (restore_disable_preemption_value,
9140 make_int (disable_preemption));
9141 disable_preemption++;
9144 DEVICE_FRAME_LOOP (frmcons, d)
9146 XFRAME (XCAR (frmcons))->clear = 1;
9148 redisplay_device (d, 0);
9150 /* See the comment in Fredisplay_frame. */
9151 RESET_CHANGED_SET_FLAGS;
9153 return unbind_to (count, Qnil);
9156 DEFUN ("redisplay-device", Fredisplay_device, 0, 2, 0, /*
9157 Ensure that DEVICE's contents are correctly displayed.
9158 This differs from `redraw-device' in that it only redraws what needs to
9159 be updated, as opposed to unconditionally clearing and redrawing
9161 DEVICE defaults to the selected device if omitted.
9162 Normally, redisplay is preempted as normal if input arrives. However,
9163 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
9164 input and is guaranteed to proceed to completion.
9166 (device, no_preempt))
9168 struct device *d = decode_device (device);
9169 int count = specpdl_depth ();
9171 if (!NILP (no_preempt))
9173 record_unwind_protect (restore_disable_preemption_value,
9174 make_int (disable_preemption));
9175 disable_preemption++;
9178 redisplay_device (d, 0);
9180 /* See the comment in Fredisplay_frame. */
9181 RESET_CHANGED_SET_FLAGS;
9183 return unbind_to (count, Qnil);
9186 /* Big lie. Big lie. This will force all modelines to be updated
9187 regardless if the all flag is set or not. It remains in existence
9188 solely for backwards compatibility. */
9189 DEFUN ("redraw-modeline", Fredraw_modeline, 0, 1, 0, /*
9190 Force the modeline of the current buffer to be redisplayed.
9191 With optional non-nil ALL, force redisplay of all modelines.
9195 MARK_MODELINE_CHANGED;
9199 DEFUN ("force-cursor-redisplay", Fforce_cursor_redisplay, 0, 1, 0, /*
9200 Force an immediate update of the cursor on FRAME.
9201 FRAME defaults to the selected frame if omitted.
9205 redisplay_redraw_cursor (decode_frame (frame), 1);
9210 /***************************************************************************/
9212 /* Lisp-variable change triggers */
9214 /***************************************************************************/
9217 margin_width_changed_in_frame (Lisp_Object specifier, struct frame *f,
9220 /* Nothing to be done? */
9224 redisplay_variable_changed (Lisp_Object sym, Lisp_Object *val,
9225 Lisp_Object in_object, int flags)
9227 /* #### clip_changed should really be renamed something like
9228 global_redisplay_change. */
9233 /* This is called if the built-in glyphs have their properties
9236 redisplay_glyph_changed (Lisp_Object glyph, Lisp_Object property,
9239 if (WINDOWP (locale))
9241 MARK_FRAME_GLYPHS_CHANGED (XFRAME (WINDOW_FRAME (XWINDOW (locale))));
9243 else if (FRAMEP (locale))
9245 MARK_FRAME_GLYPHS_CHANGED (XFRAME (locale));
9247 else if (DEVICEP (locale))
9249 Lisp_Object frmcons;
9250 DEVICE_FRAME_LOOP (frmcons, XDEVICE (locale))
9251 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9253 else if (CONSOLEP (locale))
9255 Lisp_Object frmcons, devcons;
9256 CONSOLE_FRAME_LOOP_NO_BREAK (frmcons, devcons, XCONSOLE (locale))
9257 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9259 else /* global or buffer */
9261 Lisp_Object frmcons, devcons, concons;
9262 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
9263 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9268 text_cursor_visible_p_changed (Lisp_Object specifier, struct window *w,
9271 if (XFRAME (w->frame)->init_finished)
9272 Fforce_cursor_redisplay (w->frame);
9275 #ifdef MEMORY_USAGE_STATS
9278 /***************************************************************************/
9280 /* memory usage computation */
9282 /***************************************************************************/
9285 compute_rune_dynarr_usage (rune_dynarr *dyn, struct overhead_stats *ovstats)
9287 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9291 compute_display_block_dynarr_usage (display_block_dynarr *dyn,
9292 struct overhead_stats *ovstats)
9299 total = Dynarr_memory_usage (dyn, ovstats);
9300 for (i = 0; i < Dynarr_largest (dyn); i++)
9301 total += compute_rune_dynarr_usage (Dynarr_at (dyn, i).runes, ovstats);
9307 compute_glyph_block_dynarr_usage (glyph_block_dynarr *dyn,
9308 struct overhead_stats *ovstats)
9310 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9314 compute_display_line_dynarr_usage (display_line_dynarr *dyn,
9315 struct overhead_stats *ovstats)
9322 total = Dynarr_memory_usage (dyn, ovstats);
9323 for (i = 0; i < Dynarr_largest (dyn); i++)
9325 struct display_line *dl = &Dynarr_at (dyn, i);
9326 total += compute_display_block_dynarr_usage(dl->display_blocks, ovstats);
9327 total += compute_glyph_block_dynarr_usage (dl->left_glyphs, ovstats);
9328 total += compute_glyph_block_dynarr_usage (dl->right_glyphs, ovstats);
9335 compute_line_start_cache_dynarr_usage (line_start_cache_dynarr *dyn,
9336 struct overhead_stats *ovstats)
9338 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9341 #endif /* MEMORY_USAGE_STATS */
9344 /***************************************************************************/
9346 /* initialization */
9348 /***************************************************************************/
9351 init_redisplay (void)
9353 disable_preemption = 0;
9354 preemption_count = 0;
9355 max_preempts = INIT_MAX_PREEMPTS;
9361 if (!cmotion_display_lines)
9362 cmotion_display_lines = Dynarr_new (display_line);
9363 if (!mode_spec_bufbyte_string)
9364 mode_spec_bufbyte_string = Dynarr_new (Bufbyte);
9365 if (!formatted_string_extent_dynarr)
9366 formatted_string_extent_dynarr = Dynarr_new (EXTENT);
9367 if (!formatted_string_extent_start_dynarr)
9368 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount);
9369 if (!formatted_string_extent_end_dynarr)
9370 formatted_string_extent_end_dynarr = Dynarr_new (Bytecount);
9371 if (!internal_cache)
9372 internal_cache = Dynarr_new (line_start_cache);
9375 /* window system is nil when in -batch mode */
9376 if (!initialized || noninteractive)
9379 /* If the user wants to use a window system, we shouldn't bother
9380 initializing the terminal. This is especially important when the
9381 terminal is so dumb that emacs gives up before and doesn't bother
9382 using the window system.
9384 If the DISPLAY environment variable is set, try to use X, and die
9385 with an error message if that doesn't work. */
9387 #ifdef HAVE_X_WINDOWS
9388 if (!strcmp (display_use, "x"))
9390 /* Some stuff checks this way early. */
9391 Vwindow_system = Qx;
9392 Vinitial_window_system = Qx;
9395 #endif /* HAVE_X_WINDOWS */
9398 if (!strcmp (display_use, "gtk"))
9400 Vwindow_system = Qgtk;
9401 Vinitial_window_system = Qgtk;
9406 #ifdef HAVE_MS_WINDOWS
9407 if (!strcmp (display_use, "mswindows"))
9409 /* Some stuff checks this way early. */
9410 Vwindow_system = Qmswindows;
9411 Vinitial_window_system = Qmswindows;
9414 #endif /* HAVE_MS_WINDOWS */
9417 /* If no window system has been specified, try to use the terminal. */
9420 stderr_out ("XEmacs: standard input is not a tty\n");
9424 /* Look at the TERM variable */
9425 if (!getenv ("TERM"))
9427 stderr_out ("Please set the environment variable TERM; see tset(1).\n");
9431 Vinitial_window_system = Qtty;
9433 #else /* not HAVE_TTY */
9434 /* No DISPLAY specified, and no TTY support. */
9435 stderr_out ("XEmacs: Cannot open display.\n\
9436 Please set the environmental variable DISPLAY to an appropriate value.\n");
9443 syms_of_redisplay (void)
9445 defsymbol (&Qcursor_in_echo_area, "cursor-in-echo-area");
9446 #ifndef INHIBIT_REDISPLAY_HOOKS
9447 defsymbol (&Qpre_redisplay_hook, "pre-redisplay-hook");
9448 defsymbol (&Qpost_redisplay_hook, "post-redisplay-hook");
9449 #endif /* INHIBIT_REDISPLAY_HOOKS */
9450 defsymbol (&Qdisplay_warning_buffer, "display-warning-buffer");
9451 defsymbol (&Qbar_cursor, "bar-cursor");
9452 defsymbol (&Qredisplay_end_trigger_functions,
9453 "redisplay-end-trigger-functions");
9454 defsymbol (&Qtop_bottom, "top-bottom");
9455 defsymbol (&Qbuffer_list_changed_hook, "buffer-list-changed-hook");
9457 DEFSUBR (Fredisplay_echo_area);
9458 DEFSUBR (Fredraw_frame);
9459 DEFSUBR (Fredisplay_frame);
9460 DEFSUBR (Fredraw_device);
9461 DEFSUBR (Fredisplay_device);
9462 DEFSUBR (Fredraw_modeline);
9463 DEFSUBR (Fforce_cursor_redisplay);
9467 vars_of_redisplay (void)
9471 staticpro (&last_arrow_position);
9472 staticpro (&last_arrow_string);
9473 last_arrow_position = Qnil;
9474 last_arrow_string = Qnil;
9477 /* #### Probably temporary */
9478 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /*
9479 \(Temporary) Setting this will impact the performance of the internal
9482 cache_adjustment = 2;
9484 DEFVAR_INT_MAGIC ("pixel-vertical-clip-threshold", &vertical_clip /*
9485 Minimum pixel height for clipped bottom display line.
9486 A clipped line shorter than this won't be displayed.
9488 redisplay_variable_changed);
9491 DEFVAR_INT_MAGIC ("pixel-horizontal-clip-threshold", &horizontal_clip /*
9492 Minimum visible area for clipped glyphs at right boundary.
9493 Clipped glyphs shorter than this won't be displayed.
9494 Only pixmap glyph instances are currently allowed to be clipped.
9496 redisplay_variable_changed);
9497 horizontal_clip = 5;
9499 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string /*
9500 String displayed by modeline-format's "%m" specification.
9502 Vglobal_mode_string = Qnil;
9504 DEFVAR_LISP_MAGIC ("overlay-arrow-position", &Voverlay_arrow_position /*
9505 Marker for where to display an arrow on top of the buffer text.
9506 This must be the beginning of a line in order to work.
9507 See also `overlay-arrow-string'.
9509 redisplay_variable_changed);
9510 Voverlay_arrow_position = Qnil;
9512 DEFVAR_LISP_MAGIC ("overlay-arrow-string", &Voverlay_arrow_string /*
9513 String or glyph to display as an arrow. See also `overlay-arrow-position'.
9514 \(Note that despite the name of this variable, it can be set to a glyph as
9517 redisplay_variable_changed);
9518 Voverlay_arrow_string = Qnil;
9520 DEFVAR_INT ("scroll-step", &scroll_step /*
9521 *The number of lines to try scrolling a window by when point moves out.
9522 If that fails to bring point back on frame, point is centered instead.
9523 If this is zero, point is always centered after it moves off screen.
9527 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively /*
9528 *Scroll up to this many lines, to bring point back on screen.
9530 scroll_conservatively = 0;
9532 DEFVAR_BOOL_MAGIC ("truncate-partial-width-windows",
9533 &truncate_partial_width_windows /*
9534 *Non-nil means truncate lines in all windows less than full frame wide.
9536 redisplay_variable_changed);
9537 truncate_partial_width_windows = 1;
9539 DEFVAR_LISP ("visible-bell", &Vvisible_bell /*
9540 *Non-nil substitutes a visual signal for the audible bell.
9542 Default behavior is to flash the whole screen. On some platforms,
9543 special effects are available using the following values:
9545 'display Flash the whole screen (ie, the default behavior).
9546 'top-bottom Flash only the top and bottom lines of the selected frame.
9548 When effects are unavailable on a platform, the visual bell is the
9549 default, whole screen. (Currently only X supports any special effects.)
9551 Vvisible_bell = Qnil;
9553 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter /*
9554 *Non-nil means no need to redraw entire frame after suspending.
9555 A non-nil value is useful if the terminal can automatically preserve
9556 Emacs's frame display when you reenter Emacs.
9557 It is up to you to set this variable if your terminal can do that.
9559 no_redraw_on_reenter = 0;
9561 DEFVAR_LISP ("window-system", &Vwindow_system /*
9562 A symbol naming the window-system under which Emacs is running,
9563 such as `x', or nil if emacs is running on an ordinary terminal.
9565 Do not use this variable, except for GNU Emacs compatibility, as it
9566 gives wrong values in a multi-device environment. Use `console-type'
9569 Vwindow_system = Qnil;
9571 /* #### Temporary shit until window-system is eliminated. */
9572 DEFVAR_CONST_LISP ("initial-window-system", &Vinitial_window_system /*
9575 Vinitial_window_system = Qnil;
9577 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area /*
9578 Non-nil means put cursor in minibuffer, at end of any message there.
9580 cursor_in_echo_area = 0;
9582 /* #### Shouldn't this be generalized as follows:
9584 if nil, use block cursor.
9585 if a number, use a bar cursor of that width.
9586 Otherwise, use a 1-pixel bar cursor.
9588 #### Or better yet, this variable should be trashed entirely
9589 (use a Lisp-magic variable to maintain compatibility)
9590 and a specifier `cursor-shape' added, which allows a block
9591 cursor, a bar cursor, a flashing block or bar cursor,
9592 maybe a caret cursor, etc. */
9594 DEFVAR_LISP ("bar-cursor", &Vbar_cursor /*
9595 *Use vertical bar cursor if non-nil. If t width is 1 pixel, otherwise 2.
9599 #ifndef INHIBIT_REDISPLAY_HOOKS
9600 xxDEFVAR_LISP ("pre-redisplay-hook", &Vpre_redisplay_hook /*
9601 Function or functions to run before every redisplay.
9603 Vpre_redisplay_hook = Qnil;
9605 xxDEFVAR_LISP ("post-redisplay-hook", &Vpost_redisplay_hook /*
9606 Function or functions to run after every redisplay.
9608 Vpost_redisplay_hook = Qnil;
9609 #endif /* INHIBIT_REDISPLAY_HOOKS */
9611 DEFVAR_LISP ("buffer-list-changed-hook", &Vbuffer_list_changed_hook /*
9612 Function or functions to call when a frame's buffer list has changed.
9613 This is called during redisplay, before redisplaying each frame.
9614 Functions on this hook are called with one argument, the frame.
9616 Vbuffer_list_changed_hook = Qnil;
9618 DEFVAR_INT ("display-warning-tick", &display_warning_tick /*
9619 Bump this to tell the C code to call `display-warning-buffer'
9620 at next redisplay. You should not normally change this; the function
9621 `display-warning' automatically does this at appropriate times.
9623 display_warning_tick = 0;
9625 DEFVAR_BOOL ("inhibit-warning-display", &inhibit_warning_display /*
9626 Non-nil means inhibit display of warning messages.
9627 You should *bind* this, not set it. Any pending warning messages
9628 will be displayed when the binding no longer applies.
9630 /* reset to 0 by startup.el after the splash screen has displayed.
9631 This way, the warnings don't obliterate the splash screen. */
9632 inhibit_warning_display = 1;
9634 DEFVAR_LISP ("window-size-change-functions",
9635 &Vwindow_size_change_functions /*
9636 Not currently implemented.
9637 Functions called before redisplay, if window sizes have changed.
9638 The value should be a list of functions that take one argument.
9639 Just before redisplay, for each frame, if any of its windows have changed
9640 size since the last redisplay, or have been split or deleted,
9641 all the functions in the list are called, with the frame as argument.
9643 Vwindow_size_change_functions = Qnil;
9645 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions /*
9646 Not currently implemented.
9647 Functions to call before redisplaying a window with scrolling.
9648 Each function is called with two arguments, the window
9649 and its new display-start position. Note that the value of `window-end'
9650 is not valid when these functions are called.
9652 Vwindow_scroll_functions = Qnil;
9654 DEFVAR_LISP ("redisplay-end-trigger-functions",
9655 &Vredisplay_end_trigger_functions /*
9656 See `set-window-redisplay-end-trigger'.
9658 Vredisplay_end_trigger_functions = Qnil;
9660 DEFVAR_BOOL ("column-number-start-at-one", &column_number_start_at_one /*
9661 *Non-nil means column display number starts at 1.
9663 column_number_start_at_one = 0;
9667 specifier_vars_of_redisplay (void)
9669 DEFVAR_SPECIFIER ("left-margin-width", &Vleft_margin_width /*
9670 *Width of left margin.
9671 This is a specifier; use `set-specifier' to change it.
9673 Vleft_margin_width = Fmake_specifier (Qnatnum);
9674 set_specifier_fallback (Vleft_margin_width, list1 (Fcons (Qnil, Qzero)));
9675 set_specifier_caching (Vleft_margin_width,
9676 offsetof (struct window, left_margin_width),
9677 some_window_value_changed,
9678 offsetof (struct frame, left_margin_width),
9679 margin_width_changed_in_frame, 0);
9681 DEFVAR_SPECIFIER ("right-margin-width", &Vright_margin_width /*
9682 *Width of right margin.
9683 This is a specifier; use `set-specifier' to change it.
9685 Vright_margin_width = Fmake_specifier (Qnatnum);
9686 set_specifier_fallback (Vright_margin_width, list1 (Fcons (Qnil, Qzero)));
9687 set_specifier_caching (Vright_margin_width,
9688 offsetof (struct window, right_margin_width),
9689 some_window_value_changed,
9690 offsetof (struct frame, right_margin_width),
9691 margin_width_changed_in_frame, 0);
9693 DEFVAR_SPECIFIER ("minimum-line-ascent", &Vminimum_line_ascent /*
9694 *Minimum ascent height of lines.
9695 This is a specifier; use `set-specifier' to change it.
9697 Vminimum_line_ascent = Fmake_specifier (Qnatnum);
9698 set_specifier_fallback (Vminimum_line_ascent, list1 (Fcons (Qnil, Qzero)));
9699 set_specifier_caching (Vminimum_line_ascent,
9700 offsetof (struct window, minimum_line_ascent),
9701 some_window_value_changed,
9704 DEFVAR_SPECIFIER ("minimum-line-descent", &Vminimum_line_descent /*
9705 *Minimum descent height of lines.
9706 This is a specifier; use `set-specifier' to change it.
9708 Vminimum_line_descent = Fmake_specifier (Qnatnum);
9709 set_specifier_fallback (Vminimum_line_descent, list1 (Fcons (Qnil, Qzero)));
9710 set_specifier_caching (Vminimum_line_descent,
9711 offsetof (struct window, minimum_line_descent),
9712 some_window_value_changed,
9715 DEFVAR_SPECIFIER ("use-left-overflow", &Vuse_left_overflow /*
9716 *Non-nil means use the left outside margin as extra whitespace when
9717 displaying 'whitespace or 'inside-margin glyphs.
9718 This is a specifier; use `set-specifier' to change it.
9720 Vuse_left_overflow = Fmake_specifier (Qboolean);
9721 set_specifier_fallback (Vuse_left_overflow, list1 (Fcons (Qnil, Qnil)));
9722 set_specifier_caching (Vuse_left_overflow,
9723 offsetof (struct window, use_left_overflow),
9724 some_window_value_changed,
9727 DEFVAR_SPECIFIER ("use-right-overflow", &Vuse_right_overflow /*
9728 *Non-nil means use the right outside margin as extra whitespace when
9729 displaying 'whitespace or 'inside-margin glyphs.
9730 This is a specifier; use `set-specifier' to change it.
9732 Vuse_right_overflow = Fmake_specifier (Qboolean);
9733 set_specifier_fallback (Vuse_right_overflow, list1 (Fcons (Qnil, Qnil)));
9734 set_specifier_caching (Vuse_right_overflow,
9735 offsetof (struct window, use_right_overflow),
9736 some_window_value_changed,
9739 DEFVAR_SPECIFIER ("text-cursor-visible-p", &Vtext_cursor_visible_p /*
9740 *Non-nil means the text cursor is visible (this is usually the case).
9741 This is a specifier; use `set-specifier' to change it.
9743 Vtext_cursor_visible_p = Fmake_specifier (Qboolean);
9744 set_specifier_fallback (Vtext_cursor_visible_p, list1 (Fcons (Qnil, Qt)));
9745 set_specifier_caching (Vtext_cursor_visible_p,
9746 offsetof (struct window, text_cursor_visible_p),
9747 text_cursor_visible_p_changed,