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 Fixnum 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. */
318 Fixnum vertical_clip;
320 /* Minimum visible pixel width of clipped glyphs at right margin. */
321 Fixnum horizontal_clip;
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 Fixnum 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 Fixnum last_display_warning_tick;
455 static Fixnum display_warning_tick;
456 Lisp_Object Qdisplay_warning_buffer;
457 int inhibit_warning_display;
459 Lisp_Object Vleft_margin_width, Vright_margin_width;
460 Lisp_Object Vminimum_line_ascent, Vminimum_line_descent;
461 Lisp_Object Vuse_left_overflow, Vuse_right_overflow;
462 Lisp_Object Vtext_cursor_visible_p;
464 int column_number_start_at_one;
466 Lisp_Object Qtop_bottom;
468 #define WINDOW_SCROLLED(w) ((w)->hscroll > 0 || (w)->left_xoffset)
471 /***************************************************************************/
473 /* low-level interfaces onto device routines */
475 /***************************************************************************/
478 redisplay_text_width_emchar_string (struct window *w, int findex,
479 Emchar *str, Charcount len)
481 unsigned char charsets[NUM_LEADING_BYTES];
484 find_charsets_in_emchar_string (charsets, str, len);
485 XSETWINDOW (window, w);
486 ensure_face_cachel_complete (WINDOW_FACE_CACHEL (w, findex), window,
488 return DEVMETH (XDEVICE (FRAME_DEVICE (XFRAME (WINDOW_FRAME (w)))),
489 text_width, (XFRAME (WINDOW_FRAME (w)),
490 WINDOW_FACE_CACHEL (w, findex), str, len));
493 static Emchar_dynarr *rtw_emchar_dynarr;
496 redisplay_text_width_string (struct window *w, int findex,
497 Bufbyte *nonreloc, Lisp_Object reloc,
498 Bytecount offset, Bytecount len)
500 if (!rtw_emchar_dynarr)
501 rtw_emchar_dynarr = Dynarr_new (Emchar);
502 Dynarr_reset (rtw_emchar_dynarr);
504 fixup_internal_substring (nonreloc, reloc, offset, &len);
506 nonreloc = XSTRING_DATA (reloc);
507 convert_bufbyte_string_into_emchar_dynarr (nonreloc, len, rtw_emchar_dynarr);
508 return redisplay_text_width_emchar_string
509 (w, findex, Dynarr_atp (rtw_emchar_dynarr, 0),
510 Dynarr_length (rtw_emchar_dynarr));
514 redisplay_frame_text_width_string (struct frame *f, Lisp_Object face,
515 Bufbyte *nonreloc, Lisp_Object reloc,
516 Bytecount offset, Bytecount len)
518 unsigned char charsets[NUM_LEADING_BYTES];
520 struct face_cachel cachel;
522 if (!rtw_emchar_dynarr)
523 rtw_emchar_dynarr = Dynarr_new (Emchar);
524 Dynarr_reset (rtw_emchar_dynarr);
526 fixup_internal_substring (nonreloc, reloc, offset, &len);
528 nonreloc = XSTRING_DATA (reloc);
529 convert_bufbyte_string_into_emchar_dynarr (nonreloc, len, rtw_emchar_dynarr);
530 find_charsets_in_bufbyte_string (charsets, nonreloc, len);
531 reset_face_cachel (&cachel);
533 XSETFRAME (frame, f);
534 ensure_face_cachel_complete (&cachel, frame, charsets);
535 return DEVMETH (XDEVICE (FRAME_DEVICE (f)),
536 text_width, (f, &cachel, Dynarr_atp (rtw_emchar_dynarr, 0),
537 Dynarr_length (rtw_emchar_dynarr)));
540 /* Return the display block from DL of the given TYPE. A display line
541 can have only one display block of each possible type. If DL does
542 not have a block of type TYPE, one will be created and added to DL. */
544 struct display_block *
545 get_display_block_from_line (struct display_line *dl, enum display_type type)
548 struct display_block db;
550 /* Check if this display line already has a block of the desired type and
552 if (dl->display_blocks)
554 for (elt = 0; elt < Dynarr_length (dl->display_blocks); elt++)
556 if (Dynarr_at (dl->display_blocks, elt).type == type)
557 return Dynarr_atp (dl->display_blocks, elt);
560 /* There isn't an active block of the desired type, but there
561 might still be allocated blocks we need to reuse. */
562 if (elt < Dynarr_largest (dl->display_blocks))
564 struct display_block *dbp = Dynarr_atp (dl->display_blocks, elt);
566 /* 'add' the block to the list */
567 Dynarr_increment (dl->display_blocks);
569 /* initialize and return */
576 /* This line doesn't have any display blocks, so initialize the display
578 dl->display_blocks = Dynarr_new (display_block);
581 /* The line doesn't have a block of the desired type so go ahead and create
582 one and add it to the line. */
585 db.runes = Dynarr_new (rune);
586 Dynarr_add (dl->display_blocks, db);
588 /* Return the newly added display block. */
589 elt = Dynarr_length (dl->display_blocks) - 1;
591 return Dynarr_atp (dl->display_blocks, elt);
595 tab_char_width (struct window *w)
597 struct buffer *b = XBUFFER (w->buffer);
598 int char_tab_width = XINT (b->tab_width);
600 if (char_tab_width <= 0 || char_tab_width > 1000) char_tab_width = 8;
602 return char_tab_width;
606 space_width (struct window *w)
608 /* While tabs are traditional composed of spaces, for variable-width
609 fonts the space character tends to give too narrow a value. So
610 we use 'n' instead. Except that we don't. We use the default
611 character width for the default face. If this is actually
612 defined by the font then it is probably the best thing to
613 actually use. If it isn't, we have assumed it is 'n' and have
614 already calculated its width. Thus we can avoid a call to
615 XTextWidth on X frames by just querying the default width. */
616 return XFONT_INSTANCE
617 (WINDOW_FACE_CACHEL_FONT (w, DEFAULT_INDEX, Vcharset_ascii))->width;
621 tab_pix_width (struct window *w)
623 return space_width (w) * tab_char_width (w);
626 /* Given a pixel position in a window, return the pixel location of
627 the next tabstop. Tabs are calculated from the left window edge in
628 terms of spaces displayed in the default face. Formerly the space
629 width was determined using the currently active face. That method
630 leads to tabstops which do not line up. */
633 next_tab_position (struct window *w, int start_pixpos, int left_pixpos)
635 int n_pos = left_pixpos;
636 int pix_tab_width = tab_pix_width (w);
638 /* Adjust n_pos for any hscrolling which has happened. */
639 if (WINDOW_SCROLLED (w))
640 n_pos -= space_width (w) * (w->hscroll - 1) + w->left_xoffset;
642 while (n_pos <= start_pixpos)
643 n_pos += pix_tab_width;
648 /* For the given window, calculate the outside and margin boundaries for a
649 display line. The whitespace boundaries must be calculated by the text
653 calculate_display_line_boundaries (struct window *w, int modeline)
655 layout_bounds bounds;
657 /* Set the outermost boundaries which are the boundaries of the
658 window itself minus the gutters (and minus the scrollbars if this
659 is for the modeline). */
662 bounds.left_out = WINDOW_TEXT_LEFT (w);
663 bounds.right_out = WINDOW_TEXT_RIGHT (w);
667 bounds.left_out = WINDOW_MODELINE_LEFT (w);
668 bounds.right_out = WINDOW_MODELINE_RIGHT (w);
671 /* The inner boundaries mark where the glyph margins are located. */
672 bounds.left_in = bounds.left_out + window_left_margin_width (w);
673 bounds.right_in = bounds.right_out - window_right_margin_width (w);
675 /* We cannot fully calculate the whitespace boundaries as they
676 depend on the contents of the line being displayed. */
677 bounds.left_white = bounds.left_in;
678 bounds.right_white = bounds.right_in;
683 /* Given a display line and a starting position, ensure that the
684 contents of the display line accurately represent the visual
685 representation of the buffer contents starting from the given
686 position when displayed in the given window. The display line ends
687 when the contents of the line reach the right boundary of the given
691 generate_display_line (struct window *w, struct display_line *dl, int bounds,
692 Bufpos start_pos, prop_block_dynarr **prop,
697 struct buffer *b = XBUFFER (WINDOW_BUFFER (w));
699 /* If our caller hasn't already set the boundaries, then do so now. */
701 dl->bounds = calculate_display_line_boundaries (w, 0);
703 /* Reset what this line is using. */
704 if (dl->display_blocks)
705 Dynarr_reset (dl->display_blocks);
708 Dynarr_free (dl->left_glyphs);
711 if (dl->right_glyphs)
713 Dynarr_free (dl->right_glyphs);
714 dl->right_glyphs = 0;
717 /* We aren't generating a modeline at the moment. */
720 /* Create a display block for the text region of the line. */
722 /* #### urk urk urk!!! Chuck fix this shit! */
723 Bytind hacked_up_bytind =
724 create_text_block (w, dl, bufpos_to_bytind (b, start_pos),
726 if (hacked_up_bytind > BI_BUF_ZV (b))
727 ret_bufpos = BUF_ZV (b) + 1;
729 ret_bufpos = bytind_to_bufpos (b, hacked_up_bytind);
731 dl->bufpos = start_pos;
732 if (dl->end_bufpos < dl->bufpos)
733 dl->end_bufpos = dl->bufpos;
735 if (MARKERP (Voverlay_arrow_position)
736 && EQ (w->buffer, Fmarker_buffer (Voverlay_arrow_position))
737 && start_pos == marker_position (Voverlay_arrow_position)
738 && (STRINGP (Voverlay_arrow_string)
739 || GLYPHP (Voverlay_arrow_string)))
741 overlay_width = create_overlay_glyph_block (w, dl);
746 /* If there are left glyphs associated with any character in the
747 text block, then create a display block to handle them. */
748 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
749 create_left_glyph_block (w, dl, overlay_width);
751 /* If there are right glyphs associated with any character in the
752 text block, then create a display block to handle them. */
753 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
754 create_right_glyph_block (w, dl);
756 /* In the future additional types of display blocks may be generated
759 w->last_redisplay_pos = ret_bufpos;
764 /* Adds an hscroll glyph to a display block. If this is called, then
765 the block had better be empty.
767 Yes, there are multiple places where this function is called but
768 that is the way it has to be. Each calling function has to deal
769 with bi_start_col_enabled a little differently depending on the
770 object being worked with. */
772 static prop_block_dynarr *
773 add_hscroll_rune (pos_data *data)
775 struct glyph_block gb;
776 prop_block_dynarr *retval;
777 Bytind bi_old_cursor_bufpos = data->bi_cursor_bufpos;
778 unsigned int old_cursor_type = data->cursor_type;
779 Bytind bi_old_bufpos = data->bi_bufpos;
781 if (data->cursor_type == CURSOR_ON
782 && data->bi_cursor_bufpos >= data->bi_start_col_enabled
783 && data->bi_cursor_bufpos <= data->bi_bufpos)
785 data->bi_cursor_bufpos = data->bi_start_col_enabled;
789 data->cursor_type = NO_CURSOR;
792 data->bi_endpos = data->bi_bufpos;
793 data->bi_bufpos = data->bi_start_col_enabled;
796 gb.glyph = Vhscroll_glyph;
798 int oldpixpos = data->pixpos;
799 retval = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0,
800 GLYPH_CACHEL (XWINDOW (data->window),
801 HSCROLL_GLYPH_INDEX));
802 data->hscroll_glyph_width_adjust =
803 data->pixpos - oldpixpos - space_width (XWINDOW (data->window));
806 data->bi_cursor_bufpos = bi_old_cursor_bufpos;
807 data->cursor_type = old_cursor_type;
808 data->bi_bufpos = bi_old_bufpos;
810 data->bi_start_col_enabled = 0;
814 /* Adds a character rune to a display block. If there is not enough
815 room to fit the rune on the display block (as determined by the
816 MAX_PIXPOS) then it adds nothing and returns ADD_FAILED. */
818 static prop_block_dynarr *
819 add_emchar_rune (pos_data *data)
821 struct rune rb, *crb;
832 if (data->bi_start_col_enabled)
834 return add_hscroll_rune (data);
837 if (data->ch == '\n')
839 data->font_is_bogus = 0;
840 /* Cheesy end-of-line pseudo-character. */
841 width = data->blank_width;
845 Lisp_Object charset = CHAR_CHARSET (data->ch);
846 if (!EQ (charset, data->last_charset) ||
847 data->findex != data->last_findex)
849 /* OK, we need to do things the hard way. */
850 struct window *w = XWINDOW (data->window);
851 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, data->findex);
852 Lisp_Object font_instance =
853 ensure_face_cachel_contains_charset (cachel, data->window,
855 Lisp_Font_Instance *fi;
857 if (EQ (font_instance, Vthe_null_font_instance))
859 font_instance = FACE_CACHEL_FONT (cachel, Vcharset_ascii);
860 data->font_is_bogus = 1;
863 data->font_is_bogus = 0;
865 fi = XFONT_INSTANCE (font_instance);
866 if (!fi->proportional_p)
867 /* sweetness and light. */
868 data->last_char_width = fi->width;
870 data->last_char_width = -1;
871 data->new_ascent = max (data->new_ascent, (int) fi->ascent);
872 data->new_descent = max (data->new_descent, (int) fi->descent);
873 data->last_charset = charset;
874 data->last_findex = data->findex;
877 width = data->last_char_width;
880 /* bummer. Proportional fonts. */
881 width = redisplay_text_width_emchar_string (XWINDOW (data->window),
887 if (data->max_pixpos != -1 && (data->pixpos + width > data->max_pixpos))
892 if (Dynarr_length (data->db->runes) < Dynarr_largest (data->db->runes))
894 crb = Dynarr_atp (data->db->runes, Dynarr_length (data->db->runes));
903 crb->findex = data->findex;
904 crb->xpos = data->pixpos;
908 if (NILP (data->string))
910 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
914 bytecount_to_charcount (XSTRING_DATA (data->string), data->bi_bufpos);
916 else if (data->is_modeline)
917 crb->bufpos = data->modeline_charpos;
919 /* Text but not in buffer */
921 crb->type = RUNE_CHAR;
922 crb->object.chr.ch = data->font_is_bogus ? '~' : data->ch;
925 if (data->cursor_type == CURSOR_ON)
927 if (data->bi_bufpos == data->bi_cursor_bufpos)
929 crb->cursor_type = CURSOR_ON;
930 data->cursor_x = Dynarr_length (data->db->runes);
933 crb->cursor_type = CURSOR_OFF;
935 else if (data->cursor_type == NEXT_CURSOR)
937 crb->cursor_type = CURSOR_ON;
938 data->cursor_x = Dynarr_length (data->db->runes);
939 data->cursor_type = NO_CURSOR;
941 else if (data->cursor_type == IGNORE_CURSOR)
942 crb->cursor_type = IGNORE_CURSOR;
944 crb->cursor_type = CURSOR_OFF;
947 Dynarr_add (data->db->runes, *crb);
949 Dynarr_increment (data->db->runes);
951 data->pixpos += width;
956 /* Given a string C_STRING of length C_LENGTH, call add_emchar_rune
957 for each character in the string. Propagate any left-over data
958 unless NO_PROP is non-zero. */
960 static prop_block_dynarr *
961 add_bufbyte_string_runes (pos_data *data, Bufbyte *c_string,
962 Bytecount c_length, int no_prop)
964 Bufbyte *pos, *end = c_string + c_length;
965 prop_block_dynarr *prop;
967 /* #### This function is too simplistic. It needs to do the same
968 sort of character interpretation (display-table lookup,
969 ctl-arrow checking), etc. that create_text_block() does.
970 The functionality to do this in that routine needs to be
973 for (pos = c_string; pos < end;)
975 data->ch = charptr_emchar (pos);
977 prop = add_emchar_rune (data);
985 struct prop_block pb;
986 Bytecount len = end - pos;
987 prop = Dynarr_new (prop_block);
989 pb.type = PROP_STRING;
990 pb.data.p_string.str = xnew_array (Bufbyte, len);
991 strncpy ((char *) pb.data.p_string.str, (char *) pos, len);
992 pb.data.p_string.len = len;
994 Dynarr_add (prop, pb);
1005 /* Add a single rune of the specified width. The area covered by this
1006 rune will be displayed in the foreground color of the associated
1009 static prop_block_dynarr *
1010 add_blank_rune (pos_data *data, struct window *w, int char_tab_width)
1014 /* If data->start_col is not 0 then this call to add_blank_rune must have
1015 been to add it as a tab. */
1016 if (data->start_col)
1018 /* assert (w != NULL) */
1019 prop_block_dynarr *retval;
1021 /* If we have still not fully scrolled horizontally, subtract
1022 the width of this tab and return. */
1023 if (char_tab_width < data->start_col)
1025 data->start_col -= char_tab_width;
1028 else if (char_tab_width == data->start_col)
1029 data->blank_width = 0;
1032 int spcwid = space_width (w);
1034 if (spcwid >= data->blank_width)
1035 data->blank_width = 0;
1037 data->blank_width -= spcwid;
1040 data->start_col = 0;
1041 retval = add_hscroll_rune (data);
1043 /* Could be caused by the handling of the hscroll rune. */
1044 if (retval != NULL || !data->blank_width)
1048 /* Blank runes are always calculated to fit. */
1049 assert (data->pixpos + data->blank_width <= data->max_pixpos);
1051 rb.findex = data->findex;
1052 rb.xpos = data->pixpos;
1053 rb.width = data->blank_width;
1054 if (data->bi_bufpos)
1056 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
1059 /* #### and this is really correct too? */
1062 rb.type = RUNE_BLANK;
1064 if (data->cursor_type == CURSOR_ON)
1066 if (data->bi_bufpos == data->bi_cursor_bufpos)
1068 rb.cursor_type = CURSOR_ON;
1069 data->cursor_x = Dynarr_length (data->db->runes);
1072 rb.cursor_type = CURSOR_OFF;
1074 else if (data->cursor_type == NEXT_CURSOR)
1076 rb.cursor_type = CURSOR_ON;
1077 data->cursor_x = Dynarr_length (data->db->runes);
1078 data->cursor_type = NO_CURSOR;
1081 rb.cursor_type = CURSOR_OFF;
1083 Dynarr_add (data->db->runes, rb);
1084 data->pixpos += data->blank_width;
1089 /* Add runes representing a character in octal. */
1091 #define ADD_NEXT_OCTAL_RUNE_CHAR do \
1093 if (add_failed || (add_failed = add_emchar_rune (data))) \
1095 struct prop_block pb; \
1097 prop = Dynarr_new (prop_block); \
1099 pb.type = PROP_CHAR; \
1100 pb.data.p_char.ch = data->ch; \
1101 pb.data.p_char.cursor_type = data->cursor_type; \
1102 Dynarr_add (prop, pb); \
1106 static prop_block_dynarr *
1107 add_octal_runes (pos_data *data)
1109 prop_block_dynarr *prop, *add_failed;
1110 Emchar orig_char = data->ch;
1111 unsigned int orig_cursor_type = data->cursor_type;
1117 if (data->start_col)
1120 if (!data->start_col)
1122 if (data->bi_start_col_enabled)
1124 add_failed = add_hscroll_rune (data);
1128 struct glyph_block gb;
1129 struct window *w = XWINDOW (data->window);
1132 gb.glyph = Voctal_escape_glyph;
1134 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1135 GLYPH_CACHEL (w, OCT_ESC_GLYPH_INDEX));
1139 /* We only propagate information if the glyph was partially
1144 data->cursor_type = IGNORE_CURSOR;
1146 if (data->ch >= 0x100)
1148 /* If the character is an extended Mule character, it could have
1149 up to 19 bits. For the moment, we treat it as a seven-digit
1150 octal number. This is not that pretty, but whatever. */
1151 data->ch = (7 & (orig_char >> 18)) + '0';
1152 ADD_NEXT_OCTAL_RUNE_CHAR;
1154 data->ch = (7 & (orig_char >> 15)) + '0';
1155 ADD_NEXT_OCTAL_RUNE_CHAR;
1157 data->ch = (7 & (orig_char >> 12)) + '0';
1158 ADD_NEXT_OCTAL_RUNE_CHAR;
1160 data->ch = (7 & (orig_char >> 9)) + '0';
1161 ADD_NEXT_OCTAL_RUNE_CHAR;
1164 data->ch = (7 & (orig_char >> 6)) + '0';
1165 ADD_NEXT_OCTAL_RUNE_CHAR;
1167 data->ch = (7 & (orig_char >> 3)) + '0';
1168 ADD_NEXT_OCTAL_RUNE_CHAR;
1170 data->ch = (7 & orig_char) + '0';
1171 ADD_NEXT_OCTAL_RUNE_CHAR;
1173 data->cursor_type = orig_cursor_type;
1177 #undef ADD_NEXT_OCTAL_RUNE_CHAR
1179 /* Add runes representing a control character to a display block. */
1181 static prop_block_dynarr *
1182 add_control_char_runes (pos_data *data, struct buffer *b)
1184 if (!NILP (b->ctl_arrow))
1186 prop_block_dynarr *prop;
1187 Emchar orig_char = data->ch;
1188 unsigned int old_cursor_type = data->cursor_type;
1193 if (data->start_col)
1196 if (!data->start_col)
1198 if (data->bi_start_col_enabled)
1200 prop_block_dynarr *retval;
1202 retval = add_hscroll_rune (data);
1208 struct glyph_block gb;
1209 struct window *w = XWINDOW (data->window);
1212 gb.glyph = Vcontrol_arrow_glyph;
1214 /* We only propagate information if the glyph was partially
1216 if (add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1217 GLYPH_CACHEL (w, CONTROL_GLYPH_INDEX)))
1222 if (orig_char == 0177)
1225 data->ch = orig_char ^ 0100;
1226 data->cursor_type = IGNORE_CURSOR;
1228 if (add_emchar_rune (data))
1230 struct prop_block pb;
1232 prop = Dynarr_new (prop_block);
1234 pb.type = PROP_CHAR;
1235 pb.data.p_char.ch = data->ch;
1236 pb.data.p_char.cursor_type = data->cursor_type;
1237 Dynarr_add (prop, pb);
1240 data->cursor_type = old_cursor_type;
1245 return add_octal_runes (data);
1249 static prop_block_dynarr *
1250 add_disp_table_entry_runes_1 (pos_data *data, Lisp_Object entry)
1252 prop_block_dynarr *prop = NULL;
1254 if (STRINGP (entry))
1256 prop = add_bufbyte_string_runes (data,
1257 XSTRING_DATA (entry),
1258 XSTRING_LENGTH (entry),
1261 else if (GLYPHP (entry))
1263 if (data->start_col)
1266 if (!data->start_col && data->bi_start_col_enabled)
1268 prop = add_hscroll_rune (data);
1272 struct glyph_block gb;
1276 prop = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
1279 else if (CHAR_OR_CHAR_INTP (entry))
1281 data->ch = XCHAR_OR_CHAR_INT (entry);
1282 prop = add_emchar_rune (data);
1284 else if (CONSP (entry))
1286 if (EQ (XCAR (entry), Qformat)
1287 && CONSP (XCDR (entry))
1288 && STRINGP (XCAR (XCDR (entry))))
1290 Lisp_Object format = XCAR (XCDR (entry));
1291 Bytind len = XSTRING_LENGTH (format);
1292 Bufbyte *src = XSTRING_DATA (format), *end = src + len;
1293 Bufbyte *result = alloca_array (Bufbyte, len);
1294 Bufbyte *dst = result;
1298 Emchar c = charptr_emchar (src);
1300 if (c != '%' || src == end)
1301 dst += set_charptr_emchar (dst, c);
1304 c = charptr_emchar (src);
1309 dst += long_to_string_base ((char *)dst, data->ch, 16);
1312 dst += set_charptr_emchar (dst, '%');
1314 /* #### unimplemented */
1318 prop = add_bufbyte_string_runes (data, result, dst - result, 0);
1322 /* Else blow it off because someone added a bad entry and we don't
1323 have any safe way of signaling an error. */
1327 /* Given a display table entry, call the appropriate functions to
1328 display each element of the entry. */
1330 static prop_block_dynarr *
1331 add_disp_table_entry_runes (pos_data *data, Lisp_Object entry)
1333 prop_block_dynarr *prop = NULL;
1334 if (VECTORP (entry))
1336 Lisp_Vector *de = XVECTOR (entry);
1337 EMACS_INT len = vector_length (de);
1340 for (elt = 0; elt < len; elt++)
1342 if (NILP (vector_data (de)[elt]))
1345 prop = add_disp_table_entry_runes_1 (data, vector_data (de)[elt]);
1346 /* Else blow it off because someone added a bad entry and we
1347 don't have any safe way of signaling an error. Hey, this
1348 comment sounds familiar. */
1350 /* #### Still need to add any remaining elements to the
1351 propagation information. */
1357 prop = add_disp_table_entry_runes_1 (data, entry);
1361 /* Add runes which were propagated from the previous line. */
1363 static prop_block_dynarr *
1364 add_propagation_runes (prop_block_dynarr **prop, pos_data *data)
1366 /* #### Remember to handle start_col parameter of data when the rest of
1367 this is finished. */
1368 /* #### Chuck -- I've redone this function a bit. It looked like the
1369 case of not all the propagation blocks being added was not handled
1371 /* #### Chuck -- I also think the double indirection of PROP is kind
1372 of bogus. A cleaner solution is just to check for
1373 Dynarr_length (prop) > 0. */
1374 /* #### This function also doesn't even pay attention to ADD_FAILED!
1375 This is seriously fucked! Seven ####'s in 130 lines -- is that a
1378 prop_block_dynarr *add_failed;
1379 Bytind bi_old_cursor_bufpos = data->bi_cursor_bufpos;
1380 unsigned int old_cursor_type = data->cursor_type;
1382 for (elt = 0; elt < Dynarr_length (*prop); elt++)
1384 struct prop_block *pb = Dynarr_atp (*prop, elt);
1389 data->ch = pb->data.p_char.ch;
1390 data->bi_cursor_bufpos = pb->data.p_char.bi_cursor_bufpos;
1391 data->cursor_type = pb->data.p_char.cursor_type;
1392 add_failed = add_emchar_rune (data);
1395 goto oops_no_more_space;
1398 if (pb->data.p_string.str)
1399 xfree (pb->data.p_string.str);
1400 /* #### bogus bogus -- this doesn't do anything!
1401 Should probably call add_bufbyte_string_runes(),
1402 once that function is fixed. */
1404 case PROP_MINIBUF_PROMPT:
1406 face_index old_findex = data->findex;
1407 Bytind bi_old_bufpos = data->bi_bufpos;
1409 data->findex = DEFAULT_INDEX;
1410 data->bi_bufpos = 0;
1411 data->cursor_type = NO_CURSOR;
1413 while (pb->data.p_string.len > 0)
1415 data->ch = charptr_emchar (pb->data.p_string.str);
1416 add_failed = add_emchar_rune (data);
1420 data->findex = old_findex;
1421 data->bi_bufpos = bi_old_bufpos;
1422 goto oops_no_more_space;
1426 /* Complicated equivalent of ptr++, len-- */
1427 Bufbyte *oldpos = pb->data.p_string.str;
1428 INC_CHARPTR (pb->data.p_string.str);
1429 pb->data.p_string.len -= pb->data.p_string.str - oldpos;
1433 data->findex = old_findex;
1434 /* ##### FIXME FIXME FIXME -- Upon successful return from
1435 this function, data->bi_bufpos is automatically incremented.
1436 However, we don't want that to happen if we were adding
1437 the minibuffer prompt. */
1439 struct buffer *buf =
1440 XBUFFER (WINDOW_BUFFER (XWINDOW (data->window)));
1441 /* #### Chuck fix this shit or I'm gonna scream! */
1442 if (bi_old_bufpos > BI_BUF_BEGV (buf))
1443 data->bi_bufpos = prev_bytind (buf, bi_old_bufpos);
1445 /* #### is this correct? Does anyone know?
1446 Does anyone care? Is this a cheesy hack or what? */
1447 data->bi_bufpos = BI_BUF_BEGV (buf) - 1;
1453 /* #### I think it's unnecessary and misleading to preserve
1454 the blank_width, as it implies that the value carries
1455 over from one rune to the next, which is wrong. */
1456 int old_width = data->blank_width;
1457 face_index old_findex = data->findex;
1459 data->findex = pb->data.p_blank.findex;
1460 data->blank_width = pb->data.p_blank.width;
1461 data->bi_cursor_bufpos = 0;
1462 data->cursor_type = IGNORE_CURSOR;
1464 if (data->pixpos + data->blank_width > data->max_pixpos)
1465 data->blank_width = data->max_pixpos - data->pixpos;
1467 /* We pass a bogus value of char_tab_width. It shouldn't
1468 matter because unless something is really screwed up
1469 this call won't cause that arg to be used. */
1470 add_failed = add_blank_rune (data, XWINDOW (data->window), 0);
1472 /* This can happen in the case where we have a tab which
1473 is wider than the window. */
1474 if (data->blank_width != pb->data.p_blank.width)
1476 pb->data.p_blank.width -= data->blank_width;
1477 add_failed = ADD_FAILED;
1480 data->findex = old_findex;
1481 data->blank_width = old_width;
1484 goto oops_no_more_space;
1494 data->bi_cursor_bufpos = bi_old_cursor_bufpos;
1495 data->cursor_type = old_cursor_type;
1496 if (elt < Dynarr_length (*prop))
1498 Dynarr_delete_many (*prop, 0, elt);
1503 Dynarr_free (*prop);
1508 /* Add 'text layout glyphs at position POS_TYPE that are contained to
1509 the display block, but add all other types to the appropriate list
1510 of the display line. They will be added later by different
1513 static prop_block_dynarr *
1514 add_glyph_rune (pos_data *data, struct glyph_block *gb, int pos_type,
1515 int allow_cursor, struct glyph_cachel *cachel)
1517 struct window *w = XWINDOW (data->window);
1519 /* If window faces changed, and glyph instance is text, then
1520 glyph sizes might have changed too */
1521 invalidate_glyph_geometry_maybe (gb->glyph, w);
1523 /* This makes sure the glyph is in the cachels.
1525 #### We do this to make sure the glyph is in the glyph cachels,
1526 so that the dirty flag can be reset after redisplay has
1527 finished. We should do this some other way, maybe by iterating
1528 over the window cache of subwindows. */
1529 get_glyph_cachel_index (w, gb->glyph);
1531 /* A nil extent indicates a special glyph (ex. truncator). */
1532 if (NILP (gb->extent)
1533 || (pos_type == BEGIN_GLYPHS &&
1534 extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1535 || (pos_type == END_GLYPHS &&
1536 extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1537 || pos_type == LEFT_GLYPHS || pos_type == RIGHT_GLYPHS)
1542 int ascent, descent;
1543 Lisp_Object baseline;
1545 Lisp_Object instance;
1549 width = cachel->width;
1551 width = glyph_width (gb->glyph, data->window);
1556 if (data->start_col || data->start_col_xoffset)
1558 prop_block_dynarr *retval;
1559 int glyph_char_width = width / space_width (w);
1561 /* If we still have not fully scrolled horizontally after
1562 taking into account the width of the glyph, subtract its
1563 width and return. */
1564 if (glyph_char_width < data->start_col)
1566 data->start_col -= glyph_char_width;
1569 else if (glyph_char_width == data->start_col)
1573 xoffset = space_width (w) * data->start_col;
1576 /* #### Can this happen? */
1581 data->start_col = 0;
1582 retval = add_hscroll_rune (data);
1584 /* Could be caused by the handling of the hscroll rune. */
1585 if (retval != NULL || !width)
1591 if (data->pixpos + width > data->max_pixpos)
1593 /* If this is the first object we are attempting to add to
1594 the line then we ignore the horizontal_clip threshold.
1595 Otherwise we will loop until the bottom of the window
1596 continually failing to add this glyph because it is wider
1597 than the window. We could alternatively just completely
1598 ignore the glyph and proceed from there but I think that
1599 this is a better solution. */
1600 if (Dynarr_length (data->db->runes)
1601 && data->max_pixpos - data->pixpos < horizontal_clip)
1604 width = data->max_pixpos - data->pixpos;
1609 ascent = cachel->ascent;
1610 descent = cachel->descent;
1614 ascent = glyph_ascent (gb->glyph, data->window);
1615 descent = glyph_descent (gb->glyph, data->window);
1618 baseline = glyph_baseline (gb->glyph, data->window);
1620 if (glyph_contrib_p (gb->glyph, data->window))
1622 /* A pixmap that has not had a baseline explicitly set. Its
1623 contribution will be determined later. */
1624 if (NILP (baseline))
1626 int height = ascent + descent;
1627 data->max_pixmap_height = max (data->max_pixmap_height, height);
1630 /* A string so determine contribution normally. */
1631 else if (EQ (baseline, Qt))
1633 data->new_ascent = max (data->new_ascent, ascent);
1634 data->new_descent = max (data->new_descent, descent);
1637 /* A pixmap with an explicitly set baseline. We determine the
1638 contribution here. */
1639 else if (INTP (baseline))
1641 int height = ascent + descent;
1642 int pix_ascent, pix_descent;
1644 pix_ascent = height * XINT (baseline) / 100;
1645 pix_descent = height - pix_ascent;
1647 data->new_ascent = max (data->new_ascent, pix_ascent);
1648 data->new_descent = max (data->new_descent, pix_descent);
1651 /* Otherwise something is screwed up. */
1656 face = glyph_face (gb->glyph, data->window);
1658 findex = data->findex;
1660 findex = get_builtin_face_cache_index (w, face);
1662 instance = glyph_image_instance (gb->glyph, data->window,
1664 if (TEXT_IMAGE_INSTANCEP (instance))
1666 Lisp_Object string = XIMAGE_INSTANCE_TEXT_STRING (instance);
1667 face_index orig_findex = data->findex;
1668 Bytind orig_bufpos = data->bi_bufpos;
1669 Bytind orig_start_col_enabled = data->bi_start_col_enabled;
1671 data->findex = findex;
1672 data->bi_start_col_enabled = 0;
1674 data->bi_bufpos = 0;
1675 add_bufbyte_string_runes (data, XSTRING_DATA (string),
1676 XSTRING_LENGTH (string), 0);
1677 data->findex = orig_findex;
1678 data->bi_bufpos = orig_bufpos;
1679 data->bi_start_col_enabled = orig_start_col_enabled;
1684 rb.xpos = data->pixpos;
1686 rb.bufpos = 0; /* glyphs are never "at" anywhere */
1687 if (data->bi_endpos)
1688 /* #### is this necessary at all? */
1689 rb.endpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1693 rb.type = RUNE_DGLYPH;
1694 rb.object.dglyph.glyph = gb->glyph;
1695 rb.object.dglyph.extent = gb->extent;
1696 rb.object.dglyph.xoffset = xoffset;
1700 rb.bufpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1703 if (data->cursor_type == CURSOR_ON)
1705 if (data->bi_bufpos == data->bi_cursor_bufpos)
1707 rb.cursor_type = CURSOR_ON;
1708 data->cursor_x = Dynarr_length (data->db->runes);
1711 rb.cursor_type = CURSOR_OFF;
1713 else if (data->cursor_type == NEXT_CURSOR)
1715 rb.cursor_type = CURSOR_ON;
1716 data->cursor_x = Dynarr_length (data->db->runes);
1717 data->cursor_type = NO_CURSOR;
1719 else if (data->cursor_type == IGNORE_CURSOR)
1720 rb.cursor_type = IGNORE_CURSOR;
1721 else if (data->cursor_type == NO_CURSOR)
1722 rb.cursor_type = NO_CURSOR;
1724 rb.cursor_type = CURSOR_OFF;
1727 rb.cursor_type = CURSOR_OFF;
1729 Dynarr_add (data->db->runes, rb);
1730 data->pixpos += width;
1736 if (!NILP (glyph_face (gb->glyph, data->window)))
1738 get_builtin_face_cache_index (w, glyph_face (gb->glyph,
1741 gb->findex = data->findex;
1743 if (pos_type == BEGIN_GLYPHS)
1745 if (!data->dl->left_glyphs)
1746 data->dl->left_glyphs = Dynarr_new (glyph_block);
1747 Dynarr_add (data->dl->left_glyphs, *gb);
1750 else if (pos_type == END_GLYPHS)
1752 if (!data->dl->right_glyphs)
1753 data->dl->right_glyphs = Dynarr_new (glyph_block);
1754 Dynarr_add (data->dl->right_glyphs, *gb);
1758 abort (); /* there are no unknown types */
1761 return NULL; /* shut up compiler */
1764 /* Add all glyphs at position POS_TYPE that are contained in the given
1767 static prop_block_dynarr *
1768 add_glyph_runes (pos_data *data, int pos_type)
1770 /* #### This still needs to handle the start_col parameter. Duh, Chuck,
1771 why didn't you just modify add_glyph_rune in the first place? */
1773 glyph_block_dynarr *glyph_arr = (pos_type == BEGIN_GLYPHS
1774 ? data->ef->begin_glyphs
1775 : data->ef->end_glyphs);
1776 prop_block_dynarr *prop;
1778 for (elt = 0; elt < Dynarr_length (glyph_arr); elt++)
1780 prop = add_glyph_rune (data, Dynarr_atp (glyph_arr, elt), pos_type, 0,
1785 /* #### Add some propagation information. */
1790 Dynarr_reset (glyph_arr);
1795 /* Given a position for a buffer in a window, ensure that the given
1796 display line DL accurately represents the text on a line starting
1797 at the given position.
1799 NOTE NOTE NOTE NOTE: This function works with and returns Bytinds.
1800 You must do appropriate conversion. */
1803 create_text_block (struct window *w, struct display_line *dl,
1804 Bytind bi_start_pos, prop_block_dynarr **prop,
1807 struct frame *f = XFRAME (w->frame);
1808 struct buffer *b = XBUFFER (w->buffer);
1809 struct device *d = XDEVICE (f->device);
1813 /* Don't display anything in the minibuffer if this window is not on
1814 a selected frame. We consider all other windows to be active
1815 minibuffers as it simplifies the coding. */
1816 int active_minibuffer = (!MINI_WINDOW_P (w) ||
1817 (f == device_selected_frame (d)) ||
1818 is_surrogate_for_selected_frame (f));
1820 int truncate_win = window_truncation_on (w);
1821 int end_glyph_width;
1823 /* If the buffer's value of selective_display is an integer then
1824 only lines that start with less than selective_display columns of
1825 space will be displayed. If selective_display is t then all text
1826 after a ^M is invisible. */
1827 int selective = (INTP (b->selective_display)
1828 ? XINT (b->selective_display)
1829 : (!NILP (b->selective_display) ? -1 : 0));
1831 /* The variable ctl-arrow allows the user to specify what characters
1832 can actually be displayed and which octal should be used for.
1833 #### This variable should probably have some rethought done to
1836 #### It would also be really nice if you could specify that
1837 the characters come out in hex instead of in octal. Mule
1838 does that by adding a ctl-hexa variable similar to ctl-arrow,
1839 but that's bogus -- we need a more general solution. I
1840 think you need to extend the concept of display tables
1841 into a more general conversion mechanism. Ideally you
1842 could specify a Lisp function that converts characters,
1843 but this violates the Second Golden Rule and besides would
1844 make things way way way way slow.
1846 So instead, we extend the display-table concept, which was
1847 historically limited to 256-byte vectors, to one of the
1850 a) A 256-entry vector, for backward compatibility;
1851 b) char-table, mapping characters to values;
1852 c) range-table, mapping ranges of characters to values;
1853 d) a list of the above.
1855 The (d) option allows you to specify multiple display tables
1856 instead of just one. Each display table can specify conversions
1857 for some characters and leave others unchanged. The way the
1858 character gets displayed is determined by the first display table
1859 with a binding for that character. This way, you could call a
1860 function `enable-hex-display' that adds a hex display-table to
1861 the list of display tables for the current buffer.
1863 #### ...not yet implemented... Also, we extend the concept of
1864 "mapping" to include a printf-like spec. Thus you can make all
1865 extended characters show up as hex with a display table like
1868 #s(range-table data ((256 524288) (format "%x")))
1870 Since more than one display table is possible, you have
1871 great flexibility in mapping ranges of characters. */
1872 Emchar printable_min = (CHAR_OR_CHAR_INTP (b->ctl_arrow)
1873 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
1874 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
1877 Lisp_Object face_dt, window_dt;
1879 /* The text display block for this display line. */
1880 struct display_block *db = get_display_block_from_line (dl, TEXT);
1882 /* The first time through the main loop we need to force the glyph
1883 data to be updated. */
1886 /* Apparently the new extent_fragment_update returns an end position
1887 equal to the position passed in if there are no more runs to be
1889 int no_more_frags = 0;
1891 Lisp_Object synch_minibuffers_value =
1892 symbol_value_in_buffer (Qsynchronize_minibuffers, w->buffer);
1894 dl->used_prop_data = 0;
1896 dl->line_continuation = 0;
1899 data.ef = extent_fragment_new (w->buffer, f);
1901 /* These values are used by all of the rune addition routines. We add
1902 them to this structure for ease of passing. */
1904 XSETWINDOW (data.window, w);
1909 data.bi_bufpos = bi_start_pos;
1910 data.pixpos = dl->bounds.left_in;
1911 data.last_charset = Qunbound;
1912 data.last_findex = DEFAULT_INDEX;
1913 data.result_str = Qnil;
1915 /* Set the right boundary adjusting it to take into account any end
1916 glyph. Save the width of the end glyph for later use. */
1917 data.max_pixpos = dl->bounds.right_in;
1919 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
1921 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
1922 data.max_pixpos -= end_glyph_width;
1924 if (cursor_in_echo_area && MINI_WINDOW_P (w) && echo_area_active (f))
1926 data.bi_cursor_bufpos = BI_BUF_ZV (b);
1927 data.cursor_type = CURSOR_ON;
1929 else if (MINI_WINDOW_P (w) && !active_minibuffer)
1930 data.cursor_type = NO_CURSOR;
1931 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)) &&
1932 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
1933 d == XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d))))&&
1934 f == XFRAME(DEVICE_SELECTED_FRAME(d)))
1936 data.bi_cursor_bufpos = BI_BUF_PT (b);
1937 data.cursor_type = CURSOR_ON;
1939 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)))
1941 data.bi_cursor_bufpos = bi_marker_position (w->pointm[type]);
1942 data.cursor_type = CURSOR_ON;
1945 data.cursor_type = NO_CURSOR;
1948 data.start_col = w->hscroll;
1949 data.start_col_xoffset = w->left_xoffset;
1950 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
1951 data.hscroll_glyph_width_adjust = 0;
1953 /* We regenerate the line from the very beginning. */
1954 Dynarr_reset (db->runes);
1956 /* Why is this less than or equal and not just less than? If the
1957 starting position is already equal to the maximum we can't add
1958 anything else, right? Wrong. We might still have a newline to
1959 add. A newline can use the room allocated for an end glyph since
1960 if we add it we know we aren't going to be adding any end
1963 /* #### Chuck -- I think this condition should be while (1).
1964 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
1965 and the begin-glyph ends exactly at the end of the window, the
1966 end-glyph and text might not be displayed. while (1) ensures
1967 that the loop terminates only when either (a) there is
1968 propagation data or (b) the end-of-line or end-of-buffer is hit.
1970 #### Also I think you need to ensure that the operation
1971 "add begin glyphs; add end glyphs; add text" is atomic and
1972 can't get interrupted in the middle. If you run off the end
1973 of the line during that operation, then you keep accumulating
1974 propagation data until you're done. Otherwise, if the (e.g.)
1975 there's a begin glyph at a particular position and attempting
1976 to display that glyph results in window-end being hit and
1977 propagation data being generated, then the character at that
1978 position won't be displayed.
1980 #### See also the comment after the end of this loop, below.
1982 while (data.pixpos <= data.max_pixpos
1983 && (active_minibuffer || !NILP (synch_minibuffers_value)))
1985 /* #### This check probably should not be necessary. */
1986 if (data.bi_bufpos > BI_BUF_ZV (b))
1988 /* #### urk! More of this lossage! */
1993 /* If selective display was an integer and we aren't working on
1994 a continuation line then find the next line we are actually
1995 supposed to display. */
1997 && (data.bi_bufpos == BI_BUF_BEGV (b)
1998 || BUF_FETCH_CHAR (b, prev_bytind (b, data.bi_bufpos)) == '\n'))
2000 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2003 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2004 if (data.bi_bufpos >= BI_BUF_ZV (b))
2006 data.bi_bufpos = BI_BUF_ZV (b);
2012 /* Check for face changes. */
2013 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
2015 /* Now compute the face and begin/end-glyph information. */
2017 /* Remember that the extent-fragment routines deal in Bytind's. */
2018 extent_fragment_update (w, data.ef, data.bi_bufpos);
2020 get_display_tables (w, data.findex, &face_dt, &window_dt);
2022 if (data.bi_bufpos == data.ef->end)
2027 /* Determine what is next to be displayed. We first handle any
2028 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
2029 display then we determine what to do based on the character at the
2030 current buffer position. */
2032 /* If the current position is covered by an invisible extent, do
2033 nothing (except maybe add some ellipses).
2035 #### The behavior of begin and end-glyphs at the edge of an
2036 invisible extent should be investigated further. This is
2037 fairly low priority though. */
2038 if (data.ef->invisible)
2040 /* #### Chuck, perhaps you could look at this code? I don't
2041 really know what I'm doing. */
2044 Dynarr_free (*prop);
2048 /* The extent fragment code only sets this when we should
2049 really display the ellipses. It makes sure the ellipses
2050 don't get displayed more than once in a row. */
2051 if (data.ef->invisible_ellipses)
2053 struct glyph_block gb;
2055 data.ef->invisible_ellipses_already_displayed = 1;
2056 data.ef->invisible_ellipses = 0;
2058 gb.glyph = Vinvisible_text_glyph;
2059 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2060 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2061 /* Perhaps they shouldn't propagate if the very next thing
2062 is to display a newline (for compatibility with
2063 selective-display-ellipses)? Maybe that's too
2069 /* If point is in an invisible region we place it on the
2070 next visible character. */
2071 if (data.cursor_type == CURSOR_ON
2072 && data.bi_bufpos == data.bi_cursor_bufpos)
2074 data.cursor_type = NEXT_CURSOR;
2077 /* #### What if we we're dealing with a display table? */
2081 if (data.bi_bufpos == BI_BUF_ZV (b))
2084 INC_BYTIND (b, data.bi_bufpos);
2087 /* If there is propagation data, then it represents the current
2088 buffer position being displayed. Add them and advance the
2089 position counter. This might also add the minibuffer
2093 dl->used_prop_data = 1;
2094 *prop = add_propagation_runes (prop, &data);
2097 goto done; /* gee, a really narrow window */
2098 else if (data.bi_bufpos == BI_BUF_ZV (b))
2100 else if (data.bi_bufpos < BI_BUF_BEGV (b))
2101 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
2102 data.bi_bufpos = BI_BUF_BEGV (b);
2104 INC_BYTIND (b, data.bi_bufpos);
2107 /* If there are end glyphs, add them to the line. These are
2108 the end glyphs for the previous run of text. We add them
2109 here rather than doing them at the end of handling the
2110 previous run so that glyphs at the beginning and end of
2111 a line are handled correctly. */
2112 else if (Dynarr_length (data.ef->end_glyphs) > 0)
2114 *prop = add_glyph_runes (&data, END_GLYPHS);
2119 /* If there are begin glyphs, add them to the line. */
2120 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
2122 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
2127 /* If at end-of-buffer, we've already processed begin and
2128 end-glyphs at this point and there's no text to process,
2130 else if (data.bi_bufpos == BI_BUF_ZV (b))
2135 Lisp_Object entry = Qnil;
2136 /* Get the character at the current buffer position. */
2137 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2138 if (!NILP (face_dt) || !NILP (window_dt))
2139 entry = display_table_entry (data.ch, face_dt, window_dt);
2141 /* If there is a display table entry for it, hand it off to
2142 add_disp_table_entry_runes and let it worry about it. */
2143 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
2145 *prop = add_disp_table_entry_runes (&data, entry);
2151 /* Check if we have hit a newline character. If so, add a marker
2152 to the line and end this loop. */
2153 else if (data.ch == '\n')
2155 /* We aren't going to be adding an end glyph so give its
2156 space back in order to make sure that the cursor can
2158 data.max_pixpos += end_glyph_width;
2161 && (bi_spaces_at_point
2162 (b, next_bytind (b, data.bi_bufpos))
2165 if (!NILP (b->selective_display_ellipses))
2167 struct glyph_block gb;
2170 gb.glyph = Vinvisible_text_glyph;
2171 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2172 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2176 /* Cheesy, cheesy, cheesy. We mark the end of the
2177 line with a special "character rune" whose width
2178 is the EOL cursor width and whose character is
2179 the non-printing character '\n'. */
2180 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2181 *prop = add_emchar_rune (&data);
2184 /* We need to set data.bi_bufpos to the start of the
2185 next visible region in order to make this line
2186 appear to contain all of the invisible area.
2187 Otherwise, the line cache won't work
2189 INC_BYTIND (b, data.bi_bufpos);
2190 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2193 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2194 if (data.bi_bufpos >= BI_BUF_ZV (b))
2196 data.bi_bufpos = BI_BUF_ZV (b);
2200 if (BI_BUF_FETCH_CHAR
2201 (b, prev_bytind (b, data.bi_bufpos)) == '\n')
2202 DEC_BYTIND (b, data.bi_bufpos);
2206 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2207 *prop = add_emchar_rune (&data);
2213 /* If the current character is ^M, and selective display is
2214 enabled, then add the invisible-text-glyph if
2215 selective-display-ellipses is set. In any case, this
2217 else if (data.ch == (('M' & 037)) && selective == -1)
2219 Bytind bi_next_bufpos;
2221 /* Find the buffer position at the end of the line. */
2223 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2224 if (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_next_bufpos))
2226 DEC_BYTIND (b, bi_next_bufpos);
2228 /* If the cursor is somewhere in the elided text make
2229 sure that the cursor gets drawn appropriately. */
2230 if (data.cursor_type == CURSOR_ON
2231 && (data.bi_cursor_bufpos >= data.bi_bufpos &&
2232 data.bi_cursor_bufpos < bi_next_bufpos))
2234 data.cursor_type = NEXT_CURSOR;
2237 /* We won't be adding a truncation or continuation glyph
2238 so give up the room allocated for them. */
2239 data.max_pixpos += end_glyph_width;
2241 if (!NILP (b->selective_display_ellipses))
2243 /* We don't propagate anything from the invisible
2244 text glyph if it fails to fit. This is
2246 struct glyph_block gb;
2249 gb.glyph = Vinvisible_text_glyph;
2250 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 1,
2251 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2254 /* Set the buffer position to the end of the line. We
2255 need to do this before potentially adding a newline
2256 so that the cursor flag will get set correctly (if
2258 data.bi_bufpos = bi_next_bufpos;
2260 if (NILP (b->selective_display_ellipses)
2261 || data.bi_cursor_bufpos == bi_next_bufpos)
2263 /* We have to at least add a newline character so
2264 that the cursor shows up properly. */
2266 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2267 data.findex = DEFAULT_INDEX;
2269 data.start_col_xoffset = 0;
2270 data.bi_start_col_enabled = 0;
2272 add_emchar_rune (&data);
2275 /* This had better be a newline but doing it this way
2276 we'll see obvious incorrect results if it isn't. No
2277 need to abort here. */
2278 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2283 /* If the current character is considered to be printable, then
2285 else if (data.ch >= printable_min)
2287 *prop = add_emchar_rune (&data);
2292 /* If the current character is a tab, determine the next tab
2293 starting position and add a blank rune which extends from the
2294 current pixel position to that starting position. */
2295 else if (data.ch == '\t')
2297 int tab_start_pixpos = data.pixpos;
2302 if (data.start_col > 1)
2303 tab_start_pixpos -= (space_width (w) * (data.start_col - 1))
2304 + data.start_col_xoffset;
2307 next_tab_position (w, tab_start_pixpos,
2308 dl->bounds.left_in +
2309 data.hscroll_glyph_width_adjust);
2310 if (next_tab_start > data.max_pixpos)
2312 prop_width = next_tab_start - data.max_pixpos;
2313 next_tab_start = data.max_pixpos;
2315 data.blank_width = next_tab_start - data.pixpos;
2317 (next_tab_start - tab_start_pixpos) / space_width (w);
2319 *prop = add_blank_rune (&data, w, char_tab_width);
2321 /* add_blank_rune is only supposed to be called with
2322 sizes guaranteed to fit in the available space. */
2327 struct prop_block pb;
2328 *prop = Dynarr_new (prop_block);
2330 pb.type = PROP_BLANK;
2331 pb.data.p_blank.width = prop_width;
2332 pb.data.p_blank.findex = data.findex;
2333 Dynarr_add (*prop, pb);
2339 /* If character is a control character, pass it off to
2340 add_control_char_runes.
2342 The is_*() routines have undefined results on
2343 arguments outside of the range [-1, 255]. (This
2344 often bites people who carelessly use `char' instead
2345 of `unsigned char'.)
2347 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
2349 *prop = add_control_char_runes (&data, b);
2355 /* If the character is above the ASCII range and we have not
2356 already handled it, then print it as an octal number. */
2357 else if (data.ch >= 0200)
2359 *prop = add_octal_runes (&data);
2365 /* Assume the current character is considered to be printable,
2366 then just add it. */
2369 *prop = add_emchar_rune (&data);
2374 INC_BYTIND (b, data.bi_bufpos);
2380 /* Determine the starting point of the next line if we did not hit the
2381 end of the buffer. */
2382 if (data.bi_bufpos < BI_BUF_ZV (b)
2383 && (active_minibuffer || !NILP (synch_minibuffers_value)))
2385 /* #### This check is not correct. If the line terminated
2386 due to a begin-glyph or end-glyph hitting window-end, then
2387 data.ch will not point to the character at data.bi_bufpos. If
2388 you make the two changes mentioned at the top of this loop,
2389 you should be able to say '(if (*prop))'. That should also
2390 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
2393 /* The common case is that the line ended because we hit a newline.
2394 In that case, the next character is just the next buffer
2396 if (data.ch == '\n')
2398 /* If data.start_col_enabled is still true, then the window is
2399 scrolled far enough so that nothing on this line is visible.
2400 We need to stick a truncation glyph at the beginning of the
2401 line in that case unless the line is completely blank. */
2402 if (data.bi_start_col_enabled)
2404 if (data.cursor_type == CURSOR_ON)
2406 if (data.bi_cursor_bufpos >= bi_start_pos
2407 && data.bi_cursor_bufpos <= data.bi_bufpos)
2408 data.bi_cursor_bufpos = data.bi_bufpos;
2410 data.findex = DEFAULT_INDEX;
2412 data.bi_start_col_enabled = 0;
2414 if (data.bi_bufpos != bi_start_pos)
2416 struct glyph_block gb;
2419 gb.glyph = Vhscroll_glyph;
2420 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2421 GLYPH_CACHEL (w, HSCROLL_GLYPH_INDEX));
2425 /* This duplicates code down below to add a newline to
2426 the end of an otherwise empty line.*/
2428 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2430 add_emchar_rune (&data);
2434 INC_BYTIND (b, data.bi_bufpos);
2437 /* Otherwise we have a buffer line which cannot fit on one display
2441 struct glyph_block gb;
2442 struct glyph_cachel *cachel;
2444 /* If the line is to be truncated then we actually have to look
2445 for the next newline. We also add the end-of-line glyph which
2446 we know will fit because we adjusted the right border before
2447 we starting laying out the line. */
2448 data.max_pixpos += end_glyph_width;
2449 data.findex = DEFAULT_INDEX;
2456 /* Now find the start of the next line. */
2457 bi_pos = bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2459 /* If the cursor is past the truncation line then we
2460 make it appear on the truncation glyph. If we've hit
2461 the end of the buffer then we also make the cursor
2462 appear unless eob is immediately preceded by a
2463 newline. In that case the cursor should actually
2464 appear on the next line. */
2465 if (data.cursor_type == CURSOR_ON
2466 && data.bi_cursor_bufpos >= data.bi_bufpos
2467 && (data.bi_cursor_bufpos < bi_pos ||
2468 (bi_pos == BI_BUF_ZV (b)
2469 && (bi_pos == BI_BUF_BEGV (b)
2470 || (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_pos))
2472 data.bi_cursor_bufpos = bi_pos;
2474 data.cursor_type = NO_CURSOR;
2476 data.bi_bufpos = bi_pos;
2477 gb.glyph = Vtruncation_glyph;
2478 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
2482 /* The cursor can never be on the continuation glyph. */
2483 data.cursor_type = NO_CURSOR;
2485 /* data.bi_bufpos is already at the start of the next line. */
2487 dl->line_continuation = 1;
2488 gb.glyph = Vcontinuation_glyph;
2489 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
2492 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
2494 if (truncate_win && data.bi_bufpos == BI_BUF_ZV (b)
2495 && BI_BUF_FETCH_CHAR (b, prev_bytind (b, BI_BUF_ZV (b))) != '\n')
2496 /* #### Damn this losing shit. */
2500 else if ((active_minibuffer || !NILP (synch_minibuffers_value))
2501 && (!echo_area_active (f) || data.bi_bufpos == BI_BUF_ZV (b)))
2503 /* We need to add a marker to the end of the line since there is no
2504 newline character in order for the cursor to get drawn. We label
2505 it as a newline so that it gets handled correctly by the
2506 whitespace routines below. */
2509 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2510 data.findex = DEFAULT_INDEX;
2512 data.start_col_xoffset = 0;
2513 data.bi_start_col_enabled = 0;
2515 data.max_pixpos += data.blank_width;
2516 add_emchar_rune (&data);
2517 data.max_pixpos -= data.blank_width;
2519 /* #### urk! Chuck, this shit is bad news. Going around
2520 manipulating invalid positions is guaranteed to result in
2521 trouble sooner or later. */
2522 data.bi_bufpos = BI_BUF_ZV (b) + 1;
2525 /* Calculate left whitespace boundary. */
2529 /* Whitespace past a newline is considered right whitespace. */
2530 while (elt < Dynarr_length (db->runes))
2532 struct rune *rb = Dynarr_atp (db->runes, elt);
2534 if ((rb->type == RUNE_CHAR && rb->object.chr.ch == ' ')
2535 || rb->type == RUNE_BLANK)
2537 dl->bounds.left_white += rb->width;
2541 elt = Dynarr_length (db->runes);
2545 /* Calculate right whitespace boundary. */
2547 int elt = Dynarr_length (db->runes) - 1;
2550 while (!done && elt >= 0)
2552 struct rune *rb = Dynarr_atp (db->runes, elt);
2554 if (!(rb->type == RUNE_CHAR && rb->object.chr.ch < 0x100
2555 && isspace (rb->object.chr.ch))
2556 && !rb->type == RUNE_BLANK)
2558 dl->bounds.right_white = rb->xpos + rb->width;
2566 /* The line is blank so everything is considered to be right
2569 dl->bounds.right_white = dl->bounds.left_in;
2572 /* Set the display blocks bounds. */
2573 db->start_pos = dl->bounds.left_in;
2574 if (Dynarr_length (db->runes))
2576 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
2578 db->end_pos = rb->xpos + rb->width;
2581 db->end_pos = dl->bounds.right_white;
2583 /* update line height parameters */
2584 if (!data.new_ascent && !data.new_descent)
2586 /* We've got a blank line so initialize these values from the default
2588 default_face_font_info (data.window, &data.new_ascent,
2589 &data.new_descent, 0, 0, 0);
2592 if (data.max_pixmap_height)
2594 int height = data.new_ascent + data.new_descent;
2595 int pix_ascent, pix_descent;
2597 pix_descent = data.max_pixmap_height * data.new_descent / height;
2598 pix_ascent = data.max_pixmap_height - pix_descent;
2600 data.new_ascent = max (data.new_ascent, pix_ascent);
2601 data.new_descent = max (data.new_descent, pix_descent);
2604 dl->ascent = data.new_ascent;
2605 dl->descent = data.new_descent;
2608 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
2610 if (dl->ascent < ascent)
2611 dl->ascent = ascent;
2614 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
2616 if (dl->descent < descent)
2617 dl->descent = descent;
2620 dl->cursor_elt = data.cursor_x;
2621 /* #### lossage lossage lossage! Fix this shit! */
2622 if (data.bi_bufpos > BI_BUF_ZV (b))
2623 dl->end_bufpos = BUF_ZV (b);
2625 dl->end_bufpos = bytind_to_bufpos (b, data.bi_bufpos) - 1;
2627 data.dl->num_chars = column_at_point (b, dl->end_bufpos, 0);
2629 /* This doesn't correctly take into account tabs and control
2630 characters but if the window isn't being truncated then this
2631 value isn't going to end up being used anyhow. */
2632 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
2634 /* #### handle horizontally scrolled line with text none of which
2635 was actually laid out. */
2637 /* #### handle any remainder of overlay arrow */
2639 if (*prop == ADD_FAILED)
2642 if (truncate_win && *prop)
2644 Dynarr_free (*prop);
2648 extent_fragment_delete (data.ef);
2650 /* #### If we started at EOB, then make sure we return a value past
2651 it so that regenerate_window will exit properly. This is bogus.
2652 The main loop should get fixed so that it isn't necessary to call
2653 this function if we are already at EOB. */
2655 if (data.bi_bufpos == BI_BUF_ZV (b) && bi_start_pos == BI_BUF_ZV (b))
2656 return data.bi_bufpos + 1; /* Yuck! */
2658 return data.bi_bufpos;
2661 /* Display the overlay arrow at the beginning of the given line. */
2664 create_overlay_glyph_block (struct window *w, struct display_line *dl)
2666 struct frame *f = XFRAME (w->frame);
2667 struct device *d = XDEVICE (f->device);
2670 /* If Voverlay_arrow_string isn't valid then just fail silently. */
2671 if (!STRINGP (Voverlay_arrow_string) && !GLYPHP (Voverlay_arrow_string))
2677 XSETWINDOW (data.window, w);
2678 data.db = get_display_block_from_line (dl, OVERWRITE);
2680 data.pixpos = dl->bounds.left_in;
2681 data.max_pixpos = dl->bounds.right_in;
2682 data.cursor_type = NO_CURSOR;
2684 data.findex = DEFAULT_INDEX;
2685 data.last_charset = Qunbound;
2686 data.last_findex = DEFAULT_INDEX;
2687 data.result_str = Qnil;
2690 Dynarr_reset (data.db->runes);
2692 if (STRINGP (Voverlay_arrow_string))
2694 add_bufbyte_string_runes
2696 XSTRING_DATA (Voverlay_arrow_string),
2697 XSTRING_LENGTH (Voverlay_arrow_string),
2700 else if (GLYPHP (Voverlay_arrow_string))
2702 struct glyph_block gb;
2704 gb.glyph = Voverlay_arrow_string;
2706 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, 0);
2709 if (data.max_pixmap_height)
2711 int height = data.new_ascent + data.new_descent;
2712 int pix_ascent, pix_descent;
2714 pix_descent = data.max_pixmap_height * data.new_descent / height;
2715 pix_ascent = data.max_pixmap_height - pix_descent;
2717 data.new_ascent = max (data.new_ascent, pix_ascent);
2718 data.new_descent = max (data.new_descent, pix_descent);
2721 dl->ascent = data.new_ascent;
2722 dl->descent = data.new_descent;
2724 data.db->start_pos = dl->bounds.left_in;
2725 data.db->end_pos = data.pixpos;
2727 return data.pixpos - dl->bounds.left_in;
2730 /* Add a type of glyph to a margin display block. */
2733 add_margin_runes (struct display_line *dl, struct display_block *db, int start,
2734 int count, enum glyph_layout layout, int side, Lisp_Object window)
2736 glyph_block_dynarr *gbd = (side == LEFT_GLYPHS
2738 : dl->right_glyphs);
2741 struct window *w = XWINDOW (window);
2742 struct frame *f = XFRAME (w->frame);
2743 struct device *d = XDEVICE (f->device);
2748 data.window = window;
2751 data.pixpos = start;
2752 data.cursor_type = NO_CURSOR;
2754 data.last_charset = Qunbound;
2755 data.last_findex = DEFAULT_INDEX;
2756 data.result_str = Qnil;
2758 data.new_ascent = dl->ascent;
2759 data.new_descent = dl->descent;
2761 if ((layout == GL_WHITESPACE && side == LEFT_GLYPHS)
2762 || (layout == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS))
2765 elt = Dynarr_length (gbd) - 1;
2772 end = Dynarr_length (gbd);
2775 while (count && ((!reverse && elt < end) || (reverse && elt >= end)))
2777 struct glyph_block *gb = Dynarr_atp (gbd, elt);
2779 if (NILP (gb->extent))
2780 abort (); /* these should have been handled in add_glyph_rune */
2783 ((side == LEFT_GLYPHS &&
2784 extent_begin_glyph_layout (XEXTENT (gb->extent)) == layout)
2785 || (side == RIGHT_GLYPHS &&
2786 extent_end_glyph_layout (XEXTENT (gb->extent)) == layout)))
2788 data.findex = gb->findex;
2789 data.max_pixpos = data.pixpos + gb->width;
2790 add_glyph_rune (&data, gb, side, 0, NULL);
2795 (reverse ? elt-- : elt++);
2798 if (data.max_pixmap_height)
2800 int height = data.new_ascent + data.new_descent;
2801 int pix_ascent, pix_descent;
2803 pix_descent = data.max_pixmap_height * data.new_descent / height;
2804 pix_ascent = data.max_pixmap_height - pix_descent;
2805 data.new_ascent = max (data.new_ascent, pix_ascent);
2806 data.new_descent = max (data.new_descent, pix_descent);
2809 dl->ascent = data.new_ascent;
2810 dl->descent = data.new_descent;
2815 /* Add a blank to a margin display block. */
2818 add_margin_blank (struct display_line *dl, struct display_block *db,
2819 struct window *w, int xpos, int width, int side)
2823 rb.findex = (side == LEFT_GLYPHS
2824 ? get_builtin_face_cache_index (w, Vleft_margin_face)
2825 : get_builtin_face_cache_index (w, Vright_margin_face));
2830 rb.type = RUNE_BLANK;
2831 rb.cursor_type = CURSOR_OFF;
2833 Dynarr_add (db->runes, rb);
2836 /* Display glyphs in the left outside margin, left inside margin and
2837 left whitespace area. */
2840 create_left_glyph_block (struct window *w, struct display_line *dl,
2845 int use_overflow = (NILP (w->use_left_overflow) ? 0 : 1);
2847 int out_end, in_out_start, in_in_end, white_out_start, white_in_start;
2848 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
2849 int left_in_start = dl->bounds.left_in;
2850 int left_in_end = dl->bounds.left_in + overlay_width;
2852 struct display_block *odb, *idb;
2854 XSETWINDOW (window, w);
2856 /* We have to add the glyphs to the line in the order outside,
2857 inside, whitespace. However the precedence dictates that we
2858 determine how many will fit in the reverse order. */
2860 /* Determine how many whitespace glyphs we can display and where
2861 they should start. */
2862 white_in_start = dl->bounds.left_white;
2863 white_out_start = left_in_start;
2864 white_out_cnt = white_in_cnt = 0;
2867 while (elt < Dynarr_length (dl->left_glyphs))
2869 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2871 if (NILP (gb->extent))
2872 abort (); /* these should have been handled in add_glyph_rune */
2874 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
2878 width = glyph_width (gb->glyph, window);
2880 if (white_in_start - width >= left_in_end)
2883 white_in_start -= width;
2887 else if (use_overflow
2888 && (white_out_start - width > dl->bounds.left_out))
2891 white_out_start -= width;
2902 /* Determine how many inside margin glyphs we can display and where
2903 they should start. The inside margin glyphs get whatever space
2904 is left after the whitespace glyphs have been displayed. These
2905 are tricky to calculate since if we decide to use the overflow
2906 area we basically have to start over. So for these we build up a
2907 list of just the inside margin glyphs and manipulate it to
2908 determine the needed info. */
2910 glyph_block_dynarr *ib;
2911 int avail_in, avail_out;
2914 int used_in, used_out;
2917 used_in = used_out = 0;
2918 ib = Dynarr_new (glyph_block);
2919 while (elt < Dynarr_length (dl->left_glyphs))
2921 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2923 if (NILP (gb->extent))
2924 abort (); /* these should have been handled in add_glyph_rune */
2926 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
2929 gb->width = glyph_width (gb->glyph, window);
2930 used_in += gb->width;
2931 Dynarr_add (ib, *gb);
2941 avail_in = white_in_start - left_in_end;
2949 avail_out = white_out_start - dl->bounds.left_out;
2952 while (!done && marker < Dynarr_length (ib))
2954 int width = Dynarr_atp (ib, marker)->width;
2956 /* If everything now fits in the available inside margin
2957 space, we're done. */
2958 if (used_in <= avail_in)
2962 /* Otherwise see if we have room to move a glyph to the
2964 if (used_out + width <= avail_out)
2977 /* At this point we now know that everything from marker on goes in
2978 the inside margin and everything before it goes in the outside
2979 margin. The stuff going into the outside margin is guaranteed
2980 to fit, but we may have to trim some stuff from the inside. */
2982 in_in_end = left_in_end;
2983 in_out_start = white_out_start;
2984 in_out_cnt = in_in_cnt = 0;
2988 while (elt < Dynarr_length (dl->left_glyphs))
2990 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2992 if (NILP (gb->extent))
2993 abort (); /* these should have been handled in add_glyph_rune */
2995 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
2998 int width = glyph_width (gb->glyph, window);
3003 in_out_start -= width;
3008 else if (in_in_end + width < white_in_start)
3023 /* Determine how many outside margin glyphs we can display. They
3024 always start at the left outside margin and can only use the
3025 outside margin space. */
3026 out_end = dl->bounds.left_out;
3030 while (elt < Dynarr_length (dl->left_glyphs))
3032 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3034 if (NILP (gb->extent))
3035 abort (); /* these should have been handled in add_glyph_rune */
3037 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3040 int width = glyph_width (gb->glyph, window);
3042 if (out_end + width <= in_out_start)
3056 /* Now that we know where everything goes, we add the glyphs as
3057 runes to the appropriate display blocks. */
3058 if (out_cnt || in_out_cnt || white_out_cnt)
3060 odb = get_display_block_from_line (dl, LEFT_OUTSIDE_MARGIN);
3061 odb->start_pos = dl->bounds.left_out;
3062 /* #### We should stop adding a blank to account for the space
3063 between the end of the glyphs and the margin and instead set
3064 this accordingly. */
3065 odb->end_pos = dl->bounds.left_in;
3066 Dynarr_reset (odb->runes);
3071 if (in_in_cnt || white_in_cnt)
3073 idb = get_display_block_from_line (dl, LEFT_INSIDE_MARGIN);
3074 idb->start_pos = dl->bounds.left_in;
3075 /* #### See above comment for odb->end_pos */
3076 idb->end_pos = dl->bounds.left_white;
3077 Dynarr_reset (idb->runes);
3082 /* First add the outside margin glyphs. */
3084 end_xpos = add_margin_runes (dl, odb, dl->bounds.left_out, out_cnt,
3085 GL_OUTSIDE_MARGIN, LEFT_GLYPHS, window);
3087 end_xpos = dl->bounds.left_out;
3089 /* There may be blank space between the outside margin glyphs and
3090 the inside margin glyphs. If so, add a blank. */
3091 if (in_out_cnt && (in_out_start - end_xpos))
3093 add_margin_blank (dl, odb, w, end_xpos, in_out_start - end_xpos,
3097 /* Next add the inside margin glyphs which are actually in the
3101 end_xpos = add_margin_runes (dl, odb, in_out_start, in_out_cnt,
3102 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3105 /* If we didn't add any inside margin glyphs to the outside margin,
3106 but are adding whitespace glyphs, then we need to add a blank
3108 if (!in_out_cnt && white_out_cnt && (white_out_start - end_xpos))
3110 add_margin_blank (dl, odb, w, end_xpos, white_out_start - end_xpos,
3114 /* Next add the whitespace margin glyphs which are actually in the
3118 end_xpos = add_margin_runes (dl, odb, white_out_start, white_out_cnt,
3119 GL_WHITESPACE, LEFT_GLYPHS, window);
3122 /* We take care of clearing between the end of the glyphs and the
3123 start of the inside margin for lines which have glyphs. */
3124 if (odb && (left_in_start - end_xpos))
3126 add_margin_blank (dl, odb, w, end_xpos, left_in_start - end_xpos,
3130 /* Next add the inside margin glyphs which are actually in the
3134 end_xpos = add_margin_runes (dl, idb, left_in_end, in_in_cnt,
3135 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3138 end_xpos = left_in_end;
3140 /* Make sure that the area between the end of the inside margin
3141 glyphs and the whitespace glyphs is cleared. */
3142 if (idb && (white_in_start - end_xpos > 0))
3144 add_margin_blank (dl, idb, w, end_xpos, white_in_start - end_xpos,
3148 /* Next add the whitespace margin glyphs which are actually in the
3152 add_margin_runes (dl, idb, white_in_start, white_in_cnt, GL_WHITESPACE,
3153 LEFT_GLYPHS, window);
3156 /* Whitespace glyphs always end right next to the text block so
3157 there is nothing we have to make sure is cleared after them. */
3160 /* Display glyphs in the right outside margin, right inside margin and
3161 right whitespace area. */
3164 create_right_glyph_block (struct window *w, struct display_line *dl)
3168 int use_overflow = (NILP (w->use_right_overflow) ? 0 : 1);
3170 int out_start, in_out_end, in_in_start, white_out_end, white_in_end;
3171 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
3173 struct display_block *odb, *idb;
3175 XSETWINDOW (window, w);
3177 /* We have to add the glyphs to the line in the order outside,
3178 inside, whitespace. However the precedence dictates that we
3179 determine how many will fit in the reverse order. */
3181 /* Determine how many whitespace glyphs we can display and where
3182 they should start. */
3183 white_in_end = dl->bounds.right_white;
3184 white_out_end = dl->bounds.right_in;
3185 white_out_cnt = white_in_cnt = 0;
3188 while (elt < Dynarr_length (dl->right_glyphs))
3190 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3192 if (NILP (gb->extent))
3193 abort (); /* these should have been handled in add_glyph_rune */
3195 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
3197 int width = glyph_width (gb->glyph, window);
3199 if (white_in_end + width <= dl->bounds.right_in)
3202 white_in_end += width;
3206 else if (use_overflow
3207 && (white_out_end + width <= dl->bounds.right_out))
3210 white_out_end += width;
3221 /* Determine how many inside margin glyphs we can display and where
3222 they should start. The inside margin glyphs get whatever space
3223 is left after the whitespace glyphs have been displayed. These
3224 are tricky to calculate since if we decide to use the overflow
3225 area we basically have to start over. So for these we build up a
3226 list of just the inside margin glyphs and manipulate it to
3227 determine the needed info. */
3229 glyph_block_dynarr *ib;
3230 int avail_in, avail_out;
3233 int used_in, used_out;
3236 used_in = used_out = 0;
3237 ib = Dynarr_new (glyph_block);
3238 while (elt < Dynarr_length (dl->right_glyphs))
3240 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3242 if (NILP (gb->extent))
3243 abort (); /* these should have been handled in add_glyph_rune */
3245 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3247 gb->width = glyph_width (gb->glyph, window);
3248 used_in += gb->width;
3249 Dynarr_add (ib, *gb);
3258 avail_in = dl->bounds.right_in - white_in_end;
3263 avail_out = dl->bounds.right_out - white_out_end;
3266 while (!done && marker < Dynarr_length (ib))
3268 int width = Dynarr_atp (ib, marker)->width;
3270 /* If everything now fits in the available inside margin
3271 space, we're done. */
3272 if (used_in <= avail_in)
3276 /* Otherwise see if we have room to move a glyph to the
3278 if (used_out + width <= avail_out)
3291 /* At this point we now know that everything from marker on goes in
3292 the inside margin and everything before it goes in the outside
3293 margin. The stuff going into the outside margin is guaranteed
3294 to fit, but we may have to trim some stuff from the inside. */
3296 in_in_start = dl->bounds.right_in;
3297 in_out_end = dl->bounds.right_in;
3298 in_out_cnt = in_in_cnt = 0;
3302 while (elt < Dynarr_length (dl->right_glyphs))
3304 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3306 if (NILP (gb->extent))
3307 abort (); /* these should have been handled in add_glyph_rune */
3309 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3311 int width = glyph_width (gb->glyph, window);
3316 in_out_end += width;
3321 else if (in_in_start - width >= white_in_end)
3324 in_in_start -= width;
3336 /* Determine how many outside margin glyphs we can display. They
3337 always start at the right outside margin and can only use the
3338 outside margin space. */
3339 out_start = dl->bounds.right_out;
3343 while (elt < Dynarr_length (dl->right_glyphs))
3345 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3347 if (NILP (gb->extent))
3348 abort (); /* these should have been handled in add_glyph_rune */
3350 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_OUTSIDE_MARGIN)
3352 int width = glyph_width (gb->glyph, window);
3354 if (out_start - width >= in_out_end)
3368 /* Now that we now where everything goes, we add the glyphs as runes
3369 to the appropriate display blocks. */
3370 if (out_cnt || in_out_cnt || white_out_cnt)
3372 odb = get_display_block_from_line (dl, RIGHT_OUTSIDE_MARGIN);
3373 /* #### See comments before odb->start_pos init in
3374 create_left_glyph_block */
3375 odb->start_pos = dl->bounds.right_in;
3376 odb->end_pos = dl->bounds.right_out;
3377 Dynarr_reset (odb->runes);
3382 if (in_in_cnt || white_in_cnt)
3384 idb = get_display_block_from_line (dl, RIGHT_INSIDE_MARGIN);
3385 idb->start_pos = dl->bounds.right_white;
3386 /* #### See comments before odb->start_pos init in
3387 create_left_glyph_block */
3388 idb->end_pos = dl->bounds.right_in;
3389 Dynarr_reset (idb->runes);
3394 /* First add the whitespace margin glyphs which are actually in the
3398 end_xpos = add_margin_runes (dl, idb, dl->bounds.right_white,
3399 white_in_cnt, GL_WHITESPACE, RIGHT_GLYPHS,
3403 end_xpos = dl->bounds.right_white;
3405 /* Make sure that the area between the end of the whitespace glyphs
3406 and the inside margin glyphs is cleared. */
3407 if (in_in_cnt && (in_in_start - end_xpos))
3409 add_margin_blank (dl, idb, w, end_xpos, in_in_start - end_xpos,
3413 /* Next add the inside margin glyphs which are actually in the
3417 end_xpos = add_margin_runes (dl, idb, in_in_start, in_in_cnt,
3418 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3421 /* If we didn't add any inside margin glyphs then make sure the rest
3422 of the inside margin area gets cleared. */
3423 if (idb && (dl->bounds.right_in - end_xpos))
3425 add_margin_blank (dl, idb, w, end_xpos, dl->bounds.right_in - end_xpos,
3429 /* Next add any whitespace glyphs in the outside margin. */
3432 end_xpos = add_margin_runes (dl, odb, dl->bounds.right_in, white_out_cnt,
3433 GL_WHITESPACE, RIGHT_GLYPHS, window);
3436 end_xpos = dl->bounds.right_in;
3438 /* Next add any inside margin glyphs in the outside margin. */
3441 end_xpos = add_margin_runes (dl, odb, end_xpos, in_out_cnt,
3442 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3445 /* There may be space between any whitespace or inside margin glyphs
3446 in the outside margin and the actual outside margin glyphs. */
3447 if (odb && (out_start - end_xpos))
3449 add_margin_blank (dl, odb, w, end_xpos, out_start - end_xpos,
3453 /* Finally, add the outside margin glyphs. */
3456 add_margin_runes (dl, odb, out_start, out_cnt, GL_OUTSIDE_MARGIN,
3457 RIGHT_GLYPHS, window);
3462 /***************************************************************************/
3464 /* modeline routines */
3466 /***************************************************************************/
3468 /* This function is also used in frame.c by `generate_title_string' */
3470 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str,
3471 struct window *w, struct display_line *dl,
3472 struct display_block *db, face_index findex,
3473 int min_pixpos, int max_pixpos, int type)
3475 struct frame *f = XFRAME (w->frame);
3476 struct device *d = XDEVICE (f->device);
3480 Charcount offset = 0;
3486 data.findex = findex;
3487 data.pixpos = min_pixpos;
3488 data.max_pixpos = max_pixpos;
3489 data.cursor_type = NO_CURSOR;
3490 data.last_charset = Qunbound;
3491 data.last_findex = DEFAULT_INDEX;
3492 data.result_str = result_str;
3493 data.is_modeline = 1;
3495 XSETWINDOW (data.window, w);
3497 Dynarr_reset (formatted_string_extent_dynarr);
3498 Dynarr_reset (formatted_string_extent_start_dynarr);
3499 Dynarr_reset (formatted_string_extent_end_dynarr);
3501 /* result_str is nil when we're building a frame or icon title. Otherwise,
3502 we're building a modeline, so the offset starts at the modeline
3503 horizontal scrolling amount */
3504 if (! NILP (result_str))
3505 offset = w->modeline_hscroll;
3506 generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0,
3507 max_pixpos - min_pixpos, findex, type, &offset,
3510 if (Dynarr_length (db->runes))
3513 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
3514 c_pixpos = rb->xpos + rb->width;
3517 c_pixpos = min_pixpos;
3519 /* If we don't reach the right side of the window, add a blank rune
3520 to make up the difference. This usually only occurs if the
3521 modeline face is using a proportional width font or a fixed width
3522 font of a different size from the default face font. */
3524 if (c_pixpos < max_pixpos)
3526 data.pixpos = c_pixpos;
3527 data.blank_width = max_pixpos - data.pixpos;
3529 add_blank_rune (&data, NULL, 0);
3532 /* Now create the result string and frob the extents into it. */
3533 if (!NILP (result_str))
3538 struct buffer *buf = XBUFFER (WINDOW_BUFFER (w));
3540 in_modeline_generation = 1;
3542 detach_all_extents (result_str);
3543 resize_string (XSTRING (result_str), -1,
3544 data.bytepos - XSTRING_LENGTH (result_str));
3546 strdata = XSTRING_DATA (result_str);
3548 for (elt = 0, len = 0; elt < Dynarr_length (db->runes); elt++)
3550 if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR)
3552 len += (set_charptr_emchar
3553 (strdata + len, Dynarr_atp (db->runes,
3554 elt)->object.chr.ch));
3558 for (elt = 0; elt < Dynarr_length (formatted_string_extent_dynarr);
3561 Lisp_Object extent = Qnil;
3564 XSETEXTENT (extent, Dynarr_at (formatted_string_extent_dynarr, elt));
3565 child = Fgethash (extent, buf->modeline_extent_table, Qnil);
3568 child = Fmake_extent (Qnil, Qnil, result_str);
3569 Fputhash (extent, child, buf->modeline_extent_table);
3571 Fset_extent_parent (child, extent);
3572 set_extent_endpoints
3574 Dynarr_at (formatted_string_extent_start_dynarr, elt),
3575 Dynarr_at (formatted_string_extent_end_dynarr, elt),
3579 in_modeline_generation = 0;
3583 /* Ensure that the given display line DL accurately represents the
3584 modeline for the given window. */
3586 generate_modeline (struct window *w, struct display_line *dl, int type)
3588 struct buffer *b = XBUFFER (w->buffer);
3589 struct frame *f = XFRAME (w->frame);
3590 struct device *d = XDEVICE (f->device);
3592 /* Unlike display line and rune pointers, this one can't change underneath
3594 struct display_block *db = get_display_block_from_line (dl, TEXT);
3595 int max_pixpos, min_pixpos, ypos_adj;
3596 Lisp_Object font_inst;
3598 /* This will actually determine incorrect inside boundaries for the
3599 modeline since it ignores the margins. However being aware of this fact
3600 we never use those values anywhere so it doesn't matter. */
3601 dl->bounds = calculate_display_line_boundaries (w, 1);
3603 /* We are generating a modeline. */
3605 dl->cursor_elt = -1;
3607 /* Reset the runes on the modeline. */
3608 Dynarr_reset (db->runes);
3610 if (!WINDOW_HAS_MODELINE_P (w))
3614 /* If there is a horizontal scrollbar, don't add anything. */
3615 if (window_scrollbar_height (w))
3618 dl->ascent = DEVMETH (d, divider_height, ());
3620 /* The modeline is at the bottom of the gutters. */
3621 dl->ypos = WINDOW_BOTTOM (w);
3623 rb.findex = MODELINE_INDEX;
3624 rb.xpos = dl->bounds.left_out;
3625 rb.width = dl->bounds.right_out - dl->bounds.left_out;
3628 rb.type = RUNE_HLINE;
3629 rb.object.hline.thickness = 1;
3630 rb.object.hline.yoffset = 0;
3631 rb.cursor_type = NO_CURSOR;
3633 if (!EQ (Qzero, w->modeline_shadow_thickness)
3636 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3638 dl->ypos -= shadow_thickness;
3639 rb.xpos += shadow_thickness;
3640 rb.width -= 2 * shadow_thickness;
3643 Dynarr_add (db->runes, rb);
3647 /* !!#### not right; needs to compute the max height of
3649 font_inst = WINDOW_FACE_CACHEL_FONT (w, MODELINE_INDEX, Vcharset_ascii);
3651 dl->ascent = XFONT_INSTANCE (font_inst)->ascent;
3652 dl->descent = XFONT_INSTANCE (font_inst)->descent;
3654 min_pixpos = dl->bounds.left_out;
3655 max_pixpos = dl->bounds.right_out;
3657 if (!EQ (Qzero, w->modeline_shadow_thickness) && FRAME_WIN_P (f))
3659 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3661 ypos_adj = shadow_thickness;
3662 min_pixpos += shadow_thickness;
3663 max_pixpos -= shadow_thickness;
3668 generate_formatted_string_db (b->modeline_format,
3669 b->generated_modeline_string, w, dl, db,
3670 MODELINE_INDEX, min_pixpos, max_pixpos, type);
3672 /* The modeline is at the bottom of the gutters. We have to wait to
3673 set this until we've generated the modeline in order to account
3674 for any embedded faces. */
3675 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj;
3679 add_string_to_fstring_db_runes (pos_data *data, const Bufbyte *str,
3680 Charcount pos, Charcount min_pos, Charcount max_pos)
3682 /* This function has been Mule-ized. */
3684 const Bufbyte *cur_pos = str;
3685 struct display_block *db = data->db;
3687 data->blank_width = space_width (XWINDOW (data->window));
3688 while (Dynarr_length (db->runes) < pos)
3689 add_blank_rune (data, NULL, 0);
3691 end = (Dynarr_length (db->runes) +
3692 bytecount_to_charcount (str, strlen ((const char *) str)));
3694 end = min (max_pos, end);
3696 while (pos < end && *cur_pos)
3698 const Bufbyte *old_cur_pos = cur_pos;
3701 data->ch = charptr_emchar (cur_pos);
3702 succeeded = (add_emchar_rune (data) != ADD_FAILED);
3703 INC_CHARPTR (cur_pos);
3707 data->modeline_charpos++;
3708 data->bytepos += cur_pos - old_cur_pos;
3712 while (Dynarr_length (db->runes) < min_pos &&
3713 (data->pixpos + data->blank_width <= data->max_pixpos))
3714 add_blank_rune (data, NULL, 0);
3716 return Dynarr_length (db->runes);
3719 /* #### Urk! Should also handle begin-glyphs and end-glyphs in
3720 modeline extents. */
3722 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph,
3723 Charcount pos, Charcount min_pos,
3724 Charcount max_pos, Lisp_Object extent)
3726 /* This function has been Mule-ized. */
3728 struct display_block *db = data->db;
3729 struct glyph_block gb;
3731 data->blank_width = space_width (XWINDOW (data->window));
3732 while (Dynarr_length (db->runes) < pos)
3733 add_blank_rune (data, NULL, 0);
3735 end = Dynarr_length (db->runes) + 1;
3737 end = min (max_pos, end);
3741 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
3744 while (Dynarr_length (db->runes) < pos &&
3745 (data->pixpos + data->blank_width <= data->max_pixpos))
3746 add_blank_rune (data, NULL, 0);
3748 return Dynarr_length (db->runes);
3751 /* If max_pos is == -1, it is considered to be infinite. The same is
3752 true of max_pixsize. */
3753 #define SET_CURRENT_MODE_CHARS_PIXSIZE \
3754 if (Dynarr_length (data->db->runes)) \
3755 cur_pixsize = data->pixpos - Dynarr_atp (data->db->runes, 0)->xpos; \
3759 /* Note that this function does "positions" in terms of characters and
3760 not in terms of columns. This is necessary to make the formatting
3761 work correctly when proportional width fonts are used in the
3764 generate_fstring_runes (struct window *w, pos_data *data, Charcount pos,
3765 Charcount min_pos, Charcount max_pos,
3766 Lisp_Object elt, int depth, int max_pixsize,
3767 face_index findex, int type, Charcount *offset,
3768 Lisp_Object cur_ext)
3770 /* This function has been Mule-ized. */
3771 /* #### The other losing things in this function are:
3773 -- C zero-terminated-string lossage.
3774 -- Non-printable characters should be converted into something
3775 appropriate (e.g. ^F) instead of blindly being printed anyway.
3786 /* A string. Add to the display line and check for %-constructs
3789 Bufbyte *this = XSTRING_DATA (elt);
3791 while ((pos < max_pos || max_pos == -1) && *this)
3793 Bufbyte *last = this;
3795 while (*this && *this != '%')
3800 /* No %-construct */
3802 bytecount_to_charcount (last, this - last);
3804 if (size <= *offset)
3808 Charcount tmp_max = (max_pos == -1 ? pos + size - *offset :
3809 min (pos + size - *offset, max_pos));
3810 const Bufbyte *tmp_last = charptr_n_addr (last, *offset);
3812 pos = add_string_to_fstring_db_runes (data, tmp_last,
3817 else /* *this == '%' */
3819 Charcount spec_width = 0;
3821 this++; /* skip over '%' */
3823 /* We can't allow -ve args due to the "%-" construct.
3824 * Argument specifies minwidth but not maxwidth
3825 * (maxwidth can be specified by
3826 * (<negative-number> . <stuff>) modeline elements)
3828 while (isdigit (*this))
3830 spec_width = spec_width * 10 + (*this - '0');
3837 pos = generate_fstring_runes (w, data, pos, spec_width,
3838 max_pos, Vglobal_mode_string,
3839 depth, max_pixsize, findex,
3840 type, offset, cur_ext);
3842 else if (*this == '-')
3844 Charcount num_to_add;
3846 if (max_pixsize < 0)
3848 else if (max_pos != -1)
3849 num_to_add = max_pos - pos;
3855 SET_CURRENT_MODE_CHARS_PIXSIZE;
3858 redisplay_text_width_string (w, findex, &ch, Qnil, 0,
3861 num_to_add = (max_pixsize - cur_pixsize) / dash_pixsize;
3865 while (num_to_add--)
3866 pos = add_string_to_fstring_db_runes
3867 (data, (const Bufbyte *) "-", pos, pos, max_pos);
3869 else if (*this != 0)
3871 Emchar ch = charptr_emchar (this);
3875 decode_mode_spec (w, ch, type);
3877 str = Dynarr_atp (mode_spec_bufbyte_string, 0);
3878 size = bytecount_to_charcount
3879 /* Skip the null character added by `decode_mode_spec' */
3880 (str, Dynarr_length (mode_spec_bufbyte_string)) - 1;
3882 if (size <= *offset)
3886 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3888 /* #### NOTE: I don't understand why a tmp_max is not
3889 computed and used here as in the plain string case
3891 pos = add_string_to_fstring_db_runes (data, tmp_str,
3898 /* NOT this++. There could be any sort of character at
3899 the current position. */
3903 if (max_pixsize > 0)
3906 SET_CURRENT_MODE_CHARS_PIXSIZE;
3908 if (cur_pixsize >= max_pixsize)
3913 else if (SYMBOLP (elt))
3915 /* A symbol: process the value of the symbol recursively
3916 as if it appeared here directly. */
3917 Lisp_Object tem = symbol_value_in_buffer (elt, w->buffer);
3919 if (!UNBOUNDP (tem))
3921 /* If value is a string, output that string literally:
3922 don't check for % within it. */
3925 Bufbyte *str = XSTRING_DATA (tem);
3926 Charcount size = XSTRING_CHAR_LENGTH (tem);
3928 if (size <= *offset)
3932 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3934 /* #### NOTE: I don't understand why a tmp_max is not
3935 computed and used here as in the plain string case
3937 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
3942 /* Give up right away for nil or t. */
3943 else if (!EQ (tem, elt))
3950 else if (GENERIC_SPECIFIERP (elt))
3952 Lisp_Object window, tem;
3953 XSETWINDOW (window, w);
3954 tem = specifier_instance_no_quit (elt, Qunbound, window,
3955 ERROR_ME_NOT, 0, Qzero);
3956 if (!UNBOUNDP (tem))
3962 else if (CONSP (elt))
3964 /* A cons cell: four distinct cases.
3965 * - If first element is a string or a cons, process all the elements
3966 * and effectively concatenate them.
3967 * - If first element is a negative number, truncate displaying cdr to
3968 * at most that many characters. If positive, pad (with spaces)
3969 * to at least that many characters.
3970 * - If first element is another symbol, process the cadr or caddr
3971 * recursively according to whether the symbol's value is non-nil or
3973 * - If first element is an extent, process the cdr recursively
3974 * and handle the extent's face.
3977 Lisp_Object car, tem;
3986 tem = symbol_value_in_buffer (car, w->buffer);
3987 /* elt is now the cdr, and we know it is a cons cell.
3988 Use its car if CAR has a non-nil value. */
3989 if (!UNBOUNDP (tem))
3997 /* Symbol's value is nil (or symbol is unbound)
3998 * Get the cddr of the original list
3999 * and if possible find the caddr and use that.
4004 else if (!CONSP (elt))
4012 else if (INTP (car))
4014 Charcount lim = XINT (car);
4020 /* Negative int means reduce maximum width.
4021 * DO NOT change MIN_PIXPOS here!
4022 * (20 -10 . foo) should truncate foo to 10 col
4023 * and then pad to 20.
4026 max_pos = pos - lim;
4028 max_pos = min (max_pos, pos - lim);
4032 /* Padding specified. Don't let it be more than
4036 if (max_pos != -1 && lim > max_pos)
4038 /* If that's more padding than already wanted, queue it.
4039 * But don't reduce padding already specified even if
4040 * that is beyond the current truncation point.
4047 else if (STRINGP (car) || CONSP (car))
4051 /* LIMIT is to protect against circular lists. */
4052 while (CONSP (elt) && --limit > 0
4053 && (pos < max_pos || max_pos == -1))
4055 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4056 XCAR (elt), depth, max_pixsize,
4057 findex, type, offset, cur_ext);
4061 else if (EXTENTP (car))
4063 struct extent *ext = XEXTENT (car);
4065 if (EXTENT_LIVE_P (ext))
4067 face_index old_findex = data->findex;
4069 Lisp_Object font_inst;
4070 face_index new_findex;
4071 Bytecount start = data->bytepos;
4073 face = extent_face (ext);
4076 /* #### needs to merge faces, sigh */
4077 /* #### needs to handle list of faces */
4078 new_findex = get_builtin_face_cache_index (w, face);
4079 /* !!#### not right; needs to compute the max height of
4081 font_inst = WINDOW_FACE_CACHEL_FONT (w, new_findex,
4084 data->dl->ascent = max (data->dl->ascent,
4085 XFONT_INSTANCE (font_inst)->ascent);
4086 data->dl->descent = max (data->dl->descent,
4087 XFONT_INSTANCE (font_inst)->
4091 new_findex = old_findex;
4093 data->findex = new_findex;
4094 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4095 XCDR (elt), depth - 1,
4096 max_pixsize, new_findex, type,
4098 data->findex = old_findex;
4099 Dynarr_add (formatted_string_extent_dynarr, ext);
4100 Dynarr_add (formatted_string_extent_start_dynarr, start);
4101 Dynarr_add (formatted_string_extent_end_dynarr, data->bytepos);
4105 else if (GLYPHP (elt))
4107 /* Glyphs are considered as one character with respect to the modeline
4108 horizontal scrolling facility. -- dv */
4112 pos = add_glyph_to_fstring_db_runes (data, elt, pos, pos, max_pos,
4119 char *str = GETTEXT ("*invalid*");
4120 Charcount size = (Charcount) strlen (str); /* is this ok ?? -- dv */
4122 if (size <= *offset)
4126 const Bufbyte *tmp_str =
4127 charptr_n_addr ((const Bufbyte *) str, *offset);
4129 /* #### NOTE: I don't understand why a tmp_max is not computed and
4130 used here as in the plain string case above. -- dv */
4131 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
4140 add_string_to_fstring_db_runes (data, (const Bufbyte *) "", pos,
4147 /* Update just the modeline. Assumes the desired display structs. If
4148 they do not have a modeline block, it does nothing. */
4150 regenerate_modeline (struct window *w)
4152 display_line_dynarr *dla = window_display_lines (w, DESIRED_DISP);
4154 if (!Dynarr_length (dla) || !Dynarr_atp (dla, 0)->modeline)
4158 generate_modeline (w, Dynarr_atp (dla, 0), DESIRED_DISP);
4159 redisplay_update_line (w, 0, 0, 0);
4163 /* Make sure that modeline display line is present in the given
4164 display structs if the window has a modeline and update that
4165 line. Returns true if a modeline was needed. */
4167 ensure_modeline_generated (struct window *w, int type)
4171 /* minibuffer windows don't have modelines */
4172 if (MINI_WINDOW_P (w))
4174 /* windows which haven't had it turned off do */
4175 else if (WINDOW_HAS_MODELINE_P (w))
4177 /* windows which have it turned off don't have a divider if there is
4178 a horizontal scrollbar */
4179 else if (window_scrollbar_height (w))
4181 /* and in this case there is none */
4187 display_line_dynarr *dla;
4189 dla = window_display_lines (w, type);
4191 /* We don't care if there is a display line which is not
4192 currently a modeline because it is definitely going to become
4193 one if we have gotten to this point. */
4194 if (Dynarr_length (dla) == 0)
4196 if (Dynarr_largest (dla) > 0)
4198 struct display_line *mlp = Dynarr_atp (dla, 0);
4199 Dynarr_add (dla, *mlp);
4203 struct display_line modeline;
4205 Dynarr_add (dla, modeline);
4209 /* If we're adding a new place marker go ahead and generate the
4210 modeline so that it is available for use by
4211 window_modeline_height. */
4212 generate_modeline (w, Dynarr_atp (dla, 0), type);
4215 return need_modeline;
4218 /* #### Kludge or not a kludge. I tend towards the former. */
4220 real_current_modeline_height (struct window *w)
4222 Fset_marker (w->start[CMOTION_DISP], w->start[CURRENT_DISP], w->buffer);
4223 Fset_marker (w->pointm[CMOTION_DISP], w->pointm[CURRENT_DISP], w->buffer);
4225 if (ensure_modeline_generated (w, CMOTION_DISP))
4227 display_line_dynarr *dla = window_display_lines (w, CMOTION_DISP);
4229 if (Dynarr_length (dla))
4231 if (Dynarr_atp (dla, 0)->modeline)
4232 return (Dynarr_atp (dla, 0)->ascent +
4233 Dynarr_atp (dla, 0)->descent);
4240 /***************************************************************************/
4242 /* displayable string routines */
4244 /***************************************************************************/
4246 /* Given a position for a string in a window, ensure that the given
4247 display line DL accurately represents the text on a line starting
4248 at the given position.
4250 Yes, this is duplicating the code of create_text_block, but it
4251 looked just too hard to change create_text_block to handle strings
4252 *and* buffers. We already make a distinction between the two
4253 elsewhere in the code so I think unifying them would require a
4254 complete MULE rewrite. Besides, the other distinction is that these
4255 functions cover text that the user *cannot edit* so we can remove
4256 everything to do with cursors, minibuffers etc. Eventually the
4257 modeline routines should be modified to use this code as it copes
4258 with many more types of display situation. */
4261 create_string_text_block (struct window *w, Lisp_Object disp_string,
4262 struct display_line *dl,
4264 prop_block_dynarr **prop,
4265 face_index default_face)
4267 struct frame *f = XFRAME (w->frame);
4268 /* Note that a lot of the buffer controlled stuff has been left in
4269 because you might well want to make use of it (selective display
4270 etc), its just the buffer text that we do not use. However, it
4271 seems to be possible for buffer to be nil sometimes so protect
4272 against this case. */
4273 struct buffer *b = BUFFERP (w->buffer) ? XBUFFER (w->buffer) : 0;
4274 struct device *d = XDEVICE (f->device);
4275 Lisp_String* s = XSTRING (disp_string);
4277 /* we're working with these a lot so precalculate them */
4278 Bytecount slen = XSTRING_LENGTH (disp_string);
4279 Bytecount bi_string_zv = slen;
4280 Bytind bi_start_pos = charcount_to_bytecount (string_data (s), start_pos);
4284 int truncate_win = b ? window_truncation_on (w) : 0;
4285 int end_glyph_width = 0;
4287 /* We're going to ditch selective display for static text, it's an
4288 FSF thing and invisible extents are the way to go here.
4289 Implementing it also relies on a number of buffer-specific
4290 functions that we don't have the luxury of being able to use
4293 /* The variable ctl-arrow allows the user to specify what characters
4294 can actually be displayed and which octal should be used for.
4295 #### This variable should probably have some rethought done to
4298 #### It would also be really nice if you could specify that
4299 the characters come out in hex instead of in octal. Mule
4300 does that by adding a ctl-hexa variable similar to ctl-arrow,
4301 but that's bogus -- we need a more general solution. I
4302 think you need to extend the concept of display tables
4303 into a more general conversion mechanism. Ideally you
4304 could specify a Lisp function that converts characters,
4305 but this violates the Second Golden Rule and besides would
4306 make things way way way way slow.
4308 So instead, we extend the display-table concept, which was
4309 historically limited to 256-byte vectors, to one of the
4312 a) A 256-entry vector, for backward compatibility;
4313 b) char-table, mapping characters to values;
4314 c) range-table, mapping ranges of characters to values;
4315 d) a list of the above.
4317 The (d) option allows you to specify multiple display tables
4318 instead of just one. Each display table can specify conversions
4319 for some characters and leave others unchanged. The way the
4320 character gets displayed is determined by the first display table
4321 with a binding for that character. This way, you could call a
4322 function `enable-hex-display' that adds a hex display-table to
4323 the list of display tables for the current buffer.
4325 #### ...not yet implemented... Also, we extend the concept of
4326 "mapping" to include a printf-like spec. Thus you can make all
4327 extended characters show up as hex with a display table like
4330 #s(range-table data ((256 524288) (format "%x")))
4332 Since more than one display table is possible, you have
4333 great flexibility in mapping ranges of characters. */
4334 Emchar printable_min = b ? (CHAR_OR_CHAR_INTP (b->ctl_arrow)
4335 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
4336 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
4337 ? 255 : 160)) : 255;
4339 Lisp_Object face_dt, window_dt;
4341 /* The text display block for this display line. */
4342 struct display_block *db = get_display_block_from_line (dl, TEXT);
4344 /* The first time through the main loop we need to force the glyph
4345 data to be updated. */
4348 /* Apparently the new extent_fragment_update returns an end position
4349 equal to the position passed in if there are no more runs to be
4351 int no_more_frags = 0;
4353 dl->used_prop_data = 0;
4355 dl->line_continuation = 0;
4357 /* set up faces to use for clearing areas, used by
4358 output_display_line */
4359 dl->default_findex = default_face;
4362 dl->left_margin_findex = default_face;
4363 dl->right_margin_findex = default_face;
4367 dl->left_margin_findex =
4368 get_builtin_face_cache_index (w, Vleft_margin_face);
4369 dl->right_margin_findex =
4370 get_builtin_face_cache_index (w, Vright_margin_face);
4374 data.ef = extent_fragment_new (disp_string, f);
4376 /* These values are used by all of the rune addition routines. We add
4377 them to this structure for ease of passing. */
4379 XSETWINDOW (data.window, w);
4383 data.bi_bufpos = bi_start_pos;
4384 data.pixpos = dl->bounds.left_in;
4385 data.last_charset = Qunbound;
4386 data.last_findex = default_face;
4387 data.result_str = Qnil;
4388 data.string = disp_string;
4390 /* Set the right boundary adjusting it to take into account any end
4391 glyph. Save the width of the end glyph for later use. */
4392 data.max_pixpos = dl->bounds.right_in;
4395 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
4397 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
4399 data.max_pixpos -= end_glyph_width;
4401 data.cursor_type = NO_CURSOR;
4405 /* I don't think we want this, string areas should not scroll with
4407 data.start_col = w->hscroll;
4408 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
4410 data.bi_start_col_enabled = 0;
4411 data.hscroll_glyph_width_adjust = 0;
4413 /* We regenerate the line from the very beginning. */
4414 Dynarr_reset (db->runes);
4416 /* Why is this less than or equal and not just less than? If the
4417 starting position is already equal to the maximum we can't add
4418 anything else, right? Wrong. We might still have a newline to
4419 add. A newline can use the room allocated for an end glyph since
4420 if we add it we know we aren't going to be adding any end
4423 /* #### Chuck -- I think this condition should be while (1).
4424 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
4425 and the begin-glyph ends exactly at the end of the window, the
4426 end-glyph and text might not be displayed. while (1) ensures
4427 that the loop terminates only when either (a) there is
4428 propagation data or (b) the end-of-line or end-of-buffer is hit.
4430 #### Also I think you need to ensure that the operation
4431 "add begin glyphs; add end glyphs; add text" is atomic and
4432 can't get interrupted in the middle. If you run off the end
4433 of the line during that operation, then you keep accumulating
4434 propagation data until you're done. Otherwise, if the (e.g.)
4435 there's a begin glyph at a particular position and attempting
4436 to display that glyph results in window-end being hit and
4437 propagation data being generated, then the character at that
4438 position won't be displayed.
4440 #### See also the comment after the end of this loop, below.
4442 while (data.pixpos <= data.max_pixpos)
4444 /* #### This check probably should not be necessary. */
4445 if (data.bi_bufpos > bi_string_zv)
4447 /* #### urk! More of this lossage! */
4452 /* Check for face changes. */
4453 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
4455 /* Now compute the face and begin/end-glyph information. */
4457 /* Remember that the extent-fragment routines deal in Bytind's. */
4458 extent_fragment_update (w, data.ef, data.bi_bufpos);
4459 /* This is somewhat cheesy but the alternative is to
4460 propagate default_face into extent_fragment_update. */
4461 if (data.findex == DEFAULT_INDEX)
4462 data.findex = default_face;
4464 get_display_tables (w, data.findex, &face_dt, &window_dt);
4466 if (data.bi_bufpos == data.ef->end)
4471 /* Determine what is next to be displayed. We first handle any
4472 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
4473 display then we determine what to do based on the character at the
4474 current buffer position. */
4476 /* If the current position is covered by an invisible extent, do
4477 nothing (except maybe add some ellipses).
4479 #### The behavior of begin and end-glyphs at the edge of an
4480 invisible extent should be investigated further. This is
4481 fairly low priority though. */
4482 if (data.ef->invisible)
4484 /* #### Chuck, perhaps you could look at this code? I don't
4485 really know what I'm doing. */
4488 Dynarr_free (*prop);
4492 /* The extent fragment code only sets this when we should
4493 really display the ellipses. It makes sure the ellipses
4494 don't get displayed more than once in a row. */
4495 if (data.ef->invisible_ellipses)
4497 struct glyph_block gb;
4499 data.ef->invisible_ellipses_already_displayed = 1;
4500 data.ef->invisible_ellipses = 0;
4502 gb.glyph = Vinvisible_text_glyph;
4503 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
4504 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
4505 /* Perhaps they shouldn't propagate if the very next thing
4506 is to display a newline (for compatibility with
4507 selective-display-ellipses)? Maybe that's too
4513 /* #### What if we we're dealing with a display table? */
4517 if (data.bi_bufpos == bi_string_zv)
4520 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4523 /* If there is propagation data, then it represents the current
4524 buffer position being displayed. Add them and advance the
4525 position counter. This might also add the minibuffer
4529 dl->used_prop_data = 1;
4530 *prop = add_propagation_runes (prop, &data);
4533 goto done; /* gee, a really narrow window */
4534 else if (data.bi_bufpos == bi_string_zv)
4536 else if (data.bi_bufpos < 0)
4537 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
4540 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4543 /* If there are end glyphs, add them to the line. These are
4544 the end glyphs for the previous run of text. We add them
4545 here rather than doing them at the end of handling the
4546 previous run so that glyphs at the beginning and end of
4547 a line are handled correctly. */
4548 else if (Dynarr_length (data.ef->end_glyphs) > 0)
4550 *prop = add_glyph_runes (&data, END_GLYPHS);
4555 /* If there are begin glyphs, add them to the line. */
4556 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
4558 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
4563 /* If at end-of-buffer, we've already processed begin and
4564 end-glyphs at this point and there's no text to process,
4566 else if (data.bi_bufpos == bi_string_zv)
4571 Lisp_Object entry = Qnil;
4572 /* Get the character at the current buffer position. */
4573 data.ch = string_char (s, data.bi_bufpos);
4574 if (!NILP (face_dt) || !NILP (window_dt))
4575 entry = display_table_entry (data.ch, face_dt, window_dt);
4577 /* If there is a display table entry for it, hand it off to
4578 add_disp_table_entry_runes and let it worry about it. */
4579 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
4581 *prop = add_disp_table_entry_runes (&data, entry);
4587 /* Check if we have hit a newline character. If so, add a marker
4588 to the line and end this loop. */
4589 else if (data.ch == '\n')
4591 /* We aren't going to be adding an end glyph so give its
4592 space back in order to make sure that the cursor can
4594 data.max_pixpos += end_glyph_width;
4598 /* If the current character is considered to be printable, then
4600 else if (data.ch >= printable_min)
4602 *prop = add_emchar_rune (&data);
4607 /* If the current character is a tab, determine the next tab
4608 starting position and add a blank rune which extends from the
4609 current pixel position to that starting position. */
4610 else if (data.ch == '\t')
4612 int tab_start_pixpos = data.pixpos;
4617 if (data.start_col > 1)
4618 tab_start_pixpos -= (space_width (w) * (data.start_col - 1));
4621 next_tab_position (w, tab_start_pixpos,
4622 dl->bounds.left_in +
4623 data.hscroll_glyph_width_adjust);
4624 if (next_tab_start > data.max_pixpos)
4626 prop_width = next_tab_start - data.max_pixpos;
4627 next_tab_start = data.max_pixpos;
4629 data.blank_width = next_tab_start - data.pixpos;
4631 (next_tab_start - tab_start_pixpos) / space_width (w);
4633 *prop = add_blank_rune (&data, w, char_tab_width);
4635 /* add_blank_rune is only supposed to be called with
4636 sizes guaranteed to fit in the available space. */
4641 struct prop_block pb;
4642 *prop = Dynarr_new (prop_block);
4644 pb.type = PROP_BLANK;
4645 pb.data.p_blank.width = prop_width;
4646 pb.data.p_blank.findex = data.findex;
4647 Dynarr_add (*prop, pb);
4653 /* If character is a control character, pass it off to
4654 add_control_char_runes.
4656 The is_*() routines have undefined results on
4657 arguments outside of the range [-1, 255]. (This
4658 often bites people who carelessly use `char' instead
4659 of `unsigned char'.)
4661 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
4663 *prop = add_control_char_runes (&data, b);
4669 /* If the character is above the ASCII range and we have not
4670 already handled it, then print it as an octal number. */
4671 else if (data.ch >= 0200)
4673 *prop = add_octal_runes (&data);
4679 /* Assume the current character is considered to be printable,
4680 then just add it. */
4683 *prop = add_emchar_rune (&data);
4688 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4694 /* Determine the starting point of the next line if we did not hit the
4695 end of the buffer. */
4696 if (data.bi_bufpos < bi_string_zv)
4698 /* #### This check is not correct. If the line terminated
4699 due to a begin-glyph or end-glyph hitting window-end, then
4700 data.ch will not point to the character at data.bi_bufpos. If
4701 you make the two changes mentioned at the top of this loop,
4702 you should be able to say '(if (*prop))'. That should also
4703 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
4706 /* The common case is that the line ended because we hit a newline.
4707 In that case, the next character is just the next buffer
4709 if (data.ch == '\n')
4711 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4714 /* Otherwise we have a buffer line which cannot fit on one display
4718 struct glyph_block gb;
4719 struct glyph_cachel *cachel;
4721 /* If the line is to be truncated then we actually have to look
4722 for the next newline. We also add the end-of-line glyph which
4723 we know will fit because we adjusted the right border before
4724 we starting laying out the line. */
4725 data.max_pixpos += end_glyph_width;
4726 data.findex = default_face;
4733 /* Now find the start of the next line. */
4734 bi_pos = bi_find_next_emchar_in_string (s, '\n', data.bi_bufpos, 1);
4736 data.cursor_type = NO_CURSOR;
4737 data.bi_bufpos = bi_pos;
4738 gb.glyph = Vtruncation_glyph;
4739 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
4743 /* The cursor can never be on the continuation glyph. */
4744 data.cursor_type = NO_CURSOR;
4746 /* data.bi_bufpos is already at the start of the next line. */
4748 dl->line_continuation = 1;
4749 gb.glyph = Vcontinuation_glyph;
4750 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
4753 if (end_glyph_width)
4754 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
4756 if (truncate_win && data.bi_bufpos == bi_string_zv)
4758 const Bufbyte* endb = charptr_n_addr (string_data (s), bi_string_zv);
4760 if (charptr_emchar (endb) != '\n')
4762 /* #### Damn this losing shit. */
4768 else if (data.bi_bufpos == bi_string_zv)
4770 /* create_text_block () adds a bogus \n marker here which screws
4771 up subwindow display. Since we never have a cursor in the
4772 gutter we can safely ignore it. */
4774 /* Calculate left whitespace boundary. */
4778 /* Whitespace past a newline is considered right whitespace. */
4779 while (elt < Dynarr_length (db->runes))
4781 struct rune *rb = Dynarr_atp (db->runes, elt);
4783 if ((rb->type == RUNE_CHAR && rb->object.chr.ch == ' ')
4784 || rb->type == RUNE_BLANK)
4786 dl->bounds.left_white += rb->width;
4790 elt = Dynarr_length (db->runes);
4794 /* Calculate right whitespace boundary. */
4796 int elt = Dynarr_length (db->runes) - 1;
4799 while (!done && elt >= 0)
4801 struct rune *rb = Dynarr_atp (db->runes, elt);
4803 if (!(rb->type == RUNE_CHAR && rb->object.chr.ch < 0x100
4804 && isspace (rb->object.chr.ch))
4805 && !rb->type == RUNE_BLANK)
4807 dl->bounds.right_white = rb->xpos + rb->width;
4815 /* The line is blank so everything is considered to be right
4818 dl->bounds.right_white = dl->bounds.left_in;
4821 /* Set the display blocks bounds. */
4822 db->start_pos = dl->bounds.left_in;
4823 if (Dynarr_length (db->runes))
4825 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
4827 db->end_pos = rb->xpos + rb->width;
4830 db->end_pos = dl->bounds.right_white;
4832 /* update line height parameters */
4833 if (!data.new_ascent && !data.new_descent)
4835 /* We've got a blank line so initialize these values from the default
4837 default_face_font_info (data.window, &data.new_ascent,
4838 &data.new_descent, 0, 0, 0);
4841 if (data.max_pixmap_height)
4843 int height = data.new_ascent + data.new_descent;
4844 int pix_ascent, pix_descent;
4846 pix_descent = data.max_pixmap_height * data.new_descent / height;
4847 pix_ascent = data.max_pixmap_height - pix_descent;
4849 data.new_ascent = max (data.new_ascent, pix_ascent);
4850 data.new_descent = max (data.new_descent, pix_descent);
4853 dl->ascent = data.new_ascent;
4854 dl->descent = data.new_descent;
4857 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
4859 if (dl->ascent < ascent)
4860 dl->ascent = ascent;
4863 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
4865 if (dl->descent < descent)
4866 dl->descent = descent;
4869 dl->cursor_elt = data.cursor_x;
4870 /* #### lossage lossage lossage! Fix this shit! */
4871 if (data.bi_bufpos > bi_string_zv)
4872 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, bi_string_zv);
4874 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, data.bi_bufpos) - 1;
4876 data.dl->num_chars =
4877 string_column_at_point (s, dl->end_bufpos, b ? XINT (b->tab_width) : 8);
4879 /* This doesn't correctly take into account tabs and control
4880 characters but if the window isn't being truncated then this
4881 value isn't going to end up being used anyhow. */
4882 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
4884 /* #### handle horizontally scrolled line with text none of which
4885 was actually laid out. */
4887 /* #### handle any remainder of overlay arrow */
4889 if (*prop == ADD_FAILED)
4892 if (truncate_win && *prop)
4894 Dynarr_free (*prop);
4898 extent_fragment_delete (data.ef);
4900 /* #### If we started at EOB, then make sure we return a value past
4901 it so that regenerate_window will exit properly. This is bogus.
4902 The main loop should get fixed so that it isn't necessary to call
4903 this function if we are already at EOB. */
4905 if (data.bi_bufpos == bi_string_zv && bi_start_pos == bi_string_zv)
4906 return bytecount_to_charcount (string_data (s), data.bi_bufpos) + 1; /* Yuck! */
4908 return bytecount_to_charcount (string_data (s), data.bi_bufpos);
4911 /* Given a display line and a starting position, ensure that the
4912 contents of the display line accurately represent the visual
4913 representation of the buffer contents starting from the given
4914 position when displayed in the given window. The display line ends
4915 when the contents of the line reach the right boundary of the given
4918 This is very similar to generate_display_line but with the same
4919 limitations as create_string_text_block. I have taken the liberty
4920 of fixing the bytind stuff though.*/
4923 generate_string_display_line (struct window *w, Lisp_Object disp_string,
4924 struct display_line *dl,
4926 prop_block_dynarr **prop,
4927 face_index default_face)
4931 /* you must set bounds before calling this. */
4933 /* Reset what this line is using. */
4934 if (dl->display_blocks)
4935 Dynarr_reset (dl->display_blocks);
4936 if (dl->left_glyphs)
4938 Dynarr_free (dl->left_glyphs);
4939 dl->left_glyphs = 0;
4941 if (dl->right_glyphs)
4943 Dynarr_free (dl->right_glyphs);
4944 dl->right_glyphs = 0;
4947 /* We aren't generating a modeline at the moment. */
4950 /* Create a display block for the text region of the line. */
4951 ret_bufpos = create_string_text_block (w, disp_string, dl, start_pos,
4952 prop, default_face);
4953 dl->bufpos = start_pos;
4954 if (dl->end_bufpos < dl->bufpos)
4955 dl->end_bufpos = dl->bufpos;
4957 /* If there are left glyphs associated with any character in the
4958 text block, then create a display block to handle them. */
4959 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
4960 create_left_glyph_block (w, dl, 0);
4962 /* If there are right glyphs associated with any character in the
4963 text block, then create a display block to handle them. */
4964 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
4965 create_right_glyph_block (w, dl);
4970 /* This is ripped off from regenerate_window. All we want to do is
4971 loop through elements in the string creating display lines until we
4972 have covered the provided area. Simple really. */
4974 generate_displayable_area (struct window *w, Lisp_Object disp_string,
4975 int xpos, int ypos, int width, int height,
4976 display_line_dynarr* dla,
4978 face_index default_face)
4980 int yend = ypos + height;
4983 prop_block_dynarr *prop = 0;
4984 layout_bounds bounds;
4988 /* if there's nothing to do then do nothing. code after this assumes
4989 there is something to do. */
4990 if (NILP (disp_string))
4993 s_zv = XSTRING_CHAR_LENGTH (disp_string);
4995 bounds.left_out = xpos;
4996 bounds.right_out = xpos + width;
4997 /* The inner boundaries mark where the glyph margins are located. */
4998 bounds.left_in = bounds.left_out + window_left_margin_width (w);
4999 bounds.right_in = bounds.right_out - window_right_margin_width (w);
5000 /* We cannot fully calculate the whitespace boundaries as they
5001 depend on the contents of the line being displayed. */
5002 bounds.left_white = bounds.left_in;
5003 bounds.right_white = bounds.right_in;
5007 struct display_line dl;
5008 struct display_line *dlp;
5012 if (Dynarr_length (dla) < Dynarr_largest (dla))
5014 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5025 dlp->bounds = bounds;
5027 next_pos = generate_string_display_line (w, disp_string, dlp, start_pos,
5028 &prop, default_face);
5029 /* we need to make sure that we continue along the line if there
5030 is more left to display otherwise we just end up redisplaying
5031 the same chunk over and over again. */
5032 if (next_pos == start_pos && next_pos < s_zv)
5035 start_pos = next_pos;
5037 dlp->ypos = ypos + dlp->ascent;
5038 ypos = dlp->ypos + dlp->descent;
5042 int visible_height = dlp->ascent + dlp->descent;
5044 dlp->clip = (ypos - yend);
5045 visible_height -= dlp->clip;
5047 if (visible_height < VERTICAL_CLIP (w, 1))
5050 free_display_line (dlp);
5057 Dynarr_add (dla, *dlp);
5059 /* #### This type of check needs to be done down in the
5060 generate_display_line call. */
5061 if (start_pos >= s_zv)
5070 /***************************************************************************/
5072 /* window-regeneration routines */
5074 /***************************************************************************/
5076 /* For a given window and starting position in the buffer it contains,
5077 ensure that the TYPE display lines accurately represent the
5078 presentation of the window. We pass the buffer instead of getting
5079 it from the window since redisplay_window may have temporarily
5080 changed it to the echo area buffer. */
5083 regenerate_window (struct window *w, Bufpos start_pos, Bufpos point, int type)
5085 struct frame *f = XFRAME (w->frame);
5086 struct buffer *b = XBUFFER (w->buffer);
5087 int ypos = WINDOW_TEXT_TOP (w);
5088 int yend; /* set farther down */
5089 int yclip = WINDOW_TEXT_TOP_CLIP (w);
5092 prop_block_dynarr *prop;
5093 layout_bounds bounds;
5094 display_line_dynarr *dla;
5097 /* The lines had better exist by this point. */
5098 if (!(dla = window_display_lines (w, type)))
5101 w->max_line_len = 0;
5103 /* Normally these get updated in redisplay_window but it is possible
5104 for this function to get called from some other points where that
5105 update may not have occurred. This acts as a safety check. */
5106 if (!Dynarr_length (w->face_cachels))
5107 reset_face_cachels (w);
5108 if (!Dynarr_length (w->glyph_cachels))
5109 reset_glyph_cachels (w);
5111 Fset_marker (w->start[type], make_int (start_pos), w->buffer);
5112 Fset_marker (w->pointm[type], make_int (point), w->buffer);
5113 w->last_point_x[type] = -1;
5114 w->last_point_y[type] = -1;
5116 /* Make sure a modeline is in the structs if needed. */
5117 need_modeline = ensure_modeline_generated (w, type);
5119 /* Wait until here to set this so that the structs have a modeline
5120 generated in the case where one didn't exist. */
5121 yend = WINDOW_TEXT_BOTTOM (w);
5123 bounds = calculate_display_line_boundaries (w, 0);
5125 /* 97/3/14 jhod: stuff added here to support pre-prompts (used for input systems) */
5126 if (MINI_WINDOW_P (w)
5127 && (!NILP (Vminibuf_prompt) || !NILP (Vminibuf_preprompt))
5128 && !echo_area_active (f)
5129 && start_pos == BUF_BEGV (b))
5131 struct prop_block pb;
5133 prop = Dynarr_new (prop_block);
5135 string = concat2(Vminibuf_preprompt, Vminibuf_prompt);
5136 pb.type = PROP_MINIBUF_PROMPT;
5137 pb.data.p_string.str = XSTRING_DATA(string);
5138 pb.data.p_string.len = XSTRING_LENGTH(string);
5139 Dynarr_add (prop, pb);
5144 /* When we are computing things for scrolling purposes, make
5145 sure at least one line is always generated */
5146 force = (type == CMOTION_DISP);
5148 /* Make sure this is set always */
5149 /* Note the conversion at end */
5150 w->window_end_pos[type] = start_pos;
5151 while (ypos < yend || force)
5153 struct display_line dl;
5154 struct display_line *dlp;
5157 if (Dynarr_length (dla) < Dynarr_largest (dla))
5159 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5170 dlp->bounds = bounds;
5172 start_pos = generate_display_line (w, dlp, 1, start_pos, &prop, type);
5174 if (yclip > dlp->ascent)
5176 /* this should never happen, but if it does just display the
5181 dlp->ypos = (ypos + dlp->ascent) - yclip;
5182 ypos = dlp->ypos + dlp->descent;
5184 /* See if we've been asked to start midway through a line, for
5185 partial display line scrolling. */
5188 dlp->top_clip = yclip;
5196 int visible_height = dlp->ascent + dlp->descent;
5198 dlp->clip = (ypos - yend);
5199 /* Although this seems strange we could have a single very
5200 tall line visible for which we need to account for both
5201 the top clip and the bottom clip. */
5202 visible_height -= (dlp->clip + dlp->top_clip);
5204 if (visible_height < VERTICAL_CLIP (w, 1) && !force)
5207 free_display_line (dlp);
5214 if (dlp->cursor_elt != -1)
5216 /* #### This check is steaming crap. Have to get things
5217 fixed so when create_text_block hits EOB, we're done,
5219 if (w->last_point_x[type] == -1)
5221 w->last_point_x[type] = dlp->cursor_elt;
5222 w->last_point_y[type] = Dynarr_length (dla);
5226 /* #### This means that we've added a cursor at EOB
5227 twice. Yuck oh yuck. */
5228 struct display_block *db =
5229 get_display_block_from_line (dlp, TEXT);
5231 Dynarr_atp (db->runes, dlp->cursor_elt)->cursor_type = NO_CURSOR;
5232 dlp->cursor_elt = -1;
5236 if (dlp->num_chars > w->max_line_len)
5237 w->max_line_len = dlp->num_chars;
5239 Dynarr_add (dla, *dlp);
5241 /* #### This isn't right, but it is close enough for now. */
5242 w->window_end_pos[type] = start_pos;
5244 /* #### This type of check needs to be done down in the
5245 generate_display_line call. */
5246 if (start_pos > BUF_ZV (b))
5255 /* #### More not quite right, but close enough. */
5256 /* Ben sez: apparently window_end_pos[] is measured
5257 as the number of characters between the window end and the
5258 end of the buffer? This seems rather weirdo. What's
5259 the justification for this?
5261 JV sez: Because BUF_Z (b) would be a good initial value, however
5262 that can change. This representation allows initalizing with 0.
5264 w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type];
5268 /* We know that this is the right thing to use because we put it
5269 there when we first started working in this function. */
5270 generate_modeline (w, Dynarr_atp (dla, 0), type);
5274 #define REGEN_INC_FIND_START_END \
5276 /* Determine start and end of lines. */ \
5277 if (!Dynarr_length (cdla)) \
5281 if (Dynarr_atp (cdla, 0)->modeline && Dynarr_atp (ddla, 0)->modeline) \
5285 else if (!Dynarr_atp (cdla, 0)->modeline \
5286 && !Dynarr_atp (ddla, 0)->modeline) \
5291 abort (); /* structs differ */ \
5293 dla_end = Dynarr_length (cdla) - 1; \
5296 start_pos = (Dynarr_atp (cdla, dla_start)->bufpos \
5297 + Dynarr_atp (cdla, dla_start)->offset); \
5298 /* If this isn't true, then startp has changed and we need to do a \
5300 if (startp != start_pos) \
5303 /* Point is outside the visible region so give up. */ \
5304 if (pointm < start_pos) \
5309 /* This attempts to incrementally update the display structures. It
5310 returns a boolean indicating success or failure. This function is
5311 very similar to regenerate_window_incrementally and is in fact only
5312 called from that function. However, because of the nature of the
5313 changes it deals with it sometimes makes different assumptions
5314 which can lead to success which are much more difficult to make
5315 when dealing with buffer changes. */
5318 regenerate_window_extents_only_changed (struct window *w, Bufpos startp,
5320 Charcount beg_unchanged,
5321 Charcount end_unchanged)
5323 struct buffer *b = XBUFFER (w->buffer);
5324 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5325 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5329 int first_line, last_line;
5331 /* Don't define this in the loop where it is used because we
5332 definitely want its value to survive between passes. */
5333 prop_block_dynarr *prop = NULL;
5335 /* If we don't have any buffer change recorded but the modiff flag has
5336 been incremented, then fail. I'm not sure of the exact circumstances
5337 under which this can happen, but I believe that it is probably a
5338 reasonable happening. */
5339 if (!point_visible (w, pointm, CURRENT_DISP)
5340 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b))
5343 /* If the cursor is moved we attempt to update it. If we succeed we
5344 go ahead and proceed with the optimization attempt. */
5345 if (!EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5346 || pointm != marker_position (w->last_point[CURRENT_DISP]))
5348 struct frame *f = XFRAME (w->frame);
5349 struct device *d = XDEVICE (f->device);
5350 struct frame *sel_f = device_selected_frame (d);
5353 if (w->last_point_x[CURRENT_DISP] != -1
5354 && w->last_point_y[CURRENT_DISP] != -1)
5357 if (redisplay_move_cursor (w, pointm, WINDOW_TTY_P (w)))
5359 /* Always regenerate the modeline in case it is
5360 displaying the current line or column. */
5361 regenerate_modeline (w);
5365 else if (w != XWINDOW (FRAME_SELECTED_WINDOW (sel_f)))
5367 if (f->modeline_changed)
5368 regenerate_modeline (w);
5376 if (beg_unchanged == -1 && end_unchanged == -1)
5379 /* assert: There are no buffer modifications or they are all below the
5380 visible region. We assume that regenerate_window_incrementally has
5381 not called us unless this is true. */
5383 REGEN_INC_FIND_START_END;
5385 /* If the changed are starts before the visible area, give up. */
5386 if (beg_unchanged < startp)
5389 /* Find what display line the extent changes first affect. */
5391 while (line <= dla_end)
5393 struct display_line *dl = Dynarr_atp (cdla, line);
5394 Bufpos lstart = dl->bufpos + dl->offset;
5395 Bufpos lend = dl->end_bufpos + dl->offset;
5397 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5403 /* If the changes are below the visible area then if point hasn't
5404 moved return success otherwise fail in order to be safe. */
5407 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5408 && pointm == marker_position (w->last_point[CURRENT_DISP]))
5414 /* At this point we know what line the changes first affect. We now
5415 begin redrawing lines as long as we are still in the affected
5416 region and the line's size and positioning don't change.
5417 Otherwise we fail. If we fail we will have altered the desired
5418 structs which could lead to an assertion failure. However, if we
5419 fail the next thing that is going to happen is a full regen so we
5420 will actually end up being safe. */
5421 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5422 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5423 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
5424 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
5426 first_line = last_line = line;
5427 while (line <= dla_end)
5429 Bufpos old_start, old_end, new_start;
5430 struct display_line *cdl = Dynarr_atp (cdla, line);
5431 struct display_line *ddl = Dynarr_atp (ddla, line);
5432 struct display_block *db;
5435 assert (cdl->bufpos == ddl->bufpos);
5436 assert (cdl->end_bufpos == ddl->end_bufpos);
5437 assert (cdl->offset == ddl->offset);
5439 db = get_display_block_from_line (ddl, TEXT);
5440 initial_size = Dynarr_length (db->runes);
5441 old_start = ddl->bufpos + ddl->offset;
5442 old_end = ddl->end_bufpos + ddl->offset;
5444 /* If this is the first line being updated and it used
5445 propagation data, fail. Otherwise we'll be okay because
5446 we'll have the necessary propagation data. */
5447 if (line == first_line && ddl->used_prop_data)
5450 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5451 &prop, DESIRED_DISP);
5454 /* #### If there is propagated stuff the fail. We could
5455 probably actually deal with this if the line had propagated
5456 information when originally created by a full
5464 /* If any line position parameters have changed or a
5465 cursor has disappeared or disappeared, fail. */
5466 db = get_display_block_from_line (ddl, TEXT);
5467 if (cdl->ypos != ddl->ypos
5468 || cdl->ascent != ddl->ascent
5469 || cdl->descent != ddl->descent
5470 || cdl->top_clip != ddl->top_clip
5471 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5472 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1)
5473 || old_start != ddl->bufpos
5474 || old_end != ddl->end_bufpos
5475 || initial_size != Dynarr_length (db->runes))
5480 if (ddl->cursor_elt != -1)
5482 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5483 w->last_point_y[DESIRED_DISP] = line;
5488 /* If the extent changes end on the line we just updated then
5489 we're done. Otherwise go on to the next line. */
5490 if (end_unchanged <= ddl->end_bufpos)
5496 redisplay_update_line (w, first_line, last_line, 1);
5500 /* Attempt to update the display data structures based on knowledge of
5501 the changed region in the buffer. Returns a boolean indicating
5502 success or failure. If this function returns a failure then a
5503 regenerate_window _must_ be performed next in order to maintain
5504 invariants located here. */
5507 regenerate_window_incrementally (struct window *w, Bufpos startp,
5510 struct buffer *b = XBUFFER (w->buffer);
5511 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5512 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5513 Charcount beg_unchanged, end_unchanged;
5514 Charcount extent_beg_unchanged, extent_end_unchanged;
5520 /* If this function is called, the current and desired structures
5521 had better be identical. If they are not, then that is a bug. */
5522 assert (Dynarr_length (cdla) == Dynarr_length (ddla));
5524 /* We don't handle minibuffer windows yet. The minibuffer prompt
5526 if (MINI_WINDOW_P (w))
5529 extent_beg_unchanged = BUF_EXTENT_BEGIN_UNCHANGED (b);
5530 extent_end_unchanged = (BUF_EXTENT_END_UNCHANGED (b) == -1
5532 : BUF_Z (b) - BUF_EXTENT_END_UNCHANGED (b));
5534 /* If nothing has changed in the buffer, then make sure point is ok
5536 if (BUF_BEGIN_UNCHANGED (b) == -1 && BUF_END_UNCHANGED (b) == -1)
5537 return regenerate_window_extents_only_changed (w, startp, pointm,
5538 extent_beg_unchanged,
5539 extent_end_unchanged);
5541 /* We can't deal with deleted newlines. */
5542 if (BUF_NEWLINE_WAS_DELETED (b))
5545 beg_unchanged = BUF_BEGIN_UNCHANGED (b);
5546 end_unchanged = (BUF_END_UNCHANGED (b) == -1
5548 : BUF_Z (b) - BUF_END_UNCHANGED (b));
5550 REGEN_INC_FIND_START_END;
5552 /* If the changed area starts before the visible area, give up. */
5553 if (beg_unchanged < startp)
5556 /* Find what display line the buffer changes first affect. */
5558 while (line <= dla_end)
5560 struct display_line *dl = Dynarr_atp (cdla, line);
5561 Bufpos lstart = dl->bufpos + dl->offset;
5562 Bufpos lend = dl->end_bufpos + dl->offset;
5564 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5570 /* If the changes are below the visible area then if point hasn't
5571 moved return success otherwise fail in order to be safe. */
5573 return regenerate_window_extents_only_changed (w, startp, pointm,
5574 extent_beg_unchanged,
5575 extent_end_unchanged);
5577 /* At this point we know what line the changes first affect. We
5578 now redraw that line. If the changes are contained within it
5579 we are going to succeed and can update just that one line.
5580 Otherwise we fail. If we fail we will have altered the desired
5581 structs which could lead to an assertion failure. However, if
5582 we fail the next thing that is going to happen is a full regen
5583 so we will actually end up being safe. */
5586 prop_block_dynarr *prop = NULL;
5587 struct display_line *cdl = Dynarr_atp (cdla, line);
5588 struct display_line *ddl = Dynarr_atp (ddla, line);
5590 assert (cdl->bufpos == ddl->bufpos);
5591 assert (cdl->end_bufpos == ddl->end_bufpos);
5592 assert (cdl->offset == ddl->offset);
5594 /* If the line continues to next display line, fail. */
5595 if (ddl->line_continuation)
5598 /* If the line was generated using propagation data, fail. */
5599 if (ddl->used_prop_data)
5602 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5603 &prop, DESIRED_DISP);
5606 /* If there is propagated stuff then it is pretty much a
5607 guarantee that more than just the one line is affected. */
5614 /* If the line continues to next display line, fail. */
5615 if (ddl->line_continuation)
5618 /* If any line position parameters have changed or a
5619 cursor has disappeared or disappeared, fail. */
5620 if (cdl->ypos != ddl->ypos
5621 || cdl->ascent != ddl->ascent
5622 || cdl->descent != ddl->descent
5623 || cdl->top_clip != ddl->top_clip
5624 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5625 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1))
5630 /* If the changed area also ends on this line, then we may be in
5631 business. Update everything and return success. */
5632 if (end_unchanged >= ddl->bufpos && end_unchanged <= ddl->end_bufpos)
5634 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5635 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5636 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp),
5638 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm),
5641 if (ddl->cursor_elt != -1)
5643 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5644 w->last_point_y[DESIRED_DISP] = line;
5647 redisplay_update_line (w, line, line, 1);
5648 regenerate_modeline (w);
5650 /* #### For now we just flush the cache until this has been
5651 tested. After that is done, this should correct the
5653 Dynarr_reset (w->line_start_cache);
5655 /* Adjust the extent changed boundaries to remove any
5656 overlap with the buffer changes since we've just
5657 successfully updated that area. */
5658 if (extent_beg_unchanged != -1
5659 && extent_beg_unchanged >= beg_unchanged
5660 && extent_beg_unchanged < end_unchanged)
5661 extent_beg_unchanged = end_unchanged;
5663 if (extent_end_unchanged != -1
5664 && extent_end_unchanged >= beg_unchanged
5665 && extent_end_unchanged < end_unchanged)
5666 extent_end_unchanged = beg_unchanged - 1;
5668 if (extent_end_unchanged <= extent_beg_unchanged)
5669 extent_beg_unchanged = extent_end_unchanged = -1;
5671 /* This could lead to odd results if it fails, but since the
5672 buffer changes update succeeded this probably will to.
5673 We already know that the extent changes start at or after
5674 the line because we checked before entering the loop. */
5675 if (extent_beg_unchanged != -1
5676 && extent_end_unchanged != -1
5677 && ((extent_beg_unchanged < ddl->bufpos)
5678 || (extent_end_unchanged > ddl->end_bufpos)))
5679 return regenerate_window_extents_only_changed (w, startp, pointm,
5680 extent_beg_unchanged,
5681 extent_end_unchanged);
5691 /* Given a window and a point, update the given display lines such
5692 that point is displayed in the middle of the window.
5693 Return the window's new start position. */
5696 regenerate_window_point_center (struct window *w, Bufpos point, int type)
5700 /* We need to make sure that the modeline is generated so that the
5701 window height can be calculated correctly. */
5702 ensure_modeline_generated (w, type);
5704 startp = start_with_line_at_pixpos (w, point, window_half_pixpos (w));
5705 regenerate_window (w, startp, point, type);
5706 Fset_marker (w->start[type], make_int (startp), w->buffer);
5711 /* Given a window and a set of display lines, return a boolean
5712 indicating whether the given point is contained within. */
5715 point_visible (struct window *w, Bufpos point, int type)
5717 struct buffer *b = XBUFFER (w->buffer);
5718 display_line_dynarr *dla = window_display_lines (w, type);
5721 if (Dynarr_length (dla) && Dynarr_atp (dla, 0)->modeline)
5726 if (Dynarr_length (dla) > first_line)
5729 struct display_line *dl = Dynarr_atp (dla, first_line);
5732 end = BUF_Z (b) - w->window_end_pos[type] - 1;
5734 if (point >= start && point <= end)
5736 if (!MINI_WINDOW_P (w) && scroll_on_clipped_lines)
5738 dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
5740 if (point >= (dl->bufpos + dl->offset)
5741 && point <= (dl->end_bufpos + dl->offset))
5756 /* Return pixel position the middle of the window, not including the
5757 modeline and any potential horizontal scrollbar. */
5760 window_half_pixpos (struct window *w)
5762 return WINDOW_TEXT_TOP (w) + (WINDOW_TEXT_HEIGHT (w) >> 1);
5765 /* Return the display line which is currently in the middle of the
5766 window W for display lines TYPE. */
5769 line_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5771 display_line_dynarr *dla;
5774 int first_elt = (MINI_WINDOW_P (w) ? 0 : 1);
5776 if (type == CMOTION_DISP)
5777 regenerate_window (w, start, point, type);
5779 dla = window_display_lines (w, type);
5780 half = window_half_pixpos (w);
5782 for (elt = first_elt; elt < Dynarr_length (dla); elt++)
5784 struct display_line *dl = Dynarr_atp (dla, elt);
5785 int line_bot = dl->ypos + dl->descent;
5787 if (line_bot > half)
5791 /* We may not have a line at the middle if the end of the buffer is
5796 /* Return a value for point that would place it at the beginning of
5797 the line which is in the middle of the window. */
5800 point_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5802 /* line_at_center will regenerate the display structures, if necessary. */
5803 int line = line_at_center (w, type, start, point);
5806 return BUF_ZV (XBUFFER (w->buffer));
5809 display_line_dynarr *dla = window_display_lines (w, type);
5810 struct display_line *dl = Dynarr_atp (dla, line);
5816 /* For a given window, ensure that the current visual representation
5820 redisplay_window (Lisp_Object window, int skip_selected)
5822 struct window *w = XWINDOW (window);
5823 struct frame *f = XFRAME (w->frame);
5824 struct device *d = XDEVICE (f->device);
5825 Lisp_Object old_buffer = w->buffer;
5826 Lisp_Object the_buffer = w->buffer;
5828 int echo_active = 0;
5833 int selected_in_its_frame;
5834 int selected_globally;
5835 int skip_output = 0;
5836 int truncation_changed;
5837 int inactive_minibuffer =
5838 (MINI_WINDOW_P (w) &&
5839 (f != device_selected_frame (d)) &&
5840 !is_surrogate_for_selected_frame (f));
5842 /* #### In the new world this function actually does a bunch of
5843 optimizations such as buffer-based scrolling, but none of that is
5846 /* If this is a combination window, do its children; that's all.
5847 The selected window is always a leaf so we don't check for
5848 skip_selected here. */
5849 if (!NILP (w->vchild))
5851 redisplay_windows (w->vchild, skip_selected);
5854 if (!NILP (w->hchild))
5856 redisplay_windows (w->hchild, skip_selected);
5860 /* Is this window the selected window on its frame? */
5861 selected_in_its_frame = (w == XWINDOW (FRAME_SELECTED_WINDOW (f)));
5863 selected_in_its_frame &&
5864 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
5865 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d &&
5866 XFRAME(DEVICE_SELECTED_FRAME(d)) == f;
5867 if (skip_selected && selected_in_its_frame)
5870 /* It is possible that the window is not fully initialized yet. */
5871 if (NILP (w->buffer))
5874 if (MINI_WINDOW_P (w) && echo_area_active (f))
5876 w->buffer = the_buffer = Vecho_area_buffer;
5880 b = XBUFFER (w->buffer);
5884 old_pointm = selected_globally
5886 : marker_position (w->pointm[CURRENT_DISP]);
5891 if (selected_globally)
5893 pointm = BUF_PT (b);
5897 pointm = marker_position (w->pointm[CURRENT_DISP]);
5899 if (pointm < BUF_BEGV (b))
5900 pointm = BUF_BEGV (b);
5901 else if (pointm > BUF_ZV (b))
5902 pointm = BUF_ZV (b);
5905 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm), the_buffer);
5907 /* If the buffer has changed we have to invalidate all of our face
5909 if ((!echo_active && b != window_display_buffer (w))
5910 || !Dynarr_length (w->face_cachels)
5911 || f->faces_changed)
5912 reset_face_cachels (w);
5914 mark_face_cachels_as_not_updated (w);
5916 /* Ditto the glyph cache elements, although we do *not* invalidate
5917 the cache purely because glyphs have changed - this is now
5918 handled by the dirty flag.*/
5919 if ((!echo_active && b != window_display_buffer (w))
5920 || !Dynarr_length (w->glyph_cachels) || f->faces_changed)
5921 reset_glyph_cachels (w);
5923 mark_glyph_cachels_as_not_updated (w);
5925 /* If the marker's buffer is not the window's buffer, then we need
5926 to find a new starting position. */
5927 if (!MINI_WINDOW_P (w)
5928 && !EQ (Fmarker_buffer (w->start[CURRENT_DISP]), w->buffer))
5930 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
5932 goto regeneration_done;
5937 old_startp = marker_position (w->start[CURRENT_DISP]);
5942 startp = marker_position (w->start[CURRENT_DISP]);
5943 if (startp < BUF_BEGV (b))
5944 startp = BUF_BEGV (b);
5945 else if (startp > BUF_ZV (b))
5946 startp = BUF_ZV (b);
5948 Fset_marker (w->start[DESIRED_DISP], make_int (startp), the_buffer);
5950 truncation_changed = (find_window_mirror (w)->truncate_win !=
5951 window_truncation_on (w));
5953 /* If w->force_start is set, then some function set w->start and we
5954 should display from there and change point, if necessary, to
5955 ensure that it is visible. */
5956 if (w->force_start || inactive_minibuffer)
5959 w->last_modified[DESIRED_DISP] = Qzero;
5960 w->last_facechange[DESIRED_DISP] = Qzero;
5962 regenerate_window (w, startp, pointm, DESIRED_DISP);
5964 if (!point_visible (w, pointm, DESIRED_DISP) && !inactive_minibuffer)
5966 pointm = point_at_center (w, DESIRED_DISP, 0, 0);
5968 if (selected_globally)
5969 BUF_SET_PT (b, pointm);
5971 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm),
5974 /* #### BUFU amounts of overkill just to get the cursor
5975 location marked properly. FIX ME FIX ME FIX ME */
5976 regenerate_window (w, startp, pointm, DESIRED_DISP);
5979 goto regeneration_done;
5982 /* If nothing has changed since the last redisplay, then we just
5983 need to make sure that point is still visible. */
5984 if (XINT (w->last_modified[CURRENT_DISP]) >= BUF_MODIFF (b)
5985 && XINT (w->last_facechange[CURRENT_DISP]) >= BUF_FACECHANGE (b)
5987 /* This check is to make sure we restore the minibuffer after a
5988 temporary change to the echo area. */
5989 && !(MINI_WINDOW_P (w) && f->buffers_changed)
5990 && !f->frame_changed
5991 && !truncation_changed
5992 /* check whether start is really at the beginning of a line GE */
5993 && (!w->start_at_line_beg || beginning_of_line_p (b, startp))
5996 /* Check if the cursor has actually moved. */
5997 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5998 && pointm == marker_position (w->last_point[CURRENT_DISP])
5999 && selected_globally
6000 && !w->windows_changed
6002 && !f->extents_changed
6003 && !f->faces_changed
6004 && !f->glyphs_changed
6005 && !f->subwindows_changed
6006 /* && !f->subwindows_state_changed*/
6007 && !f->point_changed
6008 && !f->windows_structure_changed)
6010 /* If not, we're done. */
6011 if (f->modeline_changed)
6012 regenerate_modeline (w);
6015 goto regeneration_done;
6019 /* If the new point is visible in the redisplay structures,
6020 then let the output update routines handle it, otherwise
6021 do things the hard way. */
6022 if (!w->windows_changed
6024 && !f->extents_changed
6025 && !f->faces_changed
6026 && !f->glyphs_changed
6027 && !f->subwindows_changed
6028 /* && !f->subwindows_state_changed*/
6029 && !f->windows_structure_changed)
6031 if (point_visible (w, pointm, CURRENT_DISP)
6032 && w->last_point_x[CURRENT_DISP] != -1
6033 && w->last_point_y[CURRENT_DISP] != -1)
6035 if (redisplay_move_cursor (w, pointm, FRAME_TTY_P (f)))
6037 /* Always regenerate in case it is displaying
6038 the current line or column. */
6039 regenerate_modeline (w);
6042 goto regeneration_done;
6045 else if (!selected_in_its_frame && !f->point_changed)
6047 if (f->modeline_changed)
6048 regenerate_modeline (w);
6051 goto regeneration_done;
6055 /* If we weren't able to take the shortcut method, then use
6056 the brute force method. */
6057 regenerate_window (w, startp, pointm, DESIRED_DISP);
6059 if (point_visible (w, pointm, DESIRED_DISP))
6060 goto regeneration_done;
6064 /* Check if the starting point is no longer at the beginning of a
6065 line, in which case find a new starting point. We also recenter
6066 if our start position is equal to point-max. Otherwise we'll end
6067 up with a blank window. */
6068 else if (((w->start_at_line_beg || MINI_WINDOW_P (w))
6069 && !(startp == BUF_BEGV (b)
6070 || BUF_FETCH_CHAR (b, startp - 1) == '\n'))
6071 || (pointm == startp &&
6072 EQ (Fmarker_buffer (w->last_start[CURRENT_DISP]), w->buffer) &&
6073 startp < marker_position (w->last_start[CURRENT_DISP]))
6074 || (startp == BUF_ZV (b)))
6076 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6078 goto regeneration_done;
6080 /* See if we can update the data structures locally based on
6081 knowledge of what changed in the buffer. */
6082 else if (!w->windows_changed
6084 && !f->faces_changed
6085 && !f->glyphs_changed
6086 && !f->subwindows_changed
6087 /* && !f->subwindows_state_changed*/
6088 && !f->windows_structure_changed
6089 && !f->frame_changed
6090 && !truncation_changed
6092 && regenerate_window_incrementally (w, startp, pointm))
6094 if (f->modeline_changed
6095 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b)
6096 || XINT (w->last_facechange[CURRENT_DISP]) < BUF_FACECHANGE (b))
6097 regenerate_modeline (w);
6100 goto regeneration_done;
6102 /* #### This is where a check for structure based scrolling would go. */
6103 /* If all else fails, try just regenerating and see what happens. */
6106 regenerate_window (w, startp, pointm, DESIRED_DISP);
6108 if (point_visible (w, pointm, DESIRED_DISP))
6109 goto regeneration_done;
6112 /* We still haven't gotten the window regenerated with point
6113 visible. Next we try scrolling a little and see if point comes
6114 back onto the screen. */
6115 if (scroll_step > 0)
6117 int scrolled = scroll_conservatively;
6118 for (; scrolled >= 0; scrolled -= scroll_step)
6120 startp = vmotion (w, startp,
6121 (pointm < startp) ? -scroll_step : scroll_step, 0);
6122 regenerate_window (w, startp, pointm, DESIRED_DISP);
6124 if (point_visible (w, pointm, DESIRED_DISP))
6125 goto regeneration_done;
6129 /* We still haven't managed to get the screen drawn with point on
6130 the screen, so just center it and be done with it. */
6131 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6136 /* If the window's frame is changed then reset the current display
6137 lines in order to force a full repaint. */
6138 if (f->frame_changed)
6140 display_line_dynarr *cla = window_display_lines (w, CURRENT_DISP);
6145 /* Must do this before calling redisplay_output_window because it
6146 sets some markers on the window. */
6149 w->buffer = old_buffer;
6150 Fset_marker (w->pointm[DESIRED_DISP], make_int (old_pointm), old_buffer);
6151 Fset_marker (w->start[DESIRED_DISP], make_int (old_startp), old_buffer);
6154 /* These also have to be set before calling redisplay_output_window
6155 since it sets the CURRENT_DISP values based on them. */
6156 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
6157 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
6158 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
6159 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
6163 Bufpos start = marker_position (w->start[DESIRED_DISP]);
6164 Bufpos end = (w->window_end_pos[DESIRED_DISP] == -1
6166 : BUF_Z (b) - w->window_end_pos[DESIRED_DISP] - 1);
6167 /* Don't pollute the cache if not sure if we are correct */
6168 if (w->start_at_line_beg)
6169 update_line_start_cache (w, start, end, pointm, 1);
6170 redisplay_output_window (w);
6172 * If we just displayed the echo area, the line start cache is
6173 * no longer valid, because the minibuffer window is associated
6174 * with the window now.
6177 w->line_cache_last_updated = make_int (-1);
6180 /* #### This should be dependent on face changes and will need to be
6181 somewhere else once tty updates occur on a per-frame basis. */
6182 mark_face_cachels_as_clean (w);
6184 /* The glyph cachels only get dirty if someone changed something.
6185 Since redisplay has now effectively ended we can reset the dirty
6186 flag since everything must be up-to-date. */
6188 mark_glyph_cachels_as_clean (w);
6190 w->windows_changed = 0;
6193 /* Call buffer_reset_changes for all buffers present in any window
6194 currently visible in all frames on all devices. #### There has to
6195 be a better way to do this. */
6198 reset_buffer_changes_mapfun (struct window *w, void *ignored_closure)
6200 buffer_reset_changes (XBUFFER (w->buffer));
6205 reset_buffer_changes (void)
6207 Lisp_Object frmcons, devcons, concons;
6209 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
6211 struct frame *f = XFRAME (XCAR (frmcons));
6213 if (FRAME_REPAINT_P (f))
6214 map_windows (f, reset_buffer_changes_mapfun, 0);
6218 /* Ensure that all windows underneath the given window in the window
6219 hierarchy are correctly displayed. */
6222 redisplay_windows (Lisp_Object window, int skip_selected)
6224 for (; !NILP (window) ; window = XWINDOW (window)->next)
6226 redisplay_window (window, skip_selected);
6231 call_redisplay_end_triggers (struct window *w, void *closure)
6233 Bufpos lrpos = w->last_redisplay_pos;
6234 w->last_redisplay_pos = 0;
6235 if (!NILP (w->buffer)
6236 && !NILP (w->redisplay_end_trigger)
6241 if (MARKERP (w->redisplay_end_trigger)
6242 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
6243 pos = marker_position (w->redisplay_end_trigger);
6244 else if (INTP (w->redisplay_end_trigger))
6245 pos = XINT (w->redisplay_end_trigger);
6248 w->redisplay_end_trigger = Qnil;
6255 XSETWINDOW (window, w);
6256 va_run_hook_with_args_in_buffer (XBUFFER (w->buffer),
6257 Qredisplay_end_trigger_functions,
6259 w->redisplay_end_trigger);
6260 w->redisplay_end_trigger = Qnil;
6267 /* Ensure that all windows on the given frame are correctly displayed. */
6270 redisplay_frame (struct frame *f, int preemption_check)
6272 struct device *d = XDEVICE (f->device);
6274 if (preemption_check)
6276 /* The preemption check itself takes a lot of time,
6277 so normally don't do it here. We do it if called
6278 from Lisp, though (`redisplay-frame'). */
6281 REDISPLAY_PREEMPTION_CHECK;
6286 if (!internal_equal (f->old_buffer_alist, f->buffer_alist, 0))
6290 f->old_buffer_alist = Freplace_list (f->old_buffer_alist,
6292 XSETFRAME (frame, f);
6293 va_run_hook_with_args (Qbuffer_list_changed_hook, 1, frame);
6296 /* Before we put a hold on frame size changes, attempt to process
6297 any which are already pending. */
6298 if (f->size_change_pending)
6299 change_frame_size (f, f->new_height, f->new_width, 0);
6301 /* If frame size might need to be changed, due to changed size
6302 of toolbars, scrollbars etc, change it now */
6303 if (f->size_slipped)
6305 adjust_frame_size (f);
6306 assert (!f->size_slipped);
6309 /* The menubar, toolbar, and icon updates must be done before
6310 hold_frame_size_changes is called and we are officially
6311 'in_display'. They may eval lisp code which may call Fsignal.
6312 If in_display is set Fsignal will abort. */
6314 #ifdef HAVE_MENUBARS
6315 /* Update the menubar. It is done first since it could change
6316 the menubar's visibility. This way we avoid having flashing
6317 caused by an Expose event generated by the visibility change
6319 update_frame_menubars (f);
6320 #endif /* HAVE_MENUBARS */
6321 #ifdef HAVE_TOOLBARS
6322 /* Update the toolbars. */
6323 update_frame_toolbars (f);
6324 #endif /* HAVE_TOOLBARS */
6325 /* Gutter update proper has to be done inside display when no frame
6326 size changes can occur, thus we separately update the gutter
6327 geometry here if it needs it. */
6328 update_frame_gutter_geometry (f);
6330 /* If we clear the frame we have to force its contents to be redrawn. */
6332 f->frame_changed = 1;
6334 /* Invalidate the subwindow caches. We use subwindows_changed here
6335 to cause subwindows to get instantiated. This is because
6336 subwindows_state_changed is less strict - dealing with things
6337 like the clicked state of button. We have to do this before
6338 redisplaying the gutters as subwindows get unmapped in the
6340 if (f->frame_changed)
6341 reset_frame_subwindow_instance_cache (f);
6343 if (f->frame_changed || f->subwindows_changed)
6345 /* we have to do this so the gutter gets regenerated. */
6346 reset_gutter_display_lines (f);
6349 hold_frame_size_changes ();
6351 /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */
6352 /* Within this section, we are defenseless and assume that the
6353 following cannot happen:
6355 1) garbage collection
6356 2) Lisp code evaluation
6357 3) frame size changes
6359 We ensure (3) by calling hold_frame_size_changes(), which
6360 will cause any pending frame size changes to get put on hold
6361 till after the end of the critical section. (1) follows
6362 automatically if (2) is met. #### Unfortunately, there are
6363 some places where Lisp code can be called within this section.
6364 We need to remove them.
6366 If Fsignal() is called during this critical section, we
6369 If garbage collection is called during this critical section,
6370 we simply return. #### We should abort instead.
6372 #### If a frame-size change does occur we should probably
6373 actually be preempting redisplay. */
6375 MAYBE_DEVMETH (d, frame_output_begin, (f));
6377 /* We can now update the gutters, safe in the knowledge that our
6378 efforts won't get undone. */
6380 /* This can call lisp, but redisplay is protected by binding
6381 inhibit_quit. More importantly the code involving display lines
6382 *assumes* that GC will not happen and so does not GCPRO
6383 anything. Since we use this code the whole time with the gutters
6384 we cannot allow GC to happen when manipulating the gutters. */
6385 update_frame_gutters (f);
6387 /* Erase the frame before outputting its contents. */
6390 MAYBE_DEVMETH (d, clear_frame, (f));
6393 /* Do the selected window first. */
6394 redisplay_window (FRAME_SELECTED_WINDOW (f), 0);
6396 /* Then do the rest. */
6397 redisplay_windows (f->root_window, 1);
6399 MAYBE_DEVMETH (d, frame_output_end, (f));
6401 update_frame_title (f);
6403 CLASS_RESET_CHANGED_FLAGS (f);
6404 f->window_face_cache_reset = 0;
6405 f->echo_area_garbaged = 0;
6408 if (!f->size_change_pending)
6409 f->size_changed = 0;
6411 /* ----------------- END CRITICAL REDISPLAY SECTION ---------------- */
6413 /* Allow frame size changes to occur again.
6415 #### what happens if changes to other frames happen? */
6416 unhold_one_frame_size_changes (f);
6418 map_windows (f, call_redisplay_end_triggers, 0);
6422 /* Ensure that all frames on the given device are correctly displayed.
6423 If AUTOMATIC is non-zero, and the device implementation indicates
6424 no automatic redisplay, as printers do, then the device is not
6425 redisplayed. AUTOMATIC is set to zero when called from lisp
6426 functions (redraw-device) and (redisplay-device), and to non-zero
6427 when called from "lazy" redisplay();
6431 redisplay_device (struct device *d, int automatic)
6433 Lisp_Object frame, frmcons;
6435 int size_change_failed = 0;
6439 && (MAYBE_INT_DEVMETH (d, device_implementation_flags, ())
6440 & XDEVIMPF_NO_AUTO_REDISPLAY))
6443 if (DEVICE_STREAM_P (d)) /* nothing to do */
6446 /* It is possible that redisplay has been called before the
6447 device is fully initialized. If so then continue with the
6449 if (NILP (DEVICE_SELECTED_FRAME (d)))
6452 REDISPLAY_PREEMPTION_CHECK;
6456 /* Always do the selected frame first. */
6457 frame = DEVICE_SELECTED_FRAME (d);
6461 if (f->icon_changed || f->windows_changed)
6462 update_frame_icon (f);
6464 if (FRAME_REPAINT_P (f))
6466 if (CLASS_REDISPLAY_FLAGS_CHANGEDP(f))
6468 preempted = redisplay_frame (f, 0);
6474 /* If the frame redisplay did not get preempted, then this flag
6475 should have gotten set to 0. It might be possible for that
6476 not to happen if a size change event were to occur at an odd
6477 time. To make sure we don't miss anything we simply don't
6478 reset the top level flags until the condition ends up being
6479 in the right state. */
6480 if (f->size_changed)
6481 size_change_failed = 1;
6484 DEVICE_FRAME_LOOP (frmcons, d)
6486 f = XFRAME (XCAR (frmcons));
6488 if (f == XFRAME (DEVICE_SELECTED_FRAME (d)))
6491 if (f->icon_changed || f->windows_changed)
6492 update_frame_icon (f);
6494 if (FRAME_REPAINT_P (f))
6496 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (f))
6498 preempted = redisplay_frame (f, 0);
6504 if (f->size_change_pending)
6505 size_change_failed = 1;
6509 /* If we get here then we redisplayed all of our frames without
6510 getting preempted so mark ourselves as clean. */
6511 CLASS_RESET_CHANGED_FLAGS (d);
6513 if (!size_change_failed)
6514 d->size_changed = 0;
6520 restore_profiling_redisplay_flag (Lisp_Object val)
6522 profiling_redisplay_flag = XINT (val);
6526 /* Ensure that all windows on all frames on all devices are displaying
6527 the current contents of their respective buffers. */
6530 redisplay_without_hooks (void)
6532 Lisp_Object devcons, concons;
6533 int size_change_failed = 0;
6534 int count = specpdl_depth ();
6536 if (profiling_active)
6538 record_unwind_protect (restore_profiling_redisplay_flag,
6539 make_int (profiling_redisplay_flag));
6540 profiling_redisplay_flag = 1;
6543 if (asynch_device_change_pending)
6544 handle_asynch_device_change ();
6546 if (!GLOBAL_REDISPLAY_FLAGS_CHANGEDP &&
6547 !disable_preemption && preemption_count < max_preempts)
6550 DEVICE_LOOP_NO_BREAK (devcons, concons)
6552 struct device *d = XDEVICE (XCAR (devcons));
6555 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (d))
6557 preempted = redisplay_device (d, 1);
6562 RESET_CHANGED_SET_FLAGS;
6566 /* See comment in redisplay_device. */
6567 if (d->size_changed)
6568 size_change_failed = 1;
6571 preemption_count = 0;
6573 /* Mark redisplay as accurate */
6574 GLOBAL_RESET_CHANGED_FLAGS;
6575 RESET_CHANGED_SET_FLAGS;
6579 mark_all_faces_as_clean ();
6583 if (!size_change_failed)
6586 reset_buffer_changes ();
6589 unbind_to (count, Qnil);
6595 if (last_display_warning_tick != display_warning_tick &&
6596 !inhibit_warning_display)
6598 /* If an error occurs during this function, oh well.
6599 If we report another warning, we could get stuck in an
6600 infinite loop reporting warnings. */
6601 call0_trapping_errors (0, Qdisplay_warning_buffer);
6602 last_display_warning_tick = display_warning_tick;
6604 /* The run_hook_trapping_errors functions are smart enough not
6605 to do any evalling if the hook function is empty, so there
6606 should not be any significant time loss. All places in the
6607 C code that call redisplay() are prepared to handle GCing,
6608 so we should be OK. */
6609 #ifndef INHIBIT_REDISPLAY_HOOKS
6610 run_hook_trapping_errors ("Error in pre-redisplay-hook",
6611 Qpre_redisplay_hook);
6612 #endif /* INHIBIT_REDISPLAY_HOOKS */
6614 redisplay_without_hooks ();
6616 #ifndef INHIBIT_REDISPLAY_HOOKS
6617 run_hook_trapping_errors ("Error in post-redisplay-hook",
6618 Qpost_redisplay_hook);
6619 #endif /* INHIBIT_REDISPLAY_HOOKS */
6623 static char window_line_number_buf[32];
6625 /* Efficiently determine the window line number, and return a pointer
6626 to its printed representation. Do this regardless of whether
6627 line-number-mode is on. The first line in the buffer is counted as
6628 1. If narrowing is in effect, the lines are counted from the
6629 beginning of the visible portion of the buffer. */
6631 window_line_number (struct window *w, int type)
6633 struct device *d = XDEVICE (XFRAME (w->frame)->device);
6634 struct buffer *b = XBUFFER (w->buffer);
6635 /* Be careful in the order of these tests. The first clause will
6636 fail if DEVICE_SELECTED_FRAME == Qnil (since w->frame cannot be).
6637 This can occur when the frame title is computed really early */
6639 ((EQ(DEVICE_SELECTED_FRAME(d), w->frame) &&
6640 (w == XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame(d)))) &&
6641 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
6642 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d )
6644 : marker_position (w->pointm[type]));
6647 line = buffer_line_number (b, pos, 1);
6649 long_to_string (window_line_number_buf, line + 1);
6651 return window_line_number_buf;
6655 /* Given a character representing an object in a modeline
6656 specification, return a string (stored into the global array
6657 `mode_spec_bufbyte_string') with the information that object
6660 This function is largely unchanged from previous versions of the
6663 Warning! This code is also used for frame titles and can be called
6664 very early in the device/frame update process! JV
6668 decode_mode_spec (struct window *w, Emchar spec, int type)
6670 Lisp_Object obj = Qnil;
6671 const char *str = NULL;
6672 struct buffer *b = XBUFFER (w->buffer);
6674 Dynarr_reset (mode_spec_bufbyte_string);
6678 /* print buffer name */
6683 /* print visited file name */
6688 /* print the current column */
6691 Bufpos pt = (w == XWINDOW (Fselected_window (Qnil)))
6693 : marker_position (w->pointm[type]);
6694 int col = column_at_point (b, pt, 1) + !!column_number_start_at_one;
6697 long_to_string (buf, col);
6699 Dynarr_add_many (mode_spec_bufbyte_string,
6700 (const Bufbyte *) buf, strlen (buf));
6702 goto decode_mode_spec_done;
6704 /* print the file coding system */
6708 Lisp_Object codesys = b->buffer_file_coding_system;
6709 /* Be very careful here not to get an error. */
6710 if (NILP (codesys) || SYMBOLP (codesys) || CODING_SYSTEMP (codesys))
6712 codesys = Ffind_coding_system (codesys);
6713 if (CODING_SYSTEMP (codesys))
6714 obj = XCODING_SYSTEM_MNEMONIC (codesys);
6717 #endif /* FILE_CODING */
6720 /* print the current line number */
6722 str = window_line_number (w, type);
6725 /* print value of mode-name (obsolete) */
6730 /* print hyphen and frame number, if != 1 */
6734 struct frame *f = XFRAME (w->frame);
6735 if (FRAME_TTY_P (f) && f->order_count > 1 && f->order_count <= 99999999)
6737 /* Naughty, naughty */
6738 char * writable_str = alloca_array (char, 10);
6739 sprintf (writable_str, "-%d", f->order_count);
6743 #endif /* HAVE_TTY */
6746 /* print Narrow if appropriate */
6748 if (BUF_BEGV (b) > BUF_BEG (b)
6749 || BUF_ZV (b) < BUF_Z (b))
6753 /* print %, * or hyphen, if buffer is read-only, modified or neither */
6755 str = (!NILP (b->read_only)
6757 : ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6762 /* print * or hyphen -- XEmacs change to allow a buffer to be
6763 read-only but still indicate whether it is modified. */
6765 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6767 : (!NILP (b->read_only)
6772 /* #### defined in 19.29 decode_mode_spec, but not in
6773 modeline-format doc string. */
6774 /* This differs from %* in that it ignores read-only-ness. */
6776 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6781 /* print process status */
6783 obj = Fget_buffer_process (w->buffer);
6785 str = GETTEXT ("no process");
6787 obj = Fsymbol_name (Fprocess_status (obj));
6790 /* Print name of selected frame. */
6792 obj = XFRAME (w->frame)->name;
6795 /* indicate TEXT or BINARY */
6797 /* #### NT does not use this any more. Now what? */
6801 /* print percent of buffer above top of window, or Top, Bot or All */
6804 Bufpos pos = marker_position (w->start[type]);
6806 /* This had better be while the desired lines are being done. */
6807 if (w->window_end_pos[type] <= BUF_Z (b) - BUF_ZV (b))
6809 if (pos <= BUF_BEGV (b))
6814 else if (pos <= BUF_BEGV (b))
6818 /* This hard limit is ok since the string it will hold has a
6819 fixed maximum length of 3. But just to be safe... */
6821 Charcount chars = pos - BUF_BEGV (b);
6822 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6824 /* Avoid overflow on big buffers */
6825 int percent = total > LONG_MAX/200 ?
6826 (chars + total/200) / (total / 100) :
6827 (chars * 100 + total/2) / total;
6829 /* We can't normally display a 3-digit number, so get us a
6830 2-digit number that is close. */
6834 sprintf (buf, "%d%%", percent);
6835 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6838 goto decode_mode_spec_done;
6843 /* print percent of buffer above bottom of window, perhaps plus
6844 Top, or print Bottom or All */
6847 Bufpos toppos = marker_position (w->start[type]);
6848 Bufpos botpos = BUF_Z (b) - w->window_end_pos[type];
6850 /* botpos is only accurate as of the last redisplay, so we can
6851 only treat it as a hint. In particular, after erase-buffer,
6852 botpos may be negative. */
6853 if (botpos < toppos)
6856 if (botpos >= BUF_ZV (b))
6858 if (toppos <= BUF_BEGV (b))
6865 /* This hard limit is ok since the string it will hold has a
6866 fixed maximum length of around 6. But just to be safe... */
6868 Charcount chars = botpos - BUF_BEGV (b);
6869 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6871 /* Avoid overflow on big buffers */
6872 int percent = total > LONG_MAX/200 ?
6873 (chars + total/200) / (total / 100) :
6874 (chars * 100 + total/2) / max (total, 1);
6876 /* We can't normally display a 3-digit number, so get us a
6877 2-digit number that is close. */
6881 if (toppos <= BUF_BEGV (b))
6882 sprintf (buf, "Top%d%%", percent);
6884 sprintf (buf, "%d%%", percent);
6886 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6889 goto decode_mode_spec_done;
6899 /* print one [ for each recursive editing level. */
6904 if (command_loop_level > 5)
6910 for (i = 0; i < command_loop_level; i++)
6911 Dynarr_add (mode_spec_bufbyte_string, '[');
6913 goto decode_mode_spec_done;
6916 /* print one ] for each recursive editing level. */
6921 if (command_loop_level > 5)
6927 for (i = 0; i < command_loop_level; i++)
6928 Dynarr_add (mode_spec_bufbyte_string, ']');
6930 goto decode_mode_spec_done;
6933 /* print infinitely many dashes -- handle at top level now */
6940 Dynarr_add_many (mode_spec_bufbyte_string,
6942 XSTRING_LENGTH (obj));
6944 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) str, strlen (str));
6946 decode_mode_spec_done:
6947 Dynarr_add (mode_spec_bufbyte_string, '\0');
6950 /* Given a display line, free all of its data structures. */
6953 free_display_line (struct display_line *dl)
6957 if (dl->display_blocks)
6959 for (block = 0; block < Dynarr_largest (dl->display_blocks); block++)
6961 struct display_block *db = Dynarr_atp (dl->display_blocks, block);
6963 Dynarr_free (db->runes);
6966 Dynarr_free (dl->display_blocks);
6967 dl->display_blocks = NULL;
6970 if (dl->left_glyphs)
6972 Dynarr_free (dl->left_glyphs);
6973 dl->left_glyphs = NULL;
6976 if (dl->right_glyphs)
6978 Dynarr_free (dl->right_glyphs);
6979 dl->right_glyphs = NULL;
6984 /* Given an array of display lines, free them and all data structures
6985 contained within them. */
6988 free_display_lines (display_line_dynarr *dla)
6992 for (line = 0; line < Dynarr_largest (dla); line++)
6994 free_display_line (Dynarr_atp (dla, line));
7000 /* Call internal free routine for each set of display lines. */
7003 free_display_structs (struct window_mirror *mir)
7005 if (mir->current_display_lines)
7007 free_display_lines (mir->current_display_lines);
7008 mir->current_display_lines = 0;
7011 if (mir->desired_display_lines)
7013 free_display_lines (mir->desired_display_lines);
7014 mir->desired_display_lines = 0;
7020 mark_glyph_block_dynarr (glyph_block_dynarr *gba)
7024 glyph_block *gb = Dynarr_atp (gba, 0);
7025 glyph_block *gb_last = Dynarr_atp (gba, Dynarr_length (gba));
7027 for (; gb < gb_last; gb++)
7029 if (!NILP (gb->glyph))
7030 mark_object (gb->glyph);
7031 if (!NILP (gb->extent))
7032 mark_object (gb->extent);
7037 /* See the comment in image_instantiate_cache_result as to why marking
7038 the glyph will also mark the image_instance. */
7040 mark_redisplay_structs (display_line_dynarr *dla)
7042 display_line *dl = Dynarr_atp (dla, 0);
7043 display_line *dl_last = Dynarr_atp (dla, Dynarr_length (dla));
7045 for (; dl < dl_last; dl++)
7047 display_block_dynarr *dba = dl->display_blocks;
7048 display_block *db = Dynarr_atp (dba, 0);
7049 display_block *db_last = Dynarr_atp (dba, Dynarr_length (dba));
7051 for (; db < db_last; db++)
7053 rune_dynarr *ra = db->runes;
7054 rune *r = Dynarr_atp (ra, 0);
7055 rune *r_last = Dynarr_atp (ra, Dynarr_length (ra));
7057 for (; r < r_last; r++)
7059 if (r->type == RUNE_DGLYPH)
7061 if (!NILP (r->object.dglyph.glyph))
7062 mark_object (r->object.dglyph.glyph);
7063 if (!NILP (r->object.dglyph.extent))
7064 mark_object (r->object.dglyph.extent);
7069 mark_glyph_block_dynarr (dl->left_glyphs);
7070 mark_glyph_block_dynarr (dl->right_glyphs);
7075 mark_window_mirror (struct window_mirror *mir)
7077 mark_redisplay_structs (mir->current_display_lines);
7078 mark_redisplay_structs (mir->desired_display_lines);
7081 mark_window_mirror (mir->next);
7084 mark_window_mirror (mir->hchild);
7085 else if (mir->vchild)
7086 mark_window_mirror (mir->vchild);
7090 mark_redisplay (void)
7092 Lisp_Object frmcons, devcons, concons;
7094 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
7096 struct frame *f = XFRAME (XCAR (frmcons));
7097 update_frame_window_mirror (f);
7098 mark_window_mirror (f->root_mirror);
7103 /*****************************************************************************
7104 Line Start Cache Description and Rationale
7106 The traditional scrolling code in Emacs breaks in a variable height world.
7107 It depends on the key assumption that the number of lines that can be
7108 displayed at any given time is fixed. This led to a complete separation
7109 of the scrolling code from the redisplay code. In order to fully support
7110 variable height lines, the scrolling code must actually be tightly
7111 integrated with redisplay. Only redisplay can determine how many lines
7112 will be displayed on a screen for any given starting point.
7114 What is ideally wanted is a complete list of the starting buffer position
7115 for every possible display line of a buffer along with the height of that
7116 display line. Maintaining such a full list would be very expensive. We
7117 settle for having it include information for all areas which we happen to
7118 generate anyhow (i.e. the region currently being displayed) and for those
7119 areas we need to work with.
7121 In order to ensure that the cache accurately represents what redisplay
7122 would actually show, it is necessary to invalidate it in many situations.
7123 If the buffer changes, the starting positions may no longer be correct.
7124 If a face or an extent has changed then the line heights may have altered.
7125 These events happen frequently enough that the cache can end up being
7126 constantly disabled. With this potentially constant invalidation when is
7127 the cache ever useful?
7129 Even if the cache is invalidated before every single usage, it is
7130 necessary. Scrolling often requires knowledge about display lines which
7131 are actually above or below the visible region. The cache provides a
7132 convenient light-weight method of storing this information for multiple
7133 display regions. This knowledge is necessary for the scrolling code to
7134 always obey the First Golden Rule of Redisplay.
7136 If the cache already contains all of the information that the scrolling
7137 routines happen to need so that it doesn't have to go generate it, then we
7138 are able to obey the Third Golden Rule of Redisplay. The first thing we
7139 do to help out the cache is to always add the displayed region. This
7140 region had to be generated anyway, so the cache ends up getting the
7141 information basically for free. In those cases where a user is simply
7142 scrolling around viewing a buffer there is a high probability that this is
7143 sufficient to always provide the needed information. The second thing we
7144 can do is be smart about invalidating the cache.
7146 TODO -- Be smart about invalidating the cache. Potential places:
7148 + Insertions at end-of-line which don't cause line-wraps do not alter the
7149 starting positions of any display lines. These types of buffer
7150 modifications should not invalidate the cache. This is actually a large
7151 optimization for redisplay speed as well.
7153 + Buffer modifications frequently only affect the display of lines at and
7154 below where they occur. In these situations we should only invalidate
7155 the part of the cache starting at where the modification occurs.
7157 In case you're wondering, the Second Golden Rule of Redisplay is not
7159 ****************************************************************************/
7161 /* This will get used quite a bit so we don't want to be constantly
7162 allocating and freeing it. */
7163 static line_start_cache_dynarr *internal_cache;
7165 /* Makes internal_cache represent the TYPE display structs and only
7166 the TYPE display structs. */
7169 update_internal_cache_list (struct window *w, int type)
7172 display_line_dynarr *dla = window_display_lines (w, type);
7174 Dynarr_reset (internal_cache);
7175 for (line = 0; line < Dynarr_length (dla); line++)
7177 struct display_line *dl = Dynarr_atp (dla, line);
7183 struct line_start_cache lsc;
7185 lsc.start = dl->bufpos;
7186 lsc.end = dl->end_bufpos;
7187 lsc.height = dl->ascent + dl->descent;
7189 Dynarr_add (internal_cache, lsc);
7194 /* Reset the line cache if necessary. This should be run at the
7195 beginning of any function which access the cache. */
7198 validate_line_start_cache (struct window *w)
7200 struct buffer *b = XBUFFER (w->buffer);
7201 struct frame *f = XFRAME (w->frame);
7203 if (!w->line_cache_validation_override)
7205 /* f->extents_changed used to be in here because extent face and
7206 size changes can cause text shifting. However, the extent
7207 covering the region is constantly having its face set and
7208 priority altered by the mouse code. This means that the line
7209 start cache is constantly being invalidated. This is bad
7210 since the mouse code also triggers heavy usage of the cache.
7211 Since it is an unlikely that f->extents being changed
7212 indicates that the cache really needs to be updated and if it
7213 does redisplay will catch it pretty quickly we no longer
7214 invalidate the cache if it is set. This greatly speeds up
7215 dragging out regions with the mouse. */
7216 if (XINT (w->line_cache_last_updated) < BUF_MODIFF (b)
7220 Dynarr_reset (w->line_start_cache);
7225 /* Return the very first buffer position contained in the given
7226 window's cache, or -1 if the cache is empty. Assumes that the
7230 line_start_cache_start (struct window *w)
7232 line_start_cache_dynarr *cache = w->line_start_cache;
7234 if (!Dynarr_length (cache))
7237 return Dynarr_atp (cache, 0)->start;
7240 /* Return the very last buffer position contained in the given
7241 window's cache, or -1 if the cache is empty. Assumes that the
7245 line_start_cache_end (struct window *w)
7247 line_start_cache_dynarr *cache = w->line_start_cache;
7249 if (!Dynarr_length (cache))
7252 return Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
7255 /* Return the index of the line POINT is contained within in window
7256 W's line start cache. It will enlarge the cache or move the cache
7257 window in order to have POINT be present in the cache. MIN_PAST is
7258 a guarantee of the number of entries in the cache present on either
7259 side of POINT (unless a buffer boundary is hit). If MIN_PAST is -1
7260 then it will be treated as 0, but the cache window will not be
7261 allowed to shift. Returns -1 if POINT cannot be found in the cache
7265 point_in_line_start_cache (struct window *w, Bufpos point, int min_past)
7267 struct buffer *b = XBUFFER (w->buffer);
7268 line_start_cache_dynarr *cache = w->line_start_cache;
7269 unsigned int top, bottom, pos;
7271 validate_line_start_cache (w);
7272 w->line_cache_validation_override++;
7274 /* Let functions pass in negative values, but we still treat -1
7276 /* #### bogosity alert */
7277 if (min_past < 0 && min_past != -1)
7278 min_past = -min_past;
7280 if (!Dynarr_length (cache) || line_start_cache_start (w) > point
7281 || line_start_cache_end (w) < point)
7284 int win_char_height = window_char_height (w, 1);
7286 /* Occasionally we get here with a 0 height
7287 window. find_next_newline_no_quit will abort if we pass it a
7288 count of 0 so handle that case. */
7289 if (!win_char_height)
7290 win_char_height = 1;
7292 if (!Dynarr_length (cache))
7294 Bufpos from = find_next_newline_no_quit (b, point, -1);
7295 Bufpos to = find_next_newline_no_quit (b, from, win_char_height);
7297 update_line_start_cache (w, from, to, point, 0);
7299 if (!Dynarr_length (cache))
7301 w->line_cache_validation_override--;
7306 assert (Dynarr_length (cache));
7309 while (line_start_cache_start (w) > point
7310 && (loop < cache_adjustment || min_past == -1))
7314 from = line_start_cache_start (w);
7315 if (from <= BUF_BEGV (b))
7318 from = find_next_newline_no_quit (b, from, -win_char_height);
7319 to = line_start_cache_end (w);
7321 update_line_start_cache (w, from, to, point, 0);
7325 if (line_start_cache_start (w) > point)
7329 from = find_next_newline_no_quit (b, point, -1);
7330 if (from >= BUF_ZV (b))
7332 to = find_next_newline_no_quit (b, from, -win_char_height);
7337 to = find_next_newline_no_quit (b, from, win_char_height);
7339 update_line_start_cache (w, from, to, point, 0);
7343 while (line_start_cache_end (w) < point
7344 && (loop < cache_adjustment || min_past == -1))
7348 to = line_start_cache_end (w);
7349 if (to >= BUF_ZV (b))
7352 from = line_start_cache_end (w);
7353 to = find_next_newline_no_quit (b, from, win_char_height);
7355 update_line_start_cache (w, from, to, point, 0);
7359 if (line_start_cache_end (w) < point)
7363 from = find_next_newline_no_quit (b, point, -1);
7364 if (from >= BUF_ZV (b))
7366 to = find_next_newline_no_quit (b, from, -win_char_height);
7371 to = find_next_newline_no_quit (b, from, win_char_height);
7373 update_line_start_cache (w, from, to, point, 0);
7377 assert (Dynarr_length (cache));
7382 /* This could happen if the buffer is narrowed. */
7383 if (line_start_cache_start (w) > point
7384 || line_start_cache_end (w) < point)
7386 w->line_cache_validation_override--;
7392 top = Dynarr_length (cache) - 1;
7397 unsigned int new_pos;
7400 pos = (bottom + top + 1) >> 1;
7401 start = Dynarr_atp (cache, pos)->start;
7402 end = Dynarr_atp (cache, pos)->end;
7404 if (point >= start && point <= end)
7406 if (pos < min_past && line_start_cache_start (w) > BUF_BEGV (b))
7409 find_next_newline_no_quit (b, line_start_cache_start (w),
7411 Bufpos to = line_start_cache_end (w);
7413 update_line_start_cache (w, from, to, point, 0);
7414 goto find_point_loop;
7416 else if ((Dynarr_length (cache) - pos - 1) < min_past
7417 && line_start_cache_end (w) < BUF_ZV (b))
7419 Bufpos from = line_start_cache_end (w);
7420 Bufpos to = find_next_newline_no_quit (b, from,
7425 update_line_start_cache (w, from, to, point, 0);
7426 goto find_point_loop;
7430 w->line_cache_validation_override--;
7434 else if (point > end)
7436 else if (point < start)
7441 new_pos = (bottom + top + 1) >> 1;
7444 w->line_cache_validation_override--;
7450 /* Return a boolean indicating if POINT would be visible in window W
7451 if display of the window was to begin at STARTP. */
7454 point_would_be_visible (struct window *w, Bufpos startp, Bufpos point)
7456 struct buffer *b = XBUFFER (w->buffer);
7457 int pixpos = -WINDOW_TEXT_TOP_CLIP(w);
7458 int bottom = WINDOW_TEXT_HEIGHT (w);
7461 /* If point is before the intended start it obviously can't be visible. */
7465 /* If point or start are not in the accessible buffer range, then
7467 if (startp < BUF_BEGV (b) || startp > BUF_ZV (b)
7468 || point < BUF_BEGV (b) || point > BUF_ZV (b))
7471 validate_line_start_cache (w);
7472 w->line_cache_validation_override++;
7474 start_elt = point_in_line_start_cache (w, startp, 0);
7475 if (start_elt == -1)
7477 w->line_cache_validation_override--;
7481 assert (line_start_cache_start (w) <= startp
7482 && line_start_cache_end (w) >= startp);
7488 /* Expand the cache if necessary. */
7489 if (start_elt == Dynarr_length (w->line_start_cache))
7492 Dynarr_atp (w->line_start_cache, start_elt - 1)->start;
7494 start_elt = point_in_line_start_cache (w, old_startp,
7495 window_char_height (w, 0));
7497 /* We've already actually processed old_startp, so increment
7501 /* If this happens we didn't add any extra elements. Bummer. */
7502 if (start_elt == Dynarr_length (w->line_start_cache))
7504 w->line_cache_validation_override--;
7509 height = Dynarr_atp (w->line_start_cache, start_elt)->height;
7511 if (pixpos + height > bottom)
7513 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7515 w->line_cache_validation_override--;
7521 if (point <= Dynarr_atp (w->line_start_cache, start_elt)->end)
7523 w->line_cache_validation_override--;
7531 /* For the given window W, if display starts at STARTP, what will be
7532 the buffer position at the beginning or end of the last line
7533 displayed. The end of the last line is also know as the window end
7536 WARNING: It is possible that redisplay failed to layout any lines for the
7537 windows. Under normal circumstances this is rare. However it seems that it
7538 does occur in the following situation: A mouse event has come in and we
7539 need to compute its location in a window. That code (in
7540 pixel_to_glyph_translation) already can handle 0 as an error return value.
7542 #### With a little work this could probably be reworked as just a
7543 call to start_with_line_at_pixpos. */
7546 start_end_of_last_line (struct window *w, Bufpos startp, int end,
7549 struct buffer *b = XBUFFER (w->buffer);
7550 line_start_cache_dynarr *cache = w->line_start_cache;
7552 int bottom = WINDOW_TEXT_HEIGHT (w);
7556 validate_line_start_cache (w);
7557 w->line_cache_validation_override++;
7559 if (startp < BUF_BEGV (b))
7560 startp = BUF_BEGV (b);
7561 else if (startp > BUF_ZV (b))
7562 startp = BUF_ZV (b);
7565 start_elt = point_in_line_start_cache (w, cur_start, 0);
7566 if (start_elt == -1)
7567 return may_error ? 0 : startp;
7571 int height = Dynarr_atp (cache, start_elt)->height;
7573 cur_start = Dynarr_atp (cache, start_elt)->start;
7575 if (pixpos + height > bottom)
7577 /* Adjust for any possible clip. */
7578 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7583 w->line_cache_validation_override--;
7587 return BUF_BEGV (b);
7591 w->line_cache_validation_override--;
7593 return Dynarr_atp (cache, start_elt)->end;
7595 return Dynarr_atp (cache, start_elt)->start;
7601 if (start_elt == Dynarr_length (cache))
7603 Bufpos from = line_start_cache_end (w);
7604 int win_char_height = window_char_height (w, 0);
7605 Bufpos to = find_next_newline_no_quit (b, from,
7610 /* We've hit the end of the bottom so that's what it is. */
7611 if (from >= BUF_ZV (b))
7613 w->line_cache_validation_override--;
7617 update_line_start_cache (w, from, to, BUF_PT (b), 0);
7619 /* Updating the cache invalidates any current indexes. */
7620 start_elt = point_in_line_start_cache (w, cur_start, -1) + 1;
7625 /* For the given window W, if display starts at STARTP, what will be
7626 the buffer position at the beginning of the last line displayed. */
7629 start_of_last_line (struct window *w, Bufpos startp)
7631 return start_end_of_last_line (w, startp, 0 , 0);
7634 /* For the given window W, if display starts at STARTP, what will be
7635 the buffer position at the end of the last line displayed. This is
7636 also know as the window end position. */
7639 end_of_last_line (struct window *w, Bufpos startp)
7641 return start_end_of_last_line (w, startp, 1, 0);
7645 end_of_last_line_may_error (struct window *w, Bufpos startp)
7647 return start_end_of_last_line (w, startp, 1, 1);
7651 /* For window W, what does the starting position have to be so that
7652 the line containing POINT will cover pixel position PIXPOS. */
7655 start_with_line_at_pixpos (struct window *w, Bufpos point, int pixpos)
7657 struct buffer *b = XBUFFER (w->buffer);
7659 Bufpos cur_pos, prev_pos = point;
7660 int point_line_height;
7661 int pixheight = pixpos - WINDOW_TEXT_TOP (w);
7663 validate_line_start_cache (w);
7664 w->line_cache_validation_override++;
7666 cur_elt = point_in_line_start_cache (w, point, 0);
7667 /* #### See comment in update_line_start_cache about big minibuffers. */
7670 w->line_cache_validation_override--;
7674 point_line_height = Dynarr_atp (w->line_start_cache, cur_elt)->height;
7678 cur_pos = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7680 pixheight -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7682 /* Do not take into account the value of vertical_clip here.
7683 That is the responsibility of the calling functions. */
7686 w->line_cache_validation_override--;
7687 if (-pixheight > point_line_height)
7688 /* We can't make the target line cover pixpos, so put it
7689 above pixpos. That way it will at least be visible. */
7699 int win_char_height;
7701 if (cur_pos <= BUF_BEGV (b))
7703 w->line_cache_validation_override--;
7704 return BUF_BEGV (b);
7707 win_char_height = window_char_height (w, 0);
7708 if (!win_char_height)
7709 win_char_height = 1;
7711 from = find_next_newline_no_quit (b, cur_pos, -win_char_height);
7712 to = line_start_cache_end (w);
7713 update_line_start_cache (w, from, to, point, 0);
7715 cur_elt = point_in_line_start_cache (w, cur_pos, 2) - 1;
7716 assert (cur_elt >= -1);
7717 /* This used to be cur_elt>=0 under the assumption that if
7718 point is in the top line and not at BUF_BEGV, then
7719 setting the window_start to a newline before the start of
7720 the first line will always cause scrolling.
7722 However in my (jv) opinion this is wrong. That new line
7723 can be hidden in various ways: invisible extents, an
7724 explicit window-start not at a newline character etc.
7725 The existence of those are indeed known to create crashes
7726 on that assert. So we have no option but to continue the
7727 search if we found point at the top of the line_start_cache
7729 cur_pos = Dynarr_atp (w->line_start_cache,0)->start;
7735 /* For window W, what does the starting position have to be so that
7736 the line containing point is on display line LINE. If LINE is
7737 positive it is considered to be the number of lines from the top of
7738 the window (0 is the top line). If it is negative the number is
7739 considered to be the number of lines from the bottom (-1 is the
7743 start_with_point_on_display_line (struct window *w, Bufpos point, int line)
7745 validate_line_start_cache (w);
7746 w->line_cache_validation_override++;
7750 int cur_elt = point_in_line_start_cache (w, point, line);
7752 if (cur_elt - line < 0)
7753 cur_elt = 0; /* Hit the top */
7757 w->line_cache_validation_override--;
7758 return Dynarr_atp (w->line_start_cache, cur_elt)->start;
7762 /* The calculated value of pixpos is correct for the bottom line
7763 or what we want when line is -1. Therefore we subtract one
7764 because we have already handled one line. */
7765 int new_line = -line - 1;
7766 int cur_elt = point_in_line_start_cache (w, point, new_line);
7767 int pixpos = WINDOW_TEXT_BOTTOM (w);
7768 Bufpos retval, search_point;
7770 /* If scroll_on_clipped_lines is false, the last "visible" line of
7771 the window covers the pixel at WINDOW_TEXT_BOTTOM (w) - 1.
7772 If s_o_c_l is true, then we don't want to count a clipped
7773 line, so back up from the bottom by the height of the line
7774 containing point. */
7775 if (scroll_on_clipped_lines)
7776 pixpos -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7780 if (cur_elt + new_line >= Dynarr_length (w->line_start_cache))
7782 /* Hit the bottom of the buffer. */
7784 (cur_elt + new_line) - Dynarr_length (w->line_start_cache) + 1;
7788 XSETWINDOW (window, w);
7789 default_face_height_and_width (window, &defheight, 0);
7791 cur_elt = Dynarr_length (w->line_start_cache) - 1;
7793 pixpos -= (adjustment * defheight);
7794 if (pixpos < WINDOW_TEXT_TOP (w))
7795 pixpos = WINDOW_TEXT_TOP (w);
7798 cur_elt = cur_elt + new_line;
7800 search_point = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7802 retval = start_with_line_at_pixpos (w, search_point, pixpos);
7803 w->line_cache_validation_override--;
7808 /* This is used to speed up vertical scrolling by caching the known
7809 buffer starting positions for display lines. This allows the
7810 scrolling routines to avoid costly calls to regenerate_window. If
7811 NO_REGEN is true then it will only add the values in the DESIRED
7812 display structs which are in the given range.
7814 Note also that the FROM/TO values are minimums. It is possible
7815 that this function will actually add information outside of the
7816 lines containing those positions. This can't hurt but it could
7819 #### We currently force the cache to have only 1 contiguous region.
7820 It might help to make the cache a dynarr of caches so that we can
7821 cover more areas. This might, however, turn out to be a lot of
7822 overhead for too little gain. */
7825 update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
7826 Bufpos point, int no_regen)
7828 struct buffer *b = XBUFFER (w->buffer);
7829 line_start_cache_dynarr *cache = w->line_start_cache;
7830 Bufpos low_bound, high_bound;
7832 validate_line_start_cache (w);
7833 w->line_cache_validation_override++;
7835 if (from < BUF_BEGV (b))
7836 from = BUF_BEGV (b);
7837 if (to > BUF_ZV (b))
7842 w->line_cache_validation_override--;
7846 if (Dynarr_length (cache))
7848 low_bound = line_start_cache_start (w);
7849 high_bound = line_start_cache_end (w);
7851 /* Check to see if the desired range is already in the cache. */
7852 if (from >= low_bound && to <= high_bound)
7854 w->line_cache_validation_override--;
7858 /* Check to make sure that the desired range is adjacent to the
7859 current cache. If not, invalidate the cache. */
7860 if (to < low_bound || from > high_bound)
7862 Dynarr_reset (cache);
7863 low_bound = high_bound = -1;
7868 low_bound = high_bound = -1;
7871 w->line_cache_last_updated = make_int (BUF_MODIFF (b));
7873 /* This could be integrated into the next two sections, but it is easier
7874 to follow what's going on by having it separate. */
7879 update_internal_cache_list (w, DESIRED_DISP);
7880 if (!Dynarr_length (internal_cache))
7882 w->line_cache_validation_override--;
7886 start = Dynarr_atp (internal_cache, 0)->start;
7888 Dynarr_atp (internal_cache, Dynarr_length (internal_cache) - 1)->end;
7890 /* We aren't allowed to generate additional information to fill in
7891 gaps, so if the DESIRED structs don't overlap the cache, reset the
7893 if (Dynarr_length (cache))
7895 if (end < low_bound || start > high_bound)
7896 Dynarr_reset (cache);
7898 /* #### What should really happen if what we are doing is
7899 extending a line (the last line)? */
7900 if (Dynarr_length (cache) == 1
7901 && Dynarr_length (internal_cache) == 1)
7902 Dynarr_reset (cache);
7905 if (!Dynarr_length (cache))
7907 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7908 Dynarr_length (internal_cache));
7909 w->line_cache_validation_override--;
7913 /* An extra check just in case the calling function didn't pass in
7914 the bounds of the DESIRED structs in the first place. */
7915 if (start >= low_bound && end <= high_bound)
7917 w->line_cache_validation_override--;
7921 /* At this point we know that the internal cache partially overlaps
7923 if (start < low_bound)
7925 int ic_elt = Dynarr_length (internal_cache) - 1;
7928 if (Dynarr_atp (internal_cache, ic_elt)->start < low_bound)
7936 Dynarr_reset (cache);
7937 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7938 Dynarr_length (internal_cache));
7939 w->line_cache_validation_override--;
7943 Dynarr_insert_many_at_start (cache, Dynarr_atp (internal_cache, 0),
7947 if (end > high_bound)
7951 while (ic_elt < Dynarr_length (internal_cache))
7953 if (Dynarr_atp (internal_cache, ic_elt)->start > high_bound)
7959 if (!(ic_elt < Dynarr_length (internal_cache)))
7961 Dynarr_reset (cache);
7962 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7963 Dynarr_length (internal_cache));
7964 w->line_cache_validation_override--;
7968 Dynarr_add_many (cache, Dynarr_atp (internal_cache, ic_elt),
7969 Dynarr_length (internal_cache) - ic_elt);
7972 w->line_cache_validation_override--;
7976 if (!Dynarr_length (cache) || from < low_bound)
7978 Bufpos startp = find_next_newline_no_quit (b, from, -1);
7980 int old_lb = low_bound;
7982 while (startp < old_lb || low_bound == -1)
7987 regenerate_window (w, startp, point, CMOTION_DISP);
7988 update_internal_cache_list (w, CMOTION_DISP);
7990 /* If this assert is triggered then regenerate_window failed
7991 to layout a single line. This is not possible since we
7992 force at least a single line to be layout for CMOTION_DISP */
7993 assert (Dynarr_length (internal_cache));
7994 assert (startp == Dynarr_atp (internal_cache, 0)->start);
7996 ic_elt = Dynarr_length (internal_cache) - 1;
7997 if (low_bound != -1)
8001 if (Dynarr_atp (internal_cache, ic_elt)->start < old_lb)
8007 assert (ic_elt >= 0);
8009 new_startp = Dynarr_atp (internal_cache, ic_elt)->end + 1;
8012 * Handle invisible text properly:
8013 * If the last line we're inserting has the same end as the
8014 * line before which it will be added, merge the two lines.
8016 if (Dynarr_length (cache) &&
8017 Dynarr_atp (internal_cache, ic_elt)->end ==
8018 Dynarr_atp (cache, marker)->end)
8020 Dynarr_atp (cache, marker)->start
8021 = Dynarr_atp (internal_cache, ic_elt)->start;
8022 Dynarr_atp (cache, marker)->height
8023 = Dynarr_atp (internal_cache, ic_elt)->height;
8027 if (ic_elt >= 0) /* we still have lines to add.. */
8029 Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0),
8030 ic_elt + 1, marker);
8031 marker += (ic_elt + 1);
8034 if (startp < low_bound || low_bound == -1)
8036 startp = new_startp;
8037 if (startp > BUF_ZV (b))
8039 w->line_cache_validation_override--;
8045 assert (Dynarr_length (cache));
8046 assert (from >= low_bound);
8048 /* Readjust the high_bound to account for any changes made while
8049 correcting the low_bound. */
8050 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8052 if (to > high_bound)
8054 Bufpos startp = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end + 1;
8058 regenerate_window (w, startp, point, CMOTION_DISP);
8059 update_internal_cache_list (w, CMOTION_DISP);
8061 /* See comment above about regenerate_window failing. */
8062 assert (Dynarr_length (internal_cache));
8064 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
8065 Dynarr_length (internal_cache));
8066 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8067 startp = high_bound + 1;
8069 while (to > high_bound);
8072 w->line_cache_validation_override--;
8073 assert (to <= high_bound);
8077 /* Given x and y coordinates in characters, relative to a window,
8078 return the pixel location corresponding to those coordinates. The
8079 pixel location returned is the center of the given character
8080 position. The pixel values are generated relative to the window,
8083 The modeline is considered to be part of the window. */
8086 glyph_to_pixel_translation (struct window *w, int char_x, int char_y,
8087 int *pix_x, int *pix_y)
8089 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
8090 int num_disp_lines, modeline;
8092 int defheight, defwidth;
8094 XSETWINDOW (window, w);
8095 default_face_height_and_width (window, &defheight, &defwidth);
8097 /* If we get a bogus value indicating somewhere above or to the left of
8098 the window, use the first window line or character position
8105 num_disp_lines = Dynarr_length (dla);
8109 if (Dynarr_atp (dla, 0)->modeline)
8116 /* First check if the y position intersects the display lines. */
8117 if (char_y < num_disp_lines)
8119 struct display_line *dl = Dynarr_atp (dla, char_y + modeline);
8120 struct display_block *db = get_display_block_from_line (dl, TEXT);
8122 *pix_y = (dl->ypos - dl->ascent +
8123 ((unsigned int) (dl->ascent + dl->descent - dl->clip) >> 1));
8125 if (char_x < Dynarr_length (db->runes))
8127 struct rune *rb = Dynarr_atp (db->runes, char_x);
8129 *pix_x = rb->xpos + (rb->width >> 1);
8133 int last_rune = Dynarr_length (db->runes) - 1;
8134 struct rune *rb = Dynarr_atp (db->runes, last_rune);
8136 char_x -= last_rune;
8138 *pix_x = rb->xpos + rb->width;
8139 *pix_x += ((char_x - 1) * defwidth);
8140 *pix_x += (defwidth >> 1);
8145 /* It didn't intersect, so extrapolate. #### For now, we include the
8146 modeline in this since we don't have true character positions in
8149 if (!Dynarr_length (w->face_cachels))
8150 reset_face_cachels (w);
8152 char_y -= num_disp_lines;
8154 if (Dynarr_length (dla))
8156 struct display_line *dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
8157 *pix_y = dl->ypos + dl->descent - dl->clip;
8160 *pix_y = WINDOW_TEXT_TOP (w);
8162 *pix_y += (char_y * defheight);
8163 *pix_y += (defheight >> 1);
8165 *pix_x = WINDOW_TEXT_LEFT (w);
8166 /* Don't adjust by one because this is still the unadjusted value. */
8167 *pix_x += (char_x * defwidth);
8168 *pix_x += (defwidth >> 1);
8171 if (*pix_x > w->pixel_left + w->pixel_width)
8172 *pix_x = w->pixel_left + w->pixel_width;
8173 if (*pix_y > w->pixel_top + w->pixel_height)
8174 *pix_y = w->pixel_top + w->pixel_height;
8176 *pix_x -= w->pixel_left;
8177 *pix_y -= w->pixel_top;
8180 /* Given a display line and a position, determine if there is a glyph
8181 there and return information about it if there is. */
8184 get_position_object (struct display_line *dl, Lisp_Object *obj1,
8185 Lisp_Object *obj2, int x_coord, int *low_x_coord,
8188 struct display_block *db;
8191 get_next_display_block (dl->bounds, dl->display_blocks, x_coord, 0);
8193 /* We use get_next_display_block to get the actual display block
8194 that would be displayed at x_coord. */
8196 if (block == NO_BLOCK)
8199 db = Dynarr_atp (dl->display_blocks, block);
8201 for (elt = 0; elt < Dynarr_length (db->runes); elt++)
8203 struct rune *rb = Dynarr_atp (db->runes, elt);
8205 if (rb->xpos <= x_coord && x_coord < (rb->xpos + rb->width))
8207 if (rb->type == RUNE_DGLYPH)
8209 *obj1 = rb->object.dglyph.glyph;
8210 *obj2 = rb->object.dglyph.extent;
8219 *low_x_coord = rb->xpos;
8221 *high_x_coord = rb->xpos + rb->width;
8228 #define UPDATE_CACHE_RETURN \
8230 d->pixel_to_glyph_cache.valid = 1; \
8231 d->pixel_to_glyph_cache.low_x_coord = low_x_coord; \
8232 d->pixel_to_glyph_cache.high_x_coord = high_x_coord; \
8233 d->pixel_to_glyph_cache.low_y_coord = low_y_coord; \
8234 d->pixel_to_glyph_cache.high_y_coord = high_y_coord; \
8235 d->pixel_to_glyph_cache.frame = f; \
8236 d->pixel_to_glyph_cache.col = *col; \
8237 d->pixel_to_glyph_cache.row = *row; \
8238 d->pixel_to_glyph_cache.obj_x = *obj_x; \
8239 d->pixel_to_glyph_cache.obj_y = *obj_y; \
8240 d->pixel_to_glyph_cache.w = *w; \
8241 d->pixel_to_glyph_cache.bufpos = *bufpos; \
8242 d->pixel_to_glyph_cache.closest = *closest; \
8243 d->pixel_to_glyph_cache.modeline_closest = *modeline_closest; \
8244 d->pixel_to_glyph_cache.obj1 = *obj1; \
8245 d->pixel_to_glyph_cache.obj2 = *obj2; \
8246 d->pixel_to_glyph_cache.retval = position; \
8247 RETURN_SANS_WARNINGS position; \
8250 /* Given x and y coordinates in pixels relative to a frame, return
8251 information about what is located under those coordinates.
8253 The return value will be one of:
8255 OVER_TOOLBAR: over one of the 4 frame toolbars
8256 OVER_MODELINE: over a modeline
8257 OVER_BORDER: over an internal border
8258 OVER_NOTHING: over the text area, but not over text
8259 OVER_OUTSIDE: outside of the frame border
8260 OVER_TEXT: over text in the text area
8266 -- nil if the coordinates are not over a glyph or a toolbar button.
8270 -- an extent, if the coordinates are over a glyph in the text area
8273 If the coordinates are over a glyph, OBJ_X and OBJ_Y give the
8274 equivalent coordinates relative to the upper-left corner of the glyph.
8276 If the coordinates are over a character, OBJ_X and OBJ_Y give the
8277 equivalent coordinates relative to the upper-left corner of the character.
8279 Otherwise, OBJ_X and OBJ_Y are undefined.
8283 pixel_to_glyph_translation (struct frame *f, int x_coord, int y_coord,
8284 int *col, int *row, int *obj_x, int *obj_y,
8285 struct window **w, Bufpos *bufpos,
8286 Bufpos *closest, Charcount *modeline_closest,
8287 Lisp_Object *obj1, Lisp_Object *obj2)
8290 struct pixel_to_glyph_translation_cache *cache;
8292 int frm_left, frm_right, frm_top, frm_bottom;
8293 int low_x_coord, high_x_coord, low_y_coord, high_y_coord;
8294 int position = OVER_NOTHING;
8295 int device_check_failed = 0;
8296 display_line_dynarr *dla;
8298 /* This is a safety valve in case this got called with a frame in
8299 the middle of being deleted. */
8300 if (!DEVICEP (f->device) || !DEVICE_LIVE_P (XDEVICE (f->device)))
8302 device_check_failed = 1;
8303 d = NULL, cache = NULL; /* Warning suppression */
8307 d = XDEVICE (f->device);
8308 cache = &d->pixel_to_glyph_cache;
8311 if (!device_check_failed
8313 && cache->frame == f
8314 && cache->low_x_coord <= x_coord
8315 && cache->high_x_coord > x_coord
8316 && cache->low_y_coord <= y_coord
8317 && cache->high_y_coord > y_coord)
8321 *obj_x = cache->obj_x;
8322 *obj_y = cache->obj_y;
8324 *bufpos = cache->bufpos;
8325 *closest = cache->closest;
8326 *modeline_closest = cache->modeline_closest;
8327 *obj1 = cache->obj1;
8328 *obj2 = cache->obj2;
8330 return cache->retval;
8341 *modeline_closest = -1;
8345 low_x_coord = x_coord;
8346 high_x_coord = x_coord + 1;
8347 low_y_coord = y_coord;
8348 high_y_coord = y_coord + 1;
8351 if (device_check_failed)
8352 return OVER_NOTHING;
8354 frm_left = FRAME_LEFT_BORDER_END (f);
8355 frm_right = FRAME_RIGHT_BORDER_START (f);
8356 frm_top = FRAME_TOP_BORDER_END (f);
8357 frm_bottom = FRAME_BOTTOM_BORDER_START (f);
8359 /* Check if the mouse is outside of the text area actually used by
8361 if (y_coord < frm_top)
8363 if (y_coord >= FRAME_TOP_BORDER_START (f))
8365 low_y_coord = FRAME_TOP_BORDER_START (f);
8366 high_y_coord = frm_top;
8367 position = OVER_BORDER;
8369 else if (y_coord >= 0)
8372 high_y_coord = FRAME_TOP_BORDER_START (f);
8373 position = OVER_TOOLBAR;
8377 low_y_coord = y_coord;
8379 position = OVER_OUTSIDE;
8382 else if (y_coord >= frm_bottom)
8384 if (y_coord < FRAME_BOTTOM_BORDER_END (f))
8386 low_y_coord = frm_bottom;
8387 high_y_coord = FRAME_BOTTOM_BORDER_END (f);
8388 position = OVER_BORDER;
8390 else if (y_coord < FRAME_PIXHEIGHT (f))
8392 low_y_coord = FRAME_BOTTOM_BORDER_END (f);
8393 high_y_coord = FRAME_PIXHEIGHT (f);
8394 position = OVER_TOOLBAR;
8398 low_y_coord = FRAME_PIXHEIGHT (f);
8399 high_y_coord = y_coord;
8400 position = OVER_OUTSIDE;
8404 if (position != OVER_TOOLBAR && position != OVER_BORDER)
8406 if (x_coord < frm_left)
8408 if (x_coord >= FRAME_LEFT_BORDER_START (f))
8410 low_x_coord = FRAME_LEFT_BORDER_START (f);
8411 high_x_coord = frm_left;
8412 position = OVER_BORDER;
8414 else if (x_coord >= 0)
8417 high_x_coord = FRAME_LEFT_BORDER_START (f);
8418 position = OVER_TOOLBAR;
8422 low_x_coord = x_coord;
8424 position = OVER_OUTSIDE;
8427 else if (x_coord >= frm_right)
8429 if (x_coord < FRAME_RIGHT_BORDER_END (f))
8431 low_x_coord = frm_right;
8432 high_x_coord = FRAME_RIGHT_BORDER_END (f);
8433 position = OVER_BORDER;
8435 else if (x_coord < FRAME_PIXWIDTH (f))
8437 low_x_coord = FRAME_RIGHT_BORDER_END (f);
8438 high_x_coord = FRAME_PIXWIDTH (f);
8439 position = OVER_TOOLBAR;
8443 low_x_coord = FRAME_PIXWIDTH (f);
8444 high_x_coord = x_coord;
8445 position = OVER_OUTSIDE;
8450 #ifdef HAVE_TOOLBARS
8451 if (position == OVER_TOOLBAR)
8453 *obj1 = toolbar_button_at_pixpos (f, x_coord, y_coord);
8456 UPDATE_CACHE_RETURN;
8458 #endif /* HAVE_TOOLBARS */
8460 /* We still have to return the window the pointer is next to and its
8461 relative y position even if it is outside the x boundary. */
8462 if (x_coord < frm_left)
8464 else if (x_coord > frm_right)
8465 x_coord = frm_right;
8467 /* Same in reverse. */
8468 if (y_coord < frm_top)
8470 else if (y_coord > frm_bottom)
8471 y_coord = frm_bottom;
8473 /* Find what window the given coordinates are actually in. */
8474 window = f->root_window;
8475 *w = find_window_by_pixel_pos (x_coord, y_coord, window);
8477 /* If we didn't find a window, we're done. */
8480 UPDATE_CACHE_RETURN;
8482 else if (position != OVER_NOTHING)
8485 *modeline_closest = -1;
8487 if (high_y_coord <= frm_top || high_y_coord >= frm_bottom)
8490 UPDATE_CACHE_RETURN;
8494 /* Check if the window is a minibuffer but isn't active. */
8495 if (MINI_WINDOW_P (*w) && !minibuf_level)
8497 /* Must reset the window value since some callers will ignore
8498 the return value if it is set. */
8500 UPDATE_CACHE_RETURN;
8503 /* See if the point is over window vertical divider */
8504 if (window_needs_vertical_divider (*w))
8506 int div_x_high = WINDOW_RIGHT (*w);
8507 int div_x_low = div_x_high - window_divider_width (*w);
8508 int div_y_high = WINDOW_BOTTOM (*w);
8509 int div_y_low = WINDOW_TOP (*w);
8511 if (div_x_low < x_coord && x_coord <= div_x_high &&
8512 div_y_low < y_coord && y_coord <= div_y_high)
8514 low_x_coord = div_x_low;
8515 high_x_coord = div_x_high;
8516 low_y_coord = div_y_low;
8517 high_y_coord = div_y_high;
8518 position = OVER_V_DIVIDER;
8519 UPDATE_CACHE_RETURN;
8523 dla = window_display_lines (*w, CURRENT_DISP);
8525 for (*row = 0; *row < Dynarr_length (dla); (*row)++)
8527 int really_over_nothing = 0;
8528 struct display_line *dl = Dynarr_atp (dla, *row);
8530 if ((int) (dl->ypos - dl->ascent) <= y_coord
8531 && y_coord <= (int) (dl->ypos + dl->descent))
8533 int check_margin_glyphs = 0;
8534 struct display_block *db = get_display_block_from_line (dl, TEXT);
8535 struct rune *rb = 0;
8537 if (x_coord < dl->bounds.left_white
8538 || x_coord >= dl->bounds.right_white)
8539 check_margin_glyphs = 1;
8541 low_y_coord = dl->ypos - dl->ascent;
8542 high_y_coord = dl->ypos + dl->descent + 1;
8544 if (position == OVER_BORDER
8545 || position == OVER_OUTSIDE
8546 || check_margin_glyphs)
8548 int x_check, left_bound;
8550 if (check_margin_glyphs)
8553 left_bound = dl->bounds.left_white;
8557 x_check = high_x_coord;
8558 left_bound = frm_left;
8561 if (Dynarr_length (db->runes))
8563 if (x_check <= left_bound)
8566 *modeline_closest = Dynarr_atp (db->runes, 0)->bufpos;
8568 *closest = Dynarr_atp (db->runes, 0)->bufpos;
8574 Dynarr_atp (db->runes,
8575 Dynarr_length (db->runes) - 1)->bufpos;
8578 Dynarr_atp (db->runes,
8579 Dynarr_length (db->runes) - 1)->bufpos;
8583 *modeline_closest += dl->offset;
8585 *closest += dl->offset;
8589 /* #### What should be here. */
8591 *modeline_closest = 0;
8596 if (check_margin_glyphs)
8598 if (x_coord < dl->bounds.left_in
8599 || x_coord >= dl->bounds.right_in)
8601 /* If we are over the outside margins then we
8602 know the loop over the text block isn't going
8603 to accomplish anything. So we go ahead and
8604 set what information we can right here and
8607 *obj_y = y_coord - (dl->ypos - dl->ascent);
8608 get_position_object (dl, obj1, obj2, x_coord,
8609 &low_x_coord, &high_x_coord);
8611 UPDATE_CACHE_RETURN;
8615 UPDATE_CACHE_RETURN;
8618 for (*col = 0; *col <= Dynarr_length (db->runes); (*col)++)
8620 int past_end = (*col == Dynarr_length (db->runes));
8623 rb = Dynarr_atp (db->runes, *col);
8626 (rb->xpos <= x_coord && x_coord < rb->xpos + rb->width))
8631 rb = Dynarr_atp (db->runes, *col);
8634 *bufpos = rb->bufpos + dl->offset;
8635 low_x_coord = rb->xpos;
8636 high_x_coord = rb->xpos + rb->width;
8638 if (rb->type == RUNE_DGLYPH)
8642 /* Find the first character after the glyph. */
8643 while (elt < Dynarr_length (db->runes))
8645 if (Dynarr_atp (db->runes, elt)->type != RUNE_DGLYPH)
8649 (Dynarr_atp (db->runes, elt)->bufpos +
8653 (Dynarr_atp (db->runes, elt)->bufpos +
8661 /* In this case we failed to find a non-glyph
8662 character so we return the last position
8663 displayed on the line. */
8664 if (elt == Dynarr_length (db->runes))
8667 *modeline_closest = dl->end_bufpos + dl->offset;
8669 *closest = dl->end_bufpos + dl->offset;
8670 really_over_nothing = 1;
8676 *modeline_closest = rb->bufpos + dl->offset;
8678 *closest = rb->bufpos + dl->offset;
8683 *row = window_displayed_height (*w);
8685 if (position == OVER_NOTHING)
8686 position = OVER_MODELINE;
8688 if (rb->type == RUNE_DGLYPH)
8690 *obj1 = rb->object.dglyph.glyph;
8691 *obj2 = rb->object.dglyph.extent;
8693 else if (rb->type == RUNE_CHAR)
8704 UPDATE_CACHE_RETURN;
8707 || (rb->type == RUNE_CHAR
8708 && rb->object.chr.ch == '\n'))
8711 /* At this point we may have glyphs in the right
8713 if (check_margin_glyphs)
8714 get_position_object (dl, obj1, obj2, x_coord,
8715 &low_x_coord, &high_x_coord);
8716 UPDATE_CACHE_RETURN;
8721 if (rb->type == RUNE_DGLYPH)
8723 *obj1 = rb->object.dglyph.glyph;
8724 *obj2 = rb->object.dglyph.extent;
8726 else if (rb->type == RUNE_CHAR)
8737 *obj_x = x_coord - rb->xpos;
8738 *obj_y = y_coord - (dl->ypos - dl->ascent);
8740 /* At this point we may have glyphs in the left
8742 if (check_margin_glyphs)
8743 get_position_object (dl, obj1, obj2, x_coord, 0, 0);
8745 if (position == OVER_NOTHING && !really_over_nothing)
8746 position = OVER_TEXT;
8748 UPDATE_CACHE_RETURN;
8755 *row = Dynarr_length (dla) - 1;
8756 if (FRAME_WIN_P (f))
8758 int bot_elt = Dynarr_length (dla) - 1;
8762 struct display_line *dl = Dynarr_atp (dla, bot_elt);
8763 int adj_area = y_coord - (dl->ypos + dl->descent);
8767 XSETWINDOW (lwin, *w);
8768 default_face_height_and_width (lwin, 0, &defheight);
8770 *row += (adj_area / defheight);
8774 /* #### This should be checked out some more to determine what
8775 should really be going on. */
8776 if (!MARKERP ((*w)->start[CURRENT_DISP]))
8779 *closest = end_of_last_line_may_error (*w,
8780 marker_position ((*w)->start[CURRENT_DISP]));
8782 UPDATE_CACHE_RETURN;
8784 #undef UPDATE_CACHE_RETURN
8787 /***************************************************************************/
8789 /* Lisp functions */
8791 /***************************************************************************/
8793 DEFUN ("redisplay-echo-area", Fredisplay_echo_area, 0, 0, 0, /*
8794 Ensure that all minibuffers are correctly showing the echo area.
8798 Lisp_Object devcons, concons;
8800 DEVICE_LOOP_NO_BREAK (devcons, concons)
8802 struct device *d = XDEVICE (XCAR (devcons));
8803 Lisp_Object frmcons;
8805 DEVICE_FRAME_LOOP (frmcons, d)
8807 struct frame *f = XFRAME (XCAR (frmcons));
8809 if (FRAME_REPAINT_P (f) && FRAME_HAS_MINIBUF_P (f))
8811 Lisp_Object window = FRAME_MINIBUF_WINDOW (f);
8813 MAYBE_DEVMETH (d, frame_output_begin, (f));
8816 * If the frame size has changed, there may be random
8817 * chud on the screen left from previous messages
8818 * because redisplay_frame hasn't been called yet.
8819 * Clear the screen to get rid of the potential mess.
8821 if (f->echo_area_garbaged)
8823 MAYBE_DEVMETH (d, clear_frame, (f));
8824 f->echo_area_garbaged = 0;
8826 redisplay_window (window, 0);
8827 MAYBE_DEVMETH (d, frame_output_end, (f));
8829 call_redisplay_end_triggers (XWINDOW (window), 0);
8838 restore_disable_preemption_value (Lisp_Object value)
8840 disable_preemption = XINT (value);
8844 DEFUN ("redraw-frame", Fredraw_frame, 0, 2, 0, /*
8845 Clear frame FRAME and output again what is supposed to appear on it.
8846 FRAME defaults to the selected frame if omitted.
8847 Normally, redisplay is preempted as normal if input arrives. However,
8848 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8849 input and is guaranteed to proceed to completion.
8851 (frame, no_preempt))
8853 struct frame *f = decode_frame (frame);
8854 int count = specpdl_depth ();
8856 if (!NILP (no_preempt))
8858 record_unwind_protect (restore_disable_preemption_value,
8859 make_int (disable_preemption));
8860 disable_preemption++;
8864 redisplay_frame (f, 1);
8866 /* See the comment in Fredisplay_frame. */
8867 RESET_CHANGED_SET_FLAGS;
8869 return unbind_to (count, Qnil);
8872 DEFUN ("redisplay-frame", Fredisplay_frame, 0, 2, 0, /*
8873 Ensure that FRAME's contents are correctly displayed.
8874 This differs from `redraw-frame' in that it only redraws what needs to
8875 be updated, as opposed to unconditionally clearing and redrawing
8877 FRAME defaults to the selected frame if omitted.
8878 Normally, redisplay is preempted as normal if input arrives. However,
8879 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8880 input and is guaranteed to proceed to completion.
8882 (frame, no_preempt))
8884 struct frame *f = decode_frame (frame);
8885 int count = specpdl_depth ();
8887 if (!NILP (no_preempt))
8889 record_unwind_protect (restore_disable_preemption_value,
8890 make_int (disable_preemption));
8891 disable_preemption++;
8894 redisplay_frame (f, 1);
8896 /* If we don't reset the global redisplay flags here, subsequent
8897 changes to the display will not get registered by redisplay
8898 because it thinks it already has registered changes. If you
8899 really knew what you were doing you could confuse redisplay by
8900 calling Fredisplay_frame while updating another frame. We assume
8901 that if you know what you are doing you will not be that
8903 RESET_CHANGED_SET_FLAGS;
8905 return unbind_to (count, Qnil);
8908 DEFUN ("redraw-device", Fredraw_device, 0, 2, 0, /*
8909 Clear device DEVICE and output again what is supposed to appear on it.
8910 DEVICE defaults to the selected device if omitted.
8911 Normally, redisplay is preempted as normal if input arrives. However,
8912 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8913 input and is guaranteed to proceed to completion.
8915 (device, no_preempt))
8917 struct device *d = decode_device (device);
8918 Lisp_Object frmcons;
8919 int count = specpdl_depth ();
8921 if (!NILP (no_preempt))
8923 record_unwind_protect (restore_disable_preemption_value,
8924 make_int (disable_preemption));
8925 disable_preemption++;
8928 DEVICE_FRAME_LOOP (frmcons, d)
8930 XFRAME (XCAR (frmcons))->clear = 1;
8932 redisplay_device (d, 0);
8934 /* See the comment in Fredisplay_frame. */
8935 RESET_CHANGED_SET_FLAGS;
8937 return unbind_to (count, Qnil);
8940 DEFUN ("redisplay-device", Fredisplay_device, 0, 2, 0, /*
8941 Ensure that DEVICE's contents are correctly displayed.
8942 This differs from `redraw-device' in that it only redraws what needs to
8943 be updated, as opposed to unconditionally clearing and redrawing
8945 DEVICE defaults to the selected device if omitted.
8946 Normally, redisplay is preempted as normal if input arrives. However,
8947 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8948 input and is guaranteed to proceed to completion.
8950 (device, no_preempt))
8952 struct device *d = decode_device (device);
8953 int count = specpdl_depth ();
8955 if (!NILP (no_preempt))
8957 record_unwind_protect (restore_disable_preemption_value,
8958 make_int (disable_preemption));
8959 disable_preemption++;
8962 redisplay_device (d, 0);
8964 /* See the comment in Fredisplay_frame. */
8965 RESET_CHANGED_SET_FLAGS;
8967 return unbind_to (count, Qnil);
8970 /* Big lie. Big lie. This will force all modelines to be updated
8971 regardless if the all flag is set or not. It remains in existence
8972 solely for backwards compatibility. */
8973 DEFUN ("redraw-modeline", Fredraw_modeline, 0, 1, 0, /*
8974 Force the modeline of the current buffer to be redisplayed.
8975 With optional non-nil ALL, force redisplay of all modelines.
8979 MARK_MODELINE_CHANGED;
8983 DEFUN ("force-cursor-redisplay", Fforce_cursor_redisplay, 0, 1, 0, /*
8984 Force an immediate update of the cursor on FRAME.
8985 FRAME defaults to the selected frame if omitted.
8989 redisplay_redraw_cursor (decode_frame (frame), 1);
8994 /***************************************************************************/
8996 /* Lisp-variable change triggers */
8998 /***************************************************************************/
9001 margin_width_changed_in_frame (Lisp_Object specifier, struct frame *f,
9004 /* Nothing to be done? */
9008 redisplay_variable_changed (Lisp_Object sym, Lisp_Object *val,
9009 Lisp_Object in_object, int flags)
9011 /* #### clip_changed should really be renamed something like
9012 global_redisplay_change. */
9017 /* This is called if the built-in glyphs have their properties
9020 redisplay_glyph_changed (Lisp_Object glyph, Lisp_Object property,
9023 if (WINDOWP (locale))
9025 MARK_FRAME_GLYPHS_CHANGED (XFRAME (WINDOW_FRAME (XWINDOW (locale))));
9027 else if (FRAMEP (locale))
9029 MARK_FRAME_GLYPHS_CHANGED (XFRAME (locale));
9031 else if (DEVICEP (locale))
9033 Lisp_Object frmcons;
9034 DEVICE_FRAME_LOOP (frmcons, XDEVICE (locale))
9035 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9037 else if (CONSOLEP (locale))
9039 Lisp_Object frmcons, devcons;
9040 CONSOLE_FRAME_LOOP_NO_BREAK (frmcons, devcons, XCONSOLE (locale))
9041 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9043 else /* global or buffer */
9045 Lisp_Object frmcons, devcons, concons;
9046 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
9047 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9052 text_cursor_visible_p_changed (Lisp_Object specifier, struct window *w,
9055 if (XFRAME (w->frame)->init_finished)
9056 Fforce_cursor_redisplay (w->frame);
9059 #ifdef MEMORY_USAGE_STATS
9062 /***************************************************************************/
9064 /* memory usage computation */
9066 /***************************************************************************/
9069 compute_rune_dynarr_usage (rune_dynarr *dyn, struct overhead_stats *ovstats)
9071 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9075 compute_display_block_dynarr_usage (display_block_dynarr *dyn,
9076 struct overhead_stats *ovstats)
9083 total = Dynarr_memory_usage (dyn, ovstats);
9084 for (i = 0; i < Dynarr_largest (dyn); i++)
9085 total += compute_rune_dynarr_usage (Dynarr_at (dyn, i).runes, ovstats);
9091 compute_glyph_block_dynarr_usage (glyph_block_dynarr *dyn,
9092 struct overhead_stats *ovstats)
9094 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9098 compute_display_line_dynarr_usage (display_line_dynarr *dyn,
9099 struct overhead_stats *ovstats)
9106 total = Dynarr_memory_usage (dyn, ovstats);
9107 for (i = 0; i < Dynarr_largest (dyn); i++)
9109 struct display_line *dl = &Dynarr_at (dyn, i);
9110 total += compute_display_block_dynarr_usage(dl->display_blocks, ovstats);
9111 total += compute_glyph_block_dynarr_usage (dl->left_glyphs, ovstats);
9112 total += compute_glyph_block_dynarr_usage (dl->right_glyphs, ovstats);
9119 compute_line_start_cache_dynarr_usage (line_start_cache_dynarr *dyn,
9120 struct overhead_stats *ovstats)
9122 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9125 #endif /* MEMORY_USAGE_STATS */
9128 /***************************************************************************/
9130 /* initialization */
9132 /***************************************************************************/
9135 init_redisplay (void)
9137 disable_preemption = 0;
9138 preemption_count = 0;
9139 max_preempts = INIT_MAX_PREEMPTS;
9145 if (!cmotion_display_lines)
9146 cmotion_display_lines = Dynarr_new (display_line);
9147 if (!mode_spec_bufbyte_string)
9148 mode_spec_bufbyte_string = Dynarr_new (Bufbyte);
9149 if (!formatted_string_extent_dynarr)
9150 formatted_string_extent_dynarr = Dynarr_new (EXTENT);
9151 if (!formatted_string_extent_start_dynarr)
9152 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount);
9153 if (!formatted_string_extent_end_dynarr)
9154 formatted_string_extent_end_dynarr = Dynarr_new (Bytecount);
9155 if (!internal_cache)
9156 internal_cache = Dynarr_new (line_start_cache);
9159 /* window system is nil when in -batch mode */
9160 if (!initialized || noninteractive)
9163 /* If the user wants to use a window system, we shouldn't bother
9164 initializing the terminal. This is especially important when the
9165 terminal is so dumb that emacs gives up before and doesn't bother
9166 using the window system.
9168 If the DISPLAY environment variable is set, try to use X, and die
9169 with an error message if that doesn't work. */
9171 #ifdef HAVE_X_WINDOWS
9172 if (!strcmp (display_use, "x"))
9174 /* Some stuff checks this way early. */
9175 Vwindow_system = Qx;
9176 Vinitial_window_system = Qx;
9179 #endif /* HAVE_X_WINDOWS */
9181 #ifdef HAVE_MS_WINDOWS
9182 if (!strcmp (display_use, "mswindows"))
9184 /* Some stuff checks this way early. */
9185 Vwindow_system = Qmswindows;
9186 Vinitial_window_system = Qmswindows;
9189 #endif /* HAVE_MS_WINDOWS */
9192 /* If no window system has been specified, try to use the terminal. */
9195 stderr_out ("XEmacs: standard input is not a tty\n");
9199 /* Look at the TERM variable */
9200 if (!getenv ("TERM"))
9202 stderr_out ("Please set the environment variable TERM; see tset(1).\n");
9206 Vinitial_window_system = Qtty;
9208 #else /* not HAVE_TTY */
9209 /* No DISPLAY specified, and no TTY support. */
9210 stderr_out ("XEmacs: Cannot open display.\n\
9211 Please set the environmental variable DISPLAY to an appropriate value.\n");
9218 syms_of_redisplay (void)
9220 defsymbol (&Qcursor_in_echo_area, "cursor-in-echo-area");
9221 #ifndef INHIBIT_REDISPLAY_HOOKS
9222 defsymbol (&Qpre_redisplay_hook, "pre-redisplay-hook");
9223 defsymbol (&Qpost_redisplay_hook, "post-redisplay-hook");
9224 #endif /* INHIBIT_REDISPLAY_HOOKS */
9225 defsymbol (&Qdisplay_warning_buffer, "display-warning-buffer");
9226 defsymbol (&Qbar_cursor, "bar-cursor");
9227 defsymbol (&Qredisplay_end_trigger_functions,
9228 "redisplay-end-trigger-functions");
9229 defsymbol (&Qtop_bottom, "top-bottom");
9230 defsymbol (&Qbuffer_list_changed_hook, "buffer-list-changed-hook");
9232 DEFSUBR (Fredisplay_echo_area);
9233 DEFSUBR (Fredraw_frame);
9234 DEFSUBR (Fredisplay_frame);
9235 DEFSUBR (Fredraw_device);
9236 DEFSUBR (Fredisplay_device);
9237 DEFSUBR (Fredraw_modeline);
9238 DEFSUBR (Fforce_cursor_redisplay);
9242 vars_of_redisplay (void)
9246 staticpro (&last_arrow_position);
9247 staticpro (&last_arrow_string);
9248 last_arrow_position = Qnil;
9249 last_arrow_string = Qnil;
9252 /* #### Probably temporary */
9253 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /*
9254 \(Temporary) Setting this will impact the performance of the internal
9257 cache_adjustment = 2;
9259 DEFVAR_INT_MAGIC ("pixel-vertical-clip-threshold", &vertical_clip /*
9260 Minimum pixel height for clipped bottom display line.
9261 A clipped line shorter than this won't be displayed.
9263 redisplay_variable_changed);
9266 DEFVAR_INT_MAGIC ("pixel-horizontal-clip-threshold", &horizontal_clip /*
9267 Minimum visible area for clipped glyphs at right boundary.
9268 Clipped glyphs shorter than this won't be displayed.
9269 Only pixmap glyph instances are currently allowed to be clipped.
9271 redisplay_variable_changed);
9272 horizontal_clip = 5;
9274 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string /*
9275 String displayed by modeline-format's "%m" specification.
9277 Vglobal_mode_string = Qnil;
9279 DEFVAR_LISP_MAGIC ("overlay-arrow-position", &Voverlay_arrow_position /*
9280 Marker for where to display an arrow on top of the buffer text.
9281 This must be the beginning of a line in order to work.
9282 See also `overlay-arrow-string'.
9284 redisplay_variable_changed);
9285 Voverlay_arrow_position = Qnil;
9287 DEFVAR_LISP_MAGIC ("overlay-arrow-string", &Voverlay_arrow_string /*
9288 String or glyph to display as an arrow. See also `overlay-arrow-position'.
9289 \(Note that despite the name of this variable, it can be set to a glyph as
9292 redisplay_variable_changed);
9293 Voverlay_arrow_string = Qnil;
9295 DEFVAR_INT ("scroll-step", &scroll_step /*
9296 *The number of lines to try scrolling a window by when point moves out.
9297 If that fails to bring point back on frame, point is centered instead.
9298 If this is zero, point is always centered after it moves off screen.
9302 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively /*
9303 *Scroll up to this many lines, to bring point back on screen.
9305 scroll_conservatively = 0;
9307 DEFVAR_BOOL_MAGIC ("truncate-partial-width-windows",
9308 &truncate_partial_width_windows /*
9309 *Non-nil means truncate lines in all windows less than full frame wide.
9311 redisplay_variable_changed);
9312 truncate_partial_width_windows = 1;
9314 DEFVAR_LISP ("visible-bell", &Vvisible_bell /*
9315 *Non-nil substitutes a visual signal for the audible bell.
9317 Default behavior is to flash the whole screen. On some platforms,
9318 special effects are available using the following values:
9320 'display Flash the whole screen (ie, the default behavior).
9321 'top-bottom Flash only the top and bottom lines of the selected frame.
9323 When effects are unavailable on a platform, the visual bell is the
9324 default, whole screen. (Currently only X supports any special effects.)
9326 Vvisible_bell = Qnil;
9328 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter /*
9329 *Non-nil means no need to redraw entire frame after suspending.
9330 A non-nil value is useful if the terminal can automatically preserve
9331 Emacs's frame display when you reenter Emacs.
9332 It is up to you to set this variable if your terminal can do that.
9334 no_redraw_on_reenter = 0;
9336 DEFVAR_LISP ("window-system", &Vwindow_system /*
9337 A symbol naming the window-system under which Emacs is running,
9338 such as `x', or nil if emacs is running on an ordinary terminal.
9340 Do not use this variable, except for GNU Emacs compatibility, as it
9341 gives wrong values in a multi-device environment. Use `console-type'
9344 Vwindow_system = Qnil;
9346 /* #### Temporary shit until window-system is eliminated. */
9347 DEFVAR_CONST_LISP ("initial-window-system", &Vinitial_window_system /*
9350 Vinitial_window_system = Qnil;
9352 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area /*
9353 Non-nil means put cursor in minibuffer, at end of any message there.
9355 cursor_in_echo_area = 0;
9357 /* #### Shouldn't this be generalized as follows:
9359 if nil, use block cursor.
9360 if a number, use a bar cursor of that width.
9361 Otherwise, use a 1-pixel bar cursor.
9363 #### Or better yet, this variable should be trashed entirely
9364 (use a Lisp-magic variable to maintain compatibility)
9365 and a specifier `cursor-shape' added, which allows a block
9366 cursor, a bar cursor, a flashing block or bar cursor,
9367 maybe a caret cursor, etc. */
9369 DEFVAR_LISP ("bar-cursor", &Vbar_cursor /*
9370 *Use vertical bar cursor if non-nil. If t width is 1 pixel, otherwise 2.
9374 #ifndef INHIBIT_REDISPLAY_HOOKS
9375 xxDEFVAR_LISP ("pre-redisplay-hook", &Vpre_redisplay_hook /*
9376 Function or functions to run before every redisplay.
9378 Vpre_redisplay_hook = Qnil;
9380 xxDEFVAR_LISP ("post-redisplay-hook", &Vpost_redisplay_hook /*
9381 Function or functions to run after every redisplay.
9383 Vpost_redisplay_hook = Qnil;
9384 #endif /* INHIBIT_REDISPLAY_HOOKS */
9386 DEFVAR_LISP ("buffer-list-changed-hook", &Vbuffer_list_changed_hook /*
9387 Function or functions to call when a frame's buffer list has changed.
9388 This is called during redisplay, before redisplaying each frame.
9389 Functions on this hook are called with one argument, the frame.
9391 Vbuffer_list_changed_hook = Qnil;
9393 DEFVAR_INT ("display-warning-tick", &display_warning_tick /*
9394 Bump this to tell the C code to call `display-warning-buffer'
9395 at next redisplay. You should not normally change this; the function
9396 `display-warning' automatically does this at appropriate times.
9398 display_warning_tick = 0;
9400 DEFVAR_BOOL ("inhibit-warning-display", &inhibit_warning_display /*
9401 Non-nil means inhibit display of warning messages.
9402 You should *bind* this, not set it. Any pending warning messages
9403 will be displayed when the binding no longer applies.
9405 /* reset to 0 by startup.el after the splash screen has displayed.
9406 This way, the warnings don't obliterate the splash screen. */
9407 inhibit_warning_display = 1;
9409 DEFVAR_LISP ("window-size-change-functions",
9410 &Vwindow_size_change_functions /*
9411 Not currently implemented.
9412 Functions called before redisplay, if window sizes have changed.
9413 The value should be a list of functions that take one argument.
9414 Just before redisplay, for each frame, if any of its windows have changed
9415 size since the last redisplay, or have been split or deleted,
9416 all the functions in the list are called, with the frame as argument.
9418 Vwindow_size_change_functions = Qnil;
9420 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions /*
9421 Not currently implemented.
9422 Functions to call before redisplaying a window with scrolling.
9423 Each function is called with two arguments, the window
9424 and its new display-start position. Note that the value of `window-end'
9425 is not valid when these functions are called.
9427 Vwindow_scroll_functions = Qnil;
9429 DEFVAR_LISP ("redisplay-end-trigger-functions",
9430 &Vredisplay_end_trigger_functions /*
9431 See `set-window-redisplay-end-trigger'.
9433 Vredisplay_end_trigger_functions = Qnil;
9435 DEFVAR_BOOL ("column-number-start-at-one", &column_number_start_at_one /*
9436 *Non-nil means column display number starts at 1.
9438 column_number_start_at_one = 0;
9442 specifier_vars_of_redisplay (void)
9444 DEFVAR_SPECIFIER ("left-margin-width", &Vleft_margin_width /*
9445 *Width of left margin.
9446 This is a specifier; use `set-specifier' to change it.
9448 Vleft_margin_width = Fmake_specifier (Qnatnum);
9449 set_specifier_fallback (Vleft_margin_width, list1 (Fcons (Qnil, Qzero)));
9450 set_specifier_caching (Vleft_margin_width,
9451 offsetof (struct window, left_margin_width),
9452 some_window_value_changed,
9453 offsetof (struct frame, left_margin_width),
9454 margin_width_changed_in_frame, 0);
9456 DEFVAR_SPECIFIER ("right-margin-width", &Vright_margin_width /*
9457 *Width of right margin.
9458 This is a specifier; use `set-specifier' to change it.
9460 Vright_margin_width = Fmake_specifier (Qnatnum);
9461 set_specifier_fallback (Vright_margin_width, list1 (Fcons (Qnil, Qzero)));
9462 set_specifier_caching (Vright_margin_width,
9463 offsetof (struct window, right_margin_width),
9464 some_window_value_changed,
9465 offsetof (struct frame, right_margin_width),
9466 margin_width_changed_in_frame, 0);
9468 DEFVAR_SPECIFIER ("minimum-line-ascent", &Vminimum_line_ascent /*
9469 *Minimum ascent height of lines.
9470 This is a specifier; use `set-specifier' to change it.
9472 Vminimum_line_ascent = Fmake_specifier (Qnatnum);
9473 set_specifier_fallback (Vminimum_line_ascent, list1 (Fcons (Qnil, Qzero)));
9474 set_specifier_caching (Vminimum_line_ascent,
9475 offsetof (struct window, minimum_line_ascent),
9476 some_window_value_changed,
9479 DEFVAR_SPECIFIER ("minimum-line-descent", &Vminimum_line_descent /*
9480 *Minimum descent height of lines.
9481 This is a specifier; use `set-specifier' to change it.
9483 Vminimum_line_descent = Fmake_specifier (Qnatnum);
9484 set_specifier_fallback (Vminimum_line_descent, list1 (Fcons (Qnil, Qzero)));
9485 set_specifier_caching (Vminimum_line_descent,
9486 offsetof (struct window, minimum_line_descent),
9487 some_window_value_changed,
9490 DEFVAR_SPECIFIER ("use-left-overflow", &Vuse_left_overflow /*
9491 *Non-nil means use the left outside margin as extra whitespace when
9492 displaying 'whitespace or 'inside-margin glyphs.
9493 This is a specifier; use `set-specifier' to change it.
9495 Vuse_left_overflow = Fmake_specifier (Qboolean);
9496 set_specifier_fallback (Vuse_left_overflow, list1 (Fcons (Qnil, Qnil)));
9497 set_specifier_caching (Vuse_left_overflow,
9498 offsetof (struct window, use_left_overflow),
9499 some_window_value_changed,
9502 DEFVAR_SPECIFIER ("use-right-overflow", &Vuse_right_overflow /*
9503 *Non-nil means use the right outside margin as extra whitespace when
9504 displaying 'whitespace or 'inside-margin glyphs.
9505 This is a specifier; use `set-specifier' to change it.
9507 Vuse_right_overflow = Fmake_specifier (Qboolean);
9508 set_specifier_fallback (Vuse_right_overflow, list1 (Fcons (Qnil, Qnil)));
9509 set_specifier_caching (Vuse_right_overflow,
9510 offsetof (struct window, use_right_overflow),
9511 some_window_value_changed,
9514 DEFVAR_SPECIFIER ("text-cursor-visible-p", &Vtext_cursor_visible_p /*
9515 *Non-nil means the text cursor is visible (this is usually the case).
9516 This is a specifier; use `set-specifier' to change it.
9518 Vtext_cursor_visible_p = Fmake_specifier (Qboolean);
9519 set_specifier_fallback (Vtext_cursor_visible_p, list1 (Fcons (Qnil, Qt)));
9520 set_specifier_caching (Vtext_cursor_visible_p,
9521 offsetof (struct window, text_cursor_visible_p),
9522 text_cursor_visible_p_changed,