1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1994, 1995, 1996 Board of Trustees, University of Illinois.
3 Copyright (C) 1995 Free Software Foundation, Inc.
4 Copyright (C) 1995, 1996 Ben Wing.
5 Copyright (C) 1995 Sun Microsystems, Inc.
6 Copyright (C) 1996 Chuck Thompson.
8 This file is part of XEmacs.
10 XEmacs is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
15 XEmacs is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with XEmacs; see the file COPYING. If not, write to
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
25 /* Synched up with: Not in FSF. */
27 /* Author: Chuck Thompson */
29 /* Fixed up by Ben Wing for Mule */
31 /* This file has been Mule-ized. */
33 /*****************************************************************************
34 The Golden Rules of Redisplay
36 First: It Is Better To Be Correct Than Fast
37 Second: Thou Shalt Not Run Elisp From Within Redisplay
38 Third: It Is Better To Be Fast Than Not To Be
39 ****************************************************************************/
58 #include "redisplay.h"
61 #include "line-number.h"
63 #include "file-coding.h"
69 #include "console-tty.h"
72 /* Note: We have to be careful throughout this code to properly handle
73 and differentiate between Bufbytes and Emchars.
75 Since strings are generally composed of Bufbytes, I've taken the tack
76 that any contiguous set of Bufbytes is called a "string", while
77 any contiguous set of Emchars is called an "array". */
79 /* Return value to indicate a failure by an add_*_rune routine to add
80 a rune, but no propagation information needs to be returned. */
81 #define ADD_FAILED (prop_block_dynarr *) 1
83 #define BEGIN_GLYPHS 0
86 #define RIGHT_GLYPHS 3
88 #define VERTICAL_CLIP(w, display) \
89 ((WINDOW_TTY_P (w) | (!display && scroll_on_clipped_lines)) \
93 /* The following structures are completely private to redisplay.c so
94 we put them here instead of in a header file, for modularity. */
96 /* NOTE: Bytinds not Bufpos's in this structure. */
98 typedef struct position_redisplay_data_type
100 /* This information is normally filled in by the create_*_block
101 routines and is used by the add_*_rune routines. */
103 /* if we are working with strings rather than buffers we need a
104 handle to the string */
107 struct display_block *db;
108 struct display_line *dl;
109 Emchar ch; /* Character that is to be added. This is
110 used to communicate this information to
111 add_emchar_rune(). */
112 Lisp_Object last_charset; /* The charset of the previous character.
113 Used to optimize some lookups -- we
114 only have to do some things when
115 the charset changes. */
116 face_index last_findex; /* The face index of the previous character.
117 Needed to ensure the validity of the
118 last_charset optimization. */
120 int last_char_width; /* The width of the previous character. */
121 int font_is_bogus; /* If true, it means we couldn't instantiate
122 the font for this charset, so we substitute
123 ~'s from the ASCII charset. */
128 int blank_width; /* Width of the blank that is to be added.
129 This is used to communicate this information
132 This is also used rather cheesily to
133 communicate the width of the eol-cursor-size
134 blank that exists at the end of the line.
135 add_emchar_rune() is called cheesily with
136 the non-printing char '\n', which is stuck
137 in the output routines with its width being
139 Bytind bi_cursor_bufpos;/* This stores the buffer position of the cursor. */
140 unsigned int cursor_type :3;
141 int cursor_x; /* rune block cursor is at */
142 int start_col; /* Number of character columns (each column has
143 a width of the default char width) that still
144 need to be skipped. This is used for horizontal
145 scrolling, where a certain number of columns
146 (those off the left side of the screen) need
147 to be skipped before anything is displayed. */
148 Bytind bi_start_col_enabled;
149 int start_col_xoffset; /* Number of pixels that still need to
150 be skipped. This is used for
151 horizontal scrolling of glyphs, where we want
152 to be able to scroll over part of the glyph. */
154 int hscroll_glyph_width_adjust; /* how much the width of the hscroll
155 glyph differs from space_width (w).
156 0 if no hscroll glyph was used,
157 i.e. the window is not scrolled
158 horizontally. Used in tab
161 /* Information about the face the text should be displayed in and
162 any begin-glyphs and end-glyphs. */
163 struct extent_fragment *ef;
166 /* The height of a pixmap may either be predetermined if the user
167 has set a baseline value, or it may be dependent on whatever the
168 line ascent and descent values end up being, based just on font
169 information. In the first case we can immediately update the
170 values, thus their inclusion here. In the last case we cannot
171 determine the actual contribution to the line height until we
172 have finished laying out all text on the line. Thus we propagate
173 the max height of such pixmaps and do a final calculation after
174 all text has been added to the line. */
177 int max_pixmap_height;
179 Lisp_Object result_str; /* String where we put the result of
180 generating a formatted string in the modeline. */
181 int is_modeline; /* Non-zero if we're generating the modeline. */
182 Charcount modeline_charpos; /* Number of chars used in result_str so far;
183 corresponds to bytepos. */
184 Bytecount bytepos; /* Number of bytes used in result_str so far.
185 We don't actually copy the bytes into result_str
186 until the end because we don't know how big the
187 string is going to be until then. */
198 /* Data that should be propagated to the next line. Either a single
199 Emchar or a string of Bufbyte's.
201 The actual data that is propagated ends up as a Dynarr of these
204 #### It's unclean that both Emchars and Bufbytes are here.
207 typedef struct prop_block prop_block;
217 Bytecount len; /* length of the string. */
223 Bytind bi_cursor_bufpos; /* NOTE: is in Bytinds */
224 unsigned int cursor_type :3;
237 Dynarr_declare (prop_block);
241 static Charcount generate_fstring_runes (struct window *w, pos_data *data,
242 Charcount pos, Charcount min_pos,
243 Charcount max_pos, Lisp_Object elt,
244 int depth, int max_pixsize,
245 face_index findex, int type,
247 Lisp_Object cur_ext);
248 static prop_block_dynarr *add_glyph_rune (pos_data *data,
249 struct glyph_block *gb,
250 int pos_type, int allow_cursor,
251 struct glyph_cachel *cachel);
252 static Bytind create_text_block (struct window *w, struct display_line *dl,
253 Bytind bi_start_pos, prop_block_dynarr **prop,
255 static int create_overlay_glyph_block (struct window *w,
256 struct display_line *dl);
257 static void create_left_glyph_block (struct window *w,
258 struct display_line *dl,
260 static void create_right_glyph_block (struct window *w,
261 struct display_line *dl);
262 static void redisplay_windows (Lisp_Object window, int skip_selected);
263 static void decode_mode_spec (struct window *w, Emchar spec, int type);
264 static void free_display_line (struct display_line *dl);
265 static void update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
266 Bufpos point, int no_regen);
267 static int point_visible (struct window *w, Bufpos point, int type);
269 /* This used to be 10 but 30 seems to give much better performance. */
270 #define INIT_MAX_PREEMPTS 30
271 static int max_preempts;
273 #define REDISPLAY_PREEMPTION_CHECK \
276 (!disable_preemption && \
277 ((preemption_count < max_preempts) || !NILP (Vexecuting_macro)) && \
278 (!INTERACTIVE || detect_input_pending ()))))
281 * Redisplay global variables.
284 /* We need a third set of display structures for the cursor motion
285 routines. We used to just give each window a third set. However,
286 we always fully regenerate the structures when needed so there
287 isn't any reason we need more than a single set. */
288 display_line_dynarr *cmotion_display_lines;
290 /* We store the extents that we need to generate in a Dynarr and then
291 frob them all on at the end of generating the string. We do it
292 this way rather than adding them as we generate the string because
293 we don't store the text into the resulting string until we're done
294 (to avoid having to resize the string multiple times), and we don't
295 want to go around adding extents to a string when the extents might
296 stretch off the end of the string. */
297 static EXTENT_dynarr *formatted_string_extent_dynarr;
298 static Bytecount_dynarr *formatted_string_extent_start_dynarr;
299 static Bytecount_dynarr *formatted_string_extent_end_dynarr;
302 /* #### probably temporary */
303 int cache_adjustment;
305 /* This holds a string representing the text corresponding to a single
307 static Bufbyte_dynarr *mode_spec_bufbyte_string;
309 int in_display; /* 1 if in redisplay. */
311 int disable_preemption; /* Used for debugging redisplay and for
314 /* We only allow max_preempts preemptions before we force a redisplay. */
315 static int preemption_count;
317 /* Minimum pixel height of clipped bottom display line. */
320 /* Minimum visible pixel width of clipped glyphs at right margin. */
323 /* Nonzero means reading single-character input with prompt
324 so put cursor on minibuffer after the prompt. */
325 int cursor_in_echo_area;
326 Lisp_Object Qcursor_in_echo_area;
328 /* Nonzero means truncate lines in all windows less wide than the frame */
329 int truncate_partial_width_windows;
331 /* non-nil if a buffer has changed since the last time redisplay completed */
333 int buffers_changed_set;
335 /* non-nil if hscroll has changed somewhere or a buffer has been
336 narrowed or widened */
338 int clip_changed_set;
340 /* non-nil if any extent has changed since the last time redisplay completed */
342 int extents_changed_set;
344 /* non-nil if any face has changed since the last time redisplay completed */
347 /* Nonzero means some frames have been marked as garbaged */
350 /* non-zero if any of the builtin display glyphs (continuation,
351 hscroll, control-arrow, etc) is in need of updating
354 int glyphs_changed_set;
356 /* non-zero if any subwindow has been deleted. */
357 int subwindows_changed;
358 int subwindows_changed_set;
360 /* non-zero if any displayed subwindow is in need of updating
362 int subwindows_state_changed;
363 int subwindows_state_changed_set;
365 /* This variable is 1 if the icon has to be updated.
366 It is set to 1 when `frame-icon-glyph' changes. */
368 int icon_changed_set;
370 /* This variable is 1 if the menubar widget has to be updated.
371 It is set to 1 by set-menubar-dirty-flag and cleared when the widget
374 int menubar_changed_set;
376 /* true iff we should redraw the modelines on the next redisplay */
377 int modeline_changed;
378 int modeline_changed_set;
380 /* non-nil if point has changed in some buffer since the last time
381 redisplay completed */
383 int point_changed_set;
385 /* non-nil if some frame has changed its size */
388 /* non-nil if some device has signaled that it wants to change size */
389 int asynch_device_change_pending;
391 /* non-nil if any toolbar has changed */
393 int toolbar_changed_set;
395 /* non-nil if any gutter has changed */
397 int gutter_changed_set;
399 /* non-nil if any window has changed since the last time redisplay completed */
402 /* non-nil if any frame's window structure has changed since the last
403 time redisplay completed */
404 int windows_structure_changed;
406 /* If non-nil, use vertical bar cursor. */
407 Lisp_Object Vbar_cursor;
408 Lisp_Object Qbar_cursor;
410 Lisp_Object Vvisible_bell; /* If true and the terminal will support it
411 then the frame will flash instead of
412 beeping when an error occurs */
414 /* Nonzero means no need to redraw the entire frame on resuming
415 a suspended Emacs. This is useful on terminals with multiple pages,
416 where one page is used for Emacs and another for all else. */
417 int no_redraw_on_reenter;
419 Lisp_Object Vwindow_system; /* nil or a symbol naming the window system
420 under which emacs is running
421 ('x is the only current possibility) */
422 Lisp_Object Vinitial_window_system;
424 Lisp_Object Vglobal_mode_string;
426 /* The number of lines scroll a window by when point leaves the window; if
427 it is <=0 then point is centered in the window */
430 /* Scroll up to this many lines, to bring point back on screen. */
431 int scroll_conservatively;
433 /* Marker for where to display an arrow on top of the buffer text. */
434 Lisp_Object Voverlay_arrow_position;
435 /* String to display for the arrow. */
436 Lisp_Object Voverlay_arrow_string;
438 Lisp_Object Vwindow_size_change_functions;
439 Lisp_Object Vwindow_scroll_functions;
440 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
442 Lisp_Object Qbuffer_list_changed_hook, Vbuffer_list_changed_hook;
445 #define INHIBIT_REDISPLAY_HOOKS /* #### Until we've thought about
447 #ifndef INHIBIT_REDISPLAY_HOOKS
448 /* #### Chuck says: I think this needs more thought.
449 Think about this for 19.14. */
450 Lisp_Object Vpre_redisplay_hook, Vpost_redisplay_hook;
451 Lisp_Object Qpre_redisplay_hook, Qpost_redisplay_hook;
452 #endif /* INHIBIT_REDISPLAY_HOOKS */
454 static int last_display_warning_tick, display_warning_tick;
455 Lisp_Object Qdisplay_warning_buffer;
456 int inhibit_warning_display;
458 Lisp_Object Vleft_margin_width, Vright_margin_width;
459 Lisp_Object Vminimum_line_ascent, Vminimum_line_descent;
460 Lisp_Object Vuse_left_overflow, Vuse_right_overflow;
461 Lisp_Object Vtext_cursor_visible_p;
463 int column_number_start_at_one;
465 Lisp_Object Qtop_bottom;
467 #define WINDOW_SCROLLED(w) \
468 (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 ammount */
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, its an
4288 FSF thing and invisble extents are the way to go
4289 here. 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 begining 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 cache. We use subwindows_changed here to
6335 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 || f->subwindows_changed)
6342 /* we have to do this so the gutter gets regenerated. */
6343 reset_gutter_display_lines (f);
6346 hold_frame_size_changes ();
6348 /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */
6349 /* Within this section, we are defenseless and assume that the
6350 following cannot happen:
6352 1) garbage collection
6353 2) Lisp code evaluation
6354 3) frame size changes
6356 We ensure (3) by calling hold_frame_size_changes(), which
6357 will cause any pending frame size changes to get put on hold
6358 till after the end of the critical section. (1) follows
6359 automatically if (2) is met. #### Unfortunately, there are
6360 some places where Lisp code can be called within this section.
6361 We need to remove them.
6363 If Fsignal() is called during this critical section, we
6366 If garbage collection is called during this critical section,
6367 we simply return. #### We should abort instead.
6369 #### If a frame-size change does occur we should probably
6370 actually be preempting redisplay. */
6372 MAYBE_DEVMETH (d, frame_output_begin, (f));
6374 /* We can now update the gutters, safe in the knowledge that our
6375 efforts won't get undone. */
6377 /* This can call lisp, but redisplay is protected by binding
6378 inhibit_quit. More importantly the code involving display lines
6379 *assumes* that GC will not happen and so does not GCPRO
6380 anything. Since we use this code the whole time with the gutters
6381 we cannot allow GC to happen when manipulating the gutters. */
6382 update_frame_gutters (f);
6384 /* Erase the frame before outputting its contents. */
6387 MAYBE_DEVMETH (d, clear_frame, (f));
6390 /* Do the selected window first. */
6391 redisplay_window (FRAME_SELECTED_WINDOW (f), 0);
6393 /* Then do the rest. */
6394 redisplay_windows (f->root_window, 1);
6396 MAYBE_DEVMETH (d, frame_output_end, (f));
6398 update_frame_title (f);
6400 CLASS_RESET_CHANGED_FLAGS (f);
6401 f->window_face_cache_reset = 0;
6402 f->echo_area_garbaged = 0;
6405 if (!f->size_change_pending)
6406 f->size_changed = 0;
6408 /* ----------------- END CRITICAL REDISPLAY SECTION ---------------- */
6410 /* Allow frame size changes to occur again.
6412 #### what happens if changes to other frames happen? */
6413 unhold_one_frame_size_changes (f);
6415 map_windows (f, call_redisplay_end_triggers, 0);
6419 /* Ensure that all frames on the given device are correctly displayed.
6420 If AUTOMATIC is non-zero, and the device implementation indicates
6421 no automatic redisplay, as printers do, then the device is not
6422 redisplayed. AUTOMATIC is set to zero when called from lisp
6423 functions (redraw-device) and (redisplay-device), and to non-zero
6424 when called from "lazy" redisplay();
6428 redisplay_device (struct device *d, int automatic)
6430 Lisp_Object frame, frmcons;
6432 int size_change_failed = 0;
6436 && (MAYBE_INT_DEVMETH (d, device_implementation_flags, ())
6437 & XDEVIMPF_NO_AUTO_REDISPLAY))
6440 if (DEVICE_STREAM_P (d)) /* nothing to do */
6443 /* It is possible that redisplay has been called before the
6444 device is fully initialized. If so then continue with the
6446 if (NILP (DEVICE_SELECTED_FRAME (d)))
6449 REDISPLAY_PREEMPTION_CHECK;
6453 /* Always do the selected frame first. */
6454 frame = DEVICE_SELECTED_FRAME (d);
6458 if (f->icon_changed || f->windows_changed)
6459 update_frame_icon (f);
6461 if (FRAME_REPAINT_P (f))
6463 if (CLASS_REDISPLAY_FLAGS_CHANGEDP(f))
6465 preempted = redisplay_frame (f, 0);
6471 /* If the frame redisplay did not get preempted, then this flag
6472 should have gotten set to 0. It might be possible for that
6473 not to happen if a size change event were to occur at an odd
6474 time. To make sure we don't miss anything we simply don't
6475 reset the top level flags until the condition ends up being
6476 in the right state. */
6477 if (f->size_changed)
6478 size_change_failed = 1;
6481 DEVICE_FRAME_LOOP (frmcons, d)
6483 f = XFRAME (XCAR (frmcons));
6485 if (f == XFRAME (DEVICE_SELECTED_FRAME (d)))
6488 if (f->icon_changed || f->windows_changed)
6489 update_frame_icon (f);
6491 if (FRAME_REPAINT_P (f))
6493 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (f))
6495 preempted = redisplay_frame (f, 0);
6501 if (f->size_change_pending)
6502 size_change_failed = 1;
6506 /* If we get here then we redisplayed all of our frames without
6507 getting preempted so mark ourselves as clean. */
6508 CLASS_RESET_CHANGED_FLAGS (d);
6510 if (!size_change_failed)
6511 d->size_changed = 0;
6517 restore_profiling_redisplay_flag (Lisp_Object val)
6519 profiling_redisplay_flag = XINT (val);
6523 /* Ensure that all windows on all frames on all devices are displaying
6524 the current contents of their respective buffers. */
6527 redisplay_without_hooks (void)
6529 Lisp_Object devcons, concons;
6530 int size_change_failed = 0;
6531 int count = specpdl_depth ();
6533 if (profiling_active)
6535 record_unwind_protect (restore_profiling_redisplay_flag,
6536 make_int (profiling_redisplay_flag));
6537 profiling_redisplay_flag = 1;
6540 if (asynch_device_change_pending)
6541 handle_asynch_device_change ();
6543 if (!GLOBAL_REDISPLAY_FLAGS_CHANGEDP &&
6544 !disable_preemption && preemption_count < max_preempts)
6547 DEVICE_LOOP_NO_BREAK (devcons, concons)
6549 struct device *d = XDEVICE (XCAR (devcons));
6552 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (d))
6554 preempted = redisplay_device (d, 1);
6559 RESET_CHANGED_SET_FLAGS;
6563 /* See comment in redisplay_device. */
6564 if (d->size_changed)
6565 size_change_failed = 1;
6568 preemption_count = 0;
6570 /* Mark redisplay as accurate */
6571 GLOBAL_RESET_CHANGED_FLAGS;
6572 RESET_CHANGED_SET_FLAGS;
6576 mark_all_faces_as_clean ();
6580 if (!size_change_failed)
6583 reset_buffer_changes ();
6586 unbind_to (count, Qnil);
6592 if (last_display_warning_tick != display_warning_tick &&
6593 !inhibit_warning_display)
6595 /* If an error occurs during this function, oh well.
6596 If we report another warning, we could get stuck in an
6597 infinite loop reporting warnings. */
6598 call0_trapping_errors (0, Qdisplay_warning_buffer);
6599 last_display_warning_tick = display_warning_tick;
6601 /* The run_hook_trapping_errors functions are smart enough not
6602 to do any evalling if the hook function is empty, so there
6603 should not be any significant time loss. All places in the
6604 C code that call redisplay() are prepared to handle GCing,
6605 so we should be OK. */
6606 #ifndef INHIBIT_REDISPLAY_HOOKS
6607 run_hook_trapping_errors ("Error in pre-redisplay-hook",
6608 Qpre_redisplay_hook);
6609 #endif /* INHIBIT_REDISPLAY_HOOKS */
6611 redisplay_without_hooks ();
6613 #ifndef INHIBIT_REDISPLAY_HOOKS
6614 run_hook_trapping_errors ("Error in post-redisplay-hook",
6615 Qpost_redisplay_hook);
6616 #endif /* INHIBIT_REDISPLAY_HOOKS */
6620 static char window_line_number_buf[32];
6622 /* Efficiently determine the window line number, and return a pointer
6623 to its printed representation. Do this regardless of whether
6624 line-number-mode is on. The first line in the buffer is counted as
6625 1. If narrowing is in effect, the lines are counted from the
6626 beginning of the visible portion of the buffer. */
6628 window_line_number (struct window *w, int type)
6630 struct device *d = XDEVICE (XFRAME (w->frame)->device);
6631 struct buffer *b = XBUFFER (w->buffer);
6632 /* Be careful in the order of these tests. The first clause will
6633 fail if DEVICE_SELECTED_FRAME == Qnil (since w->frame cannot be).
6634 This can occur when the frame title is computed really early */
6636 ((EQ(DEVICE_SELECTED_FRAME(d), w->frame) &&
6637 (w == XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame(d)))) &&
6638 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
6639 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d )
6641 : marker_position (w->pointm[type]));
6644 line = buffer_line_number (b, pos, 1);
6646 long_to_string (window_line_number_buf, line + 1);
6648 return window_line_number_buf;
6652 /* Given a character representing an object in a modeline
6653 specification, return a string (stored into the global array
6654 `mode_spec_bufbyte_string') with the information that object
6657 This function is largely unchanged from previous versions of the
6660 Warning! This code is also used for frame titles and can be called
6661 very early in the device/frame update process! JV
6665 decode_mode_spec (struct window *w, Emchar spec, int type)
6667 Lisp_Object obj = Qnil;
6668 const char *str = NULL;
6669 struct buffer *b = XBUFFER (w->buffer);
6671 Dynarr_reset (mode_spec_bufbyte_string);
6675 /* print buffer name */
6680 /* print visited file name */
6685 /* print the current column */
6688 Bufpos pt = (w == XWINDOW (Fselected_window (Qnil)))
6690 : marker_position (w->pointm[type]);
6691 int col = column_at_point (b, pt, 1) + !!column_number_start_at_one;
6694 long_to_string (buf, col);
6696 Dynarr_add_many (mode_spec_bufbyte_string,
6697 (const Bufbyte *) buf, strlen (buf));
6699 goto decode_mode_spec_done;
6701 /* print the file coding system */
6705 Lisp_Object codesys = b->buffer_file_coding_system;
6706 /* Be very careful here not to get an error. */
6707 if (NILP (codesys) || SYMBOLP (codesys) || CODING_SYSTEMP (codesys))
6709 codesys = Ffind_coding_system (codesys);
6710 if (CODING_SYSTEMP (codesys))
6711 obj = XCODING_SYSTEM_MNEMONIC (codesys);
6714 #endif /* FILE_CODING */
6717 /* print the current line number */
6719 str = window_line_number (w, type);
6722 /* print value of mode-name (obsolete) */
6727 /* print hyphen and frame number, if != 1 */
6731 struct frame *f = XFRAME (w->frame);
6732 if (FRAME_TTY_P (f) && f->order_count > 1 && f->order_count <= 99999999)
6734 /* Naughty, naughty */
6735 char * writable_str = alloca_array (char, 10);
6736 sprintf (writable_str, "-%d", f->order_count);
6740 #endif /* HAVE_TTY */
6743 /* print Narrow if appropriate */
6745 if (BUF_BEGV (b) > BUF_BEG (b)
6746 || BUF_ZV (b) < BUF_Z (b))
6750 /* print %, * or hyphen, if buffer is read-only, modified or neither */
6752 str = (!NILP (b->read_only)
6754 : ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6759 /* print * or hyphen -- XEmacs change to allow a buffer to be
6760 read-only but still indicate whether it is modified. */
6762 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6764 : (!NILP (b->read_only)
6769 /* #### defined in 19.29 decode_mode_spec, but not in
6770 modeline-format doc string. */
6771 /* This differs from %* in that it ignores read-only-ness. */
6773 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6778 /* print process status */
6780 obj = Fget_buffer_process (w->buffer);
6782 str = GETTEXT ("no process");
6784 obj = Fsymbol_name (Fprocess_status (obj));
6787 /* Print name of selected frame. */
6789 obj = XFRAME (w->frame)->name;
6792 /* indicate TEXT or BINARY */
6794 /* #### NT does not use this any more. Now what? */
6798 /* print percent of buffer above top of window, or Top, Bot or All */
6801 Bufpos pos = marker_position (w->start[type]);
6803 /* This had better be while the desired lines are being done. */
6804 if (w->window_end_pos[type] <= BUF_Z (b) - BUF_ZV (b))
6806 if (pos <= BUF_BEGV (b))
6811 else if (pos <= BUF_BEGV (b))
6815 /* This hard limit is ok since the string it will hold has a
6816 fixed maximum length of 3. But just to be safe... */
6818 Charcount chars = pos - BUF_BEGV (b);
6819 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6821 /* Avoid overflow on big buffers */
6822 int percent = total > LONG_MAX/200 ?
6823 (chars + total/200) / (total / 100) :
6824 (chars * 100 + total/2) / total;
6826 /* We can't normally display a 3-digit number, so get us a
6827 2-digit number that is close. */
6831 sprintf (buf, "%d%%", percent);
6832 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6835 goto decode_mode_spec_done;
6840 /* print percent of buffer above bottom of window, perhaps plus
6841 Top, or print Bottom or All */
6844 Bufpos toppos = marker_position (w->start[type]);
6845 Bufpos botpos = BUF_Z (b) - w->window_end_pos[type];
6847 /* botpos is only accurate as of the last redisplay, so we can
6848 only treat it as a hint. In particular, after erase-buffer,
6849 botpos may be negative. */
6850 if (botpos < toppos)
6853 if (botpos >= BUF_ZV (b))
6855 if (toppos <= BUF_BEGV (b))
6862 /* This hard limit is ok since the string it will hold has a
6863 fixed maximum length of around 6. But just to be safe... */
6865 Charcount chars = botpos - BUF_BEGV (b);
6866 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6868 /* Avoid overflow on big buffers */
6869 int percent = total > LONG_MAX/200 ?
6870 (chars + total/200) / (total / 100) :
6871 (chars * 100 + total/2) / max (total, 1);
6873 /* We can't normally display a 3-digit number, so get us a
6874 2-digit number that is close. */
6878 if (toppos <= BUF_BEGV (b))
6879 sprintf (buf, "Top%d%%", percent);
6881 sprintf (buf, "%d%%", percent);
6883 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6886 goto decode_mode_spec_done;
6896 /* print one [ for each recursive editing level. */
6901 if (command_loop_level > 5)
6907 for (i = 0; i < command_loop_level; i++)
6908 Dynarr_add (mode_spec_bufbyte_string, '[');
6910 goto decode_mode_spec_done;
6913 /* print one ] for each recursive editing level. */
6918 if (command_loop_level > 5)
6924 for (i = 0; i < command_loop_level; i++)
6925 Dynarr_add (mode_spec_bufbyte_string, ']');
6927 goto decode_mode_spec_done;
6930 /* print infinitely many dashes -- handle at top level now */
6937 Dynarr_add_many (mode_spec_bufbyte_string,
6939 XSTRING_LENGTH (obj));
6941 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) str, strlen (str));
6943 decode_mode_spec_done:
6944 Dynarr_add (mode_spec_bufbyte_string, '\0');
6947 /* Given a display line, free all of its data structures. */
6950 free_display_line (struct display_line *dl)
6954 if (dl->display_blocks)
6956 for (block = 0; block < Dynarr_largest (dl->display_blocks); block++)
6958 struct display_block *db = Dynarr_atp (dl->display_blocks, block);
6960 Dynarr_free (db->runes);
6963 Dynarr_free (dl->display_blocks);
6964 dl->display_blocks = NULL;
6967 if (dl->left_glyphs)
6969 Dynarr_free (dl->left_glyphs);
6970 dl->left_glyphs = NULL;
6973 if (dl->right_glyphs)
6975 Dynarr_free (dl->right_glyphs);
6976 dl->right_glyphs = NULL;
6981 /* Given an array of display lines, free them and all data structures
6982 contained within them. */
6985 free_display_lines (display_line_dynarr *dla)
6989 for (line = 0; line < Dynarr_largest (dla); line++)
6991 free_display_line (Dynarr_atp (dla, line));
6997 /* Call internal free routine for each set of display lines. */
7000 free_display_structs (struct window_mirror *mir)
7002 if (mir->current_display_lines)
7004 free_display_lines (mir->current_display_lines);
7005 mir->current_display_lines = 0;
7008 if (mir->desired_display_lines)
7010 free_display_lines (mir->desired_display_lines);
7011 mir->desired_display_lines = 0;
7017 mark_glyph_block_dynarr (glyph_block_dynarr *gba)
7021 glyph_block *gb = Dynarr_atp (gba, 0);
7022 glyph_block *gb_last = Dynarr_atp (gba, Dynarr_length (gba));
7024 for (; gb < gb_last; gb++)
7026 if (!NILP (gb->glyph))
7027 mark_object (gb->glyph);
7028 if (!NILP (gb->extent))
7029 mark_object (gb->extent);
7034 /* See the comment in image_instantiate_cache_result as to why marking
7035 the glyph will also mark the image_instance. */
7037 mark_redisplay_structs (display_line_dynarr *dla)
7039 display_line *dl = Dynarr_atp (dla, 0);
7040 display_line *dl_last = Dynarr_atp (dla, Dynarr_length (dla));
7042 for (; dl < dl_last; dl++)
7044 display_block_dynarr *dba = dl->display_blocks;
7045 display_block *db = Dynarr_atp (dba, 0);
7046 display_block *db_last = Dynarr_atp (dba, Dynarr_length (dba));
7048 for (; db < db_last; db++)
7050 rune_dynarr *ra = db->runes;
7051 rune *r = Dynarr_atp (ra, 0);
7052 rune *r_last = Dynarr_atp (ra, Dynarr_length (ra));
7054 for (; r < r_last; r++)
7056 if (r->type == RUNE_DGLYPH)
7058 if (!NILP (r->object.dglyph.glyph))
7059 mark_object (r->object.dglyph.glyph);
7060 if (!NILP (r->object.dglyph.extent))
7061 mark_object (r->object.dglyph.extent);
7066 mark_glyph_block_dynarr (dl->left_glyphs);
7067 mark_glyph_block_dynarr (dl->right_glyphs);
7072 mark_window_mirror (struct window_mirror *mir)
7074 mark_redisplay_structs (mir->current_display_lines);
7075 mark_redisplay_structs (mir->desired_display_lines);
7078 mark_window_mirror (mir->next);
7081 mark_window_mirror (mir->hchild);
7082 else if (mir->vchild)
7083 mark_window_mirror (mir->vchild);
7087 mark_redisplay (void)
7089 Lisp_Object frmcons, devcons, concons;
7091 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
7093 struct frame *f = XFRAME (XCAR (frmcons));
7094 update_frame_window_mirror (f);
7095 mark_window_mirror (f->root_mirror);
7100 /*****************************************************************************
7101 Line Start Cache Description and Rationale
7103 The traditional scrolling code in Emacs breaks in a variable height world.
7104 It depends on the key assumption that the number of lines that can be
7105 displayed at any given time is fixed. This led to a complete separation
7106 of the scrolling code from the redisplay code. In order to fully support
7107 variable height lines, the scrolling code must actually be tightly
7108 integrated with redisplay. Only redisplay can determine how many lines
7109 will be displayed on a screen for any given starting point.
7111 What is ideally wanted is a complete list of the starting buffer position
7112 for every possible display line of a buffer along with the height of that
7113 display line. Maintaining such a full list would be very expensive. We
7114 settle for having it include information for all areas which we happen to
7115 generate anyhow (i.e. the region currently being displayed) and for those
7116 areas we need to work with.
7118 In order to ensure that the cache accurately represents what redisplay
7119 would actually show, it is necessary to invalidate it in many situations.
7120 If the buffer changes, the starting positions may no longer be correct.
7121 If a face or an extent has changed then the line heights may have altered.
7122 These events happen frequently enough that the cache can end up being
7123 constantly disabled. With this potentially constant invalidation when is
7124 the cache ever useful?
7126 Even if the cache is invalidated before every single usage, it is
7127 necessary. Scrolling often requires knowledge about display lines which
7128 are actually above or below the visible region. The cache provides a
7129 convenient light-weight method of storing this information for multiple
7130 display regions. This knowledge is necessary for the scrolling code to
7131 always obey the First Golden Rule of Redisplay.
7133 If the cache already contains all of the information that the scrolling
7134 routines happen to need so that it doesn't have to go generate it, then we
7135 are able to obey the Third Golden Rule of Redisplay. The first thing we
7136 do to help out the cache is to always add the displayed region. This
7137 region had to be generated anyway, so the cache ends up getting the
7138 information basically for free. In those cases where a user is simply
7139 scrolling around viewing a buffer there is a high probability that this is
7140 sufficient to always provide the needed information. The second thing we
7141 can do is be smart about invalidating the cache.
7143 TODO -- Be smart about invalidating the cache. Potential places:
7145 + Insertions at end-of-line which don't cause line-wraps do not alter the
7146 starting positions of any display lines. These types of buffer
7147 modifications should not invalidate the cache. This is actually a large
7148 optimization for redisplay speed as well.
7150 + Buffer modifications frequently only affect the display of lines at and
7151 below where they occur. In these situations we should only invalidate
7152 the part of the cache starting at where the modification occurs.
7154 In case you're wondering, the Second Golden Rule of Redisplay is not
7156 ****************************************************************************/
7158 /* This will get used quite a bit so we don't want to be constantly
7159 allocating and freeing it. */
7160 static line_start_cache_dynarr *internal_cache;
7162 /* Makes internal_cache represent the TYPE display structs and only
7163 the TYPE display structs. */
7166 update_internal_cache_list (struct window *w, int type)
7169 display_line_dynarr *dla = window_display_lines (w, type);
7171 Dynarr_reset (internal_cache);
7172 for (line = 0; line < Dynarr_length (dla); line++)
7174 struct display_line *dl = Dynarr_atp (dla, line);
7180 struct line_start_cache lsc;
7182 lsc.start = dl->bufpos;
7183 lsc.end = dl->end_bufpos;
7184 lsc.height = dl->ascent + dl->descent;
7186 Dynarr_add (internal_cache, lsc);
7191 /* Reset the line cache if necessary. This should be run at the
7192 beginning of any function which access the cache. */
7195 validate_line_start_cache (struct window *w)
7197 struct buffer *b = XBUFFER (w->buffer);
7198 struct frame *f = XFRAME (w->frame);
7200 if (!w->line_cache_validation_override)
7202 /* f->extents_changed used to be in here because extent face and
7203 size changes can cause text shifting. However, the extent
7204 covering the region is constantly having its face set and
7205 priority altered by the mouse code. This means that the line
7206 start cache is constantly being invalidated. This is bad
7207 since the mouse code also triggers heavy usage of the cache.
7208 Since it is an unlikely that f->extents being changed
7209 indicates that the cache really needs to be updated and if it
7210 does redisplay will catch it pretty quickly we no longer
7211 invalidate the cache if it is set. This greatly speeds up
7212 dragging out regions with the mouse. */
7213 if (XINT (w->line_cache_last_updated) < BUF_MODIFF (b)
7217 Dynarr_reset (w->line_start_cache);
7222 /* Return the very first buffer position contained in the given
7223 window's cache, or -1 if the cache is empty. Assumes that the
7227 line_start_cache_start (struct window *w)
7229 line_start_cache_dynarr *cache = w->line_start_cache;
7231 if (!Dynarr_length (cache))
7234 return Dynarr_atp (cache, 0)->start;
7237 /* Return the very last buffer position contained in the given
7238 window's cache, or -1 if the cache is empty. Assumes that the
7242 line_start_cache_end (struct window *w)
7244 line_start_cache_dynarr *cache = w->line_start_cache;
7246 if (!Dynarr_length (cache))
7249 return Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
7252 /* Return the index of the line POINT is contained within in window
7253 W's line start cache. It will enlarge the cache or move the cache
7254 window in order to have POINT be present in the cache. MIN_PAST is
7255 a guarantee of the number of entries in the cache present on either
7256 side of POINT (unless a buffer boundary is hit). If MIN_PAST is -1
7257 then it will be treated as 0, but the cache window will not be
7258 allowed to shift. Returns -1 if POINT cannot be found in the cache
7262 point_in_line_start_cache (struct window *w, Bufpos point, int min_past)
7264 struct buffer *b = XBUFFER (w->buffer);
7265 line_start_cache_dynarr *cache = w->line_start_cache;
7266 unsigned int top, bottom, pos;
7268 validate_line_start_cache (w);
7269 w->line_cache_validation_override++;
7271 /* Let functions pass in negative values, but we still treat -1
7273 /* #### bogosity alert */
7274 if (min_past < 0 && min_past != -1)
7275 min_past = -min_past;
7277 if (!Dynarr_length (cache) || line_start_cache_start (w) > point
7278 || line_start_cache_end (w) < point)
7281 int win_char_height = window_char_height (w, 1);
7283 /* Occasionally we get here with a 0 height
7284 window. find_next_newline_no_quit will abort if we pass it a
7285 count of 0 so handle that case. */
7286 if (!win_char_height)
7287 win_char_height = 1;
7289 if (!Dynarr_length (cache))
7291 Bufpos from = find_next_newline_no_quit (b, point, -1);
7292 Bufpos to = find_next_newline_no_quit (b, from, win_char_height);
7294 update_line_start_cache (w, from, to, point, 0);
7296 if (!Dynarr_length (cache))
7298 w->line_cache_validation_override--;
7303 assert (Dynarr_length (cache));
7306 while (line_start_cache_start (w) > point
7307 && (loop < cache_adjustment || min_past == -1))
7311 from = line_start_cache_start (w);
7312 if (from <= BUF_BEGV (b))
7315 from = find_next_newline_no_quit (b, from, -win_char_height);
7316 to = line_start_cache_end (w);
7318 update_line_start_cache (w, from, to, point, 0);
7322 if (line_start_cache_start (w) > point)
7326 from = find_next_newline_no_quit (b, point, -1);
7327 if (from >= BUF_ZV (b))
7329 to = find_next_newline_no_quit (b, from, -win_char_height);
7334 to = find_next_newline_no_quit (b, from, win_char_height);
7336 update_line_start_cache (w, from, to, point, 0);
7340 while (line_start_cache_end (w) < point
7341 && (loop < cache_adjustment || min_past == -1))
7345 to = line_start_cache_end (w);
7346 if (to >= BUF_ZV (b))
7349 from = line_start_cache_end (w);
7350 to = find_next_newline_no_quit (b, from, win_char_height);
7352 update_line_start_cache (w, from, to, point, 0);
7356 if (line_start_cache_end (w) < point)
7360 from = find_next_newline_no_quit (b, point, -1);
7361 if (from >= BUF_ZV (b))
7363 to = find_next_newline_no_quit (b, from, -win_char_height);
7368 to = find_next_newline_no_quit (b, from, win_char_height);
7370 update_line_start_cache (w, from, to, point, 0);
7374 assert (Dynarr_length (cache));
7379 /* This could happen if the buffer is narrowed. */
7380 if (line_start_cache_start (w) > point
7381 || line_start_cache_end (w) < point)
7383 w->line_cache_validation_override--;
7389 top = Dynarr_length (cache) - 1;
7394 unsigned int new_pos;
7397 pos = (bottom + top + 1) >> 1;
7398 start = Dynarr_atp (cache, pos)->start;
7399 end = Dynarr_atp (cache, pos)->end;
7401 if (point >= start && point <= end)
7403 if (pos < min_past && line_start_cache_start (w) > BUF_BEGV (b))
7406 find_next_newline_no_quit (b, line_start_cache_start (w),
7408 Bufpos to = line_start_cache_end (w);
7410 update_line_start_cache (w, from, to, point, 0);
7411 goto find_point_loop;
7413 else if ((Dynarr_length (cache) - pos - 1) < min_past
7414 && line_start_cache_end (w) < BUF_ZV (b))
7416 Bufpos from = line_start_cache_end (w);
7417 Bufpos to = find_next_newline_no_quit (b, from,
7422 update_line_start_cache (w, from, to, point, 0);
7423 goto find_point_loop;
7427 w->line_cache_validation_override--;
7431 else if (point > end)
7433 else if (point < start)
7438 new_pos = (bottom + top + 1) >> 1;
7441 w->line_cache_validation_override--;
7447 /* Return a boolean indicating if POINT would be visible in window W
7448 if display of the window was to begin at STARTP. */
7451 point_would_be_visible (struct window *w, Bufpos startp, Bufpos point)
7453 struct buffer *b = XBUFFER (w->buffer);
7454 int pixpos = -WINDOW_TEXT_TOP_CLIP(w);
7455 int bottom = WINDOW_TEXT_HEIGHT (w);
7458 /* If point is before the intended start it obviously can't be visible. */
7462 /* If point or start are not in the accessible buffer range, then
7464 if (startp < BUF_BEGV (b) || startp > BUF_ZV (b)
7465 || point < BUF_BEGV (b) || point > BUF_ZV (b))
7468 validate_line_start_cache (w);
7469 w->line_cache_validation_override++;
7471 start_elt = point_in_line_start_cache (w, startp, 0);
7472 if (start_elt == -1)
7474 w->line_cache_validation_override--;
7478 assert (line_start_cache_start (w) <= startp
7479 && line_start_cache_end (w) >= startp);
7485 /* Expand the cache if necessary. */
7486 if (start_elt == Dynarr_length (w->line_start_cache))
7489 Dynarr_atp (w->line_start_cache, start_elt - 1)->start;
7491 start_elt = point_in_line_start_cache (w, old_startp,
7492 window_char_height (w, 0));
7494 /* We've already actually processed old_startp, so increment
7498 /* If this happens we didn't add any extra elements. Bummer. */
7499 if (start_elt == Dynarr_length (w->line_start_cache))
7501 w->line_cache_validation_override--;
7506 height = Dynarr_atp (w->line_start_cache, start_elt)->height;
7508 if (pixpos + height > bottom)
7510 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7512 w->line_cache_validation_override--;
7518 if (point <= Dynarr_atp (w->line_start_cache, start_elt)->end)
7520 w->line_cache_validation_override--;
7528 /* For the given window W, if display starts at STARTP, what will be
7529 the buffer position at the beginning or end of the last line
7530 displayed. The end of the last line is also know as the window end
7533 WARNING: It is possible that rediplay failed to layout any lines for the
7534 windows. Under normal circumstances this is rare. However it seems that it
7535 does occur in the following situation: A mouse event has come in and we
7536 need to compute its location in a window. That code (in
7537 pixel_to_glyph_translation) already can handle 0 as an error return value.
7539 #### With a little work this could probably be reworked as just a
7540 call to start_with_line_at_pixpos. */
7543 start_end_of_last_line (struct window *w, Bufpos startp, int end,
7546 struct buffer *b = XBUFFER (w->buffer);
7547 line_start_cache_dynarr *cache = w->line_start_cache;
7549 int bottom = WINDOW_TEXT_HEIGHT (w);
7553 validate_line_start_cache (w);
7554 w->line_cache_validation_override++;
7556 if (startp < BUF_BEGV (b))
7557 startp = BUF_BEGV (b);
7558 else if (startp > BUF_ZV (b))
7559 startp = BUF_ZV (b);
7562 start_elt = point_in_line_start_cache (w, cur_start, 0);
7563 if (start_elt == -1)
7564 return may_error ? 0 : startp;
7568 int height = Dynarr_atp (cache, start_elt)->height;
7570 cur_start = Dynarr_atp (cache, start_elt)->start;
7572 if (pixpos + height > bottom)
7574 /* Adjust for any possible clip. */
7575 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7580 w->line_cache_validation_override--;
7584 return BUF_BEGV (b);
7588 w->line_cache_validation_override--;
7590 return Dynarr_atp (cache, start_elt)->end;
7592 return Dynarr_atp (cache, start_elt)->start;
7598 if (start_elt == Dynarr_length (cache))
7600 Bufpos from = line_start_cache_end (w);
7601 int win_char_height = window_char_height (w, 0);
7602 Bufpos to = find_next_newline_no_quit (b, from,
7607 /* We've hit the end of the bottom so that's what it is. */
7608 if (from >= BUF_ZV (b))
7610 w->line_cache_validation_override--;
7614 update_line_start_cache (w, from, to, BUF_PT (b), 0);
7616 /* Updating the cache invalidates any current indexes. */
7617 start_elt = point_in_line_start_cache (w, cur_start, -1) + 1;
7622 /* For the given window W, if display starts at STARTP, what will be
7623 the buffer position at the beginning of the last line displayed. */
7626 start_of_last_line (struct window *w, Bufpos startp)
7628 return start_end_of_last_line (w, startp, 0 , 0);
7631 /* For the given window W, if display starts at STARTP, what will be
7632 the buffer position at the end of the last line displayed. This is
7633 also know as the window end position. */
7636 end_of_last_line (struct window *w, Bufpos startp)
7638 return start_end_of_last_line (w, startp, 1, 0);
7642 end_of_last_line_may_error (struct window *w, Bufpos startp)
7644 return start_end_of_last_line (w, startp, 1, 1);
7648 /* For window W, what does the starting position have to be so that
7649 the line containing POINT will cover pixel position PIXPOS. */
7652 start_with_line_at_pixpos (struct window *w, Bufpos point, int pixpos)
7654 struct buffer *b = XBUFFER (w->buffer);
7656 Bufpos cur_pos, prev_pos = point;
7657 int point_line_height;
7658 int pixheight = pixpos - WINDOW_TEXT_TOP (w);
7660 validate_line_start_cache (w);
7661 w->line_cache_validation_override++;
7663 cur_elt = point_in_line_start_cache (w, point, 0);
7664 /* #### See comment in update_line_start_cache about big minibuffers. */
7667 w->line_cache_validation_override--;
7671 point_line_height = Dynarr_atp (w->line_start_cache, cur_elt)->height;
7675 cur_pos = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7677 pixheight -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7679 /* Do not take into account the value of vertical_clip here.
7680 That is the responsibility of the calling functions. */
7683 w->line_cache_validation_override--;
7684 if (-pixheight > point_line_height)
7685 /* We can't make the target line cover pixpos, so put it
7686 above pixpos. That way it will at least be visible. */
7696 int win_char_height;
7698 if (cur_pos <= BUF_BEGV (b))
7700 w->line_cache_validation_override--;
7701 return BUF_BEGV (b);
7704 win_char_height = window_char_height (w, 0);
7705 if (!win_char_height)
7706 win_char_height = 1;
7708 from = find_next_newline_no_quit (b, cur_pos, -win_char_height);
7709 to = line_start_cache_end (w);
7710 update_line_start_cache (w, from, to, point, 0);
7712 cur_elt = point_in_line_start_cache (w, cur_pos, 2) - 1;
7713 assert (cur_elt >= -1);
7714 /* This used to be cur_elt>=0 under the assumption that if
7715 point is in the top line and not at BUF_BEGV, then
7716 setting the window_start to a newline before the start of
7717 the first line will always cause scrolling.
7719 However in my (jv) opinion this is wrong. That new line
7720 can be hidden in various ways: invisible extents, an
7721 explicit window-start not at a newline character etc.
7722 The existence of those are indeed known to create crashes
7723 on that assert. So we have no option but to continue the
7724 search if we found point at the top of the line_start_cache
7726 cur_pos = Dynarr_atp (w->line_start_cache,0)->start;
7732 /* For window W, what does the starting position have to be so that
7733 the line containing point is on display line LINE. If LINE is
7734 positive it is considered to be the number of lines from the top of
7735 the window (0 is the top line). If it is negative the number is
7736 considered to be the number of lines from the bottom (-1 is the
7740 start_with_point_on_display_line (struct window *w, Bufpos point, int line)
7742 validate_line_start_cache (w);
7743 w->line_cache_validation_override++;
7747 int cur_elt = point_in_line_start_cache (w, point, line);
7749 if (cur_elt - line < 0)
7750 cur_elt = 0; /* Hit the top */
7754 w->line_cache_validation_override--;
7755 return Dynarr_atp (w->line_start_cache, cur_elt)->start;
7759 /* The calculated value of pixpos is correct for the bottom line
7760 or what we want when line is -1. Therefore we subtract one
7761 because we have already handled one line. */
7762 int new_line = -line - 1;
7763 int cur_elt = point_in_line_start_cache (w, point, new_line);
7764 int pixpos = WINDOW_TEXT_BOTTOM (w);
7765 Bufpos retval, search_point;
7767 /* If scroll_on_clipped_lines is false, the last "visible" line of
7768 the window covers the pixel at WINDOW_TEXT_BOTTOM (w) - 1.
7769 If s_o_c_l is true, then we don't want to count a clipped
7770 line, so back up from the bottom by the height of the line
7771 containing point. */
7772 if (scroll_on_clipped_lines)
7773 pixpos -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7777 if (cur_elt + new_line >= Dynarr_length (w->line_start_cache))
7779 /* Hit the bottom of the buffer. */
7781 (cur_elt + new_line) - Dynarr_length (w->line_start_cache) + 1;
7785 XSETWINDOW (window, w);
7786 default_face_height_and_width (window, &defheight, 0);
7788 cur_elt = Dynarr_length (w->line_start_cache) - 1;
7790 pixpos -= (adjustment * defheight);
7791 if (pixpos < WINDOW_TEXT_TOP (w))
7792 pixpos = WINDOW_TEXT_TOP (w);
7795 cur_elt = cur_elt + new_line;
7797 search_point = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7799 retval = start_with_line_at_pixpos (w, search_point, pixpos);
7800 w->line_cache_validation_override--;
7805 /* This is used to speed up vertical scrolling by caching the known
7806 buffer starting positions for display lines. This allows the
7807 scrolling routines to avoid costly calls to regenerate_window. If
7808 NO_REGEN is true then it will only add the values in the DESIRED
7809 display structs which are in the given range.
7811 Note also that the FROM/TO values are minimums. It is possible
7812 that this function will actually add information outside of the
7813 lines containing those positions. This can't hurt but it could
7816 #### We currently force the cache to have only 1 contiguous region.
7817 It might help to make the cache a dynarr of caches so that we can
7818 cover more areas. This might, however, turn out to be a lot of
7819 overhead for too little gain. */
7822 update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
7823 Bufpos point, int no_regen)
7825 struct buffer *b = XBUFFER (w->buffer);
7826 line_start_cache_dynarr *cache = w->line_start_cache;
7827 Bufpos low_bound, high_bound;
7829 validate_line_start_cache (w);
7830 w->line_cache_validation_override++;
7832 if (from < BUF_BEGV (b))
7833 from = BUF_BEGV (b);
7834 if (to > BUF_ZV (b))
7839 w->line_cache_validation_override--;
7843 if (Dynarr_length (cache))
7845 low_bound = line_start_cache_start (w);
7846 high_bound = line_start_cache_end (w);
7848 /* Check to see if the desired range is already in the cache. */
7849 if (from >= low_bound && to <= high_bound)
7851 w->line_cache_validation_override--;
7855 /* Check to make sure that the desired range is adjacent to the
7856 current cache. If not, invalidate the cache. */
7857 if (to < low_bound || from > high_bound)
7859 Dynarr_reset (cache);
7860 low_bound = high_bound = -1;
7865 low_bound = high_bound = -1;
7868 w->line_cache_last_updated = make_int (BUF_MODIFF (b));
7870 /* This could be integrated into the next two sections, but it is easier
7871 to follow what's going on by having it separate. */
7876 update_internal_cache_list (w, DESIRED_DISP);
7877 if (!Dynarr_length (internal_cache))
7879 w->line_cache_validation_override--;
7883 start = Dynarr_atp (internal_cache, 0)->start;
7885 Dynarr_atp (internal_cache, Dynarr_length (internal_cache) - 1)->end;
7887 /* We aren't allowed to generate additional information to fill in
7888 gaps, so if the DESIRED structs don't overlap the cache, reset the
7890 if (Dynarr_length (cache))
7892 if (end < low_bound || start > high_bound)
7893 Dynarr_reset (cache);
7895 /* #### What should really happen if what we are doing is
7896 extending a line (the last line)? */
7897 if (Dynarr_length (cache) == 1
7898 && Dynarr_length (internal_cache) == 1)
7899 Dynarr_reset (cache);
7902 if (!Dynarr_length (cache))
7904 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7905 Dynarr_length (internal_cache));
7906 w->line_cache_validation_override--;
7910 /* An extra check just in case the calling function didn't pass in
7911 the bounds of the DESIRED structs in the first place. */
7912 if (start >= low_bound && end <= high_bound)
7914 w->line_cache_validation_override--;
7918 /* At this point we know that the internal cache partially overlaps
7920 if (start < low_bound)
7922 int ic_elt = Dynarr_length (internal_cache) - 1;
7925 if (Dynarr_atp (internal_cache, ic_elt)->start < low_bound)
7933 Dynarr_reset (cache);
7934 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7935 Dynarr_length (internal_cache));
7936 w->line_cache_validation_override--;
7940 Dynarr_insert_many_at_start (cache, Dynarr_atp (internal_cache, 0),
7944 if (end > high_bound)
7948 while (ic_elt < Dynarr_length (internal_cache))
7950 if (Dynarr_atp (internal_cache, ic_elt)->start > high_bound)
7956 if (!(ic_elt < Dynarr_length (internal_cache)))
7958 Dynarr_reset (cache);
7959 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7960 Dynarr_length (internal_cache));
7961 w->line_cache_validation_override--;
7965 Dynarr_add_many (cache, Dynarr_atp (internal_cache, ic_elt),
7966 Dynarr_length (internal_cache) - ic_elt);
7969 w->line_cache_validation_override--;
7973 if (!Dynarr_length (cache) || from < low_bound)
7975 Bufpos startp = find_next_newline_no_quit (b, from, -1);
7977 int old_lb = low_bound;
7979 while (startp < old_lb || low_bound == -1)
7984 regenerate_window (w, startp, point, CMOTION_DISP);
7985 update_internal_cache_list (w, CMOTION_DISP);
7987 /* If this assert is triggered then regenerate_window failed
7988 to layout a single line. This is not possible since we
7989 force at least a single line to be layout for CMOTION_DISP */
7990 assert (Dynarr_length (internal_cache));
7991 assert (startp == Dynarr_atp (internal_cache, 0)->start);
7993 ic_elt = Dynarr_length (internal_cache) - 1;
7994 if (low_bound != -1)
7998 if (Dynarr_atp (internal_cache, ic_elt)->start < old_lb)
8004 assert (ic_elt >= 0);
8006 new_startp = Dynarr_atp (internal_cache, ic_elt)->end + 1;
8009 * Handle invisible text properly:
8010 * If the last line we're inserting has the same end as the
8011 * line before which it will be added, merge the two lines.
8013 if (Dynarr_length (cache) &&
8014 Dynarr_atp (internal_cache, ic_elt)->end ==
8015 Dynarr_atp (cache, marker)->end)
8017 Dynarr_atp (cache, marker)->start
8018 = Dynarr_atp (internal_cache, ic_elt)->start;
8019 Dynarr_atp (cache, marker)->height
8020 = Dynarr_atp (internal_cache, ic_elt)->height;
8024 if (ic_elt >= 0) /* we still have lines to add.. */
8026 Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0),
8027 ic_elt + 1, marker);
8028 marker += (ic_elt + 1);
8031 if (startp < low_bound || low_bound == -1)
8033 startp = new_startp;
8034 if (startp > BUF_ZV (b))
8036 w->line_cache_validation_override--;
8042 assert (Dynarr_length (cache));
8043 assert (from >= low_bound);
8045 /* Readjust the high_bound to account for any changes made while
8046 correcting the low_bound. */
8047 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8049 if (to > high_bound)
8051 Bufpos startp = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end + 1;
8055 regenerate_window (w, startp, point, CMOTION_DISP);
8056 update_internal_cache_list (w, CMOTION_DISP);
8058 /* See comment above about regenerate_window failing. */
8059 assert (Dynarr_length (internal_cache));
8061 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
8062 Dynarr_length (internal_cache));
8063 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8064 startp = high_bound + 1;
8066 while (to > high_bound);
8069 w->line_cache_validation_override--;
8070 assert (to <= high_bound);
8074 /* Given x and y coordinates in characters, relative to a window,
8075 return the pixel location corresponding to those coordinates. The
8076 pixel location returned is the center of the given character
8077 position. The pixel values are generated relative to the window,
8080 The modeline is considered to be part of the window. */
8083 glyph_to_pixel_translation (struct window *w, int char_x, int char_y,
8084 int *pix_x, int *pix_y)
8086 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
8087 int num_disp_lines, modeline;
8089 int defheight, defwidth;
8091 XSETWINDOW (window, w);
8092 default_face_height_and_width (window, &defheight, &defwidth);
8094 /* If we get a bogus value indicating somewhere above or to the left of
8095 the window, use the first window line or character position
8102 num_disp_lines = Dynarr_length (dla);
8106 if (Dynarr_atp (dla, 0)->modeline)
8113 /* First check if the y position intersects the display lines. */
8114 if (char_y < num_disp_lines)
8116 struct display_line *dl = Dynarr_atp (dla, char_y + modeline);
8117 struct display_block *db = get_display_block_from_line (dl, TEXT);
8119 *pix_y = (dl->ypos - dl->ascent +
8120 ((unsigned int) (dl->ascent + dl->descent - dl->clip) >> 1));
8122 if (char_x < Dynarr_length (db->runes))
8124 struct rune *rb = Dynarr_atp (db->runes, char_x);
8126 *pix_x = rb->xpos + (rb->width >> 1);
8130 int last_rune = Dynarr_length (db->runes) - 1;
8131 struct rune *rb = Dynarr_atp (db->runes, last_rune);
8133 char_x -= last_rune;
8135 *pix_x = rb->xpos + rb->width;
8136 *pix_x += ((char_x - 1) * defwidth);
8137 *pix_x += (defwidth >> 1);
8142 /* It didn't intersect, so extrapolate. #### For now, we include the
8143 modeline in this since we don't have true character positions in
8146 if (!Dynarr_length (w->face_cachels))
8147 reset_face_cachels (w);
8149 char_y -= num_disp_lines;
8151 if (Dynarr_length (dla))
8153 struct display_line *dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
8154 *pix_y = dl->ypos + dl->descent - dl->clip;
8157 *pix_y = WINDOW_TEXT_TOP (w);
8159 *pix_y += (char_y * defheight);
8160 *pix_y += (defheight >> 1);
8162 *pix_x = WINDOW_TEXT_LEFT (w);
8163 /* Don't adjust by one because this is still the unadjusted value. */
8164 *pix_x += (char_x * defwidth);
8165 *pix_x += (defwidth >> 1);
8168 if (*pix_x > w->pixel_left + w->pixel_width)
8169 *pix_x = w->pixel_left + w->pixel_width;
8170 if (*pix_y > w->pixel_top + w->pixel_height)
8171 *pix_y = w->pixel_top + w->pixel_height;
8173 *pix_x -= w->pixel_left;
8174 *pix_y -= w->pixel_top;
8177 /* Given a display line and a position, determine if there is a glyph
8178 there and return information about it if there is. */
8181 get_position_object (struct display_line *dl, Lisp_Object *obj1,
8182 Lisp_Object *obj2, int x_coord, int *low_x_coord,
8185 struct display_block *db;
8188 get_next_display_block (dl->bounds, dl->display_blocks, x_coord, 0);
8190 /* We use get_next_display_block to get the actual display block
8191 that would be displayed at x_coord. */
8193 if (block == NO_BLOCK)
8196 db = Dynarr_atp (dl->display_blocks, block);
8198 for (elt = 0; elt < Dynarr_length (db->runes); elt++)
8200 struct rune *rb = Dynarr_atp (db->runes, elt);
8202 if (rb->xpos <= x_coord && x_coord < (rb->xpos + rb->width))
8204 if (rb->type == RUNE_DGLYPH)
8206 *obj1 = rb->object.dglyph.glyph;
8207 *obj2 = rb->object.dglyph.extent;
8216 *low_x_coord = rb->xpos;
8218 *high_x_coord = rb->xpos + rb->width;
8225 #define UPDATE_CACHE_RETURN \
8227 d->pixel_to_glyph_cache.valid = 1; \
8228 d->pixel_to_glyph_cache.low_x_coord = low_x_coord; \
8229 d->pixel_to_glyph_cache.high_x_coord = high_x_coord; \
8230 d->pixel_to_glyph_cache.low_y_coord = low_y_coord; \
8231 d->pixel_to_glyph_cache.high_y_coord = high_y_coord; \
8232 d->pixel_to_glyph_cache.frame = f; \
8233 d->pixel_to_glyph_cache.col = *col; \
8234 d->pixel_to_glyph_cache.row = *row; \
8235 d->pixel_to_glyph_cache.obj_x = *obj_x; \
8236 d->pixel_to_glyph_cache.obj_y = *obj_y; \
8237 d->pixel_to_glyph_cache.w = *w; \
8238 d->pixel_to_glyph_cache.bufpos = *bufpos; \
8239 d->pixel_to_glyph_cache.closest = *closest; \
8240 d->pixel_to_glyph_cache.modeline_closest = *modeline_closest; \
8241 d->pixel_to_glyph_cache.obj1 = *obj1; \
8242 d->pixel_to_glyph_cache.obj2 = *obj2; \
8243 d->pixel_to_glyph_cache.retval = position; \
8244 RETURN_SANS_WARNINGS position; \
8247 /* Given x and y coordinates in pixels relative to a frame, return
8248 information about what is located under those coordinates.
8250 The return value will be one of:
8252 OVER_TOOLBAR: over one of the 4 frame toolbars
8253 OVER_MODELINE: over a modeline
8254 OVER_BORDER: over an internal border
8255 OVER_NOTHING: over the text area, but not over text
8256 OVER_OUTSIDE: outside of the frame border
8257 OVER_TEXT: over text in the text area
8263 -- nil if the coordinates are not over a glyph or a toolbar button.
8267 -- an extent, if the coordinates are over a glyph in the text area
8270 If the coordinates are over a glyph, OBJ_X and OBJ_Y give the
8271 equivalent coordinates relative to the upper-left corner of the glyph.
8273 If the coordinates are over a character, OBJ_X and OBJ_Y give the
8274 equivalent coordinates relative to the upper-left corner of the character.
8276 Otherwise, OBJ_X and OBJ_Y are undefined.
8280 pixel_to_glyph_translation (struct frame *f, int x_coord, int y_coord,
8281 int *col, int *row, int *obj_x, int *obj_y,
8282 struct window **w, Bufpos *bufpos,
8283 Bufpos *closest, Charcount *modeline_closest,
8284 Lisp_Object *obj1, Lisp_Object *obj2)
8287 struct pixel_to_glyph_translation_cache *cache;
8289 int frm_left, frm_right, frm_top, frm_bottom;
8290 int low_x_coord, high_x_coord, low_y_coord, high_y_coord;
8291 int position = OVER_NOTHING;
8292 int device_check_failed = 0;
8293 display_line_dynarr *dla;
8295 /* This is a safety valve in case this got called with a frame in
8296 the middle of being deleted. */
8297 if (!DEVICEP (f->device) || !DEVICE_LIVE_P (XDEVICE (f->device)))
8299 device_check_failed = 1;
8300 d = NULL, cache = NULL; /* Warning suppression */
8304 d = XDEVICE (f->device);
8305 cache = &d->pixel_to_glyph_cache;
8308 if (!device_check_failed
8310 && cache->frame == f
8311 && cache->low_x_coord <= x_coord
8312 && cache->high_x_coord > x_coord
8313 && cache->low_y_coord <= y_coord
8314 && cache->high_y_coord > y_coord)
8318 *obj_x = cache->obj_x;
8319 *obj_y = cache->obj_y;
8321 *bufpos = cache->bufpos;
8322 *closest = cache->closest;
8323 *modeline_closest = cache->modeline_closest;
8324 *obj1 = cache->obj1;
8325 *obj2 = cache->obj2;
8327 return cache->retval;
8338 *modeline_closest = -1;
8342 low_x_coord = x_coord;
8343 high_x_coord = x_coord + 1;
8344 low_y_coord = y_coord;
8345 high_y_coord = y_coord + 1;
8348 if (device_check_failed)
8349 return OVER_NOTHING;
8351 frm_left = FRAME_LEFT_BORDER_END (f);
8352 frm_right = FRAME_RIGHT_BORDER_START (f);
8353 frm_top = FRAME_TOP_BORDER_END (f);
8354 frm_bottom = FRAME_BOTTOM_BORDER_START (f);
8356 /* Check if the mouse is outside of the text area actually used by
8358 if (y_coord < frm_top)
8360 if (y_coord >= FRAME_TOP_BORDER_START (f))
8362 low_y_coord = FRAME_TOP_BORDER_START (f);
8363 high_y_coord = frm_top;
8364 position = OVER_BORDER;
8366 else if (y_coord >= 0)
8369 high_y_coord = FRAME_TOP_BORDER_START (f);
8370 position = OVER_TOOLBAR;
8374 low_y_coord = y_coord;
8376 position = OVER_OUTSIDE;
8379 else if (y_coord >= frm_bottom)
8381 if (y_coord < FRAME_BOTTOM_BORDER_END (f))
8383 low_y_coord = frm_bottom;
8384 high_y_coord = FRAME_BOTTOM_BORDER_END (f);
8385 position = OVER_BORDER;
8387 else if (y_coord < FRAME_PIXHEIGHT (f))
8389 low_y_coord = FRAME_BOTTOM_BORDER_END (f);
8390 high_y_coord = FRAME_PIXHEIGHT (f);
8391 position = OVER_TOOLBAR;
8395 low_y_coord = FRAME_PIXHEIGHT (f);
8396 high_y_coord = y_coord;
8397 position = OVER_OUTSIDE;
8401 if (position != OVER_TOOLBAR && position != OVER_BORDER)
8403 if (x_coord < frm_left)
8405 if (x_coord >= FRAME_LEFT_BORDER_START (f))
8407 low_x_coord = FRAME_LEFT_BORDER_START (f);
8408 high_x_coord = frm_left;
8409 position = OVER_BORDER;
8411 else if (x_coord >= 0)
8414 high_x_coord = FRAME_LEFT_BORDER_START (f);
8415 position = OVER_TOOLBAR;
8419 low_x_coord = x_coord;
8421 position = OVER_OUTSIDE;
8424 else if (x_coord >= frm_right)
8426 if (x_coord < FRAME_RIGHT_BORDER_END (f))
8428 low_x_coord = frm_right;
8429 high_x_coord = FRAME_RIGHT_BORDER_END (f);
8430 position = OVER_BORDER;
8432 else if (x_coord < FRAME_PIXWIDTH (f))
8434 low_x_coord = FRAME_RIGHT_BORDER_END (f);
8435 high_x_coord = FRAME_PIXWIDTH (f);
8436 position = OVER_TOOLBAR;
8440 low_x_coord = FRAME_PIXWIDTH (f);
8441 high_x_coord = x_coord;
8442 position = OVER_OUTSIDE;
8447 #ifdef HAVE_TOOLBARS
8448 if (position == OVER_TOOLBAR)
8450 *obj1 = toolbar_button_at_pixpos (f, x_coord, y_coord);
8453 UPDATE_CACHE_RETURN;
8455 #endif /* HAVE_TOOLBARS */
8457 /* We still have to return the window the pointer is next to and its
8458 relative y position even if it is outside the x boundary. */
8459 if (x_coord < frm_left)
8461 else if (x_coord > frm_right)
8462 x_coord = frm_right;
8464 /* Same in reverse. */
8465 if (y_coord < frm_top)
8467 else if (y_coord > frm_bottom)
8468 y_coord = frm_bottom;
8470 /* Find what window the given coordinates are actually in. */
8471 window = f->root_window;
8472 *w = find_window_by_pixel_pos (x_coord, y_coord, window);
8474 /* If we didn't find a window, we're done. */
8477 UPDATE_CACHE_RETURN;
8479 else if (position != OVER_NOTHING)
8482 *modeline_closest = -1;
8484 if (high_y_coord <= frm_top || high_y_coord >= frm_bottom)
8487 UPDATE_CACHE_RETURN;
8491 /* Check if the window is a minibuffer but isn't active. */
8492 if (MINI_WINDOW_P (*w) && !minibuf_level)
8494 /* Must reset the window value since some callers will ignore
8495 the return value if it is set. */
8497 UPDATE_CACHE_RETURN;
8500 /* See if the point is over window vertical divider */
8501 if (window_needs_vertical_divider (*w))
8503 int div_x_high = WINDOW_RIGHT (*w);
8504 int div_x_low = div_x_high - window_divider_width (*w);
8505 int div_y_high = WINDOW_BOTTOM (*w);
8506 int div_y_low = WINDOW_TOP (*w);
8508 if (div_x_low < x_coord && x_coord <= div_x_high &&
8509 div_y_low < y_coord && y_coord <= div_y_high)
8511 low_x_coord = div_x_low;
8512 high_x_coord = div_x_high;
8513 low_y_coord = div_y_low;
8514 high_y_coord = div_y_high;
8515 position = OVER_V_DIVIDER;
8516 UPDATE_CACHE_RETURN;
8520 dla = window_display_lines (*w, CURRENT_DISP);
8522 for (*row = 0; *row < Dynarr_length (dla); (*row)++)
8524 int really_over_nothing = 0;
8525 struct display_line *dl = Dynarr_atp (dla, *row);
8527 if ((int) (dl->ypos - dl->ascent) <= y_coord
8528 && y_coord <= (int) (dl->ypos + dl->descent))
8530 int check_margin_glyphs = 0;
8531 struct display_block *db = get_display_block_from_line (dl, TEXT);
8532 struct rune *rb = 0;
8534 if (x_coord < dl->bounds.left_white
8535 || x_coord >= dl->bounds.right_white)
8536 check_margin_glyphs = 1;
8538 low_y_coord = dl->ypos - dl->ascent;
8539 high_y_coord = dl->ypos + dl->descent + 1;
8541 if (position == OVER_BORDER
8542 || position == OVER_OUTSIDE
8543 || check_margin_glyphs)
8545 int x_check, left_bound;
8547 if (check_margin_glyphs)
8550 left_bound = dl->bounds.left_white;
8554 x_check = high_x_coord;
8555 left_bound = frm_left;
8558 if (Dynarr_length (db->runes))
8560 if (x_check <= left_bound)
8563 *modeline_closest = Dynarr_atp (db->runes, 0)->bufpos;
8565 *closest = Dynarr_atp (db->runes, 0)->bufpos;
8571 Dynarr_atp (db->runes,
8572 Dynarr_length (db->runes) - 1)->bufpos;
8575 Dynarr_atp (db->runes,
8576 Dynarr_length (db->runes) - 1)->bufpos;
8580 *modeline_closest += dl->offset;
8582 *closest += dl->offset;
8586 /* #### What should be here. */
8588 *modeline_closest = 0;
8593 if (check_margin_glyphs)
8595 if (x_coord < dl->bounds.left_in
8596 || x_coord >= dl->bounds.right_in)
8598 /* If we are over the outside margins then we
8599 know the loop over the text block isn't going
8600 to accomplish anything. So we go ahead and
8601 set what information we can right here and
8604 *obj_y = y_coord - (dl->ypos - dl->ascent);
8605 get_position_object (dl, obj1, obj2, x_coord,
8606 &low_x_coord, &high_x_coord);
8608 UPDATE_CACHE_RETURN;
8612 UPDATE_CACHE_RETURN;
8615 for (*col = 0; *col <= Dynarr_length (db->runes); (*col)++)
8617 int past_end = (*col == Dynarr_length (db->runes));
8620 rb = Dynarr_atp (db->runes, *col);
8623 (rb->xpos <= x_coord && x_coord < rb->xpos + rb->width))
8628 rb = Dynarr_atp (db->runes, *col);
8631 *bufpos = rb->bufpos + dl->offset;
8632 low_x_coord = rb->xpos;
8633 high_x_coord = rb->xpos + rb->width;
8635 if (rb->type == RUNE_DGLYPH)
8639 /* Find the first character after the glyph. */
8640 while (elt < Dynarr_length (db->runes))
8642 if (Dynarr_atp (db->runes, elt)->type != RUNE_DGLYPH)
8646 (Dynarr_atp (db->runes, elt)->bufpos +
8650 (Dynarr_atp (db->runes, elt)->bufpos +
8658 /* In this case we failed to find a non-glyph
8659 character so we return the last position
8660 displayed on the line. */
8661 if (elt == Dynarr_length (db->runes))
8664 *modeline_closest = dl->end_bufpos + dl->offset;
8666 *closest = dl->end_bufpos + dl->offset;
8667 really_over_nothing = 1;
8673 *modeline_closest = rb->bufpos + dl->offset;
8675 *closest = rb->bufpos + dl->offset;
8680 *row = window_displayed_height (*w);
8682 if (position == OVER_NOTHING)
8683 position = OVER_MODELINE;
8685 if (rb->type == RUNE_DGLYPH)
8687 *obj1 = rb->object.dglyph.glyph;
8688 *obj2 = rb->object.dglyph.extent;
8690 else if (rb->type == RUNE_CHAR)
8701 UPDATE_CACHE_RETURN;
8704 || (rb->type == RUNE_CHAR
8705 && rb->object.chr.ch == '\n'))
8708 /* At this point we may have glyphs in the right
8710 if (check_margin_glyphs)
8711 get_position_object (dl, obj1, obj2, x_coord,
8712 &low_x_coord, &high_x_coord);
8713 UPDATE_CACHE_RETURN;
8718 if (rb->type == RUNE_DGLYPH)
8720 *obj1 = rb->object.dglyph.glyph;
8721 *obj2 = rb->object.dglyph.extent;
8723 else if (rb->type == RUNE_CHAR)
8734 *obj_x = x_coord - rb->xpos;
8735 *obj_y = y_coord - (dl->ypos - dl->ascent);
8737 /* At this point we may have glyphs in the left
8739 if (check_margin_glyphs)
8740 get_position_object (dl, obj1, obj2, x_coord, 0, 0);
8742 if (position == OVER_NOTHING && !really_over_nothing)
8743 position = OVER_TEXT;
8745 UPDATE_CACHE_RETURN;
8752 *row = Dynarr_length (dla) - 1;
8753 if (FRAME_WIN_P (f))
8755 int bot_elt = Dynarr_length (dla) - 1;
8759 struct display_line *dl = Dynarr_atp (dla, bot_elt);
8760 int adj_area = y_coord - (dl->ypos + dl->descent);
8764 XSETWINDOW (lwin, *w);
8765 default_face_height_and_width (lwin, 0, &defheight);
8767 *row += (adj_area / defheight);
8771 /* #### This should be checked out some more to determine what
8772 should really be going on. */
8773 if (!MARKERP ((*w)->start[CURRENT_DISP]))
8776 *closest = end_of_last_line_may_error (*w,
8777 marker_position ((*w)->start[CURRENT_DISP]));
8779 UPDATE_CACHE_RETURN;
8781 #undef UPDATE_CACHE_RETURN
8784 /***************************************************************************/
8786 /* Lisp functions */
8788 /***************************************************************************/
8790 DEFUN ("redisplay-echo-area", Fredisplay_echo_area, 0, 0, 0, /*
8791 Ensure that all minibuffers are correctly showing the echo area.
8795 Lisp_Object devcons, concons;
8797 DEVICE_LOOP_NO_BREAK (devcons, concons)
8799 struct device *d = XDEVICE (XCAR (devcons));
8800 Lisp_Object frmcons;
8802 DEVICE_FRAME_LOOP (frmcons, d)
8804 struct frame *f = XFRAME (XCAR (frmcons));
8806 if (FRAME_REPAINT_P (f) && FRAME_HAS_MINIBUF_P (f))
8808 Lisp_Object window = FRAME_MINIBUF_WINDOW (f);
8810 MAYBE_DEVMETH (d, frame_output_begin, (f));
8813 * If the frame size has changed, there may be random
8814 * chud on the screen left from previous messages
8815 * because redisplay_frame hasn't been called yet.
8816 * Clear the screen to get rid of the potential mess.
8818 if (f->echo_area_garbaged)
8820 MAYBE_DEVMETH (d, clear_frame, (f));
8821 f->echo_area_garbaged = 0;
8823 redisplay_window (window, 0);
8824 MAYBE_DEVMETH (d, frame_output_end, (f));
8826 call_redisplay_end_triggers (XWINDOW (window), 0);
8835 restore_disable_preemption_value (Lisp_Object value)
8837 disable_preemption = XINT (value);
8841 DEFUN ("redraw-frame", Fredraw_frame, 0, 2, 0, /*
8842 Clear frame FRAME and output again what is supposed to appear on it.
8843 FRAME defaults to the selected frame if omitted.
8844 Normally, redisplay is preempted as normal if input arrives. However,
8845 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8846 input and is guaranteed to proceed to completion.
8848 (frame, no_preempt))
8850 struct frame *f = decode_frame (frame);
8851 int count = specpdl_depth ();
8853 if (!NILP (no_preempt))
8855 record_unwind_protect (restore_disable_preemption_value,
8856 make_int (disable_preemption));
8857 disable_preemption++;
8861 redisplay_frame (f, 1);
8863 /* See the comment in Fredisplay_frame. */
8864 RESET_CHANGED_SET_FLAGS;
8866 return unbind_to (count, Qnil);
8869 DEFUN ("redisplay-frame", Fredisplay_frame, 0, 2, 0, /*
8870 Ensure that FRAME's contents are correctly displayed.
8871 This differs from `redraw-frame' in that it only redraws what needs to
8872 be updated, as opposed to unconditionally clearing and redrawing
8874 FRAME defaults to the selected frame if omitted.
8875 Normally, redisplay is preempted as normal if input arrives. However,
8876 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8877 input and is guaranteed to proceed to completion.
8879 (frame, no_preempt))
8881 struct frame *f = decode_frame (frame);
8882 int count = specpdl_depth ();
8884 if (!NILP (no_preempt))
8886 record_unwind_protect (restore_disable_preemption_value,
8887 make_int (disable_preemption));
8888 disable_preemption++;
8891 redisplay_frame (f, 1);
8893 /* If we don't reset the global redisplay flafs here, subsequent
8894 changes to the display will not get registered by redisplay
8895 because it thinks it already has registered changes. If you
8896 really knew what you were doing you could confuse redisplay by
8897 calling Fredisplay_frame while updating another frame. We assume
8898 that if you know what you are doing you will not be that
8900 RESET_CHANGED_SET_FLAGS;
8902 return unbind_to (count, Qnil);
8905 DEFUN ("redraw-device", Fredraw_device, 0, 2, 0, /*
8906 Clear device DEVICE and output again what is supposed to appear on it.
8907 DEVICE defaults to the selected device if omitted.
8908 Normally, redisplay is preempted as normal if input arrives. However,
8909 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8910 input and is guaranteed to proceed to completion.
8912 (device, no_preempt))
8914 struct device *d = decode_device (device);
8915 Lisp_Object frmcons;
8916 int count = specpdl_depth ();
8918 if (!NILP (no_preempt))
8920 record_unwind_protect (restore_disable_preemption_value,
8921 make_int (disable_preemption));
8922 disable_preemption++;
8925 DEVICE_FRAME_LOOP (frmcons, d)
8927 XFRAME (XCAR (frmcons))->clear = 1;
8929 redisplay_device (d, 0);
8931 /* See the comment in Fredisplay_frame. */
8932 RESET_CHANGED_SET_FLAGS;
8934 return unbind_to (count, Qnil);
8937 DEFUN ("redisplay-device", Fredisplay_device, 0, 2, 0, /*
8938 Ensure that DEVICE's contents are correctly displayed.
8939 This differs from `redraw-device' in that it only redraws what needs to
8940 be updated, as opposed to unconditionally clearing and redrawing
8942 DEVICE defaults to the selected device if omitted.
8943 Normally, redisplay is preempted as normal if input arrives. However,
8944 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8945 input and is guaranteed to proceed to completion.
8947 (device, no_preempt))
8949 struct device *d = decode_device (device);
8950 int count = specpdl_depth ();
8952 if (!NILP (no_preempt))
8954 record_unwind_protect (restore_disable_preemption_value,
8955 make_int (disable_preemption));
8956 disable_preemption++;
8959 redisplay_device (d, 0);
8961 /* See the comment in Fredisplay_frame. */
8962 RESET_CHANGED_SET_FLAGS;
8964 return unbind_to (count, Qnil);
8967 /* Big lie. Big lie. This will force all modelines to be updated
8968 regardless if the all flag is set or not. It remains in existence
8969 solely for backwards compatibility. */
8970 DEFUN ("redraw-modeline", Fredraw_modeline, 0, 1, 0, /*
8971 Force the modeline of the current buffer to be redisplayed.
8972 With optional non-nil ALL, force redisplay of all modelines.
8976 MARK_MODELINE_CHANGED;
8980 DEFUN ("force-cursor-redisplay", Fforce_cursor_redisplay, 0, 1, 0, /*
8981 Force an immediate update of the cursor on FRAME.
8982 FRAME defaults to the selected frame if omitted.
8986 redisplay_redraw_cursor (decode_frame (frame), 1);
8991 /***************************************************************************/
8993 /* Lisp-variable change triggers */
8995 /***************************************************************************/
8998 margin_width_changed_in_frame (Lisp_Object specifier, struct frame *f,
9001 /* Nothing to be done? */
9005 redisplay_variable_changed (Lisp_Object sym, Lisp_Object *val,
9006 Lisp_Object in_object, int flags)
9008 /* #### clip_changed should really be renamed something like
9009 global_redisplay_change. */
9014 /* This is called if the built-in glyphs have their properties
9017 redisplay_glyph_changed (Lisp_Object glyph, Lisp_Object property,
9020 if (WINDOWP (locale))
9022 MARK_FRAME_GLYPHS_CHANGED (XFRAME (WINDOW_FRAME (XWINDOW (locale))));
9024 else if (FRAMEP (locale))
9026 MARK_FRAME_GLYPHS_CHANGED (XFRAME (locale));
9028 else if (DEVICEP (locale))
9030 Lisp_Object frmcons;
9031 DEVICE_FRAME_LOOP (frmcons, XDEVICE (locale))
9032 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9034 else if (CONSOLEP (locale))
9036 Lisp_Object frmcons, devcons;
9037 CONSOLE_FRAME_LOOP_NO_BREAK (frmcons, devcons, XCONSOLE (locale))
9038 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9040 else /* global or buffer */
9042 Lisp_Object frmcons, devcons, concons;
9043 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
9044 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9049 text_cursor_visible_p_changed (Lisp_Object specifier, struct window *w,
9052 if (XFRAME (w->frame)->init_finished)
9053 Fforce_cursor_redisplay (w->frame);
9056 #ifdef MEMORY_USAGE_STATS
9059 /***************************************************************************/
9061 /* memory usage computation */
9063 /***************************************************************************/
9066 compute_rune_dynarr_usage (rune_dynarr *dyn, struct overhead_stats *ovstats)
9068 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9072 compute_display_block_dynarr_usage (display_block_dynarr *dyn,
9073 struct overhead_stats *ovstats)
9080 total = Dynarr_memory_usage (dyn, ovstats);
9081 for (i = 0; i < Dynarr_largest (dyn); i++)
9082 total += compute_rune_dynarr_usage (Dynarr_at (dyn, i).runes, ovstats);
9088 compute_glyph_block_dynarr_usage (glyph_block_dynarr *dyn,
9089 struct overhead_stats *ovstats)
9091 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9095 compute_display_line_dynarr_usage (display_line_dynarr *dyn,
9096 struct overhead_stats *ovstats)
9103 total = Dynarr_memory_usage (dyn, ovstats);
9104 for (i = 0; i < Dynarr_largest (dyn); i++)
9106 struct display_line *dl = &Dynarr_at (dyn, i);
9107 total += compute_display_block_dynarr_usage(dl->display_blocks, ovstats);
9108 total += compute_glyph_block_dynarr_usage (dl->left_glyphs, ovstats);
9109 total += compute_glyph_block_dynarr_usage (dl->right_glyphs, ovstats);
9116 compute_line_start_cache_dynarr_usage (line_start_cache_dynarr *dyn,
9117 struct overhead_stats *ovstats)
9119 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9122 #endif /* MEMORY_USAGE_STATS */
9125 /***************************************************************************/
9127 /* initialization */
9129 /***************************************************************************/
9132 init_redisplay (void)
9134 disable_preemption = 0;
9135 preemption_count = 0;
9136 max_preempts = INIT_MAX_PREEMPTS;
9142 if (!cmotion_display_lines)
9143 cmotion_display_lines = Dynarr_new (display_line);
9144 if (!mode_spec_bufbyte_string)
9145 mode_spec_bufbyte_string = Dynarr_new (Bufbyte);
9146 if (!formatted_string_extent_dynarr)
9147 formatted_string_extent_dynarr = Dynarr_new (EXTENT);
9148 if (!formatted_string_extent_start_dynarr)
9149 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount);
9150 if (!formatted_string_extent_end_dynarr)
9151 formatted_string_extent_end_dynarr = Dynarr_new (Bytecount);
9152 if (!internal_cache)
9153 internal_cache = Dynarr_new (line_start_cache);
9156 /* window system is nil when in -batch mode */
9157 if (!initialized || noninteractive)
9160 /* If the user wants to use a window system, we shouldn't bother
9161 initializing the terminal. This is especially important when the
9162 terminal is so dumb that emacs gives up before and doesn't bother
9163 using the window system.
9165 If the DISPLAY environment variable is set, try to use X, and die
9166 with an error message if that doesn't work. */
9168 #ifdef HAVE_X_WINDOWS
9169 if (!strcmp (display_use, "x"))
9171 /* Some stuff checks this way early. */
9172 Vwindow_system = Qx;
9173 Vinitial_window_system = Qx;
9176 #endif /* HAVE_X_WINDOWS */
9178 #ifdef HAVE_MS_WINDOWS
9179 if (!strcmp (display_use, "mswindows"))
9181 /* Some stuff checks this way early. */
9182 Vwindow_system = Qmswindows;
9183 Vinitial_window_system = Qmswindows;
9186 #endif /* HAVE_MS_WINDOWS */
9189 /* If no window system has been specified, try to use the terminal. */
9192 stderr_out ("XEmacs: standard input is not a tty\n");
9196 /* Look at the TERM variable */
9197 if (!getenv ("TERM"))
9199 stderr_out ("Please set the environment variable TERM; see tset(1).\n");
9203 Vinitial_window_system = Qtty;
9205 #else /* not HAVE_TTY */
9206 /* No DISPLAY specified, and no TTY support. */
9207 stderr_out ("XEmacs: Cannot open display.\n\
9208 Please set the environmental variable DISPLAY to an appropriate value.\n");
9215 syms_of_redisplay (void)
9217 defsymbol (&Qcursor_in_echo_area, "cursor-in-echo-area");
9218 #ifndef INHIBIT_REDISPLAY_HOOKS
9219 defsymbol (&Qpre_redisplay_hook, "pre-redisplay-hook");
9220 defsymbol (&Qpost_redisplay_hook, "post-redisplay-hook");
9221 #endif /* INHIBIT_REDISPLAY_HOOKS */
9222 defsymbol (&Qdisplay_warning_buffer, "display-warning-buffer");
9223 defsymbol (&Qbar_cursor, "bar-cursor");
9224 defsymbol (&Qredisplay_end_trigger_functions,
9225 "redisplay-end-trigger-functions");
9226 defsymbol (&Qtop_bottom, "top-bottom");
9227 defsymbol (&Qbuffer_list_changed_hook, "buffer-list-changed-hook");
9229 DEFSUBR (Fredisplay_echo_area);
9230 DEFSUBR (Fredraw_frame);
9231 DEFSUBR (Fredisplay_frame);
9232 DEFSUBR (Fredraw_device);
9233 DEFSUBR (Fredisplay_device);
9234 DEFSUBR (Fredraw_modeline);
9235 DEFSUBR (Fforce_cursor_redisplay);
9239 vars_of_redisplay (void)
9243 staticpro (&last_arrow_position);
9244 staticpro (&last_arrow_string);
9245 last_arrow_position = Qnil;
9246 last_arrow_string = Qnil;
9249 /* #### Probably temporary */
9250 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /*
9251 \(Temporary) Setting this will impact the performance of the internal
9254 cache_adjustment = 2;
9256 DEFVAR_INT_MAGIC ("pixel-vertical-clip-threshold", &vertical_clip /*
9257 Minimum pixel height for clipped bottom display line.
9258 A clipped line shorter than this won't be displayed.
9260 redisplay_variable_changed);
9263 DEFVAR_INT_MAGIC ("pixel-horizontal-clip-threshold", &horizontal_clip /*
9264 Minimum visible area for clipped glyphs at right boundary.
9265 Clipped glyphs shorter than this won't be displayed.
9266 Only pixmap glyph instances are currently allowed to be clipped.
9268 redisplay_variable_changed);
9269 horizontal_clip = 5;
9271 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string /*
9272 String displayed by modeline-format's "%m" specification.
9274 Vglobal_mode_string = Qnil;
9276 DEFVAR_LISP_MAGIC ("overlay-arrow-position", &Voverlay_arrow_position /*
9277 Marker for where to display an arrow on top of the buffer text.
9278 This must be the beginning of a line in order to work.
9279 See also `overlay-arrow-string'.
9281 redisplay_variable_changed);
9282 Voverlay_arrow_position = Qnil;
9284 DEFVAR_LISP_MAGIC ("overlay-arrow-string", &Voverlay_arrow_string /*
9285 String or glyph to display as an arrow. See also `overlay-arrow-position'.
9286 (Note that despite the name of this variable, it can be set to a glyph as
9289 redisplay_variable_changed);
9290 Voverlay_arrow_string = Qnil;
9292 DEFVAR_INT ("scroll-step", &scroll_step /*
9293 *The number of lines to try scrolling a window by when point moves out.
9294 If that fails to bring point back on frame, point is centered instead.
9295 If this is zero, point is always centered after it moves off screen.
9299 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively /*
9300 *Scroll up to this many lines, to bring point back on screen.
9302 scroll_conservatively = 0;
9304 DEFVAR_BOOL_MAGIC ("truncate-partial-width-windows",
9305 &truncate_partial_width_windows /*
9306 *Non-nil means truncate lines in all windows less than full frame wide.
9308 redisplay_variable_changed);
9309 truncate_partial_width_windows = 1;
9311 DEFVAR_LISP ("visible-bell", &Vvisible_bell /*
9312 *Non-nil substitutes a visual signal for the audible bell.
9314 Default behavior is to flash the whole screen. On some platforms,
9315 special effects are available using the following values:
9317 'display Flash the whole screen (ie, the default behavior).
9318 'top-bottom Flash only the top and bottom lines of the selected frame.
9320 When effects are unavailable on a platform, the visual bell is the
9321 default, whole screen. (Currently only X supports any special effects.)
9323 Vvisible_bell = Qnil;
9325 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter /*
9326 *Non-nil means no need to redraw entire frame after suspending.
9327 A non-nil value is useful if the terminal can automatically preserve
9328 Emacs's frame display when you reenter Emacs.
9329 It is up to you to set this variable if your terminal can do that.
9331 no_redraw_on_reenter = 0;
9333 DEFVAR_LISP ("window-system", &Vwindow_system /*
9334 A symbol naming the window-system under which Emacs is running,
9335 such as `x', or nil if emacs is running on an ordinary terminal.
9337 Do not use this variable, except for GNU Emacs compatibility, as it
9338 gives wrong values in a multi-device environment. Use `console-type'
9341 Vwindow_system = Qnil;
9343 /* #### Temporary shit until window-system is eliminated. */
9344 DEFVAR_CONST_LISP ("initial-window-system", &Vinitial_window_system /*
9347 Vinitial_window_system = Qnil;
9349 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area /*
9350 Non-nil means put cursor in minibuffer, at end of any message there.
9352 cursor_in_echo_area = 0;
9354 /* #### Shouldn't this be generalized as follows:
9356 if nil, use block cursor.
9357 if a number, use a bar cursor of that width.
9358 Otherwise, use a 1-pixel bar cursor.
9360 #### Or better yet, this variable should be trashed entirely
9361 (use a Lisp-magic variable to maintain compatibility)
9362 and a specifier `cursor-shape' added, which allows a block
9363 cursor, a bar cursor, a flashing block or bar cursor,
9364 maybe a caret cursor, etc. */
9366 DEFVAR_LISP ("bar-cursor", &Vbar_cursor /*
9367 Use vertical bar cursor if non-nil. If t width is 1 pixel, otherwise 2.
9371 #ifndef INHIBIT_REDISPLAY_HOOKS
9372 xxDEFVAR_LISP ("pre-redisplay-hook", &Vpre_redisplay_hook /*
9373 Function or functions to run before every redisplay.
9375 Vpre_redisplay_hook = Qnil;
9377 xxDEFVAR_LISP ("post-redisplay-hook", &Vpost_redisplay_hook /*
9378 Function or functions to run after every redisplay.
9380 Vpost_redisplay_hook = Qnil;
9381 #endif /* INHIBIT_REDISPLAY_HOOKS */
9383 DEFVAR_LISP ("buffer-list-changed-hook", &Vbuffer_list_changed_hook /*
9384 Function or functions to call when a frame's buffer list has changed.
9385 This is called during redisplay, before redisplaying each frame.
9386 Functions on this hook are called with one argument, the frame.
9388 Vbuffer_list_changed_hook = Qnil;
9390 DEFVAR_INT ("display-warning-tick", &display_warning_tick /*
9391 Bump this to tell the C code to call `display-warning-buffer'
9392 at next redisplay. You should not normally change this; the function
9393 `display-warning' automatically does this at appropriate times.
9395 display_warning_tick = 0;
9397 DEFVAR_BOOL ("inhibit-warning-display", &inhibit_warning_display /*
9398 Non-nil means inhibit display of warning messages.
9399 You should *bind* this, not set it. Any pending warning messages
9400 will be displayed when the binding no longer applies.
9402 /* reset to 0 by startup.el after the splash screen has displayed.
9403 This way, the warnings don't obliterate the splash screen. */
9404 inhibit_warning_display = 1;
9406 DEFVAR_LISP ("window-size-change-functions",
9407 &Vwindow_size_change_functions /*
9408 Not currently implemented.
9409 Functions called before redisplay, if window sizes have changed.
9410 The value should be a list of functions that take one argument.
9411 Just before redisplay, for each frame, if any of its windows have changed
9412 size since the last redisplay, or have been split or deleted,
9413 all the functions in the list are called, with the frame as argument.
9415 Vwindow_size_change_functions = Qnil;
9417 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions /*
9418 Not currently implemented.
9419 Functions to call before redisplaying a window with scrolling.
9420 Each function is called with two arguments, the window
9421 and its new display-start position. Note that the value of `window-end'
9422 is not valid when these functions are called.
9424 Vwindow_scroll_functions = Qnil;
9426 DEFVAR_LISP ("redisplay-end-trigger-functions",
9427 &Vredisplay_end_trigger_functions /*
9428 See `set-window-redisplay-end-trigger'.
9430 Vredisplay_end_trigger_functions = Qnil;
9432 DEFVAR_BOOL ("column-number-start-at-one", &column_number_start_at_one /*
9433 *Non-nil means column display number starts at 1.
9435 column_number_start_at_one = 0;
9439 specifier_vars_of_redisplay (void)
9441 DEFVAR_SPECIFIER ("left-margin-width", &Vleft_margin_width /*
9442 *Width of left margin.
9443 This is a specifier; use `set-specifier' to change it.
9445 Vleft_margin_width = Fmake_specifier (Qnatnum);
9446 set_specifier_fallback (Vleft_margin_width, list1 (Fcons (Qnil, Qzero)));
9447 set_specifier_caching (Vleft_margin_width,
9448 offsetof (struct window, left_margin_width),
9449 some_window_value_changed,
9450 offsetof (struct frame, left_margin_width),
9451 margin_width_changed_in_frame);
9453 DEFVAR_SPECIFIER ("right-margin-width", &Vright_margin_width /*
9454 *Width of right margin.
9455 This is a specifier; use `set-specifier' to change it.
9457 Vright_margin_width = Fmake_specifier (Qnatnum);
9458 set_specifier_fallback (Vright_margin_width, list1 (Fcons (Qnil, Qzero)));
9459 set_specifier_caching (Vright_margin_width,
9460 offsetof (struct window, right_margin_width),
9461 some_window_value_changed,
9462 offsetof (struct frame, right_margin_width),
9463 margin_width_changed_in_frame);
9465 DEFVAR_SPECIFIER ("minimum-line-ascent", &Vminimum_line_ascent /*
9466 *Minimum ascent height of lines.
9467 This is a specifier; use `set-specifier' to change it.
9469 Vminimum_line_ascent = Fmake_specifier (Qnatnum);
9470 set_specifier_fallback (Vminimum_line_ascent, list1 (Fcons (Qnil, Qzero)));
9471 set_specifier_caching (Vminimum_line_ascent,
9472 offsetof (struct window, minimum_line_ascent),
9473 some_window_value_changed,
9476 DEFVAR_SPECIFIER ("minimum-line-descent", &Vminimum_line_descent /*
9477 *Minimum descent height of lines.
9478 This is a specifier; use `set-specifier' to change it.
9480 Vminimum_line_descent = Fmake_specifier (Qnatnum);
9481 set_specifier_fallback (Vminimum_line_descent, list1 (Fcons (Qnil, Qzero)));
9482 set_specifier_caching (Vminimum_line_descent,
9483 offsetof (struct window, minimum_line_descent),
9484 some_window_value_changed,
9487 DEFVAR_SPECIFIER ("use-left-overflow", &Vuse_left_overflow /*
9488 *Non-nil means use the left outside margin as extra whitespace when
9489 displaying 'whitespace or 'inside-margin glyphs.
9490 This is a specifier; use `set-specifier' to change it.
9492 Vuse_left_overflow = Fmake_specifier (Qboolean);
9493 set_specifier_fallback (Vuse_left_overflow, list1 (Fcons (Qnil, Qnil)));
9494 set_specifier_caching (Vuse_left_overflow,
9495 offsetof (struct window, use_left_overflow),
9496 some_window_value_changed,
9499 DEFVAR_SPECIFIER ("use-right-overflow", &Vuse_right_overflow /*
9500 *Non-nil means use the right outside margin as extra whitespace when
9501 displaying 'whitespace or 'inside-margin glyphs.
9502 This is a specifier; use `set-specifier' to change it.
9504 Vuse_right_overflow = Fmake_specifier (Qboolean);
9505 set_specifier_fallback (Vuse_right_overflow, list1 (Fcons (Qnil, Qnil)));
9506 set_specifier_caching (Vuse_right_overflow,
9507 offsetof (struct window, use_right_overflow),
9508 some_window_value_changed,
9511 DEFVAR_SPECIFIER ("text-cursor-visible-p", &Vtext_cursor_visible_p /*
9512 *Non-nil means the text cursor is visible (this is usually the case).
9513 This is a specifier; use `set-specifier' to change it.
9515 Vtext_cursor_visible_p = Fmake_specifier (Qboolean);
9516 set_specifier_fallback (Vtext_cursor_visible_p, list1 (Fcons (Qnil, Qt)));
9517 set_specifier_caching (Vtext_cursor_visible_p,
9518 offsetof (struct window, text_cursor_visible_p),
9519 text_cursor_visible_p_changed,