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_emchar_string (struct window *w, int findex,
478 Emchar *str, Charcount len)
480 unsigned char charsets[NUM_LEADING_BYTES];
483 find_charsets_in_emchar_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 Emchar_dynarr *rtw_emchar_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_emchar_dynarr)
500 rtw_emchar_dynarr = Dynarr_new (Emchar);
501 Dynarr_reset (rtw_emchar_dynarr);
503 fixup_internal_substring (nonreloc, reloc, offset, &len);
505 nonreloc = XSTRING_DATA (reloc);
506 convert_bufbyte_string_into_emchar_dynarr (nonreloc, len, rtw_emchar_dynarr);
507 return redisplay_text_width_emchar_string
508 (w, findex, Dynarr_atp (rtw_emchar_dynarr, 0),
509 Dynarr_length (rtw_emchar_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 unsigned char charsets[NUM_LEADING_BYTES];
519 struct face_cachel cachel;
521 if (!rtw_emchar_dynarr)
522 rtw_emchar_dynarr = Dynarr_new (Emchar);
523 Dynarr_reset (rtw_emchar_dynarr);
525 fixup_internal_substring (nonreloc, reloc, offset, &len);
527 nonreloc = XSTRING_DATA (reloc);
528 convert_bufbyte_string_into_emchar_dynarr (nonreloc, len, rtw_emchar_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_emchar_dynarr, 0),
536 Dynarr_length (rtw_emchar_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;
831 if (data->bi_start_col_enabled)
833 return add_hscroll_rune (data);
836 if (data->ch == '\n')
838 data->font_is_bogus = 0;
839 /* Cheesy end-of-line pseudo-character. */
840 width = data->blank_width;
844 Lisp_Object charset = CHAR_CHARSET (data->ch);
845 if (!EQ (charset, data->last_charset) ||
846 data->findex != data->last_findex)
848 /* OK, we need to do things the hard way. */
849 struct window *w = XWINDOW (data->window);
850 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, data->findex);
851 Lisp_Object font_instance =
852 ensure_face_cachel_contains_charset (cachel, data->window,
854 Lisp_Font_Instance *fi;
856 if (EQ (font_instance, Vthe_null_font_instance))
858 font_instance = FACE_CACHEL_FONT (cachel, Vcharset_ascii);
859 data->font_is_bogus = 1;
862 data->font_is_bogus = 0;
864 fi = XFONT_INSTANCE (font_instance);
865 if (!fi->proportional_p)
866 /* sweetness and light. */
867 data->last_char_width = fi->width;
869 data->last_char_width = -1;
870 data->new_ascent = max (data->new_ascent, (int) fi->ascent);
871 data->new_descent = max (data->new_descent, (int) fi->descent);
872 data->last_charset = charset;
873 data->last_findex = data->findex;
876 width = data->last_char_width;
879 /* bummer. Proportional fonts. */
880 width = redisplay_text_width_emchar_string (XWINDOW (data->window),
886 if (data->max_pixpos != -1 && (data->pixpos + width > data->max_pixpos))
891 if (Dynarr_length (data->db->runes) < Dynarr_largest (data->db->runes))
893 crb = Dynarr_atp (data->db->runes, Dynarr_length (data->db->runes));
902 crb->findex = data->findex;
903 crb->xpos = data->pixpos;
907 if (NILP (data->string))
909 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
913 bytecount_to_charcount (XSTRING_DATA (data->string), data->bi_bufpos);
915 else if (data->is_modeline)
916 crb->bufpos = data->modeline_charpos;
918 /* Text but not in buffer */
920 crb->type = RUNE_CHAR;
921 crb->object.chr.ch = data->font_is_bogus ? '~' : data->ch;
924 if (data->cursor_type == CURSOR_ON)
926 if (data->bi_bufpos == data->bi_cursor_bufpos)
928 crb->cursor_type = CURSOR_ON;
929 data->cursor_x = Dynarr_length (data->db->runes);
932 crb->cursor_type = CURSOR_OFF;
934 else if (data->cursor_type == NEXT_CURSOR)
936 crb->cursor_type = CURSOR_ON;
937 data->cursor_x = Dynarr_length (data->db->runes);
938 data->cursor_type = NO_CURSOR;
940 else if (data->cursor_type == IGNORE_CURSOR)
941 crb->cursor_type = IGNORE_CURSOR;
943 crb->cursor_type = CURSOR_OFF;
946 Dynarr_add (data->db->runes, *crb);
948 Dynarr_increment (data->db->runes);
950 data->pixpos += width;
955 /* Given a string C_STRING of length C_LENGTH, call add_emchar_rune
956 for each character in the string. Propagate any left-over data
957 unless NO_PROP is non-zero. */
959 static prop_block_dynarr *
960 add_bufbyte_string_runes (pos_data *data, Bufbyte *c_string,
961 Bytecount c_length, int no_prop)
963 Bufbyte *pos, *end = c_string + c_length;
964 prop_block_dynarr *prop;
966 /* #### This function is too simplistic. It needs to do the same
967 sort of character interpretation (display-table lookup,
968 ctl-arrow checking), etc. that create_text_block() does.
969 The functionality to do this in that routine needs to be
972 for (pos = c_string; pos < end;)
974 data->ch = charptr_emchar (pos);
976 prop = add_emchar_rune (data);
984 struct prop_block pb;
985 Bytecount len = end - pos;
986 prop = Dynarr_new (prop_block);
988 pb.type = PROP_STRING;
989 pb.data.p_string.str = xnew_array (Bufbyte, len);
990 strncpy ((char *) pb.data.p_string.str, (char *) pos, len);
991 pb.data.p_string.len = len;
993 Dynarr_add (prop, pb);
1004 /* Add a single rune of the specified width. The area covered by this
1005 rune will be displayed in the foreground color of the associated
1008 static prop_block_dynarr *
1009 add_blank_rune (pos_data *data, struct window *w, int char_tab_width)
1013 /* If data->start_col is not 0 then this call to add_blank_rune must have
1014 been to add it as a tab. */
1015 if (data->start_col)
1017 /* assert (w != NULL) */
1018 prop_block_dynarr *retval;
1020 /* If we have still not fully scrolled horizontally, subtract
1021 the width of this tab and return. */
1022 if (char_tab_width < data->start_col)
1024 data->start_col -= char_tab_width;
1027 else if (char_tab_width == data->start_col)
1028 data->blank_width = 0;
1031 int spcwid = space_width (w);
1033 if (spcwid >= data->blank_width)
1034 data->blank_width = 0;
1036 data->blank_width -= spcwid;
1039 data->start_col = 0;
1040 retval = add_hscroll_rune (data);
1042 /* Could be caused by the handling of the hscroll rune. */
1043 if (retval != NULL || !data->blank_width)
1047 /* Blank runes are always calculated to fit. */
1048 assert (data->pixpos + data->blank_width <= data->max_pixpos);
1050 rb.findex = data->findex;
1051 rb.xpos = data->pixpos;
1052 rb.width = data->blank_width;
1053 if (data->bi_bufpos)
1055 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
1058 /* #### and this is really correct too? */
1061 rb.type = RUNE_BLANK;
1063 if (data->cursor_type == CURSOR_ON)
1065 if (data->bi_bufpos == data->bi_cursor_bufpos)
1067 rb.cursor_type = CURSOR_ON;
1068 data->cursor_x = Dynarr_length (data->db->runes);
1071 rb.cursor_type = CURSOR_OFF;
1073 else if (data->cursor_type == NEXT_CURSOR)
1075 rb.cursor_type = CURSOR_ON;
1076 data->cursor_x = Dynarr_length (data->db->runes);
1077 data->cursor_type = NO_CURSOR;
1080 rb.cursor_type = CURSOR_OFF;
1082 Dynarr_add (data->db->runes, rb);
1083 data->pixpos += data->blank_width;
1088 /* Add runes representing a character in octal. */
1090 #define ADD_NEXT_OCTAL_RUNE_CHAR do \
1092 if (add_failed || (add_failed = add_emchar_rune (data))) \
1094 struct prop_block pb; \
1096 prop = Dynarr_new (prop_block); \
1098 pb.type = PROP_CHAR; \
1099 pb.data.p_char.ch = data->ch; \
1100 pb.data.p_char.cursor_type = data->cursor_type; \
1101 Dynarr_add (prop, pb); \
1105 static prop_block_dynarr *
1106 add_octal_runes (pos_data *data)
1108 prop_block_dynarr *prop, *add_failed;
1109 Emchar orig_char = data->ch;
1110 unsigned int orig_cursor_type = data->cursor_type;
1116 if (data->start_col)
1119 if (!data->start_col)
1121 if (data->bi_start_col_enabled)
1123 add_failed = add_hscroll_rune (data);
1127 struct glyph_block gb;
1128 struct window *w = XWINDOW (data->window);
1131 gb.glyph = Voctal_escape_glyph;
1133 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1134 GLYPH_CACHEL (w, OCT_ESC_GLYPH_INDEX));
1138 /* We only propagate information if the glyph was partially
1143 data->cursor_type = IGNORE_CURSOR;
1145 if (data->ch >= 0x100)
1147 /* If the character is an extended Mule character, it could have
1148 up to 19 bits. For the moment, we treat it as a seven-digit
1149 octal number. This is not that pretty, but whatever. */
1150 data->ch = (7 & (orig_char >> 18)) + '0';
1151 ADD_NEXT_OCTAL_RUNE_CHAR;
1153 data->ch = (7 & (orig_char >> 15)) + '0';
1154 ADD_NEXT_OCTAL_RUNE_CHAR;
1156 data->ch = (7 & (orig_char >> 12)) + '0';
1157 ADD_NEXT_OCTAL_RUNE_CHAR;
1159 data->ch = (7 & (orig_char >> 9)) + '0';
1160 ADD_NEXT_OCTAL_RUNE_CHAR;
1163 data->ch = (7 & (orig_char >> 6)) + '0';
1164 ADD_NEXT_OCTAL_RUNE_CHAR;
1166 data->ch = (7 & (orig_char >> 3)) + '0';
1167 ADD_NEXT_OCTAL_RUNE_CHAR;
1169 data->ch = (7 & orig_char) + '0';
1170 ADD_NEXT_OCTAL_RUNE_CHAR;
1172 data->cursor_type = orig_cursor_type;
1176 #undef ADD_NEXT_OCTAL_RUNE_CHAR
1178 /* Add runes representing a control character to a display block. */
1180 static prop_block_dynarr *
1181 add_control_char_runes (pos_data *data, struct buffer *b)
1183 if (!NILP (b->ctl_arrow))
1185 prop_block_dynarr *prop;
1186 Emchar orig_char = data->ch;
1187 unsigned int old_cursor_type = data->cursor_type;
1192 if (data->start_col)
1195 if (!data->start_col)
1197 if (data->bi_start_col_enabled)
1199 prop_block_dynarr *retval;
1201 retval = add_hscroll_rune (data);
1207 struct glyph_block gb;
1208 struct window *w = XWINDOW (data->window);
1211 gb.glyph = Vcontrol_arrow_glyph;
1213 /* We only propagate information if the glyph was partially
1215 if (add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1216 GLYPH_CACHEL (w, CONTROL_GLYPH_INDEX)))
1221 if (orig_char == 0177)
1224 data->ch = orig_char ^ 0100;
1225 data->cursor_type = IGNORE_CURSOR;
1227 if (add_emchar_rune (data))
1229 struct prop_block pb;
1231 prop = Dynarr_new (prop_block);
1233 pb.type = PROP_CHAR;
1234 pb.data.p_char.ch = data->ch;
1235 pb.data.p_char.cursor_type = data->cursor_type;
1236 Dynarr_add (prop, pb);
1239 data->cursor_type = old_cursor_type;
1244 return add_octal_runes (data);
1248 static prop_block_dynarr *
1249 add_disp_table_entry_runes_1 (pos_data *data, Lisp_Object entry)
1251 prop_block_dynarr *prop = NULL;
1253 if (STRINGP (entry))
1255 prop = add_bufbyte_string_runes (data,
1256 XSTRING_DATA (entry),
1257 XSTRING_LENGTH (entry),
1260 else if (GLYPHP (entry))
1262 if (data->start_col)
1265 if (!data->start_col && data->bi_start_col_enabled)
1267 prop = add_hscroll_rune (data);
1271 struct glyph_block gb;
1275 prop = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
1278 else if (CHAR_OR_CHAR_INTP (entry))
1280 data->ch = XCHAR_OR_CHAR_INT (entry);
1281 prop = add_emchar_rune (data);
1283 else if (CONSP (entry))
1285 if (EQ (XCAR (entry), Qformat)
1286 && CONSP (XCDR (entry))
1287 && STRINGP (XCAR (XCDR (entry))))
1289 Lisp_Object format = XCAR (XCDR (entry));
1290 Bytind len = XSTRING_LENGTH (format);
1291 Bufbyte *src = XSTRING_DATA (format), *end = src + len;
1292 Bufbyte *result = alloca_array (Bufbyte, len);
1293 Bufbyte *dst = result;
1297 Emchar c = charptr_emchar (src);
1299 if (c != '%' || src == end)
1300 dst += set_charptr_emchar (dst, c);
1303 c = charptr_emchar (src);
1308 dst += long_to_string_base ((char *)dst, data->ch, 16);
1311 dst += set_charptr_emchar (dst, '%');
1313 /* #### unimplemented */
1317 prop = add_bufbyte_string_runes (data, result, dst - result, 0);
1321 /* Else blow it off because someone added a bad entry and we don't
1322 have any safe way of signaling an error. */
1326 /* Given a display table entry, call the appropriate functions to
1327 display each element of the entry. */
1329 static prop_block_dynarr *
1330 add_disp_table_entry_runes (pos_data *data, Lisp_Object entry)
1332 prop_block_dynarr *prop = NULL;
1333 if (VECTORP (entry))
1335 Lisp_Vector *de = XVECTOR (entry);
1336 EMACS_INT len = vector_length (de);
1339 for (elt = 0; elt < len; elt++)
1341 if (NILP (vector_data (de)[elt]))
1344 prop = add_disp_table_entry_runes_1 (data, vector_data (de)[elt]);
1345 /* Else blow it off because someone added a bad entry and we
1346 don't have any safe way of signaling an error. Hey, this
1347 comment sounds familiar. */
1349 /* #### Still need to add any remaining elements to the
1350 propagation information. */
1356 prop = add_disp_table_entry_runes_1 (data, entry);
1360 /* Add runes which were propagated from the previous line. */
1362 static prop_block_dynarr *
1363 add_propagation_runes (prop_block_dynarr **prop, pos_data *data)
1365 /* #### Remember to handle start_col parameter of data when the rest of
1366 this is finished. */
1367 /* #### Chuck -- I've redone this function a bit. It looked like the
1368 case of not all the propagation blocks being added was not handled
1370 /* #### Chuck -- I also think the double indirection of PROP is kind
1371 of bogus. A cleaner solution is just to check for
1372 Dynarr_length (prop) > 0. */
1373 /* #### This function also doesn't even pay attention to ADD_FAILED!
1374 This is seriously fucked! Seven ####'s in 130 lines -- is that a
1377 prop_block_dynarr *add_failed;
1378 Bytind bi_old_cursor_bufpos = data->bi_cursor_bufpos;
1379 unsigned int old_cursor_type = data->cursor_type;
1381 for (elt = 0; elt < Dynarr_length (*prop); elt++)
1383 struct prop_block *pb = Dynarr_atp (*prop, elt);
1388 data->ch = pb->data.p_char.ch;
1389 data->bi_cursor_bufpos = pb->data.p_char.bi_cursor_bufpos;
1390 data->cursor_type = pb->data.p_char.cursor_type;
1391 add_failed = add_emchar_rune (data);
1394 goto oops_no_more_space;
1397 if (pb->data.p_string.str)
1398 xfree (pb->data.p_string.str);
1399 /* #### bogus bogus -- this doesn't do anything!
1400 Should probably call add_bufbyte_string_runes(),
1401 once that function is fixed. */
1403 case PROP_MINIBUF_PROMPT:
1405 face_index old_findex = data->findex;
1406 Bytind bi_old_bufpos = data->bi_bufpos;
1408 data->findex = DEFAULT_INDEX;
1409 data->bi_bufpos = 0;
1410 data->cursor_type = NO_CURSOR;
1412 while (pb->data.p_string.len > 0)
1414 data->ch = charptr_emchar (pb->data.p_string.str);
1415 add_failed = add_emchar_rune (data);
1419 data->findex = old_findex;
1420 data->bi_bufpos = bi_old_bufpos;
1421 goto oops_no_more_space;
1425 /* Complicated equivalent of ptr++, len-- */
1426 Bufbyte *oldpos = pb->data.p_string.str;
1427 INC_CHARPTR (pb->data.p_string.str);
1428 pb->data.p_string.len -= pb->data.p_string.str - oldpos;
1432 data->findex = old_findex;
1433 /* ##### FIXME FIXME FIXME -- Upon successful return from
1434 this function, data->bi_bufpos is automatically incremented.
1435 However, we don't want that to happen if we were adding
1436 the minibuffer prompt. */
1438 struct buffer *buf =
1439 XBUFFER (WINDOW_BUFFER (XWINDOW (data->window)));
1440 /* #### Chuck fix this shit or I'm gonna scream! */
1441 if (bi_old_bufpos > BI_BUF_BEGV (buf))
1442 data->bi_bufpos = prev_bytind (buf, bi_old_bufpos);
1444 /* #### is this correct? Does anyone know?
1445 Does anyone care? Is this a cheesy hack or what? */
1446 data->bi_bufpos = BI_BUF_BEGV (buf) - 1;
1452 /* #### I think it's unnecessary and misleading to preserve
1453 the blank_width, as it implies that the value carries
1454 over from one rune to the next, which is wrong. */
1455 int old_width = data->blank_width;
1456 face_index old_findex = data->findex;
1458 data->findex = pb->data.p_blank.findex;
1459 data->blank_width = pb->data.p_blank.width;
1460 data->bi_cursor_bufpos = 0;
1461 data->cursor_type = IGNORE_CURSOR;
1463 if (data->pixpos + data->blank_width > data->max_pixpos)
1464 data->blank_width = data->max_pixpos - data->pixpos;
1466 /* We pass a bogus value of char_tab_width. It shouldn't
1467 matter because unless something is really screwed up
1468 this call won't cause that arg to be used. */
1469 add_failed = add_blank_rune (data, XWINDOW (data->window), 0);
1471 /* This can happen in the case where we have a tab which
1472 is wider than the window. */
1473 if (data->blank_width != pb->data.p_blank.width)
1475 pb->data.p_blank.width -= data->blank_width;
1476 add_failed = ADD_FAILED;
1479 data->findex = old_findex;
1480 data->blank_width = old_width;
1483 goto oops_no_more_space;
1493 data->bi_cursor_bufpos = bi_old_cursor_bufpos;
1494 data->cursor_type = old_cursor_type;
1495 if (elt < Dynarr_length (*prop))
1497 Dynarr_delete_many (*prop, 0, elt);
1502 Dynarr_free (*prop);
1507 /* Add 'text layout glyphs at position POS_TYPE that are contained to
1508 the display block, but add all other types to the appropriate list
1509 of the display line. They will be added later by different
1512 static prop_block_dynarr *
1513 add_glyph_rune (pos_data *data, struct glyph_block *gb, int pos_type,
1514 int allow_cursor, struct glyph_cachel *cachel)
1516 struct window *w = XWINDOW (data->window);
1518 /* If window faces changed, and glyph instance is text, then
1519 glyph sizes might have changed too */
1520 invalidate_glyph_geometry_maybe (gb->glyph, w);
1522 /* This makes sure the glyph is in the cachels.
1524 #### We do this to make sure the glyph is in the glyph cachels,
1525 so that the dirty flag can be reset after redisplay has
1526 finished. We should do this some other way, maybe by iterating
1527 over the window cache of subwindows. */
1528 get_glyph_cachel_index (w, gb->glyph);
1530 /* A nil extent indicates a special glyph (ex. truncator). */
1531 if (NILP (gb->extent)
1532 || (pos_type == BEGIN_GLYPHS &&
1533 extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1534 || (pos_type == END_GLYPHS &&
1535 extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1536 || pos_type == LEFT_GLYPHS || pos_type == RIGHT_GLYPHS)
1541 int ascent, descent;
1542 Lisp_Object baseline;
1544 Lisp_Object instance;
1548 width = cachel->width;
1550 width = glyph_width (gb->glyph, data->window);
1555 if (data->start_col || data->start_col_xoffset)
1557 prop_block_dynarr *retval;
1558 int glyph_char_width = width / space_width (w);
1560 /* If we still have not fully scrolled horizontally after
1561 taking into account the width of the glyph, subtract its
1562 width and return. */
1563 if (glyph_char_width < data->start_col)
1565 data->start_col -= glyph_char_width;
1568 else if (glyph_char_width == data->start_col)
1572 xoffset = space_width (w) * data->start_col;
1575 /* #### Can this happen? */
1580 data->start_col = 0;
1581 retval = add_hscroll_rune (data);
1583 /* Could be caused by the handling of the hscroll rune. */
1584 if (retval != NULL || !width)
1590 if (data->pixpos + width > data->max_pixpos)
1592 /* If this is the first object we are attempting to add to
1593 the line then we ignore the horizontal_clip threshold.
1594 Otherwise we will loop until the bottom of the window
1595 continually failing to add this glyph because it is wider
1596 than the window. We could alternatively just completely
1597 ignore the glyph and proceed from there but I think that
1598 this is a better solution. */
1599 if (Dynarr_length (data->db->runes)
1600 && data->max_pixpos - data->pixpos < horizontal_clip)
1603 width = data->max_pixpos - data->pixpos;
1608 ascent = cachel->ascent;
1609 descent = cachel->descent;
1613 ascent = glyph_ascent (gb->glyph, data->window);
1614 descent = glyph_descent (gb->glyph, data->window);
1617 baseline = glyph_baseline (gb->glyph, data->window);
1619 if (glyph_contrib_p (gb->glyph, data->window))
1621 /* A pixmap that has not had a baseline explicitly set. Its
1622 contribution will be determined later. */
1623 if (NILP (baseline))
1625 int height = ascent + descent;
1626 data->max_pixmap_height = max (data->max_pixmap_height, height);
1629 /* A string so determine contribution normally. */
1630 else if (EQ (baseline, Qt))
1632 data->new_ascent = max (data->new_ascent, ascent);
1633 data->new_descent = max (data->new_descent, descent);
1636 /* A pixmap with an explicitly set baseline. We determine the
1637 contribution here. */
1638 else if (INTP (baseline))
1640 int height = ascent + descent;
1641 int pix_ascent, pix_descent;
1643 pix_ascent = height * XINT (baseline) / 100;
1644 pix_descent = height - pix_ascent;
1646 data->new_ascent = max (data->new_ascent, pix_ascent);
1647 data->new_descent = max (data->new_descent, pix_descent);
1650 /* Otherwise something is screwed up. */
1655 face = glyph_face (gb->glyph, data->window);
1657 findex = data->findex;
1659 findex = get_builtin_face_cache_index (w, face);
1661 instance = glyph_image_instance (gb->glyph, data->window,
1663 if (TEXT_IMAGE_INSTANCEP (instance))
1665 Lisp_Object string = XIMAGE_INSTANCE_TEXT_STRING (instance);
1666 face_index orig_findex = data->findex;
1667 Bytind orig_bufpos = data->bi_bufpos;
1668 Bytind orig_start_col_enabled = data->bi_start_col_enabled;
1670 data->findex = findex;
1671 data->bi_start_col_enabled = 0;
1673 data->bi_bufpos = 0;
1674 add_bufbyte_string_runes (data, XSTRING_DATA (string),
1675 XSTRING_LENGTH (string), 0);
1676 data->findex = orig_findex;
1677 data->bi_bufpos = orig_bufpos;
1678 data->bi_start_col_enabled = orig_start_col_enabled;
1683 rb.xpos = data->pixpos;
1685 rb.bufpos = 0; /* glyphs are never "at" anywhere */
1686 if (data->bi_endpos)
1687 /* #### is this necessary at all? */
1688 rb.endpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1692 rb.type = RUNE_DGLYPH;
1693 rb.object.dglyph.glyph = gb->glyph;
1694 rb.object.dglyph.extent = gb->extent;
1695 rb.object.dglyph.xoffset = xoffset;
1699 rb.bufpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1702 if (data->cursor_type == CURSOR_ON)
1704 if (data->bi_bufpos == data->bi_cursor_bufpos)
1706 rb.cursor_type = CURSOR_ON;
1707 data->cursor_x = Dynarr_length (data->db->runes);
1710 rb.cursor_type = CURSOR_OFF;
1712 else if (data->cursor_type == NEXT_CURSOR)
1714 rb.cursor_type = CURSOR_ON;
1715 data->cursor_x = Dynarr_length (data->db->runes);
1716 data->cursor_type = NO_CURSOR;
1718 else if (data->cursor_type == IGNORE_CURSOR)
1719 rb.cursor_type = IGNORE_CURSOR;
1720 else if (data->cursor_type == NO_CURSOR)
1721 rb.cursor_type = NO_CURSOR;
1723 rb.cursor_type = CURSOR_OFF;
1726 rb.cursor_type = CURSOR_OFF;
1728 Dynarr_add (data->db->runes, rb);
1729 data->pixpos += width;
1735 if (!NILP (glyph_face (gb->glyph, data->window)))
1737 get_builtin_face_cache_index (w, glyph_face (gb->glyph,
1740 gb->findex = data->findex;
1742 if (pos_type == BEGIN_GLYPHS)
1744 if (!data->dl->left_glyphs)
1745 data->dl->left_glyphs = Dynarr_new (glyph_block);
1746 Dynarr_add (data->dl->left_glyphs, *gb);
1749 else if (pos_type == END_GLYPHS)
1751 if (!data->dl->right_glyphs)
1752 data->dl->right_glyphs = Dynarr_new (glyph_block);
1753 Dynarr_add (data->dl->right_glyphs, *gb);
1757 abort (); /* there are no unknown types */
1760 return NULL; /* shut up compiler */
1763 /* Add all glyphs at position POS_TYPE that are contained in the given
1766 static prop_block_dynarr *
1767 add_glyph_runes (pos_data *data, int pos_type)
1769 /* #### This still needs to handle the start_col parameter. Duh, Chuck,
1770 why didn't you just modify add_glyph_rune in the first place? */
1772 glyph_block_dynarr *glyph_arr = (pos_type == BEGIN_GLYPHS
1773 ? data->ef->begin_glyphs
1774 : data->ef->end_glyphs);
1775 prop_block_dynarr *prop;
1777 for (elt = 0; elt < Dynarr_length (glyph_arr); elt++)
1779 prop = add_glyph_rune (data, Dynarr_atp (glyph_arr, elt), pos_type, 0,
1784 /* #### Add some propagation information. */
1789 Dynarr_reset (glyph_arr);
1794 /* Given a position for a buffer in a window, ensure that the given
1795 display line DL accurately represents the text on a line starting
1796 at the given position.
1798 NOTE NOTE NOTE NOTE: This function works with and returns Bytinds.
1799 You must do appropriate conversion. */
1802 create_text_block (struct window *w, struct display_line *dl,
1803 Bytind bi_start_pos, prop_block_dynarr **prop,
1806 struct frame *f = XFRAME (w->frame);
1807 struct buffer *b = XBUFFER (w->buffer);
1808 struct device *d = XDEVICE (f->device);
1812 /* Don't display anything in the minibuffer if this window is not on
1813 a selected frame. We consider all other windows to be active
1814 minibuffers as it simplifies the coding. */
1815 int active_minibuffer = (!MINI_WINDOW_P (w) ||
1816 (f == device_selected_frame (d)) ||
1817 is_surrogate_for_selected_frame (f));
1819 int truncate_win = window_truncation_on (w);
1820 int end_glyph_width;
1822 /* If the buffer's value of selective_display is an integer then
1823 only lines that start with less than selective_display columns of
1824 space will be displayed. If selective_display is t then all text
1825 after a ^M is invisible. */
1826 int selective = (INTP (b->selective_display)
1827 ? XINT (b->selective_display)
1828 : (!NILP (b->selective_display) ? -1 : 0));
1830 /* The variable ctl-arrow allows the user to specify what characters
1831 can actually be displayed and which octal should be used for.
1832 #### This variable should probably have some rethought done to
1835 #### It would also be really nice if you could specify that
1836 the characters come out in hex instead of in octal. Mule
1837 does that by adding a ctl-hexa variable similar to ctl-arrow,
1838 but that's bogus -- we need a more general solution. I
1839 think you need to extend the concept of display tables
1840 into a more general conversion mechanism. Ideally you
1841 could specify a Lisp function that converts characters,
1842 but this violates the Second Golden Rule and besides would
1843 make things way way way way slow.
1845 So instead, we extend the display-table concept, which was
1846 historically limited to 256-byte vectors, to one of the
1849 a) A 256-entry vector, for backward compatibility;
1850 b) char-table, mapping characters to values;
1851 c) range-table, mapping ranges of characters to values;
1852 d) a list of the above.
1854 The (d) option allows you to specify multiple display tables
1855 instead of just one. Each display table can specify conversions
1856 for some characters and leave others unchanged. The way the
1857 character gets displayed is determined by the first display table
1858 with a binding for that character. This way, you could call a
1859 function `enable-hex-display' that adds a hex display-table to
1860 the list of display tables for the current buffer.
1862 #### ...not yet implemented... Also, we extend the concept of
1863 "mapping" to include a printf-like spec. Thus you can make all
1864 extended characters show up as hex with a display table like
1867 #s(range-table data ((256 524288) (format "%x")))
1869 Since more than one display table is possible, you have
1870 great flexibility in mapping ranges of characters. */
1871 Emchar printable_min = (CHAR_OR_CHAR_INTP (b->ctl_arrow)
1872 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
1873 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
1876 Lisp_Object face_dt, window_dt;
1878 /* The text display block for this display line. */
1879 struct display_block *db = get_display_block_from_line (dl, TEXT);
1881 /* The first time through the main loop we need to force the glyph
1882 data to be updated. */
1885 /* Apparently the new extent_fragment_update returns an end position
1886 equal to the position passed in if there are no more runs to be
1888 int no_more_frags = 0;
1890 Lisp_Object synch_minibuffers_value =
1891 symbol_value_in_buffer (Qsynchronize_minibuffers, w->buffer);
1893 dl->used_prop_data = 0;
1895 dl->line_continuation = 0;
1898 data.ef = extent_fragment_new (w->buffer, f);
1900 /* These values are used by all of the rune addition routines. We add
1901 them to this structure for ease of passing. */
1903 XSETWINDOW (data.window, w);
1908 data.bi_bufpos = bi_start_pos;
1909 data.pixpos = dl->bounds.left_in;
1910 data.last_charset = Qunbound;
1911 data.last_findex = DEFAULT_INDEX;
1912 data.result_str = Qnil;
1914 /* Set the right boundary adjusting it to take into account any end
1915 glyph. Save the width of the end glyph for later use. */
1916 data.max_pixpos = dl->bounds.right_in;
1918 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
1920 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
1921 data.max_pixpos -= end_glyph_width;
1923 if (cursor_in_echo_area && MINI_WINDOW_P (w) && echo_area_active (f))
1925 data.bi_cursor_bufpos = BI_BUF_ZV (b);
1926 data.cursor_type = CURSOR_ON;
1928 else if (MINI_WINDOW_P (w) && !active_minibuffer)
1929 data.cursor_type = NO_CURSOR;
1930 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)) &&
1931 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
1932 d == XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d))))&&
1933 f == XFRAME(DEVICE_SELECTED_FRAME(d)))
1935 data.bi_cursor_bufpos = BI_BUF_PT (b);
1936 data.cursor_type = CURSOR_ON;
1938 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)))
1940 data.bi_cursor_bufpos = bi_marker_position (w->pointm[type]);
1941 data.cursor_type = CURSOR_ON;
1944 data.cursor_type = NO_CURSOR;
1947 data.start_col = w->hscroll;
1948 data.start_col_xoffset = w->left_xoffset;
1949 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
1950 data.hscroll_glyph_width_adjust = 0;
1952 /* We regenerate the line from the very beginning. */
1953 Dynarr_reset (db->runes);
1955 /* Why is this less than or equal and not just less than? If the
1956 starting position is already equal to the maximum we can't add
1957 anything else, right? Wrong. We might still have a newline to
1958 add. A newline can use the room allocated for an end glyph since
1959 if we add it we know we aren't going to be adding any end
1962 /* #### Chuck -- I think this condition should be while (1).
1963 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
1964 and the begin-glyph ends exactly at the end of the window, the
1965 end-glyph and text might not be displayed. while (1) ensures
1966 that the loop terminates only when either (a) there is
1967 propagation data or (b) the end-of-line or end-of-buffer is hit.
1969 #### Also I think you need to ensure that the operation
1970 "add begin glyphs; add end glyphs; add text" is atomic and
1971 can't get interrupted in the middle. If you run off the end
1972 of the line during that operation, then you keep accumulating
1973 propagation data until you're done. Otherwise, if the (e.g.)
1974 there's a begin glyph at a particular position and attempting
1975 to display that glyph results in window-end being hit and
1976 propagation data being generated, then the character at that
1977 position won't be displayed.
1979 #### See also the comment after the end of this loop, below.
1981 while (data.pixpos <= data.max_pixpos
1982 && (active_minibuffer || !NILP (synch_minibuffers_value)))
1984 /* #### This check probably should not be necessary. */
1985 if (data.bi_bufpos > BI_BUF_ZV (b))
1987 /* #### urk! More of this lossage! */
1992 /* If selective display was an integer and we aren't working on
1993 a continuation line then find the next line we are actually
1994 supposed to display. */
1996 && (data.bi_bufpos == BI_BUF_BEGV (b)
1997 || BUF_FETCH_CHAR (b, prev_bytind (b, data.bi_bufpos)) == '\n'))
1999 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2002 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2003 if (data.bi_bufpos >= BI_BUF_ZV (b))
2005 data.bi_bufpos = BI_BUF_ZV (b);
2011 /* Check for face changes. */
2012 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
2014 /* Now compute the face and begin/end-glyph information. */
2016 /* Remember that the extent-fragment routines deal in Bytind's. */
2017 extent_fragment_update (w, data.ef, data.bi_bufpos);
2019 get_display_tables (w, data.findex, &face_dt, &window_dt);
2021 if (data.bi_bufpos == data.ef->end)
2026 /* Determine what is next to be displayed. We first handle any
2027 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
2028 display then we determine what to do based on the character at the
2029 current buffer position. */
2031 /* If the current position is covered by an invisible extent, do
2032 nothing (except maybe add some ellipses).
2034 #### The behavior of begin and end-glyphs at the edge of an
2035 invisible extent should be investigated further. This is
2036 fairly low priority though. */
2037 if (data.ef->invisible)
2039 /* #### Chuck, perhaps you could look at this code? I don't
2040 really know what I'm doing. */
2043 Dynarr_free (*prop);
2047 /* The extent fragment code only sets this when we should
2048 really display the ellipses. It makes sure the ellipses
2049 don't get displayed more than once in a row. */
2050 if (data.ef->invisible_ellipses)
2052 struct glyph_block gb;
2054 data.ef->invisible_ellipses_already_displayed = 1;
2055 data.ef->invisible_ellipses = 0;
2057 gb.glyph = Vinvisible_text_glyph;
2058 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2059 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2060 /* Perhaps they shouldn't propagate if the very next thing
2061 is to display a newline (for compatibility with
2062 selective-display-ellipses)? Maybe that's too
2068 /* If point is in an invisible region we place it on the
2069 next visible character. */
2070 if (data.cursor_type == CURSOR_ON
2071 && data.bi_bufpos == data.bi_cursor_bufpos)
2073 data.cursor_type = NEXT_CURSOR;
2076 /* #### What if we we're dealing with a display table? */
2080 if (data.bi_bufpos == BI_BUF_ZV (b))
2083 INC_BYTIND (b, data.bi_bufpos);
2086 /* If there is propagation data, then it represents the current
2087 buffer position being displayed. Add them and advance the
2088 position counter. This might also add the minibuffer
2092 dl->used_prop_data = 1;
2093 *prop = add_propagation_runes (prop, &data);
2096 goto done; /* gee, a really narrow window */
2097 else if (data.bi_bufpos == BI_BUF_ZV (b))
2099 else if (data.bi_bufpos < BI_BUF_BEGV (b))
2100 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
2101 data.bi_bufpos = BI_BUF_BEGV (b);
2103 INC_BYTIND (b, data.bi_bufpos);
2106 /* If there are end glyphs, add them to the line. These are
2107 the end glyphs for the previous run of text. We add them
2108 here rather than doing them at the end of handling the
2109 previous run so that glyphs at the beginning and end of
2110 a line are handled correctly. */
2111 else if (Dynarr_length (data.ef->end_glyphs) > 0)
2113 *prop = add_glyph_runes (&data, END_GLYPHS);
2118 /* If there are begin glyphs, add them to the line. */
2119 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
2121 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
2126 /* If at end-of-buffer, we've already processed begin and
2127 end-glyphs at this point and there's no text to process,
2129 else if (data.bi_bufpos == BI_BUF_ZV (b))
2134 Lisp_Object entry = Qnil;
2135 /* Get the character at the current buffer position. */
2136 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2137 if (!NILP (face_dt) || !NILP (window_dt))
2138 entry = display_table_entry (data.ch, face_dt, window_dt);
2140 /* If there is a display table entry for it, hand it off to
2141 add_disp_table_entry_runes and let it worry about it. */
2142 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
2144 *prop = add_disp_table_entry_runes (&data, entry);
2150 /* Check if we have hit a newline character. If so, add a marker
2151 to the line and end this loop. */
2152 else if (data.ch == '\n')
2154 /* We aren't going to be adding an end glyph so give its
2155 space back in order to make sure that the cursor can
2157 data.max_pixpos += end_glyph_width;
2160 && (bi_spaces_at_point
2161 (b, next_bytind (b, data.bi_bufpos))
2164 if (!NILP (b->selective_display_ellipses))
2166 struct glyph_block gb;
2169 gb.glyph = Vinvisible_text_glyph;
2170 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2171 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2175 /* Cheesy, cheesy, cheesy. We mark the end of the
2176 line with a special "character rune" whose width
2177 is the EOL cursor width and whose character is
2178 the non-printing character '\n'. */
2179 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2180 *prop = add_emchar_rune (&data);
2183 /* We need to set data.bi_bufpos to the start of the
2184 next visible region in order to make this line
2185 appear to contain all of the invisible area.
2186 Otherwise, the line cache won't work
2188 INC_BYTIND (b, data.bi_bufpos);
2189 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2192 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2193 if (data.bi_bufpos >= BI_BUF_ZV (b))
2195 data.bi_bufpos = BI_BUF_ZV (b);
2199 if (BI_BUF_FETCH_CHAR
2200 (b, prev_bytind (b, data.bi_bufpos)) == '\n')
2201 DEC_BYTIND (b, data.bi_bufpos);
2205 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2206 *prop = add_emchar_rune (&data);
2212 /* If the current character is ^M, and selective display is
2213 enabled, then add the invisible-text-glyph if
2214 selective-display-ellipses is set. In any case, this
2216 else if (data.ch == (('M' & 037)) && selective == -1)
2218 Bytind bi_next_bufpos;
2220 /* Find the buffer position at the end of the line. */
2222 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2223 if (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_next_bufpos))
2225 DEC_BYTIND (b, bi_next_bufpos);
2227 /* If the cursor is somewhere in the elided text make
2228 sure that the cursor gets drawn appropriately. */
2229 if (data.cursor_type == CURSOR_ON
2230 && (data.bi_cursor_bufpos >= data.bi_bufpos &&
2231 data.bi_cursor_bufpos < bi_next_bufpos))
2233 data.cursor_type = NEXT_CURSOR;
2236 /* We won't be adding a truncation or continuation glyph
2237 so give up the room allocated for them. */
2238 data.max_pixpos += end_glyph_width;
2240 if (!NILP (b->selective_display_ellipses))
2242 /* We don't propagate anything from the invisible
2243 text glyph if it fails to fit. This is
2245 struct glyph_block gb;
2248 gb.glyph = Vinvisible_text_glyph;
2249 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 1,
2250 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2253 /* Set the buffer position to the end of the line. We
2254 need to do this before potentially adding a newline
2255 so that the cursor flag will get set correctly (if
2257 data.bi_bufpos = bi_next_bufpos;
2259 if (NILP (b->selective_display_ellipses)
2260 || data.bi_cursor_bufpos == bi_next_bufpos)
2262 /* We have to at least add a newline character so
2263 that the cursor shows up properly. */
2265 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2266 data.findex = DEFAULT_INDEX;
2268 data.start_col_xoffset = 0;
2269 data.bi_start_col_enabled = 0;
2271 add_emchar_rune (&data);
2274 /* This had better be a newline but doing it this way
2275 we'll see obvious incorrect results if it isn't. No
2276 need to abort here. */
2277 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2282 /* If the current character is considered to be printable, then
2284 else if (data.ch >= printable_min)
2286 *prop = add_emchar_rune (&data);
2291 /* If the current character is a tab, determine the next tab
2292 starting position and add a blank rune which extends from the
2293 current pixel position to that starting position. */
2294 else if (data.ch == '\t')
2296 int tab_start_pixpos = data.pixpos;
2301 if (data.start_col > 1)
2302 tab_start_pixpos -= (space_width (w) * (data.start_col - 1))
2303 + data.start_col_xoffset;
2306 next_tab_position (w, tab_start_pixpos,
2307 dl->bounds.left_in +
2308 data.hscroll_glyph_width_adjust);
2309 if (next_tab_start > data.max_pixpos)
2311 prop_width = next_tab_start - data.max_pixpos;
2312 next_tab_start = data.max_pixpos;
2314 data.blank_width = next_tab_start - data.pixpos;
2316 (next_tab_start - tab_start_pixpos) / space_width (w);
2318 *prop = add_blank_rune (&data, w, char_tab_width);
2320 /* add_blank_rune is only supposed to be called with
2321 sizes guaranteed to fit in the available space. */
2326 struct prop_block pb;
2327 *prop = Dynarr_new (prop_block);
2329 pb.type = PROP_BLANK;
2330 pb.data.p_blank.width = prop_width;
2331 pb.data.p_blank.findex = data.findex;
2332 Dynarr_add (*prop, pb);
2338 /* If character is a control character, pass it off to
2339 add_control_char_runes.
2341 The is_*() routines have undefined results on
2342 arguments outside of the range [-1, 255]. (This
2343 often bites people who carelessly use `char' instead
2344 of `unsigned char'.)
2346 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
2348 *prop = add_control_char_runes (&data, b);
2354 /* If the character is above the ASCII range and we have not
2355 already handled it, then print it as an octal number. */
2356 else if (data.ch >= 0200)
2358 *prop = add_octal_runes (&data);
2364 /* Assume the current character is considered to be printable,
2365 then just add it. */
2368 *prop = add_emchar_rune (&data);
2373 INC_BYTIND (b, data.bi_bufpos);
2379 /* Determine the starting point of the next line if we did not hit the
2380 end of the buffer. */
2381 if (data.bi_bufpos < BI_BUF_ZV (b)
2382 && (active_minibuffer || !NILP (synch_minibuffers_value)))
2384 /* #### This check is not correct. If the line terminated
2385 due to a begin-glyph or end-glyph hitting window-end, then
2386 data.ch will not point to the character at data.bi_bufpos. If
2387 you make the two changes mentioned at the top of this loop,
2388 you should be able to say '(if (*prop))'. That should also
2389 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
2392 /* The common case is that the line ended because we hit a newline.
2393 In that case, the next character is just the next buffer
2395 if (data.ch == '\n')
2397 /* If data.start_col_enabled is still true, then the window is
2398 scrolled far enough so that nothing on this line is visible.
2399 We need to stick a truncation glyph at the beginning of the
2400 line in that case unless the line is completely blank. */
2401 if (data.bi_start_col_enabled)
2403 if (data.cursor_type == CURSOR_ON)
2405 if (data.bi_cursor_bufpos >= bi_start_pos
2406 && data.bi_cursor_bufpos <= data.bi_bufpos)
2407 data.bi_cursor_bufpos = data.bi_bufpos;
2409 data.findex = DEFAULT_INDEX;
2411 data.bi_start_col_enabled = 0;
2413 if (data.bi_bufpos != bi_start_pos)
2415 struct glyph_block gb;
2418 gb.glyph = Vhscroll_glyph;
2419 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2420 GLYPH_CACHEL (w, HSCROLL_GLYPH_INDEX));
2424 /* This duplicates code down below to add a newline to
2425 the end of an otherwise empty line.*/
2427 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2429 add_emchar_rune (&data);
2433 INC_BYTIND (b, data.bi_bufpos);
2436 /* Otherwise we have a buffer line which cannot fit on one display
2440 struct glyph_block gb;
2441 struct glyph_cachel *cachel;
2443 /* If the line is to be truncated then we actually have to look
2444 for the next newline. We also add the end-of-line glyph which
2445 we know will fit because we adjusted the right border before
2446 we starting laying out the line. */
2447 data.max_pixpos += end_glyph_width;
2448 data.findex = DEFAULT_INDEX;
2455 /* Now find the start of the next line. */
2456 bi_pos = bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2458 /* If the cursor is past the truncation line then we
2459 make it appear on the truncation glyph. If we've hit
2460 the end of the buffer then we also make the cursor
2461 appear unless eob is immediately preceded by a
2462 newline. In that case the cursor should actually
2463 appear on the next line. */
2464 if (data.cursor_type == CURSOR_ON
2465 && data.bi_cursor_bufpos >= data.bi_bufpos
2466 && (data.bi_cursor_bufpos < bi_pos ||
2467 (bi_pos == BI_BUF_ZV (b)
2468 && (bi_pos == BI_BUF_BEGV (b)
2469 || (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_pos))
2471 data.bi_cursor_bufpos = bi_pos;
2473 data.cursor_type = NO_CURSOR;
2475 data.bi_bufpos = bi_pos;
2476 gb.glyph = Vtruncation_glyph;
2477 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
2481 /* The cursor can never be on the continuation glyph. */
2482 data.cursor_type = NO_CURSOR;
2484 /* data.bi_bufpos is already at the start of the next line. */
2486 dl->line_continuation = 1;
2487 gb.glyph = Vcontinuation_glyph;
2488 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
2491 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
2493 if (truncate_win && data.bi_bufpos == BI_BUF_ZV (b)
2494 && BI_BUF_FETCH_CHAR (b, prev_bytind (b, BI_BUF_ZV (b))) != '\n')
2495 /* #### Damn this losing shit. */
2499 else if ((active_minibuffer || !NILP (synch_minibuffers_value))
2500 && (!echo_area_active (f) || data.bi_bufpos == BI_BUF_ZV (b)))
2502 /* We need to add a marker to the end of the line since there is no
2503 newline character in order for the cursor to get drawn. We label
2504 it as a newline so that it gets handled correctly by the
2505 whitespace routines below. */
2508 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2509 data.findex = DEFAULT_INDEX;
2511 data.start_col_xoffset = 0;
2512 data.bi_start_col_enabled = 0;
2514 data.max_pixpos += data.blank_width;
2515 add_emchar_rune (&data);
2516 data.max_pixpos -= data.blank_width;
2518 /* #### urk! Chuck, this shit is bad news. Going around
2519 manipulating invalid positions is guaranteed to result in
2520 trouble sooner or later. */
2521 data.bi_bufpos = BI_BUF_ZV (b) + 1;
2524 /* Calculate left whitespace boundary. */
2528 /* Whitespace past a newline is considered right whitespace. */
2529 while (elt < Dynarr_length (db->runes))
2531 struct rune *rb = Dynarr_atp (db->runes, elt);
2533 if ((rb->type == RUNE_CHAR && rb->object.chr.ch == ' ')
2534 || rb->type == RUNE_BLANK)
2536 dl->bounds.left_white += rb->width;
2540 elt = Dynarr_length (db->runes);
2544 /* Calculate right whitespace boundary. */
2546 int elt = Dynarr_length (db->runes) - 1;
2549 while (!done && elt >= 0)
2551 struct rune *rb = Dynarr_atp (db->runes, elt);
2553 if (!(rb->type == RUNE_CHAR && rb->object.chr.ch < 0x100
2554 && isspace (rb->object.chr.ch))
2555 && !rb->type == RUNE_BLANK)
2557 dl->bounds.right_white = rb->xpos + rb->width;
2565 /* The line is blank so everything is considered to be right
2568 dl->bounds.right_white = dl->bounds.left_in;
2571 /* Set the display blocks bounds. */
2572 db->start_pos = dl->bounds.left_in;
2573 if (Dynarr_length (db->runes))
2575 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
2577 db->end_pos = rb->xpos + rb->width;
2580 db->end_pos = dl->bounds.right_white;
2582 /* update line height parameters */
2583 if (!data.new_ascent && !data.new_descent)
2585 /* We've got a blank line so initialize these values from the default
2587 default_face_font_info (data.window, &data.new_ascent,
2588 &data.new_descent, 0, 0, 0);
2591 if (data.max_pixmap_height)
2593 int height = data.new_ascent + data.new_descent;
2594 int pix_ascent, pix_descent;
2596 pix_descent = data.max_pixmap_height * data.new_descent / height;
2597 pix_ascent = data.max_pixmap_height - pix_descent;
2599 data.new_ascent = max (data.new_ascent, pix_ascent);
2600 data.new_descent = max (data.new_descent, pix_descent);
2603 dl->ascent = data.new_ascent;
2604 dl->descent = data.new_descent;
2607 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
2609 if (dl->ascent < ascent)
2610 dl->ascent = ascent;
2613 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
2615 if (dl->descent < descent)
2616 dl->descent = descent;
2619 dl->cursor_elt = data.cursor_x;
2620 /* #### lossage lossage lossage! Fix this shit! */
2621 if (data.bi_bufpos > BI_BUF_ZV (b))
2622 dl->end_bufpos = BUF_ZV (b);
2624 dl->end_bufpos = bytind_to_bufpos (b, data.bi_bufpos) - 1;
2626 data.dl->num_chars = column_at_point (b, dl->end_bufpos, 0);
2628 /* This doesn't correctly take into account tabs and control
2629 characters but if the window isn't being truncated then this
2630 value isn't going to end up being used anyhow. */
2631 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
2633 /* #### handle horizontally scrolled line with text none of which
2634 was actually laid out. */
2636 /* #### handle any remainder of overlay arrow */
2638 if (*prop == ADD_FAILED)
2641 if (truncate_win && *prop)
2643 Dynarr_free (*prop);
2647 extent_fragment_delete (data.ef);
2649 /* #### If we started at EOB, then make sure we return a value past
2650 it so that regenerate_window will exit properly. This is bogus.
2651 The main loop should get fixed so that it isn't necessary to call
2652 this function if we are already at EOB. */
2654 if (data.bi_bufpos == BI_BUF_ZV (b) && bi_start_pos == BI_BUF_ZV (b))
2655 return data.bi_bufpos + 1; /* Yuck! */
2657 return data.bi_bufpos;
2660 /* Display the overlay arrow at the beginning of the given line. */
2663 create_overlay_glyph_block (struct window *w, struct display_line *dl)
2665 struct frame *f = XFRAME (w->frame);
2666 struct device *d = XDEVICE (f->device);
2669 /* If Voverlay_arrow_string isn't valid then just fail silently. */
2670 if (!STRINGP (Voverlay_arrow_string) && !GLYPHP (Voverlay_arrow_string))
2676 XSETWINDOW (data.window, w);
2677 data.db = get_display_block_from_line (dl, OVERWRITE);
2679 data.pixpos = dl->bounds.left_in;
2680 data.max_pixpos = dl->bounds.right_in;
2681 data.cursor_type = NO_CURSOR;
2683 data.findex = DEFAULT_INDEX;
2684 data.last_charset = Qunbound;
2685 data.last_findex = DEFAULT_INDEX;
2686 data.result_str = Qnil;
2689 Dynarr_reset (data.db->runes);
2691 if (STRINGP (Voverlay_arrow_string))
2693 add_bufbyte_string_runes
2695 XSTRING_DATA (Voverlay_arrow_string),
2696 XSTRING_LENGTH (Voverlay_arrow_string),
2699 else if (GLYPHP (Voverlay_arrow_string))
2701 struct glyph_block gb;
2703 gb.glyph = Voverlay_arrow_string;
2705 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, 0);
2708 if (data.max_pixmap_height)
2710 int height = data.new_ascent + data.new_descent;
2711 int pix_ascent, pix_descent;
2713 pix_descent = data.max_pixmap_height * data.new_descent / height;
2714 pix_ascent = data.max_pixmap_height - pix_descent;
2716 data.new_ascent = max (data.new_ascent, pix_ascent);
2717 data.new_descent = max (data.new_descent, pix_descent);
2720 dl->ascent = data.new_ascent;
2721 dl->descent = data.new_descent;
2723 data.db->start_pos = dl->bounds.left_in;
2724 data.db->end_pos = data.pixpos;
2726 return data.pixpos - dl->bounds.left_in;
2729 /* Add a type of glyph to a margin display block. */
2732 add_margin_runes (struct display_line *dl, struct display_block *db, int start,
2733 int count, enum glyph_layout layout, int side, Lisp_Object window)
2735 glyph_block_dynarr *gbd = (side == LEFT_GLYPHS
2737 : dl->right_glyphs);
2740 struct window *w = XWINDOW (window);
2741 struct frame *f = XFRAME (w->frame);
2742 struct device *d = XDEVICE (f->device);
2747 data.window = window;
2750 data.pixpos = start;
2751 data.cursor_type = NO_CURSOR;
2753 data.last_charset = Qunbound;
2754 data.last_findex = DEFAULT_INDEX;
2755 data.result_str = Qnil;
2757 data.new_ascent = dl->ascent;
2758 data.new_descent = dl->descent;
2760 if ((layout == GL_WHITESPACE && side == LEFT_GLYPHS)
2761 || (layout == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS))
2764 elt = Dynarr_length (gbd) - 1;
2771 end = Dynarr_length (gbd);
2774 while (count && ((!reverse && elt < end) || (reverse && elt >= end)))
2776 struct glyph_block *gb = Dynarr_atp (gbd, elt);
2778 if (NILP (gb->extent))
2779 abort (); /* these should have been handled in add_glyph_rune */
2782 ((side == LEFT_GLYPHS &&
2783 extent_begin_glyph_layout (XEXTENT (gb->extent)) == layout)
2784 || (side == RIGHT_GLYPHS &&
2785 extent_end_glyph_layout (XEXTENT (gb->extent)) == layout)))
2787 data.findex = gb->findex;
2788 data.max_pixpos = data.pixpos + gb->width;
2789 add_glyph_rune (&data, gb, side, 0, NULL);
2794 (reverse ? elt-- : elt++);
2797 if (data.max_pixmap_height)
2799 int height = data.new_ascent + data.new_descent;
2800 int pix_ascent, pix_descent;
2802 pix_descent = data.max_pixmap_height * data.new_descent / height;
2803 pix_ascent = data.max_pixmap_height - pix_descent;
2804 data.new_ascent = max (data.new_ascent, pix_ascent);
2805 data.new_descent = max (data.new_descent, pix_descent);
2808 dl->ascent = data.new_ascent;
2809 dl->descent = data.new_descent;
2814 /* Add a blank to a margin display block. */
2817 add_margin_blank (struct display_line *dl, struct display_block *db,
2818 struct window *w, int xpos, int width, int side)
2822 rb.findex = (side == LEFT_GLYPHS
2823 ? get_builtin_face_cache_index (w, Vleft_margin_face)
2824 : get_builtin_face_cache_index (w, Vright_margin_face));
2829 rb.type = RUNE_BLANK;
2830 rb.cursor_type = CURSOR_OFF;
2832 Dynarr_add (db->runes, rb);
2835 /* Display glyphs in the left outside margin, left inside margin and
2836 left whitespace area. */
2839 create_left_glyph_block (struct window *w, struct display_line *dl,
2844 int use_overflow = (NILP (w->use_left_overflow) ? 0 : 1);
2846 int out_end, in_out_start, in_in_end, white_out_start, white_in_start;
2847 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
2848 int left_in_start = dl->bounds.left_in;
2849 int left_in_end = dl->bounds.left_in + overlay_width;
2851 struct display_block *odb, *idb;
2853 XSETWINDOW (window, w);
2855 /* We have to add the glyphs to the line in the order outside,
2856 inside, whitespace. However the precedence dictates that we
2857 determine how many will fit in the reverse order. */
2859 /* Determine how many whitespace glyphs we can display and where
2860 they should start. */
2861 white_in_start = dl->bounds.left_white;
2862 white_out_start = left_in_start;
2863 white_out_cnt = white_in_cnt = 0;
2866 while (elt < Dynarr_length (dl->left_glyphs))
2868 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2870 if (NILP (gb->extent))
2871 abort (); /* these should have been handled in add_glyph_rune */
2873 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
2877 width = glyph_width (gb->glyph, window);
2879 if (white_in_start - width >= left_in_end)
2882 white_in_start -= width;
2886 else if (use_overflow
2887 && (white_out_start - width > dl->bounds.left_out))
2890 white_out_start -= width;
2901 /* Determine how many inside margin glyphs we can display and where
2902 they should start. The inside margin glyphs get whatever space
2903 is left after the whitespace glyphs have been displayed. These
2904 are tricky to calculate since if we decide to use the overflow
2905 area we basically have to start over. So for these we build up a
2906 list of just the inside margin glyphs and manipulate it to
2907 determine the needed info. */
2909 glyph_block_dynarr *ib;
2910 int avail_in, avail_out;
2913 int used_in, used_out;
2916 used_in = used_out = 0;
2917 ib = Dynarr_new (glyph_block);
2918 while (elt < Dynarr_length (dl->left_glyphs))
2920 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2922 if (NILP (gb->extent))
2923 abort (); /* these should have been handled in add_glyph_rune */
2925 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
2928 gb->width = glyph_width (gb->glyph, window);
2929 used_in += gb->width;
2930 Dynarr_add (ib, *gb);
2940 avail_in = white_in_start - left_in_end;
2948 avail_out = white_out_start - dl->bounds.left_out;
2951 while (!done && marker < Dynarr_length (ib))
2953 int width = Dynarr_atp (ib, marker)->width;
2955 /* If everything now fits in the available inside margin
2956 space, we're done. */
2957 if (used_in <= avail_in)
2961 /* Otherwise see if we have room to move a glyph to the
2963 if (used_out + width <= avail_out)
2976 /* At this point we now know that everything from marker on goes in
2977 the inside margin and everything before it goes in the outside
2978 margin. The stuff going into the outside margin is guaranteed
2979 to fit, but we may have to trim some stuff from the inside. */
2981 in_in_end = left_in_end;
2982 in_out_start = white_out_start;
2983 in_out_cnt = in_in_cnt = 0;
2987 while (elt < Dynarr_length (dl->left_glyphs))
2989 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2991 if (NILP (gb->extent))
2992 abort (); /* these should have been handled in add_glyph_rune */
2994 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
2997 int width = glyph_width (gb->glyph, window);
3002 in_out_start -= width;
3007 else if (in_in_end + width < white_in_start)
3022 /* Determine how many outside margin glyphs we can display. They
3023 always start at the left outside margin and can only use the
3024 outside margin space. */
3025 out_end = dl->bounds.left_out;
3029 while (elt < Dynarr_length (dl->left_glyphs))
3031 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3033 if (NILP (gb->extent))
3034 abort (); /* these should have been handled in add_glyph_rune */
3036 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3039 int width = glyph_width (gb->glyph, window);
3041 if (out_end + width <= in_out_start)
3055 /* Now that we know where everything goes, we add the glyphs as
3056 runes to the appropriate display blocks. */
3057 if (out_cnt || in_out_cnt || white_out_cnt)
3059 odb = get_display_block_from_line (dl, LEFT_OUTSIDE_MARGIN);
3060 odb->start_pos = dl->bounds.left_out;
3061 /* #### We should stop adding a blank to account for the space
3062 between the end of the glyphs and the margin and instead set
3063 this accordingly. */
3064 odb->end_pos = dl->bounds.left_in;
3065 Dynarr_reset (odb->runes);
3070 if (in_in_cnt || white_in_cnt)
3072 idb = get_display_block_from_line (dl, LEFT_INSIDE_MARGIN);
3073 idb->start_pos = dl->bounds.left_in;
3074 /* #### See above comment for odb->end_pos */
3075 idb->end_pos = dl->bounds.left_white;
3076 Dynarr_reset (idb->runes);
3081 /* First add the outside margin glyphs. */
3083 end_xpos = add_margin_runes (dl, odb, dl->bounds.left_out, out_cnt,
3084 GL_OUTSIDE_MARGIN, LEFT_GLYPHS, window);
3086 end_xpos = dl->bounds.left_out;
3088 /* There may be blank space between the outside margin glyphs and
3089 the inside margin glyphs. If so, add a blank. */
3090 if (in_out_cnt && (in_out_start - end_xpos))
3092 add_margin_blank (dl, odb, w, end_xpos, in_out_start - end_xpos,
3096 /* Next add the inside margin glyphs which are actually in the
3100 end_xpos = add_margin_runes (dl, odb, in_out_start, in_out_cnt,
3101 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3104 /* If we didn't add any inside margin glyphs to the outside margin,
3105 but are adding whitespace glyphs, then we need to add a blank
3107 if (!in_out_cnt && white_out_cnt && (white_out_start - end_xpos))
3109 add_margin_blank (dl, odb, w, end_xpos, white_out_start - end_xpos,
3113 /* Next add the whitespace margin glyphs which are actually in the
3117 end_xpos = add_margin_runes (dl, odb, white_out_start, white_out_cnt,
3118 GL_WHITESPACE, LEFT_GLYPHS, window);
3121 /* We take care of clearing between the end of the glyphs and the
3122 start of the inside margin for lines which have glyphs. */
3123 if (odb && (left_in_start - end_xpos))
3125 add_margin_blank (dl, odb, w, end_xpos, left_in_start - end_xpos,
3129 /* Next add the inside margin glyphs which are actually in the
3133 end_xpos = add_margin_runes (dl, idb, left_in_end, in_in_cnt,
3134 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3137 end_xpos = left_in_end;
3139 /* Make sure that the area between the end of the inside margin
3140 glyphs and the whitespace glyphs is cleared. */
3141 if (idb && (white_in_start - end_xpos > 0))
3143 add_margin_blank (dl, idb, w, end_xpos, white_in_start - end_xpos,
3147 /* Next add the whitespace margin glyphs which are actually in the
3151 add_margin_runes (dl, idb, white_in_start, white_in_cnt, GL_WHITESPACE,
3152 LEFT_GLYPHS, window);
3155 /* Whitespace glyphs always end right next to the text block so
3156 there is nothing we have to make sure is cleared after them. */
3159 /* Display glyphs in the right outside margin, right inside margin and
3160 right whitespace area. */
3163 create_right_glyph_block (struct window *w, struct display_line *dl)
3167 int use_overflow = (NILP (w->use_right_overflow) ? 0 : 1);
3169 int out_start, in_out_end, in_in_start, white_out_end, white_in_end;
3170 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
3172 struct display_block *odb, *idb;
3174 XSETWINDOW (window, w);
3176 /* We have to add the glyphs to the line in the order outside,
3177 inside, whitespace. However the precedence dictates that we
3178 determine how many will fit in the reverse order. */
3180 /* Determine how many whitespace glyphs we can display and where
3181 they should start. */
3182 white_in_end = dl->bounds.right_white;
3183 white_out_end = dl->bounds.right_in;
3184 white_out_cnt = white_in_cnt = 0;
3187 while (elt < Dynarr_length (dl->right_glyphs))
3189 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3191 if (NILP (gb->extent))
3192 abort (); /* these should have been handled in add_glyph_rune */
3194 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
3196 int width = glyph_width (gb->glyph, window);
3198 if (white_in_end + width <= dl->bounds.right_in)
3201 white_in_end += width;
3205 else if (use_overflow
3206 && (white_out_end + width <= dl->bounds.right_out))
3209 white_out_end += width;
3220 /* Determine how many inside margin glyphs we can display and where
3221 they should start. The inside margin glyphs get whatever space
3222 is left after the whitespace glyphs have been displayed. These
3223 are tricky to calculate since if we decide to use the overflow
3224 area we basically have to start over. So for these we build up a
3225 list of just the inside margin glyphs and manipulate it to
3226 determine the needed info. */
3228 glyph_block_dynarr *ib;
3229 int avail_in, avail_out;
3232 int used_in, used_out;
3235 used_in = used_out = 0;
3236 ib = Dynarr_new (glyph_block);
3237 while (elt < Dynarr_length (dl->right_glyphs))
3239 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3241 if (NILP (gb->extent))
3242 abort (); /* these should have been handled in add_glyph_rune */
3244 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3246 gb->width = glyph_width (gb->glyph, window);
3247 used_in += gb->width;
3248 Dynarr_add (ib, *gb);
3257 avail_in = dl->bounds.right_in - white_in_end;
3262 avail_out = dl->bounds.right_out - white_out_end;
3265 while (!done && marker < Dynarr_length (ib))
3267 int width = Dynarr_atp (ib, marker)->width;
3269 /* If everything now fits in the available inside margin
3270 space, we're done. */
3271 if (used_in <= avail_in)
3275 /* Otherwise see if we have room to move a glyph to the
3277 if (used_out + width <= avail_out)
3290 /* At this point we now know that everything from marker on goes in
3291 the inside margin and everything before it goes in the outside
3292 margin. The stuff going into the outside margin is guaranteed
3293 to fit, but we may have to trim some stuff from the inside. */
3295 in_in_start = dl->bounds.right_in;
3296 in_out_end = dl->bounds.right_in;
3297 in_out_cnt = in_in_cnt = 0;
3301 while (elt < Dynarr_length (dl->right_glyphs))
3303 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3305 if (NILP (gb->extent))
3306 abort (); /* these should have been handled in add_glyph_rune */
3308 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3310 int width = glyph_width (gb->glyph, window);
3315 in_out_end += width;
3320 else if (in_in_start - width >= white_in_end)
3323 in_in_start -= width;
3335 /* Determine how many outside margin glyphs we can display. They
3336 always start at the right outside margin and can only use the
3337 outside margin space. */
3338 out_start = dl->bounds.right_out;
3342 while (elt < Dynarr_length (dl->right_glyphs))
3344 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3346 if (NILP (gb->extent))
3347 abort (); /* these should have been handled in add_glyph_rune */
3349 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_OUTSIDE_MARGIN)
3351 int width = glyph_width (gb->glyph, window);
3353 if (out_start - width >= in_out_end)
3367 /* Now that we now where everything goes, we add the glyphs as runes
3368 to the appropriate display blocks. */
3369 if (out_cnt || in_out_cnt || white_out_cnt)
3371 odb = get_display_block_from_line (dl, RIGHT_OUTSIDE_MARGIN);
3372 /* #### See comments before odb->start_pos init in
3373 create_left_glyph_block */
3374 odb->start_pos = dl->bounds.right_in;
3375 odb->end_pos = dl->bounds.right_out;
3376 Dynarr_reset (odb->runes);
3381 if (in_in_cnt || white_in_cnt)
3383 idb = get_display_block_from_line (dl, RIGHT_INSIDE_MARGIN);
3384 idb->start_pos = dl->bounds.right_white;
3385 /* #### See comments before odb->start_pos init in
3386 create_left_glyph_block */
3387 idb->end_pos = dl->bounds.right_in;
3388 Dynarr_reset (idb->runes);
3393 /* First add the whitespace margin glyphs which are actually in the
3397 end_xpos = add_margin_runes (dl, idb, dl->bounds.right_white,
3398 white_in_cnt, GL_WHITESPACE, RIGHT_GLYPHS,
3402 end_xpos = dl->bounds.right_white;
3404 /* Make sure that the area between the end of the whitespace glyphs
3405 and the inside margin glyphs is cleared. */
3406 if (in_in_cnt && (in_in_start - end_xpos))
3408 add_margin_blank (dl, idb, w, end_xpos, in_in_start - end_xpos,
3412 /* Next add the inside margin glyphs which are actually in the
3416 end_xpos = add_margin_runes (dl, idb, in_in_start, in_in_cnt,
3417 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3420 /* If we didn't add any inside margin glyphs then make sure the rest
3421 of the inside margin area gets cleared. */
3422 if (idb && (dl->bounds.right_in - end_xpos))
3424 add_margin_blank (dl, idb, w, end_xpos, dl->bounds.right_in - end_xpos,
3428 /* Next add any whitespace glyphs in the outside margin. */
3431 end_xpos = add_margin_runes (dl, odb, dl->bounds.right_in, white_out_cnt,
3432 GL_WHITESPACE, RIGHT_GLYPHS, window);
3435 end_xpos = dl->bounds.right_in;
3437 /* Next add any inside margin glyphs in the outside margin. */
3440 end_xpos = add_margin_runes (dl, odb, end_xpos, in_out_cnt,
3441 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3444 /* There may be space between any whitespace or inside margin glyphs
3445 in the outside margin and the actual outside margin glyphs. */
3446 if (odb && (out_start - end_xpos))
3448 add_margin_blank (dl, odb, w, end_xpos, out_start - end_xpos,
3452 /* Finally, add the outside margin glyphs. */
3455 add_margin_runes (dl, odb, out_start, out_cnt, GL_OUTSIDE_MARGIN,
3456 RIGHT_GLYPHS, window);
3461 /***************************************************************************/
3463 /* modeline routines */
3465 /***************************************************************************/
3467 /* This function is also used in frame.c by `generate_title_string' */
3469 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str,
3470 struct window *w, struct display_line *dl,
3471 struct display_block *db, face_index findex,
3472 int min_pixpos, int max_pixpos, int type)
3474 struct frame *f = XFRAME (w->frame);
3475 struct device *d = XDEVICE (f->device);
3479 Charcount offset = 0;
3485 data.findex = findex;
3486 data.pixpos = min_pixpos;
3487 data.max_pixpos = max_pixpos;
3488 data.cursor_type = NO_CURSOR;
3489 data.last_charset = Qunbound;
3490 data.last_findex = DEFAULT_INDEX;
3491 data.result_str = result_str;
3492 data.is_modeline = 1;
3494 XSETWINDOW (data.window, w);
3496 Dynarr_reset (formatted_string_extent_dynarr);
3497 Dynarr_reset (formatted_string_extent_start_dynarr);
3498 Dynarr_reset (formatted_string_extent_end_dynarr);
3500 /* result_str is nil when we're building a frame or icon title. Otherwise,
3501 we're building a modeline, so the offset starts at the modeline
3502 horizontal scrolling amount */
3503 if (! NILP (result_str))
3504 offset = w->modeline_hscroll;
3505 generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0,
3506 max_pixpos - min_pixpos, findex, type, &offset,
3509 if (Dynarr_length (db->runes))
3512 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
3513 c_pixpos = rb->xpos + rb->width;
3516 c_pixpos = min_pixpos;
3518 /* If we don't reach the right side of the window, add a blank rune
3519 to make up the difference. This usually only occurs if the
3520 modeline face is using a proportional width font or a fixed width
3521 font of a different size from the default face font. */
3523 if (c_pixpos < max_pixpos)
3525 data.pixpos = c_pixpos;
3526 data.blank_width = max_pixpos - data.pixpos;
3528 add_blank_rune (&data, NULL, 0);
3531 /* Now create the result string and frob the extents into it. */
3532 if (!NILP (result_str))
3537 struct buffer *buf = XBUFFER (WINDOW_BUFFER (w));
3539 in_modeline_generation = 1;
3541 detach_all_extents (result_str);
3542 resize_string (XSTRING (result_str), -1,
3543 data.bytepos - XSTRING_LENGTH (result_str));
3545 strdata = XSTRING_DATA (result_str);
3547 for (elt = 0, len = 0; elt < Dynarr_length (db->runes); elt++)
3549 if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR)
3551 len += (set_charptr_emchar
3552 (strdata + len, Dynarr_atp (db->runes,
3553 elt)->object.chr.ch));
3557 for (elt = 0; elt < Dynarr_length (formatted_string_extent_dynarr);
3560 Lisp_Object extent = Qnil;
3563 XSETEXTENT (extent, Dynarr_at (formatted_string_extent_dynarr, elt));
3564 child = Fgethash (extent, buf->modeline_extent_table, Qnil);
3567 child = Fmake_extent (Qnil, Qnil, result_str);
3568 Fputhash (extent, child, buf->modeline_extent_table);
3570 Fset_extent_parent (child, extent);
3571 set_extent_endpoints
3573 Dynarr_at (formatted_string_extent_start_dynarr, elt),
3574 Dynarr_at (formatted_string_extent_end_dynarr, elt),
3578 in_modeline_generation = 0;
3582 /* Ensure that the given display line DL accurately represents the
3583 modeline for the given window. */
3585 generate_modeline (struct window *w, struct display_line *dl, int type)
3587 struct buffer *b = XBUFFER (w->buffer);
3588 struct frame *f = XFRAME (w->frame);
3589 struct device *d = XDEVICE (f->device);
3591 /* Unlike display line and rune pointers, this one can't change underneath
3593 struct display_block *db = get_display_block_from_line (dl, TEXT);
3594 int max_pixpos, min_pixpos, ypos_adj;
3595 Lisp_Object font_inst;
3597 /* This will actually determine incorrect inside boundaries for the
3598 modeline since it ignores the margins. However being aware of this fact
3599 we never use those values anywhere so it doesn't matter. */
3600 dl->bounds = calculate_display_line_boundaries (w, 1);
3602 /* We are generating a modeline. */
3604 dl->cursor_elt = -1;
3606 /* Reset the runes on the modeline. */
3607 Dynarr_reset (db->runes);
3609 if (!WINDOW_HAS_MODELINE_P (w))
3613 /* If there is a horizontal scrollbar, don't add anything. */
3614 if (window_scrollbar_height (w))
3617 dl->ascent = DEVMETH (d, divider_height, ());
3619 /* The modeline is at the bottom of the gutters. */
3620 dl->ypos = WINDOW_BOTTOM (w);
3622 rb.findex = MODELINE_INDEX;
3623 rb.xpos = dl->bounds.left_out;
3624 rb.width = dl->bounds.right_out - dl->bounds.left_out;
3627 rb.type = RUNE_HLINE;
3628 rb.object.hline.thickness = 1;
3629 rb.object.hline.yoffset = 0;
3630 rb.cursor_type = NO_CURSOR;
3632 if (!EQ (Qzero, w->modeline_shadow_thickness)
3635 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3637 dl->ypos -= shadow_thickness;
3638 rb.xpos += shadow_thickness;
3639 rb.width -= 2 * shadow_thickness;
3642 Dynarr_add (db->runes, rb);
3646 /* !!#### not right; needs to compute the max height of
3648 font_inst = WINDOW_FACE_CACHEL_FONT (w, MODELINE_INDEX, Vcharset_ascii);
3650 dl->ascent = XFONT_INSTANCE (font_inst)->ascent;
3651 dl->descent = XFONT_INSTANCE (font_inst)->descent;
3653 min_pixpos = dl->bounds.left_out;
3654 max_pixpos = dl->bounds.right_out;
3656 if (!EQ (Qzero, w->modeline_shadow_thickness) && FRAME_WIN_P (f))
3658 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3660 ypos_adj = shadow_thickness;
3661 min_pixpos += shadow_thickness;
3662 max_pixpos -= shadow_thickness;
3667 generate_formatted_string_db (b->modeline_format,
3668 b->generated_modeline_string, w, dl, db,
3669 MODELINE_INDEX, min_pixpos, max_pixpos, type);
3671 /* The modeline is at the bottom of the gutters. We have to wait to
3672 set this until we've generated the modeline in order to account
3673 for any embedded faces. */
3674 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj;
3678 add_string_to_fstring_db_runes (pos_data *data, const Bufbyte *str,
3679 Charcount pos, Charcount min_pos, Charcount max_pos)
3681 /* This function has been Mule-ized. */
3683 const Bufbyte *cur_pos = str;
3684 struct display_block *db = data->db;
3686 data->blank_width = space_width (XWINDOW (data->window));
3687 while (Dynarr_length (db->runes) < pos)
3688 add_blank_rune (data, NULL, 0);
3690 end = (Dynarr_length (db->runes) +
3691 bytecount_to_charcount (str, strlen ((const char *) str)));
3693 end = min (max_pos, end);
3695 while (pos < end && *cur_pos)
3697 const Bufbyte *old_cur_pos = cur_pos;
3700 data->ch = charptr_emchar (cur_pos);
3701 succeeded = (add_emchar_rune (data) != ADD_FAILED);
3702 INC_CHARPTR (cur_pos);
3706 data->modeline_charpos++;
3707 data->bytepos += cur_pos - old_cur_pos;
3711 while (Dynarr_length (db->runes) < min_pos &&
3712 (data->pixpos + data->blank_width <= data->max_pixpos))
3713 add_blank_rune (data, NULL, 0);
3715 return Dynarr_length (db->runes);
3718 /* #### Urk! Should also handle begin-glyphs and end-glyphs in
3719 modeline extents. */
3721 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph,
3722 Charcount pos, Charcount min_pos,
3723 Charcount max_pos, Lisp_Object extent)
3725 /* This function has been Mule-ized. */
3727 struct display_block *db = data->db;
3728 struct glyph_block gb;
3730 data->blank_width = space_width (XWINDOW (data->window));
3731 while (Dynarr_length (db->runes) < pos)
3732 add_blank_rune (data, NULL, 0);
3734 end = Dynarr_length (db->runes) + 1;
3736 end = min (max_pos, end);
3740 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
3743 while (Dynarr_length (db->runes) < pos &&
3744 (data->pixpos + data->blank_width <= data->max_pixpos))
3745 add_blank_rune (data, NULL, 0);
3747 return Dynarr_length (db->runes);
3750 /* If max_pos is == -1, it is considered to be infinite. The same is
3751 true of max_pixsize. */
3752 #define SET_CURRENT_MODE_CHARS_PIXSIZE \
3753 if (Dynarr_length (data->db->runes)) \
3754 cur_pixsize = data->pixpos - Dynarr_atp (data->db->runes, 0)->xpos; \
3758 /* Note that this function does "positions" in terms of characters and
3759 not in terms of columns. This is necessary to make the formatting
3760 work correctly when proportional width fonts are used in the
3763 generate_fstring_runes (struct window *w, pos_data *data, Charcount pos,
3764 Charcount min_pos, Charcount max_pos,
3765 Lisp_Object elt, int depth, int max_pixsize,
3766 face_index findex, int type, Charcount *offset,
3767 Lisp_Object cur_ext)
3769 /* This function has been Mule-ized. */
3770 /* #### The other losing things in this function are:
3772 -- C zero-terminated-string lossage.
3773 -- Non-printable characters should be converted into something
3774 appropriate (e.g. ^F) instead of blindly being printed anyway.
3785 /* A string. Add to the display line and check for %-constructs
3788 Bufbyte *this = XSTRING_DATA (elt);
3790 while ((pos < max_pos || max_pos == -1) && *this)
3792 Bufbyte *last = this;
3794 while (*this && *this != '%')
3799 /* No %-construct */
3801 bytecount_to_charcount (last, this - last);
3803 if (size <= *offset)
3807 Charcount tmp_max = (max_pos == -1 ? pos + size - *offset :
3808 min (pos + size - *offset, max_pos));
3809 const Bufbyte *tmp_last = charptr_n_addr (last, *offset);
3811 pos = add_string_to_fstring_db_runes (data, tmp_last,
3816 else /* *this == '%' */
3818 Charcount spec_width = 0;
3820 this++; /* skip over '%' */
3822 /* We can't allow -ve args due to the "%-" construct.
3823 * Argument specifies minwidth but not maxwidth
3824 * (maxwidth can be specified by
3825 * (<negative-number> . <stuff>) modeline elements)
3827 while (isdigit (*this))
3829 spec_width = spec_width * 10 + (*this - '0');
3836 pos = generate_fstring_runes (w, data, pos, spec_width,
3837 max_pos, Vglobal_mode_string,
3838 depth, max_pixsize, findex,
3839 type, offset, cur_ext);
3841 else if (*this == '-')
3843 Charcount num_to_add;
3845 if (max_pixsize < 0)
3847 else if (max_pos != -1)
3848 num_to_add = max_pos - pos;
3854 SET_CURRENT_MODE_CHARS_PIXSIZE;
3857 redisplay_text_width_string (w, findex, &ch, Qnil, 0,
3860 num_to_add = (max_pixsize - cur_pixsize) / dash_pixsize;
3864 while (num_to_add--)
3865 pos = add_string_to_fstring_db_runes
3866 (data, (const Bufbyte *) "-", pos, pos, max_pos);
3868 else if (*this != 0)
3870 Emchar ch = charptr_emchar (this);
3874 decode_mode_spec (w, ch, type);
3876 str = Dynarr_atp (mode_spec_bufbyte_string, 0);
3877 size = bytecount_to_charcount
3878 /* Skip the null character added by `decode_mode_spec' */
3879 (str, Dynarr_length (mode_spec_bufbyte_string)) - 1;
3881 if (size <= *offset)
3885 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3887 /* #### NOTE: I don't understand why a tmp_max is not
3888 computed and used here as in the plain string case
3890 pos = add_string_to_fstring_db_runes (data, tmp_str,
3897 /* NOT this++. There could be any sort of character at
3898 the current position. */
3902 if (max_pixsize > 0)
3905 SET_CURRENT_MODE_CHARS_PIXSIZE;
3907 if (cur_pixsize >= max_pixsize)
3912 else if (SYMBOLP (elt))
3914 /* A symbol: process the value of the symbol recursively
3915 as if it appeared here directly. */
3916 Lisp_Object tem = symbol_value_in_buffer (elt, w->buffer);
3918 if (!UNBOUNDP (tem))
3920 /* If value is a string, output that string literally:
3921 don't check for % within it. */
3924 Bufbyte *str = XSTRING_DATA (tem);
3925 Charcount size = XSTRING_CHAR_LENGTH (tem);
3927 if (size <= *offset)
3931 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3933 /* #### NOTE: I don't understand why a tmp_max is not
3934 computed and used here as in the plain string case
3936 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
3941 /* Give up right away for nil or t. */
3942 else if (!EQ (tem, elt))
3949 else if (GENERIC_SPECIFIERP (elt))
3951 Lisp_Object window, tem;
3952 XSETWINDOW (window, w);
3953 tem = specifier_instance_no_quit (elt, Qunbound, window,
3954 ERROR_ME_NOT, 0, Qzero);
3955 if (!UNBOUNDP (tem))
3961 else if (CONSP (elt))
3963 /* A cons cell: four distinct cases.
3964 * - If first element is a string or a cons, process all the elements
3965 * and effectively concatenate them.
3966 * - If first element is a negative number, truncate displaying cdr to
3967 * at most that many characters. If positive, pad (with spaces)
3968 * to at least that many characters.
3969 * - If first element is another symbol, process the cadr or caddr
3970 * recursively according to whether the symbol's value is non-nil or
3972 * - If first element is an extent, process the cdr recursively
3973 * and handle the extent's face.
3976 Lisp_Object car, tem;
3985 tem = symbol_value_in_buffer (car, w->buffer);
3986 /* elt is now the cdr, and we know it is a cons cell.
3987 Use its car if CAR has a non-nil value. */
3988 if (!UNBOUNDP (tem))
3996 /* Symbol's value is nil (or symbol is unbound)
3997 * Get the cddr of the original list
3998 * and if possible find the caddr and use that.
4003 else if (!CONSP (elt))
4011 else if (INTP (car))
4013 Charcount lim = XINT (car);
4019 /* Negative int means reduce maximum width.
4020 * DO NOT change MIN_PIXPOS here!
4021 * (20 -10 . foo) should truncate foo to 10 col
4022 * and then pad to 20.
4025 max_pos = pos - lim;
4027 max_pos = min (max_pos, pos - lim);
4031 /* Padding specified. Don't let it be more than
4035 if (max_pos != -1 && lim > max_pos)
4037 /* If that's more padding than already wanted, queue it.
4038 * But don't reduce padding already specified even if
4039 * that is beyond the current truncation point.
4046 else if (STRINGP (car) || CONSP (car))
4050 /* LIMIT is to protect against circular lists. */
4051 while (CONSP (elt) && --limit > 0
4052 && (pos < max_pos || max_pos == -1))
4054 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4055 XCAR (elt), depth, max_pixsize,
4056 findex, type, offset, cur_ext);
4060 else if (EXTENTP (car))
4062 struct extent *ext = XEXTENT (car);
4064 if (EXTENT_LIVE_P (ext))
4066 face_index old_findex = data->findex;
4068 Lisp_Object font_inst;
4069 face_index new_findex;
4070 Bytecount start = data->bytepos;
4072 face = extent_face (ext);
4075 /* #### needs to merge faces, sigh */
4076 /* #### needs to handle list of faces */
4077 new_findex = get_builtin_face_cache_index (w, face);
4078 /* !!#### not right; needs to compute the max height of
4080 font_inst = WINDOW_FACE_CACHEL_FONT (w, new_findex,
4083 data->dl->ascent = max (data->dl->ascent,
4084 XFONT_INSTANCE (font_inst)->ascent);
4085 data->dl->descent = max (data->dl->descent,
4086 XFONT_INSTANCE (font_inst)->
4090 new_findex = old_findex;
4092 data->findex = new_findex;
4093 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4094 XCDR (elt), depth - 1,
4095 max_pixsize, new_findex, type,
4097 data->findex = old_findex;
4098 Dynarr_add (formatted_string_extent_dynarr, ext);
4099 Dynarr_add (formatted_string_extent_start_dynarr, start);
4100 Dynarr_add (formatted_string_extent_end_dynarr, data->bytepos);
4104 else if (GLYPHP (elt))
4106 /* Glyphs are considered as one character with respect to the modeline
4107 horizontal scrolling facility. -- dv */
4111 pos = add_glyph_to_fstring_db_runes (data, elt, pos, pos, max_pos,
4118 char *str = GETTEXT ("*invalid*");
4119 Charcount size = (Charcount) strlen (str); /* is this ok ?? -- dv */
4121 if (size <= *offset)
4125 const Bufbyte *tmp_str =
4126 charptr_n_addr ((const Bufbyte *) str, *offset);
4128 /* #### NOTE: I don't understand why a tmp_max is not computed and
4129 used here as in the plain string case above. -- dv */
4130 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
4139 add_string_to_fstring_db_runes (data, (const Bufbyte *) "", pos,
4146 /* Update just the modeline. Assumes the desired display structs. If
4147 they do not have a modeline block, it does nothing. */
4149 regenerate_modeline (struct window *w)
4151 display_line_dynarr *dla = window_display_lines (w, DESIRED_DISP);
4153 if (!Dynarr_length (dla) || !Dynarr_atp (dla, 0)->modeline)
4157 generate_modeline (w, Dynarr_atp (dla, 0), DESIRED_DISP);
4158 redisplay_update_line (w, 0, 0, 0);
4162 /* Make sure that modeline display line is present in the given
4163 display structs if the window has a modeline and update that
4164 line. Returns true if a modeline was needed. */
4166 ensure_modeline_generated (struct window *w, int type)
4170 /* minibuffer windows don't have modelines */
4171 if (MINI_WINDOW_P (w))
4173 /* windows which haven't had it turned off do */
4174 else if (WINDOW_HAS_MODELINE_P (w))
4176 /* windows which have it turned off don't have a divider if there is
4177 a horizontal scrollbar */
4178 else if (window_scrollbar_height (w))
4180 /* and in this case there is none */
4186 display_line_dynarr *dla;
4188 dla = window_display_lines (w, type);
4190 /* We don't care if there is a display line which is not
4191 currently a modeline because it is definitely going to become
4192 one if we have gotten to this point. */
4193 if (Dynarr_length (dla) == 0)
4195 if (Dynarr_largest (dla) > 0)
4197 struct display_line *mlp = Dynarr_atp (dla, 0);
4198 Dynarr_add (dla, *mlp);
4202 struct display_line modeline;
4204 Dynarr_add (dla, modeline);
4208 /* If we're adding a new place marker go ahead and generate the
4209 modeline so that it is available for use by
4210 window_modeline_height. */
4211 generate_modeline (w, Dynarr_atp (dla, 0), type);
4214 return need_modeline;
4217 /* #### Kludge or not a kludge. I tend towards the former. */
4219 real_current_modeline_height (struct window *w)
4221 Fset_marker (w->start[CMOTION_DISP], w->start[CURRENT_DISP], w->buffer);
4222 Fset_marker (w->pointm[CMOTION_DISP], w->pointm[CURRENT_DISP], w->buffer);
4224 if (ensure_modeline_generated (w, CMOTION_DISP))
4226 display_line_dynarr *dla = window_display_lines (w, CMOTION_DISP);
4228 if (Dynarr_length (dla))
4230 if (Dynarr_atp (dla, 0)->modeline)
4231 return (Dynarr_atp (dla, 0)->ascent +
4232 Dynarr_atp (dla, 0)->descent);
4239 /***************************************************************************/
4241 /* displayable string routines */
4243 /***************************************************************************/
4245 /* Given a position for a string in a window, ensure that the given
4246 display line DL accurately represents the text on a line starting
4247 at the given position.
4249 Yes, this is duplicating the code of create_text_block, but it
4250 looked just too hard to change create_text_block to handle strings
4251 *and* buffers. We already make a distinction between the two
4252 elsewhere in the code so I think unifying them would require a
4253 complete MULE rewrite. Besides, the other distinction is that these
4254 functions cover text that the user *cannot edit* so we can remove
4255 everything to do with cursors, minibuffers etc. Eventually the
4256 modeline routines should be modified to use this code as it copes
4257 with many more types of display situation. */
4260 create_string_text_block (struct window *w, Lisp_Object disp_string,
4261 struct display_line *dl,
4263 prop_block_dynarr **prop,
4264 face_index default_face)
4266 struct frame *f = XFRAME (w->frame);
4267 /* Note that a lot of the buffer controlled stuff has been left in
4268 because you might well want to make use of it (selective display
4269 etc), its just the buffer text that we do not use. However, it
4270 seems to be possible for buffer to be nil sometimes so protect
4271 against this case. */
4272 struct buffer *b = BUFFERP (w->buffer) ? XBUFFER (w->buffer) : 0;
4273 struct device *d = XDEVICE (f->device);
4274 Lisp_String* s = XSTRING (disp_string);
4276 /* we're working with these a lot so precalculate them */
4277 Bytecount slen = XSTRING_LENGTH (disp_string);
4278 Bytecount bi_string_zv = slen;
4279 Bytind bi_start_pos = charcount_to_bytecount (string_data (s), start_pos);
4283 int truncate_win = b ? window_truncation_on (w) : 0;
4284 int end_glyph_width = 0;
4286 /* We're going to ditch selective display for static text, it's an
4287 FSF thing and invisible extents are the way to go here.
4288 Implementing it also relies on a number of buffer-specific
4289 functions that we don't have the luxury of being able to use
4292 /* The variable ctl-arrow allows the user to specify what characters
4293 can actually be displayed and which octal should be used for.
4294 #### This variable should probably have some rethought done to
4297 #### It would also be really nice if you could specify that
4298 the characters come out in hex instead of in octal. Mule
4299 does that by adding a ctl-hexa variable similar to ctl-arrow,
4300 but that's bogus -- we need a more general solution. I
4301 think you need to extend the concept of display tables
4302 into a more general conversion mechanism. Ideally you
4303 could specify a Lisp function that converts characters,
4304 but this violates the Second Golden Rule and besides would
4305 make things way way way way slow.
4307 So instead, we extend the display-table concept, which was
4308 historically limited to 256-byte vectors, to one of the
4311 a) A 256-entry vector, for backward compatibility;
4312 b) char-table, mapping characters to values;
4313 c) range-table, mapping ranges of characters to values;
4314 d) a list of the above.
4316 The (d) option allows you to specify multiple display tables
4317 instead of just one. Each display table can specify conversions
4318 for some characters and leave others unchanged. The way the
4319 character gets displayed is determined by the first display table
4320 with a binding for that character. This way, you could call a
4321 function `enable-hex-display' that adds a hex display-table to
4322 the list of display tables for the current buffer.
4324 #### ...not yet implemented... Also, we extend the concept of
4325 "mapping" to include a printf-like spec. Thus you can make all
4326 extended characters show up as hex with a display table like
4329 #s(range-table data ((256 524288) (format "%x")))
4331 Since more than one display table is possible, you have
4332 great flexibility in mapping ranges of characters. */
4333 Emchar printable_min = b ? (CHAR_OR_CHAR_INTP (b->ctl_arrow)
4334 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
4335 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
4336 ? 255 : 160)) : 255;
4338 Lisp_Object face_dt, window_dt;
4340 /* The text display block for this display line. */
4341 struct display_block *db = get_display_block_from_line (dl, TEXT);
4343 /* The first time through the main loop we need to force the glyph
4344 data to be updated. */
4347 /* Apparently the new extent_fragment_update returns an end position
4348 equal to the position passed in if there are no more runs to be
4350 int no_more_frags = 0;
4352 dl->used_prop_data = 0;
4354 dl->line_continuation = 0;
4356 /* set up faces to use for clearing areas, used by
4357 output_display_line */
4358 dl->default_findex = default_face;
4361 dl->left_margin_findex = default_face;
4362 dl->right_margin_findex = default_face;
4366 dl->left_margin_findex =
4367 get_builtin_face_cache_index (w, Vleft_margin_face);
4368 dl->right_margin_findex =
4369 get_builtin_face_cache_index (w, Vright_margin_face);
4373 data.ef = extent_fragment_new (disp_string, f);
4375 /* These values are used by all of the rune addition routines. We add
4376 them to this structure for ease of passing. */
4378 XSETWINDOW (data.window, w);
4382 data.bi_bufpos = bi_start_pos;
4383 data.pixpos = dl->bounds.left_in;
4384 data.last_charset = Qunbound;
4385 data.last_findex = default_face;
4386 data.result_str = Qnil;
4387 data.string = disp_string;
4389 /* Set the right boundary adjusting it to take into account any end
4390 glyph. Save the width of the end glyph for later use. */
4391 data.max_pixpos = dl->bounds.right_in;
4394 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
4396 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
4398 data.max_pixpos -= end_glyph_width;
4400 data.cursor_type = NO_CURSOR;
4404 /* I don't think we want this, string areas should not scroll with
4406 data.start_col = w->hscroll;
4407 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
4409 data.bi_start_col_enabled = 0;
4410 data.hscroll_glyph_width_adjust = 0;
4412 /* We regenerate the line from the very beginning. */
4413 Dynarr_reset (db->runes);
4415 /* Why is this less than or equal and not just less than? If the
4416 starting position is already equal to the maximum we can't add
4417 anything else, right? Wrong. We might still have a newline to
4418 add. A newline can use the room allocated for an end glyph since
4419 if we add it we know we aren't going to be adding any end
4422 /* #### Chuck -- I think this condition should be while (1).
4423 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
4424 and the begin-glyph ends exactly at the end of the window, the
4425 end-glyph and text might not be displayed. while (1) ensures
4426 that the loop terminates only when either (a) there is
4427 propagation data or (b) the end-of-line or end-of-buffer is hit.
4429 #### Also I think you need to ensure that the operation
4430 "add begin glyphs; add end glyphs; add text" is atomic and
4431 can't get interrupted in the middle. If you run off the end
4432 of the line during that operation, then you keep accumulating
4433 propagation data until you're done. Otherwise, if the (e.g.)
4434 there's a begin glyph at a particular position and attempting
4435 to display that glyph results in window-end being hit and
4436 propagation data being generated, then the character at that
4437 position won't be displayed.
4439 #### See also the comment after the end of this loop, below.
4441 while (data.pixpos <= data.max_pixpos)
4443 /* #### This check probably should not be necessary. */
4444 if (data.bi_bufpos > bi_string_zv)
4446 /* #### urk! More of this lossage! */
4451 /* Check for face changes. */
4452 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
4454 /* Now compute the face and begin/end-glyph information. */
4456 /* Remember that the extent-fragment routines deal in Bytind's. */
4457 extent_fragment_update (w, data.ef, data.bi_bufpos);
4458 /* This is somewhat cheesy but the alternative is to
4459 propagate default_face into extent_fragment_update. */
4460 if (data.findex == DEFAULT_INDEX)
4461 data.findex = default_face;
4463 get_display_tables (w, data.findex, &face_dt, &window_dt);
4465 if (data.bi_bufpos == data.ef->end)
4470 /* Determine what is next to be displayed. We first handle any
4471 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
4472 display then we determine what to do based on the character at the
4473 current buffer position. */
4475 /* If the current position is covered by an invisible extent, do
4476 nothing (except maybe add some ellipses).
4478 #### The behavior of begin and end-glyphs at the edge of an
4479 invisible extent should be investigated further. This is
4480 fairly low priority though. */
4481 if (data.ef->invisible)
4483 /* #### Chuck, perhaps you could look at this code? I don't
4484 really know what I'm doing. */
4487 Dynarr_free (*prop);
4491 /* The extent fragment code only sets this when we should
4492 really display the ellipses. It makes sure the ellipses
4493 don't get displayed more than once in a row. */
4494 if (data.ef->invisible_ellipses)
4496 struct glyph_block gb;
4498 data.ef->invisible_ellipses_already_displayed = 1;
4499 data.ef->invisible_ellipses = 0;
4501 gb.glyph = Vinvisible_text_glyph;
4502 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
4503 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
4504 /* Perhaps they shouldn't propagate if the very next thing
4505 is to display a newline (for compatibility with
4506 selective-display-ellipses)? Maybe that's too
4512 /* #### What if we we're dealing with a display table? */
4516 if (data.bi_bufpos == bi_string_zv)
4519 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4522 /* If there is propagation data, then it represents the current
4523 buffer position being displayed. Add them and advance the
4524 position counter. This might also add the minibuffer
4528 dl->used_prop_data = 1;
4529 *prop = add_propagation_runes (prop, &data);
4532 goto done; /* gee, a really narrow window */
4533 else if (data.bi_bufpos == bi_string_zv)
4535 else if (data.bi_bufpos < 0)
4536 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
4539 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4542 /* If there are end glyphs, add them to the line. These are
4543 the end glyphs for the previous run of text. We add them
4544 here rather than doing them at the end of handling the
4545 previous run so that glyphs at the beginning and end of
4546 a line are handled correctly. */
4547 else if (Dynarr_length (data.ef->end_glyphs) > 0)
4549 *prop = add_glyph_runes (&data, END_GLYPHS);
4554 /* If there are begin glyphs, add them to the line. */
4555 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
4557 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
4562 /* If at end-of-buffer, we've already processed begin and
4563 end-glyphs at this point and there's no text to process,
4565 else if (data.bi_bufpos == bi_string_zv)
4570 Lisp_Object entry = Qnil;
4571 /* Get the character at the current buffer position. */
4572 data.ch = string_char (s, data.bi_bufpos);
4573 if (!NILP (face_dt) || !NILP (window_dt))
4574 entry = display_table_entry (data.ch, face_dt, window_dt);
4576 /* If there is a display table entry for it, hand it off to
4577 add_disp_table_entry_runes and let it worry about it. */
4578 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
4580 *prop = add_disp_table_entry_runes (&data, entry);
4586 /* Check if we have hit a newline character. If so, add a marker
4587 to the line and end this loop. */
4588 else if (data.ch == '\n')
4590 /* We aren't going to be adding an end glyph so give its
4591 space back in order to make sure that the cursor can
4593 data.max_pixpos += end_glyph_width;
4597 /* If the current character is considered to be printable, then
4599 else if (data.ch >= printable_min)
4601 *prop = add_emchar_rune (&data);
4606 /* If the current character is a tab, determine the next tab
4607 starting position and add a blank rune which extends from the
4608 current pixel position to that starting position. */
4609 else if (data.ch == '\t')
4611 int tab_start_pixpos = data.pixpos;
4616 if (data.start_col > 1)
4617 tab_start_pixpos -= (space_width (w) * (data.start_col - 1));
4620 next_tab_position (w, tab_start_pixpos,
4621 dl->bounds.left_in +
4622 data.hscroll_glyph_width_adjust);
4623 if (next_tab_start > data.max_pixpos)
4625 prop_width = next_tab_start - data.max_pixpos;
4626 next_tab_start = data.max_pixpos;
4628 data.blank_width = next_tab_start - data.pixpos;
4630 (next_tab_start - tab_start_pixpos) / space_width (w);
4632 *prop = add_blank_rune (&data, w, char_tab_width);
4634 /* add_blank_rune is only supposed to be called with
4635 sizes guaranteed to fit in the available space. */
4640 struct prop_block pb;
4641 *prop = Dynarr_new (prop_block);
4643 pb.type = PROP_BLANK;
4644 pb.data.p_blank.width = prop_width;
4645 pb.data.p_blank.findex = data.findex;
4646 Dynarr_add (*prop, pb);
4652 /* If character is a control character, pass it off to
4653 add_control_char_runes.
4655 The is_*() routines have undefined results on
4656 arguments outside of the range [-1, 255]. (This
4657 often bites people who carelessly use `char' instead
4658 of `unsigned char'.)
4660 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
4662 *prop = add_control_char_runes (&data, b);
4668 /* If the character is above the ASCII range and we have not
4669 already handled it, then print it as an octal number. */
4670 else if (data.ch >= 0200)
4672 *prop = add_octal_runes (&data);
4678 /* Assume the current character is considered to be printable,
4679 then just add it. */
4682 *prop = add_emchar_rune (&data);
4687 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4693 /* Determine the starting point of the next line if we did not hit the
4694 end of the buffer. */
4695 if (data.bi_bufpos < bi_string_zv)
4697 /* #### This check is not correct. If the line terminated
4698 due to a begin-glyph or end-glyph hitting window-end, then
4699 data.ch will not point to the character at data.bi_bufpos. If
4700 you make the two changes mentioned at the top of this loop,
4701 you should be able to say '(if (*prop))'. That should also
4702 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
4705 /* The common case is that the line ended because we hit a newline.
4706 In that case, the next character is just the next buffer
4708 if (data.ch == '\n')
4710 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4713 /* Otherwise we have a buffer line which cannot fit on one display
4717 struct glyph_block gb;
4718 struct glyph_cachel *cachel;
4720 /* If the line is to be truncated then we actually have to look
4721 for the next newline. We also add the end-of-line glyph which
4722 we know will fit because we adjusted the right border before
4723 we starting laying out the line. */
4724 data.max_pixpos += end_glyph_width;
4725 data.findex = default_face;
4732 /* Now find the start of the next line. */
4733 bi_pos = bi_find_next_emchar_in_string (s, '\n', data.bi_bufpos, 1);
4735 data.cursor_type = NO_CURSOR;
4736 data.bi_bufpos = bi_pos;
4737 gb.glyph = Vtruncation_glyph;
4738 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
4742 /* The cursor can never be on the continuation glyph. */
4743 data.cursor_type = NO_CURSOR;
4745 /* data.bi_bufpos is already at the start of the next line. */
4747 dl->line_continuation = 1;
4748 gb.glyph = Vcontinuation_glyph;
4749 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
4752 if (end_glyph_width)
4753 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
4755 if (truncate_win && data.bi_bufpos == bi_string_zv)
4757 const Bufbyte* endb = charptr_n_addr (string_data (s), bi_string_zv);
4759 if (charptr_emchar (endb) != '\n')
4761 /* #### Damn this losing shit. */
4767 else if (data.bi_bufpos == bi_string_zv)
4769 /* create_text_block () adds a bogus \n marker here which screws
4770 up subwindow display. Since we never have a cursor in the
4771 gutter we can safely ignore it. */
4773 /* Calculate left whitespace boundary. */
4777 /* Whitespace past a newline is considered right whitespace. */
4778 while (elt < Dynarr_length (db->runes))
4780 struct rune *rb = Dynarr_atp (db->runes, elt);
4782 if ((rb->type == RUNE_CHAR && rb->object.chr.ch == ' ')
4783 || rb->type == RUNE_BLANK)
4785 dl->bounds.left_white += rb->width;
4789 elt = Dynarr_length (db->runes);
4793 /* Calculate right whitespace boundary. */
4795 int elt = Dynarr_length (db->runes) - 1;
4798 while (!done && elt >= 0)
4800 struct rune *rb = Dynarr_atp (db->runes, elt);
4802 if (!(rb->type == RUNE_CHAR && rb->object.chr.ch < 0x100
4803 && isspace (rb->object.chr.ch))
4804 && !rb->type == RUNE_BLANK)
4806 dl->bounds.right_white = rb->xpos + rb->width;
4814 /* The line is blank so everything is considered to be right
4817 dl->bounds.right_white = dl->bounds.left_in;
4820 /* Set the display blocks bounds. */
4821 db->start_pos = dl->bounds.left_in;
4822 if (Dynarr_length (db->runes))
4824 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
4826 db->end_pos = rb->xpos + rb->width;
4829 db->end_pos = dl->bounds.right_white;
4831 /* update line height parameters */
4832 if (!data.new_ascent && !data.new_descent)
4834 /* We've got a blank line so initialize these values from the default
4836 default_face_font_info (data.window, &data.new_ascent,
4837 &data.new_descent, 0, 0, 0);
4840 if (data.max_pixmap_height)
4842 int height = data.new_ascent + data.new_descent;
4843 int pix_ascent, pix_descent;
4845 pix_descent = data.max_pixmap_height * data.new_descent / height;
4846 pix_ascent = data.max_pixmap_height - pix_descent;
4848 data.new_ascent = max (data.new_ascent, pix_ascent);
4849 data.new_descent = max (data.new_descent, pix_descent);
4852 dl->ascent = data.new_ascent;
4853 dl->descent = data.new_descent;
4856 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
4858 if (dl->ascent < ascent)
4859 dl->ascent = ascent;
4862 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
4864 if (dl->descent < descent)
4865 dl->descent = descent;
4868 dl->cursor_elt = data.cursor_x;
4869 /* #### lossage lossage lossage! Fix this shit! */
4870 if (data.bi_bufpos > bi_string_zv)
4871 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, bi_string_zv);
4873 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, data.bi_bufpos) - 1;
4875 data.dl->num_chars =
4876 string_column_at_point (s, dl->end_bufpos, b ? XINT (b->tab_width) : 8);
4878 /* This doesn't correctly take into account tabs and control
4879 characters but if the window isn't being truncated then this
4880 value isn't going to end up being used anyhow. */
4881 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
4883 /* #### handle horizontally scrolled line with text none of which
4884 was actually laid out. */
4886 /* #### handle any remainder of overlay arrow */
4888 if (*prop == ADD_FAILED)
4891 if (truncate_win && *prop)
4893 Dynarr_free (*prop);
4897 extent_fragment_delete (data.ef);
4899 /* #### If we started at EOB, then make sure we return a value past
4900 it so that regenerate_window will exit properly. This is bogus.
4901 The main loop should get fixed so that it isn't necessary to call
4902 this function if we are already at EOB. */
4904 if (data.bi_bufpos == bi_string_zv && bi_start_pos == bi_string_zv)
4905 return bytecount_to_charcount (string_data (s), data.bi_bufpos) + 1; /* Yuck! */
4907 return bytecount_to_charcount (string_data (s), data.bi_bufpos);
4910 /* Given a display line and a starting position, ensure that the
4911 contents of the display line accurately represent the visual
4912 representation of the buffer contents starting from the given
4913 position when displayed in the given window. The display line ends
4914 when the contents of the line reach the right boundary of the given
4917 This is very similar to generate_display_line but with the same
4918 limitations as create_string_text_block. I have taken the liberty
4919 of fixing the bytind stuff though.*/
4922 generate_string_display_line (struct window *w, Lisp_Object disp_string,
4923 struct display_line *dl,
4925 prop_block_dynarr **prop,
4926 face_index default_face)
4930 /* you must set bounds before calling this. */
4932 /* Reset what this line is using. */
4933 if (dl->display_blocks)
4934 Dynarr_reset (dl->display_blocks);
4935 if (dl->left_glyphs)
4937 Dynarr_free (dl->left_glyphs);
4938 dl->left_glyphs = 0;
4940 if (dl->right_glyphs)
4942 Dynarr_free (dl->right_glyphs);
4943 dl->right_glyphs = 0;
4946 /* We aren't generating a modeline at the moment. */
4949 /* Create a display block for the text region of the line. */
4950 ret_bufpos = create_string_text_block (w, disp_string, dl, start_pos,
4951 prop, default_face);
4952 dl->bufpos = start_pos;
4953 if (dl->end_bufpos < dl->bufpos)
4954 dl->end_bufpos = dl->bufpos;
4956 /* If there are left glyphs associated with any character in the
4957 text block, then create a display block to handle them. */
4958 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
4959 create_left_glyph_block (w, dl, 0);
4961 /* If there are right glyphs associated with any character in the
4962 text block, then create a display block to handle them. */
4963 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
4964 create_right_glyph_block (w, dl);
4969 /* This is ripped off from regenerate_window. All we want to do is
4970 loop through elements in the string creating display lines until we
4971 have covered the provided area. Simple really. */
4973 generate_displayable_area (struct window *w, Lisp_Object disp_string,
4974 int xpos, int ypos, int width, int height,
4975 display_line_dynarr* dla,
4977 face_index default_face)
4979 int yend = ypos + height;
4982 prop_block_dynarr *prop = 0;
4983 layout_bounds bounds;
4987 /* if there's nothing to do then do nothing. code after this assumes
4988 there is something to do. */
4989 if (NILP (disp_string))
4992 s_zv = XSTRING_CHAR_LENGTH (disp_string);
4994 bounds.left_out = xpos;
4995 bounds.right_out = xpos + width;
4996 /* The inner boundaries mark where the glyph margins are located. */
4997 bounds.left_in = bounds.left_out + window_left_margin_width (w);
4998 bounds.right_in = bounds.right_out - window_right_margin_width (w);
4999 /* We cannot fully calculate the whitespace boundaries as they
5000 depend on the contents of the line being displayed. */
5001 bounds.left_white = bounds.left_in;
5002 bounds.right_white = bounds.right_in;
5006 struct display_line dl;
5007 struct display_line *dlp;
5011 if (Dynarr_length (dla) < Dynarr_largest (dla))
5013 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5024 dlp->bounds = bounds;
5026 next_pos = generate_string_display_line (w, disp_string, dlp, start_pos,
5027 &prop, default_face);
5028 /* we need to make sure that we continue along the line if there
5029 is more left to display otherwise we just end up redisplaying
5030 the same chunk over and over again. */
5031 if (next_pos == start_pos && next_pos < s_zv)
5034 start_pos = next_pos;
5036 dlp->ypos = ypos + dlp->ascent;
5037 ypos = dlp->ypos + dlp->descent;
5041 int visible_height = dlp->ascent + dlp->descent;
5043 dlp->clip = (ypos - yend);
5044 visible_height -= dlp->clip;
5046 if (visible_height < VERTICAL_CLIP (w, 1))
5049 free_display_line (dlp);
5056 Dynarr_add (dla, *dlp);
5058 /* #### This type of check needs to be done down in the
5059 generate_display_line call. */
5060 if (start_pos >= s_zv)
5069 /***************************************************************************/
5071 /* window-regeneration routines */
5073 /***************************************************************************/
5075 /* For a given window and starting position in the buffer it contains,
5076 ensure that the TYPE display lines accurately represent the
5077 presentation of the window. We pass the buffer instead of getting
5078 it from the window since redisplay_window may have temporarily
5079 changed it to the echo area buffer. */
5082 regenerate_window (struct window *w, Bufpos start_pos, Bufpos point, int type)
5084 struct frame *f = XFRAME (w->frame);
5085 struct buffer *b = XBUFFER (w->buffer);
5086 int ypos = WINDOW_TEXT_TOP (w);
5087 int yend; /* set farther down */
5088 int yclip = WINDOW_TEXT_TOP_CLIP (w);
5091 prop_block_dynarr *prop;
5092 layout_bounds bounds;
5093 display_line_dynarr *dla;
5096 /* The lines had better exist by this point. */
5097 if (!(dla = window_display_lines (w, type)))
5100 w->max_line_len = 0;
5102 /* Normally these get updated in redisplay_window but it is possible
5103 for this function to get called from some other points where that
5104 update may not have occurred. This acts as a safety check. */
5105 if (!Dynarr_length (w->face_cachels))
5106 reset_face_cachels (w);
5107 if (!Dynarr_length (w->glyph_cachels))
5108 reset_glyph_cachels (w);
5110 Fset_marker (w->start[type], make_int (start_pos), w->buffer);
5111 Fset_marker (w->pointm[type], make_int (point), w->buffer);
5112 w->last_point_x[type] = -1;
5113 w->last_point_y[type] = -1;
5115 /* Make sure a modeline is in the structs if needed. */
5116 need_modeline = ensure_modeline_generated (w, type);
5118 /* Wait until here to set this so that the structs have a modeline
5119 generated in the case where one didn't exist. */
5120 yend = WINDOW_TEXT_BOTTOM (w);
5122 bounds = calculate_display_line_boundaries (w, 0);
5124 /* 97/3/14 jhod: stuff added here to support pre-prompts (used for input systems) */
5125 if (MINI_WINDOW_P (w)
5126 && (!NILP (Vminibuf_prompt) || !NILP (Vminibuf_preprompt))
5127 && !echo_area_active (f)
5128 && start_pos == BUF_BEGV (b))
5130 struct prop_block pb;
5132 prop = Dynarr_new (prop_block);
5134 string = concat2(Vminibuf_preprompt, Vminibuf_prompt);
5135 pb.type = PROP_MINIBUF_PROMPT;
5136 pb.data.p_string.str = XSTRING_DATA(string);
5137 pb.data.p_string.len = XSTRING_LENGTH(string);
5138 Dynarr_add (prop, pb);
5143 /* When we are computing things for scrolling purposes, make
5144 sure at least one line is always generated */
5145 force = (type == CMOTION_DISP);
5147 /* Make sure this is set always */
5148 /* Note the conversion at end */
5149 w->window_end_pos[type] = start_pos;
5150 while (ypos < yend || force)
5152 struct display_line dl;
5153 struct display_line *dlp;
5156 if (Dynarr_length (dla) < Dynarr_largest (dla))
5158 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5169 dlp->bounds = bounds;
5171 start_pos = generate_display_line (w, dlp, 1, start_pos, &prop, type);
5173 if (yclip > dlp->ascent)
5175 /* this should never happen, but if it does just display the
5180 dlp->ypos = (ypos + dlp->ascent) - yclip;
5181 ypos = dlp->ypos + dlp->descent;
5183 /* See if we've been asked to start midway through a line, for
5184 partial display line scrolling. */
5187 dlp->top_clip = yclip;
5195 int visible_height = dlp->ascent + dlp->descent;
5197 dlp->clip = (ypos - yend);
5198 /* Although this seems strange we could have a single very
5199 tall line visible for which we need to account for both
5200 the top clip and the bottom clip. */
5201 visible_height -= (dlp->clip + dlp->top_clip);
5203 if (visible_height < VERTICAL_CLIP (w, 1) && !force)
5206 free_display_line (dlp);
5213 if (dlp->cursor_elt != -1)
5215 /* #### This check is steaming crap. Have to get things
5216 fixed so when create_text_block hits EOB, we're done,
5218 if (w->last_point_x[type] == -1)
5220 w->last_point_x[type] = dlp->cursor_elt;
5221 w->last_point_y[type] = Dynarr_length (dla);
5225 /* #### This means that we've added a cursor at EOB
5226 twice. Yuck oh yuck. */
5227 struct display_block *db =
5228 get_display_block_from_line (dlp, TEXT);
5230 Dynarr_atp (db->runes, dlp->cursor_elt)->cursor_type = NO_CURSOR;
5231 dlp->cursor_elt = -1;
5235 if (dlp->num_chars > w->max_line_len)
5236 w->max_line_len = dlp->num_chars;
5238 Dynarr_add (dla, *dlp);
5240 /* #### This isn't right, but it is close enough for now. */
5241 w->window_end_pos[type] = start_pos;
5243 /* #### This type of check needs to be done down in the
5244 generate_display_line call. */
5245 if (start_pos > BUF_ZV (b))
5254 /* #### More not quite right, but close enough. */
5255 /* Ben sez: apparently window_end_pos[] is measured
5256 as the number of characters between the window end and the
5257 end of the buffer? This seems rather weirdo. What's
5258 the justification for this?
5260 JV sez: Because BUF_Z (b) would be a good initial value, however
5261 that can change. This representation allows initalizing with 0.
5263 w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type];
5267 /* We know that this is the right thing to use because we put it
5268 there when we first started working in this function. */
5269 generate_modeline (w, Dynarr_atp (dla, 0), type);
5273 #define REGEN_INC_FIND_START_END \
5275 /* Determine start and end of lines. */ \
5276 if (!Dynarr_length (cdla)) \
5280 if (Dynarr_atp (cdla, 0)->modeline && Dynarr_atp (ddla, 0)->modeline) \
5284 else if (!Dynarr_atp (cdla, 0)->modeline \
5285 && !Dynarr_atp (ddla, 0)->modeline) \
5290 abort (); /* structs differ */ \
5292 dla_end = Dynarr_length (cdla) - 1; \
5295 start_pos = (Dynarr_atp (cdla, dla_start)->bufpos \
5296 + Dynarr_atp (cdla, dla_start)->offset); \
5297 /* If this isn't true, then startp has changed and we need to do a \
5299 if (startp != start_pos) \
5302 /* Point is outside the visible region so give up. */ \
5303 if (pointm < start_pos) \
5308 /* This attempts to incrementally update the display structures. It
5309 returns a boolean indicating success or failure. This function is
5310 very similar to regenerate_window_incrementally and is in fact only
5311 called from that function. However, because of the nature of the
5312 changes it deals with it sometimes makes different assumptions
5313 which can lead to success which are much more difficult to make
5314 when dealing with buffer changes. */
5317 regenerate_window_extents_only_changed (struct window *w, Bufpos startp,
5319 Charcount beg_unchanged,
5320 Charcount end_unchanged)
5322 struct buffer *b = XBUFFER (w->buffer);
5323 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5324 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5328 int first_line, last_line;
5330 /* Don't define this in the loop where it is used because we
5331 definitely want its value to survive between passes. */
5332 prop_block_dynarr *prop = NULL;
5334 /* If we don't have any buffer change recorded but the modiff flag has
5335 been incremented, then fail. I'm not sure of the exact circumstances
5336 under which this can happen, but I believe that it is probably a
5337 reasonable happening. */
5338 if (!point_visible (w, pointm, CURRENT_DISP)
5339 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b))
5342 /* If the cursor is moved we attempt to update it. If we succeed we
5343 go ahead and proceed with the optimization attempt. */
5344 if (!EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5345 || pointm != marker_position (w->last_point[CURRENT_DISP]))
5347 struct frame *f = XFRAME (w->frame);
5348 struct device *d = XDEVICE (f->device);
5349 struct frame *sel_f = device_selected_frame (d);
5352 if (w->last_point_x[CURRENT_DISP] != -1
5353 && w->last_point_y[CURRENT_DISP] != -1)
5356 if (redisplay_move_cursor (w, pointm, WINDOW_TTY_P (w)))
5358 /* Always regenerate the modeline in case it is
5359 displaying the current line or column. */
5360 regenerate_modeline (w);
5364 else if (w != XWINDOW (FRAME_SELECTED_WINDOW (sel_f)))
5366 if (f->modeline_changed)
5367 regenerate_modeline (w);
5375 if (beg_unchanged == -1 && end_unchanged == -1)
5378 /* assert: There are no buffer modifications or they are all below the
5379 visible region. We assume that regenerate_window_incrementally has
5380 not called us unless this is true. */
5382 REGEN_INC_FIND_START_END;
5384 /* If the changed are starts before the visible area, give up. */
5385 if (beg_unchanged < startp)
5388 /* Find what display line the extent changes first affect. */
5390 while (line <= dla_end)
5392 struct display_line *dl = Dynarr_atp (cdla, line);
5393 Bufpos lstart = dl->bufpos + dl->offset;
5394 Bufpos lend = dl->end_bufpos + dl->offset;
5396 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5402 /* If the changes are below the visible area then if point hasn't
5403 moved return success otherwise fail in order to be safe. */
5406 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5407 && pointm == marker_position (w->last_point[CURRENT_DISP]))
5413 /* At this point we know what line the changes first affect. We now
5414 begin redrawing lines as long as we are still in the affected
5415 region and the line's size and positioning don't change.
5416 Otherwise we fail. If we fail we will have altered the desired
5417 structs which could lead to an assertion failure. However, if we
5418 fail the next thing that is going to happen is a full regen so we
5419 will actually end up being safe. */
5420 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5421 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5422 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
5423 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
5425 first_line = last_line = line;
5426 while (line <= dla_end)
5428 Bufpos old_start, old_end, new_start;
5429 struct display_line *cdl = Dynarr_atp (cdla, line);
5430 struct display_line *ddl = Dynarr_atp (ddla, line);
5431 struct display_block *db;
5434 assert (cdl->bufpos == ddl->bufpos);
5435 assert (cdl->end_bufpos == ddl->end_bufpos);
5436 assert (cdl->offset == ddl->offset);
5438 db = get_display_block_from_line (ddl, TEXT);
5439 initial_size = Dynarr_length (db->runes);
5440 old_start = ddl->bufpos + ddl->offset;
5441 old_end = ddl->end_bufpos + ddl->offset;
5443 /* If this is the first line being updated and it used
5444 propagation data, fail. Otherwise we'll be okay because
5445 we'll have the necessary propagation data. */
5446 if (line == first_line && ddl->used_prop_data)
5449 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5450 &prop, DESIRED_DISP);
5453 /* #### If there is propagated stuff the fail. We could
5454 probably actually deal with this if the line had propagated
5455 information when originally created by a full
5463 /* If any line position parameters have changed or a
5464 cursor has disappeared or disappeared, fail. */
5465 db = get_display_block_from_line (ddl, TEXT);
5466 if (cdl->ypos != ddl->ypos
5467 || cdl->ascent != ddl->ascent
5468 || cdl->descent != ddl->descent
5469 || cdl->top_clip != ddl->top_clip
5470 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5471 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1)
5472 || old_start != ddl->bufpos
5473 || old_end != ddl->end_bufpos
5474 || initial_size != Dynarr_length (db->runes))
5479 if (ddl->cursor_elt != -1)
5481 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5482 w->last_point_y[DESIRED_DISP] = line;
5487 /* If the extent changes end on the line we just updated then
5488 we're done. Otherwise go on to the next line. */
5489 if (end_unchanged <= ddl->end_bufpos)
5495 redisplay_update_line (w, first_line, last_line, 1);
5499 /* Attempt to update the display data structures based on knowledge of
5500 the changed region in the buffer. Returns a boolean indicating
5501 success or failure. If this function returns a failure then a
5502 regenerate_window _must_ be performed next in order to maintain
5503 invariants located here. */
5506 regenerate_window_incrementally (struct window *w, Bufpos startp,
5509 struct buffer *b = XBUFFER (w->buffer);
5510 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5511 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5512 Charcount beg_unchanged, end_unchanged;
5513 Charcount extent_beg_unchanged, extent_end_unchanged;
5519 /* If this function is called, the current and desired structures
5520 had better be identical. If they are not, then that is a bug. */
5521 assert (Dynarr_length (cdla) == Dynarr_length (ddla));
5523 /* We don't handle minibuffer windows yet. The minibuffer prompt
5525 if (MINI_WINDOW_P (w))
5528 extent_beg_unchanged = BUF_EXTENT_BEGIN_UNCHANGED (b);
5529 extent_end_unchanged = (BUF_EXTENT_END_UNCHANGED (b) == -1
5531 : BUF_Z (b) - BUF_EXTENT_END_UNCHANGED (b));
5533 /* If nothing has changed in the buffer, then make sure point is ok
5535 if (BUF_BEGIN_UNCHANGED (b) == -1 && BUF_END_UNCHANGED (b) == -1)
5536 return regenerate_window_extents_only_changed (w, startp, pointm,
5537 extent_beg_unchanged,
5538 extent_end_unchanged);
5540 /* We can't deal with deleted newlines. */
5541 if (BUF_NEWLINE_WAS_DELETED (b))
5544 beg_unchanged = BUF_BEGIN_UNCHANGED (b);
5545 end_unchanged = (BUF_END_UNCHANGED (b) == -1
5547 : BUF_Z (b) - BUF_END_UNCHANGED (b));
5549 REGEN_INC_FIND_START_END;
5551 /* If the changed area starts before the visible area, give up. */
5552 if (beg_unchanged < startp)
5555 /* Find what display line the buffer changes first affect. */
5557 while (line <= dla_end)
5559 struct display_line *dl = Dynarr_atp (cdla, line);
5560 Bufpos lstart = dl->bufpos + dl->offset;
5561 Bufpos lend = dl->end_bufpos + dl->offset;
5563 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5569 /* If the changes are below the visible area then if point hasn't
5570 moved return success otherwise fail in order to be safe. */
5572 return regenerate_window_extents_only_changed (w, startp, pointm,
5573 extent_beg_unchanged,
5574 extent_end_unchanged);
5576 /* At this point we know what line the changes first affect. We
5577 now redraw that line. If the changes are contained within it
5578 we are going to succeed and can update just that one line.
5579 Otherwise we fail. If we fail we will have altered the desired
5580 structs which could lead to an assertion failure. However, if
5581 we fail the next thing that is going to happen is a full regen
5582 so we will actually end up being safe. */
5585 prop_block_dynarr *prop = NULL;
5586 struct display_line *cdl = Dynarr_atp (cdla, line);
5587 struct display_line *ddl = Dynarr_atp (ddla, line);
5589 assert (cdl->bufpos == ddl->bufpos);
5590 assert (cdl->end_bufpos == ddl->end_bufpos);
5591 assert (cdl->offset == ddl->offset);
5593 /* If the line continues to next display line, fail. */
5594 if (ddl->line_continuation)
5597 /* If the line was generated using propagation data, fail. */
5598 if (ddl->used_prop_data)
5601 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5602 &prop, DESIRED_DISP);
5605 /* If there is propagated stuff then it is pretty much a
5606 guarantee that more than just the one line is affected. */
5613 /* If the line continues to next display line, fail. */
5614 if (ddl->line_continuation)
5617 /* If any line position parameters have changed or a
5618 cursor has disappeared or disappeared, fail. */
5619 if (cdl->ypos != ddl->ypos
5620 || cdl->ascent != ddl->ascent
5621 || cdl->descent != ddl->descent
5622 || cdl->top_clip != ddl->top_clip
5623 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5624 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1))
5629 /* If the changed area also ends on this line, then we may be in
5630 business. Update everything and return success. */
5631 if (end_unchanged >= ddl->bufpos && end_unchanged <= ddl->end_bufpos)
5633 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5634 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5635 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp),
5637 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm),
5640 if (ddl->cursor_elt != -1)
5642 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5643 w->last_point_y[DESIRED_DISP] = line;
5646 redisplay_update_line (w, line, line, 1);
5647 regenerate_modeline (w);
5649 /* #### For now we just flush the cache until this has been
5650 tested. After that is done, this should correct the
5652 Dynarr_reset (w->line_start_cache);
5654 /* Adjust the extent changed boundaries to remove any
5655 overlap with the buffer changes since we've just
5656 successfully updated that area. */
5657 if (extent_beg_unchanged != -1
5658 && extent_beg_unchanged >= beg_unchanged
5659 && extent_beg_unchanged < end_unchanged)
5660 extent_beg_unchanged = end_unchanged;
5662 if (extent_end_unchanged != -1
5663 && extent_end_unchanged >= beg_unchanged
5664 && extent_end_unchanged < end_unchanged)
5665 extent_end_unchanged = beg_unchanged - 1;
5667 if (extent_end_unchanged <= extent_beg_unchanged)
5668 extent_beg_unchanged = extent_end_unchanged = -1;
5670 /* This could lead to odd results if it fails, but since the
5671 buffer changes update succeeded this probably will to.
5672 We already know that the extent changes start at or after
5673 the line because we checked before entering the loop. */
5674 if (extent_beg_unchanged != -1
5675 && extent_end_unchanged != -1
5676 && ((extent_beg_unchanged < ddl->bufpos)
5677 || (extent_end_unchanged > ddl->end_bufpos)))
5678 return regenerate_window_extents_only_changed (w, startp, pointm,
5679 extent_beg_unchanged,
5680 extent_end_unchanged);
5690 /* Given a window and a point, update the given display lines such
5691 that point is displayed in the middle of the window.
5692 Return the window's new start position. */
5695 regenerate_window_point_center (struct window *w, Bufpos point, int type)
5699 /* We need to make sure that the modeline is generated so that the
5700 window height can be calculated correctly. */
5701 ensure_modeline_generated (w, type);
5703 startp = start_with_line_at_pixpos (w, point, window_half_pixpos (w));
5704 regenerate_window (w, startp, point, type);
5705 Fset_marker (w->start[type], make_int (startp), w->buffer);
5710 /* Given a window and a set of display lines, return a boolean
5711 indicating whether the given point is contained within. */
5714 point_visible (struct window *w, Bufpos point, int type)
5716 struct buffer *b = XBUFFER (w->buffer);
5717 display_line_dynarr *dla = window_display_lines (w, type);
5720 if (Dynarr_length (dla) && Dynarr_atp (dla, 0)->modeline)
5725 if (Dynarr_length (dla) > first_line)
5728 struct display_line *dl = Dynarr_atp (dla, first_line);
5731 end = BUF_Z (b) - w->window_end_pos[type] - 1;
5733 if (point >= start && point <= end)
5735 if (!MINI_WINDOW_P (w) && scroll_on_clipped_lines)
5737 dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
5739 if (point >= (dl->bufpos + dl->offset)
5740 && point <= (dl->end_bufpos + dl->offset))
5755 /* Return pixel position the middle of the window, not including the
5756 modeline and any potential horizontal scrollbar. */
5759 window_half_pixpos (struct window *w)
5761 return WINDOW_TEXT_TOP (w) + (WINDOW_TEXT_HEIGHT (w) >> 1);
5764 /* Return the display line which is currently in the middle of the
5765 window W for display lines TYPE. */
5768 line_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5770 display_line_dynarr *dla;
5773 int first_elt = (MINI_WINDOW_P (w) ? 0 : 1);
5775 if (type == CMOTION_DISP)
5776 regenerate_window (w, start, point, type);
5778 dla = window_display_lines (w, type);
5779 half = window_half_pixpos (w);
5781 for (elt = first_elt; elt < Dynarr_length (dla); elt++)
5783 struct display_line *dl = Dynarr_atp (dla, elt);
5784 int line_bot = dl->ypos + dl->descent;
5786 if (line_bot > half)
5790 /* We may not have a line at the middle if the end of the buffer is
5795 /* Return a value for point that would place it at the beginning of
5796 the line which is in the middle of the window. */
5799 point_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5801 /* line_at_center will regenerate the display structures, if necessary. */
5802 int line = line_at_center (w, type, start, point);
5805 return BUF_ZV (XBUFFER (w->buffer));
5808 display_line_dynarr *dla = window_display_lines (w, type);
5809 struct display_line *dl = Dynarr_atp (dla, line);
5815 /* For a given window, ensure that the current visual representation
5819 redisplay_window (Lisp_Object window, int skip_selected)
5821 struct window *w = XWINDOW (window);
5822 struct frame *f = XFRAME (w->frame);
5823 struct device *d = XDEVICE (f->device);
5824 Lisp_Object old_buffer = w->buffer;
5825 Lisp_Object the_buffer = w->buffer;
5827 int echo_active = 0;
5832 int selected_in_its_frame;
5833 int selected_globally;
5834 int skip_output = 0;
5835 int truncation_changed;
5836 int inactive_minibuffer =
5837 (MINI_WINDOW_P (w) &&
5838 (f != device_selected_frame (d)) &&
5839 !is_surrogate_for_selected_frame (f));
5841 /* #### In the new world this function actually does a bunch of
5842 optimizations such as buffer-based scrolling, but none of that is
5845 /* If this is a combination window, do its children; that's all.
5846 The selected window is always a leaf so we don't check for
5847 skip_selected here. */
5848 if (!NILP (w->vchild))
5850 redisplay_windows (w->vchild, skip_selected);
5853 if (!NILP (w->hchild))
5855 redisplay_windows (w->hchild, skip_selected);
5859 /* Is this window the selected window on its frame? */
5860 selected_in_its_frame = (w == XWINDOW (FRAME_SELECTED_WINDOW (f)));
5862 selected_in_its_frame &&
5863 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
5864 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d &&
5865 XFRAME(DEVICE_SELECTED_FRAME(d)) == f;
5866 if (skip_selected && selected_in_its_frame)
5869 /* It is possible that the window is not fully initialized yet. */
5870 if (NILP (w->buffer))
5873 if (MINI_WINDOW_P (w) && echo_area_active (f))
5875 w->buffer = the_buffer = Vecho_area_buffer;
5879 b = XBUFFER (w->buffer);
5883 old_pointm = selected_globally
5885 : marker_position (w->pointm[CURRENT_DISP]);
5890 if (selected_globally)
5892 pointm = BUF_PT (b);
5896 pointm = marker_position (w->pointm[CURRENT_DISP]);
5898 if (pointm < BUF_BEGV (b))
5899 pointm = BUF_BEGV (b);
5900 else if (pointm > BUF_ZV (b))
5901 pointm = BUF_ZV (b);
5904 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm), the_buffer);
5906 /* If the buffer has changed we have to invalidate all of our face
5908 if ((!echo_active && b != window_display_buffer (w))
5909 || !Dynarr_length (w->face_cachels)
5910 || f->faces_changed)
5911 reset_face_cachels (w);
5913 mark_face_cachels_as_not_updated (w);
5915 /* Ditto the glyph cache elements, although we do *not* invalidate
5916 the cache purely because glyphs have changed - this is now
5917 handled by the dirty flag.*/
5918 if ((!echo_active && b != window_display_buffer (w))
5919 || !Dynarr_length (w->glyph_cachels) || f->faces_changed)
5920 reset_glyph_cachels (w);
5922 mark_glyph_cachels_as_not_updated (w);
5924 /* If the marker's buffer is not the window's buffer, then we need
5925 to find a new starting position. */
5926 if (!MINI_WINDOW_P (w)
5927 && !EQ (Fmarker_buffer (w->start[CURRENT_DISP]), w->buffer))
5929 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
5931 goto regeneration_done;
5936 old_startp = marker_position (w->start[CURRENT_DISP]);
5941 startp = marker_position (w->start[CURRENT_DISP]);
5942 if (startp < BUF_BEGV (b))
5943 startp = BUF_BEGV (b);
5944 else if (startp > BUF_ZV (b))
5945 startp = BUF_ZV (b);
5947 Fset_marker (w->start[DESIRED_DISP], make_int (startp), the_buffer);
5949 truncation_changed = (find_window_mirror (w)->truncate_win !=
5950 window_truncation_on (w));
5952 /* If w->force_start is set, then some function set w->start and we
5953 should display from there and change point, if necessary, to
5954 ensure that it is visible. */
5955 if (w->force_start || inactive_minibuffer)
5958 w->last_modified[DESIRED_DISP] = Qzero;
5959 w->last_facechange[DESIRED_DISP] = Qzero;
5961 regenerate_window (w, startp, pointm, DESIRED_DISP);
5963 if (!point_visible (w, pointm, DESIRED_DISP) && !inactive_minibuffer)
5965 pointm = point_at_center (w, DESIRED_DISP, 0, 0);
5967 if (selected_globally)
5968 BUF_SET_PT (b, pointm);
5970 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm),
5973 /* #### BUFU amounts of overkill just to get the cursor
5974 location marked properly. FIX ME FIX ME FIX ME */
5975 regenerate_window (w, startp, pointm, DESIRED_DISP);
5978 goto regeneration_done;
5981 /* If nothing has changed since the last redisplay, then we just
5982 need to make sure that point is still visible. */
5983 if (XINT (w->last_modified[CURRENT_DISP]) >= BUF_MODIFF (b)
5984 && XINT (w->last_facechange[CURRENT_DISP]) >= BUF_FACECHANGE (b)
5986 /* This check is to make sure we restore the minibuffer after a
5987 temporary change to the echo area. */
5988 && !(MINI_WINDOW_P (w) && f->buffers_changed)
5989 && !f->frame_changed
5990 && !truncation_changed
5991 /* check whether start is really at the beginning of a line GE */
5992 && (!w->start_at_line_beg || beginning_of_line_p (b, startp))
5995 /* Check if the cursor has actually moved. */
5996 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5997 && pointm == marker_position (w->last_point[CURRENT_DISP])
5998 && selected_globally
5999 && !w->windows_changed
6001 && !f->extents_changed
6002 && !f->faces_changed
6003 && !f->glyphs_changed
6004 && !f->subwindows_changed
6005 /* && !f->subwindows_state_changed*/
6006 && !f->point_changed
6007 && !f->windows_structure_changed)
6009 /* If not, we're done. */
6010 if (f->modeline_changed)
6011 regenerate_modeline (w);
6014 goto regeneration_done;
6018 /* If the new point is visible in the redisplay structures,
6019 then let the output update routines handle it, otherwise
6020 do things the hard way. */
6021 if (!w->windows_changed
6023 && !f->extents_changed
6024 && !f->faces_changed
6025 && !f->glyphs_changed
6026 && !f->subwindows_changed
6027 /* && !f->subwindows_state_changed*/
6028 && !f->windows_structure_changed)
6030 if (point_visible (w, pointm, CURRENT_DISP)
6031 && w->last_point_x[CURRENT_DISP] != -1
6032 && w->last_point_y[CURRENT_DISP] != -1)
6034 if (redisplay_move_cursor (w, pointm, FRAME_TTY_P (f)))
6036 /* Always regenerate in case it is displaying
6037 the current line or column. */
6038 regenerate_modeline (w);
6041 goto regeneration_done;
6044 else if (!selected_in_its_frame && !f->point_changed)
6046 if (f->modeline_changed)
6047 regenerate_modeline (w);
6050 goto regeneration_done;
6054 /* If we weren't able to take the shortcut method, then use
6055 the brute force method. */
6056 regenerate_window (w, startp, pointm, DESIRED_DISP);
6058 if (point_visible (w, pointm, DESIRED_DISP))
6059 goto regeneration_done;
6063 /* Check if the starting point is no longer at the beginning of a
6064 line, in which case find a new starting point. We also recenter
6065 if our start position is equal to point-max. Otherwise we'll end
6066 up with a blank window. */
6067 else if (((w->start_at_line_beg || MINI_WINDOW_P (w))
6068 && !(startp == BUF_BEGV (b)
6069 || BUF_FETCH_CHAR (b, startp - 1) == '\n'))
6070 || (pointm == startp &&
6071 EQ (Fmarker_buffer (w->last_start[CURRENT_DISP]), w->buffer) &&
6072 startp < marker_position (w->last_start[CURRENT_DISP]))
6073 || (startp == BUF_ZV (b)))
6075 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6077 goto regeneration_done;
6079 /* See if we can update the data structures locally based on
6080 knowledge of what changed in the buffer. */
6081 else if (!w->windows_changed
6083 && !f->faces_changed
6084 && !f->glyphs_changed
6085 && !f->subwindows_changed
6086 /* && !f->subwindows_state_changed*/
6087 && !f->windows_structure_changed
6088 && !f->frame_changed
6089 && !truncation_changed
6091 && regenerate_window_incrementally (w, startp, pointm))
6093 if (f->modeline_changed
6094 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b)
6095 || XINT (w->last_facechange[CURRENT_DISP]) < BUF_FACECHANGE (b))
6096 regenerate_modeline (w);
6099 goto regeneration_done;
6101 /* #### This is where a check for structure based scrolling would go. */
6102 /* If all else fails, try just regenerating and see what happens. */
6105 regenerate_window (w, startp, pointm, DESIRED_DISP);
6107 if (point_visible (w, pointm, DESIRED_DISP))
6108 goto regeneration_done;
6111 /* We still haven't gotten the window regenerated with point
6112 visible. Next we try scrolling a little and see if point comes
6113 back onto the screen. */
6114 if (scroll_step > 0)
6116 int scrolled = scroll_conservatively;
6117 for (; scrolled >= 0; scrolled -= scroll_step)
6119 startp = vmotion (w, startp,
6120 (pointm < startp) ? -scroll_step : scroll_step, 0);
6121 regenerate_window (w, startp, pointm, DESIRED_DISP);
6123 if (point_visible (w, pointm, DESIRED_DISP))
6124 goto regeneration_done;
6128 /* We still haven't managed to get the screen drawn with point on
6129 the screen, so just center it and be done with it. */
6130 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6135 /* If the window's frame is changed then reset the current display
6136 lines in order to force a full repaint. */
6137 if (f->frame_changed)
6139 display_line_dynarr *cla = window_display_lines (w, CURRENT_DISP);
6144 /* Must do this before calling redisplay_output_window because it
6145 sets some markers on the window. */
6148 w->buffer = old_buffer;
6149 Fset_marker (w->pointm[DESIRED_DISP], make_int (old_pointm), old_buffer);
6150 Fset_marker (w->start[DESIRED_DISP], make_int (old_startp), old_buffer);
6153 /* These also have to be set before calling redisplay_output_window
6154 since it sets the CURRENT_DISP values based on them. */
6155 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
6156 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
6157 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
6158 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
6162 Bufpos start = marker_position (w->start[DESIRED_DISP]);
6163 Bufpos end = (w->window_end_pos[DESIRED_DISP] == -1
6165 : BUF_Z (b) - w->window_end_pos[DESIRED_DISP] - 1);
6166 /* Don't pollute the cache if not sure if we are correct */
6167 if (w->start_at_line_beg)
6168 update_line_start_cache (w, start, end, pointm, 1);
6169 redisplay_output_window (w);
6171 * If we just displayed the echo area, the line start cache is
6172 * no longer valid, because the minibuffer window is associated
6173 * with the window now.
6176 w->line_cache_last_updated = make_int (-1);
6179 /* #### This should be dependent on face changes and will need to be
6180 somewhere else once tty updates occur on a per-frame basis. */
6181 mark_face_cachels_as_clean (w);
6183 /* The glyph cachels only get dirty if someone changed something.
6184 Since redisplay has now effectively ended we can reset the dirty
6185 flag since everything must be up-to-date. */
6187 mark_glyph_cachels_as_clean (w);
6189 w->windows_changed = 0;
6192 /* Call buffer_reset_changes for all buffers present in any window
6193 currently visible in all frames on all devices. #### There has to
6194 be a better way to do this. */
6197 reset_buffer_changes_mapfun (struct window *w, void *ignored_closure)
6199 buffer_reset_changes (XBUFFER (w->buffer));
6204 reset_buffer_changes (void)
6206 Lisp_Object frmcons, devcons, concons;
6208 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
6210 struct frame *f = XFRAME (XCAR (frmcons));
6212 if (FRAME_REPAINT_P (f))
6213 map_windows (f, reset_buffer_changes_mapfun, 0);
6217 /* Ensure that all windows underneath the given window in the window
6218 hierarchy are correctly displayed. */
6221 redisplay_windows (Lisp_Object window, int skip_selected)
6223 for (; !NILP (window) ; window = XWINDOW (window)->next)
6225 redisplay_window (window, skip_selected);
6230 call_redisplay_end_triggers (struct window *w, void *closure)
6232 Bufpos lrpos = w->last_redisplay_pos;
6233 w->last_redisplay_pos = 0;
6234 if (!NILP (w->buffer)
6235 && !NILP (w->redisplay_end_trigger)
6240 if (MARKERP (w->redisplay_end_trigger)
6241 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
6242 pos = marker_position (w->redisplay_end_trigger);
6243 else if (INTP (w->redisplay_end_trigger))
6244 pos = XINT (w->redisplay_end_trigger);
6247 w->redisplay_end_trigger = Qnil;
6254 XSETWINDOW (window, w);
6255 va_run_hook_with_args_in_buffer (XBUFFER (w->buffer),
6256 Qredisplay_end_trigger_functions,
6258 w->redisplay_end_trigger);
6259 w->redisplay_end_trigger = Qnil;
6266 /* Ensure that all windows on the given frame are correctly displayed. */
6269 redisplay_frame (struct frame *f, int preemption_check)
6271 struct device *d = XDEVICE (f->device);
6273 if (preemption_check)
6275 /* The preemption check itself takes a lot of time,
6276 so normally don't do it here. We do it if called
6277 from Lisp, though (`redisplay-frame'). */
6280 REDISPLAY_PREEMPTION_CHECK;
6285 if (!internal_equal (f->old_buffer_alist, f->buffer_alist, 0))
6289 f->old_buffer_alist = Freplace_list (f->old_buffer_alist,
6291 XSETFRAME (frame, f);
6292 va_run_hook_with_args (Qbuffer_list_changed_hook, 1, frame);
6295 /* Before we put a hold on frame size changes, attempt to process
6296 any which are already pending. */
6297 if (f->size_change_pending)
6298 change_frame_size (f, f->new_height, f->new_width, 0);
6300 /* If frame size might need to be changed, due to changed size
6301 of toolbars, scrollbars etc, change it now */
6302 if (f->size_slipped)
6304 adjust_frame_size (f);
6305 assert (!f->size_slipped);
6308 /* The menubar, toolbar, and icon updates must be done before
6309 hold_frame_size_changes is called and we are officially
6310 'in_display'. They may eval lisp code which may call Fsignal.
6311 If in_display is set Fsignal will abort. */
6313 #ifdef HAVE_MENUBARS
6314 /* Update the menubar. It is done first since it could change
6315 the menubar's visibility. This way we avoid having flashing
6316 caused by an Expose event generated by the visibility change
6318 update_frame_menubars (f);
6319 #endif /* HAVE_MENUBARS */
6320 #ifdef HAVE_TOOLBARS
6321 /* Update the toolbars. */
6322 update_frame_toolbars (f);
6323 #endif /* HAVE_TOOLBARS */
6324 /* Gutter update proper has to be done inside display when no frame
6325 size changes can occur, thus we separately update the gutter
6326 geometry here if it needs it. */
6327 update_frame_gutter_geometry (f);
6329 /* If we clear the frame we have to force its contents to be redrawn. */
6331 f->frame_changed = 1;
6333 /* Invalidate the subwindow caches. We use subwindows_changed here
6334 to cause subwindows to get instantiated. This is because
6335 subwindows_state_changed is less strict - dealing with things
6336 like the clicked state of button. We have to do this before
6337 redisplaying the gutters as subwindows get unmapped in the
6339 if (f->frame_changed)
6340 reset_frame_subwindow_instance_cache (f);
6342 if (f->frame_changed || f->subwindows_changed)
6344 /* we have to do this so the gutter gets regenerated. */
6345 reset_gutter_display_lines (f);
6348 hold_frame_size_changes ();
6350 /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */
6351 /* Within this section, we are defenseless and assume that the
6352 following cannot happen:
6354 1) garbage collection
6355 2) Lisp code evaluation
6356 3) frame size changes
6358 We ensure (3) by calling hold_frame_size_changes(), which
6359 will cause any pending frame size changes to get put on hold
6360 till after the end of the critical section. (1) follows
6361 automatically if (2) is met. #### Unfortunately, there are
6362 some places where Lisp code can be called within this section.
6363 We need to remove them.
6365 If Fsignal() is called during this critical section, we
6368 If garbage collection is called during this critical section,
6369 we simply return. #### We should abort instead.
6371 #### If a frame-size change does occur we should probably
6372 actually be preempting redisplay. */
6374 MAYBE_DEVMETH (d, frame_output_begin, (f));
6376 /* We can now update the gutters, safe in the knowledge that our
6377 efforts won't get undone. */
6379 /* This can call lisp, but redisplay is protected by binding
6380 inhibit_quit. More importantly the code involving display lines
6381 *assumes* that GC will not happen and so does not GCPRO
6382 anything. Since we use this code the whole time with the gutters
6383 we cannot allow GC to happen when manipulating the gutters. */
6384 update_frame_gutters (f);
6386 /* Erase the frame before outputting its contents. */
6389 MAYBE_DEVMETH (d, clear_frame, (f));
6392 /* Do the selected window first. */
6393 redisplay_window (FRAME_SELECTED_WINDOW (f), 0);
6395 /* Then do the rest. */
6396 redisplay_windows (f->root_window, 1);
6398 MAYBE_DEVMETH (d, frame_output_end, (f));
6400 update_frame_title (f);
6402 CLASS_RESET_CHANGED_FLAGS (f);
6403 f->window_face_cache_reset = 0;
6404 f->echo_area_garbaged = 0;
6407 if (!f->size_change_pending)
6408 f->size_changed = 0;
6410 /* ----------------- END CRITICAL REDISPLAY SECTION ---------------- */
6412 /* Allow frame size changes to occur again.
6414 #### what happens if changes to other frames happen? */
6415 unhold_one_frame_size_changes (f);
6417 map_windows (f, call_redisplay_end_triggers, 0);
6421 /* Ensure that all frames on the given device are correctly displayed.
6422 If AUTOMATIC is non-zero, and the device implementation indicates
6423 no automatic redisplay, as printers do, then the device is not
6424 redisplayed. AUTOMATIC is set to zero when called from lisp
6425 functions (redraw-device) and (redisplay-device), and to non-zero
6426 when called from "lazy" redisplay();
6430 redisplay_device (struct device *d, int automatic)
6432 Lisp_Object frame, frmcons;
6434 int size_change_failed = 0;
6438 && (MAYBE_INT_DEVMETH (d, device_implementation_flags, ())
6439 & XDEVIMPF_NO_AUTO_REDISPLAY))
6442 if (DEVICE_STREAM_P (d)) /* nothing to do */
6445 /* It is possible that redisplay has been called before the
6446 device is fully initialized. If so then continue with the
6448 if (NILP (DEVICE_SELECTED_FRAME (d)))
6451 REDISPLAY_PREEMPTION_CHECK;
6455 /* Always do the selected frame first. */
6456 frame = DEVICE_SELECTED_FRAME (d);
6460 if (f->icon_changed || f->windows_changed)
6461 update_frame_icon (f);
6463 if (FRAME_REPAINT_P (f))
6465 if (CLASS_REDISPLAY_FLAGS_CHANGEDP(f))
6467 preempted = redisplay_frame (f, 0);
6473 /* If the frame redisplay did not get preempted, then this flag
6474 should have gotten set to 0. It might be possible for that
6475 not to happen if a size change event were to occur at an odd
6476 time. To make sure we don't miss anything we simply don't
6477 reset the top level flags until the condition ends up being
6478 in the right state. */
6479 if (f->size_changed)
6480 size_change_failed = 1;
6483 DEVICE_FRAME_LOOP (frmcons, d)
6485 f = XFRAME (XCAR (frmcons));
6487 if (f == XFRAME (DEVICE_SELECTED_FRAME (d)))
6490 if (f->icon_changed || f->windows_changed)
6491 update_frame_icon (f);
6493 if (FRAME_REPAINT_P (f))
6495 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (f))
6497 preempted = redisplay_frame (f, 0);
6503 if (f->size_change_pending)
6504 size_change_failed = 1;
6508 /* If we get here then we redisplayed all of our frames without
6509 getting preempted so mark ourselves as clean. */
6510 CLASS_RESET_CHANGED_FLAGS (d);
6512 if (!size_change_failed)
6513 d->size_changed = 0;
6519 restore_profiling_redisplay_flag (Lisp_Object val)
6521 profiling_redisplay_flag = XINT (val);
6525 /* Ensure that all windows on all frames on all devices are displaying
6526 the current contents of their respective buffers. */
6529 redisplay_without_hooks (void)
6531 Lisp_Object devcons, concons;
6532 int size_change_failed = 0;
6533 int count = specpdl_depth ();
6535 if (profiling_active)
6537 record_unwind_protect (restore_profiling_redisplay_flag,
6538 make_int (profiling_redisplay_flag));
6539 profiling_redisplay_flag = 1;
6542 if (asynch_device_change_pending)
6543 handle_asynch_device_change ();
6545 if (!GLOBAL_REDISPLAY_FLAGS_CHANGEDP &&
6546 !disable_preemption && preemption_count < max_preempts)
6549 DEVICE_LOOP_NO_BREAK (devcons, concons)
6551 struct device *d = XDEVICE (XCAR (devcons));
6554 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (d))
6556 preempted = redisplay_device (d, 1);
6561 RESET_CHANGED_SET_FLAGS;
6565 /* See comment in redisplay_device. */
6566 if (d->size_changed)
6567 size_change_failed = 1;
6570 preemption_count = 0;
6572 /* Mark redisplay as accurate */
6573 GLOBAL_RESET_CHANGED_FLAGS;
6574 RESET_CHANGED_SET_FLAGS;
6578 mark_all_faces_as_clean ();
6582 if (!size_change_failed)
6585 reset_buffer_changes ();
6588 unbind_to (count, Qnil);
6594 if (last_display_warning_tick != display_warning_tick &&
6595 !inhibit_warning_display)
6597 /* If an error occurs during this function, oh well.
6598 If we report another warning, we could get stuck in an
6599 infinite loop reporting warnings. */
6600 call0_trapping_errors (0, Qdisplay_warning_buffer);
6601 last_display_warning_tick = display_warning_tick;
6603 /* The run_hook_trapping_errors functions are smart enough not
6604 to do any evalling if the hook function is empty, so there
6605 should not be any significant time loss. All places in the
6606 C code that call redisplay() are prepared to handle GCing,
6607 so we should be OK. */
6608 #ifndef INHIBIT_REDISPLAY_HOOKS
6609 run_hook_trapping_errors ("Error in pre-redisplay-hook",
6610 Qpre_redisplay_hook);
6611 #endif /* INHIBIT_REDISPLAY_HOOKS */
6613 redisplay_without_hooks ();
6615 #ifndef INHIBIT_REDISPLAY_HOOKS
6616 run_hook_trapping_errors ("Error in post-redisplay-hook",
6617 Qpost_redisplay_hook);
6618 #endif /* INHIBIT_REDISPLAY_HOOKS */
6622 static char window_line_number_buf[32];
6624 /* Efficiently determine the window line number, and return a pointer
6625 to its printed representation. Do this regardless of whether
6626 line-number-mode is on. The first line in the buffer is counted as
6627 1. If narrowing is in effect, the lines are counted from the
6628 beginning of the visible portion of the buffer. */
6630 window_line_number (struct window *w, int type)
6632 struct device *d = XDEVICE (XFRAME (w->frame)->device);
6633 struct buffer *b = XBUFFER (w->buffer);
6634 /* Be careful in the order of these tests. The first clause will
6635 fail if DEVICE_SELECTED_FRAME == Qnil (since w->frame cannot be).
6636 This can occur when the frame title is computed really early */
6638 ((EQ(DEVICE_SELECTED_FRAME(d), w->frame) &&
6639 (w == XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame(d)))) &&
6640 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
6641 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d )
6643 : marker_position (w->pointm[type]));
6646 line = buffer_line_number (b, pos, 1);
6648 long_to_string (window_line_number_buf, line + 1);
6650 return window_line_number_buf;
6654 /* Given a character representing an object in a modeline
6655 specification, return a string (stored into the global array
6656 `mode_spec_bufbyte_string') with the information that object
6659 This function is largely unchanged from previous versions of the
6662 Warning! This code is also used for frame titles and can be called
6663 very early in the device/frame update process! JV
6667 decode_mode_spec (struct window *w, Emchar spec, int type)
6669 Lisp_Object obj = Qnil;
6670 const char *str = NULL;
6671 struct buffer *b = XBUFFER (w->buffer);
6673 Dynarr_reset (mode_spec_bufbyte_string);
6677 /* print buffer name */
6682 /* print visited file name */
6687 /* print the current column */
6690 Bufpos pt = (w == XWINDOW (Fselected_window (Qnil)))
6692 : marker_position (w->pointm[type]);
6693 int col = column_at_point (b, pt, 1) + !!column_number_start_at_one;
6696 long_to_string (buf, col);
6698 Dynarr_add_many (mode_spec_bufbyte_string,
6699 (const Bufbyte *) buf, strlen (buf));
6701 goto decode_mode_spec_done;
6703 /* print the file coding system */
6707 Lisp_Object codesys = b->buffer_file_coding_system;
6708 /* Be very careful here not to get an error. */
6709 if (NILP (codesys) || SYMBOLP (codesys) || CODING_SYSTEMP (codesys))
6711 codesys = Ffind_coding_system (codesys);
6712 if (CODING_SYSTEMP (codesys))
6713 obj = XCODING_SYSTEM_MNEMONIC (codesys);
6716 #endif /* FILE_CODING */
6719 /* print the current line number */
6721 str = window_line_number (w, type);
6724 /* print value of mode-name (obsolete) */
6729 /* print hyphen and frame number, if != 1 */
6733 struct frame *f = XFRAME (w->frame);
6734 if (FRAME_TTY_P (f) && f->order_count > 1 && f->order_count <= 99999999)
6736 /* Naughty, naughty */
6737 char * writable_str = alloca_array (char, 10);
6738 sprintf (writable_str, "-%d", f->order_count);
6742 #endif /* HAVE_TTY */
6745 /* print Narrow if appropriate */
6747 if (BUF_BEGV (b) > BUF_BEG (b)
6748 || BUF_ZV (b) < BUF_Z (b))
6752 /* print %, * or hyphen, if buffer is read-only, modified or neither */
6754 str = (!NILP (b->read_only)
6756 : ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6761 /* print * or hyphen -- XEmacs change to allow a buffer to be
6762 read-only but still indicate whether it is modified. */
6764 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6766 : (!NILP (b->read_only)
6771 /* #### defined in 19.29 decode_mode_spec, but not in
6772 modeline-format doc string. */
6773 /* This differs from %* in that it ignores read-only-ness. */
6775 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6780 /* print process status */
6782 obj = Fget_buffer_process (w->buffer);
6784 str = GETTEXT ("no process");
6786 obj = Fsymbol_name (Fprocess_status (obj));
6789 /* Print name of selected frame. */
6791 obj = XFRAME (w->frame)->name;
6794 /* indicate TEXT or BINARY */
6796 /* #### NT does not use this any more. Now what? */
6800 /* print percent of buffer above top of window, or Top, Bot or All */
6803 Bufpos pos = marker_position (w->start[type]);
6805 /* This had better be while the desired lines are being done. */
6806 if (w->window_end_pos[type] <= BUF_Z (b) - BUF_ZV (b))
6808 if (pos <= BUF_BEGV (b))
6813 else if (pos <= BUF_BEGV (b))
6817 /* This hard limit is ok since the string it will hold has a
6818 fixed maximum length of 3. But just to be safe... */
6820 Charcount chars = pos - BUF_BEGV (b);
6821 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6823 /* Avoid overflow on big buffers */
6824 int percent = total > LONG_MAX/200 ?
6825 (chars + total/200) / (total / 100) :
6826 (chars * 100 + total/2) / total;
6828 /* We can't normally display a 3-digit number, so get us a
6829 2-digit number that is close. */
6833 sprintf (buf, "%d%%", percent);
6834 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6837 goto decode_mode_spec_done;
6842 /* print percent of buffer above bottom of window, perhaps plus
6843 Top, or print Bottom or All */
6846 Bufpos toppos = marker_position (w->start[type]);
6847 Bufpos botpos = BUF_Z (b) - w->window_end_pos[type];
6849 /* botpos is only accurate as of the last redisplay, so we can
6850 only treat it as a hint. In particular, after erase-buffer,
6851 botpos may be negative. */
6852 if (botpos < toppos)
6855 if (botpos >= BUF_ZV (b))
6857 if (toppos <= BUF_BEGV (b))
6864 /* This hard limit is ok since the string it will hold has a
6865 fixed maximum length of around 6. But just to be safe... */
6867 Charcount chars = botpos - BUF_BEGV (b);
6868 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6870 /* Avoid overflow on big buffers */
6871 int percent = total > LONG_MAX/200 ?
6872 (chars + total/200) / (total / 100) :
6873 (chars * 100 + total/2) / max (total, 1);
6875 /* We can't normally display a 3-digit number, so get us a
6876 2-digit number that is close. */
6880 if (toppos <= BUF_BEGV (b))
6881 sprintf (buf, "Top%d%%", percent);
6883 sprintf (buf, "%d%%", percent);
6885 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6888 goto decode_mode_spec_done;
6898 /* print one [ for each recursive editing level. */
6903 if (command_loop_level > 5)
6909 for (i = 0; i < command_loop_level; i++)
6910 Dynarr_add (mode_spec_bufbyte_string, '[');
6912 goto decode_mode_spec_done;
6915 /* print one ] for each recursive editing level. */
6920 if (command_loop_level > 5)
6926 for (i = 0; i < command_loop_level; i++)
6927 Dynarr_add (mode_spec_bufbyte_string, ']');
6929 goto decode_mode_spec_done;
6932 /* print infinitely many dashes -- handle at top level now */
6939 Dynarr_add_many (mode_spec_bufbyte_string,
6941 XSTRING_LENGTH (obj));
6943 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) str, strlen (str));
6945 decode_mode_spec_done:
6946 Dynarr_add (mode_spec_bufbyte_string, '\0');
6949 /* Given a display line, free all of its data structures. */
6952 free_display_line (struct display_line *dl)
6956 if (dl->display_blocks)
6958 for (block = 0; block < Dynarr_largest (dl->display_blocks); block++)
6960 struct display_block *db = Dynarr_atp (dl->display_blocks, block);
6962 Dynarr_free (db->runes);
6965 Dynarr_free (dl->display_blocks);
6966 dl->display_blocks = NULL;
6969 if (dl->left_glyphs)
6971 Dynarr_free (dl->left_glyphs);
6972 dl->left_glyphs = NULL;
6975 if (dl->right_glyphs)
6977 Dynarr_free (dl->right_glyphs);
6978 dl->right_glyphs = NULL;
6983 /* Given an array of display lines, free them and all data structures
6984 contained within them. */
6987 free_display_lines (display_line_dynarr *dla)
6991 for (line = 0; line < Dynarr_largest (dla); line++)
6993 free_display_line (Dynarr_atp (dla, line));
6999 /* Call internal free routine for each set of display lines. */
7002 free_display_structs (struct window_mirror *mir)
7004 if (mir->current_display_lines)
7006 free_display_lines (mir->current_display_lines);
7007 mir->current_display_lines = 0;
7010 if (mir->desired_display_lines)
7012 free_display_lines (mir->desired_display_lines);
7013 mir->desired_display_lines = 0;
7019 mark_glyph_block_dynarr (glyph_block_dynarr *gba)
7023 glyph_block *gb = Dynarr_atp (gba, 0);
7024 glyph_block *gb_last = Dynarr_atp (gba, Dynarr_length (gba));
7026 for (; gb < gb_last; gb++)
7028 if (!NILP (gb->glyph))
7029 mark_object (gb->glyph);
7030 if (!NILP (gb->extent))
7031 mark_object (gb->extent);
7036 /* See the comment in image_instantiate_cache_result as to why marking
7037 the glyph will also mark the image_instance. */
7039 mark_redisplay_structs (display_line_dynarr *dla)
7041 display_line *dl = Dynarr_atp (dla, 0);
7042 display_line *dl_last = Dynarr_atp (dla, Dynarr_length (dla));
7044 for (; dl < dl_last; dl++)
7046 display_block_dynarr *dba = dl->display_blocks;
7047 display_block *db = Dynarr_atp (dba, 0);
7048 display_block *db_last = Dynarr_atp (dba, Dynarr_length (dba));
7050 for (; db < db_last; db++)
7052 rune_dynarr *ra = db->runes;
7053 rune *r = Dynarr_atp (ra, 0);
7054 rune *r_last = Dynarr_atp (ra, Dynarr_length (ra));
7056 for (; r < r_last; r++)
7058 if (r->type == RUNE_DGLYPH)
7060 if (!NILP (r->object.dglyph.glyph))
7061 mark_object (r->object.dglyph.glyph);
7062 if (!NILP (r->object.dglyph.extent))
7063 mark_object (r->object.dglyph.extent);
7068 mark_glyph_block_dynarr (dl->left_glyphs);
7069 mark_glyph_block_dynarr (dl->right_glyphs);
7074 mark_window_mirror (struct window_mirror *mir)
7076 mark_redisplay_structs (mir->current_display_lines);
7077 mark_redisplay_structs (mir->desired_display_lines);
7080 mark_window_mirror (mir->next);
7083 mark_window_mirror (mir->hchild);
7084 else if (mir->vchild)
7085 mark_window_mirror (mir->vchild);
7089 mark_redisplay (void)
7091 Lisp_Object frmcons, devcons, concons;
7093 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
7095 struct frame *f = XFRAME (XCAR (frmcons));
7096 update_frame_window_mirror (f);
7097 mark_window_mirror (f->root_mirror);
7102 /*****************************************************************************
7103 Line Start Cache Description and Rationale
7105 The traditional scrolling code in Emacs breaks in a variable height world.
7106 It depends on the key assumption that the number of lines that can be
7107 displayed at any given time is fixed. This led to a complete separation
7108 of the scrolling code from the redisplay code. In order to fully support
7109 variable height lines, the scrolling code must actually be tightly
7110 integrated with redisplay. Only redisplay can determine how many lines
7111 will be displayed on a screen for any given starting point.
7113 What is ideally wanted is a complete list of the starting buffer position
7114 for every possible display line of a buffer along with the height of that
7115 display line. Maintaining such a full list would be very expensive. We
7116 settle for having it include information for all areas which we happen to
7117 generate anyhow (i.e. the region currently being displayed) and for those
7118 areas we need to work with.
7120 In order to ensure that the cache accurately represents what redisplay
7121 would actually show, it is necessary to invalidate it in many situations.
7122 If the buffer changes, the starting positions may no longer be correct.
7123 If a face or an extent has changed then the line heights may have altered.
7124 These events happen frequently enough that the cache can end up being
7125 constantly disabled. With this potentially constant invalidation when is
7126 the cache ever useful?
7128 Even if the cache is invalidated before every single usage, it is
7129 necessary. Scrolling often requires knowledge about display lines which
7130 are actually above or below the visible region. The cache provides a
7131 convenient light-weight method of storing this information for multiple
7132 display regions. This knowledge is necessary for the scrolling code to
7133 always obey the First Golden Rule of Redisplay.
7135 If the cache already contains all of the information that the scrolling
7136 routines happen to need so that it doesn't have to go generate it, then we
7137 are able to obey the Third Golden Rule of Redisplay. The first thing we
7138 do to help out the cache is to always add the displayed region. This
7139 region had to be generated anyway, so the cache ends up getting the
7140 information basically for free. In those cases where a user is simply
7141 scrolling around viewing a buffer there is a high probability that this is
7142 sufficient to always provide the needed information. The second thing we
7143 can do is be smart about invalidating the cache.
7145 TODO -- Be smart about invalidating the cache. Potential places:
7147 + Insertions at end-of-line which don't cause line-wraps do not alter the
7148 starting positions of any display lines. These types of buffer
7149 modifications should not invalidate the cache. This is actually a large
7150 optimization for redisplay speed as well.
7152 + Buffer modifications frequently only affect the display of lines at and
7153 below where they occur. In these situations we should only invalidate
7154 the part of the cache starting at where the modification occurs.
7156 In case you're wondering, the Second Golden Rule of Redisplay is not
7158 ****************************************************************************/
7160 /* This will get used quite a bit so we don't want to be constantly
7161 allocating and freeing it. */
7162 static line_start_cache_dynarr *internal_cache;
7164 /* Makes internal_cache represent the TYPE display structs and only
7165 the TYPE display structs. */
7168 update_internal_cache_list (struct window *w, int type)
7171 display_line_dynarr *dla = window_display_lines (w, type);
7173 Dynarr_reset (internal_cache);
7174 for (line = 0; line < Dynarr_length (dla); line++)
7176 struct display_line *dl = Dynarr_atp (dla, line);
7182 struct line_start_cache lsc;
7184 lsc.start = dl->bufpos;
7185 lsc.end = dl->end_bufpos;
7186 lsc.height = dl->ascent + dl->descent;
7188 Dynarr_add (internal_cache, lsc);
7193 /* Reset the line cache if necessary. This should be run at the
7194 beginning of any function which access the cache. */
7197 validate_line_start_cache (struct window *w)
7199 struct buffer *b = XBUFFER (w->buffer);
7200 struct frame *f = XFRAME (w->frame);
7202 if (!w->line_cache_validation_override)
7204 /* f->extents_changed used to be in here because extent face and
7205 size changes can cause text shifting. However, the extent
7206 covering the region is constantly having its face set and
7207 priority altered by the mouse code. This means that the line
7208 start cache is constantly being invalidated. This is bad
7209 since the mouse code also triggers heavy usage of the cache.
7210 Since it is an unlikely that f->extents being changed
7211 indicates that the cache really needs to be updated and if it
7212 does redisplay will catch it pretty quickly we no longer
7213 invalidate the cache if it is set. This greatly speeds up
7214 dragging out regions with the mouse. */
7215 if (XINT (w->line_cache_last_updated) < BUF_MODIFF (b)
7219 Dynarr_reset (w->line_start_cache);
7224 /* Return the very first buffer position contained in the given
7225 window's cache, or -1 if the cache is empty. Assumes that the
7229 line_start_cache_start (struct window *w)
7231 line_start_cache_dynarr *cache = w->line_start_cache;
7233 if (!Dynarr_length (cache))
7236 return Dynarr_atp (cache, 0)->start;
7239 /* Return the very last buffer position contained in the given
7240 window's cache, or -1 if the cache is empty. Assumes that the
7244 line_start_cache_end (struct window *w)
7246 line_start_cache_dynarr *cache = w->line_start_cache;
7248 if (!Dynarr_length (cache))
7251 return Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
7254 /* Return the index of the line POINT is contained within in window
7255 W's line start cache. It will enlarge the cache or move the cache
7256 window in order to have POINT be present in the cache. MIN_PAST is
7257 a guarantee of the number of entries in the cache present on either
7258 side of POINT (unless a buffer boundary is hit). If MIN_PAST is -1
7259 then it will be treated as 0, but the cache window will not be
7260 allowed to shift. Returns -1 if POINT cannot be found in the cache
7264 point_in_line_start_cache (struct window *w, Bufpos point, int min_past)
7266 struct buffer *b = XBUFFER (w->buffer);
7267 line_start_cache_dynarr *cache = w->line_start_cache;
7268 unsigned int top, bottom, pos;
7270 validate_line_start_cache (w);
7271 w->line_cache_validation_override++;
7273 /* Let functions pass in negative values, but we still treat -1
7275 /* #### bogosity alert */
7276 if (min_past < 0 && min_past != -1)
7277 min_past = -min_past;
7279 if (!Dynarr_length (cache) || line_start_cache_start (w) > point
7280 || line_start_cache_end (w) < point)
7283 int win_char_height = window_char_height (w, 1);
7285 /* Occasionally we get here with a 0 height
7286 window. find_next_newline_no_quit will abort if we pass it a
7287 count of 0 so handle that case. */
7288 if (!win_char_height)
7289 win_char_height = 1;
7291 if (!Dynarr_length (cache))
7293 Bufpos from = find_next_newline_no_quit (b, point, -1);
7294 Bufpos to = find_next_newline_no_quit (b, from, win_char_height);
7296 update_line_start_cache (w, from, to, point, 0);
7298 if (!Dynarr_length (cache))
7300 w->line_cache_validation_override--;
7305 assert (Dynarr_length (cache));
7308 while (line_start_cache_start (w) > point
7309 && (loop < cache_adjustment || min_past == -1))
7313 from = line_start_cache_start (w);
7314 if (from <= BUF_BEGV (b))
7317 from = find_next_newline_no_quit (b, from, -win_char_height);
7318 to = line_start_cache_end (w);
7320 update_line_start_cache (w, from, to, point, 0);
7324 if (line_start_cache_start (w) > point)
7328 from = find_next_newline_no_quit (b, point, -1);
7329 if (from >= BUF_ZV (b))
7331 to = find_next_newline_no_quit (b, from, -win_char_height);
7336 to = find_next_newline_no_quit (b, from, win_char_height);
7338 update_line_start_cache (w, from, to, point, 0);
7342 while (line_start_cache_end (w) < point
7343 && (loop < cache_adjustment || min_past == -1))
7347 to = line_start_cache_end (w);
7348 if (to >= BUF_ZV (b))
7351 from = line_start_cache_end (w);
7352 to = find_next_newline_no_quit (b, from, win_char_height);
7354 update_line_start_cache (w, from, to, point, 0);
7358 if (line_start_cache_end (w) < point)
7362 from = find_next_newline_no_quit (b, point, -1);
7363 if (from >= BUF_ZV (b))
7365 to = find_next_newline_no_quit (b, from, -win_char_height);
7370 to = find_next_newline_no_quit (b, from, win_char_height);
7372 update_line_start_cache (w, from, to, point, 0);
7376 assert (Dynarr_length (cache));
7381 /* This could happen if the buffer is narrowed. */
7382 if (line_start_cache_start (w) > point
7383 || line_start_cache_end (w) < point)
7385 w->line_cache_validation_override--;
7391 top = Dynarr_length (cache) - 1;
7396 unsigned int new_pos;
7399 pos = (bottom + top + 1) >> 1;
7400 start = Dynarr_atp (cache, pos)->start;
7401 end = Dynarr_atp (cache, pos)->end;
7403 if (point >= start && point <= end)
7405 if (pos < min_past && line_start_cache_start (w) > BUF_BEGV (b))
7408 find_next_newline_no_quit (b, line_start_cache_start (w),
7410 Bufpos to = line_start_cache_end (w);
7412 update_line_start_cache (w, from, to, point, 0);
7413 goto find_point_loop;
7415 else if ((Dynarr_length (cache) - pos - 1) < min_past
7416 && line_start_cache_end (w) < BUF_ZV (b))
7418 Bufpos from = line_start_cache_end (w);
7419 Bufpos to = find_next_newline_no_quit (b, from,
7424 update_line_start_cache (w, from, to, point, 0);
7425 goto find_point_loop;
7429 w->line_cache_validation_override--;
7433 else if (point > end)
7435 else if (point < start)
7440 new_pos = (bottom + top + 1) >> 1;
7443 w->line_cache_validation_override--;
7449 /* Return a boolean indicating if POINT would be visible in window W
7450 if display of the window was to begin at STARTP. */
7453 point_would_be_visible (struct window *w, Bufpos startp, Bufpos point)
7455 struct buffer *b = XBUFFER (w->buffer);
7456 int pixpos = -WINDOW_TEXT_TOP_CLIP(w);
7457 int bottom = WINDOW_TEXT_HEIGHT (w);
7460 /* If point is before the intended start it obviously can't be visible. */
7464 /* If point or start are not in the accessible buffer range, then
7466 if (startp < BUF_BEGV (b) || startp > BUF_ZV (b)
7467 || point < BUF_BEGV (b) || point > BUF_ZV (b))
7470 validate_line_start_cache (w);
7471 w->line_cache_validation_override++;
7473 start_elt = point_in_line_start_cache (w, startp, 0);
7474 if (start_elt == -1)
7476 w->line_cache_validation_override--;
7480 assert (line_start_cache_start (w) <= startp
7481 && line_start_cache_end (w) >= startp);
7487 /* Expand the cache if necessary. */
7488 if (start_elt == Dynarr_length (w->line_start_cache))
7491 Dynarr_atp (w->line_start_cache, start_elt - 1)->start;
7493 start_elt = point_in_line_start_cache (w, old_startp,
7494 window_char_height (w, 0));
7496 /* We've already actually processed old_startp, so increment
7500 /* If this happens we didn't add any extra elements. Bummer. */
7501 if (start_elt == Dynarr_length (w->line_start_cache))
7503 w->line_cache_validation_override--;
7508 height = Dynarr_atp (w->line_start_cache, start_elt)->height;
7510 if (pixpos + height > bottom)
7512 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7514 w->line_cache_validation_override--;
7520 if (point <= Dynarr_atp (w->line_start_cache, start_elt)->end)
7522 w->line_cache_validation_override--;
7530 /* For the given window W, if display starts at STARTP, what will be
7531 the buffer position at the beginning or end of the last line
7532 displayed. The end of the last line is also know as the window end
7535 WARNING: It is possible that redisplay failed to layout any lines for the
7536 windows. Under normal circumstances this is rare. However it seems that it
7537 does occur in the following situation: A mouse event has come in and we
7538 need to compute its location in a window. That code (in
7539 pixel_to_glyph_translation) already can handle 0 as an error return value.
7541 #### With a little work this could probably be reworked as just a
7542 call to start_with_line_at_pixpos. */
7545 start_end_of_last_line (struct window *w, Bufpos startp, int end,
7548 struct buffer *b = XBUFFER (w->buffer);
7549 line_start_cache_dynarr *cache = w->line_start_cache;
7551 int bottom = WINDOW_TEXT_HEIGHT (w);
7555 validate_line_start_cache (w);
7556 w->line_cache_validation_override++;
7558 if (startp < BUF_BEGV (b))
7559 startp = BUF_BEGV (b);
7560 else if (startp > BUF_ZV (b))
7561 startp = BUF_ZV (b);
7564 start_elt = point_in_line_start_cache (w, cur_start, 0);
7565 if (start_elt == -1)
7566 return may_error ? 0 : startp;
7570 int height = Dynarr_atp (cache, start_elt)->height;
7572 cur_start = Dynarr_atp (cache, start_elt)->start;
7574 if (pixpos + height > bottom)
7576 /* Adjust for any possible clip. */
7577 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7582 w->line_cache_validation_override--;
7586 return BUF_BEGV (b);
7590 w->line_cache_validation_override--;
7592 return Dynarr_atp (cache, start_elt)->end;
7594 return Dynarr_atp (cache, start_elt)->start;
7600 if (start_elt == Dynarr_length (cache))
7602 Bufpos from = line_start_cache_end (w);
7603 int win_char_height = window_char_height (w, 0);
7604 Bufpos to = find_next_newline_no_quit (b, from,
7609 /* We've hit the end of the bottom so that's what it is. */
7610 if (from >= BUF_ZV (b))
7612 w->line_cache_validation_override--;
7616 update_line_start_cache (w, from, to, BUF_PT (b), 0);
7618 /* Updating the cache invalidates any current indexes. */
7619 start_elt = point_in_line_start_cache (w, cur_start, -1) + 1;
7624 /* For the given window W, if display starts at STARTP, what will be
7625 the buffer position at the beginning of the last line displayed. */
7628 start_of_last_line (struct window *w, Bufpos startp)
7630 return start_end_of_last_line (w, startp, 0 , 0);
7633 /* For the given window W, if display starts at STARTP, what will be
7634 the buffer position at the end of the last line displayed. This is
7635 also know as the window end position. */
7638 end_of_last_line (struct window *w, Bufpos startp)
7640 return start_end_of_last_line (w, startp, 1, 0);
7644 end_of_last_line_may_error (struct window *w, Bufpos startp)
7646 return start_end_of_last_line (w, startp, 1, 1);
7650 /* For window W, what does the starting position have to be so that
7651 the line containing POINT will cover pixel position PIXPOS. */
7654 start_with_line_at_pixpos (struct window *w, Bufpos point, int pixpos)
7656 struct buffer *b = XBUFFER (w->buffer);
7658 Bufpos cur_pos, prev_pos = point;
7659 int point_line_height;
7660 int pixheight = pixpos - WINDOW_TEXT_TOP (w);
7662 validate_line_start_cache (w);
7663 w->line_cache_validation_override++;
7665 cur_elt = point_in_line_start_cache (w, point, 0);
7666 /* #### See comment in update_line_start_cache about big minibuffers. */
7669 w->line_cache_validation_override--;
7673 point_line_height = Dynarr_atp (w->line_start_cache, cur_elt)->height;
7677 cur_pos = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7679 pixheight -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7681 /* Do not take into account the value of vertical_clip here.
7682 That is the responsibility of the calling functions. */
7685 w->line_cache_validation_override--;
7686 if (-pixheight > point_line_height)
7687 /* We can't make the target line cover pixpos, so put it
7688 above pixpos. That way it will at least be visible. */
7698 int win_char_height;
7700 if (cur_pos <= BUF_BEGV (b))
7702 w->line_cache_validation_override--;
7703 return BUF_BEGV (b);
7706 win_char_height = window_char_height (w, 0);
7707 if (!win_char_height)
7708 win_char_height = 1;
7710 from = find_next_newline_no_quit (b, cur_pos, -win_char_height);
7711 to = line_start_cache_end (w);
7712 update_line_start_cache (w, from, to, point, 0);
7714 cur_elt = point_in_line_start_cache (w, cur_pos, 2) - 1;
7715 assert (cur_elt >= -1);
7716 /* This used to be cur_elt>=0 under the assumption that if
7717 point is in the top line and not at BUF_BEGV, then
7718 setting the window_start to a newline before the start of
7719 the first line will always cause scrolling.
7721 However in my (jv) opinion this is wrong. That new line
7722 can be hidden in various ways: invisible extents, an
7723 explicit window-start not at a newline character etc.
7724 The existence of those are indeed known to create crashes
7725 on that assert. So we have no option but to continue the
7726 search if we found point at the top of the line_start_cache
7728 cur_pos = Dynarr_atp (w->line_start_cache,0)->start;
7734 /* For window W, what does the starting position have to be so that
7735 the line containing point is on display line LINE. If LINE is
7736 positive it is considered to be the number of lines from the top of
7737 the window (0 is the top line). If it is negative the number is
7738 considered to be the number of lines from the bottom (-1 is the
7742 start_with_point_on_display_line (struct window *w, Bufpos point, int line)
7744 validate_line_start_cache (w);
7745 w->line_cache_validation_override++;
7749 int cur_elt = point_in_line_start_cache (w, point, line);
7751 if (cur_elt - line < 0)
7752 cur_elt = 0; /* Hit the top */
7756 w->line_cache_validation_override--;
7757 return Dynarr_atp (w->line_start_cache, cur_elt)->start;
7761 /* The calculated value of pixpos is correct for the bottom line
7762 or what we want when line is -1. Therefore we subtract one
7763 because we have already handled one line. */
7764 int new_line = -line - 1;
7765 int cur_elt = point_in_line_start_cache (w, point, new_line);
7766 int pixpos = WINDOW_TEXT_BOTTOM (w);
7767 Bufpos retval, search_point;
7769 /* If scroll_on_clipped_lines is false, the last "visible" line of
7770 the window covers the pixel at WINDOW_TEXT_BOTTOM (w) - 1.
7771 If s_o_c_l is true, then we don't want to count a clipped
7772 line, so back up from the bottom by the height of the line
7773 containing point. */
7774 if (scroll_on_clipped_lines)
7775 pixpos -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7779 if (cur_elt + new_line >= Dynarr_length (w->line_start_cache))
7781 /* Hit the bottom of the buffer. */
7783 (cur_elt + new_line) - Dynarr_length (w->line_start_cache) + 1;
7787 XSETWINDOW (window, w);
7788 default_face_height_and_width (window, &defheight, 0);
7790 cur_elt = Dynarr_length (w->line_start_cache) - 1;
7792 pixpos -= (adjustment * defheight);
7793 if (pixpos < WINDOW_TEXT_TOP (w))
7794 pixpos = WINDOW_TEXT_TOP (w);
7797 cur_elt = cur_elt + new_line;
7799 search_point = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7801 retval = start_with_line_at_pixpos (w, search_point, pixpos);
7802 w->line_cache_validation_override--;
7807 /* This is used to speed up vertical scrolling by caching the known
7808 buffer starting positions for display lines. This allows the
7809 scrolling routines to avoid costly calls to regenerate_window. If
7810 NO_REGEN is true then it will only add the values in the DESIRED
7811 display structs which are in the given range.
7813 Note also that the FROM/TO values are minimums. It is possible
7814 that this function will actually add information outside of the
7815 lines containing those positions. This can't hurt but it could
7818 #### We currently force the cache to have only 1 contiguous region.
7819 It might help to make the cache a dynarr of caches so that we can
7820 cover more areas. This might, however, turn out to be a lot of
7821 overhead for too little gain. */
7824 update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
7825 Bufpos point, int no_regen)
7827 struct buffer *b = XBUFFER (w->buffer);
7828 line_start_cache_dynarr *cache = w->line_start_cache;
7829 Bufpos low_bound, high_bound;
7831 validate_line_start_cache (w);
7832 w->line_cache_validation_override++;
7834 if (from < BUF_BEGV (b))
7835 from = BUF_BEGV (b);
7836 if (to > BUF_ZV (b))
7841 w->line_cache_validation_override--;
7845 if (Dynarr_length (cache))
7847 low_bound = line_start_cache_start (w);
7848 high_bound = line_start_cache_end (w);
7850 /* Check to see if the desired range is already in the cache. */
7851 if (from >= low_bound && to <= high_bound)
7853 w->line_cache_validation_override--;
7857 /* Check to make sure that the desired range is adjacent to the
7858 current cache. If not, invalidate the cache. */
7859 if (to < low_bound || from > high_bound)
7861 Dynarr_reset (cache);
7862 low_bound = high_bound = -1;
7867 low_bound = high_bound = -1;
7870 w->line_cache_last_updated = make_int (BUF_MODIFF (b));
7872 /* This could be integrated into the next two sections, but it is easier
7873 to follow what's going on by having it separate. */
7878 update_internal_cache_list (w, DESIRED_DISP);
7879 if (!Dynarr_length (internal_cache))
7881 w->line_cache_validation_override--;
7885 start = Dynarr_atp (internal_cache, 0)->start;
7887 Dynarr_atp (internal_cache, Dynarr_length (internal_cache) - 1)->end;
7889 /* We aren't allowed to generate additional information to fill in
7890 gaps, so if the DESIRED structs don't overlap the cache, reset the
7892 if (Dynarr_length (cache))
7894 if (end < low_bound || start > high_bound)
7895 Dynarr_reset (cache);
7897 /* #### What should really happen if what we are doing is
7898 extending a line (the last line)? */
7899 if (Dynarr_length (cache) == 1
7900 && Dynarr_length (internal_cache) == 1)
7901 Dynarr_reset (cache);
7904 if (!Dynarr_length (cache))
7906 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7907 Dynarr_length (internal_cache));
7908 w->line_cache_validation_override--;
7912 /* An extra check just in case the calling function didn't pass in
7913 the bounds of the DESIRED structs in the first place. */
7914 if (start >= low_bound && end <= high_bound)
7916 w->line_cache_validation_override--;
7920 /* At this point we know that the internal cache partially overlaps
7922 if (start < low_bound)
7924 int ic_elt = Dynarr_length (internal_cache) - 1;
7927 if (Dynarr_atp (internal_cache, ic_elt)->start < low_bound)
7935 Dynarr_reset (cache);
7936 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7937 Dynarr_length (internal_cache));
7938 w->line_cache_validation_override--;
7942 Dynarr_insert_many_at_start (cache, Dynarr_atp (internal_cache, 0),
7946 if (end > high_bound)
7950 while (ic_elt < Dynarr_length (internal_cache))
7952 if (Dynarr_atp (internal_cache, ic_elt)->start > high_bound)
7958 if (!(ic_elt < Dynarr_length (internal_cache)))
7960 Dynarr_reset (cache);
7961 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7962 Dynarr_length (internal_cache));
7963 w->line_cache_validation_override--;
7967 Dynarr_add_many (cache, Dynarr_atp (internal_cache, ic_elt),
7968 Dynarr_length (internal_cache) - ic_elt);
7971 w->line_cache_validation_override--;
7975 if (!Dynarr_length (cache) || from < low_bound)
7977 Bufpos startp = find_next_newline_no_quit (b, from, -1);
7979 int old_lb = low_bound;
7981 while (startp < old_lb || low_bound == -1)
7986 regenerate_window (w, startp, point, CMOTION_DISP);
7987 update_internal_cache_list (w, CMOTION_DISP);
7989 /* If this assert is triggered then regenerate_window failed
7990 to layout a single line. This is not possible since we
7991 force at least a single line to be layout for CMOTION_DISP */
7992 assert (Dynarr_length (internal_cache));
7993 assert (startp == Dynarr_atp (internal_cache, 0)->start);
7995 ic_elt = Dynarr_length (internal_cache) - 1;
7996 if (low_bound != -1)
8000 if (Dynarr_atp (internal_cache, ic_elt)->start < old_lb)
8006 assert (ic_elt >= 0);
8008 new_startp = Dynarr_atp (internal_cache, ic_elt)->end + 1;
8011 * Handle invisible text properly:
8012 * If the last line we're inserting has the same end as the
8013 * line before which it will be added, merge the two lines.
8015 if (Dynarr_length (cache) &&
8016 Dynarr_atp (internal_cache, ic_elt)->end ==
8017 Dynarr_atp (cache, marker)->end)
8019 Dynarr_atp (cache, marker)->start
8020 = Dynarr_atp (internal_cache, ic_elt)->start;
8021 Dynarr_atp (cache, marker)->height
8022 = Dynarr_atp (internal_cache, ic_elt)->height;
8026 if (ic_elt >= 0) /* we still have lines to add.. */
8028 Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0),
8029 ic_elt + 1, marker);
8030 marker += (ic_elt + 1);
8033 if (startp < low_bound || low_bound == -1)
8035 startp = new_startp;
8036 if (startp > BUF_ZV (b))
8038 w->line_cache_validation_override--;
8044 assert (Dynarr_length (cache));
8045 assert (from >= low_bound);
8047 /* Readjust the high_bound to account for any changes made while
8048 correcting the low_bound. */
8049 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8051 if (to > high_bound)
8053 Bufpos startp = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end + 1;
8057 regenerate_window (w, startp, point, CMOTION_DISP);
8058 update_internal_cache_list (w, CMOTION_DISP);
8060 /* See comment above about regenerate_window failing. */
8061 assert (Dynarr_length (internal_cache));
8063 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
8064 Dynarr_length (internal_cache));
8065 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8066 startp = high_bound + 1;
8068 while (to > high_bound);
8071 w->line_cache_validation_override--;
8072 assert (to <= high_bound);
8076 /* Given x and y coordinates in characters, relative to a window,
8077 return the pixel location corresponding to those coordinates. The
8078 pixel location returned is the center of the given character
8079 position. The pixel values are generated relative to the window,
8082 The modeline is considered to be part of the window. */
8085 glyph_to_pixel_translation (struct window *w, int char_x, int char_y,
8086 int *pix_x, int *pix_y)
8088 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
8089 int num_disp_lines, modeline;
8091 int defheight, defwidth;
8093 XSETWINDOW (window, w);
8094 default_face_height_and_width (window, &defheight, &defwidth);
8096 /* If we get a bogus value indicating somewhere above or to the left of
8097 the window, use the first window line or character position
8104 num_disp_lines = Dynarr_length (dla);
8108 if (Dynarr_atp (dla, 0)->modeline)
8115 /* First check if the y position intersects the display lines. */
8116 if (char_y < num_disp_lines)
8118 struct display_line *dl = Dynarr_atp (dla, char_y + modeline);
8119 struct display_block *db = get_display_block_from_line (dl, TEXT);
8121 *pix_y = (dl->ypos - dl->ascent +
8122 ((unsigned int) (dl->ascent + dl->descent - dl->clip) >> 1));
8124 if (char_x < Dynarr_length (db->runes))
8126 struct rune *rb = Dynarr_atp (db->runes, char_x);
8128 *pix_x = rb->xpos + (rb->width >> 1);
8132 int last_rune = Dynarr_length (db->runes) - 1;
8133 struct rune *rb = Dynarr_atp (db->runes, last_rune);
8135 char_x -= last_rune;
8137 *pix_x = rb->xpos + rb->width;
8138 *pix_x += ((char_x - 1) * defwidth);
8139 *pix_x += (defwidth >> 1);
8144 /* It didn't intersect, so extrapolate. #### For now, we include the
8145 modeline in this since we don't have true character positions in
8148 if (!Dynarr_length (w->face_cachels))
8149 reset_face_cachels (w);
8151 char_y -= num_disp_lines;
8153 if (Dynarr_length (dla))
8155 struct display_line *dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
8156 *pix_y = dl->ypos + dl->descent - dl->clip;
8159 *pix_y = WINDOW_TEXT_TOP (w);
8161 *pix_y += (char_y * defheight);
8162 *pix_y += (defheight >> 1);
8164 *pix_x = WINDOW_TEXT_LEFT (w);
8165 /* Don't adjust by one because this is still the unadjusted value. */
8166 *pix_x += (char_x * defwidth);
8167 *pix_x += (defwidth >> 1);
8170 if (*pix_x > w->pixel_left + w->pixel_width)
8171 *pix_x = w->pixel_left + w->pixel_width;
8172 if (*pix_y > w->pixel_top + w->pixel_height)
8173 *pix_y = w->pixel_top + w->pixel_height;
8175 *pix_x -= w->pixel_left;
8176 *pix_y -= w->pixel_top;
8179 /* Given a display line and a position, determine if there is a glyph
8180 there and return information about it if there is. */
8183 get_position_object (struct display_line *dl, Lisp_Object *obj1,
8184 Lisp_Object *obj2, int x_coord, int *low_x_coord,
8187 struct display_block *db;
8190 get_next_display_block (dl->bounds, dl->display_blocks, x_coord, 0);
8192 /* We use get_next_display_block to get the actual display block
8193 that would be displayed at x_coord. */
8195 if (block == NO_BLOCK)
8198 db = Dynarr_atp (dl->display_blocks, block);
8200 for (elt = 0; elt < Dynarr_length (db->runes); elt++)
8202 struct rune *rb = Dynarr_atp (db->runes, elt);
8204 if (rb->xpos <= x_coord && x_coord < (rb->xpos + rb->width))
8206 if (rb->type == RUNE_DGLYPH)
8208 *obj1 = rb->object.dglyph.glyph;
8209 *obj2 = rb->object.dglyph.extent;
8218 *low_x_coord = rb->xpos;
8220 *high_x_coord = rb->xpos + rb->width;
8227 #define UPDATE_CACHE_RETURN \
8229 d->pixel_to_glyph_cache.valid = 1; \
8230 d->pixel_to_glyph_cache.low_x_coord = low_x_coord; \
8231 d->pixel_to_glyph_cache.high_x_coord = high_x_coord; \
8232 d->pixel_to_glyph_cache.low_y_coord = low_y_coord; \
8233 d->pixel_to_glyph_cache.high_y_coord = high_y_coord; \
8234 d->pixel_to_glyph_cache.frame = f; \
8235 d->pixel_to_glyph_cache.col = *col; \
8236 d->pixel_to_glyph_cache.row = *row; \
8237 d->pixel_to_glyph_cache.obj_x = *obj_x; \
8238 d->pixel_to_glyph_cache.obj_y = *obj_y; \
8239 d->pixel_to_glyph_cache.w = *w; \
8240 d->pixel_to_glyph_cache.bufpos = *bufpos; \
8241 d->pixel_to_glyph_cache.closest = *closest; \
8242 d->pixel_to_glyph_cache.modeline_closest = *modeline_closest; \
8243 d->pixel_to_glyph_cache.obj1 = *obj1; \
8244 d->pixel_to_glyph_cache.obj2 = *obj2; \
8245 d->pixel_to_glyph_cache.retval = position; \
8246 RETURN_SANS_WARNINGS position; \
8249 /* Given x and y coordinates in pixels relative to a frame, return
8250 information about what is located under those coordinates.
8252 The return value will be one of:
8254 OVER_TOOLBAR: over one of the 4 frame toolbars
8255 OVER_MODELINE: over a modeline
8256 OVER_BORDER: over an internal border
8257 OVER_NOTHING: over the text area, but not over text
8258 OVER_OUTSIDE: outside of the frame border
8259 OVER_TEXT: over text in the text area
8265 -- nil if the coordinates are not over a glyph or a toolbar button.
8269 -- an extent, if the coordinates are over a glyph in the text area
8272 If the coordinates are over a glyph, OBJ_X and OBJ_Y give the
8273 equivalent coordinates relative to the upper-left corner of the glyph.
8275 If the coordinates are over a character, OBJ_X and OBJ_Y give the
8276 equivalent coordinates relative to the upper-left corner of the character.
8278 Otherwise, OBJ_X and OBJ_Y are undefined.
8282 pixel_to_glyph_translation (struct frame *f, int x_coord, int y_coord,
8283 int *col, int *row, int *obj_x, int *obj_y,
8284 struct window **w, Bufpos *bufpos,
8285 Bufpos *closest, Charcount *modeline_closest,
8286 Lisp_Object *obj1, Lisp_Object *obj2)
8289 struct pixel_to_glyph_translation_cache *cache;
8291 int frm_left, frm_right, frm_top, frm_bottom;
8292 int low_x_coord, high_x_coord, low_y_coord, high_y_coord;
8293 int position = OVER_NOTHING;
8294 int device_check_failed = 0;
8295 display_line_dynarr *dla;
8297 /* This is a safety valve in case this got called with a frame in
8298 the middle of being deleted. */
8299 if (!DEVICEP (f->device) || !DEVICE_LIVE_P (XDEVICE (f->device)))
8301 device_check_failed = 1;
8302 d = NULL, cache = NULL; /* Warning suppression */
8306 d = XDEVICE (f->device);
8307 cache = &d->pixel_to_glyph_cache;
8310 if (!device_check_failed
8312 && cache->frame == f
8313 && cache->low_x_coord <= x_coord
8314 && cache->high_x_coord > x_coord
8315 && cache->low_y_coord <= y_coord
8316 && cache->high_y_coord > y_coord)
8320 *obj_x = cache->obj_x;
8321 *obj_y = cache->obj_y;
8323 *bufpos = cache->bufpos;
8324 *closest = cache->closest;
8325 *modeline_closest = cache->modeline_closest;
8326 *obj1 = cache->obj1;
8327 *obj2 = cache->obj2;
8329 return cache->retval;
8340 *modeline_closest = -1;
8344 low_x_coord = x_coord;
8345 high_x_coord = x_coord + 1;
8346 low_y_coord = y_coord;
8347 high_y_coord = y_coord + 1;
8350 if (device_check_failed)
8351 return OVER_NOTHING;
8353 frm_left = FRAME_LEFT_BORDER_END (f);
8354 frm_right = FRAME_RIGHT_BORDER_START (f);
8355 frm_top = FRAME_TOP_BORDER_END (f);
8356 frm_bottom = FRAME_BOTTOM_BORDER_START (f);
8358 /* Check if the mouse is outside of the text area actually used by
8360 if (y_coord < frm_top)
8362 if (y_coord >= FRAME_TOP_BORDER_START (f))
8364 low_y_coord = FRAME_TOP_BORDER_START (f);
8365 high_y_coord = frm_top;
8366 position = OVER_BORDER;
8368 else if (y_coord >= 0)
8371 high_y_coord = FRAME_TOP_BORDER_START (f);
8372 position = OVER_TOOLBAR;
8376 low_y_coord = y_coord;
8378 position = OVER_OUTSIDE;
8381 else if (y_coord >= frm_bottom)
8383 if (y_coord < FRAME_BOTTOM_BORDER_END (f))
8385 low_y_coord = frm_bottom;
8386 high_y_coord = FRAME_BOTTOM_BORDER_END (f);
8387 position = OVER_BORDER;
8389 else if (y_coord < FRAME_PIXHEIGHT (f))
8391 low_y_coord = FRAME_BOTTOM_BORDER_END (f);
8392 high_y_coord = FRAME_PIXHEIGHT (f);
8393 position = OVER_TOOLBAR;
8397 low_y_coord = FRAME_PIXHEIGHT (f);
8398 high_y_coord = y_coord;
8399 position = OVER_OUTSIDE;
8403 if (position != OVER_TOOLBAR && position != OVER_BORDER)
8405 if (x_coord < frm_left)
8407 if (x_coord >= FRAME_LEFT_BORDER_START (f))
8409 low_x_coord = FRAME_LEFT_BORDER_START (f);
8410 high_x_coord = frm_left;
8411 position = OVER_BORDER;
8413 else if (x_coord >= 0)
8416 high_x_coord = FRAME_LEFT_BORDER_START (f);
8417 position = OVER_TOOLBAR;
8421 low_x_coord = x_coord;
8423 position = OVER_OUTSIDE;
8426 else if (x_coord >= frm_right)
8428 if (x_coord < FRAME_RIGHT_BORDER_END (f))
8430 low_x_coord = frm_right;
8431 high_x_coord = FRAME_RIGHT_BORDER_END (f);
8432 position = OVER_BORDER;
8434 else if (x_coord < FRAME_PIXWIDTH (f))
8436 low_x_coord = FRAME_RIGHT_BORDER_END (f);
8437 high_x_coord = FRAME_PIXWIDTH (f);
8438 position = OVER_TOOLBAR;
8442 low_x_coord = FRAME_PIXWIDTH (f);
8443 high_x_coord = x_coord;
8444 position = OVER_OUTSIDE;
8449 #ifdef HAVE_TOOLBARS
8450 if (position == OVER_TOOLBAR)
8452 *obj1 = toolbar_button_at_pixpos (f, x_coord, y_coord);
8455 UPDATE_CACHE_RETURN;
8457 #endif /* HAVE_TOOLBARS */
8459 /* We still have to return the window the pointer is next to and its
8460 relative y position even if it is outside the x boundary. */
8461 if (x_coord < frm_left)
8463 else if (x_coord > frm_right)
8464 x_coord = frm_right;
8466 /* Same in reverse. */
8467 if (y_coord < frm_top)
8469 else if (y_coord > frm_bottom)
8470 y_coord = frm_bottom;
8472 /* Find what window the given coordinates are actually in. */
8473 window = f->root_window;
8474 *w = find_window_by_pixel_pos (x_coord, y_coord, window);
8476 /* If we didn't find a window, we're done. */
8479 UPDATE_CACHE_RETURN;
8481 else if (position != OVER_NOTHING)
8484 *modeline_closest = -1;
8486 if (high_y_coord <= frm_top || high_y_coord >= frm_bottom)
8489 UPDATE_CACHE_RETURN;
8493 /* Check if the window is a minibuffer but isn't active. */
8494 if (MINI_WINDOW_P (*w) && !minibuf_level)
8496 /* Must reset the window value since some callers will ignore
8497 the return value if it is set. */
8499 UPDATE_CACHE_RETURN;
8502 /* See if the point is over window vertical divider */
8503 if (window_needs_vertical_divider (*w))
8505 int div_x_high = WINDOW_RIGHT (*w);
8506 int div_x_low = div_x_high - window_divider_width (*w);
8507 int div_y_high = WINDOW_BOTTOM (*w);
8508 int div_y_low = WINDOW_TOP (*w);
8510 if (div_x_low < x_coord && x_coord <= div_x_high &&
8511 div_y_low < y_coord && y_coord <= div_y_high)
8513 low_x_coord = div_x_low;
8514 high_x_coord = div_x_high;
8515 low_y_coord = div_y_low;
8516 high_y_coord = div_y_high;
8517 position = OVER_V_DIVIDER;
8518 UPDATE_CACHE_RETURN;
8522 dla = window_display_lines (*w, CURRENT_DISP);
8524 for (*row = 0; *row < Dynarr_length (dla); (*row)++)
8526 int really_over_nothing = 0;
8527 struct display_line *dl = Dynarr_atp (dla, *row);
8529 if ((int) (dl->ypos - dl->ascent) <= y_coord
8530 && y_coord <= (int) (dl->ypos + dl->descent))
8532 int check_margin_glyphs = 0;
8533 struct display_block *db = get_display_block_from_line (dl, TEXT);
8534 struct rune *rb = 0;
8536 if (x_coord < dl->bounds.left_white
8537 || x_coord >= dl->bounds.right_white)
8538 check_margin_glyphs = 1;
8540 low_y_coord = dl->ypos - dl->ascent;
8541 high_y_coord = dl->ypos + dl->descent + 1;
8543 if (position == OVER_BORDER
8544 || position == OVER_OUTSIDE
8545 || check_margin_glyphs)
8547 int x_check, left_bound;
8549 if (check_margin_glyphs)
8552 left_bound = dl->bounds.left_white;
8556 x_check = high_x_coord;
8557 left_bound = frm_left;
8560 if (Dynarr_length (db->runes))
8562 if (x_check <= left_bound)
8565 *modeline_closest = Dynarr_atp (db->runes, 0)->bufpos;
8567 *closest = Dynarr_atp (db->runes, 0)->bufpos;
8573 Dynarr_atp (db->runes,
8574 Dynarr_length (db->runes) - 1)->bufpos;
8577 Dynarr_atp (db->runes,
8578 Dynarr_length (db->runes) - 1)->bufpos;
8582 *modeline_closest += dl->offset;
8584 *closest += dl->offset;
8588 /* #### What should be here. */
8590 *modeline_closest = 0;
8595 if (check_margin_glyphs)
8597 if (x_coord < dl->bounds.left_in
8598 || x_coord >= dl->bounds.right_in)
8600 /* If we are over the outside margins then we
8601 know the loop over the text block isn't going
8602 to accomplish anything. So we go ahead and
8603 set what information we can right here and
8606 *obj_y = y_coord - (dl->ypos - dl->ascent);
8607 get_position_object (dl, obj1, obj2, x_coord,
8608 &low_x_coord, &high_x_coord);
8610 UPDATE_CACHE_RETURN;
8614 UPDATE_CACHE_RETURN;
8617 for (*col = 0; *col <= Dynarr_length (db->runes); (*col)++)
8619 int past_end = (*col == Dynarr_length (db->runes));
8622 rb = Dynarr_atp (db->runes, *col);
8625 (rb->xpos <= x_coord && x_coord < rb->xpos + rb->width))
8630 rb = Dynarr_atp (db->runes, *col);
8633 *bufpos = rb->bufpos + dl->offset;
8634 low_x_coord = rb->xpos;
8635 high_x_coord = rb->xpos + rb->width;
8637 if (rb->type == RUNE_DGLYPH)
8641 /* Find the first character after the glyph. */
8642 while (elt < Dynarr_length (db->runes))
8644 if (Dynarr_atp (db->runes, elt)->type != RUNE_DGLYPH)
8648 (Dynarr_atp (db->runes, elt)->bufpos +
8652 (Dynarr_atp (db->runes, elt)->bufpos +
8660 /* In this case we failed to find a non-glyph
8661 character so we return the last position
8662 displayed on the line. */
8663 if (elt == Dynarr_length (db->runes))
8666 *modeline_closest = dl->end_bufpos + dl->offset;
8668 *closest = dl->end_bufpos + dl->offset;
8669 really_over_nothing = 1;
8675 *modeline_closest = rb->bufpos + dl->offset;
8677 *closest = rb->bufpos + dl->offset;
8682 *row = window_displayed_height (*w);
8684 if (position == OVER_NOTHING)
8685 position = OVER_MODELINE;
8687 if (rb->type == RUNE_DGLYPH)
8689 *obj1 = rb->object.dglyph.glyph;
8690 *obj2 = rb->object.dglyph.extent;
8692 else if (rb->type == RUNE_CHAR)
8703 UPDATE_CACHE_RETURN;
8706 || (rb->type == RUNE_CHAR
8707 && rb->object.chr.ch == '\n'))
8710 /* At this point we may have glyphs in the right
8712 if (check_margin_glyphs)
8713 get_position_object (dl, obj1, obj2, x_coord,
8714 &low_x_coord, &high_x_coord);
8715 UPDATE_CACHE_RETURN;
8720 if (rb->type == RUNE_DGLYPH)
8722 *obj1 = rb->object.dglyph.glyph;
8723 *obj2 = rb->object.dglyph.extent;
8725 else if (rb->type == RUNE_CHAR)
8736 *obj_x = x_coord - rb->xpos;
8737 *obj_y = y_coord - (dl->ypos - dl->ascent);
8739 /* At this point we may have glyphs in the left
8741 if (check_margin_glyphs)
8742 get_position_object (dl, obj1, obj2, x_coord, 0, 0);
8744 if (position == OVER_NOTHING && !really_over_nothing)
8745 position = OVER_TEXT;
8747 UPDATE_CACHE_RETURN;
8754 *row = Dynarr_length (dla) - 1;
8755 if (FRAME_WIN_P (f))
8757 int bot_elt = Dynarr_length (dla) - 1;
8761 struct display_line *dl = Dynarr_atp (dla, bot_elt);
8762 int adj_area = y_coord - (dl->ypos + dl->descent);
8766 XSETWINDOW (lwin, *w);
8767 default_face_height_and_width (lwin, 0, &defheight);
8769 *row += (adj_area / defheight);
8773 /* #### This should be checked out some more to determine what
8774 should really be going on. */
8775 if (!MARKERP ((*w)->start[CURRENT_DISP]))
8778 *closest = end_of_last_line_may_error (*w,
8779 marker_position ((*w)->start[CURRENT_DISP]));
8781 UPDATE_CACHE_RETURN;
8783 #undef UPDATE_CACHE_RETURN
8786 /***************************************************************************/
8788 /* Lisp functions */
8790 /***************************************************************************/
8792 DEFUN ("redisplay-echo-area", Fredisplay_echo_area, 0, 0, 0, /*
8793 Ensure that all minibuffers are correctly showing the echo area.
8797 Lisp_Object devcons, concons;
8799 DEVICE_LOOP_NO_BREAK (devcons, concons)
8801 struct device *d = XDEVICE (XCAR (devcons));
8802 Lisp_Object frmcons;
8804 DEVICE_FRAME_LOOP (frmcons, d)
8806 struct frame *f = XFRAME (XCAR (frmcons));
8808 if (FRAME_REPAINT_P (f) && FRAME_HAS_MINIBUF_P (f))
8810 Lisp_Object window = FRAME_MINIBUF_WINDOW (f);
8812 MAYBE_DEVMETH (d, frame_output_begin, (f));
8815 * If the frame size has changed, there may be random
8816 * chud on the screen left from previous messages
8817 * because redisplay_frame hasn't been called yet.
8818 * Clear the screen to get rid of the potential mess.
8820 if (f->echo_area_garbaged)
8822 MAYBE_DEVMETH (d, clear_frame, (f));
8823 f->echo_area_garbaged = 0;
8825 redisplay_window (window, 0);
8826 MAYBE_DEVMETH (d, frame_output_end, (f));
8828 call_redisplay_end_triggers (XWINDOW (window), 0);
8837 restore_disable_preemption_value (Lisp_Object value)
8839 disable_preemption = XINT (value);
8843 DEFUN ("redraw-frame", Fredraw_frame, 0, 2, 0, /*
8844 Clear frame FRAME and output again what is supposed to appear on it.
8845 FRAME defaults to the selected frame if omitted.
8846 Normally, redisplay is preempted as normal if input arrives. However,
8847 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8848 input and is guaranteed to proceed to completion.
8850 (frame, no_preempt))
8852 struct frame *f = decode_frame (frame);
8853 int count = specpdl_depth ();
8855 if (!NILP (no_preempt))
8857 record_unwind_protect (restore_disable_preemption_value,
8858 make_int (disable_preemption));
8859 disable_preemption++;
8863 redisplay_frame (f, 1);
8865 /* See the comment in Fredisplay_frame. */
8866 RESET_CHANGED_SET_FLAGS;
8868 return unbind_to (count, Qnil);
8871 DEFUN ("redisplay-frame", Fredisplay_frame, 0, 2, 0, /*
8872 Ensure that FRAME's contents are correctly displayed.
8873 This differs from `redraw-frame' in that it only redraws what needs to
8874 be updated, as opposed to unconditionally clearing and redrawing
8876 FRAME defaults to the selected frame if omitted.
8877 Normally, redisplay is preempted as normal if input arrives. However,
8878 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8879 input and is guaranteed to proceed to completion.
8881 (frame, no_preempt))
8883 struct frame *f = decode_frame (frame);
8884 int count = specpdl_depth ();
8886 if (!NILP (no_preempt))
8888 record_unwind_protect (restore_disable_preemption_value,
8889 make_int (disable_preemption));
8890 disable_preemption++;
8893 redisplay_frame (f, 1);
8895 /* If we don't reset the global redisplay flags here, subsequent
8896 changes to the display will not get registered by redisplay
8897 because it thinks it already has registered changes. If you
8898 really knew what you were doing you could confuse redisplay by
8899 calling Fredisplay_frame while updating another frame. We assume
8900 that if you know what you are doing you will not be that
8902 RESET_CHANGED_SET_FLAGS;
8904 return unbind_to (count, Qnil);
8907 DEFUN ("redraw-device", Fredraw_device, 0, 2, 0, /*
8908 Clear device DEVICE and output again what is supposed to appear on it.
8909 DEVICE defaults to the selected device if omitted.
8910 Normally, redisplay is preempted as normal if input arrives. However,
8911 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8912 input and is guaranteed to proceed to completion.
8914 (device, no_preempt))
8916 struct device *d = decode_device (device);
8917 Lisp_Object frmcons;
8918 int count = specpdl_depth ();
8920 if (!NILP (no_preempt))
8922 record_unwind_protect (restore_disable_preemption_value,
8923 make_int (disable_preemption));
8924 disable_preemption++;
8927 DEVICE_FRAME_LOOP (frmcons, d)
8929 XFRAME (XCAR (frmcons))->clear = 1;
8931 redisplay_device (d, 0);
8933 /* See the comment in Fredisplay_frame. */
8934 RESET_CHANGED_SET_FLAGS;
8936 return unbind_to (count, Qnil);
8939 DEFUN ("redisplay-device", Fredisplay_device, 0, 2, 0, /*
8940 Ensure that DEVICE's contents are correctly displayed.
8941 This differs from `redraw-device' in that it only redraws what needs to
8942 be updated, as opposed to unconditionally clearing and redrawing
8944 DEVICE defaults to the selected device if omitted.
8945 Normally, redisplay is preempted as normal if input arrives. However,
8946 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8947 input and is guaranteed to proceed to completion.
8949 (device, no_preempt))
8951 struct device *d = decode_device (device);
8952 int count = specpdl_depth ();
8954 if (!NILP (no_preempt))
8956 record_unwind_protect (restore_disable_preemption_value,
8957 make_int (disable_preemption));
8958 disable_preemption++;
8961 redisplay_device (d, 0);
8963 /* See the comment in Fredisplay_frame. */
8964 RESET_CHANGED_SET_FLAGS;
8966 return unbind_to (count, Qnil);
8969 /* Big lie. Big lie. This will force all modelines to be updated
8970 regardless if the all flag is set or not. It remains in existence
8971 solely for backwards compatibility. */
8972 DEFUN ("redraw-modeline", Fredraw_modeline, 0, 1, 0, /*
8973 Force the modeline of the current buffer to be redisplayed.
8974 With optional non-nil ALL, force redisplay of all modelines.
8978 MARK_MODELINE_CHANGED;
8982 DEFUN ("force-cursor-redisplay", Fforce_cursor_redisplay, 0, 1, 0, /*
8983 Force an immediate update of the cursor on FRAME.
8984 FRAME defaults to the selected frame if omitted.
8988 redisplay_redraw_cursor (decode_frame (frame), 1);
8993 /***************************************************************************/
8995 /* Lisp-variable change triggers */
8997 /***************************************************************************/
9000 margin_width_changed_in_frame (Lisp_Object specifier, struct frame *f,
9003 /* Nothing to be done? */
9007 redisplay_variable_changed (Lisp_Object sym, Lisp_Object *val,
9008 Lisp_Object in_object, int flags)
9010 /* #### clip_changed should really be renamed something like
9011 global_redisplay_change. */
9016 /* This is called if the built-in glyphs have their properties
9019 redisplay_glyph_changed (Lisp_Object glyph, Lisp_Object property,
9022 if (WINDOWP (locale))
9024 MARK_FRAME_GLYPHS_CHANGED (XFRAME (WINDOW_FRAME (XWINDOW (locale))));
9026 else if (FRAMEP (locale))
9028 MARK_FRAME_GLYPHS_CHANGED (XFRAME (locale));
9030 else if (DEVICEP (locale))
9032 Lisp_Object frmcons;
9033 DEVICE_FRAME_LOOP (frmcons, XDEVICE (locale))
9034 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9036 else if (CONSOLEP (locale))
9038 Lisp_Object frmcons, devcons;
9039 CONSOLE_FRAME_LOOP_NO_BREAK (frmcons, devcons, XCONSOLE (locale))
9040 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9042 else /* global or buffer */
9044 Lisp_Object frmcons, devcons, concons;
9045 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
9046 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9051 text_cursor_visible_p_changed (Lisp_Object specifier, struct window *w,
9054 if (XFRAME (w->frame)->init_finished)
9055 Fforce_cursor_redisplay (w->frame);
9058 #ifdef MEMORY_USAGE_STATS
9061 /***************************************************************************/
9063 /* memory usage computation */
9065 /***************************************************************************/
9068 compute_rune_dynarr_usage (rune_dynarr *dyn, struct overhead_stats *ovstats)
9070 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9074 compute_display_block_dynarr_usage (display_block_dynarr *dyn,
9075 struct overhead_stats *ovstats)
9082 total = Dynarr_memory_usage (dyn, ovstats);
9083 for (i = 0; i < Dynarr_largest (dyn); i++)
9084 total += compute_rune_dynarr_usage (Dynarr_at (dyn, i).runes, ovstats);
9090 compute_glyph_block_dynarr_usage (glyph_block_dynarr *dyn,
9091 struct overhead_stats *ovstats)
9093 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9097 compute_display_line_dynarr_usage (display_line_dynarr *dyn,
9098 struct overhead_stats *ovstats)
9105 total = Dynarr_memory_usage (dyn, ovstats);
9106 for (i = 0; i < Dynarr_largest (dyn); i++)
9108 struct display_line *dl = &Dynarr_at (dyn, i);
9109 total += compute_display_block_dynarr_usage(dl->display_blocks, ovstats);
9110 total += compute_glyph_block_dynarr_usage (dl->left_glyphs, ovstats);
9111 total += compute_glyph_block_dynarr_usage (dl->right_glyphs, ovstats);
9118 compute_line_start_cache_dynarr_usage (line_start_cache_dynarr *dyn,
9119 struct overhead_stats *ovstats)
9121 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9124 #endif /* MEMORY_USAGE_STATS */
9127 /***************************************************************************/
9129 /* initialization */
9131 /***************************************************************************/
9134 init_redisplay (void)
9136 disable_preemption = 0;
9137 preemption_count = 0;
9138 max_preempts = INIT_MAX_PREEMPTS;
9144 if (!cmotion_display_lines)
9145 cmotion_display_lines = Dynarr_new (display_line);
9146 if (!mode_spec_bufbyte_string)
9147 mode_spec_bufbyte_string = Dynarr_new (Bufbyte);
9148 if (!formatted_string_extent_dynarr)
9149 formatted_string_extent_dynarr = Dynarr_new (EXTENT);
9150 if (!formatted_string_extent_start_dynarr)
9151 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount);
9152 if (!formatted_string_extent_end_dynarr)
9153 formatted_string_extent_end_dynarr = Dynarr_new (Bytecount);
9154 if (!internal_cache)
9155 internal_cache = Dynarr_new (line_start_cache);
9158 /* window system is nil when in -batch mode */
9159 if (!initialized || noninteractive)
9162 /* If the user wants to use a window system, we shouldn't bother
9163 initializing the terminal. This is especially important when the
9164 terminal is so dumb that emacs gives up before and doesn't bother
9165 using the window system.
9167 If the DISPLAY environment variable is set, try to use X, and die
9168 with an error message if that doesn't work. */
9170 #ifdef HAVE_X_WINDOWS
9171 if (!strcmp (display_use, "x"))
9173 /* Some stuff checks this way early. */
9174 Vwindow_system = Qx;
9175 Vinitial_window_system = Qx;
9178 #endif /* HAVE_X_WINDOWS */
9180 #ifdef HAVE_MS_WINDOWS
9181 if (!strcmp (display_use, "mswindows"))
9183 /* Some stuff checks this way early. */
9184 Vwindow_system = Qmswindows;
9185 Vinitial_window_system = Qmswindows;
9188 #endif /* HAVE_MS_WINDOWS */
9191 /* If no window system has been specified, try to use the terminal. */
9194 stderr_out ("XEmacs: standard input is not a tty\n");
9198 /* Look at the TERM variable */
9199 if (!getenv ("TERM"))
9201 stderr_out ("Please set the environment variable TERM; see tset(1).\n");
9205 Vinitial_window_system = Qtty;
9207 #else /* not HAVE_TTY */
9208 /* No DISPLAY specified, and no TTY support. */
9209 stderr_out ("XEmacs: Cannot open display.\n\
9210 Please set the environmental variable DISPLAY to an appropriate value.\n");
9217 syms_of_redisplay (void)
9219 defsymbol (&Qcursor_in_echo_area, "cursor-in-echo-area");
9220 #ifndef INHIBIT_REDISPLAY_HOOKS
9221 defsymbol (&Qpre_redisplay_hook, "pre-redisplay-hook");
9222 defsymbol (&Qpost_redisplay_hook, "post-redisplay-hook");
9223 #endif /* INHIBIT_REDISPLAY_HOOKS */
9224 defsymbol (&Qdisplay_warning_buffer, "display-warning-buffer");
9225 defsymbol (&Qbar_cursor, "bar-cursor");
9226 defsymbol (&Qredisplay_end_trigger_functions,
9227 "redisplay-end-trigger-functions");
9228 defsymbol (&Qtop_bottom, "top-bottom");
9229 defsymbol (&Qbuffer_list_changed_hook, "buffer-list-changed-hook");
9231 DEFSUBR (Fredisplay_echo_area);
9232 DEFSUBR (Fredraw_frame);
9233 DEFSUBR (Fredisplay_frame);
9234 DEFSUBR (Fredraw_device);
9235 DEFSUBR (Fredisplay_device);
9236 DEFSUBR (Fredraw_modeline);
9237 DEFSUBR (Fforce_cursor_redisplay);
9241 vars_of_redisplay (void)
9245 staticpro (&last_arrow_position);
9246 staticpro (&last_arrow_string);
9247 last_arrow_position = Qnil;
9248 last_arrow_string = Qnil;
9251 /* #### Probably temporary */
9252 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /*
9253 \(Temporary) Setting this will impact the performance of the internal
9256 cache_adjustment = 2;
9258 DEFVAR_INT_MAGIC ("pixel-vertical-clip-threshold", &vertical_clip /*
9259 Minimum pixel height for clipped bottom display line.
9260 A clipped line shorter than this won't be displayed.
9262 redisplay_variable_changed);
9265 DEFVAR_INT_MAGIC ("pixel-horizontal-clip-threshold", &horizontal_clip /*
9266 Minimum visible area for clipped glyphs at right boundary.
9267 Clipped glyphs shorter than this won't be displayed.
9268 Only pixmap glyph instances are currently allowed to be clipped.
9270 redisplay_variable_changed);
9271 horizontal_clip = 5;
9273 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string /*
9274 String displayed by modeline-format's "%m" specification.
9276 Vglobal_mode_string = Qnil;
9278 DEFVAR_LISP_MAGIC ("overlay-arrow-position", &Voverlay_arrow_position /*
9279 Marker for where to display an arrow on top of the buffer text.
9280 This must be the beginning of a line in order to work.
9281 See also `overlay-arrow-string'.
9283 redisplay_variable_changed);
9284 Voverlay_arrow_position = Qnil;
9286 DEFVAR_LISP_MAGIC ("overlay-arrow-string", &Voverlay_arrow_string /*
9287 String or glyph to display as an arrow. See also `overlay-arrow-position'.
9288 \(Note that despite the name of this variable, it can be set to a glyph as
9291 redisplay_variable_changed);
9292 Voverlay_arrow_string = Qnil;
9294 DEFVAR_INT ("scroll-step", &scroll_step /*
9295 *The number of lines to try scrolling a window by when point moves out.
9296 If that fails to bring point back on frame, point is centered instead.
9297 If this is zero, point is always centered after it moves off screen.
9301 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively /*
9302 *Scroll up to this many lines, to bring point back on screen.
9304 scroll_conservatively = 0;
9306 DEFVAR_BOOL_MAGIC ("truncate-partial-width-windows",
9307 &truncate_partial_width_windows /*
9308 *Non-nil means truncate lines in all windows less than full frame wide.
9310 redisplay_variable_changed);
9311 truncate_partial_width_windows = 1;
9313 DEFVAR_LISP ("visible-bell", &Vvisible_bell /*
9314 *Non-nil substitutes a visual signal for the audible bell.
9316 Default behavior is to flash the whole screen. On some platforms,
9317 special effects are available using the following values:
9319 'display Flash the whole screen (ie, the default behavior).
9320 'top-bottom Flash only the top and bottom lines of the selected frame.
9322 When effects are unavailable on a platform, the visual bell is the
9323 default, whole screen. (Currently only X supports any special effects.)
9325 Vvisible_bell = Qnil;
9327 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter /*
9328 *Non-nil means no need to redraw entire frame after suspending.
9329 A non-nil value is useful if the terminal can automatically preserve
9330 Emacs's frame display when you reenter Emacs.
9331 It is up to you to set this variable if your terminal can do that.
9333 no_redraw_on_reenter = 0;
9335 DEFVAR_LISP ("window-system", &Vwindow_system /*
9336 A symbol naming the window-system under which Emacs is running,
9337 such as `x', or nil if emacs is running on an ordinary terminal.
9339 Do not use this variable, except for GNU Emacs compatibility, as it
9340 gives wrong values in a multi-device environment. Use `console-type'
9343 Vwindow_system = Qnil;
9345 /* #### Temporary shit until window-system is eliminated. */
9346 DEFVAR_CONST_LISP ("initial-window-system", &Vinitial_window_system /*
9349 Vinitial_window_system = Qnil;
9351 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area /*
9352 Non-nil means put cursor in minibuffer, at end of any message there.
9354 cursor_in_echo_area = 0;
9356 /* #### Shouldn't this be generalized as follows:
9358 if nil, use block cursor.
9359 if a number, use a bar cursor of that width.
9360 Otherwise, use a 1-pixel bar cursor.
9362 #### Or better yet, this variable should be trashed entirely
9363 (use a Lisp-magic variable to maintain compatibility)
9364 and a specifier `cursor-shape' added, which allows a block
9365 cursor, a bar cursor, a flashing block or bar cursor,
9366 maybe a caret cursor, etc. */
9368 DEFVAR_LISP ("bar-cursor", &Vbar_cursor /*
9369 Use vertical bar cursor if non-nil. If t width is 1 pixel, otherwise 2.
9373 #ifndef INHIBIT_REDISPLAY_HOOKS
9374 xxDEFVAR_LISP ("pre-redisplay-hook", &Vpre_redisplay_hook /*
9375 Function or functions to run before every redisplay.
9377 Vpre_redisplay_hook = Qnil;
9379 xxDEFVAR_LISP ("post-redisplay-hook", &Vpost_redisplay_hook /*
9380 Function or functions to run after every redisplay.
9382 Vpost_redisplay_hook = Qnil;
9383 #endif /* INHIBIT_REDISPLAY_HOOKS */
9385 DEFVAR_LISP ("buffer-list-changed-hook", &Vbuffer_list_changed_hook /*
9386 Function or functions to call when a frame's buffer list has changed.
9387 This is called during redisplay, before redisplaying each frame.
9388 Functions on this hook are called with one argument, the frame.
9390 Vbuffer_list_changed_hook = Qnil;
9392 DEFVAR_INT ("display-warning-tick", &display_warning_tick /*
9393 Bump this to tell the C code to call `display-warning-buffer'
9394 at next redisplay. You should not normally change this; the function
9395 `display-warning' automatically does this at appropriate times.
9397 display_warning_tick = 0;
9399 DEFVAR_BOOL ("inhibit-warning-display", &inhibit_warning_display /*
9400 Non-nil means inhibit display of warning messages.
9401 You should *bind* this, not set it. Any pending warning messages
9402 will be displayed when the binding no longer applies.
9404 /* reset to 0 by startup.el after the splash screen has displayed.
9405 This way, the warnings don't obliterate the splash screen. */
9406 inhibit_warning_display = 1;
9408 DEFVAR_LISP ("window-size-change-functions",
9409 &Vwindow_size_change_functions /*
9410 Not currently implemented.
9411 Functions called before redisplay, if window sizes have changed.
9412 The value should be a list of functions that take one argument.
9413 Just before redisplay, for each frame, if any of its windows have changed
9414 size since the last redisplay, or have been split or deleted,
9415 all the functions in the list are called, with the frame as argument.
9417 Vwindow_size_change_functions = Qnil;
9419 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions /*
9420 Not currently implemented.
9421 Functions to call before redisplaying a window with scrolling.
9422 Each function is called with two arguments, the window
9423 and its new display-start position. Note that the value of `window-end'
9424 is not valid when these functions are called.
9426 Vwindow_scroll_functions = Qnil;
9428 DEFVAR_LISP ("redisplay-end-trigger-functions",
9429 &Vredisplay_end_trigger_functions /*
9430 See `set-window-redisplay-end-trigger'.
9432 Vredisplay_end_trigger_functions = Qnil;
9434 DEFVAR_BOOL ("column-number-start-at-one", &column_number_start_at_one /*
9435 *Non-nil means column display number starts at 1.
9437 column_number_start_at_one = 0;
9441 specifier_vars_of_redisplay (void)
9443 DEFVAR_SPECIFIER ("left-margin-width", &Vleft_margin_width /*
9444 *Width of left margin.
9445 This is a specifier; use `set-specifier' to change it.
9447 Vleft_margin_width = Fmake_specifier (Qnatnum);
9448 set_specifier_fallback (Vleft_margin_width, list1 (Fcons (Qnil, Qzero)));
9449 set_specifier_caching (Vleft_margin_width,
9450 offsetof (struct window, left_margin_width),
9451 some_window_value_changed,
9452 offsetof (struct frame, left_margin_width),
9453 margin_width_changed_in_frame, 0);
9455 DEFVAR_SPECIFIER ("right-margin-width", &Vright_margin_width /*
9456 *Width of right margin.
9457 This is a specifier; use `set-specifier' to change it.
9459 Vright_margin_width = Fmake_specifier (Qnatnum);
9460 set_specifier_fallback (Vright_margin_width, list1 (Fcons (Qnil, Qzero)));
9461 set_specifier_caching (Vright_margin_width,
9462 offsetof (struct window, right_margin_width),
9463 some_window_value_changed,
9464 offsetof (struct frame, right_margin_width),
9465 margin_width_changed_in_frame, 0);
9467 DEFVAR_SPECIFIER ("minimum-line-ascent", &Vminimum_line_ascent /*
9468 *Minimum ascent height of lines.
9469 This is a specifier; use `set-specifier' to change it.
9471 Vminimum_line_ascent = Fmake_specifier (Qnatnum);
9472 set_specifier_fallback (Vminimum_line_ascent, list1 (Fcons (Qnil, Qzero)));
9473 set_specifier_caching (Vminimum_line_ascent,
9474 offsetof (struct window, minimum_line_ascent),
9475 some_window_value_changed,
9478 DEFVAR_SPECIFIER ("minimum-line-descent", &Vminimum_line_descent /*
9479 *Minimum descent height of lines.
9480 This is a specifier; use `set-specifier' to change it.
9482 Vminimum_line_descent = Fmake_specifier (Qnatnum);
9483 set_specifier_fallback (Vminimum_line_descent, list1 (Fcons (Qnil, Qzero)));
9484 set_specifier_caching (Vminimum_line_descent,
9485 offsetof (struct window, minimum_line_descent),
9486 some_window_value_changed,
9489 DEFVAR_SPECIFIER ("use-left-overflow", &Vuse_left_overflow /*
9490 *Non-nil means use the left outside margin as extra whitespace when
9491 displaying 'whitespace or 'inside-margin glyphs.
9492 This is a specifier; use `set-specifier' to change it.
9494 Vuse_left_overflow = Fmake_specifier (Qboolean);
9495 set_specifier_fallback (Vuse_left_overflow, list1 (Fcons (Qnil, Qnil)));
9496 set_specifier_caching (Vuse_left_overflow,
9497 offsetof (struct window, use_left_overflow),
9498 some_window_value_changed,
9501 DEFVAR_SPECIFIER ("use-right-overflow", &Vuse_right_overflow /*
9502 *Non-nil means use the right outside margin as extra whitespace when
9503 displaying 'whitespace or 'inside-margin glyphs.
9504 This is a specifier; use `set-specifier' to change it.
9506 Vuse_right_overflow = Fmake_specifier (Qboolean);
9507 set_specifier_fallback (Vuse_right_overflow, list1 (Fcons (Qnil, Qnil)));
9508 set_specifier_caching (Vuse_right_overflow,
9509 offsetof (struct window, use_right_overflow),
9510 some_window_value_changed,
9513 DEFVAR_SPECIFIER ("text-cursor-visible-p", &Vtext_cursor_visible_p /*
9514 *Non-nil means the text cursor is visible (this is usually the case).
9515 This is a specifier; use `set-specifier' to change it.
9517 Vtext_cursor_visible_p = Fmake_specifier (Qboolean);
9518 set_specifier_fallback (Vtext_cursor_visible_p, list1 (Fcons (Qnil, Qt)));
9519 set_specifier_caching (Vtext_cursor_visible_p,
9520 offsetof (struct window, text_cursor_visible_p),
9521 text_cursor_visible_p_changed,