1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1994, 1995, 1996 Board of Trustees, University of Illinois.
3 Copyright (C) 1995 Free Software Foundation, Inc.
4 Copyright (C) 1995, 1996 Ben Wing.
5 Copyright (C) 1995 Sun Microsystems, Inc.
6 Copyright (C) 1996 Chuck Thompson.
8 This file is part of XEmacs.
10 XEmacs is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
15 XEmacs is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with XEmacs; see the file COPYING. If not, write to
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
25 /* Synched up with: Not in FSF. */
27 /* Author: Chuck Thompson */
29 /* Fixed up by Ben Wing for Mule */
31 /* This file has been Mule-ized. */
33 /*****************************************************************************
34 The Golden Rules of Redisplay
36 First: It Is Better To Be Correct Than Fast
37 Second: Thou Shalt Not Run Elisp From Within Redisplay
38 Third: It Is Better To Be Fast Than Not To Be
39 ****************************************************************************/
59 #include "redisplay.h"
62 #include "line-number.h"
64 #include "file-coding.h"
68 #include "console-tty.h"
70 #include <unistd.h> /* for isatty() */
74 /* Note: We have to be careful throughout this code to properly handle
75 and differentiate between Bufbytes and Emchars.
77 Since strings are generally composed of Bufbytes, I've taken the tack
78 that any contiguous set of Bufbytes is called a "string", while
79 any contiguous set of Emchars is called an "array". */
81 /* Return value to indicate a failure by an add_*_rune routine to add
82 a rune, but no propagation information needs to be returned. */
83 #define ADD_FAILED (prop_block_dynarr *) 1
85 #define BEGIN_GLYPHS 0
88 #define RIGHT_GLYPHS 3
90 #define VERTICAL_CLIP(w, display) \
91 ((WINDOW_TTY_P (w) | (!display && scroll_on_clipped_lines)) \
95 /* The following structures are completely private to redisplay.c so
96 we put them here instead of in a header file, for modularity. */
98 /* NOTE: Bytinds not Bufpos's in this structure. */
100 typedef struct position_redisplay_data_type
102 /* This information is normally filled in by the create_*_block
103 routines and is used by the add_*_rune routines. */
105 /* if we are working with strings rather than buffers we need a
106 handle to the string */
109 struct display_block *db;
110 struct display_line *dl;
111 Emchar ch; /* Character that is to be added. This is
112 used to communicate this information to
113 add_emchar_rune(). */
114 Lisp_Object last_charset; /* The charset of the previous character.
115 Used to optimize some lookups -- we
116 only have to do some things when
117 the charset changes. */
118 face_index last_findex; /* The face index of the previous character.
119 Needed to ensure the validity of the
120 last_charset optimization. */
122 int last_char_width; /* The width of the previous character. */
123 int font_is_bogus; /* If true, it means we couldn't instantiate
124 the font for this charset, so we substitute
125 ~'s from the ASCII charset. */
130 int blank_width; /* Width of the blank that is to be added.
131 This is used to communicate this information
134 This is also used rather cheesily to
135 communicate the width of the eol-cursor-size
136 blank that exists at the end of the line.
137 add_emchar_rune() is called cheesily with
138 the non-printing char '\n', which is stuck
139 in the output routines with its width being
141 Bytind bi_cursor_bufpos;/* This stores the buffer position of the cursor. */
142 unsigned int cursor_type :3;
143 int cursor_x; /* rune block cursor is at */
144 int start_col; /* Number of character columns (each column has
145 a width of the default char width) that still
146 need to be skipped. This is used for horizontal
147 scrolling, where a certain number of columns
148 (those off the left side of the screen) need
149 to be skipped before anything is displayed. */
150 Bytind bi_start_col_enabled;
151 int start_col_xoffset; /* Number of pixels that still need to
152 be skipped. This is used for
153 horizontal scrolling of glyphs, where we want
154 to be able to scroll over part of the glyph. */
156 int hscroll_glyph_width_adjust; /* how much the width of the hscroll
157 glyph differs from space_width (w).
158 0 if no hscroll glyph was used,
159 i.e. the window is not scrolled
160 horizontally. Used in tab
163 /* Information about the face the text should be displayed in and
164 any begin-glyphs and end-glyphs. */
165 struct extent_fragment *ef;
168 /* The height of a pixmap may either be predetermined if the user
169 has set a baseline value, or it may be dependent on whatever the
170 line ascent and descent values end up being, based just on font
171 information. In the first case we can immediately update the
172 values, thus their inclusion here. In the last case we cannot
173 determine the actual contribution to the line height until we
174 have finished laying out all text on the line. Thus we propagate
175 the max height of such pixmaps and do a final calculation after
176 all text has been added to the line. */
179 int max_pixmap_height;
181 Lisp_Object result_str; /* String where we put the result of
182 generating a formatted string in the modeline. */
183 int is_modeline; /* Non-zero if we're generating the modeline. */
184 Charcount modeline_charpos; /* Number of chars used in result_str so far;
185 corresponds to bytepos. */
186 Bytecount bytepos; /* Number of bytes used in result_str so far.
187 We don't actually copy the bytes into result_str
188 until the end because we don't know how big the
189 string is going to be until then. */
200 /* Data that should be propagated to the next line. Either a single
201 Emchar or a string of Bufbyte's.
203 The actual data that is propagated ends up as a Dynarr of these
206 #### It's unclean that both Emchars and Bufbytes are here.
209 typedef struct prop_block prop_block;
219 Bytecount len; /* length of the string. */
225 Bytind bi_cursor_bufpos; /* NOTE: is in Bytinds */
226 unsigned int cursor_type :3;
239 Dynarr_declare (prop_block);
243 static Charcount generate_fstring_runes (struct window *w, pos_data *data,
244 Charcount pos, Charcount min_pos,
245 Charcount max_pos, Lisp_Object elt,
246 int depth, int max_pixsize,
247 face_index findex, int type,
249 Lisp_Object cur_ext);
250 static prop_block_dynarr *add_glyph_rune (pos_data *data,
251 struct glyph_block *gb,
252 int pos_type, int allow_cursor,
253 struct glyph_cachel *cachel);
254 static Bytind create_text_block (struct window *w, struct display_line *dl,
255 Bytind bi_start_pos, prop_block_dynarr **prop,
257 static int create_overlay_glyph_block (struct window *w,
258 struct display_line *dl);
259 static void create_left_glyph_block (struct window *w,
260 struct display_line *dl,
262 static void create_right_glyph_block (struct window *w,
263 struct display_line *dl);
264 static void redisplay_windows (Lisp_Object window, int skip_selected);
265 static void decode_mode_spec (struct window *w, Emchar spec, int type);
266 static void free_display_line (struct display_line *dl);
267 static void update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
268 Bufpos point, int no_regen);
269 static int point_visible (struct window *w, Bufpos point, int type);
271 /* This used to be 10 but 30 seems to give much better performance. */
272 #define INIT_MAX_PREEMPTS 30
273 static int max_preempts;
275 #define REDISPLAY_PREEMPTION_CHECK \
278 (!disable_preemption && \
279 ((preemption_count < max_preempts) || !NILP (Vexecuting_macro)) && \
280 (!INTERACTIVE || detect_input_pending ()))))
283 * Redisplay global variables.
286 /* We need a third set of display structures for the cursor motion
287 routines. We used to just give each window a third set. However,
288 we always fully regenerate the structures when needed so there
289 isn't any reason we need more than a single set. */
290 display_line_dynarr *cmotion_display_lines;
292 /* We store the extents that we need to generate in a Dynarr and then
293 frob them all on at the end of generating the string. We do it
294 this way rather than adding them as we generate the string because
295 we don't store the text into the resulting string until we're done
296 (to avoid having to resize the string multiple times), and we don't
297 want to go around adding extents to a string when the extents might
298 stretch off the end of the string. */
299 static EXTENT_dynarr *formatted_string_extent_dynarr;
300 static Bytecount_dynarr *formatted_string_extent_start_dynarr;
301 static Bytecount_dynarr *formatted_string_extent_end_dynarr;
304 /* #### probably temporary */
305 int cache_adjustment;
307 /* This holds a string representing the text corresponding to a single
309 static Bufbyte_dynarr *mode_spec_bufbyte_string;
311 int in_display; /* 1 if in redisplay. */
313 int disable_preemption; /* Used for debugging redisplay and for
316 /* We only allow max_preempts preemptions before we force a redisplay. */
317 static int preemption_count;
319 /* Minimum pixel height of clipped bottom display line. */
322 /* Minimum visible pixel width of clipped glyphs at right margin. */
325 /* Nonzero means reading single-character input with prompt
326 so put cursor on minibuffer after the prompt. */
327 int cursor_in_echo_area;
328 Lisp_Object Qcursor_in_echo_area;
330 /* Nonzero means truncate lines in all windows less wide than the frame */
331 int truncate_partial_width_windows;
333 /* non-nil if a buffer has changed since the last time redisplay completed */
335 int buffers_changed_set;
337 /* non-nil if hscroll has changed somewhere or a buffer has been
338 narrowed or widened */
340 int clip_changed_set;
342 /* non-nil if any extent has changed since the last time redisplay completed */
344 int extents_changed_set;
346 /* non-nil if any face has changed since the last time redisplay completed */
349 /* Nonzero means some frames have been marked as garbaged */
352 /* non-zero if any of the builtin display glyphs (continuation,
353 hscroll, control-arrow, etc) is in need of updating
356 int glyphs_changed_set;
358 /* non-zero if any subwindow has been deleted. */
359 int subwindows_changed;
360 int subwindows_changed_set;
362 /* non-zero if any displayed subwindow is in need of updating
364 int subwindows_state_changed;
365 int subwindows_state_changed_set;
367 /* This variable is 1 if the icon has to be updated.
368 It is set to 1 when `frame-icon-glyph' changes. */
370 int icon_changed_set;
372 /* This variable is 1 if the menubar widget has to be updated.
373 It is set to 1 by set-menubar-dirty-flag and cleared when the widget
376 int menubar_changed_set;
378 /* true iff we should redraw the modelines on the next redisplay */
379 int modeline_changed;
380 int modeline_changed_set;
382 /* non-nil if point has changed in some buffer since the last time
383 redisplay completed */
385 int point_changed_set;
387 /* non-nil if some frame has changed its size */
390 /* non-nil if some device has signaled that it wants to change size */
391 int asynch_device_change_pending;
393 /* non-nil if any toolbar has changed */
395 int toolbar_changed_set;
397 /* non-nil if any gutter has changed */
399 int gutter_changed_set;
401 /* non-nil if any window has changed since the last time redisplay completed */
404 /* non-nil if any frame's window structure has changed since the last
405 time redisplay completed */
406 int windows_structure_changed;
408 /* If non-nil, use vertical bar cursor. */
409 Lisp_Object Vbar_cursor;
410 Lisp_Object Qbar_cursor;
412 Lisp_Object Vvisible_bell; /* If true and the terminal will support it
413 then the frame will flash instead of
414 beeping when an error occurs */
416 /* Nonzero means no need to redraw the entire frame on resuming
417 a suspended Emacs. This is useful on terminals with multiple pages,
418 where one page is used for Emacs and another for all else. */
419 int no_redraw_on_reenter;
421 Lisp_Object Vwindow_system; /* nil or a symbol naming the window system
422 under which emacs is running
423 ('x is the only current possibility) */
424 Lisp_Object Vinitial_window_system;
426 Lisp_Object Vglobal_mode_string;
428 /* The number of lines scroll a window by when point leaves the window; if
429 it is <=0 then point is centered in the window */
432 /* Scroll up to this many lines, to bring point back on screen. */
433 int scroll_conservatively;
435 /* Marker for where to display an arrow on top of the buffer text. */
436 Lisp_Object Voverlay_arrow_position;
437 /* String to display for the arrow. */
438 Lisp_Object Voverlay_arrow_string;
440 Lisp_Object Vwindow_size_change_functions;
441 Lisp_Object Vwindow_scroll_functions;
442 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
444 Lisp_Object Qbuffer_list_changed_hook, Vbuffer_list_changed_hook;
447 #define INHIBIT_REDISPLAY_HOOKS /* #### Until we've thought about
449 #ifndef INHIBIT_REDISPLAY_HOOKS
450 /* #### Chuck says: I think this needs more thought.
451 Think about this for 19.14. */
452 Lisp_Object Vpre_redisplay_hook, Vpost_redisplay_hook;
453 Lisp_Object Qpre_redisplay_hook, Qpost_redisplay_hook;
454 #endif /* INHIBIT_REDISPLAY_HOOKS */
456 static int last_display_warning_tick, display_warning_tick;
457 Lisp_Object Qdisplay_warning_buffer;
458 int inhibit_warning_display;
460 Lisp_Object Vleft_margin_width, Vright_margin_width;
461 Lisp_Object Vminimum_line_ascent, Vminimum_line_descent;
462 Lisp_Object Vuse_left_overflow, Vuse_right_overflow;
463 Lisp_Object Vtext_cursor_visible_p;
465 int column_number_start_at_one;
467 Lisp_Object Qtop_bottom;
469 #define WINDOW_SCROLLED(w) \
470 (w->hscroll > 0 || w->left_xoffset)
473 /***************************************************************************/
475 /* low-level interfaces onto device routines */
477 /***************************************************************************/
480 redisplay_text_width_charc_string (struct window *w, int findex,
481 Charc *str, Charcount len)
483 Charset_ID charsets[NUM_LEADING_BYTES];
486 find_charsets_in_charc_string (charsets, str, len);
487 XSETWINDOW (window, w);
488 ensure_face_cachel_complete (WINDOW_FACE_CACHEL (w, findex), window,
490 return DEVMETH (XDEVICE (FRAME_DEVICE (XFRAME (WINDOW_FRAME (w)))),
491 text_width, (XFRAME (WINDOW_FRAME (w)),
492 WINDOW_FACE_CACHEL (w, findex), str, len));
495 static Charc_dynarr *rtw_charc_dynarr;
498 redisplay_text_width_string (struct window *w, int findex,
499 Bufbyte *nonreloc, Lisp_Object reloc,
500 Bytecount offset, Bytecount len)
502 if (!rtw_charc_dynarr)
503 rtw_charc_dynarr = Dynarr_new (Charc);
504 Dynarr_reset (rtw_charc_dynarr);
506 fixup_internal_substring (nonreloc, reloc, offset, &len);
508 nonreloc = XSTRING_DATA (reloc);
509 convert_bufbyte_string_into_charc_dynarr (nonreloc, len, rtw_charc_dynarr);
510 return redisplay_text_width_charc_string
511 (w, findex, Dynarr_atp (rtw_charc_dynarr, 0),
512 Dynarr_length (rtw_charc_dynarr));
516 redisplay_frame_text_width_string (struct frame *f, Lisp_Object face,
517 Bufbyte *nonreloc, Lisp_Object reloc,
518 Bytecount offset, Bytecount len)
520 Charset_ID charsets[NUM_LEADING_BYTES];
522 struct face_cachel cachel;
524 if (!rtw_charc_dynarr)
525 rtw_charc_dynarr = Dynarr_new (Charc);
526 Dynarr_reset (rtw_charc_dynarr);
528 fixup_internal_substring (nonreloc, reloc, offset, &len);
530 nonreloc = XSTRING_DATA (reloc);
531 convert_bufbyte_string_into_charc_dynarr (nonreloc, len, rtw_charc_dynarr);
532 find_charsets_in_bufbyte_string (charsets, nonreloc, len);
533 reset_face_cachel (&cachel);
535 XSETFRAME (frame, f);
536 ensure_face_cachel_complete (&cachel, frame, charsets);
537 return DEVMETH (XDEVICE (FRAME_DEVICE (f)),
538 text_width, (f, &cachel, Dynarr_atp (rtw_charc_dynarr, 0),
539 Dynarr_length (rtw_charc_dynarr)));
542 /* Return the display block from DL of the given TYPE. A display line
543 can have only one display block of each possible type. If DL does
544 not have a block of type TYPE, one will be created and added to DL. */
546 struct display_block *
547 get_display_block_from_line (struct display_line *dl, enum display_type type)
550 struct display_block db;
552 /* Check if this display line already has a block of the desired type and
554 if (dl->display_blocks)
556 for (elt = 0; elt < Dynarr_length (dl->display_blocks); elt++)
558 if (Dynarr_at (dl->display_blocks, elt).type == type)
559 return Dynarr_atp (dl->display_blocks, elt);
562 /* There isn't an active block of the desired type, but there
563 might still be allocated blocks we need to reuse. */
564 if (elt < Dynarr_largest (dl->display_blocks))
566 struct display_block *dbp = Dynarr_atp (dl->display_blocks, elt);
568 /* 'add' the block to the list */
569 Dynarr_increment (dl->display_blocks);
571 /* initialize and return */
578 /* This line doesn't have any display blocks, so initialize the display
580 dl->display_blocks = Dynarr_new (display_block);
583 /* The line doesn't have a block of the desired type so go ahead and create
584 one and add it to the line. */
587 db.runes = Dynarr_new (rune);
588 Dynarr_add (dl->display_blocks, db);
590 /* Return the newly added display block. */
591 elt = Dynarr_length (dl->display_blocks) - 1;
593 return Dynarr_atp (dl->display_blocks, elt);
597 tab_char_width (struct window *w)
599 struct buffer *b = XBUFFER (w->buffer);
600 int char_tab_width = XINT (b->tab_width);
602 if (char_tab_width <= 0 || char_tab_width > 1000) char_tab_width = 8;
604 return char_tab_width;
608 space_width (struct window *w)
610 /* While tabs are traditional composed of spaces, for variable-width
611 fonts the space character tends to give too narrow a value. So
612 we use 'n' instead. Except that we don't. We use the default
613 character width for the default face. If this is actually
614 defined by the font then it is probably the best thing to
615 actually use. If it isn't, we have assumed it is 'n' and have
616 already calculated its width. Thus we can avoid a call to
617 XTextWidth on X frames by just querying the default width. */
618 return XFONT_INSTANCE
619 (WINDOW_FACE_CACHEL_FONT (w, DEFAULT_INDEX, Vcharset_ascii))->width;
623 tab_pix_width (struct window *w)
625 return space_width (w) * tab_char_width (w);
628 /* Given a pixel position in a window, return the pixel location of
629 the next tabstop. Tabs are calculated from the left window edge in
630 terms of spaces displayed in the default face. Formerly the space
631 width was determined using the currently active face. That method
632 leads to tabstops which do not line up. */
635 next_tab_position (struct window *w, int start_pixpos, int left_pixpos)
637 int n_pos = left_pixpos;
638 int pix_tab_width = tab_pix_width (w);
640 /* Adjust n_pos for any hscrolling which has happened. */
641 if (WINDOW_SCROLLED (w))
642 n_pos -= space_width (w) * (w->hscroll - 1) + w->left_xoffset;
644 while (n_pos <= start_pixpos)
645 n_pos += pix_tab_width;
650 /* For the given window, calculate the outside and margin boundaries for a
651 display line. The whitespace boundaries must be calculated by the text
655 calculate_display_line_boundaries (struct window *w, int modeline)
657 layout_bounds bounds;
659 /* Set the outermost boundaries which are the boundaries of the
660 window itself minus the gutters (and minus the scrollbars if this
661 is for the modeline). */
664 bounds.left_out = WINDOW_TEXT_LEFT (w);
665 bounds.right_out = WINDOW_TEXT_RIGHT (w);
669 bounds.left_out = WINDOW_MODELINE_LEFT (w);
670 bounds.right_out = WINDOW_MODELINE_RIGHT (w);
673 /* The inner boundaries mark where the glyph margins are located. */
674 bounds.left_in = bounds.left_out + window_left_margin_width (w);
675 bounds.right_in = bounds.right_out - window_right_margin_width (w);
677 /* We cannot fully calculate the whitespace boundaries as they
678 depend on the contents of the line being displayed. */
679 bounds.left_white = bounds.left_in;
680 bounds.right_white = bounds.right_in;
685 /* Given a display line and a starting position, ensure that the
686 contents of the display line accurately represent the visual
687 representation of the buffer contents starting from the given
688 position when displayed in the given window. The display line ends
689 when the contents of the line reach the right boundary of the given
693 generate_display_line (struct window *w, struct display_line *dl, int bounds,
694 Bufpos start_pos, prop_block_dynarr **prop,
699 struct buffer *b = XBUFFER (WINDOW_BUFFER (w));
701 /* If our caller hasn't already set the boundaries, then do so now. */
703 dl->bounds = calculate_display_line_boundaries (w, 0);
705 /* Reset what this line is using. */
706 if (dl->display_blocks)
707 Dynarr_reset (dl->display_blocks);
710 Dynarr_free (dl->left_glyphs);
713 if (dl->right_glyphs)
715 Dynarr_free (dl->right_glyphs);
716 dl->right_glyphs = 0;
719 /* We aren't generating a modeline at the moment. */
722 /* Create a display block for the text region of the line. */
724 /* #### urk urk urk!!! Chuck fix this shit! */
725 Bytind hacked_up_bytind =
726 create_text_block (w, dl, bufpos_to_bytind (b, start_pos),
728 if (hacked_up_bytind > BI_BUF_ZV (b))
729 ret_bufpos = BUF_ZV (b) + 1;
731 ret_bufpos = bytind_to_bufpos (b, hacked_up_bytind);
733 dl->bufpos = start_pos;
734 if (dl->end_bufpos < dl->bufpos)
735 dl->end_bufpos = dl->bufpos;
737 if (MARKERP (Voverlay_arrow_position)
738 && EQ (w->buffer, Fmarker_buffer (Voverlay_arrow_position))
739 && start_pos == marker_position (Voverlay_arrow_position)
740 && (STRINGP (Voverlay_arrow_string)
741 || GLYPHP (Voverlay_arrow_string)))
743 overlay_width = create_overlay_glyph_block (w, dl);
748 /* If there are left glyphs associated with any character in the
749 text block, then create a display block to handle them. */
750 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
751 create_left_glyph_block (w, dl, overlay_width);
753 /* If there are right glyphs associated with any character in the
754 text block, then create a display block to handle them. */
755 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
756 create_right_glyph_block (w, dl);
758 /* In the future additional types of display blocks may be generated
761 w->last_redisplay_pos = ret_bufpos;
766 /* Adds an hscroll glyph to a display block. If this is called, then
767 the block had better be empty.
769 Yes, there are multiple places where this function is called but
770 that is the way it has to be. Each calling function has to deal
771 with bi_start_col_enabled a little differently depending on the
772 object being worked with. */
774 static prop_block_dynarr *
775 add_hscroll_rune (pos_data *data)
777 struct glyph_block gb;
778 prop_block_dynarr *retval;
779 Bytind bi_old_cursor_bufpos = data->bi_cursor_bufpos;
780 unsigned int old_cursor_type = data->cursor_type;
781 Bytind bi_old_bufpos = data->bi_bufpos;
783 if (data->cursor_type == CURSOR_ON
784 && data->bi_cursor_bufpos >= data->bi_start_col_enabled
785 && data->bi_cursor_bufpos <= data->bi_bufpos)
787 data->bi_cursor_bufpos = data->bi_start_col_enabled;
791 data->cursor_type = NO_CURSOR;
794 data->bi_endpos = data->bi_bufpos;
795 data->bi_bufpos = data->bi_start_col_enabled;
798 gb.glyph = Vhscroll_glyph;
800 int oldpixpos = data->pixpos;
801 retval = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0,
802 GLYPH_CACHEL (XWINDOW (data->window),
803 HSCROLL_GLYPH_INDEX));
804 data->hscroll_glyph_width_adjust =
805 data->pixpos - oldpixpos - space_width (XWINDOW (data->window));
808 data->bi_cursor_bufpos = bi_old_cursor_bufpos;
809 data->cursor_type = old_cursor_type;
810 data->bi_bufpos = bi_old_bufpos;
812 data->bi_start_col_enabled = 0;
816 /* Adds a character rune to a display block. If there is not enough
817 room to fit the rune on the display block (as determined by the
818 MAX_PIXPOS) then it adds nothing and returns ADD_FAILED. */
820 static prop_block_dynarr *
821 add_emchar_rune (pos_data *data)
823 struct rune rb, *crb;
835 if (data->bi_start_col_enabled)
837 return add_hscroll_rune (data);
840 if (data->ch == '\n')
842 char_glyph.charset = Vcharset_ascii;
843 char_glyph.code_point = '\n';
844 data->font_is_bogus = 0;
845 /* Cheesy end-of-line pseudo-character. */
846 width = data->blank_width;
850 char_glyph.code_point = ENCODE_CHAR (data->ch, char_glyph.charset);
851 if (!EQ (char_glyph.charset, data->last_charset) ||
852 data->findex != data->last_findex)
854 /* OK, we need to do things the hard way. */
855 struct window *w = XWINDOW (data->window);
856 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, data->findex);
857 Lisp_Object font_instance =
858 ensure_face_cachel_contains_charset (cachel, data->window,
860 Lisp_Font_Instance *fi;
862 if (EQ (font_instance, Vthe_null_font_instance))
864 font_instance = FACE_CACHEL_FONT (cachel, Vcharset_ascii);
865 data->font_is_bogus = 1;
868 data->font_is_bogus = 0;
870 fi = XFONT_INSTANCE (font_instance);
871 if (!fi->proportional_p)
872 /* sweetness and light. */
873 data->last_char_width = fi->width;
875 data->last_char_width = -1;
876 data->new_ascent = max (data->new_ascent, (int) fi->ascent);
877 data->new_descent = max (data->new_descent, (int) fi->descent);
878 data->last_charset = char_glyph.charset;
879 data->last_findex = data->findex;
882 width = data->last_char_width;
885 /* bummer. Proportional fonts. */
886 width = redisplay_text_width_charc_string (XWINDOW (data->window),
892 if (data->max_pixpos != -1 && (data->pixpos + width > data->max_pixpos))
897 if (Dynarr_length (data->db->runes) < Dynarr_largest (data->db->runes))
899 crb = Dynarr_atp (data->db->runes, Dynarr_length (data->db->runes));
908 crb->findex = data->findex;
909 crb->xpos = data->pixpos;
913 if (NILP (data->string))
915 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
919 bytecount_to_charcount (XSTRING_DATA (data->string),
922 else if (data->is_modeline)
923 crb->bufpos = data->modeline_charpos;
925 /* Text but not in buffer */
927 crb->type = RUNE_CHAR;
928 if (data->font_is_bogus)
930 char_glyph.charset = Vcharset_ascii;
931 char_glyph.code_point = '~';
932 crb->object.cglyph = char_glyph;
935 crb->object.cglyph = char_glyph;
938 if (data->cursor_type == CURSOR_ON)
940 if (data->bi_bufpos == data->bi_cursor_bufpos)
942 crb->cursor_type = CURSOR_ON;
943 data->cursor_x = Dynarr_length (data->db->runes);
946 crb->cursor_type = CURSOR_OFF;
948 else if (data->cursor_type == NEXT_CURSOR)
950 crb->cursor_type = CURSOR_ON;
951 data->cursor_x = Dynarr_length (data->db->runes);
952 data->cursor_type = NO_CURSOR;
954 else if (data->cursor_type == IGNORE_CURSOR)
955 crb->cursor_type = IGNORE_CURSOR;
957 crb->cursor_type = CURSOR_OFF;
960 Dynarr_add (data->db->runes, *crb);
962 Dynarr_increment (data->db->runes);
964 data->pixpos += width;
969 /* Given a string C_STRING of length C_LENGTH, call add_emchar_rune
970 for each character in the string. Propagate any left-over data
971 unless NO_PROP is non-zero. */
973 static prop_block_dynarr *
974 add_bufbyte_string_runes (pos_data *data, Bufbyte *c_string,
975 Bytecount c_length, int no_prop)
977 Bufbyte *pos, *end = c_string + c_length;
978 prop_block_dynarr *prop;
980 /* #### This function is too simplistic. It needs to do the same
981 sort of character interpretation (display-table lookup,
982 ctl-arrow checking), etc. that create_text_block() does.
983 The functionality to do this in that routine needs to be
986 for (pos = c_string; pos < end;)
988 data->ch = charptr_emchar (pos);
990 prop = add_emchar_rune (data);
998 struct prop_block pb;
999 Bytecount len = end - pos;
1000 prop = Dynarr_new (prop_block);
1002 pb.type = PROP_STRING;
1003 pb.data.p_string.str = xnew_array (Bufbyte, len);
1004 strncpy ((char *) pb.data.p_string.str, (char *) pos, len);
1005 pb.data.p_string.len = len;
1007 Dynarr_add (prop, pb);
1012 assert (pos <= end);
1018 /* Add a single rune of the specified width. The area covered by this
1019 rune will be displayed in the foreground color of the associated
1022 static prop_block_dynarr *
1023 add_blank_rune (pos_data *data, struct window *w, int char_tab_width)
1027 /* If data->start_col is not 0 then this call to add_blank_rune must have
1028 been to add it as a tab. */
1029 if (data->start_col)
1031 /* assert (w != NULL) */
1032 prop_block_dynarr *retval;
1034 /* If we have still not fully scrolled horizontally, subtract
1035 the width of this tab and return. */
1036 if (char_tab_width < data->start_col)
1038 data->start_col -= char_tab_width;
1041 else if (char_tab_width == data->start_col)
1042 data->blank_width = 0;
1045 int spcwid = space_width (w);
1047 if (spcwid >= data->blank_width)
1048 data->blank_width = 0;
1050 data->blank_width -= spcwid;
1053 data->start_col = 0;
1054 retval = add_hscroll_rune (data);
1056 /* Could be caused by the handling of the hscroll rune. */
1057 if (retval != NULL || !data->blank_width)
1061 /* Blank runes are always calculated to fit. */
1062 assert (data->pixpos + data->blank_width <= data->max_pixpos);
1064 rb.findex = data->findex;
1065 rb.xpos = data->pixpos;
1066 rb.width = data->blank_width;
1067 if (data->bi_bufpos)
1069 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
1072 /* #### and this is really correct too? */
1075 rb.type = RUNE_BLANK;
1077 if (data->cursor_type == CURSOR_ON)
1079 if (data->bi_bufpos == data->bi_cursor_bufpos)
1081 rb.cursor_type = CURSOR_ON;
1082 data->cursor_x = Dynarr_length (data->db->runes);
1085 rb.cursor_type = CURSOR_OFF;
1087 else if (data->cursor_type == NEXT_CURSOR)
1089 rb.cursor_type = CURSOR_ON;
1090 data->cursor_x = Dynarr_length (data->db->runes);
1091 data->cursor_type = NO_CURSOR;
1094 rb.cursor_type = CURSOR_OFF;
1096 Dynarr_add (data->db->runes, rb);
1097 data->pixpos += data->blank_width;
1102 /* Add runes representing a character in octal. */
1104 #define ADD_NEXT_OCTAL_RUNE_CHAR do \
1106 if (add_failed || (add_failed = add_emchar_rune (data))) \
1108 struct prop_block pb; \
1110 prop = Dynarr_new (prop_block); \
1112 pb.type = PROP_CHAR; \
1113 pb.data.p_char.ch = data->ch; \
1114 pb.data.p_char.cursor_type = data->cursor_type; \
1115 Dynarr_add (prop, pb); \
1119 static prop_block_dynarr *
1120 add_octal_runes (pos_data *data)
1122 prop_block_dynarr *prop, *add_failed;
1123 Emchar orig_char = data->ch;
1124 unsigned int orig_cursor_type = data->cursor_type;
1130 if (data->start_col)
1133 if (!data->start_col)
1135 if (data->bi_start_col_enabled)
1137 add_failed = add_hscroll_rune (data);
1141 struct glyph_block gb;
1142 struct window *w = XWINDOW (data->window);
1145 gb.glyph = Voctal_escape_glyph;
1147 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1148 GLYPH_CACHEL (w, OCT_ESC_GLYPH_INDEX));
1152 /* We only propagate information if the glyph was partially
1157 data->cursor_type = IGNORE_CURSOR;
1159 if (data->ch >= 0x100)
1161 /* If the character is an extended Mule character, it could have
1162 up to 19 bits. For the moment, we treat it as a seven-digit
1163 octal number. This is not that pretty, but whatever. */
1164 data->ch = (7 & (orig_char >> 18)) + '0';
1165 ADD_NEXT_OCTAL_RUNE_CHAR;
1167 data->ch = (7 & (orig_char >> 15)) + '0';
1168 ADD_NEXT_OCTAL_RUNE_CHAR;
1170 data->ch = (7 & (orig_char >> 12)) + '0';
1171 ADD_NEXT_OCTAL_RUNE_CHAR;
1173 data->ch = (7 & (orig_char >> 9)) + '0';
1174 ADD_NEXT_OCTAL_RUNE_CHAR;
1177 data->ch = (7 & (orig_char >> 6)) + '0';
1178 ADD_NEXT_OCTAL_RUNE_CHAR;
1180 data->ch = (7 & (orig_char >> 3)) + '0';
1181 ADD_NEXT_OCTAL_RUNE_CHAR;
1183 data->ch = (7 & orig_char) + '0';
1184 ADD_NEXT_OCTAL_RUNE_CHAR;
1186 data->cursor_type = orig_cursor_type;
1190 #undef ADD_NEXT_OCTAL_RUNE_CHAR
1192 /* Add runes representing a control character to a display block. */
1194 static prop_block_dynarr *
1195 add_control_char_runes (pos_data *data, struct buffer *b)
1197 if (!NILP (b->ctl_arrow))
1199 prop_block_dynarr *prop;
1200 Emchar orig_char = data->ch;
1201 unsigned int old_cursor_type = data->cursor_type;
1206 if (data->start_col)
1209 if (!data->start_col)
1211 if (data->bi_start_col_enabled)
1213 prop_block_dynarr *retval;
1215 retval = add_hscroll_rune (data);
1221 struct glyph_block gb;
1222 struct window *w = XWINDOW (data->window);
1225 gb.glyph = Vcontrol_arrow_glyph;
1227 /* We only propagate information if the glyph was partially
1229 if (add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1230 GLYPH_CACHEL (w, CONTROL_GLYPH_INDEX)))
1235 if (orig_char == 0177)
1238 data->ch = orig_char ^ 0100;
1239 data->cursor_type = IGNORE_CURSOR;
1241 if (add_emchar_rune (data))
1243 struct prop_block pb;
1245 prop = Dynarr_new (prop_block);
1247 pb.type = PROP_CHAR;
1248 pb.data.p_char.ch = data->ch;
1249 pb.data.p_char.cursor_type = data->cursor_type;
1250 Dynarr_add (prop, pb);
1253 data->cursor_type = old_cursor_type;
1258 return add_octal_runes (data);
1262 static prop_block_dynarr *
1263 add_disp_table_entry_runes_1 (pos_data *data, Lisp_Object entry)
1265 prop_block_dynarr *prop = NULL;
1267 if (STRINGP (entry))
1269 prop = add_bufbyte_string_runes (data,
1270 XSTRING_DATA (entry),
1271 XSTRING_LENGTH (entry),
1274 else if (GLYPHP (entry))
1276 if (data->start_col)
1279 if (!data->start_col && data->bi_start_col_enabled)
1281 prop = add_hscroll_rune (data);
1285 struct glyph_block gb;
1289 prop = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
1292 else if (CHAR_OR_CHAR_INTP (entry))
1294 data->ch = XCHAR_OR_CHAR_INT (entry);
1295 prop = add_emchar_rune (data);
1297 else if (CONSP (entry))
1299 if (EQ (XCAR (entry), Qformat)
1300 && CONSP (XCDR (entry))
1301 && STRINGP (XCAR (XCDR (entry))))
1303 Lisp_Object format = XCAR (XCDR (entry));
1304 Bytind len = XSTRING_LENGTH (format);
1305 Bufbyte *src = XSTRING_DATA (format), *end = src + len;
1306 Bufbyte *result = alloca_array (Bufbyte, len);
1307 Bufbyte *dst = result;
1311 Emchar c = charptr_emchar (src);
1313 if (c != '%' || src == end)
1314 dst += set_charptr_emchar (dst, c);
1317 c = charptr_emchar (src);
1322 dst += long_to_string_base ((char *)dst, data->ch, 16);
1325 dst += set_charptr_emchar (dst, '%');
1327 /* #### unimplemented */
1331 prop = add_bufbyte_string_runes (data, result, dst - result, 0);
1335 /* Else blow it off because someone added a bad entry and we don't
1336 have any safe way of signaling an error. */
1340 /* Given a display table entry, call the appropriate functions to
1341 display each element of the entry. */
1343 static prop_block_dynarr *
1344 add_disp_table_entry_runes (pos_data *data, Lisp_Object entry)
1346 prop_block_dynarr *prop = NULL;
1347 if (VECTORP (entry))
1349 Lisp_Vector *de = XVECTOR (entry);
1350 EMACS_INT len = vector_length (de);
1353 for (elt = 0; elt < len; elt++)
1355 if (NILP (vector_data (de)[elt]))
1358 prop = add_disp_table_entry_runes_1 (data, vector_data (de)[elt]);
1359 /* Else blow it off because someone added a bad entry and we
1360 don't have any safe way of signaling an error. Hey, this
1361 comment sounds familiar. */
1363 /* #### Still need to add any remaining elements to the
1364 propagation information. */
1370 prop = add_disp_table_entry_runes_1 (data, entry);
1374 /* Add runes which were propagated from the previous line. */
1376 static prop_block_dynarr *
1377 add_propagation_runes (prop_block_dynarr **prop, pos_data *data)
1379 /* #### Remember to handle start_col parameter of data when the rest of
1380 this is finished. */
1381 /* #### Chuck -- I've redone this function a bit. It looked like the
1382 case of not all the propagation blocks being added was not handled
1384 /* #### Chuck -- I also think the double indirection of PROP is kind
1385 of bogus. A cleaner solution is just to check for
1386 Dynarr_length (prop) > 0. */
1387 /* #### This function also doesn't even pay attention to ADD_FAILED!
1388 This is seriously fucked! Seven ####'s in 130 lines -- is that a
1391 prop_block_dynarr *add_failed;
1392 Bytind bi_old_cursor_bufpos = data->bi_cursor_bufpos;
1393 unsigned int old_cursor_type = data->cursor_type;
1395 for (elt = 0; elt < Dynarr_length (*prop); elt++)
1397 struct prop_block *pb = Dynarr_atp (*prop, elt);
1402 data->ch = pb->data.p_char.ch;
1403 data->bi_cursor_bufpos = pb->data.p_char.bi_cursor_bufpos;
1404 data->cursor_type = pb->data.p_char.cursor_type;
1405 add_failed = add_emchar_rune (data);
1408 goto oops_no_more_space;
1411 if (pb->data.p_string.str)
1412 xfree (pb->data.p_string.str);
1413 /* #### bogus bogus -- this doesn't do anything!
1414 Should probably call add_bufbyte_string_runes(),
1415 once that function is fixed. */
1417 case PROP_MINIBUF_PROMPT:
1419 face_index old_findex = data->findex;
1420 Bytind bi_old_bufpos = data->bi_bufpos;
1422 data->findex = DEFAULT_INDEX;
1423 data->bi_bufpos = 0;
1424 data->cursor_type = NO_CURSOR;
1426 while (pb->data.p_string.len > 0)
1428 data->ch = charptr_emchar (pb->data.p_string.str);
1429 add_failed = add_emchar_rune (data);
1433 data->findex = old_findex;
1434 data->bi_bufpos = bi_old_bufpos;
1435 goto oops_no_more_space;
1439 /* Complicated equivalent of ptr++, len-- */
1440 Bufbyte *oldpos = pb->data.p_string.str;
1441 INC_CHARPTR (pb->data.p_string.str);
1442 pb->data.p_string.len -= pb->data.p_string.str - oldpos;
1446 data->findex = old_findex;
1447 /* ##### FIXME FIXME FIXME -- Upon successful return from
1448 this function, data->bi_bufpos is automatically incremented.
1449 However, we don't want that to happen if we were adding
1450 the minibuffer prompt. */
1452 struct buffer *buf =
1453 XBUFFER (WINDOW_BUFFER (XWINDOW (data->window)));
1454 /* #### Chuck fix this shit or I'm gonna scream! */
1455 if (bi_old_bufpos > BI_BUF_BEGV (buf))
1456 data->bi_bufpos = prev_bytind (buf, bi_old_bufpos);
1458 /* #### is this correct? Does anyone know?
1459 Does anyone care? Is this a cheesy hack or what? */
1460 data->bi_bufpos = BI_BUF_BEGV (buf) - 1;
1466 /* #### I think it's unnecessary and misleading to preserve
1467 the blank_width, as it implies that the value carries
1468 over from one rune to the next, which is wrong. */
1469 int old_width = data->blank_width;
1470 face_index old_findex = data->findex;
1472 data->findex = pb->data.p_blank.findex;
1473 data->blank_width = pb->data.p_blank.width;
1474 data->bi_cursor_bufpos = 0;
1475 data->cursor_type = IGNORE_CURSOR;
1477 if (data->pixpos + data->blank_width > data->max_pixpos)
1478 data->blank_width = data->max_pixpos - data->pixpos;
1480 /* We pass a bogus value of char_tab_width. It shouldn't
1481 matter because unless something is really screwed up
1482 this call won't cause that arg to be used. */
1483 add_failed = add_blank_rune (data, XWINDOW (data->window), 0);
1485 /* This can happen in the case where we have a tab which
1486 is wider than the window. */
1487 if (data->blank_width != pb->data.p_blank.width)
1489 pb->data.p_blank.width -= data->blank_width;
1490 add_failed = ADD_FAILED;
1493 data->findex = old_findex;
1494 data->blank_width = old_width;
1497 goto oops_no_more_space;
1507 data->bi_cursor_bufpos = bi_old_cursor_bufpos;
1508 data->cursor_type = old_cursor_type;
1509 if (elt < Dynarr_length (*prop))
1511 Dynarr_delete_many (*prop, 0, elt);
1516 Dynarr_free (*prop);
1521 /* Add 'text layout glyphs at position POS_TYPE that are contained to
1522 the display block, but add all other types to the appropriate list
1523 of the display line. They will be added later by different
1526 static prop_block_dynarr *
1527 add_glyph_rune (pos_data *data, struct glyph_block *gb, int pos_type,
1528 int allow_cursor, struct glyph_cachel *cachel)
1530 struct window *w = XWINDOW (data->window);
1532 /* If window faces changed, and glyph instance is text, then
1533 glyph sizes might have changed too */
1534 invalidate_glyph_geometry_maybe (gb->glyph, w);
1536 /* This makes sure the glyph is in the cachels.
1538 #### We do this to make sure the glyph is in the glyph cachels,
1539 so that the dirty flag can be reset after redisplay has
1540 finished. We should do this some other way, maybe by iterating
1541 over the window cache of subwindows. */
1542 get_glyph_cachel_index (w, gb->glyph);
1544 /* A nil extent indicates a special glyph (ex. truncator). */
1545 if (NILP (gb->extent)
1546 || (pos_type == BEGIN_GLYPHS &&
1547 extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1548 || (pos_type == END_GLYPHS &&
1549 extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1550 || pos_type == LEFT_GLYPHS || pos_type == RIGHT_GLYPHS)
1555 int ascent, descent;
1556 Lisp_Object baseline;
1558 Lisp_Object instance;
1562 width = cachel->width;
1564 width = glyph_width (gb->glyph, data->window);
1569 if (data->start_col || data->start_col_xoffset)
1571 prop_block_dynarr *retval;
1572 int glyph_char_width = width / space_width (w);
1574 /* If we still have not fully scrolled horizontally after
1575 taking into account the width of the glyph, subtract its
1576 width and return. */
1577 if (glyph_char_width < data->start_col)
1579 data->start_col -= glyph_char_width;
1582 else if (glyph_char_width == data->start_col)
1586 xoffset = space_width (w) * data->start_col;
1589 /* #### Can this happen? */
1594 data->start_col = 0;
1595 retval = add_hscroll_rune (data);
1597 /* Could be caused by the handling of the hscroll rune. */
1598 if (retval != NULL || !width)
1604 if (data->pixpos + width > data->max_pixpos)
1606 /* If this is the first object we are attempting to add to
1607 the line then we ignore the horizontal_clip threshold.
1608 Otherwise we will loop until the bottom of the window
1609 continually failing to add this glyph because it is wider
1610 than the window. We could alternatively just completely
1611 ignore the glyph and proceed from there but I think that
1612 this is a better solution. */
1613 if (Dynarr_length (data->db->runes)
1614 && data->max_pixpos - data->pixpos < horizontal_clip)
1617 width = data->max_pixpos - data->pixpos;
1622 ascent = cachel->ascent;
1623 descent = cachel->descent;
1627 ascent = glyph_ascent (gb->glyph, data->window);
1628 descent = glyph_descent (gb->glyph, data->window);
1631 baseline = glyph_baseline (gb->glyph, data->window);
1633 if (glyph_contrib_p (gb->glyph, data->window))
1635 /* A pixmap that has not had a baseline explicitly set. Its
1636 contribution will be determined later. */
1637 if (NILP (baseline))
1639 int height = ascent + descent;
1640 data->max_pixmap_height = max (data->max_pixmap_height, height);
1643 /* A string so determine contribution normally. */
1644 else if (EQ (baseline, Qt))
1646 data->new_ascent = max (data->new_ascent, ascent);
1647 data->new_descent = max (data->new_descent, descent);
1650 /* A pixmap with an explicitly set baseline. We determine the
1651 contribution here. */
1652 else if (INTP (baseline))
1654 int height = ascent + descent;
1655 int pix_ascent, pix_descent;
1657 pix_ascent = height * XINT (baseline) / 100;
1658 pix_descent = height - pix_ascent;
1660 data->new_ascent = max (data->new_ascent, pix_ascent);
1661 data->new_descent = max (data->new_descent, pix_descent);
1664 /* Otherwise something is screwed up. */
1669 face = glyph_face (gb->glyph, data->window);
1671 findex = data->findex;
1673 findex = get_builtin_face_cache_index (w, face);
1675 instance = glyph_image_instance (gb->glyph, data->window,
1677 if (TEXT_IMAGE_INSTANCEP (instance))
1679 Lisp_Object string = XIMAGE_INSTANCE_TEXT_STRING (instance);
1680 face_index orig_findex = data->findex;
1681 Bytind orig_bufpos = data->bi_bufpos;
1682 Bytind orig_start_col_enabled = data->bi_start_col_enabled;
1684 data->findex = findex;
1685 data->bi_start_col_enabled = 0;
1687 data->bi_bufpos = 0;
1688 add_bufbyte_string_runes (data, XSTRING_DATA (string),
1689 XSTRING_LENGTH (string), 0);
1690 data->findex = orig_findex;
1691 data->bi_bufpos = orig_bufpos;
1692 data->bi_start_col_enabled = orig_start_col_enabled;
1697 rb.xpos = data->pixpos;
1699 rb.bufpos = 0; /* glyphs are never "at" anywhere */
1700 if (data->bi_endpos)
1701 /* #### is this necessary at all? */
1702 rb.endpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1706 rb.type = RUNE_DGLYPH;
1707 rb.object.dglyph.glyph = gb->glyph;
1708 rb.object.dglyph.extent = gb->extent;
1709 rb.object.dglyph.xoffset = xoffset;
1713 rb.bufpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1716 if (data->cursor_type == CURSOR_ON)
1718 if (data->bi_bufpos == data->bi_cursor_bufpos)
1720 rb.cursor_type = CURSOR_ON;
1721 data->cursor_x = Dynarr_length (data->db->runes);
1724 rb.cursor_type = CURSOR_OFF;
1726 else if (data->cursor_type == NEXT_CURSOR)
1728 rb.cursor_type = CURSOR_ON;
1729 data->cursor_x = Dynarr_length (data->db->runes);
1730 data->cursor_type = NO_CURSOR;
1732 else if (data->cursor_type == IGNORE_CURSOR)
1733 rb.cursor_type = IGNORE_CURSOR;
1734 else if (data->cursor_type == NO_CURSOR)
1735 rb.cursor_type = NO_CURSOR;
1737 rb.cursor_type = CURSOR_OFF;
1740 rb.cursor_type = CURSOR_OFF;
1742 Dynarr_add (data->db->runes, rb);
1743 data->pixpos += width;
1749 if (!NILP (glyph_face (gb->glyph, data->window)))
1751 get_builtin_face_cache_index (w, glyph_face (gb->glyph,
1754 gb->findex = data->findex;
1756 if (pos_type == BEGIN_GLYPHS)
1758 if (!data->dl->left_glyphs)
1759 data->dl->left_glyphs = Dynarr_new (glyph_block);
1760 Dynarr_add (data->dl->left_glyphs, *gb);
1763 else if (pos_type == END_GLYPHS)
1765 if (!data->dl->right_glyphs)
1766 data->dl->right_glyphs = Dynarr_new (glyph_block);
1767 Dynarr_add (data->dl->right_glyphs, *gb);
1771 abort (); /* there are no unknown types */
1774 return NULL; /* shut up compiler */
1777 /* Add all glyphs at position POS_TYPE that are contained in the given
1780 static prop_block_dynarr *
1781 add_glyph_runes (pos_data *data, int pos_type)
1783 /* #### This still needs to handle the start_col parameter. Duh, Chuck,
1784 why didn't you just modify add_glyph_rune in the first place? */
1786 glyph_block_dynarr *glyph_arr = (pos_type == BEGIN_GLYPHS
1787 ? data->ef->begin_glyphs
1788 : data->ef->end_glyphs);
1789 prop_block_dynarr *prop;
1791 for (elt = 0; elt < Dynarr_length (glyph_arr); elt++)
1793 prop = add_glyph_rune (data, Dynarr_atp (glyph_arr, elt), pos_type, 0,
1798 /* #### Add some propagation information. */
1803 Dynarr_reset (glyph_arr);
1808 /* Given a position for a buffer in a window, ensure that the given
1809 display line DL accurately represents the text on a line starting
1810 at the given position.
1812 NOTE NOTE NOTE NOTE: This function works with and returns Bytinds.
1813 You must do appropriate conversion. */
1816 create_text_block (struct window *w, struct display_line *dl,
1817 Bytind bi_start_pos, prop_block_dynarr **prop,
1820 struct frame *f = XFRAME (w->frame);
1821 struct buffer *b = XBUFFER (w->buffer);
1822 struct device *d = XDEVICE (f->device);
1826 /* Don't display anything in the minibuffer if this window is not on
1827 a selected frame. We consider all other windows to be active
1828 minibuffers as it simplifies the coding. */
1829 int active_minibuffer = (!MINI_WINDOW_P (w) ||
1830 (f == device_selected_frame (d)) ||
1831 is_surrogate_for_selected_frame (f));
1833 int truncate_win = window_truncation_on (w);
1834 int end_glyph_width;
1836 /* If the buffer's value of selective_display is an integer then
1837 only lines that start with less than selective_display columns of
1838 space will be displayed. If selective_display is t then all text
1839 after a ^M is invisible. */
1840 int selective = (INTP (b->selective_display)
1841 ? XINT (b->selective_display)
1842 : (!NILP (b->selective_display) ? -1 : 0));
1844 /* The variable ctl-arrow allows the user to specify what characters
1845 can actually be displayed and which octal should be used for.
1846 #### This variable should probably have some rethought done to
1849 #### It would also be really nice if you could specify that
1850 the characters come out in hex instead of in octal. Mule
1851 does that by adding a ctl-hexa variable similar to ctl-arrow,
1852 but that's bogus -- we need a more general solution. I
1853 think you need to extend the concept of display tables
1854 into a more general conversion mechanism. Ideally you
1855 could specify a Lisp function that converts characters,
1856 but this violates the Second Golden Rule and besides would
1857 make things way way way way slow.
1859 So instead, we extend the display-table concept, which was
1860 historically limited to 256-byte vectors, to one of the
1863 a) A 256-entry vector, for backward compatibility;
1864 b) char-table, mapping characters to values;
1865 c) range-table, mapping ranges of characters to values;
1866 d) a list of the above.
1868 The (d) option allows you to specify multiple display tables
1869 instead of just one. Each display table can specify conversions
1870 for some characters and leave others unchanged. The way the
1871 character gets displayed is determined by the first display table
1872 with a binding for that character. This way, you could call a
1873 function `enable-hex-display' that adds a hex display-table to
1874 the list of display tables for the current buffer.
1876 #### ...not yet implemented... Also, we extend the concept of
1877 "mapping" to include a printf-like spec. Thus you can make all
1878 extended characters show up as hex with a display table like
1881 #s(range-table data ((256 524288) (format "%x")))
1883 Since more than one display table is possible, you have
1884 great flexibility in mapping ranges of characters. */
1885 Emchar printable_min = (CHAR_OR_CHAR_INTP (b->ctl_arrow)
1886 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
1887 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
1890 Lisp_Object face_dt, window_dt;
1892 /* The text display block for this display line. */
1893 struct display_block *db = get_display_block_from_line (dl, TEXT);
1895 /* The first time through the main loop we need to force the glyph
1896 data to be updated. */
1899 /* Apparently the new extent_fragment_update returns an end position
1900 equal to the position passed in if there are no more runs to be
1902 int no_more_frags = 0;
1904 Lisp_Object synch_minibuffers_value =
1905 symbol_value_in_buffer (Qsynchronize_minibuffers, w->buffer);
1907 dl->used_prop_data = 0;
1909 dl->line_continuation = 0;
1912 data.ef = extent_fragment_new (w->buffer, f);
1914 /* These values are used by all of the rune addition routines. We add
1915 them to this structure for ease of passing. */
1917 XSETWINDOW (data.window, w);
1922 data.bi_bufpos = bi_start_pos;
1923 data.pixpos = dl->bounds.left_in;
1924 data.last_charset = Qunbound;
1925 data.last_findex = DEFAULT_INDEX;
1926 data.result_str = Qnil;
1928 /* Set the right boundary adjusting it to take into account any end
1929 glyph. Save the width of the end glyph for later use. */
1930 data.max_pixpos = dl->bounds.right_in;
1932 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
1934 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
1935 data.max_pixpos -= end_glyph_width;
1937 if (cursor_in_echo_area && MINI_WINDOW_P (w) && echo_area_active (f))
1939 data.bi_cursor_bufpos = BI_BUF_ZV (b);
1940 data.cursor_type = CURSOR_ON;
1942 else if (MINI_WINDOW_P (w) && !active_minibuffer)
1943 data.cursor_type = NO_CURSOR;
1944 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)) &&
1945 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
1946 d == XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d))))&&
1947 f == XFRAME(DEVICE_SELECTED_FRAME(d)))
1949 data.bi_cursor_bufpos = BI_BUF_PT (b);
1950 data.cursor_type = CURSOR_ON;
1952 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)))
1954 data.bi_cursor_bufpos = bi_marker_position (w->pointm[type]);
1955 data.cursor_type = CURSOR_ON;
1958 data.cursor_type = NO_CURSOR;
1961 data.start_col = w->hscroll;
1962 data.start_col_xoffset = w->left_xoffset;
1963 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
1964 data.hscroll_glyph_width_adjust = 0;
1966 /* We regenerate the line from the very beginning. */
1967 Dynarr_reset (db->runes);
1969 /* Why is this less than or equal and not just less than? If the
1970 starting position is already equal to the maximum we can't add
1971 anything else, right? Wrong. We might still have a newline to
1972 add. A newline can use the room allocated for an end glyph since
1973 if we add it we know we aren't going to be adding any end
1976 /* #### Chuck -- I think this condition should be while (1).
1977 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
1978 and the begin-glyph ends exactly at the end of the window, the
1979 end-glyph and text might not be displayed. while (1) ensures
1980 that the loop terminates only when either (a) there is
1981 propagation data or (b) the end-of-line or end-of-buffer is hit.
1983 #### Also I think you need to ensure that the operation
1984 "add begin glyphs; add end glyphs; add text" is atomic and
1985 can't get interrupted in the middle. If you run off the end
1986 of the line during that operation, then you keep accumulating
1987 propagation data until you're done. Otherwise, if the (e.g.)
1988 there's a begin glyph at a particular position and attempting
1989 to display that glyph results in window-end being hit and
1990 propagation data being generated, then the character at that
1991 position won't be displayed.
1993 #### See also the comment after the end of this loop, below.
1995 while (data.pixpos <= data.max_pixpos
1996 && (active_minibuffer || !NILP (synch_minibuffers_value)))
1998 /* #### This check probably should not be necessary. */
1999 if (data.bi_bufpos > BI_BUF_ZV (b))
2001 /* #### urk! More of this lossage! */
2006 /* If selective display was an integer and we aren't working on
2007 a continuation line then find the next line we are actually
2008 supposed to display. */
2010 && (data.bi_bufpos == BI_BUF_BEGV (b)
2011 || BUF_FETCH_CHAR (b, prev_bytind (b, data.bi_bufpos)) == '\n'))
2013 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2016 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2017 if (data.bi_bufpos >= BI_BUF_ZV (b))
2019 data.bi_bufpos = BI_BUF_ZV (b);
2025 /* Check for face changes. */
2026 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
2028 /* Now compute the face and begin/end-glyph information. */
2030 /* Remember that the extent-fragment routines deal in Bytind's. */
2031 extent_fragment_update (w, data.ef, data.bi_bufpos);
2033 get_display_tables (w, data.findex, &face_dt, &window_dt);
2035 if (data.bi_bufpos == data.ef->end)
2040 /* Determine what is next to be displayed. We first handle any
2041 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
2042 display then we determine what to do based on the character at the
2043 current buffer position. */
2045 /* If the current position is covered by an invisible extent, do
2046 nothing (except maybe add some ellipses).
2048 #### The behavior of begin and end-glyphs at the edge of an
2049 invisible extent should be investigated further. This is
2050 fairly low priority though. */
2051 if (data.ef->invisible)
2053 /* #### Chuck, perhaps you could look at this code? I don't
2054 really know what I'm doing. */
2057 Dynarr_free (*prop);
2061 /* The extent fragment code only sets this when we should
2062 really display the ellipses. It makes sure the ellipses
2063 don't get displayed more than once in a row. */
2064 if (data.ef->invisible_ellipses)
2066 struct glyph_block gb;
2068 data.ef->invisible_ellipses_already_displayed = 1;
2069 data.ef->invisible_ellipses = 0;
2071 gb.glyph = Vinvisible_text_glyph;
2072 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2073 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2074 /* Perhaps they shouldn't propagate if the very next thing
2075 is to display a newline (for compatibility with
2076 selective-display-ellipses)? Maybe that's too
2082 /* If point is in an invisible region we place it on the
2083 next visible character. */
2084 if (data.cursor_type == CURSOR_ON
2085 && data.bi_bufpos == data.bi_cursor_bufpos)
2087 data.cursor_type = NEXT_CURSOR;
2090 /* #### What if we we're dealing with a display table? */
2094 if (data.bi_bufpos == BI_BUF_ZV (b))
2097 INC_BYTIND (b, data.bi_bufpos);
2100 /* If there is propagation data, then it represents the current
2101 buffer position being displayed. Add them and advance the
2102 position counter. This might also add the minibuffer
2106 dl->used_prop_data = 1;
2107 *prop = add_propagation_runes (prop, &data);
2110 goto done; /* gee, a really narrow window */
2111 else if (data.bi_bufpos == BI_BUF_ZV (b))
2113 else if (data.bi_bufpos < BI_BUF_BEGV (b))
2114 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
2115 data.bi_bufpos = BI_BUF_BEGV (b);
2117 INC_BYTIND (b, data.bi_bufpos);
2120 /* If there are end glyphs, add them to the line. These are
2121 the end glyphs for the previous run of text. We add them
2122 here rather than doing them at the end of handling the
2123 previous run so that glyphs at the beginning and end of
2124 a line are handled correctly. */
2125 else if (Dynarr_length (data.ef->end_glyphs) > 0)
2127 *prop = add_glyph_runes (&data, END_GLYPHS);
2132 /* If there are begin glyphs, add them to the line. */
2133 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
2135 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
2140 /* If at end-of-buffer, we've already processed begin and
2141 end-glyphs at this point and there's no text to process,
2143 else if (data.bi_bufpos == BI_BUF_ZV (b))
2148 Lisp_Object entry = Qnil;
2149 /* Get the character at the current buffer position. */
2150 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2151 if (!NILP (face_dt) || !NILP (window_dt))
2152 entry = display_table_entry (data.ch, face_dt, window_dt);
2154 /* If there is a display table entry for it, hand it off to
2155 add_disp_table_entry_runes and let it worry about it. */
2156 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
2158 *prop = add_disp_table_entry_runes (&data, entry);
2164 /* Check if we have hit a newline character. If so, add a marker
2165 to the line and end this loop. */
2166 else if (data.ch == '\n')
2168 /* We aren't going to be adding an end glyph so give its
2169 space back in order to make sure that the cursor can
2171 data.max_pixpos += end_glyph_width;
2174 && (bi_spaces_at_point
2175 (b, next_bytind (b, data.bi_bufpos))
2178 if (!NILP (b->selective_display_ellipses))
2180 struct glyph_block gb;
2183 gb.glyph = Vinvisible_text_glyph;
2184 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2185 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2189 /* Cheesy, cheesy, cheesy. We mark the end of the
2190 line with a special "character rune" whose width
2191 is the EOL cursor width and whose character is
2192 the non-printing character '\n'. */
2193 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2194 *prop = add_emchar_rune (&data);
2197 /* We need to set data.bi_bufpos to the start of the
2198 next visible region in order to make this line
2199 appear to contain all of the invisible area.
2200 Otherwise, the line cache won't work
2202 INC_BYTIND (b, data.bi_bufpos);
2203 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2206 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2207 if (data.bi_bufpos >= BI_BUF_ZV (b))
2209 data.bi_bufpos = BI_BUF_ZV (b);
2213 if (BI_BUF_FETCH_CHAR
2214 (b, prev_bytind (b, data.bi_bufpos)) == '\n')
2215 DEC_BYTIND (b, data.bi_bufpos);
2219 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2220 *prop = add_emchar_rune (&data);
2226 /* If the current character is ^M, and selective display is
2227 enabled, then add the invisible-text-glyph if
2228 selective-display-ellipses is set. In any case, this
2230 else if (data.ch == (('M' & 037)) && selective == -1)
2232 Bytind bi_next_bufpos;
2234 /* Find the buffer position at the end of the line. */
2236 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2237 if (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_next_bufpos))
2239 DEC_BYTIND (b, bi_next_bufpos);
2241 /* If the cursor is somewhere in the elided text make
2242 sure that the cursor gets drawn appropriately. */
2243 if (data.cursor_type == CURSOR_ON
2244 && (data.bi_cursor_bufpos >= data.bi_bufpos &&
2245 data.bi_cursor_bufpos < bi_next_bufpos))
2247 data.cursor_type = NEXT_CURSOR;
2250 /* We won't be adding a truncation or continuation glyph
2251 so give up the room allocated for them. */
2252 data.max_pixpos += end_glyph_width;
2254 if (!NILP (b->selective_display_ellipses))
2256 /* We don't propagate anything from the invisible
2257 text glyph if it fails to fit. This is
2259 struct glyph_block gb;
2262 gb.glyph = Vinvisible_text_glyph;
2263 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 1,
2264 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2267 /* Set the buffer position to the end of the line. We
2268 need to do this before potentially adding a newline
2269 so that the cursor flag will get set correctly (if
2271 data.bi_bufpos = bi_next_bufpos;
2273 if (NILP (b->selective_display_ellipses)
2274 || data.bi_cursor_bufpos == bi_next_bufpos)
2276 /* We have to at least add a newline character so
2277 that the cursor shows up properly. */
2279 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2280 data.findex = DEFAULT_INDEX;
2282 data.start_col_xoffset = 0;
2283 data.bi_start_col_enabled = 0;
2285 add_emchar_rune (&data);
2288 /* This had better be a newline but doing it this way
2289 we'll see obvious incorrect results if it isn't. No
2290 need to abort here. */
2291 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2296 /* If the current character is considered to be printable, then
2298 else if (data.ch >= printable_min)
2300 *prop = add_emchar_rune (&data);
2305 /* If the current character is a tab, determine the next tab
2306 starting position and add a blank rune which extends from the
2307 current pixel position to that starting position. */
2308 else if (data.ch == '\t')
2310 int tab_start_pixpos = data.pixpos;
2315 if (data.start_col > 1)
2316 tab_start_pixpos -= (space_width (w) * (data.start_col - 1))
2317 + data.start_col_xoffset;
2320 next_tab_position (w, tab_start_pixpos,
2321 dl->bounds.left_in +
2322 data.hscroll_glyph_width_adjust);
2323 if (next_tab_start > data.max_pixpos)
2325 prop_width = next_tab_start - data.max_pixpos;
2326 next_tab_start = data.max_pixpos;
2328 data.blank_width = next_tab_start - data.pixpos;
2330 (next_tab_start - tab_start_pixpos) / space_width (w);
2332 *prop = add_blank_rune (&data, w, char_tab_width);
2334 /* add_blank_rune is only supposed to be called with
2335 sizes guaranteed to fit in the available space. */
2340 struct prop_block pb;
2341 *prop = Dynarr_new (prop_block);
2343 pb.type = PROP_BLANK;
2344 pb.data.p_blank.width = prop_width;
2345 pb.data.p_blank.findex = data.findex;
2346 Dynarr_add (*prop, pb);
2352 /* If character is a control character, pass it off to
2353 add_control_char_runes.
2355 The is_*() routines have undefined results on
2356 arguments outside of the range [-1, 255]. (This
2357 often bites people who carelessly use `char' instead
2358 of `unsigned char'.)
2360 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
2362 *prop = add_control_char_runes (&data, b);
2368 /* If the character is above the ASCII range and we have not
2369 already handled it, then print it as an octal number. */
2370 else if (data.ch >= 0200)
2372 *prop = add_octal_runes (&data);
2378 /* Assume the current character is considered to be printable,
2379 then just add it. */
2382 *prop = add_emchar_rune (&data);
2387 INC_BYTIND (b, data.bi_bufpos);
2393 /* Determine the starting point of the next line if we did not hit the
2394 end of the buffer. */
2395 if (data.bi_bufpos < BI_BUF_ZV (b)
2396 && (active_minibuffer || !NILP (synch_minibuffers_value)))
2398 /* #### This check is not correct. If the line terminated
2399 due to a begin-glyph or end-glyph hitting window-end, then
2400 data.ch will not point to the character at data.bi_bufpos. If
2401 you make the two changes mentioned at the top of this loop,
2402 you should be able to say '(if (*prop))'. That should also
2403 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
2406 /* The common case is that the line ended because we hit a newline.
2407 In that case, the next character is just the next buffer
2409 if (data.ch == '\n')
2411 /* If data.start_col_enabled is still true, then the window is
2412 scrolled far enough so that nothing on this line is visible.
2413 We need to stick a truncation glyph at the beginning of the
2414 line in that case unless the line is completely blank. */
2415 if (data.bi_start_col_enabled)
2417 if (data.cursor_type == CURSOR_ON)
2419 if (data.bi_cursor_bufpos >= bi_start_pos
2420 && data.bi_cursor_bufpos <= data.bi_bufpos)
2421 data.bi_cursor_bufpos = data.bi_bufpos;
2423 data.findex = DEFAULT_INDEX;
2425 data.bi_start_col_enabled = 0;
2427 if (data.bi_bufpos != bi_start_pos)
2429 struct glyph_block gb;
2432 gb.glyph = Vhscroll_glyph;
2433 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2434 GLYPH_CACHEL (w, HSCROLL_GLYPH_INDEX));
2438 /* This duplicates code down below to add a newline to
2439 the end of an otherwise empty line.*/
2441 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2443 add_emchar_rune (&data);
2447 INC_BYTIND (b, data.bi_bufpos);
2450 /* Otherwise we have a buffer line which cannot fit on one display
2454 struct glyph_block gb;
2455 struct glyph_cachel *cachel;
2457 /* If the line is to be truncated then we actually have to look
2458 for the next newline. We also add the end-of-line glyph which
2459 we know will fit because we adjusted the right border before
2460 we starting laying out the line. */
2461 data.max_pixpos += end_glyph_width;
2462 data.findex = DEFAULT_INDEX;
2469 /* Now find the start of the next line. */
2470 bi_pos = bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2472 /* If the cursor is past the truncation line then we
2473 make it appear on the truncation glyph. If we've hit
2474 the end of the buffer then we also make the cursor
2475 appear unless eob is immediately preceded by a
2476 newline. In that case the cursor should actually
2477 appear on the next line. */
2478 if (data.cursor_type == CURSOR_ON
2479 && data.bi_cursor_bufpos >= data.bi_bufpos
2480 && (data.bi_cursor_bufpos < bi_pos ||
2481 (bi_pos == BI_BUF_ZV (b)
2482 && (bi_pos == BI_BUF_BEGV (b)
2483 || (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_pos))
2485 data.bi_cursor_bufpos = bi_pos;
2487 data.cursor_type = NO_CURSOR;
2489 data.bi_bufpos = bi_pos;
2490 gb.glyph = Vtruncation_glyph;
2491 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
2495 /* The cursor can never be on the continuation glyph. */
2496 data.cursor_type = NO_CURSOR;
2498 /* data.bi_bufpos is already at the start of the next line. */
2500 dl->line_continuation = 1;
2501 gb.glyph = Vcontinuation_glyph;
2502 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
2505 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
2507 if (truncate_win && data.bi_bufpos == BI_BUF_ZV (b)
2508 && BI_BUF_FETCH_CHAR (b, prev_bytind (b, BI_BUF_ZV (b))) != '\n')
2509 /* #### Damn this losing shit. */
2513 else if ((active_minibuffer || !NILP (synch_minibuffers_value))
2514 && (!echo_area_active (f) || data.bi_bufpos == BI_BUF_ZV (b)))
2516 /* We need to add a marker to the end of the line since there is no
2517 newline character in order for the cursor to get drawn. We label
2518 it as a newline so that it gets handled correctly by the
2519 whitespace routines below. */
2522 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2523 data.findex = DEFAULT_INDEX;
2525 data.start_col_xoffset = 0;
2526 data.bi_start_col_enabled = 0;
2528 data.max_pixpos += data.blank_width;
2529 add_emchar_rune (&data);
2530 data.max_pixpos -= data.blank_width;
2532 /* #### urk! Chuck, this shit is bad news. Going around
2533 manipulating invalid positions is guaranteed to result in
2534 trouble sooner or later. */
2535 data.bi_bufpos = BI_BUF_ZV (b) + 1;
2538 /* Calculate left whitespace boundary. */
2542 /* Whitespace past a newline is considered right whitespace. */
2543 while (elt < Dynarr_length (db->runes))
2545 struct rune *rb = Dynarr_atp (db->runes, elt);
2547 if ((rb->type == RUNE_CHAR
2548 && EQ (rb->object.cglyph.charset, Vcharset_ascii)
2549 && rb->object.cglyph.code_point == ' ')
2550 || rb->type == RUNE_BLANK)
2552 dl->bounds.left_white += rb->width;
2556 elt = Dynarr_length (db->runes);
2560 /* Calculate right whitespace boundary. */
2562 int elt = Dynarr_length (db->runes) - 1;
2565 while (!done && elt >= 0)
2567 struct rune *rb = Dynarr_atp (db->runes, elt);
2569 if (!(rb->type == RUNE_CHAR
2570 && (EQ (rb->object.cglyph.charset, Vcharset_ascii)
2571 || EQ (rb->object.cglyph.charset, Vcharset_control_1)
2572 || EQ (rb->object.cglyph.charset, Vcharset_latin_iso8859_1))
2573 && isspace (rb->object.cglyph.code_point))
2574 && !rb->type == RUNE_BLANK)
2576 dl->bounds.right_white = rb->xpos + rb->width;
2584 /* The line is blank so everything is considered to be right
2587 dl->bounds.right_white = dl->bounds.left_in;
2590 /* Set the display blocks bounds. */
2591 db->start_pos = dl->bounds.left_in;
2592 if (Dynarr_length (db->runes))
2594 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
2596 db->end_pos = rb->xpos + rb->width;
2599 db->end_pos = dl->bounds.right_white;
2601 /* update line height parameters */
2602 if (!data.new_ascent && !data.new_descent)
2604 /* We've got a blank line so initialize these values from the default
2606 default_face_font_info (data.window, &data.new_ascent,
2607 &data.new_descent, 0, 0, 0);
2610 if (data.max_pixmap_height)
2612 int height = data.new_ascent + data.new_descent;
2613 int pix_ascent, pix_descent;
2615 pix_descent = data.max_pixmap_height * data.new_descent / height;
2616 pix_ascent = data.max_pixmap_height - pix_descent;
2618 data.new_ascent = max (data.new_ascent, pix_ascent);
2619 data.new_descent = max (data.new_descent, pix_descent);
2622 dl->ascent = data.new_ascent;
2623 dl->descent = data.new_descent;
2626 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
2628 if (dl->ascent < ascent)
2629 dl->ascent = ascent;
2632 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
2634 if (dl->descent < descent)
2635 dl->descent = descent;
2638 dl->cursor_elt = data.cursor_x;
2639 /* #### lossage lossage lossage! Fix this shit! */
2640 if (data.bi_bufpos > BI_BUF_ZV (b))
2641 dl->end_bufpos = BUF_ZV (b);
2643 dl->end_bufpos = bytind_to_bufpos (b, data.bi_bufpos) - 1;
2645 data.dl->num_chars = column_at_point (b, dl->end_bufpos, 0);
2647 /* This doesn't correctly take into account tabs and control
2648 characters but if the window isn't being truncated then this
2649 value isn't going to end up being used anyhow. */
2650 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
2652 /* #### handle horizontally scrolled line with text none of which
2653 was actually laid out. */
2655 /* #### handle any remainder of overlay arrow */
2657 if (*prop == ADD_FAILED)
2660 if (truncate_win && *prop)
2662 Dynarr_free (*prop);
2666 extent_fragment_delete (data.ef);
2668 /* #### If we started at EOB, then make sure we return a value past
2669 it so that regenerate_window will exit properly. This is bogus.
2670 The main loop should get fixed so that it isn't necessary to call
2671 this function if we are already at EOB. */
2673 if (data.bi_bufpos == BI_BUF_ZV (b) && bi_start_pos == BI_BUF_ZV (b))
2674 return data.bi_bufpos + 1; /* Yuck! */
2676 return data.bi_bufpos;
2679 /* Display the overlay arrow at the beginning of the given line. */
2682 create_overlay_glyph_block (struct window *w, struct display_line *dl)
2684 struct frame *f = XFRAME (w->frame);
2685 struct device *d = XDEVICE (f->device);
2688 /* If Voverlay_arrow_string isn't valid then just fail silently. */
2689 if (!STRINGP (Voverlay_arrow_string) && !GLYPHP (Voverlay_arrow_string))
2695 XSETWINDOW (data.window, w);
2696 data.db = get_display_block_from_line (dl, OVERWRITE);
2698 data.pixpos = dl->bounds.left_in;
2699 data.max_pixpos = dl->bounds.right_in;
2700 data.cursor_type = NO_CURSOR;
2702 data.findex = DEFAULT_INDEX;
2703 data.last_charset = Qunbound;
2704 data.last_findex = DEFAULT_INDEX;
2705 data.result_str = Qnil;
2708 Dynarr_reset (data.db->runes);
2710 if (STRINGP (Voverlay_arrow_string))
2712 add_bufbyte_string_runes
2714 XSTRING_DATA (Voverlay_arrow_string),
2715 XSTRING_LENGTH (Voverlay_arrow_string),
2718 else if (GLYPHP (Voverlay_arrow_string))
2720 struct glyph_block gb;
2722 gb.glyph = Voverlay_arrow_string;
2724 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, 0);
2727 if (data.max_pixmap_height)
2729 int height = data.new_ascent + data.new_descent;
2730 int pix_ascent, pix_descent;
2732 pix_descent = data.max_pixmap_height * data.new_descent / height;
2733 pix_ascent = data.max_pixmap_height - pix_descent;
2735 data.new_ascent = max (data.new_ascent, pix_ascent);
2736 data.new_descent = max (data.new_descent, pix_descent);
2739 dl->ascent = data.new_ascent;
2740 dl->descent = data.new_descent;
2742 data.db->start_pos = dl->bounds.left_in;
2743 data.db->end_pos = data.pixpos;
2745 return data.pixpos - dl->bounds.left_in;
2748 /* Add a type of glyph to a margin display block. */
2751 add_margin_runes (struct display_line *dl, struct display_block *db, int start,
2752 int count, enum glyph_layout layout, int side, Lisp_Object window)
2754 glyph_block_dynarr *gbd = (side == LEFT_GLYPHS
2756 : dl->right_glyphs);
2759 struct window *w = XWINDOW (window);
2760 struct frame *f = XFRAME (w->frame);
2761 struct device *d = XDEVICE (f->device);
2766 data.window = window;
2769 data.pixpos = start;
2770 data.cursor_type = NO_CURSOR;
2772 data.last_charset = Qunbound;
2773 data.last_findex = DEFAULT_INDEX;
2774 data.result_str = Qnil;
2776 data.new_ascent = dl->ascent;
2777 data.new_descent = dl->descent;
2779 if ((layout == GL_WHITESPACE && side == LEFT_GLYPHS)
2780 || (layout == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS))
2783 elt = Dynarr_length (gbd) - 1;
2790 end = Dynarr_length (gbd);
2793 while (count && ((!reverse && elt < end) || (reverse && elt >= end)))
2795 struct glyph_block *gb = Dynarr_atp (gbd, elt);
2797 if (NILP (gb->extent))
2798 abort (); /* these should have been handled in add_glyph_rune */
2801 ((side == LEFT_GLYPHS &&
2802 extent_begin_glyph_layout (XEXTENT (gb->extent)) == layout)
2803 || (side == RIGHT_GLYPHS &&
2804 extent_end_glyph_layout (XEXTENT (gb->extent)) == layout)))
2806 data.findex = gb->findex;
2807 data.max_pixpos = data.pixpos + gb->width;
2808 add_glyph_rune (&data, gb, side, 0, NULL);
2813 (reverse ? elt-- : elt++);
2816 if (data.max_pixmap_height)
2818 int height = data.new_ascent + data.new_descent;
2819 int pix_ascent, pix_descent;
2821 pix_descent = data.max_pixmap_height * data.new_descent / height;
2822 pix_ascent = data.max_pixmap_height - pix_descent;
2823 data.new_ascent = max (data.new_ascent, pix_ascent);
2824 data.new_descent = max (data.new_descent, pix_descent);
2827 dl->ascent = data.new_ascent;
2828 dl->descent = data.new_descent;
2833 /* Add a blank to a margin display block. */
2836 add_margin_blank (struct display_line *dl, struct display_block *db,
2837 struct window *w, int xpos, int width, int side)
2841 rb.findex = (side == LEFT_GLYPHS
2842 ? get_builtin_face_cache_index (w, Vleft_margin_face)
2843 : get_builtin_face_cache_index (w, Vright_margin_face));
2848 rb.type = RUNE_BLANK;
2849 rb.cursor_type = CURSOR_OFF;
2851 Dynarr_add (db->runes, rb);
2854 /* Display glyphs in the left outside margin, left inside margin and
2855 left whitespace area. */
2858 create_left_glyph_block (struct window *w, struct display_line *dl,
2863 int use_overflow = (NILP (w->use_left_overflow) ? 0 : 1);
2865 int out_end, in_out_start, in_in_end, white_out_start, white_in_start;
2866 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
2867 int left_in_start = dl->bounds.left_in;
2868 int left_in_end = dl->bounds.left_in + overlay_width;
2870 struct display_block *odb, *idb;
2872 XSETWINDOW (window, w);
2874 /* We have to add the glyphs to the line in the order outside,
2875 inside, whitespace. However the precedence dictates that we
2876 determine how many will fit in the reverse order. */
2878 /* Determine how many whitespace glyphs we can display and where
2879 they should start. */
2880 white_in_start = dl->bounds.left_white;
2881 white_out_start = left_in_start;
2882 white_out_cnt = white_in_cnt = 0;
2885 while (elt < Dynarr_length (dl->left_glyphs))
2887 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2889 if (NILP (gb->extent))
2890 abort (); /* these should have been handled in add_glyph_rune */
2892 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
2896 width = glyph_width (gb->glyph, window);
2898 if (white_in_start - width >= left_in_end)
2901 white_in_start -= width;
2905 else if (use_overflow
2906 && (white_out_start - width > dl->bounds.left_out))
2909 white_out_start -= width;
2920 /* Determine how many inside margin glyphs we can display and where
2921 they should start. The inside margin glyphs get whatever space
2922 is left after the whitespace glyphs have been displayed. These
2923 are tricky to calculate since if we decide to use the overflow
2924 area we basically have to start over. So for these we build up a
2925 list of just the inside margin glyphs and manipulate it to
2926 determine the needed info. */
2928 glyph_block_dynarr *ib;
2929 int avail_in, avail_out;
2932 int used_in, used_out;
2935 used_in = used_out = 0;
2936 ib = Dynarr_new (glyph_block);
2937 while (elt < Dynarr_length (dl->left_glyphs))
2939 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2941 if (NILP (gb->extent))
2942 abort (); /* these should have been handled in add_glyph_rune */
2944 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
2947 gb->width = glyph_width (gb->glyph, window);
2948 used_in += gb->width;
2949 Dynarr_add (ib, *gb);
2959 avail_in = white_in_start - left_in_end;
2967 avail_out = white_out_start - dl->bounds.left_out;
2970 while (!done && marker < Dynarr_length (ib))
2972 int width = Dynarr_atp (ib, marker)->width;
2974 /* If everything now fits in the available inside margin
2975 space, we're done. */
2976 if (used_in <= avail_in)
2980 /* Otherwise see if we have room to move a glyph to the
2982 if (used_out + width <= avail_out)
2995 /* At this point we now know that everything from marker on goes in
2996 the inside margin and everything before it goes in the outside
2997 margin. The stuff going into the outside margin is guaranteed
2998 to fit, but we may have to trim some stuff from the inside. */
3000 in_in_end = left_in_end;
3001 in_out_start = white_out_start;
3002 in_out_cnt = in_in_cnt = 0;
3006 while (elt < Dynarr_length (dl->left_glyphs))
3008 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3010 if (NILP (gb->extent))
3011 abort (); /* these should have been handled in add_glyph_rune */
3013 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3016 int width = glyph_width (gb->glyph, window);
3021 in_out_start -= width;
3026 else if (in_in_end + width < white_in_start)
3041 /* Determine how many outside margin glyphs we can display. They
3042 always start at the left outside margin and can only use the
3043 outside margin space. */
3044 out_end = dl->bounds.left_out;
3048 while (elt < Dynarr_length (dl->left_glyphs))
3050 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3052 if (NILP (gb->extent))
3053 abort (); /* these should have been handled in add_glyph_rune */
3055 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3058 int width = glyph_width (gb->glyph, window);
3060 if (out_end + width <= in_out_start)
3074 /* Now that we know where everything goes, we add the glyphs as
3075 runes to the appropriate display blocks. */
3076 if (out_cnt || in_out_cnt || white_out_cnt)
3078 odb = get_display_block_from_line (dl, LEFT_OUTSIDE_MARGIN);
3079 odb->start_pos = dl->bounds.left_out;
3080 /* #### We should stop adding a blank to account for the space
3081 between the end of the glyphs and the margin and instead set
3082 this accordingly. */
3083 odb->end_pos = dl->bounds.left_in;
3084 Dynarr_reset (odb->runes);
3089 if (in_in_cnt || white_in_cnt)
3091 idb = get_display_block_from_line (dl, LEFT_INSIDE_MARGIN);
3092 idb->start_pos = dl->bounds.left_in;
3093 /* #### See above comment for odb->end_pos */
3094 idb->end_pos = dl->bounds.left_white;
3095 Dynarr_reset (idb->runes);
3100 /* First add the outside margin glyphs. */
3102 end_xpos = add_margin_runes (dl, odb, dl->bounds.left_out, out_cnt,
3103 GL_OUTSIDE_MARGIN, LEFT_GLYPHS, window);
3105 end_xpos = dl->bounds.left_out;
3107 /* There may be blank space between the outside margin glyphs and
3108 the inside margin glyphs. If so, add a blank. */
3109 if (in_out_cnt && (in_out_start - end_xpos))
3111 add_margin_blank (dl, odb, w, end_xpos, in_out_start - end_xpos,
3115 /* Next add the inside margin glyphs which are actually in the
3119 end_xpos = add_margin_runes (dl, odb, in_out_start, in_out_cnt,
3120 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3123 /* If we didn't add any inside margin glyphs to the outside margin,
3124 but are adding whitespace glyphs, then we need to add a blank
3126 if (!in_out_cnt && white_out_cnt && (white_out_start - end_xpos))
3128 add_margin_blank (dl, odb, w, end_xpos, white_out_start - end_xpos,
3132 /* Next add the whitespace margin glyphs which are actually in the
3136 end_xpos = add_margin_runes (dl, odb, white_out_start, white_out_cnt,
3137 GL_WHITESPACE, LEFT_GLYPHS, window);
3140 /* We take care of clearing between the end of the glyphs and the
3141 start of the inside margin for lines which have glyphs. */
3142 if (odb && (left_in_start - end_xpos))
3144 add_margin_blank (dl, odb, w, end_xpos, left_in_start - end_xpos,
3148 /* Next add the inside margin glyphs which are actually in the
3152 end_xpos = add_margin_runes (dl, idb, left_in_end, in_in_cnt,
3153 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3156 end_xpos = left_in_end;
3158 /* Make sure that the area between the end of the inside margin
3159 glyphs and the whitespace glyphs is cleared. */
3160 if (idb && (white_in_start - end_xpos > 0))
3162 add_margin_blank (dl, idb, w, end_xpos, white_in_start - end_xpos,
3166 /* Next add the whitespace margin glyphs which are actually in the
3170 add_margin_runes (dl, idb, white_in_start, white_in_cnt, GL_WHITESPACE,
3171 LEFT_GLYPHS, window);
3174 /* Whitespace glyphs always end right next to the text block so
3175 there is nothing we have to make sure is cleared after them. */
3178 /* Display glyphs in the right outside margin, right inside margin and
3179 right whitespace area. */
3182 create_right_glyph_block (struct window *w, struct display_line *dl)
3186 int use_overflow = (NILP (w->use_right_overflow) ? 0 : 1);
3188 int out_start, in_out_end, in_in_start, white_out_end, white_in_end;
3189 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
3191 struct display_block *odb, *idb;
3193 XSETWINDOW (window, w);
3195 /* We have to add the glyphs to the line in the order outside,
3196 inside, whitespace. However the precedence dictates that we
3197 determine how many will fit in the reverse order. */
3199 /* Determine how many whitespace glyphs we can display and where
3200 they should start. */
3201 white_in_end = dl->bounds.right_white;
3202 white_out_end = dl->bounds.right_in;
3203 white_out_cnt = white_in_cnt = 0;
3206 while (elt < Dynarr_length (dl->right_glyphs))
3208 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3210 if (NILP (gb->extent))
3211 abort (); /* these should have been handled in add_glyph_rune */
3213 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
3215 int width = glyph_width (gb->glyph, window);
3217 if (white_in_end + width <= dl->bounds.right_in)
3220 white_in_end += width;
3224 else if (use_overflow
3225 && (white_out_end + width <= dl->bounds.right_out))
3228 white_out_end += width;
3239 /* Determine how many inside margin glyphs we can display and where
3240 they should start. The inside margin glyphs get whatever space
3241 is left after the whitespace glyphs have been displayed. These
3242 are tricky to calculate since if we decide to use the overflow
3243 area we basically have to start over. So for these we build up a
3244 list of just the inside margin glyphs and manipulate it to
3245 determine the needed info. */
3247 glyph_block_dynarr *ib;
3248 int avail_in, avail_out;
3251 int used_in, used_out;
3254 used_in = used_out = 0;
3255 ib = Dynarr_new (glyph_block);
3256 while (elt < Dynarr_length (dl->right_glyphs))
3258 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3260 if (NILP (gb->extent))
3261 abort (); /* these should have been handled in add_glyph_rune */
3263 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3265 gb->width = glyph_width (gb->glyph, window);
3266 used_in += gb->width;
3267 Dynarr_add (ib, *gb);
3276 avail_in = dl->bounds.right_in - white_in_end;
3281 avail_out = dl->bounds.right_out - white_out_end;
3284 while (!done && marker < Dynarr_length (ib))
3286 int width = Dynarr_atp (ib, marker)->width;
3288 /* If everything now fits in the available inside margin
3289 space, we're done. */
3290 if (used_in <= avail_in)
3294 /* Otherwise see if we have room to move a glyph to the
3296 if (used_out + width <= avail_out)
3309 /* At this point we now know that everything from marker on goes in
3310 the inside margin and everything before it goes in the outside
3311 margin. The stuff going into the outside margin is guaranteed
3312 to fit, but we may have to trim some stuff from the inside. */
3314 in_in_start = dl->bounds.right_in;
3315 in_out_end = dl->bounds.right_in;
3316 in_out_cnt = in_in_cnt = 0;
3320 while (elt < Dynarr_length (dl->right_glyphs))
3322 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3324 if (NILP (gb->extent))
3325 abort (); /* these should have been handled in add_glyph_rune */
3327 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3329 int width = glyph_width (gb->glyph, window);
3334 in_out_end += width;
3339 else if (in_in_start - width >= white_in_end)
3342 in_in_start -= width;
3354 /* Determine how many outside margin glyphs we can display. They
3355 always start at the right outside margin and can only use the
3356 outside margin space. */
3357 out_start = dl->bounds.right_out;
3361 while (elt < Dynarr_length (dl->right_glyphs))
3363 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3365 if (NILP (gb->extent))
3366 abort (); /* these should have been handled in add_glyph_rune */
3368 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_OUTSIDE_MARGIN)
3370 int width = glyph_width (gb->glyph, window);
3372 if (out_start - width >= in_out_end)
3386 /* Now that we now where everything goes, we add the glyphs as runes
3387 to the appropriate display blocks. */
3388 if (out_cnt || in_out_cnt || white_out_cnt)
3390 odb = get_display_block_from_line (dl, RIGHT_OUTSIDE_MARGIN);
3391 /* #### See comments before odb->start_pos init in
3392 create_left_glyph_block */
3393 odb->start_pos = dl->bounds.right_in;
3394 odb->end_pos = dl->bounds.right_out;
3395 Dynarr_reset (odb->runes);
3400 if (in_in_cnt || white_in_cnt)
3402 idb = get_display_block_from_line (dl, RIGHT_INSIDE_MARGIN);
3403 idb->start_pos = dl->bounds.right_white;
3404 /* #### See comments before odb->start_pos init in
3405 create_left_glyph_block */
3406 idb->end_pos = dl->bounds.right_in;
3407 Dynarr_reset (idb->runes);
3412 /* First add the whitespace margin glyphs which are actually in the
3416 end_xpos = add_margin_runes (dl, idb, dl->bounds.right_white,
3417 white_in_cnt, GL_WHITESPACE, RIGHT_GLYPHS,
3421 end_xpos = dl->bounds.right_white;
3423 /* Make sure that the area between the end of the whitespace glyphs
3424 and the inside margin glyphs is cleared. */
3425 if (in_in_cnt && (in_in_start - end_xpos))
3427 add_margin_blank (dl, idb, w, end_xpos, in_in_start - end_xpos,
3431 /* Next add the inside margin glyphs which are actually in the
3435 end_xpos = add_margin_runes (dl, idb, in_in_start, in_in_cnt,
3436 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3439 /* If we didn't add any inside margin glyphs then make sure the rest
3440 of the inside margin area gets cleared. */
3441 if (idb && (dl->bounds.right_in - end_xpos))
3443 add_margin_blank (dl, idb, w, end_xpos, dl->bounds.right_in - end_xpos,
3447 /* Next add any whitespace glyphs in the outside margin. */
3450 end_xpos = add_margin_runes (dl, odb, dl->bounds.right_in, white_out_cnt,
3451 GL_WHITESPACE, RIGHT_GLYPHS, window);
3454 end_xpos = dl->bounds.right_in;
3456 /* Next add any inside margin glyphs in the outside margin. */
3459 end_xpos = add_margin_runes (dl, odb, end_xpos, in_out_cnt,
3460 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3463 /* There may be space between any whitespace or inside margin glyphs
3464 in the outside margin and the actual outside margin glyphs. */
3465 if (odb && (out_start - end_xpos))
3467 add_margin_blank (dl, odb, w, end_xpos, out_start - end_xpos,
3471 /* Finally, add the outside margin glyphs. */
3474 add_margin_runes (dl, odb, out_start, out_cnt, GL_OUTSIDE_MARGIN,
3475 RIGHT_GLYPHS, window);
3480 /***************************************************************************/
3482 /* modeline routines */
3484 /***************************************************************************/
3486 /* This function is also used in frame.c by `generate_title_string' */
3488 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str,
3489 struct window *w, struct display_line *dl,
3490 struct display_block *db, face_index findex,
3491 int min_pixpos, int max_pixpos, int type)
3493 struct frame *f = XFRAME (w->frame);
3494 struct device *d = XDEVICE (f->device);
3498 Charcount offset = 0;
3504 data.findex = findex;
3505 data.pixpos = min_pixpos;
3506 data.max_pixpos = max_pixpos;
3507 data.cursor_type = NO_CURSOR;
3508 data.last_charset = Qunbound;
3509 data.last_findex = DEFAULT_INDEX;
3510 data.result_str = result_str;
3511 data.is_modeline = 1;
3513 XSETWINDOW (data.window, w);
3515 Dynarr_reset (formatted_string_extent_dynarr);
3516 Dynarr_reset (formatted_string_extent_start_dynarr);
3517 Dynarr_reset (formatted_string_extent_end_dynarr);
3519 /* result_str is nil when we're building a frame or icon title. Otherwise,
3520 we're building a modeline, so the offset starts at the modeline
3521 horizontal scrolling ammount */
3522 if (! NILP (result_str))
3523 offset = w->modeline_hscroll;
3524 generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0,
3525 max_pixpos - min_pixpos, findex, type, &offset,
3528 if (Dynarr_length (db->runes))
3531 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
3532 c_pixpos = rb->xpos + rb->width;
3535 c_pixpos = min_pixpos;
3537 /* If we don't reach the right side of the window, add a blank rune
3538 to make up the difference. This usually only occurs if the
3539 modeline face is using a proportional width font or a fixed width
3540 font of a different size from the default face font. */
3542 if (c_pixpos < max_pixpos)
3544 data.pixpos = c_pixpos;
3545 data.blank_width = max_pixpos - data.pixpos;
3547 add_blank_rune (&data, NULL, 0);
3550 /* Now create the result string and frob the extents into it. */
3551 if (!NILP (result_str))
3556 struct buffer *buf = XBUFFER (WINDOW_BUFFER (w));
3558 in_modeline_generation = 1;
3560 detach_all_extents (result_str);
3561 resize_string (XSTRING (result_str), -1,
3562 data.bytepos - XSTRING_LENGTH (result_str));
3564 strdata = XSTRING_DATA (result_str);
3566 for (elt = 0, len = 0; elt < Dynarr_length (db->runes); elt++)
3568 if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR)
3570 Charc ec = Dynarr_atp (db->runes, elt)->object.cglyph;
3572 len += (set_charptr_emchar (strdata + len,
3573 DECODE_CHAR (ec.charset,
3578 for (elt = 0; elt < Dynarr_length (formatted_string_extent_dynarr);
3581 Lisp_Object extent = Qnil;
3584 XSETEXTENT (extent, Dynarr_at (formatted_string_extent_dynarr, elt));
3585 child = Fgethash (extent, buf->modeline_extent_table, Qnil);
3588 child = Fmake_extent (Qnil, Qnil, result_str);
3589 Fputhash (extent, child, buf->modeline_extent_table);
3591 Fset_extent_parent (child, extent);
3592 set_extent_endpoints
3594 Dynarr_at (formatted_string_extent_start_dynarr, elt),
3595 Dynarr_at (formatted_string_extent_end_dynarr, elt),
3599 in_modeline_generation = 0;
3603 /* Ensure that the given display line DL accurately represents the
3604 modeline for the given window. */
3606 generate_modeline (struct window *w, struct display_line *dl, int type)
3608 struct buffer *b = XBUFFER (w->buffer);
3609 struct frame *f = XFRAME (w->frame);
3610 struct device *d = XDEVICE (f->device);
3612 /* Unlike display line and rune pointers, this one can't change underneath
3614 struct display_block *db = get_display_block_from_line (dl, TEXT);
3615 int max_pixpos, min_pixpos, ypos_adj;
3616 Lisp_Object font_inst;
3618 /* This will actually determine incorrect inside boundaries for the
3619 modeline since it ignores the margins. However being aware of this fact
3620 we never use those values anywhere so it doesn't matter. */
3621 dl->bounds = calculate_display_line_boundaries (w, 1);
3623 /* We are generating a modeline. */
3625 dl->cursor_elt = -1;
3627 /* Reset the runes on the modeline. */
3628 Dynarr_reset (db->runes);
3630 if (!WINDOW_HAS_MODELINE_P (w))
3634 /* If there is a horizontal scrollbar, don't add anything. */
3635 if (window_scrollbar_height (w))
3638 dl->ascent = DEVMETH (d, divider_height, ());
3640 /* The modeline is at the bottom of the gutters. */
3641 dl->ypos = WINDOW_BOTTOM (w);
3643 rb.findex = MODELINE_INDEX;
3644 rb.xpos = dl->bounds.left_out;
3645 rb.width = dl->bounds.right_out - dl->bounds.left_out;
3648 rb.type = RUNE_HLINE;
3649 rb.object.hline.thickness = 1;
3650 rb.object.hline.yoffset = 0;
3651 rb.cursor_type = NO_CURSOR;
3653 if (!EQ (Qzero, w->modeline_shadow_thickness)
3656 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3658 dl->ypos -= shadow_thickness;
3659 rb.xpos += shadow_thickness;
3660 rb.width -= 2 * shadow_thickness;
3663 Dynarr_add (db->runes, rb);
3667 /* !!#### not right; needs to compute the max height of
3669 font_inst = WINDOW_FACE_CACHEL_FONT (w, MODELINE_INDEX, Vcharset_ascii);
3671 dl->ascent = XFONT_INSTANCE (font_inst)->ascent;
3672 dl->descent = XFONT_INSTANCE (font_inst)->descent;
3674 min_pixpos = dl->bounds.left_out;
3675 max_pixpos = dl->bounds.right_out;
3677 if (!EQ (Qzero, w->modeline_shadow_thickness) && FRAME_WIN_P (f))
3679 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3681 ypos_adj = shadow_thickness;
3682 min_pixpos += shadow_thickness;
3683 max_pixpos -= shadow_thickness;
3688 generate_formatted_string_db (b->modeline_format,
3689 b->generated_modeline_string, w, dl, db,
3690 MODELINE_INDEX, min_pixpos, max_pixpos, type);
3692 /* The modeline is at the bottom of the gutters. We have to wait to
3693 set this until we've generated the modeline in order to account
3694 for any embedded faces. */
3695 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj;
3699 add_string_to_fstring_db_runes (pos_data *data, const Bufbyte *str,
3700 Charcount pos, Charcount min_pos, Charcount max_pos)
3702 /* This function has been Mule-ized. */
3704 const Bufbyte *cur_pos = str;
3705 struct display_block *db = data->db;
3707 data->blank_width = space_width (XWINDOW (data->window));
3708 while (Dynarr_length (db->runes) < pos)
3709 add_blank_rune (data, NULL, 0);
3711 end = (Dynarr_length (db->runes) +
3712 bytecount_to_charcount (str, strlen ((const char *) str)));
3714 end = min (max_pos, end);
3716 while (pos < end && *cur_pos)
3718 const Bufbyte *old_cur_pos = cur_pos;
3721 data->ch = charptr_emchar (cur_pos);
3722 succeeded = (add_emchar_rune (data) != ADD_FAILED);
3723 INC_CHARPTR (cur_pos);
3727 data->modeline_charpos++;
3728 data->bytepos += cur_pos - old_cur_pos;
3732 while (Dynarr_length (db->runes) < min_pos &&
3733 (data->pixpos + data->blank_width <= data->max_pixpos))
3734 add_blank_rune (data, NULL, 0);
3736 return Dynarr_length (db->runes);
3739 /* #### Urk! Should also handle begin-glyphs and end-glyphs in
3740 modeline extents. */
3742 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph,
3743 Charcount pos, Charcount min_pos,
3744 Charcount max_pos, Lisp_Object extent)
3746 /* This function has been Mule-ized. */
3748 struct display_block *db = data->db;
3749 struct glyph_block gb;
3751 data->blank_width = space_width (XWINDOW (data->window));
3752 while (Dynarr_length (db->runes) < pos)
3753 add_blank_rune (data, NULL, 0);
3755 end = Dynarr_length (db->runes) + 1;
3757 end = min (max_pos, end);
3761 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
3764 while (Dynarr_length (db->runes) < pos &&
3765 (data->pixpos + data->blank_width <= data->max_pixpos))
3766 add_blank_rune (data, NULL, 0);
3768 return Dynarr_length (db->runes);
3771 /* If max_pos is == -1, it is considered to be infinite. The same is
3772 true of max_pixsize. */
3773 #define SET_CURRENT_MODE_CHARS_PIXSIZE \
3774 if (Dynarr_length (data->db->runes)) \
3775 cur_pixsize = data->pixpos - Dynarr_atp (data->db->runes, 0)->xpos; \
3779 /* Note that this function does "positions" in terms of characters and
3780 not in terms of columns. This is necessary to make the formatting
3781 work correctly when proportional width fonts are used in the
3784 generate_fstring_runes (struct window *w, pos_data *data, Charcount pos,
3785 Charcount min_pos, Charcount max_pos,
3786 Lisp_Object elt, int depth, int max_pixsize,
3787 face_index findex, int type, Charcount *offset,
3788 Lisp_Object cur_ext)
3790 /* This function has been Mule-ized. */
3791 /* #### The other losing things in this function are:
3793 -- C zero-terminated-string lossage.
3794 -- Non-printable characters should be converted into something
3795 appropriate (e.g. ^F) instead of blindly being printed anyway.
3806 /* A string. Add to the display line and check for %-constructs
3809 Bufbyte *this = XSTRING_DATA (elt);
3811 while ((pos < max_pos || max_pos == -1) && *this)
3813 Bufbyte *last = this;
3815 while (*this && *this != '%')
3820 /* No %-construct */
3822 bytecount_to_charcount (last, this - last);
3824 if (size <= *offset)
3828 Charcount tmp_max = (max_pos == -1 ? pos + size - *offset :
3829 min (pos + size - *offset, max_pos));
3830 const Bufbyte *tmp_last = charptr_n_addr (last, *offset);
3832 pos = add_string_to_fstring_db_runes (data, tmp_last,
3837 else /* *this == '%' */
3839 Charcount spec_width = 0;
3841 this++; /* skip over '%' */
3843 /* We can't allow -ve args due to the "%-" construct.
3844 * Argument specifies minwidth but not maxwidth
3845 * (maxwidth can be specified by
3846 * (<negative-number> . <stuff>) modeline elements)
3848 while (isdigit (*this))
3850 spec_width = spec_width * 10 + (*this - '0');
3857 pos = generate_fstring_runes (w, data, pos, spec_width,
3858 max_pos, Vglobal_mode_string,
3859 depth, max_pixsize, findex,
3860 type, offset, cur_ext);
3862 else if (*this == '-')
3864 Charcount num_to_add;
3866 if (max_pixsize < 0)
3868 else if (max_pos != -1)
3869 num_to_add = max_pos - pos;
3875 SET_CURRENT_MODE_CHARS_PIXSIZE;
3878 redisplay_text_width_string (w, findex, &ch, Qnil, 0,
3881 num_to_add = (max_pixsize - cur_pixsize) / dash_pixsize;
3885 while (num_to_add--)
3886 pos = add_string_to_fstring_db_runes
3887 (data, (const Bufbyte *) "-", pos, pos, max_pos);
3889 else if (*this != 0)
3891 Emchar ch = charptr_emchar (this);
3895 decode_mode_spec (w, ch, type);
3897 str = Dynarr_atp (mode_spec_bufbyte_string, 0);
3898 size = bytecount_to_charcount
3899 /* Skip the null character added by `decode_mode_spec' */
3900 (str, Dynarr_length (mode_spec_bufbyte_string)) - 1;
3902 if (size <= *offset)
3906 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3908 /* #### NOTE: I don't understand why a tmp_max is not
3909 computed and used here as in the plain string case
3911 pos = add_string_to_fstring_db_runes (data, tmp_str,
3918 /* NOT this++. There could be any sort of character at
3919 the current position. */
3923 if (max_pixsize > 0)
3926 SET_CURRENT_MODE_CHARS_PIXSIZE;
3928 if (cur_pixsize >= max_pixsize)
3933 else if (SYMBOLP (elt))
3935 /* A symbol: process the value of the symbol recursively
3936 as if it appeared here directly. */
3937 Lisp_Object tem = symbol_value_in_buffer (elt, w->buffer);
3939 if (!UNBOUNDP (tem))
3941 /* If value is a string, output that string literally:
3942 don't check for % within it. */
3945 Bufbyte *str = XSTRING_DATA (tem);
3946 Charcount size = XSTRING_CHAR_LENGTH (tem);
3948 if (size <= *offset)
3952 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3954 /* #### NOTE: I don't understand why a tmp_max is not
3955 computed and used here as in the plain string case
3957 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
3962 /* Give up right away for nil or t. */
3963 else if (!EQ (tem, elt))
3970 else if (GENERIC_SPECIFIERP (elt))
3972 Lisp_Object window, tem;
3973 XSETWINDOW (window, w);
3974 tem = specifier_instance_no_quit (elt, Qunbound, window,
3975 ERROR_ME_NOT, 0, Qzero);
3976 if (!UNBOUNDP (tem))
3982 else if (CONSP (elt))
3984 /* A cons cell: four distinct cases.
3985 * - If first element is a string or a cons, process all the elements
3986 * and effectively concatenate them.
3987 * - If first element is a negative number, truncate displaying cdr to
3988 * at most that many characters. If positive, pad (with spaces)
3989 * to at least that many characters.
3990 * - If first element is another symbol, process the cadr or caddr
3991 * recursively according to whether the symbol's value is non-nil or
3993 * - If first element is an extent, process the cdr recursively
3994 * and handle the extent's face.
3997 Lisp_Object car, tem;
4006 tem = symbol_value_in_buffer (car, w->buffer);
4007 /* elt is now the cdr, and we know it is a cons cell.
4008 Use its car if CAR has a non-nil value. */
4009 if (!UNBOUNDP (tem))
4017 /* Symbol's value is nil (or symbol is unbound)
4018 * Get the cddr of the original list
4019 * and if possible find the caddr and use that.
4024 else if (!CONSP (elt))
4032 else if (INTP (car))
4034 Charcount lim = XINT (car);
4040 /* Negative int means reduce maximum width.
4041 * DO NOT change MIN_PIXPOS here!
4042 * (20 -10 . foo) should truncate foo to 10 col
4043 * and then pad to 20.
4046 max_pos = pos - lim;
4048 max_pos = min (max_pos, pos - lim);
4052 /* Padding specified. Don't let it be more than
4056 if (max_pos != -1 && lim > max_pos)
4058 /* If that's more padding than already wanted, queue it.
4059 * But don't reduce padding already specified even if
4060 * that is beyond the current truncation point.
4067 else if (STRINGP (car) || CONSP (car))
4071 /* LIMIT is to protect against circular lists. */
4072 while (CONSP (elt) && --limit > 0
4073 && (pos < max_pos || max_pos == -1))
4075 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4076 XCAR (elt), depth, max_pixsize,
4077 findex, type, offset, cur_ext);
4081 else if (EXTENTP (car))
4083 struct extent *ext = XEXTENT (car);
4085 if (EXTENT_LIVE_P (ext))
4087 face_index old_findex = data->findex;
4089 Lisp_Object font_inst;
4090 face_index new_findex;
4091 Bytecount start = data->bytepos;
4093 face = extent_face (ext);
4096 /* #### needs to merge faces, sigh */
4097 /* #### needs to handle list of faces */
4098 new_findex = get_builtin_face_cache_index (w, face);
4099 /* !!#### not right; needs to compute the max height of
4101 font_inst = WINDOW_FACE_CACHEL_FONT (w, new_findex,
4104 data->dl->ascent = max (data->dl->ascent,
4105 XFONT_INSTANCE (font_inst)->ascent);
4106 data->dl->descent = max (data->dl->descent,
4107 XFONT_INSTANCE (font_inst)->
4111 new_findex = old_findex;
4113 data->findex = new_findex;
4114 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4115 XCDR (elt), depth - 1,
4116 max_pixsize, new_findex, type,
4118 data->findex = old_findex;
4119 Dynarr_add (formatted_string_extent_dynarr, ext);
4120 Dynarr_add (formatted_string_extent_start_dynarr, start);
4121 Dynarr_add (formatted_string_extent_end_dynarr, data->bytepos);
4125 else if (GLYPHP (elt))
4127 /* Glyphs are considered as one character with respect to the modeline
4128 horizontal scrolling facility. -- dv */
4132 pos = add_glyph_to_fstring_db_runes (data, elt, pos, pos, max_pos,
4139 char *str = GETTEXT ("*invalid*");
4140 Charcount size = (Charcount) strlen (str); /* is this ok ?? -- dv */
4142 if (size <= *offset)
4146 const Bufbyte *tmp_str =
4147 charptr_n_addr ((const Bufbyte *) str, *offset);
4149 /* #### NOTE: I don't understand why a tmp_max is not computed and
4150 used here as in the plain string case above. -- dv */
4151 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
4160 add_string_to_fstring_db_runes (data, (const Bufbyte *) "", pos,
4167 /* Update just the modeline. Assumes the desired display structs. If
4168 they do not have a modeline block, it does nothing. */
4170 regenerate_modeline (struct window *w)
4172 display_line_dynarr *dla = window_display_lines (w, DESIRED_DISP);
4174 if (!Dynarr_length (dla) || !Dynarr_atp (dla, 0)->modeline)
4178 generate_modeline (w, Dynarr_atp (dla, 0), DESIRED_DISP);
4179 redisplay_update_line (w, 0, 0, 0);
4183 /* Make sure that modeline display line is present in the given
4184 display structs if the window has a modeline and update that
4185 line. Returns true if a modeline was needed. */
4187 ensure_modeline_generated (struct window *w, int type)
4191 /* minibuffer windows don't have modelines */
4192 if (MINI_WINDOW_P (w))
4194 /* windows which haven't had it turned off do */
4195 else if (WINDOW_HAS_MODELINE_P (w))
4197 /* windows which have it turned off don't have a divider if there is
4198 a horizontal scrollbar */
4199 else if (window_scrollbar_height (w))
4201 /* and in this case there is none */
4207 display_line_dynarr *dla;
4209 dla = window_display_lines (w, type);
4211 /* We don't care if there is a display line which is not
4212 currently a modeline because it is definitely going to become
4213 one if we have gotten to this point. */
4214 if (Dynarr_length (dla) == 0)
4216 if (Dynarr_largest (dla) > 0)
4218 struct display_line *mlp = Dynarr_atp (dla, 0);
4219 Dynarr_add (dla, *mlp);
4223 struct display_line modeline;
4225 Dynarr_add (dla, modeline);
4229 /* If we're adding a new place marker go ahead and generate the
4230 modeline so that it is available for use by
4231 window_modeline_height. */
4232 generate_modeline (w, Dynarr_atp (dla, 0), type);
4235 return need_modeline;
4238 /* #### Kludge or not a kludge. I tend towards the former. */
4240 real_current_modeline_height (struct window *w)
4242 Fset_marker (w->start[CMOTION_DISP], w->start[CURRENT_DISP], w->buffer);
4243 Fset_marker (w->pointm[CMOTION_DISP], w->pointm[CURRENT_DISP], w->buffer);
4245 if (ensure_modeline_generated (w, CMOTION_DISP))
4247 display_line_dynarr *dla = window_display_lines (w, CMOTION_DISP);
4249 if (Dynarr_length (dla))
4251 if (Dynarr_atp (dla, 0)->modeline)
4252 return (Dynarr_atp (dla, 0)->ascent +
4253 Dynarr_atp (dla, 0)->descent);
4260 /***************************************************************************/
4262 /* displayable string routines */
4264 /***************************************************************************/
4266 /* Given a position for a string in a window, ensure that the given
4267 display line DL accurately represents the text on a line starting
4268 at the given position.
4270 Yes, this is duplicating the code of create_text_block, but it
4271 looked just too hard to change create_text_block to handle strings
4272 *and* buffers. We already make a distinction between the two
4273 elsewhere in the code so I think unifying them would require a
4274 complete MULE rewrite. Besides, the other distinction is that these
4275 functions cover text that the user *cannot edit* so we can remove
4276 everything to do with cursors, minibuffers etc. Eventually the
4277 modeline routines should be modified to use this code as it copes
4278 with many more types of display situation. */
4281 create_string_text_block (struct window *w, Lisp_Object disp_string,
4282 struct display_line *dl,
4284 prop_block_dynarr **prop,
4285 face_index default_face)
4287 struct frame *f = XFRAME (w->frame);
4288 /* Note that a lot of the buffer controlled stuff has been left in
4289 because you might well want to make use of it (selective display
4290 etc), its just the buffer text that we do not use. However, it
4291 seems to be possible for buffer to be nil sometimes so protect
4292 against this case. */
4293 struct buffer *b = BUFFERP (w->buffer) ? XBUFFER (w->buffer) : 0;
4294 struct device *d = XDEVICE (f->device);
4295 Lisp_String* s = XSTRING (disp_string);
4297 /* we're working with these a lot so precalculate them */
4298 Bytecount slen = XSTRING_LENGTH (disp_string);
4299 Bytecount bi_string_zv = slen;
4300 Bytind bi_start_pos = charcount_to_bytecount (string_data (s), start_pos);
4304 int truncate_win = b ? window_truncation_on (w) : 0;
4305 int end_glyph_width = 0;
4307 /* we're going to ditch selective display for static text, its an
4308 FSF thing and invisble extents are the way to go
4309 here. Implementing it also relies on a number of buffer-specific
4310 functions that we don't have the luxury of being able to use
4313 /* The variable ctl-arrow allows the user to specify what characters
4314 can actually be displayed and which octal should be used for.
4315 #### This variable should probably have some rethought done to
4318 #### It would also be really nice if you could specify that
4319 the characters come out in hex instead of in octal. Mule
4320 does that by adding a ctl-hexa variable similar to ctl-arrow,
4321 but that's bogus -- we need a more general solution. I
4322 think you need to extend the concept of display tables
4323 into a more general conversion mechanism. Ideally you
4324 could specify a Lisp function that converts characters,
4325 but this violates the Second Golden Rule and besides would
4326 make things way way way way slow.
4328 So instead, we extend the display-table concept, which was
4329 historically limited to 256-byte vectors, to one of the
4332 a) A 256-entry vector, for backward compatibility;
4333 b) char-table, mapping characters to values;
4334 c) range-table, mapping ranges of characters to values;
4335 d) a list of the above.
4337 The (d) option allows you to specify multiple display tables
4338 instead of just one. Each display table can specify conversions
4339 for some characters and leave others unchanged. The way the
4340 character gets displayed is determined by the first display table
4341 with a binding for that character. This way, you could call a
4342 function `enable-hex-display' that adds a hex display-table to
4343 the list of display tables for the current buffer.
4345 #### ...not yet implemented... Also, we extend the concept of
4346 "mapping" to include a printf-like spec. Thus you can make all
4347 extended characters show up as hex with a display table like
4350 #s(range-table data ((256 524288) (format "%x")))
4352 Since more than one display table is possible, you have
4353 great flexibility in mapping ranges of characters. */
4354 Emchar printable_min = b ? (CHAR_OR_CHAR_INTP (b->ctl_arrow)
4355 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
4356 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
4357 ? 255 : 160)) : 255;
4359 Lisp_Object face_dt, window_dt;
4361 /* The text display block for this display line. */
4362 struct display_block *db = get_display_block_from_line (dl, TEXT);
4364 /* The first time through the main loop we need to force the glyph
4365 data to be updated. */
4368 /* Apparently the new extent_fragment_update returns an end position
4369 equal to the position passed in if there are no more runs to be
4371 int no_more_frags = 0;
4373 dl->used_prop_data = 0;
4375 dl->line_continuation = 0;
4377 /* set up faces to use for clearing areas, used by
4378 output_display_line */
4379 dl->default_findex = default_face;
4382 dl->left_margin_findex = default_face;
4383 dl->right_margin_findex = default_face;
4387 dl->left_margin_findex =
4388 get_builtin_face_cache_index (w, Vleft_margin_face);
4389 dl->right_margin_findex =
4390 get_builtin_face_cache_index (w, Vright_margin_face);
4394 data.ef = extent_fragment_new (disp_string, f);
4396 /* These values are used by all of the rune addition routines. We add
4397 them to this structure for ease of passing. */
4399 XSETWINDOW (data.window, w);
4403 data.bi_bufpos = bi_start_pos;
4404 data.pixpos = dl->bounds.left_in;
4405 data.last_charset = Qunbound;
4406 data.last_findex = default_face;
4407 data.result_str = Qnil;
4408 data.string = disp_string;
4410 /* Set the right boundary adjusting it to take into account any end
4411 glyph. Save the width of the end glyph for later use. */
4412 data.max_pixpos = dl->bounds.right_in;
4415 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
4417 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
4419 data.max_pixpos -= end_glyph_width;
4421 data.cursor_type = NO_CURSOR;
4425 /* I don't think we want this, string areas should not scroll with
4427 data.start_col = w->hscroll;
4428 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
4430 data.bi_start_col_enabled = 0;
4431 data.hscroll_glyph_width_adjust = 0;
4433 /* We regenerate the line from the very beginning. */
4434 Dynarr_reset (db->runes);
4436 /* Why is this less than or equal and not just less than? If the
4437 starting position is already equal to the maximum we can't add
4438 anything else, right? Wrong. We might still have a newline to
4439 add. A newline can use the room allocated for an end glyph since
4440 if we add it we know we aren't going to be adding any end
4443 /* #### Chuck -- I think this condition should be while (1).
4444 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
4445 and the begin-glyph ends exactly at the end of the window, the
4446 end-glyph and text might not be displayed. while (1) ensures
4447 that the loop terminates only when either (a) there is
4448 propagation data or (b) the end-of-line or end-of-buffer is hit.
4450 #### Also I think you need to ensure that the operation
4451 "add begin glyphs; add end glyphs; add text" is atomic and
4452 can't get interrupted in the middle. If you run off the end
4453 of the line during that operation, then you keep accumulating
4454 propagation data until you're done. Otherwise, if the (e.g.)
4455 there's a begin glyph at a particular position and attempting
4456 to display that glyph results in window-end being hit and
4457 propagation data being generated, then the character at that
4458 position won't be displayed.
4460 #### See also the comment after the end of this loop, below.
4462 while (data.pixpos <= data.max_pixpos)
4464 /* #### This check probably should not be necessary. */
4465 if (data.bi_bufpos > bi_string_zv)
4467 /* #### urk! More of this lossage! */
4472 /* Check for face changes. */
4473 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
4475 /* Now compute the face and begin/end-glyph information. */
4477 /* Remember that the extent-fragment routines deal in Bytind's. */
4478 extent_fragment_update (w, data.ef, data.bi_bufpos);
4479 /* This is somewhat cheesy but the alternative is to
4480 propagate default_face into extent_fragment_update. */
4481 if (data.findex == DEFAULT_INDEX)
4482 data.findex = default_face;
4484 get_display_tables (w, data.findex, &face_dt, &window_dt);
4486 if (data.bi_bufpos == data.ef->end)
4491 /* Determine what is next to be displayed. We first handle any
4492 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
4493 display then we determine what to do based on the character at the
4494 current buffer position. */
4496 /* If the current position is covered by an invisible extent, do
4497 nothing (except maybe add some ellipses).
4499 #### The behavior of begin and end-glyphs at the edge of an
4500 invisible extent should be investigated further. This is
4501 fairly low priority though. */
4502 if (data.ef->invisible)
4504 /* #### Chuck, perhaps you could look at this code? I don't
4505 really know what I'm doing. */
4508 Dynarr_free (*prop);
4512 /* The extent fragment code only sets this when we should
4513 really display the ellipses. It makes sure the ellipses
4514 don't get displayed more than once in a row. */
4515 if (data.ef->invisible_ellipses)
4517 struct glyph_block gb;
4519 data.ef->invisible_ellipses_already_displayed = 1;
4520 data.ef->invisible_ellipses = 0;
4522 gb.glyph = Vinvisible_text_glyph;
4523 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
4524 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
4525 /* Perhaps they shouldn't propagate if the very next thing
4526 is to display a newline (for compatibility with
4527 selective-display-ellipses)? Maybe that's too
4533 /* #### What if we we're dealing with a display table? */
4537 if (data.bi_bufpos == bi_string_zv)
4540 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4543 /* If there is propagation data, then it represents the current
4544 buffer position being displayed. Add them and advance the
4545 position counter. This might also add the minibuffer
4549 dl->used_prop_data = 1;
4550 *prop = add_propagation_runes (prop, &data);
4553 goto done; /* gee, a really narrow window */
4554 else if (data.bi_bufpos == bi_string_zv)
4556 else if (data.bi_bufpos < 0)
4557 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
4560 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4563 /* If there are end glyphs, add them to the line. These are
4564 the end glyphs for the previous run of text. We add them
4565 here rather than doing them at the end of handling the
4566 previous run so that glyphs at the beginning and end of
4567 a line are handled correctly. */
4568 else if (Dynarr_length (data.ef->end_glyphs) > 0)
4570 *prop = add_glyph_runes (&data, END_GLYPHS);
4575 /* If there are begin glyphs, add them to the line. */
4576 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
4578 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
4583 /* If at end-of-buffer, we've already processed begin and
4584 end-glyphs at this point and there's no text to process,
4586 else if (data.bi_bufpos == bi_string_zv)
4591 Lisp_Object entry = Qnil;
4592 /* Get the character at the current buffer position. */
4593 data.ch = string_char (s, data.bi_bufpos);
4594 if (!NILP (face_dt) || !NILP (window_dt))
4595 entry = display_table_entry (data.ch, face_dt, window_dt);
4597 /* If there is a display table entry for it, hand it off to
4598 add_disp_table_entry_runes and let it worry about it. */
4599 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
4601 *prop = add_disp_table_entry_runes (&data, entry);
4607 /* Check if we have hit a newline character. If so, add a marker
4608 to the line and end this loop. */
4609 else if (data.ch == '\n')
4611 /* We aren't going to be adding an end glyph so give its
4612 space back in order to make sure that the cursor can
4614 data.max_pixpos += end_glyph_width;
4618 /* If the current character is considered to be printable, then
4620 else if (data.ch >= printable_min)
4622 *prop = add_emchar_rune (&data);
4627 /* If the current character is a tab, determine the next tab
4628 starting position and add a blank rune which extends from the
4629 current pixel position to that starting position. */
4630 else if (data.ch == '\t')
4632 int tab_start_pixpos = data.pixpos;
4637 if (data.start_col > 1)
4638 tab_start_pixpos -= (space_width (w) * (data.start_col - 1));
4641 next_tab_position (w, tab_start_pixpos,
4642 dl->bounds.left_in +
4643 data.hscroll_glyph_width_adjust);
4644 if (next_tab_start > data.max_pixpos)
4646 prop_width = next_tab_start - data.max_pixpos;
4647 next_tab_start = data.max_pixpos;
4649 data.blank_width = next_tab_start - data.pixpos;
4651 (next_tab_start - tab_start_pixpos) / space_width (w);
4653 *prop = add_blank_rune (&data, w, char_tab_width);
4655 /* add_blank_rune is only supposed to be called with
4656 sizes guaranteed to fit in the available space. */
4661 struct prop_block pb;
4662 *prop = Dynarr_new (prop_block);
4664 pb.type = PROP_BLANK;
4665 pb.data.p_blank.width = prop_width;
4666 pb.data.p_blank.findex = data.findex;
4667 Dynarr_add (*prop, pb);
4673 /* If character is a control character, pass it off to
4674 add_control_char_runes.
4676 The is_*() routines have undefined results on
4677 arguments outside of the range [-1, 255]. (This
4678 often bites people who carelessly use `char' instead
4679 of `unsigned char'.)
4681 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
4683 *prop = add_control_char_runes (&data, b);
4689 /* If the character is above the ASCII range and we have not
4690 already handled it, then print it as an octal number. */
4691 else if (data.ch >= 0200)
4693 *prop = add_octal_runes (&data);
4699 /* Assume the current character is considered to be printable,
4700 then just add it. */
4703 *prop = add_emchar_rune (&data);
4708 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4714 /* Determine the starting point of the next line if we did not hit the
4715 end of the buffer. */
4716 if (data.bi_bufpos < bi_string_zv)
4718 /* #### This check is not correct. If the line terminated
4719 due to a begin-glyph or end-glyph hitting window-end, then
4720 data.ch will not point to the character at data.bi_bufpos. If
4721 you make the two changes mentioned at the top of this loop,
4722 you should be able to say '(if (*prop))'. That should also
4723 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
4726 /* The common case is that the line ended because we hit a newline.
4727 In that case, the next character is just the next buffer
4729 if (data.ch == '\n')
4731 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4734 /* Otherwise we have a buffer line which cannot fit on one display
4738 struct glyph_block gb;
4739 struct glyph_cachel *cachel;
4741 /* If the line is to be truncated then we actually have to look
4742 for the next newline. We also add the end-of-line glyph which
4743 we know will fit because we adjusted the right border before
4744 we starting laying out the line. */
4745 data.max_pixpos += end_glyph_width;
4746 data.findex = default_face;
4753 /* Now find the start of the next line. */
4754 bi_pos = bi_find_next_emchar_in_string (s, '\n', data.bi_bufpos, 1);
4756 data.cursor_type = NO_CURSOR;
4757 data.bi_bufpos = bi_pos;
4758 gb.glyph = Vtruncation_glyph;
4759 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
4763 /* The cursor can never be on the continuation glyph. */
4764 data.cursor_type = NO_CURSOR;
4766 /* data.bi_bufpos is already at the start of the next line. */
4768 dl->line_continuation = 1;
4769 gb.glyph = Vcontinuation_glyph;
4770 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
4773 if (end_glyph_width)
4774 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
4776 if (truncate_win && data.bi_bufpos == bi_string_zv)
4778 const Bufbyte* endb = charptr_n_addr (string_data (s), bi_string_zv);
4780 if (charptr_emchar (endb) != '\n')
4782 /* #### Damn this losing shit. */
4788 else if (data.bi_bufpos == bi_string_zv)
4790 /* create_text_block () adds a bogus \n marker here which screws
4791 up subwindow display. Since we never have a cursor in the
4792 gutter we can safely ignore it. */
4794 /* Calculate left whitespace boundary. */
4798 /* Whitespace past a newline is considered right whitespace. */
4799 while (elt < Dynarr_length (db->runes))
4801 struct rune *rb = Dynarr_atp (db->runes, elt);
4803 if ((rb->type == RUNE_CHAR
4804 && EQ (rb->object.cglyph.charset, Vcharset_ascii)
4805 && rb->object.cglyph.code_point == ' ')
4806 || rb->type == RUNE_BLANK)
4808 dl->bounds.left_white += rb->width;
4812 elt = Dynarr_length (db->runes);
4816 /* Calculate right whitespace boundary. */
4818 int elt = Dynarr_length (db->runes) - 1;
4821 while (!done && elt >= 0)
4823 struct rune *rb = Dynarr_atp (db->runes, elt);
4825 if (!(rb->type == RUNE_CHAR
4826 && (EQ (rb->object.cglyph.charset, Vcharset_ascii)
4827 || EQ (rb->object.cglyph.charset, Vcharset_control_1)
4828 || EQ (rb->object.cglyph.charset, Vcharset_latin_iso8859_1))
4829 && isspace (rb->object.cglyph.code_point))
4830 && !rb->type == RUNE_BLANK)
4832 dl->bounds.right_white = rb->xpos + rb->width;
4840 /* The line is blank so everything is considered to be right
4843 dl->bounds.right_white = dl->bounds.left_in;
4846 /* Set the display blocks bounds. */
4847 db->start_pos = dl->bounds.left_in;
4848 if (Dynarr_length (db->runes))
4850 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
4852 db->end_pos = rb->xpos + rb->width;
4855 db->end_pos = dl->bounds.right_white;
4857 /* update line height parameters */
4858 if (!data.new_ascent && !data.new_descent)
4860 /* We've got a blank line so initialize these values from the default
4862 default_face_font_info (data.window, &data.new_ascent,
4863 &data.new_descent, 0, 0, 0);
4866 if (data.max_pixmap_height)
4868 int height = data.new_ascent + data.new_descent;
4869 int pix_ascent, pix_descent;
4871 pix_descent = data.max_pixmap_height * data.new_descent / height;
4872 pix_ascent = data.max_pixmap_height - pix_descent;
4874 data.new_ascent = max (data.new_ascent, pix_ascent);
4875 data.new_descent = max (data.new_descent, pix_descent);
4878 dl->ascent = data.new_ascent;
4879 dl->descent = data.new_descent;
4882 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
4884 if (dl->ascent < ascent)
4885 dl->ascent = ascent;
4888 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
4890 if (dl->descent < descent)
4891 dl->descent = descent;
4894 dl->cursor_elt = data.cursor_x;
4895 /* #### lossage lossage lossage! Fix this shit! */
4896 if (data.bi_bufpos > bi_string_zv)
4897 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, bi_string_zv);
4899 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, data.bi_bufpos) - 1;
4901 data.dl->num_chars =
4902 string_column_at_point (s, dl->end_bufpos, b ? XINT (b->tab_width) : 8);
4904 /* This doesn't correctly take into account tabs and control
4905 characters but if the window isn't being truncated then this
4906 value isn't going to end up being used anyhow. */
4907 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
4909 /* #### handle horizontally scrolled line with text none of which
4910 was actually laid out. */
4912 /* #### handle any remainder of overlay arrow */
4914 if (*prop == ADD_FAILED)
4917 if (truncate_win && *prop)
4919 Dynarr_free (*prop);
4923 extent_fragment_delete (data.ef);
4925 /* #### If we started at EOB, then make sure we return a value past
4926 it so that regenerate_window will exit properly. This is bogus.
4927 The main loop should get fixed so that it isn't necessary to call
4928 this function if we are already at EOB. */
4930 if (data.bi_bufpos == bi_string_zv && bi_start_pos == bi_string_zv)
4931 return bytecount_to_charcount (string_data (s), data.bi_bufpos) + 1; /* Yuck! */
4933 return bytecount_to_charcount (string_data (s), data.bi_bufpos);
4936 /* Given a display line and a starting position, ensure that the
4937 contents of the display line accurately represent the visual
4938 representation of the buffer contents starting from the given
4939 position when displayed in the given window. The display line ends
4940 when the contents of the line reach the right boundary of the given
4943 This is very similar to generate_display_line but with the same
4944 limitations as create_string_text_block. I have taken the liberty
4945 of fixing the bytind stuff though.*/
4948 generate_string_display_line (struct window *w, Lisp_Object disp_string,
4949 struct display_line *dl,
4951 prop_block_dynarr **prop,
4952 face_index default_face)
4956 /* you must set bounds before calling this. */
4958 /* Reset what this line is using. */
4959 if (dl->display_blocks)
4960 Dynarr_reset (dl->display_blocks);
4961 if (dl->left_glyphs)
4963 Dynarr_free (dl->left_glyphs);
4964 dl->left_glyphs = 0;
4966 if (dl->right_glyphs)
4968 Dynarr_free (dl->right_glyphs);
4969 dl->right_glyphs = 0;
4972 /* We aren't generating a modeline at the moment. */
4975 /* Create a display block for the text region of the line. */
4976 ret_bufpos = create_string_text_block (w, disp_string, dl, start_pos,
4977 prop, default_face);
4978 dl->bufpos = start_pos;
4979 if (dl->end_bufpos < dl->bufpos)
4980 dl->end_bufpos = dl->bufpos;
4982 /* If there are left glyphs associated with any character in the
4983 text block, then create a display block to handle them. */
4984 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
4985 create_left_glyph_block (w, dl, 0);
4987 /* If there are right glyphs associated with any character in the
4988 text block, then create a display block to handle them. */
4989 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
4990 create_right_glyph_block (w, dl);
4995 /* This is ripped off from regenerate_window. All we want to do is
4996 loop through elements in the string creating display lines until we
4997 have covered the provided area. Simple really. */
4999 generate_displayable_area (struct window *w, Lisp_Object disp_string,
5000 int xpos, int ypos, int width, int height,
5001 display_line_dynarr* dla,
5003 face_index default_face)
5005 int yend = ypos + height;
5008 prop_block_dynarr *prop = 0;
5009 layout_bounds bounds;
5013 /* if there's nothing to do then do nothing. code after this assumes
5014 there is something to do. */
5015 if (NILP (disp_string))
5018 s_zv = XSTRING_CHAR_LENGTH (disp_string);
5020 bounds.left_out = xpos;
5021 bounds.right_out = xpos + width;
5022 /* The inner boundaries mark where the glyph margins are located. */
5023 bounds.left_in = bounds.left_out + window_left_margin_width (w);
5024 bounds.right_in = bounds.right_out - window_right_margin_width (w);
5025 /* We cannot fully calculate the whitespace boundaries as they
5026 depend on the contents of the line being displayed. */
5027 bounds.left_white = bounds.left_in;
5028 bounds.right_white = bounds.right_in;
5032 struct display_line dl;
5033 struct display_line *dlp;
5037 if (Dynarr_length (dla) < Dynarr_largest (dla))
5039 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5050 dlp->bounds = bounds;
5052 next_pos = generate_string_display_line (w, disp_string, dlp, start_pos,
5053 &prop, default_face);
5054 /* we need to make sure that we continue along the line if there
5055 is more left to display otherwise we just end up redisplaying
5056 the same chunk over and over again. */
5057 if (next_pos == start_pos && next_pos < s_zv)
5060 start_pos = next_pos;
5062 dlp->ypos = ypos + dlp->ascent;
5063 ypos = dlp->ypos + dlp->descent;
5067 int visible_height = dlp->ascent + dlp->descent;
5069 dlp->clip = (ypos - yend);
5070 visible_height -= dlp->clip;
5072 if (visible_height < VERTICAL_CLIP (w, 1))
5075 free_display_line (dlp);
5082 Dynarr_add (dla, *dlp);
5084 /* #### This type of check needs to be done down in the
5085 generate_display_line call. */
5086 if (start_pos >= s_zv)
5095 /***************************************************************************/
5097 /* window-regeneration routines */
5099 /***************************************************************************/
5101 /* For a given window and starting position in the buffer it contains,
5102 ensure that the TYPE display lines accurately represent the
5103 presentation of the window. We pass the buffer instead of getting
5104 it from the window since redisplay_window may have temporarily
5105 changed it to the echo area buffer. */
5108 regenerate_window (struct window *w, Bufpos start_pos, Bufpos point, int type)
5110 struct frame *f = XFRAME (w->frame);
5111 struct buffer *b = XBUFFER (w->buffer);
5112 int ypos = WINDOW_TEXT_TOP (w);
5113 int yend; /* set farther down */
5114 int yclip = WINDOW_TEXT_TOP_CLIP (w);
5117 prop_block_dynarr *prop;
5118 layout_bounds bounds;
5119 display_line_dynarr *dla;
5122 /* The lines had better exist by this point. */
5123 if (!(dla = window_display_lines (w, type)))
5126 w->max_line_len = 0;
5128 /* Normally these get updated in redisplay_window but it is possible
5129 for this function to get called from some other points where that
5130 update may not have occurred. This acts as a safety check. */
5131 if (!Dynarr_length (w->face_cachels))
5132 reset_face_cachels (w);
5133 if (!Dynarr_length (w->glyph_cachels))
5134 reset_glyph_cachels (w);
5136 Fset_marker (w->start[type], make_int (start_pos), w->buffer);
5137 Fset_marker (w->pointm[type], make_int (point), w->buffer);
5138 w->last_point_x[type] = -1;
5139 w->last_point_y[type] = -1;
5141 /* Make sure a modeline is in the structs if needed. */
5142 need_modeline = ensure_modeline_generated (w, type);
5144 /* Wait until here to set this so that the structs have a modeline
5145 generated in the case where one didn't exist. */
5146 yend = WINDOW_TEXT_BOTTOM (w);
5148 bounds = calculate_display_line_boundaries (w, 0);
5150 /* 97/3/14 jhod: stuff added here to support pre-prompts (used for input systems) */
5151 if (MINI_WINDOW_P (w)
5152 && (!NILP (Vminibuf_prompt) || !NILP (Vminibuf_preprompt))
5153 && !echo_area_active (f)
5154 && start_pos == BUF_BEGV (b))
5156 struct prop_block pb;
5158 prop = Dynarr_new (prop_block);
5160 string = concat2(Vminibuf_preprompt, Vminibuf_prompt);
5161 pb.type = PROP_MINIBUF_PROMPT;
5162 pb.data.p_string.str = XSTRING_DATA(string);
5163 pb.data.p_string.len = XSTRING_LENGTH(string);
5164 Dynarr_add (prop, pb);
5169 /* When we are computing things for scrolling purposes, make
5170 sure at least one line is always generated */
5171 force = (type == CMOTION_DISP);
5173 /* Make sure this is set always */
5174 /* Note the conversion at end */
5175 w->window_end_pos[type] = start_pos;
5176 while (ypos < yend || force)
5178 struct display_line dl;
5179 struct display_line *dlp;
5182 if (Dynarr_length (dla) < Dynarr_largest (dla))
5184 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5195 dlp->bounds = bounds;
5197 start_pos = generate_display_line (w, dlp, 1, start_pos, &prop, type);
5199 if (yclip > dlp->ascent)
5201 /* this should never happen, but if it does just display the
5206 dlp->ypos = (ypos + dlp->ascent) - yclip;
5207 ypos = dlp->ypos + dlp->descent;
5209 /* See if we've been asked to start midway through a line, for
5210 partial display line scrolling. */
5213 dlp->top_clip = yclip;
5221 int visible_height = dlp->ascent + dlp->descent;
5223 dlp->clip = (ypos - yend);
5224 /* Although this seems strange we could have a single very
5225 tall line visible for which we need to account for both
5226 the top clip and the bottom clip. */
5227 visible_height -= (dlp->clip + dlp->top_clip);
5229 if (visible_height < VERTICAL_CLIP (w, 1) && !force)
5232 free_display_line (dlp);
5239 if (dlp->cursor_elt != -1)
5241 /* #### This check is steaming crap. Have to get things
5242 fixed so when create_text_block hits EOB, we're done,
5244 if (w->last_point_x[type] == -1)
5246 w->last_point_x[type] = dlp->cursor_elt;
5247 w->last_point_y[type] = Dynarr_length (dla);
5251 /* #### This means that we've added a cursor at EOB
5252 twice. Yuck oh yuck. */
5253 struct display_block *db =
5254 get_display_block_from_line (dlp, TEXT);
5256 Dynarr_atp (db->runes, dlp->cursor_elt)->cursor_type = NO_CURSOR;
5257 dlp->cursor_elt = -1;
5261 if (dlp->num_chars > w->max_line_len)
5262 w->max_line_len = dlp->num_chars;
5264 Dynarr_add (dla, *dlp);
5266 /* #### This isn't right, but it is close enough for now. */
5267 w->window_end_pos[type] = start_pos;
5269 /* #### This type of check needs to be done down in the
5270 generate_display_line call. */
5271 if (start_pos > BUF_ZV (b))
5280 /* #### More not quite right, but close enough. */
5281 /* Ben sez: apparently window_end_pos[] is measured
5282 as the number of characters between the window end and the
5283 end of the buffer? This seems rather weirdo. What's
5284 the justification for this?
5286 JV sez: Because BUF_Z (b) would be a good initial value, however
5287 that can change. This representation allows initalizing with 0.
5289 w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type];
5293 /* We know that this is the right thing to use because we put it
5294 there when we first started working in this function. */
5295 generate_modeline (w, Dynarr_atp (dla, 0), type);
5299 #define REGEN_INC_FIND_START_END \
5301 /* Determine start and end of lines. */ \
5302 if (!Dynarr_length (cdla)) \
5306 if (Dynarr_atp (cdla, 0)->modeline && Dynarr_atp (ddla, 0)->modeline) \
5310 else if (!Dynarr_atp (cdla, 0)->modeline \
5311 && !Dynarr_atp (ddla, 0)->modeline) \
5316 abort (); /* structs differ */ \
5318 dla_end = Dynarr_length (cdla) - 1; \
5321 start_pos = (Dynarr_atp (cdla, dla_start)->bufpos \
5322 + Dynarr_atp (cdla, dla_start)->offset); \
5323 /* If this isn't true, then startp has changed and we need to do a \
5325 if (startp != start_pos) \
5328 /* Point is outside the visible region so give up. */ \
5329 if (pointm < start_pos) \
5334 /* This attempts to incrementally update the display structures. It
5335 returns a boolean indicating success or failure. This function is
5336 very similar to regenerate_window_incrementally and is in fact only
5337 called from that function. However, because of the nature of the
5338 changes it deals with it sometimes makes different assumptions
5339 which can lead to success which are much more difficult to make
5340 when dealing with buffer changes. */
5343 regenerate_window_extents_only_changed (struct window *w, Bufpos startp,
5345 Charcount beg_unchanged,
5346 Charcount end_unchanged)
5348 struct buffer *b = XBUFFER (w->buffer);
5349 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5350 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5354 int first_line, last_line;
5356 /* Don't define this in the loop where it is used because we
5357 definitely want its value to survive between passes. */
5358 prop_block_dynarr *prop = NULL;
5360 /* If we don't have any buffer change recorded but the modiff flag has
5361 been incremented, then fail. I'm not sure of the exact circumstances
5362 under which this can happen, but I believe that it is probably a
5363 reasonable happening. */
5364 if (!point_visible (w, pointm, CURRENT_DISP)
5365 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b))
5368 /* If the cursor is moved we attempt to update it. If we succeed we
5369 go ahead and proceed with the optimization attempt. */
5370 if (!EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5371 || pointm != marker_position (w->last_point[CURRENT_DISP]))
5373 struct frame *f = XFRAME (w->frame);
5374 struct device *d = XDEVICE (f->device);
5375 struct frame *sel_f = device_selected_frame (d);
5378 if (w->last_point_x[CURRENT_DISP] != -1
5379 && w->last_point_y[CURRENT_DISP] != -1)
5382 if (redisplay_move_cursor (w, pointm, WINDOW_TTY_P (w)))
5384 /* Always regenerate the modeline in case it is
5385 displaying the current line or column. */
5386 regenerate_modeline (w);
5390 else if (w != XWINDOW (FRAME_SELECTED_WINDOW (sel_f)))
5392 if (f->modeline_changed)
5393 regenerate_modeline (w);
5401 if (beg_unchanged == -1 && end_unchanged == -1)
5404 /* assert: There are no buffer modifications or they are all below the
5405 visible region. We assume that regenerate_window_incrementally has
5406 not called us unless this is true. */
5408 REGEN_INC_FIND_START_END;
5410 /* If the changed are starts before the visible area, give up. */
5411 if (beg_unchanged < startp)
5414 /* Find what display line the extent changes first affect. */
5416 while (line <= dla_end)
5418 struct display_line *dl = Dynarr_atp (cdla, line);
5419 Bufpos lstart = dl->bufpos + dl->offset;
5420 Bufpos lend = dl->end_bufpos + dl->offset;
5422 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5428 /* If the changes are below the visible area then if point hasn't
5429 moved return success otherwise fail in order to be safe. */
5432 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5433 && pointm == marker_position (w->last_point[CURRENT_DISP]))
5439 /* At this point we know what line the changes first affect. We now
5440 begin redrawing lines as long as we are still in the affected
5441 region and the line's size and positioning don't change.
5442 Otherwise we fail. If we fail we will have altered the desired
5443 structs which could lead to an assertion failure. However, if we
5444 fail the next thing that is going to happen is a full regen so we
5445 will actually end up being safe. */
5446 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5447 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5448 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
5449 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
5451 first_line = last_line = line;
5452 while (line <= dla_end)
5454 Bufpos old_start, old_end, new_start;
5455 struct display_line *cdl = Dynarr_atp (cdla, line);
5456 struct display_line *ddl = Dynarr_atp (ddla, line);
5457 struct display_block *db;
5460 assert (cdl->bufpos == ddl->bufpos);
5461 assert (cdl->end_bufpos == ddl->end_bufpos);
5462 assert (cdl->offset == ddl->offset);
5464 db = get_display_block_from_line (ddl, TEXT);
5465 initial_size = Dynarr_length (db->runes);
5466 old_start = ddl->bufpos + ddl->offset;
5467 old_end = ddl->end_bufpos + ddl->offset;
5469 /* If this is the first line being updated and it used
5470 propagation data, fail. Otherwise we'll be okay because
5471 we'll have the necessary propagation data. */
5472 if (line == first_line && ddl->used_prop_data)
5475 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5476 &prop, DESIRED_DISP);
5479 /* #### If there is propagated stuff the fail. We could
5480 probably actually deal with this if the line had propagated
5481 information when originally created by a full
5489 /* If any line position parameters have changed or a
5490 cursor has disappeared or disappeared, fail. */
5491 db = get_display_block_from_line (ddl, TEXT);
5492 if (cdl->ypos != ddl->ypos
5493 || cdl->ascent != ddl->ascent
5494 || cdl->descent != ddl->descent
5495 || cdl->top_clip != ddl->top_clip
5496 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5497 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1)
5498 || old_start != ddl->bufpos
5499 || old_end != ddl->end_bufpos
5500 || initial_size != Dynarr_length (db->runes))
5505 if (ddl->cursor_elt != -1)
5507 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5508 w->last_point_y[DESIRED_DISP] = line;
5513 /* If the extent changes end on the line we just updated then
5514 we're done. Otherwise go on to the next line. */
5515 if (end_unchanged <= ddl->end_bufpos)
5521 redisplay_update_line (w, first_line, last_line, 1);
5525 /* Attempt to update the display data structures based on knowledge of
5526 the changed region in the buffer. Returns a boolean indicating
5527 success or failure. If this function returns a failure then a
5528 regenerate_window _must_ be performed next in order to maintain
5529 invariants located here. */
5532 regenerate_window_incrementally (struct window *w, Bufpos startp,
5535 struct buffer *b = XBUFFER (w->buffer);
5536 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5537 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5538 Charcount beg_unchanged, end_unchanged;
5539 Charcount extent_beg_unchanged, extent_end_unchanged;
5545 /* If this function is called, the current and desired structures
5546 had better be identical. If they are not, then that is a bug. */
5547 assert (Dynarr_length (cdla) == Dynarr_length (ddla));
5549 /* We don't handle minibuffer windows yet. The minibuffer prompt
5551 if (MINI_WINDOW_P (w))
5554 extent_beg_unchanged = BUF_EXTENT_BEGIN_UNCHANGED (b);
5555 extent_end_unchanged = (BUF_EXTENT_END_UNCHANGED (b) == -1
5557 : BUF_Z (b) - BUF_EXTENT_END_UNCHANGED (b));
5559 /* If nothing has changed in the buffer, then make sure point is ok
5561 if (BUF_BEGIN_UNCHANGED (b) == -1 && BUF_END_UNCHANGED (b) == -1)
5562 return regenerate_window_extents_only_changed (w, startp, pointm,
5563 extent_beg_unchanged,
5564 extent_end_unchanged);
5566 /* We can't deal with deleted newlines. */
5567 if (BUF_NEWLINE_WAS_DELETED (b))
5570 beg_unchanged = BUF_BEGIN_UNCHANGED (b);
5571 end_unchanged = (BUF_END_UNCHANGED (b) == -1
5573 : BUF_Z (b) - BUF_END_UNCHANGED (b));
5575 REGEN_INC_FIND_START_END;
5577 /* If the changed area starts before the visible area, give up. */
5578 if (beg_unchanged < startp)
5581 /* Find what display line the buffer changes first affect. */
5583 while (line <= dla_end)
5585 struct display_line *dl = Dynarr_atp (cdla, line);
5586 Bufpos lstart = dl->bufpos + dl->offset;
5587 Bufpos lend = dl->end_bufpos + dl->offset;
5589 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5595 /* If the changes are below the visible area then if point hasn't
5596 moved return success otherwise fail in order to be safe. */
5598 return regenerate_window_extents_only_changed (w, startp, pointm,
5599 extent_beg_unchanged,
5600 extent_end_unchanged);
5602 /* At this point we know what line the changes first affect. We
5603 now redraw that line. If the changes are contained within it
5604 we are going to succeed and can update just that one line.
5605 Otherwise we fail. If we fail we will have altered the desired
5606 structs which could lead to an assertion failure. However, if
5607 we fail the next thing that is going to happen is a full regen
5608 so we will actually end up being safe. */
5611 prop_block_dynarr *prop = NULL;
5612 struct display_line *cdl = Dynarr_atp (cdla, line);
5613 struct display_line *ddl = Dynarr_atp (ddla, line);
5615 assert (cdl->bufpos == ddl->bufpos);
5616 assert (cdl->end_bufpos == ddl->end_bufpos);
5617 assert (cdl->offset == ddl->offset);
5619 /* If the line continues to next display line, fail. */
5620 if (ddl->line_continuation)
5623 /* If the line was generated using propagation data, fail. */
5624 if (ddl->used_prop_data)
5627 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5628 &prop, DESIRED_DISP);
5631 /* If there is propagated stuff then it is pretty much a
5632 guarantee that more than just the one line is affected. */
5639 /* If the line continues to next display line, fail. */
5640 if (ddl->line_continuation)
5643 /* If any line position parameters have changed or a
5644 cursor has disappeared or disappeared, fail. */
5645 if (cdl->ypos != ddl->ypos
5646 || cdl->ascent != ddl->ascent
5647 || cdl->descent != ddl->descent
5648 || cdl->top_clip != ddl->top_clip
5649 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5650 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1))
5655 /* If the changed area also ends on this line, then we may be in
5656 business. Update everything and return success. */
5657 if (end_unchanged >= ddl->bufpos && end_unchanged <= ddl->end_bufpos)
5659 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5660 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5661 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp),
5663 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm),
5666 if (ddl->cursor_elt != -1)
5668 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5669 w->last_point_y[DESIRED_DISP] = line;
5672 redisplay_update_line (w, line, line, 1);
5673 regenerate_modeline (w);
5675 /* #### For now we just flush the cache until this has been
5676 tested. After that is done, this should correct the
5678 Dynarr_reset (w->line_start_cache);
5680 /* Adjust the extent changed boundaries to remove any
5681 overlap with the buffer changes since we've just
5682 successfully updated that area. */
5683 if (extent_beg_unchanged != -1
5684 && extent_beg_unchanged >= beg_unchanged
5685 && extent_beg_unchanged < end_unchanged)
5686 extent_beg_unchanged = end_unchanged;
5688 if (extent_end_unchanged != -1
5689 && extent_end_unchanged >= beg_unchanged
5690 && extent_end_unchanged < end_unchanged)
5691 extent_end_unchanged = beg_unchanged - 1;
5693 if (extent_end_unchanged <= extent_beg_unchanged)
5694 extent_beg_unchanged = extent_end_unchanged = -1;
5696 /* This could lead to odd results if it fails, but since the
5697 buffer changes update succeeded this probably will to.
5698 We already know that the extent changes start at or after
5699 the line because we checked before entering the loop. */
5700 if (extent_beg_unchanged != -1
5701 && extent_end_unchanged != -1
5702 && ((extent_beg_unchanged < ddl->bufpos)
5703 || (extent_end_unchanged > ddl->end_bufpos)))
5704 return regenerate_window_extents_only_changed (w, startp, pointm,
5705 extent_beg_unchanged,
5706 extent_end_unchanged);
5716 /* Given a window and a point, update the given display lines such
5717 that point is displayed in the middle of the window.
5718 Return the window's new start position. */
5721 regenerate_window_point_center (struct window *w, Bufpos point, int type)
5725 /* We need to make sure that the modeline is generated so that the
5726 window height can be calculated correctly. */
5727 ensure_modeline_generated (w, type);
5729 startp = start_with_line_at_pixpos (w, point, window_half_pixpos (w));
5730 regenerate_window (w, startp, point, type);
5731 Fset_marker (w->start[type], make_int (startp), w->buffer);
5736 /* Given a window and a set of display lines, return a boolean
5737 indicating whether the given point is contained within. */
5740 point_visible (struct window *w, Bufpos point, int type)
5742 struct buffer *b = XBUFFER (w->buffer);
5743 display_line_dynarr *dla = window_display_lines (w, type);
5746 if (Dynarr_length (dla) && Dynarr_atp (dla, 0)->modeline)
5751 if (Dynarr_length (dla) > first_line)
5754 struct display_line *dl = Dynarr_atp (dla, first_line);
5757 end = BUF_Z (b) - w->window_end_pos[type] - 1;
5759 if (point >= start && point <= end)
5761 if (!MINI_WINDOW_P (w) && scroll_on_clipped_lines)
5763 dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
5765 if (point >= (dl->bufpos + dl->offset)
5766 && point <= (dl->end_bufpos + dl->offset))
5781 /* Return pixel position the middle of the window, not including the
5782 modeline and any potential horizontal scrollbar. */
5785 window_half_pixpos (struct window *w)
5787 return WINDOW_TEXT_TOP (w) + (WINDOW_TEXT_HEIGHT (w) >> 1);
5790 /* Return the display line which is currently in the middle of the
5791 window W for display lines TYPE. */
5794 line_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5796 display_line_dynarr *dla;
5799 int first_elt = (MINI_WINDOW_P (w) ? 0 : 1);
5801 if (type == CMOTION_DISP)
5802 regenerate_window (w, start, point, type);
5804 dla = window_display_lines (w, type);
5805 half = window_half_pixpos (w);
5807 for (elt = first_elt; elt < Dynarr_length (dla); elt++)
5809 struct display_line *dl = Dynarr_atp (dla, elt);
5810 int line_bot = dl->ypos + dl->descent;
5812 if (line_bot > half)
5816 /* We may not have a line at the middle if the end of the buffer is
5821 /* Return a value for point that would place it at the beginning of
5822 the line which is in the middle of the window. */
5825 point_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5827 /* line_at_center will regenerate the display structures, if necessary. */
5828 int line = line_at_center (w, type, start, point);
5831 return BUF_ZV (XBUFFER (w->buffer));
5834 display_line_dynarr *dla = window_display_lines (w, type);
5835 struct display_line *dl = Dynarr_atp (dla, line);
5841 /* For a given window, ensure that the current visual representation
5845 redisplay_window (Lisp_Object window, int skip_selected)
5847 struct window *w = XWINDOW (window);
5848 struct frame *f = XFRAME (w->frame);
5849 struct device *d = XDEVICE (f->device);
5850 Lisp_Object old_buffer = w->buffer;
5851 Lisp_Object the_buffer = w->buffer;
5853 int echo_active = 0;
5858 int selected_in_its_frame;
5859 int selected_globally;
5860 int skip_output = 0;
5861 int truncation_changed;
5862 int inactive_minibuffer =
5863 (MINI_WINDOW_P (w) &&
5864 (f != device_selected_frame (d)) &&
5865 !is_surrogate_for_selected_frame (f));
5867 /* #### In the new world this function actually does a bunch of
5868 optimizations such as buffer-based scrolling, but none of that is
5871 /* If this is a combination window, do its children; that's all.
5872 The selected window is always a leaf so we don't check for
5873 skip_selected here. */
5874 if (!NILP (w->vchild))
5876 redisplay_windows (w->vchild, skip_selected);
5879 if (!NILP (w->hchild))
5881 redisplay_windows (w->hchild, skip_selected);
5885 /* Is this window the selected window on its frame? */
5886 selected_in_its_frame = (w == XWINDOW (FRAME_SELECTED_WINDOW (f)));
5888 selected_in_its_frame &&
5889 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
5890 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d &&
5891 XFRAME(DEVICE_SELECTED_FRAME(d)) == f;
5892 if (skip_selected && selected_in_its_frame)
5895 /* It is possible that the window is not fully initialized yet. */
5896 if (NILP (w->buffer))
5899 if (MINI_WINDOW_P (w) && echo_area_active (f))
5901 w->buffer = the_buffer = Vecho_area_buffer;
5905 b = XBUFFER (w->buffer);
5909 old_pointm = selected_globally
5911 : marker_position (w->pointm[CURRENT_DISP]);
5916 if (selected_globally)
5918 pointm = BUF_PT (b);
5922 pointm = marker_position (w->pointm[CURRENT_DISP]);
5924 if (pointm < BUF_BEGV (b))
5925 pointm = BUF_BEGV (b);
5926 else if (pointm > BUF_ZV (b))
5927 pointm = BUF_ZV (b);
5930 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm), the_buffer);
5932 /* If the buffer has changed we have to invalidate all of our face
5934 if ((!echo_active && b != window_display_buffer (w))
5935 || !Dynarr_length (w->face_cachels)
5936 || f->faces_changed)
5937 reset_face_cachels (w);
5939 mark_face_cachels_as_not_updated (w);
5941 /* Ditto the glyph cache elements, although we do *not* invalidate
5942 the cache purely because glyphs have changed - this is now
5943 handled by the dirty flag.*/
5944 if ((!echo_active && b != window_display_buffer (w))
5945 || !Dynarr_length (w->glyph_cachels) || f->faces_changed)
5946 reset_glyph_cachels (w);
5948 mark_glyph_cachels_as_not_updated (w);
5950 /* If the marker's buffer is not the window's buffer, then we need
5951 to find a new starting position. */
5952 if (!MINI_WINDOW_P (w)
5953 && !EQ (Fmarker_buffer (w->start[CURRENT_DISP]), w->buffer))
5955 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
5957 goto regeneration_done;
5962 old_startp = marker_position (w->start[CURRENT_DISP]);
5967 startp = marker_position (w->start[CURRENT_DISP]);
5968 if (startp < BUF_BEGV (b))
5969 startp = BUF_BEGV (b);
5970 else if (startp > BUF_ZV (b))
5971 startp = BUF_ZV (b);
5973 Fset_marker (w->start[DESIRED_DISP], make_int (startp), the_buffer);
5975 truncation_changed = (find_window_mirror (w)->truncate_win !=
5976 window_truncation_on (w));
5978 /* If w->force_start is set, then some function set w->start and we
5979 should display from there and change point, if necessary, to
5980 ensure that it is visible. */
5981 if (w->force_start || inactive_minibuffer)
5984 w->last_modified[DESIRED_DISP] = Qzero;
5985 w->last_facechange[DESIRED_DISP] = Qzero;
5987 regenerate_window (w, startp, pointm, DESIRED_DISP);
5989 if (!point_visible (w, pointm, DESIRED_DISP) && !inactive_minibuffer)
5991 pointm = point_at_center (w, DESIRED_DISP, 0, 0);
5993 if (selected_globally)
5994 BUF_SET_PT (b, pointm);
5996 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm),
5999 /* #### BUFU amounts of overkill just to get the cursor
6000 location marked properly. FIX ME FIX ME FIX ME */
6001 regenerate_window (w, startp, pointm, DESIRED_DISP);
6004 goto regeneration_done;
6007 /* If nothing has changed since the last redisplay, then we just
6008 need to make sure that point is still visible. */
6009 if (XINT (w->last_modified[CURRENT_DISP]) >= BUF_MODIFF (b)
6010 && XINT (w->last_facechange[CURRENT_DISP]) >= BUF_FACECHANGE (b)
6012 /* This check is to make sure we restore the minibuffer after a
6013 temporary change to the echo area. */
6014 && !(MINI_WINDOW_P (w) && f->buffers_changed)
6015 && !f->frame_changed
6016 && !truncation_changed
6017 /* check whether start is really at the begining of a line GE */
6018 && (!w->start_at_line_beg || beginning_of_line_p (b, startp))
6021 /* Check if the cursor has actually moved. */
6022 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
6023 && pointm == marker_position (w->last_point[CURRENT_DISP])
6024 && selected_globally
6025 && !w->windows_changed
6027 && !f->extents_changed
6028 && !f->faces_changed
6029 && !f->glyphs_changed
6030 && !f->subwindows_changed
6031 /* && !f->subwindows_state_changed*/
6032 && !f->point_changed
6033 && !f->windows_structure_changed)
6035 /* If not, we're done. */
6036 if (f->modeline_changed)
6037 regenerate_modeline (w);
6040 goto regeneration_done;
6044 /* If the new point is visible in the redisplay structures,
6045 then let the output update routines handle it, otherwise
6046 do things the hard way. */
6047 if (!w->windows_changed
6049 && !f->extents_changed
6050 && !f->faces_changed
6051 && !f->glyphs_changed
6052 && !f->subwindows_changed
6053 /* && !f->subwindows_state_changed*/
6054 && !f->windows_structure_changed)
6056 if (point_visible (w, pointm, CURRENT_DISP)
6057 && w->last_point_x[CURRENT_DISP] != -1
6058 && w->last_point_y[CURRENT_DISP] != -1)
6060 if (redisplay_move_cursor (w, pointm, FRAME_TTY_P (f)))
6062 /* Always regenerate in case it is displaying
6063 the current line or column. */
6064 regenerate_modeline (w);
6067 goto regeneration_done;
6070 else if (!selected_in_its_frame && !f->point_changed)
6072 if (f->modeline_changed)
6073 regenerate_modeline (w);
6076 goto regeneration_done;
6080 /* If we weren't able to take the shortcut method, then use
6081 the brute force method. */
6082 regenerate_window (w, startp, pointm, DESIRED_DISP);
6084 if (point_visible (w, pointm, DESIRED_DISP))
6085 goto regeneration_done;
6089 /* Check if the starting point is no longer at the beginning of a
6090 line, in which case find a new starting point. We also recenter
6091 if our start position is equal to point-max. Otherwise we'll end
6092 up with a blank window. */
6093 else if (((w->start_at_line_beg || MINI_WINDOW_P (w))
6094 && !(startp == BUF_BEGV (b)
6095 || BUF_FETCH_CHAR (b, startp - 1) == '\n'))
6096 || (pointm == startp &&
6097 EQ (Fmarker_buffer (w->last_start[CURRENT_DISP]), w->buffer) &&
6098 startp < marker_position (w->last_start[CURRENT_DISP]))
6099 || (startp == BUF_ZV (b)))
6101 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6103 goto regeneration_done;
6105 /* See if we can update the data structures locally based on
6106 knowledge of what changed in the buffer. */
6107 else if (!w->windows_changed
6109 && !f->faces_changed
6110 && !f->glyphs_changed
6111 && !f->subwindows_changed
6112 /* && !f->subwindows_state_changed*/
6113 && !f->windows_structure_changed
6114 && !f->frame_changed
6115 && !truncation_changed
6117 && regenerate_window_incrementally (w, startp, pointm))
6119 if (f->modeline_changed
6120 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b)
6121 || XINT (w->last_facechange[CURRENT_DISP]) < BUF_FACECHANGE (b))
6122 regenerate_modeline (w);
6125 goto regeneration_done;
6127 /* #### This is where a check for structure based scrolling would go. */
6128 /* If all else fails, try just regenerating and see what happens. */
6131 regenerate_window (w, startp, pointm, DESIRED_DISP);
6133 if (point_visible (w, pointm, DESIRED_DISP))
6134 goto regeneration_done;
6137 /* We still haven't gotten the window regenerated with point
6138 visible. Next we try scrolling a little and see if point comes
6139 back onto the screen. */
6140 if (scroll_step > 0)
6142 int scrolled = scroll_conservatively;
6143 for (; scrolled >= 0; scrolled -= scroll_step)
6145 startp = vmotion (w, startp,
6146 (pointm < startp) ? -scroll_step : scroll_step, 0);
6147 regenerate_window (w, startp, pointm, DESIRED_DISP);
6149 if (point_visible (w, pointm, DESIRED_DISP))
6150 goto regeneration_done;
6154 /* We still haven't managed to get the screen drawn with point on
6155 the screen, so just center it and be done with it. */
6156 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6161 /* If the window's frame is changed then reset the current display
6162 lines in order to force a full repaint. */
6163 if (f->frame_changed)
6165 display_line_dynarr *cla = window_display_lines (w, CURRENT_DISP);
6170 /* Must do this before calling redisplay_output_window because it
6171 sets some markers on the window. */
6174 w->buffer = old_buffer;
6175 Fset_marker (w->pointm[DESIRED_DISP], make_int (old_pointm), old_buffer);
6176 Fset_marker (w->start[DESIRED_DISP], make_int (old_startp), old_buffer);
6179 /* These also have to be set before calling redisplay_output_window
6180 since it sets the CURRENT_DISP values based on them. */
6181 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
6182 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
6183 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
6184 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
6188 Bufpos start = marker_position (w->start[DESIRED_DISP]);
6189 Bufpos end = (w->window_end_pos[DESIRED_DISP] == -1
6191 : BUF_Z (b) - w->window_end_pos[DESIRED_DISP] - 1);
6192 /* Don't pollute the cache if not sure if we are correct */
6193 if (w->start_at_line_beg)
6194 update_line_start_cache (w, start, end, pointm, 1);
6195 redisplay_output_window (w);
6197 * If we just displayed the echo area, the line start cache is
6198 * no longer valid, because the minibuffer window is associated
6199 * with the window now.
6202 w->line_cache_last_updated = make_int (-1);
6205 /* #### This should be dependent on face changes and will need to be
6206 somewhere else once tty updates occur on a per-frame basis. */
6207 mark_face_cachels_as_clean (w);
6209 /* The glyph cachels only get dirty if someone changed something.
6210 Since redisplay has now effectively ended we can reset the dirty
6211 flag since everything must be up-to-date. */
6213 mark_glyph_cachels_as_clean (w);
6215 w->windows_changed = 0;
6218 /* Call buffer_reset_changes for all buffers present in any window
6219 currently visible in all frames on all devices. #### There has to
6220 be a better way to do this. */
6223 reset_buffer_changes_mapfun (struct window *w, void *ignored_closure)
6225 buffer_reset_changes (XBUFFER (w->buffer));
6230 reset_buffer_changes (void)
6232 Lisp_Object frmcons, devcons, concons;
6234 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
6236 struct frame *f = XFRAME (XCAR (frmcons));
6238 if (FRAME_REPAINT_P (f))
6239 map_windows (f, reset_buffer_changes_mapfun, 0);
6243 /* Ensure that all windows underneath the given window in the window
6244 hierarchy are correctly displayed. */
6247 redisplay_windows (Lisp_Object window, int skip_selected)
6249 for (; !NILP (window) ; window = XWINDOW (window)->next)
6251 redisplay_window (window, skip_selected);
6256 call_redisplay_end_triggers (struct window *w, void *closure)
6258 Bufpos lrpos = w->last_redisplay_pos;
6259 w->last_redisplay_pos = 0;
6260 if (!NILP (w->buffer)
6261 && !NILP (w->redisplay_end_trigger)
6266 if (MARKERP (w->redisplay_end_trigger)
6267 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
6268 pos = marker_position (w->redisplay_end_trigger);
6269 else if (INTP (w->redisplay_end_trigger))
6270 pos = XINT (w->redisplay_end_trigger);
6273 w->redisplay_end_trigger = Qnil;
6280 XSETWINDOW (window, w);
6281 va_run_hook_with_args_in_buffer (XBUFFER (w->buffer),
6282 Qredisplay_end_trigger_functions,
6284 w->redisplay_end_trigger);
6285 w->redisplay_end_trigger = Qnil;
6292 /* Ensure that all windows on the given frame are correctly displayed. */
6295 redisplay_frame (struct frame *f, int preemption_check)
6297 struct device *d = XDEVICE (f->device);
6299 if (preemption_check)
6301 /* The preemption check itself takes a lot of time,
6302 so normally don't do it here. We do it if called
6303 from Lisp, though (`redisplay-frame'). */
6306 REDISPLAY_PREEMPTION_CHECK;
6311 if (!internal_equal (f->old_buffer_alist, f->buffer_alist, 0))
6315 f->old_buffer_alist = Freplace_list (f->old_buffer_alist,
6317 XSETFRAME (frame, f);
6318 va_run_hook_with_args (Qbuffer_list_changed_hook, 1, frame);
6321 /* Before we put a hold on frame size changes, attempt to process
6322 any which are already pending. */
6323 if (f->size_change_pending)
6324 change_frame_size (f, f->new_height, f->new_width, 0);
6326 /* If frame size might need to be changed, due to changed size
6327 of toolbars, scrollbars etc, change it now */
6328 if (f->size_slipped)
6330 adjust_frame_size (f);
6331 assert (!f->size_slipped);
6334 /* The menubar, toolbar, and icon updates must be done before
6335 hold_frame_size_changes is called and we are officially
6336 'in_display'. They may eval lisp code which may call Fsignal.
6337 If in_display is set Fsignal will abort. */
6339 #ifdef HAVE_MENUBARS
6340 /* Update the menubar. It is done first since it could change
6341 the menubar's visibility. This way we avoid having flashing
6342 caused by an Expose event generated by the visibility change
6344 update_frame_menubars (f);
6345 #endif /* HAVE_MENUBARS */
6346 #ifdef HAVE_TOOLBARS
6347 /* Update the toolbars. */
6348 update_frame_toolbars (f);
6349 #endif /* HAVE_TOOLBARS */
6350 /* Gutter update proper has to be done inside display when no frame
6351 size changes can occur, thus we separately update the gutter
6352 geometry here if it needs it. */
6353 update_frame_gutter_geometry (f);
6355 /* If we clear the frame we have to force its contents to be redrawn. */
6357 f->frame_changed = 1;
6359 /* Invalidate the subwindow cache. We use subwindows_changed here to
6360 cause subwindows to get instantiated. This is because
6361 subwindows_state_changed is less strict - dealing with things
6362 like the clicked state of button. We have to do this before
6363 redisplaying the gutters as subwindows get unmapped in the
6365 if (f->frame_changed || f->subwindows_changed)
6367 /* we have to do this so the gutter gets regenerated. */
6368 reset_gutter_display_lines (f);
6371 hold_frame_size_changes ();
6373 /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */
6374 /* Within this section, we are defenseless and assume that the
6375 following cannot happen:
6377 1) garbage collection
6378 2) Lisp code evaluation
6379 3) frame size changes
6381 We ensure (3) by calling hold_frame_size_changes(), which
6382 will cause any pending frame size changes to get put on hold
6383 till after the end of the critical section. (1) follows
6384 automatically if (2) is met. #### Unfortunately, there are
6385 some places where Lisp code can be called within this section.
6386 We need to remove them.
6388 If Fsignal() is called during this critical section, we
6391 If garbage collection is called during this critical section,
6392 we simply return. #### We should abort instead.
6394 #### If a frame-size change does occur we should probably
6395 actually be preempting redisplay. */
6397 MAYBE_DEVMETH (d, frame_output_begin, (f));
6399 /* We can now update the gutters, safe in the knowledge that our
6400 efforts won't get undone. */
6402 /* This can call lisp, but redisplay is protected by binding
6403 inhibit_quit. More importantly the code involving display lines
6404 *assumes* that GC will not happen and so does not GCPRO
6405 anything. Since we use this code the whole time with the gutters
6406 we cannot allow GC to happen when manipulating the gutters. */
6407 update_frame_gutters (f);
6409 /* Erase the frame before outputting its contents. */
6412 MAYBE_DEVMETH (d, clear_frame, (f));
6415 /* Do the selected window first. */
6416 redisplay_window (FRAME_SELECTED_WINDOW (f), 0);
6418 /* Then do the rest. */
6419 redisplay_windows (f->root_window, 1);
6421 MAYBE_DEVMETH (d, frame_output_end, (f));
6423 update_frame_title (f);
6425 CLASS_RESET_CHANGED_FLAGS (f);
6426 f->window_face_cache_reset = 0;
6427 f->echo_area_garbaged = 0;
6430 if (!f->size_change_pending)
6431 f->size_changed = 0;
6433 /* ----------------- END CRITICAL REDISPLAY SECTION ---------------- */
6435 /* Allow frame size changes to occur again.
6437 #### what happens if changes to other frames happen? */
6438 unhold_one_frame_size_changes (f);
6440 map_windows (f, call_redisplay_end_triggers, 0);
6444 /* Ensure that all frames on the given device are correctly displayed.
6445 If AUTOMATIC is non-zero, and the device implementation indicates
6446 no automatic redisplay, as printers do, then the device is not
6447 redisplayed. AUTOMATIC is set to zero when called from lisp
6448 functions (redraw-device) and (redisplay-device), and to non-zero
6449 when called from "lazy" redisplay();
6453 redisplay_device (struct device *d, int automatic)
6455 Lisp_Object frame, frmcons;
6457 int size_change_failed = 0;
6461 && (MAYBE_INT_DEVMETH (d, device_implementation_flags, ())
6462 & XDEVIMPF_NO_AUTO_REDISPLAY))
6465 if (DEVICE_STREAM_P (d)) /* nothing to do */
6468 /* It is possible that redisplay has been called before the
6469 device is fully initialized. If so then continue with the
6471 if (NILP (DEVICE_SELECTED_FRAME (d)))
6474 REDISPLAY_PREEMPTION_CHECK;
6478 /* Always do the selected frame first. */
6479 frame = DEVICE_SELECTED_FRAME (d);
6483 if (f->icon_changed || f->windows_changed)
6484 update_frame_icon (f);
6486 if (FRAME_REPAINT_P (f))
6488 if (CLASS_REDISPLAY_FLAGS_CHANGEDP(f))
6490 preempted = redisplay_frame (f, 0);
6496 /* If the frame redisplay did not get preempted, then this flag
6497 should have gotten set to 0. It might be possible for that
6498 not to happen if a size change event were to occur at an odd
6499 time. To make sure we don't miss anything we simply don't
6500 reset the top level flags until the condition ends up being
6501 in the right state. */
6502 if (f->size_changed)
6503 size_change_failed = 1;
6506 DEVICE_FRAME_LOOP (frmcons, d)
6508 f = XFRAME (XCAR (frmcons));
6510 if (f == XFRAME (DEVICE_SELECTED_FRAME (d)))
6513 if (f->icon_changed || f->windows_changed)
6514 update_frame_icon (f);
6516 if (FRAME_REPAINT_P (f))
6518 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (f))
6520 preempted = redisplay_frame (f, 0);
6526 if (f->size_change_pending)
6527 size_change_failed = 1;
6531 /* If we get here then we redisplayed all of our frames without
6532 getting preempted so mark ourselves as clean. */
6533 CLASS_RESET_CHANGED_FLAGS (d);
6535 if (!size_change_failed)
6536 d->size_changed = 0;
6542 restore_profiling_redisplay_flag (Lisp_Object val)
6544 profiling_redisplay_flag = XINT (val);
6548 /* Ensure that all windows on all frames on all devices are displaying
6549 the current contents of their respective buffers. */
6552 redisplay_without_hooks (void)
6554 Lisp_Object devcons, concons;
6555 int size_change_failed = 0;
6556 int count = specpdl_depth ();
6558 if (profiling_active)
6560 record_unwind_protect (restore_profiling_redisplay_flag,
6561 make_int (profiling_redisplay_flag));
6562 profiling_redisplay_flag = 1;
6565 if (asynch_device_change_pending)
6566 handle_asynch_device_change ();
6568 if (!GLOBAL_REDISPLAY_FLAGS_CHANGEDP &&
6569 !disable_preemption && preemption_count < max_preempts)
6572 DEVICE_LOOP_NO_BREAK (devcons, concons)
6574 struct device *d = XDEVICE (XCAR (devcons));
6577 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (d))
6579 preempted = redisplay_device (d, 1);
6584 RESET_CHANGED_SET_FLAGS;
6588 /* See comment in redisplay_device. */
6589 if (d->size_changed)
6590 size_change_failed = 1;
6593 preemption_count = 0;
6595 /* Mark redisplay as accurate */
6596 GLOBAL_RESET_CHANGED_FLAGS;
6597 RESET_CHANGED_SET_FLAGS;
6601 mark_all_faces_as_clean ();
6605 if (!size_change_failed)
6608 reset_buffer_changes ();
6611 unbind_to (count, Qnil);
6617 if (last_display_warning_tick != display_warning_tick &&
6618 !inhibit_warning_display)
6620 /* If an error occurs during this function, oh well.
6621 If we report another warning, we could get stuck in an
6622 infinite loop reporting warnings. */
6623 call0_trapping_errors (0, Qdisplay_warning_buffer);
6624 last_display_warning_tick = display_warning_tick;
6626 /* The run_hook_trapping_errors functions are smart enough not
6627 to do any evalling if the hook function is empty, so there
6628 should not be any significant time loss. All places in the
6629 C code that call redisplay() are prepared to handle GCing,
6630 so we should be OK. */
6631 #ifndef INHIBIT_REDISPLAY_HOOKS
6632 run_hook_trapping_errors ("Error in pre-redisplay-hook",
6633 Qpre_redisplay_hook);
6634 #endif /* INHIBIT_REDISPLAY_HOOKS */
6636 redisplay_without_hooks ();
6638 #ifndef INHIBIT_REDISPLAY_HOOKS
6639 run_hook_trapping_errors ("Error in post-redisplay-hook",
6640 Qpost_redisplay_hook);
6641 #endif /* INHIBIT_REDISPLAY_HOOKS */
6645 static char window_line_number_buf[32];
6647 /* Efficiently determine the window line number, and return a pointer
6648 to its printed representation. Do this regardless of whether
6649 line-number-mode is on. The first line in the buffer is counted as
6650 1. If narrowing is in effect, the lines are counted from the
6651 beginning of the visible portion of the buffer. */
6653 window_line_number (struct window *w, int type)
6655 struct device *d = XDEVICE (XFRAME (w->frame)->device);
6656 struct buffer *b = XBUFFER (w->buffer);
6657 /* Be careful in the order of these tests. The first clause will
6658 fail if DEVICE_SELECTED_FRAME == Qnil (since w->frame cannot be).
6659 This can occur when the frame title is computed really early */
6661 ((EQ(DEVICE_SELECTED_FRAME(d), w->frame) &&
6662 (w == XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame(d)))) &&
6663 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
6664 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d )
6666 : marker_position (w->pointm[type]));
6669 line = buffer_line_number (b, pos, 1);
6671 long_to_string (window_line_number_buf, line + 1);
6673 return window_line_number_buf;
6677 /* Given a character representing an object in a modeline
6678 specification, return a string (stored into the global array
6679 `mode_spec_bufbyte_string') with the information that object
6682 This function is largely unchanged from previous versions of the
6685 Warning! This code is also used for frame titles and can be called
6686 very early in the device/frame update process! JV
6690 decode_mode_spec (struct window *w, Emchar spec, int type)
6692 Lisp_Object obj = Qnil;
6693 const char *str = NULL;
6694 struct buffer *b = XBUFFER (w->buffer);
6696 Dynarr_reset (mode_spec_bufbyte_string);
6700 /* print buffer name */
6705 /* print visited file name */
6710 /* print the current column */
6713 Bufpos pt = (w == XWINDOW (Fselected_window (Qnil)))
6715 : marker_position (w->pointm[type]);
6716 int col = column_at_point (b, pt, 1) + !!column_number_start_at_one;
6719 long_to_string (buf, col);
6721 Dynarr_add_many (mode_spec_bufbyte_string,
6722 (const Bufbyte *) buf, strlen (buf));
6724 goto decode_mode_spec_done;
6726 /* print the file coding system */
6730 Lisp_Object codesys = b->buffer_file_coding_system;
6731 /* Be very careful here not to get an error. */
6732 if (NILP (codesys) || SYMBOLP (codesys) || CODING_SYSTEMP (codesys))
6734 codesys = Ffind_coding_system (codesys);
6735 if (CODING_SYSTEMP (codesys))
6736 obj = XCODING_SYSTEM_MNEMONIC (codesys);
6739 #endif /* FILE_CODING */
6742 /* print the current line number */
6744 str = window_line_number (w, type);
6747 /* print value of mode-name (obsolete) */
6752 /* print hyphen and frame number, if != 1 */
6756 struct frame *f = XFRAME (w->frame);
6757 if (FRAME_TTY_P (f) && f->order_count > 1 && f->order_count <= 99999999)
6759 /* Naughty, naughty */
6760 char * writable_str = alloca_array (char, 10);
6761 sprintf (writable_str, "-%d", f->order_count);
6765 #endif /* HAVE_TTY */
6768 /* print Narrow if appropriate */
6770 if (BUF_BEGV (b) > BUF_BEG (b)
6771 || BUF_ZV (b) < BUF_Z (b))
6775 /* print %, * or hyphen, if buffer is read-only, modified or neither */
6777 str = (!NILP (b->read_only)
6779 : ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6784 /* print * or hyphen -- XEmacs change to allow a buffer to be
6785 read-only but still indicate whether it is modified. */
6787 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6789 : (!NILP (b->read_only)
6794 /* #### defined in 19.29 decode_mode_spec, but not in
6795 modeline-format doc string. */
6796 /* This differs from %* in that it ignores read-only-ness. */
6798 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6803 /* print process status */
6805 obj = Fget_buffer_process (w->buffer);
6807 str = GETTEXT ("no process");
6809 obj = Fsymbol_name (Fprocess_status (obj));
6812 /* Print name of selected frame. */
6814 obj = XFRAME (w->frame)->name;
6817 /* indicate TEXT or BINARY */
6819 /* #### NT does not use this any more. Now what? */
6823 /* print percent of buffer above top of window, or Top, Bot or All */
6826 Bufpos pos = marker_position (w->start[type]);
6828 /* This had better be while the desired lines are being done. */
6829 if (w->window_end_pos[type] <= BUF_Z (b) - BUF_ZV (b))
6831 if (pos <= BUF_BEGV (b))
6836 else if (pos <= BUF_BEGV (b))
6840 /* This hard limit is ok since the string it will hold has a
6841 fixed maximum length of 3. But just to be safe... */
6843 Charcount chars = pos - BUF_BEGV (b);
6844 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6846 /* Avoid overflow on big buffers */
6847 int percent = total > LONG_MAX/200 ?
6848 (chars + total/200) / (total / 100) :
6849 (chars * 100 + total/2) / total;
6851 /* We can't normally display a 3-digit number, so get us a
6852 2-digit number that is close. */
6856 sprintf (buf, "%d%%", percent);
6857 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6860 goto decode_mode_spec_done;
6865 /* print percent of buffer above bottom of window, perhaps plus
6866 Top, or print Bottom or All */
6869 Bufpos toppos = marker_position (w->start[type]);
6870 Bufpos botpos = BUF_Z (b) - w->window_end_pos[type];
6872 /* botpos is only accurate as of the last redisplay, so we can
6873 only treat it as a hint. In particular, after erase-buffer,
6874 botpos may be negative. */
6875 if (botpos < toppos)
6878 if (botpos >= BUF_ZV (b))
6880 if (toppos <= BUF_BEGV (b))
6887 /* This hard limit is ok since the string it will hold has a
6888 fixed maximum length of around 6. But just to be safe... */
6890 Charcount chars = botpos - BUF_BEGV (b);
6891 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6893 /* Avoid overflow on big buffers */
6894 int percent = total > LONG_MAX/200 ?
6895 (chars + total/200) / (total / 100) :
6896 (chars * 100 + total/2) / max (total, 1);
6898 /* We can't normally display a 3-digit number, so get us a
6899 2-digit number that is close. */
6903 if (toppos <= BUF_BEGV (b))
6904 sprintf (buf, "Top%d%%", percent);
6906 sprintf (buf, "%d%%", percent);
6908 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6911 goto decode_mode_spec_done;
6921 /* print one [ for each recursive editing level. */
6926 if (command_loop_level > 5)
6932 for (i = 0; i < command_loop_level; i++)
6933 Dynarr_add (mode_spec_bufbyte_string, '[');
6935 goto decode_mode_spec_done;
6938 /* print one ] for each recursive editing level. */
6943 if (command_loop_level > 5)
6949 for (i = 0; i < command_loop_level; i++)
6950 Dynarr_add (mode_spec_bufbyte_string, ']');
6952 goto decode_mode_spec_done;
6955 /* print infinitely many dashes -- handle at top level now */
6962 Dynarr_add_many (mode_spec_bufbyte_string,
6964 XSTRING_LENGTH (obj));
6966 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) str, strlen (str));
6968 decode_mode_spec_done:
6969 Dynarr_add (mode_spec_bufbyte_string, '\0');
6972 /* Given a display line, free all of its data structures. */
6975 free_display_line (struct display_line *dl)
6979 if (dl->display_blocks)
6981 for (block = 0; block < Dynarr_largest (dl->display_blocks); block++)
6983 struct display_block *db = Dynarr_atp (dl->display_blocks, block);
6985 Dynarr_free (db->runes);
6988 Dynarr_free (dl->display_blocks);
6989 dl->display_blocks = NULL;
6992 if (dl->left_glyphs)
6994 Dynarr_free (dl->left_glyphs);
6995 dl->left_glyphs = NULL;
6998 if (dl->right_glyphs)
7000 Dynarr_free (dl->right_glyphs);
7001 dl->right_glyphs = NULL;
7006 /* Given an array of display lines, free them and all data structures
7007 contained within them. */
7010 free_display_lines (display_line_dynarr *dla)
7014 for (line = 0; line < Dynarr_largest (dla); line++)
7016 free_display_line (Dynarr_atp (dla, line));
7022 /* Call internal free routine for each set of display lines. */
7025 free_display_structs (struct window_mirror *mir)
7027 if (mir->current_display_lines)
7029 free_display_lines (mir->current_display_lines);
7030 mir->current_display_lines = 0;
7033 if (mir->desired_display_lines)
7035 free_display_lines (mir->desired_display_lines);
7036 mir->desired_display_lines = 0;
7042 mark_glyph_block_dynarr (glyph_block_dynarr *gba)
7046 glyph_block *gb = Dynarr_atp (gba, 0);
7047 glyph_block *gb_last = Dynarr_atp (gba, Dynarr_length (gba));
7049 for (; gb < gb_last; gb++)
7051 if (!NILP (gb->glyph))
7052 mark_object (gb->glyph);
7053 if (!NILP (gb->extent))
7054 mark_object (gb->extent);
7059 /* See the comment in image_instantiate_cache_result as to why marking
7060 the glyph will also mark the image_instance. */
7062 mark_redisplay_structs (display_line_dynarr *dla)
7064 display_line *dl = Dynarr_atp (dla, 0);
7065 display_line *dl_last = Dynarr_atp (dla, Dynarr_length (dla));
7067 for (; dl < dl_last; dl++)
7069 display_block_dynarr *dba = dl->display_blocks;
7070 display_block *db = Dynarr_atp (dba, 0);
7071 display_block *db_last = Dynarr_atp (dba, Dynarr_length (dba));
7073 for (; db < db_last; db++)
7075 rune_dynarr *ra = db->runes;
7076 rune *r = Dynarr_atp (ra, 0);
7077 rune *r_last = Dynarr_atp (ra, Dynarr_length (ra));
7079 for (; r < r_last; r++)
7081 if (r->type == RUNE_DGLYPH)
7083 if (!NILP (r->object.dglyph.glyph))
7084 mark_object (r->object.dglyph.glyph);
7085 if (!NILP (r->object.dglyph.extent))
7086 mark_object (r->object.dglyph.extent);
7091 mark_glyph_block_dynarr (dl->left_glyphs);
7092 mark_glyph_block_dynarr (dl->right_glyphs);
7097 mark_window_mirror (struct window_mirror *mir)
7099 mark_redisplay_structs (mir->current_display_lines);
7100 mark_redisplay_structs (mir->desired_display_lines);
7103 mark_window_mirror (mir->next);
7106 mark_window_mirror (mir->hchild);
7107 else if (mir->vchild)
7108 mark_window_mirror (mir->vchild);
7112 mark_redisplay (void)
7114 Lisp_Object frmcons, devcons, concons;
7116 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
7118 struct frame *f = XFRAME (XCAR (frmcons));
7119 update_frame_window_mirror (f);
7120 mark_window_mirror (f->root_mirror);
7125 /*****************************************************************************
7126 Line Start Cache Description and Rationale
7128 The traditional scrolling code in Emacs breaks in a variable height world.
7129 It depends on the key assumption that the number of lines that can be
7130 displayed at any given time is fixed. This led to a complete separation
7131 of the scrolling code from the redisplay code. In order to fully support
7132 variable height lines, the scrolling code must actually be tightly
7133 integrated with redisplay. Only redisplay can determine how many lines
7134 will be displayed on a screen for any given starting point.
7136 What is ideally wanted is a complete list of the starting buffer position
7137 for every possible display line of a buffer along with the height of that
7138 display line. Maintaining such a full list would be very expensive. We
7139 settle for having it include information for all areas which we happen to
7140 generate anyhow (i.e. the region currently being displayed) and for those
7141 areas we need to work with.
7143 In order to ensure that the cache accurately represents what redisplay
7144 would actually show, it is necessary to invalidate it in many situations.
7145 If the buffer changes, the starting positions may no longer be correct.
7146 If a face or an extent has changed then the line heights may have altered.
7147 These events happen frequently enough that the cache can end up being
7148 constantly disabled. With this potentially constant invalidation when is
7149 the cache ever useful?
7151 Even if the cache is invalidated before every single usage, it is
7152 necessary. Scrolling often requires knowledge about display lines which
7153 are actually above or below the visible region. The cache provides a
7154 convenient light-weight method of storing this information for multiple
7155 display regions. This knowledge is necessary for the scrolling code to
7156 always obey the First Golden Rule of Redisplay.
7158 If the cache already contains all of the information that the scrolling
7159 routines happen to need so that it doesn't have to go generate it, then we
7160 are able to obey the Third Golden Rule of Redisplay. The first thing we
7161 do to help out the cache is to always add the displayed region. This
7162 region had to be generated anyway, so the cache ends up getting the
7163 information basically for free. In those cases where a user is simply
7164 scrolling around viewing a buffer there is a high probability that this is
7165 sufficient to always provide the needed information. The second thing we
7166 can do is be smart about invalidating the cache.
7168 TODO -- Be smart about invalidating the cache. Potential places:
7170 + Insertions at end-of-line which don't cause line-wraps do not alter the
7171 starting positions of any display lines. These types of buffer
7172 modifications should not invalidate the cache. This is actually a large
7173 optimization for redisplay speed as well.
7175 + Buffer modifications frequently only affect the display of lines at and
7176 below where they occur. In these situations we should only invalidate
7177 the part of the cache starting at where the modification occurs.
7179 In case you're wondering, the Second Golden Rule of Redisplay is not
7181 ****************************************************************************/
7183 /* This will get used quite a bit so we don't want to be constantly
7184 allocating and freeing it. */
7185 static line_start_cache_dynarr *internal_cache;
7187 /* Makes internal_cache represent the TYPE display structs and only
7188 the TYPE display structs. */
7191 update_internal_cache_list (struct window *w, int type)
7194 display_line_dynarr *dla = window_display_lines (w, type);
7196 Dynarr_reset (internal_cache);
7197 for (line = 0; line < Dynarr_length (dla); line++)
7199 struct display_line *dl = Dynarr_atp (dla, line);
7205 struct line_start_cache lsc;
7207 lsc.start = dl->bufpos;
7208 lsc.end = dl->end_bufpos;
7209 lsc.height = dl->ascent + dl->descent;
7211 Dynarr_add (internal_cache, lsc);
7216 /* Reset the line cache if necessary. This should be run at the
7217 beginning of any function which access the cache. */
7220 validate_line_start_cache (struct window *w)
7222 struct buffer *b = XBUFFER (w->buffer);
7223 struct frame *f = XFRAME (w->frame);
7225 if (!w->line_cache_validation_override)
7227 /* f->extents_changed used to be in here because extent face and
7228 size changes can cause text shifting. However, the extent
7229 covering the region is constantly having its face set and
7230 priority altered by the mouse code. This means that the line
7231 start cache is constantly being invalidated. This is bad
7232 since the mouse code also triggers heavy usage of the cache.
7233 Since it is an unlikely that f->extents being changed
7234 indicates that the cache really needs to be updated and if it
7235 does redisplay will catch it pretty quickly we no longer
7236 invalidate the cache if it is set. This greatly speeds up
7237 dragging out regions with the mouse. */
7238 if (XINT (w->line_cache_last_updated) < BUF_MODIFF (b)
7242 Dynarr_reset (w->line_start_cache);
7247 /* Return the very first buffer position contained in the given
7248 window's cache, or -1 if the cache is empty. Assumes that the
7252 line_start_cache_start (struct window *w)
7254 line_start_cache_dynarr *cache = w->line_start_cache;
7256 if (!Dynarr_length (cache))
7259 return Dynarr_atp (cache, 0)->start;
7262 /* Return the very last buffer position contained in the given
7263 window's cache, or -1 if the cache is empty. Assumes that the
7267 line_start_cache_end (struct window *w)
7269 line_start_cache_dynarr *cache = w->line_start_cache;
7271 if (!Dynarr_length (cache))
7274 return Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
7277 /* Return the index of the line POINT is contained within in window
7278 W's line start cache. It will enlarge the cache or move the cache
7279 window in order to have POINT be present in the cache. MIN_PAST is
7280 a guarantee of the number of entries in the cache present on either
7281 side of POINT (unless a buffer boundary is hit). If MIN_PAST is -1
7282 then it will be treated as 0, but the cache window will not be
7283 allowed to shift. Returns -1 if POINT cannot be found in the cache
7287 point_in_line_start_cache (struct window *w, Bufpos point, int min_past)
7289 struct buffer *b = XBUFFER (w->buffer);
7290 line_start_cache_dynarr *cache = w->line_start_cache;
7291 unsigned int top, bottom, pos;
7293 validate_line_start_cache (w);
7294 w->line_cache_validation_override++;
7296 /* Let functions pass in negative values, but we still treat -1
7298 /* #### bogosity alert */
7299 if (min_past < 0 && min_past != -1)
7300 min_past = -min_past;
7302 if (!Dynarr_length (cache) || line_start_cache_start (w) > point
7303 || line_start_cache_end (w) < point)
7306 int win_char_height = window_char_height (w, 1);
7308 /* Occasionally we get here with a 0 height
7309 window. find_next_newline_no_quit will abort if we pass it a
7310 count of 0 so handle that case. */
7311 if (!win_char_height)
7312 win_char_height = 1;
7314 if (!Dynarr_length (cache))
7316 Bufpos from = find_next_newline_no_quit (b, point, -1);
7317 Bufpos to = find_next_newline_no_quit (b, from, win_char_height);
7319 update_line_start_cache (w, from, to, point, 0);
7321 if (!Dynarr_length (cache))
7323 w->line_cache_validation_override--;
7328 assert (Dynarr_length (cache));
7331 while (line_start_cache_start (w) > point
7332 && (loop < cache_adjustment || min_past == -1))
7336 from = line_start_cache_start (w);
7337 if (from <= BUF_BEGV (b))
7340 from = find_next_newline_no_quit (b, from, -win_char_height);
7341 to = line_start_cache_end (w);
7343 update_line_start_cache (w, from, to, point, 0);
7347 if (line_start_cache_start (w) > point)
7351 from = find_next_newline_no_quit (b, point, -1);
7352 if (from >= BUF_ZV (b))
7354 to = find_next_newline_no_quit (b, from, -win_char_height);
7359 to = find_next_newline_no_quit (b, from, win_char_height);
7361 update_line_start_cache (w, from, to, point, 0);
7365 while (line_start_cache_end (w) < point
7366 && (loop < cache_adjustment || min_past == -1))
7370 to = line_start_cache_end (w);
7371 if (to >= BUF_ZV (b))
7374 from = line_start_cache_end (w);
7375 to = find_next_newline_no_quit (b, from, win_char_height);
7377 update_line_start_cache (w, from, to, point, 0);
7381 if (line_start_cache_end (w) < point)
7385 from = find_next_newline_no_quit (b, point, -1);
7386 if (from >= BUF_ZV (b))
7388 to = find_next_newline_no_quit (b, from, -win_char_height);
7393 to = find_next_newline_no_quit (b, from, win_char_height);
7395 update_line_start_cache (w, from, to, point, 0);
7399 assert (Dynarr_length (cache));
7404 /* This could happen if the buffer is narrowed. */
7405 if (line_start_cache_start (w) > point
7406 || line_start_cache_end (w) < point)
7408 w->line_cache_validation_override--;
7414 top = Dynarr_length (cache) - 1;
7419 unsigned int new_pos;
7422 pos = (bottom + top + 1) >> 1;
7423 start = Dynarr_atp (cache, pos)->start;
7424 end = Dynarr_atp (cache, pos)->end;
7426 if (point >= start && point <= end)
7428 if (pos < min_past && line_start_cache_start (w) > BUF_BEGV (b))
7431 find_next_newline_no_quit (b, line_start_cache_start (w),
7433 Bufpos to = line_start_cache_end (w);
7435 update_line_start_cache (w, from, to, point, 0);
7436 goto find_point_loop;
7438 else if ((Dynarr_length (cache) - pos - 1) < min_past
7439 && line_start_cache_end (w) < BUF_ZV (b))
7441 Bufpos from = line_start_cache_end (w);
7442 Bufpos to = find_next_newline_no_quit (b, from,
7447 update_line_start_cache (w, from, to, point, 0);
7448 goto find_point_loop;
7452 w->line_cache_validation_override--;
7456 else if (point > end)
7458 else if (point < start)
7463 new_pos = (bottom + top + 1) >> 1;
7466 w->line_cache_validation_override--;
7472 /* Return a boolean indicating if POINT would be visible in window W
7473 if display of the window was to begin at STARTP. */
7476 point_would_be_visible (struct window *w, Bufpos startp, Bufpos point)
7478 struct buffer *b = XBUFFER (w->buffer);
7479 int pixpos = -WINDOW_TEXT_TOP_CLIP(w);
7480 int bottom = WINDOW_TEXT_HEIGHT (w);
7483 /* If point is before the intended start it obviously can't be visible. */
7487 /* If point or start are not in the accessible buffer range, then
7489 if (startp < BUF_BEGV (b) || startp > BUF_ZV (b)
7490 || point < BUF_BEGV (b) || point > BUF_ZV (b))
7493 validate_line_start_cache (w);
7494 w->line_cache_validation_override++;
7496 start_elt = point_in_line_start_cache (w, startp, 0);
7497 if (start_elt == -1)
7499 w->line_cache_validation_override--;
7503 assert (line_start_cache_start (w) <= startp
7504 && line_start_cache_end (w) >= startp);
7510 /* Expand the cache if necessary. */
7511 if (start_elt == Dynarr_length (w->line_start_cache))
7514 Dynarr_atp (w->line_start_cache, start_elt - 1)->start;
7516 start_elt = point_in_line_start_cache (w, old_startp,
7517 window_char_height (w, 0));
7519 /* We've already actually processed old_startp, so increment
7523 /* If this happens we didn't add any extra elements. Bummer. */
7524 if (start_elt == Dynarr_length (w->line_start_cache))
7526 w->line_cache_validation_override--;
7531 height = Dynarr_atp (w->line_start_cache, start_elt)->height;
7533 if (pixpos + height > bottom)
7535 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7537 w->line_cache_validation_override--;
7543 if (point <= Dynarr_atp (w->line_start_cache, start_elt)->end)
7545 w->line_cache_validation_override--;
7553 /* For the given window W, if display starts at STARTP, what will be
7554 the buffer position at the beginning or end of the last line
7555 displayed. The end of the last line is also know as the window end
7558 WARNING: It is possible that rediplay failed to layout any lines for the
7559 windows. Under normal circumstances this is rare. However it seems that it
7560 does occur in the following situation: A mouse event has come in and we
7561 need to compute its location in a window. That code (in
7562 pixel_to_glyph_translation) already can handle 0 as an error return value.
7564 #### With a little work this could probably be reworked as just a
7565 call to start_with_line_at_pixpos. */
7568 start_end_of_last_line (struct window *w, Bufpos startp, int end,
7571 struct buffer *b = XBUFFER (w->buffer);
7572 line_start_cache_dynarr *cache = w->line_start_cache;
7574 int bottom = WINDOW_TEXT_HEIGHT (w);
7578 validate_line_start_cache (w);
7579 w->line_cache_validation_override++;
7581 if (startp < BUF_BEGV (b))
7582 startp = BUF_BEGV (b);
7583 else if (startp > BUF_ZV (b))
7584 startp = BUF_ZV (b);
7587 start_elt = point_in_line_start_cache (w, cur_start, 0);
7588 if (start_elt == -1)
7589 return may_error ? 0 : startp;
7593 int height = Dynarr_atp (cache, start_elt)->height;
7595 cur_start = Dynarr_atp (cache, start_elt)->start;
7597 if (pixpos + height > bottom)
7599 /* Adjust for any possible clip. */
7600 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7605 w->line_cache_validation_override--;
7609 return BUF_BEGV (b);
7613 w->line_cache_validation_override--;
7615 return Dynarr_atp (cache, start_elt)->end;
7617 return Dynarr_atp (cache, start_elt)->start;
7623 if (start_elt == Dynarr_length (cache))
7625 Bufpos from = line_start_cache_end (w);
7626 int win_char_height = window_char_height (w, 0);
7627 Bufpos to = find_next_newline_no_quit (b, from,
7632 /* We've hit the end of the bottom so that's what it is. */
7633 if (from >= BUF_ZV (b))
7635 w->line_cache_validation_override--;
7639 update_line_start_cache (w, from, to, BUF_PT (b), 0);
7641 /* Updating the cache invalidates any current indexes. */
7642 start_elt = point_in_line_start_cache (w, cur_start, -1) + 1;
7647 /* For the given window W, if display starts at STARTP, what will be
7648 the buffer position at the beginning of the last line displayed. */
7651 start_of_last_line (struct window *w, Bufpos startp)
7653 return start_end_of_last_line (w, startp, 0 , 0);
7656 /* For the given window W, if display starts at STARTP, what will be
7657 the buffer position at the end of the last line displayed. This is
7658 also know as the window end position. */
7661 end_of_last_line (struct window *w, Bufpos startp)
7663 return start_end_of_last_line (w, startp, 1, 0);
7667 end_of_last_line_may_error (struct window *w, Bufpos startp)
7669 return start_end_of_last_line (w, startp, 1, 1);
7673 /* For window W, what does the starting position have to be so that
7674 the line containing POINT will cover pixel position PIXPOS. */
7677 start_with_line_at_pixpos (struct window *w, Bufpos point, int pixpos)
7679 struct buffer *b = XBUFFER (w->buffer);
7681 Bufpos cur_pos, prev_pos = point;
7682 int point_line_height;
7683 int pixheight = pixpos - WINDOW_TEXT_TOP (w);
7685 validate_line_start_cache (w);
7686 w->line_cache_validation_override++;
7688 cur_elt = point_in_line_start_cache (w, point, 0);
7689 /* #### See comment in update_line_start_cache about big minibuffers. */
7692 w->line_cache_validation_override--;
7696 point_line_height = Dynarr_atp (w->line_start_cache, cur_elt)->height;
7700 cur_pos = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7702 pixheight -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7704 /* Do not take into account the value of vertical_clip here.
7705 That is the responsibility of the calling functions. */
7708 w->line_cache_validation_override--;
7709 if (-pixheight > point_line_height)
7710 /* We can't make the target line cover pixpos, so put it
7711 above pixpos. That way it will at least be visible. */
7721 int win_char_height;
7723 if (cur_pos <= BUF_BEGV (b))
7725 w->line_cache_validation_override--;
7726 return BUF_BEGV (b);
7729 win_char_height = window_char_height (w, 0);
7730 if (!win_char_height)
7731 win_char_height = 1;
7733 from = find_next_newline_no_quit (b, cur_pos, -win_char_height);
7734 to = line_start_cache_end (w);
7735 update_line_start_cache (w, from, to, point, 0);
7737 cur_elt = point_in_line_start_cache (w, cur_pos, 2) - 1;
7738 assert (cur_elt >= -1);
7739 /* This used to be cur_elt>=0 under the assumption that if
7740 point is in the top line and not at BUF_BEGV, then
7741 setting the window_start to a newline before the start of
7742 the first line will always cause scrolling.
7744 However in my (jv) opinion this is wrong. That new line
7745 can be hidden in various ways: invisible extents, an
7746 explicit window-start not at a newline character etc.
7747 The existence of those are indeed known to create crashes
7748 on that assert. So we have no option but to continue the
7749 search if we found point at the top of the line_start_cache
7751 cur_pos = Dynarr_atp (w->line_start_cache,0)->start;
7757 /* For window W, what does the starting position have to be so that
7758 the line containing point is on display line LINE. If LINE is
7759 positive it is considered to be the number of lines from the top of
7760 the window (0 is the top line). If it is negative the number is
7761 considered to be the number of lines from the bottom (-1 is the
7765 start_with_point_on_display_line (struct window *w, Bufpos point, int line)
7767 validate_line_start_cache (w);
7768 w->line_cache_validation_override++;
7772 int cur_elt = point_in_line_start_cache (w, point, line);
7774 if (cur_elt - line < 0)
7775 cur_elt = 0; /* Hit the top */
7779 w->line_cache_validation_override--;
7780 return Dynarr_atp (w->line_start_cache, cur_elt)->start;
7784 /* The calculated value of pixpos is correct for the bottom line
7785 or what we want when line is -1. Therefore we subtract one
7786 because we have already handled one line. */
7787 int new_line = -line - 1;
7788 int cur_elt = point_in_line_start_cache (w, point, new_line);
7789 int pixpos = WINDOW_TEXT_BOTTOM (w);
7790 Bufpos retval, search_point;
7792 /* If scroll_on_clipped_lines is false, the last "visible" line of
7793 the window covers the pixel at WINDOW_TEXT_BOTTOM (w) - 1.
7794 If s_o_c_l is true, then we don't want to count a clipped
7795 line, so back up from the bottom by the height of the line
7796 containing point. */
7797 if (scroll_on_clipped_lines)
7798 pixpos -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7802 if (cur_elt + new_line >= Dynarr_length (w->line_start_cache))
7804 /* Hit the bottom of the buffer. */
7806 (cur_elt + new_line) - Dynarr_length (w->line_start_cache) + 1;
7810 XSETWINDOW (window, w);
7811 default_face_height_and_width (window, &defheight, 0);
7813 cur_elt = Dynarr_length (w->line_start_cache) - 1;
7815 pixpos -= (adjustment * defheight);
7816 if (pixpos < WINDOW_TEXT_TOP (w))
7817 pixpos = WINDOW_TEXT_TOP (w);
7820 cur_elt = cur_elt + new_line;
7822 search_point = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7824 retval = start_with_line_at_pixpos (w, search_point, pixpos);
7825 w->line_cache_validation_override--;
7830 /* This is used to speed up vertical scrolling by caching the known
7831 buffer starting positions for display lines. This allows the
7832 scrolling routines to avoid costly calls to regenerate_window. If
7833 NO_REGEN is true then it will only add the values in the DESIRED
7834 display structs which are in the given range.
7836 Note also that the FROM/TO values are minimums. It is possible
7837 that this function will actually add information outside of the
7838 lines containing those positions. This can't hurt but it could
7841 #### We currently force the cache to have only 1 contiguous region.
7842 It might help to make the cache a dynarr of caches so that we can
7843 cover more areas. This might, however, turn out to be a lot of
7844 overhead for too little gain. */
7847 update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
7848 Bufpos point, int no_regen)
7850 struct buffer *b = XBUFFER (w->buffer);
7851 line_start_cache_dynarr *cache = w->line_start_cache;
7852 Bufpos low_bound, high_bound;
7854 validate_line_start_cache (w);
7855 w->line_cache_validation_override++;
7857 if (from < BUF_BEGV (b))
7858 from = BUF_BEGV (b);
7859 if (to > BUF_ZV (b))
7864 w->line_cache_validation_override--;
7868 if (Dynarr_length (cache))
7870 low_bound = line_start_cache_start (w);
7871 high_bound = line_start_cache_end (w);
7873 /* Check to see if the desired range is already in the cache. */
7874 if (from >= low_bound && to <= high_bound)
7876 w->line_cache_validation_override--;
7880 /* Check to make sure that the desired range is adjacent to the
7881 current cache. If not, invalidate the cache. */
7882 if (to < low_bound || from > high_bound)
7884 Dynarr_reset (cache);
7885 low_bound = high_bound = -1;
7890 low_bound = high_bound = -1;
7893 w->line_cache_last_updated = make_int (BUF_MODIFF (b));
7895 /* This could be integrated into the next two sections, but it is easier
7896 to follow what's going on by having it separate. */
7901 update_internal_cache_list (w, DESIRED_DISP);
7902 if (!Dynarr_length (internal_cache))
7904 w->line_cache_validation_override--;
7908 start = Dynarr_atp (internal_cache, 0)->start;
7910 Dynarr_atp (internal_cache, Dynarr_length (internal_cache) - 1)->end;
7912 /* We aren't allowed to generate additional information to fill in
7913 gaps, so if the DESIRED structs don't overlap the cache, reset the
7915 if (Dynarr_length (cache))
7917 if (end < low_bound || start > high_bound)
7918 Dynarr_reset (cache);
7920 /* #### What should really happen if what we are doing is
7921 extending a line (the last line)? */
7922 if (Dynarr_length (cache) == 1
7923 && Dynarr_length (internal_cache) == 1)
7924 Dynarr_reset (cache);
7927 if (!Dynarr_length (cache))
7929 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7930 Dynarr_length (internal_cache));
7931 w->line_cache_validation_override--;
7935 /* An extra check just in case the calling function didn't pass in
7936 the bounds of the DESIRED structs in the first place. */
7937 if (start >= low_bound && end <= high_bound)
7939 w->line_cache_validation_override--;
7943 /* At this point we know that the internal cache partially overlaps
7945 if (start < low_bound)
7947 int ic_elt = Dynarr_length (internal_cache) - 1;
7950 if (Dynarr_atp (internal_cache, ic_elt)->start < low_bound)
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_insert_many_at_start (cache, Dynarr_atp (internal_cache, 0),
7969 if (end > high_bound)
7973 while (ic_elt < Dynarr_length (internal_cache))
7975 if (Dynarr_atp (internal_cache, ic_elt)->start > high_bound)
7981 if (!(ic_elt < Dynarr_length (internal_cache)))
7983 Dynarr_reset (cache);
7984 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7985 Dynarr_length (internal_cache));
7986 w->line_cache_validation_override--;
7990 Dynarr_add_many (cache, Dynarr_atp (internal_cache, ic_elt),
7991 Dynarr_length (internal_cache) - ic_elt);
7994 w->line_cache_validation_override--;
7998 if (!Dynarr_length (cache) || from < low_bound)
8000 Bufpos startp = find_next_newline_no_quit (b, from, -1);
8002 int old_lb = low_bound;
8004 while (startp < old_lb || low_bound == -1)
8009 regenerate_window (w, startp, point, CMOTION_DISP);
8010 update_internal_cache_list (w, CMOTION_DISP);
8012 /* If this assert is triggered then regenerate_window failed
8013 to layout a single line. This is not possible since we
8014 force at least a single line to be layout for CMOTION_DISP */
8015 assert (Dynarr_length (internal_cache));
8016 assert (startp == Dynarr_atp (internal_cache, 0)->start);
8018 ic_elt = Dynarr_length (internal_cache) - 1;
8019 if (low_bound != -1)
8023 if (Dynarr_atp (internal_cache, ic_elt)->start < old_lb)
8029 assert (ic_elt >= 0);
8031 new_startp = Dynarr_atp (internal_cache, ic_elt)->end + 1;
8034 * Handle invisible text properly:
8035 * If the last line we're inserting has the same end as the
8036 * line before which it will be added, merge the two lines.
8038 if (Dynarr_length (cache) &&
8039 Dynarr_atp (internal_cache, ic_elt)->end ==
8040 Dynarr_atp (cache, marker)->end)
8042 Dynarr_atp (cache, marker)->start
8043 = Dynarr_atp (internal_cache, ic_elt)->start;
8044 Dynarr_atp (cache, marker)->height
8045 = Dynarr_atp (internal_cache, ic_elt)->height;
8049 if (ic_elt >= 0) /* we still have lines to add.. */
8051 Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0),
8052 ic_elt + 1, marker);
8053 marker += (ic_elt + 1);
8056 if (startp < low_bound || low_bound == -1)
8058 startp = new_startp;
8059 if (startp > BUF_ZV (b))
8061 w->line_cache_validation_override--;
8067 assert (Dynarr_length (cache));
8068 assert (from >= low_bound);
8070 /* Readjust the high_bound to account for any changes made while
8071 correcting the low_bound. */
8072 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8074 if (to > high_bound)
8076 Bufpos startp = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end + 1;
8080 regenerate_window (w, startp, point, CMOTION_DISP);
8081 update_internal_cache_list (w, CMOTION_DISP);
8083 /* See comment above about regenerate_window failing. */
8084 assert (Dynarr_length (internal_cache));
8086 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
8087 Dynarr_length (internal_cache));
8088 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8089 startp = high_bound + 1;
8091 while (to > high_bound);
8094 w->line_cache_validation_override--;
8095 assert (to <= high_bound);
8099 /* Given x and y coordinates in characters, relative to a window,
8100 return the pixel location corresponding to those coordinates. The
8101 pixel location returned is the center of the given character
8102 position. The pixel values are generated relative to the window,
8105 The modeline is considered to be part of the window. */
8108 glyph_to_pixel_translation (struct window *w, int char_x, int char_y,
8109 int *pix_x, int *pix_y)
8111 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
8112 int num_disp_lines, modeline;
8114 int defheight, defwidth;
8116 XSETWINDOW (window, w);
8117 default_face_height_and_width (window, &defheight, &defwidth);
8119 /* If we get a bogus value indicating somewhere above or to the left of
8120 the window, use the first window line or character position
8127 num_disp_lines = Dynarr_length (dla);
8131 if (Dynarr_atp (dla, 0)->modeline)
8138 /* First check if the y position intersects the display lines. */
8139 if (char_y < num_disp_lines)
8141 struct display_line *dl = Dynarr_atp (dla, char_y + modeline);
8142 struct display_block *db = get_display_block_from_line (dl, TEXT);
8144 *pix_y = (dl->ypos - dl->ascent +
8145 ((unsigned int) (dl->ascent + dl->descent - dl->clip) >> 1));
8147 if (char_x < Dynarr_length (db->runes))
8149 struct rune *rb = Dynarr_atp (db->runes, char_x);
8151 *pix_x = rb->xpos + (rb->width >> 1);
8155 int last_rune = Dynarr_length (db->runes) - 1;
8156 struct rune *rb = Dynarr_atp (db->runes, last_rune);
8158 char_x -= last_rune;
8160 *pix_x = rb->xpos + rb->width;
8161 *pix_x += ((char_x - 1) * defwidth);
8162 *pix_x += (defwidth >> 1);
8167 /* It didn't intersect, so extrapolate. #### For now, we include the
8168 modeline in this since we don't have true character positions in
8171 if (!Dynarr_length (w->face_cachels))
8172 reset_face_cachels (w);
8174 char_y -= num_disp_lines;
8176 if (Dynarr_length (dla))
8178 struct display_line *dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
8179 *pix_y = dl->ypos + dl->descent - dl->clip;
8182 *pix_y = WINDOW_TEXT_TOP (w);
8184 *pix_y += (char_y * defheight);
8185 *pix_y += (defheight >> 1);
8187 *pix_x = WINDOW_TEXT_LEFT (w);
8188 /* Don't adjust by one because this is still the unadjusted value. */
8189 *pix_x += (char_x * defwidth);
8190 *pix_x += (defwidth >> 1);
8193 if (*pix_x > w->pixel_left + w->pixel_width)
8194 *pix_x = w->pixel_left + w->pixel_width;
8195 if (*pix_y > w->pixel_top + w->pixel_height)
8196 *pix_y = w->pixel_top + w->pixel_height;
8198 *pix_x -= w->pixel_left;
8199 *pix_y -= w->pixel_top;
8202 /* Given a display line and a position, determine if there is a glyph
8203 there and return information about it if there is. */
8206 get_position_object (struct display_line *dl, Lisp_Object *obj1,
8207 Lisp_Object *obj2, int x_coord, int *low_x_coord,
8210 struct display_block *db;
8213 get_next_display_block (dl->bounds, dl->display_blocks, x_coord, 0);
8215 /* We use get_next_display_block to get the actual display block
8216 that would be displayed at x_coord. */
8218 if (block == NO_BLOCK)
8221 db = Dynarr_atp (dl->display_blocks, block);
8223 for (elt = 0; elt < Dynarr_length (db->runes); elt++)
8225 struct rune *rb = Dynarr_atp (db->runes, elt);
8227 if (rb->xpos <= x_coord && x_coord < (rb->xpos + rb->width))
8229 if (rb->type == RUNE_DGLYPH)
8231 *obj1 = rb->object.dglyph.glyph;
8232 *obj2 = rb->object.dglyph.extent;
8241 *low_x_coord = rb->xpos;
8243 *high_x_coord = rb->xpos + rb->width;
8250 #define UPDATE_CACHE_RETURN \
8252 d->pixel_to_glyph_cache.valid = 1; \
8253 d->pixel_to_glyph_cache.low_x_coord = low_x_coord; \
8254 d->pixel_to_glyph_cache.high_x_coord = high_x_coord; \
8255 d->pixel_to_glyph_cache.low_y_coord = low_y_coord; \
8256 d->pixel_to_glyph_cache.high_y_coord = high_y_coord; \
8257 d->pixel_to_glyph_cache.frame = f; \
8258 d->pixel_to_glyph_cache.col = *col; \
8259 d->pixel_to_glyph_cache.row = *row; \
8260 d->pixel_to_glyph_cache.obj_x = *obj_x; \
8261 d->pixel_to_glyph_cache.obj_y = *obj_y; \
8262 d->pixel_to_glyph_cache.w = *w; \
8263 d->pixel_to_glyph_cache.bufpos = *bufpos; \
8264 d->pixel_to_glyph_cache.closest = *closest; \
8265 d->pixel_to_glyph_cache.modeline_closest = *modeline_closest; \
8266 d->pixel_to_glyph_cache.obj1 = *obj1; \
8267 d->pixel_to_glyph_cache.obj2 = *obj2; \
8268 d->pixel_to_glyph_cache.retval = position; \
8269 RETURN_SANS_WARNINGS position; \
8272 /* Given x and y coordinates in pixels relative to a frame, return
8273 information about what is located under those coordinates.
8275 The return value will be one of:
8277 OVER_TOOLBAR: over one of the 4 frame toolbars
8278 OVER_MODELINE: over a modeline
8279 OVER_BORDER: over an internal border
8280 OVER_NOTHING: over the text area, but not over text
8281 OVER_OUTSIDE: outside of the frame border
8282 OVER_TEXT: over text in the text area
8288 -- nil if the coordinates are not over a glyph or a toolbar button.
8292 -- an extent, if the coordinates are over a glyph in the text area
8295 If the coordinates are over a glyph, OBJ_X and OBJ_Y give the
8296 equivalent coordinates relative to the upper-left corner of the glyph.
8298 If the coordinates are over a character, OBJ_X and OBJ_Y give the
8299 equivalent coordinates relative to the upper-left corner of the character.
8301 Otherwise, OBJ_X and OBJ_Y are undefined.
8305 pixel_to_glyph_translation (struct frame *f, int x_coord, int y_coord,
8306 int *col, int *row, int *obj_x, int *obj_y,
8307 struct window **w, Bufpos *bufpos,
8308 Bufpos *closest, Charcount *modeline_closest,
8309 Lisp_Object *obj1, Lisp_Object *obj2)
8312 struct pixel_to_glyph_translation_cache *cache;
8314 int frm_left, frm_right, frm_top, frm_bottom;
8315 int low_x_coord, high_x_coord, low_y_coord, high_y_coord;
8316 int position = OVER_NOTHING;
8317 int device_check_failed = 0;
8318 display_line_dynarr *dla;
8320 /* This is a safety valve in case this got called with a frame in
8321 the middle of being deleted. */
8322 if (!DEVICEP (f->device) || !DEVICE_LIVE_P (XDEVICE (f->device)))
8324 device_check_failed = 1;
8325 d = NULL, cache = NULL; /* Warning suppression */
8329 d = XDEVICE (f->device);
8330 cache = &d->pixel_to_glyph_cache;
8333 if (!device_check_failed
8335 && cache->frame == f
8336 && cache->low_x_coord <= x_coord
8337 && cache->high_x_coord > x_coord
8338 && cache->low_y_coord <= y_coord
8339 && cache->high_y_coord > y_coord)
8343 *obj_x = cache->obj_x;
8344 *obj_y = cache->obj_y;
8346 *bufpos = cache->bufpos;
8347 *closest = cache->closest;
8348 *modeline_closest = cache->modeline_closest;
8349 *obj1 = cache->obj1;
8350 *obj2 = cache->obj2;
8352 return cache->retval;
8363 *modeline_closest = -1;
8367 low_x_coord = x_coord;
8368 high_x_coord = x_coord + 1;
8369 low_y_coord = y_coord;
8370 high_y_coord = y_coord + 1;
8373 if (device_check_failed)
8374 return OVER_NOTHING;
8376 frm_left = FRAME_LEFT_BORDER_END (f);
8377 frm_right = FRAME_RIGHT_BORDER_START (f);
8378 frm_top = FRAME_TOP_BORDER_END (f);
8379 frm_bottom = FRAME_BOTTOM_BORDER_START (f);
8381 /* Check if the mouse is outside of the text area actually used by
8383 if (y_coord < frm_top)
8385 if (y_coord >= FRAME_TOP_BORDER_START (f))
8387 low_y_coord = FRAME_TOP_BORDER_START (f);
8388 high_y_coord = frm_top;
8389 position = OVER_BORDER;
8391 else if (y_coord >= 0)
8394 high_y_coord = FRAME_TOP_BORDER_START (f);
8395 position = OVER_TOOLBAR;
8399 low_y_coord = y_coord;
8401 position = OVER_OUTSIDE;
8404 else if (y_coord >= frm_bottom)
8406 if (y_coord < FRAME_BOTTOM_BORDER_END (f))
8408 low_y_coord = frm_bottom;
8409 high_y_coord = FRAME_BOTTOM_BORDER_END (f);
8410 position = OVER_BORDER;
8412 else if (y_coord < FRAME_PIXHEIGHT (f))
8414 low_y_coord = FRAME_BOTTOM_BORDER_END (f);
8415 high_y_coord = FRAME_PIXHEIGHT (f);
8416 position = OVER_TOOLBAR;
8420 low_y_coord = FRAME_PIXHEIGHT (f);
8421 high_y_coord = y_coord;
8422 position = OVER_OUTSIDE;
8426 if (position != OVER_TOOLBAR && position != OVER_BORDER)
8428 if (x_coord < frm_left)
8430 if (x_coord >= FRAME_LEFT_BORDER_START (f))
8432 low_x_coord = FRAME_LEFT_BORDER_START (f);
8433 high_x_coord = frm_left;
8434 position = OVER_BORDER;
8436 else if (x_coord >= 0)
8439 high_x_coord = FRAME_LEFT_BORDER_START (f);
8440 position = OVER_TOOLBAR;
8444 low_x_coord = x_coord;
8446 position = OVER_OUTSIDE;
8449 else if (x_coord >= frm_right)
8451 if (x_coord < FRAME_RIGHT_BORDER_END (f))
8453 low_x_coord = frm_right;
8454 high_x_coord = FRAME_RIGHT_BORDER_END (f);
8455 position = OVER_BORDER;
8457 else if (x_coord < FRAME_PIXWIDTH (f))
8459 low_x_coord = FRAME_RIGHT_BORDER_END (f);
8460 high_x_coord = FRAME_PIXWIDTH (f);
8461 position = OVER_TOOLBAR;
8465 low_x_coord = FRAME_PIXWIDTH (f);
8466 high_x_coord = x_coord;
8467 position = OVER_OUTSIDE;
8472 #ifdef HAVE_TOOLBARS
8473 if (position == OVER_TOOLBAR)
8475 *obj1 = toolbar_button_at_pixpos (f, x_coord, y_coord);
8478 UPDATE_CACHE_RETURN;
8480 #endif /* HAVE_TOOLBARS */
8482 /* We still have to return the window the pointer is next to and its
8483 relative y position even if it is outside the x boundary. */
8484 if (x_coord < frm_left)
8486 else if (x_coord > frm_right)
8487 x_coord = frm_right;
8489 /* Same in reverse. */
8490 if (y_coord < frm_top)
8492 else if (y_coord > frm_bottom)
8493 y_coord = frm_bottom;
8495 /* Find what window the given coordinates are actually in. */
8496 window = f->root_window;
8497 *w = find_window_by_pixel_pos (x_coord, y_coord, window);
8499 /* If we didn't find a window, we're done. */
8502 UPDATE_CACHE_RETURN;
8504 else if (position != OVER_NOTHING)
8507 *modeline_closest = -1;
8509 if (high_y_coord <= frm_top || high_y_coord >= frm_bottom)
8512 UPDATE_CACHE_RETURN;
8516 /* Check if the window is a minibuffer but isn't active. */
8517 if (MINI_WINDOW_P (*w) && !minibuf_level)
8519 /* Must reset the window value since some callers will ignore
8520 the return value if it is set. */
8522 UPDATE_CACHE_RETURN;
8525 /* See if the point is over window vertical divider */
8526 if (window_needs_vertical_divider (*w))
8528 int div_x_high = WINDOW_RIGHT (*w);
8529 int div_x_low = div_x_high - window_divider_width (*w);
8530 int div_y_high = WINDOW_BOTTOM (*w);
8531 int div_y_low = WINDOW_TOP (*w);
8533 if (div_x_low < x_coord && x_coord <= div_x_high &&
8534 div_y_low < y_coord && y_coord <= div_y_high)
8536 low_x_coord = div_x_low;
8537 high_x_coord = div_x_high;
8538 low_y_coord = div_y_low;
8539 high_y_coord = div_y_high;
8540 position = OVER_V_DIVIDER;
8541 UPDATE_CACHE_RETURN;
8545 dla = window_display_lines (*w, CURRENT_DISP);
8547 for (*row = 0; *row < Dynarr_length (dla); (*row)++)
8549 int really_over_nothing = 0;
8550 struct display_line *dl = Dynarr_atp (dla, *row);
8552 if ((int) (dl->ypos - dl->ascent) <= y_coord
8553 && y_coord <= (int) (dl->ypos + dl->descent))
8555 int check_margin_glyphs = 0;
8556 struct display_block *db = get_display_block_from_line (dl, TEXT);
8557 struct rune *rb = 0;
8559 if (x_coord < dl->bounds.left_white
8560 || x_coord >= dl->bounds.right_white)
8561 check_margin_glyphs = 1;
8563 low_y_coord = dl->ypos - dl->ascent;
8564 high_y_coord = dl->ypos + dl->descent + 1;
8566 if (position == OVER_BORDER
8567 || position == OVER_OUTSIDE
8568 || check_margin_glyphs)
8570 int x_check, left_bound;
8572 if (check_margin_glyphs)
8575 left_bound = dl->bounds.left_white;
8579 x_check = high_x_coord;
8580 left_bound = frm_left;
8583 if (Dynarr_length (db->runes))
8585 if (x_check <= left_bound)
8588 *modeline_closest = Dynarr_atp (db->runes, 0)->bufpos;
8590 *closest = Dynarr_atp (db->runes, 0)->bufpos;
8596 Dynarr_atp (db->runes,
8597 Dynarr_length (db->runes) - 1)->bufpos;
8600 Dynarr_atp (db->runes,
8601 Dynarr_length (db->runes) - 1)->bufpos;
8605 *modeline_closest += dl->offset;
8607 *closest += dl->offset;
8611 /* #### What should be here. */
8613 *modeline_closest = 0;
8618 if (check_margin_glyphs)
8620 if (x_coord < dl->bounds.left_in
8621 || x_coord >= dl->bounds.right_in)
8623 /* If we are over the outside margins then we
8624 know the loop over the text block isn't going
8625 to accomplish anything. So we go ahead and
8626 set what information we can right here and
8629 *obj_y = y_coord - (dl->ypos - dl->ascent);
8630 get_position_object (dl, obj1, obj2, x_coord,
8631 &low_x_coord, &high_x_coord);
8633 UPDATE_CACHE_RETURN;
8637 UPDATE_CACHE_RETURN;
8640 for (*col = 0; *col <= Dynarr_length (db->runes); (*col)++)
8642 int past_end = (*col == Dynarr_length (db->runes));
8645 rb = Dynarr_atp (db->runes, *col);
8648 (rb->xpos <= x_coord && x_coord < rb->xpos + rb->width))
8653 rb = Dynarr_atp (db->runes, *col);
8656 *bufpos = rb->bufpos + dl->offset;
8657 low_x_coord = rb->xpos;
8658 high_x_coord = rb->xpos + rb->width;
8660 if (rb->type == RUNE_DGLYPH)
8664 /* Find the first character after the glyph. */
8665 while (elt < Dynarr_length (db->runes))
8667 if (Dynarr_atp (db->runes, elt)->type != RUNE_DGLYPH)
8671 (Dynarr_atp (db->runes, elt)->bufpos +
8675 (Dynarr_atp (db->runes, elt)->bufpos +
8683 /* In this case we failed to find a non-glyph
8684 character so we return the last position
8685 displayed on the line. */
8686 if (elt == Dynarr_length (db->runes))
8689 *modeline_closest = dl->end_bufpos + dl->offset;
8691 *closest = dl->end_bufpos + dl->offset;
8692 really_over_nothing = 1;
8698 *modeline_closest = rb->bufpos + dl->offset;
8700 *closest = rb->bufpos + dl->offset;
8705 *row = window_displayed_height (*w);
8707 if (position == OVER_NOTHING)
8708 position = OVER_MODELINE;
8710 if (rb->type == RUNE_DGLYPH)
8712 *obj1 = rb->object.dglyph.glyph;
8713 *obj2 = rb->object.dglyph.extent;
8715 else if (rb->type == RUNE_CHAR)
8726 UPDATE_CACHE_RETURN;
8729 || (rb->type == RUNE_CHAR
8730 && EQ (rb->object.cglyph.charset,
8732 && rb->object.cglyph.code_point == '\n'))
8735 /* At this point we may have glyphs in the right
8737 if (check_margin_glyphs)
8738 get_position_object (dl, obj1, obj2, x_coord,
8739 &low_x_coord, &high_x_coord);
8740 UPDATE_CACHE_RETURN;
8745 if (rb->type == RUNE_DGLYPH)
8747 *obj1 = rb->object.dglyph.glyph;
8748 *obj2 = rb->object.dglyph.extent;
8750 else if (rb->type == RUNE_CHAR)
8761 *obj_x = x_coord - rb->xpos;
8762 *obj_y = y_coord - (dl->ypos - dl->ascent);
8764 /* At this point we may have glyphs in the left
8766 if (check_margin_glyphs)
8767 get_position_object (dl, obj1, obj2, x_coord, 0, 0);
8769 if (position == OVER_NOTHING && !really_over_nothing)
8770 position = OVER_TEXT;
8772 UPDATE_CACHE_RETURN;
8779 *row = Dynarr_length (dla) - 1;
8780 if (FRAME_WIN_P (f))
8782 int bot_elt = Dynarr_length (dla) - 1;
8786 struct display_line *dl = Dynarr_atp (dla, bot_elt);
8787 int adj_area = y_coord - (dl->ypos + dl->descent);
8791 XSETWINDOW (lwin, *w);
8792 default_face_height_and_width (lwin, 0, &defheight);
8794 *row += (adj_area / defheight);
8798 /* #### This should be checked out some more to determine what
8799 should really be going on. */
8800 if (!MARKERP ((*w)->start[CURRENT_DISP]))
8803 *closest = end_of_last_line_may_error (*w,
8804 marker_position ((*w)->start[CURRENT_DISP]));
8806 UPDATE_CACHE_RETURN;
8808 #undef UPDATE_CACHE_RETURN
8811 /***************************************************************************/
8813 /* Lisp functions */
8815 /***************************************************************************/
8817 DEFUN ("redisplay-echo-area", Fredisplay_echo_area, 0, 0, 0, /*
8818 Ensure that all minibuffers are correctly showing the echo area.
8822 Lisp_Object devcons, concons;
8824 DEVICE_LOOP_NO_BREAK (devcons, concons)
8826 struct device *d = XDEVICE (XCAR (devcons));
8827 Lisp_Object frmcons;
8829 DEVICE_FRAME_LOOP (frmcons, d)
8831 struct frame *f = XFRAME (XCAR (frmcons));
8833 if (FRAME_REPAINT_P (f) && FRAME_HAS_MINIBUF_P (f))
8835 Lisp_Object window = FRAME_MINIBUF_WINDOW (f);
8837 MAYBE_DEVMETH (d, frame_output_begin, (f));
8840 * If the frame size has changed, there may be random
8841 * chud on the screen left from previous messages
8842 * because redisplay_frame hasn't been called yet.
8843 * Clear the screen to get rid of the potential mess.
8845 if (f->echo_area_garbaged)
8847 MAYBE_DEVMETH (d, clear_frame, (f));
8848 f->echo_area_garbaged = 0;
8850 redisplay_window (window, 0);
8851 MAYBE_DEVMETH (d, frame_output_end, (f));
8853 call_redisplay_end_triggers (XWINDOW (window), 0);
8862 restore_disable_preemption_value (Lisp_Object value)
8864 disable_preemption = XINT (value);
8868 DEFUN ("redraw-frame", Fredraw_frame, 0, 2, 0, /*
8869 Clear frame FRAME and output again what is supposed to appear on it.
8870 FRAME defaults to the selected frame if omitted.
8871 Normally, redisplay is preempted as normal if input arrives. However,
8872 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8873 input and is guaranteed to proceed to completion.
8875 (frame, no_preempt))
8877 struct frame *f = decode_frame (frame);
8878 int count = specpdl_depth ();
8880 if (!NILP (no_preempt))
8882 record_unwind_protect (restore_disable_preemption_value,
8883 make_int (disable_preemption));
8884 disable_preemption++;
8888 redisplay_frame (f, 1);
8890 /* See the comment in Fredisplay_frame. */
8891 RESET_CHANGED_SET_FLAGS;
8893 return unbind_to (count, Qnil);
8896 DEFUN ("redisplay-frame", Fredisplay_frame, 0, 2, 0, /*
8897 Ensure that FRAME's contents are correctly displayed.
8898 This differs from `redraw-frame' in that it only redraws what needs to
8899 be updated, as opposed to unconditionally clearing and redrawing
8901 FRAME defaults to the selected frame if omitted.
8902 Normally, redisplay is preempted as normal if input arrives. However,
8903 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8904 input and is guaranteed to proceed to completion.
8906 (frame, no_preempt))
8908 struct frame *f = decode_frame (frame);
8909 int count = specpdl_depth ();
8911 if (!NILP (no_preempt))
8913 record_unwind_protect (restore_disable_preemption_value,
8914 make_int (disable_preemption));
8915 disable_preemption++;
8918 redisplay_frame (f, 1);
8920 /* If we don't reset the global redisplay flafs here, subsequent
8921 changes to the display will not get registered by redisplay
8922 because it thinks it already has registered changes. If you
8923 really knew what you were doing you could confuse redisplay by
8924 calling Fredisplay_frame while updating another frame. We assume
8925 that if you know what you are doing you will not be that
8927 RESET_CHANGED_SET_FLAGS;
8929 return unbind_to (count, Qnil);
8932 DEFUN ("redraw-device", Fredraw_device, 0, 2, 0, /*
8933 Clear device DEVICE and output again what is supposed to appear on it.
8934 DEVICE defaults to the selected device if omitted.
8935 Normally, redisplay is preempted as normal if input arrives. However,
8936 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8937 input and is guaranteed to proceed to completion.
8939 (device, no_preempt))
8941 struct device *d = decode_device (device);
8942 Lisp_Object frmcons;
8943 int count = specpdl_depth ();
8945 if (!NILP (no_preempt))
8947 record_unwind_protect (restore_disable_preemption_value,
8948 make_int (disable_preemption));
8949 disable_preemption++;
8952 DEVICE_FRAME_LOOP (frmcons, d)
8954 XFRAME (XCAR (frmcons))->clear = 1;
8956 redisplay_device (d, 0);
8958 /* See the comment in Fredisplay_frame. */
8959 RESET_CHANGED_SET_FLAGS;
8961 return unbind_to (count, Qnil);
8964 DEFUN ("redisplay-device", Fredisplay_device, 0, 2, 0, /*
8965 Ensure that DEVICE's contents are correctly displayed.
8966 This differs from `redraw-device' in that it only redraws what needs to
8967 be updated, as opposed to unconditionally clearing and redrawing
8969 DEVICE defaults to the selected device if omitted.
8970 Normally, redisplay is preempted as normal if input arrives. However,
8971 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8972 input and is guaranteed to proceed to completion.
8974 (device, no_preempt))
8976 struct device *d = decode_device (device);
8977 int count = specpdl_depth ();
8979 if (!NILP (no_preempt))
8981 record_unwind_protect (restore_disable_preemption_value,
8982 make_int (disable_preemption));
8983 disable_preemption++;
8986 redisplay_device (d, 0);
8988 /* See the comment in Fredisplay_frame. */
8989 RESET_CHANGED_SET_FLAGS;
8991 return unbind_to (count, Qnil);
8994 /* Big lie. Big lie. This will force all modelines to be updated
8995 regardless if the all flag is set or not. It remains in existence
8996 solely for backwards compatibility. */
8997 DEFUN ("redraw-modeline", Fredraw_modeline, 0, 1, 0, /*
8998 Force the modeline of the current buffer to be redisplayed.
8999 With optional non-nil ALL, force redisplay of all modelines.
9003 MARK_MODELINE_CHANGED;
9007 DEFUN ("force-cursor-redisplay", Fforce_cursor_redisplay, 0, 1, 0, /*
9008 Force an immediate update of the cursor on FRAME.
9009 FRAME defaults to the selected frame if omitted.
9013 redisplay_redraw_cursor (decode_frame (frame), 1);
9018 /***************************************************************************/
9020 /* Lisp-variable change triggers */
9022 /***************************************************************************/
9025 margin_width_changed_in_frame (Lisp_Object specifier, struct frame *f,
9028 /* Nothing to be done? */
9032 redisplay_variable_changed (Lisp_Object sym, Lisp_Object *val,
9033 Lisp_Object in_object, int flags)
9035 /* #### clip_changed should really be renamed something like
9036 global_redisplay_change. */
9041 /* This is called if the built-in glyphs have their properties
9044 redisplay_glyph_changed (Lisp_Object glyph, Lisp_Object property,
9047 if (WINDOWP (locale))
9049 MARK_FRAME_GLYPHS_CHANGED (XFRAME (WINDOW_FRAME (XWINDOW (locale))));
9051 else if (FRAMEP (locale))
9053 MARK_FRAME_GLYPHS_CHANGED (XFRAME (locale));
9055 else if (DEVICEP (locale))
9057 Lisp_Object frmcons;
9058 DEVICE_FRAME_LOOP (frmcons, XDEVICE (locale))
9059 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9061 else if (CONSOLEP (locale))
9063 Lisp_Object frmcons, devcons;
9064 CONSOLE_FRAME_LOOP_NO_BREAK (frmcons, devcons, XCONSOLE (locale))
9065 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9067 else /* global or buffer */
9069 Lisp_Object frmcons, devcons, concons;
9070 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
9071 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9076 text_cursor_visible_p_changed (Lisp_Object specifier, struct window *w,
9079 if (XFRAME (w->frame)->init_finished)
9080 Fforce_cursor_redisplay (w->frame);
9083 #ifdef MEMORY_USAGE_STATS
9086 /***************************************************************************/
9088 /* memory usage computation */
9090 /***************************************************************************/
9093 compute_rune_dynarr_usage (rune_dynarr *dyn, struct overhead_stats *ovstats)
9095 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9099 compute_display_block_dynarr_usage (display_block_dynarr *dyn,
9100 struct overhead_stats *ovstats)
9107 total = Dynarr_memory_usage (dyn, ovstats);
9108 for (i = 0; i < Dynarr_largest (dyn); i++)
9109 total += compute_rune_dynarr_usage (Dynarr_at (dyn, i).runes, ovstats);
9115 compute_glyph_block_dynarr_usage (glyph_block_dynarr *dyn,
9116 struct overhead_stats *ovstats)
9118 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9122 compute_display_line_dynarr_usage (display_line_dynarr *dyn,
9123 struct overhead_stats *ovstats)
9130 total = Dynarr_memory_usage (dyn, ovstats);
9131 for (i = 0; i < Dynarr_largest (dyn); i++)
9133 struct display_line *dl = &Dynarr_at (dyn, i);
9134 total += compute_display_block_dynarr_usage(dl->display_blocks, ovstats);
9135 total += compute_glyph_block_dynarr_usage (dl->left_glyphs, ovstats);
9136 total += compute_glyph_block_dynarr_usage (dl->right_glyphs, ovstats);
9143 compute_line_start_cache_dynarr_usage (line_start_cache_dynarr *dyn,
9144 struct overhead_stats *ovstats)
9146 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9149 #endif /* MEMORY_USAGE_STATS */
9152 /***************************************************************************/
9154 /* initialization */
9156 /***************************************************************************/
9159 init_redisplay (void)
9161 disable_preemption = 0;
9162 preemption_count = 0;
9163 max_preempts = INIT_MAX_PREEMPTS;
9169 if (!cmotion_display_lines)
9170 cmotion_display_lines = Dynarr_new (display_line);
9171 if (!mode_spec_bufbyte_string)
9172 mode_spec_bufbyte_string = Dynarr_new (Bufbyte);
9173 if (!formatted_string_extent_dynarr)
9174 formatted_string_extent_dynarr = Dynarr_new (EXTENT);
9175 if (!formatted_string_extent_start_dynarr)
9176 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount);
9177 if (!formatted_string_extent_end_dynarr)
9178 formatted_string_extent_end_dynarr = Dynarr_new (Bytecount);
9179 if (!internal_cache)
9180 internal_cache = Dynarr_new (line_start_cache);
9183 /* window system is nil when in -batch mode */
9184 if (!initialized || noninteractive)
9187 /* If the user wants to use a window system, we shouldn't bother
9188 initializing the terminal. This is especially important when the
9189 terminal is so dumb that emacs gives up before and doesn't bother
9190 using the window system.
9192 If the DISPLAY environment variable is set, try to use X, and die
9193 with an error message if that doesn't work. */
9195 #ifdef HAVE_X_WINDOWS
9196 if (!strcmp (display_use, "x"))
9198 /* Some stuff checks this way early. */
9199 Vwindow_system = Qx;
9200 Vinitial_window_system = Qx;
9203 #endif /* HAVE_X_WINDOWS */
9205 #ifdef HAVE_MS_WINDOWS
9206 if (!strcmp (display_use, "mswindows"))
9208 /* Some stuff checks this way early. */
9209 Vwindow_system = Qmswindows;
9210 Vinitial_window_system = Qmswindows;
9213 #endif /* HAVE_MS_WINDOWS */
9216 /* If no window system has been specified, try to use the terminal. */
9219 stderr_out ("XEmacs: standard input is not a tty\n");
9223 /* Look at the TERM variable */
9224 if (!getenv ("TERM"))
9226 stderr_out ("Please set the environment variable TERM; see tset(1).\n");
9230 Vinitial_window_system = Qtty;
9232 #else /* not HAVE_TTY */
9233 /* No DISPLAY specified, and no TTY support. */
9234 stderr_out ("XEmacs: Cannot open display.\n\
9235 Please set the environmental variable DISPLAY to an appropriate value.\n");
9242 syms_of_redisplay (void)
9244 defsymbol (&Qcursor_in_echo_area, "cursor-in-echo-area");
9245 #ifndef INHIBIT_REDISPLAY_HOOKS
9246 defsymbol (&Qpre_redisplay_hook, "pre-redisplay-hook");
9247 defsymbol (&Qpost_redisplay_hook, "post-redisplay-hook");
9248 #endif /* INHIBIT_REDISPLAY_HOOKS */
9249 defsymbol (&Qdisplay_warning_buffer, "display-warning-buffer");
9250 defsymbol (&Qbar_cursor, "bar-cursor");
9251 defsymbol (&Qredisplay_end_trigger_functions,
9252 "redisplay-end-trigger-functions");
9253 defsymbol (&Qtop_bottom, "top-bottom");
9254 defsymbol (&Qbuffer_list_changed_hook, "buffer-list-changed-hook");
9256 DEFSUBR (Fredisplay_echo_area);
9257 DEFSUBR (Fredraw_frame);
9258 DEFSUBR (Fredisplay_frame);
9259 DEFSUBR (Fredraw_device);
9260 DEFSUBR (Fredisplay_device);
9261 DEFSUBR (Fredraw_modeline);
9262 DEFSUBR (Fforce_cursor_redisplay);
9266 vars_of_redisplay (void)
9270 staticpro (&last_arrow_position);
9271 staticpro (&last_arrow_string);
9272 last_arrow_position = Qnil;
9273 last_arrow_string = Qnil;
9276 /* #### Probably temporary */
9277 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /*
9278 \(Temporary) Setting this will impact the performance of the internal
9281 cache_adjustment = 2;
9283 DEFVAR_INT_MAGIC ("pixel-vertical-clip-threshold", &vertical_clip /*
9284 Minimum pixel height for clipped bottom display line.
9285 A clipped line shorter than this won't be displayed.
9287 redisplay_variable_changed);
9290 DEFVAR_INT_MAGIC ("pixel-horizontal-clip-threshold", &horizontal_clip /*
9291 Minimum visible area for clipped glyphs at right boundary.
9292 Clipped glyphs shorter than this won't be displayed.
9293 Only pixmap glyph instances are currently allowed to be clipped.
9295 redisplay_variable_changed);
9296 horizontal_clip = 5;
9298 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string /*
9299 String displayed by modeline-format's "%m" specification.
9301 Vglobal_mode_string = Qnil;
9303 DEFVAR_LISP_MAGIC ("overlay-arrow-position", &Voverlay_arrow_position /*
9304 Marker for where to display an arrow on top of the buffer text.
9305 This must be the beginning of a line in order to work.
9306 See also `overlay-arrow-string'.
9308 redisplay_variable_changed);
9309 Voverlay_arrow_position = Qnil;
9311 DEFVAR_LISP_MAGIC ("overlay-arrow-string", &Voverlay_arrow_string /*
9312 String or glyph to display as an arrow. See also `overlay-arrow-position'.
9313 (Note that despite the name of this variable, it can be set to a glyph as
9316 redisplay_variable_changed);
9317 Voverlay_arrow_string = Qnil;
9319 DEFVAR_INT ("scroll-step", &scroll_step /*
9320 *The number of lines to try scrolling a window by when point moves out.
9321 If that fails to bring point back on frame, point is centered instead.
9322 If this is zero, point is always centered after it moves off screen.
9326 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively /*
9327 *Scroll up to this many lines, to bring point back on screen.
9329 scroll_conservatively = 0;
9331 DEFVAR_BOOL_MAGIC ("truncate-partial-width-windows",
9332 &truncate_partial_width_windows /*
9333 *Non-nil means truncate lines in all windows less than full frame wide.
9335 redisplay_variable_changed);
9336 truncate_partial_width_windows = 1;
9338 DEFVAR_LISP ("visible-bell", &Vvisible_bell /*
9339 *Non-nil substitutes a visual signal for the audible bell.
9341 Default behavior is to flash the whole screen. On some platforms,
9342 special effects are available using the following values:
9344 'display Flash the whole screen (ie, the default behavior).
9345 'top-bottom Flash only the top and bottom lines of the selected frame.
9347 When effects are unavailable on a platform, the visual bell is the
9348 default, whole screen. (Currently only X supports any special effects.)
9350 Vvisible_bell = Qnil;
9352 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter /*
9353 *Non-nil means no need to redraw entire frame after suspending.
9354 A non-nil value is useful if the terminal can automatically preserve
9355 Emacs's frame display when you reenter Emacs.
9356 It is up to you to set this variable if your terminal can do that.
9358 no_redraw_on_reenter = 0;
9360 DEFVAR_LISP ("window-system", &Vwindow_system /*
9361 A symbol naming the window-system under which Emacs is running,
9362 such as `x', or nil if emacs is running on an ordinary terminal.
9364 Do not use this variable, except for GNU Emacs compatibility, as it
9365 gives wrong values in a multi-device environment. Use `console-type'
9368 Vwindow_system = Qnil;
9370 /* #### Temporary shit until window-system is eliminated. */
9371 DEFVAR_CONST_LISP ("initial-window-system", &Vinitial_window_system /*
9374 Vinitial_window_system = Qnil;
9376 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area /*
9377 Non-nil means put cursor in minibuffer, at end of any message there.
9379 cursor_in_echo_area = 0;
9381 /* #### Shouldn't this be generalized as follows:
9383 if nil, use block cursor.
9384 if a number, use a bar cursor of that width.
9385 Otherwise, use a 1-pixel bar cursor.
9387 #### Or better yet, this variable should be trashed entirely
9388 (use a Lisp-magic variable to maintain compatibility)
9389 and a specifier `cursor-shape' added, which allows a block
9390 cursor, a bar cursor, a flashing block or bar cursor,
9391 maybe a caret cursor, etc. */
9393 DEFVAR_LISP ("bar-cursor", &Vbar_cursor /*
9394 Use vertical bar cursor if non-nil. If t width is 1 pixel, otherwise 2.
9398 #ifndef INHIBIT_REDISPLAY_HOOKS
9399 xxDEFVAR_LISP ("pre-redisplay-hook", &Vpre_redisplay_hook /*
9400 Function or functions to run before every redisplay.
9402 Vpre_redisplay_hook = Qnil;
9404 xxDEFVAR_LISP ("post-redisplay-hook", &Vpost_redisplay_hook /*
9405 Function or functions to run after every redisplay.
9407 Vpost_redisplay_hook = Qnil;
9408 #endif /* INHIBIT_REDISPLAY_HOOKS */
9410 DEFVAR_LISP ("buffer-list-changed-hook", &Vbuffer_list_changed_hook /*
9411 Function or functions to call when a frame's buffer list has changed.
9412 This is called during redisplay, before redisplaying each frame.
9413 Functions on this hook are called with one argument, the frame.
9415 Vbuffer_list_changed_hook = Qnil;
9417 DEFVAR_INT ("display-warning-tick", &display_warning_tick /*
9418 Bump this to tell the C code to call `display-warning-buffer'
9419 at next redisplay. You should not normally change this; the function
9420 `display-warning' automatically does this at appropriate times.
9422 display_warning_tick = 0;
9424 DEFVAR_BOOL ("inhibit-warning-display", &inhibit_warning_display /*
9425 Non-nil means inhibit display of warning messages.
9426 You should *bind* this, not set it. Any pending warning messages
9427 will be displayed when the binding no longer applies.
9429 /* reset to 0 by startup.el after the splash screen has displayed.
9430 This way, the warnings don't obliterate the splash screen. */
9431 inhibit_warning_display = 1;
9433 DEFVAR_LISP ("window-size-change-functions",
9434 &Vwindow_size_change_functions /*
9435 Not currently implemented.
9436 Functions called before redisplay, if window sizes have changed.
9437 The value should be a list of functions that take one argument.
9438 Just before redisplay, for each frame, if any of its windows have changed
9439 size since the last redisplay, or have been split or deleted,
9440 all the functions in the list are called, with the frame as argument.
9442 Vwindow_size_change_functions = Qnil;
9444 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions /*
9445 Not currently implemented.
9446 Functions to call before redisplaying a window with scrolling.
9447 Each function is called with two arguments, the window
9448 and its new display-start position. Note that the value of `window-end'
9449 is not valid when these functions are called.
9451 Vwindow_scroll_functions = Qnil;
9453 DEFVAR_LISP ("redisplay-end-trigger-functions",
9454 &Vredisplay_end_trigger_functions /*
9455 See `set-window-redisplay-end-trigger'.
9457 Vredisplay_end_trigger_functions = Qnil;
9459 DEFVAR_BOOL ("column-number-start-at-one", &column_number_start_at_one /*
9460 *Non-nil means column display number starts at 1.
9462 column_number_start_at_one = 0;
9466 specifier_vars_of_redisplay (void)
9468 DEFVAR_SPECIFIER ("left-margin-width", &Vleft_margin_width /*
9469 *Width of left margin.
9470 This is a specifier; use `set-specifier' to change it.
9472 Vleft_margin_width = Fmake_specifier (Qnatnum);
9473 set_specifier_fallback (Vleft_margin_width, list1 (Fcons (Qnil, Qzero)));
9474 set_specifier_caching (Vleft_margin_width,
9475 offsetof (struct window, left_margin_width),
9476 some_window_value_changed,
9477 offsetof (struct frame, left_margin_width),
9478 margin_width_changed_in_frame);
9480 DEFVAR_SPECIFIER ("right-margin-width", &Vright_margin_width /*
9481 *Width of right margin.
9482 This is a specifier; use `set-specifier' to change it.
9484 Vright_margin_width = Fmake_specifier (Qnatnum);
9485 set_specifier_fallback (Vright_margin_width, list1 (Fcons (Qnil, Qzero)));
9486 set_specifier_caching (Vright_margin_width,
9487 offsetof (struct window, right_margin_width),
9488 some_window_value_changed,
9489 offsetof (struct frame, right_margin_width),
9490 margin_width_changed_in_frame);
9492 DEFVAR_SPECIFIER ("minimum-line-ascent", &Vminimum_line_ascent /*
9493 *Minimum ascent height of lines.
9494 This is a specifier; use `set-specifier' to change it.
9496 Vminimum_line_ascent = Fmake_specifier (Qnatnum);
9497 set_specifier_fallback (Vminimum_line_ascent, list1 (Fcons (Qnil, Qzero)));
9498 set_specifier_caching (Vminimum_line_ascent,
9499 offsetof (struct window, minimum_line_ascent),
9500 some_window_value_changed,
9503 DEFVAR_SPECIFIER ("minimum-line-descent", &Vminimum_line_descent /*
9504 *Minimum descent height of lines.
9505 This is a specifier; use `set-specifier' to change it.
9507 Vminimum_line_descent = Fmake_specifier (Qnatnum);
9508 set_specifier_fallback (Vminimum_line_descent, list1 (Fcons (Qnil, Qzero)));
9509 set_specifier_caching (Vminimum_line_descent,
9510 offsetof (struct window, minimum_line_descent),
9511 some_window_value_changed,
9514 DEFVAR_SPECIFIER ("use-left-overflow", &Vuse_left_overflow /*
9515 *Non-nil means use the left outside margin as extra whitespace when
9516 displaying 'whitespace or 'inside-margin glyphs.
9517 This is a specifier; use `set-specifier' to change it.
9519 Vuse_left_overflow = Fmake_specifier (Qboolean);
9520 set_specifier_fallback (Vuse_left_overflow, list1 (Fcons (Qnil, Qnil)));
9521 set_specifier_caching (Vuse_left_overflow,
9522 offsetof (struct window, use_left_overflow),
9523 some_window_value_changed,
9526 DEFVAR_SPECIFIER ("use-right-overflow", &Vuse_right_overflow /*
9527 *Non-nil means use the right outside margin as extra whitespace when
9528 displaying 'whitespace or 'inside-margin glyphs.
9529 This is a specifier; use `set-specifier' to change it.
9531 Vuse_right_overflow = Fmake_specifier (Qboolean);
9532 set_specifier_fallback (Vuse_right_overflow, list1 (Fcons (Qnil, Qnil)));
9533 set_specifier_caching (Vuse_right_overflow,
9534 offsetof (struct window, use_right_overflow),
9535 some_window_value_changed,
9538 DEFVAR_SPECIFIER ("text-cursor-visible-p", &Vtext_cursor_visible_p /*
9539 *Non-nil means the text cursor is visible (this is usually the case).
9540 This is a specifier; use `set-specifier' to change it.
9542 Vtext_cursor_visible_p = Fmake_specifier (Qboolean);
9543 set_specifier_fallback (Vtext_cursor_visible_p, list1 (Fcons (Qnil, Qt)));
9544 set_specifier_caching (Vtext_cursor_visible_p,
9545 offsetof (struct window, text_cursor_visible_p),
9546 text_cursor_visible_p_changed,