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 ****************************************************************************/
59 #include "redisplay.h"
62 #include "line-number.h"
64 #include "file-coding.h"
68 #include "console-tty.h"
70 #include <unistd.h> /* for isatty() */
74 /* Note: We have to be careful throughout this code to properly handle
75 and differentiate between Bufbytes and Emchars.
77 Since strings are generally composed of Bufbytes, I've taken the tack
78 that any contiguous set of Bufbytes is called a "string", while
79 any contiguous set of Emchars is called an "array". */
81 /* Return value to indicate a failure by an add_*_rune routine to add
82 a rune, but no propagation information needs to be returned. */
83 #define ADD_FAILED (prop_block_dynarr *) 1
85 #define BEGIN_GLYPHS 0
88 #define RIGHT_GLYPHS 3
90 /* Set the vertical clip to 0 if we are currently updating the line
91 start cache. Otherwise for buffers of line height 1 it may fail to
92 be able to work properly because regenerate_window will not layout
94 #define VERTICAL_CLIP(w, display) \
95 (updating_line_start_cache \
97 : ((WINDOW_TTY_P (w) | (!display && scroll_on_clipped_lines)) \
101 /* The following structures are completely private to redisplay.c so
102 we put them here instead of in a header file, for modularity. */
104 /* NOTE: Bytinds not Bufpos's in this structure. */
106 typedef struct position_redisplay_data_type
108 /* This information is normally filled in by the create_*_block
109 routines and is used by the add_*_rune routines. */
111 /* if we are working with strings rather than buffers we need a
112 handle to the string */
115 struct display_block *db;
116 struct display_line *dl;
117 Emchar ch; /* Character that is to be added. This is
118 used to communicate this information to
119 add_emchar_rune(). */
120 Lisp_Object last_charset; /* The charset of the previous character.
121 Used to optimize some lookups -- we
122 only have to do some things when
123 the charset changes. */
124 face_index last_findex; /* The face index of the previous character.
125 Needed to ensure the validity of the
126 last_charset optimization. */
128 int last_char_width; /* The width of the previous character. */
129 int font_is_bogus; /* If true, it means we couldn't instantiate
130 the font for this charset, so we substitute
131 ~'s from the ASCII charset. */
136 int blank_width; /* Width of the blank that is to be added.
137 This is used to communicate this information
140 This is also used rather cheesily to
141 communicate the width of the eol-cursor-size
142 blank that exists at the end of the line.
143 add_emchar_rune() is called cheesily with
144 the non-printing char '\n', which is stuck
145 in the output routines with its width being
147 Bytind bi_cursor_bufpos;/* This stores the buffer position of the cursor. */
148 unsigned int cursor_type :3;
149 int cursor_x; /* rune block cursor is at */
150 int start_col; /* Number of character columns (each column has
151 a width of the default char width) that still
152 need to be skipped. This is used for horizontal
153 scrolling, where a certain number of columns
154 (those off the left side of the screen) need
155 to be skipped before anything is displayed. */
156 Bytind bi_start_col_enabled;
157 int start_col_xoffset; /* Number of pixels that still need to
158 be skipped. This is used for
159 horizontal scrolling of glyphs, where we want
160 to be able to scroll over part of the glyph. */
162 int hscroll_glyph_width_adjust; /* how much the width of the hscroll
163 glyph differs from space_width (w).
164 0 if no hscroll glyph was used,
165 i.e. the window is not scrolled
166 horizontally. Used in tab
169 /* Information about the face the text should be displayed in and
170 any begin-glyphs and end-glyphs. */
171 struct extent_fragment *ef;
174 /* The height of a pixmap may either be predetermined if the user
175 has set a baseline value, or it may be dependent on whatever the
176 line ascent and descent values end up being, based just on font
177 information. In the first case we can immediately update the
178 values, thus their inclusion here. In the last case we cannot
179 determine the actual contribution to the line height until we
180 have finished laying out all text on the line. Thus we propagate
181 the max height of such pixmaps and do a final calculation after
182 all text has been added to the line. */
185 int max_pixmap_height;
187 Lisp_Object result_str; /* String where we put the result of
188 generating a formatted string in the modeline. */
189 int is_modeline; /* Non-zero if we're generating the modeline. */
190 Charcount modeline_charpos; /* Number of chars used in result_str so far;
191 corresponds to bytepos. */
192 Bytecount bytepos; /* Number of bytes used in result_str so far.
193 We don't actually copy the bytes into result_str
194 until the end because we don't know how big the
195 string is going to be until then. */
206 /* Data that should be propagated to the next line. Either a single
207 Emchar or a string of Bufbyte's.
209 The actual data that is propagated ends up as a Dynarr of these
212 #### It's unclean that both Emchars and Bufbytes are here.
215 typedef struct prop_block prop_block;
225 Bytecount len; /* length of the string. */
231 Bytind bi_cursor_bufpos; /* NOTE: is in Bytinds */
232 unsigned int cursor_type :3;
245 Dynarr_declare (prop_block);
249 static Charcount generate_fstring_runes (struct window *w, pos_data *data,
250 Charcount pos, Charcount min_pos,
251 Charcount max_pos, Lisp_Object elt,
252 int depth, int max_pixsize,
253 face_index findex, int type,
255 Lisp_Object cur_ext);
256 static prop_block_dynarr *add_glyph_rune (pos_data *data,
257 struct glyph_block *gb,
258 int pos_type, int allow_cursor,
259 struct glyph_cachel *cachel);
260 static Bytind create_text_block (struct window *w, struct display_line *dl,
261 Bytind bi_start_pos, prop_block_dynarr **prop,
263 static int create_overlay_glyph_block (struct window *w,
264 struct display_line *dl);
265 static void create_left_glyph_block (struct window *w,
266 struct display_line *dl,
268 static void create_right_glyph_block (struct window *w,
269 struct display_line *dl);
270 static void redisplay_windows (Lisp_Object window, int skip_selected);
271 static void decode_mode_spec (struct window *w, Emchar spec, int type);
272 static void free_display_line (struct display_line *dl);
273 static void update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
274 Bufpos point, int no_regen);
275 static int point_visible (struct window *w, Bufpos point, int type);
277 /* This used to be 10 but 30 seems to give much better performance. */
278 #define INIT_MAX_PREEMPTS 30
279 static int max_preempts;
281 #define REDISPLAY_PREEMPTION_CHECK \
284 (!disable_preemption && \
285 ((preemption_count < max_preempts) || !NILP (Vexecuting_macro)) && \
286 (!INTERACTIVE || detect_input_pending ()))))
289 * Redisplay global variables.
292 /* We need a third set of display structures for the cursor motion
293 routines. We used to just give each window a third set. However,
294 we always fully regenerate the structures when needed so there
295 isn't any reason we need more than a single set. */
296 display_line_dynarr *cmotion_display_lines;
298 /* We store the extents that we need to generate in a Dynarr and then
299 frob them all on at the end of generating the string. We do it
300 this way rather than adding them as we generate the string because
301 we don't store the text into the resulting string until we're done
302 (to avoid having to resize the string multiple times), and we don't
303 want to go around adding extents to a string when the extents might
304 stretch off the end of the string. */
305 static EXTENT_dynarr *formatted_string_extent_dynarr;
306 static Bytecount_dynarr *formatted_string_extent_start_dynarr;
307 static Bytecount_dynarr *formatted_string_extent_end_dynarr;
310 /* #### probably temporary */
311 int cache_adjustment;
313 /* This holds a string representing the text corresponding to a single
315 static Bufbyte_dynarr *mode_spec_bufbyte_string;
317 int in_display; /* 1 if in redisplay. */
319 int disable_preemption; /* Used for debugging redisplay and for
322 /* We only allow max_preempts preemptions before we force a redisplay. */
323 static int preemption_count;
325 /* Minimum pixel height of clipped bottom display line. */
328 /* Minimum visible pixel width of clipped glyphs at right margin. */
331 /* Set if currently inside update_line_start_cache. */
332 static int updating_line_start_cache;
334 /* Nonzero means reading single-character input with prompt
335 so put cursor on minibuffer after the prompt. */
336 int cursor_in_echo_area;
337 Lisp_Object Qcursor_in_echo_area;
339 /* Nonzero means truncate lines in all windows less wide than the frame */
340 int truncate_partial_width_windows;
342 /* non-nil if a buffer has changed since the last time redisplay completed */
344 int buffers_changed_set;
346 /* non-nil if hscroll has changed somewhere or a buffer has been
347 narrowed or widened */
349 int clip_changed_set;
351 /* non-nil if any extent has changed since the last time redisplay completed */
353 int extents_changed_set;
355 /* non-nil if any face has changed since the last time redisplay completed */
358 /* Nonzero means some frames have been marked as garbaged */
361 /* non-zero if any of the builtin display glyphs (continuation,
362 hscroll, control-arrow, etc) is in need of updating
365 int glyphs_changed_set;
367 /* non-zero if any subwindow has been deleted. */
368 int subwindows_changed;
369 int subwindows_changed_set;
371 /* non-zero if any displayed subwindow is in need of updating
373 int subwindows_state_changed;
374 int subwindows_state_changed_set;
376 /* This variable is 1 if the icon has to be updated.
377 It is set to 1 when `frame-icon-glyph' changes. */
379 int icon_changed_set;
381 /* This variable is 1 if the menubar widget has to be updated.
382 It is set to 1 by set-menubar-dirty-flag and cleared when the widget
385 int menubar_changed_set;
387 /* true iff we should redraw the modelines on the next redisplay */
388 int modeline_changed;
389 int modeline_changed_set;
391 /* non-nil if point has changed in some buffer since the last time
392 redisplay completed */
394 int point_changed_set;
396 /* non-nil if some frame has changed its size */
399 /* non-nil if some device has signaled that it wants to change size */
400 int asynch_device_change_pending;
402 /* non-nil if any toolbar has changed */
404 int toolbar_changed_set;
406 /* non-nil if any gutter has changed */
408 int gutter_changed_set;
410 /* non-nil if any window has changed since the last time redisplay completed */
413 /* non-nil if any frame's window structure has changed since the last
414 time redisplay completed */
415 int windows_structure_changed;
417 /* If non-nil, use vertical bar cursor. */
418 Lisp_Object Vbar_cursor;
419 Lisp_Object Qbar_cursor;
421 Lisp_Object Vvisible_bell; /* If true and the terminal will support it
422 then the frame will flash instead of
423 beeping when an error occurs */
425 /* Nonzero means no need to redraw the entire frame on resuming
426 a suspended Emacs. This is useful on terminals with multiple pages,
427 where one page is used for Emacs and another for all else. */
428 int no_redraw_on_reenter;
430 Lisp_Object Vwindow_system; /* nil or a symbol naming the window system
431 under which emacs is running
432 ('x is the only current possibility) */
433 Lisp_Object Vinitial_window_system;
435 Lisp_Object Vglobal_mode_string;
437 /* The number of lines scroll a window by when point leaves the window; if
438 it is <=0 then point is centered in the window */
441 /* Scroll up to this many lines, to bring point back on screen. */
442 int scroll_conservatively;
444 /* Marker for where to display an arrow on top of the buffer text. */
445 Lisp_Object Voverlay_arrow_position;
446 /* String to display for the arrow. */
447 Lisp_Object Voverlay_arrow_string;
449 Lisp_Object Vwindow_size_change_functions;
450 Lisp_Object Vwindow_scroll_functions;
451 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
453 Lisp_Object Qbuffer_list_changed_hook, Vbuffer_list_changed_hook;
456 #define INHIBIT_REDISPLAY_HOOKS /* #### Until we've thought about
458 #ifndef INHIBIT_REDISPLAY_HOOKS
459 /* #### Chuck says: I think this needs more thought.
460 Think about this for 19.14. */
461 Lisp_Object Vpre_redisplay_hook, Vpost_redisplay_hook;
462 Lisp_Object Qpre_redisplay_hook, Qpost_redisplay_hook;
463 #endif /* INHIBIT_REDISPLAY_HOOKS */
465 static int last_display_warning_tick, display_warning_tick;
466 Lisp_Object Qdisplay_warning_buffer;
467 int inhibit_warning_display;
469 Lisp_Object Vleft_margin_width, Vright_margin_width;
470 Lisp_Object Vminimum_line_ascent, Vminimum_line_descent;
471 Lisp_Object Vuse_left_overflow, Vuse_right_overflow;
472 Lisp_Object Vtext_cursor_visible_p;
474 int column_number_start_at_one;
476 Lisp_Object Qtop_bottom;
478 #define WINDOW_SCROLLED(w) \
479 (w->hscroll > 0 || w->left_xoffset)
482 /***************************************************************************/
484 /* low-level interfaces onto device routines */
486 /***************************************************************************/
489 redisplay_text_width_emchar_string (struct window *w, int findex,
490 Emchar *str, Charcount len)
492 Charset_ID charsets[NUM_LEADING_BYTES];
495 find_charsets_in_emchar_string (charsets, str, len);
496 XSETWINDOW (window, w);
497 ensure_face_cachel_complete (WINDOW_FACE_CACHEL (w, findex), window,
499 return DEVMETH (XDEVICE (FRAME_DEVICE (XFRAME (WINDOW_FRAME (w)))),
500 text_width, (XFRAME (WINDOW_FRAME (w)),
501 WINDOW_FACE_CACHEL (w, findex), str, len));
504 static Emchar_dynarr *rtw_emchar_dynarr;
507 redisplay_text_width_string (struct window *w, int findex,
508 Bufbyte *nonreloc, Lisp_Object reloc,
509 Bytecount offset, Bytecount len)
511 if (!rtw_emchar_dynarr)
512 rtw_emchar_dynarr = Dynarr_new (Emchar);
513 Dynarr_reset (rtw_emchar_dynarr);
515 fixup_internal_substring (nonreloc, reloc, offset, &len);
517 nonreloc = XSTRING_DATA (reloc);
518 convert_bufbyte_string_into_emchar_dynarr (nonreloc, len, rtw_emchar_dynarr);
519 return redisplay_text_width_emchar_string
520 (w, findex, Dynarr_atp (rtw_emchar_dynarr, 0),
521 Dynarr_length (rtw_emchar_dynarr));
525 redisplay_frame_text_width_string (struct frame *f, Lisp_Object face,
526 Bufbyte *nonreloc, Lisp_Object reloc,
527 Bytecount offset, Bytecount len)
529 Charset_ID charsets[NUM_LEADING_BYTES];
531 struct face_cachel cachel;
533 if (!rtw_emchar_dynarr)
534 rtw_emchar_dynarr = Dynarr_new (Emchar);
535 Dynarr_reset (rtw_emchar_dynarr);
537 fixup_internal_substring (nonreloc, reloc, offset, &len);
539 nonreloc = XSTRING_DATA (reloc);
540 convert_bufbyte_string_into_emchar_dynarr (nonreloc, len, rtw_emchar_dynarr);
541 find_charsets_in_bufbyte_string (charsets, nonreloc, len);
542 reset_face_cachel (&cachel);
544 XSETFRAME (frame, f);
545 ensure_face_cachel_complete (&cachel, frame, charsets);
546 return DEVMETH (XDEVICE (FRAME_DEVICE (f)),
547 text_width, (f, &cachel, Dynarr_atp (rtw_emchar_dynarr, 0),
548 Dynarr_length (rtw_emchar_dynarr)));
551 /* Return the display block from DL of the given TYPE. A display line
552 can have only one display block of each possible type. If DL does
553 not have a block of type TYPE, one will be created and added to DL. */
555 struct display_block *
556 get_display_block_from_line (struct display_line *dl, enum display_type type)
559 struct display_block db;
561 /* Check if this display line already has a block of the desired type and
563 if (dl->display_blocks)
565 for (elt = 0; elt < Dynarr_length (dl->display_blocks); elt++)
567 if (Dynarr_at (dl->display_blocks, elt).type == type)
568 return Dynarr_atp (dl->display_blocks, elt);
571 /* There isn't an active block of the desired type, but there
572 might still be allocated blocks we need to reuse. */
573 if (elt < Dynarr_largest (dl->display_blocks))
575 struct display_block *dbp = Dynarr_atp (dl->display_blocks, elt);
577 /* 'add' the block to the list */
578 Dynarr_increment (dl->display_blocks);
580 /* initialize and return */
587 /* This line doesn't have any display blocks, so initialize the display
589 dl->display_blocks = Dynarr_new (display_block);
592 /* The line doesn't have a block of the desired type so go ahead and create
593 one and add it to the line. */
596 db.runes = Dynarr_new (rune);
597 Dynarr_add (dl->display_blocks, db);
599 /* Return the newly added display block. */
600 elt = Dynarr_length (dl->display_blocks) - 1;
602 return Dynarr_atp (dl->display_blocks, elt);
606 tab_char_width (struct window *w)
608 struct buffer *b = XBUFFER (w->buffer);
609 int char_tab_width = XINT (b->tab_width);
611 if (char_tab_width <= 0 || char_tab_width > 1000) char_tab_width = 8;
613 return char_tab_width;
617 space_width (struct window *w)
619 /* While tabs are traditional composed of spaces, for variable-width
620 fonts the space character tends to give too narrow a value. So
621 we use 'n' instead. Except that we don't. We use the default
622 character width for the default face. If this is actually
623 defined by the font then it is probably the best thing to
624 actually use. If it isn't, we have assumed it is 'n' and have
625 already calculated its width. Thus we can avoid a call to
626 XTextWidth on X frames by just querying the default width. */
627 return XFONT_INSTANCE
628 (WINDOW_FACE_CACHEL_FONT (w, DEFAULT_INDEX, Vcharset_ascii))->width;
632 tab_pix_width (struct window *w)
634 return space_width (w) * tab_char_width (w);
637 /* Given a pixel position in a window, return the pixel location of
638 the next tabstop. Tabs are calculated from the left window edge in
639 terms of spaces displayed in the default face. Formerly the space
640 width was determined using the currently active face. That method
641 leads to tabstops which do not line up. */
644 next_tab_position (struct window *w, int start_pixpos, int left_pixpos)
646 int n_pos = left_pixpos;
647 int pix_tab_width = tab_pix_width (w);
649 /* Adjust n_pos for any hscrolling which has happened. */
650 if (WINDOW_SCROLLED (w))
651 n_pos -= space_width (w) * (w->hscroll - 1) + w->left_xoffset;
653 while (n_pos <= start_pixpos)
654 n_pos += pix_tab_width;
659 /* For the given window, calculate the outside and margin boundaries for a
660 display line. The whitespace boundaries must be calculated by the text
664 calculate_display_line_boundaries (struct window *w, int modeline)
666 layout_bounds bounds;
668 /* Set the outermost boundaries which are the boundaries of the
669 window itself minus the gutters (and minus the scrollbars if this
670 is for the modeline). */
673 bounds.left_out = WINDOW_TEXT_LEFT (w);
674 bounds.right_out = WINDOW_TEXT_RIGHT (w);
678 bounds.left_out = WINDOW_MODELINE_LEFT (w);
679 bounds.right_out = WINDOW_MODELINE_RIGHT (w);
682 /* The inner boundaries mark where the glyph margins are located. */
683 bounds.left_in = bounds.left_out + window_left_margin_width (w);
684 bounds.right_in = bounds.right_out - window_right_margin_width (w);
686 /* We cannot fully calculate the whitespace boundaries as they
687 depend on the contents of the line being displayed. */
688 bounds.left_white = bounds.left_in;
689 bounds.right_white = bounds.right_in;
694 /* Given a display line and a starting position, ensure that the
695 contents of the display line accurately represent the visual
696 representation of the buffer contents starting from the given
697 position when displayed in the given window. The display line ends
698 when the contents of the line reach the right boundary of the given
702 generate_display_line (struct window *w, struct display_line *dl, int bounds,
703 Bufpos start_pos, prop_block_dynarr **prop,
708 struct buffer *b = XBUFFER (WINDOW_BUFFER (w));
710 /* If our caller hasn't already set the boundaries, then do so now. */
712 dl->bounds = calculate_display_line_boundaries (w, 0);
714 /* Reset what this line is using. */
715 if (dl->display_blocks)
716 Dynarr_reset (dl->display_blocks);
719 Dynarr_free (dl->left_glyphs);
722 if (dl->right_glyphs)
724 Dynarr_free (dl->right_glyphs);
725 dl->right_glyphs = 0;
728 /* We aren't generating a modeline at the moment. */
731 /* Create a display block for the text region of the line. */
733 /* #### urk urk urk!!! Chuck fix this shit! */
734 Bytind hacked_up_bytind =
735 create_text_block (w, dl, bufpos_to_bytind (b, start_pos),
737 if (hacked_up_bytind > BI_BUF_ZV (b))
738 ret_bufpos = BUF_ZV (b) + 1;
740 ret_bufpos = bytind_to_bufpos (b, hacked_up_bytind);
742 dl->bufpos = start_pos;
743 if (dl->end_bufpos < dl->bufpos)
744 dl->end_bufpos = dl->bufpos;
746 if (MARKERP (Voverlay_arrow_position)
747 && EQ (w->buffer, Fmarker_buffer (Voverlay_arrow_position))
748 && start_pos == marker_position (Voverlay_arrow_position)
749 && (STRINGP (Voverlay_arrow_string)
750 || GLYPHP (Voverlay_arrow_string)))
752 overlay_width = create_overlay_glyph_block (w, dl);
757 /* If there are left glyphs associated with any character in the
758 text block, then create a display block to handle them. */
759 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
760 create_left_glyph_block (w, dl, overlay_width);
762 /* If there are right glyphs associated with any character in the
763 text block, then create a display block to handle them. */
764 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
765 create_right_glyph_block (w, dl);
767 /* In the future additional types of display blocks may be generated
770 w->last_redisplay_pos = ret_bufpos;
775 /* Adds an hscroll glyph to a display block. If this is called, then
776 the block had better be empty.
778 Yes, there are multiple places where this function is called but
779 that is the way it has to be. Each calling function has to deal
780 with bi_start_col_enabled a little differently depending on the
781 object being worked with. */
783 static prop_block_dynarr *
784 add_hscroll_rune (pos_data *data)
786 struct glyph_block gb;
787 prop_block_dynarr *retval;
788 Bytind bi_old_cursor_bufpos = data->bi_cursor_bufpos;
789 unsigned int old_cursor_type = data->cursor_type;
790 Bytind bi_old_bufpos = data->bi_bufpos;
792 if (data->cursor_type == CURSOR_ON
793 && data->bi_cursor_bufpos >= data->bi_start_col_enabled
794 && data->bi_cursor_bufpos <= data->bi_bufpos)
796 data->bi_cursor_bufpos = data->bi_start_col_enabled;
800 data->cursor_type = NO_CURSOR;
803 data->bi_endpos = data->bi_bufpos;
804 data->bi_bufpos = data->bi_start_col_enabled;
807 gb.glyph = Vhscroll_glyph;
809 int oldpixpos = data->pixpos;
810 retval = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0,
811 GLYPH_CACHEL (XWINDOW (data->window),
812 HSCROLL_GLYPH_INDEX));
813 data->hscroll_glyph_width_adjust =
814 data->pixpos - oldpixpos - space_width (XWINDOW (data->window));
817 data->bi_cursor_bufpos = bi_old_cursor_bufpos;
818 data->cursor_type = old_cursor_type;
819 data->bi_bufpos = bi_old_bufpos;
821 data->bi_start_col_enabled = 0;
825 /* Adds a character rune to a display block. If there is not enough
826 room to fit the rune on the display block (as determined by the
827 MAX_PIXPOS) then it adds nothing and returns ADD_FAILED. */
829 static prop_block_dynarr *
830 add_emchar_rune (pos_data *data)
832 struct rune rb, *crb;
843 if (data->bi_start_col_enabled)
845 return add_hscroll_rune (data);
848 if (data->ch == '\n')
850 data->font_is_bogus = 0;
851 /* Cheesy end-of-line pseudo-character. */
852 width = data->blank_width;
856 Lisp_Object charset = CHAR_CHARSET (data->ch);
857 if (!EQ (charset, data->last_charset) ||
858 data->findex != data->last_findex)
860 /* OK, we need to do things the hard way. */
861 struct window *w = XWINDOW (data->window);
862 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, data->findex);
863 Lisp_Object font_instance =
864 ensure_face_cachel_contains_charset (cachel, data->window,
866 Lisp_Font_Instance *fi;
868 if (EQ (font_instance, Vthe_null_font_instance))
870 font_instance = FACE_CACHEL_FONT (cachel, Vcharset_ascii);
871 data->font_is_bogus = 1;
874 data->font_is_bogus = 0;
876 fi = XFONT_INSTANCE (font_instance);
877 if (!fi->proportional_p)
878 /* sweetness and light. */
879 data->last_char_width = fi->width;
881 data->last_char_width = -1;
882 data->new_ascent = max (data->new_ascent, (int) fi->ascent);
883 data->new_descent = max (data->new_descent, (int) fi->descent);
884 data->last_charset = charset;
885 data->last_findex = data->findex;
888 width = data->last_char_width;
891 /* bummer. Proportional fonts. */
892 width = redisplay_text_width_emchar_string (XWINDOW (data->window),
898 if (data->max_pixpos != -1 && (data->pixpos + width > data->max_pixpos))
903 if (Dynarr_length (data->db->runes) < Dynarr_largest (data->db->runes))
905 crb = Dynarr_atp (data->db->runes, Dynarr_length (data->db->runes));
914 crb->findex = data->findex;
915 crb->xpos = data->pixpos;
919 if (NILP (data->string))
921 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
925 bytecount_to_charcount (XSTRING_DATA (data->string), data->bi_bufpos);
927 else if (data->is_modeline)
928 crb->bufpos = data->modeline_charpos;
930 /* Text but not in buffer */
932 crb->type = RUNE_CHAR;
933 crb->object.chr.ch = data->font_is_bogus ? '~' : data->ch;
936 if (data->cursor_type == CURSOR_ON)
938 if (data->bi_bufpos == data->bi_cursor_bufpos)
940 crb->cursor_type = CURSOR_ON;
941 data->cursor_x = Dynarr_length (data->db->runes);
944 crb->cursor_type = CURSOR_OFF;
946 else if (data->cursor_type == NEXT_CURSOR)
948 crb->cursor_type = CURSOR_ON;
949 data->cursor_x = Dynarr_length (data->db->runes);
950 data->cursor_type = NO_CURSOR;
952 else if (data->cursor_type == IGNORE_CURSOR)
953 crb->cursor_type = IGNORE_CURSOR;
955 crb->cursor_type = CURSOR_OFF;
958 Dynarr_add (data->db->runes, *crb);
960 Dynarr_increment (data->db->runes);
962 data->pixpos += width;
967 /* Given a string C_STRING of length C_LENGTH, call add_emchar_rune
968 for each character in the string. Propagate any left-over data
969 unless NO_PROP is non-zero. */
971 static prop_block_dynarr *
972 add_bufbyte_string_runes (pos_data *data, Bufbyte *c_string,
973 Bytecount c_length, int no_prop)
975 Bufbyte *pos, *end = c_string + c_length;
976 prop_block_dynarr *prop;
978 /* #### This function is too simplistic. It needs to do the same
979 sort of character interpretation (display-table lookup,
980 ctl-arrow checking), etc. that create_text_block() does.
981 The functionality to do this in that routine needs to be
984 for (pos = c_string; pos < end;)
986 data->ch = charptr_emchar (pos);
988 prop = add_emchar_rune (data);
996 struct prop_block pb;
997 Bytecount len = end - pos;
998 prop = Dynarr_new (prop_block);
1000 pb.type = PROP_STRING;
1001 pb.data.p_string.str = xnew_array (Bufbyte, len);
1002 strncpy ((char *) pb.data.p_string.str, (char *) pos, len);
1003 pb.data.p_string.len = len;
1005 Dynarr_add (prop, pb);
1010 assert (pos <= end);
1016 /* Add a single rune of the specified width. The area covered by this
1017 rune will be displayed in the foreground color of the associated
1020 static prop_block_dynarr *
1021 add_blank_rune (pos_data *data, struct window *w, int char_tab_width)
1025 /* If data->start_col is not 0 then this call to add_blank_rune must have
1026 been to add it as a tab. */
1027 if (data->start_col)
1029 /* assert (w != NULL) */
1030 prop_block_dynarr *retval;
1032 /* If we have still not fully scrolled horizontally, subtract
1033 the width of this tab and return. */
1034 if (char_tab_width < data->start_col)
1036 data->start_col -= char_tab_width;
1039 else if (char_tab_width == data->start_col)
1040 data->blank_width = 0;
1043 int spcwid = space_width (w);
1045 if (spcwid >= data->blank_width)
1046 data->blank_width = 0;
1048 data->blank_width -= spcwid;
1051 data->start_col = 0;
1052 retval = add_hscroll_rune (data);
1054 /* Could be caused by the handling of the hscroll rune. */
1055 if (retval != NULL || !data->blank_width)
1059 /* Blank runes are always calculated to fit. */
1060 assert (data->pixpos + data->blank_width <= data->max_pixpos);
1062 rb.findex = data->findex;
1063 rb.xpos = data->pixpos;
1064 rb.width = data->blank_width;
1065 if (data->bi_bufpos)
1067 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
1070 /* #### and this is really correct too? */
1073 rb.type = RUNE_BLANK;
1075 if (data->cursor_type == CURSOR_ON)
1077 if (data->bi_bufpos == data->bi_cursor_bufpos)
1079 rb.cursor_type = CURSOR_ON;
1080 data->cursor_x = Dynarr_length (data->db->runes);
1083 rb.cursor_type = CURSOR_OFF;
1085 else if (data->cursor_type == NEXT_CURSOR)
1087 rb.cursor_type = CURSOR_ON;
1088 data->cursor_x = Dynarr_length (data->db->runes);
1089 data->cursor_type = NO_CURSOR;
1092 rb.cursor_type = CURSOR_OFF;
1094 Dynarr_add (data->db->runes, rb);
1095 data->pixpos += data->blank_width;
1100 /* Add runes representing a character in octal. */
1102 #define ADD_NEXT_OCTAL_RUNE_CHAR do \
1104 if (add_failed || (add_failed = add_emchar_rune (data))) \
1106 struct prop_block pb; \
1108 prop = Dynarr_new (prop_block); \
1110 pb.type = PROP_CHAR; \
1111 pb.data.p_char.ch = data->ch; \
1112 pb.data.p_char.cursor_type = data->cursor_type; \
1113 Dynarr_add (prop, pb); \
1117 static prop_block_dynarr *
1118 add_octal_runes (pos_data *data)
1120 prop_block_dynarr *prop, *add_failed;
1121 Emchar orig_char = data->ch;
1122 unsigned int orig_cursor_type = data->cursor_type;
1128 if (data->start_col)
1131 if (!data->start_col)
1133 if (data->bi_start_col_enabled)
1135 add_failed = add_hscroll_rune (data);
1139 struct glyph_block gb;
1140 struct window *w = XWINDOW (data->window);
1143 gb.glyph = Voctal_escape_glyph;
1145 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1146 GLYPH_CACHEL (w, OCT_ESC_GLYPH_INDEX));
1150 /* We only propagate information if the glyph was partially
1155 data->cursor_type = IGNORE_CURSOR;
1157 if (data->ch >= 0x100)
1159 /* If the character is an extended Mule character, it could have
1160 up to 19 bits. For the moment, we treat it as a seven-digit
1161 octal number. This is not that pretty, but whatever. */
1162 data->ch = (7 & (orig_char >> 18)) + '0';
1163 ADD_NEXT_OCTAL_RUNE_CHAR;
1165 data->ch = (7 & (orig_char >> 15)) + '0';
1166 ADD_NEXT_OCTAL_RUNE_CHAR;
1168 data->ch = (7 & (orig_char >> 12)) + '0';
1169 ADD_NEXT_OCTAL_RUNE_CHAR;
1171 data->ch = (7 & (orig_char >> 9)) + '0';
1172 ADD_NEXT_OCTAL_RUNE_CHAR;
1175 data->ch = (7 & (orig_char >> 6)) + '0';
1176 ADD_NEXT_OCTAL_RUNE_CHAR;
1178 data->ch = (7 & (orig_char >> 3)) + '0';
1179 ADD_NEXT_OCTAL_RUNE_CHAR;
1181 data->ch = (7 & orig_char) + '0';
1182 ADD_NEXT_OCTAL_RUNE_CHAR;
1184 data->cursor_type = orig_cursor_type;
1188 #undef ADD_NEXT_OCTAL_RUNE_CHAR
1190 /* Add runes representing a control character to a display block. */
1192 static prop_block_dynarr *
1193 add_control_char_runes (pos_data *data, struct buffer *b)
1195 if (!NILP (b->ctl_arrow))
1197 prop_block_dynarr *prop;
1198 Emchar orig_char = data->ch;
1199 unsigned int old_cursor_type = data->cursor_type;
1204 if (data->start_col)
1207 if (!data->start_col)
1209 if (data->bi_start_col_enabled)
1211 prop_block_dynarr *retval;
1213 retval = add_hscroll_rune (data);
1219 struct glyph_block gb;
1220 struct window *w = XWINDOW (data->window);
1223 gb.glyph = Vcontrol_arrow_glyph;
1225 /* We only propagate information if the glyph was partially
1227 if (add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1228 GLYPH_CACHEL (w, CONTROL_GLYPH_INDEX)))
1233 if (orig_char == 0177)
1236 data->ch = orig_char ^ 0100;
1237 data->cursor_type = IGNORE_CURSOR;
1239 if (add_emchar_rune (data))
1241 struct prop_block pb;
1243 prop = Dynarr_new (prop_block);
1245 pb.type = PROP_CHAR;
1246 pb.data.p_char.ch = data->ch;
1247 pb.data.p_char.cursor_type = data->cursor_type;
1248 Dynarr_add (prop, pb);
1251 data->cursor_type = old_cursor_type;
1256 return add_octal_runes (data);
1260 static prop_block_dynarr *
1261 add_disp_table_entry_runes_1 (pos_data *data, Lisp_Object entry)
1263 prop_block_dynarr *prop = NULL;
1265 if (STRINGP (entry))
1267 prop = add_bufbyte_string_runes (data,
1268 XSTRING_DATA (entry),
1269 XSTRING_LENGTH (entry),
1272 else if (GLYPHP (entry))
1274 if (data->start_col)
1277 if (!data->start_col && data->bi_start_col_enabled)
1279 prop = add_hscroll_rune (data);
1283 struct glyph_block gb;
1287 prop = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
1290 else if (CHAR_OR_CHAR_INTP (entry))
1292 data->ch = XCHAR_OR_CHAR_INT (entry);
1293 prop = add_emchar_rune (data);
1295 else if (CONSP (entry))
1297 if (EQ (XCAR (entry), Qformat)
1298 && CONSP (XCDR (entry))
1299 && STRINGP (XCAR (XCDR (entry))))
1301 Lisp_Object format = XCAR (XCDR (entry));
1302 Bytind len = XSTRING_LENGTH (format);
1303 Bufbyte *src = XSTRING_DATA (format), *end = src + len;
1304 Bufbyte *result = alloca_array (Bufbyte, len);
1305 Bufbyte *dst = result;
1309 Emchar c = charptr_emchar (src);
1311 if (c != '%' || src == end)
1312 dst += set_charptr_emchar (dst, c);
1315 c = charptr_emchar (src);
1320 dst += long_to_string_base ((char *)dst, data->ch, 16);
1323 dst += set_charptr_emchar (dst, '%');
1328 prop = add_bufbyte_string_runes (data, result, dst - result, 0);
1332 /* Else blow it off because someone added a bad entry and we don't
1333 have any safe way of signaling an error. */
1337 /* Given a display table entry, call the appropriate functions to
1338 display each element of the entry. */
1340 static prop_block_dynarr *
1341 add_disp_table_entry_runes (pos_data *data, Lisp_Object entry)
1343 prop_block_dynarr *prop = NULL;
1344 if (VECTORP (entry))
1346 Lisp_Vector *de = XVECTOR (entry);
1347 EMACS_INT len = vector_length (de);
1350 for (elt = 0; elt < len; elt++)
1352 if (NILP (vector_data (de)[elt]))
1355 prop = add_disp_table_entry_runes_1 (data, vector_data (de)[elt]);
1356 /* Else blow it off because someone added a bad entry and we
1357 don't have any safe way of signaling an error. Hey, this
1358 comment sounds familiar. */
1360 /* #### Still need to add any remaining elements to the
1361 propagation information. */
1367 prop = add_disp_table_entry_runes_1 (data, entry);
1371 /* Add runes which were propagated from the previous line. */
1373 static prop_block_dynarr *
1374 add_propagation_runes (prop_block_dynarr **prop, pos_data *data)
1376 /* #### Remember to handle start_col parameter of data when the rest of
1377 this is finished. */
1378 /* #### Chuck -- I've redone this function a bit. It looked like the
1379 case of not all the propagation blocks being added was not handled
1381 /* #### Chuck -- I also think the double indirection of PROP is kind
1382 of bogus. A cleaner solution is just to check for
1383 Dynarr_length (prop) > 0. */
1384 /* #### This function also doesn't even pay attention to ADD_FAILED!
1385 This is seriously fucked! Seven ####'s in 130 lines -- is that a
1388 prop_block_dynarr *add_failed;
1389 Bytind bi_old_cursor_bufpos = data->bi_cursor_bufpos;
1390 unsigned int old_cursor_type = data->cursor_type;
1392 for (elt = 0; elt < Dynarr_length (*prop); elt++)
1394 struct prop_block *pb = Dynarr_atp (*prop, elt);
1399 data->ch = pb->data.p_char.ch;
1400 data->bi_cursor_bufpos = pb->data.p_char.bi_cursor_bufpos;
1401 data->cursor_type = pb->data.p_char.cursor_type;
1402 add_failed = add_emchar_rune (data);
1405 goto oops_no_more_space;
1408 if (pb->data.p_string.str)
1409 xfree (pb->data.p_string.str);
1410 /* #### bogus bogus -- this doesn't do anything!
1411 Should probably call add_bufbyte_string_runes(),
1412 once that function is fixed. */
1414 case PROP_MINIBUF_PROMPT:
1416 face_index old_findex = data->findex;
1417 Bytind bi_old_bufpos = data->bi_bufpos;
1419 data->findex = DEFAULT_INDEX;
1420 data->bi_bufpos = 0;
1421 data->cursor_type = NO_CURSOR;
1423 while (pb->data.p_string.len > 0)
1425 data->ch = charptr_emchar (pb->data.p_string.str);
1426 add_failed = add_emchar_rune (data);
1430 data->findex = old_findex;
1431 data->bi_bufpos = bi_old_bufpos;
1432 goto oops_no_more_space;
1436 /* Complicated equivalent of ptr++, len-- */
1437 Bufbyte *oldpos = pb->data.p_string.str;
1438 INC_CHARPTR (pb->data.p_string.str);
1439 pb->data.p_string.len -= pb->data.p_string.str - oldpos;
1443 data->findex = old_findex;
1444 /* ##### FIXME FIXME FIXME -- Upon successful return from
1445 this function, data->bi_bufpos is automatically incremented.
1446 However, we don't want that to happen if we were adding
1447 the minibuffer prompt. */
1449 struct buffer *buf =
1450 XBUFFER (WINDOW_BUFFER (XWINDOW (data->window)));
1451 /* #### Chuck fix this shit or I'm gonna scream! */
1452 if (bi_old_bufpos > BI_BUF_BEGV (buf))
1453 data->bi_bufpos = prev_bytind (buf, bi_old_bufpos);
1455 /* #### is this correct? Does anyone know?
1456 Does anyone care? Is this a cheesy hack or what? */
1457 data->bi_bufpos = BI_BUF_BEGV (buf) - 1;
1463 /* #### I think it's unnecessary and misleading to preserve
1464 the blank_width, as it implies that the value carries
1465 over from one rune to the next, which is wrong. */
1466 int old_width = data->blank_width;
1467 face_index old_findex = data->findex;
1469 data->findex = pb->data.p_blank.findex;
1470 data->blank_width = pb->data.p_blank.width;
1471 data->bi_cursor_bufpos = 0;
1472 data->cursor_type = IGNORE_CURSOR;
1474 if (data->pixpos + data->blank_width > data->max_pixpos)
1475 data->blank_width = data->max_pixpos - data->pixpos;
1477 /* We pass a bogus value of char_tab_width. It shouldn't
1478 matter because unless something is really screwed up
1479 this call won't cause that arg to be used. */
1480 add_failed = add_blank_rune (data, XWINDOW (data->window), 0);
1482 /* This can happen in the case where we have a tab which
1483 is wider than the window. */
1484 if (data->blank_width != pb->data.p_blank.width)
1486 pb->data.p_blank.width -= data->blank_width;
1487 add_failed = ADD_FAILED;
1490 data->findex = old_findex;
1491 data->blank_width = old_width;
1494 goto oops_no_more_space;
1504 data->bi_cursor_bufpos = bi_old_cursor_bufpos;
1505 data->cursor_type = old_cursor_type;
1506 if (elt < Dynarr_length (*prop))
1508 Dynarr_delete_many (*prop, 0, elt);
1513 Dynarr_free (*prop);
1518 /* Add 'text layout glyphs at position POS_TYPE that are contained to
1519 the display block, but add all other types to the appropriate list
1520 of the display line. They will be added later by different
1523 static prop_block_dynarr *
1524 add_glyph_rune (pos_data *data, struct glyph_block *gb, int pos_type,
1525 int allow_cursor, struct glyph_cachel *cachel)
1527 struct window *w = XWINDOW (data->window);
1529 /* If window faces changed, and glyph instance is text, then
1530 glyph sizes might have changed too */
1531 invalidate_glyph_geometry_maybe (gb->glyph, w);
1533 /* This makes sure the glyph is in the cachels.
1535 #### We do this to make sure the glyph is in the glyph cachels,
1536 so that the dirty flag can be reset after redisplay has
1537 finished. We should do this some other way, maybe by iterating
1538 over the window cache of subwindows. */
1539 get_glyph_cachel_index (w, gb->glyph);
1541 /* A nil extent indicates a special glyph (ex. truncator). */
1542 if (NILP (gb->extent)
1543 || (pos_type == BEGIN_GLYPHS &&
1544 extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1545 || (pos_type == END_GLYPHS &&
1546 extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1547 || pos_type == LEFT_GLYPHS || pos_type == RIGHT_GLYPHS)
1552 int ascent, descent;
1553 Lisp_Object baseline;
1555 Lisp_Object instance;
1559 width = cachel->width;
1561 width = glyph_width (gb->glyph, data->window);
1566 if (data->start_col || data->start_col_xoffset)
1568 prop_block_dynarr *retval;
1569 int glyph_char_width = width / space_width (w);
1571 /* If we still have not fully scrolled horizontally after
1572 taking into account the width of the glyph, subtract its
1573 width and return. */
1574 if (glyph_char_width < data->start_col)
1576 data->start_col -= glyph_char_width;
1579 else if (glyph_char_width == data->start_col)
1583 xoffset = space_width (w) * data->start_col;
1586 /* #### Can this happen? */
1591 data->start_col = 0;
1592 retval = add_hscroll_rune (data);
1594 /* Could be caused by the handling of the hscroll rune. */
1595 if (retval != NULL || !width)
1601 if (data->pixpos + width > data->max_pixpos)
1603 /* If this is the first object we are attempting to add to
1604 the line then we ignore the horizontal_clip threshold.
1605 Otherwise we will loop until the bottom of the window
1606 continually failing to add this glyph because it is wider
1607 than the window. We could alternatively just completely
1608 ignore the glyph and proceed from there but I think that
1609 this is a better solution. */
1610 if (Dynarr_length (data->db->runes)
1611 && data->max_pixpos - data->pixpos < horizontal_clip)
1614 width = data->max_pixpos - data->pixpos;
1619 ascent = cachel->ascent;
1620 descent = cachel->descent;
1624 ascent = glyph_ascent (gb->glyph, data->window);
1625 descent = glyph_descent (gb->glyph, data->window);
1628 baseline = glyph_baseline (gb->glyph, data->window);
1630 if (glyph_contrib_p (gb->glyph, data->window))
1632 /* A pixmap that has not had a baseline explicitly set. Its
1633 contribution will be determined later. */
1634 if (NILP (baseline))
1636 int height = ascent + descent;
1637 data->max_pixmap_height = max (data->max_pixmap_height, height);
1640 /* A string so determine contribution normally. */
1641 else if (EQ (baseline, Qt))
1643 data->new_ascent = max (data->new_ascent, ascent);
1644 data->new_descent = max (data->new_descent, descent);
1647 /* A pixmap with an explicitly set baseline. We determine the
1648 contribution here. */
1649 else if (INTP (baseline))
1651 int height = ascent + descent;
1652 int pix_ascent, pix_descent;
1654 pix_ascent = height * XINT (baseline) / 100;
1655 pix_descent = height - pix_ascent;
1657 data->new_ascent = max (data->new_ascent, pix_ascent);
1658 data->new_descent = max (data->new_descent, pix_descent);
1661 /* Otherwise something is screwed up. */
1666 face = glyph_face (gb->glyph, data->window);
1668 findex = data->findex;
1670 findex = get_builtin_face_cache_index (w, face);
1672 instance = glyph_image_instance (gb->glyph, data->window,
1674 if (TEXT_IMAGE_INSTANCEP (instance))
1676 Lisp_Object string = XIMAGE_INSTANCE_TEXT_STRING (instance);
1677 face_index orig_findex = data->findex;
1678 Bytind orig_bufpos = data->bi_bufpos;
1679 Bytind orig_start_col_enabled = data->bi_start_col_enabled;
1681 data->findex = findex;
1682 data->bi_start_col_enabled = 0;
1684 data->bi_bufpos = 0;
1685 add_bufbyte_string_runes (data, XSTRING_DATA (string),
1686 XSTRING_LENGTH (string), 0);
1687 data->findex = orig_findex;
1688 data->bi_bufpos = orig_bufpos;
1689 data->bi_start_col_enabled = orig_start_col_enabled;
1694 rb.xpos = data->pixpos;
1696 rb.bufpos = 0; /* glyphs are never "at" anywhere */
1697 if (data->bi_endpos)
1698 /* #### is this necessary at all? */
1699 rb.endpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1703 rb.type = RUNE_DGLYPH;
1704 rb.object.dglyph.glyph = gb->glyph;
1705 rb.object.dglyph.extent = gb->extent;
1706 rb.object.dglyph.xoffset = xoffset;
1710 rb.bufpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1713 if (data->cursor_type == CURSOR_ON)
1715 if (data->bi_bufpos == data->bi_cursor_bufpos)
1717 rb.cursor_type = CURSOR_ON;
1718 data->cursor_x = Dynarr_length (data->db->runes);
1721 rb.cursor_type = CURSOR_OFF;
1723 else if (data->cursor_type == NEXT_CURSOR)
1725 rb.cursor_type = CURSOR_ON;
1726 data->cursor_x = Dynarr_length (data->db->runes);
1727 data->cursor_type = NO_CURSOR;
1729 else if (data->cursor_type == IGNORE_CURSOR)
1730 rb.cursor_type = IGNORE_CURSOR;
1731 else if (data->cursor_type == NO_CURSOR)
1732 rb.cursor_type = NO_CURSOR;
1734 rb.cursor_type = CURSOR_OFF;
1737 rb.cursor_type = CURSOR_OFF;
1739 Dynarr_add (data->db->runes, rb);
1740 data->pixpos += width;
1746 if (!NILP (glyph_face (gb->glyph, data->window)))
1748 get_builtin_face_cache_index (w, glyph_face (gb->glyph,
1751 gb->findex = data->findex;
1753 if (pos_type == BEGIN_GLYPHS)
1755 if (!data->dl->left_glyphs)
1756 data->dl->left_glyphs = Dynarr_new (glyph_block);
1757 Dynarr_add (data->dl->left_glyphs, *gb);
1760 else if (pos_type == END_GLYPHS)
1762 if (!data->dl->right_glyphs)
1763 data->dl->right_glyphs = Dynarr_new (glyph_block);
1764 Dynarr_add (data->dl->right_glyphs, *gb);
1768 abort (); /* there are no unknown types */
1771 return NULL; /* shut up compiler */
1774 /* Add all glyphs at position POS_TYPE that are contained in the given
1777 static prop_block_dynarr *
1778 add_glyph_runes (pos_data *data, int pos_type)
1780 /* #### This still needs to handle the start_col parameter. Duh, Chuck,
1781 why didn't you just modify add_glyph_rune in the first place? */
1783 glyph_block_dynarr *glyph_arr = (pos_type == BEGIN_GLYPHS
1784 ? data->ef->begin_glyphs
1785 : data->ef->end_glyphs);
1786 prop_block_dynarr *prop;
1788 for (elt = 0; elt < Dynarr_length (glyph_arr); elt++)
1790 prop = add_glyph_rune (data, Dynarr_atp (glyph_arr, elt), pos_type, 0,
1795 /* #### Add some propagation information. */
1800 Dynarr_reset (glyph_arr);
1805 /* Given a position for a buffer in a window, ensure that the given
1806 display line DL accurately represents the text on a line starting
1807 at the given position.
1809 NOTE NOTE NOTE NOTE: This function works with and returns Bytinds.
1810 You must do appropriate conversion. */
1813 create_text_block (struct window *w, struct display_line *dl,
1814 Bytind bi_start_pos, prop_block_dynarr **prop,
1817 struct frame *f = XFRAME (w->frame);
1818 struct buffer *b = XBUFFER (w->buffer);
1819 struct device *d = XDEVICE (f->device);
1823 /* Don't display anything in the minibuffer if this window is not on
1824 a selected frame. We consider all other windows to be active
1825 minibuffers as it simplifies the coding. */
1826 int active_minibuffer = (!MINI_WINDOW_P (w) ||
1827 (f == device_selected_frame (d)) ||
1828 is_surrogate_for_selected_frame (f));
1830 int truncate_win = window_truncation_on (w);
1831 int end_glyph_width;
1833 /* If the buffer's value of selective_display is an integer then
1834 only lines that start with less than selective_display columns of
1835 space will be displayed. If selective_display is t then all text
1836 after a ^M is invisible. */
1837 int selective = (INTP (b->selective_display)
1838 ? XINT (b->selective_display)
1839 : (!NILP (b->selective_display) ? -1 : 0));
1841 /* The variable ctl-arrow allows the user to specify what characters
1842 can actually be displayed and which octal should be used for.
1843 #### This variable should probably have some rethought done to
1846 #### It would also be really nice if you could specify that
1847 the characters come out in hex instead of in octal. Mule
1848 does that by adding a ctl-hexa variable similar to ctl-arrow,
1849 but that's bogus -- we need a more general solution. I
1850 think you need to extend the concept of display tables
1851 into a more general conversion mechanism. Ideally you
1852 could specify a Lisp function that converts characters,
1853 but this violates the Second Golden Rule and besides would
1854 make things way way way way slow.
1856 So instead, we extend the display-table concept, which was
1857 historically limited to 256-byte vectors, to one of the
1860 a) A 256-entry vector, for backward compatibility;
1861 b) char-table, mapping characters to values;
1862 c) range-table, mapping ranges of characters to values;
1863 d) a list of the above.
1865 The (d) option allows you to specify multiple display tables
1866 instead of just one. Each display table can specify conversions
1867 for some characters and leave others unchanged. The way the
1868 character gets displayed is determined by the first display table
1869 with a binding for that character. This way, you could call a
1870 function `enable-hex-display' that adds a hex display-table to
1871 the list of display tables for the current buffer.
1873 #### ...not yet implemented... Also, we extend the concept of
1874 "mapping" to include a printf-like spec. Thus you can make all
1875 extended characters show up as hex with a display table like
1878 #s(range-table data ((256 524288) (format "%x")))
1880 Since more than one display table is possible, you have
1881 great flexibility in mapping ranges of characters. */
1882 Emchar printable_min = (CHAR_OR_CHAR_INTP (b->ctl_arrow)
1883 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
1884 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
1887 Lisp_Object face_dt, window_dt;
1889 /* The text display block for this display line. */
1890 struct display_block *db = get_display_block_from_line (dl, TEXT);
1892 /* The first time through the main loop we need to force the glyph
1893 data to be updated. */
1896 /* Apparently the new extent_fragment_update returns an end position
1897 equal to the position passed in if there are no more runs to be
1899 int no_more_frags = 0;
1901 Lisp_Object synch_minibuffers_value =
1902 symbol_value_in_buffer (Qsynchronize_minibuffers, w->buffer);
1904 dl->used_prop_data = 0;
1906 dl->line_continuation = 0;
1909 data.ef = extent_fragment_new (w->buffer, f);
1911 /* These values are used by all of the rune addition routines. We add
1912 them to this structure for ease of passing. */
1914 XSETWINDOW (data.window, w);
1919 data.bi_bufpos = bi_start_pos;
1920 data.pixpos = dl->bounds.left_in;
1921 data.last_charset = Qunbound;
1922 data.last_findex = DEFAULT_INDEX;
1923 data.result_str = Qnil;
1925 /* Set the right boundary adjusting it to take into account any end
1926 glyph. Save the width of the end glyph for later use. */
1927 data.max_pixpos = dl->bounds.right_in;
1929 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
1931 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
1932 data.max_pixpos -= end_glyph_width;
1934 if (cursor_in_echo_area && MINI_WINDOW_P (w) && echo_area_active (f))
1936 data.bi_cursor_bufpos = BI_BUF_ZV (b);
1937 data.cursor_type = CURSOR_ON;
1939 else if (MINI_WINDOW_P (w) && !active_minibuffer)
1940 data.cursor_type = NO_CURSOR;
1941 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)) &&
1942 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
1943 d == XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d))))&&
1944 f == XFRAME(DEVICE_SELECTED_FRAME(d)))
1946 data.bi_cursor_bufpos = BI_BUF_PT (b);
1947 data.cursor_type = CURSOR_ON;
1949 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)))
1951 data.bi_cursor_bufpos = bi_marker_position (w->pointm[type]);
1952 data.cursor_type = CURSOR_ON;
1955 data.cursor_type = NO_CURSOR;
1958 data.start_col = w->hscroll;
1959 data.start_col_xoffset = w->left_xoffset;
1960 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
1961 data.hscroll_glyph_width_adjust = 0;
1963 /* We regenerate the line from the very beginning. */
1964 Dynarr_reset (db->runes);
1966 /* Why is this less than or equal and not just less than? If the
1967 starting position is already equal to the maximum we can't add
1968 anything else, right? Wrong. We might still have a newline to
1969 add. A newline can use the room allocated for an end glyph since
1970 if we add it we know we aren't going to be adding any end
1973 /* #### Chuck -- I think this condition should be while (1).
1974 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
1975 and the begin-glyph ends exactly at the end of the window, the
1976 end-glyph and text might not be displayed. while (1) ensures
1977 that the loop terminates only when either (a) there is
1978 propagation data or (b) the end-of-line or end-of-buffer is hit.
1980 #### Also I think you need to ensure that the operation
1981 "add begin glyphs; add end glyphs; add text" is atomic and
1982 can't get interrupted in the middle. If you run off the end
1983 of the line during that operation, then you keep accumulating
1984 propagation data until you're done. Otherwise, if the (e.g.)
1985 there's a begin glyph at a particular position and attempting
1986 to display that glyph results in window-end being hit and
1987 propagation data being generated, then the character at that
1988 position won't be displayed.
1990 #### See also the comment after the end of this loop, below.
1992 while (data.pixpos <= data.max_pixpos
1993 && (active_minibuffer || !NILP (synch_minibuffers_value)))
1995 /* #### This check probably should not be necessary. */
1996 if (data.bi_bufpos > BI_BUF_ZV (b))
1998 /* #### urk! More of this lossage! */
2003 /* If selective display was an integer and we aren't working on
2004 a continuation line then find the next line we are actually
2005 supposed to display. */
2007 && (data.bi_bufpos == BI_BUF_BEGV (b)
2008 || BUF_FETCH_CHAR (b, prev_bytind (b, data.bi_bufpos)) == '\n'))
2010 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2013 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2014 if (data.bi_bufpos >= BI_BUF_ZV (b))
2016 data.bi_bufpos = BI_BUF_ZV (b);
2022 /* Check for face changes. */
2023 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
2025 /* Now compute the face and begin/end-glyph information. */
2027 /* Remember that the extent-fragment routines deal in Bytind's. */
2028 extent_fragment_update (w, data.ef, data.bi_bufpos);
2030 get_display_tables (w, data.findex, &face_dt, &window_dt);
2032 if (data.bi_bufpos == data.ef->end)
2037 /* Determine what is next to be displayed. We first handle any
2038 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
2039 display then we determine what to do based on the character at the
2040 current buffer position. */
2042 /* If the current position is covered by an invisible extent, do
2043 nothing (except maybe add some ellipses).
2045 #### The behavior of begin and end-glyphs at the edge of an
2046 invisible extent should be investigated further. This is
2047 fairly low priority though. */
2048 if (data.ef->invisible)
2050 /* #### Chuck, perhaps you could look at this code? I don't
2051 really know what I'm doing. */
2054 Dynarr_free (*prop);
2058 /* The extent fragment code only sets this when we should
2059 really display the ellipses. It makes sure the ellipses
2060 don't get displayed more than once in a row. */
2061 if (data.ef->invisible_ellipses)
2063 struct glyph_block gb;
2065 data.ef->invisible_ellipses_already_displayed = 1;
2066 data.ef->invisible_ellipses = 0;
2068 gb.glyph = Vinvisible_text_glyph;
2069 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2070 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2071 /* Perhaps they shouldn't propagate if the very next thing
2072 is to display a newline (for compatibility with
2073 selective-display-ellipses)? Maybe that's too
2079 /* If point is in an invisible region we place it on the
2080 next visible character. */
2081 if (data.cursor_type == CURSOR_ON
2082 && data.bi_bufpos == data.bi_cursor_bufpos)
2084 data.cursor_type = NEXT_CURSOR;
2087 /* #### What if we we're dealing with a display table? */
2091 if (data.bi_bufpos == BI_BUF_ZV (b))
2094 INC_BYTIND (b, data.bi_bufpos);
2097 /* If there is propagation data, then it represents the current
2098 buffer position being displayed. Add them and advance the
2099 position counter. This might also add the minibuffer
2103 dl->used_prop_data = 1;
2104 *prop = add_propagation_runes (prop, &data);
2107 goto done; /* gee, a really narrow window */
2108 else if (data.bi_bufpos == BI_BUF_ZV (b))
2110 else if (data.bi_bufpos < BI_BUF_BEGV (b))
2111 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
2112 data.bi_bufpos = BI_BUF_BEGV (b);
2114 INC_BYTIND (b, data.bi_bufpos);
2117 /* If there are end glyphs, add them to the line. These are
2118 the end glyphs for the previous run of text. We add them
2119 here rather than doing them at the end of handling the
2120 previous run so that glyphs at the beginning and end of
2121 a line are handled correctly. */
2122 else if (Dynarr_length (data.ef->end_glyphs) > 0)
2124 *prop = add_glyph_runes (&data, END_GLYPHS);
2129 /* If there are begin glyphs, add them to the line. */
2130 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
2132 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
2137 /* If at end-of-buffer, we've already processed begin and
2138 end-glyphs at this point and there's no text to process,
2140 else if (data.bi_bufpos == BI_BUF_ZV (b))
2145 Lisp_Object entry = Qnil;
2146 /* Get the character at the current buffer position. */
2147 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2148 if (!NILP (face_dt) || !NILP (window_dt))
2149 entry = display_table_entry (data.ch, face_dt, window_dt);
2151 /* If there is a display table entry for it, hand it off to
2152 add_disp_table_entry_runes and let it worry about it. */
2153 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
2155 *prop = add_disp_table_entry_runes (&data, entry);
2161 /* Check if we have hit a newline character. If so, add a marker
2162 to the line and end this loop. */
2163 else if (data.ch == '\n')
2165 /* We aren't going to be adding an end glyph so give its
2166 space back in order to make sure that the cursor can
2168 data.max_pixpos += end_glyph_width;
2171 && (bi_spaces_at_point
2172 (b, next_bytind (b, data.bi_bufpos))
2175 if (!NILP (b->selective_display_ellipses))
2177 struct glyph_block gb;
2180 gb.glyph = Vinvisible_text_glyph;
2181 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2182 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2186 /* Cheesy, cheesy, cheesy. We mark the end of the
2187 line with a special "character rune" whose width
2188 is the EOL cursor width and whose character is
2189 the non-printing character '\n'. */
2190 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2191 *prop = add_emchar_rune (&data);
2194 /* We need to set data.bi_bufpos to the start of the
2195 next visible region in order to make this line
2196 appear to contain all of the invisible area.
2197 Otherwise, the line cache won't work
2199 INC_BYTIND (b, data.bi_bufpos);
2200 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2203 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2204 if (data.bi_bufpos >= BI_BUF_ZV (b))
2206 data.bi_bufpos = BI_BUF_ZV (b);
2210 if (BI_BUF_FETCH_CHAR
2211 (b, prev_bytind (b, data.bi_bufpos)) == '\n')
2212 DEC_BYTIND (b, data.bi_bufpos);
2216 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2217 *prop = add_emchar_rune (&data);
2223 /* If the current character is ^M, and selective display is
2224 enabled, then add the invisible-text-glyph if
2225 selective-display-ellipses is set. In any case, this
2227 else if (data.ch == (('M' & 037)) && selective == -1)
2229 Bytind bi_next_bufpos;
2231 /* Find the buffer position at the end of the line. */
2233 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2234 if (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_next_bufpos))
2236 DEC_BYTIND (b, bi_next_bufpos);
2238 /* If the cursor is somewhere in the elided text make
2239 sure that the cursor gets drawn appropriately. */
2240 if (data.cursor_type == CURSOR_ON
2241 && (data.bi_cursor_bufpos >= data.bi_bufpos &&
2242 data.bi_cursor_bufpos < bi_next_bufpos))
2244 data.cursor_type = NEXT_CURSOR;
2247 /* We won't be adding a truncation or continuation glyph
2248 so give up the room allocated for them. */
2249 data.max_pixpos += end_glyph_width;
2251 if (!NILP (b->selective_display_ellipses))
2253 /* We don't propagate anything from the invisible
2254 text glyph if it fails to fit. This is
2256 struct glyph_block gb;
2259 gb.glyph = Vinvisible_text_glyph;
2260 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 1,
2261 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2264 /* Set the buffer position to the end of the line. We
2265 need to do this before potentially adding a newline
2266 so that the cursor flag will get set correctly (if
2268 data.bi_bufpos = bi_next_bufpos;
2270 if (NILP (b->selective_display_ellipses)
2271 || data.bi_cursor_bufpos == bi_next_bufpos)
2273 /* We have to at least add a newline character so
2274 that the cursor shows up properly. */
2276 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2277 data.findex = DEFAULT_INDEX;
2279 data.start_col_xoffset = 0;
2280 data.bi_start_col_enabled = 0;
2282 add_emchar_rune (&data);
2285 /* This had better be a newline but doing it this way
2286 we'll see obvious incorrect results if it isn't. No
2287 need to abort here. */
2288 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2293 /* If the current character is considered to be printable, then
2295 else if (data.ch >= printable_min)
2297 *prop = add_emchar_rune (&data);
2302 /* If the current character is a tab, determine the next tab
2303 starting position and add a blank rune which extends from the
2304 current pixel position to that starting position. */
2305 else if (data.ch == '\t')
2307 int tab_start_pixpos = data.pixpos;
2312 if (data.start_col > 1)
2313 tab_start_pixpos -= (space_width (w) * (data.start_col - 1))
2314 + data.start_col_xoffset;
2317 next_tab_position (w, tab_start_pixpos,
2318 dl->bounds.left_in +
2319 data.hscroll_glyph_width_adjust);
2320 if (next_tab_start > data.max_pixpos)
2322 prop_width = next_tab_start - data.max_pixpos;
2323 next_tab_start = data.max_pixpos;
2325 data.blank_width = next_tab_start - data.pixpos;
2327 (next_tab_start - tab_start_pixpos) / space_width (w);
2329 *prop = add_blank_rune (&data, w, char_tab_width);
2331 /* add_blank_rune is only supposed to be called with
2332 sizes guaranteed to fit in the available space. */
2337 struct prop_block pb;
2338 *prop = Dynarr_new (prop_block);
2340 pb.type = PROP_BLANK;
2341 pb.data.p_blank.width = prop_width;
2342 pb.data.p_blank.findex = data.findex;
2343 Dynarr_add (*prop, pb);
2349 /* If character is a control character, pass it off to
2350 add_control_char_runes.
2352 The is_*() routines have undefined results on
2353 arguments outside of the range [-1, 255]. (This
2354 often bites people who carelessly use `char' instead
2355 of `unsigned char'.)
2357 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
2359 *prop = add_control_char_runes (&data, b);
2365 /* If the character is above the ASCII range and we have not
2366 already handled it, then print it as an octal number. */
2367 else if (data.ch >= 0200)
2369 *prop = add_octal_runes (&data);
2375 /* Assume the current character is considered to be printable,
2376 then just add it. */
2379 *prop = add_emchar_rune (&data);
2384 INC_BYTIND (b, data.bi_bufpos);
2390 /* Determine the starting point of the next line if we did not hit the
2391 end of the buffer. */
2392 if (data.bi_bufpos < BI_BUF_ZV (b)
2393 && (active_minibuffer || !NILP (synch_minibuffers_value)))
2395 /* #### This check is not correct. If the line terminated
2396 due to a begin-glyph or end-glyph hitting window-end, then
2397 data.ch will not point to the character at data.bi_bufpos. If
2398 you make the two changes mentioned at the top of this loop,
2399 you should be able to say '(if (*prop))'. That should also
2400 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
2403 /* The common case is that the line ended because we hit a newline.
2404 In that case, the next character is just the next buffer
2406 if (data.ch == '\n')
2408 /* If data.start_col_enabled is still true, then the window is
2409 scrolled far enough so that nothing on this line is visible.
2410 We need to stick a truncation glyph at the beginning of the
2411 line in that case unless the line is completely blank. */
2412 if (data.bi_start_col_enabled)
2414 if (data.cursor_type == CURSOR_ON)
2416 if (data.bi_cursor_bufpos >= bi_start_pos
2417 && data.bi_cursor_bufpos <= data.bi_bufpos)
2418 data.bi_cursor_bufpos = data.bi_bufpos;
2420 data.findex = DEFAULT_INDEX;
2422 data.bi_start_col_enabled = 0;
2424 if (data.bi_bufpos != bi_start_pos)
2426 struct glyph_block gb;
2429 gb.glyph = Vhscroll_glyph;
2430 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2431 GLYPH_CACHEL (w, HSCROLL_GLYPH_INDEX));
2435 /* This duplicates code down below to add a newline to
2436 the end of an otherwise empty line.*/
2438 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2440 add_emchar_rune (&data);
2444 INC_BYTIND (b, data.bi_bufpos);
2447 /* Otherwise we have a buffer line which cannot fit on one display
2451 struct glyph_block gb;
2452 struct glyph_cachel *cachel;
2454 /* If the line is to be truncated then we actually have to look
2455 for the next newline. We also add the end-of-line glyph which
2456 we know will fit because we adjusted the right border before
2457 we starting laying out the line. */
2458 data.max_pixpos += end_glyph_width;
2459 data.findex = DEFAULT_INDEX;
2466 /* Now find the start of the next line. */
2467 bi_pos = bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2469 /* If the cursor is past the truncation line then we
2470 make it appear on the truncation glyph. If we've hit
2471 the end of the buffer then we also make the cursor
2472 appear unless eob is immediately preceded by a
2473 newline. In that case the cursor should actually
2474 appear on the next line. */
2475 if (data.cursor_type == CURSOR_ON
2476 && data.bi_cursor_bufpos >= data.bi_bufpos
2477 && (data.bi_cursor_bufpos < bi_pos ||
2478 (bi_pos == BI_BUF_ZV (b)
2479 && (bi_pos == BI_BUF_BEGV (b)
2480 || (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_pos))
2482 data.bi_cursor_bufpos = bi_pos;
2484 data.cursor_type = NO_CURSOR;
2486 data.bi_bufpos = bi_pos;
2487 gb.glyph = Vtruncation_glyph;
2488 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
2492 /* The cursor can never be on the continuation glyph. */
2493 data.cursor_type = NO_CURSOR;
2495 /* data.bi_bufpos is already at the start of the next line. */
2497 dl->line_continuation = 1;
2498 gb.glyph = Vcontinuation_glyph;
2499 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
2502 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
2504 if (truncate_win && data.bi_bufpos == BI_BUF_ZV (b)
2505 && BI_BUF_FETCH_CHAR (b, prev_bytind (b, BI_BUF_ZV (b))) != '\n')
2506 /* #### Damn this losing shit. */
2510 else if ((active_minibuffer || !NILP (synch_minibuffers_value))
2511 && (!echo_area_active (f) || data.bi_bufpos == BI_BUF_ZV (b)))
2513 /* We need to add a marker to the end of the line since there is no
2514 newline character in order for the cursor to get drawn. We label
2515 it as a newline so that it gets handled correctly by the
2516 whitespace routines below. */
2519 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2520 data.findex = DEFAULT_INDEX;
2522 data.start_col_xoffset = 0;
2523 data.bi_start_col_enabled = 0;
2525 data.max_pixpos += data.blank_width;
2526 add_emchar_rune (&data);
2527 data.max_pixpos -= data.blank_width;
2529 /* #### urk! Chuck, this shit is bad news. Going around
2530 manipulating invalid positions is guaranteed to result in
2531 trouble sooner or later. */
2532 data.bi_bufpos = BI_BUF_ZV (b) + 1;
2535 /* Calculate left whitespace boundary. */
2539 /* Whitespace past a newline is considered right whitespace. */
2540 while (elt < Dynarr_length (db->runes))
2542 struct rune *rb = Dynarr_atp (db->runes, elt);
2544 if ((rb->type == RUNE_CHAR && rb->object.chr.ch == ' ')
2545 || rb->type == RUNE_BLANK)
2547 dl->bounds.left_white += rb->width;
2551 elt = Dynarr_length (db->runes);
2555 /* Calculate right whitespace boundary. */
2557 int elt = Dynarr_length (db->runes) - 1;
2560 while (!done && elt >= 0)
2562 struct rune *rb = Dynarr_atp (db->runes, elt);
2564 if (!(rb->type == RUNE_CHAR && rb->object.chr.ch < 0x100
2565 && isspace (rb->object.chr.ch))
2566 && !rb->type == RUNE_BLANK)
2568 dl->bounds.right_white = rb->xpos + rb->width;
2576 /* The line is blank so everything is considered to be right
2579 dl->bounds.right_white = dl->bounds.left_in;
2582 /* Set the display blocks bounds. */
2583 db->start_pos = dl->bounds.left_in;
2584 if (Dynarr_length (db->runes))
2586 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
2588 db->end_pos = rb->xpos + rb->width;
2591 db->end_pos = dl->bounds.right_white;
2593 /* update line height parameters */
2594 if (!data.new_ascent && !data.new_descent)
2596 /* We've got a blank line so initialize these values from the default
2598 default_face_font_info (data.window, &data.new_ascent,
2599 &data.new_descent, 0, 0, 0);
2602 if (data.max_pixmap_height)
2604 int height = data.new_ascent + data.new_descent;
2605 int pix_ascent, pix_descent;
2607 pix_descent = data.max_pixmap_height * data.new_descent / height;
2608 pix_ascent = data.max_pixmap_height - pix_descent;
2610 data.new_ascent = max (data.new_ascent, pix_ascent);
2611 data.new_descent = max (data.new_descent, pix_descent);
2614 dl->ascent = data.new_ascent;
2615 dl->descent = data.new_descent;
2618 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
2620 if (dl->ascent < ascent)
2621 dl->ascent = ascent;
2624 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
2626 if (dl->descent < descent)
2627 dl->descent = descent;
2630 dl->cursor_elt = data.cursor_x;
2631 /* #### lossage lossage lossage! Fix this shit! */
2632 if (data.bi_bufpos > BI_BUF_ZV (b))
2633 dl->end_bufpos = BUF_ZV (b);
2635 dl->end_bufpos = bytind_to_bufpos (b, data.bi_bufpos) - 1;
2637 data.dl->num_chars = column_at_point (b, dl->end_bufpos, 0);
2639 /* This doesn't correctly take into account tabs and control
2640 characters but if the window isn't being truncated then this
2641 value isn't going to end up being used anyhow. */
2642 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
2644 /* #### handle horizontally scrolled line with text none of which
2645 was actually laid out. */
2647 /* #### handle any remainder of overlay arrow */
2649 if (*prop == ADD_FAILED)
2652 if (truncate_win && *prop)
2654 Dynarr_free (*prop);
2658 extent_fragment_delete (data.ef);
2660 /* #### If we started at EOB, then make sure we return a value past
2661 it so that regenerate_window will exit properly. This is bogus.
2662 The main loop should get fixed so that it isn't necessary to call
2663 this function if we are already at EOB. */
2665 if (data.bi_bufpos == BI_BUF_ZV (b) && bi_start_pos == BI_BUF_ZV (b))
2666 return data.bi_bufpos + 1; /* Yuck! */
2668 return data.bi_bufpos;
2671 /* Display the overlay arrow at the beginning of the given line. */
2674 create_overlay_glyph_block (struct window *w, struct display_line *dl)
2676 struct frame *f = XFRAME (w->frame);
2677 struct device *d = XDEVICE (f->device);
2680 /* If Voverlay_arrow_string isn't valid then just fail silently. */
2681 if (!STRINGP (Voverlay_arrow_string) && !GLYPHP (Voverlay_arrow_string))
2687 XSETWINDOW (data.window, w);
2688 data.db = get_display_block_from_line (dl, OVERWRITE);
2690 data.pixpos = dl->bounds.left_in;
2691 data.max_pixpos = dl->bounds.right_in;
2692 data.cursor_type = NO_CURSOR;
2694 data.findex = DEFAULT_INDEX;
2695 data.last_charset = Qunbound;
2696 data.last_findex = DEFAULT_INDEX;
2697 data.result_str = Qnil;
2700 Dynarr_reset (data.db->runes);
2702 if (STRINGP (Voverlay_arrow_string))
2704 add_bufbyte_string_runes
2706 XSTRING_DATA (Voverlay_arrow_string),
2707 XSTRING_LENGTH (Voverlay_arrow_string),
2710 else if (GLYPHP (Voverlay_arrow_string))
2712 struct glyph_block gb;
2714 gb.glyph = Voverlay_arrow_string;
2716 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, 0);
2719 if (data.max_pixmap_height)
2721 int height = data.new_ascent + data.new_descent;
2722 int pix_ascent, pix_descent;
2724 pix_descent = data.max_pixmap_height * data.new_descent / height;
2725 pix_ascent = data.max_pixmap_height - pix_descent;
2727 data.new_ascent = max (data.new_ascent, pix_ascent);
2728 data.new_descent = max (data.new_descent, pix_descent);
2731 dl->ascent = data.new_ascent;
2732 dl->descent = data.new_descent;
2734 data.db->start_pos = dl->bounds.left_in;
2735 data.db->end_pos = data.pixpos;
2737 return data.pixpos - dl->bounds.left_in;
2740 /* Add a type of glyph to a margin display block. */
2743 add_margin_runes (struct display_line *dl, struct display_block *db, int start,
2744 int count, enum glyph_layout layout, int side, Lisp_Object window)
2746 glyph_block_dynarr *gbd = (side == LEFT_GLYPHS
2748 : dl->right_glyphs);
2751 struct window *w = XWINDOW (window);
2752 struct frame *f = XFRAME (w->frame);
2753 struct device *d = XDEVICE (f->device);
2758 data.window = window;
2761 data.pixpos = start;
2762 data.cursor_type = NO_CURSOR;
2764 data.last_charset = Qunbound;
2765 data.last_findex = DEFAULT_INDEX;
2766 data.result_str = Qnil;
2768 data.new_ascent = dl->ascent;
2769 data.new_descent = dl->descent;
2771 if ((layout == GL_WHITESPACE && side == LEFT_GLYPHS)
2772 || (layout == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS))
2775 elt = Dynarr_length (gbd) - 1;
2782 end = Dynarr_length (gbd);
2785 while (count && ((!reverse && elt < end) || (reverse && elt >= end)))
2787 struct glyph_block *gb = Dynarr_atp (gbd, elt);
2789 if (NILP (gb->extent))
2790 abort (); /* these should have been handled in add_glyph_rune */
2793 ((side == LEFT_GLYPHS &&
2794 extent_begin_glyph_layout (XEXTENT (gb->extent)) == layout)
2795 || (side == RIGHT_GLYPHS &&
2796 extent_end_glyph_layout (XEXTENT (gb->extent)) == layout)))
2798 data.findex = gb->findex;
2799 data.max_pixpos = data.pixpos + gb->width;
2800 add_glyph_rune (&data, gb, side, 0, NULL);
2805 (reverse ? elt-- : elt++);
2808 if (data.max_pixmap_height)
2810 int height = data.new_ascent + data.new_descent;
2811 int pix_ascent, pix_descent;
2813 pix_descent = data.max_pixmap_height * data.new_descent / height;
2814 pix_ascent = data.max_pixmap_height - pix_descent;
2815 data.new_ascent = max (data.new_ascent, pix_ascent);
2816 data.new_descent = max (data.new_descent, pix_descent);
2819 dl->ascent = data.new_ascent;
2820 dl->descent = data.new_descent;
2825 /* Add a blank to a margin display block. */
2828 add_margin_blank (struct display_line *dl, struct display_block *db,
2829 struct window *w, int xpos, int width, int side)
2833 rb.findex = (side == LEFT_GLYPHS
2834 ? get_builtin_face_cache_index (w, Vleft_margin_face)
2835 : get_builtin_face_cache_index (w, Vright_margin_face));
2840 rb.type = RUNE_BLANK;
2841 rb.cursor_type = CURSOR_OFF;
2843 Dynarr_add (db->runes, rb);
2846 /* Display glyphs in the left outside margin, left inside margin and
2847 left whitespace area. */
2850 create_left_glyph_block (struct window *w, struct display_line *dl,
2855 int use_overflow = (NILP (w->use_left_overflow) ? 0 : 1);
2857 int out_end, in_out_start, in_in_end, white_out_start, white_in_start;
2858 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
2859 int left_in_start = dl->bounds.left_in;
2860 int left_in_end = dl->bounds.left_in + overlay_width;
2862 struct display_block *odb, *idb;
2864 XSETWINDOW (window, w);
2866 /* We have to add the glyphs to the line in the order outside,
2867 inside, whitespace. However the precedence dictates that we
2868 determine how many will fit in the reverse order. */
2870 /* Determine how many whitespace glyphs we can display and where
2871 they should start. */
2872 white_in_start = dl->bounds.left_white;
2873 white_out_start = left_in_start;
2874 white_out_cnt = white_in_cnt = 0;
2877 while (elt < Dynarr_length (dl->left_glyphs))
2879 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2881 if (NILP (gb->extent))
2882 abort (); /* these should have been handled in add_glyph_rune */
2884 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
2888 width = glyph_width (gb->glyph, window);
2890 if (white_in_start - width >= left_in_end)
2893 white_in_start -= width;
2897 else if (use_overflow
2898 && (white_out_start - width > dl->bounds.left_out))
2901 white_out_start -= width;
2912 /* Determine how many inside margin glyphs we can display and where
2913 they should start. The inside margin glyphs get whatever space
2914 is left after the whitespace glyphs have been displayed. These
2915 are tricky to calculate since if we decide to use the overflow
2916 area we basically have to start over. So for these we build up a
2917 list of just the inside margin glyphs and manipulate it to
2918 determine the needed info. */
2920 glyph_block_dynarr *ib;
2921 int avail_in, avail_out;
2924 int used_in, used_out;
2927 used_in = used_out = 0;
2928 ib = Dynarr_new (glyph_block);
2929 while (elt < Dynarr_length (dl->left_glyphs))
2931 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2933 if (NILP (gb->extent))
2934 abort (); /* these should have been handled in add_glyph_rune */
2936 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
2939 gb->width = glyph_width (gb->glyph, window);
2940 used_in += gb->width;
2941 Dynarr_add (ib, *gb);
2951 avail_in = white_in_start - left_in_end;
2959 avail_out = white_out_start - dl->bounds.left_out;
2962 while (!done && marker < Dynarr_length (ib))
2964 int width = Dynarr_atp (ib, marker)->width;
2966 /* If everything now fits in the available inside margin
2967 space, we're done. */
2968 if (used_in <= avail_in)
2972 /* Otherwise see if we have room to move a glyph to the
2974 if (used_out + width <= avail_out)
2987 /* At this point we now know that everything from marker on goes in
2988 the inside margin and everything before it goes in the outside
2989 margin. The stuff going into the outside margin is guaranteed
2990 to fit, but we may have to trim some stuff from the inside. */
2992 in_in_end = left_in_end;
2993 in_out_start = white_out_start;
2994 in_out_cnt = in_in_cnt = 0;
2998 while (elt < Dynarr_length (dl->left_glyphs))
3000 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3002 if (NILP (gb->extent))
3003 abort (); /* these should have been handled in add_glyph_rune */
3005 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3008 int width = glyph_width (gb->glyph, window);
3013 in_out_start -= width;
3018 else if (in_in_end + width < white_in_start)
3033 /* Determine how many outside margin glyphs we can display. They
3034 always start at the left outside margin and can only use the
3035 outside margin space. */
3036 out_end = dl->bounds.left_out;
3040 while (elt < Dynarr_length (dl->left_glyphs))
3042 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3044 if (NILP (gb->extent))
3045 abort (); /* these should have been handled in add_glyph_rune */
3047 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3050 int width = glyph_width (gb->glyph, window);
3052 if (out_end + width <= in_out_start)
3066 /* Now that we know where everything goes, we add the glyphs as
3067 runes to the appropriate display blocks. */
3068 if (out_cnt || in_out_cnt || white_out_cnt)
3070 odb = get_display_block_from_line (dl, LEFT_OUTSIDE_MARGIN);
3071 odb->start_pos = dl->bounds.left_out;
3072 /* #### We should stop adding a blank to account for the space
3073 between the end of the glyphs and the margin and instead set
3074 this accordingly. */
3075 odb->end_pos = dl->bounds.left_in;
3076 Dynarr_reset (odb->runes);
3081 if (in_in_cnt || white_in_cnt)
3083 idb = get_display_block_from_line (dl, LEFT_INSIDE_MARGIN);
3084 idb->start_pos = dl->bounds.left_in;
3085 /* #### See above comment for odb->end_pos */
3086 idb->end_pos = dl->bounds.left_white;
3087 Dynarr_reset (idb->runes);
3092 /* First add the outside margin glyphs. */
3094 end_xpos = add_margin_runes (dl, odb, dl->bounds.left_out, out_cnt,
3095 GL_OUTSIDE_MARGIN, LEFT_GLYPHS, window);
3097 end_xpos = dl->bounds.left_out;
3099 /* There may be blank space between the outside margin glyphs and
3100 the inside margin glyphs. If so, add a blank. */
3101 if (in_out_cnt && (in_out_start - end_xpos))
3103 add_margin_blank (dl, odb, w, end_xpos, in_out_start - end_xpos,
3107 /* Next add the inside margin glyphs which are actually in the
3111 end_xpos = add_margin_runes (dl, odb, in_out_start, in_out_cnt,
3112 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3115 /* If we didn't add any inside margin glyphs to the outside margin,
3116 but are adding whitespace glyphs, then we need to add a blank
3118 if (!in_out_cnt && white_out_cnt && (white_out_start - end_xpos))
3120 add_margin_blank (dl, odb, w, end_xpos, white_out_start - end_xpos,
3124 /* Next add the whitespace margin glyphs which are actually in the
3128 end_xpos = add_margin_runes (dl, odb, white_out_start, white_out_cnt,
3129 GL_WHITESPACE, LEFT_GLYPHS, window);
3132 /* We take care of clearing between the end of the glyphs and the
3133 start of the inside margin for lines which have glyphs. */
3134 if (odb && (left_in_start - end_xpos))
3136 add_margin_blank (dl, odb, w, end_xpos, left_in_start - end_xpos,
3140 /* Next add the inside margin glyphs which are actually in the
3144 end_xpos = add_margin_runes (dl, idb, left_in_end, in_in_cnt,
3145 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3148 end_xpos = left_in_end;
3150 /* Make sure that the area between the end of the inside margin
3151 glyphs and the whitespace glyphs is cleared. */
3152 if (idb && (white_in_start - end_xpos > 0))
3154 add_margin_blank (dl, idb, w, end_xpos, white_in_start - end_xpos,
3158 /* Next add the whitespace margin glyphs which are actually in the
3162 add_margin_runes (dl, idb, white_in_start, white_in_cnt, GL_WHITESPACE,
3163 LEFT_GLYPHS, window);
3166 /* Whitespace glyphs always end right next to the text block so
3167 there is nothing we have to make sure is cleared after them. */
3170 /* Display glyphs in the right outside margin, right inside margin and
3171 right whitespace area. */
3174 create_right_glyph_block (struct window *w, struct display_line *dl)
3178 int use_overflow = (NILP (w->use_right_overflow) ? 0 : 1);
3180 int out_start, in_out_end, in_in_start, white_out_end, white_in_end;
3181 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
3183 struct display_block *odb, *idb;
3185 XSETWINDOW (window, w);
3187 /* We have to add the glyphs to the line in the order outside,
3188 inside, whitespace. However the precedence dictates that we
3189 determine how many will fit in the reverse order. */
3191 /* Determine how many whitespace glyphs we can display and where
3192 they should start. */
3193 white_in_end = dl->bounds.right_white;
3194 white_out_end = dl->bounds.right_in;
3195 white_out_cnt = white_in_cnt = 0;
3198 while (elt < Dynarr_length (dl->right_glyphs))
3200 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3202 if (NILP (gb->extent))
3203 abort (); /* these should have been handled in add_glyph_rune */
3205 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
3207 int width = glyph_width (gb->glyph, window);
3209 if (white_in_end + width <= dl->bounds.right_in)
3212 white_in_end += width;
3216 else if (use_overflow
3217 && (white_out_end + width <= dl->bounds.right_out))
3220 white_out_end += width;
3231 /* Determine how many inside margin glyphs we can display and where
3232 they should start. The inside margin glyphs get whatever space
3233 is left after the whitespace glyphs have been displayed. These
3234 are tricky to calculate since if we decide to use the overflow
3235 area we basically have to start over. So for these we build up a
3236 list of just the inside margin glyphs and manipulate it to
3237 determine the needed info. */
3239 glyph_block_dynarr *ib;
3240 int avail_in, avail_out;
3243 int used_in, used_out;
3246 used_in = used_out = 0;
3247 ib = Dynarr_new (glyph_block);
3248 while (elt < Dynarr_length (dl->right_glyphs))
3250 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3252 if (NILP (gb->extent))
3253 abort (); /* these should have been handled in add_glyph_rune */
3255 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3257 gb->width = glyph_width (gb->glyph, window);
3258 used_in += gb->width;
3259 Dynarr_add (ib, *gb);
3268 avail_in = dl->bounds.right_in - white_in_end;
3273 avail_out = dl->bounds.right_out - white_out_end;
3276 while (!done && marker < Dynarr_length (ib))
3278 int width = Dynarr_atp (ib, marker)->width;
3280 /* If everything now fits in the available inside margin
3281 space, we're done. */
3282 if (used_in <= avail_in)
3286 /* Otherwise see if we have room to move a glyph to the
3288 if (used_out + width <= avail_out)
3301 /* At this point we now know that everything from marker on goes in
3302 the inside margin and everything before it goes in the outside
3303 margin. The stuff going into the outside margin is guaranteed
3304 to fit, but we may have to trim some stuff from the inside. */
3306 in_in_start = dl->bounds.right_in;
3307 in_out_end = dl->bounds.right_in;
3308 in_out_cnt = in_in_cnt = 0;
3312 while (elt < Dynarr_length (dl->right_glyphs))
3314 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3316 if (NILP (gb->extent))
3317 abort (); /* these should have been handled in add_glyph_rune */
3319 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3321 int width = glyph_width (gb->glyph, window);
3326 in_out_end += width;
3331 else if (in_in_start - width >= white_in_end)
3334 in_in_start -= width;
3346 /* Determine how many outside margin glyphs we can display. They
3347 always start at the right outside margin and can only use the
3348 outside margin space. */
3349 out_start = dl->bounds.right_out;
3353 while (elt < Dynarr_length (dl->right_glyphs))
3355 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3357 if (NILP (gb->extent))
3358 abort (); /* these should have been handled in add_glyph_rune */
3360 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_OUTSIDE_MARGIN)
3362 int width = glyph_width (gb->glyph, window);
3364 if (out_start - width >= in_out_end)
3378 /* Now that we now where everything goes, we add the glyphs as runes
3379 to the appropriate display blocks. */
3380 if (out_cnt || in_out_cnt || white_out_cnt)
3382 odb = get_display_block_from_line (dl, RIGHT_OUTSIDE_MARGIN);
3383 /* #### See comments before odb->start_pos init in
3384 create_left_glyph_block */
3385 odb->start_pos = dl->bounds.right_in;
3386 odb->end_pos = dl->bounds.right_out;
3387 Dynarr_reset (odb->runes);
3392 if (in_in_cnt || white_in_cnt)
3394 idb = get_display_block_from_line (dl, RIGHT_INSIDE_MARGIN);
3395 idb->start_pos = dl->bounds.right_white;
3396 /* #### See comments before odb->start_pos init in
3397 create_left_glyph_block */
3398 idb->end_pos = dl->bounds.right_in;
3399 Dynarr_reset (idb->runes);
3404 /* First add the whitespace margin glyphs which are actually in the
3408 end_xpos = add_margin_runes (dl, idb, dl->bounds.right_white,
3409 white_in_cnt, GL_WHITESPACE, RIGHT_GLYPHS,
3413 end_xpos = dl->bounds.right_white;
3415 /* Make sure that the area between the end of the whitespace glyphs
3416 and the inside margin glyphs is cleared. */
3417 if (in_in_cnt && (in_in_start - end_xpos))
3419 add_margin_blank (dl, idb, w, end_xpos, in_in_start - end_xpos,
3423 /* Next add the inside margin glyphs which are actually in the
3427 end_xpos = add_margin_runes (dl, idb, in_in_start, in_in_cnt,
3428 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3431 /* If we didn't add any inside margin glyphs then make sure the rest
3432 of the inside margin area gets cleared. */
3433 if (idb && (dl->bounds.right_in - end_xpos))
3435 add_margin_blank (dl, idb, w, end_xpos, dl->bounds.right_in - end_xpos,
3439 /* Next add any whitespace glyphs in the outside margin. */
3442 end_xpos = add_margin_runes (dl, odb, dl->bounds.right_in, white_out_cnt,
3443 GL_WHITESPACE, RIGHT_GLYPHS, window);
3446 end_xpos = dl->bounds.right_in;
3448 /* Next add any inside margin glyphs in the outside margin. */
3451 end_xpos = add_margin_runes (dl, odb, end_xpos, in_out_cnt,
3452 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3455 /* There may be space between any whitespace or inside margin glyphs
3456 in the outside margin and the actual outside margin glyphs. */
3457 if (odb && (out_start - end_xpos))
3459 add_margin_blank (dl, odb, w, end_xpos, out_start - end_xpos,
3463 /* Finally, add the outside margin glyphs. */
3466 add_margin_runes (dl, odb, out_start, out_cnt, GL_OUTSIDE_MARGIN,
3467 RIGHT_GLYPHS, window);
3472 /***************************************************************************/
3474 /* modeline routines */
3476 /***************************************************************************/
3478 /* This function is also used in frame.c by `generate_title_string' */
3480 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str,
3481 struct window *w, struct display_line *dl,
3482 struct display_block *db, face_index findex,
3483 int min_pixpos, int max_pixpos, int type)
3485 struct frame *f = XFRAME (w->frame);
3486 struct device *d = XDEVICE (f->device);
3490 Charcount offset = 0;
3496 data.findex = findex;
3497 data.pixpos = min_pixpos;
3498 data.max_pixpos = max_pixpos;
3499 data.cursor_type = NO_CURSOR;
3500 data.last_charset = Qunbound;
3501 data.last_findex = DEFAULT_INDEX;
3502 data.result_str = result_str;
3503 data.is_modeline = 1;
3505 XSETWINDOW (data.window, w);
3507 Dynarr_reset (formatted_string_extent_dynarr);
3508 Dynarr_reset (formatted_string_extent_start_dynarr);
3509 Dynarr_reset (formatted_string_extent_end_dynarr);
3511 /* result_str is nil when we're building a frame or icon title. Otherwise,
3512 we're building a modeline, so the offset starts at the modeline
3513 horizontal scrolling ammount */
3514 if (! NILP (result_str))
3515 offset = w->modeline_hscroll;
3516 generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0,
3517 max_pixpos - min_pixpos, findex, type, &offset,
3520 if (Dynarr_length (db->runes))
3523 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
3524 c_pixpos = rb->xpos + rb->width;
3527 c_pixpos = min_pixpos;
3529 /* If we don't reach the right side of the window, add a blank rune
3530 to make up the difference. This usually only occurs if the
3531 modeline face is using a proportional width font or a fixed width
3532 font of a different size from the default face font. */
3534 if (c_pixpos < max_pixpos)
3536 data.pixpos = c_pixpos;
3537 data.blank_width = max_pixpos - data.pixpos;
3539 add_blank_rune (&data, NULL, 0);
3542 /* Now create the result string and frob the extents into it. */
3543 if (!NILP (result_str))
3548 struct buffer *buf = XBUFFER (WINDOW_BUFFER (w));
3550 in_modeline_generation = 1;
3552 detach_all_extents (result_str);
3553 resize_string (XSTRING (result_str), -1,
3554 data.bytepos - XSTRING_LENGTH (result_str));
3556 strdata = XSTRING_DATA (result_str);
3558 for (elt = 0, len = 0; elt < Dynarr_length (db->runes); elt++)
3560 if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR)
3562 len += (set_charptr_emchar
3563 (strdata + len, Dynarr_atp (db->runes,
3564 elt)->object.chr.ch));
3568 for (elt = 0; elt < Dynarr_length (formatted_string_extent_dynarr);
3571 Lisp_Object extent = Qnil;
3574 XSETEXTENT (extent, Dynarr_at (formatted_string_extent_dynarr, elt));
3575 child = Fgethash (extent, buf->modeline_extent_table, Qnil);
3578 child = Fmake_extent (Qnil, Qnil, result_str);
3579 Fputhash (extent, child, buf->modeline_extent_table);
3581 Fset_extent_parent (child, extent);
3582 set_extent_endpoints
3584 Dynarr_at (formatted_string_extent_start_dynarr, elt),
3585 Dynarr_at (formatted_string_extent_end_dynarr, elt),
3589 in_modeline_generation = 0;
3593 /* Ensure that the given display line DL accurately represents the
3594 modeline for the given window. */
3596 generate_modeline (struct window *w, struct display_line *dl, int type)
3598 struct buffer *b = XBUFFER (w->buffer);
3599 struct frame *f = XFRAME (w->frame);
3600 struct device *d = XDEVICE (f->device);
3602 /* Unlike display line and rune pointers, this one can't change underneath
3604 struct display_block *db = get_display_block_from_line (dl, TEXT);
3605 int max_pixpos, min_pixpos, ypos_adj;
3606 Lisp_Object font_inst;
3608 /* This will actually determine incorrect inside boundaries for the
3609 modeline since it ignores the margins. However being aware of this fact
3610 we never use those values anywhere so it doesn't matter. */
3611 dl->bounds = calculate_display_line_boundaries (w, 1);
3613 /* We are generating a modeline. */
3615 dl->cursor_elt = -1;
3617 /* Reset the runes on the modeline. */
3618 Dynarr_reset (db->runes);
3620 if (!WINDOW_HAS_MODELINE_P (w))
3624 /* If there is a horizontal scrollbar, don't add anything. */
3625 if (window_scrollbar_height (w))
3628 dl->ascent = DEVMETH (d, divider_height, ());
3630 /* The modeline is at the bottom of the gutters. */
3631 dl->ypos = WINDOW_BOTTOM (w);
3633 rb.findex = MODELINE_INDEX;
3634 rb.xpos = dl->bounds.left_out;
3635 rb.width = dl->bounds.right_out - dl->bounds.left_out;
3638 rb.type = RUNE_HLINE;
3639 rb.object.hline.thickness = 1;
3640 rb.object.hline.yoffset = 0;
3641 rb.cursor_type = NO_CURSOR;
3643 if (!EQ (Qzero, w->modeline_shadow_thickness)
3646 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3648 dl->ypos -= shadow_thickness;
3649 rb.xpos += shadow_thickness;
3650 rb.width -= 2 * shadow_thickness;
3653 Dynarr_add (db->runes, rb);
3657 /* !!#### not right; needs to compute the max height of
3659 font_inst = WINDOW_FACE_CACHEL_FONT (w, MODELINE_INDEX, Vcharset_ascii);
3661 dl->ascent = XFONT_INSTANCE (font_inst)->ascent;
3662 dl->descent = XFONT_INSTANCE (font_inst)->descent;
3664 min_pixpos = dl->bounds.left_out;
3665 max_pixpos = dl->bounds.right_out;
3667 if (!EQ (Qzero, w->modeline_shadow_thickness) && FRAME_WIN_P (f))
3669 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3671 ypos_adj = shadow_thickness;
3672 min_pixpos += shadow_thickness;
3673 max_pixpos -= shadow_thickness;
3678 generate_formatted_string_db (b->modeline_format,
3679 b->generated_modeline_string, w, dl, db,
3680 MODELINE_INDEX, min_pixpos, max_pixpos, type);
3682 /* The modeline is at the bottom of the gutters. We have to wait to
3683 set this until we've generated the modeline in order to account
3684 for any embedded faces. */
3685 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj;
3689 add_string_to_fstring_db_runes (pos_data *data, const Bufbyte *str,
3690 Charcount pos, Charcount min_pos, Charcount max_pos)
3692 /* This function has been Mule-ized. */
3694 const Bufbyte *cur_pos = str;
3695 struct display_block *db = data->db;
3697 data->blank_width = space_width (XWINDOW (data->window));
3698 while (Dynarr_length (db->runes) < pos)
3699 add_blank_rune (data, NULL, 0);
3701 end = (Dynarr_length (db->runes) +
3702 bytecount_to_charcount (str, strlen ((const char *) str)));
3704 end = min (max_pos, end);
3706 while (pos < end && *cur_pos)
3708 const Bufbyte *old_cur_pos = cur_pos;
3711 data->ch = charptr_emchar (cur_pos);
3712 succeeded = (add_emchar_rune (data) != ADD_FAILED);
3713 INC_CHARPTR (cur_pos);
3717 data->modeline_charpos++;
3718 data->bytepos += cur_pos - old_cur_pos;
3722 while (Dynarr_length (db->runes) < min_pos &&
3723 (data->pixpos + data->blank_width <= data->max_pixpos))
3724 add_blank_rune (data, NULL, 0);
3726 return Dynarr_length (db->runes);
3729 /* #### Urk! Should also handle begin-glyphs and end-glyphs in
3730 modeline extents. */
3732 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph,
3733 Charcount pos, Charcount min_pos,
3734 Charcount max_pos, Lisp_Object extent)
3736 /* This function has been Mule-ized. */
3738 struct display_block *db = data->db;
3739 struct glyph_block gb;
3741 data->blank_width = space_width (XWINDOW (data->window));
3742 while (Dynarr_length (db->runes) < pos)
3743 add_blank_rune (data, NULL, 0);
3745 end = Dynarr_length (db->runes) + 1;
3747 end = min (max_pos, end);
3751 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
3754 while (Dynarr_length (db->runes) < pos &&
3755 (data->pixpos + data->blank_width <= data->max_pixpos))
3756 add_blank_rune (data, NULL, 0);
3758 return Dynarr_length (db->runes);
3761 /* If max_pos is == -1, it is considered to be infinite. The same is
3762 true of max_pixsize. */
3763 #define SET_CURRENT_MODE_CHARS_PIXSIZE \
3764 if (Dynarr_length (data->db->runes)) \
3765 cur_pixsize = data->pixpos - Dynarr_atp (data->db->runes, 0)->xpos; \
3769 /* Note that this function does "positions" in terms of characters and
3770 not in terms of columns. This is necessary to make the formatting
3771 work correctly when proportional width fonts are used in the
3774 generate_fstring_runes (struct window *w, pos_data *data, Charcount pos,
3775 Charcount min_pos, Charcount max_pos,
3776 Lisp_Object elt, int depth, int max_pixsize,
3777 face_index findex, int type, Charcount *offset,
3778 Lisp_Object cur_ext)
3780 /* This function has been Mule-ized. */
3781 /* #### The other losing things in this function are:
3783 -- C zero-terminated-string lossage.
3784 -- Non-printable characters should be converted into something
3785 appropriate (e.g. ^F) instead of blindly being printed anyway.
3796 /* A string. Add to the display line and check for %-constructs
3799 Bufbyte *this = XSTRING_DATA (elt);
3801 while ((pos < max_pos || max_pos == -1) && *this)
3803 Bufbyte *last = this;
3805 while (*this && *this != '%')
3810 /* No %-construct */
3812 bytecount_to_charcount (last, this - last);
3814 if (size <= *offset)
3818 Charcount tmp_max = (max_pos == -1 ? pos + size - *offset :
3819 min (pos + size - *offset, max_pos));
3820 const Bufbyte *tmp_last = charptr_n_addr (last, *offset);
3822 pos = add_string_to_fstring_db_runes (data, tmp_last,
3827 else /* *this == '%' */
3829 Charcount spec_width = 0;
3831 this++; /* skip over '%' */
3833 /* We can't allow -ve args due to the "%-" construct.
3834 * Argument specifies minwidth but not maxwidth
3835 * (maxwidth can be specified by
3836 * (<negative-number> . <stuff>) modeline elements)
3838 while (isdigit (*this))
3840 spec_width = spec_width * 10 + (*this - '0');
3847 pos = generate_fstring_runes (w, data, pos, spec_width,
3848 max_pos, Vglobal_mode_string,
3849 depth, max_pixsize, findex,
3850 type, offset, cur_ext);
3852 else if (*this == '-')
3854 Charcount num_to_add;
3856 if (max_pixsize < 0)
3858 else if (max_pos != -1)
3859 num_to_add = max_pos - pos;
3865 SET_CURRENT_MODE_CHARS_PIXSIZE;
3868 redisplay_text_width_string (w, findex, &ch, Qnil, 0,
3871 num_to_add = (max_pixsize - cur_pixsize) / dash_pixsize;
3875 while (num_to_add--)
3876 pos = add_string_to_fstring_db_runes
3877 (data, (const Bufbyte *) "-", pos, pos, max_pos);
3879 else if (*this != 0)
3881 Emchar ch = charptr_emchar (this);
3885 decode_mode_spec (w, ch, type);
3887 str = Dynarr_atp (mode_spec_bufbyte_string, 0);
3888 size = bytecount_to_charcount
3889 /* Skip the null character added by `decode_mode_spec' */
3890 (str, Dynarr_length (mode_spec_bufbyte_string)) - 1;
3892 if (size <= *offset)
3896 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3898 /* #### NOTE: I don't understand why a tmp_max is not
3899 computed and used here as in the plain string case
3901 pos = add_string_to_fstring_db_runes (data, tmp_str,
3908 /* NOT this++. There could be any sort of character at
3909 the current position. */
3913 if (max_pixsize > 0)
3916 SET_CURRENT_MODE_CHARS_PIXSIZE;
3918 if (cur_pixsize >= max_pixsize)
3923 else if (SYMBOLP (elt))
3925 /* A symbol: process the value of the symbol recursively
3926 as if it appeared here directly. */
3927 Lisp_Object tem = symbol_value_in_buffer (elt, w->buffer);
3929 if (!UNBOUNDP (tem))
3931 /* If value is a string, output that string literally:
3932 don't check for % within it. */
3935 Bufbyte *str = XSTRING_DATA (tem);
3936 Charcount size = XSTRING_CHAR_LENGTH (tem);
3938 if (size <= *offset)
3942 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3944 /* #### NOTE: I don't understand why a tmp_max is not
3945 computed and used here as in the plain string case
3947 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
3952 /* Give up right away for nil or t. */
3953 else if (!EQ (tem, elt))
3960 else if (GENERIC_SPECIFIERP (elt))
3962 Lisp_Object window, tem;
3963 XSETWINDOW (window, w);
3964 tem = specifier_instance_no_quit (elt, Qunbound, window,
3965 ERROR_ME_NOT, 0, Qzero);
3966 if (!UNBOUNDP (tem))
3972 else if (CONSP (elt))
3974 /* A cons cell: four distinct cases.
3975 * - If first element is a string or a cons, process all the elements
3976 * and effectively concatenate them.
3977 * - If first element is a negative number, truncate displaying cdr to
3978 * at most that many characters. If positive, pad (with spaces)
3979 * to at least that many characters.
3980 * - If first element is another symbol, process the cadr or caddr
3981 * recursively according to whether the symbol's value is non-nil or
3983 * - If first element is a face, process the cdr recursively
3984 * without altering the depth.
3987 Lisp_Object car, tem;
3996 tem = symbol_value_in_buffer (car, w->buffer);
3997 /* elt is now the cdr, and we know it is a cons cell.
3998 Use its car if CAR has a non-nil value. */
3999 if (!UNBOUNDP (tem))
4007 /* Symbol's value is nil (or symbol is unbound)
4008 * Get the cddr of the original list
4009 * and if possible find the caddr and use that.
4014 else if (!CONSP (elt))
4022 else if (INTP (car))
4024 Charcount lim = XINT (car);
4030 /* Negative int means reduce maximum width.
4031 * DO NOT change MIN_PIXPOS here!
4032 * (20 -10 . foo) should truncate foo to 10 col
4033 * and then pad to 20.
4036 max_pos = pos - lim;
4038 max_pos = min (max_pos, pos - lim);
4042 /* Padding specified. Don't let it be more than
4046 if (max_pos != -1 && lim > max_pos)
4048 /* If that's more padding than already wanted, queue it.
4049 * But don't reduce padding already specified even if
4050 * that is beyond the current truncation point.
4057 else if (STRINGP (car) || CONSP (car))
4061 /* LIMIT is to protect against circular lists. */
4062 while (CONSP (elt) && --limit > 0
4063 && (pos < max_pos || max_pos == -1))
4065 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4066 XCAR (elt), depth, max_pixsize,
4067 findex, type, offset, cur_ext);
4071 else if (EXTENTP (car))
4073 struct extent *ext = XEXTENT (car);
4075 if (EXTENT_LIVE_P (ext))
4077 face_index old_findex = data->findex;
4079 Lisp_Object font_inst;
4080 face_index new_findex;
4081 Bytecount start = data->bytepos;
4083 face = extent_face (ext);
4086 /* #### needs to merge faces, sigh */
4087 /* #### needs to handle list of faces */
4088 new_findex = get_builtin_face_cache_index (w, face);
4089 /* !!#### not right; needs to compute the max height of
4091 font_inst = WINDOW_FACE_CACHEL_FONT (w, new_findex,
4094 data->dl->ascent = max (data->dl->ascent,
4095 XFONT_INSTANCE (font_inst)->ascent);
4096 data->dl->descent = max (data->dl->descent,
4097 XFONT_INSTANCE (font_inst)->
4101 new_findex = old_findex;
4103 data->findex = new_findex;
4104 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4105 XCDR (elt), depth - 1,
4106 max_pixsize, new_findex, type,
4108 data->findex = old_findex;
4109 Dynarr_add (formatted_string_extent_dynarr, ext);
4110 Dynarr_add (formatted_string_extent_start_dynarr, start);
4111 Dynarr_add (formatted_string_extent_end_dynarr, data->bytepos);
4115 else if (GLYPHP (elt))
4117 /* Glyphs are considered as one character with respect to the modeline
4118 horizontal scrolling facility. -- dv */
4122 pos = add_glyph_to_fstring_db_runes (data, elt, pos, pos, max_pos,
4129 char *str = GETTEXT ("*invalid*");
4130 Charcount size = (Charcount) strlen (str); /* is this ok ?? -- dv */
4132 if (size <= *offset)
4136 const Bufbyte *tmp_str =
4137 charptr_n_addr ((const Bufbyte *) str, *offset);
4139 /* #### NOTE: I don't understand why a tmp_max is not computed and
4140 used here as in the plain string case above. -- dv */
4141 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
4150 add_string_to_fstring_db_runes (data, (const Bufbyte *) "", pos,
4157 /* Update just the modeline. Assumes the desired display structs. If
4158 they do not have a modeline block, it does nothing. */
4160 regenerate_modeline (struct window *w)
4162 display_line_dynarr *dla = window_display_lines (w, DESIRED_DISP);
4164 if (!Dynarr_length (dla) || !Dynarr_atp (dla, 0)->modeline)
4168 generate_modeline (w, Dynarr_atp (dla, 0), DESIRED_DISP);
4169 redisplay_update_line (w, 0, 0, 0);
4173 /* Make sure that modeline display line is present in the given
4174 display structs if the window has a modeline and update that
4175 line. Returns true if a modeline was needed. */
4177 ensure_modeline_generated (struct window *w, int type)
4181 /* minibuffer windows don't have modelines */
4182 if (MINI_WINDOW_P (w))
4184 /* windows which haven't had it turned off do */
4185 else if (WINDOW_HAS_MODELINE_P (w))
4187 /* windows which have it turned off don't have a divider if there is
4188 a horizontal scrollbar */
4189 else if (window_scrollbar_height (w))
4191 /* and in this case there is none */
4197 display_line_dynarr *dla;
4199 dla = window_display_lines (w, type);
4201 /* We don't care if there is a display line which is not
4202 currently a modeline because it is definitely going to become
4203 one if we have gotten to this point. */
4204 if (Dynarr_length (dla) == 0)
4206 if (Dynarr_largest (dla) > 0)
4208 struct display_line *mlp = Dynarr_atp (dla, 0);
4209 Dynarr_add (dla, *mlp);
4213 struct display_line modeline;
4215 Dynarr_add (dla, modeline);
4219 /* If we're adding a new place marker go ahead and generate the
4220 modeline so that it is available for use by
4221 window_modeline_height. */
4222 generate_modeline (w, Dynarr_atp (dla, 0), type);
4225 return need_modeline;
4228 /* #### Kludge or not a kludge. I tend towards the former. */
4230 real_current_modeline_height (struct window *w)
4232 Fset_marker (w->start[CMOTION_DISP], w->start[CURRENT_DISP], w->buffer);
4233 Fset_marker (w->pointm[CMOTION_DISP], w->pointm[CURRENT_DISP], w->buffer);
4235 if (ensure_modeline_generated (w, CMOTION_DISP))
4237 display_line_dynarr *dla = window_display_lines (w, CMOTION_DISP);
4239 if (Dynarr_length (dla))
4241 if (Dynarr_atp (dla, 0)->modeline)
4242 return (Dynarr_atp (dla, 0)->ascent +
4243 Dynarr_atp (dla, 0)->descent);
4250 /***************************************************************************/
4252 /* displayable string routines */
4254 /***************************************************************************/
4256 /* Given a position for a string in a window, ensure that the given
4257 display line DL accurately represents the text on a line starting
4258 at the given position.
4260 Yes, this is duplicating the code of create_text_block, but it
4261 looked just too hard to change create_text_block to handle strings
4262 *and* buffers. We already make a distinction between the two
4263 elsewhere in the code so I think unifying them would require a
4264 complete MULE rewrite. Besides, the other distinction is that these
4265 functions cover text that the user *cannot edit* so we can remove
4266 everything to do with cursors, minibuffers etc. Eventually the
4267 modeline routines should be modified to use this code as it copes
4268 with many more types of display situation. */
4271 create_string_text_block (struct window *w, Lisp_Object disp_string,
4272 struct display_line *dl,
4274 prop_block_dynarr **prop,
4275 face_index default_face)
4277 struct frame *f = XFRAME (w->frame);
4278 /* Note that a lot of the buffer controlled stuff has been left in
4279 because you might well want to make use of it (selective display
4280 etc), its just the buffer text that we do not use. However, it
4281 seems to be possible for buffer to be nil sometimes so protect
4282 against this case. */
4283 struct buffer *b = BUFFERP (w->buffer) ? XBUFFER (w->buffer) : 0;
4284 struct device *d = XDEVICE (f->device);
4285 Lisp_String* s = XSTRING (disp_string);
4287 /* we're working with these a lot so precalculate them */
4288 Bytecount slen = XSTRING_LENGTH (disp_string);
4289 Bytecount bi_string_zv = slen;
4290 Bytind bi_start_pos = charcount_to_bytecount (string_data (s), start_pos);
4294 int truncate_win = b ? window_truncation_on (w) : 0;
4295 int end_glyph_width = 0;
4297 /* we're going to ditch selective display for static text, its an
4298 FSF thing and invisble extents are the way to go
4299 here. Implementing it also relies on a number of buffer-specific
4300 functions that we don't have the luxury of being able to use
4303 /* The variable ctl-arrow allows the user to specify what characters
4304 can actually be displayed and which octal should be used for.
4305 #### This variable should probably have some rethought done to
4308 #### It would also be really nice if you could specify that
4309 the characters come out in hex instead of in octal. Mule
4310 does that by adding a ctl-hexa variable similar to ctl-arrow,
4311 but that's bogus -- we need a more general solution. I
4312 think you need to extend the concept of display tables
4313 into a more general conversion mechanism. Ideally you
4314 could specify a Lisp function that converts characters,
4315 but this violates the Second Golden Rule and besides would
4316 make things way way way way slow.
4318 So instead, we extend the display-table concept, which was
4319 historically limited to 256-byte vectors, to one of the
4322 a) A 256-entry vector, for backward compatibility;
4323 b) char-table, mapping characters to values;
4324 c) range-table, mapping ranges of characters to values;
4325 d) a list of the above.
4327 The (d) option allows you to specify multiple display tables
4328 instead of just one. Each display table can specify conversions
4329 for some characters and leave others unchanged. The way the
4330 character gets displayed is determined by the first display table
4331 with a binding for that character. This way, you could call a
4332 function `enable-hex-display' that adds a hex display-table to
4333 the list of display tables for the current buffer.
4335 #### ...not yet implemented... Also, we extend the concept of
4336 "mapping" to include a printf-like spec. Thus you can make all
4337 extended characters show up as hex with a display table like
4340 #s(range-table data ((256 524288) (format "%x")))
4342 Since more than one display table is possible, you have
4343 great flexibility in mapping ranges of characters. */
4344 Emchar printable_min = b ? (CHAR_OR_CHAR_INTP (b->ctl_arrow)
4345 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
4346 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
4347 ? 255 : 160)) : 255;
4349 Lisp_Object face_dt, window_dt;
4351 /* The text display block for this display line. */
4352 struct display_block *db = get_display_block_from_line (dl, TEXT);
4354 /* The first time through the main loop we need to force the glyph
4355 data to be updated. */
4358 /* Apparently the new extent_fragment_update returns an end position
4359 equal to the position passed in if there are no more runs to be
4361 int no_more_frags = 0;
4363 dl->used_prop_data = 0;
4365 dl->line_continuation = 0;
4367 /* set up faces to use for clearing areas, used by
4368 output_display_line */
4369 dl->default_findex = default_face;
4372 dl->left_margin_findex = default_face;
4373 dl->right_margin_findex = default_face;
4377 dl->left_margin_findex =
4378 get_builtin_face_cache_index (w, Vleft_margin_face);
4379 dl->right_margin_findex =
4380 get_builtin_face_cache_index (w, Vright_margin_face);
4384 data.ef = extent_fragment_new (disp_string, f);
4386 /* These values are used by all of the rune addition routines. We add
4387 them to this structure for ease of passing. */
4389 XSETWINDOW (data.window, w);
4393 data.bi_bufpos = bi_start_pos;
4394 data.pixpos = dl->bounds.left_in;
4395 data.last_charset = Qunbound;
4396 data.last_findex = default_face;
4397 data.result_str = Qnil;
4398 data.string = disp_string;
4400 /* Set the right boundary adjusting it to take into account any end
4401 glyph. Save the width of the end glyph for later use. */
4402 data.max_pixpos = dl->bounds.right_in;
4405 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
4407 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
4409 data.max_pixpos -= end_glyph_width;
4411 data.cursor_type = NO_CURSOR;
4415 /* I don't think we want this, string areas should not scroll with
4417 data.start_col = w->hscroll;
4418 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
4420 data.bi_start_col_enabled = 0;
4421 data.hscroll_glyph_width_adjust = 0;
4423 /* We regenerate the line from the very beginning. */
4424 Dynarr_reset (db->runes);
4426 /* Why is this less than or equal and not just less than? If the
4427 starting position is already equal to the maximum we can't add
4428 anything else, right? Wrong. We might still have a newline to
4429 add. A newline can use the room allocated for an end glyph since
4430 if we add it we know we aren't going to be adding any end
4433 /* #### Chuck -- I think this condition should be while (1).
4434 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
4435 and the begin-glyph ends exactly at the end of the window, the
4436 end-glyph and text might not be displayed. while (1) ensures
4437 that the loop terminates only when either (a) there is
4438 propagation data or (b) the end-of-line or end-of-buffer is hit.
4440 #### Also I think you need to ensure that the operation
4441 "add begin glyphs; add end glyphs; add text" is atomic and
4442 can't get interrupted in the middle. If you run off the end
4443 of the line during that operation, then you keep accumulating
4444 propagation data until you're done. Otherwise, if the (e.g.)
4445 there's a begin glyph at a particular position and attempting
4446 to display that glyph results in window-end being hit and
4447 propagation data being generated, then the character at that
4448 position won't be displayed.
4450 #### See also the comment after the end of this loop, below.
4452 while (data.pixpos <= data.max_pixpos)
4454 /* #### This check probably should not be necessary. */
4455 if (data.bi_bufpos > bi_string_zv)
4457 /* #### urk! More of this lossage! */
4462 /* Check for face changes. */
4463 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
4465 /* Now compute the face and begin/end-glyph information. */
4467 /* Remember that the extent-fragment routines deal in Bytind's. */
4468 extent_fragment_update (w, data.ef, data.bi_bufpos);
4469 /* This is somewhat cheesy but the alternative is to
4470 propagate default_face into extent_fragment_update. */
4471 if (data.findex == DEFAULT_INDEX)
4472 data.findex = default_face;
4474 get_display_tables (w, data.findex, &face_dt, &window_dt);
4476 if (data.bi_bufpos == data.ef->end)
4481 /* Determine what is next to be displayed. We first handle any
4482 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
4483 display then we determine what to do based on the character at the
4484 current buffer position. */
4486 /* If the current position is covered by an invisible extent, do
4487 nothing (except maybe add some ellipses).
4489 #### The behavior of begin and end-glyphs at the edge of an
4490 invisible extent should be investigated further. This is
4491 fairly low priority though. */
4492 if (data.ef->invisible)
4494 /* #### Chuck, perhaps you could look at this code? I don't
4495 really know what I'm doing. */
4498 Dynarr_free (*prop);
4502 /* The extent fragment code only sets this when we should
4503 really display the ellipses. It makes sure the ellipses
4504 don't get displayed more than once in a row. */
4505 if (data.ef->invisible_ellipses)
4507 struct glyph_block gb;
4509 data.ef->invisible_ellipses_already_displayed = 1;
4510 data.ef->invisible_ellipses = 0;
4512 gb.glyph = Vinvisible_text_glyph;
4513 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
4514 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
4515 /* Perhaps they shouldn't propagate if the very next thing
4516 is to display a newline (for compatibility with
4517 selective-display-ellipses)? Maybe that's too
4523 /* #### What if we we're dealing with a display table? */
4527 if (data.bi_bufpos == bi_string_zv)
4530 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4533 /* If there is propagation data, then it represents the current
4534 buffer position being displayed. Add them and advance the
4535 position counter. This might also add the minibuffer
4539 dl->used_prop_data = 1;
4540 *prop = add_propagation_runes (prop, &data);
4543 goto done; /* gee, a really narrow window */
4544 else if (data.bi_bufpos == bi_string_zv)
4546 else if (data.bi_bufpos < 0)
4547 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
4550 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4553 /* If there are end glyphs, add them to the line. These are
4554 the end glyphs for the previous run of text. We add them
4555 here rather than doing them at the end of handling the
4556 previous run so that glyphs at the beginning and end of
4557 a line are handled correctly. */
4558 else if (Dynarr_length (data.ef->end_glyphs) > 0)
4560 *prop = add_glyph_runes (&data, END_GLYPHS);
4565 /* If there are begin glyphs, add them to the line. */
4566 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
4568 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
4573 /* If at end-of-buffer, we've already processed begin and
4574 end-glyphs at this point and there's no text to process,
4576 else if (data.bi_bufpos == bi_string_zv)
4581 Lisp_Object entry = Qnil;
4582 /* Get the character at the current buffer position. */
4583 data.ch = string_char (s, data.bi_bufpos);
4584 if (!NILP (face_dt) || !NILP (window_dt))
4585 entry = display_table_entry (data.ch, face_dt, window_dt);
4587 /* If there is a display table entry for it, hand it off to
4588 add_disp_table_entry_runes and let it worry about it. */
4589 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
4591 *prop = add_disp_table_entry_runes (&data, entry);
4597 /* Check if we have hit a newline character. If so, add a marker
4598 to the line and end this loop. */
4599 else if (data.ch == '\n')
4601 /* We aren't going to be adding an end glyph so give its
4602 space back in order to make sure that the cursor can
4604 data.max_pixpos += end_glyph_width;
4608 /* If the current character is considered to be printable, then
4610 else if (data.ch >= printable_min)
4612 *prop = add_emchar_rune (&data);
4617 /* If the current character is a tab, determine the next tab
4618 starting position and add a blank rune which extends from the
4619 current pixel position to that starting position. */
4620 else if (data.ch == '\t')
4622 int tab_start_pixpos = data.pixpos;
4627 if (data.start_col > 1)
4628 tab_start_pixpos -= (space_width (w) * (data.start_col - 1));
4631 next_tab_position (w, tab_start_pixpos,
4632 dl->bounds.left_in +
4633 data.hscroll_glyph_width_adjust);
4634 if (next_tab_start > data.max_pixpos)
4636 prop_width = next_tab_start - data.max_pixpos;
4637 next_tab_start = data.max_pixpos;
4639 data.blank_width = next_tab_start - data.pixpos;
4641 (next_tab_start - tab_start_pixpos) / space_width (w);
4643 *prop = add_blank_rune (&data, w, char_tab_width);
4645 /* add_blank_rune is only supposed to be called with
4646 sizes guaranteed to fit in the available space. */
4651 struct prop_block pb;
4652 *prop = Dynarr_new (prop_block);
4654 pb.type = PROP_BLANK;
4655 pb.data.p_blank.width = prop_width;
4656 pb.data.p_blank.findex = data.findex;
4657 Dynarr_add (*prop, pb);
4663 /* If character is a control character, pass it off to
4664 add_control_char_runes.
4666 The is_*() routines have undefined results on
4667 arguments outside of the range [-1, 255]. (This
4668 often bites people who carelessly use `char' instead
4669 of `unsigned char'.)
4671 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
4673 *prop = add_control_char_runes (&data, b);
4679 /* If the character is above the ASCII range and we have not
4680 already handled it, then print it as an octal number. */
4681 else if (data.ch >= 0200)
4683 *prop = add_octal_runes (&data);
4689 /* Assume the current character is considered to be printable,
4690 then just add it. */
4693 *prop = add_emchar_rune (&data);
4698 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4704 /* Determine the starting point of the next line if we did not hit the
4705 end of the buffer. */
4706 if (data.bi_bufpos < bi_string_zv)
4708 /* #### This check is not correct. If the line terminated
4709 due to a begin-glyph or end-glyph hitting window-end, then
4710 data.ch will not point to the character at data.bi_bufpos. If
4711 you make the two changes mentioned at the top of this loop,
4712 you should be able to say '(if (*prop))'. That should also
4713 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
4716 /* The common case is that the line ended because we hit a newline.
4717 In that case, the next character is just the next buffer
4719 if (data.ch == '\n')
4721 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4724 /* Otherwise we have a buffer line which cannot fit on one display
4728 struct glyph_block gb;
4729 struct glyph_cachel *cachel;
4731 /* If the line is to be truncated then we actually have to look
4732 for the next newline. We also add the end-of-line glyph which
4733 we know will fit because we adjusted the right border before
4734 we starting laying out the line. */
4735 data.max_pixpos += end_glyph_width;
4736 data.findex = default_face;
4743 /* Now find the start of the next line. */
4744 bi_pos = bi_find_next_emchar_in_string (s, '\n', data.bi_bufpos, 1);
4746 data.cursor_type = NO_CURSOR;
4747 data.bi_bufpos = bi_pos;
4748 gb.glyph = Vtruncation_glyph;
4749 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
4753 /* The cursor can never be on the continuation glyph. */
4754 data.cursor_type = NO_CURSOR;
4756 /* data.bi_bufpos is already at the start of the next line. */
4758 dl->line_continuation = 1;
4759 gb.glyph = Vcontinuation_glyph;
4760 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
4763 if (end_glyph_width)
4764 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
4766 if (truncate_win && data.bi_bufpos == bi_string_zv)
4768 const Bufbyte* endb = charptr_n_addr (string_data (s), bi_string_zv);
4770 if (charptr_emchar (endb) != '\n')
4772 /* #### Damn this losing shit. */
4778 else if (data.bi_bufpos == bi_string_zv)
4780 /* create_text_block () adds a bogus \n marker here which screws
4781 up subwindow display. Since we never have a cursor in the
4782 gutter we can safely ignore it. */
4784 /* Calculate left whitespace boundary. */
4788 /* Whitespace past a newline is considered right whitespace. */
4789 while (elt < Dynarr_length (db->runes))
4791 struct rune *rb = Dynarr_atp (db->runes, elt);
4793 if ((rb->type == RUNE_CHAR && rb->object.chr.ch == ' ')
4794 || rb->type == RUNE_BLANK)
4796 dl->bounds.left_white += rb->width;
4800 elt = Dynarr_length (db->runes);
4804 /* Calculate right whitespace boundary. */
4806 int elt = Dynarr_length (db->runes) - 1;
4809 while (!done && elt >= 0)
4811 struct rune *rb = Dynarr_atp (db->runes, elt);
4813 if (!(rb->type == RUNE_CHAR && rb->object.chr.ch < 0x100
4814 && isspace (rb->object.chr.ch))
4815 && !rb->type == RUNE_BLANK)
4817 dl->bounds.right_white = rb->xpos + rb->width;
4825 /* The line is blank so everything is considered to be right
4828 dl->bounds.right_white = dl->bounds.left_in;
4831 /* Set the display blocks bounds. */
4832 db->start_pos = dl->bounds.left_in;
4833 if (Dynarr_length (db->runes))
4835 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
4837 db->end_pos = rb->xpos + rb->width;
4840 db->end_pos = dl->bounds.right_white;
4842 /* update line height parameters */
4843 if (!data.new_ascent && !data.new_descent)
4845 /* We've got a blank line so initialize these values from the default
4847 default_face_font_info (data.window, &data.new_ascent,
4848 &data.new_descent, 0, 0, 0);
4851 if (data.max_pixmap_height)
4853 int height = data.new_ascent + data.new_descent;
4854 int pix_ascent, pix_descent;
4856 pix_descent = data.max_pixmap_height * data.new_descent / height;
4857 pix_ascent = data.max_pixmap_height - pix_descent;
4859 data.new_ascent = max (data.new_ascent, pix_ascent);
4860 data.new_descent = max (data.new_descent, pix_descent);
4863 dl->ascent = data.new_ascent;
4864 dl->descent = data.new_descent;
4867 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
4869 if (dl->ascent < ascent)
4870 dl->ascent = ascent;
4873 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
4875 if (dl->descent < descent)
4876 dl->descent = descent;
4879 dl->cursor_elt = data.cursor_x;
4880 /* #### lossage lossage lossage! Fix this shit! */
4881 if (data.bi_bufpos > bi_string_zv)
4882 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, bi_string_zv);
4884 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, data.bi_bufpos) - 1;
4886 data.dl->num_chars =
4887 string_column_at_point (s, dl->end_bufpos, b ? XINT (b->tab_width) : 8);
4889 /* This doesn't correctly take into account tabs and control
4890 characters but if the window isn't being truncated then this
4891 value isn't going to end up being used anyhow. */
4892 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
4894 /* #### handle horizontally scrolled line with text none of which
4895 was actually laid out. */
4897 /* #### handle any remainder of overlay arrow */
4899 if (*prop == ADD_FAILED)
4902 if (truncate_win && *prop)
4904 Dynarr_free (*prop);
4908 extent_fragment_delete (data.ef);
4910 /* #### If we started at EOB, then make sure we return a value past
4911 it so that regenerate_window will exit properly. This is bogus.
4912 The main loop should get fixed so that it isn't necessary to call
4913 this function if we are already at EOB. */
4915 if (data.bi_bufpos == bi_string_zv && bi_start_pos == bi_string_zv)
4916 return bytecount_to_charcount (string_data (s), data.bi_bufpos) + 1; /* Yuck! */
4918 return bytecount_to_charcount (string_data (s), data.bi_bufpos);
4921 /* Given a display line and a starting position, ensure that the
4922 contents of the display line accurately represent the visual
4923 representation of the buffer contents starting from the given
4924 position when displayed in the given window. The display line ends
4925 when the contents of the line reach the right boundary of the given
4928 This is very similar to generate_display_line but with the same
4929 limitations as create_string_text_block. I have taken the liberty
4930 of fixing the bytind stuff though.*/
4933 generate_string_display_line (struct window *w, Lisp_Object disp_string,
4934 struct display_line *dl,
4936 prop_block_dynarr **prop,
4937 face_index default_face)
4941 /* you must set bounds before calling this. */
4943 /* Reset what this line is using. */
4944 if (dl->display_blocks)
4945 Dynarr_reset (dl->display_blocks);
4946 if (dl->left_glyphs)
4948 Dynarr_free (dl->left_glyphs);
4949 dl->left_glyphs = 0;
4951 if (dl->right_glyphs)
4953 Dynarr_free (dl->right_glyphs);
4954 dl->right_glyphs = 0;
4957 /* We aren't generating a modeline at the moment. */
4960 /* Create a display block for the text region of the line. */
4961 ret_bufpos = create_string_text_block (w, disp_string, dl, start_pos,
4962 prop, default_face);
4963 dl->bufpos = start_pos;
4964 if (dl->end_bufpos < dl->bufpos)
4965 dl->end_bufpos = dl->bufpos;
4967 /* If there are left glyphs associated with any character in the
4968 text block, then create a display block to handle them. */
4969 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
4970 create_left_glyph_block (w, dl, 0);
4972 /* If there are right glyphs associated with any character in the
4973 text block, then create a display block to handle them. */
4974 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
4975 create_right_glyph_block (w, dl);
4980 /* This is ripped off from regenerate_window. All we want to do is
4981 loop through elements in the string creating display lines until we
4982 have covered the provided area. Simple really. */
4984 generate_displayable_area (struct window *w, Lisp_Object disp_string,
4985 int xpos, int ypos, int width, int height,
4986 display_line_dynarr* dla,
4988 face_index default_face)
4990 int yend = ypos + height;
4993 prop_block_dynarr *prop = 0;
4994 layout_bounds bounds;
4998 /* if there's nothing to do then do nothing. code after this assumes
4999 there is something to do. */
5000 if (NILP (disp_string))
5003 s_zv = XSTRING_CHAR_LENGTH (disp_string);
5005 bounds.left_out = xpos;
5006 bounds.right_out = xpos + width;
5007 /* The inner boundaries mark where the glyph margins are located. */
5008 bounds.left_in = bounds.left_out + window_left_margin_width (w);
5009 bounds.right_in = bounds.right_out - window_right_margin_width (w);
5010 /* We cannot fully calculate the whitespace boundaries as they
5011 depend on the contents of the line being displayed. */
5012 bounds.left_white = bounds.left_in;
5013 bounds.right_white = bounds.right_in;
5017 struct display_line dl;
5018 struct display_line *dlp;
5022 if (Dynarr_length (dla) < Dynarr_largest (dla))
5024 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5035 dlp->bounds = bounds;
5037 next_pos = generate_string_display_line (w, disp_string, dlp, start_pos,
5038 &prop, default_face);
5039 /* we need to make sure that we continue along the line if there
5040 is more left to display otherwise we just end up redisplaying
5041 the same chunk over and over again. */
5042 if (next_pos == start_pos && next_pos < s_zv)
5045 start_pos = next_pos;
5047 dlp->ypos = ypos + dlp->ascent;
5048 ypos = dlp->ypos + dlp->descent;
5052 int visible_height = dlp->ascent + dlp->descent;
5054 dlp->clip = (ypos - yend);
5055 visible_height -= dlp->clip;
5057 if (visible_height < VERTICAL_CLIP (w, 1))
5060 free_display_line (dlp);
5067 Dynarr_add (dla, *dlp);
5069 /* #### This type of check needs to be done down in the
5070 generate_display_line call. */
5071 if (start_pos >= s_zv)
5080 /***************************************************************************/
5082 /* window-regeneration routines */
5084 /***************************************************************************/
5086 /* For a given window and starting position in the buffer it contains,
5087 ensure that the TYPE display lines accurately represent the
5088 presentation of the window. We pass the buffer instead of getting
5089 it from the window since redisplay_window may have temporarily
5090 changed it to the echo area buffer. */
5093 regenerate_window (struct window *w, Bufpos start_pos, Bufpos point, int type)
5095 struct frame *f = XFRAME (w->frame);
5096 struct buffer *b = XBUFFER (w->buffer);
5097 int ypos = WINDOW_TEXT_TOP (w);
5098 int yend; /* set farther down */
5099 int yclip = WINDOW_TEXT_TOP_CLIP (w);
5101 prop_block_dynarr *prop;
5102 layout_bounds bounds;
5103 display_line_dynarr *dla;
5106 /* The lines had better exist by this point. */
5107 if (!(dla = window_display_lines (w, type)))
5110 w->max_line_len = 0;
5112 /* Normally these get updated in redisplay_window but it is possible
5113 for this function to get called from some other points where that
5114 update may not have occurred. This acts as a safety check. */
5115 if (!Dynarr_length (w->face_cachels))
5116 reset_face_cachels (w);
5117 if (!Dynarr_length (w->glyph_cachels))
5118 reset_glyph_cachels (w);
5120 Fset_marker (w->start[type], make_int (start_pos), w->buffer);
5121 Fset_marker (w->pointm[type], make_int (point), w->buffer);
5122 w->last_point_x[type] = -1;
5123 w->last_point_y[type] = -1;
5125 /* Make sure a modeline is in the structs if needed. */
5126 need_modeline = ensure_modeline_generated (w, type);
5128 /* Wait until here to set this so that the structs have a modeline
5129 generated in the case where one didn't exist. */
5130 yend = WINDOW_TEXT_BOTTOM (w);
5132 bounds = calculate_display_line_boundaries (w, 0);
5134 /* 97/3/14 jhod: stuff added here to support pre-prompts (used for input systems) */
5135 if (MINI_WINDOW_P (w)
5136 && (!NILP (Vminibuf_prompt) || !NILP (Vminibuf_preprompt))
5137 && !echo_area_active (f)
5138 && start_pos == BUF_BEGV (b))
5140 struct prop_block pb;
5142 prop = Dynarr_new (prop_block);
5144 string = concat2(Vminibuf_preprompt, Vminibuf_prompt);
5145 pb.type = PROP_MINIBUF_PROMPT;
5146 pb.data.p_string.str = XSTRING_DATA(string);
5147 pb.data.p_string.len = XSTRING_LENGTH(string);
5148 Dynarr_add (prop, pb);
5153 /* Make sure this is set always */
5154 /* Note the conversion at end */
5155 w->window_end_pos[type] = start_pos;
5158 struct display_line dl;
5159 struct display_line *dlp;
5162 if (Dynarr_length (dla) < Dynarr_largest (dla))
5164 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5175 dlp->bounds = bounds;
5177 start_pos = generate_display_line (w, dlp, 1, start_pos, &prop, type);
5179 if (yclip > dlp->ascent)
5181 /* this should never happen, but if it does just display the
5186 dlp->ypos = (ypos + dlp->ascent) - yclip;
5187 ypos = dlp->ypos + dlp->descent;
5189 /* See if we've been asked to start midway through a line, for
5190 partial display line scrolling. */
5193 dlp->top_clip = yclip;
5201 int visible_height = dlp->ascent + dlp->descent;
5203 dlp->clip = (ypos - yend);
5204 /* Although this seems strange we could have a single very
5205 tall line visible for which we need to account for both
5206 the top clip and the bottom clip. */
5207 visible_height -= (dlp->clip + dlp->top_clip);
5209 if (visible_height < VERTICAL_CLIP (w, 1))
5212 free_display_line (dlp);
5219 if (dlp->cursor_elt != -1)
5221 /* #### This check is steaming crap. Have to get things
5222 fixed so when create_text_block hits EOB, we're done,
5224 if (w->last_point_x[type] == -1)
5226 w->last_point_x[type] = dlp->cursor_elt;
5227 w->last_point_y[type] = Dynarr_length (dla);
5231 /* #### This means that we've added a cursor at EOB
5232 twice. Yuck oh yuck. */
5233 struct display_block *db =
5234 get_display_block_from_line (dlp, TEXT);
5236 Dynarr_atp (db->runes, dlp->cursor_elt)->cursor_type = NO_CURSOR;
5237 dlp->cursor_elt = -1;
5241 if (dlp->num_chars > w->max_line_len)
5242 w->max_line_len = dlp->num_chars;
5244 Dynarr_add (dla, *dlp);
5246 /* #### This isn't right, but it is close enough for now. */
5247 w->window_end_pos[type] = start_pos;
5249 /* #### This type of check needs to be done down in the
5250 generate_display_line call. */
5251 if (start_pos > BUF_ZV (b))
5258 /* #### More not quite right, but close enough. */
5259 /* Ben sez: apparently window_end_pos[] is measured
5260 as the number of characters between the window end and the
5261 end of the buffer? This seems rather weirdo. What's
5262 the justification for this?
5264 JV sez: Because BUF_Z (b) would be a good initial value, however
5265 that can change. This representation allows initalizing with 0.
5267 w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type];
5271 /* We know that this is the right thing to use because we put it
5272 there when we first started working in this function. */
5273 generate_modeline (w, Dynarr_atp (dla, 0), type);
5277 #define REGEN_INC_FIND_START_END \
5279 /* Determine start and end of lines. */ \
5280 if (!Dynarr_length (cdla)) \
5284 if (Dynarr_atp (cdla, 0)->modeline && Dynarr_atp (ddla, 0)->modeline) \
5288 else if (!Dynarr_atp (cdla, 0)->modeline \
5289 && !Dynarr_atp (ddla, 0)->modeline) \
5294 abort (); /* structs differ */ \
5296 dla_end = Dynarr_length (cdla) - 1; \
5299 start_pos = (Dynarr_atp (cdla, dla_start)->bufpos \
5300 + Dynarr_atp (cdla, dla_start)->offset); \
5301 /* If this isn't true, then startp has changed and we need to do a \
5303 if (startp != start_pos) \
5306 /* Point is outside the visible region so give up. */ \
5307 if (pointm < start_pos) \
5312 /* This attempts to incrementally update the display structures. It
5313 returns a boolean indicating success or failure. This function is
5314 very similar to regenerate_window_incrementally and is in fact only
5315 called from that function. However, because of the nature of the
5316 changes it deals with it sometimes makes different assumptions
5317 which can lead to success which are much more difficult to make
5318 when dealing with buffer changes. */
5321 regenerate_window_extents_only_changed (struct window *w, Bufpos startp,
5323 Charcount beg_unchanged,
5324 Charcount end_unchanged)
5326 struct buffer *b = XBUFFER (w->buffer);
5327 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5328 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5332 int first_line, last_line;
5334 /* Don't define this in the loop where it is used because we
5335 definitely want its value to survive between passes. */
5336 prop_block_dynarr *prop = NULL;
5338 /* If we don't have any buffer change recorded but the modiff flag has
5339 been incremented, then fail. I'm not sure of the exact circumstances
5340 under which this can happen, but I believe that it is probably a
5341 reasonable happening. */
5342 if (!point_visible (w, pointm, CURRENT_DISP)
5343 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b))
5346 /* If the cursor is moved we attempt to update it. If we succeed we
5347 go ahead and proceed with the optimization attempt. */
5348 if (!EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5349 || pointm != marker_position (w->last_point[CURRENT_DISP]))
5351 struct frame *f = XFRAME (w->frame);
5352 struct device *d = XDEVICE (f->device);
5353 struct frame *sel_f = device_selected_frame (d);
5356 if (w->last_point_x[CURRENT_DISP] != -1
5357 && w->last_point_y[CURRENT_DISP] != -1)
5360 if (redisplay_move_cursor (w, pointm, WINDOW_TTY_P (w)))
5362 /* Always regenerate the modeline in case it is
5363 displaying the current line or column. */
5364 regenerate_modeline (w);
5368 else if (w != XWINDOW (FRAME_SELECTED_WINDOW (sel_f)))
5370 if (f->modeline_changed)
5371 regenerate_modeline (w);
5379 if (beg_unchanged == -1 && end_unchanged == -1)
5382 /* assert: There are no buffer modifications or they are all below the
5383 visible region. We assume that regenerate_window_incrementally has
5384 not called us unless this is true. */
5386 REGEN_INC_FIND_START_END;
5388 /* If the changed are starts before the visible area, give up. */
5389 if (beg_unchanged < startp)
5392 /* Find what display line the extent changes first affect. */
5394 while (line <= dla_end)
5396 struct display_line *dl = Dynarr_atp (cdla, line);
5397 Bufpos lstart = dl->bufpos + dl->offset;
5398 Bufpos lend = dl->end_bufpos + dl->offset;
5400 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5406 /* If the changes are below the visible area then if point hasn't
5407 moved return success otherwise fail in order to be safe. */
5410 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5411 && pointm == marker_position (w->last_point[CURRENT_DISP]))
5417 /* At this point we know what line the changes first affect. We now
5418 begin redrawing lines as long as we are still in the affected
5419 region and the line's size and positioning don't change.
5420 Otherwise we fail. If we fail we will have altered the desired
5421 structs which could lead to an assertion failure. However, if we
5422 fail the next thing that is going to happen is a full regen so we
5423 will actually end up being safe. */
5424 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5425 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5426 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
5427 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
5429 first_line = last_line = line;
5430 while (line <= dla_end)
5432 Bufpos old_start, old_end, new_start;
5433 struct display_line *cdl = Dynarr_atp (cdla, line);
5434 struct display_line *ddl = Dynarr_atp (ddla, line);
5435 struct display_block *db;
5438 assert (cdl->bufpos == ddl->bufpos);
5439 assert (cdl->end_bufpos == ddl->end_bufpos);
5440 assert (cdl->offset == ddl->offset);
5442 db = get_display_block_from_line (ddl, TEXT);
5443 initial_size = Dynarr_length (db->runes);
5444 old_start = ddl->bufpos + ddl->offset;
5445 old_end = ddl->end_bufpos + ddl->offset;
5447 /* If this is the first line being updated and it used
5448 propagation data, fail. Otherwise we'll be okay because
5449 we'll have the necessary propagation data. */
5450 if (line == first_line && ddl->used_prop_data)
5453 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5454 &prop, DESIRED_DISP);
5457 /* #### If there is propagated stuff the fail. We could
5458 probably actually deal with this if the line had propagated
5459 information when originally created by a full
5467 /* If any line position parameters have changed or a
5468 cursor has disappeared or disappeared, fail. */
5469 db = get_display_block_from_line (ddl, TEXT);
5470 if (cdl->ypos != ddl->ypos
5471 || cdl->ascent != ddl->ascent
5472 || cdl->descent != ddl->descent
5473 || cdl->top_clip != ddl->top_clip
5474 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5475 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1)
5476 || old_start != ddl->bufpos
5477 || old_end != ddl->end_bufpos
5478 || initial_size != Dynarr_length (db->runes))
5483 if (ddl->cursor_elt != -1)
5485 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5486 w->last_point_y[DESIRED_DISP] = line;
5491 /* If the extent changes end on the line we just updated then
5492 we're done. Otherwise go on to the next line. */
5493 if (end_unchanged <= ddl->end_bufpos)
5499 redisplay_update_line (w, first_line, last_line, 1);
5503 /* Attempt to update the display data structures based on knowledge of
5504 the changed region in the buffer. Returns a boolean indicating
5505 success or failure. If this function returns a failure then a
5506 regenerate_window _must_ be performed next in order to maintain
5507 invariants located here. */
5510 regenerate_window_incrementally (struct window *w, Bufpos startp,
5513 struct buffer *b = XBUFFER (w->buffer);
5514 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5515 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5516 Charcount beg_unchanged, end_unchanged;
5517 Charcount extent_beg_unchanged, extent_end_unchanged;
5523 /* If this function is called, the current and desired structures
5524 had better be identical. If they are not, then that is a bug. */
5525 assert (Dynarr_length (cdla) == Dynarr_length (ddla));
5527 /* We don't handle minibuffer windows yet. The minibuffer prompt
5529 if (MINI_WINDOW_P (w))
5532 extent_beg_unchanged = BUF_EXTENT_BEGIN_UNCHANGED (b);
5533 extent_end_unchanged = (BUF_EXTENT_END_UNCHANGED (b) == -1
5535 : BUF_Z (b) - BUF_EXTENT_END_UNCHANGED (b));
5537 /* If nothing has changed in the buffer, then make sure point is ok
5539 if (BUF_BEGIN_UNCHANGED (b) == -1 && BUF_END_UNCHANGED (b) == -1)
5540 return regenerate_window_extents_only_changed (w, startp, pointm,
5541 extent_beg_unchanged,
5542 extent_end_unchanged);
5544 /* We can't deal with deleted newlines. */
5545 if (BUF_NEWLINE_WAS_DELETED (b))
5548 beg_unchanged = BUF_BEGIN_UNCHANGED (b);
5549 end_unchanged = (BUF_END_UNCHANGED (b) == -1
5551 : BUF_Z (b) - BUF_END_UNCHANGED (b));
5553 REGEN_INC_FIND_START_END;
5555 /* If the changed area starts before the visible area, give up. */
5556 if (beg_unchanged < startp)
5559 /* Find what display line the buffer changes first affect. */
5561 while (line <= dla_end)
5563 struct display_line *dl = Dynarr_atp (cdla, line);
5564 Bufpos lstart = dl->bufpos + dl->offset;
5565 Bufpos lend = dl->end_bufpos + dl->offset;
5567 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5573 /* If the changes are below the visible area then if point hasn't
5574 moved return success otherwise fail in order to be safe. */
5576 return regenerate_window_extents_only_changed (w, startp, pointm,
5577 extent_beg_unchanged,
5578 extent_end_unchanged);
5580 /* At this point we know what line the changes first affect. We
5581 now redraw that line. If the changes are contained within it
5582 we are going to succeed and can update just that one line.
5583 Otherwise we fail. If we fail we will have altered the desired
5584 structs which could lead to an assertion failure. However, if
5585 we fail the next thing that is going to happen is a full regen
5586 so we will actually end up being safe. */
5589 prop_block_dynarr *prop = NULL;
5590 struct display_line *cdl = Dynarr_atp (cdla, line);
5591 struct display_line *ddl = Dynarr_atp (ddla, line);
5593 assert (cdl->bufpos == ddl->bufpos);
5594 assert (cdl->end_bufpos == ddl->end_bufpos);
5595 assert (cdl->offset == ddl->offset);
5597 /* If the line continues to next display line, fail. */
5598 if (ddl->line_continuation)
5601 /* If the line was generated using propagation data, fail. */
5602 if (ddl->used_prop_data)
5605 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5606 &prop, DESIRED_DISP);
5609 /* If there is propagated stuff then it is pretty much a
5610 guarantee that more than just the one line is affected. */
5617 /* If the line continues to next display line, fail. */
5618 if (ddl->line_continuation)
5621 /* If any line position parameters have changed or a
5622 cursor has disappeared or disappeared, fail. */
5623 if (cdl->ypos != ddl->ypos
5624 || cdl->ascent != ddl->ascent
5625 || cdl->descent != ddl->descent
5626 || cdl->top_clip != ddl->top_clip
5627 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5628 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1))
5633 /* If the changed area also ends on this line, then we may be in
5634 business. Update everything and return success. */
5635 if (end_unchanged >= ddl->bufpos && end_unchanged <= ddl->end_bufpos)
5637 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5638 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5639 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp),
5641 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm),
5644 if (ddl->cursor_elt != -1)
5646 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5647 w->last_point_y[DESIRED_DISP] = line;
5650 redisplay_update_line (w, line, line, 1);
5651 regenerate_modeline (w);
5653 /* #### For now we just flush the cache until this has been
5654 tested. After that is done, this should correct the
5656 Dynarr_reset (w->line_start_cache);
5658 /* Adjust the extent changed boundaries to remove any
5659 overlap with the buffer changes since we've just
5660 successfully updated that area. */
5661 if (extent_beg_unchanged != -1
5662 && extent_beg_unchanged >= beg_unchanged
5663 && extent_beg_unchanged < end_unchanged)
5664 extent_beg_unchanged = end_unchanged;
5666 if (extent_end_unchanged != -1
5667 && extent_end_unchanged >= beg_unchanged
5668 && extent_end_unchanged < end_unchanged)
5669 extent_end_unchanged = beg_unchanged - 1;
5671 if (extent_end_unchanged <= extent_beg_unchanged)
5672 extent_beg_unchanged = extent_end_unchanged = -1;
5674 /* This could lead to odd results if it fails, but since the
5675 buffer changes update succeeded this probably will to.
5676 We already know that the extent changes start at or after
5677 the line because we checked before entering the loop. */
5678 if (extent_beg_unchanged != -1
5679 && extent_end_unchanged != -1
5680 && ((extent_beg_unchanged < ddl->bufpos)
5681 || (extent_end_unchanged > ddl->end_bufpos)))
5682 return regenerate_window_extents_only_changed (w, startp, pointm,
5683 extent_beg_unchanged,
5684 extent_end_unchanged);
5694 /* Given a window and a point, update the given display lines such
5695 that point is displayed in the middle of the window.
5696 Return the window's new start position. */
5699 regenerate_window_point_center (struct window *w, Bufpos point, int type)
5703 /* We need to make sure that the modeline is generated so that the
5704 window height can be calculated correctly. */
5705 ensure_modeline_generated (w, type);
5707 startp = start_with_line_at_pixpos (w, point, window_half_pixpos (w));
5708 regenerate_window (w, startp, point, type);
5709 Fset_marker (w->start[type], make_int (startp), w->buffer);
5714 /* Given a window and a set of display lines, return a boolean
5715 indicating whether the given point is contained within. */
5718 point_visible (struct window *w, Bufpos point, int type)
5720 struct buffer *b = XBUFFER (w->buffer);
5721 display_line_dynarr *dla = window_display_lines (w, type);
5724 if (Dynarr_length (dla) && Dynarr_atp (dla, 0)->modeline)
5729 if (Dynarr_length (dla) > first_line)
5732 struct display_line *dl = Dynarr_atp (dla, first_line);
5735 end = BUF_Z (b) - w->window_end_pos[type] - 1;
5737 if (point >= start && point <= end)
5739 if (!MINI_WINDOW_P (w) && scroll_on_clipped_lines)
5741 dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
5743 if (point >= (dl->bufpos + dl->offset)
5744 && point <= (dl->end_bufpos + dl->offset))
5759 /* Return pixel position the middle of the window, not including the
5760 modeline and any potential horizontal scrollbar. */
5763 window_half_pixpos (struct window *w)
5765 return WINDOW_TEXT_TOP (w) + (WINDOW_TEXT_HEIGHT (w) >> 1);
5768 /* Return the display line which is currently in the middle of the
5769 window W for display lines TYPE. */
5772 line_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5774 display_line_dynarr *dla;
5777 int first_elt = (MINI_WINDOW_P (w) ? 0 : 1);
5779 if (type == CMOTION_DISP)
5780 regenerate_window (w, start, point, type);
5782 dla = window_display_lines (w, type);
5783 half = window_half_pixpos (w);
5785 for (elt = first_elt; elt < Dynarr_length (dla); elt++)
5787 struct display_line *dl = Dynarr_atp (dla, elt);
5788 int line_bot = dl->ypos + dl->descent;
5790 if (line_bot > half)
5794 /* We may not have a line at the middle if the end of the buffer is
5799 /* Return a value for point that would place it at the beginning of
5800 the line which is in the middle of the window. */
5803 point_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5805 /* line_at_center will regenerate the display structures, if necessary. */
5806 int line = line_at_center (w, type, start, point);
5809 return BUF_ZV (XBUFFER (w->buffer));
5812 display_line_dynarr *dla = window_display_lines (w, type);
5813 struct display_line *dl = Dynarr_atp (dla, line);
5819 /* For a given window, ensure that the current visual representation
5823 redisplay_window (Lisp_Object window, int skip_selected)
5825 struct window *w = XWINDOW (window);
5826 struct frame *f = XFRAME (w->frame);
5827 struct device *d = XDEVICE (f->device);
5828 Lisp_Object old_buffer = w->buffer;
5829 Lisp_Object the_buffer = w->buffer;
5831 int echo_active = 0;
5836 int selected_in_its_frame;
5837 int selected_globally;
5838 int skip_output = 0;
5839 int truncation_changed;
5840 int inactive_minibuffer =
5841 (MINI_WINDOW_P (w) &&
5842 (f != device_selected_frame (d)) &&
5843 !is_surrogate_for_selected_frame (f));
5845 /* #### In the new world this function actually does a bunch of
5846 optimizations such as buffer-based scrolling, but none of that is
5849 /* If this is a combination window, do its children; that's all.
5850 The selected window is always a leaf so we don't check for
5851 skip_selected here. */
5852 if (!NILP (w->vchild))
5854 redisplay_windows (w->vchild, skip_selected);
5857 if (!NILP (w->hchild))
5859 redisplay_windows (w->hchild, skip_selected);
5863 /* Is this window the selected window on its frame? */
5864 selected_in_its_frame = (w == XWINDOW (FRAME_SELECTED_WINDOW (f)));
5866 selected_in_its_frame &&
5867 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
5868 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d &&
5869 XFRAME(DEVICE_SELECTED_FRAME(d)) == f;
5870 if (skip_selected && selected_in_its_frame)
5873 /* It is possible that the window is not fully initialized yet. */
5874 if (NILP (w->buffer))
5877 if (MINI_WINDOW_P (w) && echo_area_active (f))
5879 w->buffer = the_buffer = Vecho_area_buffer;
5883 b = XBUFFER (w->buffer);
5887 old_pointm = selected_globally
5889 : marker_position (w->pointm[CURRENT_DISP]);
5894 if (selected_globally)
5896 pointm = BUF_PT (b);
5900 pointm = marker_position (w->pointm[CURRENT_DISP]);
5902 if (pointm < BUF_BEGV (b))
5903 pointm = BUF_BEGV (b);
5904 else if (pointm > BUF_ZV (b))
5905 pointm = BUF_ZV (b);
5908 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm), the_buffer);
5910 /* If the buffer has changed we have to invalidate all of our face
5912 if ((!echo_active && b != window_display_buffer (w))
5913 || !Dynarr_length (w->face_cachels)
5914 || f->faces_changed)
5915 reset_face_cachels (w);
5917 mark_face_cachels_as_not_updated (w);
5919 /* Ditto the glyph cache elements, although we do *not* invalidate
5920 the cache purely because glyphs have changed - this is now
5921 handled by the dirty flag.*/
5922 if ((!echo_active && b != window_display_buffer (w))
5923 || !Dynarr_length (w->glyph_cachels) || f->faces_changed)
5924 reset_glyph_cachels (w);
5926 mark_glyph_cachels_as_not_updated (w);
5928 /* If the marker's buffer is not the window's buffer, then we need
5929 to find a new starting position. */
5930 if (!MINI_WINDOW_P (w)
5931 && !EQ (Fmarker_buffer (w->start[CURRENT_DISP]), w->buffer))
5933 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
5935 goto regeneration_done;
5940 old_startp = marker_position (w->start[CURRENT_DISP]);
5945 startp = marker_position (w->start[CURRENT_DISP]);
5946 if (startp < BUF_BEGV (b))
5947 startp = BUF_BEGV (b);
5948 else if (startp > BUF_ZV (b))
5949 startp = BUF_ZV (b);
5951 Fset_marker (w->start[DESIRED_DISP], make_int (startp), the_buffer);
5953 truncation_changed = (find_window_mirror (w)->truncate_win !=
5954 window_truncation_on (w));
5956 /* If w->force_start is set, then some function set w->start and we
5957 should display from there and change point, if necessary, to
5958 ensure that it is visible. */
5959 if (w->force_start || inactive_minibuffer)
5962 w->last_modified[DESIRED_DISP] = Qzero;
5963 w->last_facechange[DESIRED_DISP] = Qzero;
5965 regenerate_window (w, startp, pointm, DESIRED_DISP);
5967 if (!point_visible (w, pointm, DESIRED_DISP) && !inactive_minibuffer)
5969 pointm = point_at_center (w, DESIRED_DISP, 0, 0);
5971 if (selected_globally)
5972 BUF_SET_PT (b, pointm);
5974 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm),
5977 /* #### BUFU amounts of overkill just to get the cursor
5978 location marked properly. FIX ME FIX ME FIX ME */
5979 regenerate_window (w, startp, pointm, DESIRED_DISP);
5982 goto regeneration_done;
5985 /* If nothing has changed since the last redisplay, then we just
5986 need to make sure that point is still visible. */
5987 if (XINT (w->last_modified[CURRENT_DISP]) >= BUF_MODIFF (b)
5988 && XINT (w->last_facechange[CURRENT_DISP]) >= BUF_FACECHANGE (b)
5990 /* This check is to make sure we restore the minibuffer after a
5991 temporary change to the echo area. */
5992 && !(MINI_WINDOW_P (w) && f->buffers_changed)
5993 && !f->frame_changed
5994 && !truncation_changed
5995 /* check whether start is really at the begining of a line GE */
5996 && (!w->start_at_line_beg || beginning_of_line_p (b, startp))
5999 /* Check if the cursor has actually moved. */
6000 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
6001 && pointm == marker_position (w->last_point[CURRENT_DISP])
6002 && selected_globally
6003 && !w->windows_changed
6005 && !f->extents_changed
6006 && !f->faces_changed
6007 && !f->glyphs_changed
6008 && !f->subwindows_changed
6009 /* && !f->subwindows_state_changed*/
6010 && !f->point_changed
6011 && !f->windows_structure_changed)
6013 /* If not, we're done. */
6014 if (f->modeline_changed)
6015 regenerate_modeline (w);
6018 goto regeneration_done;
6022 /* If the new point is visible in the redisplay structures,
6023 then let the output update routines handle it, otherwise
6024 do things the hard way. */
6025 if (!w->windows_changed
6027 && !f->extents_changed
6028 && !f->faces_changed
6029 && !f->glyphs_changed
6030 && !f->subwindows_changed
6031 /* && !f->subwindows_state_changed*/
6032 && !f->windows_structure_changed)
6034 if (point_visible (w, pointm, CURRENT_DISP)
6035 && w->last_point_x[CURRENT_DISP] != -1
6036 && w->last_point_y[CURRENT_DISP] != -1)
6038 if (redisplay_move_cursor (w, pointm, FRAME_TTY_P (f)))
6040 /* Always regenerate in case it is displaying
6041 the current line or column. */
6042 regenerate_modeline (w);
6045 goto regeneration_done;
6048 else if (!selected_in_its_frame && !f->point_changed)
6050 if (f->modeline_changed)
6051 regenerate_modeline (w);
6054 goto regeneration_done;
6058 /* If we weren't able to take the shortcut method, then use
6059 the brute force method. */
6060 regenerate_window (w, startp, pointm, DESIRED_DISP);
6062 if (point_visible (w, pointm, DESIRED_DISP))
6063 goto regeneration_done;
6067 /* Check if the starting point is no longer at the beginning of a
6068 line, in which case find a new starting point. We also recenter
6069 if our start position is equal to point-max. Otherwise we'll end
6070 up with a blank window. */
6071 else if (((w->start_at_line_beg || MINI_WINDOW_P (w))
6072 && !(startp == BUF_BEGV (b)
6073 || BUF_FETCH_CHAR (b, startp - 1) == '\n'))
6074 || (pointm == startp &&
6075 EQ (Fmarker_buffer (w->last_start[CURRENT_DISP]), w->buffer) &&
6076 startp < marker_position (w->last_start[CURRENT_DISP]))
6077 || (startp == BUF_ZV (b)))
6079 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6081 goto regeneration_done;
6083 /* See if we can update the data structures locally based on
6084 knowledge of what changed in the buffer. */
6085 else if (!w->windows_changed
6087 && !f->faces_changed
6088 && !f->glyphs_changed
6089 && !f->subwindows_changed
6090 /* && !f->subwindows_state_changed*/
6091 && !f->windows_structure_changed
6092 && !f->frame_changed
6093 && !truncation_changed
6095 && regenerate_window_incrementally (w, startp, pointm))
6097 if (f->modeline_changed
6098 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b)
6099 || XINT (w->last_facechange[CURRENT_DISP]) < BUF_FACECHANGE (b))
6100 regenerate_modeline (w);
6103 goto regeneration_done;
6105 /* #### This is where a check for structure based scrolling would go. */
6106 /* If all else fails, try just regenerating and see what happens. */
6109 regenerate_window (w, startp, pointm, DESIRED_DISP);
6111 if (point_visible (w, pointm, DESIRED_DISP))
6112 goto regeneration_done;
6115 /* We still haven't gotten the window regenerated with point
6116 visible. Next we try scrolling a little and see if point comes
6117 back onto the screen. */
6118 if (scroll_step > 0)
6120 int scrolled = scroll_conservatively;
6121 for (; scrolled >= 0; scrolled -= scroll_step)
6123 startp = vmotion (w, startp,
6124 (pointm < startp) ? -scroll_step : scroll_step, 0);
6125 regenerate_window (w, startp, pointm, DESIRED_DISP);
6127 if (point_visible (w, pointm, DESIRED_DISP))
6128 goto regeneration_done;
6132 /* We still haven't managed to get the screen drawn with point on
6133 the screen, so just center it and be done with it. */
6134 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6139 /* If the window's frame is changed then reset the current display
6140 lines in order to force a full repaint. */
6141 if (f->frame_changed)
6143 display_line_dynarr *cla = window_display_lines (w, CURRENT_DISP);
6148 /* Must do this before calling redisplay_output_window because it
6149 sets some markers on the window. */
6152 w->buffer = old_buffer;
6153 Fset_marker (w->pointm[DESIRED_DISP], make_int (old_pointm), old_buffer);
6154 Fset_marker (w->start[DESIRED_DISP], make_int (old_startp), old_buffer);
6157 /* These also have to be set before calling redisplay_output_window
6158 since it sets the CURRENT_DISP values based on them. */
6159 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
6160 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
6161 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
6162 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
6166 Bufpos start = marker_position (w->start[DESIRED_DISP]);
6167 Bufpos end = (w->window_end_pos[DESIRED_DISP] == -1
6169 : BUF_Z (b) - w->window_end_pos[DESIRED_DISP] - 1);
6170 /* Don't pollute the cache if not sure if we are correct */
6171 if (w->start_at_line_beg)
6172 update_line_start_cache (w, start, end, pointm, 1);
6173 redisplay_output_window (w);
6175 * If we just displayed the echo area, the line start cache is
6176 * no longer valid, because the minibuffer window is associated
6177 * with the window now.
6180 w->line_cache_last_updated = make_int (-1);
6183 /* #### This should be dependent on face changes and will need to be
6184 somewhere else once tty updates occur on a per-frame basis. */
6185 mark_face_cachels_as_clean (w);
6187 /* The glyph cachels only get dirty if someone changed something.
6188 Since redisplay has now effectively ended we can reset the dirty
6189 flag since everything must be up-to-date. */
6191 mark_glyph_cachels_as_clean (w);
6193 w->windows_changed = 0;
6196 /* Call buffer_reset_changes for all buffers present in any window
6197 currently visible in all frames on all devices. #### There has to
6198 be a better way to do this. */
6201 reset_buffer_changes_mapfun (struct window *w, void *ignored_closure)
6203 buffer_reset_changes (XBUFFER (w->buffer));
6208 reset_buffer_changes (void)
6210 Lisp_Object frmcons, devcons, concons;
6212 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
6214 struct frame *f = XFRAME (XCAR (frmcons));
6216 if (FRAME_REPAINT_P (f))
6217 map_windows (f, reset_buffer_changes_mapfun, 0);
6221 /* Ensure that all windows underneath the given window in the window
6222 hierarchy are correctly displayed. */
6225 redisplay_windows (Lisp_Object window, int skip_selected)
6227 for (; !NILP (window) ; window = XWINDOW (window)->next)
6229 redisplay_window (window, skip_selected);
6234 call_redisplay_end_triggers (struct window *w, void *closure)
6236 Bufpos lrpos = w->last_redisplay_pos;
6237 w->last_redisplay_pos = 0;
6238 if (!NILP (w->buffer)
6239 && !NILP (w->redisplay_end_trigger)
6244 if (MARKERP (w->redisplay_end_trigger)
6245 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
6246 pos = marker_position (w->redisplay_end_trigger);
6247 else if (INTP (w->redisplay_end_trigger))
6248 pos = XINT (w->redisplay_end_trigger);
6251 w->redisplay_end_trigger = Qnil;
6258 XSETWINDOW (window, w);
6259 va_run_hook_with_args_in_buffer (XBUFFER (w->buffer),
6260 Qredisplay_end_trigger_functions,
6262 w->redisplay_end_trigger);
6263 w->redisplay_end_trigger = Qnil;
6270 /* Ensure that all windows on the given frame are correctly displayed. */
6273 redisplay_frame (struct frame *f, int preemption_check)
6275 struct device *d = XDEVICE (f->device);
6277 if (preemption_check)
6279 /* The preemption check itself takes a lot of time,
6280 so normally don't do it here. We do it if called
6281 from Lisp, though (`redisplay-frame'). */
6284 REDISPLAY_PREEMPTION_CHECK;
6289 if (!internal_equal (f->old_buffer_alist, f->buffer_alist, 0))
6293 f->old_buffer_alist = Freplace_list (f->old_buffer_alist,
6295 XSETFRAME (frame, f);
6296 va_run_hook_with_args (Qbuffer_list_changed_hook, 1, frame);
6299 /* Before we put a hold on frame size changes, attempt to process
6300 any which are already pending. */
6301 if (f->size_change_pending)
6302 change_frame_size (f, f->new_height, f->new_width, 0);
6304 /* If frame size might need to be changed, due to changed size
6305 of toolbars, scrollbars etc, change it now */
6306 if (f->size_slipped)
6308 adjust_frame_size (f);
6309 assert (!f->size_slipped);
6312 /* The menubar, toolbar, and icon updates must be done before
6313 hold_frame_size_changes is called and we are officially
6314 'in_display'. They may eval lisp code which may call Fsignal.
6315 If in_display is set Fsignal will abort. */
6317 #ifdef HAVE_MENUBARS
6318 /* Update the menubar. It is done first since it could change
6319 the menubar's visibility. This way we avoid having flashing
6320 caused by an Expose event generated by the visibility change
6322 update_frame_menubars (f);
6323 #endif /* HAVE_MENUBARS */
6324 #ifdef HAVE_TOOLBARS
6325 /* Update the toolbars. */
6326 update_frame_toolbars (f);
6327 #endif /* HAVE_TOOLBARS */
6328 /* Gutter update proper has to be done inside display when no frame
6329 size changes can occur, thus we separately update the gutter
6330 geometry here if it needs it. */
6331 update_frame_gutter_geometry (f);
6333 /* If we clear the frame we have to force its contents to be redrawn. */
6335 f->frame_changed = 1;
6337 /* Invalidate the subwindow cache. We use subwindows_changed here to
6338 cause subwindows to get instantiated. This is because
6339 subwindows_state_changed is less strict - dealing with things
6340 like the clicked state of button. We have to do this before
6341 redisplaying the gutters as subwindows get unmapped in the
6343 if (f->frame_changed || f->subwindows_changed)
6345 reset_subwindow_cachels (f);
6346 /* we have to do this so the gutter gets regenerated. */
6347 reset_gutter_display_lines (f);
6350 mark_subwindow_cachels_as_not_updated (f);
6352 hold_frame_size_changes ();
6354 /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */
6355 /* Within this section, we are defenseless and assume that the
6356 following cannot happen:
6358 1) garbage collection
6359 2) Lisp code evaluation
6360 3) frame size changes
6362 We ensure (3) by calling hold_frame_size_changes(), which
6363 will cause any pending frame size changes to get put on hold
6364 till after the end of the critical section. (1) follows
6365 automatically if (2) is met. #### Unfortunately, there are
6366 some places where Lisp code can be called within this section.
6367 We need to remove them.
6369 If Fsignal() is called during this critical section, we
6372 If garbage collection is called during this critical section,
6373 we simply return. #### We should abort instead.
6375 #### If a frame-size change does occur we should probably
6376 actually be preempting redisplay. */
6378 /* We can now update the gutters, safe in the knowledge that our
6379 efforts won't get undone. */
6381 /* This can call lisp, but redisplay is protected by binding
6382 inhibit_quit. More importantly the code involving display lines
6383 *assumes* that GC will not happen and so does not GCPRO
6384 anything. Since we use this code the whole time with the gutters
6385 we cannot allow GC to happen when manipulating the gutters. */
6386 update_frame_gutters (f);
6388 /* Erase the frame before outputting its contents. */
6391 DEVMETH (d, clear_frame, (f));
6394 /* Do the selected window first. */
6395 redisplay_window (FRAME_SELECTED_WINDOW (f), 0);
6397 /* Then do the rest. */
6398 redisplay_windows (f->root_window, 1);
6400 /* We now call the output_end routine for tty frames. We delay
6401 doing so in order to avoid cursor flicker. So much for 100%
6403 if (FRAME_TTY_P (f))
6404 DEVMETH (d, output_end, (d));
6406 update_frame_title (f);
6408 CLASS_RESET_CHANGED_FLAGS (f);
6409 f->window_face_cache_reset = 0;
6410 f->echo_area_garbaged = 0;
6413 if (!f->size_change_pending)
6414 f->size_changed = 0;
6416 /* ----------------- END CRITICAL REDISPLAY SECTION ---------------- */
6418 /* Allow frame size changes to occur again.
6420 #### what happens if changes to other frames happen? */
6421 unhold_one_frame_size_changes (f);
6423 map_windows (f, call_redisplay_end_triggers, 0);
6427 /* Ensure that all frames on the given device are correctly displayed.
6428 If AUTOMATIC is non-zero, and the device implementation indicates
6429 no automatic redisplay, as printers do, then the device is not
6430 redisplayed. AUTOMATIC is set to zero when called from lisp
6431 functions (redraw-device) and (redisplay-device), and to non-zero
6432 when called from "lazy" redisplay();
6436 redisplay_device (struct device *d, int automatic)
6438 Lisp_Object frame, frmcons;
6440 int size_change_failed = 0;
6444 && (MAYBE_INT_DEVMETH (d, device_implementation_flags, ())
6445 & XDEVIMPF_NO_AUTO_REDISPLAY))
6448 if (DEVICE_STREAM_P (d)) /* nothing to do */
6451 /* It is possible that redisplay has been called before the
6452 device is fully initialized. If so then continue with the
6454 if (NILP (DEVICE_SELECTED_FRAME (d)))
6457 REDISPLAY_PREEMPTION_CHECK;
6461 /* Always do the selected frame first. */
6462 frame = DEVICE_SELECTED_FRAME (d);
6466 if (f->icon_changed || f->windows_changed)
6467 update_frame_icon (f);
6469 if (FRAME_REPAINT_P (f))
6471 if (CLASS_REDISPLAY_FLAGS_CHANGEDP(f))
6473 preempted = redisplay_frame (f, 0);
6479 /* If the frame redisplay did not get preempted, then this flag
6480 should have gotten set to 0. It might be possible for that
6481 not to happen if a size change event were to occur at an odd
6482 time. To make sure we don't miss anything we simply don't
6483 reset the top level flags until the condition ends up being
6484 in the right state. */
6485 if (f->size_changed)
6486 size_change_failed = 1;
6489 DEVICE_FRAME_LOOP (frmcons, d)
6491 f = XFRAME (XCAR (frmcons));
6493 if (f == XFRAME (DEVICE_SELECTED_FRAME (d)))
6496 if (f->icon_changed || f->windows_changed)
6497 update_frame_icon (f);
6499 if (FRAME_REPAINT_P (f))
6501 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (f))
6503 preempted = redisplay_frame (f, 0);
6509 if (f->size_change_pending)
6510 size_change_failed = 1;
6514 /* If we get here then we redisplayed all of our frames without
6515 getting preempted so mark ourselves as clean. */
6516 CLASS_RESET_CHANGED_FLAGS (d);
6518 if (!size_change_failed)
6519 d->size_changed = 0;
6525 restore_profiling_redisplay_flag (Lisp_Object val)
6527 profiling_redisplay_flag = XINT (val);
6531 /* Ensure that all windows on all frames on all devices are displaying
6532 the current contents of their respective buffers. */
6535 redisplay_without_hooks (void)
6537 Lisp_Object devcons, concons;
6538 int size_change_failed = 0;
6539 int count = specpdl_depth ();
6541 if (profiling_active)
6543 record_unwind_protect (restore_profiling_redisplay_flag,
6544 make_int (profiling_redisplay_flag));
6545 profiling_redisplay_flag = 1;
6548 if (asynch_device_change_pending)
6549 handle_asynch_device_change ();
6551 if (!GLOBAL_REDISPLAY_FLAGS_CHANGEDP &&
6552 !disable_preemption && preemption_count < max_preempts)
6555 DEVICE_LOOP_NO_BREAK (devcons, concons)
6557 struct device *d = XDEVICE (XCAR (devcons));
6560 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (d))
6562 preempted = redisplay_device (d, 1);
6567 RESET_CHANGED_SET_FLAGS;
6571 /* See comment in redisplay_device. */
6572 if (d->size_changed)
6573 size_change_failed = 1;
6576 preemption_count = 0;
6578 /* Mark redisplay as accurate */
6579 GLOBAL_RESET_CHANGED_FLAGS;
6580 RESET_CHANGED_SET_FLAGS;
6584 mark_all_faces_as_clean ();
6588 if (!size_change_failed)
6591 reset_buffer_changes ();
6594 unbind_to (count, Qnil);
6600 if (last_display_warning_tick != display_warning_tick &&
6601 !inhibit_warning_display)
6603 /* If an error occurs during this function, oh well.
6604 If we report another warning, we could get stuck in an
6605 infinite loop reporting warnings. */
6606 call0_trapping_errors (0, Qdisplay_warning_buffer);
6607 last_display_warning_tick = display_warning_tick;
6609 /* The run_hook_trapping_errors functions are smart enough not
6610 to do any evalling if the hook function is empty, so there
6611 should not be any significant time loss. All places in the
6612 C code that call redisplay() are prepared to handle GCing,
6613 so we should be OK. */
6614 #ifndef INHIBIT_REDISPLAY_HOOKS
6615 run_hook_trapping_errors ("Error in pre-redisplay-hook",
6616 Qpre_redisplay_hook);
6617 #endif /* INHIBIT_REDISPLAY_HOOKS */
6619 redisplay_without_hooks ();
6621 #ifndef INHIBIT_REDISPLAY_HOOKS
6622 run_hook_trapping_errors ("Error in post-redisplay-hook",
6623 Qpost_redisplay_hook);
6624 #endif /* INHIBIT_REDISPLAY_HOOKS */
6628 static char window_line_number_buf[32];
6630 /* Efficiently determine the window line number, and return a pointer
6631 to its printed representation. Do this regardless of whether
6632 line-number-mode is on. The first line in the buffer is counted as
6633 1. If narrowing is in effect, the lines are counted from the
6634 beginning of the visible portion of the buffer. */
6636 window_line_number (struct window *w, int type)
6638 struct device *d = XDEVICE (XFRAME (w->frame)->device);
6639 struct buffer *b = XBUFFER (w->buffer);
6640 /* Be careful in the order of these tests. The first clause will
6641 fail if DEVICE_SELECTED_FRAME == Qnil (since w->frame cannot be).
6642 This can occur when the frame title is computed really early */
6644 ((EQ(DEVICE_SELECTED_FRAME(d), w->frame) &&
6645 (w == XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame(d)))) &&
6646 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
6647 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d )
6649 : marker_position (w->pointm[type]));
6652 line = buffer_line_number (b, pos, 1);
6654 long_to_string (window_line_number_buf, line + 1);
6656 return window_line_number_buf;
6660 /* Given a character representing an object in a modeline
6661 specification, return a string (stored into the global array
6662 `mode_spec_bufbyte_string') with the information that object
6665 This function is largely unchanged from previous versions of the
6668 Warning! This code is also used for frame titles and can be called
6669 very early in the device/frame update process! JV
6673 decode_mode_spec (struct window *w, Emchar spec, int type)
6675 Lisp_Object obj = Qnil;
6676 const char *str = NULL;
6677 struct buffer *b = XBUFFER (w->buffer);
6679 Dynarr_reset (mode_spec_bufbyte_string);
6683 /* print buffer name */
6688 /* print visited file name */
6693 /* print the current column */
6696 Bufpos pt = (w == XWINDOW (Fselected_window (Qnil)))
6698 : marker_position (w->pointm[type]);
6699 int col = column_at_point (b, pt, 1) + !!column_number_start_at_one;
6702 long_to_string (buf, col);
6704 Dynarr_add_many (mode_spec_bufbyte_string,
6705 (const Bufbyte *) buf, strlen (buf));
6707 goto decode_mode_spec_done;
6709 /* print the file coding system */
6713 Lisp_Object codesys = b->buffer_file_coding_system;
6714 /* Be very careful here not to get an error. */
6715 if (NILP (codesys) || SYMBOLP (codesys) || CODING_SYSTEMP (codesys))
6717 codesys = Ffind_coding_system (codesys);
6718 if (CODING_SYSTEMP (codesys))
6719 obj = XCODING_SYSTEM_MNEMONIC (codesys);
6722 #endif /* FILE_CODING */
6725 /* print the current line number */
6727 str = window_line_number (w, type);
6730 /* print value of mode-name (obsolete) */
6735 /* print hyphen and frame number, if != 1 */
6739 struct frame *f = XFRAME (w->frame);
6740 if (FRAME_TTY_P (f) && f->order_count > 1 && f->order_count <= 99999999)
6742 /* Naughty, naughty */
6743 char * writable_str = alloca_array (char, 10);
6744 sprintf (writable_str, "-%d", f->order_count);
6748 #endif /* HAVE_TTY */
6751 /* print Narrow if appropriate */
6753 if (BUF_BEGV (b) > BUF_BEG (b)
6754 || BUF_ZV (b) < BUF_Z (b))
6758 /* print %, * or hyphen, if buffer is read-only, modified or neither */
6760 str = (!NILP (b->read_only)
6762 : ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6767 /* print * or hyphen -- XEmacs change to allow a buffer to be
6768 read-only but still indicate whether it is modified. */
6770 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6772 : (!NILP (b->read_only)
6777 /* #### defined in 19.29 decode_mode_spec, but not in
6778 modeline-format doc string. */
6779 /* This differs from %* in that it ignores read-only-ness. */
6781 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6786 /* print process status */
6788 obj = Fget_buffer_process (w->buffer);
6790 str = GETTEXT ("no process");
6792 obj = Fsymbol_name (Fprocess_status (obj));
6795 /* Print name of selected frame. */
6797 obj = XFRAME (w->frame)->name;
6800 /* indicate TEXT or BINARY */
6802 /* #### NT does not use this any more. Now what? */
6806 /* print percent of buffer above top of window, or Top, Bot or All */
6809 Bufpos pos = marker_position (w->start[type]);
6811 /* This had better be while the desired lines are being done. */
6812 if (w->window_end_pos[type] <= BUF_Z (b) - BUF_ZV (b))
6814 if (pos <= BUF_BEGV (b))
6819 else if (pos <= BUF_BEGV (b))
6823 /* This hard limit is ok since the string it will hold has a
6824 fixed maximum length of 3. But just to be safe... */
6826 Charcount chars = pos - BUF_BEGV (b);
6827 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6829 /* Avoid overflow on big buffers */
6830 int percent = total > LONG_MAX/200 ?
6831 (chars + total/200) / (total / 100) :
6832 (chars * 100 + total/2) / total;
6834 /* We can't normally display a 3-digit number, so get us a
6835 2-digit number that is close. */
6839 sprintf (buf, "%d%%", percent);
6840 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6843 goto decode_mode_spec_done;
6848 /* print percent of buffer above bottom of window, perhaps plus
6849 Top, or print Bottom or All */
6852 Bufpos toppos = marker_position (w->start[type]);
6853 Bufpos botpos = BUF_Z (b) - w->window_end_pos[type];
6855 /* botpos is only accurate as of the last redisplay, so we can
6856 only treat it as a hint. In particular, after erase-buffer,
6857 botpos may be negative. */
6858 if (botpos < toppos)
6861 if (botpos >= BUF_ZV (b))
6863 if (toppos <= BUF_BEGV (b))
6870 /* This hard limit is ok since the string it will hold has a
6871 fixed maximum length of around 6. But just to be safe... */
6873 Charcount chars = botpos - BUF_BEGV (b);
6874 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6876 /* Avoid overflow on big buffers */
6877 int percent = total > LONG_MAX/200 ?
6878 (chars + total/200) / (total / 100) :
6879 (chars * 100 + total/2) / max (total, 1);
6881 /* We can't normally display a 3-digit number, so get us a
6882 2-digit number that is close. */
6886 if (toppos <= BUF_BEGV (b))
6887 sprintf (buf, "Top%d%%", percent);
6889 sprintf (buf, "%d%%", percent);
6891 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6894 goto decode_mode_spec_done;
6904 /* print one [ for each recursive editing level. */
6909 if (command_loop_level > 5)
6915 for (i = 0; i < command_loop_level; i++)
6916 Dynarr_add (mode_spec_bufbyte_string, '[');
6918 goto decode_mode_spec_done;
6921 /* print one ] for each recursive editing level. */
6926 if (command_loop_level > 5)
6932 for (i = 0; i < command_loop_level; i++)
6933 Dynarr_add (mode_spec_bufbyte_string, ']');
6935 goto decode_mode_spec_done;
6938 /* print infinitely many dashes -- handle at top level now */
6945 Dynarr_add_many (mode_spec_bufbyte_string,
6947 XSTRING_LENGTH (obj));
6949 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) str, strlen (str));
6951 decode_mode_spec_done:
6952 Dynarr_add (mode_spec_bufbyte_string, '\0');
6955 /* Given a display line, free all of its data structures. */
6958 free_display_line (struct display_line *dl)
6962 if (dl->display_blocks)
6964 for (block = 0; block < Dynarr_largest (dl->display_blocks); block++)
6966 struct display_block *db = Dynarr_atp (dl->display_blocks, block);
6968 Dynarr_free (db->runes);
6971 Dynarr_free (dl->display_blocks);
6972 dl->display_blocks = NULL;
6975 if (dl->left_glyphs)
6977 Dynarr_free (dl->left_glyphs);
6978 dl->left_glyphs = NULL;
6981 if (dl->right_glyphs)
6983 Dynarr_free (dl->right_glyphs);
6984 dl->right_glyphs = NULL;
6989 /* Given an array of display lines, free them and all data structures
6990 contained within them. */
6993 free_display_lines (display_line_dynarr *dla)
6997 for (line = 0; line < Dynarr_largest (dla); line++)
6999 free_display_line (Dynarr_atp (dla, line));
7005 /* Call internal free routine for each set of display lines. */
7008 free_display_structs (struct window_mirror *mir)
7010 if (mir->current_display_lines)
7012 free_display_lines (mir->current_display_lines);
7013 mir->current_display_lines = 0;
7016 if (mir->desired_display_lines)
7018 free_display_lines (mir->desired_display_lines);
7019 mir->desired_display_lines = 0;
7025 mark_glyph_block_dynarr (glyph_block_dynarr *gba)
7029 glyph_block *gb = Dynarr_atp (gba, 0);
7030 glyph_block *gb_last = Dynarr_atp (gba, Dynarr_length (gba));
7032 for (; gb < gb_last; gb++)
7034 if (!NILP (gb->glyph))
7035 mark_object (gb->glyph);
7036 if (!NILP (gb->extent))
7037 mark_object (gb->extent);
7042 /* See the comment in image_instantiate_cache_result as to why marking
7043 the glyph will also mark the image_instance. */
7045 mark_redisplay_structs (display_line_dynarr *dla)
7047 display_line *dl = Dynarr_atp (dla, 0);
7048 display_line *dl_last = Dynarr_atp (dla, Dynarr_length (dla));
7050 for (; dl < dl_last; dl++)
7052 display_block_dynarr *dba = dl->display_blocks;
7053 display_block *db = Dynarr_atp (dba, 0);
7054 display_block *db_last = Dynarr_atp (dba, Dynarr_length (dba));
7056 for (; db < db_last; db++)
7058 rune_dynarr *ra = db->runes;
7059 rune *r = Dynarr_atp (ra, 0);
7060 rune *r_last = Dynarr_atp (ra, Dynarr_length (ra));
7062 for (; r < r_last; r++)
7064 if (r->type == RUNE_DGLYPH)
7066 if (!NILP (r->object.dglyph.glyph))
7067 mark_object (r->object.dglyph.glyph);
7068 if (!NILP (r->object.dglyph.extent))
7069 mark_object (r->object.dglyph.extent);
7074 mark_glyph_block_dynarr (dl->left_glyphs);
7075 mark_glyph_block_dynarr (dl->right_glyphs);
7080 mark_window_mirror (struct window_mirror *mir)
7082 mark_redisplay_structs (mir->current_display_lines);
7083 mark_redisplay_structs (mir->desired_display_lines);
7086 mark_window_mirror (mir->next);
7089 mark_window_mirror (mir->hchild);
7090 else if (mir->vchild)
7091 mark_window_mirror (mir->vchild);
7095 mark_redisplay (void)
7097 Lisp_Object frmcons, devcons, concons;
7099 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
7101 struct frame *f = XFRAME (XCAR (frmcons));
7102 update_frame_window_mirror (f);
7103 mark_window_mirror (f->root_mirror);
7108 /*****************************************************************************
7109 Line Start Cache Description and Rationale
7111 The traditional scrolling code in Emacs breaks in a variable height world.
7112 It depends on the key assumption that the number of lines that can be
7113 displayed at any given time is fixed. This led to a complete separation
7114 of the scrolling code from the redisplay code. In order to fully support
7115 variable height lines, the scrolling code must actually be tightly
7116 integrated with redisplay. Only redisplay can determine how many lines
7117 will be displayed on a screen for any given starting point.
7119 What is ideally wanted is a complete list of the starting buffer position
7120 for every possible display line of a buffer along with the height of that
7121 display line. Maintaining such a full list would be very expensive. We
7122 settle for having it include information for all areas which we happen to
7123 generate anyhow (i.e. the region currently being displayed) and for those
7124 areas we need to work with.
7126 In order to ensure that the cache accurately represents what redisplay
7127 would actually show, it is necessary to invalidate it in many situations.
7128 If the buffer changes, the starting positions may no longer be correct.
7129 If a face or an extent has changed then the line heights may have altered.
7130 These events happen frequently enough that the cache can end up being
7131 constantly disabled. With this potentially constant invalidation when is
7132 the cache ever useful?
7134 Even if the cache is invalidated before every single usage, it is
7135 necessary. Scrolling often requires knowledge about display lines which
7136 are actually above or below the visible region. The cache provides a
7137 convenient light-weight method of storing this information for multiple
7138 display regions. This knowledge is necessary for the scrolling code to
7139 always obey the First Golden Rule of Redisplay.
7141 If the cache already contains all of the information that the scrolling
7142 routines happen to need so that it doesn't have to go generate it, then we
7143 are able to obey the Third Golden Rule of Redisplay. The first thing we
7144 do to help out the cache is to always add the displayed region. This
7145 region had to be generated anyway, so the cache ends up getting the
7146 information basically for free. In those cases where a user is simply
7147 scrolling around viewing a buffer there is a high probability that this is
7148 sufficient to always provide the needed information. The second thing we
7149 can do is be smart about invalidating the cache.
7151 TODO -- Be smart about invalidating the cache. Potential places:
7153 + Insertions at end-of-line which don't cause line-wraps do not alter the
7154 starting positions of any display lines. These types of buffer
7155 modifications should not invalidate the cache. This is actually a large
7156 optimization for redisplay speed as well.
7158 + Buffer modifications frequently only affect the display of lines at and
7159 below where they occur. In these situations we should only invalidate
7160 the part of the cache starting at where the modification occurs.
7162 In case you're wondering, the Second Golden Rule of Redisplay is not
7164 ****************************************************************************/
7166 /* This will get used quite a bit so we don't want to be constantly
7167 allocating and freeing it. */
7168 static line_start_cache_dynarr *internal_cache;
7170 /* Makes internal_cache represent the TYPE display structs and only
7171 the TYPE display structs. */
7174 update_internal_cache_list (struct window *w, int type)
7177 display_line_dynarr *dla = window_display_lines (w, type);
7179 Dynarr_reset (internal_cache);
7180 for (line = 0; line < Dynarr_length (dla); line++)
7182 struct display_line *dl = Dynarr_atp (dla, line);
7188 struct line_start_cache lsc;
7190 lsc.start = dl->bufpos;
7191 lsc.end = dl->end_bufpos;
7192 lsc.height = dl->ascent + dl->descent;
7194 Dynarr_add (internal_cache, lsc);
7199 /* Reset the line cache if necessary. This should be run at the
7200 beginning of any function which access the cache. */
7203 validate_line_start_cache (struct window *w)
7205 struct buffer *b = XBUFFER (w->buffer);
7206 struct frame *f = XFRAME (w->frame);
7208 if (!w->line_cache_validation_override)
7210 /* f->extents_changed used to be in here because extent face and
7211 size changes can cause text shifting. However, the extent
7212 covering the region is constantly having its face set and
7213 priority altered by the mouse code. This means that the line
7214 start cache is constantly being invalidated. This is bad
7215 since the mouse code also triggers heavy usage of the cache.
7216 Since it is an unlikely that f->extents being changed
7217 indicates that the cache really needs to be updated and if it
7218 does redisplay will catch it pretty quickly we no longer
7219 invalidate the cache if it is set. This greatly speeds up
7220 dragging out regions with the mouse. */
7221 if (XINT (w->line_cache_last_updated) < BUF_MODIFF (b)
7225 Dynarr_reset (w->line_start_cache);
7230 /* Return the very first buffer position contained in the given
7231 window's cache, or -1 if the cache is empty. Assumes that the
7235 line_start_cache_start (struct window *w)
7237 line_start_cache_dynarr *cache = w->line_start_cache;
7239 if (!Dynarr_length (cache))
7242 return Dynarr_atp (cache, 0)->start;
7245 /* Return the very last buffer position contained in the given
7246 window's cache, or -1 if the cache is empty. Assumes that the
7250 line_start_cache_end (struct window *w)
7252 line_start_cache_dynarr *cache = w->line_start_cache;
7254 if (!Dynarr_length (cache))
7257 return Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
7260 /* Return the index of the line POINT is contained within in window
7261 W's line start cache. It will enlarge the cache or move the cache
7262 window in order to have POINT be present in the cache. MIN_PAST is
7263 a guarantee of the number of entries in the cache present on either
7264 side of POINT (unless a buffer boundary is hit). If MIN_PAST is -1
7265 then it will be treated as 0, but the cache window will not be
7266 allowed to shift. Returns -1 if POINT cannot be found in the cache
7270 point_in_line_start_cache (struct window *w, Bufpos point, int min_past)
7272 struct buffer *b = XBUFFER (w->buffer);
7273 line_start_cache_dynarr *cache = w->line_start_cache;
7274 unsigned int top, bottom, pos;
7276 validate_line_start_cache (w);
7277 w->line_cache_validation_override++;
7279 /* Let functions pass in negative values, but we still treat -1
7281 /* #### bogosity alert */
7282 if (min_past < 0 && min_past != -1)
7283 min_past = -min_past;
7285 if (!Dynarr_length (cache) || line_start_cache_start (w) > point
7286 || line_start_cache_end (w) < point)
7289 int win_char_height = window_char_height (w, 1);
7291 /* Occasionally we get here with a 0 height
7292 window. find_next_newline_no_quit will abort if we pass it a
7293 count of 0 so handle that case. */
7294 if (!win_char_height)
7295 win_char_height = 1;
7297 if (!Dynarr_length (cache))
7299 Bufpos from = find_next_newline_no_quit (b, point, -1);
7300 Bufpos to = find_next_newline_no_quit (b, from, win_char_height);
7302 update_line_start_cache (w, from, to, point, 0);
7304 if (!Dynarr_length (cache))
7306 w->line_cache_validation_override--;
7311 assert (Dynarr_length (cache));
7314 while (line_start_cache_start (w) > point
7315 && (loop < cache_adjustment || min_past == -1))
7319 from = line_start_cache_start (w);
7320 if (from <= BUF_BEGV (b))
7323 from = find_next_newline_no_quit (b, from, -win_char_height);
7324 to = line_start_cache_end (w);
7326 update_line_start_cache (w, from, to, point, 0);
7330 if (line_start_cache_start (w) > point)
7334 from = find_next_newline_no_quit (b, point, -1);
7335 if (from >= BUF_ZV (b))
7337 to = find_next_newline_no_quit (b, from, -win_char_height);
7342 to = find_next_newline_no_quit (b, from, win_char_height);
7344 update_line_start_cache (w, from, to, point, 0);
7348 while (line_start_cache_end (w) < point
7349 && (loop < cache_adjustment || min_past == -1))
7353 to = line_start_cache_end (w);
7354 if (to >= BUF_ZV (b))
7357 from = line_start_cache_end (w);
7358 to = find_next_newline_no_quit (b, from, win_char_height);
7360 update_line_start_cache (w, from, to, point, 0);
7364 if (line_start_cache_end (w) < point)
7368 from = find_next_newline_no_quit (b, point, -1);
7369 if (from >= BUF_ZV (b))
7371 to = find_next_newline_no_quit (b, from, -win_char_height);
7376 to = find_next_newline_no_quit (b, from, win_char_height);
7378 update_line_start_cache (w, from, to, point, 0);
7382 assert (Dynarr_length (cache));
7387 /* This could happen if the buffer is narrowed. */
7388 if (line_start_cache_start (w) > point
7389 || line_start_cache_end (w) < point)
7391 w->line_cache_validation_override--;
7397 top = Dynarr_length (cache) - 1;
7402 unsigned int new_pos;
7405 pos = (bottom + top + 1) >> 1;
7406 start = Dynarr_atp (cache, pos)->start;
7407 end = Dynarr_atp (cache, pos)->end;
7409 if (point >= start && point <= end)
7411 if (pos < min_past && line_start_cache_start (w) > BUF_BEGV (b))
7414 find_next_newline_no_quit (b, line_start_cache_start (w),
7416 Bufpos to = line_start_cache_end (w);
7418 update_line_start_cache (w, from, to, point, 0);
7419 goto find_point_loop;
7421 else if ((Dynarr_length (cache) - pos - 1) < min_past
7422 && line_start_cache_end (w) < BUF_ZV (b))
7424 Bufpos from = line_start_cache_end (w);
7425 Bufpos to = find_next_newline_no_quit (b, from,
7430 update_line_start_cache (w, from, to, point, 0);
7431 goto find_point_loop;
7435 w->line_cache_validation_override--;
7439 else if (point > end)
7441 else if (point < start)
7446 new_pos = (bottom + top + 1) >> 1;
7449 w->line_cache_validation_override--;
7455 /* Return a boolean indicating if POINT would be visible in window W
7456 if display of the window was to begin at STARTP. */
7459 point_would_be_visible (struct window *w, Bufpos startp, Bufpos point)
7461 struct buffer *b = XBUFFER (w->buffer);
7462 int pixpos = -WINDOW_TEXT_TOP_CLIP(w);
7463 int bottom = WINDOW_TEXT_HEIGHT (w);
7466 /* If point is before the intended start it obviously can't be visible. */
7470 /* If point or start are not in the accessible buffer range, then
7472 if (startp < BUF_BEGV (b) || startp > BUF_ZV (b)
7473 || point < BUF_BEGV (b) || point > BUF_ZV (b))
7476 validate_line_start_cache (w);
7477 w->line_cache_validation_override++;
7479 start_elt = point_in_line_start_cache (w, startp, 0);
7480 if (start_elt == -1)
7482 w->line_cache_validation_override--;
7486 assert (line_start_cache_start (w) <= startp
7487 && line_start_cache_end (w) >= startp);
7493 /* Expand the cache if necessary. */
7494 if (start_elt == Dynarr_length (w->line_start_cache))
7497 Dynarr_atp (w->line_start_cache, start_elt - 1)->start;
7499 start_elt = point_in_line_start_cache (w, old_startp,
7500 window_char_height (w, 0));
7502 /* We've already actually processed old_startp, so increment
7506 /* If this happens we didn't add any extra elements. Bummer. */
7507 if (start_elt == Dynarr_length (w->line_start_cache))
7509 w->line_cache_validation_override--;
7514 height = Dynarr_atp (w->line_start_cache, start_elt)->height;
7516 if (pixpos + height > bottom)
7518 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7520 w->line_cache_validation_override--;
7526 if (point <= Dynarr_atp (w->line_start_cache, start_elt)->end)
7528 w->line_cache_validation_override--;
7536 /* For the given window W, if display starts at STARTP, what will be
7537 the buffer position at the beginning or end of the last line
7538 displayed. The end of the last line is also know as the window end
7541 WARNING: It is possible that rediplay failed to layout any lines for the
7542 windows. Under normal circumstances this is rare. However it seems that it
7543 does occur in the following situation: A mouse event has come in and we
7544 need to compute its location in a window. That code (in
7545 pixel_to_glyph_translation) already can handle 0 as an error return value.
7547 #### With a little work this could probably be reworked as just a
7548 call to start_with_line_at_pixpos. */
7551 start_end_of_last_line (struct window *w, Bufpos startp, int end,
7554 struct buffer *b = XBUFFER (w->buffer);
7555 line_start_cache_dynarr *cache = w->line_start_cache;
7557 int bottom = WINDOW_TEXT_HEIGHT (w);
7561 validate_line_start_cache (w);
7562 w->line_cache_validation_override++;
7564 if (startp < BUF_BEGV (b))
7565 startp = BUF_BEGV (b);
7566 else if (startp > BUF_ZV (b))
7567 startp = BUF_ZV (b);
7570 start_elt = point_in_line_start_cache (w, cur_start, 0);
7571 if (start_elt == -1)
7572 return may_error ? 0 : startp;
7576 int height = Dynarr_atp (cache, start_elt)->height;
7578 cur_start = Dynarr_atp (cache, start_elt)->start;
7580 if (pixpos + height > bottom)
7582 /* Adjust for any possible clip. */
7583 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7588 w->line_cache_validation_override--;
7592 return BUF_BEGV (b);
7596 w->line_cache_validation_override--;
7598 return Dynarr_atp (cache, start_elt)->end;
7600 return Dynarr_atp (cache, start_elt)->start;
7606 if (start_elt == Dynarr_length (cache))
7608 Bufpos from = line_start_cache_end (w);
7609 int win_char_height = window_char_height (w, 0);
7610 Bufpos to = find_next_newline_no_quit (b, from,
7615 /* We've hit the end of the bottom so that's what it is. */
7616 if (from >= BUF_ZV (b))
7618 w->line_cache_validation_override--;
7622 update_line_start_cache (w, from, to, BUF_PT (b), 0);
7624 /* Updating the cache invalidates any current indexes. */
7625 start_elt = point_in_line_start_cache (w, cur_start, -1) + 1;
7630 /* For the given window W, if display starts at STARTP, what will be
7631 the buffer position at the beginning of the last line displayed. */
7634 start_of_last_line (struct window *w, Bufpos startp)
7636 return start_end_of_last_line (w, startp, 0 , 0);
7639 /* For the given window W, if display starts at STARTP, what will be
7640 the buffer position at the end of the last line displayed. This is
7641 also know as the window end position. */
7644 end_of_last_line (struct window *w, Bufpos startp)
7646 return start_end_of_last_line (w, startp, 1, 0);
7650 end_of_last_line_may_error (struct window *w, Bufpos startp)
7652 return start_end_of_last_line (w, startp, 1, 1);
7656 /* For window W, what does the starting position have to be so that
7657 the line containing POINT will cover pixel position PIXPOS. */
7660 start_with_line_at_pixpos (struct window *w, Bufpos point, int pixpos)
7662 struct buffer *b = XBUFFER (w->buffer);
7664 Bufpos cur_pos, prev_pos = point;
7665 int point_line_height;
7666 int pixheight = pixpos - WINDOW_TEXT_TOP (w);
7668 validate_line_start_cache (w);
7669 w->line_cache_validation_override++;
7671 cur_elt = point_in_line_start_cache (w, point, 0);
7672 /* #### See comment in update_line_start_cache about big minibuffers. */
7675 w->line_cache_validation_override--;
7679 point_line_height = Dynarr_atp (w->line_start_cache, cur_elt)->height;
7683 cur_pos = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7685 pixheight -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7687 /* Do not take into account the value of vertical_clip here.
7688 That is the responsibility of the calling functions. */
7691 w->line_cache_validation_override--;
7692 if (-pixheight > point_line_height)
7693 /* We can't make the target line cover pixpos, so put it
7694 above pixpos. That way it will at least be visible. */
7704 int win_char_height;
7706 if (cur_pos <= BUF_BEGV (b))
7708 w->line_cache_validation_override--;
7709 return BUF_BEGV (b);
7712 win_char_height = window_char_height (w, 0);
7713 if (!win_char_height)
7714 win_char_height = 1;
7716 from = find_next_newline_no_quit (b, cur_pos, -win_char_height);
7717 to = line_start_cache_end (w);
7718 update_line_start_cache (w, from, to, point, 0);
7720 cur_elt = point_in_line_start_cache (w, cur_pos, 2) - 1;
7721 assert (cur_elt >= -1);
7722 /* This used to be cur_elt>=0 under the assumption that if
7723 point is in the top line and not at BUF_BEGV, then
7724 setting the window_start to a newline before the start of
7725 the first line will always cause scrolling.
7727 However in my (jv) opinion this is wrong. That new line
7728 can be hidden in various ways: invisible extents, an
7729 explicit window-start not at a newline character etc.
7730 The existence of those are indeed known to create crashes
7731 on that assert. So we have no option but to continue the
7732 search if we found point at the top of the line_start_cache
7734 cur_pos = Dynarr_atp (w->line_start_cache,0)->start;
7740 /* For window W, what does the starting position have to be so that
7741 the line containing point is on display line LINE. If LINE is
7742 positive it is considered to be the number of lines from the top of
7743 the window (0 is the top line). If it is negative the number is
7744 considered to be the number of lines from the bottom (-1 is the
7748 start_with_point_on_display_line (struct window *w, Bufpos point, int line)
7750 validate_line_start_cache (w);
7751 w->line_cache_validation_override++;
7755 int cur_elt = point_in_line_start_cache (w, point, line);
7757 if (cur_elt - line < 0)
7758 cur_elt = 0; /* Hit the top */
7762 w->line_cache_validation_override--;
7763 return Dynarr_atp (w->line_start_cache, cur_elt)->start;
7767 /* The calculated value of pixpos is correct for the bottom line
7768 or what we want when line is -1. Therefore we subtract one
7769 because we have already handled one line. */
7770 int new_line = -line - 1;
7771 int cur_elt = point_in_line_start_cache (w, point, new_line);
7772 int pixpos = WINDOW_TEXT_BOTTOM (w);
7773 Bufpos retval, search_point;
7775 /* If scroll_on_clipped_lines is false, the last "visible" line of
7776 the window covers the pixel at WINDOW_TEXT_BOTTOM (w) - 1.
7777 If s_o_c_l is true, then we don't want to count a clipped
7778 line, so back up from the bottom by the height of the line
7779 containing point. */
7780 if (scroll_on_clipped_lines)
7781 pixpos -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7785 if (cur_elt + new_line >= Dynarr_length (w->line_start_cache))
7787 /* Hit the bottom of the buffer. */
7789 (cur_elt + new_line) - Dynarr_length (w->line_start_cache) + 1;
7793 XSETWINDOW (window, w);
7794 default_face_height_and_width (window, &defheight, 0);
7796 cur_elt = Dynarr_length (w->line_start_cache) - 1;
7798 pixpos -= (adjustment * defheight);
7799 if (pixpos < WINDOW_TEXT_TOP (w))
7800 pixpos = WINDOW_TEXT_TOP (w);
7803 cur_elt = cur_elt + new_line;
7805 search_point = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7807 retval = start_with_line_at_pixpos (w, search_point, pixpos);
7808 w->line_cache_validation_override--;
7813 /* This is used to speed up vertical scrolling by caching the known
7814 buffer starting positions for display lines. This allows the
7815 scrolling routines to avoid costly calls to regenerate_window. If
7816 NO_REGEN is true then it will only add the values in the DESIRED
7817 display structs which are in the given range.
7819 Note also that the FROM/TO values are minimums. It is possible
7820 that this function will actually add information outside of the
7821 lines containing those positions. This can't hurt but it could
7824 #### We currently force the cache to have only 1 contiguous region.
7825 It might help to make the cache a dynarr of caches so that we can
7826 cover more areas. This might, however, turn out to be a lot of
7827 overhead for too little gain. */
7830 update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
7831 Bufpos point, int no_regen)
7833 struct buffer *b = XBUFFER (w->buffer);
7834 line_start_cache_dynarr *cache = w->line_start_cache;
7835 Bufpos low_bound, high_bound;
7837 validate_line_start_cache (w);
7838 w->line_cache_validation_override++;
7839 updating_line_start_cache = 1;
7841 if (from < BUF_BEGV (b))
7842 from = BUF_BEGV (b);
7843 if (to > BUF_ZV (b))
7848 updating_line_start_cache = 0;
7849 w->line_cache_validation_override--;
7853 if (Dynarr_length (cache))
7855 low_bound = line_start_cache_start (w);
7856 high_bound = line_start_cache_end (w);
7858 /* Check to see if the desired range is already in the cache. */
7859 if (from >= low_bound && to <= high_bound)
7861 updating_line_start_cache = 0;
7862 w->line_cache_validation_override--;
7866 /* Check to make sure that the desired range is adjacent to the
7867 current cache. If not, invalidate the cache. */
7868 if (to < low_bound || from > high_bound)
7870 Dynarr_reset (cache);
7871 low_bound = high_bound = -1;
7876 low_bound = high_bound = -1;
7879 w->line_cache_last_updated = make_int (BUF_MODIFF (b));
7881 /* This could be integrated into the next two sections, but it is easier
7882 to follow what's going on by having it separate. */
7887 update_internal_cache_list (w, DESIRED_DISP);
7888 if (!Dynarr_length (internal_cache))
7890 updating_line_start_cache = 0;
7891 w->line_cache_validation_override--;
7895 start = Dynarr_atp (internal_cache, 0)->start;
7897 Dynarr_atp (internal_cache, Dynarr_length (internal_cache) - 1)->end;
7899 /* We aren't allowed to generate additional information to fill in
7900 gaps, so if the DESIRED structs don't overlap the cache, reset the
7902 if (Dynarr_length (cache))
7904 if (end < low_bound || start > high_bound)
7905 Dynarr_reset (cache);
7907 /* #### What should really happen if what we are doing is
7908 extending a line (the last line)? */
7909 if (Dynarr_length (cache) == 1
7910 && Dynarr_length (internal_cache) == 1)
7911 Dynarr_reset (cache);
7914 if (!Dynarr_length (cache))
7916 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7917 Dynarr_length (internal_cache));
7918 updating_line_start_cache = 0;
7919 w->line_cache_validation_override--;
7923 /* An extra check just in case the calling function didn't pass in
7924 the bounds of the DESIRED structs in the first place. */
7925 if (start >= low_bound && end <= high_bound)
7927 updating_line_start_cache = 0;
7928 w->line_cache_validation_override--;
7932 /* At this point we know that the internal cache partially overlaps
7934 if (start < low_bound)
7936 int ic_elt = Dynarr_length (internal_cache) - 1;
7939 if (Dynarr_atp (internal_cache, ic_elt)->start < low_bound)
7947 Dynarr_reset (cache);
7948 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7949 Dynarr_length (internal_cache));
7950 updating_line_start_cache = 0;
7951 w->line_cache_validation_override--;
7955 Dynarr_insert_many_at_start (cache, Dynarr_atp (internal_cache, 0),
7959 if (end > high_bound)
7963 while (ic_elt < Dynarr_length (internal_cache))
7965 if (Dynarr_atp (internal_cache, ic_elt)->start > high_bound)
7971 if (!(ic_elt < Dynarr_length (internal_cache)))
7973 Dynarr_reset (cache);
7974 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7975 Dynarr_length (internal_cache));
7976 updating_line_start_cache = 0;
7977 w->line_cache_validation_override--;
7981 Dynarr_add_many (cache, Dynarr_atp (internal_cache, ic_elt),
7982 Dynarr_length (internal_cache) - ic_elt);
7985 updating_line_start_cache = 0;
7986 w->line_cache_validation_override--;
7990 if (!Dynarr_length (cache) || from < low_bound)
7992 Bufpos startp = find_next_newline_no_quit (b, from, -1);
7994 int old_lb = low_bound;
7996 while (startp < old_lb || low_bound == -1)
8001 regenerate_window (w, startp, point, CMOTION_DISP);
8002 update_internal_cache_list (w, CMOTION_DISP);
8004 /* If this assert is triggered then regenerate_window failed
8005 to layout a single line. That is not supposed to be
8006 possible because we impose a minimum height on the buffer
8007 and override vertical clip when we are in here. */
8008 /* #### Ah, but it is because the window may temporarily
8009 exist but not have any lines at all if the minibuffer is
8010 real big. Look into that situation better. */
8011 if (!Dynarr_length (internal_cache))
8013 if (old_lb == -1 && low_bound == -1)
8015 updating_line_start_cache = 0;
8016 w->line_cache_validation_override--;
8020 assert (Dynarr_length (internal_cache));
8022 assert (startp == Dynarr_atp (internal_cache, 0)->start);
8024 ic_elt = Dynarr_length (internal_cache) - 1;
8025 if (low_bound != -1)
8029 if (Dynarr_atp (internal_cache, ic_elt)->start < old_lb)
8035 assert (ic_elt >= 0);
8037 new_startp = Dynarr_atp (internal_cache, ic_elt)->end + 1;
8040 * Handle invisible text properly:
8041 * If the last line we're inserting has the same end as the
8042 * line before which it will be added, merge the two lines.
8044 if (Dynarr_length (cache) &&
8045 Dynarr_atp (internal_cache, ic_elt)->end ==
8046 Dynarr_atp (cache, marker)->end)
8048 Dynarr_atp (cache, marker)->start
8049 = Dynarr_atp (internal_cache, ic_elt)->start;
8050 Dynarr_atp (cache, marker)->height
8051 = Dynarr_atp (internal_cache, ic_elt)->height;
8055 if (ic_elt >= 0) /* we still have lines to add.. */
8057 Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0),
8058 ic_elt + 1, marker);
8059 marker += (ic_elt + 1);
8062 if (startp < low_bound || low_bound == -1)
8064 startp = new_startp;
8065 if (startp > BUF_ZV (b))
8067 updating_line_start_cache = 0;
8068 w->line_cache_validation_override--;
8074 assert (Dynarr_length (cache));
8075 assert (from >= low_bound);
8077 /* Readjust the high_bound to account for any changes made while
8078 correcting the low_bound. */
8079 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8081 if (to > high_bound)
8083 Bufpos startp = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end + 1;
8087 regenerate_window (w, startp, point, CMOTION_DISP);
8088 update_internal_cache_list (w, CMOTION_DISP);
8090 /* See comment above about regenerate_window failing. */
8091 assert (Dynarr_length (internal_cache));
8093 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
8094 Dynarr_length (internal_cache));
8095 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8096 startp = high_bound + 1;
8098 while (to > high_bound);
8101 updating_line_start_cache = 0;
8102 w->line_cache_validation_override--;
8103 assert (to <= high_bound);
8107 /* Given x and y coordinates in characters, relative to a window,
8108 return the pixel location corresponding to those coordinates. The
8109 pixel location returned is the center of the given character
8110 position. The pixel values are generated relative to the window,
8113 The modeline is considered to be part of the window. */
8116 glyph_to_pixel_translation (struct window *w, int char_x, int char_y,
8117 int *pix_x, int *pix_y)
8119 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
8120 int num_disp_lines, modeline;
8122 int defheight, defwidth;
8124 XSETWINDOW (window, w);
8125 default_face_height_and_width (window, &defheight, &defwidth);
8127 /* If we get a bogus value indicating somewhere above or to the left of
8128 the window, use the first window line or character position
8135 num_disp_lines = Dynarr_length (dla);
8139 if (Dynarr_atp (dla, 0)->modeline)
8146 /* First check if the y position intersects the display lines. */
8147 if (char_y < num_disp_lines)
8149 struct display_line *dl = Dynarr_atp (dla, char_y + modeline);
8150 struct display_block *db = get_display_block_from_line (dl, TEXT);
8152 *pix_y = (dl->ypos - dl->ascent +
8153 ((unsigned int) (dl->ascent + dl->descent - dl->clip) >> 1));
8155 if (char_x < Dynarr_length (db->runes))
8157 struct rune *rb = Dynarr_atp (db->runes, char_x);
8159 *pix_x = rb->xpos + (rb->width >> 1);
8163 int last_rune = Dynarr_length (db->runes) - 1;
8164 struct rune *rb = Dynarr_atp (db->runes, last_rune);
8166 char_x -= last_rune;
8168 *pix_x = rb->xpos + rb->width;
8169 *pix_x += ((char_x - 1) * defwidth);
8170 *pix_x += (defwidth >> 1);
8175 /* It didn't intersect, so extrapolate. #### For now, we include the
8176 modeline in this since we don't have true character positions in
8179 if (!Dynarr_length (w->face_cachels))
8180 reset_face_cachels (w);
8182 char_y -= num_disp_lines;
8184 if (Dynarr_length (dla))
8186 struct display_line *dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
8187 *pix_y = dl->ypos + dl->descent - dl->clip;
8190 *pix_y = WINDOW_TEXT_TOP (w);
8192 *pix_y += (char_y * defheight);
8193 *pix_y += (defheight >> 1);
8195 *pix_x = WINDOW_TEXT_LEFT (w);
8196 /* Don't adjust by one because this is still the unadjusted value. */
8197 *pix_x += (char_x * defwidth);
8198 *pix_x += (defwidth >> 1);
8201 if (*pix_x > w->pixel_left + w->pixel_width)
8202 *pix_x = w->pixel_left + w->pixel_width;
8203 if (*pix_y > w->pixel_top + w->pixel_height)
8204 *pix_y = w->pixel_top + w->pixel_height;
8206 *pix_x -= w->pixel_left;
8207 *pix_y -= w->pixel_top;
8210 /* Given a display line and a position, determine if there is a glyph
8211 there and return information about it if there is. */
8214 get_position_object (struct display_line *dl, Lisp_Object *obj1,
8215 Lisp_Object *obj2, int x_coord, int *low_x_coord,
8218 struct display_block *db;
8221 get_next_display_block (dl->bounds, dl->display_blocks, x_coord, 0);
8223 /* We use get_next_display_block to get the actual display block
8224 that would be displayed at x_coord. */
8226 if (block == NO_BLOCK)
8229 db = Dynarr_atp (dl->display_blocks, block);
8231 for (elt = 0; elt < Dynarr_length (db->runes); elt++)
8233 struct rune *rb = Dynarr_atp (db->runes, elt);
8235 if (rb->xpos <= x_coord && x_coord < (rb->xpos + rb->width))
8237 if (rb->type == RUNE_DGLYPH)
8239 *obj1 = rb->object.dglyph.glyph;
8240 *obj2 = rb->object.dglyph.extent;
8249 *low_x_coord = rb->xpos;
8251 *high_x_coord = rb->xpos + rb->width;
8258 #define UPDATE_CACHE_RETURN \
8260 d->pixel_to_glyph_cache.valid = 1; \
8261 d->pixel_to_glyph_cache.low_x_coord = low_x_coord; \
8262 d->pixel_to_glyph_cache.high_x_coord = high_x_coord; \
8263 d->pixel_to_glyph_cache.low_y_coord = low_y_coord; \
8264 d->pixel_to_glyph_cache.high_y_coord = high_y_coord; \
8265 d->pixel_to_glyph_cache.frame = f; \
8266 d->pixel_to_glyph_cache.col = *col; \
8267 d->pixel_to_glyph_cache.row = *row; \
8268 d->pixel_to_glyph_cache.obj_x = *obj_x; \
8269 d->pixel_to_glyph_cache.obj_y = *obj_y; \
8270 d->pixel_to_glyph_cache.w = *w; \
8271 d->pixel_to_glyph_cache.bufpos = *bufpos; \
8272 d->pixel_to_glyph_cache.closest = *closest; \
8273 d->pixel_to_glyph_cache.modeline_closest = *modeline_closest; \
8274 d->pixel_to_glyph_cache.obj1 = *obj1; \
8275 d->pixel_to_glyph_cache.obj2 = *obj2; \
8276 d->pixel_to_glyph_cache.retval = position; \
8277 RETURN_SANS_WARNINGS position; \
8280 /* Given x and y coordinates in pixels relative to a frame, return
8281 information about what is located under those coordinates.
8283 The return value will be one of:
8285 OVER_TOOLBAR: over one of the 4 frame toolbars
8286 OVER_MODELINE: over a modeline
8287 OVER_BORDER: over an internal border
8288 OVER_NOTHING: over the text area, but not over text
8289 OVER_OUTSIDE: outside of the frame border
8290 OVER_TEXT: over text in the text area
8296 -- nil if the coordinates are not over a glyph or a toolbar button.
8300 -- an extent, if the coordinates are over a glyph in the text area
8303 If the coordinates are over a glyph, OBJ_X and OBJ_Y give the
8304 equivalent coordinates relative to the upper-left corner of the glyph.
8306 If the coordinates are over a character, OBJ_X and OBJ_Y give the
8307 equivalent coordinates relative to the upper-left corner of the character.
8309 Otherwise, OBJ_X and OBJ_Y are undefined.
8313 pixel_to_glyph_translation (struct frame *f, int x_coord, int y_coord,
8314 int *col, int *row, int *obj_x, int *obj_y,
8315 struct window **w, Bufpos *bufpos,
8316 Bufpos *closest, Charcount *modeline_closest,
8317 Lisp_Object *obj1, Lisp_Object *obj2)
8320 struct pixel_to_glyph_translation_cache *cache;
8322 int frm_left, frm_right, frm_top, frm_bottom;
8323 int low_x_coord, high_x_coord, low_y_coord, high_y_coord;
8324 int position = OVER_NOTHING;
8325 int device_check_failed = 0;
8326 display_line_dynarr *dla;
8328 /* This is a safety valve in case this got called with a frame in
8329 the middle of being deleted. */
8330 if (!DEVICEP (f->device) || !DEVICE_LIVE_P (XDEVICE (f->device)))
8332 device_check_failed = 1;
8333 d = NULL, cache = NULL; /* Warning suppression */
8337 d = XDEVICE (f->device);
8338 cache = &d->pixel_to_glyph_cache;
8341 if (!device_check_failed
8343 && cache->frame == f
8344 && cache->low_x_coord <= x_coord
8345 && cache->high_x_coord > x_coord
8346 && cache->low_y_coord <= y_coord
8347 && cache->high_y_coord > y_coord)
8351 *obj_x = cache->obj_x;
8352 *obj_y = cache->obj_y;
8354 *bufpos = cache->bufpos;
8355 *closest = cache->closest;
8356 *modeline_closest = cache->modeline_closest;
8357 *obj1 = cache->obj1;
8358 *obj2 = cache->obj2;
8360 return cache->retval;
8371 *modeline_closest = -1;
8375 low_x_coord = x_coord;
8376 high_x_coord = x_coord + 1;
8377 low_y_coord = y_coord;
8378 high_y_coord = y_coord + 1;
8381 if (device_check_failed)
8382 return OVER_NOTHING;
8384 frm_left = FRAME_LEFT_BORDER_END (f);
8385 frm_right = FRAME_RIGHT_BORDER_START (f);
8386 frm_top = FRAME_TOP_BORDER_END (f);
8387 frm_bottom = FRAME_BOTTOM_BORDER_START (f);
8389 /* Check if the mouse is outside of the text area actually used by
8391 if (y_coord < frm_top)
8393 if (y_coord >= FRAME_TOP_BORDER_START (f))
8395 low_y_coord = FRAME_TOP_BORDER_START (f);
8396 high_y_coord = frm_top;
8397 position = OVER_BORDER;
8399 else if (y_coord >= 0)
8402 high_y_coord = FRAME_TOP_BORDER_START (f);
8403 position = OVER_TOOLBAR;
8407 low_y_coord = y_coord;
8409 position = OVER_OUTSIDE;
8412 else if (y_coord >= frm_bottom)
8414 if (y_coord < FRAME_BOTTOM_BORDER_END (f))
8416 low_y_coord = frm_bottom;
8417 high_y_coord = FRAME_BOTTOM_BORDER_END (f);
8418 position = OVER_BORDER;
8420 else if (y_coord < FRAME_PIXHEIGHT (f))
8422 low_y_coord = FRAME_BOTTOM_BORDER_END (f);
8423 high_y_coord = FRAME_PIXHEIGHT (f);
8424 position = OVER_TOOLBAR;
8428 low_y_coord = FRAME_PIXHEIGHT (f);
8429 high_y_coord = y_coord;
8430 position = OVER_OUTSIDE;
8434 if (position != OVER_TOOLBAR && position != OVER_BORDER)
8436 if (x_coord < frm_left)
8438 if (x_coord >= FRAME_LEFT_BORDER_START (f))
8440 low_x_coord = FRAME_LEFT_BORDER_START (f);
8441 high_x_coord = frm_left;
8442 position = OVER_BORDER;
8444 else if (x_coord >= 0)
8447 high_x_coord = FRAME_LEFT_BORDER_START (f);
8448 position = OVER_TOOLBAR;
8452 low_x_coord = x_coord;
8454 position = OVER_OUTSIDE;
8457 else if (x_coord >= frm_right)
8459 if (x_coord < FRAME_RIGHT_BORDER_END (f))
8461 low_x_coord = frm_right;
8462 high_x_coord = FRAME_RIGHT_BORDER_END (f);
8463 position = OVER_BORDER;
8465 else if (x_coord < FRAME_PIXWIDTH (f))
8467 low_x_coord = FRAME_RIGHT_BORDER_END (f);
8468 high_x_coord = FRAME_PIXWIDTH (f);
8469 position = OVER_TOOLBAR;
8473 low_x_coord = FRAME_PIXWIDTH (f);
8474 high_x_coord = x_coord;
8475 position = OVER_OUTSIDE;
8480 #ifdef HAVE_TOOLBARS
8481 if (position == OVER_TOOLBAR)
8483 *obj1 = toolbar_button_at_pixpos (f, x_coord, y_coord);
8486 UPDATE_CACHE_RETURN;
8488 #endif /* HAVE_TOOLBARS */
8490 /* We still have to return the window the pointer is next to and its
8491 relative y position even if it is outside the x boundary. */
8492 if (x_coord < frm_left)
8494 else if (x_coord > frm_right)
8495 x_coord = frm_right;
8497 /* Same in reverse. */
8498 if (y_coord < frm_top)
8500 else if (y_coord > frm_bottom)
8501 y_coord = frm_bottom;
8503 /* Find what window the given coordinates are actually in. */
8504 window = f->root_window;
8505 *w = find_window_by_pixel_pos (x_coord, y_coord, window);
8507 /* If we didn't find a window, we're done. */
8510 UPDATE_CACHE_RETURN;
8512 else if (position != OVER_NOTHING)
8515 *modeline_closest = -1;
8517 if (high_y_coord <= frm_top || high_y_coord >= frm_bottom)
8520 UPDATE_CACHE_RETURN;
8524 /* Check if the window is a minibuffer but isn't active. */
8525 if (MINI_WINDOW_P (*w) && !minibuf_level)
8527 /* Must reset the window value since some callers will ignore
8528 the return value if it is set. */
8530 UPDATE_CACHE_RETURN;
8533 /* See if the point is over window vertical divider */
8534 if (window_needs_vertical_divider (*w))
8536 int div_x_high = WINDOW_RIGHT (*w);
8537 int div_x_low = div_x_high - window_divider_width (*w);
8538 int div_y_high = WINDOW_BOTTOM (*w);
8539 int div_y_low = WINDOW_TOP (*w);
8541 if (div_x_low < x_coord && x_coord <= div_x_high &&
8542 div_y_low < y_coord && y_coord <= div_y_high)
8544 low_x_coord = div_x_low;
8545 high_x_coord = div_x_high;
8546 low_y_coord = div_y_low;
8547 high_y_coord = div_y_high;
8548 position = OVER_V_DIVIDER;
8549 UPDATE_CACHE_RETURN;
8553 dla = window_display_lines (*w, CURRENT_DISP);
8555 for (*row = 0; *row < Dynarr_length (dla); (*row)++)
8557 int really_over_nothing = 0;
8558 struct display_line *dl = Dynarr_atp (dla, *row);
8560 if ((int) (dl->ypos - dl->ascent) <= y_coord
8561 && y_coord <= (int) (dl->ypos + dl->descent))
8563 int check_margin_glyphs = 0;
8564 struct display_block *db = get_display_block_from_line (dl, TEXT);
8565 struct rune *rb = 0;
8567 if (x_coord < dl->bounds.left_white
8568 || x_coord >= dl->bounds.right_white)
8569 check_margin_glyphs = 1;
8571 low_y_coord = dl->ypos - dl->ascent;
8572 high_y_coord = dl->ypos + dl->descent + 1;
8574 if (position == OVER_BORDER
8575 || position == OVER_OUTSIDE
8576 || check_margin_glyphs)
8578 int x_check, left_bound;
8580 if (check_margin_glyphs)
8583 left_bound = dl->bounds.left_white;
8587 x_check = high_x_coord;
8588 left_bound = frm_left;
8591 if (Dynarr_length (db->runes))
8593 if (x_check <= left_bound)
8596 *modeline_closest = Dynarr_atp (db->runes, 0)->bufpos;
8598 *closest = Dynarr_atp (db->runes, 0)->bufpos;
8604 Dynarr_atp (db->runes,
8605 Dynarr_length (db->runes) - 1)->bufpos;
8608 Dynarr_atp (db->runes,
8609 Dynarr_length (db->runes) - 1)->bufpos;
8613 *modeline_closest += dl->offset;
8615 *closest += dl->offset;
8619 /* #### What should be here. */
8621 *modeline_closest = 0;
8626 if (check_margin_glyphs)
8628 if (x_coord < dl->bounds.left_in
8629 || x_coord >= dl->bounds.right_in)
8631 /* If we are over the outside margins then we
8632 know the loop over the text block isn't going
8633 to accomplish anything. So we go ahead and
8634 set what information we can right here and
8637 *obj_y = y_coord - (dl->ypos - dl->ascent);
8638 get_position_object (dl, obj1, obj2, x_coord,
8639 &low_x_coord, &high_x_coord);
8641 UPDATE_CACHE_RETURN;
8645 UPDATE_CACHE_RETURN;
8648 for (*col = 0; *col <= Dynarr_length (db->runes); (*col)++)
8650 int past_end = (*col == Dynarr_length (db->runes));
8653 rb = Dynarr_atp (db->runes, *col);
8656 (rb->xpos <= x_coord && x_coord < rb->xpos + rb->width))
8661 rb = Dynarr_atp (db->runes, *col);
8664 *bufpos = rb->bufpos + dl->offset;
8665 low_x_coord = rb->xpos;
8666 high_x_coord = rb->xpos + rb->width;
8668 if (rb->type == RUNE_DGLYPH)
8672 /* Find the first character after the glyph. */
8673 while (elt < Dynarr_length (db->runes))
8675 if (Dynarr_atp (db->runes, elt)->type != RUNE_DGLYPH)
8679 (Dynarr_atp (db->runes, elt)->bufpos +
8683 (Dynarr_atp (db->runes, elt)->bufpos +
8691 /* In this case we failed to find a non-glyph
8692 character so we return the last position
8693 displayed on the line. */
8694 if (elt == Dynarr_length (db->runes))
8697 *modeline_closest = dl->end_bufpos + dl->offset;
8699 *closest = dl->end_bufpos + dl->offset;
8700 really_over_nothing = 1;
8706 *modeline_closest = rb->bufpos + dl->offset;
8708 *closest = rb->bufpos + dl->offset;
8713 *row = window_displayed_height (*w);
8715 if (position == OVER_NOTHING)
8716 position = OVER_MODELINE;
8718 if (rb->type == RUNE_DGLYPH)
8720 *obj1 = rb->object.dglyph.glyph;
8721 *obj2 = rb->object.dglyph.extent;
8723 else if (rb->type == RUNE_CHAR)
8734 UPDATE_CACHE_RETURN;
8737 || (rb->type == RUNE_CHAR
8738 && rb->object.chr.ch == '\n'))
8741 /* At this point we may have glyphs in the right
8743 if (check_margin_glyphs)
8744 get_position_object (dl, obj1, obj2, x_coord,
8745 &low_x_coord, &high_x_coord);
8746 UPDATE_CACHE_RETURN;
8751 if (rb->type == RUNE_DGLYPH)
8753 *obj1 = rb->object.dglyph.glyph;
8754 *obj2 = rb->object.dglyph.extent;
8756 else if (rb->type == RUNE_CHAR)
8767 *obj_x = x_coord - rb->xpos;
8768 *obj_y = y_coord - (dl->ypos - dl->ascent);
8770 /* At this point we may have glyphs in the left
8772 if (check_margin_glyphs)
8773 get_position_object (dl, obj1, obj2, x_coord, 0, 0);
8775 if (position == OVER_NOTHING && !really_over_nothing)
8776 position = OVER_TEXT;
8778 UPDATE_CACHE_RETURN;
8785 *row = Dynarr_length (dla) - 1;
8786 if (FRAME_WIN_P (f))
8788 int bot_elt = Dynarr_length (dla) - 1;
8792 struct display_line *dl = Dynarr_atp (dla, bot_elt);
8793 int adj_area = y_coord - (dl->ypos + dl->descent);
8797 XSETWINDOW (lwin, *w);
8798 default_face_height_and_width (lwin, 0, &defheight);
8800 *row += (adj_area / defheight);
8804 /* #### This should be checked out some more to determine what
8805 should really be going on. */
8806 if (!MARKERP ((*w)->start[CURRENT_DISP]))
8809 *closest = end_of_last_line_may_error (*w,
8810 marker_position ((*w)->start[CURRENT_DISP]));
8812 UPDATE_CACHE_RETURN;
8814 #undef UPDATE_CACHE_RETURN
8817 /***************************************************************************/
8819 /* Lisp functions */
8821 /***************************************************************************/
8823 DEFUN ("redisplay-echo-area", Fredisplay_echo_area, 0, 0, 0, /*
8824 Ensure that all minibuffers are correctly showing the echo area.
8828 Lisp_Object devcons, concons;
8830 DEVICE_LOOP_NO_BREAK (devcons, concons)
8832 struct device *d = XDEVICE (XCAR (devcons));
8833 Lisp_Object frmcons;
8835 DEVICE_FRAME_LOOP (frmcons, d)
8837 struct frame *f = XFRAME (XCAR (frmcons));
8839 if (FRAME_REPAINT_P (f) && FRAME_HAS_MINIBUF_P (f))
8841 Lisp_Object window = FRAME_MINIBUF_WINDOW (f);
8843 * If the frame size has changed, there may be random
8844 * chud on the screen left from previous messages
8845 * because redisplay_frame hasn't been called yet.
8846 * Clear the screen to get rid of the potential mess.
8848 if (f->echo_area_garbaged)
8850 DEVMETH (d, clear_frame, (f));
8851 f->echo_area_garbaged = 0;
8853 redisplay_window (window, 0);
8854 call_redisplay_end_triggers (XWINDOW (window), 0);
8858 /* We now call the output_end routine for tty frames. We delay
8859 doing so in order to avoid cursor flicker. So much for 100%
8861 if (DEVICE_TTY_P (d))
8862 DEVMETH (d, output_end, (d));
8869 restore_disable_preemption_value (Lisp_Object value)
8871 disable_preemption = XINT (value);
8875 DEFUN ("redraw-frame", Fredraw_frame, 0, 2, 0, /*
8876 Clear frame FRAME and output again what is supposed to appear on it.
8877 FRAME defaults to the selected frame if omitted.
8878 Normally, redisplay is preempted as normal if input arrives. However,
8879 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8880 input and is guaranteed to proceed to completion.
8882 (frame, no_preempt))
8884 struct frame *f = decode_frame (frame);
8885 int count = specpdl_depth ();
8887 if (!NILP (no_preempt))
8889 record_unwind_protect (restore_disable_preemption_value,
8890 make_int (disable_preemption));
8891 disable_preemption++;
8895 redisplay_frame (f, 1);
8897 /* See the comment in Fredisplay_frame. */
8898 RESET_CHANGED_SET_FLAGS;
8900 return unbind_to (count, Qnil);
8903 DEFUN ("redisplay-frame", Fredisplay_frame, 0, 2, 0, /*
8904 Ensure that FRAME's contents are correctly displayed.
8905 This differs from `redraw-frame' in that it only redraws what needs to
8906 be updated, as opposed to unconditionally clearing and redrawing
8908 FRAME defaults to the selected frame if omitted.
8909 Normally, redisplay is preempted as normal if input arrives. However,
8910 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8911 input and is guaranteed to proceed to completion.
8913 (frame, no_preempt))
8915 struct frame *f = decode_frame (frame);
8916 int count = specpdl_depth ();
8918 if (!NILP (no_preempt))
8920 record_unwind_protect (restore_disable_preemption_value,
8921 make_int (disable_preemption));
8922 disable_preemption++;
8925 redisplay_frame (f, 1);
8927 /* If we don't reset the global redisplay flafs here, subsequent
8928 changes to the display will not get registered by redisplay
8929 because it thinks it already has registered changes. If you
8930 really knew what you were doing you could confuse redisplay by
8931 calling Fredisplay_frame while updating another frame. We assume
8932 that if you know what you are doing you will not be that
8934 RESET_CHANGED_SET_FLAGS;
8936 return unbind_to (count, Qnil);
8939 DEFUN ("redraw-device", Fredraw_device, 0, 2, 0, /*
8940 Clear device DEVICE and output again what is supposed to appear on it.
8941 DEVICE defaults to the selected device if omitted.
8942 Normally, redisplay is preempted as normal if input arrives. However,
8943 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8944 input and is guaranteed to proceed to completion.
8946 (device, no_preempt))
8948 struct device *d = decode_device (device);
8949 Lisp_Object frmcons;
8950 int count = specpdl_depth ();
8952 if (!NILP (no_preempt))
8954 record_unwind_protect (restore_disable_preemption_value,
8955 make_int (disable_preemption));
8956 disable_preemption++;
8959 DEVICE_FRAME_LOOP (frmcons, d)
8961 XFRAME (XCAR (frmcons))->clear = 1;
8963 redisplay_device (d, 0);
8965 /* See the comment in Fredisplay_frame. */
8966 RESET_CHANGED_SET_FLAGS;
8968 return unbind_to (count, Qnil);
8971 DEFUN ("redisplay-device", Fredisplay_device, 0, 2, 0, /*
8972 Ensure that DEVICE's contents are correctly displayed.
8973 This differs from `redraw-device' in that it only redraws what needs to
8974 be updated, as opposed to unconditionally clearing and redrawing
8976 DEVICE defaults to the selected device if omitted.
8977 Normally, redisplay is preempted as normal if input arrives. However,
8978 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8979 input and is guaranteed to proceed to completion.
8981 (device, no_preempt))
8983 struct device *d = decode_device (device);
8984 int count = specpdl_depth ();
8986 if (!NILP (no_preempt))
8988 record_unwind_protect (restore_disable_preemption_value,
8989 make_int (disable_preemption));
8990 disable_preemption++;
8993 redisplay_device (d, 0);
8995 /* See the comment in Fredisplay_frame. */
8996 RESET_CHANGED_SET_FLAGS;
8998 return unbind_to (count, Qnil);
9001 /* Big lie. Big lie. This will force all modelines to be updated
9002 regardless if the all flag is set or not. It remains in existence
9003 solely for backwards compatibility. */
9004 DEFUN ("redraw-modeline", Fredraw_modeline, 0, 1, 0, /*
9005 Force the modeline of the current buffer to be redisplayed.
9006 With optional non-nil ALL, force redisplay of all modelines.
9010 MARK_MODELINE_CHANGED;
9014 DEFUN ("force-cursor-redisplay", Fforce_cursor_redisplay, 0, 1, 0, /*
9015 Force an immediate update of the cursor on FRAME.
9016 FRAME defaults to the selected frame if omitted.
9020 redisplay_redraw_cursor (decode_frame (frame), 1);
9025 /***************************************************************************/
9027 /* Lisp-variable change triggers */
9029 /***************************************************************************/
9032 margin_width_changed_in_frame (Lisp_Object specifier, struct frame *f,
9035 /* Nothing to be done? */
9039 redisplay_variable_changed (Lisp_Object sym, Lisp_Object *val,
9040 Lisp_Object in_object, int flags)
9042 /* #### clip_changed should really be renamed something like
9043 global_redisplay_change. */
9048 /* This is called if the built-in glyphs have their properties
9051 redisplay_glyph_changed (Lisp_Object glyph, Lisp_Object property,
9054 if (WINDOWP (locale))
9056 MARK_FRAME_GLYPHS_CHANGED (XFRAME (WINDOW_FRAME (XWINDOW (locale))));
9058 else if (FRAMEP (locale))
9060 MARK_FRAME_GLYPHS_CHANGED (XFRAME (locale));
9062 else if (DEVICEP (locale))
9064 Lisp_Object frmcons;
9065 DEVICE_FRAME_LOOP (frmcons, XDEVICE (locale))
9066 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9068 else if (CONSOLEP (locale))
9070 Lisp_Object frmcons, devcons;
9071 CONSOLE_FRAME_LOOP_NO_BREAK (frmcons, devcons, XCONSOLE (locale))
9072 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9074 else /* global or buffer */
9076 Lisp_Object frmcons, devcons, concons;
9077 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
9078 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9083 text_cursor_visible_p_changed (Lisp_Object specifier, struct window *w,
9086 if (XFRAME (w->frame)->init_finished)
9087 Fforce_cursor_redisplay (w->frame);
9090 #ifdef MEMORY_USAGE_STATS
9093 /***************************************************************************/
9095 /* memory usage computation */
9097 /***************************************************************************/
9100 compute_rune_dynarr_usage (rune_dynarr *dyn, struct overhead_stats *ovstats)
9102 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9106 compute_display_block_dynarr_usage (display_block_dynarr *dyn,
9107 struct overhead_stats *ovstats)
9114 total = Dynarr_memory_usage (dyn, ovstats);
9115 for (i = 0; i < Dynarr_largest (dyn); i++)
9116 total += compute_rune_dynarr_usage (Dynarr_at (dyn, i).runes, ovstats);
9122 compute_glyph_block_dynarr_usage (glyph_block_dynarr *dyn,
9123 struct overhead_stats *ovstats)
9125 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9129 compute_display_line_dynarr_usage (display_line_dynarr *dyn,
9130 struct overhead_stats *ovstats)
9137 total = Dynarr_memory_usage (dyn, ovstats);
9138 for (i = 0; i < Dynarr_largest (dyn); i++)
9140 struct display_line *dl = &Dynarr_at (dyn, i);
9141 total += compute_display_block_dynarr_usage(dl->display_blocks, ovstats);
9142 total += compute_glyph_block_dynarr_usage (dl->left_glyphs, ovstats);
9143 total += compute_glyph_block_dynarr_usage (dl->right_glyphs, ovstats);
9150 compute_line_start_cache_dynarr_usage (line_start_cache_dynarr *dyn,
9151 struct overhead_stats *ovstats)
9153 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9156 #endif /* MEMORY_USAGE_STATS */
9159 /***************************************************************************/
9161 /* initialization */
9163 /***************************************************************************/
9166 init_redisplay (void)
9168 disable_preemption = 0;
9169 preemption_count = 0;
9170 max_preempts = INIT_MAX_PREEMPTS;
9176 if (!cmotion_display_lines)
9177 cmotion_display_lines = Dynarr_new (display_line);
9178 if (!mode_spec_bufbyte_string)
9179 mode_spec_bufbyte_string = Dynarr_new (Bufbyte);
9180 if (!formatted_string_extent_dynarr)
9181 formatted_string_extent_dynarr = Dynarr_new (EXTENT);
9182 if (!formatted_string_extent_start_dynarr)
9183 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount);
9184 if (!formatted_string_extent_end_dynarr)
9185 formatted_string_extent_end_dynarr = Dynarr_new (Bytecount);
9186 if (!internal_cache)
9187 internal_cache = Dynarr_new (line_start_cache);
9190 /* window system is nil when in -batch mode */
9191 if (!initialized || noninteractive)
9194 /* If the user wants to use a window system, we shouldn't bother
9195 initializing the terminal. This is especially important when the
9196 terminal is so dumb that emacs gives up before and doesn't bother
9197 using the window system.
9199 If the DISPLAY environment variable is set, try to use X, and die
9200 with an error message if that doesn't work. */
9202 #ifdef HAVE_X_WINDOWS
9203 if (!strcmp (display_use, "x"))
9205 /* Some stuff checks this way early. */
9206 Vwindow_system = Qx;
9207 Vinitial_window_system = Qx;
9210 #endif /* HAVE_X_WINDOWS */
9212 #ifdef HAVE_MS_WINDOWS
9213 if (!strcmp (display_use, "mswindows"))
9215 /* Some stuff checks this way early. */
9216 Vwindow_system = Qmswindows;
9217 Vinitial_window_system = Qmswindows;
9220 #endif /* HAVE_MS_WINDOWS */
9223 /* If no window system has been specified, try to use the terminal. */
9226 stderr_out ("XEmacs: standard input is not a tty\n");
9230 /* Look at the TERM variable */
9231 if (!getenv ("TERM"))
9233 stderr_out ("Please set the environment variable TERM; see tset(1).\n");
9237 Vinitial_window_system = Qtty;
9239 #else /* not HAVE_TTY */
9240 /* No DISPLAY specified, and no TTY support. */
9241 stderr_out ("XEmacs: Cannot open display.\n\
9242 Please set the environmental variable DISPLAY to an appropriate value.\n");
9249 syms_of_redisplay (void)
9251 defsymbol (&Qcursor_in_echo_area, "cursor-in-echo-area");
9252 #ifndef INHIBIT_REDISPLAY_HOOKS
9253 defsymbol (&Qpre_redisplay_hook, "pre-redisplay-hook");
9254 defsymbol (&Qpost_redisplay_hook, "post-redisplay-hook");
9255 #endif /* INHIBIT_REDISPLAY_HOOKS */
9256 defsymbol (&Qdisplay_warning_buffer, "display-warning-buffer");
9257 defsymbol (&Qbar_cursor, "bar-cursor");
9258 defsymbol (&Qredisplay_end_trigger_functions,
9259 "redisplay-end-trigger-functions");
9260 defsymbol (&Qtop_bottom, "top-bottom");
9261 defsymbol (&Qbuffer_list_changed_hook, "buffer-list-changed-hook");
9263 DEFSUBR (Fredisplay_echo_area);
9264 DEFSUBR (Fredraw_frame);
9265 DEFSUBR (Fredisplay_frame);
9266 DEFSUBR (Fredraw_device);
9267 DEFSUBR (Fredisplay_device);
9268 DEFSUBR (Fredraw_modeline);
9269 DEFSUBR (Fforce_cursor_redisplay);
9273 reinit_vars_of_redisplay (void)
9275 updating_line_start_cache = 0;
9279 vars_of_redisplay (void)
9281 reinit_vars_of_redisplay ();
9284 staticpro (&last_arrow_position);
9285 staticpro (&last_arrow_string);
9286 last_arrow_position = Qnil;
9287 last_arrow_string = Qnil;
9290 /* #### Probably temporary */
9291 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /*
9292 \(Temporary) Setting this will impact the performance of the internal
9295 cache_adjustment = 2;
9297 DEFVAR_INT_MAGIC ("pixel-vertical-clip-threshold", &vertical_clip /*
9298 Minimum pixel height for clipped bottom display line.
9299 A clipped line shorter than this won't be displayed.
9301 redisplay_variable_changed);
9304 DEFVAR_INT_MAGIC ("pixel-horizontal-clip-threshold", &horizontal_clip /*
9305 Minimum visible area for clipped glyphs at right boundary.
9306 Clipped glyphs shorter than this won't be displayed.
9307 Only pixmap glyph instances are currently allowed to be clipped.
9309 redisplay_variable_changed);
9310 horizontal_clip = 5;
9312 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string /*
9313 String displayed by modeline-format's "%m" specification.
9315 Vglobal_mode_string = Qnil;
9317 DEFVAR_LISP_MAGIC ("overlay-arrow-position", &Voverlay_arrow_position /*
9318 Marker for where to display an arrow on top of the buffer text.
9319 This must be the beginning of a line in order to work.
9320 See also `overlay-arrow-string'.
9322 redisplay_variable_changed);
9323 Voverlay_arrow_position = Qnil;
9325 DEFVAR_LISP_MAGIC ("overlay-arrow-string", &Voverlay_arrow_string /*
9326 String to display as an arrow. See also `overlay-arrow-position'.
9328 redisplay_variable_changed);
9329 Voverlay_arrow_string = Qnil;
9331 DEFVAR_INT ("scroll-step", &scroll_step /*
9332 *The number of lines to try scrolling a window by when point moves out.
9333 If that fails to bring point back on frame, point is centered instead.
9334 If this is zero, point is always centered after it moves off screen.
9338 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively /*
9339 *Scroll up to this many lines, to bring point back on screen.
9341 scroll_conservatively = 0;
9343 DEFVAR_BOOL_MAGIC ("truncate-partial-width-windows",
9344 &truncate_partial_width_windows /*
9345 *Non-nil means truncate lines in all windows less than full frame wide.
9347 redisplay_variable_changed);
9348 truncate_partial_width_windows = 1;
9350 DEFVAR_LISP ("visible-bell", &Vvisible_bell /*
9351 *Non-nil substitutes a visual signal for the audible bell.
9353 Default behavior is to flash the whole screen. On some platforms,
9354 special effects are available using the following values:
9356 'display Flash the whole screen (ie, the default behavior).
9357 'top-bottom Flash only the top and bottom lines of the selected frame.
9359 When effects are unavailable on a platform, the visual bell is the
9360 default, whole screen. (Currently only X supports any special effects.)
9362 Vvisible_bell = Qnil;
9364 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter /*
9365 *Non-nil means no need to redraw entire frame after suspending.
9366 A non-nil value is useful if the terminal can automatically preserve
9367 Emacs's frame display when you reenter Emacs.
9368 It is up to you to set this variable if your terminal can do that.
9370 no_redraw_on_reenter = 0;
9372 DEFVAR_LISP ("window-system", &Vwindow_system /*
9373 A symbol naming the window-system under which Emacs is running,
9374 such as `x', or nil if emacs is running on an ordinary terminal.
9376 Do not use this variable, except for GNU Emacs compatibility, as it
9377 gives wrong values in a multi-device environment. Use `console-type'
9380 Vwindow_system = Qnil;
9382 /* #### Temporary shit until window-system is eliminated. */
9383 DEFVAR_CONST_LISP ("initial-window-system", &Vinitial_window_system /*
9386 Vinitial_window_system = Qnil;
9388 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area /*
9389 Non-nil means put cursor in minibuffer, at end of any message there.
9391 cursor_in_echo_area = 0;
9393 /* #### Shouldn't this be generalized as follows:
9395 if nil, use block cursor.
9396 if a number, use a bar cursor of that width.
9397 Otherwise, use a 1-pixel bar cursor.
9399 #### Or better yet, this variable should be trashed entirely
9400 (use a Lisp-magic variable to maintain compatibility)
9401 and a specifier `cursor-shape' added, which allows a block
9402 cursor, a bar cursor, a flashing block or bar cursor,
9403 maybe a caret cursor, etc. */
9405 DEFVAR_LISP ("bar-cursor", &Vbar_cursor /*
9406 Use vertical bar cursor if non-nil. If t width is 1 pixel, otherwise 2.
9410 #ifndef INHIBIT_REDISPLAY_HOOKS
9411 xxDEFVAR_LISP ("pre-redisplay-hook", &Vpre_redisplay_hook /*
9412 Function or functions to run before every redisplay.
9414 Vpre_redisplay_hook = Qnil;
9416 xxDEFVAR_LISP ("post-redisplay-hook", &Vpost_redisplay_hook /*
9417 Function or functions to run after every redisplay.
9419 Vpost_redisplay_hook = Qnil;
9420 #endif /* INHIBIT_REDISPLAY_HOOKS */
9422 DEFVAR_LISP ("buffer-list-changed-hook", &Vbuffer_list_changed_hook /*
9423 Function or functions to call when a frame's buffer list has changed.
9424 This is called during redisplay, before redisplaying each frame.
9425 Functions on this hook are called with one argument, the frame.
9427 Vbuffer_list_changed_hook = Qnil;
9429 DEFVAR_INT ("display-warning-tick", &display_warning_tick /*
9430 Bump this to tell the C code to call `display-warning-buffer'
9431 at next redisplay. You should not normally change this; the function
9432 `display-warning' automatically does this at appropriate times.
9434 display_warning_tick = 0;
9436 DEFVAR_BOOL ("inhibit-warning-display", &inhibit_warning_display /*
9437 Non-nil means inhibit display of warning messages.
9438 You should *bind* this, not set it. Any pending warning messages
9439 will be displayed when the binding no longer applies.
9441 /* reset to 0 by startup.el after the splash screen has displayed.
9442 This way, the warnings don't obliterate the splash screen. */
9443 inhibit_warning_display = 1;
9445 DEFVAR_LISP ("window-size-change-functions",
9446 &Vwindow_size_change_functions /*
9447 Not currently implemented.
9448 Functions called before redisplay, if window sizes have changed.
9449 The value should be a list of functions that take one argument.
9450 Just before redisplay, for each frame, if any of its windows have changed
9451 size since the last redisplay, or have been split or deleted,
9452 all the functions in the list are called, with the frame as argument.
9454 Vwindow_size_change_functions = Qnil;
9456 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions /*
9457 Not currently implemented.
9458 Functions to call before redisplaying a window with scrolling.
9459 Each function is called with two arguments, the window
9460 and its new display-start position. Note that the value of `window-end'
9461 is not valid when these functions are called.
9463 Vwindow_scroll_functions = Qnil;
9465 DEFVAR_LISP ("redisplay-end-trigger-functions",
9466 &Vredisplay_end_trigger_functions /*
9467 See `set-window-redisplay-end-trigger'.
9469 Vredisplay_end_trigger_functions = Qnil;
9471 DEFVAR_BOOL ("column-number-start-at-one", &column_number_start_at_one /*
9472 *Non-nil means column display number starts at 1.
9474 column_number_start_at_one = 0;
9478 specifier_vars_of_redisplay (void)
9480 DEFVAR_SPECIFIER ("left-margin-width", &Vleft_margin_width /*
9481 *Width of left margin.
9482 This is a specifier; use `set-specifier' to change it.
9484 Vleft_margin_width = Fmake_specifier (Qnatnum);
9485 set_specifier_fallback (Vleft_margin_width, list1 (Fcons (Qnil, Qzero)));
9486 set_specifier_caching (Vleft_margin_width,
9487 offsetof (struct window, left_margin_width),
9488 some_window_value_changed,
9489 offsetof (struct frame, left_margin_width),
9490 margin_width_changed_in_frame);
9492 DEFVAR_SPECIFIER ("right-margin-width", &Vright_margin_width /*
9493 *Width of right margin.
9494 This is a specifier; use `set-specifier' to change it.
9496 Vright_margin_width = Fmake_specifier (Qnatnum);
9497 set_specifier_fallback (Vright_margin_width, list1 (Fcons (Qnil, Qzero)));
9498 set_specifier_caching (Vright_margin_width,
9499 offsetof (struct window, right_margin_width),
9500 some_window_value_changed,
9501 offsetof (struct frame, right_margin_width),
9502 margin_width_changed_in_frame);
9504 DEFVAR_SPECIFIER ("minimum-line-ascent", &Vminimum_line_ascent /*
9505 *Minimum ascent height of lines.
9506 This is a specifier; use `set-specifier' to change it.
9508 Vminimum_line_ascent = Fmake_specifier (Qnatnum);
9509 set_specifier_fallback (Vminimum_line_ascent, list1 (Fcons (Qnil, Qzero)));
9510 set_specifier_caching (Vminimum_line_ascent,
9511 offsetof (struct window, minimum_line_ascent),
9512 some_window_value_changed,
9515 DEFVAR_SPECIFIER ("minimum-line-descent", &Vminimum_line_descent /*
9516 *Minimum descent height of lines.
9517 This is a specifier; use `set-specifier' to change it.
9519 Vminimum_line_descent = Fmake_specifier (Qnatnum);
9520 set_specifier_fallback (Vminimum_line_descent, list1 (Fcons (Qnil, Qzero)));
9521 set_specifier_caching (Vminimum_line_descent,
9522 offsetof (struct window, minimum_line_descent),
9523 some_window_value_changed,
9526 DEFVAR_SPECIFIER ("use-left-overflow", &Vuse_left_overflow /*
9527 *Non-nil means use the left outside margin as extra whitespace when
9528 displaying 'whitespace or 'inside-margin glyphs.
9529 This is a specifier; use `set-specifier' to change it.
9531 Vuse_left_overflow = Fmake_specifier (Qboolean);
9532 set_specifier_fallback (Vuse_left_overflow, list1 (Fcons (Qnil, Qnil)));
9533 set_specifier_caching (Vuse_left_overflow,
9534 offsetof (struct window, use_left_overflow),
9535 some_window_value_changed,
9538 DEFVAR_SPECIFIER ("use-right-overflow", &Vuse_right_overflow /*
9539 *Non-nil means use the right outside margin as extra whitespace when
9540 displaying 'whitespace or 'inside-margin glyphs.
9541 This is a specifier; use `set-specifier' to change it.
9543 Vuse_right_overflow = Fmake_specifier (Qboolean);
9544 set_specifier_fallback (Vuse_right_overflow, list1 (Fcons (Qnil, Qnil)));
9545 set_specifier_caching (Vuse_right_overflow,
9546 offsetof (struct window, use_right_overflow),
9547 some_window_value_changed,
9550 DEFVAR_SPECIFIER ("text-cursor-visible-p", &Vtext_cursor_visible_p /*
9551 *Non-nil means the text cursor is visible (this is usually the case).
9552 This is a specifier; use `set-specifier' to change it.
9554 Vtext_cursor_visible_p = Fmake_specifier (Qboolean);
9555 set_specifier_fallback (Vtext_cursor_visible_p, list1 (Fcons (Qnil, Qt)));
9556 set_specifier_caching (Vtext_cursor_visible_p,
9557 offsetof (struct window, text_cursor_visible_p),
9558 text_cursor_visible_p_changed,