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_emchar_string (struct window *w, int findex,
505 Emchar *str, Charcount len)
507 unsigned char charsets[NUM_LEADING_BYTES];
510 find_charsets_in_emchar_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 Emchar_dynarr *rtw_emchar_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_emchar_dynarr)
527 rtw_emchar_dynarr = Dynarr_new (Emchar);
528 Dynarr_reset (rtw_emchar_dynarr);
530 fixup_internal_substring (nonreloc, reloc, offset, &len);
532 nonreloc = XSTRING_DATA (reloc);
533 convert_bufbyte_string_into_emchar_dynarr (nonreloc, len, rtw_emchar_dynarr);
534 return redisplay_text_width_emchar_string
535 (w, findex, Dynarr_atp (rtw_emchar_dynarr, 0),
536 Dynarr_length (rtw_emchar_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 unsigned char charsets[NUM_LEADING_BYTES];
546 struct face_cachel cachel;
548 if (!rtw_emchar_dynarr)
549 rtw_emchar_dynarr = Dynarr_new (Emchar);
550 Dynarr_reset (rtw_emchar_dynarr);
552 fixup_internal_substring (nonreloc, reloc, offset, &len);
554 nonreloc = XSTRING_DATA (reloc);
555 convert_bufbyte_string_into_emchar_dynarr (nonreloc, len, rtw_emchar_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_emchar_dynarr, 0),
563 Dynarr_length (rtw_emchar_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;
962 if (data->bi_start_col_enabled)
964 return add_hscroll_rune (data);
967 if (data->ch == '\n')
969 data->font_is_bogus = 0;
970 /* Cheesy end-of-line pseudo-character. */
971 width = data->blank_width;
975 Lisp_Object charset = CHAR_CHARSET (data->ch);
976 if (!EQ (charset, data->last_charset) ||
977 data->findex != data->last_findex)
979 /* OK, we need to do things the hard way. */
980 struct window *w = XWINDOW (data->window);
981 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, data->findex);
982 Lisp_Object font_instance =
983 ensure_face_cachel_contains_charset (cachel, data->window,
985 Lisp_Font_Instance *fi;
987 if (EQ (font_instance, Vthe_null_font_instance))
989 font_instance = FACE_CACHEL_FONT (cachel, Vcharset_ascii);
990 data->font_is_bogus = 1;
993 data->font_is_bogus = 0;
995 fi = XFONT_INSTANCE (font_instance);
996 if (!fi->proportional_p)
997 /* sweetness and light. */
998 data->last_char_width = fi->width;
1000 data->last_char_width = -1;
1002 if (!no_contribute_to_line_height)
1004 data->new_ascent = max (data->new_ascent, (int) fi->ascent);
1005 data->new_descent = max (data->new_descent, (int) fi->descent);
1008 data->last_charset = charset;
1009 data->last_findex = data->findex;
1012 width = data->last_char_width;
1015 /* bummer. Proportional fonts. */
1016 width = redisplay_text_width_emchar_string (XWINDOW (data->window),
1022 if (data->max_pixpos != -1 && (data->pixpos + width > data->max_pixpos))
1027 if (Dynarr_length (data->db->runes) < Dynarr_largest (data->db->runes))
1029 crb = Dynarr_atp (data->db->runes, Dynarr_length (data->db->runes));
1038 crb->findex = data->findex;
1039 crb->xpos = data->pixpos;
1041 if (data->bi_bufpos)
1043 if (NILP (data->string))
1045 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
1049 bytecount_to_charcount (XSTRING_DATA (data->string), data->bi_bufpos);
1051 else if (data->is_modeline)
1052 crb->bufpos = data->modeline_charpos;
1054 /* Text but not in buffer */
1056 crb->type = RUNE_CHAR;
1057 crb->object.chr.ch = data->font_is_bogus ? '~' : data->ch;
1060 if (data->cursor_type == CURSOR_ON)
1062 if (data->bi_bufpos == data->bi_cursor_bufpos)
1064 crb->cursor_type = CURSOR_ON;
1065 data->cursor_x = Dynarr_length (data->db->runes);
1068 crb->cursor_type = CURSOR_OFF;
1070 else if (data->cursor_type == NEXT_CURSOR)
1072 crb->cursor_type = CURSOR_ON;
1073 data->cursor_x = Dynarr_length (data->db->runes);
1074 data->cursor_type = NO_CURSOR;
1076 else if (data->cursor_type == IGNORE_CURSOR)
1077 crb->cursor_type = IGNORE_CURSOR;
1079 crb->cursor_type = CURSOR_OFF;
1082 Dynarr_add (data->db->runes, *crb);
1084 Dynarr_increment (data->db->runes);
1086 data->pixpos += width;
1091 static prop_block_dynarr *
1092 add_emchar_rune (pos_data *data)
1094 return add_emchar_rune_1 (data, 0);
1097 /* Given a string C_STRING of length C_LENGTH, call add_emchar_rune for
1098 each character in the string. Propagate any left-over data unless
1099 NO_PROP is non-zero. If NO_CONTRIBUTE_TO_LINE_HEIGHT is non-zero, don't
1100 allow this character to increase the total height of the line. (This is
1101 used when the character is part of a text glyph. In that case, the
1102 glyph code itself adjusts the line height as necessary, depending on
1103 whether glyph-contrib-p is true.) */
1105 static prop_block_dynarr *
1106 add_bufbyte_string_runes (pos_data *data, Bufbyte *c_string,
1107 Bytecount c_length, int no_prop,
1108 int no_contribute_to_line_height)
1110 Bufbyte *pos, *end = c_string + c_length;
1111 prop_block_dynarr *prop;
1113 /* #### This function is too simplistic. It needs to do the same
1114 sort of character interpretation (display-table lookup,
1115 ctl-arrow checking), etc. that create_text_block() does.
1116 The functionality to do this in that routine needs to be
1119 for (pos = c_string; pos < end;)
1121 Bufbyte *old_pos = pos;
1123 data->ch = charptr_emchar (pos);
1125 prop = add_emchar_rune_1 (data, no_contribute_to_line_height);
1133 struct prop_block pb;
1134 Bytecount len = end - pos;
1135 prop = Dynarr_new (prop_block);
1137 pb.type = PROP_STRING;
1138 pb.data.p_string.str = xnew_array (Bufbyte, len);
1139 strncpy ((char *) pb.data.p_string.str, (char *) pos, len);
1140 pb.data.p_string.len = len;
1142 Dynarr_add (prop, pb);
1147 assert (pos <= end);
1148 /* #### Duplicate code from add_string_to_fstring_db_runes
1149 should we do more?*/
1150 data->bytepos += pos - old_pos;
1156 /* Add a single rune of the specified width. The area covered by this
1157 rune will be displayed in the foreground color of the associated
1160 static prop_block_dynarr *
1161 add_blank_rune (pos_data *data, struct window *w, int char_tab_width)
1165 /* If data->start_col is not 0 then this call to add_blank_rune must have
1166 been to add it as a tab. */
1167 if (data->start_col)
1169 /* assert (w != NULL) */
1170 prop_block_dynarr *retval;
1172 /* If we have still not fully scrolled horizontally, subtract
1173 the width of this tab and return. */
1174 if (char_tab_width < data->start_col)
1176 data->start_col -= char_tab_width;
1179 else if (char_tab_width == data->start_col)
1180 data->blank_width = 0;
1183 int spcwid = space_width (w);
1185 if (spcwid >= data->blank_width)
1186 data->blank_width = 0;
1188 data->blank_width -= spcwid;
1191 data->start_col = 0;
1192 retval = add_hscroll_rune (data);
1194 /* Could be caused by the handling of the hscroll rune. */
1195 if (retval != NULL || !data->blank_width)
1199 /* Blank runes are always calculated to fit. */
1200 assert (data->pixpos + data->blank_width <= data->max_pixpos);
1202 rb.findex = data->findex;
1203 rb.xpos = data->pixpos;
1204 rb.width = data->blank_width;
1205 if (data->bi_bufpos)
1207 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
1210 /* #### and this is really correct too? */
1213 rb.type = RUNE_BLANK;
1215 if (data->cursor_type == CURSOR_ON)
1217 if (data->bi_bufpos == data->bi_cursor_bufpos)
1219 rb.cursor_type = CURSOR_ON;
1220 data->cursor_x = Dynarr_length (data->db->runes);
1223 rb.cursor_type = CURSOR_OFF;
1225 else if (data->cursor_type == NEXT_CURSOR)
1227 rb.cursor_type = CURSOR_ON;
1228 data->cursor_x = Dynarr_length (data->db->runes);
1229 data->cursor_type = NO_CURSOR;
1232 rb.cursor_type = CURSOR_OFF;
1234 Dynarr_add (data->db->runes, rb);
1235 data->pixpos += data->blank_width;
1240 /* Add runes representing a character in octal. */
1242 #define ADD_NEXT_OCTAL_RUNE_CHAR do \
1244 if (add_failed || (add_failed = add_emchar_rune (data))) \
1246 struct prop_block pb; \
1248 prop = Dynarr_new (prop_block); \
1250 pb.type = PROP_CHAR; \
1251 pb.data.p_char.ch = data->ch; \
1252 pb.data.p_char.cursor_type = data->cursor_type; \
1253 Dynarr_add (prop, pb); \
1257 static prop_block_dynarr *
1258 add_octal_runes (pos_data *data)
1260 prop_block_dynarr *add_failed, *prop = 0;
1261 Emchar orig_char = data->ch;
1262 unsigned int orig_cursor_type = data->cursor_type;
1267 if (data->start_col)
1270 if (!data->start_col)
1272 if (data->bi_start_col_enabled)
1274 add_failed = add_hscroll_rune (data);
1278 struct glyph_block gb;
1279 struct window *w = XWINDOW (data->window);
1282 gb.glyph = Voctal_escape_glyph;
1284 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1285 GLYPH_CACHEL (w, OCT_ESC_GLYPH_INDEX));
1289 /* We only propagate information if the glyph was partially
1294 data->cursor_type = IGNORE_CURSOR;
1296 if (data->ch >= 0x100)
1298 /* If the character is an extended Mule character, it could have
1299 up to 19 bits. For the moment, we treat it as a seven-digit
1300 octal number. This is not that pretty, but whatever. */
1301 data->ch = (7 & (orig_char >> 18)) + '0';
1302 ADD_NEXT_OCTAL_RUNE_CHAR;
1304 data->ch = (7 & (orig_char >> 15)) + '0';
1305 ADD_NEXT_OCTAL_RUNE_CHAR;
1307 data->ch = (7 & (orig_char >> 12)) + '0';
1308 ADD_NEXT_OCTAL_RUNE_CHAR;
1310 data->ch = (7 & (orig_char >> 9)) + '0';
1311 ADD_NEXT_OCTAL_RUNE_CHAR;
1314 data->ch = (7 & (orig_char >> 6)) + '0';
1315 ADD_NEXT_OCTAL_RUNE_CHAR;
1317 data->ch = (7 & (orig_char >> 3)) + '0';
1318 ADD_NEXT_OCTAL_RUNE_CHAR;
1320 data->ch = (7 & orig_char) + '0';
1321 ADD_NEXT_OCTAL_RUNE_CHAR;
1323 data->cursor_type = orig_cursor_type;
1327 #undef ADD_NEXT_OCTAL_RUNE_CHAR
1329 /* Add runes representing a control character to a display block. */
1331 static prop_block_dynarr *
1332 add_control_char_runes (pos_data *data, struct buffer *b)
1334 if (!NILP (b->ctl_arrow))
1336 prop_block_dynarr *prop;
1337 Emchar orig_char = data->ch;
1338 unsigned int old_cursor_type = data->cursor_type;
1343 if (data->start_col)
1346 if (!data->start_col)
1348 if (data->bi_start_col_enabled)
1350 prop_block_dynarr *retval;
1352 retval = add_hscroll_rune (data);
1358 struct glyph_block gb;
1359 struct window *w = XWINDOW (data->window);
1362 gb.glyph = Vcontrol_arrow_glyph;
1364 /* We only propagate information if the glyph was partially
1366 if (add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1367 GLYPH_CACHEL (w, CONTROL_GLYPH_INDEX)))
1372 if (orig_char == 0177)
1375 data->ch = orig_char ^ 0100;
1376 data->cursor_type = IGNORE_CURSOR;
1378 if (add_emchar_rune (data))
1380 struct prop_block pb;
1382 prop = Dynarr_new (prop_block);
1384 pb.type = PROP_CHAR;
1385 pb.data.p_char.ch = data->ch;
1386 pb.data.p_char.cursor_type = data->cursor_type;
1387 Dynarr_add (prop, pb);
1390 data->cursor_type = old_cursor_type;
1395 return add_octal_runes (data);
1399 static prop_block_dynarr *
1400 add_disp_table_entry_runes_1 (pos_data *data, Lisp_Object entry)
1402 prop_block_dynarr *prop = NULL;
1404 if (STRINGP (entry))
1406 prop = add_bufbyte_string_runes (data,
1407 XSTRING_DATA (entry),
1408 XSTRING_LENGTH (entry),
1411 else if (GLYPHP (entry))
1413 if (data->start_col)
1416 if (!data->start_col && data->bi_start_col_enabled)
1418 prop = add_hscroll_rune (data);
1422 struct glyph_block gb;
1426 prop = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
1429 else if (CHAR_OR_CHAR_INTP (entry))
1431 data->ch = XCHAR_OR_CHAR_INT (entry);
1432 prop = add_emchar_rune (data);
1434 else if (CONSP (entry))
1436 if (EQ (XCAR (entry), Qformat)
1437 && CONSP (XCDR (entry))
1438 && STRINGP (XCAR (XCDR (entry))))
1440 Lisp_Object format = XCAR (XCDR (entry));
1441 Bytind len = XSTRING_LENGTH (format);
1442 Bufbyte *src = XSTRING_DATA (format), *end = src + len;
1443 Bufbyte *result = alloca_array (Bufbyte, len);
1444 Bufbyte *dst = result;
1448 Emchar c = charptr_emchar (src);
1450 if (c != '%' || src == end)
1451 dst += set_charptr_emchar (dst, c);
1454 c = charptr_emchar (src);
1459 dst += long_to_string_base ((char *)dst, data->ch, 16);
1462 dst += set_charptr_emchar (dst, '%');
1464 /* #### unimplemented */
1468 prop = add_bufbyte_string_runes (data, result, dst - result, 0, 0);
1472 /* Else blow it off because someone added a bad entry and we don't
1473 have any safe way of signaling an error. */
1477 /* Given a display table entry, call the appropriate functions to
1478 display each element of the entry. */
1480 static prop_block_dynarr *
1481 add_disp_table_entry_runes (pos_data *data, Lisp_Object entry)
1483 prop_block_dynarr *prop = NULL;
1484 if (VECTORP (entry))
1486 Lisp_Vector *de = XVECTOR (entry);
1487 EMACS_INT len = vector_length (de);
1490 for (elt = 0; elt < len; elt++)
1492 if (NILP (vector_data (de)[elt]))
1495 prop = add_disp_table_entry_runes_1 (data, vector_data (de)[elt]);
1496 /* Else blow it off because someone added a bad entry and we
1497 don't have any safe way of signaling an error. Hey, this
1498 comment sounds familiar. */
1500 /* #### Still need to add any remaining elements to the
1501 propagation information. */
1507 prop = add_disp_table_entry_runes_1 (data, entry);
1511 /* Add runes which were propagated from the previous line. */
1513 static prop_block_dynarr *
1514 add_propagation_runes (prop_block_dynarr **prop, pos_data *data)
1516 /* #### Remember to handle start_col parameter of data when the rest of
1517 this is finished. */
1518 /* #### Chuck -- I've redone this function a bit. It looked like the
1519 case of not all the propagation blocks being added was not handled
1521 /* #### Chuck -- I also think the double indirection of PROP is kind
1522 of bogus. A cleaner solution is just to check for
1523 Dynarr_length (prop) > 0. */
1524 /* #### This function also doesn't even pay attention to ADD_FAILED!
1525 This is seriously fucked! Seven ####'s in 130 lines -- is that a
1528 prop_block_dynarr *add_failed;
1529 Bytind bi_old_cursor_bufpos = data->bi_cursor_bufpos;
1530 unsigned int old_cursor_type = data->cursor_type;
1532 for (elt = 0; elt < Dynarr_length (*prop); elt++)
1534 struct prop_block *pb = Dynarr_atp (*prop, elt);
1539 data->ch = pb->data.p_char.ch;
1540 data->bi_cursor_bufpos = pb->data.p_char.bi_cursor_bufpos;
1541 data->cursor_type = pb->data.p_char.cursor_type;
1542 add_failed = add_emchar_rune (data);
1545 goto oops_no_more_space;
1548 if (pb->data.p_string.str)
1549 xfree (pb->data.p_string.str);
1550 /* #### bogus bogus -- this doesn't do anything!
1551 Should probably call add_bufbyte_string_runes(),
1552 once that function is fixed. */
1554 case PROP_MINIBUF_PROMPT:
1556 face_index old_findex = data->findex;
1557 Bytind bi_old_bufpos = data->bi_bufpos;
1559 data->findex = DEFAULT_INDEX;
1560 data->bi_bufpos = 0;
1561 data->cursor_type = NO_CURSOR;
1563 while (pb->data.p_string.len > 0)
1565 data->ch = charptr_emchar (pb->data.p_string.str);
1566 add_failed = add_emchar_rune (data);
1570 data->findex = old_findex;
1571 data->bi_bufpos = bi_old_bufpos;
1572 goto oops_no_more_space;
1576 /* Complicated equivalent of ptr++, len-- */
1577 Bufbyte *oldpos = pb->data.p_string.str;
1578 INC_CHARPTR (pb->data.p_string.str);
1579 pb->data.p_string.len -= pb->data.p_string.str - oldpos;
1583 data->findex = old_findex;
1584 /* ##### FIXME FIXME FIXME -- Upon successful return from
1585 this function, data->bi_bufpos is automatically incremented.
1586 However, we don't want that to happen if we were adding
1587 the minibuffer prompt. */
1589 struct buffer *buf =
1590 XBUFFER (WINDOW_BUFFER (XWINDOW (data->window)));
1591 /* #### Chuck fix this shit or I'm gonna scream! */
1592 if (bi_old_bufpos > BI_BUF_BEGV (buf))
1593 data->bi_bufpos = prev_bytind (buf, bi_old_bufpos);
1595 /* #### is this correct? Does anyone know?
1596 Does anyone care? Is this a cheesy hack or what? */
1597 data->bi_bufpos = BI_BUF_BEGV (buf) - 1;
1603 /* #### I think it's unnecessary and misleading to preserve
1604 the blank_width, as it implies that the value carries
1605 over from one rune to the next, which is wrong. */
1606 int old_width = data->blank_width;
1607 face_index old_findex = data->findex;
1609 data->findex = pb->data.p_blank.findex;
1610 data->blank_width = pb->data.p_blank.width;
1611 data->bi_cursor_bufpos = 0;
1612 data->cursor_type = IGNORE_CURSOR;
1614 if (data->pixpos + data->blank_width > data->max_pixpos)
1615 data->blank_width = data->max_pixpos - data->pixpos;
1617 /* We pass a bogus value of char_tab_width. It shouldn't
1618 matter because unless something is really screwed up
1619 this call won't cause that arg to be used. */
1620 add_failed = add_blank_rune (data, XWINDOW (data->window), 0);
1622 /* This can happen in the case where we have a tab which
1623 is wider than the window. */
1624 if (data->blank_width != pb->data.p_blank.width)
1626 pb->data.p_blank.width -= data->blank_width;
1627 add_failed = ADD_FAILED;
1630 data->findex = old_findex;
1631 data->blank_width = old_width;
1634 goto oops_no_more_space;
1644 data->bi_cursor_bufpos = bi_old_cursor_bufpos;
1645 data->cursor_type = old_cursor_type;
1646 if (elt < Dynarr_length (*prop))
1648 Dynarr_delete_many (*prop, 0, elt);
1653 Dynarr_free (*prop);
1658 /* Add 'text layout glyphs at position POS_TYPE that are contained to
1659 the display block, but add all other types to the appropriate list
1660 of the display line. They will be added later by different
1663 static prop_block_dynarr *
1664 add_glyph_rune (pos_data *data, struct glyph_block *gb, int pos_type,
1665 int allow_cursor, struct glyph_cachel *cachel)
1667 struct window *w = XWINDOW (data->window);
1669 /* If window faces changed, and glyph instance is text, then
1670 glyph sizes might have changed too */
1671 invalidate_glyph_geometry_maybe (gb->glyph, w);
1673 /* This makes sure the glyph is in the cachels.
1675 #### We do this to make sure the glyph is in the glyph cachels,
1676 so that the dirty flag can be reset after redisplay has
1677 finished. We should do this some other way, maybe by iterating
1678 over the window cache of subwindows. */
1679 get_glyph_cachel_index (w, gb->glyph);
1681 /* A nil extent indicates a special glyph (ex. truncator). */
1682 if (NILP (gb->extent)
1683 || (pos_type == BEGIN_GLYPHS &&
1684 extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1685 || (pos_type == END_GLYPHS &&
1686 extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1687 || pos_type == LEFT_GLYPHS || pos_type == RIGHT_GLYPHS)
1692 int ascent, descent;
1693 Lisp_Object baseline;
1695 Lisp_Object instance;
1697 prop_block_dynarr *retval = 0;
1700 width = cachel->width;
1702 width = glyph_width (gb->glyph, data->window);
1707 if (data->start_col || data->start_col_xoffset)
1709 int glyph_char_width = width / space_width (w);
1711 /* If we still have not fully scrolled horizontally after
1712 taking into account the width of the glyph, subtract its
1713 width and return. */
1714 if (glyph_char_width < data->start_col)
1716 data->start_col -= glyph_char_width;
1719 else if (glyph_char_width == data->start_col)
1723 xoffset = space_width (w) * data->start_col;
1726 /* #### Can this happen? */
1731 data->start_col = 0;
1732 retval = add_hscroll_rune (data);
1734 /* Could be caused by the handling of the hscroll rune. */
1735 if (retval != NULL || !width)
1741 if (data->pixpos + width > data->max_pixpos)
1743 /* If this is the first object we are attempting to add to
1744 the line then we ignore the horizontal_clip threshold.
1745 Otherwise we will loop until the bottom of the window
1746 continually failing to add this glyph because it is wider
1747 than the window. We could alternatively just completely
1748 ignore the glyph and proceed from there but I think that
1749 this is a better solution.
1751 This does, however, create a different problem in that we
1752 can end up adding the object to every single line, never
1753 getting any further - for instance an extent with a long
1754 start-glyph that covers multitple following
1756 if (Dynarr_length (data->db->runes)
1757 && data->max_pixpos - data->pixpos < horizontal_clip)
1760 struct prop_block pb;
1762 /* We need to account for the width of the end-of-line
1763 glyph if there is nothing more in the line to display,
1764 since we will not display it in this instance. It seems
1765 kind of gross doing it here, but otherwise we have to
1766 search the runes in create_text_block(). */
1767 if (data->ch == '\n')
1768 data->max_pixpos += data->end_glyph_width;
1769 width = data->max_pixpos - data->pixpos;
1770 /* Add the glyph we are displaying, but clipping, to the
1771 propagation data so that we don't try and do it
1773 retval = Dynarr_new (prop_block);
1774 pb.type = PROP_GLYPH;
1775 pb.data.p_glyph.glyph = gb->glyph;
1776 pb.data.p_glyph.width = width;
1777 Dynarr_add (retval, pb);
1783 ascent = cachel->ascent;
1784 descent = cachel->descent;
1788 ascent = glyph_ascent (gb->glyph, data->window);
1789 descent = glyph_descent (gb->glyph, data->window);
1792 baseline = glyph_baseline (gb->glyph, data->window);
1794 rb.object.dglyph.descent = 0; /* Gets reset lower down, if it is known. */
1796 if (glyph_contrib_p (gb->glyph, data->window))
1798 /* A pixmap that has not had a baseline explicitly set. Its
1799 contribution will be determined later. */
1800 if (NILP (baseline))
1802 int height = ascent + descent;
1803 data->need_baseline_computation = 1;
1804 data->max_pixmap_height = max (data->max_pixmap_height, height);
1807 /* A string so determine contribution normally. */
1808 else if (EQ (baseline, Qt))
1810 data->new_ascent = max (data->new_ascent, ascent);
1811 data->new_descent = max (data->new_descent, descent);
1814 /* A pixmap with an explicitly set baseline. We determine the
1815 contribution here. */
1816 else if (INTP (baseline))
1818 int height = ascent + descent;
1819 int pix_ascent, pix_descent;
1821 pix_ascent = height * XINT (baseline) / 100;
1822 pix_descent = height - pix_ascent;
1824 data->new_ascent = max (data->new_ascent, pix_ascent);
1825 data->new_descent = max (data->new_descent, pix_descent);
1826 data->max_pixmap_height = max (data->max_pixmap_height, height);
1828 rb.object.dglyph.descent = pix_descent;
1831 /* Otherwise something is screwed up. */
1836 face = glyph_face (gb->glyph, data->window);
1838 findex = data->findex;
1840 findex = get_builtin_face_cache_index (w, face);
1842 instance = glyph_image_instance (gb->glyph, data->window,
1844 if (TEXT_IMAGE_INSTANCEP (instance))
1846 Lisp_Object string = XIMAGE_INSTANCE_TEXT_STRING (instance);
1847 face_index orig_findex = data->findex;
1848 Bytind orig_bufpos = data->bi_bufpos;
1849 Bytind orig_start_col_enabled = data->bi_start_col_enabled;
1851 data->findex = findex;
1852 data->bi_start_col_enabled = 0;
1854 data->bi_bufpos = 0;
1855 add_bufbyte_string_runes (data, XSTRING_DATA (string),
1856 XSTRING_LENGTH (string), 0, 1);
1857 data->findex = orig_findex;
1858 data->bi_bufpos = orig_bufpos;
1859 data->bi_start_col_enabled = orig_start_col_enabled;
1864 rb.xpos = data->pixpos;
1866 rb.bufpos = 0; /* glyphs are never "at" anywhere */
1867 if (data->bi_endpos)
1868 /* #### is this necessary at all? */
1869 rb.endpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1873 rb.type = RUNE_DGLYPH;
1874 rb.object.dglyph.glyph = gb->glyph;
1875 rb.object.dglyph.extent = gb->extent;
1876 rb.object.dglyph.xoffset = xoffset;
1877 rb.object.dglyph.ascent = ascent;
1878 rb.object.dglyph.yoffset = 0; /* Until we know better, assume that it has
1879 a normal (textual) baseline. */
1883 rb.bufpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1886 if (data->cursor_type == CURSOR_ON)
1888 if (data->bi_bufpos == data->bi_cursor_bufpos)
1890 rb.cursor_type = CURSOR_ON;
1891 data->cursor_x = Dynarr_length (data->db->runes);
1894 rb.cursor_type = CURSOR_OFF;
1896 else if (data->cursor_type == NEXT_CURSOR)
1898 rb.cursor_type = CURSOR_ON;
1899 data->cursor_x = Dynarr_length (data->db->runes);
1900 data->cursor_type = NO_CURSOR;
1902 else if (data->cursor_type == IGNORE_CURSOR)
1903 rb.cursor_type = IGNORE_CURSOR;
1904 else if (data->cursor_type == NO_CURSOR)
1905 rb.cursor_type = NO_CURSOR;
1907 rb.cursor_type = CURSOR_OFF;
1910 rb.cursor_type = CURSOR_OFF;
1912 Dynarr_add (data->db->runes, rb);
1913 data->pixpos += width;
1919 if (!NILP (glyph_face (gb->glyph, data->window)))
1921 get_builtin_face_cache_index (w, glyph_face (gb->glyph,
1924 gb->findex = data->findex;
1926 if (pos_type == BEGIN_GLYPHS)
1928 if (!data->dl->left_glyphs)
1929 data->dl->left_glyphs = Dynarr_new (glyph_block);
1930 Dynarr_add (data->dl->left_glyphs, *gb);
1933 else if (pos_type == END_GLYPHS)
1935 if (!data->dl->right_glyphs)
1936 data->dl->right_glyphs = Dynarr_new (glyph_block);
1937 Dynarr_add (data->dl->right_glyphs, *gb);
1941 abort (); /* there are no unknown types */
1947 /* Add all glyphs at position POS_TYPE that are contained in the given
1950 static prop_block_dynarr *
1951 add_glyph_runes (pos_data *data, int pos_type)
1953 /* #### This still needs to handle the start_col parameter. Duh, Chuck,
1954 why didn't you just modify add_glyph_rune in the first place? */
1956 glyph_block_dynarr *glyph_arr = (pos_type == BEGIN_GLYPHS
1957 ? data->ef->begin_glyphs
1958 : data->ef->end_glyphs);
1959 prop_block_dynarr *prop;
1961 for (elt = 0; elt < Dynarr_length (glyph_arr); elt++)
1963 prop = add_glyph_rune (data, Dynarr_atp (glyph_arr, elt), pos_type, 0,
1968 /* #### Add some propagation information. */
1973 Dynarr_reset (glyph_arr);
1978 /* Given a position for a buffer in a window, ensure that the given
1979 display line DL accurately represents the text on a line starting
1980 at the given position.
1982 NOTE NOTE NOTE NOTE: This function works with and returns Bytinds.
1983 You must do appropriate conversion. */
1986 create_text_block (struct window *w, struct display_line *dl,
1987 Bytind bi_start_pos, prop_block_dynarr **prop,
1990 struct frame *f = XFRAME (w->frame);
1991 struct buffer *b = XBUFFER (w->buffer);
1992 struct device *d = XDEVICE (f->device);
1996 /* Don't display anything in the minibuffer if this window is not on
1997 a selected frame. We consider all other windows to be active
1998 minibuffers as it simplifies the coding. */
1999 int active_minibuffer = (!MINI_WINDOW_P (w) ||
2000 (f == device_selected_frame (d)) ||
2001 is_surrogate_for_selected_frame (f));
2003 int truncate_win = window_truncation_on (w);
2005 /* If the buffer's value of selective_display is an integer then
2006 only lines that start with less than selective_display columns of
2007 space will be displayed. If selective_display is t then all text
2008 after a ^M is invisible. */
2009 int selective = (INTP (b->selective_display)
2010 ? XINT (b->selective_display)
2011 : (!NILP (b->selective_display) ? -1 : 0));
2013 /* The variable ctl-arrow allows the user to specify what characters
2014 can actually be displayed and which octal should be used for.
2015 #### This variable should probably have some rethought done to
2018 #### It would also be really nice if you could specify that
2019 the characters come out in hex instead of in octal. Mule
2020 does that by adding a ctl-hexa variable similar to ctl-arrow,
2021 but that's bogus -- we need a more general solution. I
2022 think you need to extend the concept of display tables
2023 into a more general conversion mechanism. Ideally you
2024 could specify a Lisp function that converts characters,
2025 but this violates the Second Golden Rule and besides would
2026 make things way way way way slow.
2028 So instead, we extend the display-table concept, which was
2029 historically limited to 256-byte vectors, to one of the
2032 a) A 256-entry vector, for backward compatibility;
2033 b) char-table, mapping characters to values;
2034 c) range-table, mapping ranges of characters to values;
2035 d) a list of the above.
2037 The (d) option allows you to specify multiple display tables
2038 instead of just one. Each display table can specify conversions
2039 for some characters and leave others unchanged. The way the
2040 character gets displayed is determined by the first display table
2041 with a binding for that character. This way, you could call a
2042 function `enable-hex-display' that adds a hex display-table to
2043 the list of display tables for the current buffer.
2045 #### ...not yet implemented... Also, we extend the concept of
2046 "mapping" to include a printf-like spec. Thus you can make all
2047 extended characters show up as hex with a display table like
2050 #s(range-table data ((256 524288) (format "%x")))
2052 Since more than one display table is possible, you have
2053 great flexibility in mapping ranges of characters. */
2054 Emchar printable_min = (CHAR_OR_CHAR_INTP (b->ctl_arrow)
2055 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
2056 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
2059 Lisp_Object face_dt, window_dt;
2061 /* The text display block for this display line. */
2062 struct display_block *db = get_display_block_from_line (dl, TEXT);
2064 /* The first time through the main loop we need to force the glyph
2065 data to be updated. */
2068 /* Apparently the new extent_fragment_update returns an end position
2069 equal to the position passed in if there are no more runs to be
2071 int no_more_frags = 0;
2073 Lisp_Object synch_minibuffers_value =
2074 symbol_value_in_buffer (Qsynchronize_minibuffers, w->buffer);
2076 dl->used_prop_data = 0;
2078 dl->line_continuation = 0;
2081 data.ef = extent_fragment_new (w->buffer, f);
2083 /* These values are used by all of the rune addition routines. We add
2084 them to this structure for ease of passing. */
2086 XSETWINDOW (data.window, w);
2091 data.bi_bufpos = bi_start_pos;
2092 data.pixpos = dl->bounds.left_in;
2093 data.last_charset = Qunbound;
2094 data.last_findex = DEFAULT_INDEX;
2095 data.result_str = Qnil;
2097 /* Set the right boundary adjusting it to take into account any end
2098 glyph. Save the width of the end glyph for later use. */
2099 data.max_pixpos = dl->bounds.right_in;
2101 data.end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
2103 data.end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
2104 data.max_pixpos -= data.end_glyph_width;
2106 if (cursor_in_echo_area && MINI_WINDOW_P (w) && echo_area_active (f))
2108 data.bi_cursor_bufpos = BI_BUF_ZV (b);
2109 data.cursor_type = CURSOR_ON;
2111 else if (MINI_WINDOW_P (w) && !active_minibuffer)
2112 data.cursor_type = NO_CURSOR;
2113 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)) &&
2114 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
2115 d == XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d))))&&
2116 f == XFRAME(DEVICE_SELECTED_FRAME(d)))
2118 data.bi_cursor_bufpos = BI_BUF_PT (b);
2119 data.cursor_type = CURSOR_ON;
2121 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)))
2123 data.bi_cursor_bufpos = bi_marker_position (w->pointm[type]);
2124 data.cursor_type = CURSOR_ON;
2127 data.cursor_type = NO_CURSOR;
2130 data.start_col = w->hscroll;
2131 data.start_col_xoffset = w->left_xoffset;
2132 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
2133 data.hscroll_glyph_width_adjust = 0;
2135 /* We regenerate the line from the very beginning. */
2136 Dynarr_reset (db->runes);
2138 /* Why is this less than or equal and not just less than? If the
2139 starting position is already equal to the maximum we can't add
2140 anything else, right? Wrong. We might still have a newline to
2141 add. A newline can use the room allocated for an end glyph since
2142 if we add it we know we aren't going to be adding any end
2145 /* #### Chuck -- I think this condition should be while (1).
2146 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
2147 and the begin-glyph ends exactly at the end of the window, the
2148 end-glyph and text might not be displayed. while (1) ensures
2149 that the loop terminates only when either (a) there is
2150 propagation data or (b) the end-of-line or end-of-buffer is hit.
2152 #### Also I think you need to ensure that the operation
2153 "add begin glyphs; add end glyphs; add text" is atomic and
2154 can't get interrupted in the middle. If you run off the end
2155 of the line during that operation, then you keep accumulating
2156 propagation data until you're done. Otherwise, if the (e.g.)
2157 there's a begin glyph at a particular position and attempting
2158 to display that glyph results in window-end being hit and
2159 propagation data being generated, then the character at that
2160 position won't be displayed.
2162 #### See also the comment after the end of this loop, below.
2164 while (data.pixpos <= data.max_pixpos
2165 && (active_minibuffer || !NILP (synch_minibuffers_value)))
2167 /* #### This check probably should not be necessary. */
2168 if (data.bi_bufpos > BI_BUF_ZV (b))
2170 /* #### urk! More of this lossage! */
2175 /* If selective display was an integer and we aren't working on
2176 a continuation line then find the next line we are actually
2177 supposed to display. */
2179 && (data.bi_bufpos == BI_BUF_BEGV (b)
2180 || BUF_FETCH_CHAR (b, prev_bytind (b, data.bi_bufpos)) == '\n'))
2182 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2185 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2186 if (data.bi_bufpos >= BI_BUF_ZV (b))
2188 data.bi_bufpos = BI_BUF_ZV (b);
2194 /* Check for face changes. */
2195 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
2197 Lisp_Object last_glyph = Qnil;
2199 /* Deal with glyphs that we have already displayed. The
2200 theory is that if we end up with a PROP_GLYPH in the
2201 propagation data then we are clipping the glyph and there
2202 can be no propagation data before that point. The theory
2203 works because we always recalculate the extent-fragments
2204 for propagated data, we never actually propagate the
2205 fragments that still need to be displayed. */
2206 if (*prop && Dynarr_atp (*prop, 0)->type == PROP_GLYPH)
2208 last_glyph = Dynarr_atp (*prop, 0)->data.p_glyph.glyph;
2209 Dynarr_free (*prop);
2212 /* Now compute the face and begin/end-glyph information. */
2214 /* Remember that the extent-fragment routines deal in Bytind's. */
2215 extent_fragment_update (w, data.ef, data.bi_bufpos, last_glyph);
2217 get_display_tables (w, data.findex, &face_dt, &window_dt);
2219 if (data.bi_bufpos == data.ef->end)
2224 /* Determine what is next to be displayed. We first handle any
2225 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
2226 display then we determine what to do based on the character at the
2227 current buffer position. */
2229 /* If the current position is covered by an invisible extent, do
2230 nothing (except maybe add some ellipses).
2232 #### The behavior of begin and end-glyphs at the edge of an
2233 invisible extent should be investigated further. This is
2234 fairly low priority though. */
2235 if (data.ef->invisible)
2237 /* #### Chuck, perhaps you could look at this code? I don't
2238 really know what I'm doing. */
2241 Dynarr_free (*prop);
2245 /* The extent fragment code only sets this when we should
2246 really display the ellipses. It makes sure the ellipses
2247 don't get displayed more than once in a row. */
2248 if (data.ef->invisible_ellipses)
2250 struct glyph_block gb;
2252 data.ef->invisible_ellipses_already_displayed = 1;
2253 data.ef->invisible_ellipses = 0;
2255 gb.glyph = Vinvisible_text_glyph;
2256 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2257 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2258 /* Perhaps they shouldn't propagate if the very next thing
2259 is to display a newline (for compatibility with
2260 selective-display-ellipses)? Maybe that's too
2266 /* If point is in an invisible region we place it on the
2267 next visible character. */
2268 if (data.cursor_type == CURSOR_ON
2269 && data.bi_bufpos == data.bi_cursor_bufpos)
2271 data.cursor_type = NEXT_CURSOR;
2274 /* #### What if we we're dealing with a display table? */
2278 if (data.bi_bufpos == BI_BUF_ZV (b))
2281 INC_BYTIND (b, data.bi_bufpos);
2284 /* If there is propagation data, then it represents the current
2285 buffer position being displayed. Add them and advance the
2286 position counter. This might also add the minibuffer
2290 dl->used_prop_data = 1;
2291 *prop = add_propagation_runes (prop, &data);
2294 goto done; /* gee, a really narrow window */
2295 else if (data.bi_bufpos == BI_BUF_ZV (b))
2297 else if (data.bi_bufpos < BI_BUF_BEGV (b))
2298 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
2299 data.bi_bufpos = BI_BUF_BEGV (b);
2301 INC_BYTIND (b, data.bi_bufpos);
2304 /* If there are end glyphs, add them to the line. These are
2305 the end glyphs for the previous run of text. We add them
2306 here rather than doing them at the end of handling the
2307 previous run so that glyphs at the beginning and end of
2308 a line are handled correctly. */
2309 else if (Dynarr_length (data.ef->end_glyphs) > 0
2310 || Dynarr_length (data.ef->begin_glyphs) > 0)
2312 glyph_block_dynarr* tmpglyphs = 0;
2313 /* #### I think this is safe, but could be wrong. */
2314 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2316 if (Dynarr_length (data.ef->end_glyphs) > 0)
2318 *prop = add_glyph_runes (&data, END_GLYPHS);
2319 tmpglyphs = data.ef->end_glyphs;
2322 /* If there are begin glyphs, add them to the line. */
2323 if (!*prop && Dynarr_length (data.ef->begin_glyphs) > 0)
2325 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
2326 tmpglyphs = data.ef->begin_glyphs;
2331 /* If we just clipped a glyph and we are at the end of a
2332 line and there are more glyphs to display then do
2333 appropriate processing to not get a continuation
2335 if (*prop != ADD_FAILED
2336 && Dynarr_atp (*prop, 0)->type == PROP_GLYPH
2339 /* If there are no more glyphs then do the normal
2342 #### This doesn't actually work if the same glyph is
2343 present more than once in the block. To solve
2344 this we would have to carry the index around
2345 which might be problematic since the fragment is
2346 recalculated for each line. */
2347 if (EQ (Dynarr_end (tmpglyphs)->glyph,
2348 Dynarr_atp (*prop, 0)->data.p_glyph.glyph))
2350 Dynarr_free (*prop);
2354 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2355 add_emchar_rune (&data); /* discard prop data. */
2364 /* If at end-of-buffer, we've already processed begin and
2365 end-glyphs at this point and there's no text to process,
2367 else if (data.bi_bufpos == BI_BUF_ZV (b))
2372 Lisp_Object entry = Qnil;
2373 /* Get the character at the current buffer position. */
2374 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2375 if (!NILP (face_dt) || !NILP (window_dt))
2376 entry = display_table_entry (data.ch, face_dt, window_dt);
2378 /* If there is a display table entry for it, hand it off to
2379 add_disp_table_entry_runes and let it worry about it. */
2380 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
2382 *prop = add_disp_table_entry_runes (&data, entry);
2388 /* Check if we have hit a newline character. If so, add a marker
2389 to the line and end this loop. */
2390 else if (data.ch == '\n')
2392 /* We aren't going to be adding an end glyph so give its
2393 space back in order to make sure that the cursor can
2395 data.max_pixpos += data.end_glyph_width;
2398 && (bi_spaces_at_point
2399 (b, next_bytind (b, data.bi_bufpos))
2402 if (!NILP (b->selective_display_ellipses))
2404 struct glyph_block gb;
2407 gb.glyph = Vinvisible_text_glyph;
2408 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2409 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2413 /* Cheesy, cheesy, cheesy. We mark the end of the
2414 line with a special "character rune" whose width
2415 is the EOL cursor width and whose character is
2416 the non-printing character '\n'. */
2417 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2418 *prop = add_emchar_rune (&data);
2421 /* We need to set data.bi_bufpos to the start of the
2422 next visible region in order to make this line
2423 appear to contain all of the invisible area.
2424 Otherwise, the line cache won't work
2426 INC_BYTIND (b, data.bi_bufpos);
2427 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2430 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2431 if (data.bi_bufpos >= BI_BUF_ZV (b))
2433 data.bi_bufpos = BI_BUF_ZV (b);
2437 if (BI_BUF_FETCH_CHAR
2438 (b, prev_bytind (b, data.bi_bufpos)) == '\n')
2439 DEC_BYTIND (b, data.bi_bufpos);
2443 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2444 *prop = add_emchar_rune (&data);
2450 /* If the current character is ^M, and selective display is
2451 enabled, then add the invisible-text-glyph if
2452 selective-display-ellipses is set. In any case, this
2454 else if (data.ch == (('M' & 037)) && selective == -1)
2456 Bytind bi_next_bufpos;
2458 /* Find the buffer position at the end of the line. */
2460 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2461 if (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_next_bufpos))
2463 DEC_BYTIND (b, bi_next_bufpos);
2465 /* If the cursor is somewhere in the elided text make
2466 sure that the cursor gets drawn appropriately. */
2467 if (data.cursor_type == CURSOR_ON
2468 && (data.bi_cursor_bufpos >= data.bi_bufpos &&
2469 data.bi_cursor_bufpos < bi_next_bufpos))
2471 data.cursor_type = NEXT_CURSOR;
2474 /* We won't be adding a truncation or continuation glyph
2475 so give up the room allocated for them. */
2476 data.max_pixpos += data.end_glyph_width;
2478 if (!NILP (b->selective_display_ellipses))
2480 /* We don't propagate anything from the invisible
2481 text glyph if it fails to fit. This is
2483 struct glyph_block gb;
2486 gb.glyph = Vinvisible_text_glyph;
2487 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 1,
2488 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2491 /* Set the buffer position to the end of the line. We
2492 need to do this before potentially adding a newline
2493 so that the cursor flag will get set correctly (if
2495 data.bi_bufpos = bi_next_bufpos;
2497 if (NILP (b->selective_display_ellipses)
2498 || data.bi_cursor_bufpos == bi_next_bufpos)
2500 /* We have to at least add a newline character so
2501 that the cursor shows up properly. */
2503 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2504 data.findex = DEFAULT_INDEX;
2506 data.start_col_xoffset = 0;
2507 data.bi_start_col_enabled = 0;
2509 add_emchar_rune (&data);
2512 /* This had better be a newline but doing it this way
2513 we'll see obvious incorrect results if it isn't. No
2514 need to abort here. */
2515 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2520 /* If the current character is considered to be printable, then
2522 else if (data.ch >= printable_min)
2524 *prop = add_emchar_rune (&data);
2529 /* If the current character is a tab, determine the next tab
2530 starting position and add a blank rune which extends from the
2531 current pixel position to that starting position. */
2532 else if (data.ch == '\t')
2534 int tab_start_pixpos = data.pixpos;
2539 if (data.start_col > 1)
2540 tab_start_pixpos -= (space_width (w) * (data.start_col - 1))
2541 + data.start_col_xoffset;
2544 next_tab_position (w, tab_start_pixpos,
2545 dl->bounds.left_in +
2546 data.hscroll_glyph_width_adjust);
2547 if (next_tab_start > data.max_pixpos)
2549 prop_width = next_tab_start - data.max_pixpos;
2550 next_tab_start = data.max_pixpos;
2552 data.blank_width = next_tab_start - data.pixpos;
2554 (next_tab_start - tab_start_pixpos) / space_width (w);
2556 *prop = add_blank_rune (&data, w, char_tab_width);
2558 /* add_blank_rune is only supposed to be called with
2559 sizes guaranteed to fit in the available space. */
2564 struct prop_block pb;
2565 *prop = Dynarr_new (prop_block);
2567 pb.type = PROP_BLANK;
2568 pb.data.p_blank.width = prop_width;
2569 pb.data.p_blank.findex = data.findex;
2570 Dynarr_add (*prop, pb);
2576 /* If character is a control character, pass it off to
2577 add_control_char_runes.
2579 The is_*() routines have undefined results on
2580 arguments outside of the range [-1, 255]. (This
2581 often bites people who carelessly use `char' instead
2582 of `unsigned char'.)
2584 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
2586 *prop = add_control_char_runes (&data, b);
2592 /* If the character is above the ASCII range and we have not
2593 already handled it, then print it as an octal number. */
2594 else if (data.ch >= 0200)
2596 *prop = add_octal_runes (&data);
2602 /* Assume the current character is considered to be printable,
2603 then just add it. */
2606 *prop = add_emchar_rune (&data);
2611 INC_BYTIND (b, data.bi_bufpos);
2617 /* Determine the starting point of the next line if we did not hit the
2618 end of the buffer. */
2619 if (data.bi_bufpos < BI_BUF_ZV (b)
2620 && (active_minibuffer || !NILP (synch_minibuffers_value)))
2622 /* #### This check is not correct. If the line terminated
2623 due to a begin-glyph or end-glyph hitting window-end, then
2624 data.ch will not point to the character at data.bi_bufpos. If
2625 you make the two changes mentioned at the top of this loop,
2626 you should be able to say '(if (*prop))'. That should also
2627 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
2630 /* The common case is that the line ended because we hit a newline.
2631 In that case, the next character is just the next buffer
2633 if (data.ch == '\n')
2635 /* If data.start_col_enabled is still true, then the window is
2636 scrolled far enough so that nothing on this line is visible.
2637 We need to stick a truncation glyph at the beginning of the
2638 line in that case unless the line is completely blank. */
2639 if (data.bi_start_col_enabled)
2641 if (data.cursor_type == CURSOR_ON)
2643 if (data.bi_cursor_bufpos >= bi_start_pos
2644 && data.bi_cursor_bufpos <= data.bi_bufpos)
2645 data.bi_cursor_bufpos = data.bi_bufpos;
2647 data.findex = DEFAULT_INDEX;
2649 data.bi_start_col_enabled = 0;
2651 if (data.bi_bufpos != bi_start_pos)
2653 struct glyph_block gb;
2656 gb.glyph = Vhscroll_glyph;
2657 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2658 GLYPH_CACHEL (w, HSCROLL_GLYPH_INDEX));
2662 /* This duplicates code down below to add a newline to
2663 the end of an otherwise empty line.*/
2665 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2667 add_emchar_rune (&data);
2671 INC_BYTIND (b, data.bi_bufpos);
2674 /* Otherwise we have a buffer line which cannot fit on one display
2678 struct glyph_block gb;
2679 struct glyph_cachel *cachel;
2681 /* If the line is to be truncated then we actually have to look
2682 for the next newline. We also add the end-of-line glyph which
2683 we know will fit because we adjusted the right border before
2684 we starting laying out the line. */
2685 data.max_pixpos += data.end_glyph_width;
2686 data.findex = DEFAULT_INDEX;
2693 /* Now find the start of the next line. */
2694 bi_pos = bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2696 /* If the cursor is past the truncation line then we
2697 make it appear on the truncation glyph. If we've hit
2698 the end of the buffer then we also make the cursor
2699 appear unless eob is immediately preceded by a
2700 newline. In that case the cursor should actually
2701 appear on the next line. */
2702 if (data.cursor_type == CURSOR_ON
2703 && data.bi_cursor_bufpos >= data.bi_bufpos
2704 && (data.bi_cursor_bufpos < bi_pos ||
2705 (bi_pos == BI_BUF_ZV (b)
2706 && (bi_pos == BI_BUF_BEGV (b)
2707 || (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_pos))
2709 data.bi_cursor_bufpos = bi_pos;
2711 data.cursor_type = NO_CURSOR;
2713 data.bi_bufpos = bi_pos;
2714 gb.glyph = Vtruncation_glyph;
2715 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
2719 /* The cursor can never be on the continuation glyph. */
2720 data.cursor_type = NO_CURSOR;
2722 /* data.bi_bufpos is already at the start of the next line. */
2724 dl->line_continuation = 1;
2725 gb.glyph = Vcontinuation_glyph;
2726 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
2729 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
2731 if (truncate_win && data.bi_bufpos == BI_BUF_ZV (b)
2732 && BI_BUF_FETCH_CHAR (b, prev_bytind (b, BI_BUF_ZV (b))) != '\n')
2733 /* #### Damn this losing shit. */
2737 else if ((active_minibuffer || !NILP (synch_minibuffers_value))
2738 && (!echo_area_active (f) || data.bi_bufpos == BI_BUF_ZV (b)))
2740 /* We need to add a marker to the end of the line since there is no
2741 newline character in order for the cursor to get drawn. We label
2742 it as a newline so that it gets handled correctly by the
2743 whitespace routines below. */
2746 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2747 data.findex = DEFAULT_INDEX;
2749 data.start_col_xoffset = 0;
2750 data.bi_start_col_enabled = 0;
2752 data.max_pixpos += data.blank_width;
2753 add_emchar_rune (&data);
2754 data.max_pixpos -= data.blank_width;
2756 /* #### urk! Chuck, this shit is bad news. Going around
2757 manipulating invalid positions is guaranteed to result in
2758 trouble sooner or later. */
2759 data.bi_bufpos = BI_BUF_ZV (b) + 1;
2762 /* Calculate left whitespace boundary. */
2766 /* Whitespace past a newline is considered right whitespace. */
2767 while (elt < Dynarr_length (db->runes))
2769 struct rune *rb = Dynarr_atp (db->runes, elt);
2771 if ((rb->type == RUNE_CHAR && rb->object.chr.ch == ' ')
2772 || rb->type == RUNE_BLANK)
2774 dl->bounds.left_white += rb->width;
2778 elt = Dynarr_length (db->runes);
2782 /* Calculate right whitespace boundary. */
2784 int elt = Dynarr_length (db->runes) - 1;
2787 while (!done && elt >= 0)
2789 struct rune *rb = Dynarr_atp (db->runes, elt);
2791 if (!(rb->type == RUNE_CHAR && rb->object.chr.ch < 0x100
2792 && isspace (rb->object.chr.ch))
2793 && !rb->type == RUNE_BLANK)
2795 dl->bounds.right_white = rb->xpos + rb->width;
2803 /* The line is blank so everything is considered to be right
2806 dl->bounds.right_white = dl->bounds.left_in;
2809 /* Set the display blocks bounds. */
2810 db->start_pos = dl->bounds.left_in;
2811 if (Dynarr_length (db->runes))
2813 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
2815 db->end_pos = rb->xpos + rb->width;
2818 db->end_pos = dl->bounds.right_white;
2820 calculate_baseline (&data);
2822 dl->ascent = data.new_ascent;
2823 dl->descent = data.new_descent;
2826 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
2828 if (dl->ascent < ascent)
2829 dl->ascent = ascent;
2832 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
2834 if (dl->descent < descent)
2835 dl->descent = descent;
2838 calculate_yoffset (dl, db);
2840 dl->cursor_elt = data.cursor_x;
2841 /* #### lossage lossage lossage! Fix this shit! */
2842 if (data.bi_bufpos > BI_BUF_ZV (b))
2843 dl->end_bufpos = BUF_ZV (b);
2845 dl->end_bufpos = bytind_to_bufpos (b, data.bi_bufpos) - 1;
2847 data.dl->num_chars = column_at_point (b, dl->end_bufpos, 0);
2849 /* This doesn't correctly take into account tabs and control
2850 characters but if the window isn't being truncated then this
2851 value isn't going to end up being used anyhow. */
2852 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
2854 /* #### handle horizontally scrolled line with text none of which
2855 was actually laid out. */
2857 /* #### handle any remainder of overlay arrow */
2859 if (*prop == ADD_FAILED)
2862 if (truncate_win && *prop)
2864 Dynarr_free (*prop);
2868 extent_fragment_delete (data.ef);
2870 /* #### If we started at EOB, then make sure we return a value past
2871 it so that regenerate_window will exit properly. This is bogus.
2872 The main loop should get fixed so that it isn't necessary to call
2873 this function if we are already at EOB. */
2875 if (data.bi_bufpos == BI_BUF_ZV (b) && bi_start_pos == BI_BUF_ZV (b))
2876 return data.bi_bufpos + 1; /* Yuck! */
2878 return data.bi_bufpos;
2881 /* Display the overlay arrow at the beginning of the given line. */
2884 create_overlay_glyph_block (struct window *w, struct display_line *dl)
2886 struct frame *f = XFRAME (w->frame);
2887 struct device *d = XDEVICE (f->device);
2890 /* If Voverlay_arrow_string isn't valid then just fail silently. */
2891 if (!STRINGP (Voverlay_arrow_string) && !GLYPHP (Voverlay_arrow_string))
2897 XSETWINDOW (data.window, w);
2898 data.db = get_display_block_from_line (dl, OVERWRITE);
2900 data.pixpos = dl->bounds.left_in;
2901 data.max_pixpos = dl->bounds.right_in;
2902 data.cursor_type = NO_CURSOR;
2904 data.findex = DEFAULT_INDEX;
2905 data.last_charset = Qunbound;
2906 data.last_findex = DEFAULT_INDEX;
2907 data.result_str = Qnil;
2910 Dynarr_reset (data.db->runes);
2912 if (STRINGP (Voverlay_arrow_string))
2914 add_bufbyte_string_runes
2916 XSTRING_DATA (Voverlay_arrow_string),
2917 XSTRING_LENGTH (Voverlay_arrow_string),
2920 else if (GLYPHP (Voverlay_arrow_string))
2922 struct glyph_block gb;
2924 gb.glyph = Voverlay_arrow_string;
2926 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, 0);
2929 calculate_baseline (&data);
2931 dl->ascent = data.new_ascent;
2932 dl->descent = data.new_descent;
2934 data.db->start_pos = dl->bounds.left_in;
2935 data.db->end_pos = data.pixpos;
2937 calculate_yoffset (dl, data.db);
2939 return data.pixpos - dl->bounds.left_in;
2942 /* Add a type of glyph to a margin display block. */
2945 add_margin_runes (struct display_line *dl, struct display_block *db, int start,
2946 int count, enum glyph_layout layout, int side, Lisp_Object window)
2948 glyph_block_dynarr *gbd = (side == LEFT_GLYPHS
2950 : dl->right_glyphs);
2953 struct window *w = XWINDOW (window);
2954 struct frame *f = XFRAME (w->frame);
2955 struct device *d = XDEVICE (f->device);
2960 data.window = window;
2963 data.pixpos = start;
2964 data.cursor_type = NO_CURSOR;
2966 data.last_charset = Qunbound;
2967 data.last_findex = DEFAULT_INDEX;
2968 data.result_str = Qnil;
2970 data.new_ascent = dl->ascent;
2971 data.new_descent = dl->descent;
2973 if ((layout == GL_WHITESPACE && side == LEFT_GLYPHS)
2974 || (layout == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS))
2977 elt = Dynarr_length (gbd) - 1;
2984 end = Dynarr_length (gbd);
2987 while (count && ((!reverse && elt < end) || (reverse && elt >= end)))
2989 struct glyph_block *gb = Dynarr_atp (gbd, elt);
2991 if (NILP (gb->extent))
2992 abort (); /* these should have been handled in add_glyph_rune */
2995 ((side == LEFT_GLYPHS &&
2996 extent_begin_glyph_layout (XEXTENT (gb->extent)) == layout)
2997 || (side == RIGHT_GLYPHS &&
2998 extent_end_glyph_layout (XEXTENT (gb->extent)) == layout)))
3000 data.findex = gb->findex;
3001 data.max_pixpos = data.pixpos + gb->width;
3002 add_glyph_rune (&data, gb, side, 0, NULL);
3007 (reverse ? elt-- : elt++);
3010 calculate_baseline (&data);
3012 dl->ascent = data.new_ascent;
3013 dl->descent = data.new_descent;
3015 calculate_yoffset (dl, data.db);
3020 /* Add a blank to a margin display block. */
3023 add_margin_blank (struct display_line *dl, struct display_block *db,
3024 struct window *w, int xpos, int width, int side)
3028 rb.findex = (side == LEFT_GLYPHS
3029 ? get_builtin_face_cache_index (w, Vleft_margin_face)
3030 : get_builtin_face_cache_index (w, Vright_margin_face));
3035 rb.type = RUNE_BLANK;
3036 rb.cursor_type = CURSOR_OFF;
3038 Dynarr_add (db->runes, rb);
3041 /* Display glyphs in the left outside margin, left inside margin and
3042 left whitespace area. */
3045 create_left_glyph_block (struct window *w, struct display_line *dl,
3050 int use_overflow = (NILP (w->use_left_overflow) ? 0 : 1);
3052 int out_end, in_out_start, in_in_end, white_out_start, white_in_start;
3053 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
3054 int left_in_start = dl->bounds.left_in;
3055 int left_in_end = dl->bounds.left_in + overlay_width;
3057 struct display_block *odb, *idb;
3059 XSETWINDOW (window, w);
3061 /* We have to add the glyphs to the line in the order outside,
3062 inside, whitespace. However the precedence dictates that we
3063 determine how many will fit in the reverse order. */
3065 /* Determine how many whitespace glyphs we can display and where
3066 they should start. */
3067 white_in_start = dl->bounds.left_white;
3068 white_out_start = left_in_start;
3069 white_out_cnt = white_in_cnt = 0;
3072 while (elt < Dynarr_length (dl->left_glyphs))
3074 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3076 if (NILP (gb->extent))
3077 abort (); /* these should have been handled in add_glyph_rune */
3079 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
3083 width = glyph_width (gb->glyph, window);
3085 if (white_in_start - width >= left_in_end)
3088 white_in_start -= width;
3092 else if (use_overflow
3093 && (white_out_start - width > dl->bounds.left_out))
3096 white_out_start -= width;
3107 /* Determine how many inside margin glyphs we can display and where
3108 they should start. The inside margin glyphs get whatever space
3109 is left after the whitespace glyphs have been displayed. These
3110 are tricky to calculate since if we decide to use the overflow
3111 area we basically have to start over. So for these we build up a
3112 list of just the inside margin glyphs and manipulate it to
3113 determine the needed info. */
3115 glyph_block_dynarr *ib;
3116 int avail_in, avail_out;
3119 int used_in, used_out;
3122 used_in = used_out = 0;
3123 ib = Dynarr_new (glyph_block);
3124 while (elt < Dynarr_length (dl->left_glyphs))
3126 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3128 if (NILP (gb->extent))
3129 abort (); /* these should have been handled in add_glyph_rune */
3131 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3134 gb->width = glyph_width (gb->glyph, window);
3135 used_in += gb->width;
3136 Dynarr_add (ib, *gb);
3146 avail_in = white_in_start - left_in_end;
3154 avail_out = white_out_start - dl->bounds.left_out;
3157 while (!done && marker < Dynarr_length (ib))
3159 int width = Dynarr_atp (ib, marker)->width;
3161 /* If everything now fits in the available inside margin
3162 space, we're done. */
3163 if (used_in <= avail_in)
3167 /* Otherwise see if we have room to move a glyph to the
3169 if (used_out + width <= avail_out)
3182 /* At this point we now know that everything from marker on goes in
3183 the inside margin and everything before it goes in the outside
3184 margin. The stuff going into the outside margin is guaranteed
3185 to fit, but we may have to trim some stuff from the inside. */
3187 in_in_end = left_in_end;
3188 in_out_start = white_out_start;
3189 in_out_cnt = in_in_cnt = 0;
3193 while (elt < Dynarr_length (dl->left_glyphs))
3195 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3197 if (NILP (gb->extent))
3198 abort (); /* these should have been handled in add_glyph_rune */
3200 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3203 int width = glyph_width (gb->glyph, window);
3208 in_out_start -= width;
3213 else if (in_in_end + width < white_in_start)
3228 /* Determine how many outside margin glyphs we can display. They
3229 always start at the left outside margin and can only use the
3230 outside margin space. */
3231 out_end = dl->bounds.left_out;
3235 while (elt < Dynarr_length (dl->left_glyphs))
3237 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3239 if (NILP (gb->extent))
3240 abort (); /* these should have been handled in add_glyph_rune */
3242 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3245 int width = glyph_width (gb->glyph, window);
3247 if (out_end + width <= in_out_start)
3261 /* Now that we know where everything goes, we add the glyphs as
3262 runes to the appropriate display blocks. */
3263 if (out_cnt || in_out_cnt || white_out_cnt)
3265 odb = get_display_block_from_line (dl, LEFT_OUTSIDE_MARGIN);
3266 odb->start_pos = dl->bounds.left_out;
3267 /* #### We should stop adding a blank to account for the space
3268 between the end of the glyphs and the margin and instead set
3269 this accordingly. */
3270 odb->end_pos = dl->bounds.left_in;
3271 Dynarr_reset (odb->runes);
3276 if (in_in_cnt || white_in_cnt)
3278 idb = get_display_block_from_line (dl, LEFT_INSIDE_MARGIN);
3279 idb->start_pos = dl->bounds.left_in;
3280 /* #### See above comment for odb->end_pos */
3281 idb->end_pos = dl->bounds.left_white;
3282 Dynarr_reset (idb->runes);
3287 /* First add the outside margin glyphs. */
3289 end_xpos = add_margin_runes (dl, odb, dl->bounds.left_out, out_cnt,
3290 GL_OUTSIDE_MARGIN, LEFT_GLYPHS, window);
3292 end_xpos = dl->bounds.left_out;
3294 /* There may be blank space between the outside margin glyphs and
3295 the inside margin glyphs. If so, add a blank. */
3296 if (in_out_cnt && (in_out_start - end_xpos))
3298 add_margin_blank (dl, odb, w, end_xpos, in_out_start - end_xpos,
3302 /* Next add the inside margin glyphs which are actually in the
3306 end_xpos = add_margin_runes (dl, odb, in_out_start, in_out_cnt,
3307 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3310 /* If we didn't add any inside margin glyphs to the outside margin,
3311 but are adding whitespace glyphs, then we need to add a blank
3313 if (!in_out_cnt && white_out_cnt && (white_out_start - end_xpos))
3315 add_margin_blank (dl, odb, w, end_xpos, white_out_start - end_xpos,
3319 /* Next add the whitespace margin glyphs which are actually in the
3323 end_xpos = add_margin_runes (dl, odb, white_out_start, white_out_cnt,
3324 GL_WHITESPACE, LEFT_GLYPHS, window);
3327 /* We take care of clearing between the end of the glyphs and the
3328 start of the inside margin for lines which have glyphs. */
3329 if (odb && (left_in_start - end_xpos))
3331 add_margin_blank (dl, odb, w, end_xpos, left_in_start - end_xpos,
3335 /* Next add the inside margin glyphs which are actually in the
3339 end_xpos = add_margin_runes (dl, idb, left_in_end, in_in_cnt,
3340 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3343 end_xpos = left_in_end;
3345 /* Make sure that the area between the end of the inside margin
3346 glyphs and the whitespace glyphs is cleared. */
3347 if (idb && (white_in_start - end_xpos > 0))
3349 add_margin_blank (dl, idb, w, end_xpos, white_in_start - end_xpos,
3353 /* Next add the whitespace margin glyphs which are actually in the
3357 add_margin_runes (dl, idb, white_in_start, white_in_cnt, GL_WHITESPACE,
3358 LEFT_GLYPHS, window);
3361 /* Whitespace glyphs always end right next to the text block so
3362 there is nothing we have to make sure is cleared after them. */
3365 /* Display glyphs in the right outside margin, right inside margin and
3366 right whitespace area. */
3369 create_right_glyph_block (struct window *w, struct display_line *dl)
3373 int use_overflow = (NILP (w->use_right_overflow) ? 0 : 1);
3375 int out_start, in_out_end, in_in_start, white_out_end, white_in_end;
3376 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
3378 struct display_block *odb, *idb;
3380 XSETWINDOW (window, w);
3382 /* We have to add the glyphs to the line in the order outside,
3383 inside, whitespace. However the precedence dictates that we
3384 determine how many will fit in the reverse order. */
3386 /* Determine how many whitespace glyphs we can display and where
3387 they should start. */
3388 white_in_end = dl->bounds.right_white;
3389 white_out_end = dl->bounds.right_in;
3390 white_out_cnt = white_in_cnt = 0;
3393 while (elt < Dynarr_length (dl->right_glyphs))
3395 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3397 if (NILP (gb->extent))
3398 abort (); /* these should have been handled in add_glyph_rune */
3400 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
3402 int width = glyph_width (gb->glyph, window);
3404 if (white_in_end + width <= dl->bounds.right_in)
3407 white_in_end += width;
3411 else if (use_overflow
3412 && (white_out_end + width <= dl->bounds.right_out))
3415 white_out_end += width;
3426 /* Determine how many inside margin glyphs we can display and where
3427 they should start. The inside margin glyphs get whatever space
3428 is left after the whitespace glyphs have been displayed. These
3429 are tricky to calculate since if we decide to use the overflow
3430 area we basically have to start over. So for these we build up a
3431 list of just the inside margin glyphs and manipulate it to
3432 determine the needed info. */
3434 glyph_block_dynarr *ib;
3435 int avail_in, avail_out;
3438 int used_in, used_out;
3441 used_in = used_out = 0;
3442 ib = Dynarr_new (glyph_block);
3443 while (elt < Dynarr_length (dl->right_glyphs))
3445 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3447 if (NILP (gb->extent))
3448 abort (); /* these should have been handled in add_glyph_rune */
3450 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3452 gb->width = glyph_width (gb->glyph, window);
3453 used_in += gb->width;
3454 Dynarr_add (ib, *gb);
3463 avail_in = dl->bounds.right_in - white_in_end;
3468 avail_out = dl->bounds.right_out - white_out_end;
3471 while (!done && marker < Dynarr_length (ib))
3473 int width = Dynarr_atp (ib, marker)->width;
3475 /* If everything now fits in the available inside margin
3476 space, we're done. */
3477 if (used_in <= avail_in)
3481 /* Otherwise see if we have room to move a glyph to the
3483 if (used_out + width <= avail_out)
3496 /* At this point we now know that everything from marker on goes in
3497 the inside margin and everything before it goes in the outside
3498 margin. The stuff going into the outside margin is guaranteed
3499 to fit, but we may have to trim some stuff from the inside. */
3501 in_in_start = dl->bounds.right_in;
3502 in_out_end = dl->bounds.right_in;
3503 in_out_cnt = in_in_cnt = 0;
3507 while (elt < Dynarr_length (dl->right_glyphs))
3509 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3511 if (NILP (gb->extent))
3512 abort (); /* these should have been handled in add_glyph_rune */
3514 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3516 int width = glyph_width (gb->glyph, window);
3521 in_out_end += width;
3526 else if (in_in_start - width >= white_in_end)
3529 in_in_start -= width;
3541 /* Determine how many outside margin glyphs we can display. They
3542 always start at the right outside margin and can only use the
3543 outside margin space. */
3544 out_start = dl->bounds.right_out;
3548 while (elt < Dynarr_length (dl->right_glyphs))
3550 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3552 if (NILP (gb->extent))
3553 abort (); /* these should have been handled in add_glyph_rune */
3555 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_OUTSIDE_MARGIN)
3557 int width = glyph_width (gb->glyph, window);
3559 if (out_start - width >= in_out_end)
3573 /* Now that we now where everything goes, we add the glyphs as runes
3574 to the appropriate display blocks. */
3575 if (out_cnt || in_out_cnt || white_out_cnt)
3577 odb = get_display_block_from_line (dl, RIGHT_OUTSIDE_MARGIN);
3578 /* #### See comments before odb->start_pos init in
3579 create_left_glyph_block */
3580 odb->start_pos = dl->bounds.right_in;
3581 odb->end_pos = dl->bounds.right_out;
3582 Dynarr_reset (odb->runes);
3587 if (in_in_cnt || white_in_cnt)
3589 idb = get_display_block_from_line (dl, RIGHT_INSIDE_MARGIN);
3590 idb->start_pos = dl->bounds.right_white;
3591 /* #### See comments before odb->start_pos init in
3592 create_left_glyph_block */
3593 idb->end_pos = dl->bounds.right_in;
3594 Dynarr_reset (idb->runes);
3599 /* First add the whitespace margin glyphs which are actually in the
3603 end_xpos = add_margin_runes (dl, idb, dl->bounds.right_white,
3604 white_in_cnt, GL_WHITESPACE, RIGHT_GLYPHS,
3608 end_xpos = dl->bounds.right_white;
3610 /* Make sure that the area between the end of the whitespace glyphs
3611 and the inside margin glyphs is cleared. */
3612 if (in_in_cnt && (in_in_start - end_xpos))
3614 add_margin_blank (dl, idb, w, end_xpos, in_in_start - end_xpos,
3618 /* Next add the inside margin glyphs which are actually in the
3622 end_xpos = add_margin_runes (dl, idb, in_in_start, in_in_cnt,
3623 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3626 /* If we didn't add any inside margin glyphs then make sure the rest
3627 of the inside margin area gets cleared. */
3628 if (idb && (dl->bounds.right_in - end_xpos))
3630 add_margin_blank (dl, idb, w, end_xpos, dl->bounds.right_in - end_xpos,
3634 /* Next add any whitespace glyphs in the outside margin. */
3637 end_xpos = add_margin_runes (dl, odb, dl->bounds.right_in, white_out_cnt,
3638 GL_WHITESPACE, RIGHT_GLYPHS, window);
3641 end_xpos = dl->bounds.right_in;
3643 /* Next add any inside margin glyphs in the outside margin. */
3646 end_xpos = add_margin_runes (dl, odb, end_xpos, in_out_cnt,
3647 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3650 /* There may be space between any whitespace or inside margin glyphs
3651 in the outside margin and the actual outside margin glyphs. */
3652 if (odb && (out_start - end_xpos))
3654 add_margin_blank (dl, odb, w, end_xpos, out_start - end_xpos,
3658 /* Finally, add the outside margin glyphs. */
3661 add_margin_runes (dl, odb, out_start, out_cnt, GL_OUTSIDE_MARGIN,
3662 RIGHT_GLYPHS, window);
3667 /***************************************************************************/
3669 /* modeline routines */
3671 /***************************************************************************/
3673 /* This function is also used in frame.c by `generate_title_string' */
3675 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str,
3676 struct window *w, struct display_line *dl,
3677 struct display_block *db, face_index findex,
3678 int min_pixpos, int max_pixpos, int type)
3680 struct frame *f = XFRAME (w->frame);
3681 struct device *d = XDEVICE (f->device);
3685 Charcount offset = 0;
3691 data.findex = findex;
3692 data.pixpos = min_pixpos;
3693 data.max_pixpos = max_pixpos;
3694 data.cursor_type = NO_CURSOR;
3695 data.last_charset = Qunbound;
3696 data.last_findex = DEFAULT_INDEX;
3697 data.result_str = result_str;
3698 data.is_modeline = 1;
3700 XSETWINDOW (data.window, w);
3702 Dynarr_reset (formatted_string_extent_dynarr);
3703 Dynarr_reset (formatted_string_extent_start_dynarr);
3704 Dynarr_reset (formatted_string_extent_end_dynarr);
3706 /* result_str is nil when we're building a frame or icon title. Otherwise,
3707 we're building a modeline, so the offset starts at the modeline
3708 horizontal scrolling amount */
3709 if (! NILP (result_str))
3710 offset = w->modeline_hscroll;
3711 generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0,
3712 max_pixpos - min_pixpos, findex, type, &offset,
3715 if (Dynarr_length (db->runes))
3718 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
3719 c_pixpos = rb->xpos + rb->width;
3722 c_pixpos = min_pixpos;
3724 /* If we don't reach the right side of the window, add a blank rune
3725 to make up the difference. This usually only occurs if the
3726 modeline face is using a proportional width font or a fixed width
3727 font of a different size from the default face font. */
3729 if (c_pixpos < max_pixpos)
3731 data.pixpos = c_pixpos;
3732 data.blank_width = max_pixpos - data.pixpos;
3734 add_blank_rune (&data, NULL, 0);
3737 /* Now create the result string and frob the extents into it. */
3738 if (!NILP (result_str))
3743 struct buffer *buf = XBUFFER (WINDOW_BUFFER (w));
3745 in_modeline_generation = 1;
3747 detach_all_extents (result_str);
3748 resize_string (XSTRING (result_str), -1,
3749 data.bytepos - XSTRING_LENGTH (result_str));
3751 strdata = XSTRING_DATA (result_str);
3753 for (elt = 0, len = 0; elt < Dynarr_length (db->runes); elt++)
3755 if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR)
3757 len += (set_charptr_emchar
3758 (strdata + len, Dynarr_atp (db->runes,
3759 elt)->object.chr.ch));
3763 for (elt = 0; elt < Dynarr_length (formatted_string_extent_dynarr);
3766 Lisp_Object extent = Qnil;
3769 XSETEXTENT (extent, Dynarr_at (formatted_string_extent_dynarr, elt));
3770 child = Fgethash (extent, buf->modeline_extent_table, Qnil);
3773 child = Fmake_extent (Qnil, Qnil, result_str);
3774 Fputhash (extent, child, buf->modeline_extent_table);
3776 Fset_extent_parent (child, extent);
3777 set_extent_endpoints
3779 Dynarr_at (formatted_string_extent_start_dynarr, elt),
3780 Dynarr_at (formatted_string_extent_end_dynarr, elt),
3784 in_modeline_generation = 0;
3788 /* Ensure that the given display line DL accurately represents the
3789 modeline for the given window. */
3791 generate_modeline (struct window *w, struct display_line *dl, int type)
3793 struct buffer *b = XBUFFER (w->buffer);
3794 struct frame *f = XFRAME (w->frame);
3795 struct device *d = XDEVICE (f->device);
3797 /* Unlike display line and rune pointers, this one can't change underneath
3799 struct display_block *db = get_display_block_from_line (dl, TEXT);
3800 int max_pixpos, min_pixpos, ypos_adj;
3801 Lisp_Object font_inst;
3803 /* This will actually determine incorrect inside boundaries for the
3804 modeline since it ignores the margins. However being aware of this fact
3805 we never use those values anywhere so it doesn't matter. */
3806 dl->bounds = calculate_display_line_boundaries (w, 1);
3808 /* We are generating a modeline. */
3810 dl->cursor_elt = -1;
3812 /* Reset the runes on the modeline. */
3813 Dynarr_reset (db->runes);
3815 if (!WINDOW_HAS_MODELINE_P (w))
3819 /* If there is a horizontal scrollbar, don't add anything. */
3820 if (window_scrollbar_height (w))
3823 dl->ascent = DEVMETH (d, divider_height, ());
3825 /* The modeline is at the bottom of the gutters. */
3826 dl->ypos = WINDOW_BOTTOM (w);
3828 rb.findex = MODELINE_INDEX;
3829 rb.xpos = dl->bounds.left_out;
3830 rb.width = dl->bounds.right_out - dl->bounds.left_out;
3833 rb.type = RUNE_HLINE;
3834 rb.object.hline.thickness = 1;
3835 rb.object.hline.yoffset = 0;
3836 rb.cursor_type = NO_CURSOR;
3838 if (!EQ (Qzero, w->modeline_shadow_thickness)
3841 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3843 dl->ypos -= shadow_thickness;
3844 rb.xpos += shadow_thickness;
3845 rb.width -= 2 * shadow_thickness;
3848 Dynarr_add (db->runes, rb);
3852 /* !!#### not right; needs to compute the max height of
3854 font_inst = WINDOW_FACE_CACHEL_FONT (w, MODELINE_INDEX, Vcharset_ascii);
3856 dl->ascent = XFONT_INSTANCE (font_inst)->ascent;
3857 dl->descent = XFONT_INSTANCE (font_inst)->descent;
3859 min_pixpos = dl->bounds.left_out;
3860 max_pixpos = dl->bounds.right_out;
3862 if (!EQ (Qzero, w->modeline_shadow_thickness) && FRAME_WIN_P (f))
3864 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3866 ypos_adj = shadow_thickness;
3867 min_pixpos += shadow_thickness;
3868 max_pixpos -= shadow_thickness;
3873 generate_formatted_string_db (b->modeline_format,
3874 b->generated_modeline_string, w, dl, db,
3875 MODELINE_INDEX, min_pixpos, max_pixpos, type);
3877 /* The modeline is at the bottom of the gutters. We have to wait to
3878 set this until we've generated the modeline in order to account
3879 for any embedded faces. */
3880 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj;
3884 add_string_to_fstring_db_runes (pos_data *data, const Bufbyte *str,
3885 Charcount pos, Charcount min_pos, Charcount max_pos)
3887 /* This function has been Mule-ized. */
3889 const Bufbyte *cur_pos = str;
3890 struct display_block *db = data->db;
3892 data->blank_width = space_width (XWINDOW (data->window));
3893 while (Dynarr_length (db->runes) < pos)
3894 add_blank_rune (data, NULL, 0);
3896 end = (Dynarr_length (db->runes) +
3897 bytecount_to_charcount (str, strlen ((const char *) str)));
3899 end = min (max_pos, end);
3901 while (pos < end && *cur_pos)
3903 const Bufbyte *old_cur_pos = cur_pos;
3906 data->ch = charptr_emchar (cur_pos);
3907 succeeded = (add_emchar_rune (data) != ADD_FAILED);
3908 INC_CHARPTR (cur_pos);
3912 data->modeline_charpos++;
3913 data->bytepos += cur_pos - old_cur_pos;
3917 while (Dynarr_length (db->runes) < min_pos &&
3918 (data->pixpos + data->blank_width <= data->max_pixpos))
3919 add_blank_rune (data, NULL, 0);
3921 return Dynarr_length (db->runes);
3924 /* #### Urk! Should also handle begin-glyphs and end-glyphs in
3925 modeline extents. */
3927 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph,
3928 Charcount pos, Charcount min_pos,
3929 Charcount max_pos, Lisp_Object extent)
3931 /* This function has been Mule-ized. */
3933 struct display_block *db = data->db;
3934 struct glyph_block gb;
3936 data->blank_width = space_width (XWINDOW (data->window));
3937 while (Dynarr_length (db->runes) < pos)
3938 add_blank_rune (data, NULL, 0);
3940 end = Dynarr_length (db->runes) + 1;
3942 end = min (max_pos, end);
3946 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
3949 while (Dynarr_length (db->runes) < pos &&
3950 (data->pixpos + data->blank_width <= data->max_pixpos))
3951 add_blank_rune (data, NULL, 0);
3953 return Dynarr_length (db->runes);
3956 /* If max_pos is == -1, it is considered to be infinite. The same is
3957 true of max_pixsize. */
3958 #define SET_CURRENT_MODE_CHARS_PIXSIZE \
3959 if (Dynarr_length (data->db->runes)) \
3960 cur_pixsize = data->pixpos - Dynarr_atp (data->db->runes, 0)->xpos; \
3964 /* Note that this function does "positions" in terms of characters and
3965 not in terms of columns. This is necessary to make the formatting
3966 work correctly when proportional width fonts are used in the
3969 generate_fstring_runes (struct window *w, pos_data *data, Charcount pos,
3970 Charcount min_pos, Charcount max_pos,
3971 Lisp_Object elt, int depth, int max_pixsize,
3972 face_index findex, int type, Charcount *offset,
3973 Lisp_Object cur_ext)
3975 /* This function has been Mule-ized. */
3976 /* #### The other losing things in this function are:
3978 -- C zero-terminated-string lossage.
3979 -- Non-printable characters should be converted into something
3980 appropriate (e.g. ^F) instead of blindly being printed anyway.
3991 /* A string. Add to the display line and check for %-constructs
3994 Bufbyte *this = XSTRING_DATA (elt);
3996 while ((pos < max_pos || max_pos == -1) && *this)
3998 Bufbyte *last = this;
4000 while (*this && *this != '%')
4005 /* No %-construct */
4007 bytecount_to_charcount (last, this - last);
4009 if (size <= *offset)
4013 Charcount tmp_max = (max_pos == -1 ? pos + size - *offset :
4014 min (pos + size - *offset, max_pos));
4015 const Bufbyte *tmp_last = charptr_n_addr (last, *offset);
4017 pos = add_string_to_fstring_db_runes (data, tmp_last,
4022 else /* *this == '%' */
4024 Charcount spec_width = 0;
4026 this++; /* skip over '%' */
4028 /* We can't allow -ve args due to the "%-" construct.
4029 * Argument specifies minwidth but not maxwidth
4030 * (maxwidth can be specified by
4031 * (<negative-number> . <stuff>) modeline elements)
4033 while (isdigit (*this))
4035 spec_width = spec_width * 10 + (*this - '0');
4042 pos = generate_fstring_runes (w, data, pos, spec_width,
4043 max_pos, Vglobal_mode_string,
4044 depth, max_pixsize, findex,
4045 type, offset, cur_ext);
4047 else if (*this == '-')
4049 Charcount num_to_add;
4051 if (max_pixsize < 0)
4053 else if (max_pos != -1)
4054 num_to_add = max_pos - pos;
4060 SET_CURRENT_MODE_CHARS_PIXSIZE;
4063 redisplay_text_width_string (w, findex, &ch, Qnil, 0,
4066 num_to_add = (max_pixsize - cur_pixsize) / dash_pixsize;
4070 while (num_to_add--)
4071 pos = add_string_to_fstring_db_runes
4072 (data, (const Bufbyte *) "-", pos, pos, max_pos);
4074 else if (*this != 0)
4076 Emchar ch = charptr_emchar (this);
4080 decode_mode_spec (w, ch, type);
4082 str = Dynarr_atp (mode_spec_bufbyte_string, 0);
4083 size = bytecount_to_charcount
4084 /* Skip the null character added by `decode_mode_spec' */
4085 (str, Dynarr_length (mode_spec_bufbyte_string)) - 1;
4087 if (size <= *offset)
4091 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
4093 /* #### NOTE: I don't understand why a tmp_max is not
4094 computed and used here as in the plain string case
4096 pos = add_string_to_fstring_db_runes (data, tmp_str,
4103 /* NOT this++. There could be any sort of character at
4104 the current position. */
4108 if (max_pixsize > 0)
4111 SET_CURRENT_MODE_CHARS_PIXSIZE;
4113 if (cur_pixsize >= max_pixsize)
4118 else if (SYMBOLP (elt))
4120 /* A symbol: process the value of the symbol recursively
4121 as if it appeared here directly. */
4122 Lisp_Object tem = symbol_value_in_buffer (elt, w->buffer);
4124 if (!UNBOUNDP (tem))
4126 /* If value is a string, output that string literally:
4127 don't check for % within it. */
4130 Bufbyte *str = XSTRING_DATA (tem);
4131 Charcount size = XSTRING_CHAR_LENGTH (tem);
4133 if (size <= *offset)
4137 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
4139 /* #### NOTE: I don't understand why a tmp_max is not
4140 computed and used here as in the plain string case
4142 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
4147 /* Give up right away for nil or t. */
4148 else if (!EQ (tem, elt))
4155 else if (GENERIC_SPECIFIERP (elt))
4157 Lisp_Object window, tem;
4158 XSETWINDOW (window, w);
4159 tem = specifier_instance_no_quit (elt, Qunbound, window,
4160 ERROR_ME_NOT, 0, Qzero);
4161 if (!UNBOUNDP (tem))
4167 else if (CONSP (elt))
4169 /* A cons cell: four distinct cases.
4170 * - If first element is a string or a cons, process all the elements
4171 * and effectively concatenate them.
4172 * - If first element is a negative number, truncate displaying cdr to
4173 * at most that many characters. If positive, pad (with spaces)
4174 * to at least that many characters.
4175 * - If first element is another symbol, process the cadr or caddr
4176 * recursively according to whether the symbol's value is non-nil or
4178 * - If first element is an extent, process the cdr recursively
4179 * and handle the extent's face.
4182 Lisp_Object car, tem;
4191 tem = symbol_value_in_buffer (car, w->buffer);
4192 /* elt is now the cdr, and we know it is a cons cell.
4193 Use its car if CAR has a non-nil value. */
4194 if (!UNBOUNDP (tem))
4202 /* Symbol's value is nil (or symbol is unbound)
4203 * Get the cddr of the original list
4204 * and if possible find the caddr and use that.
4209 else if (!CONSP (elt))
4217 else if (INTP (car))
4219 Charcount lim = XINT (car);
4225 /* Negative int means reduce maximum width.
4226 * DO NOT change MIN_PIXPOS here!
4227 * (20 -10 . foo) should truncate foo to 10 col
4228 * and then pad to 20.
4231 max_pos = pos - lim;
4233 max_pos = min (max_pos, pos - lim);
4237 /* Padding specified. Don't let it be more than
4241 if (max_pos != -1 && lim > max_pos)
4243 /* If that's more padding than already wanted, queue it.
4244 * But don't reduce padding already specified even if
4245 * that is beyond the current truncation point.
4252 else if (STRINGP (car) || CONSP (car))
4256 /* LIMIT is to protect against circular lists. */
4257 while (CONSP (elt) && --limit > 0
4258 && (pos < max_pos || max_pos == -1))
4260 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4261 XCAR (elt), depth, max_pixsize,
4262 findex, type, offset, cur_ext);
4266 else if (EXTENTP (car))
4268 struct extent *ext = XEXTENT (car);
4270 if (EXTENT_LIVE_P (ext))
4272 face_index old_findex = data->findex;
4274 Lisp_Object font_inst;
4275 face_index new_findex;
4276 Bytecount start = data->bytepos;
4278 face = extent_face (ext);
4281 /* #### needs to merge faces, sigh */
4282 /* #### needs to handle list of faces */
4283 new_findex = get_builtin_face_cache_index (w, face);
4284 /* !!#### not right; needs to compute the max height of
4286 font_inst = WINDOW_FACE_CACHEL_FONT (w, new_findex,
4289 data->dl->ascent = max (data->dl->ascent,
4290 XFONT_INSTANCE (font_inst)->ascent);
4291 data->dl->descent = max (data->dl->descent,
4292 XFONT_INSTANCE (font_inst)->
4296 new_findex = old_findex;
4298 data->findex = new_findex;
4299 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4300 XCDR (elt), depth - 1,
4301 max_pixsize, new_findex, type,
4303 data->findex = old_findex;
4304 Dynarr_add (formatted_string_extent_dynarr, ext);
4305 Dynarr_add (formatted_string_extent_start_dynarr, start);
4306 Dynarr_add (formatted_string_extent_end_dynarr, data->bytepos);
4310 else if (GLYPHP (elt))
4312 /* Glyphs are considered as one character with respect to the modeline
4313 horizontal scrolling facility. -- dv */
4317 pos = add_glyph_to_fstring_db_runes (data, elt, pos, pos, max_pos,
4324 char *str = GETTEXT ("*invalid*");
4325 Charcount size = (Charcount) strlen (str); /* is this ok ?? -- dv */
4327 if (size <= *offset)
4331 const Bufbyte *tmp_str =
4332 charptr_n_addr ((const Bufbyte *) str, *offset);
4334 /* #### NOTE: I don't understand why a tmp_max is not computed and
4335 used here as in the plain string case above. -- dv */
4336 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
4345 add_string_to_fstring_db_runes (data, (const Bufbyte *) "", pos,
4352 /* Update just the modeline. Assumes the desired display structs. If
4353 they do not have a modeline block, it does nothing. */
4355 regenerate_modeline (struct window *w)
4357 display_line_dynarr *dla = window_display_lines (w, DESIRED_DISP);
4359 if (!Dynarr_length (dla) || !Dynarr_atp (dla, 0)->modeline)
4363 generate_modeline (w, Dynarr_atp (dla, 0), DESIRED_DISP);
4364 redisplay_update_line (w, 0, 0, 0);
4368 /* Make sure that modeline display line is present in the given
4369 display structs if the window has a modeline and update that
4370 line. Returns true if a modeline was needed. */
4372 ensure_modeline_generated (struct window *w, int type)
4376 /* minibuffer windows don't have modelines */
4377 if (MINI_WINDOW_P (w))
4379 /* windows which haven't had it turned off do */
4380 else if (WINDOW_HAS_MODELINE_P (w))
4382 /* windows which have it turned off don't have a divider if there is
4383 a horizontal scrollbar */
4384 else if (window_scrollbar_height (w))
4386 /* and in this case there is none */
4392 display_line_dynarr *dla;
4394 dla = window_display_lines (w, type);
4396 /* We don't care if there is a display line which is not
4397 currently a modeline because it is definitely going to become
4398 one if we have gotten to this point. */
4399 if (Dynarr_length (dla) == 0)
4401 if (Dynarr_largest (dla) > 0)
4403 struct display_line *mlp = Dynarr_atp (dla, 0);
4404 Dynarr_add (dla, *mlp);
4408 struct display_line modeline;
4410 Dynarr_add (dla, modeline);
4414 /* If we're adding a new place marker go ahead and generate the
4415 modeline so that it is available for use by
4416 window_modeline_height. */
4417 generate_modeline (w, Dynarr_atp (dla, 0), type);
4420 return need_modeline;
4423 /* #### Kludge or not a kludge. I tend towards the former. */
4425 real_current_modeline_height (struct window *w)
4427 Fset_marker (w->start[CMOTION_DISP], w->start[CURRENT_DISP], w->buffer);
4428 Fset_marker (w->pointm[CMOTION_DISP], w->pointm[CURRENT_DISP], w->buffer);
4430 if (ensure_modeline_generated (w, CMOTION_DISP))
4432 display_line_dynarr *dla = window_display_lines (w, CMOTION_DISP);
4434 if (Dynarr_length (dla))
4436 if (Dynarr_atp (dla, 0)->modeline)
4437 return (Dynarr_atp (dla, 0)->ascent +
4438 Dynarr_atp (dla, 0)->descent);
4445 /***************************************************************************/
4447 /* displayable string routines */
4449 /***************************************************************************/
4451 /* Given a position for a string in a window, ensure that the given
4452 display line DL accurately represents the text on a line starting
4453 at the given position.
4455 Yes, this is duplicating the code of create_text_block, but it
4456 looked just too hard to change create_text_block to handle strings
4457 *and* buffers. We already make a distinction between the two
4458 elsewhere in the code so I think unifying them would require a
4459 complete MULE rewrite. Besides, the other distinction is that these
4460 functions cover text that the user *cannot edit* so we can remove
4461 everything to do with cursors, minibuffers etc. Eventually the
4462 modeline routines should be modified to use this code as it copes
4463 with many more types of display situation. */
4466 create_string_text_block (struct window *w, Lisp_Object disp_string,
4467 struct display_line *dl,
4469 prop_block_dynarr **prop,
4470 face_index default_face)
4472 struct frame *f = XFRAME (w->frame);
4473 /* Note that a lot of the buffer controlled stuff has been left in
4474 because you might well want to make use of it (selective display
4475 etc), its just the buffer text that we do not use. However, it
4476 seems to be possible for buffer to be nil sometimes so protect
4477 against this case. */
4478 struct buffer *b = BUFFERP (w->buffer) ? XBUFFER (w->buffer) : 0;
4479 struct device *d = XDEVICE (f->device);
4480 Lisp_String* s = XSTRING (disp_string);
4482 /* we're working with these a lot so precalculate them */
4483 Bytecount slen = XSTRING_LENGTH (disp_string);
4484 Bytecount bi_string_zv = slen;
4485 Bytind bi_start_pos = charcount_to_bytecount (string_data (s), start_pos);
4489 int truncate_win = b ? window_truncation_on (w) : 0;
4491 /* We're going to ditch selective display for static text, it's an
4492 FSF thing and invisible extents are the way to go here.
4493 Implementing it also relies on a number of buffer-specific
4494 functions that we don't have the luxury of being able to use
4497 /* The variable ctl-arrow allows the user to specify what characters
4498 can actually be displayed and which octal should be used for.
4499 #### This variable should probably have some rethought done to
4502 #### It would also be really nice if you could specify that
4503 the characters come out in hex instead of in octal. Mule
4504 does that by adding a ctl-hexa variable similar to ctl-arrow,
4505 but that's bogus -- we need a more general solution. I
4506 think you need to extend the concept of display tables
4507 into a more general conversion mechanism. Ideally you
4508 could specify a Lisp function that converts characters,
4509 but this violates the Second Golden Rule and besides would
4510 make things way way way way slow.
4512 So instead, we extend the display-table concept, which was
4513 historically limited to 256-byte vectors, to one of the
4516 a) A 256-entry vector, for backward compatibility;
4517 b) char-table, mapping characters to values;
4518 c) range-table, mapping ranges of characters to values;
4519 d) a list of the above.
4521 The (d) option allows you to specify multiple display tables
4522 instead of just one. Each display table can specify conversions
4523 for some characters and leave others unchanged. The way the
4524 character gets displayed is determined by the first display table
4525 with a binding for that character. This way, you could call a
4526 function `enable-hex-display' that adds a hex display-table to
4527 the list of display tables for the current buffer.
4529 #### ...not yet implemented... Also, we extend the concept of
4530 "mapping" to include a printf-like spec. Thus you can make all
4531 extended characters show up as hex with a display table like
4534 #s(range-table data ((256 524288) (format "%x")))
4536 Since more than one display table is possible, you have
4537 great flexibility in mapping ranges of characters. */
4538 Emchar printable_min = b ? (CHAR_OR_CHAR_INTP (b->ctl_arrow)
4539 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
4540 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
4541 ? 255 : 160)) : 255;
4543 Lisp_Object face_dt, window_dt;
4545 /* The text display block for this display line. */
4546 struct display_block *db = get_display_block_from_line (dl, TEXT);
4548 /* The first time through the main loop we need to force the glyph
4549 data to be updated. */
4552 /* Apparently the new extent_fragment_update returns an end position
4553 equal to the position passed in if there are no more runs to be
4555 int no_more_frags = 0;
4557 dl->used_prop_data = 0;
4559 dl->line_continuation = 0;
4561 /* set up faces to use for clearing areas, used by
4562 output_display_line */
4563 dl->default_findex = default_face;
4566 dl->left_margin_findex = default_face;
4567 dl->right_margin_findex = default_face;
4571 dl->left_margin_findex =
4572 get_builtin_face_cache_index (w, Vleft_margin_face);
4573 dl->right_margin_findex =
4574 get_builtin_face_cache_index (w, Vright_margin_face);
4578 data.ef = extent_fragment_new (disp_string, f);
4580 /* These values are used by all of the rune addition routines. We add
4581 them to this structure for ease of passing. */
4583 XSETWINDOW (data.window, w);
4587 data.bi_bufpos = bi_start_pos;
4588 data.pixpos = dl->bounds.left_in;
4589 data.last_charset = Qunbound;
4590 data.last_findex = default_face;
4591 data.result_str = Qnil;
4592 data.string = disp_string;
4594 /* Set the right boundary adjusting it to take into account any end
4595 glyph. Save the width of the end glyph for later use. */
4596 data.max_pixpos = dl->bounds.right_in;
4597 data.max_pixpos -= data.end_glyph_width;
4599 data.cursor_type = NO_CURSOR;
4603 /* I don't think we want this, string areas should not scroll with
4605 data.start_col = w->hscroll;
4606 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
4608 data.bi_start_col_enabled = 0;
4609 data.hscroll_glyph_width_adjust = 0;
4611 /* We regenerate the line from the very beginning. */
4612 Dynarr_reset (db->runes);
4614 /* Why is this less than or equal and not just less than? If the
4615 starting position is already equal to the maximum we can't add
4616 anything else, right? Wrong. We might still have a newline to
4617 add. A newline can use the room allocated for an end glyph since
4618 if we add it we know we aren't going to be adding any end
4621 /* #### Chuck -- I think this condition should be while (1).
4622 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
4623 and the begin-glyph ends exactly at the end of the window, the
4624 end-glyph and text might not be displayed. while (1) ensures
4625 that the loop terminates only when either (a) there is
4626 propagation data or (b) the end-of-line or end-of-buffer is hit.
4628 #### Also I think you need to ensure that the operation
4629 "add begin glyphs; add end glyphs; add text" is atomic and
4630 can't get interrupted in the middle. If you run off the end
4631 of the line during that operation, then you keep accumulating
4632 propagation data until you're done. Otherwise, if the (e.g.)
4633 there's a begin glyph at a particular position and attempting
4634 to display that glyph results in window-end being hit and
4635 propagation data being generated, then the character at that
4636 position won't be displayed.
4638 #### See also the comment after the end of this loop, below.
4640 while (data.pixpos <= data.max_pixpos)
4642 /* #### This check probably should not be necessary. */
4643 if (data.bi_bufpos > bi_string_zv)
4645 /* #### urk! More of this lossage! */
4650 /* Check for face changes. */
4651 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
4653 Lisp_Object last_glyph = Qnil;
4654 /* Deal with clipped glyphs that we have already displayed. */
4655 if (*prop && Dynarr_atp (*prop, 0)->type == PROP_GLYPH)
4657 last_glyph = Dynarr_atp (*prop, 0)->data.p_glyph.glyph;
4658 Dynarr_free (*prop);
4661 /* Now compute the face and begin/end-glyph information. */
4663 /* Remember that the extent-fragment routines deal in Bytind's. */
4664 extent_fragment_update (w, data.ef, data.bi_bufpos, last_glyph);
4665 /* This is somewhat cheesy but the alternative is to
4666 propagate default_face into extent_fragment_update. */
4667 if (data.findex == DEFAULT_INDEX)
4668 data.findex = default_face;
4670 get_display_tables (w, data.findex, &face_dt, &window_dt);
4672 if (data.bi_bufpos == data.ef->end)
4677 /* Determine what is next to be displayed. We first handle any
4678 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
4679 display then we determine what to do based on the character at the
4680 current buffer position. */
4682 /* If the current position is covered by an invisible extent, do
4683 nothing (except maybe add some ellipses).
4685 #### The behavior of begin and end-glyphs at the edge of an
4686 invisible extent should be investigated further. This is
4687 fairly low priority though. */
4688 if (data.ef->invisible)
4690 /* #### Chuck, perhaps you could look at this code? I don't
4691 really know what I'm doing. */
4694 Dynarr_free (*prop);
4698 /* The extent fragment code only sets this when we should
4699 really display the ellipses. It makes sure the ellipses
4700 don't get displayed more than once in a row. */
4701 if (data.ef->invisible_ellipses)
4703 struct glyph_block gb;
4705 data.ef->invisible_ellipses_already_displayed = 1;
4706 data.ef->invisible_ellipses = 0;
4708 gb.glyph = Vinvisible_text_glyph;
4709 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
4710 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
4711 /* Perhaps they shouldn't propagate if the very next thing
4712 is to display a newline (for compatibility with
4713 selective-display-ellipses)? Maybe that's too
4719 /* #### What if we're dealing with a display table? */
4723 if (data.bi_bufpos == bi_string_zv)
4726 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4729 /* If there is propagation data, then it represents the current
4730 buffer position being displayed. Add them and advance the
4731 position counter. This might also add the minibuffer
4735 dl->used_prop_data = 1;
4736 *prop = add_propagation_runes (prop, &data);
4739 goto done; /* gee, a really narrow window */
4740 else if (data.bi_bufpos == bi_string_zv)
4742 else if (data.bi_bufpos < 0)
4743 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
4746 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4749 /* If there are end glyphs, add them to the line. These are
4750 the end glyphs for the previous run of text. We add them
4751 here rather than doing them at the end of handling the
4752 previous run so that glyphs at the beginning and end of
4753 a line are handled correctly. */
4754 else if (Dynarr_length (data.ef->end_glyphs) > 0)
4756 data.ch = string_char (s, data.bi_bufpos);
4757 *prop = add_glyph_runes (&data, END_GLYPHS);
4764 /* If there are begin glyphs, add them to the line. */
4765 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
4767 data.ch = string_char (s, data.bi_bufpos);
4768 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
4775 /* If at end-of-buffer, we've already processed begin and
4776 end-glyphs at this point and there's no text to process,
4778 else if (data.bi_bufpos == bi_string_zv)
4783 Lisp_Object entry = Qnil;
4784 /* Get the character at the current buffer position. */
4785 data.ch = string_char (s, data.bi_bufpos);
4786 if (!NILP (face_dt) || !NILP (window_dt))
4787 entry = display_table_entry (data.ch, face_dt, window_dt);
4789 /* If there is a display table entry for it, hand it off to
4790 add_disp_table_entry_runes and let it worry about it. */
4791 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
4793 *prop = add_disp_table_entry_runes (&data, entry);
4799 /* Check if we have hit a newline character. If so, add a marker
4800 to the line and end this loop. */
4801 else if (data.ch == '\n')
4803 /* We aren't going to be adding an end glyph so give its
4804 space back in order to make sure that the cursor can
4806 data.max_pixpos += data.end_glyph_width;
4810 /* If the current character is considered to be printable, then
4812 else if (data.ch >= printable_min)
4814 *prop = add_emchar_rune (&data);
4819 /* If the current character is a tab, determine the next tab
4820 starting position and add a blank rune which extends from the
4821 current pixel position to that starting position. */
4822 else if (data.ch == '\t')
4824 int tab_start_pixpos = data.pixpos;
4829 if (data.start_col > 1)
4830 tab_start_pixpos -= (space_width (w) * (data.start_col - 1));
4833 next_tab_position (w, tab_start_pixpos,
4834 dl->bounds.left_in +
4835 data.hscroll_glyph_width_adjust);
4836 if (next_tab_start > data.max_pixpos)
4838 prop_width = next_tab_start - data.max_pixpos;
4839 next_tab_start = data.max_pixpos;
4841 data.blank_width = next_tab_start - data.pixpos;
4843 (next_tab_start - tab_start_pixpos) / space_width (w);
4845 *prop = add_blank_rune (&data, w, char_tab_width);
4847 /* add_blank_rune is only supposed to be called with
4848 sizes guaranteed to fit in the available space. */
4853 struct prop_block pb;
4854 *prop = Dynarr_new (prop_block);
4856 pb.type = PROP_BLANK;
4857 pb.data.p_blank.width = prop_width;
4858 pb.data.p_blank.findex = data.findex;
4859 Dynarr_add (*prop, pb);
4865 /* If character is a control character, pass it off to
4866 add_control_char_runes.
4868 The is_*() routines have undefined results on
4869 arguments outside of the range [-1, 255]. (This
4870 often bites people who carelessly use `char' instead
4871 of `unsigned char'.)
4873 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
4875 *prop = add_control_char_runes (&data, b);
4881 /* If the character is above the ASCII range and we have not
4882 already handled it, then print it as an octal number. */
4883 else if (data.ch >= 0200)
4885 *prop = add_octal_runes (&data);
4891 /* Assume the current character is considered to be printable,
4892 then just add it. */
4895 *prop = add_emchar_rune (&data);
4900 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4906 /* Determine the starting point of the next line if we did not hit the
4907 end of the buffer. */
4908 if (data.bi_bufpos < bi_string_zv)
4910 /* #### This check is not correct. If the line terminated
4911 due to a begin-glyph or end-glyph hitting window-end, then
4912 data.ch will not point to the character at data.bi_bufpos. If
4913 you make the two changes mentioned at the top of this loop,
4914 you should be able to say '(if (*prop))'. That should also
4915 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
4918 /* The common case is that the line ended because we hit a newline.
4919 In that case, the next character is just the next buffer
4921 if (data.ch == '\n')
4923 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4926 /* Otherwise we have a buffer line which cannot fit on one display
4930 struct glyph_block gb;
4931 struct glyph_cachel *cachel;
4933 /* If the line is to be truncated then we actually have to look
4934 for the next newline. We also add the end-of-line glyph which
4935 we know will fit because we adjusted the right border before
4936 we starting laying out the line. */
4937 data.max_pixpos += data.end_glyph_width;
4938 data.findex = default_face;
4945 /* Now find the start of the next line. */
4946 bi_pos = bi_find_next_emchar_in_string (s, '\n', data.bi_bufpos, 1);
4948 data.cursor_type = NO_CURSOR;
4949 data.bi_bufpos = bi_pos;
4950 gb.glyph = Vtruncation_glyph;
4951 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
4955 /* The cursor can never be on the continuation glyph. */
4956 data.cursor_type = NO_CURSOR;
4958 /* data.bi_bufpos is already at the start of the next line. */
4960 dl->line_continuation = 1;
4961 gb.glyph = Vcontinuation_glyph;
4962 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
4965 if (data.end_glyph_width)
4966 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
4968 if (truncate_win && data.bi_bufpos == bi_string_zv)
4970 const Bufbyte* endb = charptr_n_addr (string_data (s), bi_string_zv);
4972 if (charptr_emchar (endb) != '\n')
4974 /* #### Damn this losing shit. */
4980 else if (data.bi_bufpos == bi_string_zv)
4982 /* create_text_block () adds a bogus \n marker here which screws
4983 up subwindow display. Since we never have a cursor in the
4984 gutter we can safely ignore it. */
4986 /* Calculate left whitespace boundary. */
4990 /* Whitespace past a newline is considered right whitespace. */
4991 while (elt < Dynarr_length (db->runes))
4993 struct rune *rb = Dynarr_atp (db->runes, elt);
4995 if ((rb->type == RUNE_CHAR && rb->object.chr.ch == ' ')
4996 || rb->type == RUNE_BLANK)
4998 dl->bounds.left_white += rb->width;
5002 elt = Dynarr_length (db->runes);
5006 /* Calculate right whitespace boundary. */
5008 int elt = Dynarr_length (db->runes) - 1;
5011 while (!done && elt >= 0)
5013 struct rune *rb = Dynarr_atp (db->runes, elt);
5015 if (!(rb->type == RUNE_CHAR && rb->object.chr.ch < 0x100
5016 && isspace (rb->object.chr.ch))
5017 && !rb->type == RUNE_BLANK)
5019 dl->bounds.right_white = rb->xpos + rb->width;
5027 /* The line is blank so everything is considered to be right
5030 dl->bounds.right_white = dl->bounds.left_in;
5033 /* Set the display blocks bounds. */
5034 db->start_pos = dl->bounds.left_in;
5035 if (Dynarr_length (db->runes))
5037 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
5039 db->end_pos = rb->xpos + rb->width;
5042 db->end_pos = dl->bounds.right_white;
5044 calculate_baseline (&data);
5046 dl->ascent = data.new_ascent;
5047 dl->descent = data.new_descent;
5050 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
5052 if (dl->ascent < ascent)
5053 dl->ascent = ascent;
5056 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
5058 if (dl->descent < descent)
5059 dl->descent = descent;
5062 calculate_yoffset (dl, db);
5064 dl->cursor_elt = data.cursor_x;
5065 /* #### lossage lossage lossage! Fix this shit! */
5066 if (data.bi_bufpos > bi_string_zv)
5067 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, bi_string_zv);
5069 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, data.bi_bufpos) - 1;
5071 data.dl->num_chars =
5072 string_column_at_point (s, dl->end_bufpos, b ? XINT (b->tab_width) : 8);
5074 /* This doesn't correctly take into account tabs and control
5075 characters but if the window isn't being truncated then this
5076 value isn't going to end up being used anyhow. */
5077 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
5079 /* #### handle horizontally scrolled line with text none of which
5080 was actually laid out. */
5082 /* #### handle any remainder of overlay arrow */
5084 if (*prop == ADD_FAILED)
5087 if (truncate_win && *prop)
5089 Dynarr_free (*prop);
5093 extent_fragment_delete (data.ef);
5095 /* #### If we started at EOB, then make sure we return a value past
5096 it so that regenerate_window will exit properly. This is bogus.
5097 The main loop should get fixed so that it isn't necessary to call
5098 this function if we are already at EOB. */
5100 if (data.bi_bufpos == bi_string_zv && bi_start_pos == bi_string_zv)
5101 return bytecount_to_charcount (string_data (s), data.bi_bufpos) + 1; /* Yuck! */
5103 return bytecount_to_charcount (string_data (s), data.bi_bufpos);
5106 /* Given a display line and a starting position, ensure that the
5107 contents of the display line accurately represent the visual
5108 representation of the buffer contents starting from the given
5109 position when displayed in the given window. The display line ends
5110 when the contents of the line reach the right boundary of the given
5113 This is very similar to generate_display_line but with the same
5114 limitations as create_string_text_block. I have taken the liberty
5115 of fixing the bytind stuff though.*/
5118 generate_string_display_line (struct window *w, Lisp_Object disp_string,
5119 struct display_line *dl,
5121 prop_block_dynarr **prop,
5122 face_index default_face)
5126 /* you must set bounds before calling this. */
5128 /* Reset what this line is using. */
5129 if (dl->display_blocks)
5130 Dynarr_reset (dl->display_blocks);
5131 if (dl->left_glyphs)
5133 Dynarr_free (dl->left_glyphs);
5134 dl->left_glyphs = 0;
5136 if (dl->right_glyphs)
5138 Dynarr_free (dl->right_glyphs);
5139 dl->right_glyphs = 0;
5142 /* We aren't generating a modeline at the moment. */
5145 /* Create a display block for the text region of the line. */
5146 ret_bufpos = create_string_text_block (w, disp_string, dl, start_pos,
5147 prop, default_face);
5148 dl->bufpos = start_pos;
5149 if (dl->end_bufpos < dl->bufpos)
5150 dl->end_bufpos = dl->bufpos;
5152 /* If there are left glyphs associated with any character in the
5153 text block, then create a display block to handle them. */
5154 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
5155 create_left_glyph_block (w, dl, 0);
5157 /* If there are right glyphs associated with any character in the
5158 text block, then create a display block to handle them. */
5159 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
5160 create_right_glyph_block (w, dl);
5165 /* This is ripped off from regenerate_window. All we want to do is
5166 loop through elements in the string creating display lines until we
5167 have covered the provided area. Simple really. */
5169 generate_displayable_area (struct window *w, Lisp_Object disp_string,
5170 int xpos, int ypos, int width, int height,
5171 display_line_dynarr* dla,
5173 face_index default_face)
5175 int yend = ypos + height;
5178 prop_block_dynarr *prop = 0;
5179 layout_bounds bounds;
5183 /* if there's nothing to do then do nothing. code after this assumes
5184 there is something to do. */
5185 if (NILP (disp_string))
5188 s_zv = XSTRING_CHAR_LENGTH (disp_string);
5190 bounds.left_out = xpos;
5191 bounds.right_out = xpos + width;
5192 /* The inner boundaries mark where the glyph margins are located. */
5193 bounds.left_in = bounds.left_out + window_left_margin_width (w);
5194 bounds.right_in = bounds.right_out - window_right_margin_width (w);
5195 /* We cannot fully calculate the whitespace boundaries as they
5196 depend on the contents of the line being displayed. */
5197 bounds.left_white = bounds.left_in;
5198 bounds.right_white = bounds.right_in;
5202 struct display_line dl;
5203 struct display_line *dlp;
5207 if (Dynarr_length (dla) < Dynarr_largest (dla))
5209 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5220 dlp->bounds = bounds;
5222 next_pos = generate_string_display_line (w, disp_string, dlp, start_pos,
5223 &prop, default_face);
5224 /* we need to make sure that we continue along the line if there
5225 is more left to display otherwise we just end up redisplaying
5226 the same chunk over and over again. */
5227 if (next_pos == start_pos && next_pos < s_zv)
5230 start_pos = next_pos;
5232 dlp->ypos = ypos + dlp->ascent;
5233 ypos = dlp->ypos + dlp->descent;
5237 int visible_height = dlp->ascent + dlp->descent;
5239 dlp->clip = (ypos - yend);
5240 visible_height -= dlp->clip;
5242 if (visible_height < VERTICAL_CLIP (w, 1))
5245 free_display_line (dlp);
5252 Dynarr_add (dla, *dlp);
5254 /* #### This type of check needs to be done down in the
5255 generate_display_line call. */
5256 if (start_pos >= s_zv)
5265 /***************************************************************************/
5267 /* window-regeneration routines */
5269 /***************************************************************************/
5271 /* For a given window and starting position in the buffer it contains,
5272 ensure that the TYPE display lines accurately represent the
5273 presentation of the window. We pass the buffer instead of getting
5274 it from the window since redisplay_window may have temporarily
5275 changed it to the echo area buffer. */
5278 regenerate_window (struct window *w, Bufpos start_pos, Bufpos point, int type)
5280 struct frame *f = XFRAME (w->frame);
5281 struct buffer *b = XBUFFER (w->buffer);
5282 int ypos = WINDOW_TEXT_TOP (w);
5283 int yend; /* set farther down */
5284 int yclip = WINDOW_TEXT_TOP_CLIP (w);
5287 prop_block_dynarr *prop;
5288 layout_bounds bounds;
5289 display_line_dynarr *dla;
5292 /* The lines had better exist by this point. */
5293 if (!(dla = window_display_lines (w, type)))
5296 w->max_line_len = 0;
5298 /* Normally these get updated in redisplay_window but it is possible
5299 for this function to get called from some other points where that
5300 update may not have occurred. This acts as a safety check. */
5301 if (!Dynarr_length (w->face_cachels))
5302 reset_face_cachels (w);
5303 if (!Dynarr_length (w->glyph_cachels))
5304 reset_glyph_cachels (w);
5306 Fset_marker (w->start[type], make_int (start_pos), w->buffer);
5307 Fset_marker (w->pointm[type], make_int (point), w->buffer);
5308 w->last_point_x[type] = -1;
5309 w->last_point_y[type] = -1;
5311 /* Make sure a modeline is in the structs if needed. */
5312 need_modeline = ensure_modeline_generated (w, type);
5314 /* Wait until here to set this so that the structs have a modeline
5315 generated in the case where one didn't exist. */
5316 yend = WINDOW_TEXT_BOTTOM (w);
5318 bounds = calculate_display_line_boundaries (w, 0);
5320 /* 97/3/14 jhod: stuff added here to support pre-prompts (used for input systems) */
5321 if (MINI_WINDOW_P (w)
5322 && (!NILP (Vminibuf_prompt) || !NILP (Vminibuf_preprompt))
5323 && !echo_area_active (f)
5324 && start_pos == BUF_BEGV (b))
5326 struct prop_block pb;
5328 prop = Dynarr_new (prop_block);
5330 string = concat2(Vminibuf_preprompt, Vminibuf_prompt);
5331 pb.type = PROP_MINIBUF_PROMPT;
5332 pb.data.p_string.str = XSTRING_DATA(string);
5333 pb.data.p_string.len = XSTRING_LENGTH(string);
5334 Dynarr_add (prop, pb);
5339 /* When we are computing things for scrolling purposes, make
5340 sure at least one line is always generated */
5341 force = (type == CMOTION_DISP);
5343 /* Make sure this is set always */
5344 /* Note the conversion at end */
5345 w->window_end_pos[type] = start_pos;
5346 while (ypos < yend || force)
5348 struct display_line dl;
5349 struct display_line *dlp;
5352 if (Dynarr_length (dla) < Dynarr_largest (dla))
5354 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5365 dlp->bounds = bounds;
5367 start_pos = generate_display_line (w, dlp, 1, start_pos, &prop, type);
5369 if (yclip > dlp->ascent)
5371 /* this should never happen, but if it does just display the
5376 dlp->ypos = (ypos + dlp->ascent) - yclip;
5377 ypos = dlp->ypos + dlp->descent;
5379 /* See if we've been asked to start midway through a line, for
5380 partial display line scrolling. */
5383 dlp->top_clip = yclip;
5391 int visible_height = dlp->ascent + dlp->descent;
5393 dlp->clip = (ypos - yend);
5394 /* Although this seems strange we could have a single very
5395 tall line visible for which we need to account for both
5396 the top clip and the bottom clip. */
5397 visible_height -= (dlp->clip + dlp->top_clip);
5399 if (visible_height < VERTICAL_CLIP (w, 1) && !force)
5402 free_display_line (dlp);
5409 if (dlp->cursor_elt != -1)
5411 /* #### This check is steaming crap. Have to get things
5412 fixed so when create_text_block hits EOB, we're done,
5414 if (w->last_point_x[type] == -1)
5416 w->last_point_x[type] = dlp->cursor_elt;
5417 w->last_point_y[type] = Dynarr_length (dla);
5421 /* #### This means that we've added a cursor at EOB
5422 twice. Yuck oh yuck. */
5423 struct display_block *db =
5424 get_display_block_from_line (dlp, TEXT);
5426 Dynarr_atp (db->runes, dlp->cursor_elt)->cursor_type = NO_CURSOR;
5427 dlp->cursor_elt = -1;
5431 if (dlp->num_chars > w->max_line_len)
5432 w->max_line_len = dlp->num_chars;
5434 Dynarr_add (dla, *dlp);
5436 /* #### This isn't right, but it is close enough for now. */
5437 w->window_end_pos[type] = start_pos;
5439 /* #### This type of check needs to be done down in the
5440 generate_display_line call. */
5441 if (start_pos > BUF_ZV (b))
5450 /* #### More not quite right, but close enough. */
5451 /* Ben sez: apparently window_end_pos[] is measured
5452 as the number of characters between the window end and the
5453 end of the buffer? This seems rather weirdo. What's
5454 the justification for this?
5456 JV sez: Because BUF_Z (b) would be a good initial value, however
5457 that can change. This representation allows initalizing with 0.
5459 w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type];
5463 /* We know that this is the right thing to use because we put it
5464 there when we first started working in this function. */
5465 generate_modeline (w, Dynarr_atp (dla, 0), type);
5469 #define REGEN_INC_FIND_START_END \
5471 /* Determine start and end of lines. */ \
5472 if (!Dynarr_length (cdla)) \
5476 if (Dynarr_atp (cdla, 0)->modeline && Dynarr_atp (ddla, 0)->modeline) \
5480 else if (!Dynarr_atp (cdla, 0)->modeline \
5481 && !Dynarr_atp (ddla, 0)->modeline) \
5486 abort (); /* structs differ */ \
5488 dla_end = Dynarr_length (cdla) - 1; \
5491 start_pos = (Dynarr_atp (cdla, dla_start)->bufpos \
5492 + Dynarr_atp (cdla, dla_start)->offset); \
5493 /* If this isn't true, then startp has changed and we need to do a \
5495 if (startp != start_pos) \
5498 /* Point is outside the visible region so give up. */ \
5499 if (pointm < start_pos) \
5504 /* This attempts to incrementally update the display structures. It
5505 returns a boolean indicating success or failure. This function is
5506 very similar to regenerate_window_incrementally and is in fact only
5507 called from that function. However, because of the nature of the
5508 changes it deals with it sometimes makes different assumptions
5509 which can lead to success which are much more difficult to make
5510 when dealing with buffer changes. */
5513 regenerate_window_extents_only_changed (struct window *w, Bufpos startp,
5515 Charcount beg_unchanged,
5516 Charcount end_unchanged)
5518 struct buffer *b = XBUFFER (w->buffer);
5519 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5520 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5524 int first_line, last_line;
5526 /* Don't define this in the loop where it is used because we
5527 definitely want its value to survive between passes. */
5528 prop_block_dynarr *prop = NULL;
5530 /* If we don't have any buffer change recorded but the modiff flag has
5531 been incremented, then fail. I'm not sure of the exact circumstances
5532 under which this can happen, but I believe that it is probably a
5533 reasonable happening. */
5534 if (!point_visible (w, pointm, CURRENT_DISP)
5535 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b))
5538 /* If the cursor is moved we attempt to update it. If we succeed we
5539 go ahead and proceed with the optimization attempt. */
5540 if (!EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5541 || pointm != marker_position (w->last_point[CURRENT_DISP]))
5543 struct frame *f = XFRAME (w->frame);
5544 struct device *d = XDEVICE (f->device);
5545 struct frame *sel_f = device_selected_frame (d);
5548 if (w->last_point_x[CURRENT_DISP] != -1
5549 && w->last_point_y[CURRENT_DISP] != -1)
5552 if (redisplay_move_cursor (w, pointm, WINDOW_TTY_P (w)))
5554 /* Always regenerate the modeline in case it is
5555 displaying the current line or column. */
5556 regenerate_modeline (w);
5560 else if (w != XWINDOW (FRAME_SELECTED_WINDOW (sel_f)))
5562 if (f->modeline_changed)
5563 regenerate_modeline (w);
5571 if (beg_unchanged == -1 && end_unchanged == -1)
5574 /* assert: There are no buffer modifications or they are all below the
5575 visible region. We assume that regenerate_window_incrementally has
5576 not called us unless this is true. */
5578 REGEN_INC_FIND_START_END;
5580 /* If the changed are starts before the visible area, give up. */
5581 if (beg_unchanged < startp)
5584 /* Find what display line the extent changes first affect. */
5586 while (line <= dla_end)
5588 struct display_line *dl = Dynarr_atp (cdla, line);
5589 Bufpos lstart = dl->bufpos + dl->offset;
5590 Bufpos lend = dl->end_bufpos + dl->offset;
5592 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5598 /* If the changes are below the visible area then if point hasn't
5599 moved return success otherwise fail in order to be safe. */
5602 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5603 && pointm == marker_position (w->last_point[CURRENT_DISP]))
5609 /* At this point we know what line the changes first affect. We now
5610 begin redrawing lines as long as we are still in the affected
5611 region and the line's size and positioning don't change.
5612 Otherwise we fail. If we fail we will have altered the desired
5613 structs which could lead to an assertion failure. However, if we
5614 fail the next thing that is going to happen is a full regen so we
5615 will actually end up being safe. */
5616 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5617 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5618 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
5619 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
5621 first_line = last_line = line;
5622 while (line <= dla_end)
5624 Bufpos old_start, old_end, new_start;
5625 struct display_line *cdl = Dynarr_atp (cdla, line);
5626 struct display_line *ddl = Dynarr_atp (ddla, line);
5627 struct display_block *db;
5630 assert (cdl->bufpos == ddl->bufpos);
5631 assert (cdl->end_bufpos == ddl->end_bufpos);
5632 assert (cdl->offset == ddl->offset);
5634 db = get_display_block_from_line (ddl, TEXT);
5635 initial_size = Dynarr_length (db->runes);
5636 old_start = ddl->bufpos + ddl->offset;
5637 old_end = ddl->end_bufpos + ddl->offset;
5639 /* If this is the first line being updated and it used
5640 propagation data, fail. Otherwise we'll be okay because
5641 we'll have the necessary propagation data. */
5642 if (line == first_line && ddl->used_prop_data)
5645 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5646 &prop, DESIRED_DISP);
5649 /* #### If there is propagated stuff the fail. We could
5650 probably actually deal with this if the line had propagated
5651 information when originally created by a full
5659 /* If any line position parameters have changed or a
5660 cursor has disappeared or disappeared, fail. */
5661 db = get_display_block_from_line (ddl, TEXT);
5662 if (cdl->ypos != ddl->ypos
5663 || cdl->ascent != ddl->ascent
5664 || cdl->descent != ddl->descent
5665 || cdl->top_clip != ddl->top_clip
5666 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5667 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1)
5668 || old_start != ddl->bufpos
5669 || old_end != ddl->end_bufpos
5670 || initial_size != Dynarr_length (db->runes))
5675 if (ddl->cursor_elt != -1)
5677 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5678 w->last_point_y[DESIRED_DISP] = line;
5683 /* If the extent changes end on the line we just updated then
5684 we're done. Otherwise go on to the next line. */
5685 if (end_unchanged <= ddl->end_bufpos)
5691 redisplay_update_line (w, first_line, last_line, 1);
5695 /* Attempt to update the display data structures based on knowledge of
5696 the changed region in the buffer. Returns a boolean indicating
5697 success or failure. If this function returns a failure then a
5698 regenerate_window _must_ be performed next in order to maintain
5699 invariants located here. */
5702 regenerate_window_incrementally (struct window *w, Bufpos startp,
5705 struct buffer *b = XBUFFER (w->buffer);
5706 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5707 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5708 Charcount beg_unchanged, end_unchanged;
5709 Charcount extent_beg_unchanged, extent_end_unchanged;
5715 /* If this function is called, the current and desired structures
5716 had better be identical. If they are not, then that is a bug. */
5717 assert (Dynarr_length (cdla) == Dynarr_length (ddla));
5719 /* We don't handle minibuffer windows yet. The minibuffer prompt
5721 if (MINI_WINDOW_P (w))
5724 extent_beg_unchanged = BUF_EXTENT_BEGIN_UNCHANGED (b);
5725 extent_end_unchanged = (BUF_EXTENT_END_UNCHANGED (b) == -1
5727 : BUF_Z (b) - BUF_EXTENT_END_UNCHANGED (b));
5729 /* If nothing has changed in the buffer, then make sure point is ok
5731 if (BUF_BEGIN_UNCHANGED (b) == -1 && BUF_END_UNCHANGED (b) == -1)
5732 return regenerate_window_extents_only_changed (w, startp, pointm,
5733 extent_beg_unchanged,
5734 extent_end_unchanged);
5736 /* We can't deal with deleted newlines. */
5737 if (BUF_NEWLINE_WAS_DELETED (b))
5740 beg_unchanged = BUF_BEGIN_UNCHANGED (b);
5741 end_unchanged = (BUF_END_UNCHANGED (b) == -1
5743 : BUF_Z (b) - BUF_END_UNCHANGED (b));
5745 REGEN_INC_FIND_START_END;
5747 /* If the changed area starts before the visible area, give up. */
5748 if (beg_unchanged < startp)
5751 /* Find what display line the buffer changes first affect. */
5753 while (line <= dla_end)
5755 struct display_line *dl = Dynarr_atp (cdla, line);
5756 Bufpos lstart = dl->bufpos + dl->offset;
5757 Bufpos lend = dl->end_bufpos + dl->offset;
5759 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5765 /* If the changes are below the visible area then if point hasn't
5766 moved return success otherwise fail in order to be safe. */
5768 return regenerate_window_extents_only_changed (w, startp, pointm,
5769 extent_beg_unchanged,
5770 extent_end_unchanged);
5772 /* At this point we know what line the changes first affect. We
5773 now redraw that line. If the changes are contained within it
5774 we are going to succeed and can update just that one line.
5775 Otherwise we fail. If we fail we will have altered the desired
5776 structs which could lead to an assertion failure. However, if
5777 we fail the next thing that is going to happen is a full regen
5778 so we will actually end up being safe. */
5781 prop_block_dynarr *prop = NULL;
5782 struct display_line *cdl = Dynarr_atp (cdla, line);
5783 struct display_line *ddl = Dynarr_atp (ddla, line);
5785 assert (cdl->bufpos == ddl->bufpos);
5786 assert (cdl->end_bufpos == ddl->end_bufpos);
5787 assert (cdl->offset == ddl->offset);
5789 /* If the line continues to next display line, fail. */
5790 if (ddl->line_continuation)
5793 /* If the line was generated using propagation data, fail. */
5794 if (ddl->used_prop_data)
5797 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5798 &prop, DESIRED_DISP);
5801 /* If there is propagated stuff then it is pretty much a
5802 guarantee that more than just the one line is affected. */
5809 /* If the line continues to next display line, fail. */
5810 if (ddl->line_continuation)
5813 /* If any line position parameters have changed or a
5814 cursor has disappeared or disappeared, fail. */
5815 if (cdl->ypos != ddl->ypos
5816 || cdl->ascent != ddl->ascent
5817 || cdl->descent != ddl->descent
5818 || cdl->top_clip != ddl->top_clip
5819 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5820 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1))
5825 /* If the changed area also ends on this line, then we may be in
5826 business. Update everything and return success. */
5827 if (end_unchanged >= ddl->bufpos && end_unchanged <= ddl->end_bufpos)
5829 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5830 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5831 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp),
5833 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm),
5836 if (ddl->cursor_elt != -1)
5838 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5839 w->last_point_y[DESIRED_DISP] = line;
5842 redisplay_update_line (w, line, line, 1);
5843 regenerate_modeline (w);
5845 /* #### For now we just flush the cache until this has been
5846 tested. After that is done, this should correct the
5848 Dynarr_reset (w->line_start_cache);
5850 /* Adjust the extent changed boundaries to remove any
5851 overlap with the buffer changes since we've just
5852 successfully updated that area. */
5853 if (extent_beg_unchanged != -1
5854 && extent_beg_unchanged >= beg_unchanged
5855 && extent_beg_unchanged < end_unchanged)
5856 extent_beg_unchanged = end_unchanged;
5858 if (extent_end_unchanged != -1
5859 && extent_end_unchanged >= beg_unchanged
5860 && extent_end_unchanged < end_unchanged)
5861 extent_end_unchanged = beg_unchanged - 1;
5863 if (extent_end_unchanged <= extent_beg_unchanged)
5864 extent_beg_unchanged = extent_end_unchanged = -1;
5866 /* This could lead to odd results if it fails, but since the
5867 buffer changes update succeeded this probably will to.
5868 We already know that the extent changes start at or after
5869 the line because we checked before entering the loop. */
5870 if (extent_beg_unchanged != -1
5871 && extent_end_unchanged != -1
5872 && ((extent_beg_unchanged < ddl->bufpos)
5873 || (extent_end_unchanged > ddl->end_bufpos)))
5874 return regenerate_window_extents_only_changed (w, startp, pointm,
5875 extent_beg_unchanged,
5876 extent_end_unchanged);
5886 /* Given a window and a point, update the given display lines such
5887 that point is displayed in the middle of the window.
5888 Return the window's new start position. */
5891 regenerate_window_point_center (struct window *w, Bufpos point, int type)
5895 /* We need to make sure that the modeline is generated so that the
5896 window height can be calculated correctly. */
5897 ensure_modeline_generated (w, type);
5899 startp = start_with_line_at_pixpos (w, point, window_half_pixpos (w));
5900 regenerate_window (w, startp, point, type);
5901 Fset_marker (w->start[type], make_int (startp), w->buffer);
5906 /* Given a window and a set of display lines, return a boolean
5907 indicating whether the given point is contained within. */
5910 point_visible (struct window *w, Bufpos point, int type)
5912 struct buffer *b = XBUFFER (w->buffer);
5913 display_line_dynarr *dla = window_display_lines (w, type);
5916 if (Dynarr_length (dla) && Dynarr_atp (dla, 0)->modeline)
5921 if (Dynarr_length (dla) > first_line)
5924 struct display_line *dl = Dynarr_atp (dla, first_line);
5927 end = BUF_Z (b) - w->window_end_pos[type] - 1;
5929 if (point >= start && point <= end)
5931 if (!MINI_WINDOW_P (w) && scroll_on_clipped_lines)
5933 dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
5935 if (point >= (dl->bufpos + dl->offset)
5936 && point <= (dl->end_bufpos + dl->offset))
5951 /* Return pixel position the middle of the window, not including the
5952 modeline and any potential horizontal scrollbar. */
5955 window_half_pixpos (struct window *w)
5957 return WINDOW_TEXT_TOP (w) + (WINDOW_TEXT_HEIGHT (w) >> 1);
5960 /* Return the display line which is currently in the middle of the
5961 window W for display lines TYPE. */
5964 line_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5966 display_line_dynarr *dla;
5969 int first_elt = (MINI_WINDOW_P (w) ? 0 : 1);
5971 if (type == CMOTION_DISP)
5972 regenerate_window (w, start, point, type);
5974 dla = window_display_lines (w, type);
5975 half = window_half_pixpos (w);
5977 for (elt = first_elt; elt < Dynarr_length (dla); elt++)
5979 struct display_line *dl = Dynarr_atp (dla, elt);
5980 int line_bot = dl->ypos + dl->descent;
5982 if (line_bot > half)
5986 /* We may not have a line at the middle if the end of the buffer is
5991 /* Return a value for point that would place it at the beginning of
5992 the line which is in the middle of the window. */
5995 point_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5997 /* line_at_center will regenerate the display structures, if necessary. */
5998 int line = line_at_center (w, type, start, point);
6001 return BUF_ZV (XBUFFER (w->buffer));
6004 display_line_dynarr *dla = window_display_lines (w, type);
6005 struct display_line *dl = Dynarr_atp (dla, line);
6011 /* For a given window, ensure that the current visual representation
6015 redisplay_window (Lisp_Object window, int skip_selected)
6017 struct window *w = XWINDOW (window);
6018 struct frame *f = XFRAME (w->frame);
6019 struct device *d = XDEVICE (f->device);
6020 Lisp_Object old_buffer = w->buffer;
6021 Lisp_Object the_buffer = w->buffer;
6023 int echo_active = 0;
6028 int selected_in_its_frame;
6029 int selected_globally;
6030 int skip_output = 0;
6031 int truncation_changed;
6032 int inactive_minibuffer =
6033 (MINI_WINDOW_P (w) &&
6034 (f != device_selected_frame (d)) &&
6035 !is_surrogate_for_selected_frame (f));
6037 /* #### In the new world this function actually does a bunch of
6038 optimizations such as buffer-based scrolling, but none of that is
6041 /* If this is a combination window, do its children; that's all.
6042 The selected window is always a leaf so we don't check for
6043 skip_selected here. */
6044 if (!NILP (w->vchild))
6046 redisplay_windows (w->vchild, skip_selected);
6049 if (!NILP (w->hchild))
6051 redisplay_windows (w->hchild, skip_selected);
6055 /* Is this window the selected window on its frame? */
6056 selected_in_its_frame = (w == XWINDOW (FRAME_SELECTED_WINDOW (f)));
6058 selected_in_its_frame &&
6059 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
6060 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d &&
6061 XFRAME(DEVICE_SELECTED_FRAME(d)) == f;
6062 if (skip_selected && selected_in_its_frame)
6065 /* It is possible that the window is not fully initialized yet. */
6066 if (NILP (w->buffer))
6069 if (MINI_WINDOW_P (w) && echo_area_active (f))
6071 w->buffer = the_buffer = Vecho_area_buffer;
6075 b = XBUFFER (w->buffer);
6079 old_pointm = selected_globally
6081 : marker_position (w->pointm[CURRENT_DISP]);
6086 if (selected_globally)
6088 pointm = BUF_PT (b);
6092 pointm = marker_position (w->pointm[CURRENT_DISP]);
6094 if (pointm < BUF_BEGV (b))
6095 pointm = BUF_BEGV (b);
6096 else if (pointm > BUF_ZV (b))
6097 pointm = BUF_ZV (b);
6100 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm), the_buffer);
6102 /* If the buffer has changed we have to invalidate all of our face
6104 if ((!echo_active && b != window_display_buffer (w))
6105 || !Dynarr_length (w->face_cachels)
6106 || f->faces_changed)
6107 reset_face_cachels (w);
6109 mark_face_cachels_as_not_updated (w);
6111 /* Ditto the glyph cache elements, although we do *not* invalidate
6112 the cache purely because glyphs have changed - this is now
6113 handled by the dirty flag.*/
6114 if ((!echo_active && b != window_display_buffer (w))
6115 || !Dynarr_length (w->glyph_cachels) || f->faces_changed)
6116 reset_glyph_cachels (w);
6118 mark_glyph_cachels_as_not_updated (w);
6120 /* If the marker's buffer is not the window's buffer, then we need
6121 to find a new starting position. */
6122 if (!MINI_WINDOW_P (w)
6123 && !EQ (Fmarker_buffer (w->start[CURRENT_DISP]), w->buffer))
6125 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6127 goto regeneration_done;
6132 old_startp = marker_position (w->start[CURRENT_DISP]);
6137 startp = marker_position (w->start[CURRENT_DISP]);
6138 if (startp < BUF_BEGV (b))
6139 startp = BUF_BEGV (b);
6140 else if (startp > BUF_ZV (b))
6141 startp = BUF_ZV (b);
6143 Fset_marker (w->start[DESIRED_DISP], make_int (startp), the_buffer);
6145 truncation_changed = (find_window_mirror (w)->truncate_win !=
6146 window_truncation_on (w));
6148 /* If w->force_start is set, then some function set w->start and we
6149 should display from there and change point, if necessary, to
6150 ensure that it is visible. */
6151 if (w->force_start || inactive_minibuffer)
6154 w->last_modified[DESIRED_DISP] = Qzero;
6155 w->last_facechange[DESIRED_DISP] = Qzero;
6157 regenerate_window (w, startp, pointm, DESIRED_DISP);
6159 if (!point_visible (w, pointm, DESIRED_DISP) && !inactive_minibuffer)
6161 pointm = point_at_center (w, DESIRED_DISP, 0, 0);
6163 if (selected_globally)
6164 BUF_SET_PT (b, pointm);
6166 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm),
6169 /* #### BUFU amounts of overkill just to get the cursor
6170 location marked properly. FIX ME FIX ME FIX ME */
6171 regenerate_window (w, startp, pointm, DESIRED_DISP);
6174 goto regeneration_done;
6177 /* If nothing has changed since the last redisplay, then we just
6178 need to make sure that point is still visible. */
6179 if (XINT (w->last_modified[CURRENT_DISP]) >= BUF_MODIFF (b)
6180 && XINT (w->last_facechange[CURRENT_DISP]) >= BUF_FACECHANGE (b)
6182 /* This check is to make sure we restore the minibuffer after a
6183 temporary change to the echo area. */
6184 && !(MINI_WINDOW_P (w) && f->buffers_changed)
6185 && !f->frame_changed
6186 && !truncation_changed
6187 /* check whether start is really at the beginning of a line GE */
6188 && (!w->start_at_line_beg || beginning_of_line_p (b, startp))
6191 /* Check if the cursor has actually moved. */
6192 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
6193 && pointm == marker_position (w->last_point[CURRENT_DISP])
6194 && selected_globally
6195 && !w->windows_changed
6197 && !f->extents_changed
6198 && !f->faces_changed
6199 && !f->glyphs_changed
6200 && !f->subwindows_changed
6201 /* && !f->subwindows_state_changed*/
6202 && !f->point_changed
6203 && !f->windows_structure_changed)
6205 /* If not, we're done. */
6206 if (f->modeline_changed)
6207 regenerate_modeline (w);
6210 goto regeneration_done;
6214 /* If the new point is visible in the redisplay structures,
6215 then let the output update routines handle it, otherwise
6216 do things the hard way. */
6217 if (!w->windows_changed
6219 && !f->extents_changed
6220 && !f->faces_changed
6221 && !f->glyphs_changed
6222 && !f->subwindows_changed
6223 /* && !f->subwindows_state_changed*/
6224 && !f->windows_structure_changed)
6226 if (point_visible (w, pointm, CURRENT_DISP)
6227 && w->last_point_x[CURRENT_DISP] != -1
6228 && w->last_point_y[CURRENT_DISP] != -1)
6230 if (redisplay_move_cursor (w, pointm, FRAME_TTY_P (f)))
6232 /* Always regenerate in case it is displaying
6233 the current line or column. */
6234 regenerate_modeline (w);
6237 goto regeneration_done;
6240 else if (!selected_in_its_frame && !f->point_changed)
6242 if (f->modeline_changed)
6243 regenerate_modeline (w);
6246 goto regeneration_done;
6250 /* If we weren't able to take the shortcut method, then use
6251 the brute force method. */
6252 regenerate_window (w, startp, pointm, DESIRED_DISP);
6254 if (point_visible (w, pointm, DESIRED_DISP))
6255 goto regeneration_done;
6259 /* Check if the starting point is no longer at the beginning of a
6260 line, in which case find a new starting point. We also recenter
6261 if our start position is equal to point-max. Otherwise we'll end
6262 up with a blank window. */
6263 else if (((w->start_at_line_beg || MINI_WINDOW_P (w))
6264 && !(startp == BUF_BEGV (b)
6265 || BUF_FETCH_CHAR (b, startp - 1) == '\n'))
6266 || (pointm == startp &&
6267 EQ (Fmarker_buffer (w->last_start[CURRENT_DISP]), w->buffer) &&
6268 startp < marker_position (w->last_start[CURRENT_DISP]))
6269 || (startp == BUF_ZV (b)))
6271 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6273 goto regeneration_done;
6275 /* See if we can update the data structures locally based on
6276 knowledge of what changed in the buffer. */
6277 else if (!w->windows_changed
6279 && !f->faces_changed
6280 && !f->glyphs_changed
6281 && !f->subwindows_changed
6282 /* && !f->subwindows_state_changed*/
6283 && !f->windows_structure_changed
6284 && !f->frame_changed
6285 && !truncation_changed
6287 && regenerate_window_incrementally (w, startp, pointm))
6289 if (f->modeline_changed
6290 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b)
6291 || XINT (w->last_facechange[CURRENT_DISP]) < BUF_FACECHANGE (b))
6292 regenerate_modeline (w);
6295 goto regeneration_done;
6297 /* #### This is where a check for structure based scrolling would go. */
6298 /* If all else fails, try just regenerating and see what happens. */
6301 regenerate_window (w, startp, pointm, DESIRED_DISP);
6303 if (point_visible (w, pointm, DESIRED_DISP))
6304 goto regeneration_done;
6307 /* We still haven't gotten the window regenerated with point
6308 visible. Next we try scrolling a little and see if point comes
6309 back onto the screen. */
6310 if (scroll_step > 0)
6312 int scrolled = scroll_conservatively;
6313 for (; scrolled >= 0; scrolled -= scroll_step)
6315 startp = vmotion (w, startp,
6316 (pointm < startp) ? -scroll_step : scroll_step, 0);
6317 regenerate_window (w, startp, pointm, DESIRED_DISP);
6319 if (point_visible (w, pointm, DESIRED_DISP))
6320 goto regeneration_done;
6324 /* We still haven't managed to get the screen drawn with point on
6325 the screen, so just center it and be done with it. */
6326 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6331 /* If the window's frame is changed then reset the current display
6332 lines in order to force a full repaint. */
6333 if (f->frame_changed)
6335 display_line_dynarr *cla = window_display_lines (w, CURRENT_DISP);
6340 /* Must do this before calling redisplay_output_window because it
6341 sets some markers on the window. */
6344 w->buffer = old_buffer;
6345 Fset_marker (w->pointm[DESIRED_DISP], make_int (old_pointm), old_buffer);
6346 Fset_marker (w->start[DESIRED_DISP], make_int (old_startp), old_buffer);
6349 /* These also have to be set before calling redisplay_output_window
6350 since it sets the CURRENT_DISP values based on them. */
6351 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
6352 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
6353 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
6354 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
6358 Bufpos start = marker_position (w->start[DESIRED_DISP]);
6359 Bufpos end = (w->window_end_pos[DESIRED_DISP] == -1
6361 : BUF_Z (b) - w->window_end_pos[DESIRED_DISP] - 1);
6362 /* Don't pollute the cache if not sure if we are correct */
6363 if (w->start_at_line_beg)
6364 update_line_start_cache (w, start, end, pointm, 1);
6365 redisplay_output_window (w);
6367 * If we just displayed the echo area, the line start cache is
6368 * no longer valid, because the minibuffer window is associated
6369 * with the window now.
6372 w->line_cache_last_updated = make_int (-1);
6375 /* #### This should be dependent on face changes and will need to be
6376 somewhere else once tty updates occur on a per-frame basis. */
6377 mark_face_cachels_as_clean (w);
6379 /* The glyph cachels only get dirty if someone changed something.
6380 Since redisplay has now effectively ended we can reset the dirty
6381 flag since everything must be up-to-date. */
6383 mark_glyph_cachels_as_clean (w);
6385 w->windows_changed = 0;
6388 /* Call buffer_reset_changes for all buffers present in any window
6389 currently visible in all frames on all devices. #### There has to
6390 be a better way to do this. */
6393 reset_buffer_changes_mapfun (struct window *w, void *ignored_closure)
6395 buffer_reset_changes (XBUFFER (w->buffer));
6400 reset_buffer_changes (void)
6402 Lisp_Object frmcons, devcons, concons;
6404 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
6406 struct frame *f = XFRAME (XCAR (frmcons));
6408 if (FRAME_REPAINT_P (f))
6409 map_windows (f, reset_buffer_changes_mapfun, 0);
6413 /* Ensure that all windows underneath the given window in the window
6414 hierarchy are correctly displayed. */
6417 redisplay_windows (Lisp_Object window, int skip_selected)
6419 for (; !NILP (window) ; window = XWINDOW (window)->next)
6421 redisplay_window (window, skip_selected);
6426 call_redisplay_end_triggers (struct window *w, void *closure)
6428 Bufpos lrpos = w->last_redisplay_pos;
6429 w->last_redisplay_pos = 0;
6430 if (!NILP (w->buffer)
6431 && !NILP (w->redisplay_end_trigger)
6436 if (MARKERP (w->redisplay_end_trigger)
6437 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
6438 pos = marker_position (w->redisplay_end_trigger);
6439 else if (INTP (w->redisplay_end_trigger))
6440 pos = XINT (w->redisplay_end_trigger);
6443 w->redisplay_end_trigger = Qnil;
6450 XSETWINDOW (window, w);
6451 va_run_hook_with_args_in_buffer (XBUFFER (w->buffer),
6452 Qredisplay_end_trigger_functions,
6454 w->redisplay_end_trigger);
6455 w->redisplay_end_trigger = Qnil;
6462 /* Ensure that all windows on the given frame are correctly displayed. */
6465 redisplay_frame (struct frame *f, int preemption_check)
6467 struct device *d = XDEVICE (f->device);
6469 if (preemption_check
6470 && !DEVICE_IMPL_FLAG (d, XDEVIMPF_DONT_PREEMPT_REDISPLAY))
6472 /* The preemption check itself takes a lot of time,
6473 so normally don't do it here. We do it if called
6474 from Lisp, though (`redisplay-frame'). */
6477 REDISPLAY_PREEMPTION_CHECK;
6482 if (!internal_equal (f->old_buffer_alist, f->buffer_alist, 0))
6486 f->old_buffer_alist = Freplace_list (f->old_buffer_alist,
6488 XSETFRAME (frame, f);
6489 va_run_hook_with_args (Qbuffer_list_changed_hook, 1, frame);
6492 /* Before we put a hold on frame size changes, attempt to process
6493 any which are already pending. */
6494 if (f->size_change_pending)
6495 change_frame_size (f, f->new_height, f->new_width, 0);
6497 /* If frame size might need to be changed, due to changed size
6498 of toolbars, scrollbars etc, change it now */
6499 if (f->size_slipped)
6501 adjust_frame_size (f);
6502 assert (!f->size_slipped);
6505 /* The menubar, toolbar, and icon updates must be done before
6506 hold_frame_size_changes is called and we are officially
6507 'in_display'. They may eval lisp code which may call Fsignal.
6508 If in_display is set Fsignal will abort. */
6510 #ifdef HAVE_MENUBARS
6511 /* Update the menubar. It is done first since it could change
6512 the menubar's visibility. This way we avoid having flashing
6513 caused by an Expose event generated by the visibility change
6515 update_frame_menubars (f);
6516 #endif /* HAVE_MENUBARS */
6517 #ifdef HAVE_TOOLBARS
6518 /* Update the toolbars geometry. We don't update the toolbars
6519 themselves at this point since the space they are trying to
6520 occupy may currently by occupied by gutter elements. Instead we
6521 update the geometry, then update the gutter geometry, then update
6522 the gutters - which will cause mapped windows to be repositioned
6523 - and finally update the toolbars. */
6524 update_frame_toolbars_geometry (f);
6525 #endif /* HAVE_TOOLBARS */
6526 /* Gutter update proper has to be done inside display when no frame
6527 size changes can occur, thus we separately update the gutter
6528 geometry here if it needs it. */
6529 update_frame_gutter_geometry (f);
6531 /* If we clear the frame we have to force its contents to be redrawn. */
6533 f->frame_changed = 1;
6535 /* Invalidate the subwindow caches. We use subwindows_changed here
6536 to cause subwindows to get instantiated. This is because
6537 subwindows_state_changed is less strict - dealing with things
6538 like the clicked state of button. We have to do this before
6539 redisplaying the gutters as subwindows get unmapped in the
6541 if (f->frame_changed)
6542 reset_frame_subwindow_instance_cache (f);
6544 if (f->frame_changed || f->subwindows_changed)
6546 /* we have to do this so the gutter gets regenerated. */
6547 reset_gutter_display_lines (f);
6550 hold_frame_size_changes ();
6552 /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */
6553 /* Within this section, we are defenseless and assume that the
6554 following cannot happen:
6556 1) garbage collection
6557 2) Lisp code evaluation
6558 3) frame size changes
6560 We ensure (3) by calling hold_frame_size_changes(), which
6561 will cause any pending frame size changes to get put on hold
6562 till after the end of the critical section. (1) follows
6563 automatically if (2) is met. #### Unfortunately, there are
6564 some places where Lisp code can be called within this section.
6565 We need to remove them.
6567 If Fsignal() is called during this critical section, we
6570 If garbage collection is called during this critical section,
6571 we simply return. #### We should abort instead.
6573 #### If a frame-size change does occur we should probably
6574 actually be preempting redisplay. */
6576 MAYBE_DEVMETH (d, frame_output_begin, (f));
6578 /* We can now update the gutters, safe in the knowledge that our
6579 efforts won't get undone. */
6581 /* This can call lisp, but redisplay is protected by binding
6582 inhibit_quit. More importantly the code involving display lines
6583 *assumes* that GC will not happen and so does not GCPRO
6584 anything. Since we use this code the whole time with the gutters
6585 we cannot allow GC to happen when manipulating the gutters. */
6586 update_frame_gutters (f);
6588 /* Erase the frame before outputting its contents. */
6591 MAYBE_DEVMETH (d, clear_frame, (f));
6594 /* Do the selected window first. */
6595 redisplay_window (FRAME_SELECTED_WINDOW (f), 0);
6597 /* Then do the rest. */
6598 redisplay_windows (f->root_window, 1);
6600 MAYBE_DEVMETH (d, frame_output_end, (f));
6602 update_frame_title (f);
6604 #ifdef HAVE_TOOLBARS
6605 /* Finally update the toolbars. It seems its possible to get in a
6606 cycle between updating the gutter and the toolbars. Basically we
6607 want to end up with both being up-to-date and this doesn't seem
6608 possible in a single pass. */
6609 update_frame_toolbars (f);
6610 #endif /* HAVE_TOOLBARS */
6612 CLASS_RESET_CHANGED_FLAGS (f);
6613 f->window_face_cache_reset = 0;
6614 f->echo_area_garbaged = 0;
6617 if (!f->size_change_pending)
6618 f->size_changed = 0;
6620 /* ----------------- END CRITICAL REDISPLAY SECTION ---------------- */
6622 /* Allow frame size changes to occur again.
6624 #### what happens if changes to other frames happen? */
6625 unhold_one_frame_size_changes (f);
6627 map_windows (f, call_redisplay_end_triggers, 0);
6631 /* Ensure that all frames on the given device are correctly displayed.
6632 If AUTOMATIC is non-zero, and the device implementation indicates
6633 no automatic redisplay, as printers do, then the device is not
6634 redisplayed. AUTOMATIC is set to zero when called from lisp
6635 functions (redraw-device) and (redisplay-device), and to non-zero
6636 when called from "lazy" redisplay();
6640 redisplay_device (struct device *d, int automatic)
6642 Lisp_Object frame, frmcons;
6643 int size_change_failed = 0;
6646 if (automatic && DEVICE_IMPL_FLAG (d, XDEVIMPF_NO_AUTO_REDISPLAY))
6649 if (DEVICE_STREAM_P (d)) /* nothing to do */
6652 /* It is possible that redisplay has been called before the
6653 device is fully initialized, or that the console implementation
6654 allows frameless devices. If so then continue with the next
6656 if (NILP (DEVICE_SELECTED_FRAME (d)))
6659 if (!DEVICE_IMPL_FLAG (d, XDEVIMPF_DONT_PREEMPT_REDISPLAY))
6662 REDISPLAY_PREEMPTION_CHECK;
6667 /* Always do the selected frame first. */
6668 frame = DEVICE_SELECTED_FRAME (d);
6672 if (f->icon_changed || f->windows_changed)
6673 update_frame_icon (f);
6675 if (FRAME_REPAINT_P (f))
6677 if (CLASS_REDISPLAY_FLAGS_CHANGEDP(f))
6679 int preempted = redisplay_frame (f, 0);
6684 /* If the frame redisplay did not get preempted, then this flag
6685 should have gotten set to 0. It might be possible for that
6686 not to happen if a size change event were to occur at an odd
6687 time. To make sure we don't miss anything we simply don't
6688 reset the top level flags until the condition ends up being
6689 in the right state. */
6690 if (f->size_changed)
6691 size_change_failed = 1;
6694 DEVICE_FRAME_LOOP (frmcons, d)
6696 f = XFRAME (XCAR (frmcons));
6698 if (f == XFRAME (DEVICE_SELECTED_FRAME (d)))
6701 if (f->icon_changed || f->windows_changed)
6702 update_frame_icon (f);
6704 if (FRAME_REPAINT_P (f))
6706 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (f))
6708 int preempted = redisplay_frame (f, 0);
6713 if (f->size_change_pending)
6714 size_change_failed = 1;
6718 /* If we get here then we redisplayed all of our frames without
6719 getting preempted so mark ourselves as clean. */
6720 CLASS_RESET_CHANGED_FLAGS (d);
6722 if (!size_change_failed)
6723 d->size_changed = 0;
6729 restore_profiling_redisplay_flag (Lisp_Object val)
6731 profiling_redisplay_flag = XINT (val);
6735 /* Ensure that all windows on all frames on all devices are displaying
6736 the current contents of their respective buffers. */
6739 redisplay_without_hooks (void)
6741 Lisp_Object devcons, concons;
6742 int size_change_failed = 0;
6743 int count = specpdl_depth ();
6745 if (profiling_active)
6747 record_unwind_protect (restore_profiling_redisplay_flag,
6748 make_int (profiling_redisplay_flag));
6749 profiling_redisplay_flag = 1;
6752 if (asynch_device_change_pending)
6753 handle_asynch_device_change ();
6755 if (!GLOBAL_REDISPLAY_FLAGS_CHANGEDP &&
6756 !disable_preemption && preemption_count < max_preempts)
6759 DEVICE_LOOP_NO_BREAK (devcons, concons)
6761 struct device *d = XDEVICE (XCAR (devcons));
6764 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (d))
6766 preempted = redisplay_device (d, 1);
6771 RESET_CHANGED_SET_FLAGS;
6775 /* See comment in redisplay_device. */
6776 if (d->size_changed)
6777 size_change_failed = 1;
6780 preemption_count = 0;
6782 /* Mark redisplay as accurate */
6783 GLOBAL_RESET_CHANGED_FLAGS;
6784 RESET_CHANGED_SET_FLAGS;
6788 mark_all_faces_as_clean ();
6792 if (!size_change_failed)
6795 reset_buffer_changes ();
6798 unbind_to (count, Qnil);
6804 if (last_display_warning_tick != display_warning_tick &&
6805 !inhibit_warning_display)
6807 /* If an error occurs during this function, oh well.
6808 If we report another warning, we could get stuck in an
6809 infinite loop reporting warnings. */
6810 call0_trapping_errors (0, Qdisplay_warning_buffer);
6811 last_display_warning_tick = display_warning_tick;
6813 /* The run_hook_trapping_errors functions are smart enough not
6814 to do any evalling if the hook function is empty, so there
6815 should not be any significant time loss. All places in the
6816 C code that call redisplay() are prepared to handle GCing,
6817 so we should be OK. */
6818 #ifndef INHIBIT_REDISPLAY_HOOKS
6819 run_hook_trapping_errors ("Error in pre-redisplay-hook",
6820 Qpre_redisplay_hook);
6821 #endif /* INHIBIT_REDISPLAY_HOOKS */
6823 redisplay_without_hooks ();
6825 #ifndef INHIBIT_REDISPLAY_HOOKS
6826 run_hook_trapping_errors ("Error in post-redisplay-hook",
6827 Qpost_redisplay_hook);
6828 #endif /* INHIBIT_REDISPLAY_HOOKS */
6832 static char window_line_number_buf[32];
6834 /* Efficiently determine the window line number, and return a pointer
6835 to its printed representation. Do this regardless of whether
6836 line-number-mode is on. The first line in the buffer is counted as
6837 1. If narrowing is in effect, the lines are counted from the
6838 beginning of the visible portion of the buffer. */
6840 window_line_number (struct window *w, int type)
6842 struct device *d = XDEVICE (XFRAME (w->frame)->device);
6843 struct buffer *b = XBUFFER (w->buffer);
6844 /* Be careful in the order of these tests. The first clause will
6845 fail if DEVICE_SELECTED_FRAME == Qnil (since w->frame cannot be).
6846 This can occur when the frame title is computed really early */
6848 ((EQ(DEVICE_SELECTED_FRAME(d), w->frame) &&
6849 (w == XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame(d)))) &&
6850 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
6851 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d )
6853 : marker_position (w->pointm[type]));
6856 line = buffer_line_number (b, pos, 1);
6858 long_to_string (window_line_number_buf, line + 1);
6860 return window_line_number_buf;
6864 /* Given a character representing an object in a modeline
6865 specification, return a string (stored into the global array
6866 `mode_spec_bufbyte_string') with the information that object
6869 This function is largely unchanged from previous versions of the
6872 Warning! This code is also used for frame titles and can be called
6873 very early in the device/frame update process! JV
6877 decode_mode_spec (struct window *w, Emchar spec, int type)
6879 Lisp_Object obj = Qnil;
6880 const char *str = NULL;
6881 struct buffer *b = XBUFFER (w->buffer);
6883 Dynarr_reset (mode_spec_bufbyte_string);
6887 /* print buffer name */
6892 /* print visited file name */
6897 /* print the current column */
6900 Bufpos pt = (w == XWINDOW (Fselected_window (Qnil)))
6902 : marker_position (w->pointm[type]);
6903 int col = column_at_point (b, pt, 1) + !!column_number_start_at_one;
6906 long_to_string (buf, col);
6908 Dynarr_add_many (mode_spec_bufbyte_string,
6909 (const Bufbyte *) buf, strlen (buf));
6911 goto decode_mode_spec_done;
6913 /* print the file coding system */
6917 Lisp_Object codesys = b->buffer_file_coding_system;
6918 /* Be very careful here not to get an error. */
6919 if (NILP (codesys) || SYMBOLP (codesys) || CODING_SYSTEMP (codesys))
6921 codesys = Ffind_coding_system (codesys);
6922 if (CODING_SYSTEMP (codesys))
6923 obj = XCODING_SYSTEM_MNEMONIC (codesys);
6926 #endif /* FILE_CODING */
6929 /* print the current line number */
6931 str = window_line_number (w, type);
6934 /* print value of mode-name (obsolete) */
6939 /* print hyphen and frame number, if != 1 */
6943 struct frame *f = XFRAME (w->frame);
6944 if (FRAME_TTY_P (f) && f->order_count > 1 && f->order_count <= 99999999)
6946 /* Naughty, naughty */
6947 char * writable_str = alloca_array (char, 10);
6948 sprintf (writable_str, "-%d", f->order_count);
6952 #endif /* HAVE_TTY */
6955 /* print Narrow if appropriate */
6957 if (BUF_BEGV (b) > BUF_BEG (b)
6958 || BUF_ZV (b) < BUF_Z (b))
6962 /* print %, * or hyphen, if buffer is read-only, modified or neither */
6964 str = (!NILP (b->read_only)
6966 : ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6971 /* print * or hyphen -- XEmacs change to allow a buffer to be
6972 read-only but still indicate whether it is modified. */
6974 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6976 : (!NILP (b->read_only)
6981 /* #### defined in 19.29 decode_mode_spec, but not in
6982 modeline-format doc string. */
6983 /* This differs from %* in that it ignores read-only-ness. */
6985 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6990 /* print process status */
6992 obj = Fget_buffer_process (w->buffer);
6994 str = GETTEXT ("no process");
6996 obj = Fsymbol_name (Fprocess_status (obj));
6999 /* Print name of selected frame. */
7001 obj = XFRAME (w->frame)->name;
7004 /* indicate TEXT or BINARY */
7006 /* #### NT does not use this any more. Now what? */
7010 /* print percent of buffer above top of window, or Top, Bot or All */
7013 Bufpos pos = marker_position (w->start[type]);
7015 /* This had better be while the desired lines are being done. */
7016 if (w->window_end_pos[type] <= BUF_Z (b) - BUF_ZV (b))
7018 if (pos <= BUF_BEGV (b))
7023 else if (pos <= BUF_BEGV (b))
7027 /* This hard limit is ok since the string it will hold has a
7028 fixed maximum length of 3. But just to be safe... */
7030 Charcount chars = pos - BUF_BEGV (b);
7031 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
7033 /* Avoid overflow on big buffers */
7034 int percent = total > LONG_MAX/200 ?
7035 (chars + total/200) / (total / 100) :
7036 (chars * 100 + total/2) / total;
7038 /* We can't normally display a 3-digit number, so get us a
7039 2-digit number that is close. */
7043 sprintf (buf, "%d%%", percent);
7044 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
7047 goto decode_mode_spec_done;
7052 /* print percent of buffer above bottom of window, perhaps plus
7053 Top, or print Bottom or All */
7056 Bufpos toppos = marker_position (w->start[type]);
7057 Bufpos botpos = BUF_Z (b) - w->window_end_pos[type];
7059 /* botpos is only accurate as of the last redisplay, so we can
7060 only treat it as a hint. In particular, after erase-buffer,
7061 botpos may be negative. */
7062 if (botpos < toppos)
7065 if (botpos >= BUF_ZV (b))
7067 if (toppos <= BUF_BEGV (b))
7074 /* This hard limit is ok since the string it will hold has a
7075 fixed maximum length of around 6. But just to be safe... */
7077 Charcount chars = botpos - BUF_BEGV (b);
7078 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
7080 /* Avoid overflow on big buffers */
7081 int percent = total > LONG_MAX/200 ?
7082 (chars + total/200) / (total / 100) :
7083 (chars * 100 + total/2) / max (total, 1);
7085 /* We can't normally display a 3-digit number, so get us a
7086 2-digit number that is close. */
7090 if (toppos <= BUF_BEGV (b))
7091 sprintf (buf, "Top%d%%", percent);
7093 sprintf (buf, "%d%%", percent);
7095 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
7098 goto decode_mode_spec_done;
7108 /* print one [ for each recursive editing level. */
7113 if (command_loop_level > 5)
7119 for (i = 0; i < command_loop_level; i++)
7120 Dynarr_add (mode_spec_bufbyte_string, '[');
7122 goto decode_mode_spec_done;
7125 /* print one ] for each recursive editing level. */
7130 if (command_loop_level > 5)
7136 for (i = 0; i < command_loop_level; i++)
7137 Dynarr_add (mode_spec_bufbyte_string, ']');
7139 goto decode_mode_spec_done;
7142 /* print infinitely many dashes -- handle at top level now */
7149 Dynarr_add_many (mode_spec_bufbyte_string,
7151 XSTRING_LENGTH (obj));
7153 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) str, strlen (str));
7155 decode_mode_spec_done:
7156 Dynarr_add (mode_spec_bufbyte_string, '\0');
7159 /* Given a display line, free all of its data structures. */
7162 free_display_line (struct display_line *dl)
7166 if (dl->display_blocks)
7168 for (block = 0; block < Dynarr_largest (dl->display_blocks); block++)
7170 struct display_block *db = Dynarr_atp (dl->display_blocks, block);
7172 Dynarr_free (db->runes);
7175 Dynarr_free (dl->display_blocks);
7176 dl->display_blocks = NULL;
7179 if (dl->left_glyphs)
7181 Dynarr_free (dl->left_glyphs);
7182 dl->left_glyphs = NULL;
7185 if (dl->right_glyphs)
7187 Dynarr_free (dl->right_glyphs);
7188 dl->right_glyphs = NULL;
7193 /* Given an array of display lines, free them and all data structures
7194 contained within them. */
7197 free_display_lines (display_line_dynarr *dla)
7201 for (line = 0; line < Dynarr_largest (dla); line++)
7203 free_display_line (Dynarr_atp (dla, line));
7209 /* Call internal free routine for each set of display lines. */
7212 free_display_structs (struct window_mirror *mir)
7214 if (mir->current_display_lines)
7216 free_display_lines (mir->current_display_lines);
7217 mir->current_display_lines = 0;
7220 if (mir->desired_display_lines)
7222 free_display_lines (mir->desired_display_lines);
7223 mir->desired_display_lines = 0;
7229 mark_glyph_block_dynarr (glyph_block_dynarr *gba)
7233 glyph_block *gb = Dynarr_atp (gba, 0);
7234 glyph_block *gb_last = Dynarr_atp (gba, Dynarr_length (gba));
7236 for (; gb < gb_last; gb++)
7238 if (!NILP (gb->glyph))
7239 mark_object (gb->glyph);
7240 if (!NILP (gb->extent))
7241 mark_object (gb->extent);
7246 /* See the comment in image_instantiate_cache_result as to why marking
7247 the glyph will also mark the image_instance. */
7249 mark_redisplay_structs (display_line_dynarr *dla)
7251 display_line *dl = Dynarr_atp (dla, 0);
7252 display_line *dl_last = Dynarr_atp (dla, Dynarr_length (dla));
7254 for (; dl < dl_last; dl++)
7256 display_block_dynarr *dba = dl->display_blocks;
7257 display_block *db = Dynarr_atp (dba, 0);
7258 display_block *db_last = Dynarr_atp (dba, Dynarr_length (dba));
7260 for (; db < db_last; db++)
7262 rune_dynarr *ra = db->runes;
7263 rune *r = Dynarr_atp (ra, 0);
7264 rune *r_last = Dynarr_atp (ra, Dynarr_length (ra));
7266 for (; r < r_last; r++)
7268 if (r->type == RUNE_DGLYPH)
7270 if (!NILP (r->object.dglyph.glyph))
7271 mark_object (r->object.dglyph.glyph);
7272 if (!NILP (r->object.dglyph.extent))
7273 mark_object (r->object.dglyph.extent);
7278 mark_glyph_block_dynarr (dl->left_glyphs);
7279 mark_glyph_block_dynarr (dl->right_glyphs);
7284 mark_window_mirror (struct window_mirror *mir)
7286 mark_redisplay_structs (mir->current_display_lines);
7287 mark_redisplay_structs (mir->desired_display_lines);
7290 mark_window_mirror (mir->next);
7293 mark_window_mirror (mir->hchild);
7294 else if (mir->vchild)
7295 mark_window_mirror (mir->vchild);
7299 mark_redisplay (void)
7301 Lisp_Object frmcons, devcons, concons;
7303 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
7305 struct frame *f = XFRAME (XCAR (frmcons));
7306 mark_window_mirror (f->root_mirror);
7311 /*****************************************************************************
7312 Line Start Cache Description and Rationale
7314 The traditional scrolling code in Emacs breaks in a variable height world.
7315 It depends on the key assumption that the number of lines that can be
7316 displayed at any given time is fixed. This led to a complete separation
7317 of the scrolling code from the redisplay code. In order to fully support
7318 variable height lines, the scrolling code must actually be tightly
7319 integrated with redisplay. Only redisplay can determine how many lines
7320 will be displayed on a screen for any given starting point.
7322 What is ideally wanted is a complete list of the starting buffer position
7323 for every possible display line of a buffer along with the height of that
7324 display line. Maintaining such a full list would be very expensive. We
7325 settle for having it include information for all areas which we happen to
7326 generate anyhow (i.e. the region currently being displayed) and for those
7327 areas we need to work with.
7329 In order to ensure that the cache accurately represents what redisplay
7330 would actually show, it is necessary to invalidate it in many situations.
7331 If the buffer changes, the starting positions may no longer be correct.
7332 If a face or an extent has changed then the line heights may have altered.
7333 These events happen frequently enough that the cache can end up being
7334 constantly disabled. With this potentially constant invalidation when is
7335 the cache ever useful?
7337 Even if the cache is invalidated before every single usage, it is
7338 necessary. Scrolling often requires knowledge about display lines which
7339 are actually above or below the visible region. The cache provides a
7340 convenient light-weight method of storing this information for multiple
7341 display regions. This knowledge is necessary for the scrolling code to
7342 always obey the First Golden Rule of Redisplay.
7344 If the cache already contains all of the information that the scrolling
7345 routines happen to need so that it doesn't have to go generate it, then we
7346 are able to obey the Third Golden Rule of Redisplay. The first thing we
7347 do to help out the cache is to always add the displayed region. This
7348 region had to be generated anyway, so the cache ends up getting the
7349 information basically for free. In those cases where a user is simply
7350 scrolling around viewing a buffer there is a high probability that this is
7351 sufficient to always provide the needed information. The second thing we
7352 can do is be smart about invalidating the cache.
7354 TODO -- Be smart about invalidating the cache. Potential places:
7356 + Insertions at end-of-line which don't cause line-wraps do not alter the
7357 starting positions of any display lines. These types of buffer
7358 modifications should not invalidate the cache. This is actually a large
7359 optimization for redisplay speed as well.
7361 + Buffer modifications frequently only affect the display of lines at and
7362 below where they occur. In these situations we should only invalidate
7363 the part of the cache starting at where the modification occurs.
7365 In case you're wondering, the Second Golden Rule of Redisplay is not
7367 ****************************************************************************/
7369 /* This will get used quite a bit so we don't want to be constantly
7370 allocating and freeing it. */
7371 static line_start_cache_dynarr *internal_cache;
7373 /* Makes internal_cache represent the TYPE display structs and only
7374 the TYPE display structs. */
7377 update_internal_cache_list (struct window *w, int type)
7380 display_line_dynarr *dla = window_display_lines (w, type);
7382 Dynarr_reset (internal_cache);
7383 for (line = 0; line < Dynarr_length (dla); line++)
7385 struct display_line *dl = Dynarr_atp (dla, line);
7391 struct line_start_cache lsc;
7393 lsc.start = dl->bufpos;
7394 lsc.end = dl->end_bufpos;
7395 lsc.height = dl->ascent + dl->descent;
7397 Dynarr_add (internal_cache, lsc);
7402 /* Reset the line cache if necessary. This should be run at the
7403 beginning of any function which access the cache. */
7406 validate_line_start_cache (struct window *w)
7408 struct buffer *b = XBUFFER (w->buffer);
7409 struct frame *f = XFRAME (w->frame);
7411 if (!w->line_cache_validation_override)
7413 /* f->extents_changed used to be in here because extent face and
7414 size changes can cause text shifting. However, the extent
7415 covering the region is constantly having its face set and
7416 priority altered by the mouse code. This means that the line
7417 start cache is constantly being invalidated. This is bad
7418 since the mouse code also triggers heavy usage of the cache.
7419 Since it is an unlikely that f->extents being changed
7420 indicates that the cache really needs to be updated and if it
7421 does redisplay will catch it pretty quickly we no longer
7422 invalidate the cache if it is set. This greatly speeds up
7423 dragging out regions with the mouse. */
7424 if (XINT (w->line_cache_last_updated) < BUF_MODIFF (b)
7428 Dynarr_reset (w->line_start_cache);
7433 /* Return the very first buffer position contained in the given
7434 window's cache, or -1 if the cache is empty. Assumes that the
7438 line_start_cache_start (struct window *w)
7440 line_start_cache_dynarr *cache = w->line_start_cache;
7442 if (!Dynarr_length (cache))
7445 return Dynarr_atp (cache, 0)->start;
7448 /* Return the very last buffer position contained in the given
7449 window's cache, or -1 if the cache is empty. Assumes that the
7453 line_start_cache_end (struct window *w)
7455 line_start_cache_dynarr *cache = w->line_start_cache;
7457 if (!Dynarr_length (cache))
7460 return Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
7463 /* Return the index of the line POINT is contained within in window
7464 W's line start cache. It will enlarge the cache or move the cache
7465 window in order to have POINT be present in the cache. MIN_PAST is
7466 a guarantee of the number of entries in the cache present on either
7467 side of POINT (unless a buffer boundary is hit). If MIN_PAST is -1
7468 then it will be treated as 0, but the cache window will not be
7469 allowed to shift. Returns -1 if POINT cannot be found in the cache
7473 point_in_line_start_cache (struct window *w, Bufpos point, int min_past)
7475 struct buffer *b = XBUFFER (w->buffer);
7476 line_start_cache_dynarr *cache = w->line_start_cache;
7477 unsigned int top, bottom;
7480 validate_line_start_cache (w);
7481 w->line_cache_validation_override++;
7483 /* Let functions pass in negative values, but we still treat -1
7485 /* #### bogosity alert */
7486 if (min_past < 0 && min_past != -1)
7487 min_past = -min_past;
7489 if (!Dynarr_length (cache) || line_start_cache_start (w) > point
7490 || line_start_cache_end (w) < point)
7493 int win_char_height = window_char_height (w, 1);
7495 /* Occasionally we get here with a 0 height
7496 window. find_next_newline_no_quit will abort if we pass it a
7497 count of 0 so handle that case. */
7498 if (!win_char_height)
7499 win_char_height = 1;
7501 if (!Dynarr_length (cache))
7503 Bufpos from = find_next_newline_no_quit (b, point, -1);
7504 Bufpos to = find_next_newline_no_quit (b, from, win_char_height);
7506 update_line_start_cache (w, from, to, point, 0);
7508 if (!Dynarr_length (cache))
7510 w->line_cache_validation_override--;
7515 assert (Dynarr_length (cache));
7518 while (line_start_cache_start (w) > point
7519 && (loop < cache_adjustment || min_past == -1))
7523 from = line_start_cache_start (w);
7524 if (from <= BUF_BEGV (b))
7527 from = find_next_newline_no_quit (b, from, -win_char_height);
7528 to = line_start_cache_end (w);
7530 update_line_start_cache (w, from, to, point, 0);
7534 if (line_start_cache_start (w) > point)
7538 from = find_next_newline_no_quit (b, point, -1);
7539 if (from >= BUF_ZV (b))
7541 to = find_next_newline_no_quit (b, from, -win_char_height);
7546 to = find_next_newline_no_quit (b, from, win_char_height);
7548 update_line_start_cache (w, from, to, point, 0);
7552 while (line_start_cache_end (w) < point
7553 && (loop < cache_adjustment || min_past == -1))
7557 to = line_start_cache_end (w);
7558 if (to >= BUF_ZV (b))
7561 from = line_start_cache_end (w);
7562 to = find_next_newline_no_quit (b, from, win_char_height);
7564 update_line_start_cache (w, from, to, point, 0);
7568 if (line_start_cache_end (w) < point)
7572 from = find_next_newline_no_quit (b, point, -1);
7573 if (from >= BUF_ZV (b))
7575 to = find_next_newline_no_quit (b, from, -win_char_height);
7580 to = find_next_newline_no_quit (b, from, win_char_height);
7582 update_line_start_cache (w, from, to, point, 0);
7586 assert (Dynarr_length (cache));
7591 /* This could happen if the buffer is narrowed. */
7592 if (line_start_cache_start (w) > point
7593 || line_start_cache_end (w) < point)
7595 w->line_cache_validation_override--;
7601 top = Dynarr_length (cache) - 1;
7609 pos = (bottom + top + 1) >> 1;
7610 start = Dynarr_atp (cache, pos)->start;
7611 end = Dynarr_atp (cache, pos)->end;
7613 if (point >= start && point <= end)
7615 if (pos < min_past && line_start_cache_start (w) > BUF_BEGV (b))
7618 find_next_newline_no_quit (b, line_start_cache_start (w),
7620 Bufpos to = line_start_cache_end (w);
7622 update_line_start_cache (w, from, to, point, 0);
7623 goto find_point_loop;
7625 else if ((Dynarr_length (cache) - pos - 1) < min_past
7626 && line_start_cache_end (w) < BUF_ZV (b))
7628 Bufpos from = line_start_cache_end (w);
7629 Bufpos to = find_next_newline_no_quit (b, from,
7634 update_line_start_cache (w, from, to, point, 0);
7635 goto find_point_loop;
7639 w->line_cache_validation_override--;
7643 else if (point > end)
7645 else if (point < start)
7650 new_pos = (bottom + top + 1) >> 1;
7653 w->line_cache_validation_override--;
7659 /* Return a boolean indicating if POINT would be visible in window W
7660 if display of the window was to begin at STARTP. */
7663 point_would_be_visible (struct window *w, Bufpos startp, Bufpos point)
7665 struct buffer *b = XBUFFER (w->buffer);
7666 int pixpos = -WINDOW_TEXT_TOP_CLIP(w);
7667 int bottom = WINDOW_TEXT_HEIGHT (w);
7670 /* If point is before the intended start it obviously can't be visible. */
7674 /* If point or start are not in the accessible buffer range, then
7676 if (startp < BUF_BEGV (b) || startp > BUF_ZV (b)
7677 || point < BUF_BEGV (b) || point > BUF_ZV (b))
7680 validate_line_start_cache (w);
7681 w->line_cache_validation_override++;
7683 start_elt = point_in_line_start_cache (w, startp, 0);
7684 if (start_elt == -1)
7686 w->line_cache_validation_override--;
7690 assert (line_start_cache_start (w) <= startp
7691 && line_start_cache_end (w) >= startp);
7697 /* Expand the cache if necessary. */
7698 if (start_elt == Dynarr_length (w->line_start_cache))
7701 Dynarr_atp (w->line_start_cache, start_elt - 1)->start;
7703 start_elt = point_in_line_start_cache (w, old_startp,
7704 window_char_height (w, 0));
7706 /* We've already actually processed old_startp, so increment
7710 /* If this happens we didn't add any extra elements. Bummer. */
7711 if (start_elt == Dynarr_length (w->line_start_cache))
7713 w->line_cache_validation_override--;
7718 height = Dynarr_atp (w->line_start_cache, start_elt)->height;
7720 if (pixpos + height > bottom)
7722 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7724 w->line_cache_validation_override--;
7730 if (point <= Dynarr_atp (w->line_start_cache, start_elt)->end)
7732 w->line_cache_validation_override--;
7740 /* For the given window W, if display starts at STARTP, what will be
7741 the buffer position at the beginning or end of the last line
7742 displayed. The end of the last line is also know as the window end
7745 WARNING: It is possible that redisplay failed to layout any lines for the
7746 windows. Under normal circumstances this is rare. However it seems that it
7747 does occur in the following situation: A mouse event has come in and we
7748 need to compute its location in a window. That code (in
7749 pixel_to_glyph_translation) already can handle 0 as an error return value.
7751 #### With a little work this could probably be reworked as just a
7752 call to start_with_line_at_pixpos. */
7755 start_end_of_last_line (struct window *w, Bufpos startp, int end,
7758 struct buffer *b = XBUFFER (w->buffer);
7759 line_start_cache_dynarr *cache = w->line_start_cache;
7761 int bottom = WINDOW_TEXT_HEIGHT (w);
7765 validate_line_start_cache (w);
7766 w->line_cache_validation_override++;
7768 if (startp < BUF_BEGV (b))
7769 startp = BUF_BEGV (b);
7770 else if (startp > BUF_ZV (b))
7771 startp = BUF_ZV (b);
7774 start_elt = point_in_line_start_cache (w, cur_start, 0);
7775 if (start_elt == -1)
7776 return may_error ? 0 : startp;
7780 int height = Dynarr_atp (cache, start_elt)->height;
7782 cur_start = Dynarr_atp (cache, start_elt)->start;
7784 if (pixpos + height > bottom)
7786 /* Adjust for any possible clip. */
7787 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7792 w->line_cache_validation_override--;
7796 return BUF_BEGV (b);
7800 w->line_cache_validation_override--;
7802 return Dynarr_atp (cache, start_elt)->end;
7804 return Dynarr_atp (cache, start_elt)->start;
7810 if (start_elt == Dynarr_length (cache))
7812 Bufpos from = line_start_cache_end (w);
7813 int win_char_height = window_char_height (w, 0);
7814 Bufpos to = find_next_newline_no_quit (b, from,
7819 /* We've hit the end of the bottom so that's what it is. */
7820 if (from >= BUF_ZV (b))
7822 w->line_cache_validation_override--;
7826 update_line_start_cache (w, from, to, BUF_PT (b), 0);
7828 /* Updating the cache invalidates any current indexes. */
7829 start_elt = point_in_line_start_cache (w, cur_start, -1) + 1;
7834 /* For the given window W, if display starts at STARTP, what will be
7835 the buffer position at the beginning of the last line displayed. */
7838 start_of_last_line (struct window *w, Bufpos startp)
7840 return start_end_of_last_line (w, startp, 0 , 0);
7843 /* For the given window W, if display starts at STARTP, what will be
7844 the buffer position at the end of the last line displayed. This is
7845 also know as the window end position. */
7848 end_of_last_line (struct window *w, Bufpos startp)
7850 return start_end_of_last_line (w, startp, 1, 0);
7854 end_of_last_line_may_error (struct window *w, Bufpos startp)
7856 return start_end_of_last_line (w, startp, 1, 1);
7860 /* For window W, what does the starting position have to be so that
7861 the line containing POINT will cover pixel position PIXPOS. */
7864 start_with_line_at_pixpos (struct window *w, Bufpos point, int pixpos)
7866 struct buffer *b = XBUFFER (w->buffer);
7868 Bufpos cur_pos, prev_pos = point;
7869 int point_line_height;
7870 int pixheight = pixpos - WINDOW_TEXT_TOP (w);
7872 validate_line_start_cache (w);
7873 w->line_cache_validation_override++;
7875 cur_elt = point_in_line_start_cache (w, point, 0);
7876 /* #### See comment in update_line_start_cache about big minibuffers. */
7879 w->line_cache_validation_override--;
7883 point_line_height = Dynarr_atp (w->line_start_cache, cur_elt)->height;
7887 cur_pos = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7889 pixheight -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7891 /* Do not take into account the value of vertical_clip here.
7892 That is the responsibility of the calling functions. */
7895 w->line_cache_validation_override--;
7896 if (-pixheight > point_line_height)
7897 /* We can't make the target line cover pixpos, so put it
7898 above pixpos. That way it will at least be visible. */
7908 int win_char_height;
7910 if (cur_pos <= BUF_BEGV (b))
7912 w->line_cache_validation_override--;
7913 return BUF_BEGV (b);
7916 win_char_height = window_char_height (w, 0);
7917 if (!win_char_height)
7918 win_char_height = 1;
7920 from = find_next_newline_no_quit (b, cur_pos, -win_char_height);
7921 to = line_start_cache_end (w);
7922 update_line_start_cache (w, from, to, point, 0);
7924 cur_elt = point_in_line_start_cache (w, cur_pos, 2) - 1;
7925 assert (cur_elt >= -1);
7926 /* This used to be cur_elt>=0 under the assumption that if
7927 point is in the top line and not at BUF_BEGV, then
7928 setting the window_start to a newline before the start of
7929 the first line will always cause scrolling.
7931 However in my (jv) opinion this is wrong. That new line
7932 can be hidden in various ways: invisible extents, an
7933 explicit window-start not at a newline character etc.
7934 The existence of those are indeed known to create crashes
7935 on that assert. So we have no option but to continue the
7936 search if we found point at the top of the line_start_cache
7938 cur_pos = Dynarr_atp (w->line_start_cache,0)->start;
7944 /* For window W, what does the starting position have to be so that
7945 the line containing point is on display line LINE. If LINE is
7946 positive it is considered to be the number of lines from the top of
7947 the window (0 is the top line). If it is negative the number is
7948 considered to be the number of lines from the bottom (-1 is the
7952 start_with_point_on_display_line (struct window *w, Bufpos point, int line)
7954 validate_line_start_cache (w);
7955 w->line_cache_validation_override++;
7959 int cur_elt = point_in_line_start_cache (w, point, line);
7961 if (cur_elt - line < 0)
7962 cur_elt = 0; /* Hit the top */
7966 w->line_cache_validation_override--;
7967 return Dynarr_atp (w->line_start_cache, cur_elt)->start;
7971 /* The calculated value of pixpos is correct for the bottom line
7972 or what we want when line is -1. Therefore we subtract one
7973 because we have already handled one line. */
7974 int new_line = -line - 1;
7975 int cur_elt = point_in_line_start_cache (w, point, new_line);
7976 int pixpos = WINDOW_TEXT_BOTTOM (w);
7977 Bufpos retval, search_point;
7979 /* If scroll_on_clipped_lines is false, the last "visible" line of
7980 the window covers the pixel at WINDOW_TEXT_BOTTOM (w) - 1.
7981 If s_o_c_l is true, then we don't want to count a clipped
7982 line, so back up from the bottom by the height of the line
7983 containing point. */
7984 if (scroll_on_clipped_lines)
7985 pixpos -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7989 if (cur_elt + new_line >= Dynarr_length (w->line_start_cache))
7991 /* Hit the bottom of the buffer. */
7993 (cur_elt + new_line) - Dynarr_length (w->line_start_cache) + 1;
7997 XSETWINDOW (window, w);
7998 default_face_height_and_width (window, &defheight, 0);
8000 cur_elt = Dynarr_length (w->line_start_cache) - 1;
8002 pixpos -= (adjustment * defheight);
8003 if (pixpos < WINDOW_TEXT_TOP (w))
8004 pixpos = WINDOW_TEXT_TOP (w);
8007 cur_elt = cur_elt + new_line;
8009 search_point = Dynarr_atp (w->line_start_cache, cur_elt)->start;
8011 retval = start_with_line_at_pixpos (w, search_point, pixpos);
8012 w->line_cache_validation_override--;
8017 /* This is used to speed up vertical scrolling by caching the known
8018 buffer starting positions for display lines. This allows the
8019 scrolling routines to avoid costly calls to regenerate_window. If
8020 NO_REGEN is true then it will only add the values in the DESIRED
8021 display structs which are in the given range.
8023 Note also that the FROM/TO values are minimums. It is possible
8024 that this function will actually add information outside of the
8025 lines containing those positions. This can't hurt but it could
8028 #### We currently force the cache to have only 1 contiguous region.
8029 It might help to make the cache a dynarr of caches so that we can
8030 cover more areas. This might, however, turn out to be a lot of
8031 overhead for too little gain. */
8034 update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
8035 Bufpos point, int no_regen)
8037 struct buffer *b = XBUFFER (w->buffer);
8038 line_start_cache_dynarr *cache = w->line_start_cache;
8039 Bufpos low_bound, high_bound;
8041 validate_line_start_cache (w);
8042 w->line_cache_validation_override++;
8044 if (from < BUF_BEGV (b))
8045 from = BUF_BEGV (b);
8046 if (to > BUF_ZV (b))
8051 w->line_cache_validation_override--;
8055 if (Dynarr_length (cache))
8057 low_bound = line_start_cache_start (w);
8058 high_bound = line_start_cache_end (w);
8060 /* Check to see if the desired range is already in the cache. */
8061 if (from >= low_bound && to <= high_bound)
8063 w->line_cache_validation_override--;
8067 /* Check to make sure that the desired range is adjacent to the
8068 current cache. If not, invalidate the cache. */
8069 if (to < low_bound || from > high_bound)
8071 Dynarr_reset (cache);
8072 low_bound = high_bound = -1;
8077 low_bound = high_bound = -1;
8080 w->line_cache_last_updated = make_int (BUF_MODIFF (b));
8082 /* This could be integrated into the next two sections, but it is easier
8083 to follow what's going on by having it separate. */
8088 update_internal_cache_list (w, DESIRED_DISP);
8089 if (!Dynarr_length (internal_cache))
8091 w->line_cache_validation_override--;
8095 start = Dynarr_atp (internal_cache, 0)->start;
8097 Dynarr_atp (internal_cache, Dynarr_length (internal_cache) - 1)->end;
8099 /* We aren't allowed to generate additional information to fill in
8100 gaps, so if the DESIRED structs don't overlap the cache, reset the
8102 if (Dynarr_length (cache))
8104 if (end < low_bound || start > high_bound)
8105 Dynarr_reset (cache);
8107 /* #### What should really happen if what we are doing is
8108 extending a line (the last line)? */
8109 if (Dynarr_length (cache) == 1
8110 && Dynarr_length (internal_cache) == 1)
8111 Dynarr_reset (cache);
8114 if (!Dynarr_length (cache))
8116 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
8117 Dynarr_length (internal_cache));
8118 w->line_cache_validation_override--;
8122 /* An extra check just in case the calling function didn't pass in
8123 the bounds of the DESIRED structs in the first place. */
8124 if (start >= low_bound && end <= high_bound)
8126 w->line_cache_validation_override--;
8130 /* At this point we know that the internal cache partially overlaps
8132 if (start < low_bound)
8134 int ic_elt = Dynarr_length (internal_cache) - 1;
8137 if (Dynarr_atp (internal_cache, ic_elt)->start < low_bound)
8145 Dynarr_reset (cache);
8146 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
8147 Dynarr_length (internal_cache));
8148 w->line_cache_validation_override--;
8152 Dynarr_insert_many_at_start (cache, Dynarr_atp (internal_cache, 0),
8156 if (end > high_bound)
8160 while (ic_elt < Dynarr_length (internal_cache))
8162 if (Dynarr_atp (internal_cache, ic_elt)->start > high_bound)
8168 if (!(ic_elt < Dynarr_length (internal_cache)))
8170 Dynarr_reset (cache);
8171 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
8172 Dynarr_length (internal_cache));
8173 w->line_cache_validation_override--;
8177 Dynarr_add_many (cache, Dynarr_atp (internal_cache, ic_elt),
8178 Dynarr_length (internal_cache) - ic_elt);
8181 w->line_cache_validation_override--;
8185 if (!Dynarr_length (cache) || from < low_bound)
8187 Bufpos startp = find_next_newline_no_quit (b, from, -1);
8189 int old_lb = low_bound;
8191 while (startp < old_lb || low_bound == -1)
8196 regenerate_window (w, startp, point, CMOTION_DISP);
8197 update_internal_cache_list (w, CMOTION_DISP);
8199 /* If this assert is triggered then regenerate_window failed
8200 to layout a single line. This is not possible since we
8201 force at least a single line to be layout for CMOTION_DISP */
8202 assert (Dynarr_length (internal_cache));
8203 assert (startp == Dynarr_atp (internal_cache, 0)->start);
8205 ic_elt = Dynarr_length (internal_cache) - 1;
8206 if (low_bound != -1)
8210 if (Dynarr_atp (internal_cache, ic_elt)->start < old_lb)
8216 assert (ic_elt >= 0);
8218 new_startp = Dynarr_atp (internal_cache, ic_elt)->end + 1;
8221 * Handle invisible text properly:
8222 * If the last line we're inserting has the same end as the
8223 * line before which it will be added, merge the two lines.
8225 if (Dynarr_length (cache) &&
8226 Dynarr_atp (internal_cache, ic_elt)->end ==
8227 Dynarr_atp (cache, marker)->end)
8229 Dynarr_atp (cache, marker)->start
8230 = Dynarr_atp (internal_cache, ic_elt)->start;
8231 Dynarr_atp (cache, marker)->height
8232 = Dynarr_atp (internal_cache, ic_elt)->height;
8236 if (ic_elt >= 0) /* we still have lines to add.. */
8238 Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0),
8239 ic_elt + 1, marker);
8240 marker += (ic_elt + 1);
8243 if (startp < low_bound || low_bound == -1)
8245 startp = new_startp;
8246 if (startp > BUF_ZV (b))
8248 w->line_cache_validation_override--;
8254 assert (Dynarr_length (cache));
8255 assert (from >= low_bound);
8257 /* Readjust the high_bound to account for any changes made while
8258 correcting the low_bound. */
8259 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8261 if (to > high_bound)
8263 Bufpos startp = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end + 1;
8267 regenerate_window (w, startp, point, CMOTION_DISP);
8268 update_internal_cache_list (w, CMOTION_DISP);
8270 /* See comment above about regenerate_window failing. */
8271 assert (Dynarr_length (internal_cache));
8273 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
8274 Dynarr_length (internal_cache));
8275 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8276 startp = high_bound + 1;
8278 while (to > high_bound);
8281 w->line_cache_validation_override--;
8282 assert (to <= high_bound);
8286 /* Given x and y coordinates in characters, relative to a window,
8287 return the pixel location corresponding to those coordinates. The
8288 pixel location returned is the center of the given character
8289 position. The pixel values are generated relative to the window,
8292 The modeline is considered to be part of the window. */
8295 glyph_to_pixel_translation (struct window *w, int char_x, int char_y,
8296 int *pix_x, int *pix_y)
8298 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
8299 int num_disp_lines, modeline;
8301 int defheight, defwidth;
8303 XSETWINDOW (window, w);
8304 default_face_height_and_width (window, &defheight, &defwidth);
8306 /* If we get a bogus value indicating somewhere above or to the left of
8307 the window, use the first window line or character position
8314 num_disp_lines = Dynarr_length (dla);
8318 if (Dynarr_atp (dla, 0)->modeline)
8325 /* First check if the y position intersects the display lines. */
8326 if (char_y < num_disp_lines)
8328 struct display_line *dl = Dynarr_atp (dla, char_y + modeline);
8329 struct display_block *db = get_display_block_from_line (dl, TEXT);
8331 *pix_y = (dl->ypos - dl->ascent +
8332 ((unsigned int) (dl->ascent + dl->descent - dl->clip) >> 1));
8334 if (char_x < Dynarr_length (db->runes))
8336 struct rune *rb = Dynarr_atp (db->runes, char_x);
8338 *pix_x = rb->xpos + (rb->width >> 1);
8342 int last_rune = Dynarr_length (db->runes) - 1;
8343 struct rune *rb = Dynarr_atp (db->runes, last_rune);
8345 char_x -= last_rune;
8347 *pix_x = rb->xpos + rb->width;
8348 *pix_x += ((char_x - 1) * defwidth);
8349 *pix_x += (defwidth >> 1);
8354 /* It didn't intersect, so extrapolate. #### For now, we include the
8355 modeline in this since we don't have true character positions in
8358 if (!Dynarr_length (w->face_cachels))
8359 reset_face_cachels (w);
8361 char_y -= num_disp_lines;
8363 if (Dynarr_length (dla))
8365 struct display_line *dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
8366 *pix_y = dl->ypos + dl->descent - dl->clip;
8369 *pix_y = WINDOW_TEXT_TOP (w);
8371 *pix_y += (char_y * defheight);
8372 *pix_y += (defheight >> 1);
8374 *pix_x = WINDOW_TEXT_LEFT (w);
8375 /* Don't adjust by one because this is still the unadjusted value. */
8376 *pix_x += (char_x * defwidth);
8377 *pix_x += (defwidth >> 1);
8380 if (*pix_x > w->pixel_left + w->pixel_width)
8381 *pix_x = w->pixel_left + w->pixel_width;
8382 if (*pix_y > w->pixel_top + w->pixel_height)
8383 *pix_y = w->pixel_top + w->pixel_height;
8385 *pix_x -= w->pixel_left;
8386 *pix_y -= w->pixel_top;
8389 /* Given a display line and a position, determine if there is a glyph
8390 there and return information about it if there is. */
8393 get_position_object (struct display_line *dl, Lisp_Object *obj1,
8394 Lisp_Object *obj2, int x_coord, int *low_x_coord,
8397 struct display_block *db;
8400 get_next_display_block (dl->bounds, dl->display_blocks, x_coord, 0);
8402 /* We use get_next_display_block to get the actual display block
8403 that would be displayed at x_coord. */
8405 if (block == NO_BLOCK)
8408 db = Dynarr_atp (dl->display_blocks, block);
8410 for (elt = 0; elt < Dynarr_length (db->runes); elt++)
8412 struct rune *rb = Dynarr_atp (db->runes, elt);
8414 if (rb->xpos <= x_coord && x_coord < (rb->xpos + rb->width))
8416 if (rb->type == RUNE_DGLYPH)
8418 *obj1 = rb->object.dglyph.glyph;
8419 *obj2 = rb->object.dglyph.extent;
8428 *low_x_coord = rb->xpos;
8430 *high_x_coord = rb->xpos + rb->width;
8437 #define UPDATE_CACHE_RETURN \
8439 d->pixel_to_glyph_cache.valid = 1; \
8440 d->pixel_to_glyph_cache.low_x_coord = low_x_coord; \
8441 d->pixel_to_glyph_cache.high_x_coord = high_x_coord; \
8442 d->pixel_to_glyph_cache.low_y_coord = low_y_coord; \
8443 d->pixel_to_glyph_cache.high_y_coord = high_y_coord; \
8444 d->pixel_to_glyph_cache.frame = f; \
8445 d->pixel_to_glyph_cache.col = *col; \
8446 d->pixel_to_glyph_cache.row = *row; \
8447 d->pixel_to_glyph_cache.obj_x = *obj_x; \
8448 d->pixel_to_glyph_cache.obj_y = *obj_y; \
8449 d->pixel_to_glyph_cache.w = *w; \
8450 d->pixel_to_glyph_cache.bufpos = *bufpos; \
8451 d->pixel_to_glyph_cache.closest = *closest; \
8452 d->pixel_to_glyph_cache.modeline_closest = *modeline_closest; \
8453 d->pixel_to_glyph_cache.obj1 = *obj1; \
8454 d->pixel_to_glyph_cache.obj2 = *obj2; \
8455 d->pixel_to_glyph_cache.retval = position; \
8456 RETURN_SANS_WARNINGS position; \
8459 /* Given x and y coordinates in pixels relative to a frame, return
8460 information about what is located under those coordinates.
8462 The return value will be one of:
8464 OVER_TOOLBAR: over one of the 4 frame toolbars
8465 OVER_MODELINE: over a modeline
8466 OVER_BORDER: over an internal border
8467 OVER_NOTHING: over the text area, but not over text
8468 OVER_OUTSIDE: outside of the frame border
8469 OVER_TEXT: over text in the text area
8475 -- nil if the coordinates are not over a glyph or a toolbar button.
8479 -- an extent, if the coordinates are over a glyph in the text area
8482 If the coordinates are over a glyph, OBJ_X and OBJ_Y give the
8483 equivalent coordinates relative to the upper-left corner of the glyph.
8485 If the coordinates are over a character, OBJ_X and OBJ_Y give the
8486 equivalent coordinates relative to the upper-left corner of the character.
8488 Otherwise, OBJ_X and OBJ_Y are undefined.
8492 pixel_to_glyph_translation (struct frame *f, int x_coord, int y_coord,
8493 int *col, int *row, int *obj_x, int *obj_y,
8494 struct window **w, Bufpos *bufpos,
8495 Bufpos *closest, Charcount *modeline_closest,
8496 Lisp_Object *obj1, Lisp_Object *obj2)
8499 struct pixel_to_glyph_translation_cache *cache;
8501 int frm_left, frm_right, frm_top, frm_bottom;
8502 int low_x_coord, high_x_coord, low_y_coord, high_y_coord;
8503 int position = OVER_NOTHING;
8504 int device_check_failed = 0;
8505 display_line_dynarr *dla;
8507 /* This is a safety valve in case this got called with a frame in
8508 the middle of being deleted. */
8509 if (!DEVICEP (f->device) || !DEVICE_LIVE_P (XDEVICE (f->device)))
8511 device_check_failed = 1;
8512 d = NULL, cache = NULL; /* Warning suppression */
8516 d = XDEVICE (f->device);
8517 cache = &d->pixel_to_glyph_cache;
8520 if (!device_check_failed
8522 && cache->frame == f
8523 && cache->low_x_coord <= x_coord
8524 && cache->high_x_coord > x_coord
8525 && cache->low_y_coord <= y_coord
8526 && cache->high_y_coord > y_coord)
8530 *obj_x = cache->obj_x;
8531 *obj_y = cache->obj_y;
8533 *bufpos = cache->bufpos;
8534 *closest = cache->closest;
8535 *modeline_closest = cache->modeline_closest;
8536 *obj1 = cache->obj1;
8537 *obj2 = cache->obj2;
8539 return cache->retval;
8550 *modeline_closest = -1;
8554 low_x_coord = x_coord;
8555 high_x_coord = x_coord + 1;
8556 low_y_coord = y_coord;
8557 high_y_coord = y_coord + 1;
8560 if (device_check_failed)
8561 return OVER_NOTHING;
8563 frm_left = FRAME_LEFT_BORDER_END (f);
8564 frm_right = FRAME_RIGHT_BORDER_START (f);
8565 frm_top = FRAME_TOP_BORDER_END (f);
8566 frm_bottom = FRAME_BOTTOM_BORDER_START (f);
8568 /* Check if the mouse is outside of the text area actually used by
8570 if (y_coord < frm_top)
8572 if (y_coord >= FRAME_TOP_BORDER_START (f))
8574 low_y_coord = FRAME_TOP_BORDER_START (f);
8575 high_y_coord = frm_top;
8576 position = OVER_BORDER;
8578 else if (y_coord >= 0)
8581 high_y_coord = FRAME_TOP_BORDER_START (f);
8582 position = OVER_TOOLBAR;
8586 low_y_coord = y_coord;
8588 position = OVER_OUTSIDE;
8591 else if (y_coord >= frm_bottom)
8593 if (y_coord < FRAME_BOTTOM_BORDER_END (f))
8595 low_y_coord = frm_bottom;
8596 high_y_coord = FRAME_BOTTOM_BORDER_END (f);
8597 position = OVER_BORDER;
8599 else if (y_coord < FRAME_PIXHEIGHT (f))
8601 low_y_coord = FRAME_BOTTOM_BORDER_END (f);
8602 high_y_coord = FRAME_PIXHEIGHT (f);
8603 position = OVER_TOOLBAR;
8607 low_y_coord = FRAME_PIXHEIGHT (f);
8608 high_y_coord = y_coord;
8609 position = OVER_OUTSIDE;
8613 if (position != OVER_TOOLBAR && position != OVER_BORDER)
8615 if (x_coord < frm_left)
8617 if (x_coord >= FRAME_LEFT_BORDER_START (f))
8619 low_x_coord = FRAME_LEFT_BORDER_START (f);
8620 high_x_coord = frm_left;
8621 position = OVER_BORDER;
8623 else if (x_coord >= 0)
8626 high_x_coord = FRAME_LEFT_BORDER_START (f);
8627 position = OVER_TOOLBAR;
8631 low_x_coord = x_coord;
8633 position = OVER_OUTSIDE;
8636 else if (x_coord >= frm_right)
8638 if (x_coord < FRAME_RIGHT_BORDER_END (f))
8640 low_x_coord = frm_right;
8641 high_x_coord = FRAME_RIGHT_BORDER_END (f);
8642 position = OVER_BORDER;
8644 else if (x_coord < FRAME_PIXWIDTH (f))
8646 low_x_coord = FRAME_RIGHT_BORDER_END (f);
8647 high_x_coord = FRAME_PIXWIDTH (f);
8648 position = OVER_TOOLBAR;
8652 low_x_coord = FRAME_PIXWIDTH (f);
8653 high_x_coord = x_coord;
8654 position = OVER_OUTSIDE;
8659 #ifdef HAVE_TOOLBARS
8660 if (position == OVER_TOOLBAR)
8662 *obj1 = toolbar_button_at_pixpos (f, x_coord, y_coord);
8665 UPDATE_CACHE_RETURN;
8667 #endif /* HAVE_TOOLBARS */
8669 /* We still have to return the window the pointer is next to and its
8670 relative y position even if it is outside the x boundary. */
8671 if (x_coord < frm_left)
8673 else if (x_coord > frm_right)
8674 x_coord = frm_right;
8676 /* Same in reverse. */
8677 if (y_coord < frm_top)
8679 else if (y_coord > frm_bottom)
8680 y_coord = frm_bottom;
8682 /* Find what window the given coordinates are actually in. */
8683 window = f->root_window;
8684 *w = find_window_by_pixel_pos (x_coord, y_coord, window);
8686 /* If we didn't find a window, we're done. */
8689 UPDATE_CACHE_RETURN;
8691 else if (position != OVER_NOTHING)
8694 *modeline_closest = -1;
8696 if (high_y_coord <= frm_top || high_y_coord >= frm_bottom)
8699 UPDATE_CACHE_RETURN;
8703 /* Check if the window is a minibuffer but isn't active. */
8704 if (MINI_WINDOW_P (*w) && !minibuf_level)
8706 /* Must reset the window value since some callers will ignore
8707 the return value if it is set. */
8709 UPDATE_CACHE_RETURN;
8712 /* See if the point is over window vertical divider */
8713 if (window_needs_vertical_divider (*w))
8715 int div_x_high = WINDOW_RIGHT (*w);
8716 int div_x_low = div_x_high - window_divider_width (*w);
8717 int div_y_high = WINDOW_BOTTOM (*w);
8718 int div_y_low = WINDOW_TOP (*w);
8720 if (div_x_low < x_coord && x_coord <= div_x_high &&
8721 div_y_low < y_coord && y_coord <= div_y_high)
8723 low_x_coord = div_x_low;
8724 high_x_coord = div_x_high;
8725 low_y_coord = div_y_low;
8726 high_y_coord = div_y_high;
8727 position = OVER_V_DIVIDER;
8728 UPDATE_CACHE_RETURN;
8732 dla = window_display_lines (*w, CURRENT_DISP);
8734 for (*row = 0; *row < Dynarr_length (dla); (*row)++)
8736 int really_over_nothing = 0;
8737 struct display_line *dl = Dynarr_atp (dla, *row);
8739 if ((int) (dl->ypos - dl->ascent) <= y_coord
8740 && y_coord <= (int) (dl->ypos + dl->descent))
8742 int check_margin_glyphs = 0;
8743 struct display_block *db = get_display_block_from_line (dl, TEXT);
8744 struct rune *rb = 0;
8746 if (x_coord < dl->bounds.left_white
8747 || x_coord >= dl->bounds.right_white)
8748 check_margin_glyphs = 1;
8750 low_y_coord = dl->ypos - dl->ascent;
8751 high_y_coord = dl->ypos + dl->descent + 1;
8753 if (position == OVER_BORDER
8754 || position == OVER_OUTSIDE
8755 || check_margin_glyphs)
8757 int x_check, left_bound;
8759 if (check_margin_glyphs)
8762 left_bound = dl->bounds.left_white;
8766 x_check = high_x_coord;
8767 left_bound = frm_left;
8770 if (Dynarr_length (db->runes))
8772 if (x_check <= left_bound)
8775 *modeline_closest = Dynarr_atp (db->runes, 0)->bufpos;
8777 *closest = Dynarr_atp (db->runes, 0)->bufpos;
8783 Dynarr_atp (db->runes,
8784 Dynarr_length (db->runes) - 1)->bufpos;
8787 Dynarr_atp (db->runes,
8788 Dynarr_length (db->runes) - 1)->bufpos;
8792 *modeline_closest += dl->offset;
8794 *closest += dl->offset;
8798 /* #### What should be here. */
8800 *modeline_closest = 0;
8805 if (check_margin_glyphs)
8807 if (x_coord < dl->bounds.left_in
8808 || x_coord >= dl->bounds.right_in)
8810 /* If we are over the outside margins then we
8811 know the loop over the text block isn't going
8812 to accomplish anything. So we go ahead and
8813 set what information we can right here and
8816 *obj_y = y_coord - (dl->ypos - dl->ascent);
8817 get_position_object (dl, obj1, obj2, x_coord,
8818 &low_x_coord, &high_x_coord);
8820 UPDATE_CACHE_RETURN;
8824 UPDATE_CACHE_RETURN;
8827 for (*col = 0; *col <= Dynarr_length (db->runes); (*col)++)
8829 int past_end = (*col == Dynarr_length (db->runes));
8832 rb = Dynarr_atp (db->runes, *col);
8835 (rb->xpos <= x_coord && x_coord < rb->xpos + rb->width))
8840 rb = Dynarr_atp (db->runes, *col);
8843 *bufpos = rb->bufpos + dl->offset;
8844 low_x_coord = rb->xpos;
8845 high_x_coord = rb->xpos + rb->width;
8847 if (rb->type == RUNE_DGLYPH)
8851 /* Find the first character after the glyph. */
8852 while (elt < Dynarr_length (db->runes))
8854 if (Dynarr_atp (db->runes, elt)->type != RUNE_DGLYPH)
8858 (Dynarr_atp (db->runes, elt)->bufpos +
8862 (Dynarr_atp (db->runes, elt)->bufpos +
8870 /* In this case we failed to find a non-glyph
8871 character so we return the last position
8872 displayed on the line. */
8873 if (elt == Dynarr_length (db->runes))
8876 *modeline_closest = dl->end_bufpos + dl->offset;
8878 *closest = dl->end_bufpos + dl->offset;
8879 really_over_nothing = 1;
8885 *modeline_closest = rb->bufpos + dl->offset;
8887 *closest = rb->bufpos + dl->offset;
8892 *row = window_displayed_height (*w);
8894 if (position == OVER_NOTHING)
8895 position = OVER_MODELINE;
8897 if (rb->type == RUNE_DGLYPH)
8899 *obj1 = rb->object.dglyph.glyph;
8900 *obj2 = rb->object.dglyph.extent;
8902 else if (rb->type == RUNE_CHAR)
8913 UPDATE_CACHE_RETURN;
8916 || (rb->type == RUNE_CHAR
8917 && rb->object.chr.ch == '\n'))
8920 /* At this point we may have glyphs in the right
8922 if (check_margin_glyphs)
8923 get_position_object (dl, obj1, obj2, x_coord,
8924 &low_x_coord, &high_x_coord);
8925 UPDATE_CACHE_RETURN;
8930 if (rb->type == RUNE_DGLYPH)
8932 *obj1 = rb->object.dglyph.glyph;
8933 *obj2 = rb->object.dglyph.extent;
8935 else if (rb->type == RUNE_CHAR)
8946 *obj_x = x_coord - rb->xpos;
8947 *obj_y = y_coord - (dl->ypos - dl->ascent);
8949 /* At this point we may have glyphs in the left
8951 if (check_margin_glyphs)
8952 get_position_object (dl, obj1, obj2, x_coord, 0, 0);
8954 if (position == OVER_NOTHING && !really_over_nothing)
8955 position = OVER_TEXT;
8957 UPDATE_CACHE_RETURN;
8964 *row = Dynarr_length (dla) - 1;
8965 if (FRAME_WIN_P (f))
8967 int bot_elt = Dynarr_length (dla) - 1;
8971 struct display_line *dl = Dynarr_atp (dla, bot_elt);
8972 int adj_area = y_coord - (dl->ypos + dl->descent);
8976 XSETWINDOW (lwin, *w);
8977 default_face_height_and_width (lwin, 0, &defheight);
8979 *row += (adj_area / defheight);
8983 /* #### This should be checked out some more to determine what
8984 should really be going on. */
8985 if (!MARKERP ((*w)->start[CURRENT_DISP]))
8988 *closest = end_of_last_line_may_error (*w,
8989 marker_position ((*w)->start[CURRENT_DISP]));
8991 UPDATE_CACHE_RETURN;
8993 #undef UPDATE_CACHE_RETURN
8996 /***************************************************************************/
8998 /* Lisp functions */
9000 /***************************************************************************/
9002 DEFUN ("redisplay-echo-area", Fredisplay_echo_area, 0, 0, 0, /*
9003 Ensure that all minibuffers are correctly showing the echo area.
9007 Lisp_Object devcons, concons;
9009 DEVICE_LOOP_NO_BREAK (devcons, concons)
9011 struct device *d = XDEVICE (XCAR (devcons));
9012 Lisp_Object frmcons;
9014 DEVICE_FRAME_LOOP (frmcons, d)
9016 struct frame *f = XFRAME (XCAR (frmcons));
9018 if (FRAME_REPAINT_P (f) && FRAME_HAS_MINIBUF_P (f))
9020 Lisp_Object window = FRAME_MINIBUF_WINDOW (f);
9022 MAYBE_DEVMETH (d, frame_output_begin, (f));
9025 * If the frame size has changed, there may be random
9026 * chud on the screen left from previous messages
9027 * because redisplay_frame hasn't been called yet.
9028 * Clear the screen to get rid of the potential mess.
9030 if (f->echo_area_garbaged)
9032 MAYBE_DEVMETH (d, clear_frame, (f));
9033 f->echo_area_garbaged = 0;
9035 redisplay_window (window, 0);
9036 MAYBE_DEVMETH (d, frame_output_end, (f));
9038 call_redisplay_end_triggers (XWINDOW (window), 0);
9047 restore_disable_preemption_value (Lisp_Object value)
9049 disable_preemption = XINT (value);
9053 DEFUN ("redraw-frame", Fredraw_frame, 0, 2, 0, /*
9054 Clear frame FRAME and output again what is supposed to appear on it.
9055 FRAME defaults to the selected frame if omitted.
9056 Normally, redisplay is preempted as normal if input arrives. However,
9057 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
9058 input and is guaranteed to proceed to completion.
9060 (frame, no_preempt))
9062 struct frame *f = decode_frame (frame);
9063 int count = specpdl_depth ();
9065 if (!NILP (no_preempt))
9067 record_unwind_protect (restore_disable_preemption_value,
9068 make_int (disable_preemption));
9069 disable_preemption++;
9073 redisplay_frame (f, 1);
9075 /* See the comment in Fredisplay_frame. */
9076 RESET_CHANGED_SET_FLAGS;
9078 return unbind_to (count, Qnil);
9081 DEFUN ("redisplay-frame", Fredisplay_frame, 0, 2, 0, /*
9082 Ensure that FRAME's contents are correctly displayed.
9083 This differs from `redraw-frame' in that it only redraws what needs to
9084 be updated, as opposed to unconditionally clearing and redrawing
9086 FRAME defaults to the selected frame if omitted.
9087 Normally, redisplay is preempted as normal if input arrives. However,
9088 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
9089 input and is guaranteed to proceed to completion.
9091 (frame, no_preempt))
9093 struct frame *f = decode_frame (frame);
9094 int count = specpdl_depth ();
9096 if (!NILP (no_preempt))
9098 record_unwind_protect (restore_disable_preemption_value,
9099 make_int (disable_preemption));
9100 disable_preemption++;
9103 redisplay_frame (f, 1);
9105 /* If we don't reset the global redisplay flags here, subsequent
9106 changes to the display will not get registered by redisplay
9107 because it thinks it already has registered changes. If you
9108 really knew what you were doing you could confuse redisplay by
9109 calling Fredisplay_frame while updating another frame. We assume
9110 that if you know what you are doing you will not be that
9112 RESET_CHANGED_SET_FLAGS;
9114 return unbind_to (count, Qnil);
9117 DEFUN ("redraw-device", Fredraw_device, 0, 2, 0, /*
9118 Clear device DEVICE and output again what is supposed to appear on it.
9119 DEVICE defaults to the selected device if omitted.
9120 Normally, redisplay is preempted as normal if input arrives. However,
9121 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
9122 input and is guaranteed to proceed to completion.
9124 (device, no_preempt))
9126 struct device *d = decode_device (device);
9127 Lisp_Object frmcons;
9128 int count = specpdl_depth ();
9130 if (!NILP (no_preempt))
9132 record_unwind_protect (restore_disable_preemption_value,
9133 make_int (disable_preemption));
9134 disable_preemption++;
9137 DEVICE_FRAME_LOOP (frmcons, d)
9139 XFRAME (XCAR (frmcons))->clear = 1;
9141 redisplay_device (d, 0);
9143 /* See the comment in Fredisplay_frame. */
9144 RESET_CHANGED_SET_FLAGS;
9146 return unbind_to (count, Qnil);
9149 DEFUN ("redisplay-device", Fredisplay_device, 0, 2, 0, /*
9150 Ensure that DEVICE's contents are correctly displayed.
9151 This differs from `redraw-device' in that it only redraws what needs to
9152 be updated, as opposed to unconditionally clearing and redrawing
9154 DEVICE defaults to the selected device if omitted.
9155 Normally, redisplay is preempted as normal if input arrives. However,
9156 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
9157 input and is guaranteed to proceed to completion.
9159 (device, no_preempt))
9161 struct device *d = decode_device (device);
9162 int count = specpdl_depth ();
9164 if (!NILP (no_preempt))
9166 record_unwind_protect (restore_disable_preemption_value,
9167 make_int (disable_preemption));
9168 disable_preemption++;
9171 redisplay_device (d, 0);
9173 /* See the comment in Fredisplay_frame. */
9174 RESET_CHANGED_SET_FLAGS;
9176 return unbind_to (count, Qnil);
9179 /* Big lie. Big lie. This will force all modelines to be updated
9180 regardless if the all flag is set or not. It remains in existence
9181 solely for backwards compatibility. */
9182 DEFUN ("redraw-modeline", Fredraw_modeline, 0, 1, 0, /*
9183 Force the modeline of the current buffer to be redisplayed.
9184 With optional non-nil ALL, force redisplay of all modelines.
9188 MARK_MODELINE_CHANGED;
9192 DEFUN ("force-cursor-redisplay", Fforce_cursor_redisplay, 0, 1, 0, /*
9193 Force an immediate update of the cursor on FRAME.
9194 FRAME defaults to the selected frame if omitted.
9198 redisplay_redraw_cursor (decode_frame (frame), 1);
9203 /***************************************************************************/
9205 /* Lisp-variable change triggers */
9207 /***************************************************************************/
9210 margin_width_changed_in_frame (Lisp_Object specifier, struct frame *f,
9213 /* Nothing to be done? */
9217 redisplay_variable_changed (Lisp_Object sym, Lisp_Object *val,
9218 Lisp_Object in_object, int flags)
9220 /* #### clip_changed should really be renamed something like
9221 global_redisplay_change. */
9226 /* This is called if the built-in glyphs have their properties
9229 redisplay_glyph_changed (Lisp_Object glyph, Lisp_Object property,
9232 if (WINDOWP (locale))
9234 MARK_FRAME_GLYPHS_CHANGED (XFRAME (WINDOW_FRAME (XWINDOW (locale))));
9236 else if (FRAMEP (locale))
9238 MARK_FRAME_GLYPHS_CHANGED (XFRAME (locale));
9240 else if (DEVICEP (locale))
9242 Lisp_Object frmcons;
9243 DEVICE_FRAME_LOOP (frmcons, XDEVICE (locale))
9244 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9246 else if (CONSOLEP (locale))
9248 Lisp_Object frmcons, devcons;
9249 CONSOLE_FRAME_LOOP_NO_BREAK (frmcons, devcons, XCONSOLE (locale))
9250 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9252 else /* global or buffer */
9254 Lisp_Object frmcons, devcons, concons;
9255 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
9256 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9261 text_cursor_visible_p_changed (Lisp_Object specifier, struct window *w,
9264 if (XFRAME (w->frame)->init_finished)
9265 Fforce_cursor_redisplay (w->frame);
9268 #ifdef MEMORY_USAGE_STATS
9271 /***************************************************************************/
9273 /* memory usage computation */
9275 /***************************************************************************/
9278 compute_rune_dynarr_usage (rune_dynarr *dyn, struct overhead_stats *ovstats)
9280 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9284 compute_display_block_dynarr_usage (display_block_dynarr *dyn,
9285 struct overhead_stats *ovstats)
9292 total = Dynarr_memory_usage (dyn, ovstats);
9293 for (i = 0; i < Dynarr_largest (dyn); i++)
9294 total += compute_rune_dynarr_usage (Dynarr_at (dyn, i).runes, ovstats);
9300 compute_glyph_block_dynarr_usage (glyph_block_dynarr *dyn,
9301 struct overhead_stats *ovstats)
9303 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9307 compute_display_line_dynarr_usage (display_line_dynarr *dyn,
9308 struct overhead_stats *ovstats)
9315 total = Dynarr_memory_usage (dyn, ovstats);
9316 for (i = 0; i < Dynarr_largest (dyn); i++)
9318 struct display_line *dl = &Dynarr_at (dyn, i);
9319 total += compute_display_block_dynarr_usage(dl->display_blocks, ovstats);
9320 total += compute_glyph_block_dynarr_usage (dl->left_glyphs, ovstats);
9321 total += compute_glyph_block_dynarr_usage (dl->right_glyphs, ovstats);
9328 compute_line_start_cache_dynarr_usage (line_start_cache_dynarr *dyn,
9329 struct overhead_stats *ovstats)
9331 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9334 #endif /* MEMORY_USAGE_STATS */
9337 /***************************************************************************/
9339 /* initialization */
9341 /***************************************************************************/
9344 init_redisplay (void)
9346 disable_preemption = 0;
9347 preemption_count = 0;
9348 max_preempts = INIT_MAX_PREEMPTS;
9354 if (!cmotion_display_lines)
9355 cmotion_display_lines = Dynarr_new (display_line);
9356 if (!mode_spec_bufbyte_string)
9357 mode_spec_bufbyte_string = Dynarr_new (Bufbyte);
9358 if (!formatted_string_extent_dynarr)
9359 formatted_string_extent_dynarr = Dynarr_new (EXTENT);
9360 if (!formatted_string_extent_start_dynarr)
9361 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount);
9362 if (!formatted_string_extent_end_dynarr)
9363 formatted_string_extent_end_dynarr = Dynarr_new (Bytecount);
9364 if (!internal_cache)
9365 internal_cache = Dynarr_new (line_start_cache);
9368 /* window system is nil when in -batch mode */
9369 if (!initialized || noninteractive)
9372 /* If the user wants to use a window system, we shouldn't bother
9373 initializing the terminal. This is especially important when the
9374 terminal is so dumb that emacs gives up before and doesn't bother
9375 using the window system.
9377 If the DISPLAY environment variable is set, try to use X, and die
9378 with an error message if that doesn't work. */
9380 #ifdef HAVE_X_WINDOWS
9381 if (!strcmp (display_use, "x"))
9383 /* Some stuff checks this way early. */
9384 Vwindow_system = Qx;
9385 Vinitial_window_system = Qx;
9388 #endif /* HAVE_X_WINDOWS */
9391 if (!strcmp (display_use, "gtk"))
9393 Vwindow_system = Qgtk;
9394 Vinitial_window_system = Qgtk;
9399 #ifdef HAVE_MS_WINDOWS
9400 if (!strcmp (display_use, "mswindows"))
9402 /* Some stuff checks this way early. */
9403 Vwindow_system = Qmswindows;
9404 Vinitial_window_system = Qmswindows;
9407 #endif /* HAVE_MS_WINDOWS */
9410 /* If no window system has been specified, try to use the terminal. */
9413 stderr_out ("XEmacs: standard input is not a tty\n");
9417 /* Look at the TERM variable */
9418 if (!getenv ("TERM"))
9420 stderr_out ("Please set the environment variable TERM; see tset(1).\n");
9424 Vinitial_window_system = Qtty;
9426 #else /* not HAVE_TTY */
9427 /* No DISPLAY specified, and no TTY support. */
9428 stderr_out ("XEmacs: Cannot open display.\n\
9429 Please set the environmental variable DISPLAY to an appropriate value.\n");
9436 syms_of_redisplay (void)
9438 defsymbol (&Qcursor_in_echo_area, "cursor-in-echo-area");
9439 #ifndef INHIBIT_REDISPLAY_HOOKS
9440 defsymbol (&Qpre_redisplay_hook, "pre-redisplay-hook");
9441 defsymbol (&Qpost_redisplay_hook, "post-redisplay-hook");
9442 #endif /* INHIBIT_REDISPLAY_HOOKS */
9443 defsymbol (&Qdisplay_warning_buffer, "display-warning-buffer");
9444 defsymbol (&Qbar_cursor, "bar-cursor");
9445 defsymbol (&Qredisplay_end_trigger_functions,
9446 "redisplay-end-trigger-functions");
9447 defsymbol (&Qtop_bottom, "top-bottom");
9448 defsymbol (&Qbuffer_list_changed_hook, "buffer-list-changed-hook");
9450 DEFSUBR (Fredisplay_echo_area);
9451 DEFSUBR (Fredraw_frame);
9452 DEFSUBR (Fredisplay_frame);
9453 DEFSUBR (Fredraw_device);
9454 DEFSUBR (Fredisplay_device);
9455 DEFSUBR (Fredraw_modeline);
9456 DEFSUBR (Fforce_cursor_redisplay);
9460 vars_of_redisplay (void)
9464 staticpro (&last_arrow_position);
9465 staticpro (&last_arrow_string);
9466 last_arrow_position = Qnil;
9467 last_arrow_string = Qnil;
9470 /* #### Probably temporary */
9471 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /*
9472 \(Temporary) Setting this will impact the performance of the internal
9475 cache_adjustment = 2;
9477 DEFVAR_INT_MAGIC ("pixel-vertical-clip-threshold", &vertical_clip /*
9478 Minimum pixel height for clipped bottom display line.
9479 A clipped line shorter than this won't be displayed.
9481 redisplay_variable_changed);
9484 DEFVAR_INT_MAGIC ("pixel-horizontal-clip-threshold", &horizontal_clip /*
9485 Minimum visible area for clipped glyphs at right boundary.
9486 Clipped glyphs shorter than this won't be displayed.
9487 Only pixmap glyph instances are currently allowed to be clipped.
9489 redisplay_variable_changed);
9490 horizontal_clip = 5;
9492 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string /*
9493 String displayed by modeline-format's "%m" specification.
9495 Vglobal_mode_string = Qnil;
9497 DEFVAR_LISP_MAGIC ("overlay-arrow-position", &Voverlay_arrow_position /*
9498 Marker for where to display an arrow on top of the buffer text.
9499 This must be the beginning of a line in order to work.
9500 See also `overlay-arrow-string'.
9502 redisplay_variable_changed);
9503 Voverlay_arrow_position = Qnil;
9505 DEFVAR_LISP_MAGIC ("overlay-arrow-string", &Voverlay_arrow_string /*
9506 String or glyph to display as an arrow. See also `overlay-arrow-position'.
9507 \(Note that despite the name of this variable, it can be set to a glyph as
9510 redisplay_variable_changed);
9511 Voverlay_arrow_string = Qnil;
9513 DEFVAR_INT ("scroll-step", &scroll_step /*
9514 *The number of lines to try scrolling a window by when point moves out.
9515 If that fails to bring point back on frame, point is centered instead.
9516 If this is zero, point is always centered after it moves off screen.
9520 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively /*
9521 *Scroll up to this many lines, to bring point back on screen.
9523 scroll_conservatively = 0;
9525 DEFVAR_BOOL_MAGIC ("truncate-partial-width-windows",
9526 &truncate_partial_width_windows /*
9527 *Non-nil means truncate lines in all windows less than full frame wide.
9529 redisplay_variable_changed);
9530 truncate_partial_width_windows = 1;
9532 DEFVAR_LISP ("visible-bell", &Vvisible_bell /*
9533 *Non-nil substitutes a visual signal for the audible bell.
9535 Default behavior is to flash the whole screen. On some platforms,
9536 special effects are available using the following values:
9538 'display Flash the whole screen (ie, the default behavior).
9539 'top-bottom Flash only the top and bottom lines of the selected frame.
9541 When effects are unavailable on a platform, the visual bell is the
9542 default, whole screen. (Currently only X supports any special effects.)
9544 Vvisible_bell = Qnil;
9546 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter /*
9547 *Non-nil means no need to redraw entire frame after suspending.
9548 A non-nil value is useful if the terminal can automatically preserve
9549 Emacs's frame display when you reenter Emacs.
9550 It is up to you to set this variable if your terminal can do that.
9552 no_redraw_on_reenter = 0;
9554 DEFVAR_LISP ("window-system", &Vwindow_system /*
9555 A symbol naming the window-system under which Emacs is running,
9556 such as `x', or nil if emacs is running on an ordinary terminal.
9558 Do not use this variable, except for GNU Emacs compatibility, as it
9559 gives wrong values in a multi-device environment. Use `console-type'
9562 Vwindow_system = Qnil;
9564 /* #### Temporary shit until window-system is eliminated. */
9565 DEFVAR_CONST_LISP ("initial-window-system", &Vinitial_window_system /*
9568 Vinitial_window_system = Qnil;
9570 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area /*
9571 Non-nil means put cursor in minibuffer, at end of any message there.
9573 cursor_in_echo_area = 0;
9575 /* #### Shouldn't this be generalized as follows:
9577 if nil, use block cursor.
9578 if a number, use a bar cursor of that width.
9579 Otherwise, use a 1-pixel bar cursor.
9581 #### Or better yet, this variable should be trashed entirely
9582 (use a Lisp-magic variable to maintain compatibility)
9583 and a specifier `cursor-shape' added, which allows a block
9584 cursor, a bar cursor, a flashing block or bar cursor,
9585 maybe a caret cursor, etc. */
9587 DEFVAR_LISP ("bar-cursor", &Vbar_cursor /*
9588 *Use vertical bar cursor if non-nil. If t width is 1 pixel, otherwise 2.
9592 #ifndef INHIBIT_REDISPLAY_HOOKS
9593 xxDEFVAR_LISP ("pre-redisplay-hook", &Vpre_redisplay_hook /*
9594 Function or functions to run before every redisplay.
9596 Vpre_redisplay_hook = Qnil;
9598 xxDEFVAR_LISP ("post-redisplay-hook", &Vpost_redisplay_hook /*
9599 Function or functions to run after every redisplay.
9601 Vpost_redisplay_hook = Qnil;
9602 #endif /* INHIBIT_REDISPLAY_HOOKS */
9604 DEFVAR_LISP ("buffer-list-changed-hook", &Vbuffer_list_changed_hook /*
9605 Function or functions to call when a frame's buffer list has changed.
9606 This is called during redisplay, before redisplaying each frame.
9607 Functions on this hook are called with one argument, the frame.
9609 Vbuffer_list_changed_hook = Qnil;
9611 DEFVAR_INT ("display-warning-tick", &display_warning_tick /*
9612 Bump this to tell the C code to call `display-warning-buffer'
9613 at next redisplay. You should not normally change this; the function
9614 `display-warning' automatically does this at appropriate times.
9616 display_warning_tick = 0;
9618 DEFVAR_BOOL ("inhibit-warning-display", &inhibit_warning_display /*
9619 Non-nil means inhibit display of warning messages.
9620 You should *bind* this, not set it. Any pending warning messages
9621 will be displayed when the binding no longer applies.
9623 /* reset to 0 by startup.el after the splash screen has displayed.
9624 This way, the warnings don't obliterate the splash screen. */
9625 inhibit_warning_display = 1;
9627 DEFVAR_LISP ("window-size-change-functions",
9628 &Vwindow_size_change_functions /*
9629 Not currently implemented.
9630 Functions called before redisplay, if window sizes have changed.
9631 The value should be a list of functions that take one argument.
9632 Just before redisplay, for each frame, if any of its windows have changed
9633 size since the last redisplay, or have been split or deleted,
9634 all the functions in the list are called, with the frame as argument.
9636 Vwindow_size_change_functions = Qnil;
9638 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions /*
9639 Not currently implemented.
9640 Functions to call before redisplaying a window with scrolling.
9641 Each function is called with two arguments, the window
9642 and its new display-start position. Note that the value of `window-end'
9643 is not valid when these functions are called.
9645 Vwindow_scroll_functions = Qnil;
9647 DEFVAR_LISP ("redisplay-end-trigger-functions",
9648 &Vredisplay_end_trigger_functions /*
9649 See `set-window-redisplay-end-trigger'.
9651 Vredisplay_end_trigger_functions = Qnil;
9653 DEFVAR_BOOL ("column-number-start-at-one", &column_number_start_at_one /*
9654 *Non-nil means column display number starts at 1.
9656 column_number_start_at_one = 0;
9660 specifier_vars_of_redisplay (void)
9662 DEFVAR_SPECIFIER ("left-margin-width", &Vleft_margin_width /*
9663 *Width of left margin.
9664 This is a specifier; use `set-specifier' to change it.
9666 Vleft_margin_width = Fmake_specifier (Qnatnum);
9667 set_specifier_fallback (Vleft_margin_width, list1 (Fcons (Qnil, Qzero)));
9668 set_specifier_caching (Vleft_margin_width,
9669 offsetof (struct window, left_margin_width),
9670 some_window_value_changed,
9671 offsetof (struct frame, left_margin_width),
9672 margin_width_changed_in_frame, 0);
9674 DEFVAR_SPECIFIER ("right-margin-width", &Vright_margin_width /*
9675 *Width of right margin.
9676 This is a specifier; use `set-specifier' to change it.
9678 Vright_margin_width = Fmake_specifier (Qnatnum);
9679 set_specifier_fallback (Vright_margin_width, list1 (Fcons (Qnil, Qzero)));
9680 set_specifier_caching (Vright_margin_width,
9681 offsetof (struct window, right_margin_width),
9682 some_window_value_changed,
9683 offsetof (struct frame, right_margin_width),
9684 margin_width_changed_in_frame, 0);
9686 DEFVAR_SPECIFIER ("minimum-line-ascent", &Vminimum_line_ascent /*
9687 *Minimum ascent height of lines.
9688 This is a specifier; use `set-specifier' to change it.
9690 Vminimum_line_ascent = Fmake_specifier (Qnatnum);
9691 set_specifier_fallback (Vminimum_line_ascent, list1 (Fcons (Qnil, Qzero)));
9692 set_specifier_caching (Vminimum_line_ascent,
9693 offsetof (struct window, minimum_line_ascent),
9694 some_window_value_changed,
9697 DEFVAR_SPECIFIER ("minimum-line-descent", &Vminimum_line_descent /*
9698 *Minimum descent height of lines.
9699 This is a specifier; use `set-specifier' to change it.
9701 Vminimum_line_descent = Fmake_specifier (Qnatnum);
9702 set_specifier_fallback (Vminimum_line_descent, list1 (Fcons (Qnil, Qzero)));
9703 set_specifier_caching (Vminimum_line_descent,
9704 offsetof (struct window, minimum_line_descent),
9705 some_window_value_changed,
9708 DEFVAR_SPECIFIER ("use-left-overflow", &Vuse_left_overflow /*
9709 *Non-nil means use the left outside margin as extra whitespace when
9710 displaying 'whitespace or 'inside-margin glyphs.
9711 This is a specifier; use `set-specifier' to change it.
9713 Vuse_left_overflow = Fmake_specifier (Qboolean);
9714 set_specifier_fallback (Vuse_left_overflow, list1 (Fcons (Qnil, Qnil)));
9715 set_specifier_caching (Vuse_left_overflow,
9716 offsetof (struct window, use_left_overflow),
9717 some_window_value_changed,
9720 DEFVAR_SPECIFIER ("use-right-overflow", &Vuse_right_overflow /*
9721 *Non-nil means use the right outside margin as extra whitespace when
9722 displaying 'whitespace or 'inside-margin glyphs.
9723 This is a specifier; use `set-specifier' to change it.
9725 Vuse_right_overflow = Fmake_specifier (Qboolean);
9726 set_specifier_fallback (Vuse_right_overflow, list1 (Fcons (Qnil, Qnil)));
9727 set_specifier_caching (Vuse_right_overflow,
9728 offsetof (struct window, use_right_overflow),
9729 some_window_value_changed,
9732 DEFVAR_SPECIFIER ("text-cursor-visible-p", &Vtext_cursor_visible_p /*
9733 *Non-nil means the text cursor is visible (this is usually the case).
9734 This is a specifier; use `set-specifier' to change it.
9736 Vtext_cursor_visible_p = Fmake_specifier (Qboolean);
9737 set_specifier_fallback (Vtext_cursor_visible_p, list1 (Fcons (Qnil, Qt)));
9738 set_specifier_caching (Vtext_cursor_visible_p,
9739 offsetof (struct window, text_cursor_visible_p),
9740 text_cursor_visible_p_changed,