1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1994, 1995, 1996 Board of Trustees, University of Illinois.
3 Copyright (C) 1995 Free Software Foundation, Inc.
4 Copyright (C) 1995, 1996 Ben Wing.
5 Copyright (C) 1995 Sun Microsystems, Inc.
6 Copyright (C) 1996 Chuck Thompson.
8 This file is part of XEmacs.
10 XEmacs is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
15 XEmacs is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with XEmacs; see the file COPYING. If not, write to
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
25 /* Synched up with: Not in FSF. */
27 /* Author: Chuck Thompson */
29 /* Fixed up by Ben Wing for Mule */
31 /* This file has been Mule-ized. */
33 /*****************************************************************************
34 The Golden Rules of Redisplay
36 First: It Is Better To Be Correct Than Fast
37 Second: Thou Shalt Not Run Elisp From Within Redisplay
38 Third: It Is Better To Be Fast Than Not To Be
39 ****************************************************************************/
58 #include "redisplay.h"
61 #include "line-number.h"
63 #include "file-coding.h"
69 #include "console-tty.h"
72 /* Note: We have to be careful throughout this code to properly handle
73 and differentiate between Bufbytes and Emchars.
75 Since strings are generally composed of Bufbytes, I've taken the tack
76 that any contiguous set of Bufbytes is called a "string", while
77 any contiguous set of Emchars is called an "array". */
79 /* Return value to indicate a failure by an add_*_rune routine to add
80 a rune, but no propagation information needs to be returned. */
81 #define ADD_FAILED (prop_block_dynarr *) 1
83 #define BEGIN_GLYPHS 0
86 #define RIGHT_GLYPHS 3
88 #define VERTICAL_CLIP(w, display) \
89 ((WINDOW_TTY_P (w) | (!display && scroll_on_clipped_lines)) \
93 /* The following structures are completely private to redisplay.c so
94 we put them here instead of in a header file, for modularity. */
96 /* NOTE: Bytinds not Bufpos's in this structure. */
98 typedef struct position_redisplay_data_type
100 /* This information is normally filled in by the create_*_block
101 routines and is used by the add_*_rune routines. */
103 /* if we are working with strings rather than buffers we need a
104 handle to the string */
107 struct display_block *db;
108 struct display_line *dl;
109 Emchar ch; /* Character that is to be added. This is
110 used to communicate this information to
111 add_emchar_rune(). */
112 Lisp_Object last_charset; /* The charset of the previous character.
113 Used to optimize some lookups -- we
114 only have to do some things when
115 the charset changes. */
116 face_index last_findex; /* The face index of the previous character.
117 Needed to ensure the validity of the
118 last_charset optimization. */
120 int last_char_width; /* The width of the previous character. */
121 int font_is_bogus; /* If true, it means we couldn't instantiate
122 the font for this charset, so we substitute
123 ~'s from the ASCII charset. */
128 int blank_width; /* Width of the blank that is to be added.
129 This is used to communicate this information
132 This is also used rather cheesily to
133 communicate the width of the eol-cursor-size
134 blank that exists at the end of the line.
135 add_emchar_rune() is called cheesily with
136 the non-printing char '\n', which is stuck
137 in the output routines with its width being
139 Bytind bi_cursor_bufpos;/* This stores the buffer position of the cursor. */
140 unsigned int cursor_type :3;
141 int cursor_x; /* rune block cursor is at */
142 int start_col; /* Number of character columns (each column has
143 a width of the default char width) that still
144 need to be skipped. This is used for horizontal
145 scrolling, where a certain number of columns
146 (those off the left side of the screen) need
147 to be skipped before anything is displayed. */
148 Bytind bi_start_col_enabled;
149 int start_col_xoffset; /* Number of pixels that still need to
150 be skipped. This is used for
151 horizontal scrolling of glyphs, where we want
152 to be able to scroll over part of the glyph. */
154 int hscroll_glyph_width_adjust; /* how much the width of the hscroll
155 glyph differs from space_width (w).
156 0 if no hscroll glyph was used,
157 i.e. the window is not scrolled
158 horizontally. Used in tab
161 /* Information about the face the text should be displayed in and
162 any begin-glyphs and end-glyphs. */
163 struct extent_fragment *ef;
166 /* The height of a pixmap may either be predetermined if the user
167 has set a baseline value, or it may be dependent on whatever the
168 line ascent and descent values end up being, based just on font
169 information. In the first case we can immediately update the
170 values, thus their inclusion here. In the last case we cannot
171 determine the actual contribution to the line height until we
172 have finished laying out all text on the line. Thus we propagate
173 the max height of such pixmaps and do a final calculation after
174 all text has been added to the line. */
177 int max_pixmap_height;
179 Lisp_Object result_str; /* String where we put the result of
180 generating a formatted string in the modeline. */
181 int is_modeline; /* Non-zero if we're generating the modeline. */
182 Charcount modeline_charpos; /* Number of chars used in result_str so far;
183 corresponds to bytepos. */
184 Bytecount bytepos; /* Number of bytes used in result_str so far.
185 We don't actually copy the bytes into result_str
186 until the end because we don't know how big the
187 string is going to be until then. */
198 /* Data that should be propagated to the next line. Either a single
199 Emchar or a string of Bufbyte's.
201 The actual data that is propagated ends up as a Dynarr of these
204 #### It's unclean that both Emchars and Bufbytes are here.
207 typedef struct prop_block prop_block;
217 Bytecount len; /* length of the string. */
223 Bytind bi_cursor_bufpos; /* NOTE: is in Bytinds */
224 unsigned int cursor_type :3;
237 Dynarr_declare (prop_block);
241 static Charcount generate_fstring_runes (struct window *w, pos_data *data,
242 Charcount pos, Charcount min_pos,
243 Charcount max_pos, Lisp_Object elt,
244 int depth, int max_pixsize,
245 face_index findex, int type,
247 Lisp_Object cur_ext);
248 static prop_block_dynarr *add_glyph_rune (pos_data *data,
249 struct glyph_block *gb,
250 int pos_type, int allow_cursor,
251 struct glyph_cachel *cachel);
252 static Bytind create_text_block (struct window *w, struct display_line *dl,
253 Bytind bi_start_pos, prop_block_dynarr **prop,
255 static int create_overlay_glyph_block (struct window *w,
256 struct display_line *dl);
257 static void create_left_glyph_block (struct window *w,
258 struct display_line *dl,
260 static void create_right_glyph_block (struct window *w,
261 struct display_line *dl);
262 static void redisplay_windows (Lisp_Object window, int skip_selected);
263 static void decode_mode_spec (struct window *w, Emchar spec, int type);
264 static void free_display_line (struct display_line *dl);
265 static void update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
266 Bufpos point, int no_regen);
267 static int point_visible (struct window *w, Bufpos point, int type);
269 /* This used to be 10 but 30 seems to give much better performance. */
270 #define INIT_MAX_PREEMPTS 30
271 static int max_preempts;
273 #define REDISPLAY_PREEMPTION_CHECK \
276 (!disable_preemption && \
277 ((preemption_count < max_preempts) || !NILP (Vexecuting_macro)) && \
278 (!INTERACTIVE || detect_input_pending ()))))
281 * Redisplay global variables.
284 /* We need a third set of display structures for the cursor motion
285 routines. We used to just give each window a third set. However,
286 we always fully regenerate the structures when needed so there
287 isn't any reason we need more than a single set. */
288 display_line_dynarr *cmotion_display_lines;
290 /* We store the extents that we need to generate in a Dynarr and then
291 frob them all on at the end of generating the string. We do it
292 this way rather than adding them as we generate the string because
293 we don't store the text into the resulting string until we're done
294 (to avoid having to resize the string multiple times), and we don't
295 want to go around adding extents to a string when the extents might
296 stretch off the end of the string. */
297 static EXTENT_dynarr *formatted_string_extent_dynarr;
298 static Bytecount_dynarr *formatted_string_extent_start_dynarr;
299 static Bytecount_dynarr *formatted_string_extent_end_dynarr;
302 /* #### probably temporary */
303 int cache_adjustment;
305 /* This holds a string representing the text corresponding to a single
307 static Bufbyte_dynarr *mode_spec_bufbyte_string;
309 int in_display; /* 1 if in redisplay. */
311 int disable_preemption; /* Used for debugging redisplay and for
314 /* We only allow max_preempts preemptions before we force a redisplay. */
315 static int preemption_count;
317 /* Minimum pixel height of clipped bottom display line. */
320 /* Minimum visible pixel width of clipped glyphs at right margin. */
323 /* Nonzero means reading single-character input with prompt
324 so put cursor on minibuffer after the prompt. */
325 int cursor_in_echo_area;
326 Lisp_Object Qcursor_in_echo_area;
328 /* Nonzero means truncate lines in all windows less wide than the frame */
329 int truncate_partial_width_windows;
331 /* non-nil if a buffer has changed since the last time redisplay completed */
333 int buffers_changed_set;
335 /* non-nil if hscroll has changed somewhere or a buffer has been
336 narrowed or widened */
338 int clip_changed_set;
340 /* non-nil if any extent has changed since the last time redisplay completed */
342 int extents_changed_set;
344 /* non-nil if any face has changed since the last time redisplay completed */
347 /* Nonzero means some frames have been marked as garbaged */
350 /* non-zero if any of the builtin display glyphs (continuation,
351 hscroll, control-arrow, etc) is in need of updating
354 int glyphs_changed_set;
356 /* non-zero if any subwindow has been deleted. */
357 int subwindows_changed;
358 int subwindows_changed_set;
360 /* non-zero if any displayed subwindow is in need of updating
362 int subwindows_state_changed;
363 int subwindows_state_changed_set;
365 /* This variable is 1 if the icon has to be updated.
366 It is set to 1 when `frame-icon-glyph' changes. */
368 int icon_changed_set;
370 /* This variable is 1 if the menubar widget has to be updated.
371 It is set to 1 by set-menubar-dirty-flag and cleared when the widget
374 int menubar_changed_set;
376 /* true iff we should redraw the modelines on the next redisplay */
377 int modeline_changed;
378 int modeline_changed_set;
380 /* non-nil if point has changed in some buffer since the last time
381 redisplay completed */
383 int point_changed_set;
385 /* non-nil if some frame has changed its size */
388 /* non-nil if some device has signaled that it wants to change size */
389 int asynch_device_change_pending;
391 /* non-nil if any toolbar has changed */
393 int toolbar_changed_set;
395 /* non-nil if any gutter has changed */
397 int gutter_changed_set;
399 /* non-nil if any window has changed since the last time redisplay completed */
402 /* non-nil if any frame's window structure has changed since the last
403 time redisplay completed */
404 int windows_structure_changed;
406 /* If non-nil, use vertical bar cursor. */
407 Lisp_Object Vbar_cursor;
408 Lisp_Object Qbar_cursor;
410 Lisp_Object Vvisible_bell; /* If true and the terminal will support it
411 then the frame will flash instead of
412 beeping when an error occurs */
414 /* Nonzero means no need to redraw the entire frame on resuming
415 a suspended Emacs. This is useful on terminals with multiple pages,
416 where one page is used for Emacs and another for all else. */
417 int no_redraw_on_reenter;
419 Lisp_Object Vwindow_system; /* nil or a symbol naming the window system
420 under which emacs is running
421 ('x is the only current possibility) */
422 Lisp_Object Vinitial_window_system;
424 Lisp_Object Vglobal_mode_string;
426 /* The number of lines scroll a window by when point leaves the window; if
427 it is <=0 then point is centered in the window */
430 /* Scroll up to this many lines, to bring point back on screen. */
431 int scroll_conservatively;
433 /* Marker for where to display an arrow on top of the buffer text. */
434 Lisp_Object Voverlay_arrow_position;
435 /* String to display for the arrow. */
436 Lisp_Object Voverlay_arrow_string;
438 Lisp_Object Vwindow_size_change_functions;
439 Lisp_Object Vwindow_scroll_functions;
440 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
442 Lisp_Object Qbuffer_list_changed_hook, Vbuffer_list_changed_hook;
445 #define INHIBIT_REDISPLAY_HOOKS /* #### Until we've thought about
447 #ifndef INHIBIT_REDISPLAY_HOOKS
448 /* #### Chuck says: I think this needs more thought.
449 Think about this for 19.14. */
450 Lisp_Object Vpre_redisplay_hook, Vpost_redisplay_hook;
451 Lisp_Object Qpre_redisplay_hook, Qpost_redisplay_hook;
452 #endif /* INHIBIT_REDISPLAY_HOOKS */
454 static int last_display_warning_tick, display_warning_tick;
455 Lisp_Object Qdisplay_warning_buffer;
456 int inhibit_warning_display;
458 Lisp_Object Vleft_margin_width, Vright_margin_width;
459 Lisp_Object Vminimum_line_ascent, Vminimum_line_descent;
460 Lisp_Object Vuse_left_overflow, Vuse_right_overflow;
461 Lisp_Object Vtext_cursor_visible_p;
463 int column_number_start_at_one;
465 Lisp_Object Qtop_bottom;
467 #define WINDOW_SCROLLED(w) ((w)->hscroll > 0 || (w)->left_xoffset)
470 /***************************************************************************/
472 /* low-level interfaces onto device routines */
474 /***************************************************************************/
477 redisplay_text_width_charc_string (struct window *w, int findex,
478 Charc *str, Charcount len)
480 Charset_ID charsets[NUM_LEADING_BYTES];
483 find_charsets_in_charc_string (charsets, str, len);
484 XSETWINDOW (window, w);
485 ensure_face_cachel_complete (WINDOW_FACE_CACHEL (w, findex), window,
487 return DEVMETH (XDEVICE (FRAME_DEVICE (XFRAME (WINDOW_FRAME (w)))),
488 text_width, (XFRAME (WINDOW_FRAME (w)),
489 WINDOW_FACE_CACHEL (w, findex), str, len));
492 static Charc_dynarr *rtw_charc_dynarr;
495 redisplay_text_width_string (struct window *w, int findex,
496 Bufbyte *nonreloc, Lisp_Object reloc,
497 Bytecount offset, Bytecount len)
499 if (!rtw_charc_dynarr)
500 rtw_charc_dynarr = Dynarr_new (Charc);
501 Dynarr_reset (rtw_charc_dynarr);
503 fixup_internal_substring (nonreloc, reloc, offset, &len);
505 nonreloc = XSTRING_DATA (reloc);
506 convert_bufbyte_string_into_charc_dynarr (nonreloc, len, rtw_charc_dynarr);
507 return redisplay_text_width_charc_string
508 (w, findex, Dynarr_atp (rtw_charc_dynarr, 0),
509 Dynarr_length (rtw_charc_dynarr));
513 redisplay_frame_text_width_string (struct frame *f, Lisp_Object face,
514 Bufbyte *nonreloc, Lisp_Object reloc,
515 Bytecount offset, Bytecount len)
517 Charset_ID charsets[NUM_LEADING_BYTES];
519 struct face_cachel cachel;
521 if (!rtw_charc_dynarr)
522 rtw_charc_dynarr = Dynarr_new (Charc);
523 Dynarr_reset (rtw_charc_dynarr);
525 fixup_internal_substring (nonreloc, reloc, offset, &len);
527 nonreloc = XSTRING_DATA (reloc);
528 convert_bufbyte_string_into_charc_dynarr (nonreloc, len, rtw_charc_dynarr);
529 find_charsets_in_bufbyte_string (charsets, nonreloc, len);
530 reset_face_cachel (&cachel);
532 XSETFRAME (frame, f);
533 ensure_face_cachel_complete (&cachel, frame, charsets);
534 return DEVMETH (XDEVICE (FRAME_DEVICE (f)),
535 text_width, (f, &cachel, Dynarr_atp (rtw_charc_dynarr, 0),
536 Dynarr_length (rtw_charc_dynarr)));
539 /* Return the display block from DL of the given TYPE. A display line
540 can have only one display block of each possible type. If DL does
541 not have a block of type TYPE, one will be created and added to DL. */
543 struct display_block *
544 get_display_block_from_line (struct display_line *dl, enum display_type type)
547 struct display_block db;
549 /* Check if this display line already has a block of the desired type and
551 if (dl->display_blocks)
553 for (elt = 0; elt < Dynarr_length (dl->display_blocks); elt++)
555 if (Dynarr_at (dl->display_blocks, elt).type == type)
556 return Dynarr_atp (dl->display_blocks, elt);
559 /* There isn't an active block of the desired type, but there
560 might still be allocated blocks we need to reuse. */
561 if (elt < Dynarr_largest (dl->display_blocks))
563 struct display_block *dbp = Dynarr_atp (dl->display_blocks, elt);
565 /* 'add' the block to the list */
566 Dynarr_increment (dl->display_blocks);
568 /* initialize and return */
575 /* This line doesn't have any display blocks, so initialize the display
577 dl->display_blocks = Dynarr_new (display_block);
580 /* The line doesn't have a block of the desired type so go ahead and create
581 one and add it to the line. */
584 db.runes = Dynarr_new (rune);
585 Dynarr_add (dl->display_blocks, db);
587 /* Return the newly added display block. */
588 elt = Dynarr_length (dl->display_blocks) - 1;
590 return Dynarr_atp (dl->display_blocks, elt);
594 tab_char_width (struct window *w)
596 struct buffer *b = XBUFFER (w->buffer);
597 int char_tab_width = XINT (b->tab_width);
599 if (char_tab_width <= 0 || char_tab_width > 1000) char_tab_width = 8;
601 return char_tab_width;
605 space_width (struct window *w)
607 /* While tabs are traditional composed of spaces, for variable-width
608 fonts the space character tends to give too narrow a value. So
609 we use 'n' instead. Except that we don't. We use the default
610 character width for the default face. If this is actually
611 defined by the font then it is probably the best thing to
612 actually use. If it isn't, we have assumed it is 'n' and have
613 already calculated its width. Thus we can avoid a call to
614 XTextWidth on X frames by just querying the default width. */
615 return XFONT_INSTANCE
616 (WINDOW_FACE_CACHEL_FONT (w, DEFAULT_INDEX, Vcharset_ascii))->width;
620 tab_pix_width (struct window *w)
622 return space_width (w) * tab_char_width (w);
625 /* Given a pixel position in a window, return the pixel location of
626 the next tabstop. Tabs are calculated from the left window edge in
627 terms of spaces displayed in the default face. Formerly the space
628 width was determined using the currently active face. That method
629 leads to tabstops which do not line up. */
632 next_tab_position (struct window *w, int start_pixpos, int left_pixpos)
634 int n_pos = left_pixpos;
635 int pix_tab_width = tab_pix_width (w);
637 /* Adjust n_pos for any hscrolling which has happened. */
638 if (WINDOW_SCROLLED (w))
639 n_pos -= space_width (w) * (w->hscroll - 1) + w->left_xoffset;
641 while (n_pos <= start_pixpos)
642 n_pos += pix_tab_width;
647 /* For the given window, calculate the outside and margin boundaries for a
648 display line. The whitespace boundaries must be calculated by the text
652 calculate_display_line_boundaries (struct window *w, int modeline)
654 layout_bounds bounds;
656 /* Set the outermost boundaries which are the boundaries of the
657 window itself minus the gutters (and minus the scrollbars if this
658 is for the modeline). */
661 bounds.left_out = WINDOW_TEXT_LEFT (w);
662 bounds.right_out = WINDOW_TEXT_RIGHT (w);
666 bounds.left_out = WINDOW_MODELINE_LEFT (w);
667 bounds.right_out = WINDOW_MODELINE_RIGHT (w);
670 /* The inner boundaries mark where the glyph margins are located. */
671 bounds.left_in = bounds.left_out + window_left_margin_width (w);
672 bounds.right_in = bounds.right_out - window_right_margin_width (w);
674 /* We cannot fully calculate the whitespace boundaries as they
675 depend on the contents of the line being displayed. */
676 bounds.left_white = bounds.left_in;
677 bounds.right_white = bounds.right_in;
682 /* Given a display line and a starting position, ensure that the
683 contents of the display line accurately represent the visual
684 representation of the buffer contents starting from the given
685 position when displayed in the given window. The display line ends
686 when the contents of the line reach the right boundary of the given
690 generate_display_line (struct window *w, struct display_line *dl, int bounds,
691 Bufpos start_pos, prop_block_dynarr **prop,
696 struct buffer *b = XBUFFER (WINDOW_BUFFER (w));
698 /* If our caller hasn't already set the boundaries, then do so now. */
700 dl->bounds = calculate_display_line_boundaries (w, 0);
702 /* Reset what this line is using. */
703 if (dl->display_blocks)
704 Dynarr_reset (dl->display_blocks);
707 Dynarr_free (dl->left_glyphs);
710 if (dl->right_glyphs)
712 Dynarr_free (dl->right_glyphs);
713 dl->right_glyphs = 0;
716 /* We aren't generating a modeline at the moment. */
719 /* Create a display block for the text region of the line. */
721 /* #### urk urk urk!!! Chuck fix this shit! */
722 Bytind hacked_up_bytind =
723 create_text_block (w, dl, bufpos_to_bytind (b, start_pos),
725 if (hacked_up_bytind > BI_BUF_ZV (b))
726 ret_bufpos = BUF_ZV (b) + 1;
728 ret_bufpos = bytind_to_bufpos (b, hacked_up_bytind);
730 dl->bufpos = start_pos;
731 if (dl->end_bufpos < dl->bufpos)
732 dl->end_bufpos = dl->bufpos;
734 if (MARKERP (Voverlay_arrow_position)
735 && EQ (w->buffer, Fmarker_buffer (Voverlay_arrow_position))
736 && start_pos == marker_position (Voverlay_arrow_position)
737 && (STRINGP (Voverlay_arrow_string)
738 || GLYPHP (Voverlay_arrow_string)))
740 overlay_width = create_overlay_glyph_block (w, dl);
745 /* If there are left glyphs associated with any character in the
746 text block, then create a display block to handle them. */
747 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
748 create_left_glyph_block (w, dl, overlay_width);
750 /* If there are right glyphs associated with any character in the
751 text block, then create a display block to handle them. */
752 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
753 create_right_glyph_block (w, dl);
755 /* In the future additional types of display blocks may be generated
758 w->last_redisplay_pos = ret_bufpos;
763 /* Adds an hscroll glyph to a display block. If this is called, then
764 the block had better be empty.
766 Yes, there are multiple places where this function is called but
767 that is the way it has to be. Each calling function has to deal
768 with bi_start_col_enabled a little differently depending on the
769 object being worked with. */
771 static prop_block_dynarr *
772 add_hscroll_rune (pos_data *data)
774 struct glyph_block gb;
775 prop_block_dynarr *retval;
776 Bytind bi_old_cursor_bufpos = data->bi_cursor_bufpos;
777 unsigned int old_cursor_type = data->cursor_type;
778 Bytind bi_old_bufpos = data->bi_bufpos;
780 if (data->cursor_type == CURSOR_ON
781 && data->bi_cursor_bufpos >= data->bi_start_col_enabled
782 && data->bi_cursor_bufpos <= data->bi_bufpos)
784 data->bi_cursor_bufpos = data->bi_start_col_enabled;
788 data->cursor_type = NO_CURSOR;
791 data->bi_endpos = data->bi_bufpos;
792 data->bi_bufpos = data->bi_start_col_enabled;
795 gb.glyph = Vhscroll_glyph;
797 int oldpixpos = data->pixpos;
798 retval = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0,
799 GLYPH_CACHEL (XWINDOW (data->window),
800 HSCROLL_GLYPH_INDEX));
801 data->hscroll_glyph_width_adjust =
802 data->pixpos - oldpixpos - space_width (XWINDOW (data->window));
805 data->bi_cursor_bufpos = bi_old_cursor_bufpos;
806 data->cursor_type = old_cursor_type;
807 data->bi_bufpos = bi_old_bufpos;
809 data->bi_start_col_enabled = 0;
813 /* Adds a character rune to a display block. If there is not enough
814 room to fit the rune on the display block (as determined by the
815 MAX_PIXPOS) then it adds nothing and returns ADD_FAILED. */
817 static prop_block_dynarr *
818 add_emchar_rune (pos_data *data)
820 struct rune rb, *crb;
832 if (data->bi_start_col_enabled)
834 return add_hscroll_rune (data);
837 if (data->ch == '\n')
839 char_glyph = ASCII_TO_CHARC ('\n');
840 data->font_is_bogus = 0;
841 /* Cheesy end-of-line pseudo-character. */
842 width = data->blank_width;
848 char_glyph = CHAR_TO_CHARC (data->ch);
849 charset = CHARC_CHARSET (char_glyph);
850 if (!EQ (charset, data->last_charset) ||
851 data->findex != data->last_findex)
853 /* OK, we need to do things the hard way. */
854 struct window *w = XWINDOW (data->window);
855 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, data->findex);
856 Lisp_Object font_instance =
857 ensure_face_cachel_contains_charset (cachel, data->window,
859 Lisp_Font_Instance *fi;
861 if (EQ (font_instance, Vthe_null_font_instance))
863 font_instance = FACE_CACHEL_FONT (cachel, Vcharset_ascii);
864 data->font_is_bogus = 1;
867 data->font_is_bogus = 0;
869 fi = XFONT_INSTANCE (font_instance);
870 if (!fi->proportional_p)
871 /* sweetness and light. */
872 data->last_char_width = fi->width;
874 data->last_char_width = -1;
875 data->new_ascent = max (data->new_ascent, (int) fi->ascent);
876 data->new_descent = max (data->new_descent, (int) fi->descent);
877 data->last_charset = charset;
878 data->last_findex = data->findex;
881 width = data->last_char_width;
884 /* bummer. Proportional fonts. */
885 width = redisplay_text_width_charc_string (XWINDOW (data->window),
891 if (data->max_pixpos != -1 && (data->pixpos + width > data->max_pixpos))
896 if (Dynarr_length (data->db->runes) < Dynarr_largest (data->db->runes))
898 crb = Dynarr_atp (data->db->runes, Dynarr_length (data->db->runes));
907 crb->findex = data->findex;
908 crb->xpos = data->pixpos;
912 if (NILP (data->string))
914 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
918 bytecount_to_charcount (XSTRING_DATA (data->string),
921 else if (data->is_modeline)
922 crb->bufpos = data->modeline_charpos;
924 /* Text but not in buffer */
926 crb->type = RUNE_CHAR;
927 crb->object.cglyph = data->font_is_bogus
928 ? ASCII_TO_CHARC ('~')
932 if (data->cursor_type == CURSOR_ON)
934 if (data->bi_bufpos == data->bi_cursor_bufpos)
936 crb->cursor_type = CURSOR_ON;
937 data->cursor_x = Dynarr_length (data->db->runes);
940 crb->cursor_type = CURSOR_OFF;
942 else if (data->cursor_type == NEXT_CURSOR)
944 crb->cursor_type = CURSOR_ON;
945 data->cursor_x = Dynarr_length (data->db->runes);
946 data->cursor_type = NO_CURSOR;
948 else if (data->cursor_type == IGNORE_CURSOR)
949 crb->cursor_type = IGNORE_CURSOR;
951 crb->cursor_type = CURSOR_OFF;
954 Dynarr_add (data->db->runes, *crb);
956 Dynarr_increment (data->db->runes);
958 data->pixpos += width;
963 /* Given a string C_STRING of length C_LENGTH, call add_emchar_rune
964 for each character in the string. Propagate any left-over data
965 unless NO_PROP is non-zero. */
967 static prop_block_dynarr *
968 add_bufbyte_string_runes (pos_data *data, Bufbyte *c_string,
969 Bytecount c_length, int no_prop)
971 Bufbyte *pos, *end = c_string + c_length;
972 prop_block_dynarr *prop;
974 /* #### This function is too simplistic. It needs to do the same
975 sort of character interpretation (display-table lookup,
976 ctl-arrow checking), etc. that create_text_block() does.
977 The functionality to do this in that routine needs to be
980 for (pos = c_string; pos < end;)
982 data->ch = charptr_emchar (pos);
984 prop = add_emchar_rune (data);
992 struct prop_block pb;
993 Bytecount len = end - pos;
994 prop = Dynarr_new (prop_block);
996 pb.type = PROP_STRING;
997 pb.data.p_string.str = xnew_array (Bufbyte, len);
998 strncpy ((char *) pb.data.p_string.str, (char *) pos, len);
999 pb.data.p_string.len = len;
1001 Dynarr_add (prop, pb);
1006 assert (pos <= end);
1012 /* Add a single rune of the specified width. The area covered by this
1013 rune will be displayed in the foreground color of the associated
1016 static prop_block_dynarr *
1017 add_blank_rune (pos_data *data, struct window *w, int char_tab_width)
1021 /* If data->start_col is not 0 then this call to add_blank_rune must have
1022 been to add it as a tab. */
1023 if (data->start_col)
1025 /* assert (w != NULL) */
1026 prop_block_dynarr *retval;
1028 /* If we have still not fully scrolled horizontally, subtract
1029 the width of this tab and return. */
1030 if (char_tab_width < data->start_col)
1032 data->start_col -= char_tab_width;
1035 else if (char_tab_width == data->start_col)
1036 data->blank_width = 0;
1039 int spcwid = space_width (w);
1041 if (spcwid >= data->blank_width)
1042 data->blank_width = 0;
1044 data->blank_width -= spcwid;
1047 data->start_col = 0;
1048 retval = add_hscroll_rune (data);
1050 /* Could be caused by the handling of the hscroll rune. */
1051 if (retval != NULL || !data->blank_width)
1055 /* Blank runes are always calculated to fit. */
1056 assert (data->pixpos + data->blank_width <= data->max_pixpos);
1058 rb.findex = data->findex;
1059 rb.xpos = data->pixpos;
1060 rb.width = data->blank_width;
1061 if (data->bi_bufpos)
1063 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
1066 /* #### and this is really correct too? */
1069 rb.type = RUNE_BLANK;
1071 if (data->cursor_type == CURSOR_ON)
1073 if (data->bi_bufpos == data->bi_cursor_bufpos)
1075 rb.cursor_type = CURSOR_ON;
1076 data->cursor_x = Dynarr_length (data->db->runes);
1079 rb.cursor_type = CURSOR_OFF;
1081 else if (data->cursor_type == NEXT_CURSOR)
1083 rb.cursor_type = CURSOR_ON;
1084 data->cursor_x = Dynarr_length (data->db->runes);
1085 data->cursor_type = NO_CURSOR;
1088 rb.cursor_type = CURSOR_OFF;
1090 Dynarr_add (data->db->runes, rb);
1091 data->pixpos += data->blank_width;
1096 /* Add runes representing a character in octal. */
1098 #define ADD_NEXT_OCTAL_RUNE_CHAR do \
1100 if (add_failed || (add_failed = add_emchar_rune (data))) \
1102 struct prop_block pb; \
1104 prop = Dynarr_new (prop_block); \
1106 pb.type = PROP_CHAR; \
1107 pb.data.p_char.ch = data->ch; \
1108 pb.data.p_char.cursor_type = data->cursor_type; \
1109 Dynarr_add (prop, pb); \
1113 static prop_block_dynarr *
1114 add_octal_runes (pos_data *data)
1116 prop_block_dynarr *prop, *add_failed;
1117 Emchar orig_char = data->ch;
1118 unsigned int orig_cursor_type = data->cursor_type;
1124 if (data->start_col)
1127 if (!data->start_col)
1129 if (data->bi_start_col_enabled)
1131 add_failed = add_hscroll_rune (data);
1135 struct glyph_block gb;
1136 struct window *w = XWINDOW (data->window);
1139 gb.glyph = Voctal_escape_glyph;
1141 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1142 GLYPH_CACHEL (w, OCT_ESC_GLYPH_INDEX));
1146 /* We only propagate information if the glyph was partially
1151 data->cursor_type = IGNORE_CURSOR;
1153 if (data->ch >= 0x100)
1155 /* If the character is an extended Mule character, it could have
1156 up to 19 bits. For the moment, we treat it as a seven-digit
1157 octal number. This is not that pretty, but whatever. */
1158 data->ch = (7 & (orig_char >> 18)) + '0';
1159 ADD_NEXT_OCTAL_RUNE_CHAR;
1161 data->ch = (7 & (orig_char >> 15)) + '0';
1162 ADD_NEXT_OCTAL_RUNE_CHAR;
1164 data->ch = (7 & (orig_char >> 12)) + '0';
1165 ADD_NEXT_OCTAL_RUNE_CHAR;
1167 data->ch = (7 & (orig_char >> 9)) + '0';
1168 ADD_NEXT_OCTAL_RUNE_CHAR;
1171 data->ch = (7 & (orig_char >> 6)) + '0';
1172 ADD_NEXT_OCTAL_RUNE_CHAR;
1174 data->ch = (7 & (orig_char >> 3)) + '0';
1175 ADD_NEXT_OCTAL_RUNE_CHAR;
1177 data->ch = (7 & orig_char) + '0';
1178 ADD_NEXT_OCTAL_RUNE_CHAR;
1180 data->cursor_type = orig_cursor_type;
1184 #undef ADD_NEXT_OCTAL_RUNE_CHAR
1186 /* Add runes representing a control character to a display block. */
1188 static prop_block_dynarr *
1189 add_control_char_runes (pos_data *data, struct buffer *b)
1191 if (!NILP (b->ctl_arrow))
1193 prop_block_dynarr *prop;
1194 Emchar orig_char = data->ch;
1195 unsigned int old_cursor_type = data->cursor_type;
1200 if (data->start_col)
1203 if (!data->start_col)
1205 if (data->bi_start_col_enabled)
1207 prop_block_dynarr *retval;
1209 retval = add_hscroll_rune (data);
1215 struct glyph_block gb;
1216 struct window *w = XWINDOW (data->window);
1219 gb.glyph = Vcontrol_arrow_glyph;
1221 /* We only propagate information if the glyph was partially
1223 if (add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1224 GLYPH_CACHEL (w, CONTROL_GLYPH_INDEX)))
1229 if (orig_char == 0177)
1232 data->ch = orig_char ^ 0100;
1233 data->cursor_type = IGNORE_CURSOR;
1235 if (add_emchar_rune (data))
1237 struct prop_block pb;
1239 prop = Dynarr_new (prop_block);
1241 pb.type = PROP_CHAR;
1242 pb.data.p_char.ch = data->ch;
1243 pb.data.p_char.cursor_type = data->cursor_type;
1244 Dynarr_add (prop, pb);
1247 data->cursor_type = old_cursor_type;
1252 return add_octal_runes (data);
1256 static prop_block_dynarr *
1257 add_disp_table_entry_runes_1 (pos_data *data, Lisp_Object entry)
1259 prop_block_dynarr *prop = NULL;
1261 if (STRINGP (entry))
1263 prop = add_bufbyte_string_runes (data,
1264 XSTRING_DATA (entry),
1265 XSTRING_LENGTH (entry),
1268 else if (GLYPHP (entry))
1270 if (data->start_col)
1273 if (!data->start_col && data->bi_start_col_enabled)
1275 prop = add_hscroll_rune (data);
1279 struct glyph_block gb;
1283 prop = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
1286 else if (CHAR_OR_CHAR_INTP (entry))
1288 data->ch = XCHAR_OR_CHAR_INT (entry);
1289 prop = add_emchar_rune (data);
1291 else if (CONSP (entry))
1293 if (EQ (XCAR (entry), Qformat)
1294 && CONSP (XCDR (entry))
1295 && STRINGP (XCAR (XCDR (entry))))
1297 Lisp_Object format = XCAR (XCDR (entry));
1298 Bytind len = XSTRING_LENGTH (format);
1299 Bufbyte *src = XSTRING_DATA (format), *end = src + len;
1300 Bufbyte *result = alloca_array (Bufbyte, len);
1301 Bufbyte *dst = result;
1305 Emchar c = charptr_emchar (src);
1307 if (c != '%' || src == end)
1308 dst += set_charptr_emchar (dst, c);
1311 c = charptr_emchar (src);
1316 dst += long_to_string_base ((char *)dst, data->ch, 16);
1319 dst += set_charptr_emchar (dst, '%');
1321 /* #### unimplemented */
1325 prop = add_bufbyte_string_runes (data, result, dst - result, 0);
1329 /* Else blow it off because someone added a bad entry and we don't
1330 have any safe way of signaling an error. */
1334 /* Given a display table entry, call the appropriate functions to
1335 display each element of the entry. */
1337 static prop_block_dynarr *
1338 add_disp_table_entry_runes (pos_data *data, Lisp_Object entry)
1340 prop_block_dynarr *prop = NULL;
1341 if (VECTORP (entry))
1343 Lisp_Vector *de = XVECTOR (entry);
1344 EMACS_INT len = vector_length (de);
1347 for (elt = 0; elt < len; elt++)
1349 if (NILP (vector_data (de)[elt]))
1352 prop = add_disp_table_entry_runes_1 (data, vector_data (de)[elt]);
1353 /* Else blow it off because someone added a bad entry and we
1354 don't have any safe way of signaling an error. Hey, this
1355 comment sounds familiar. */
1357 /* #### Still need to add any remaining elements to the
1358 propagation information. */
1364 prop = add_disp_table_entry_runes_1 (data, entry);
1368 /* Add runes which were propagated from the previous line. */
1370 static prop_block_dynarr *
1371 add_propagation_runes (prop_block_dynarr **prop, pos_data *data)
1373 /* #### Remember to handle start_col parameter of data when the rest of
1374 this is finished. */
1375 /* #### Chuck -- I've redone this function a bit. It looked like the
1376 case of not all the propagation blocks being added was not handled
1378 /* #### Chuck -- I also think the double indirection of PROP is kind
1379 of bogus. A cleaner solution is just to check for
1380 Dynarr_length (prop) > 0. */
1381 /* #### This function also doesn't even pay attention to ADD_FAILED!
1382 This is seriously fucked! Seven ####'s in 130 lines -- is that a
1385 prop_block_dynarr *add_failed;
1386 Bytind bi_old_cursor_bufpos = data->bi_cursor_bufpos;
1387 unsigned int old_cursor_type = data->cursor_type;
1389 for (elt = 0; elt < Dynarr_length (*prop); elt++)
1391 struct prop_block *pb = Dynarr_atp (*prop, elt);
1396 data->ch = pb->data.p_char.ch;
1397 data->bi_cursor_bufpos = pb->data.p_char.bi_cursor_bufpos;
1398 data->cursor_type = pb->data.p_char.cursor_type;
1399 add_failed = add_emchar_rune (data);
1402 goto oops_no_more_space;
1405 if (pb->data.p_string.str)
1406 xfree (pb->data.p_string.str);
1407 /* #### bogus bogus -- this doesn't do anything!
1408 Should probably call add_bufbyte_string_runes(),
1409 once that function is fixed. */
1411 case PROP_MINIBUF_PROMPT:
1413 face_index old_findex = data->findex;
1414 Bytind bi_old_bufpos = data->bi_bufpos;
1416 data->findex = DEFAULT_INDEX;
1417 data->bi_bufpos = 0;
1418 data->cursor_type = NO_CURSOR;
1420 while (pb->data.p_string.len > 0)
1422 data->ch = charptr_emchar (pb->data.p_string.str);
1423 add_failed = add_emchar_rune (data);
1427 data->findex = old_findex;
1428 data->bi_bufpos = bi_old_bufpos;
1429 goto oops_no_more_space;
1433 /* Complicated equivalent of ptr++, len-- */
1434 Bufbyte *oldpos = pb->data.p_string.str;
1435 INC_CHARPTR (pb->data.p_string.str);
1436 pb->data.p_string.len -= pb->data.p_string.str - oldpos;
1440 data->findex = old_findex;
1441 /* ##### FIXME FIXME FIXME -- Upon successful return from
1442 this function, data->bi_bufpos is automatically incremented.
1443 However, we don't want that to happen if we were adding
1444 the minibuffer prompt. */
1446 struct buffer *buf =
1447 XBUFFER (WINDOW_BUFFER (XWINDOW (data->window)));
1448 /* #### Chuck fix this shit or I'm gonna scream! */
1449 if (bi_old_bufpos > BI_BUF_BEGV (buf))
1450 data->bi_bufpos = prev_bytind (buf, bi_old_bufpos);
1452 /* #### is this correct? Does anyone know?
1453 Does anyone care? Is this a cheesy hack or what? */
1454 data->bi_bufpos = BI_BUF_BEGV (buf) - 1;
1460 /* #### I think it's unnecessary and misleading to preserve
1461 the blank_width, as it implies that the value carries
1462 over from one rune to the next, which is wrong. */
1463 int old_width = data->blank_width;
1464 face_index old_findex = data->findex;
1466 data->findex = pb->data.p_blank.findex;
1467 data->blank_width = pb->data.p_blank.width;
1468 data->bi_cursor_bufpos = 0;
1469 data->cursor_type = IGNORE_CURSOR;
1471 if (data->pixpos + data->blank_width > data->max_pixpos)
1472 data->blank_width = data->max_pixpos - data->pixpos;
1474 /* We pass a bogus value of char_tab_width. It shouldn't
1475 matter because unless something is really screwed up
1476 this call won't cause that arg to be used. */
1477 add_failed = add_blank_rune (data, XWINDOW (data->window), 0);
1479 /* This can happen in the case where we have a tab which
1480 is wider than the window. */
1481 if (data->blank_width != pb->data.p_blank.width)
1483 pb->data.p_blank.width -= data->blank_width;
1484 add_failed = ADD_FAILED;
1487 data->findex = old_findex;
1488 data->blank_width = old_width;
1491 goto oops_no_more_space;
1501 data->bi_cursor_bufpos = bi_old_cursor_bufpos;
1502 data->cursor_type = old_cursor_type;
1503 if (elt < Dynarr_length (*prop))
1505 Dynarr_delete_many (*prop, 0, elt);
1510 Dynarr_free (*prop);
1515 /* Add 'text layout glyphs at position POS_TYPE that are contained to
1516 the display block, but add all other types to the appropriate list
1517 of the display line. They will be added later by different
1520 static prop_block_dynarr *
1521 add_glyph_rune (pos_data *data, struct glyph_block *gb, int pos_type,
1522 int allow_cursor, struct glyph_cachel *cachel)
1524 struct window *w = XWINDOW (data->window);
1526 /* If window faces changed, and glyph instance is text, then
1527 glyph sizes might have changed too */
1528 invalidate_glyph_geometry_maybe (gb->glyph, w);
1530 /* This makes sure the glyph is in the cachels.
1532 #### We do this to make sure the glyph is in the glyph cachels,
1533 so that the dirty flag can be reset after redisplay has
1534 finished. We should do this some other way, maybe by iterating
1535 over the window cache of subwindows. */
1536 get_glyph_cachel_index (w, gb->glyph);
1538 /* A nil extent indicates a special glyph (ex. truncator). */
1539 if (NILP (gb->extent)
1540 || (pos_type == BEGIN_GLYPHS &&
1541 extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1542 || (pos_type == END_GLYPHS &&
1543 extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1544 || pos_type == LEFT_GLYPHS || pos_type == RIGHT_GLYPHS)
1549 int ascent, descent;
1550 Lisp_Object baseline;
1552 Lisp_Object instance;
1556 width = cachel->width;
1558 width = glyph_width (gb->glyph, data->window);
1563 if (data->start_col || data->start_col_xoffset)
1565 prop_block_dynarr *retval;
1566 int glyph_char_width = width / space_width (w);
1568 /* If we still have not fully scrolled horizontally after
1569 taking into account the width of the glyph, subtract its
1570 width and return. */
1571 if (glyph_char_width < data->start_col)
1573 data->start_col -= glyph_char_width;
1576 else if (glyph_char_width == data->start_col)
1580 xoffset = space_width (w) * data->start_col;
1583 /* #### Can this happen? */
1588 data->start_col = 0;
1589 retval = add_hscroll_rune (data);
1591 /* Could be caused by the handling of the hscroll rune. */
1592 if (retval != NULL || !width)
1598 if (data->pixpos + width > data->max_pixpos)
1600 /* If this is the first object we are attempting to add to
1601 the line then we ignore the horizontal_clip threshold.
1602 Otherwise we will loop until the bottom of the window
1603 continually failing to add this glyph because it is wider
1604 than the window. We could alternatively just completely
1605 ignore the glyph and proceed from there but I think that
1606 this is a better solution. */
1607 if (Dynarr_length (data->db->runes)
1608 && data->max_pixpos - data->pixpos < horizontal_clip)
1611 width = data->max_pixpos - data->pixpos;
1616 ascent = cachel->ascent;
1617 descent = cachel->descent;
1621 ascent = glyph_ascent (gb->glyph, data->window);
1622 descent = glyph_descent (gb->glyph, data->window);
1625 baseline = glyph_baseline (gb->glyph, data->window);
1627 if (glyph_contrib_p (gb->glyph, data->window))
1629 /* A pixmap that has not had a baseline explicitly set. Its
1630 contribution will be determined later. */
1631 if (NILP (baseline))
1633 int height = ascent + descent;
1634 data->max_pixmap_height = max (data->max_pixmap_height, height);
1637 /* A string so determine contribution normally. */
1638 else if (EQ (baseline, Qt))
1640 data->new_ascent = max (data->new_ascent, ascent);
1641 data->new_descent = max (data->new_descent, descent);
1644 /* A pixmap with an explicitly set baseline. We determine the
1645 contribution here. */
1646 else if (INTP (baseline))
1648 int height = ascent + descent;
1649 int pix_ascent, pix_descent;
1651 pix_ascent = height * XINT (baseline) / 100;
1652 pix_descent = height - pix_ascent;
1654 data->new_ascent = max (data->new_ascent, pix_ascent);
1655 data->new_descent = max (data->new_descent, pix_descent);
1658 /* Otherwise something is screwed up. */
1663 face = glyph_face (gb->glyph, data->window);
1665 findex = data->findex;
1667 findex = get_builtin_face_cache_index (w, face);
1669 instance = glyph_image_instance (gb->glyph, data->window,
1671 if (TEXT_IMAGE_INSTANCEP (instance))
1673 Lisp_Object string = XIMAGE_INSTANCE_TEXT_STRING (instance);
1674 face_index orig_findex = data->findex;
1675 Bytind orig_bufpos = data->bi_bufpos;
1676 Bytind orig_start_col_enabled = data->bi_start_col_enabled;
1678 data->findex = findex;
1679 data->bi_start_col_enabled = 0;
1681 data->bi_bufpos = 0;
1682 add_bufbyte_string_runes (data, XSTRING_DATA (string),
1683 XSTRING_LENGTH (string), 0);
1684 data->findex = orig_findex;
1685 data->bi_bufpos = orig_bufpos;
1686 data->bi_start_col_enabled = orig_start_col_enabled;
1691 rb.xpos = data->pixpos;
1693 rb.bufpos = 0; /* glyphs are never "at" anywhere */
1694 if (data->bi_endpos)
1695 /* #### is this necessary at all? */
1696 rb.endpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1700 rb.type = RUNE_DGLYPH;
1701 rb.object.dglyph.glyph = gb->glyph;
1702 rb.object.dglyph.extent = gb->extent;
1703 rb.object.dglyph.xoffset = xoffset;
1707 rb.bufpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1710 if (data->cursor_type == CURSOR_ON)
1712 if (data->bi_bufpos == data->bi_cursor_bufpos)
1714 rb.cursor_type = CURSOR_ON;
1715 data->cursor_x = Dynarr_length (data->db->runes);
1718 rb.cursor_type = CURSOR_OFF;
1720 else if (data->cursor_type == NEXT_CURSOR)
1722 rb.cursor_type = CURSOR_ON;
1723 data->cursor_x = Dynarr_length (data->db->runes);
1724 data->cursor_type = NO_CURSOR;
1726 else if (data->cursor_type == IGNORE_CURSOR)
1727 rb.cursor_type = IGNORE_CURSOR;
1728 else if (data->cursor_type == NO_CURSOR)
1729 rb.cursor_type = NO_CURSOR;
1731 rb.cursor_type = CURSOR_OFF;
1734 rb.cursor_type = CURSOR_OFF;
1736 Dynarr_add (data->db->runes, rb);
1737 data->pixpos += width;
1743 if (!NILP (glyph_face (gb->glyph, data->window)))
1745 get_builtin_face_cache_index (w, glyph_face (gb->glyph,
1748 gb->findex = data->findex;
1750 if (pos_type == BEGIN_GLYPHS)
1752 if (!data->dl->left_glyphs)
1753 data->dl->left_glyphs = Dynarr_new (glyph_block);
1754 Dynarr_add (data->dl->left_glyphs, *gb);
1757 else if (pos_type == END_GLYPHS)
1759 if (!data->dl->right_glyphs)
1760 data->dl->right_glyphs = Dynarr_new (glyph_block);
1761 Dynarr_add (data->dl->right_glyphs, *gb);
1765 abort (); /* there are no unknown types */
1768 return NULL; /* shut up compiler */
1771 /* Add all glyphs at position POS_TYPE that are contained in the given
1774 static prop_block_dynarr *
1775 add_glyph_runes (pos_data *data, int pos_type)
1777 /* #### This still needs to handle the start_col parameter. Duh, Chuck,
1778 why didn't you just modify add_glyph_rune in the first place? */
1780 glyph_block_dynarr *glyph_arr = (pos_type == BEGIN_GLYPHS
1781 ? data->ef->begin_glyphs
1782 : data->ef->end_glyphs);
1783 prop_block_dynarr *prop;
1785 for (elt = 0; elt < Dynarr_length (glyph_arr); elt++)
1787 prop = add_glyph_rune (data, Dynarr_atp (glyph_arr, elt), pos_type, 0,
1792 /* #### Add some propagation information. */
1797 Dynarr_reset (glyph_arr);
1802 /* Given a position for a buffer in a window, ensure that the given
1803 display line DL accurately represents the text on a line starting
1804 at the given position.
1806 NOTE NOTE NOTE NOTE: This function works with and returns Bytinds.
1807 You must do appropriate conversion. */
1810 create_text_block (struct window *w, struct display_line *dl,
1811 Bytind bi_start_pos, prop_block_dynarr **prop,
1814 struct frame *f = XFRAME (w->frame);
1815 struct buffer *b = XBUFFER (w->buffer);
1816 struct device *d = XDEVICE (f->device);
1820 /* Don't display anything in the minibuffer if this window is not on
1821 a selected frame. We consider all other windows to be active
1822 minibuffers as it simplifies the coding. */
1823 int active_minibuffer = (!MINI_WINDOW_P (w) ||
1824 (f == device_selected_frame (d)) ||
1825 is_surrogate_for_selected_frame (f));
1827 int truncate_win = window_truncation_on (w);
1828 int end_glyph_width;
1830 /* If the buffer's value of selective_display is an integer then
1831 only lines that start with less than selective_display columns of
1832 space will be displayed. If selective_display is t then all text
1833 after a ^M is invisible. */
1834 int selective = (INTP (b->selective_display)
1835 ? XINT (b->selective_display)
1836 : (!NILP (b->selective_display) ? -1 : 0));
1838 /* The variable ctl-arrow allows the user to specify what characters
1839 can actually be displayed and which octal should be used for.
1840 #### This variable should probably have some rethought done to
1843 #### It would also be really nice if you could specify that
1844 the characters come out in hex instead of in octal. Mule
1845 does that by adding a ctl-hexa variable similar to ctl-arrow,
1846 but that's bogus -- we need a more general solution. I
1847 think you need to extend the concept of display tables
1848 into a more general conversion mechanism. Ideally you
1849 could specify a Lisp function that converts characters,
1850 but this violates the Second Golden Rule and besides would
1851 make things way way way way slow.
1853 So instead, we extend the display-table concept, which was
1854 historically limited to 256-byte vectors, to one of the
1857 a) A 256-entry vector, for backward compatibility;
1858 b) char-table, mapping characters to values;
1859 c) range-table, mapping ranges of characters to values;
1860 d) a list of the above.
1862 The (d) option allows you to specify multiple display tables
1863 instead of just one. Each display table can specify conversions
1864 for some characters and leave others unchanged. The way the
1865 character gets displayed is determined by the first display table
1866 with a binding for that character. This way, you could call a
1867 function `enable-hex-display' that adds a hex display-table to
1868 the list of display tables for the current buffer.
1870 #### ...not yet implemented... Also, we extend the concept of
1871 "mapping" to include a printf-like spec. Thus you can make all
1872 extended characters show up as hex with a display table like
1875 #s(range-table data ((256 524288) (format "%x")))
1877 Since more than one display table is possible, you have
1878 great flexibility in mapping ranges of characters. */
1879 Emchar printable_min = (CHAR_OR_CHAR_INTP (b->ctl_arrow)
1880 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
1881 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
1884 Lisp_Object face_dt, window_dt;
1886 /* The text display block for this display line. */
1887 struct display_block *db = get_display_block_from_line (dl, TEXT);
1889 /* The first time through the main loop we need to force the glyph
1890 data to be updated. */
1893 /* Apparently the new extent_fragment_update returns an end position
1894 equal to the position passed in if there are no more runs to be
1896 int no_more_frags = 0;
1898 Lisp_Object synch_minibuffers_value =
1899 symbol_value_in_buffer (Qsynchronize_minibuffers, w->buffer);
1901 dl->used_prop_data = 0;
1903 dl->line_continuation = 0;
1906 data.ef = extent_fragment_new (w->buffer, f);
1908 /* These values are used by all of the rune addition routines. We add
1909 them to this structure for ease of passing. */
1911 XSETWINDOW (data.window, w);
1916 data.bi_bufpos = bi_start_pos;
1917 data.pixpos = dl->bounds.left_in;
1918 data.last_charset = Qunbound;
1919 data.last_findex = DEFAULT_INDEX;
1920 data.result_str = Qnil;
1922 /* Set the right boundary adjusting it to take into account any end
1923 glyph. Save the width of the end glyph for later use. */
1924 data.max_pixpos = dl->bounds.right_in;
1926 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
1928 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
1929 data.max_pixpos -= end_glyph_width;
1931 if (cursor_in_echo_area && MINI_WINDOW_P (w) && echo_area_active (f))
1933 data.bi_cursor_bufpos = BI_BUF_ZV (b);
1934 data.cursor_type = CURSOR_ON;
1936 else if (MINI_WINDOW_P (w) && !active_minibuffer)
1937 data.cursor_type = NO_CURSOR;
1938 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)) &&
1939 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
1940 d == XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d))))&&
1941 f == XFRAME(DEVICE_SELECTED_FRAME(d)))
1943 data.bi_cursor_bufpos = BI_BUF_PT (b);
1944 data.cursor_type = CURSOR_ON;
1946 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)))
1948 data.bi_cursor_bufpos = bi_marker_position (w->pointm[type]);
1949 data.cursor_type = CURSOR_ON;
1952 data.cursor_type = NO_CURSOR;
1955 data.start_col = w->hscroll;
1956 data.start_col_xoffset = w->left_xoffset;
1957 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
1958 data.hscroll_glyph_width_adjust = 0;
1960 /* We regenerate the line from the very beginning. */
1961 Dynarr_reset (db->runes);
1963 /* Why is this less than or equal and not just less than? If the
1964 starting position is already equal to the maximum we can't add
1965 anything else, right? Wrong. We might still have a newline to
1966 add. A newline can use the room allocated for an end glyph since
1967 if we add it we know we aren't going to be adding any end
1970 /* #### Chuck -- I think this condition should be while (1).
1971 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
1972 and the begin-glyph ends exactly at the end of the window, the
1973 end-glyph and text might not be displayed. while (1) ensures
1974 that the loop terminates only when either (a) there is
1975 propagation data or (b) the end-of-line or end-of-buffer is hit.
1977 #### Also I think you need to ensure that the operation
1978 "add begin glyphs; add end glyphs; add text" is atomic and
1979 can't get interrupted in the middle. If you run off the end
1980 of the line during that operation, then you keep accumulating
1981 propagation data until you're done. Otherwise, if the (e.g.)
1982 there's a begin glyph at a particular position and attempting
1983 to display that glyph results in window-end being hit and
1984 propagation data being generated, then the character at that
1985 position won't be displayed.
1987 #### See also the comment after the end of this loop, below.
1989 while (data.pixpos <= data.max_pixpos
1990 && (active_minibuffer || !NILP (synch_minibuffers_value)))
1992 /* #### This check probably should not be necessary. */
1993 if (data.bi_bufpos > BI_BUF_ZV (b))
1995 /* #### urk! More of this lossage! */
2000 /* If selective display was an integer and we aren't working on
2001 a continuation line then find the next line we are actually
2002 supposed to display. */
2004 && (data.bi_bufpos == BI_BUF_BEGV (b)
2005 || BUF_FETCH_CHAR (b, prev_bytind (b, data.bi_bufpos)) == '\n'))
2007 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2010 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2011 if (data.bi_bufpos >= BI_BUF_ZV (b))
2013 data.bi_bufpos = BI_BUF_ZV (b);
2019 /* Check for face changes. */
2020 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
2022 /* Now compute the face and begin/end-glyph information. */
2024 /* Remember that the extent-fragment routines deal in Bytind's. */
2025 extent_fragment_update (w, data.ef, data.bi_bufpos);
2027 get_display_tables (w, data.findex, &face_dt, &window_dt);
2029 if (data.bi_bufpos == data.ef->end)
2034 /* Determine what is next to be displayed. We first handle any
2035 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
2036 display then we determine what to do based on the character at the
2037 current buffer position. */
2039 /* If the current position is covered by an invisible extent, do
2040 nothing (except maybe add some ellipses).
2042 #### The behavior of begin and end-glyphs at the edge of an
2043 invisible extent should be investigated further. This is
2044 fairly low priority though. */
2045 if (data.ef->invisible)
2047 /* #### Chuck, perhaps you could look at this code? I don't
2048 really know what I'm doing. */
2051 Dynarr_free (*prop);
2055 /* The extent fragment code only sets this when we should
2056 really display the ellipses. It makes sure the ellipses
2057 don't get displayed more than once in a row. */
2058 if (data.ef->invisible_ellipses)
2060 struct glyph_block gb;
2062 data.ef->invisible_ellipses_already_displayed = 1;
2063 data.ef->invisible_ellipses = 0;
2065 gb.glyph = Vinvisible_text_glyph;
2066 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2067 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2068 /* Perhaps they shouldn't propagate if the very next thing
2069 is to display a newline (for compatibility with
2070 selective-display-ellipses)? Maybe that's too
2076 /* If point is in an invisible region we place it on the
2077 next visible character. */
2078 if (data.cursor_type == CURSOR_ON
2079 && data.bi_bufpos == data.bi_cursor_bufpos)
2081 data.cursor_type = NEXT_CURSOR;
2084 /* #### What if we we're dealing with a display table? */
2088 if (data.bi_bufpos == BI_BUF_ZV (b))
2091 INC_BYTIND (b, data.bi_bufpos);
2094 /* If there is propagation data, then it represents the current
2095 buffer position being displayed. Add them and advance the
2096 position counter. This might also add the minibuffer
2100 dl->used_prop_data = 1;
2101 *prop = add_propagation_runes (prop, &data);
2104 goto done; /* gee, a really narrow window */
2105 else if (data.bi_bufpos == BI_BUF_ZV (b))
2107 else if (data.bi_bufpos < BI_BUF_BEGV (b))
2108 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
2109 data.bi_bufpos = BI_BUF_BEGV (b);
2111 INC_BYTIND (b, data.bi_bufpos);
2114 /* If there are end glyphs, add them to the line. These are
2115 the end glyphs for the previous run of text. We add them
2116 here rather than doing them at the end of handling the
2117 previous run so that glyphs at the beginning and end of
2118 a line are handled correctly. */
2119 else if (Dynarr_length (data.ef->end_glyphs) > 0)
2121 *prop = add_glyph_runes (&data, END_GLYPHS);
2126 /* If there are begin glyphs, add them to the line. */
2127 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
2129 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
2134 /* If at end-of-buffer, we've already processed begin and
2135 end-glyphs at this point and there's no text to process,
2137 else if (data.bi_bufpos == BI_BUF_ZV (b))
2142 Lisp_Object entry = Qnil;
2143 /* Get the character at the current buffer position. */
2144 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2145 if (!NILP (face_dt) || !NILP (window_dt))
2146 entry = display_table_entry (data.ch, face_dt, window_dt);
2148 /* If there is a display table entry for it, hand it off to
2149 add_disp_table_entry_runes and let it worry about it. */
2150 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
2152 *prop = add_disp_table_entry_runes (&data, entry);
2158 /* Check if we have hit a newline character. If so, add a marker
2159 to the line and end this loop. */
2160 else if (data.ch == '\n')
2162 /* We aren't going to be adding an end glyph so give its
2163 space back in order to make sure that the cursor can
2165 data.max_pixpos += end_glyph_width;
2168 && (bi_spaces_at_point
2169 (b, next_bytind (b, data.bi_bufpos))
2172 if (!NILP (b->selective_display_ellipses))
2174 struct glyph_block gb;
2177 gb.glyph = Vinvisible_text_glyph;
2178 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2179 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2183 /* Cheesy, cheesy, cheesy. We mark the end of the
2184 line with a special "character rune" whose width
2185 is the EOL cursor width and whose character is
2186 the non-printing character '\n'. */
2187 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2188 *prop = add_emchar_rune (&data);
2191 /* We need to set data.bi_bufpos to the start of the
2192 next visible region in order to make this line
2193 appear to contain all of the invisible area.
2194 Otherwise, the line cache won't work
2196 INC_BYTIND (b, data.bi_bufpos);
2197 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2200 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2201 if (data.bi_bufpos >= BI_BUF_ZV (b))
2203 data.bi_bufpos = BI_BUF_ZV (b);
2207 if (BI_BUF_FETCH_CHAR
2208 (b, prev_bytind (b, data.bi_bufpos)) == '\n')
2209 DEC_BYTIND (b, data.bi_bufpos);
2213 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2214 *prop = add_emchar_rune (&data);
2220 /* If the current character is ^M, and selective display is
2221 enabled, then add the invisible-text-glyph if
2222 selective-display-ellipses is set. In any case, this
2224 else if (data.ch == (('M' & 037)) && selective == -1)
2226 Bytind bi_next_bufpos;
2228 /* Find the buffer position at the end of the line. */
2230 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2231 if (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_next_bufpos))
2233 DEC_BYTIND (b, bi_next_bufpos);
2235 /* If the cursor is somewhere in the elided text make
2236 sure that the cursor gets drawn appropriately. */
2237 if (data.cursor_type == CURSOR_ON
2238 && (data.bi_cursor_bufpos >= data.bi_bufpos &&
2239 data.bi_cursor_bufpos < bi_next_bufpos))
2241 data.cursor_type = NEXT_CURSOR;
2244 /* We won't be adding a truncation or continuation glyph
2245 so give up the room allocated for them. */
2246 data.max_pixpos += end_glyph_width;
2248 if (!NILP (b->selective_display_ellipses))
2250 /* We don't propagate anything from the invisible
2251 text glyph if it fails to fit. This is
2253 struct glyph_block gb;
2256 gb.glyph = Vinvisible_text_glyph;
2257 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 1,
2258 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2261 /* Set the buffer position to the end of the line. We
2262 need to do this before potentially adding a newline
2263 so that the cursor flag will get set correctly (if
2265 data.bi_bufpos = bi_next_bufpos;
2267 if (NILP (b->selective_display_ellipses)
2268 || data.bi_cursor_bufpos == bi_next_bufpos)
2270 /* We have to at least add a newline character so
2271 that the cursor shows up properly. */
2273 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2274 data.findex = DEFAULT_INDEX;
2276 data.start_col_xoffset = 0;
2277 data.bi_start_col_enabled = 0;
2279 add_emchar_rune (&data);
2282 /* This had better be a newline but doing it this way
2283 we'll see obvious incorrect results if it isn't. No
2284 need to abort here. */
2285 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2290 /* If the current character is considered to be printable, then
2292 else if (data.ch >= printable_min)
2294 *prop = add_emchar_rune (&data);
2299 /* If the current character is a tab, determine the next tab
2300 starting position and add a blank rune which extends from the
2301 current pixel position to that starting position. */
2302 else if (data.ch == '\t')
2304 int tab_start_pixpos = data.pixpos;
2309 if (data.start_col > 1)
2310 tab_start_pixpos -= (space_width (w) * (data.start_col - 1))
2311 + data.start_col_xoffset;
2314 next_tab_position (w, tab_start_pixpos,
2315 dl->bounds.left_in +
2316 data.hscroll_glyph_width_adjust);
2317 if (next_tab_start > data.max_pixpos)
2319 prop_width = next_tab_start - data.max_pixpos;
2320 next_tab_start = data.max_pixpos;
2322 data.blank_width = next_tab_start - data.pixpos;
2324 (next_tab_start - tab_start_pixpos) / space_width (w);
2326 *prop = add_blank_rune (&data, w, char_tab_width);
2328 /* add_blank_rune is only supposed to be called with
2329 sizes guaranteed to fit in the available space. */
2334 struct prop_block pb;
2335 *prop = Dynarr_new (prop_block);
2337 pb.type = PROP_BLANK;
2338 pb.data.p_blank.width = prop_width;
2339 pb.data.p_blank.findex = data.findex;
2340 Dynarr_add (*prop, pb);
2346 /* If character is a control character, pass it off to
2347 add_control_char_runes.
2349 The is_*() routines have undefined results on
2350 arguments outside of the range [-1, 255]. (This
2351 often bites people who carelessly use `char' instead
2352 of `unsigned char'.)
2354 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
2356 *prop = add_control_char_runes (&data, b);
2362 /* If the character is above the ASCII range and we have not
2363 already handled it, then print it as an octal number. */
2364 else if (data.ch >= 0200)
2366 *prop = add_octal_runes (&data);
2372 /* Assume the current character is considered to be printable,
2373 then just add it. */
2376 *prop = add_emchar_rune (&data);
2381 INC_BYTIND (b, data.bi_bufpos);
2387 /* Determine the starting point of the next line if we did not hit the
2388 end of the buffer. */
2389 if (data.bi_bufpos < BI_BUF_ZV (b)
2390 && (active_minibuffer || !NILP (synch_minibuffers_value)))
2392 /* #### This check is not correct. If the line terminated
2393 due to a begin-glyph or end-glyph hitting window-end, then
2394 data.ch will not point to the character at data.bi_bufpos. If
2395 you make the two changes mentioned at the top of this loop,
2396 you should be able to say '(if (*prop))'. That should also
2397 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
2400 /* The common case is that the line ended because we hit a newline.
2401 In that case, the next character is just the next buffer
2403 if (data.ch == '\n')
2405 /* If data.start_col_enabled is still true, then the window is
2406 scrolled far enough so that nothing on this line is visible.
2407 We need to stick a truncation glyph at the beginning of the
2408 line in that case unless the line is completely blank. */
2409 if (data.bi_start_col_enabled)
2411 if (data.cursor_type == CURSOR_ON)
2413 if (data.bi_cursor_bufpos >= bi_start_pos
2414 && data.bi_cursor_bufpos <= data.bi_bufpos)
2415 data.bi_cursor_bufpos = data.bi_bufpos;
2417 data.findex = DEFAULT_INDEX;
2419 data.bi_start_col_enabled = 0;
2421 if (data.bi_bufpos != bi_start_pos)
2423 struct glyph_block gb;
2426 gb.glyph = Vhscroll_glyph;
2427 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2428 GLYPH_CACHEL (w, HSCROLL_GLYPH_INDEX));
2432 /* This duplicates code down below to add a newline to
2433 the end of an otherwise empty line.*/
2435 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2437 add_emchar_rune (&data);
2441 INC_BYTIND (b, data.bi_bufpos);
2444 /* Otherwise we have a buffer line which cannot fit on one display
2448 struct glyph_block gb;
2449 struct glyph_cachel *cachel;
2451 /* If the line is to be truncated then we actually have to look
2452 for the next newline. We also add the end-of-line glyph which
2453 we know will fit because we adjusted the right border before
2454 we starting laying out the line. */
2455 data.max_pixpos += end_glyph_width;
2456 data.findex = DEFAULT_INDEX;
2463 /* Now find the start of the next line. */
2464 bi_pos = bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2466 /* If the cursor is past the truncation line then we
2467 make it appear on the truncation glyph. If we've hit
2468 the end of the buffer then we also make the cursor
2469 appear unless eob is immediately preceded by a
2470 newline. In that case the cursor should actually
2471 appear on the next line. */
2472 if (data.cursor_type == CURSOR_ON
2473 && data.bi_cursor_bufpos >= data.bi_bufpos
2474 && (data.bi_cursor_bufpos < bi_pos ||
2475 (bi_pos == BI_BUF_ZV (b)
2476 && (bi_pos == BI_BUF_BEGV (b)
2477 || (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_pos))
2479 data.bi_cursor_bufpos = bi_pos;
2481 data.cursor_type = NO_CURSOR;
2483 data.bi_bufpos = bi_pos;
2484 gb.glyph = Vtruncation_glyph;
2485 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
2489 /* The cursor can never be on the continuation glyph. */
2490 data.cursor_type = NO_CURSOR;
2492 /* data.bi_bufpos is already at the start of the next line. */
2494 dl->line_continuation = 1;
2495 gb.glyph = Vcontinuation_glyph;
2496 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
2499 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
2501 if (truncate_win && data.bi_bufpos == BI_BUF_ZV (b)
2502 && BI_BUF_FETCH_CHAR (b, prev_bytind (b, BI_BUF_ZV (b))) != '\n')
2503 /* #### Damn this losing shit. */
2507 else if ((active_minibuffer || !NILP (synch_minibuffers_value))
2508 && (!echo_area_active (f) || data.bi_bufpos == BI_BUF_ZV (b)))
2510 /* We need to add a marker to the end of the line since there is no
2511 newline character in order for the cursor to get drawn. We label
2512 it as a newline so that it gets handled correctly by the
2513 whitespace routines below. */
2516 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2517 data.findex = DEFAULT_INDEX;
2519 data.start_col_xoffset = 0;
2520 data.bi_start_col_enabled = 0;
2522 data.max_pixpos += data.blank_width;
2523 add_emchar_rune (&data);
2524 data.max_pixpos -= data.blank_width;
2526 /* #### urk! Chuck, this shit is bad news. Going around
2527 manipulating invalid positions is guaranteed to result in
2528 trouble sooner or later. */
2529 data.bi_bufpos = BI_BUF_ZV (b) + 1;
2532 /* Calculate left whitespace boundary. */
2536 /* Whitespace past a newline is considered right whitespace. */
2537 while (elt < Dynarr_length (db->runes))
2539 struct rune *rb = Dynarr_atp (db->runes, elt);
2541 if ((rb->type == RUNE_CHAR && CHARC_ASCII_EQ (rb->object.cglyph, ' '))
2542 || rb->type == RUNE_BLANK)
2544 dl->bounds.left_white += rb->width;
2548 elt = Dynarr_length (db->runes);
2552 /* Calculate right whitespace boundary. */
2554 int elt = Dynarr_length (db->runes) - 1;
2557 while (!done && elt >= 0)
2559 struct rune *rb = Dynarr_atp (db->runes, elt);
2561 if (!(rb->type == RUNE_CHAR && CHARC_IS_SPACE (rb->object.cglyph))
2562 && !rb->type == RUNE_BLANK)
2564 dl->bounds.right_white = rb->xpos + rb->width;
2572 /* The line is blank so everything is considered to be right
2575 dl->bounds.right_white = dl->bounds.left_in;
2578 /* Set the display blocks bounds. */
2579 db->start_pos = dl->bounds.left_in;
2580 if (Dynarr_length (db->runes))
2582 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
2584 db->end_pos = rb->xpos + rb->width;
2587 db->end_pos = dl->bounds.right_white;
2589 /* update line height parameters */
2590 if (!data.new_ascent && !data.new_descent)
2592 /* We've got a blank line so initialize these values from the default
2594 default_face_font_info (data.window, &data.new_ascent,
2595 &data.new_descent, 0, 0, 0);
2598 if (data.max_pixmap_height)
2600 int height = data.new_ascent + data.new_descent;
2601 int pix_ascent, pix_descent;
2603 pix_descent = data.max_pixmap_height * data.new_descent / height;
2604 pix_ascent = data.max_pixmap_height - pix_descent;
2606 data.new_ascent = max (data.new_ascent, pix_ascent);
2607 data.new_descent = max (data.new_descent, pix_descent);
2610 dl->ascent = data.new_ascent;
2611 dl->descent = data.new_descent;
2614 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
2616 if (dl->ascent < ascent)
2617 dl->ascent = ascent;
2620 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
2622 if (dl->descent < descent)
2623 dl->descent = descent;
2626 dl->cursor_elt = data.cursor_x;
2627 /* #### lossage lossage lossage! Fix this shit! */
2628 if (data.bi_bufpos > BI_BUF_ZV (b))
2629 dl->end_bufpos = BUF_ZV (b);
2631 dl->end_bufpos = bytind_to_bufpos (b, data.bi_bufpos) - 1;
2633 data.dl->num_chars = column_at_point (b, dl->end_bufpos, 0);
2635 /* This doesn't correctly take into account tabs and control
2636 characters but if the window isn't being truncated then this
2637 value isn't going to end up being used anyhow. */
2638 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
2640 /* #### handle horizontally scrolled line with text none of which
2641 was actually laid out. */
2643 /* #### handle any remainder of overlay arrow */
2645 if (*prop == ADD_FAILED)
2648 if (truncate_win && *prop)
2650 Dynarr_free (*prop);
2654 extent_fragment_delete (data.ef);
2656 /* #### If we started at EOB, then make sure we return a value past
2657 it so that regenerate_window will exit properly. This is bogus.
2658 The main loop should get fixed so that it isn't necessary to call
2659 this function if we are already at EOB. */
2661 if (data.bi_bufpos == BI_BUF_ZV (b) && bi_start_pos == BI_BUF_ZV (b))
2662 return data.bi_bufpos + 1; /* Yuck! */
2664 return data.bi_bufpos;
2667 /* Display the overlay arrow at the beginning of the given line. */
2670 create_overlay_glyph_block (struct window *w, struct display_line *dl)
2672 struct frame *f = XFRAME (w->frame);
2673 struct device *d = XDEVICE (f->device);
2676 /* If Voverlay_arrow_string isn't valid then just fail silently. */
2677 if (!STRINGP (Voverlay_arrow_string) && !GLYPHP (Voverlay_arrow_string))
2683 XSETWINDOW (data.window, w);
2684 data.db = get_display_block_from_line (dl, OVERWRITE);
2686 data.pixpos = dl->bounds.left_in;
2687 data.max_pixpos = dl->bounds.right_in;
2688 data.cursor_type = NO_CURSOR;
2690 data.findex = DEFAULT_INDEX;
2691 data.last_charset = Qunbound;
2692 data.last_findex = DEFAULT_INDEX;
2693 data.result_str = Qnil;
2696 Dynarr_reset (data.db->runes);
2698 if (STRINGP (Voverlay_arrow_string))
2700 add_bufbyte_string_runes
2702 XSTRING_DATA (Voverlay_arrow_string),
2703 XSTRING_LENGTH (Voverlay_arrow_string),
2706 else if (GLYPHP (Voverlay_arrow_string))
2708 struct glyph_block gb;
2710 gb.glyph = Voverlay_arrow_string;
2712 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, 0);
2715 if (data.max_pixmap_height)
2717 int height = data.new_ascent + data.new_descent;
2718 int pix_ascent, pix_descent;
2720 pix_descent = data.max_pixmap_height * data.new_descent / height;
2721 pix_ascent = data.max_pixmap_height - pix_descent;
2723 data.new_ascent = max (data.new_ascent, pix_ascent);
2724 data.new_descent = max (data.new_descent, pix_descent);
2727 dl->ascent = data.new_ascent;
2728 dl->descent = data.new_descent;
2730 data.db->start_pos = dl->bounds.left_in;
2731 data.db->end_pos = data.pixpos;
2733 return data.pixpos - dl->bounds.left_in;
2736 /* Add a type of glyph to a margin display block. */
2739 add_margin_runes (struct display_line *dl, struct display_block *db, int start,
2740 int count, enum glyph_layout layout, int side, Lisp_Object window)
2742 glyph_block_dynarr *gbd = (side == LEFT_GLYPHS
2744 : dl->right_glyphs);
2747 struct window *w = XWINDOW (window);
2748 struct frame *f = XFRAME (w->frame);
2749 struct device *d = XDEVICE (f->device);
2754 data.window = window;
2757 data.pixpos = start;
2758 data.cursor_type = NO_CURSOR;
2760 data.last_charset = Qunbound;
2761 data.last_findex = DEFAULT_INDEX;
2762 data.result_str = Qnil;
2764 data.new_ascent = dl->ascent;
2765 data.new_descent = dl->descent;
2767 if ((layout == GL_WHITESPACE && side == LEFT_GLYPHS)
2768 || (layout == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS))
2771 elt = Dynarr_length (gbd) - 1;
2778 end = Dynarr_length (gbd);
2781 while (count && ((!reverse && elt < end) || (reverse && elt >= end)))
2783 struct glyph_block *gb = Dynarr_atp (gbd, elt);
2785 if (NILP (gb->extent))
2786 abort (); /* these should have been handled in add_glyph_rune */
2789 ((side == LEFT_GLYPHS &&
2790 extent_begin_glyph_layout (XEXTENT (gb->extent)) == layout)
2791 || (side == RIGHT_GLYPHS &&
2792 extent_end_glyph_layout (XEXTENT (gb->extent)) == layout)))
2794 data.findex = gb->findex;
2795 data.max_pixpos = data.pixpos + gb->width;
2796 add_glyph_rune (&data, gb, side, 0, NULL);
2801 (reverse ? elt-- : elt++);
2804 if (data.max_pixmap_height)
2806 int height = data.new_ascent + data.new_descent;
2807 int pix_ascent, pix_descent;
2809 pix_descent = data.max_pixmap_height * data.new_descent / height;
2810 pix_ascent = data.max_pixmap_height - pix_descent;
2811 data.new_ascent = max (data.new_ascent, pix_ascent);
2812 data.new_descent = max (data.new_descent, pix_descent);
2815 dl->ascent = data.new_ascent;
2816 dl->descent = data.new_descent;
2821 /* Add a blank to a margin display block. */
2824 add_margin_blank (struct display_line *dl, struct display_block *db,
2825 struct window *w, int xpos, int width, int side)
2829 rb.findex = (side == LEFT_GLYPHS
2830 ? get_builtin_face_cache_index (w, Vleft_margin_face)
2831 : get_builtin_face_cache_index (w, Vright_margin_face));
2836 rb.type = RUNE_BLANK;
2837 rb.cursor_type = CURSOR_OFF;
2839 Dynarr_add (db->runes, rb);
2842 /* Display glyphs in the left outside margin, left inside margin and
2843 left whitespace area. */
2846 create_left_glyph_block (struct window *w, struct display_line *dl,
2851 int use_overflow = (NILP (w->use_left_overflow) ? 0 : 1);
2853 int out_end, in_out_start, in_in_end, white_out_start, white_in_start;
2854 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
2855 int left_in_start = dl->bounds.left_in;
2856 int left_in_end = dl->bounds.left_in + overlay_width;
2858 struct display_block *odb, *idb;
2860 XSETWINDOW (window, w);
2862 /* We have to add the glyphs to the line in the order outside,
2863 inside, whitespace. However the precedence dictates that we
2864 determine how many will fit in the reverse order. */
2866 /* Determine how many whitespace glyphs we can display and where
2867 they should start. */
2868 white_in_start = dl->bounds.left_white;
2869 white_out_start = left_in_start;
2870 white_out_cnt = white_in_cnt = 0;
2873 while (elt < Dynarr_length (dl->left_glyphs))
2875 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2877 if (NILP (gb->extent))
2878 abort (); /* these should have been handled in add_glyph_rune */
2880 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
2884 width = glyph_width (gb->glyph, window);
2886 if (white_in_start - width >= left_in_end)
2889 white_in_start -= width;
2893 else if (use_overflow
2894 && (white_out_start - width > dl->bounds.left_out))
2897 white_out_start -= width;
2908 /* Determine how many inside margin glyphs we can display and where
2909 they should start. The inside margin glyphs get whatever space
2910 is left after the whitespace glyphs have been displayed. These
2911 are tricky to calculate since if we decide to use the overflow
2912 area we basically have to start over. So for these we build up a
2913 list of just the inside margin glyphs and manipulate it to
2914 determine the needed info. */
2916 glyph_block_dynarr *ib;
2917 int avail_in, avail_out;
2920 int used_in, used_out;
2923 used_in = used_out = 0;
2924 ib = Dynarr_new (glyph_block);
2925 while (elt < Dynarr_length (dl->left_glyphs))
2927 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2929 if (NILP (gb->extent))
2930 abort (); /* these should have been handled in add_glyph_rune */
2932 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
2935 gb->width = glyph_width (gb->glyph, window);
2936 used_in += gb->width;
2937 Dynarr_add (ib, *gb);
2947 avail_in = white_in_start - left_in_end;
2955 avail_out = white_out_start - dl->bounds.left_out;
2958 while (!done && marker < Dynarr_length (ib))
2960 int width = Dynarr_atp (ib, marker)->width;
2962 /* If everything now fits in the available inside margin
2963 space, we're done. */
2964 if (used_in <= avail_in)
2968 /* Otherwise see if we have room to move a glyph to the
2970 if (used_out + width <= avail_out)
2983 /* At this point we now know that everything from marker on goes in
2984 the inside margin and everything before it goes in the outside
2985 margin. The stuff going into the outside margin is guaranteed
2986 to fit, but we may have to trim some stuff from the inside. */
2988 in_in_end = left_in_end;
2989 in_out_start = white_out_start;
2990 in_out_cnt = in_in_cnt = 0;
2994 while (elt < Dynarr_length (dl->left_glyphs))
2996 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2998 if (NILP (gb->extent))
2999 abort (); /* these should have been handled in add_glyph_rune */
3001 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3004 int width = glyph_width (gb->glyph, window);
3009 in_out_start -= width;
3014 else if (in_in_end + width < white_in_start)
3029 /* Determine how many outside margin glyphs we can display. They
3030 always start at the left outside margin and can only use the
3031 outside margin space. */
3032 out_end = dl->bounds.left_out;
3036 while (elt < Dynarr_length (dl->left_glyphs))
3038 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3040 if (NILP (gb->extent))
3041 abort (); /* these should have been handled in add_glyph_rune */
3043 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3046 int width = glyph_width (gb->glyph, window);
3048 if (out_end + width <= in_out_start)
3062 /* Now that we know where everything goes, we add the glyphs as
3063 runes to the appropriate display blocks. */
3064 if (out_cnt || in_out_cnt || white_out_cnt)
3066 odb = get_display_block_from_line (dl, LEFT_OUTSIDE_MARGIN);
3067 odb->start_pos = dl->bounds.left_out;
3068 /* #### We should stop adding a blank to account for the space
3069 between the end of the glyphs and the margin and instead set
3070 this accordingly. */
3071 odb->end_pos = dl->bounds.left_in;
3072 Dynarr_reset (odb->runes);
3077 if (in_in_cnt || white_in_cnt)
3079 idb = get_display_block_from_line (dl, LEFT_INSIDE_MARGIN);
3080 idb->start_pos = dl->bounds.left_in;
3081 /* #### See above comment for odb->end_pos */
3082 idb->end_pos = dl->bounds.left_white;
3083 Dynarr_reset (idb->runes);
3088 /* First add the outside margin glyphs. */
3090 end_xpos = add_margin_runes (dl, odb, dl->bounds.left_out, out_cnt,
3091 GL_OUTSIDE_MARGIN, LEFT_GLYPHS, window);
3093 end_xpos = dl->bounds.left_out;
3095 /* There may be blank space between the outside margin glyphs and
3096 the inside margin glyphs. If so, add a blank. */
3097 if (in_out_cnt && (in_out_start - end_xpos))
3099 add_margin_blank (dl, odb, w, end_xpos, in_out_start - end_xpos,
3103 /* Next add the inside margin glyphs which are actually in the
3107 end_xpos = add_margin_runes (dl, odb, in_out_start, in_out_cnt,
3108 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3111 /* If we didn't add any inside margin glyphs to the outside margin,
3112 but are adding whitespace glyphs, then we need to add a blank
3114 if (!in_out_cnt && white_out_cnt && (white_out_start - end_xpos))
3116 add_margin_blank (dl, odb, w, end_xpos, white_out_start - end_xpos,
3120 /* Next add the whitespace margin glyphs which are actually in the
3124 end_xpos = add_margin_runes (dl, odb, white_out_start, white_out_cnt,
3125 GL_WHITESPACE, LEFT_GLYPHS, window);
3128 /* We take care of clearing between the end of the glyphs and the
3129 start of the inside margin for lines which have glyphs. */
3130 if (odb && (left_in_start - end_xpos))
3132 add_margin_blank (dl, odb, w, end_xpos, left_in_start - end_xpos,
3136 /* Next add the inside margin glyphs which are actually in the
3140 end_xpos = add_margin_runes (dl, idb, left_in_end, in_in_cnt,
3141 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3144 end_xpos = left_in_end;
3146 /* Make sure that the area between the end of the inside margin
3147 glyphs and the whitespace glyphs is cleared. */
3148 if (idb && (white_in_start - end_xpos > 0))
3150 add_margin_blank (dl, idb, w, end_xpos, white_in_start - end_xpos,
3154 /* Next add the whitespace margin glyphs which are actually in the
3158 add_margin_runes (dl, idb, white_in_start, white_in_cnt, GL_WHITESPACE,
3159 LEFT_GLYPHS, window);
3162 /* Whitespace glyphs always end right next to the text block so
3163 there is nothing we have to make sure is cleared after them. */
3166 /* Display glyphs in the right outside margin, right inside margin and
3167 right whitespace area. */
3170 create_right_glyph_block (struct window *w, struct display_line *dl)
3174 int use_overflow = (NILP (w->use_right_overflow) ? 0 : 1);
3176 int out_start, in_out_end, in_in_start, white_out_end, white_in_end;
3177 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
3179 struct display_block *odb, *idb;
3181 XSETWINDOW (window, w);
3183 /* We have to add the glyphs to the line in the order outside,
3184 inside, whitespace. However the precedence dictates that we
3185 determine how many will fit in the reverse order. */
3187 /* Determine how many whitespace glyphs we can display and where
3188 they should start. */
3189 white_in_end = dl->bounds.right_white;
3190 white_out_end = dl->bounds.right_in;
3191 white_out_cnt = white_in_cnt = 0;
3194 while (elt < Dynarr_length (dl->right_glyphs))
3196 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3198 if (NILP (gb->extent))
3199 abort (); /* these should have been handled in add_glyph_rune */
3201 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
3203 int width = glyph_width (gb->glyph, window);
3205 if (white_in_end + width <= dl->bounds.right_in)
3208 white_in_end += width;
3212 else if (use_overflow
3213 && (white_out_end + width <= dl->bounds.right_out))
3216 white_out_end += width;
3227 /* Determine how many inside margin glyphs we can display and where
3228 they should start. The inside margin glyphs get whatever space
3229 is left after the whitespace glyphs have been displayed. These
3230 are tricky to calculate since if we decide to use the overflow
3231 area we basically have to start over. So for these we build up a
3232 list of just the inside margin glyphs and manipulate it to
3233 determine the needed info. */
3235 glyph_block_dynarr *ib;
3236 int avail_in, avail_out;
3239 int used_in, used_out;
3242 used_in = used_out = 0;
3243 ib = Dynarr_new (glyph_block);
3244 while (elt < Dynarr_length (dl->right_glyphs))
3246 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3248 if (NILP (gb->extent))
3249 abort (); /* these should have been handled in add_glyph_rune */
3251 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3253 gb->width = glyph_width (gb->glyph, window);
3254 used_in += gb->width;
3255 Dynarr_add (ib, *gb);
3264 avail_in = dl->bounds.right_in - white_in_end;
3269 avail_out = dl->bounds.right_out - white_out_end;
3272 while (!done && marker < Dynarr_length (ib))
3274 int width = Dynarr_atp (ib, marker)->width;
3276 /* If everything now fits in the available inside margin
3277 space, we're done. */
3278 if (used_in <= avail_in)
3282 /* Otherwise see if we have room to move a glyph to the
3284 if (used_out + width <= avail_out)
3297 /* At this point we now know that everything from marker on goes in
3298 the inside margin and everything before it goes in the outside
3299 margin. The stuff going into the outside margin is guaranteed
3300 to fit, but we may have to trim some stuff from the inside. */
3302 in_in_start = dl->bounds.right_in;
3303 in_out_end = dl->bounds.right_in;
3304 in_out_cnt = in_in_cnt = 0;
3308 while (elt < Dynarr_length (dl->right_glyphs))
3310 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3312 if (NILP (gb->extent))
3313 abort (); /* these should have been handled in add_glyph_rune */
3315 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3317 int width = glyph_width (gb->glyph, window);
3322 in_out_end += width;
3327 else if (in_in_start - width >= white_in_end)
3330 in_in_start -= width;
3342 /* Determine how many outside margin glyphs we can display. They
3343 always start at the right outside margin and can only use the
3344 outside margin space. */
3345 out_start = dl->bounds.right_out;
3349 while (elt < Dynarr_length (dl->right_glyphs))
3351 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3353 if (NILP (gb->extent))
3354 abort (); /* these should have been handled in add_glyph_rune */
3356 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_OUTSIDE_MARGIN)
3358 int width = glyph_width (gb->glyph, window);
3360 if (out_start - width >= in_out_end)
3374 /* Now that we now where everything goes, we add the glyphs as runes
3375 to the appropriate display blocks. */
3376 if (out_cnt || in_out_cnt || white_out_cnt)
3378 odb = get_display_block_from_line (dl, RIGHT_OUTSIDE_MARGIN);
3379 /* #### See comments before odb->start_pos init in
3380 create_left_glyph_block */
3381 odb->start_pos = dl->bounds.right_in;
3382 odb->end_pos = dl->bounds.right_out;
3383 Dynarr_reset (odb->runes);
3388 if (in_in_cnt || white_in_cnt)
3390 idb = get_display_block_from_line (dl, RIGHT_INSIDE_MARGIN);
3391 idb->start_pos = dl->bounds.right_white;
3392 /* #### See comments before odb->start_pos init in
3393 create_left_glyph_block */
3394 idb->end_pos = dl->bounds.right_in;
3395 Dynarr_reset (idb->runes);
3400 /* First add the whitespace margin glyphs which are actually in the
3404 end_xpos = add_margin_runes (dl, idb, dl->bounds.right_white,
3405 white_in_cnt, GL_WHITESPACE, RIGHT_GLYPHS,
3409 end_xpos = dl->bounds.right_white;
3411 /* Make sure that the area between the end of the whitespace glyphs
3412 and the inside margin glyphs is cleared. */
3413 if (in_in_cnt && (in_in_start - end_xpos))
3415 add_margin_blank (dl, idb, w, end_xpos, in_in_start - end_xpos,
3419 /* Next add the inside margin glyphs which are actually in the
3423 end_xpos = add_margin_runes (dl, idb, in_in_start, in_in_cnt,
3424 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3427 /* If we didn't add any inside margin glyphs then make sure the rest
3428 of the inside margin area gets cleared. */
3429 if (idb && (dl->bounds.right_in - end_xpos))
3431 add_margin_blank (dl, idb, w, end_xpos, dl->bounds.right_in - end_xpos,
3435 /* Next add any whitespace glyphs in the outside margin. */
3438 end_xpos = add_margin_runes (dl, odb, dl->bounds.right_in, white_out_cnt,
3439 GL_WHITESPACE, RIGHT_GLYPHS, window);
3442 end_xpos = dl->bounds.right_in;
3444 /* Next add any inside margin glyphs in the outside margin. */
3447 end_xpos = add_margin_runes (dl, odb, end_xpos, in_out_cnt,
3448 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3451 /* There may be space between any whitespace or inside margin glyphs
3452 in the outside margin and the actual outside margin glyphs. */
3453 if (odb && (out_start - end_xpos))
3455 add_margin_blank (dl, odb, w, end_xpos, out_start - end_xpos,
3459 /* Finally, add the outside margin glyphs. */
3462 add_margin_runes (dl, odb, out_start, out_cnt, GL_OUTSIDE_MARGIN,
3463 RIGHT_GLYPHS, window);
3468 /***************************************************************************/
3470 /* modeline routines */
3472 /***************************************************************************/
3474 /* This function is also used in frame.c by `generate_title_string' */
3476 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str,
3477 struct window *w, struct display_line *dl,
3478 struct display_block *db, face_index findex,
3479 int min_pixpos, int max_pixpos, int type)
3481 struct frame *f = XFRAME (w->frame);
3482 struct device *d = XDEVICE (f->device);
3486 Charcount offset = 0;
3492 data.findex = findex;
3493 data.pixpos = min_pixpos;
3494 data.max_pixpos = max_pixpos;
3495 data.cursor_type = NO_CURSOR;
3496 data.last_charset = Qunbound;
3497 data.last_findex = DEFAULT_INDEX;
3498 data.result_str = result_str;
3499 data.is_modeline = 1;
3501 XSETWINDOW (data.window, w);
3503 Dynarr_reset (formatted_string_extent_dynarr);
3504 Dynarr_reset (formatted_string_extent_start_dynarr);
3505 Dynarr_reset (formatted_string_extent_end_dynarr);
3507 /* result_str is nil when we're building a frame or icon title. Otherwise,
3508 we're building a modeline, so the offset starts at the modeline
3509 horizontal scrolling amount */
3510 if (! NILP (result_str))
3511 offset = w->modeline_hscroll;
3512 generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0,
3513 max_pixpos - min_pixpos, findex, type, &offset,
3516 if (Dynarr_length (db->runes))
3519 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
3520 c_pixpos = rb->xpos + rb->width;
3523 c_pixpos = min_pixpos;
3525 /* If we don't reach the right side of the window, add a blank rune
3526 to make up the difference. This usually only occurs if the
3527 modeline face is using a proportional width font or a fixed width
3528 font of a different size from the default face font. */
3530 if (c_pixpos < max_pixpos)
3532 data.pixpos = c_pixpos;
3533 data.blank_width = max_pixpos - data.pixpos;
3535 add_blank_rune (&data, NULL, 0);
3538 /* Now create the result string and frob the extents into it. */
3539 if (!NILP (result_str))
3544 struct buffer *buf = XBUFFER (WINDOW_BUFFER (w));
3546 in_modeline_generation = 1;
3548 detach_all_extents (result_str);
3549 resize_string (XSTRING (result_str), -1,
3550 data.bytepos - XSTRING_LENGTH (result_str));
3552 strdata = XSTRING_DATA (result_str);
3554 for (elt = 0, len = 0; elt < Dynarr_length (db->runes); elt++)
3556 if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR)
3558 len += (set_charptr_emchar
3560 CHARC_TO_CHAR (Dynarr_atp (db->runes,
3561 elt)->object.cglyph)));
3565 for (elt = 0; elt < Dynarr_length (formatted_string_extent_dynarr);
3568 Lisp_Object extent = Qnil;
3571 XSETEXTENT (extent, Dynarr_at (formatted_string_extent_dynarr, elt));
3572 child = Fgethash (extent, buf->modeline_extent_table, Qnil);
3575 child = Fmake_extent (Qnil, Qnil, result_str);
3576 Fputhash (extent, child, buf->modeline_extent_table);
3578 Fset_extent_parent (child, extent);
3579 set_extent_endpoints
3581 Dynarr_at (formatted_string_extent_start_dynarr, elt),
3582 Dynarr_at (formatted_string_extent_end_dynarr, elt),
3586 in_modeline_generation = 0;
3590 /* Ensure that the given display line DL accurately represents the
3591 modeline for the given window. */
3593 generate_modeline (struct window *w, struct display_line *dl, int type)
3595 struct buffer *b = XBUFFER (w->buffer);
3596 struct frame *f = XFRAME (w->frame);
3597 struct device *d = XDEVICE (f->device);
3599 /* Unlike display line and rune pointers, this one can't change underneath
3601 struct display_block *db = get_display_block_from_line (dl, TEXT);
3602 int max_pixpos, min_pixpos, ypos_adj;
3603 Lisp_Object font_inst;
3605 /* This will actually determine incorrect inside boundaries for the
3606 modeline since it ignores the margins. However being aware of this fact
3607 we never use those values anywhere so it doesn't matter. */
3608 dl->bounds = calculate_display_line_boundaries (w, 1);
3610 /* We are generating a modeline. */
3612 dl->cursor_elt = -1;
3614 /* Reset the runes on the modeline. */
3615 Dynarr_reset (db->runes);
3617 if (!WINDOW_HAS_MODELINE_P (w))
3621 /* If there is a horizontal scrollbar, don't add anything. */
3622 if (window_scrollbar_height (w))
3625 dl->ascent = DEVMETH (d, divider_height, ());
3627 /* The modeline is at the bottom of the gutters. */
3628 dl->ypos = WINDOW_BOTTOM (w);
3630 rb.findex = MODELINE_INDEX;
3631 rb.xpos = dl->bounds.left_out;
3632 rb.width = dl->bounds.right_out - dl->bounds.left_out;
3635 rb.type = RUNE_HLINE;
3636 rb.object.hline.thickness = 1;
3637 rb.object.hline.yoffset = 0;
3638 rb.cursor_type = NO_CURSOR;
3640 if (!EQ (Qzero, w->modeline_shadow_thickness)
3643 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3645 dl->ypos -= shadow_thickness;
3646 rb.xpos += shadow_thickness;
3647 rb.width -= 2 * shadow_thickness;
3650 Dynarr_add (db->runes, rb);
3654 /* !!#### not right; needs to compute the max height of
3656 font_inst = WINDOW_FACE_CACHEL_FONT (w, MODELINE_INDEX, Vcharset_ascii);
3658 dl->ascent = XFONT_INSTANCE (font_inst)->ascent;
3659 dl->descent = XFONT_INSTANCE (font_inst)->descent;
3661 min_pixpos = dl->bounds.left_out;
3662 max_pixpos = dl->bounds.right_out;
3664 if (!EQ (Qzero, w->modeline_shadow_thickness) && FRAME_WIN_P (f))
3666 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3668 ypos_adj = shadow_thickness;
3669 min_pixpos += shadow_thickness;
3670 max_pixpos -= shadow_thickness;
3675 generate_formatted_string_db (b->modeline_format,
3676 b->generated_modeline_string, w, dl, db,
3677 MODELINE_INDEX, min_pixpos, max_pixpos, type);
3679 /* The modeline is at the bottom of the gutters. We have to wait to
3680 set this until we've generated the modeline in order to account
3681 for any embedded faces. */
3682 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj;
3686 add_string_to_fstring_db_runes (pos_data *data, const Bufbyte *str,
3687 Charcount pos, Charcount min_pos, Charcount max_pos)
3689 /* This function has been Mule-ized. */
3691 const Bufbyte *cur_pos = str;
3692 struct display_block *db = data->db;
3694 data->blank_width = space_width (XWINDOW (data->window));
3695 while (Dynarr_length (db->runes) < pos)
3696 add_blank_rune (data, NULL, 0);
3698 end = (Dynarr_length (db->runes) +
3699 bytecount_to_charcount (str, strlen ((const char *) str)));
3701 end = min (max_pos, end);
3703 while (pos < end && *cur_pos)
3705 const Bufbyte *old_cur_pos = cur_pos;
3708 data->ch = charptr_emchar (cur_pos);
3709 succeeded = (add_emchar_rune (data) != ADD_FAILED);
3710 INC_CHARPTR (cur_pos);
3714 data->modeline_charpos++;
3715 data->bytepos += cur_pos - old_cur_pos;
3719 while (Dynarr_length (db->runes) < min_pos &&
3720 (data->pixpos + data->blank_width <= data->max_pixpos))
3721 add_blank_rune (data, NULL, 0);
3723 return Dynarr_length (db->runes);
3726 /* #### Urk! Should also handle begin-glyphs and end-glyphs in
3727 modeline extents. */
3729 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph,
3730 Charcount pos, Charcount min_pos,
3731 Charcount max_pos, Lisp_Object extent)
3733 /* This function has been Mule-ized. */
3735 struct display_block *db = data->db;
3736 struct glyph_block gb;
3738 data->blank_width = space_width (XWINDOW (data->window));
3739 while (Dynarr_length (db->runes) < pos)
3740 add_blank_rune (data, NULL, 0);
3742 end = Dynarr_length (db->runes) + 1;
3744 end = min (max_pos, end);
3748 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
3751 while (Dynarr_length (db->runes) < pos &&
3752 (data->pixpos + data->blank_width <= data->max_pixpos))
3753 add_blank_rune (data, NULL, 0);
3755 return Dynarr_length (db->runes);
3758 /* If max_pos is == -1, it is considered to be infinite. The same is
3759 true of max_pixsize. */
3760 #define SET_CURRENT_MODE_CHARS_PIXSIZE \
3761 if (Dynarr_length (data->db->runes)) \
3762 cur_pixsize = data->pixpos - Dynarr_atp (data->db->runes, 0)->xpos; \
3766 /* Note that this function does "positions" in terms of characters and
3767 not in terms of columns. This is necessary to make the formatting
3768 work correctly when proportional width fonts are used in the
3771 generate_fstring_runes (struct window *w, pos_data *data, Charcount pos,
3772 Charcount min_pos, Charcount max_pos,
3773 Lisp_Object elt, int depth, int max_pixsize,
3774 face_index findex, int type, Charcount *offset,
3775 Lisp_Object cur_ext)
3777 /* This function has been Mule-ized. */
3778 /* #### The other losing things in this function are:
3780 -- C zero-terminated-string lossage.
3781 -- Non-printable characters should be converted into something
3782 appropriate (e.g. ^F) instead of blindly being printed anyway.
3793 /* A string. Add to the display line and check for %-constructs
3796 Bufbyte *this = XSTRING_DATA (elt);
3798 while ((pos < max_pos || max_pos == -1) && *this)
3800 Bufbyte *last = this;
3802 while (*this && *this != '%')
3807 /* No %-construct */
3809 bytecount_to_charcount (last, this - last);
3811 if (size <= *offset)
3815 Charcount tmp_max = (max_pos == -1 ? pos + size - *offset :
3816 min (pos + size - *offset, max_pos));
3817 const Bufbyte *tmp_last = charptr_n_addr (last, *offset);
3819 pos = add_string_to_fstring_db_runes (data, tmp_last,
3824 else /* *this == '%' */
3826 Charcount spec_width = 0;
3828 this++; /* skip over '%' */
3830 /* We can't allow -ve args due to the "%-" construct.
3831 * Argument specifies minwidth but not maxwidth
3832 * (maxwidth can be specified by
3833 * (<negative-number> . <stuff>) modeline elements)
3835 while (isdigit (*this))
3837 spec_width = spec_width * 10 + (*this - '0');
3844 pos = generate_fstring_runes (w, data, pos, spec_width,
3845 max_pos, Vglobal_mode_string,
3846 depth, max_pixsize, findex,
3847 type, offset, cur_ext);
3849 else if (*this == '-')
3851 Charcount num_to_add;
3853 if (max_pixsize < 0)
3855 else if (max_pos != -1)
3856 num_to_add = max_pos - pos;
3862 SET_CURRENT_MODE_CHARS_PIXSIZE;
3865 redisplay_text_width_string (w, findex, &ch, Qnil, 0,
3868 num_to_add = (max_pixsize - cur_pixsize) / dash_pixsize;
3872 while (num_to_add--)
3873 pos = add_string_to_fstring_db_runes
3874 (data, (const Bufbyte *) "-", pos, pos, max_pos);
3876 else if (*this != 0)
3878 Emchar ch = charptr_emchar (this);
3882 decode_mode_spec (w, ch, type);
3884 str = Dynarr_atp (mode_spec_bufbyte_string, 0);
3885 size = bytecount_to_charcount
3886 /* Skip the null character added by `decode_mode_spec' */
3887 (str, Dynarr_length (mode_spec_bufbyte_string)) - 1;
3889 if (size <= *offset)
3893 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3895 /* #### NOTE: I don't understand why a tmp_max is not
3896 computed and used here as in the plain string case
3898 pos = add_string_to_fstring_db_runes (data, tmp_str,
3905 /* NOT this++. There could be any sort of character at
3906 the current position. */
3910 if (max_pixsize > 0)
3913 SET_CURRENT_MODE_CHARS_PIXSIZE;
3915 if (cur_pixsize >= max_pixsize)
3920 else if (SYMBOLP (elt))
3922 /* A symbol: process the value of the symbol recursively
3923 as if it appeared here directly. */
3924 Lisp_Object tem = symbol_value_in_buffer (elt, w->buffer);
3926 if (!UNBOUNDP (tem))
3928 /* If value is a string, output that string literally:
3929 don't check for % within it. */
3932 Bufbyte *str = XSTRING_DATA (tem);
3933 Charcount size = XSTRING_CHAR_LENGTH (tem);
3935 if (size <= *offset)
3939 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3941 /* #### NOTE: I don't understand why a tmp_max is not
3942 computed and used here as in the plain string case
3944 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
3949 /* Give up right away for nil or t. */
3950 else if (!EQ (tem, elt))
3957 else if (GENERIC_SPECIFIERP (elt))
3959 Lisp_Object window, tem;
3960 XSETWINDOW (window, w);
3961 tem = specifier_instance_no_quit (elt, Qunbound, window,
3962 ERROR_ME_NOT, 0, Qzero);
3963 if (!UNBOUNDP (tem))
3969 else if (CONSP (elt))
3971 /* A cons cell: four distinct cases.
3972 * - If first element is a string or a cons, process all the elements
3973 * and effectively concatenate them.
3974 * - If first element is a negative number, truncate displaying cdr to
3975 * at most that many characters. If positive, pad (with spaces)
3976 * to at least that many characters.
3977 * - If first element is another symbol, process the cadr or caddr
3978 * recursively according to whether the symbol's value is non-nil or
3980 * - If first element is an extent, process the cdr recursively
3981 * and handle the extent's face.
3984 Lisp_Object car, tem;
3993 tem = symbol_value_in_buffer (car, w->buffer);
3994 /* elt is now the cdr, and we know it is a cons cell.
3995 Use its car if CAR has a non-nil value. */
3996 if (!UNBOUNDP (tem))
4004 /* Symbol's value is nil (or symbol is unbound)
4005 * Get the cddr of the original list
4006 * and if possible find the caddr and use that.
4011 else if (!CONSP (elt))
4019 else if (INTP (car))
4021 Charcount lim = XINT (car);
4027 /* Negative int means reduce maximum width.
4028 * DO NOT change MIN_PIXPOS here!
4029 * (20 -10 . foo) should truncate foo to 10 col
4030 * and then pad to 20.
4033 max_pos = pos - lim;
4035 max_pos = min (max_pos, pos - lim);
4039 /* Padding specified. Don't let it be more than
4043 if (max_pos != -1 && lim > max_pos)
4045 /* If that's more padding than already wanted, queue it.
4046 * But don't reduce padding already specified even if
4047 * that is beyond the current truncation point.
4054 else if (STRINGP (car) || CONSP (car))
4058 /* LIMIT is to protect against circular lists. */
4059 while (CONSP (elt) && --limit > 0
4060 && (pos < max_pos || max_pos == -1))
4062 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4063 XCAR (elt), depth, max_pixsize,
4064 findex, type, offset, cur_ext);
4068 else if (EXTENTP (car))
4070 struct extent *ext = XEXTENT (car);
4072 if (EXTENT_LIVE_P (ext))
4074 face_index old_findex = data->findex;
4076 Lisp_Object font_inst;
4077 face_index new_findex;
4078 Bytecount start = data->bytepos;
4080 face = extent_face (ext);
4083 /* #### needs to merge faces, sigh */
4084 /* #### needs to handle list of faces */
4085 new_findex = get_builtin_face_cache_index (w, face);
4086 /* !!#### not right; needs to compute the max height of
4088 font_inst = WINDOW_FACE_CACHEL_FONT (w, new_findex,
4091 data->dl->ascent = max (data->dl->ascent,
4092 XFONT_INSTANCE (font_inst)->ascent);
4093 data->dl->descent = max (data->dl->descent,
4094 XFONT_INSTANCE (font_inst)->
4098 new_findex = old_findex;
4100 data->findex = new_findex;
4101 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4102 XCDR (elt), depth - 1,
4103 max_pixsize, new_findex, type,
4105 data->findex = old_findex;
4106 Dynarr_add (formatted_string_extent_dynarr, ext);
4107 Dynarr_add (formatted_string_extent_start_dynarr, start);
4108 Dynarr_add (formatted_string_extent_end_dynarr, data->bytepos);
4112 else if (GLYPHP (elt))
4114 /* Glyphs are considered as one character with respect to the modeline
4115 horizontal scrolling facility. -- dv */
4119 pos = add_glyph_to_fstring_db_runes (data, elt, pos, pos, max_pos,
4126 char *str = GETTEXT ("*invalid*");
4127 Charcount size = (Charcount) strlen (str); /* is this ok ?? -- dv */
4129 if (size <= *offset)
4133 const Bufbyte *tmp_str =
4134 charptr_n_addr ((const Bufbyte *) str, *offset);
4136 /* #### NOTE: I don't understand why a tmp_max is not computed and
4137 used here as in the plain string case above. -- dv */
4138 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
4147 add_string_to_fstring_db_runes (data, (const Bufbyte *) "", pos,
4154 /* Update just the modeline. Assumes the desired display structs. If
4155 they do not have a modeline block, it does nothing. */
4157 regenerate_modeline (struct window *w)
4159 display_line_dynarr *dla = window_display_lines (w, DESIRED_DISP);
4161 if (!Dynarr_length (dla) || !Dynarr_atp (dla, 0)->modeline)
4165 generate_modeline (w, Dynarr_atp (dla, 0), DESIRED_DISP);
4166 redisplay_update_line (w, 0, 0, 0);
4170 /* Make sure that modeline display line is present in the given
4171 display structs if the window has a modeline and update that
4172 line. Returns true if a modeline was needed. */
4174 ensure_modeline_generated (struct window *w, int type)
4178 /* minibuffer windows don't have modelines */
4179 if (MINI_WINDOW_P (w))
4181 /* windows which haven't had it turned off do */
4182 else if (WINDOW_HAS_MODELINE_P (w))
4184 /* windows which have it turned off don't have a divider if there is
4185 a horizontal scrollbar */
4186 else if (window_scrollbar_height (w))
4188 /* and in this case there is none */
4194 display_line_dynarr *dla;
4196 dla = window_display_lines (w, type);
4198 /* We don't care if there is a display line which is not
4199 currently a modeline because it is definitely going to become
4200 one if we have gotten to this point. */
4201 if (Dynarr_length (dla) == 0)
4203 if (Dynarr_largest (dla) > 0)
4205 struct display_line *mlp = Dynarr_atp (dla, 0);
4206 Dynarr_add (dla, *mlp);
4210 struct display_line modeline;
4212 Dynarr_add (dla, modeline);
4216 /* If we're adding a new place marker go ahead and generate the
4217 modeline so that it is available for use by
4218 window_modeline_height. */
4219 generate_modeline (w, Dynarr_atp (dla, 0), type);
4222 return need_modeline;
4225 /* #### Kludge or not a kludge. I tend towards the former. */
4227 real_current_modeline_height (struct window *w)
4229 Fset_marker (w->start[CMOTION_DISP], w->start[CURRENT_DISP], w->buffer);
4230 Fset_marker (w->pointm[CMOTION_DISP], w->pointm[CURRENT_DISP], w->buffer);
4232 if (ensure_modeline_generated (w, CMOTION_DISP))
4234 display_line_dynarr *dla = window_display_lines (w, CMOTION_DISP);
4236 if (Dynarr_length (dla))
4238 if (Dynarr_atp (dla, 0)->modeline)
4239 return (Dynarr_atp (dla, 0)->ascent +
4240 Dynarr_atp (dla, 0)->descent);
4247 /***************************************************************************/
4249 /* displayable string routines */
4251 /***************************************************************************/
4253 /* Given a position for a string in a window, ensure that the given
4254 display line DL accurately represents the text on a line starting
4255 at the given position.
4257 Yes, this is duplicating the code of create_text_block, but it
4258 looked just too hard to change create_text_block to handle strings
4259 *and* buffers. We already make a distinction between the two
4260 elsewhere in the code so I think unifying them would require a
4261 complete MULE rewrite. Besides, the other distinction is that these
4262 functions cover text that the user *cannot edit* so we can remove
4263 everything to do with cursors, minibuffers etc. Eventually the
4264 modeline routines should be modified to use this code as it copes
4265 with many more types of display situation. */
4268 create_string_text_block (struct window *w, Lisp_Object disp_string,
4269 struct display_line *dl,
4271 prop_block_dynarr **prop,
4272 face_index default_face)
4274 struct frame *f = XFRAME (w->frame);
4275 /* Note that a lot of the buffer controlled stuff has been left in
4276 because you might well want to make use of it (selective display
4277 etc), its just the buffer text that we do not use. However, it
4278 seems to be possible for buffer to be nil sometimes so protect
4279 against this case. */
4280 struct buffer *b = BUFFERP (w->buffer) ? XBUFFER (w->buffer) : 0;
4281 struct device *d = XDEVICE (f->device);
4282 Lisp_String* s = XSTRING (disp_string);
4284 /* we're working with these a lot so precalculate them */
4285 Bytecount slen = XSTRING_LENGTH (disp_string);
4286 Bytecount bi_string_zv = slen;
4287 Bytind bi_start_pos = charcount_to_bytecount (string_data (s), start_pos);
4291 int truncate_win = b ? window_truncation_on (w) : 0;
4292 int end_glyph_width = 0;
4294 /* We're going to ditch selective display for static text, it's an
4295 FSF thing and invisible extents are the way to go here.
4296 Implementing it also relies on a number of buffer-specific
4297 functions that we don't have the luxury of being able to use
4300 /* The variable ctl-arrow allows the user to specify what characters
4301 can actually be displayed and which octal should be used for.
4302 #### This variable should probably have some rethought done to
4305 #### It would also be really nice if you could specify that
4306 the characters come out in hex instead of in octal. Mule
4307 does that by adding a ctl-hexa variable similar to ctl-arrow,
4308 but that's bogus -- we need a more general solution. I
4309 think you need to extend the concept of display tables
4310 into a more general conversion mechanism. Ideally you
4311 could specify a Lisp function that converts characters,
4312 but this violates the Second Golden Rule and besides would
4313 make things way way way way slow.
4315 So instead, we extend the display-table concept, which was
4316 historically limited to 256-byte vectors, to one of the
4319 a) A 256-entry vector, for backward compatibility;
4320 b) char-table, mapping characters to values;
4321 c) range-table, mapping ranges of characters to values;
4322 d) a list of the above.
4324 The (d) option allows you to specify multiple display tables
4325 instead of just one. Each display table can specify conversions
4326 for some characters and leave others unchanged. The way the
4327 character gets displayed is determined by the first display table
4328 with a binding for that character. This way, you could call a
4329 function `enable-hex-display' that adds a hex display-table to
4330 the list of display tables for the current buffer.
4332 #### ...not yet implemented... Also, we extend the concept of
4333 "mapping" to include a printf-like spec. Thus you can make all
4334 extended characters show up as hex with a display table like
4337 #s(range-table data ((256 524288) (format "%x")))
4339 Since more than one display table is possible, you have
4340 great flexibility in mapping ranges of characters. */
4341 Emchar printable_min = b ? (CHAR_OR_CHAR_INTP (b->ctl_arrow)
4342 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
4343 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
4344 ? 255 : 160)) : 255;
4346 Lisp_Object face_dt, window_dt;
4348 /* The text display block for this display line. */
4349 struct display_block *db = get_display_block_from_line (dl, TEXT);
4351 /* The first time through the main loop we need to force the glyph
4352 data to be updated. */
4355 /* Apparently the new extent_fragment_update returns an end position
4356 equal to the position passed in if there are no more runs to be
4358 int no_more_frags = 0;
4360 dl->used_prop_data = 0;
4362 dl->line_continuation = 0;
4364 /* set up faces to use for clearing areas, used by
4365 output_display_line */
4366 dl->default_findex = default_face;
4369 dl->left_margin_findex = default_face;
4370 dl->right_margin_findex = default_face;
4374 dl->left_margin_findex =
4375 get_builtin_face_cache_index (w, Vleft_margin_face);
4376 dl->right_margin_findex =
4377 get_builtin_face_cache_index (w, Vright_margin_face);
4381 data.ef = extent_fragment_new (disp_string, f);
4383 /* These values are used by all of the rune addition routines. We add
4384 them to this structure for ease of passing. */
4386 XSETWINDOW (data.window, w);
4390 data.bi_bufpos = bi_start_pos;
4391 data.pixpos = dl->bounds.left_in;
4392 data.last_charset = Qunbound;
4393 data.last_findex = default_face;
4394 data.result_str = Qnil;
4395 data.string = disp_string;
4397 /* Set the right boundary adjusting it to take into account any end
4398 glyph. Save the width of the end glyph for later use. */
4399 data.max_pixpos = dl->bounds.right_in;
4402 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
4404 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
4406 data.max_pixpos -= end_glyph_width;
4408 data.cursor_type = NO_CURSOR;
4412 /* I don't think we want this, string areas should not scroll with
4414 data.start_col = w->hscroll;
4415 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
4417 data.bi_start_col_enabled = 0;
4418 data.hscroll_glyph_width_adjust = 0;
4420 /* We regenerate the line from the very beginning. */
4421 Dynarr_reset (db->runes);
4423 /* Why is this less than or equal and not just less than? If the
4424 starting position is already equal to the maximum we can't add
4425 anything else, right? Wrong. We might still have a newline to
4426 add. A newline can use the room allocated for an end glyph since
4427 if we add it we know we aren't going to be adding any end
4430 /* #### Chuck -- I think this condition should be while (1).
4431 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
4432 and the begin-glyph ends exactly at the end of the window, the
4433 end-glyph and text might not be displayed. while (1) ensures
4434 that the loop terminates only when either (a) there is
4435 propagation data or (b) the end-of-line or end-of-buffer is hit.
4437 #### Also I think you need to ensure that the operation
4438 "add begin glyphs; add end glyphs; add text" is atomic and
4439 can't get interrupted in the middle. If you run off the end
4440 of the line during that operation, then you keep accumulating
4441 propagation data until you're done. Otherwise, if the (e.g.)
4442 there's a begin glyph at a particular position and attempting
4443 to display that glyph results in window-end being hit and
4444 propagation data being generated, then the character at that
4445 position won't be displayed.
4447 #### See also the comment after the end of this loop, below.
4449 while (data.pixpos <= data.max_pixpos)
4451 /* #### This check probably should not be necessary. */
4452 if (data.bi_bufpos > bi_string_zv)
4454 /* #### urk! More of this lossage! */
4459 /* Check for face changes. */
4460 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
4462 /* Now compute the face and begin/end-glyph information. */
4464 /* Remember that the extent-fragment routines deal in Bytind's. */
4465 extent_fragment_update (w, data.ef, data.bi_bufpos);
4466 /* This is somewhat cheesy but the alternative is to
4467 propagate default_face into extent_fragment_update. */
4468 if (data.findex == DEFAULT_INDEX)
4469 data.findex = default_face;
4471 get_display_tables (w, data.findex, &face_dt, &window_dt);
4473 if (data.bi_bufpos == data.ef->end)
4478 /* Determine what is next to be displayed. We first handle any
4479 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
4480 display then we determine what to do based on the character at the
4481 current buffer position. */
4483 /* If the current position is covered by an invisible extent, do
4484 nothing (except maybe add some ellipses).
4486 #### The behavior of begin and end-glyphs at the edge of an
4487 invisible extent should be investigated further. This is
4488 fairly low priority though. */
4489 if (data.ef->invisible)
4491 /* #### Chuck, perhaps you could look at this code? I don't
4492 really know what I'm doing. */
4495 Dynarr_free (*prop);
4499 /* The extent fragment code only sets this when we should
4500 really display the ellipses. It makes sure the ellipses
4501 don't get displayed more than once in a row. */
4502 if (data.ef->invisible_ellipses)
4504 struct glyph_block gb;
4506 data.ef->invisible_ellipses_already_displayed = 1;
4507 data.ef->invisible_ellipses = 0;
4509 gb.glyph = Vinvisible_text_glyph;
4510 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
4511 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
4512 /* Perhaps they shouldn't propagate if the very next thing
4513 is to display a newline (for compatibility with
4514 selective-display-ellipses)? Maybe that's too
4520 /* #### What if we we're dealing with a display table? */
4524 if (data.bi_bufpos == bi_string_zv)
4527 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4530 /* If there is propagation data, then it represents the current
4531 buffer position being displayed. Add them and advance the
4532 position counter. This might also add the minibuffer
4536 dl->used_prop_data = 1;
4537 *prop = add_propagation_runes (prop, &data);
4540 goto done; /* gee, a really narrow window */
4541 else if (data.bi_bufpos == bi_string_zv)
4543 else if (data.bi_bufpos < 0)
4544 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
4547 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4550 /* If there are end glyphs, add them to the line. These are
4551 the end glyphs for the previous run of text. We add them
4552 here rather than doing them at the end of handling the
4553 previous run so that glyphs at the beginning and end of
4554 a line are handled correctly. */
4555 else if (Dynarr_length (data.ef->end_glyphs) > 0)
4557 *prop = add_glyph_runes (&data, END_GLYPHS);
4562 /* If there are begin glyphs, add them to the line. */
4563 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
4565 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
4570 /* If at end-of-buffer, we've already processed begin and
4571 end-glyphs at this point and there's no text to process,
4573 else if (data.bi_bufpos == bi_string_zv)
4578 Lisp_Object entry = Qnil;
4579 /* Get the character at the current buffer position. */
4580 data.ch = string_char (s, data.bi_bufpos);
4581 if (!NILP (face_dt) || !NILP (window_dt))
4582 entry = display_table_entry (data.ch, face_dt, window_dt);
4584 /* If there is a display table entry for it, hand it off to
4585 add_disp_table_entry_runes and let it worry about it. */
4586 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
4588 *prop = add_disp_table_entry_runes (&data, entry);
4594 /* Check if we have hit a newline character. If so, add a marker
4595 to the line and end this loop. */
4596 else if (data.ch == '\n')
4598 /* We aren't going to be adding an end glyph so give its
4599 space back in order to make sure that the cursor can
4601 data.max_pixpos += end_glyph_width;
4605 /* If the current character is considered to be printable, then
4607 else if (data.ch >= printable_min)
4609 *prop = add_emchar_rune (&data);
4614 /* If the current character is a tab, determine the next tab
4615 starting position and add a blank rune which extends from the
4616 current pixel position to that starting position. */
4617 else if (data.ch == '\t')
4619 int tab_start_pixpos = data.pixpos;
4624 if (data.start_col > 1)
4625 tab_start_pixpos -= (space_width (w) * (data.start_col - 1));
4628 next_tab_position (w, tab_start_pixpos,
4629 dl->bounds.left_in +
4630 data.hscroll_glyph_width_adjust);
4631 if (next_tab_start > data.max_pixpos)
4633 prop_width = next_tab_start - data.max_pixpos;
4634 next_tab_start = data.max_pixpos;
4636 data.blank_width = next_tab_start - data.pixpos;
4638 (next_tab_start - tab_start_pixpos) / space_width (w);
4640 *prop = add_blank_rune (&data, w, char_tab_width);
4642 /* add_blank_rune is only supposed to be called with
4643 sizes guaranteed to fit in the available space. */
4648 struct prop_block pb;
4649 *prop = Dynarr_new (prop_block);
4651 pb.type = PROP_BLANK;
4652 pb.data.p_blank.width = prop_width;
4653 pb.data.p_blank.findex = data.findex;
4654 Dynarr_add (*prop, pb);
4660 /* If character is a control character, pass it off to
4661 add_control_char_runes.
4663 The is_*() routines have undefined results on
4664 arguments outside of the range [-1, 255]. (This
4665 often bites people who carelessly use `char' instead
4666 of `unsigned char'.)
4668 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
4670 *prop = add_control_char_runes (&data, b);
4676 /* If the character is above the ASCII range and we have not
4677 already handled it, then print it as an octal number. */
4678 else if (data.ch >= 0200)
4680 *prop = add_octal_runes (&data);
4686 /* Assume the current character is considered to be printable,
4687 then just add it. */
4690 *prop = add_emchar_rune (&data);
4695 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4701 /* Determine the starting point of the next line if we did not hit the
4702 end of the buffer. */
4703 if (data.bi_bufpos < bi_string_zv)
4705 /* #### This check is not correct. If the line terminated
4706 due to a begin-glyph or end-glyph hitting window-end, then
4707 data.ch will not point to the character at data.bi_bufpos. If
4708 you make the two changes mentioned at the top of this loop,
4709 you should be able to say '(if (*prop))'. That should also
4710 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
4713 /* The common case is that the line ended because we hit a newline.
4714 In that case, the next character is just the next buffer
4716 if (data.ch == '\n')
4718 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4721 /* Otherwise we have a buffer line which cannot fit on one display
4725 struct glyph_block gb;
4726 struct glyph_cachel *cachel;
4728 /* If the line is to be truncated then we actually have to look
4729 for the next newline. We also add the end-of-line glyph which
4730 we know will fit because we adjusted the right border before
4731 we starting laying out the line. */
4732 data.max_pixpos += end_glyph_width;
4733 data.findex = default_face;
4740 /* Now find the start of the next line. */
4741 bi_pos = bi_find_next_emchar_in_string (s, '\n', data.bi_bufpos, 1);
4743 data.cursor_type = NO_CURSOR;
4744 data.bi_bufpos = bi_pos;
4745 gb.glyph = Vtruncation_glyph;
4746 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
4750 /* The cursor can never be on the continuation glyph. */
4751 data.cursor_type = NO_CURSOR;
4753 /* data.bi_bufpos is already at the start of the next line. */
4755 dl->line_continuation = 1;
4756 gb.glyph = Vcontinuation_glyph;
4757 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
4760 if (end_glyph_width)
4761 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
4763 if (truncate_win && data.bi_bufpos == bi_string_zv)
4765 const Bufbyte* endb = charptr_n_addr (string_data (s), bi_string_zv);
4767 if (charptr_emchar (endb) != '\n')
4769 /* #### Damn this losing shit. */
4775 else if (data.bi_bufpos == bi_string_zv)
4777 /* create_text_block () adds a bogus \n marker here which screws
4778 up subwindow display. Since we never have a cursor in the
4779 gutter we can safely ignore it. */
4781 /* Calculate left whitespace boundary. */
4785 /* Whitespace past a newline is considered right whitespace. */
4786 while (elt < Dynarr_length (db->runes))
4788 struct rune *rb = Dynarr_atp (db->runes, elt);
4790 if ((rb->type == RUNE_CHAR && CHARC_ASCII_EQ (rb->object.cglyph, ' '))
4791 || rb->type == RUNE_BLANK)
4793 dl->bounds.left_white += rb->width;
4797 elt = Dynarr_length (db->runes);
4801 /* Calculate right whitespace boundary. */
4803 int elt = Dynarr_length (db->runes) - 1;
4806 while (!done && elt >= 0)
4808 struct rune *rb = Dynarr_atp (db->runes, elt);
4810 if (!(rb->type == RUNE_CHAR && CHARC_IS_SPACE (rb->object.cglyph))
4811 && !rb->type == RUNE_BLANK)
4813 dl->bounds.right_white = rb->xpos + rb->width;
4821 /* The line is blank so everything is considered to be right
4824 dl->bounds.right_white = dl->bounds.left_in;
4827 /* Set the display blocks bounds. */
4828 db->start_pos = dl->bounds.left_in;
4829 if (Dynarr_length (db->runes))
4831 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
4833 db->end_pos = rb->xpos + rb->width;
4836 db->end_pos = dl->bounds.right_white;
4838 /* update line height parameters */
4839 if (!data.new_ascent && !data.new_descent)
4841 /* We've got a blank line so initialize these values from the default
4843 default_face_font_info (data.window, &data.new_ascent,
4844 &data.new_descent, 0, 0, 0);
4847 if (data.max_pixmap_height)
4849 int height = data.new_ascent + data.new_descent;
4850 int pix_ascent, pix_descent;
4852 pix_descent = data.max_pixmap_height * data.new_descent / height;
4853 pix_ascent = data.max_pixmap_height - pix_descent;
4855 data.new_ascent = max (data.new_ascent, pix_ascent);
4856 data.new_descent = max (data.new_descent, pix_descent);
4859 dl->ascent = data.new_ascent;
4860 dl->descent = data.new_descent;
4863 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
4865 if (dl->ascent < ascent)
4866 dl->ascent = ascent;
4869 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
4871 if (dl->descent < descent)
4872 dl->descent = descent;
4875 dl->cursor_elt = data.cursor_x;
4876 /* #### lossage lossage lossage! Fix this shit! */
4877 if (data.bi_bufpos > bi_string_zv)
4878 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, bi_string_zv);
4880 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, data.bi_bufpos) - 1;
4882 data.dl->num_chars =
4883 string_column_at_point (s, dl->end_bufpos, b ? XINT (b->tab_width) : 8);
4885 /* This doesn't correctly take into account tabs and control
4886 characters but if the window isn't being truncated then this
4887 value isn't going to end up being used anyhow. */
4888 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
4890 /* #### handle horizontally scrolled line with text none of which
4891 was actually laid out. */
4893 /* #### handle any remainder of overlay arrow */
4895 if (*prop == ADD_FAILED)
4898 if (truncate_win && *prop)
4900 Dynarr_free (*prop);
4904 extent_fragment_delete (data.ef);
4906 /* #### If we started at EOB, then make sure we return a value past
4907 it so that regenerate_window will exit properly. This is bogus.
4908 The main loop should get fixed so that it isn't necessary to call
4909 this function if we are already at EOB. */
4911 if (data.bi_bufpos == bi_string_zv && bi_start_pos == bi_string_zv)
4912 return bytecount_to_charcount (string_data (s), data.bi_bufpos) + 1; /* Yuck! */
4914 return bytecount_to_charcount (string_data (s), data.bi_bufpos);
4917 /* Given a display line and a starting position, ensure that the
4918 contents of the display line accurately represent the visual
4919 representation of the buffer contents starting from the given
4920 position when displayed in the given window. The display line ends
4921 when the contents of the line reach the right boundary of the given
4924 This is very similar to generate_display_line but with the same
4925 limitations as create_string_text_block. I have taken the liberty
4926 of fixing the bytind stuff though.*/
4929 generate_string_display_line (struct window *w, Lisp_Object disp_string,
4930 struct display_line *dl,
4932 prop_block_dynarr **prop,
4933 face_index default_face)
4937 /* you must set bounds before calling this. */
4939 /* Reset what this line is using. */
4940 if (dl->display_blocks)
4941 Dynarr_reset (dl->display_blocks);
4942 if (dl->left_glyphs)
4944 Dynarr_free (dl->left_glyphs);
4945 dl->left_glyphs = 0;
4947 if (dl->right_glyphs)
4949 Dynarr_free (dl->right_glyphs);
4950 dl->right_glyphs = 0;
4953 /* We aren't generating a modeline at the moment. */
4956 /* Create a display block for the text region of the line. */
4957 ret_bufpos = create_string_text_block (w, disp_string, dl, start_pos,
4958 prop, default_face);
4959 dl->bufpos = start_pos;
4960 if (dl->end_bufpos < dl->bufpos)
4961 dl->end_bufpos = dl->bufpos;
4963 /* If there are left glyphs associated with any character in the
4964 text block, then create a display block to handle them. */
4965 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
4966 create_left_glyph_block (w, dl, 0);
4968 /* If there are right glyphs associated with any character in the
4969 text block, then create a display block to handle them. */
4970 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
4971 create_right_glyph_block (w, dl);
4976 /* This is ripped off from regenerate_window. All we want to do is
4977 loop through elements in the string creating display lines until we
4978 have covered the provided area. Simple really. */
4980 generate_displayable_area (struct window *w, Lisp_Object disp_string,
4981 int xpos, int ypos, int width, int height,
4982 display_line_dynarr* dla,
4984 face_index default_face)
4986 int yend = ypos + height;
4989 prop_block_dynarr *prop = 0;
4990 layout_bounds bounds;
4994 /* if there's nothing to do then do nothing. code after this assumes
4995 there is something to do. */
4996 if (NILP (disp_string))
4999 s_zv = XSTRING_CHAR_LENGTH (disp_string);
5001 bounds.left_out = xpos;
5002 bounds.right_out = xpos + width;
5003 /* The inner boundaries mark where the glyph margins are located. */
5004 bounds.left_in = bounds.left_out + window_left_margin_width (w);
5005 bounds.right_in = bounds.right_out - window_right_margin_width (w);
5006 /* We cannot fully calculate the whitespace boundaries as they
5007 depend on the contents of the line being displayed. */
5008 bounds.left_white = bounds.left_in;
5009 bounds.right_white = bounds.right_in;
5013 struct display_line dl;
5014 struct display_line *dlp;
5018 if (Dynarr_length (dla) < Dynarr_largest (dla))
5020 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5031 dlp->bounds = bounds;
5033 next_pos = generate_string_display_line (w, disp_string, dlp, start_pos,
5034 &prop, default_face);
5035 /* we need to make sure that we continue along the line if there
5036 is more left to display otherwise we just end up redisplaying
5037 the same chunk over and over again. */
5038 if (next_pos == start_pos && next_pos < s_zv)
5041 start_pos = next_pos;
5043 dlp->ypos = ypos + dlp->ascent;
5044 ypos = dlp->ypos + dlp->descent;
5048 int visible_height = dlp->ascent + dlp->descent;
5050 dlp->clip = (ypos - yend);
5051 visible_height -= dlp->clip;
5053 if (visible_height < VERTICAL_CLIP (w, 1))
5056 free_display_line (dlp);
5063 Dynarr_add (dla, *dlp);
5065 /* #### This type of check needs to be done down in the
5066 generate_display_line call. */
5067 if (start_pos >= s_zv)
5076 /***************************************************************************/
5078 /* window-regeneration routines */
5080 /***************************************************************************/
5082 /* For a given window and starting position in the buffer it contains,
5083 ensure that the TYPE display lines accurately represent the
5084 presentation of the window. We pass the buffer instead of getting
5085 it from the window since redisplay_window may have temporarily
5086 changed it to the echo area buffer. */
5089 regenerate_window (struct window *w, Bufpos start_pos, Bufpos point, int type)
5091 struct frame *f = XFRAME (w->frame);
5092 struct buffer *b = XBUFFER (w->buffer);
5093 int ypos = WINDOW_TEXT_TOP (w);
5094 int yend; /* set farther down */
5095 int yclip = WINDOW_TEXT_TOP_CLIP (w);
5098 prop_block_dynarr *prop;
5099 layout_bounds bounds;
5100 display_line_dynarr *dla;
5103 /* The lines had better exist by this point. */
5104 if (!(dla = window_display_lines (w, type)))
5107 w->max_line_len = 0;
5109 /* Normally these get updated in redisplay_window but it is possible
5110 for this function to get called from some other points where that
5111 update may not have occurred. This acts as a safety check. */
5112 if (!Dynarr_length (w->face_cachels))
5113 reset_face_cachels (w);
5114 if (!Dynarr_length (w->glyph_cachels))
5115 reset_glyph_cachels (w);
5117 Fset_marker (w->start[type], make_int (start_pos), w->buffer);
5118 Fset_marker (w->pointm[type], make_int (point), w->buffer);
5119 w->last_point_x[type] = -1;
5120 w->last_point_y[type] = -1;
5122 /* Make sure a modeline is in the structs if needed. */
5123 need_modeline = ensure_modeline_generated (w, type);
5125 /* Wait until here to set this so that the structs have a modeline
5126 generated in the case where one didn't exist. */
5127 yend = WINDOW_TEXT_BOTTOM (w);
5129 bounds = calculate_display_line_boundaries (w, 0);
5131 /* 97/3/14 jhod: stuff added here to support pre-prompts (used for input systems) */
5132 if (MINI_WINDOW_P (w)
5133 && (!NILP (Vminibuf_prompt) || !NILP (Vminibuf_preprompt))
5134 && !echo_area_active (f)
5135 && start_pos == BUF_BEGV (b))
5137 struct prop_block pb;
5139 prop = Dynarr_new (prop_block);
5141 string = concat2(Vminibuf_preprompt, Vminibuf_prompt);
5142 pb.type = PROP_MINIBUF_PROMPT;
5143 pb.data.p_string.str = XSTRING_DATA(string);
5144 pb.data.p_string.len = XSTRING_LENGTH(string);
5145 Dynarr_add (prop, pb);
5150 /* When we are computing things for scrolling purposes, make
5151 sure at least one line is always generated */
5152 force = (type == CMOTION_DISP);
5154 /* Make sure this is set always */
5155 /* Note the conversion at end */
5156 w->window_end_pos[type] = start_pos;
5157 while (ypos < yend || force)
5159 struct display_line dl;
5160 struct display_line *dlp;
5163 if (Dynarr_length (dla) < Dynarr_largest (dla))
5165 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5176 dlp->bounds = bounds;
5178 start_pos = generate_display_line (w, dlp, 1, start_pos, &prop, type);
5180 if (yclip > dlp->ascent)
5182 /* this should never happen, but if it does just display the
5187 dlp->ypos = (ypos + dlp->ascent) - yclip;
5188 ypos = dlp->ypos + dlp->descent;
5190 /* See if we've been asked to start midway through a line, for
5191 partial display line scrolling. */
5194 dlp->top_clip = yclip;
5202 int visible_height = dlp->ascent + dlp->descent;
5204 dlp->clip = (ypos - yend);
5205 /* Although this seems strange we could have a single very
5206 tall line visible for which we need to account for both
5207 the top clip and the bottom clip. */
5208 visible_height -= (dlp->clip + dlp->top_clip);
5210 if (visible_height < VERTICAL_CLIP (w, 1) && !force)
5213 free_display_line (dlp);
5220 if (dlp->cursor_elt != -1)
5222 /* #### This check is steaming crap. Have to get things
5223 fixed so when create_text_block hits EOB, we're done,
5225 if (w->last_point_x[type] == -1)
5227 w->last_point_x[type] = dlp->cursor_elt;
5228 w->last_point_y[type] = Dynarr_length (dla);
5232 /* #### This means that we've added a cursor at EOB
5233 twice. Yuck oh yuck. */
5234 struct display_block *db =
5235 get_display_block_from_line (dlp, TEXT);
5237 Dynarr_atp (db->runes, dlp->cursor_elt)->cursor_type = NO_CURSOR;
5238 dlp->cursor_elt = -1;
5242 if (dlp->num_chars > w->max_line_len)
5243 w->max_line_len = dlp->num_chars;
5245 Dynarr_add (dla, *dlp);
5247 /* #### This isn't right, but it is close enough for now. */
5248 w->window_end_pos[type] = start_pos;
5250 /* #### This type of check needs to be done down in the
5251 generate_display_line call. */
5252 if (start_pos > BUF_ZV (b))
5261 /* #### More not quite right, but close enough. */
5262 /* Ben sez: apparently window_end_pos[] is measured
5263 as the number of characters between the window end and the
5264 end of the buffer? This seems rather weirdo. What's
5265 the justification for this?
5267 JV sez: Because BUF_Z (b) would be a good initial value, however
5268 that can change. This representation allows initalizing with 0.
5270 w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type];
5274 /* We know that this is the right thing to use because we put it
5275 there when we first started working in this function. */
5276 generate_modeline (w, Dynarr_atp (dla, 0), type);
5280 #define REGEN_INC_FIND_START_END \
5282 /* Determine start and end of lines. */ \
5283 if (!Dynarr_length (cdla)) \
5287 if (Dynarr_atp (cdla, 0)->modeline && Dynarr_atp (ddla, 0)->modeline) \
5291 else if (!Dynarr_atp (cdla, 0)->modeline \
5292 && !Dynarr_atp (ddla, 0)->modeline) \
5297 abort (); /* structs differ */ \
5299 dla_end = Dynarr_length (cdla) - 1; \
5302 start_pos = (Dynarr_atp (cdla, dla_start)->bufpos \
5303 + Dynarr_atp (cdla, dla_start)->offset); \
5304 /* If this isn't true, then startp has changed and we need to do a \
5306 if (startp != start_pos) \
5309 /* Point is outside the visible region so give up. */ \
5310 if (pointm < start_pos) \
5315 /* This attempts to incrementally update the display structures. It
5316 returns a boolean indicating success or failure. This function is
5317 very similar to regenerate_window_incrementally and is in fact only
5318 called from that function. However, because of the nature of the
5319 changes it deals with it sometimes makes different assumptions
5320 which can lead to success which are much more difficult to make
5321 when dealing with buffer changes. */
5324 regenerate_window_extents_only_changed (struct window *w, Bufpos startp,
5326 Charcount beg_unchanged,
5327 Charcount end_unchanged)
5329 struct buffer *b = XBUFFER (w->buffer);
5330 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5331 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5335 int first_line, last_line;
5337 /* Don't define this in the loop where it is used because we
5338 definitely want its value to survive between passes. */
5339 prop_block_dynarr *prop = NULL;
5341 /* If we don't have any buffer change recorded but the modiff flag has
5342 been incremented, then fail. I'm not sure of the exact circumstances
5343 under which this can happen, but I believe that it is probably a
5344 reasonable happening. */
5345 if (!point_visible (w, pointm, CURRENT_DISP)
5346 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b))
5349 /* If the cursor is moved we attempt to update it. If we succeed we
5350 go ahead and proceed with the optimization attempt. */
5351 if (!EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5352 || pointm != marker_position (w->last_point[CURRENT_DISP]))
5354 struct frame *f = XFRAME (w->frame);
5355 struct device *d = XDEVICE (f->device);
5356 struct frame *sel_f = device_selected_frame (d);
5359 if (w->last_point_x[CURRENT_DISP] != -1
5360 && w->last_point_y[CURRENT_DISP] != -1)
5363 if (redisplay_move_cursor (w, pointm, WINDOW_TTY_P (w)))
5365 /* Always regenerate the modeline in case it is
5366 displaying the current line or column. */
5367 regenerate_modeline (w);
5371 else if (w != XWINDOW (FRAME_SELECTED_WINDOW (sel_f)))
5373 if (f->modeline_changed)
5374 regenerate_modeline (w);
5382 if (beg_unchanged == -1 && end_unchanged == -1)
5385 /* assert: There are no buffer modifications or they are all below the
5386 visible region. We assume that regenerate_window_incrementally has
5387 not called us unless this is true. */
5389 REGEN_INC_FIND_START_END;
5391 /* If the changed are starts before the visible area, give up. */
5392 if (beg_unchanged < startp)
5395 /* Find what display line the extent changes first affect. */
5397 while (line <= dla_end)
5399 struct display_line *dl = Dynarr_atp (cdla, line);
5400 Bufpos lstart = dl->bufpos + dl->offset;
5401 Bufpos lend = dl->end_bufpos + dl->offset;
5403 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5409 /* If the changes are below the visible area then if point hasn't
5410 moved return success otherwise fail in order to be safe. */
5413 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5414 && pointm == marker_position (w->last_point[CURRENT_DISP]))
5420 /* At this point we know what line the changes first affect. We now
5421 begin redrawing lines as long as we are still in the affected
5422 region and the line's size and positioning don't change.
5423 Otherwise we fail. If we fail we will have altered the desired
5424 structs which could lead to an assertion failure. However, if we
5425 fail the next thing that is going to happen is a full regen so we
5426 will actually end up being safe. */
5427 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5428 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5429 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
5430 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
5432 first_line = last_line = line;
5433 while (line <= dla_end)
5435 Bufpos old_start, old_end, new_start;
5436 struct display_line *cdl = Dynarr_atp (cdla, line);
5437 struct display_line *ddl = Dynarr_atp (ddla, line);
5438 struct display_block *db;
5441 assert (cdl->bufpos == ddl->bufpos);
5442 assert (cdl->end_bufpos == ddl->end_bufpos);
5443 assert (cdl->offset == ddl->offset);
5445 db = get_display_block_from_line (ddl, TEXT);
5446 initial_size = Dynarr_length (db->runes);
5447 old_start = ddl->bufpos + ddl->offset;
5448 old_end = ddl->end_bufpos + ddl->offset;
5450 /* If this is the first line being updated and it used
5451 propagation data, fail. Otherwise we'll be okay because
5452 we'll have the necessary propagation data. */
5453 if (line == first_line && ddl->used_prop_data)
5456 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5457 &prop, DESIRED_DISP);
5460 /* #### If there is propagated stuff the fail. We could
5461 probably actually deal with this if the line had propagated
5462 information when originally created by a full
5470 /* If any line position parameters have changed or a
5471 cursor has disappeared or disappeared, fail. */
5472 db = get_display_block_from_line (ddl, TEXT);
5473 if (cdl->ypos != ddl->ypos
5474 || cdl->ascent != ddl->ascent
5475 || cdl->descent != ddl->descent
5476 || cdl->top_clip != ddl->top_clip
5477 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5478 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1)
5479 || old_start != ddl->bufpos
5480 || old_end != ddl->end_bufpos
5481 || initial_size != Dynarr_length (db->runes))
5486 if (ddl->cursor_elt != -1)
5488 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5489 w->last_point_y[DESIRED_DISP] = line;
5494 /* If the extent changes end on the line we just updated then
5495 we're done. Otherwise go on to the next line. */
5496 if (end_unchanged <= ddl->end_bufpos)
5502 redisplay_update_line (w, first_line, last_line, 1);
5506 /* Attempt to update the display data structures based on knowledge of
5507 the changed region in the buffer. Returns a boolean indicating
5508 success or failure. If this function returns a failure then a
5509 regenerate_window _must_ be performed next in order to maintain
5510 invariants located here. */
5513 regenerate_window_incrementally (struct window *w, Bufpos startp,
5516 struct buffer *b = XBUFFER (w->buffer);
5517 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5518 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5519 Charcount beg_unchanged, end_unchanged;
5520 Charcount extent_beg_unchanged, extent_end_unchanged;
5526 /* If this function is called, the current and desired structures
5527 had better be identical. If they are not, then that is a bug. */
5528 assert (Dynarr_length (cdla) == Dynarr_length (ddla));
5530 /* We don't handle minibuffer windows yet. The minibuffer prompt
5532 if (MINI_WINDOW_P (w))
5535 extent_beg_unchanged = BUF_EXTENT_BEGIN_UNCHANGED (b);
5536 extent_end_unchanged = (BUF_EXTENT_END_UNCHANGED (b) == -1
5538 : BUF_Z (b) - BUF_EXTENT_END_UNCHANGED (b));
5540 /* If nothing has changed in the buffer, then make sure point is ok
5542 if (BUF_BEGIN_UNCHANGED (b) == -1 && BUF_END_UNCHANGED (b) == -1)
5543 return regenerate_window_extents_only_changed (w, startp, pointm,
5544 extent_beg_unchanged,
5545 extent_end_unchanged);
5547 /* We can't deal with deleted newlines. */
5548 if (BUF_NEWLINE_WAS_DELETED (b))
5551 beg_unchanged = BUF_BEGIN_UNCHANGED (b);
5552 end_unchanged = (BUF_END_UNCHANGED (b) == -1
5554 : BUF_Z (b) - BUF_END_UNCHANGED (b));
5556 REGEN_INC_FIND_START_END;
5558 /* If the changed area starts before the visible area, give up. */
5559 if (beg_unchanged < startp)
5562 /* Find what display line the buffer changes first affect. */
5564 while (line <= dla_end)
5566 struct display_line *dl = Dynarr_atp (cdla, line);
5567 Bufpos lstart = dl->bufpos + dl->offset;
5568 Bufpos lend = dl->end_bufpos + dl->offset;
5570 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5576 /* If the changes are below the visible area then if point hasn't
5577 moved return success otherwise fail in order to be safe. */
5579 return regenerate_window_extents_only_changed (w, startp, pointm,
5580 extent_beg_unchanged,
5581 extent_end_unchanged);
5583 /* At this point we know what line the changes first affect. We
5584 now redraw that line. If the changes are contained within it
5585 we are going to succeed and can update just that one line.
5586 Otherwise we fail. If we fail we will have altered the desired
5587 structs which could lead to an assertion failure. However, if
5588 we fail the next thing that is going to happen is a full regen
5589 so we will actually end up being safe. */
5592 prop_block_dynarr *prop = NULL;
5593 struct display_line *cdl = Dynarr_atp (cdla, line);
5594 struct display_line *ddl = Dynarr_atp (ddla, line);
5596 assert (cdl->bufpos == ddl->bufpos);
5597 assert (cdl->end_bufpos == ddl->end_bufpos);
5598 assert (cdl->offset == ddl->offset);
5600 /* If the line continues to next display line, fail. */
5601 if (ddl->line_continuation)
5604 /* If the line was generated using propagation data, fail. */
5605 if (ddl->used_prop_data)
5608 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5609 &prop, DESIRED_DISP);
5612 /* If there is propagated stuff then it is pretty much a
5613 guarantee that more than just the one line is affected. */
5620 /* If the line continues to next display line, fail. */
5621 if (ddl->line_continuation)
5624 /* If any line position parameters have changed or a
5625 cursor has disappeared or disappeared, fail. */
5626 if (cdl->ypos != ddl->ypos
5627 || cdl->ascent != ddl->ascent
5628 || cdl->descent != ddl->descent
5629 || cdl->top_clip != ddl->top_clip
5630 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5631 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1))
5636 /* If the changed area also ends on this line, then we may be in
5637 business. Update everything and return success. */
5638 if (end_unchanged >= ddl->bufpos && end_unchanged <= ddl->end_bufpos)
5640 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5641 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5642 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp),
5644 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm),
5647 if (ddl->cursor_elt != -1)
5649 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5650 w->last_point_y[DESIRED_DISP] = line;
5653 redisplay_update_line (w, line, line, 1);
5654 regenerate_modeline (w);
5656 /* #### For now we just flush the cache until this has been
5657 tested. After that is done, this should correct the
5659 Dynarr_reset (w->line_start_cache);
5661 /* Adjust the extent changed boundaries to remove any
5662 overlap with the buffer changes since we've just
5663 successfully updated that area. */
5664 if (extent_beg_unchanged != -1
5665 && extent_beg_unchanged >= beg_unchanged
5666 && extent_beg_unchanged < end_unchanged)
5667 extent_beg_unchanged = end_unchanged;
5669 if (extent_end_unchanged != -1
5670 && extent_end_unchanged >= beg_unchanged
5671 && extent_end_unchanged < end_unchanged)
5672 extent_end_unchanged = beg_unchanged - 1;
5674 if (extent_end_unchanged <= extent_beg_unchanged)
5675 extent_beg_unchanged = extent_end_unchanged = -1;
5677 /* This could lead to odd results if it fails, but since the
5678 buffer changes update succeeded this probably will to.
5679 We already know that the extent changes start at or after
5680 the line because we checked before entering the loop. */
5681 if (extent_beg_unchanged != -1
5682 && extent_end_unchanged != -1
5683 && ((extent_beg_unchanged < ddl->bufpos)
5684 || (extent_end_unchanged > ddl->end_bufpos)))
5685 return regenerate_window_extents_only_changed (w, startp, pointm,
5686 extent_beg_unchanged,
5687 extent_end_unchanged);
5697 /* Given a window and a point, update the given display lines such
5698 that point is displayed in the middle of the window.
5699 Return the window's new start position. */
5702 regenerate_window_point_center (struct window *w, Bufpos point, int type)
5706 /* We need to make sure that the modeline is generated so that the
5707 window height can be calculated correctly. */
5708 ensure_modeline_generated (w, type);
5710 startp = start_with_line_at_pixpos (w, point, window_half_pixpos (w));
5711 regenerate_window (w, startp, point, type);
5712 Fset_marker (w->start[type], make_int (startp), w->buffer);
5717 /* Given a window and a set of display lines, return a boolean
5718 indicating whether the given point is contained within. */
5721 point_visible (struct window *w, Bufpos point, int type)
5723 struct buffer *b = XBUFFER (w->buffer);
5724 display_line_dynarr *dla = window_display_lines (w, type);
5727 if (Dynarr_length (dla) && Dynarr_atp (dla, 0)->modeline)
5732 if (Dynarr_length (dla) > first_line)
5735 struct display_line *dl = Dynarr_atp (dla, first_line);
5738 end = BUF_Z (b) - w->window_end_pos[type] - 1;
5740 if (point >= start && point <= end)
5742 if (!MINI_WINDOW_P (w) && scroll_on_clipped_lines)
5744 dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
5746 if (point >= (dl->bufpos + dl->offset)
5747 && point <= (dl->end_bufpos + dl->offset))
5762 /* Return pixel position the middle of the window, not including the
5763 modeline and any potential horizontal scrollbar. */
5766 window_half_pixpos (struct window *w)
5768 return WINDOW_TEXT_TOP (w) + (WINDOW_TEXT_HEIGHT (w) >> 1);
5771 /* Return the display line which is currently in the middle of the
5772 window W for display lines TYPE. */
5775 line_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5777 display_line_dynarr *dla;
5780 int first_elt = (MINI_WINDOW_P (w) ? 0 : 1);
5782 if (type == CMOTION_DISP)
5783 regenerate_window (w, start, point, type);
5785 dla = window_display_lines (w, type);
5786 half = window_half_pixpos (w);
5788 for (elt = first_elt; elt < Dynarr_length (dla); elt++)
5790 struct display_line *dl = Dynarr_atp (dla, elt);
5791 int line_bot = dl->ypos + dl->descent;
5793 if (line_bot > half)
5797 /* We may not have a line at the middle if the end of the buffer is
5802 /* Return a value for point that would place it at the beginning of
5803 the line which is in the middle of the window. */
5806 point_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5808 /* line_at_center will regenerate the display structures, if necessary. */
5809 int line = line_at_center (w, type, start, point);
5812 return BUF_ZV (XBUFFER (w->buffer));
5815 display_line_dynarr *dla = window_display_lines (w, type);
5816 struct display_line *dl = Dynarr_atp (dla, line);
5822 /* For a given window, ensure that the current visual representation
5826 redisplay_window (Lisp_Object window, int skip_selected)
5828 struct window *w = XWINDOW (window);
5829 struct frame *f = XFRAME (w->frame);
5830 struct device *d = XDEVICE (f->device);
5831 Lisp_Object old_buffer = w->buffer;
5832 Lisp_Object the_buffer = w->buffer;
5834 int echo_active = 0;
5839 int selected_in_its_frame;
5840 int selected_globally;
5841 int skip_output = 0;
5842 int truncation_changed;
5843 int inactive_minibuffer =
5844 (MINI_WINDOW_P (w) &&
5845 (f != device_selected_frame (d)) &&
5846 !is_surrogate_for_selected_frame (f));
5848 /* #### In the new world this function actually does a bunch of
5849 optimizations such as buffer-based scrolling, but none of that is
5852 /* If this is a combination window, do its children; that's all.
5853 The selected window is always a leaf so we don't check for
5854 skip_selected here. */
5855 if (!NILP (w->vchild))
5857 redisplay_windows (w->vchild, skip_selected);
5860 if (!NILP (w->hchild))
5862 redisplay_windows (w->hchild, skip_selected);
5866 /* Is this window the selected window on its frame? */
5867 selected_in_its_frame = (w == XWINDOW (FRAME_SELECTED_WINDOW (f)));
5869 selected_in_its_frame &&
5870 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
5871 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d &&
5872 XFRAME(DEVICE_SELECTED_FRAME(d)) == f;
5873 if (skip_selected && selected_in_its_frame)
5876 /* It is possible that the window is not fully initialized yet. */
5877 if (NILP (w->buffer))
5880 if (MINI_WINDOW_P (w) && echo_area_active (f))
5882 w->buffer = the_buffer = Vecho_area_buffer;
5886 b = XBUFFER (w->buffer);
5890 old_pointm = selected_globally
5892 : marker_position (w->pointm[CURRENT_DISP]);
5897 if (selected_globally)
5899 pointm = BUF_PT (b);
5903 pointm = marker_position (w->pointm[CURRENT_DISP]);
5905 if (pointm < BUF_BEGV (b))
5906 pointm = BUF_BEGV (b);
5907 else if (pointm > BUF_ZV (b))
5908 pointm = BUF_ZV (b);
5911 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm), the_buffer);
5913 /* If the buffer has changed we have to invalidate all of our face
5915 if ((!echo_active && b != window_display_buffer (w))
5916 || !Dynarr_length (w->face_cachels)
5917 || f->faces_changed)
5918 reset_face_cachels (w);
5920 mark_face_cachels_as_not_updated (w);
5922 /* Ditto the glyph cache elements, although we do *not* invalidate
5923 the cache purely because glyphs have changed - this is now
5924 handled by the dirty flag.*/
5925 if ((!echo_active && b != window_display_buffer (w))
5926 || !Dynarr_length (w->glyph_cachels) || f->faces_changed)
5927 reset_glyph_cachels (w);
5929 mark_glyph_cachels_as_not_updated (w);
5931 /* If the marker's buffer is not the window's buffer, then we need
5932 to find a new starting position. */
5933 if (!MINI_WINDOW_P (w)
5934 && !EQ (Fmarker_buffer (w->start[CURRENT_DISP]), w->buffer))
5936 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
5938 goto regeneration_done;
5943 old_startp = marker_position (w->start[CURRENT_DISP]);
5948 startp = marker_position (w->start[CURRENT_DISP]);
5949 if (startp < BUF_BEGV (b))
5950 startp = BUF_BEGV (b);
5951 else if (startp > BUF_ZV (b))
5952 startp = BUF_ZV (b);
5954 Fset_marker (w->start[DESIRED_DISP], make_int (startp), the_buffer);
5956 truncation_changed = (find_window_mirror (w)->truncate_win !=
5957 window_truncation_on (w));
5959 /* If w->force_start is set, then some function set w->start and we
5960 should display from there and change point, if necessary, to
5961 ensure that it is visible. */
5962 if (w->force_start || inactive_minibuffer)
5965 w->last_modified[DESIRED_DISP] = Qzero;
5966 w->last_facechange[DESIRED_DISP] = Qzero;
5968 regenerate_window (w, startp, pointm, DESIRED_DISP);
5970 if (!point_visible (w, pointm, DESIRED_DISP) && !inactive_minibuffer)
5972 pointm = point_at_center (w, DESIRED_DISP, 0, 0);
5974 if (selected_globally)
5975 BUF_SET_PT (b, pointm);
5977 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm),
5980 /* #### BUFU amounts of overkill just to get the cursor
5981 location marked properly. FIX ME FIX ME FIX ME */
5982 regenerate_window (w, startp, pointm, DESIRED_DISP);
5985 goto regeneration_done;
5988 /* If nothing has changed since the last redisplay, then we just
5989 need to make sure that point is still visible. */
5990 if (XINT (w->last_modified[CURRENT_DISP]) >= BUF_MODIFF (b)
5991 && XINT (w->last_facechange[CURRENT_DISP]) >= BUF_FACECHANGE (b)
5993 /* This check is to make sure we restore the minibuffer after a
5994 temporary change to the echo area. */
5995 && !(MINI_WINDOW_P (w) && f->buffers_changed)
5996 && !f->frame_changed
5997 && !truncation_changed
5998 /* check whether start is really at the beginning of a line GE */
5999 && (!w->start_at_line_beg || beginning_of_line_p (b, startp))
6002 /* Check if the cursor has actually moved. */
6003 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
6004 && pointm == marker_position (w->last_point[CURRENT_DISP])
6005 && selected_globally
6006 && !w->windows_changed
6008 && !f->extents_changed
6009 && !f->faces_changed
6010 && !f->glyphs_changed
6011 && !f->subwindows_changed
6012 /* && !f->subwindows_state_changed*/
6013 && !f->point_changed
6014 && !f->windows_structure_changed)
6016 /* If not, we're done. */
6017 if (f->modeline_changed)
6018 regenerate_modeline (w);
6021 goto regeneration_done;
6025 /* If the new point is visible in the redisplay structures,
6026 then let the output update routines handle it, otherwise
6027 do things the hard way. */
6028 if (!w->windows_changed
6030 && !f->extents_changed
6031 && !f->faces_changed
6032 && !f->glyphs_changed
6033 && !f->subwindows_changed
6034 /* && !f->subwindows_state_changed*/
6035 && !f->windows_structure_changed)
6037 if (point_visible (w, pointm, CURRENT_DISP)
6038 && w->last_point_x[CURRENT_DISP] != -1
6039 && w->last_point_y[CURRENT_DISP] != -1)
6041 if (redisplay_move_cursor (w, pointm, FRAME_TTY_P (f)))
6043 /* Always regenerate in case it is displaying
6044 the current line or column. */
6045 regenerate_modeline (w);
6048 goto regeneration_done;
6051 else if (!selected_in_its_frame && !f->point_changed)
6053 if (f->modeline_changed)
6054 regenerate_modeline (w);
6057 goto regeneration_done;
6061 /* If we weren't able to take the shortcut method, then use
6062 the brute force method. */
6063 regenerate_window (w, startp, pointm, DESIRED_DISP);
6065 if (point_visible (w, pointm, DESIRED_DISP))
6066 goto regeneration_done;
6070 /* Check if the starting point is no longer at the beginning of a
6071 line, in which case find a new starting point. We also recenter
6072 if our start position is equal to point-max. Otherwise we'll end
6073 up with a blank window. */
6074 else if (((w->start_at_line_beg || MINI_WINDOW_P (w))
6075 && !(startp == BUF_BEGV (b)
6076 || BUF_FETCH_CHAR (b, startp - 1) == '\n'))
6077 || (pointm == startp &&
6078 EQ (Fmarker_buffer (w->last_start[CURRENT_DISP]), w->buffer) &&
6079 startp < marker_position (w->last_start[CURRENT_DISP]))
6080 || (startp == BUF_ZV (b)))
6082 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6084 goto regeneration_done;
6086 /* See if we can update the data structures locally based on
6087 knowledge of what changed in the buffer. */
6088 else if (!w->windows_changed
6090 && !f->faces_changed
6091 && !f->glyphs_changed
6092 && !f->subwindows_changed
6093 /* && !f->subwindows_state_changed*/
6094 && !f->windows_structure_changed
6095 && !f->frame_changed
6096 && !truncation_changed
6098 && regenerate_window_incrementally (w, startp, pointm))
6100 if (f->modeline_changed
6101 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b)
6102 || XINT (w->last_facechange[CURRENT_DISP]) < BUF_FACECHANGE (b))
6103 regenerate_modeline (w);
6106 goto regeneration_done;
6108 /* #### This is where a check for structure based scrolling would go. */
6109 /* If all else fails, try just regenerating and see what happens. */
6112 regenerate_window (w, startp, pointm, DESIRED_DISP);
6114 if (point_visible (w, pointm, DESIRED_DISP))
6115 goto regeneration_done;
6118 /* We still haven't gotten the window regenerated with point
6119 visible. Next we try scrolling a little and see if point comes
6120 back onto the screen. */
6121 if (scroll_step > 0)
6123 int scrolled = scroll_conservatively;
6124 for (; scrolled >= 0; scrolled -= scroll_step)
6126 startp = vmotion (w, startp,
6127 (pointm < startp) ? -scroll_step : scroll_step, 0);
6128 regenerate_window (w, startp, pointm, DESIRED_DISP);
6130 if (point_visible (w, pointm, DESIRED_DISP))
6131 goto regeneration_done;
6135 /* We still haven't managed to get the screen drawn with point on
6136 the screen, so just center it and be done with it. */
6137 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6142 /* If the window's frame is changed then reset the current display
6143 lines in order to force a full repaint. */
6144 if (f->frame_changed)
6146 display_line_dynarr *cla = window_display_lines (w, CURRENT_DISP);
6151 /* Must do this before calling redisplay_output_window because it
6152 sets some markers on the window. */
6155 w->buffer = old_buffer;
6156 Fset_marker (w->pointm[DESIRED_DISP], make_int (old_pointm), old_buffer);
6157 Fset_marker (w->start[DESIRED_DISP], make_int (old_startp), old_buffer);
6160 /* These also have to be set before calling redisplay_output_window
6161 since it sets the CURRENT_DISP values based on them. */
6162 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
6163 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
6164 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
6165 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
6169 Bufpos start = marker_position (w->start[DESIRED_DISP]);
6170 Bufpos end = (w->window_end_pos[DESIRED_DISP] == -1
6172 : BUF_Z (b) - w->window_end_pos[DESIRED_DISP] - 1);
6173 /* Don't pollute the cache if not sure if we are correct */
6174 if (w->start_at_line_beg)
6175 update_line_start_cache (w, start, end, pointm, 1);
6176 redisplay_output_window (w);
6178 * If we just displayed the echo area, the line start cache is
6179 * no longer valid, because the minibuffer window is associated
6180 * with the window now.
6183 w->line_cache_last_updated = make_int (-1);
6186 /* #### This should be dependent on face changes and will need to be
6187 somewhere else once tty updates occur on a per-frame basis. */
6188 mark_face_cachels_as_clean (w);
6190 /* The glyph cachels only get dirty if someone changed something.
6191 Since redisplay has now effectively ended we can reset the dirty
6192 flag since everything must be up-to-date. */
6194 mark_glyph_cachels_as_clean (w);
6196 w->windows_changed = 0;
6199 /* Call buffer_reset_changes for all buffers present in any window
6200 currently visible in all frames on all devices. #### There has to
6201 be a better way to do this. */
6204 reset_buffer_changes_mapfun (struct window *w, void *ignored_closure)
6206 buffer_reset_changes (XBUFFER (w->buffer));
6211 reset_buffer_changes (void)
6213 Lisp_Object frmcons, devcons, concons;
6215 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
6217 struct frame *f = XFRAME (XCAR (frmcons));
6219 if (FRAME_REPAINT_P (f))
6220 map_windows (f, reset_buffer_changes_mapfun, 0);
6224 /* Ensure that all windows underneath the given window in the window
6225 hierarchy are correctly displayed. */
6228 redisplay_windows (Lisp_Object window, int skip_selected)
6230 for (; !NILP (window) ; window = XWINDOW (window)->next)
6232 redisplay_window (window, skip_selected);
6237 call_redisplay_end_triggers (struct window *w, void *closure)
6239 Bufpos lrpos = w->last_redisplay_pos;
6240 w->last_redisplay_pos = 0;
6241 if (!NILP (w->buffer)
6242 && !NILP (w->redisplay_end_trigger)
6247 if (MARKERP (w->redisplay_end_trigger)
6248 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
6249 pos = marker_position (w->redisplay_end_trigger);
6250 else if (INTP (w->redisplay_end_trigger))
6251 pos = XINT (w->redisplay_end_trigger);
6254 w->redisplay_end_trigger = Qnil;
6261 XSETWINDOW (window, w);
6262 va_run_hook_with_args_in_buffer (XBUFFER (w->buffer),
6263 Qredisplay_end_trigger_functions,
6265 w->redisplay_end_trigger);
6266 w->redisplay_end_trigger = Qnil;
6273 /* Ensure that all windows on the given frame are correctly displayed. */
6276 redisplay_frame (struct frame *f, int preemption_check)
6278 struct device *d = XDEVICE (f->device);
6280 if (preemption_check)
6282 /* The preemption check itself takes a lot of time,
6283 so normally don't do it here. We do it if called
6284 from Lisp, though (`redisplay-frame'). */
6287 REDISPLAY_PREEMPTION_CHECK;
6292 if (!internal_equal (f->old_buffer_alist, f->buffer_alist, 0))
6296 f->old_buffer_alist = Freplace_list (f->old_buffer_alist,
6298 XSETFRAME (frame, f);
6299 va_run_hook_with_args (Qbuffer_list_changed_hook, 1, frame);
6302 /* Before we put a hold on frame size changes, attempt to process
6303 any which are already pending. */
6304 if (f->size_change_pending)
6305 change_frame_size (f, f->new_height, f->new_width, 0);
6307 /* If frame size might need to be changed, due to changed size
6308 of toolbars, scrollbars etc, change it now */
6309 if (f->size_slipped)
6311 adjust_frame_size (f);
6312 assert (!f->size_slipped);
6315 /* The menubar, toolbar, and icon updates must be done before
6316 hold_frame_size_changes is called and we are officially
6317 'in_display'. They may eval lisp code which may call Fsignal.
6318 If in_display is set Fsignal will abort. */
6320 #ifdef HAVE_MENUBARS
6321 /* Update the menubar. It is done first since it could change
6322 the menubar's visibility. This way we avoid having flashing
6323 caused by an Expose event generated by the visibility change
6325 update_frame_menubars (f);
6326 #endif /* HAVE_MENUBARS */
6327 #ifdef HAVE_TOOLBARS
6328 /* Update the toolbars. */
6329 update_frame_toolbars (f);
6330 #endif /* HAVE_TOOLBARS */
6331 /* Gutter update proper has to be done inside display when no frame
6332 size changes can occur, thus we separately update the gutter
6333 geometry here if it needs it. */
6334 update_frame_gutter_geometry (f);
6336 /* If we clear the frame we have to force its contents to be redrawn. */
6338 f->frame_changed = 1;
6340 /* Invalidate the subwindow caches. We use subwindows_changed here
6341 to cause subwindows to get instantiated. This is because
6342 subwindows_state_changed is less strict - dealing with things
6343 like the clicked state of button. We have to do this before
6344 redisplaying the gutters as subwindows get unmapped in the
6346 if (f->frame_changed)
6347 reset_frame_subwindow_instance_cache (f);
6349 if (f->frame_changed || f->subwindows_changed)
6351 /* we have to do this so the gutter gets regenerated. */
6352 reset_gutter_display_lines (f);
6355 hold_frame_size_changes ();
6357 /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */
6358 /* Within this section, we are defenseless and assume that the
6359 following cannot happen:
6361 1) garbage collection
6362 2) Lisp code evaluation
6363 3) frame size changes
6365 We ensure (3) by calling hold_frame_size_changes(), which
6366 will cause any pending frame size changes to get put on hold
6367 till after the end of the critical section. (1) follows
6368 automatically if (2) is met. #### Unfortunately, there are
6369 some places where Lisp code can be called within this section.
6370 We need to remove them.
6372 If Fsignal() is called during this critical section, we
6375 If garbage collection is called during this critical section,
6376 we simply return. #### We should abort instead.
6378 #### If a frame-size change does occur we should probably
6379 actually be preempting redisplay. */
6381 MAYBE_DEVMETH (d, frame_output_begin, (f));
6383 /* We can now update the gutters, safe in the knowledge that our
6384 efforts won't get undone. */
6386 /* This can call lisp, but redisplay is protected by binding
6387 inhibit_quit. More importantly the code involving display lines
6388 *assumes* that GC will not happen and so does not GCPRO
6389 anything. Since we use this code the whole time with the gutters
6390 we cannot allow GC to happen when manipulating the gutters. */
6391 update_frame_gutters (f);
6393 /* Erase the frame before outputting its contents. */
6396 MAYBE_DEVMETH (d, clear_frame, (f));
6399 /* Do the selected window first. */
6400 redisplay_window (FRAME_SELECTED_WINDOW (f), 0);
6402 /* Then do the rest. */
6403 redisplay_windows (f->root_window, 1);
6405 MAYBE_DEVMETH (d, frame_output_end, (f));
6407 update_frame_title (f);
6409 CLASS_RESET_CHANGED_FLAGS (f);
6410 f->window_face_cache_reset = 0;
6411 f->echo_area_garbaged = 0;
6414 if (!f->size_change_pending)
6415 f->size_changed = 0;
6417 /* ----------------- END CRITICAL REDISPLAY SECTION ---------------- */
6419 /* Allow frame size changes to occur again.
6421 #### what happens if changes to other frames happen? */
6422 unhold_one_frame_size_changes (f);
6424 map_windows (f, call_redisplay_end_triggers, 0);
6428 /* Ensure that all frames on the given device are correctly displayed.
6429 If AUTOMATIC is non-zero, and the device implementation indicates
6430 no automatic redisplay, as printers do, then the device is not
6431 redisplayed. AUTOMATIC is set to zero when called from lisp
6432 functions (redraw-device) and (redisplay-device), and to non-zero
6433 when called from "lazy" redisplay();
6437 redisplay_device (struct device *d, int automatic)
6439 Lisp_Object frame, frmcons;
6441 int size_change_failed = 0;
6445 && (MAYBE_INT_DEVMETH (d, device_implementation_flags, ())
6446 & XDEVIMPF_NO_AUTO_REDISPLAY))
6449 if (DEVICE_STREAM_P (d)) /* nothing to do */
6452 /* It is possible that redisplay has been called before the
6453 device is fully initialized. If so then continue with the
6455 if (NILP (DEVICE_SELECTED_FRAME (d)))
6458 REDISPLAY_PREEMPTION_CHECK;
6462 /* Always do the selected frame first. */
6463 frame = DEVICE_SELECTED_FRAME (d);
6467 if (f->icon_changed || f->windows_changed)
6468 update_frame_icon (f);
6470 if (FRAME_REPAINT_P (f))
6472 if (CLASS_REDISPLAY_FLAGS_CHANGEDP(f))
6474 preempted = redisplay_frame (f, 0);
6480 /* If the frame redisplay did not get preempted, then this flag
6481 should have gotten set to 0. It might be possible for that
6482 not to happen if a size change event were to occur at an odd
6483 time. To make sure we don't miss anything we simply don't
6484 reset the top level flags until the condition ends up being
6485 in the right state. */
6486 if (f->size_changed)
6487 size_change_failed = 1;
6490 DEVICE_FRAME_LOOP (frmcons, d)
6492 f = XFRAME (XCAR (frmcons));
6494 if (f == XFRAME (DEVICE_SELECTED_FRAME (d)))
6497 if (f->icon_changed || f->windows_changed)
6498 update_frame_icon (f);
6500 if (FRAME_REPAINT_P (f))
6502 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (f))
6504 preempted = redisplay_frame (f, 0);
6510 if (f->size_change_pending)
6511 size_change_failed = 1;
6515 /* If we get here then we redisplayed all of our frames without
6516 getting preempted so mark ourselves as clean. */
6517 CLASS_RESET_CHANGED_FLAGS (d);
6519 if (!size_change_failed)
6520 d->size_changed = 0;
6526 restore_profiling_redisplay_flag (Lisp_Object val)
6528 profiling_redisplay_flag = XINT (val);
6532 /* Ensure that all windows on all frames on all devices are displaying
6533 the current contents of their respective buffers. */
6536 redisplay_without_hooks (void)
6538 Lisp_Object devcons, concons;
6539 int size_change_failed = 0;
6540 int count = specpdl_depth ();
6542 if (profiling_active)
6544 record_unwind_protect (restore_profiling_redisplay_flag,
6545 make_int (profiling_redisplay_flag));
6546 profiling_redisplay_flag = 1;
6549 if (asynch_device_change_pending)
6550 handle_asynch_device_change ();
6552 if (!GLOBAL_REDISPLAY_FLAGS_CHANGEDP &&
6553 !disable_preemption && preemption_count < max_preempts)
6556 DEVICE_LOOP_NO_BREAK (devcons, concons)
6558 struct device *d = XDEVICE (XCAR (devcons));
6561 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (d))
6563 preempted = redisplay_device (d, 1);
6568 RESET_CHANGED_SET_FLAGS;
6572 /* See comment in redisplay_device. */
6573 if (d->size_changed)
6574 size_change_failed = 1;
6577 preemption_count = 0;
6579 /* Mark redisplay as accurate */
6580 GLOBAL_RESET_CHANGED_FLAGS;
6581 RESET_CHANGED_SET_FLAGS;
6585 mark_all_faces_as_clean ();
6589 if (!size_change_failed)
6592 reset_buffer_changes ();
6595 unbind_to (count, Qnil);
6601 if (last_display_warning_tick != display_warning_tick &&
6602 !inhibit_warning_display)
6604 /* If an error occurs during this function, oh well.
6605 If we report another warning, we could get stuck in an
6606 infinite loop reporting warnings. */
6607 call0_trapping_errors (0, Qdisplay_warning_buffer);
6608 last_display_warning_tick = display_warning_tick;
6610 /* The run_hook_trapping_errors functions are smart enough not
6611 to do any evalling if the hook function is empty, so there
6612 should not be any significant time loss. All places in the
6613 C code that call redisplay() are prepared to handle GCing,
6614 so we should be OK. */
6615 #ifndef INHIBIT_REDISPLAY_HOOKS
6616 run_hook_trapping_errors ("Error in pre-redisplay-hook",
6617 Qpre_redisplay_hook);
6618 #endif /* INHIBIT_REDISPLAY_HOOKS */
6620 redisplay_without_hooks ();
6622 #ifndef INHIBIT_REDISPLAY_HOOKS
6623 run_hook_trapping_errors ("Error in post-redisplay-hook",
6624 Qpost_redisplay_hook);
6625 #endif /* INHIBIT_REDISPLAY_HOOKS */
6629 static char window_line_number_buf[32];
6631 /* Efficiently determine the window line number, and return a pointer
6632 to its printed representation. Do this regardless of whether
6633 line-number-mode is on. The first line in the buffer is counted as
6634 1. If narrowing is in effect, the lines are counted from the
6635 beginning of the visible portion of the buffer. */
6637 window_line_number (struct window *w, int type)
6639 struct device *d = XDEVICE (XFRAME (w->frame)->device);
6640 struct buffer *b = XBUFFER (w->buffer);
6641 /* Be careful in the order of these tests. The first clause will
6642 fail if DEVICE_SELECTED_FRAME == Qnil (since w->frame cannot be).
6643 This can occur when the frame title is computed really early */
6645 ((EQ(DEVICE_SELECTED_FRAME(d), w->frame) &&
6646 (w == XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame(d)))) &&
6647 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
6648 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d )
6650 : marker_position (w->pointm[type]));
6653 line = buffer_line_number (b, pos, 1);
6655 long_to_string (window_line_number_buf, line + 1);
6657 return window_line_number_buf;
6661 /* Given a character representing an object in a modeline
6662 specification, return a string (stored into the global array
6663 `mode_spec_bufbyte_string') with the information that object
6666 This function is largely unchanged from previous versions of the
6669 Warning! This code is also used for frame titles and can be called
6670 very early in the device/frame update process! JV
6674 decode_mode_spec (struct window *w, Emchar spec, int type)
6676 Lisp_Object obj = Qnil;
6677 const char *str = NULL;
6678 struct buffer *b = XBUFFER (w->buffer);
6680 Dynarr_reset (mode_spec_bufbyte_string);
6684 /* print buffer name */
6689 /* print visited file name */
6694 /* print the current column */
6697 Bufpos pt = (w == XWINDOW (Fselected_window (Qnil)))
6699 : marker_position (w->pointm[type]);
6700 int col = column_at_point (b, pt, 1) + !!column_number_start_at_one;
6703 long_to_string (buf, col);
6705 Dynarr_add_many (mode_spec_bufbyte_string,
6706 (const Bufbyte *) buf, strlen (buf));
6708 goto decode_mode_spec_done;
6710 /* print the file coding system */
6714 Lisp_Object codesys = b->buffer_file_coding_system;
6715 /* Be very careful here not to get an error. */
6716 if (NILP (codesys) || SYMBOLP (codesys) || CODING_SYSTEMP (codesys))
6718 codesys = Ffind_coding_system (codesys);
6719 if (CODING_SYSTEMP (codesys))
6720 obj = XCODING_SYSTEM_MNEMONIC (codesys);
6723 #endif /* FILE_CODING */
6726 /* print the current line number */
6728 str = window_line_number (w, type);
6731 /* print value of mode-name (obsolete) */
6736 /* print hyphen and frame number, if != 1 */
6740 struct frame *f = XFRAME (w->frame);
6741 if (FRAME_TTY_P (f) && f->order_count > 1 && f->order_count <= 99999999)
6743 /* Naughty, naughty */
6744 char * writable_str = alloca_array (char, 10);
6745 sprintf (writable_str, "-%d", f->order_count);
6749 #endif /* HAVE_TTY */
6752 /* print Narrow if appropriate */
6754 if (BUF_BEGV (b) > BUF_BEG (b)
6755 || BUF_ZV (b) < BUF_Z (b))
6759 /* print %, * or hyphen, if buffer is read-only, modified or neither */
6761 str = (!NILP (b->read_only)
6763 : ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6768 /* print * or hyphen -- XEmacs change to allow a buffer to be
6769 read-only but still indicate whether it is modified. */
6771 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6773 : (!NILP (b->read_only)
6778 /* #### defined in 19.29 decode_mode_spec, but not in
6779 modeline-format doc string. */
6780 /* This differs from %* in that it ignores read-only-ness. */
6782 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6787 /* print process status */
6789 obj = Fget_buffer_process (w->buffer);
6791 str = GETTEXT ("no process");
6793 obj = Fsymbol_name (Fprocess_status (obj));
6796 /* Print name of selected frame. */
6798 obj = XFRAME (w->frame)->name;
6801 /* indicate TEXT or BINARY */
6803 /* #### NT does not use this any more. Now what? */
6807 /* print percent of buffer above top of window, or Top, Bot or All */
6810 Bufpos pos = marker_position (w->start[type]);
6812 /* This had better be while the desired lines are being done. */
6813 if (w->window_end_pos[type] <= BUF_Z (b) - BUF_ZV (b))
6815 if (pos <= BUF_BEGV (b))
6820 else if (pos <= BUF_BEGV (b))
6824 /* This hard limit is ok since the string it will hold has a
6825 fixed maximum length of 3. But just to be safe... */
6827 Charcount chars = pos - BUF_BEGV (b);
6828 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6830 /* Avoid overflow on big buffers */
6831 int percent = total > LONG_MAX/200 ?
6832 (chars + total/200) / (total / 100) :
6833 (chars * 100 + total/2) / total;
6835 /* We can't normally display a 3-digit number, so get us a
6836 2-digit number that is close. */
6840 sprintf (buf, "%d%%", percent);
6841 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6844 goto decode_mode_spec_done;
6849 /* print percent of buffer above bottom of window, perhaps plus
6850 Top, or print Bottom or All */
6853 Bufpos toppos = marker_position (w->start[type]);
6854 Bufpos botpos = BUF_Z (b) - w->window_end_pos[type];
6856 /* botpos is only accurate as of the last redisplay, so we can
6857 only treat it as a hint. In particular, after erase-buffer,
6858 botpos may be negative. */
6859 if (botpos < toppos)
6862 if (botpos >= BUF_ZV (b))
6864 if (toppos <= BUF_BEGV (b))
6871 /* This hard limit is ok since the string it will hold has a
6872 fixed maximum length of around 6. But just to be safe... */
6874 Charcount chars = botpos - BUF_BEGV (b);
6875 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6877 /* Avoid overflow on big buffers */
6878 int percent = total > LONG_MAX/200 ?
6879 (chars + total/200) / (total / 100) :
6880 (chars * 100 + total/2) / max (total, 1);
6882 /* We can't normally display a 3-digit number, so get us a
6883 2-digit number that is close. */
6887 if (toppos <= BUF_BEGV (b))
6888 sprintf (buf, "Top%d%%", percent);
6890 sprintf (buf, "%d%%", percent);
6892 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6895 goto decode_mode_spec_done;
6905 /* print one [ for each recursive editing level. */
6910 if (command_loop_level > 5)
6916 for (i = 0; i < command_loop_level; i++)
6917 Dynarr_add (mode_spec_bufbyte_string, '[');
6919 goto decode_mode_spec_done;
6922 /* print one ] for each recursive editing level. */
6927 if (command_loop_level > 5)
6933 for (i = 0; i < command_loop_level; i++)
6934 Dynarr_add (mode_spec_bufbyte_string, ']');
6936 goto decode_mode_spec_done;
6939 /* print infinitely many dashes -- handle at top level now */
6946 Dynarr_add_many (mode_spec_bufbyte_string,
6948 XSTRING_LENGTH (obj));
6950 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) str, strlen (str));
6952 decode_mode_spec_done:
6953 Dynarr_add (mode_spec_bufbyte_string, '\0');
6956 /* Given a display line, free all of its data structures. */
6959 free_display_line (struct display_line *dl)
6963 if (dl->display_blocks)
6965 for (block = 0; block < Dynarr_largest (dl->display_blocks); block++)
6967 struct display_block *db = Dynarr_atp (dl->display_blocks, block);
6969 Dynarr_free (db->runes);
6972 Dynarr_free (dl->display_blocks);
6973 dl->display_blocks = NULL;
6976 if (dl->left_glyphs)
6978 Dynarr_free (dl->left_glyphs);
6979 dl->left_glyphs = NULL;
6982 if (dl->right_glyphs)
6984 Dynarr_free (dl->right_glyphs);
6985 dl->right_glyphs = NULL;
6990 /* Given an array of display lines, free them and all data structures
6991 contained within them. */
6994 free_display_lines (display_line_dynarr *dla)
6998 for (line = 0; line < Dynarr_largest (dla); line++)
7000 free_display_line (Dynarr_atp (dla, line));
7006 /* Call internal free routine for each set of display lines. */
7009 free_display_structs (struct window_mirror *mir)
7011 if (mir->current_display_lines)
7013 free_display_lines (mir->current_display_lines);
7014 mir->current_display_lines = 0;
7017 if (mir->desired_display_lines)
7019 free_display_lines (mir->desired_display_lines);
7020 mir->desired_display_lines = 0;
7026 mark_glyph_block_dynarr (glyph_block_dynarr *gba)
7030 glyph_block *gb = Dynarr_atp (gba, 0);
7031 glyph_block *gb_last = Dynarr_atp (gba, Dynarr_length (gba));
7033 for (; gb < gb_last; gb++)
7035 if (!NILP (gb->glyph))
7036 mark_object (gb->glyph);
7037 if (!NILP (gb->extent))
7038 mark_object (gb->extent);
7043 /* See the comment in image_instantiate_cache_result as to why marking
7044 the glyph will also mark the image_instance. */
7046 mark_redisplay_structs (display_line_dynarr *dla)
7048 display_line *dl = Dynarr_atp (dla, 0);
7049 display_line *dl_last = Dynarr_atp (dla, Dynarr_length (dla));
7051 for (; dl < dl_last; dl++)
7053 display_block_dynarr *dba = dl->display_blocks;
7054 display_block *db = Dynarr_atp (dba, 0);
7055 display_block *db_last = Dynarr_atp (dba, Dynarr_length (dba));
7057 for (; db < db_last; db++)
7059 rune_dynarr *ra = db->runes;
7060 rune *r = Dynarr_atp (ra, 0);
7061 rune *r_last = Dynarr_atp (ra, Dynarr_length (ra));
7063 for (; r < r_last; r++)
7065 if (r->type == RUNE_DGLYPH)
7067 if (!NILP (r->object.dglyph.glyph))
7068 mark_object (r->object.dglyph.glyph);
7069 if (!NILP (r->object.dglyph.extent))
7070 mark_object (r->object.dglyph.extent);
7075 mark_glyph_block_dynarr (dl->left_glyphs);
7076 mark_glyph_block_dynarr (dl->right_glyphs);
7081 mark_window_mirror (struct window_mirror *mir)
7083 mark_redisplay_structs (mir->current_display_lines);
7084 mark_redisplay_structs (mir->desired_display_lines);
7087 mark_window_mirror (mir->next);
7090 mark_window_mirror (mir->hchild);
7091 else if (mir->vchild)
7092 mark_window_mirror (mir->vchild);
7096 mark_redisplay (void)
7098 Lisp_Object frmcons, devcons, concons;
7100 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
7102 struct frame *f = XFRAME (XCAR (frmcons));
7103 update_frame_window_mirror (f);
7104 mark_window_mirror (f->root_mirror);
7109 /*****************************************************************************
7110 Line Start Cache Description and Rationale
7112 The traditional scrolling code in Emacs breaks in a variable height world.
7113 It depends on the key assumption that the number of lines that can be
7114 displayed at any given time is fixed. This led to a complete separation
7115 of the scrolling code from the redisplay code. In order to fully support
7116 variable height lines, the scrolling code must actually be tightly
7117 integrated with redisplay. Only redisplay can determine how many lines
7118 will be displayed on a screen for any given starting point.
7120 What is ideally wanted is a complete list of the starting buffer position
7121 for every possible display line of a buffer along with the height of that
7122 display line. Maintaining such a full list would be very expensive. We
7123 settle for having it include information for all areas which we happen to
7124 generate anyhow (i.e. the region currently being displayed) and for those
7125 areas we need to work with.
7127 In order to ensure that the cache accurately represents what redisplay
7128 would actually show, it is necessary to invalidate it in many situations.
7129 If the buffer changes, the starting positions may no longer be correct.
7130 If a face or an extent has changed then the line heights may have altered.
7131 These events happen frequently enough that the cache can end up being
7132 constantly disabled. With this potentially constant invalidation when is
7133 the cache ever useful?
7135 Even if the cache is invalidated before every single usage, it is
7136 necessary. Scrolling often requires knowledge about display lines which
7137 are actually above or below the visible region. The cache provides a
7138 convenient light-weight method of storing this information for multiple
7139 display regions. This knowledge is necessary for the scrolling code to
7140 always obey the First Golden Rule of Redisplay.
7142 If the cache already contains all of the information that the scrolling
7143 routines happen to need so that it doesn't have to go generate it, then we
7144 are able to obey the Third Golden Rule of Redisplay. The first thing we
7145 do to help out the cache is to always add the displayed region. This
7146 region had to be generated anyway, so the cache ends up getting the
7147 information basically for free. In those cases where a user is simply
7148 scrolling around viewing a buffer there is a high probability that this is
7149 sufficient to always provide the needed information. The second thing we
7150 can do is be smart about invalidating the cache.
7152 TODO -- Be smart about invalidating the cache. Potential places:
7154 + Insertions at end-of-line which don't cause line-wraps do not alter the
7155 starting positions of any display lines. These types of buffer
7156 modifications should not invalidate the cache. This is actually a large
7157 optimization for redisplay speed as well.
7159 + Buffer modifications frequently only affect the display of lines at and
7160 below where they occur. In these situations we should only invalidate
7161 the part of the cache starting at where the modification occurs.
7163 In case you're wondering, the Second Golden Rule of Redisplay is not
7165 ****************************************************************************/
7167 /* This will get used quite a bit so we don't want to be constantly
7168 allocating and freeing it. */
7169 static line_start_cache_dynarr *internal_cache;
7171 /* Makes internal_cache represent the TYPE display structs and only
7172 the TYPE display structs. */
7175 update_internal_cache_list (struct window *w, int type)
7178 display_line_dynarr *dla = window_display_lines (w, type);
7180 Dynarr_reset (internal_cache);
7181 for (line = 0; line < Dynarr_length (dla); line++)
7183 struct display_line *dl = Dynarr_atp (dla, line);
7189 struct line_start_cache lsc;
7191 lsc.start = dl->bufpos;
7192 lsc.end = dl->end_bufpos;
7193 lsc.height = dl->ascent + dl->descent;
7195 Dynarr_add (internal_cache, lsc);
7200 /* Reset the line cache if necessary. This should be run at the
7201 beginning of any function which access the cache. */
7204 validate_line_start_cache (struct window *w)
7206 struct buffer *b = XBUFFER (w->buffer);
7207 struct frame *f = XFRAME (w->frame);
7209 if (!w->line_cache_validation_override)
7211 /* f->extents_changed used to be in here because extent face and
7212 size changes can cause text shifting. However, the extent
7213 covering the region is constantly having its face set and
7214 priority altered by the mouse code. This means that the line
7215 start cache is constantly being invalidated. This is bad
7216 since the mouse code also triggers heavy usage of the cache.
7217 Since it is an unlikely that f->extents being changed
7218 indicates that the cache really needs to be updated and if it
7219 does redisplay will catch it pretty quickly we no longer
7220 invalidate the cache if it is set. This greatly speeds up
7221 dragging out regions with the mouse. */
7222 if (XINT (w->line_cache_last_updated) < BUF_MODIFF (b)
7226 Dynarr_reset (w->line_start_cache);
7231 /* Return the very first buffer position contained in the given
7232 window's cache, or -1 if the cache is empty. Assumes that the
7236 line_start_cache_start (struct window *w)
7238 line_start_cache_dynarr *cache = w->line_start_cache;
7240 if (!Dynarr_length (cache))
7243 return Dynarr_atp (cache, 0)->start;
7246 /* Return the very last buffer position contained in the given
7247 window's cache, or -1 if the cache is empty. Assumes that the
7251 line_start_cache_end (struct window *w)
7253 line_start_cache_dynarr *cache = w->line_start_cache;
7255 if (!Dynarr_length (cache))
7258 return Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
7261 /* Return the index of the line POINT is contained within in window
7262 W's line start cache. It will enlarge the cache or move the cache
7263 window in order to have POINT be present in the cache. MIN_PAST is
7264 a guarantee of the number of entries in the cache present on either
7265 side of POINT (unless a buffer boundary is hit). If MIN_PAST is -1
7266 then it will be treated as 0, but the cache window will not be
7267 allowed to shift. Returns -1 if POINT cannot be found in the cache
7271 point_in_line_start_cache (struct window *w, Bufpos point, int min_past)
7273 struct buffer *b = XBUFFER (w->buffer);
7274 line_start_cache_dynarr *cache = w->line_start_cache;
7275 unsigned int top, bottom, pos;
7277 validate_line_start_cache (w);
7278 w->line_cache_validation_override++;
7280 /* Let functions pass in negative values, but we still treat -1
7282 /* #### bogosity alert */
7283 if (min_past < 0 && min_past != -1)
7284 min_past = -min_past;
7286 if (!Dynarr_length (cache) || line_start_cache_start (w) > point
7287 || line_start_cache_end (w) < point)
7290 int win_char_height = window_char_height (w, 1);
7292 /* Occasionally we get here with a 0 height
7293 window. find_next_newline_no_quit will abort if we pass it a
7294 count of 0 so handle that case. */
7295 if (!win_char_height)
7296 win_char_height = 1;
7298 if (!Dynarr_length (cache))
7300 Bufpos from = find_next_newline_no_quit (b, point, -1);
7301 Bufpos to = find_next_newline_no_quit (b, from, win_char_height);
7303 update_line_start_cache (w, from, to, point, 0);
7305 if (!Dynarr_length (cache))
7307 w->line_cache_validation_override--;
7312 assert (Dynarr_length (cache));
7315 while (line_start_cache_start (w) > point
7316 && (loop < cache_adjustment || min_past == -1))
7320 from = line_start_cache_start (w);
7321 if (from <= BUF_BEGV (b))
7324 from = find_next_newline_no_quit (b, from, -win_char_height);
7325 to = line_start_cache_end (w);
7327 update_line_start_cache (w, from, to, point, 0);
7331 if (line_start_cache_start (w) > point)
7335 from = find_next_newline_no_quit (b, point, -1);
7336 if (from >= BUF_ZV (b))
7338 to = find_next_newline_no_quit (b, from, -win_char_height);
7343 to = find_next_newline_no_quit (b, from, win_char_height);
7345 update_line_start_cache (w, from, to, point, 0);
7349 while (line_start_cache_end (w) < point
7350 && (loop < cache_adjustment || min_past == -1))
7354 to = line_start_cache_end (w);
7355 if (to >= BUF_ZV (b))
7358 from = line_start_cache_end (w);
7359 to = find_next_newline_no_quit (b, from, win_char_height);
7361 update_line_start_cache (w, from, to, point, 0);
7365 if (line_start_cache_end (w) < point)
7369 from = find_next_newline_no_quit (b, point, -1);
7370 if (from >= BUF_ZV (b))
7372 to = find_next_newline_no_quit (b, from, -win_char_height);
7377 to = find_next_newline_no_quit (b, from, win_char_height);
7379 update_line_start_cache (w, from, to, point, 0);
7383 assert (Dynarr_length (cache));
7388 /* This could happen if the buffer is narrowed. */
7389 if (line_start_cache_start (w) > point
7390 || line_start_cache_end (w) < point)
7392 w->line_cache_validation_override--;
7398 top = Dynarr_length (cache) - 1;
7403 unsigned int new_pos;
7406 pos = (bottom + top + 1) >> 1;
7407 start = Dynarr_atp (cache, pos)->start;
7408 end = Dynarr_atp (cache, pos)->end;
7410 if (point >= start && point <= end)
7412 if (pos < min_past && line_start_cache_start (w) > BUF_BEGV (b))
7415 find_next_newline_no_quit (b, line_start_cache_start (w),
7417 Bufpos to = line_start_cache_end (w);
7419 update_line_start_cache (w, from, to, point, 0);
7420 goto find_point_loop;
7422 else if ((Dynarr_length (cache) - pos - 1) < min_past
7423 && line_start_cache_end (w) < BUF_ZV (b))
7425 Bufpos from = line_start_cache_end (w);
7426 Bufpos to = find_next_newline_no_quit (b, from,
7431 update_line_start_cache (w, from, to, point, 0);
7432 goto find_point_loop;
7436 w->line_cache_validation_override--;
7440 else if (point > end)
7442 else if (point < start)
7447 new_pos = (bottom + top + 1) >> 1;
7450 w->line_cache_validation_override--;
7456 /* Return a boolean indicating if POINT would be visible in window W
7457 if display of the window was to begin at STARTP. */
7460 point_would_be_visible (struct window *w, Bufpos startp, Bufpos point)
7462 struct buffer *b = XBUFFER (w->buffer);
7463 int pixpos = -WINDOW_TEXT_TOP_CLIP(w);
7464 int bottom = WINDOW_TEXT_HEIGHT (w);
7467 /* If point is before the intended start it obviously can't be visible. */
7471 /* If point or start are not in the accessible buffer range, then
7473 if (startp < BUF_BEGV (b) || startp > BUF_ZV (b)
7474 || point < BUF_BEGV (b) || point > BUF_ZV (b))
7477 validate_line_start_cache (w);
7478 w->line_cache_validation_override++;
7480 start_elt = point_in_line_start_cache (w, startp, 0);
7481 if (start_elt == -1)
7483 w->line_cache_validation_override--;
7487 assert (line_start_cache_start (w) <= startp
7488 && line_start_cache_end (w) >= startp);
7494 /* Expand the cache if necessary. */
7495 if (start_elt == Dynarr_length (w->line_start_cache))
7498 Dynarr_atp (w->line_start_cache, start_elt - 1)->start;
7500 start_elt = point_in_line_start_cache (w, old_startp,
7501 window_char_height (w, 0));
7503 /* We've already actually processed old_startp, so increment
7507 /* If this happens we didn't add any extra elements. Bummer. */
7508 if (start_elt == Dynarr_length (w->line_start_cache))
7510 w->line_cache_validation_override--;
7515 height = Dynarr_atp (w->line_start_cache, start_elt)->height;
7517 if (pixpos + height > bottom)
7519 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7521 w->line_cache_validation_override--;
7527 if (point <= Dynarr_atp (w->line_start_cache, start_elt)->end)
7529 w->line_cache_validation_override--;
7537 /* For the given window W, if display starts at STARTP, what will be
7538 the buffer position at the beginning or end of the last line
7539 displayed. The end of the last line is also know as the window end
7542 WARNING: It is possible that redisplay failed to layout any lines for the
7543 windows. Under normal circumstances this is rare. However it seems that it
7544 does occur in the following situation: A mouse event has come in and we
7545 need to compute its location in a window. That code (in
7546 pixel_to_glyph_translation) already can handle 0 as an error return value.
7548 #### With a little work this could probably be reworked as just a
7549 call to start_with_line_at_pixpos. */
7552 start_end_of_last_line (struct window *w, Bufpos startp, int end,
7555 struct buffer *b = XBUFFER (w->buffer);
7556 line_start_cache_dynarr *cache = w->line_start_cache;
7558 int bottom = WINDOW_TEXT_HEIGHT (w);
7562 validate_line_start_cache (w);
7563 w->line_cache_validation_override++;
7565 if (startp < BUF_BEGV (b))
7566 startp = BUF_BEGV (b);
7567 else if (startp > BUF_ZV (b))
7568 startp = BUF_ZV (b);
7571 start_elt = point_in_line_start_cache (w, cur_start, 0);
7572 if (start_elt == -1)
7573 return may_error ? 0 : startp;
7577 int height = Dynarr_atp (cache, start_elt)->height;
7579 cur_start = Dynarr_atp (cache, start_elt)->start;
7581 if (pixpos + height > bottom)
7583 /* Adjust for any possible clip. */
7584 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7589 w->line_cache_validation_override--;
7593 return BUF_BEGV (b);
7597 w->line_cache_validation_override--;
7599 return Dynarr_atp (cache, start_elt)->end;
7601 return Dynarr_atp (cache, start_elt)->start;
7607 if (start_elt == Dynarr_length (cache))
7609 Bufpos from = line_start_cache_end (w);
7610 int win_char_height = window_char_height (w, 0);
7611 Bufpos to = find_next_newline_no_quit (b, from,
7616 /* We've hit the end of the bottom so that's what it is. */
7617 if (from >= BUF_ZV (b))
7619 w->line_cache_validation_override--;
7623 update_line_start_cache (w, from, to, BUF_PT (b), 0);
7625 /* Updating the cache invalidates any current indexes. */
7626 start_elt = point_in_line_start_cache (w, cur_start, -1) + 1;
7631 /* For the given window W, if display starts at STARTP, what will be
7632 the buffer position at the beginning of the last line displayed. */
7635 start_of_last_line (struct window *w, Bufpos startp)
7637 return start_end_of_last_line (w, startp, 0 , 0);
7640 /* For the given window W, if display starts at STARTP, what will be
7641 the buffer position at the end of the last line displayed. This is
7642 also know as the window end position. */
7645 end_of_last_line (struct window *w, Bufpos startp)
7647 return start_end_of_last_line (w, startp, 1, 0);
7651 end_of_last_line_may_error (struct window *w, Bufpos startp)
7653 return start_end_of_last_line (w, startp, 1, 1);
7657 /* For window W, what does the starting position have to be so that
7658 the line containing POINT will cover pixel position PIXPOS. */
7661 start_with_line_at_pixpos (struct window *w, Bufpos point, int pixpos)
7663 struct buffer *b = XBUFFER (w->buffer);
7665 Bufpos cur_pos, prev_pos = point;
7666 int point_line_height;
7667 int pixheight = pixpos - WINDOW_TEXT_TOP (w);
7669 validate_line_start_cache (w);
7670 w->line_cache_validation_override++;
7672 cur_elt = point_in_line_start_cache (w, point, 0);
7673 /* #### See comment in update_line_start_cache about big minibuffers. */
7676 w->line_cache_validation_override--;
7680 point_line_height = Dynarr_atp (w->line_start_cache, cur_elt)->height;
7684 cur_pos = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7686 pixheight -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7688 /* Do not take into account the value of vertical_clip here.
7689 That is the responsibility of the calling functions. */
7692 w->line_cache_validation_override--;
7693 if (-pixheight > point_line_height)
7694 /* We can't make the target line cover pixpos, so put it
7695 above pixpos. That way it will at least be visible. */
7705 int win_char_height;
7707 if (cur_pos <= BUF_BEGV (b))
7709 w->line_cache_validation_override--;
7710 return BUF_BEGV (b);
7713 win_char_height = window_char_height (w, 0);
7714 if (!win_char_height)
7715 win_char_height = 1;
7717 from = find_next_newline_no_quit (b, cur_pos, -win_char_height);
7718 to = line_start_cache_end (w);
7719 update_line_start_cache (w, from, to, point, 0);
7721 cur_elt = point_in_line_start_cache (w, cur_pos, 2) - 1;
7722 assert (cur_elt >= -1);
7723 /* This used to be cur_elt>=0 under the assumption that if
7724 point is in the top line and not at BUF_BEGV, then
7725 setting the window_start to a newline before the start of
7726 the first line will always cause scrolling.
7728 However in my (jv) opinion this is wrong. That new line
7729 can be hidden in various ways: invisible extents, an
7730 explicit window-start not at a newline character etc.
7731 The existence of those are indeed known to create crashes
7732 on that assert. So we have no option but to continue the
7733 search if we found point at the top of the line_start_cache
7735 cur_pos = Dynarr_atp (w->line_start_cache,0)->start;
7741 /* For window W, what does the starting position have to be so that
7742 the line containing point is on display line LINE. If LINE is
7743 positive it is considered to be the number of lines from the top of
7744 the window (0 is the top line). If it is negative the number is
7745 considered to be the number of lines from the bottom (-1 is the
7749 start_with_point_on_display_line (struct window *w, Bufpos point, int line)
7751 validate_line_start_cache (w);
7752 w->line_cache_validation_override++;
7756 int cur_elt = point_in_line_start_cache (w, point, line);
7758 if (cur_elt - line < 0)
7759 cur_elt = 0; /* Hit the top */
7763 w->line_cache_validation_override--;
7764 return Dynarr_atp (w->line_start_cache, cur_elt)->start;
7768 /* The calculated value of pixpos is correct for the bottom line
7769 or what we want when line is -1. Therefore we subtract one
7770 because we have already handled one line. */
7771 int new_line = -line - 1;
7772 int cur_elt = point_in_line_start_cache (w, point, new_line);
7773 int pixpos = WINDOW_TEXT_BOTTOM (w);
7774 Bufpos retval, search_point;
7776 /* If scroll_on_clipped_lines is false, the last "visible" line of
7777 the window covers the pixel at WINDOW_TEXT_BOTTOM (w) - 1.
7778 If s_o_c_l is true, then we don't want to count a clipped
7779 line, so back up from the bottom by the height of the line
7780 containing point. */
7781 if (scroll_on_clipped_lines)
7782 pixpos -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7786 if (cur_elt + new_line >= Dynarr_length (w->line_start_cache))
7788 /* Hit the bottom of the buffer. */
7790 (cur_elt + new_line) - Dynarr_length (w->line_start_cache) + 1;
7794 XSETWINDOW (window, w);
7795 default_face_height_and_width (window, &defheight, 0);
7797 cur_elt = Dynarr_length (w->line_start_cache) - 1;
7799 pixpos -= (adjustment * defheight);
7800 if (pixpos < WINDOW_TEXT_TOP (w))
7801 pixpos = WINDOW_TEXT_TOP (w);
7804 cur_elt = cur_elt + new_line;
7806 search_point = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7808 retval = start_with_line_at_pixpos (w, search_point, pixpos);
7809 w->line_cache_validation_override--;
7814 /* This is used to speed up vertical scrolling by caching the known
7815 buffer starting positions for display lines. This allows the
7816 scrolling routines to avoid costly calls to regenerate_window. If
7817 NO_REGEN is true then it will only add the values in the DESIRED
7818 display structs which are in the given range.
7820 Note also that the FROM/TO values are minimums. It is possible
7821 that this function will actually add information outside of the
7822 lines containing those positions. This can't hurt but it could
7825 #### We currently force the cache to have only 1 contiguous region.
7826 It might help to make the cache a dynarr of caches so that we can
7827 cover more areas. This might, however, turn out to be a lot of
7828 overhead for too little gain. */
7831 update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
7832 Bufpos point, int no_regen)
7834 struct buffer *b = XBUFFER (w->buffer);
7835 line_start_cache_dynarr *cache = w->line_start_cache;
7836 Bufpos low_bound, high_bound;
7838 validate_line_start_cache (w);
7839 w->line_cache_validation_override++;
7841 if (from < BUF_BEGV (b))
7842 from = BUF_BEGV (b);
7843 if (to > BUF_ZV (b))
7848 w->line_cache_validation_override--;
7852 if (Dynarr_length (cache))
7854 low_bound = line_start_cache_start (w);
7855 high_bound = line_start_cache_end (w);
7857 /* Check to see if the desired range is already in the cache. */
7858 if (from >= low_bound && to <= high_bound)
7860 w->line_cache_validation_override--;
7864 /* Check to make sure that the desired range is adjacent to the
7865 current cache. If not, invalidate the cache. */
7866 if (to < low_bound || from > high_bound)
7868 Dynarr_reset (cache);
7869 low_bound = high_bound = -1;
7874 low_bound = high_bound = -1;
7877 w->line_cache_last_updated = make_int (BUF_MODIFF (b));
7879 /* This could be integrated into the next two sections, but it is easier
7880 to follow what's going on by having it separate. */
7885 update_internal_cache_list (w, DESIRED_DISP);
7886 if (!Dynarr_length (internal_cache))
7888 w->line_cache_validation_override--;
7892 start = Dynarr_atp (internal_cache, 0)->start;
7894 Dynarr_atp (internal_cache, Dynarr_length (internal_cache) - 1)->end;
7896 /* We aren't allowed to generate additional information to fill in
7897 gaps, so if the DESIRED structs don't overlap the cache, reset the
7899 if (Dynarr_length (cache))
7901 if (end < low_bound || start > high_bound)
7902 Dynarr_reset (cache);
7904 /* #### What should really happen if what we are doing is
7905 extending a line (the last line)? */
7906 if (Dynarr_length (cache) == 1
7907 && Dynarr_length (internal_cache) == 1)
7908 Dynarr_reset (cache);
7911 if (!Dynarr_length (cache))
7913 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7914 Dynarr_length (internal_cache));
7915 w->line_cache_validation_override--;
7919 /* An extra check just in case the calling function didn't pass in
7920 the bounds of the DESIRED structs in the first place. */
7921 if (start >= low_bound && end <= high_bound)
7923 w->line_cache_validation_override--;
7927 /* At this point we know that the internal cache partially overlaps
7929 if (start < low_bound)
7931 int ic_elt = Dynarr_length (internal_cache) - 1;
7934 if (Dynarr_atp (internal_cache, ic_elt)->start < low_bound)
7942 Dynarr_reset (cache);
7943 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7944 Dynarr_length (internal_cache));
7945 w->line_cache_validation_override--;
7949 Dynarr_insert_many_at_start (cache, Dynarr_atp (internal_cache, 0),
7953 if (end > high_bound)
7957 while (ic_elt < Dynarr_length (internal_cache))
7959 if (Dynarr_atp (internal_cache, ic_elt)->start > high_bound)
7965 if (!(ic_elt < Dynarr_length (internal_cache)))
7967 Dynarr_reset (cache);
7968 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7969 Dynarr_length (internal_cache));
7970 w->line_cache_validation_override--;
7974 Dynarr_add_many (cache, Dynarr_atp (internal_cache, ic_elt),
7975 Dynarr_length (internal_cache) - ic_elt);
7978 w->line_cache_validation_override--;
7982 if (!Dynarr_length (cache) || from < low_bound)
7984 Bufpos startp = find_next_newline_no_quit (b, from, -1);
7986 int old_lb = low_bound;
7988 while (startp < old_lb || low_bound == -1)
7993 regenerate_window (w, startp, point, CMOTION_DISP);
7994 update_internal_cache_list (w, CMOTION_DISP);
7996 /* If this assert is triggered then regenerate_window failed
7997 to layout a single line. This is not possible since we
7998 force at least a single line to be layout for CMOTION_DISP */
7999 assert (Dynarr_length (internal_cache));
8000 assert (startp == Dynarr_atp (internal_cache, 0)->start);
8002 ic_elt = Dynarr_length (internal_cache) - 1;
8003 if (low_bound != -1)
8007 if (Dynarr_atp (internal_cache, ic_elt)->start < old_lb)
8013 assert (ic_elt >= 0);
8015 new_startp = Dynarr_atp (internal_cache, ic_elt)->end + 1;
8018 * Handle invisible text properly:
8019 * If the last line we're inserting has the same end as the
8020 * line before which it will be added, merge the two lines.
8022 if (Dynarr_length (cache) &&
8023 Dynarr_atp (internal_cache, ic_elt)->end ==
8024 Dynarr_atp (cache, marker)->end)
8026 Dynarr_atp (cache, marker)->start
8027 = Dynarr_atp (internal_cache, ic_elt)->start;
8028 Dynarr_atp (cache, marker)->height
8029 = Dynarr_atp (internal_cache, ic_elt)->height;
8033 if (ic_elt >= 0) /* we still have lines to add.. */
8035 Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0),
8036 ic_elt + 1, marker);
8037 marker += (ic_elt + 1);
8040 if (startp < low_bound || low_bound == -1)
8042 startp = new_startp;
8043 if (startp > BUF_ZV (b))
8045 w->line_cache_validation_override--;
8051 assert (Dynarr_length (cache));
8052 assert (from >= low_bound);
8054 /* Readjust the high_bound to account for any changes made while
8055 correcting the low_bound. */
8056 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8058 if (to > high_bound)
8060 Bufpos startp = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end + 1;
8064 regenerate_window (w, startp, point, CMOTION_DISP);
8065 update_internal_cache_list (w, CMOTION_DISP);
8067 /* See comment above about regenerate_window failing. */
8068 assert (Dynarr_length (internal_cache));
8070 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
8071 Dynarr_length (internal_cache));
8072 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8073 startp = high_bound + 1;
8075 while (to > high_bound);
8078 w->line_cache_validation_override--;
8079 assert (to <= high_bound);
8083 /* Given x and y coordinates in characters, relative to a window,
8084 return the pixel location corresponding to those coordinates. The
8085 pixel location returned is the center of the given character
8086 position. The pixel values are generated relative to the window,
8089 The modeline is considered to be part of the window. */
8092 glyph_to_pixel_translation (struct window *w, int char_x, int char_y,
8093 int *pix_x, int *pix_y)
8095 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
8096 int num_disp_lines, modeline;
8098 int defheight, defwidth;
8100 XSETWINDOW (window, w);
8101 default_face_height_and_width (window, &defheight, &defwidth);
8103 /* If we get a bogus value indicating somewhere above or to the left of
8104 the window, use the first window line or character position
8111 num_disp_lines = Dynarr_length (dla);
8115 if (Dynarr_atp (dla, 0)->modeline)
8122 /* First check if the y position intersects the display lines. */
8123 if (char_y < num_disp_lines)
8125 struct display_line *dl = Dynarr_atp (dla, char_y + modeline);
8126 struct display_block *db = get_display_block_from_line (dl, TEXT);
8128 *pix_y = (dl->ypos - dl->ascent +
8129 ((unsigned int) (dl->ascent + dl->descent - dl->clip) >> 1));
8131 if (char_x < Dynarr_length (db->runes))
8133 struct rune *rb = Dynarr_atp (db->runes, char_x);
8135 *pix_x = rb->xpos + (rb->width >> 1);
8139 int last_rune = Dynarr_length (db->runes) - 1;
8140 struct rune *rb = Dynarr_atp (db->runes, last_rune);
8142 char_x -= last_rune;
8144 *pix_x = rb->xpos + rb->width;
8145 *pix_x += ((char_x - 1) * defwidth);
8146 *pix_x += (defwidth >> 1);
8151 /* It didn't intersect, so extrapolate. #### For now, we include the
8152 modeline in this since we don't have true character positions in
8155 if (!Dynarr_length (w->face_cachels))
8156 reset_face_cachels (w);
8158 char_y -= num_disp_lines;
8160 if (Dynarr_length (dla))
8162 struct display_line *dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
8163 *pix_y = dl->ypos + dl->descent - dl->clip;
8166 *pix_y = WINDOW_TEXT_TOP (w);
8168 *pix_y += (char_y * defheight);
8169 *pix_y += (defheight >> 1);
8171 *pix_x = WINDOW_TEXT_LEFT (w);
8172 /* Don't adjust by one because this is still the unadjusted value. */
8173 *pix_x += (char_x * defwidth);
8174 *pix_x += (defwidth >> 1);
8177 if (*pix_x > w->pixel_left + w->pixel_width)
8178 *pix_x = w->pixel_left + w->pixel_width;
8179 if (*pix_y > w->pixel_top + w->pixel_height)
8180 *pix_y = w->pixel_top + w->pixel_height;
8182 *pix_x -= w->pixel_left;
8183 *pix_y -= w->pixel_top;
8186 /* Given a display line and a position, determine if there is a glyph
8187 there and return information about it if there is. */
8190 get_position_object (struct display_line *dl, Lisp_Object *obj1,
8191 Lisp_Object *obj2, int x_coord, int *low_x_coord,
8194 struct display_block *db;
8197 get_next_display_block (dl->bounds, dl->display_blocks, x_coord, 0);
8199 /* We use get_next_display_block to get the actual display block
8200 that would be displayed at x_coord. */
8202 if (block == NO_BLOCK)
8205 db = Dynarr_atp (dl->display_blocks, block);
8207 for (elt = 0; elt < Dynarr_length (db->runes); elt++)
8209 struct rune *rb = Dynarr_atp (db->runes, elt);
8211 if (rb->xpos <= x_coord && x_coord < (rb->xpos + rb->width))
8213 if (rb->type == RUNE_DGLYPH)
8215 *obj1 = rb->object.dglyph.glyph;
8216 *obj2 = rb->object.dglyph.extent;
8225 *low_x_coord = rb->xpos;
8227 *high_x_coord = rb->xpos + rb->width;
8234 #define UPDATE_CACHE_RETURN \
8236 d->pixel_to_glyph_cache.valid = 1; \
8237 d->pixel_to_glyph_cache.low_x_coord = low_x_coord; \
8238 d->pixel_to_glyph_cache.high_x_coord = high_x_coord; \
8239 d->pixel_to_glyph_cache.low_y_coord = low_y_coord; \
8240 d->pixel_to_glyph_cache.high_y_coord = high_y_coord; \
8241 d->pixel_to_glyph_cache.frame = f; \
8242 d->pixel_to_glyph_cache.col = *col; \
8243 d->pixel_to_glyph_cache.row = *row; \
8244 d->pixel_to_glyph_cache.obj_x = *obj_x; \
8245 d->pixel_to_glyph_cache.obj_y = *obj_y; \
8246 d->pixel_to_glyph_cache.w = *w; \
8247 d->pixel_to_glyph_cache.bufpos = *bufpos; \
8248 d->pixel_to_glyph_cache.closest = *closest; \
8249 d->pixel_to_glyph_cache.modeline_closest = *modeline_closest; \
8250 d->pixel_to_glyph_cache.obj1 = *obj1; \
8251 d->pixel_to_glyph_cache.obj2 = *obj2; \
8252 d->pixel_to_glyph_cache.retval = position; \
8253 RETURN_SANS_WARNINGS position; \
8256 /* Given x and y coordinates in pixels relative to a frame, return
8257 information about what is located under those coordinates.
8259 The return value will be one of:
8261 OVER_TOOLBAR: over one of the 4 frame toolbars
8262 OVER_MODELINE: over a modeline
8263 OVER_BORDER: over an internal border
8264 OVER_NOTHING: over the text area, but not over text
8265 OVER_OUTSIDE: outside of the frame border
8266 OVER_TEXT: over text in the text area
8272 -- nil if the coordinates are not over a glyph or a toolbar button.
8276 -- an extent, if the coordinates are over a glyph in the text area
8279 If the coordinates are over a glyph, OBJ_X and OBJ_Y give the
8280 equivalent coordinates relative to the upper-left corner of the glyph.
8282 If the coordinates are over a character, OBJ_X and OBJ_Y give the
8283 equivalent coordinates relative to the upper-left corner of the character.
8285 Otherwise, OBJ_X and OBJ_Y are undefined.
8289 pixel_to_glyph_translation (struct frame *f, int x_coord, int y_coord,
8290 int *col, int *row, int *obj_x, int *obj_y,
8291 struct window **w, Bufpos *bufpos,
8292 Bufpos *closest, Charcount *modeline_closest,
8293 Lisp_Object *obj1, Lisp_Object *obj2)
8296 struct pixel_to_glyph_translation_cache *cache;
8298 int frm_left, frm_right, frm_top, frm_bottom;
8299 int low_x_coord, high_x_coord, low_y_coord, high_y_coord;
8300 int position = OVER_NOTHING;
8301 int device_check_failed = 0;
8302 display_line_dynarr *dla;
8304 /* This is a safety valve in case this got called with a frame in
8305 the middle of being deleted. */
8306 if (!DEVICEP (f->device) || !DEVICE_LIVE_P (XDEVICE (f->device)))
8308 device_check_failed = 1;
8309 d = NULL, cache = NULL; /* Warning suppression */
8313 d = XDEVICE (f->device);
8314 cache = &d->pixel_to_glyph_cache;
8317 if (!device_check_failed
8319 && cache->frame == f
8320 && cache->low_x_coord <= x_coord
8321 && cache->high_x_coord > x_coord
8322 && cache->low_y_coord <= y_coord
8323 && cache->high_y_coord > y_coord)
8327 *obj_x = cache->obj_x;
8328 *obj_y = cache->obj_y;
8330 *bufpos = cache->bufpos;
8331 *closest = cache->closest;
8332 *modeline_closest = cache->modeline_closest;
8333 *obj1 = cache->obj1;
8334 *obj2 = cache->obj2;
8336 return cache->retval;
8347 *modeline_closest = -1;
8351 low_x_coord = x_coord;
8352 high_x_coord = x_coord + 1;
8353 low_y_coord = y_coord;
8354 high_y_coord = y_coord + 1;
8357 if (device_check_failed)
8358 return OVER_NOTHING;
8360 frm_left = FRAME_LEFT_BORDER_END (f);
8361 frm_right = FRAME_RIGHT_BORDER_START (f);
8362 frm_top = FRAME_TOP_BORDER_END (f);
8363 frm_bottom = FRAME_BOTTOM_BORDER_START (f);
8365 /* Check if the mouse is outside of the text area actually used by
8367 if (y_coord < frm_top)
8369 if (y_coord >= FRAME_TOP_BORDER_START (f))
8371 low_y_coord = FRAME_TOP_BORDER_START (f);
8372 high_y_coord = frm_top;
8373 position = OVER_BORDER;
8375 else if (y_coord >= 0)
8378 high_y_coord = FRAME_TOP_BORDER_START (f);
8379 position = OVER_TOOLBAR;
8383 low_y_coord = y_coord;
8385 position = OVER_OUTSIDE;
8388 else if (y_coord >= frm_bottom)
8390 if (y_coord < FRAME_BOTTOM_BORDER_END (f))
8392 low_y_coord = frm_bottom;
8393 high_y_coord = FRAME_BOTTOM_BORDER_END (f);
8394 position = OVER_BORDER;
8396 else if (y_coord < FRAME_PIXHEIGHT (f))
8398 low_y_coord = FRAME_BOTTOM_BORDER_END (f);
8399 high_y_coord = FRAME_PIXHEIGHT (f);
8400 position = OVER_TOOLBAR;
8404 low_y_coord = FRAME_PIXHEIGHT (f);
8405 high_y_coord = y_coord;
8406 position = OVER_OUTSIDE;
8410 if (position != OVER_TOOLBAR && position != OVER_BORDER)
8412 if (x_coord < frm_left)
8414 if (x_coord >= FRAME_LEFT_BORDER_START (f))
8416 low_x_coord = FRAME_LEFT_BORDER_START (f);
8417 high_x_coord = frm_left;
8418 position = OVER_BORDER;
8420 else if (x_coord >= 0)
8423 high_x_coord = FRAME_LEFT_BORDER_START (f);
8424 position = OVER_TOOLBAR;
8428 low_x_coord = x_coord;
8430 position = OVER_OUTSIDE;
8433 else if (x_coord >= frm_right)
8435 if (x_coord < FRAME_RIGHT_BORDER_END (f))
8437 low_x_coord = frm_right;
8438 high_x_coord = FRAME_RIGHT_BORDER_END (f);
8439 position = OVER_BORDER;
8441 else if (x_coord < FRAME_PIXWIDTH (f))
8443 low_x_coord = FRAME_RIGHT_BORDER_END (f);
8444 high_x_coord = FRAME_PIXWIDTH (f);
8445 position = OVER_TOOLBAR;
8449 low_x_coord = FRAME_PIXWIDTH (f);
8450 high_x_coord = x_coord;
8451 position = OVER_OUTSIDE;
8456 #ifdef HAVE_TOOLBARS
8457 if (position == OVER_TOOLBAR)
8459 *obj1 = toolbar_button_at_pixpos (f, x_coord, y_coord);
8462 UPDATE_CACHE_RETURN;
8464 #endif /* HAVE_TOOLBARS */
8466 /* We still have to return the window the pointer is next to and its
8467 relative y position even if it is outside the x boundary. */
8468 if (x_coord < frm_left)
8470 else if (x_coord > frm_right)
8471 x_coord = frm_right;
8473 /* Same in reverse. */
8474 if (y_coord < frm_top)
8476 else if (y_coord > frm_bottom)
8477 y_coord = frm_bottom;
8479 /* Find what window the given coordinates are actually in. */
8480 window = f->root_window;
8481 *w = find_window_by_pixel_pos (x_coord, y_coord, window);
8483 /* If we didn't find a window, we're done. */
8486 UPDATE_CACHE_RETURN;
8488 else if (position != OVER_NOTHING)
8491 *modeline_closest = -1;
8493 if (high_y_coord <= frm_top || high_y_coord >= frm_bottom)
8496 UPDATE_CACHE_RETURN;
8500 /* Check if the window is a minibuffer but isn't active. */
8501 if (MINI_WINDOW_P (*w) && !minibuf_level)
8503 /* Must reset the window value since some callers will ignore
8504 the return value if it is set. */
8506 UPDATE_CACHE_RETURN;
8509 /* See if the point is over window vertical divider */
8510 if (window_needs_vertical_divider (*w))
8512 int div_x_high = WINDOW_RIGHT (*w);
8513 int div_x_low = div_x_high - window_divider_width (*w);
8514 int div_y_high = WINDOW_BOTTOM (*w);
8515 int div_y_low = WINDOW_TOP (*w);
8517 if (div_x_low < x_coord && x_coord <= div_x_high &&
8518 div_y_low < y_coord && y_coord <= div_y_high)
8520 low_x_coord = div_x_low;
8521 high_x_coord = div_x_high;
8522 low_y_coord = div_y_low;
8523 high_y_coord = div_y_high;
8524 position = OVER_V_DIVIDER;
8525 UPDATE_CACHE_RETURN;
8529 dla = window_display_lines (*w, CURRENT_DISP);
8531 for (*row = 0; *row < Dynarr_length (dla); (*row)++)
8533 int really_over_nothing = 0;
8534 struct display_line *dl = Dynarr_atp (dla, *row);
8536 if ((int) (dl->ypos - dl->ascent) <= y_coord
8537 && y_coord <= (int) (dl->ypos + dl->descent))
8539 int check_margin_glyphs = 0;
8540 struct display_block *db = get_display_block_from_line (dl, TEXT);
8541 struct rune *rb = 0;
8543 if (x_coord < dl->bounds.left_white
8544 || x_coord >= dl->bounds.right_white)
8545 check_margin_glyphs = 1;
8547 low_y_coord = dl->ypos - dl->ascent;
8548 high_y_coord = dl->ypos + dl->descent + 1;
8550 if (position == OVER_BORDER
8551 || position == OVER_OUTSIDE
8552 || check_margin_glyphs)
8554 int x_check, left_bound;
8556 if (check_margin_glyphs)
8559 left_bound = dl->bounds.left_white;
8563 x_check = high_x_coord;
8564 left_bound = frm_left;
8567 if (Dynarr_length (db->runes))
8569 if (x_check <= left_bound)
8572 *modeline_closest = Dynarr_atp (db->runes, 0)->bufpos;
8574 *closest = Dynarr_atp (db->runes, 0)->bufpos;
8580 Dynarr_atp (db->runes,
8581 Dynarr_length (db->runes) - 1)->bufpos;
8584 Dynarr_atp (db->runes,
8585 Dynarr_length (db->runes) - 1)->bufpos;
8589 *modeline_closest += dl->offset;
8591 *closest += dl->offset;
8595 /* #### What should be here. */
8597 *modeline_closest = 0;
8602 if (check_margin_glyphs)
8604 if (x_coord < dl->bounds.left_in
8605 || x_coord >= dl->bounds.right_in)
8607 /* If we are over the outside margins then we
8608 know the loop over the text block isn't going
8609 to accomplish anything. So we go ahead and
8610 set what information we can right here and
8613 *obj_y = y_coord - (dl->ypos - dl->ascent);
8614 get_position_object (dl, obj1, obj2, x_coord,
8615 &low_x_coord, &high_x_coord);
8617 UPDATE_CACHE_RETURN;
8621 UPDATE_CACHE_RETURN;
8624 for (*col = 0; *col <= Dynarr_length (db->runes); (*col)++)
8626 int past_end = (*col == Dynarr_length (db->runes));
8629 rb = Dynarr_atp (db->runes, *col);
8632 (rb->xpos <= x_coord && x_coord < rb->xpos + rb->width))
8637 rb = Dynarr_atp (db->runes, *col);
8640 *bufpos = rb->bufpos + dl->offset;
8641 low_x_coord = rb->xpos;
8642 high_x_coord = rb->xpos + rb->width;
8644 if (rb->type == RUNE_DGLYPH)
8648 /* Find the first character after the glyph. */
8649 while (elt < Dynarr_length (db->runes))
8651 if (Dynarr_atp (db->runes, elt)->type != RUNE_DGLYPH)
8655 (Dynarr_atp (db->runes, elt)->bufpos +
8659 (Dynarr_atp (db->runes, elt)->bufpos +
8667 /* In this case we failed to find a non-glyph
8668 character so we return the last position
8669 displayed on the line. */
8670 if (elt == Dynarr_length (db->runes))
8673 *modeline_closest = dl->end_bufpos + dl->offset;
8675 *closest = dl->end_bufpos + dl->offset;
8676 really_over_nothing = 1;
8682 *modeline_closest = rb->bufpos + dl->offset;
8684 *closest = rb->bufpos + dl->offset;
8689 *row = window_displayed_height (*w);
8691 if (position == OVER_NOTHING)
8692 position = OVER_MODELINE;
8694 if (rb->type == RUNE_DGLYPH)
8696 *obj1 = rb->object.dglyph.glyph;
8697 *obj2 = rb->object.dglyph.extent;
8699 else if (rb->type == RUNE_CHAR)
8710 UPDATE_CACHE_RETURN;
8713 || (rb->type == RUNE_CHAR
8714 && CHARC_ASCII_EQ (rb->object.cglyph, '\n')))
8717 /* At this point we may have glyphs in the right
8719 if (check_margin_glyphs)
8720 get_position_object (dl, obj1, obj2, x_coord,
8721 &low_x_coord, &high_x_coord);
8722 UPDATE_CACHE_RETURN;
8727 if (rb->type == RUNE_DGLYPH)
8729 *obj1 = rb->object.dglyph.glyph;
8730 *obj2 = rb->object.dglyph.extent;
8732 else if (rb->type == RUNE_CHAR)
8743 *obj_x = x_coord - rb->xpos;
8744 *obj_y = y_coord - (dl->ypos - dl->ascent);
8746 /* At this point we may have glyphs in the left
8748 if (check_margin_glyphs)
8749 get_position_object (dl, obj1, obj2, x_coord, 0, 0);
8751 if (position == OVER_NOTHING && !really_over_nothing)
8752 position = OVER_TEXT;
8754 UPDATE_CACHE_RETURN;
8761 *row = Dynarr_length (dla) - 1;
8762 if (FRAME_WIN_P (f))
8764 int bot_elt = Dynarr_length (dla) - 1;
8768 struct display_line *dl = Dynarr_atp (dla, bot_elt);
8769 int adj_area = y_coord - (dl->ypos + dl->descent);
8773 XSETWINDOW (lwin, *w);
8774 default_face_height_and_width (lwin, 0, &defheight);
8776 *row += (adj_area / defheight);
8780 /* #### This should be checked out some more to determine what
8781 should really be going on. */
8782 if (!MARKERP ((*w)->start[CURRENT_DISP]))
8785 *closest = end_of_last_line_may_error (*w,
8786 marker_position ((*w)->start[CURRENT_DISP]));
8788 UPDATE_CACHE_RETURN;
8790 #undef UPDATE_CACHE_RETURN
8793 /***************************************************************************/
8795 /* Lisp functions */
8797 /***************************************************************************/
8799 DEFUN ("redisplay-echo-area", Fredisplay_echo_area, 0, 0, 0, /*
8800 Ensure that all minibuffers are correctly showing the echo area.
8804 Lisp_Object devcons, concons;
8806 DEVICE_LOOP_NO_BREAK (devcons, concons)
8808 struct device *d = XDEVICE (XCAR (devcons));
8809 Lisp_Object frmcons;
8811 DEVICE_FRAME_LOOP (frmcons, d)
8813 struct frame *f = XFRAME (XCAR (frmcons));
8815 if (FRAME_REPAINT_P (f) && FRAME_HAS_MINIBUF_P (f))
8817 Lisp_Object window = FRAME_MINIBUF_WINDOW (f);
8819 MAYBE_DEVMETH (d, frame_output_begin, (f));
8822 * If the frame size has changed, there may be random
8823 * chud on the screen left from previous messages
8824 * because redisplay_frame hasn't been called yet.
8825 * Clear the screen to get rid of the potential mess.
8827 if (f->echo_area_garbaged)
8829 MAYBE_DEVMETH (d, clear_frame, (f));
8830 f->echo_area_garbaged = 0;
8832 redisplay_window (window, 0);
8833 MAYBE_DEVMETH (d, frame_output_end, (f));
8835 call_redisplay_end_triggers (XWINDOW (window), 0);
8844 restore_disable_preemption_value (Lisp_Object value)
8846 disable_preemption = XINT (value);
8850 DEFUN ("redraw-frame", Fredraw_frame, 0, 2, 0, /*
8851 Clear frame FRAME and output again what is supposed to appear on it.
8852 FRAME defaults to the selected frame if omitted.
8853 Normally, redisplay is preempted as normal if input arrives. However,
8854 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8855 input and is guaranteed to proceed to completion.
8857 (frame, no_preempt))
8859 struct frame *f = decode_frame (frame);
8860 int count = specpdl_depth ();
8862 if (!NILP (no_preempt))
8864 record_unwind_protect (restore_disable_preemption_value,
8865 make_int (disable_preemption));
8866 disable_preemption++;
8870 redisplay_frame (f, 1);
8872 /* See the comment in Fredisplay_frame. */
8873 RESET_CHANGED_SET_FLAGS;
8875 return unbind_to (count, Qnil);
8878 DEFUN ("redisplay-frame", Fredisplay_frame, 0, 2, 0, /*
8879 Ensure that FRAME's contents are correctly displayed.
8880 This differs from `redraw-frame' in that it only redraws what needs to
8881 be updated, as opposed to unconditionally clearing and redrawing
8883 FRAME defaults to the selected frame if omitted.
8884 Normally, redisplay is preempted as normal if input arrives. However,
8885 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8886 input and is guaranteed to proceed to completion.
8888 (frame, no_preempt))
8890 struct frame *f = decode_frame (frame);
8891 int count = specpdl_depth ();
8893 if (!NILP (no_preempt))
8895 record_unwind_protect (restore_disable_preemption_value,
8896 make_int (disable_preemption));
8897 disable_preemption++;
8900 redisplay_frame (f, 1);
8902 /* If we don't reset the global redisplay flags here, subsequent
8903 changes to the display will not get registered by redisplay
8904 because it thinks it already has registered changes. If you
8905 really knew what you were doing you could confuse redisplay by
8906 calling Fredisplay_frame while updating another frame. We assume
8907 that if you know what you are doing you will not be that
8909 RESET_CHANGED_SET_FLAGS;
8911 return unbind_to (count, Qnil);
8914 DEFUN ("redraw-device", Fredraw_device, 0, 2, 0, /*
8915 Clear device DEVICE and output again what is supposed to appear on it.
8916 DEVICE defaults to the selected device if omitted.
8917 Normally, redisplay is preempted as normal if input arrives. However,
8918 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8919 input and is guaranteed to proceed to completion.
8921 (device, no_preempt))
8923 struct device *d = decode_device (device);
8924 Lisp_Object frmcons;
8925 int count = specpdl_depth ();
8927 if (!NILP (no_preempt))
8929 record_unwind_protect (restore_disable_preemption_value,
8930 make_int (disable_preemption));
8931 disable_preemption++;
8934 DEVICE_FRAME_LOOP (frmcons, d)
8936 XFRAME (XCAR (frmcons))->clear = 1;
8938 redisplay_device (d, 0);
8940 /* See the comment in Fredisplay_frame. */
8941 RESET_CHANGED_SET_FLAGS;
8943 return unbind_to (count, Qnil);
8946 DEFUN ("redisplay-device", Fredisplay_device, 0, 2, 0, /*
8947 Ensure that DEVICE's contents are correctly displayed.
8948 This differs from `redraw-device' in that it only redraws what needs to
8949 be updated, as opposed to unconditionally clearing and redrawing
8951 DEVICE defaults to the selected device if omitted.
8952 Normally, redisplay is preempted as normal if input arrives. However,
8953 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8954 input and is guaranteed to proceed to completion.
8956 (device, no_preempt))
8958 struct device *d = decode_device (device);
8959 int count = specpdl_depth ();
8961 if (!NILP (no_preempt))
8963 record_unwind_protect (restore_disable_preemption_value,
8964 make_int (disable_preemption));
8965 disable_preemption++;
8968 redisplay_device (d, 0);
8970 /* See the comment in Fredisplay_frame. */
8971 RESET_CHANGED_SET_FLAGS;
8973 return unbind_to (count, Qnil);
8976 /* Big lie. Big lie. This will force all modelines to be updated
8977 regardless if the all flag is set or not. It remains in existence
8978 solely for backwards compatibility. */
8979 DEFUN ("redraw-modeline", Fredraw_modeline, 0, 1, 0, /*
8980 Force the modeline of the current buffer to be redisplayed.
8981 With optional non-nil ALL, force redisplay of all modelines.
8985 MARK_MODELINE_CHANGED;
8989 DEFUN ("force-cursor-redisplay", Fforce_cursor_redisplay, 0, 1, 0, /*
8990 Force an immediate update of the cursor on FRAME.
8991 FRAME defaults to the selected frame if omitted.
8995 redisplay_redraw_cursor (decode_frame (frame), 1);
9000 /***************************************************************************/
9002 /* Lisp-variable change triggers */
9004 /***************************************************************************/
9007 margin_width_changed_in_frame (Lisp_Object specifier, struct frame *f,
9010 /* Nothing to be done? */
9014 redisplay_variable_changed (Lisp_Object sym, Lisp_Object *val,
9015 Lisp_Object in_object, int flags)
9017 /* #### clip_changed should really be renamed something like
9018 global_redisplay_change. */
9023 /* This is called if the built-in glyphs have their properties
9026 redisplay_glyph_changed (Lisp_Object glyph, Lisp_Object property,
9029 if (WINDOWP (locale))
9031 MARK_FRAME_GLYPHS_CHANGED (XFRAME (WINDOW_FRAME (XWINDOW (locale))));
9033 else if (FRAMEP (locale))
9035 MARK_FRAME_GLYPHS_CHANGED (XFRAME (locale));
9037 else if (DEVICEP (locale))
9039 Lisp_Object frmcons;
9040 DEVICE_FRAME_LOOP (frmcons, XDEVICE (locale))
9041 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9043 else if (CONSOLEP (locale))
9045 Lisp_Object frmcons, devcons;
9046 CONSOLE_FRAME_LOOP_NO_BREAK (frmcons, devcons, XCONSOLE (locale))
9047 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9049 else /* global or buffer */
9051 Lisp_Object frmcons, devcons, concons;
9052 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
9053 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9058 text_cursor_visible_p_changed (Lisp_Object specifier, struct window *w,
9061 if (XFRAME (w->frame)->init_finished)
9062 Fforce_cursor_redisplay (w->frame);
9065 #ifdef MEMORY_USAGE_STATS
9068 /***************************************************************************/
9070 /* memory usage computation */
9072 /***************************************************************************/
9075 compute_rune_dynarr_usage (rune_dynarr *dyn, struct overhead_stats *ovstats)
9077 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9081 compute_display_block_dynarr_usage (display_block_dynarr *dyn,
9082 struct overhead_stats *ovstats)
9089 total = Dynarr_memory_usage (dyn, ovstats);
9090 for (i = 0; i < Dynarr_largest (dyn); i++)
9091 total += compute_rune_dynarr_usage (Dynarr_at (dyn, i).runes, ovstats);
9097 compute_glyph_block_dynarr_usage (glyph_block_dynarr *dyn,
9098 struct overhead_stats *ovstats)
9100 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9104 compute_display_line_dynarr_usage (display_line_dynarr *dyn,
9105 struct overhead_stats *ovstats)
9112 total = Dynarr_memory_usage (dyn, ovstats);
9113 for (i = 0; i < Dynarr_largest (dyn); i++)
9115 struct display_line *dl = &Dynarr_at (dyn, i);
9116 total += compute_display_block_dynarr_usage(dl->display_blocks, ovstats);
9117 total += compute_glyph_block_dynarr_usage (dl->left_glyphs, ovstats);
9118 total += compute_glyph_block_dynarr_usage (dl->right_glyphs, ovstats);
9125 compute_line_start_cache_dynarr_usage (line_start_cache_dynarr *dyn,
9126 struct overhead_stats *ovstats)
9128 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9131 #endif /* MEMORY_USAGE_STATS */
9134 /***************************************************************************/
9136 /* initialization */
9138 /***************************************************************************/
9141 init_redisplay (void)
9143 disable_preemption = 0;
9144 preemption_count = 0;
9145 max_preempts = INIT_MAX_PREEMPTS;
9151 if (!cmotion_display_lines)
9152 cmotion_display_lines = Dynarr_new (display_line);
9153 if (!mode_spec_bufbyte_string)
9154 mode_spec_bufbyte_string = Dynarr_new (Bufbyte);
9155 if (!formatted_string_extent_dynarr)
9156 formatted_string_extent_dynarr = Dynarr_new (EXTENT);
9157 if (!formatted_string_extent_start_dynarr)
9158 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount);
9159 if (!formatted_string_extent_end_dynarr)
9160 formatted_string_extent_end_dynarr = Dynarr_new (Bytecount);
9161 if (!internal_cache)
9162 internal_cache = Dynarr_new (line_start_cache);
9165 /* window system is nil when in -batch mode */
9166 if (!initialized || noninteractive)
9169 /* If the user wants to use a window system, we shouldn't bother
9170 initializing the terminal. This is especially important when the
9171 terminal is so dumb that emacs gives up before and doesn't bother
9172 using the window system.
9174 If the DISPLAY environment variable is set, try to use X, and die
9175 with an error message if that doesn't work. */
9177 #ifdef HAVE_X_WINDOWS
9178 if (!strcmp (display_use, "x"))
9180 /* Some stuff checks this way early. */
9181 Vwindow_system = Qx;
9182 Vinitial_window_system = Qx;
9185 #endif /* HAVE_X_WINDOWS */
9187 #ifdef HAVE_MS_WINDOWS
9188 if (!strcmp (display_use, "mswindows"))
9190 /* Some stuff checks this way early. */
9191 Vwindow_system = Qmswindows;
9192 Vinitial_window_system = Qmswindows;
9195 #endif /* HAVE_MS_WINDOWS */
9198 /* If no window system has been specified, try to use the terminal. */
9201 stderr_out ("XEmacs: standard input is not a tty\n");
9205 /* Look at the TERM variable */
9206 if (!getenv ("TERM"))
9208 stderr_out ("Please set the environment variable TERM; see tset(1).\n");
9212 Vinitial_window_system = Qtty;
9214 #else /* not HAVE_TTY */
9215 /* No DISPLAY specified, and no TTY support. */
9216 stderr_out ("XEmacs: Cannot open display.\n\
9217 Please set the environmental variable DISPLAY to an appropriate value.\n");
9224 syms_of_redisplay (void)
9226 defsymbol (&Qcursor_in_echo_area, "cursor-in-echo-area");
9227 #ifndef INHIBIT_REDISPLAY_HOOKS
9228 defsymbol (&Qpre_redisplay_hook, "pre-redisplay-hook");
9229 defsymbol (&Qpost_redisplay_hook, "post-redisplay-hook");
9230 #endif /* INHIBIT_REDISPLAY_HOOKS */
9231 defsymbol (&Qdisplay_warning_buffer, "display-warning-buffer");
9232 defsymbol (&Qbar_cursor, "bar-cursor");
9233 defsymbol (&Qredisplay_end_trigger_functions,
9234 "redisplay-end-trigger-functions");
9235 defsymbol (&Qtop_bottom, "top-bottom");
9236 defsymbol (&Qbuffer_list_changed_hook, "buffer-list-changed-hook");
9238 DEFSUBR (Fredisplay_echo_area);
9239 DEFSUBR (Fredraw_frame);
9240 DEFSUBR (Fredisplay_frame);
9241 DEFSUBR (Fredraw_device);
9242 DEFSUBR (Fredisplay_device);
9243 DEFSUBR (Fredraw_modeline);
9244 DEFSUBR (Fforce_cursor_redisplay);
9248 vars_of_redisplay (void)
9252 staticpro (&last_arrow_position);
9253 staticpro (&last_arrow_string);
9254 last_arrow_position = Qnil;
9255 last_arrow_string = Qnil;
9258 /* #### Probably temporary */
9259 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /*
9260 \(Temporary) Setting this will impact the performance of the internal
9263 cache_adjustment = 2;
9265 DEFVAR_INT_MAGIC ("pixel-vertical-clip-threshold", &vertical_clip /*
9266 Minimum pixel height for clipped bottom display line.
9267 A clipped line shorter than this won't be displayed.
9269 redisplay_variable_changed);
9272 DEFVAR_INT_MAGIC ("pixel-horizontal-clip-threshold", &horizontal_clip /*
9273 Minimum visible area for clipped glyphs at right boundary.
9274 Clipped glyphs shorter than this won't be displayed.
9275 Only pixmap glyph instances are currently allowed to be clipped.
9277 redisplay_variable_changed);
9278 horizontal_clip = 5;
9280 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string /*
9281 String displayed by modeline-format's "%m" specification.
9283 Vglobal_mode_string = Qnil;
9285 DEFVAR_LISP_MAGIC ("overlay-arrow-position", &Voverlay_arrow_position /*
9286 Marker for where to display an arrow on top of the buffer text.
9287 This must be the beginning of a line in order to work.
9288 See also `overlay-arrow-string'.
9290 redisplay_variable_changed);
9291 Voverlay_arrow_position = Qnil;
9293 DEFVAR_LISP_MAGIC ("overlay-arrow-string", &Voverlay_arrow_string /*
9294 String or glyph to display as an arrow. See also `overlay-arrow-position'.
9295 \(Note that despite the name of this variable, it can be set to a glyph as
9298 redisplay_variable_changed);
9299 Voverlay_arrow_string = Qnil;
9301 DEFVAR_INT ("scroll-step", &scroll_step /*
9302 *The number of lines to try scrolling a window by when point moves out.
9303 If that fails to bring point back on frame, point is centered instead.
9304 If this is zero, point is always centered after it moves off screen.
9308 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively /*
9309 *Scroll up to this many lines, to bring point back on screen.
9311 scroll_conservatively = 0;
9313 DEFVAR_BOOL_MAGIC ("truncate-partial-width-windows",
9314 &truncate_partial_width_windows /*
9315 *Non-nil means truncate lines in all windows less than full frame wide.
9317 redisplay_variable_changed);
9318 truncate_partial_width_windows = 1;
9320 DEFVAR_LISP ("visible-bell", &Vvisible_bell /*
9321 *Non-nil substitutes a visual signal for the audible bell.
9323 Default behavior is to flash the whole screen. On some platforms,
9324 special effects are available using the following values:
9326 'display Flash the whole screen (ie, the default behavior).
9327 'top-bottom Flash only the top and bottom lines of the selected frame.
9329 When effects are unavailable on a platform, the visual bell is the
9330 default, whole screen. (Currently only X supports any special effects.)
9332 Vvisible_bell = Qnil;
9334 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter /*
9335 *Non-nil means no need to redraw entire frame after suspending.
9336 A non-nil value is useful if the terminal can automatically preserve
9337 Emacs's frame display when you reenter Emacs.
9338 It is up to you to set this variable if your terminal can do that.
9340 no_redraw_on_reenter = 0;
9342 DEFVAR_LISP ("window-system", &Vwindow_system /*
9343 A symbol naming the window-system under which Emacs is running,
9344 such as `x', or nil if emacs is running on an ordinary terminal.
9346 Do not use this variable, except for GNU Emacs compatibility, as it
9347 gives wrong values in a multi-device environment. Use `console-type'
9350 Vwindow_system = Qnil;
9352 /* #### Temporary shit until window-system is eliminated. */
9353 DEFVAR_CONST_LISP ("initial-window-system", &Vinitial_window_system /*
9356 Vinitial_window_system = Qnil;
9358 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area /*
9359 Non-nil means put cursor in minibuffer, at end of any message there.
9361 cursor_in_echo_area = 0;
9363 /* #### Shouldn't this be generalized as follows:
9365 if nil, use block cursor.
9366 if a number, use a bar cursor of that width.
9367 Otherwise, use a 1-pixel bar cursor.
9369 #### Or better yet, this variable should be trashed entirely
9370 (use a Lisp-magic variable to maintain compatibility)
9371 and a specifier `cursor-shape' added, which allows a block
9372 cursor, a bar cursor, a flashing block or bar cursor,
9373 maybe a caret cursor, etc. */
9375 DEFVAR_LISP ("bar-cursor", &Vbar_cursor /*
9376 *Use vertical bar cursor if non-nil. If t width is 1 pixel, otherwise 2.
9380 #ifndef INHIBIT_REDISPLAY_HOOKS
9381 xxDEFVAR_LISP ("pre-redisplay-hook", &Vpre_redisplay_hook /*
9382 Function or functions to run before every redisplay.
9384 Vpre_redisplay_hook = Qnil;
9386 xxDEFVAR_LISP ("post-redisplay-hook", &Vpost_redisplay_hook /*
9387 Function or functions to run after every redisplay.
9389 Vpost_redisplay_hook = Qnil;
9390 #endif /* INHIBIT_REDISPLAY_HOOKS */
9392 DEFVAR_LISP ("buffer-list-changed-hook", &Vbuffer_list_changed_hook /*
9393 Function or functions to call when a frame's buffer list has changed.
9394 This is called during redisplay, before redisplaying each frame.
9395 Functions on this hook are called with one argument, the frame.
9397 Vbuffer_list_changed_hook = Qnil;
9399 DEFVAR_INT ("display-warning-tick", &display_warning_tick /*
9400 Bump this to tell the C code to call `display-warning-buffer'
9401 at next redisplay. You should not normally change this; the function
9402 `display-warning' automatically does this at appropriate times.
9404 display_warning_tick = 0;
9406 DEFVAR_BOOL ("inhibit-warning-display", &inhibit_warning_display /*
9407 Non-nil means inhibit display of warning messages.
9408 You should *bind* this, not set it. Any pending warning messages
9409 will be displayed when the binding no longer applies.
9411 /* reset to 0 by startup.el after the splash screen has displayed.
9412 This way, the warnings don't obliterate the splash screen. */
9413 inhibit_warning_display = 1;
9415 DEFVAR_LISP ("window-size-change-functions",
9416 &Vwindow_size_change_functions /*
9417 Not currently implemented.
9418 Functions called before redisplay, if window sizes have changed.
9419 The value should be a list of functions that take one argument.
9420 Just before redisplay, for each frame, if any of its windows have changed
9421 size since the last redisplay, or have been split or deleted,
9422 all the functions in the list are called, with the frame as argument.
9424 Vwindow_size_change_functions = Qnil;
9426 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions /*
9427 Not currently implemented.
9428 Functions to call before redisplaying a window with scrolling.
9429 Each function is called with two arguments, the window
9430 and its new display-start position. Note that the value of `window-end'
9431 is not valid when these functions are called.
9433 Vwindow_scroll_functions = Qnil;
9435 DEFVAR_LISP ("redisplay-end-trigger-functions",
9436 &Vredisplay_end_trigger_functions /*
9437 See `set-window-redisplay-end-trigger'.
9439 Vredisplay_end_trigger_functions = Qnil;
9441 DEFVAR_BOOL ("column-number-start-at-one", &column_number_start_at_one /*
9442 *Non-nil means column display number starts at 1.
9444 column_number_start_at_one = 0;
9448 specifier_vars_of_redisplay (void)
9450 DEFVAR_SPECIFIER ("left-margin-width", &Vleft_margin_width /*
9451 *Width of left margin.
9452 This is a specifier; use `set-specifier' to change it.
9454 Vleft_margin_width = Fmake_specifier (Qnatnum);
9455 set_specifier_fallback (Vleft_margin_width, list1 (Fcons (Qnil, Qzero)));
9456 set_specifier_caching (Vleft_margin_width,
9457 offsetof (struct window, left_margin_width),
9458 some_window_value_changed,
9459 offsetof (struct frame, left_margin_width),
9460 margin_width_changed_in_frame, 0);
9462 DEFVAR_SPECIFIER ("right-margin-width", &Vright_margin_width /*
9463 *Width of right margin.
9464 This is a specifier; use `set-specifier' to change it.
9466 Vright_margin_width = Fmake_specifier (Qnatnum);
9467 set_specifier_fallback (Vright_margin_width, list1 (Fcons (Qnil, Qzero)));
9468 set_specifier_caching (Vright_margin_width,
9469 offsetof (struct window, right_margin_width),
9470 some_window_value_changed,
9471 offsetof (struct frame, right_margin_width),
9472 margin_width_changed_in_frame, 0);
9474 DEFVAR_SPECIFIER ("minimum-line-ascent", &Vminimum_line_ascent /*
9475 *Minimum ascent height of lines.
9476 This is a specifier; use `set-specifier' to change it.
9478 Vminimum_line_ascent = Fmake_specifier (Qnatnum);
9479 set_specifier_fallback (Vminimum_line_ascent, list1 (Fcons (Qnil, Qzero)));
9480 set_specifier_caching (Vminimum_line_ascent,
9481 offsetof (struct window, minimum_line_ascent),
9482 some_window_value_changed,
9485 DEFVAR_SPECIFIER ("minimum-line-descent", &Vminimum_line_descent /*
9486 *Minimum descent height of lines.
9487 This is a specifier; use `set-specifier' to change it.
9489 Vminimum_line_descent = Fmake_specifier (Qnatnum);
9490 set_specifier_fallback (Vminimum_line_descent, list1 (Fcons (Qnil, Qzero)));
9491 set_specifier_caching (Vminimum_line_descent,
9492 offsetof (struct window, minimum_line_descent),
9493 some_window_value_changed,
9496 DEFVAR_SPECIFIER ("use-left-overflow", &Vuse_left_overflow /*
9497 *Non-nil means use the left outside margin as extra whitespace when
9498 displaying 'whitespace or 'inside-margin glyphs.
9499 This is a specifier; use `set-specifier' to change it.
9501 Vuse_left_overflow = Fmake_specifier (Qboolean);
9502 set_specifier_fallback (Vuse_left_overflow, list1 (Fcons (Qnil, Qnil)));
9503 set_specifier_caching (Vuse_left_overflow,
9504 offsetof (struct window, use_left_overflow),
9505 some_window_value_changed,
9508 DEFVAR_SPECIFIER ("use-right-overflow", &Vuse_right_overflow /*
9509 *Non-nil means use the right outside margin as extra whitespace when
9510 displaying 'whitespace or 'inside-margin glyphs.
9511 This is a specifier; use `set-specifier' to change it.
9513 Vuse_right_overflow = Fmake_specifier (Qboolean);
9514 set_specifier_fallback (Vuse_right_overflow, list1 (Fcons (Qnil, Qnil)));
9515 set_specifier_caching (Vuse_right_overflow,
9516 offsetof (struct window, use_right_overflow),
9517 some_window_value_changed,
9520 DEFVAR_SPECIFIER ("text-cursor-visible-p", &Vtext_cursor_visible_p /*
9521 *Non-nil means the text cursor is visible (this is usually the case).
9522 This is a specifier; use `set-specifier' to change it.
9524 Vtext_cursor_visible_p = Fmake_specifier (Qboolean);
9525 set_specifier_fallback (Vtext_cursor_visible_p, list1 (Fcons (Qnil, Qt)));
9526 set_specifier_caching (Vtext_cursor_visible_p,
9527 offsetof (struct window, text_cursor_visible_p),
9528 text_cursor_visible_p_changed,