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_emchar_string (struct window *w, int findex,
481 Emchar *str, Charcount len)
483 Charset_ID charsets[NUM_LEADING_BYTES];
486 find_charsets_in_emchar_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 Emchar_dynarr *rtw_emchar_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_emchar_dynarr)
503 rtw_emchar_dynarr = Dynarr_new (Emchar);
504 Dynarr_reset (rtw_emchar_dynarr);
506 fixup_internal_substring (nonreloc, reloc, offset, &len);
508 nonreloc = XSTRING_DATA (reloc);
509 convert_bufbyte_string_into_emchar_dynarr (nonreloc, len, rtw_emchar_dynarr);
510 return redisplay_text_width_emchar_string
511 (w, findex, Dynarr_atp (rtw_emchar_dynarr, 0),
512 Dynarr_length (rtw_emchar_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_emchar_dynarr)
525 rtw_emchar_dynarr = Dynarr_new (Emchar);
526 Dynarr_reset (rtw_emchar_dynarr);
528 fixup_internal_substring (nonreloc, reloc, offset, &len);
530 nonreloc = XSTRING_DATA (reloc);
531 convert_bufbyte_string_into_emchar_dynarr (nonreloc, len, rtw_emchar_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_emchar_dynarr, 0),
539 Dynarr_length (rtw_emchar_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;
834 if (data->bi_start_col_enabled)
836 return add_hscroll_rune (data);
839 if (data->ch == '\n')
841 data->font_is_bogus = 0;
842 /* Cheesy end-of-line pseudo-character. */
843 width = data->blank_width;
847 Lisp_Object charset = CHAR_CHARSET (data->ch);
848 if (!EQ (charset, data->last_charset) ||
849 data->findex != data->last_findex)
851 /* OK, we need to do things the hard way. */
852 struct window *w = XWINDOW (data->window);
853 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, data->findex);
854 Lisp_Object font_instance =
855 ensure_face_cachel_contains_charset (cachel, data->window,
857 Lisp_Font_Instance *fi;
859 if (EQ (font_instance, Vthe_null_font_instance))
861 font_instance = FACE_CACHEL_FONT (cachel, Vcharset_ascii);
862 data->font_is_bogus = 1;
865 data->font_is_bogus = 0;
867 fi = XFONT_INSTANCE (font_instance);
868 if (!fi->proportional_p)
869 /* sweetness and light. */
870 data->last_char_width = fi->width;
872 data->last_char_width = -1;
873 data->new_ascent = max (data->new_ascent, (int) fi->ascent);
874 data->new_descent = max (data->new_descent, (int) fi->descent);
875 data->last_charset = charset;
876 data->last_findex = data->findex;
879 width = data->last_char_width;
882 /* bummer. Proportional fonts. */
883 width = redisplay_text_width_emchar_string (XWINDOW (data->window),
889 if (data->max_pixpos != -1 && (data->pixpos + width > data->max_pixpos))
894 if (Dynarr_length (data->db->runes) < Dynarr_largest (data->db->runes))
896 crb = Dynarr_atp (data->db->runes, Dynarr_length (data->db->runes));
905 crb->findex = data->findex;
906 crb->xpos = data->pixpos;
910 if (NILP (data->string))
912 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
916 bytecount_to_charcount (XSTRING_DATA (data->string), data->bi_bufpos);
918 else if (data->is_modeline)
919 crb->bufpos = data->modeline_charpos;
921 /* Text but not in buffer */
923 crb->type = RUNE_CHAR;
924 crb->object.chr.ch = data->font_is_bogus ? '~' : data->ch;
927 if (data->cursor_type == CURSOR_ON)
929 if (data->bi_bufpos == data->bi_cursor_bufpos)
931 crb->cursor_type = CURSOR_ON;
932 data->cursor_x = Dynarr_length (data->db->runes);
935 crb->cursor_type = CURSOR_OFF;
937 else if (data->cursor_type == NEXT_CURSOR)
939 crb->cursor_type = CURSOR_ON;
940 data->cursor_x = Dynarr_length (data->db->runes);
941 data->cursor_type = NO_CURSOR;
943 else if (data->cursor_type == IGNORE_CURSOR)
944 crb->cursor_type = IGNORE_CURSOR;
946 crb->cursor_type = CURSOR_OFF;
949 Dynarr_add (data->db->runes, *crb);
951 Dynarr_increment (data->db->runes);
953 data->pixpos += width;
958 /* Given a string C_STRING of length C_LENGTH, call add_emchar_rune
959 for each character in the string. Propagate any left-over data
960 unless NO_PROP is non-zero. */
962 static prop_block_dynarr *
963 add_bufbyte_string_runes (pos_data *data, Bufbyte *c_string,
964 Bytecount c_length, int no_prop)
966 Bufbyte *pos, *end = c_string + c_length;
967 prop_block_dynarr *prop;
969 /* #### This function is too simplistic. It needs to do the same
970 sort of character interpretation (display-table lookup,
971 ctl-arrow checking), etc. that create_text_block() does.
972 The functionality to do this in that routine needs to be
975 for (pos = c_string; pos < end;)
977 data->ch = charptr_emchar (pos);
979 prop = add_emchar_rune (data);
987 struct prop_block pb;
988 Bytecount len = end - pos;
989 prop = Dynarr_new (prop_block);
991 pb.type = PROP_STRING;
992 pb.data.p_string.str = xnew_array (Bufbyte, len);
993 strncpy ((char *) pb.data.p_string.str, (char *) pos, len);
994 pb.data.p_string.len = len;
996 Dynarr_add (prop, pb);
1001 assert (pos <= end);
1007 /* Add a single rune of the specified width. The area covered by this
1008 rune will be displayed in the foreground color of the associated
1011 static prop_block_dynarr *
1012 add_blank_rune (pos_data *data, struct window *w, int char_tab_width)
1016 /* If data->start_col is not 0 then this call to add_blank_rune must have
1017 been to add it as a tab. */
1018 if (data->start_col)
1020 /* assert (w != NULL) */
1021 prop_block_dynarr *retval;
1023 /* If we have still not fully scrolled horizontally, subtract
1024 the width of this tab and return. */
1025 if (char_tab_width < data->start_col)
1027 data->start_col -= char_tab_width;
1030 else if (char_tab_width == data->start_col)
1031 data->blank_width = 0;
1034 int spcwid = space_width (w);
1036 if (spcwid >= data->blank_width)
1037 data->blank_width = 0;
1039 data->blank_width -= spcwid;
1042 data->start_col = 0;
1043 retval = add_hscroll_rune (data);
1045 /* Could be caused by the handling of the hscroll rune. */
1046 if (retval != NULL || !data->blank_width)
1050 /* Blank runes are always calculated to fit. */
1051 assert (data->pixpos + data->blank_width <= data->max_pixpos);
1053 rb.findex = data->findex;
1054 rb.xpos = data->pixpos;
1055 rb.width = data->blank_width;
1056 if (data->bi_bufpos)
1058 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
1061 /* #### and this is really correct too? */
1064 rb.type = RUNE_BLANK;
1066 if (data->cursor_type == CURSOR_ON)
1068 if (data->bi_bufpos == data->bi_cursor_bufpos)
1070 rb.cursor_type = CURSOR_ON;
1071 data->cursor_x = Dynarr_length (data->db->runes);
1074 rb.cursor_type = CURSOR_OFF;
1076 else if (data->cursor_type == NEXT_CURSOR)
1078 rb.cursor_type = CURSOR_ON;
1079 data->cursor_x = Dynarr_length (data->db->runes);
1080 data->cursor_type = NO_CURSOR;
1083 rb.cursor_type = CURSOR_OFF;
1085 Dynarr_add (data->db->runes, rb);
1086 data->pixpos += data->blank_width;
1091 /* Add runes representing a character in octal. */
1093 #define ADD_NEXT_OCTAL_RUNE_CHAR do \
1095 if (add_failed || (add_failed = add_emchar_rune (data))) \
1097 struct prop_block pb; \
1099 prop = Dynarr_new (prop_block); \
1101 pb.type = PROP_CHAR; \
1102 pb.data.p_char.ch = data->ch; \
1103 pb.data.p_char.cursor_type = data->cursor_type; \
1104 Dynarr_add (prop, pb); \
1108 static prop_block_dynarr *
1109 add_octal_runes (pos_data *data)
1111 prop_block_dynarr *prop, *add_failed;
1112 Emchar orig_char = data->ch;
1113 unsigned int orig_cursor_type = data->cursor_type;
1119 if (data->start_col)
1122 if (!data->start_col)
1124 if (data->bi_start_col_enabled)
1126 add_failed = add_hscroll_rune (data);
1130 struct glyph_block gb;
1131 struct window *w = XWINDOW (data->window);
1134 gb.glyph = Voctal_escape_glyph;
1136 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1137 GLYPH_CACHEL (w, OCT_ESC_GLYPH_INDEX));
1141 /* We only propagate information if the glyph was partially
1146 data->cursor_type = IGNORE_CURSOR;
1148 if (data->ch >= 0x100)
1150 /* If the character is an extended Mule character, it could have
1151 up to 19 bits. For the moment, we treat it as a seven-digit
1152 octal number. This is not that pretty, but whatever. */
1153 data->ch = (7 & (orig_char >> 18)) + '0';
1154 ADD_NEXT_OCTAL_RUNE_CHAR;
1156 data->ch = (7 & (orig_char >> 15)) + '0';
1157 ADD_NEXT_OCTAL_RUNE_CHAR;
1159 data->ch = (7 & (orig_char >> 12)) + '0';
1160 ADD_NEXT_OCTAL_RUNE_CHAR;
1162 data->ch = (7 & (orig_char >> 9)) + '0';
1163 ADD_NEXT_OCTAL_RUNE_CHAR;
1166 data->ch = (7 & (orig_char >> 6)) + '0';
1167 ADD_NEXT_OCTAL_RUNE_CHAR;
1169 data->ch = (7 & (orig_char >> 3)) + '0';
1170 ADD_NEXT_OCTAL_RUNE_CHAR;
1172 data->ch = (7 & orig_char) + '0';
1173 ADD_NEXT_OCTAL_RUNE_CHAR;
1175 data->cursor_type = orig_cursor_type;
1179 #undef ADD_NEXT_OCTAL_RUNE_CHAR
1181 /* Add runes representing a control character to a display block. */
1183 static prop_block_dynarr *
1184 add_control_char_runes (pos_data *data, struct buffer *b)
1186 if (!NILP (b->ctl_arrow))
1188 prop_block_dynarr *prop;
1189 Emchar orig_char = data->ch;
1190 unsigned int old_cursor_type = data->cursor_type;
1195 if (data->start_col)
1198 if (!data->start_col)
1200 if (data->bi_start_col_enabled)
1202 prop_block_dynarr *retval;
1204 retval = add_hscroll_rune (data);
1210 struct glyph_block gb;
1211 struct window *w = XWINDOW (data->window);
1214 gb.glyph = Vcontrol_arrow_glyph;
1216 /* We only propagate information if the glyph was partially
1218 if (add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1219 GLYPH_CACHEL (w, CONTROL_GLYPH_INDEX)))
1224 if (orig_char == 0177)
1227 data->ch = orig_char ^ 0100;
1228 data->cursor_type = IGNORE_CURSOR;
1230 if (add_emchar_rune (data))
1232 struct prop_block pb;
1234 prop = Dynarr_new (prop_block);
1236 pb.type = PROP_CHAR;
1237 pb.data.p_char.ch = data->ch;
1238 pb.data.p_char.cursor_type = data->cursor_type;
1239 Dynarr_add (prop, pb);
1242 data->cursor_type = old_cursor_type;
1247 return add_octal_runes (data);
1251 static prop_block_dynarr *
1252 add_disp_table_entry_runes_1 (pos_data *data, Lisp_Object entry)
1254 prop_block_dynarr *prop = NULL;
1256 if (STRINGP (entry))
1258 prop = add_bufbyte_string_runes (data,
1259 XSTRING_DATA (entry),
1260 XSTRING_LENGTH (entry),
1263 else if (GLYPHP (entry))
1265 if (data->start_col)
1268 if (!data->start_col && data->bi_start_col_enabled)
1270 prop = add_hscroll_rune (data);
1274 struct glyph_block gb;
1278 prop = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
1281 else if (CHAR_OR_CHAR_INTP (entry))
1283 data->ch = XCHAR_OR_CHAR_INT (entry);
1284 prop = add_emchar_rune (data);
1286 else if (CONSP (entry))
1288 if (EQ (XCAR (entry), Qformat)
1289 && CONSP (XCDR (entry))
1290 && STRINGP (XCAR (XCDR (entry))))
1292 Lisp_Object format = XCAR (XCDR (entry));
1293 Bytind len = XSTRING_LENGTH (format);
1294 Bufbyte *src = XSTRING_DATA (format), *end = src + len;
1295 Bufbyte *result = alloca_array (Bufbyte, len);
1296 Bufbyte *dst = result;
1300 Emchar c = charptr_emchar (src);
1302 if (c != '%' || src == end)
1303 dst += set_charptr_emchar (dst, c);
1306 c = charptr_emchar (src);
1311 dst += long_to_string_base ((char *)dst, data->ch, 16);
1314 dst += set_charptr_emchar (dst, '%');
1316 /* #### unimplemented */
1320 prop = add_bufbyte_string_runes (data, result, dst - result, 0);
1324 /* Else blow it off because someone added a bad entry and we don't
1325 have any safe way of signaling an error. */
1329 /* Given a display table entry, call the appropriate functions to
1330 display each element of the entry. */
1332 static prop_block_dynarr *
1333 add_disp_table_entry_runes (pos_data *data, Lisp_Object entry)
1335 prop_block_dynarr *prop = NULL;
1336 if (VECTORP (entry))
1338 Lisp_Vector *de = XVECTOR (entry);
1339 EMACS_INT len = vector_length (de);
1342 for (elt = 0; elt < len; elt++)
1344 if (NILP (vector_data (de)[elt]))
1347 prop = add_disp_table_entry_runes_1 (data, vector_data (de)[elt]);
1348 /* Else blow it off because someone added a bad entry and we
1349 don't have any safe way of signaling an error. Hey, this
1350 comment sounds familiar. */
1352 /* #### Still need to add any remaining elements to the
1353 propagation information. */
1359 prop = add_disp_table_entry_runes_1 (data, entry);
1363 /* Add runes which were propagated from the previous line. */
1365 static prop_block_dynarr *
1366 add_propagation_runes (prop_block_dynarr **prop, pos_data *data)
1368 /* #### Remember to handle start_col parameter of data when the rest of
1369 this is finished. */
1370 /* #### Chuck -- I've redone this function a bit. It looked like the
1371 case of not all the propagation blocks being added was not handled
1373 /* #### Chuck -- I also think the double indirection of PROP is kind
1374 of bogus. A cleaner solution is just to check for
1375 Dynarr_length (prop) > 0. */
1376 /* #### This function also doesn't even pay attention to ADD_FAILED!
1377 This is seriously fucked! Seven ####'s in 130 lines -- is that a
1380 prop_block_dynarr *add_failed;
1381 Bytind bi_old_cursor_bufpos = data->bi_cursor_bufpos;
1382 unsigned int old_cursor_type = data->cursor_type;
1384 for (elt = 0; elt < Dynarr_length (*prop); elt++)
1386 struct prop_block *pb = Dynarr_atp (*prop, elt);
1391 data->ch = pb->data.p_char.ch;
1392 data->bi_cursor_bufpos = pb->data.p_char.bi_cursor_bufpos;
1393 data->cursor_type = pb->data.p_char.cursor_type;
1394 add_failed = add_emchar_rune (data);
1397 goto oops_no_more_space;
1400 if (pb->data.p_string.str)
1401 xfree (pb->data.p_string.str);
1402 /* #### bogus bogus -- this doesn't do anything!
1403 Should probably call add_bufbyte_string_runes(),
1404 once that function is fixed. */
1406 case PROP_MINIBUF_PROMPT:
1408 face_index old_findex = data->findex;
1409 Bytind bi_old_bufpos = data->bi_bufpos;
1411 data->findex = DEFAULT_INDEX;
1412 data->bi_bufpos = 0;
1413 data->cursor_type = NO_CURSOR;
1415 while (pb->data.p_string.len > 0)
1417 data->ch = charptr_emchar (pb->data.p_string.str);
1418 add_failed = add_emchar_rune (data);
1422 data->findex = old_findex;
1423 data->bi_bufpos = bi_old_bufpos;
1424 goto oops_no_more_space;
1428 /* Complicated equivalent of ptr++, len-- */
1429 Bufbyte *oldpos = pb->data.p_string.str;
1430 INC_CHARPTR (pb->data.p_string.str);
1431 pb->data.p_string.len -= pb->data.p_string.str - oldpos;
1435 data->findex = old_findex;
1436 /* ##### FIXME FIXME FIXME -- Upon successful return from
1437 this function, data->bi_bufpos is automatically incremented.
1438 However, we don't want that to happen if we were adding
1439 the minibuffer prompt. */
1441 struct buffer *buf =
1442 XBUFFER (WINDOW_BUFFER (XWINDOW (data->window)));
1443 /* #### Chuck fix this shit or I'm gonna scream! */
1444 if (bi_old_bufpos > BI_BUF_BEGV (buf))
1445 data->bi_bufpos = prev_bytind (buf, bi_old_bufpos);
1447 /* #### is this correct? Does anyone know?
1448 Does anyone care? Is this a cheesy hack or what? */
1449 data->bi_bufpos = BI_BUF_BEGV (buf) - 1;
1455 /* #### I think it's unnecessary and misleading to preserve
1456 the blank_width, as it implies that the value carries
1457 over from one rune to the next, which is wrong. */
1458 int old_width = data->blank_width;
1459 face_index old_findex = data->findex;
1461 data->findex = pb->data.p_blank.findex;
1462 data->blank_width = pb->data.p_blank.width;
1463 data->bi_cursor_bufpos = 0;
1464 data->cursor_type = IGNORE_CURSOR;
1466 if (data->pixpos + data->blank_width > data->max_pixpos)
1467 data->blank_width = data->max_pixpos - data->pixpos;
1469 /* We pass a bogus value of char_tab_width. It shouldn't
1470 matter because unless something is really screwed up
1471 this call won't cause that arg to be used. */
1472 add_failed = add_blank_rune (data, XWINDOW (data->window), 0);
1474 /* This can happen in the case where we have a tab which
1475 is wider than the window. */
1476 if (data->blank_width != pb->data.p_blank.width)
1478 pb->data.p_blank.width -= data->blank_width;
1479 add_failed = ADD_FAILED;
1482 data->findex = old_findex;
1483 data->blank_width = old_width;
1486 goto oops_no_more_space;
1496 data->bi_cursor_bufpos = bi_old_cursor_bufpos;
1497 data->cursor_type = old_cursor_type;
1498 if (elt < Dynarr_length (*prop))
1500 Dynarr_delete_many (*prop, 0, elt);
1505 Dynarr_free (*prop);
1510 /* Add 'text layout glyphs at position POS_TYPE that are contained to
1511 the display block, but add all other types to the appropriate list
1512 of the display line. They will be added later by different
1515 static prop_block_dynarr *
1516 add_glyph_rune (pos_data *data, struct glyph_block *gb, int pos_type,
1517 int allow_cursor, struct glyph_cachel *cachel)
1519 struct window *w = XWINDOW (data->window);
1521 /* If window faces changed, and glyph instance is text, then
1522 glyph sizes might have changed too */
1523 invalidate_glyph_geometry_maybe (gb->glyph, w);
1525 /* This makes sure the glyph is in the cachels.
1527 #### We do this to make sure the glyph is in the glyph cachels,
1528 so that the dirty flag can be reset after redisplay has
1529 finished. We should do this some other way, maybe by iterating
1530 over the window cache of subwindows. */
1531 get_glyph_cachel_index (w, gb->glyph);
1533 /* A nil extent indicates a special glyph (ex. truncator). */
1534 if (NILP (gb->extent)
1535 || (pos_type == BEGIN_GLYPHS &&
1536 extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1537 || (pos_type == END_GLYPHS &&
1538 extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1539 || pos_type == LEFT_GLYPHS || pos_type == RIGHT_GLYPHS)
1544 int ascent, descent;
1545 Lisp_Object baseline;
1547 Lisp_Object instance;
1551 width = cachel->width;
1553 width = glyph_width (gb->glyph, data->window);
1558 if (data->start_col || data->start_col_xoffset)
1560 prop_block_dynarr *retval;
1561 int glyph_char_width = width / space_width (w);
1563 /* If we still have not fully scrolled horizontally after
1564 taking into account the width of the glyph, subtract its
1565 width and return. */
1566 if (glyph_char_width < data->start_col)
1568 data->start_col -= glyph_char_width;
1571 else if (glyph_char_width == data->start_col)
1575 xoffset = space_width (w) * data->start_col;
1578 /* #### Can this happen? */
1583 data->start_col = 0;
1584 retval = add_hscroll_rune (data);
1586 /* Could be caused by the handling of the hscroll rune. */
1587 if (retval != NULL || !width)
1593 if (data->pixpos + width > data->max_pixpos)
1595 /* If this is the first object we are attempting to add to
1596 the line then we ignore the horizontal_clip threshold.
1597 Otherwise we will loop until the bottom of the window
1598 continually failing to add this glyph because it is wider
1599 than the window. We could alternatively just completely
1600 ignore the glyph and proceed from there but I think that
1601 this is a better solution. */
1602 if (Dynarr_length (data->db->runes)
1603 && data->max_pixpos - data->pixpos < horizontal_clip)
1606 width = data->max_pixpos - data->pixpos;
1611 ascent = cachel->ascent;
1612 descent = cachel->descent;
1616 ascent = glyph_ascent (gb->glyph, data->window);
1617 descent = glyph_descent (gb->glyph, data->window);
1620 baseline = glyph_baseline (gb->glyph, data->window);
1622 if (glyph_contrib_p (gb->glyph, data->window))
1624 /* A pixmap that has not had a baseline explicitly set. Its
1625 contribution will be determined later. */
1626 if (NILP (baseline))
1628 int height = ascent + descent;
1629 data->max_pixmap_height = max (data->max_pixmap_height, height);
1632 /* A string so determine contribution normally. */
1633 else if (EQ (baseline, Qt))
1635 data->new_ascent = max (data->new_ascent, ascent);
1636 data->new_descent = max (data->new_descent, descent);
1639 /* A pixmap with an explicitly set baseline. We determine the
1640 contribution here. */
1641 else if (INTP (baseline))
1643 int height = ascent + descent;
1644 int pix_ascent, pix_descent;
1646 pix_ascent = height * XINT (baseline) / 100;
1647 pix_descent = height - pix_ascent;
1649 data->new_ascent = max (data->new_ascent, pix_ascent);
1650 data->new_descent = max (data->new_descent, pix_descent);
1653 /* Otherwise something is screwed up. */
1658 face = glyph_face (gb->glyph, data->window);
1660 findex = data->findex;
1662 findex = get_builtin_face_cache_index (w, face);
1664 instance = glyph_image_instance (gb->glyph, data->window,
1666 if (TEXT_IMAGE_INSTANCEP (instance))
1668 Lisp_Object string = XIMAGE_INSTANCE_TEXT_STRING (instance);
1669 face_index orig_findex = data->findex;
1670 Bytind orig_bufpos = data->bi_bufpos;
1671 Bytind orig_start_col_enabled = data->bi_start_col_enabled;
1673 data->findex = findex;
1674 data->bi_start_col_enabled = 0;
1676 data->bi_bufpos = 0;
1677 add_bufbyte_string_runes (data, XSTRING_DATA (string),
1678 XSTRING_LENGTH (string), 0);
1679 data->findex = orig_findex;
1680 data->bi_bufpos = orig_bufpos;
1681 data->bi_start_col_enabled = orig_start_col_enabled;
1686 rb.xpos = data->pixpos;
1688 rb.bufpos = 0; /* glyphs are never "at" anywhere */
1689 if (data->bi_endpos)
1690 /* #### is this necessary at all? */
1691 rb.endpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1695 rb.type = RUNE_DGLYPH;
1696 rb.object.dglyph.glyph = gb->glyph;
1697 rb.object.dglyph.extent = gb->extent;
1698 rb.object.dglyph.xoffset = xoffset;
1702 rb.bufpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1705 if (data->cursor_type == CURSOR_ON)
1707 if (data->bi_bufpos == data->bi_cursor_bufpos)
1709 rb.cursor_type = CURSOR_ON;
1710 data->cursor_x = Dynarr_length (data->db->runes);
1713 rb.cursor_type = CURSOR_OFF;
1715 else if (data->cursor_type == NEXT_CURSOR)
1717 rb.cursor_type = CURSOR_ON;
1718 data->cursor_x = Dynarr_length (data->db->runes);
1719 data->cursor_type = NO_CURSOR;
1721 else if (data->cursor_type == IGNORE_CURSOR)
1722 rb.cursor_type = IGNORE_CURSOR;
1723 else if (data->cursor_type == NO_CURSOR)
1724 rb.cursor_type = NO_CURSOR;
1726 rb.cursor_type = CURSOR_OFF;
1729 rb.cursor_type = CURSOR_OFF;
1731 Dynarr_add (data->db->runes, rb);
1732 data->pixpos += width;
1738 if (!NILP (glyph_face (gb->glyph, data->window)))
1740 get_builtin_face_cache_index (w, glyph_face (gb->glyph,
1743 gb->findex = data->findex;
1745 if (pos_type == BEGIN_GLYPHS)
1747 if (!data->dl->left_glyphs)
1748 data->dl->left_glyphs = Dynarr_new (glyph_block);
1749 Dynarr_add (data->dl->left_glyphs, *gb);
1752 else if (pos_type == END_GLYPHS)
1754 if (!data->dl->right_glyphs)
1755 data->dl->right_glyphs = Dynarr_new (glyph_block);
1756 Dynarr_add (data->dl->right_glyphs, *gb);
1760 abort (); /* there are no unknown types */
1763 return NULL; /* shut up compiler */
1766 /* Add all glyphs at position POS_TYPE that are contained in the given
1769 static prop_block_dynarr *
1770 add_glyph_runes (pos_data *data, int pos_type)
1772 /* #### This still needs to handle the start_col parameter. Duh, Chuck,
1773 why didn't you just modify add_glyph_rune in the first place? */
1775 glyph_block_dynarr *glyph_arr = (pos_type == BEGIN_GLYPHS
1776 ? data->ef->begin_glyphs
1777 : data->ef->end_glyphs);
1778 prop_block_dynarr *prop;
1780 for (elt = 0; elt < Dynarr_length (glyph_arr); elt++)
1782 prop = add_glyph_rune (data, Dynarr_atp (glyph_arr, elt), pos_type, 0,
1787 /* #### Add some propagation information. */
1792 Dynarr_reset (glyph_arr);
1797 /* Given a position for a buffer in a window, ensure that the given
1798 display line DL accurately represents the text on a line starting
1799 at the given position.
1801 NOTE NOTE NOTE NOTE: This function works with and returns Bytinds.
1802 You must do appropriate conversion. */
1805 create_text_block (struct window *w, struct display_line *dl,
1806 Bytind bi_start_pos, prop_block_dynarr **prop,
1809 struct frame *f = XFRAME (w->frame);
1810 struct buffer *b = XBUFFER (w->buffer);
1811 struct device *d = XDEVICE (f->device);
1815 /* Don't display anything in the minibuffer if this window is not on
1816 a selected frame. We consider all other windows to be active
1817 minibuffers as it simplifies the coding. */
1818 int active_minibuffer = (!MINI_WINDOW_P (w) ||
1819 (f == device_selected_frame (d)) ||
1820 is_surrogate_for_selected_frame (f));
1822 int truncate_win = window_truncation_on (w);
1823 int end_glyph_width;
1825 /* If the buffer's value of selective_display is an integer then
1826 only lines that start with less than selective_display columns of
1827 space will be displayed. If selective_display is t then all text
1828 after a ^M is invisible. */
1829 int selective = (INTP (b->selective_display)
1830 ? XINT (b->selective_display)
1831 : (!NILP (b->selective_display) ? -1 : 0));
1833 /* The variable ctl-arrow allows the user to specify what characters
1834 can actually be displayed and which octal should be used for.
1835 #### This variable should probably have some rethought done to
1838 #### It would also be really nice if you could specify that
1839 the characters come out in hex instead of in octal. Mule
1840 does that by adding a ctl-hexa variable similar to ctl-arrow,
1841 but that's bogus -- we need a more general solution. I
1842 think you need to extend the concept of display tables
1843 into a more general conversion mechanism. Ideally you
1844 could specify a Lisp function that converts characters,
1845 but this violates the Second Golden Rule and besides would
1846 make things way way way way slow.
1848 So instead, we extend the display-table concept, which was
1849 historically limited to 256-byte vectors, to one of the
1852 a) A 256-entry vector, for backward compatibility;
1853 b) char-table, mapping characters to values;
1854 c) range-table, mapping ranges of characters to values;
1855 d) a list of the above.
1857 The (d) option allows you to specify multiple display tables
1858 instead of just one. Each display table can specify conversions
1859 for some characters and leave others unchanged. The way the
1860 character gets displayed is determined by the first display table
1861 with a binding for that character. This way, you could call a
1862 function `enable-hex-display' that adds a hex display-table to
1863 the list of display tables for the current buffer.
1865 #### ...not yet implemented... Also, we extend the concept of
1866 "mapping" to include a printf-like spec. Thus you can make all
1867 extended characters show up as hex with a display table like
1870 #s(range-table data ((256 524288) (format "%x")))
1872 Since more than one display table is possible, you have
1873 great flexibility in mapping ranges of characters. */
1874 Emchar printable_min = (CHAR_OR_CHAR_INTP (b->ctl_arrow)
1875 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
1876 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
1879 Lisp_Object face_dt, window_dt;
1881 /* The text display block for this display line. */
1882 struct display_block *db = get_display_block_from_line (dl, TEXT);
1884 /* The first time through the main loop we need to force the glyph
1885 data to be updated. */
1888 /* Apparently the new extent_fragment_update returns an end position
1889 equal to the position passed in if there are no more runs to be
1891 int no_more_frags = 0;
1893 Lisp_Object synch_minibuffers_value =
1894 symbol_value_in_buffer (Qsynchronize_minibuffers, w->buffer);
1896 dl->used_prop_data = 0;
1898 dl->line_continuation = 0;
1901 data.ef = extent_fragment_new (w->buffer, f);
1903 /* These values are used by all of the rune addition routines. We add
1904 them to this structure for ease of passing. */
1906 XSETWINDOW (data.window, w);
1911 data.bi_bufpos = bi_start_pos;
1912 data.pixpos = dl->bounds.left_in;
1913 data.last_charset = Qunbound;
1914 data.last_findex = DEFAULT_INDEX;
1915 data.result_str = Qnil;
1917 /* Set the right boundary adjusting it to take into account any end
1918 glyph. Save the width of the end glyph for later use. */
1919 data.max_pixpos = dl->bounds.right_in;
1921 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
1923 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
1924 data.max_pixpos -= end_glyph_width;
1926 if (cursor_in_echo_area && MINI_WINDOW_P (w) && echo_area_active (f))
1928 data.bi_cursor_bufpos = BI_BUF_ZV (b);
1929 data.cursor_type = CURSOR_ON;
1931 else if (MINI_WINDOW_P (w) && !active_minibuffer)
1932 data.cursor_type = NO_CURSOR;
1933 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)) &&
1934 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
1935 d == XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d))))&&
1936 f == XFRAME(DEVICE_SELECTED_FRAME(d)))
1938 data.bi_cursor_bufpos = BI_BUF_PT (b);
1939 data.cursor_type = CURSOR_ON;
1941 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)))
1943 data.bi_cursor_bufpos = bi_marker_position (w->pointm[type]);
1944 data.cursor_type = CURSOR_ON;
1947 data.cursor_type = NO_CURSOR;
1950 data.start_col = w->hscroll;
1951 data.start_col_xoffset = w->left_xoffset;
1952 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
1953 data.hscroll_glyph_width_adjust = 0;
1955 /* We regenerate the line from the very beginning. */
1956 Dynarr_reset (db->runes);
1958 /* Why is this less than or equal and not just less than? If the
1959 starting position is already equal to the maximum we can't add
1960 anything else, right? Wrong. We might still have a newline to
1961 add. A newline can use the room allocated for an end glyph since
1962 if we add it we know we aren't going to be adding any end
1965 /* #### Chuck -- I think this condition should be while (1).
1966 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
1967 and the begin-glyph ends exactly at the end of the window, the
1968 end-glyph and text might not be displayed. while (1) ensures
1969 that the loop terminates only when either (a) there is
1970 propagation data or (b) the end-of-line or end-of-buffer is hit.
1972 #### Also I think you need to ensure that the operation
1973 "add begin glyphs; add end glyphs; add text" is atomic and
1974 can't get interrupted in the middle. If you run off the end
1975 of the line during that operation, then you keep accumulating
1976 propagation data until you're done. Otherwise, if the (e.g.)
1977 there's a begin glyph at a particular position and attempting
1978 to display that glyph results in window-end being hit and
1979 propagation data being generated, then the character at that
1980 position won't be displayed.
1982 #### See also the comment after the end of this loop, below.
1984 while (data.pixpos <= data.max_pixpos
1985 && (active_minibuffer || !NILP (synch_minibuffers_value)))
1987 /* #### This check probably should not be necessary. */
1988 if (data.bi_bufpos > BI_BUF_ZV (b))
1990 /* #### urk! More of this lossage! */
1995 /* If selective display was an integer and we aren't working on
1996 a continuation line then find the next line we are actually
1997 supposed to display. */
1999 && (data.bi_bufpos == BI_BUF_BEGV (b)
2000 || BUF_FETCH_CHAR (b, prev_bytind (b, data.bi_bufpos)) == '\n'))
2002 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2005 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2006 if (data.bi_bufpos >= BI_BUF_ZV (b))
2008 data.bi_bufpos = BI_BUF_ZV (b);
2014 /* Check for face changes. */
2015 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
2017 /* Now compute the face and begin/end-glyph information. */
2019 /* Remember that the extent-fragment routines deal in Bytind's. */
2020 extent_fragment_update (w, data.ef, data.bi_bufpos);
2022 get_display_tables (w, data.findex, &face_dt, &window_dt);
2024 if (data.bi_bufpos == data.ef->end)
2029 /* Determine what is next to be displayed. We first handle any
2030 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
2031 display then we determine what to do based on the character at the
2032 current buffer position. */
2034 /* If the current position is covered by an invisible extent, do
2035 nothing (except maybe add some ellipses).
2037 #### The behavior of begin and end-glyphs at the edge of an
2038 invisible extent should be investigated further. This is
2039 fairly low priority though. */
2040 if (data.ef->invisible)
2042 /* #### Chuck, perhaps you could look at this code? I don't
2043 really know what I'm doing. */
2046 Dynarr_free (*prop);
2050 /* The extent fragment code only sets this when we should
2051 really display the ellipses. It makes sure the ellipses
2052 don't get displayed more than once in a row. */
2053 if (data.ef->invisible_ellipses)
2055 struct glyph_block gb;
2057 data.ef->invisible_ellipses_already_displayed = 1;
2058 data.ef->invisible_ellipses = 0;
2060 gb.glyph = Vinvisible_text_glyph;
2061 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2062 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2063 /* Perhaps they shouldn't propagate if the very next thing
2064 is to display a newline (for compatibility with
2065 selective-display-ellipses)? Maybe that's too
2071 /* If point is in an invisible region we place it on the
2072 next visible character. */
2073 if (data.cursor_type == CURSOR_ON
2074 && data.bi_bufpos == data.bi_cursor_bufpos)
2076 data.cursor_type = NEXT_CURSOR;
2079 /* #### What if we we're dealing with a display table? */
2083 if (data.bi_bufpos == BI_BUF_ZV (b))
2086 INC_BYTIND (b, data.bi_bufpos);
2089 /* If there is propagation data, then it represents the current
2090 buffer position being displayed. Add them and advance the
2091 position counter. This might also add the minibuffer
2095 dl->used_prop_data = 1;
2096 *prop = add_propagation_runes (prop, &data);
2099 goto done; /* gee, a really narrow window */
2100 else if (data.bi_bufpos == BI_BUF_ZV (b))
2102 else if (data.bi_bufpos < BI_BUF_BEGV (b))
2103 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
2104 data.bi_bufpos = BI_BUF_BEGV (b);
2106 INC_BYTIND (b, data.bi_bufpos);
2109 /* If there are end glyphs, add them to the line. These are
2110 the end glyphs for the previous run of text. We add them
2111 here rather than doing them at the end of handling the
2112 previous run so that glyphs at the beginning and end of
2113 a line are handled correctly. */
2114 else if (Dynarr_length (data.ef->end_glyphs) > 0)
2116 *prop = add_glyph_runes (&data, END_GLYPHS);
2121 /* If there are begin glyphs, add them to the line. */
2122 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
2124 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
2129 /* If at end-of-buffer, we've already processed begin and
2130 end-glyphs at this point and there's no text to process,
2132 else if (data.bi_bufpos == BI_BUF_ZV (b))
2137 Lisp_Object entry = Qnil;
2138 /* Get the character at the current buffer position. */
2139 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2140 if (!NILP (face_dt) || !NILP (window_dt))
2141 entry = display_table_entry (data.ch, face_dt, window_dt);
2143 /* If there is a display table entry for it, hand it off to
2144 add_disp_table_entry_runes and let it worry about it. */
2145 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
2147 *prop = add_disp_table_entry_runes (&data, entry);
2153 /* Check if we have hit a newline character. If so, add a marker
2154 to the line and end this loop. */
2155 else if (data.ch == '\n')
2157 /* We aren't going to be adding an end glyph so give its
2158 space back in order to make sure that the cursor can
2160 data.max_pixpos += end_glyph_width;
2163 && (bi_spaces_at_point
2164 (b, next_bytind (b, data.bi_bufpos))
2167 if (!NILP (b->selective_display_ellipses))
2169 struct glyph_block gb;
2172 gb.glyph = Vinvisible_text_glyph;
2173 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2174 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2178 /* Cheesy, cheesy, cheesy. We mark the end of the
2179 line with a special "character rune" whose width
2180 is the EOL cursor width and whose character is
2181 the non-printing character '\n'. */
2182 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2183 *prop = add_emchar_rune (&data);
2186 /* We need to set data.bi_bufpos to the start of the
2187 next visible region in order to make this line
2188 appear to contain all of the invisible area.
2189 Otherwise, the line cache won't work
2191 INC_BYTIND (b, data.bi_bufpos);
2192 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2195 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2196 if (data.bi_bufpos >= BI_BUF_ZV (b))
2198 data.bi_bufpos = BI_BUF_ZV (b);
2202 if (BI_BUF_FETCH_CHAR
2203 (b, prev_bytind (b, data.bi_bufpos)) == '\n')
2204 DEC_BYTIND (b, data.bi_bufpos);
2208 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2209 *prop = add_emchar_rune (&data);
2215 /* If the current character is ^M, and selective display is
2216 enabled, then add the invisible-text-glyph if
2217 selective-display-ellipses is set. In any case, this
2219 else if (data.ch == (('M' & 037)) && selective == -1)
2221 Bytind bi_next_bufpos;
2223 /* Find the buffer position at the end of the line. */
2225 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2226 if (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_next_bufpos))
2228 DEC_BYTIND (b, bi_next_bufpos);
2230 /* If the cursor is somewhere in the elided text make
2231 sure that the cursor gets drawn appropriately. */
2232 if (data.cursor_type == CURSOR_ON
2233 && (data.bi_cursor_bufpos >= data.bi_bufpos &&
2234 data.bi_cursor_bufpos < bi_next_bufpos))
2236 data.cursor_type = NEXT_CURSOR;
2239 /* We won't be adding a truncation or continuation glyph
2240 so give up the room allocated for them. */
2241 data.max_pixpos += end_glyph_width;
2243 if (!NILP (b->selective_display_ellipses))
2245 /* We don't propagate anything from the invisible
2246 text glyph if it fails to fit. This is
2248 struct glyph_block gb;
2251 gb.glyph = Vinvisible_text_glyph;
2252 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 1,
2253 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2256 /* Set the buffer position to the end of the line. We
2257 need to do this before potentially adding a newline
2258 so that the cursor flag will get set correctly (if
2260 data.bi_bufpos = bi_next_bufpos;
2262 if (NILP (b->selective_display_ellipses)
2263 || data.bi_cursor_bufpos == bi_next_bufpos)
2265 /* We have to at least add a newline character so
2266 that the cursor shows up properly. */
2268 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2269 data.findex = DEFAULT_INDEX;
2271 data.start_col_xoffset = 0;
2272 data.bi_start_col_enabled = 0;
2274 add_emchar_rune (&data);
2277 /* This had better be a newline but doing it this way
2278 we'll see obvious incorrect results if it isn't. No
2279 need to abort here. */
2280 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2285 /* If the current character is considered to be printable, then
2287 else if (data.ch >= printable_min)
2289 *prop = add_emchar_rune (&data);
2294 /* If the current character is a tab, determine the next tab
2295 starting position and add a blank rune which extends from the
2296 current pixel position to that starting position. */
2297 else if (data.ch == '\t')
2299 int tab_start_pixpos = data.pixpos;
2304 if (data.start_col > 1)
2305 tab_start_pixpos -= (space_width (w) * (data.start_col - 1))
2306 + data.start_col_xoffset;
2309 next_tab_position (w, tab_start_pixpos,
2310 dl->bounds.left_in +
2311 data.hscroll_glyph_width_adjust);
2312 if (next_tab_start > data.max_pixpos)
2314 prop_width = next_tab_start - data.max_pixpos;
2315 next_tab_start = data.max_pixpos;
2317 data.blank_width = next_tab_start - data.pixpos;
2319 (next_tab_start - tab_start_pixpos) / space_width (w);
2321 *prop = add_blank_rune (&data, w, char_tab_width);
2323 /* add_blank_rune is only supposed to be called with
2324 sizes guaranteed to fit in the available space. */
2329 struct prop_block pb;
2330 *prop = Dynarr_new (prop_block);
2332 pb.type = PROP_BLANK;
2333 pb.data.p_blank.width = prop_width;
2334 pb.data.p_blank.findex = data.findex;
2335 Dynarr_add (*prop, pb);
2341 /* If character is a control character, pass it off to
2342 add_control_char_runes.
2344 The is_*() routines have undefined results on
2345 arguments outside of the range [-1, 255]. (This
2346 often bites people who carelessly use `char' instead
2347 of `unsigned char'.)
2349 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
2351 *prop = add_control_char_runes (&data, b);
2357 /* If the character is above the ASCII range and we have not
2358 already handled it, then print it as an octal number. */
2359 else if (data.ch >= 0200)
2361 *prop = add_octal_runes (&data);
2367 /* Assume the current character is considered to be printable,
2368 then just add it. */
2371 *prop = add_emchar_rune (&data);
2376 INC_BYTIND (b, data.bi_bufpos);
2382 /* Determine the starting point of the next line if we did not hit the
2383 end of the buffer. */
2384 if (data.bi_bufpos < BI_BUF_ZV (b)
2385 && (active_minibuffer || !NILP (synch_minibuffers_value)))
2387 /* #### This check is not correct. If the line terminated
2388 due to a begin-glyph or end-glyph hitting window-end, then
2389 data.ch will not point to the character at data.bi_bufpos. If
2390 you make the two changes mentioned at the top of this loop,
2391 you should be able to say '(if (*prop))'. That should also
2392 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
2395 /* The common case is that the line ended because we hit a newline.
2396 In that case, the next character is just the next buffer
2398 if (data.ch == '\n')
2400 /* If data.start_col_enabled is still true, then the window is
2401 scrolled far enough so that nothing on this line is visible.
2402 We need to stick a truncation glyph at the beginning of the
2403 line in that case unless the line is completely blank. */
2404 if (data.bi_start_col_enabled)
2406 if (data.cursor_type == CURSOR_ON)
2408 if (data.bi_cursor_bufpos >= bi_start_pos
2409 && data.bi_cursor_bufpos <= data.bi_bufpos)
2410 data.bi_cursor_bufpos = data.bi_bufpos;
2412 data.findex = DEFAULT_INDEX;
2414 data.bi_start_col_enabled = 0;
2416 if (data.bi_bufpos != bi_start_pos)
2418 struct glyph_block gb;
2421 gb.glyph = Vhscroll_glyph;
2422 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2423 GLYPH_CACHEL (w, HSCROLL_GLYPH_INDEX));
2427 /* This duplicates code down below to add a newline to
2428 the end of an otherwise empty line.*/
2430 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2432 add_emchar_rune (&data);
2436 INC_BYTIND (b, data.bi_bufpos);
2439 /* Otherwise we have a buffer line which cannot fit on one display
2443 struct glyph_block gb;
2444 struct glyph_cachel *cachel;
2446 /* If the line is to be truncated then we actually have to look
2447 for the next newline. We also add the end-of-line glyph which
2448 we know will fit because we adjusted the right border before
2449 we starting laying out the line. */
2450 data.max_pixpos += end_glyph_width;
2451 data.findex = DEFAULT_INDEX;
2458 /* Now find the start of the next line. */
2459 bi_pos = bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2461 /* If the cursor is past the truncation line then we
2462 make it appear on the truncation glyph. If we've hit
2463 the end of the buffer then we also make the cursor
2464 appear unless eob is immediately preceded by a
2465 newline. In that case the cursor should actually
2466 appear on the next line. */
2467 if (data.cursor_type == CURSOR_ON
2468 && data.bi_cursor_bufpos >= data.bi_bufpos
2469 && (data.bi_cursor_bufpos < bi_pos ||
2470 (bi_pos == BI_BUF_ZV (b)
2471 && (bi_pos == BI_BUF_BEGV (b)
2472 || (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_pos))
2474 data.bi_cursor_bufpos = bi_pos;
2476 data.cursor_type = NO_CURSOR;
2478 data.bi_bufpos = bi_pos;
2479 gb.glyph = Vtruncation_glyph;
2480 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
2484 /* The cursor can never be on the continuation glyph. */
2485 data.cursor_type = NO_CURSOR;
2487 /* data.bi_bufpos is already at the start of the next line. */
2489 dl->line_continuation = 1;
2490 gb.glyph = Vcontinuation_glyph;
2491 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
2494 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
2496 if (truncate_win && data.bi_bufpos == BI_BUF_ZV (b)
2497 && BI_BUF_FETCH_CHAR (b, prev_bytind (b, BI_BUF_ZV (b))) != '\n')
2498 /* #### Damn this losing shit. */
2502 else if ((active_minibuffer || !NILP (synch_minibuffers_value))
2503 && (!echo_area_active (f) || data.bi_bufpos == BI_BUF_ZV (b)))
2505 /* We need to add a marker to the end of the line since there is no
2506 newline character in order for the cursor to get drawn. We label
2507 it as a newline so that it gets handled correctly by the
2508 whitespace routines below. */
2511 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2512 data.findex = DEFAULT_INDEX;
2514 data.start_col_xoffset = 0;
2515 data.bi_start_col_enabled = 0;
2517 data.max_pixpos += data.blank_width;
2518 add_emchar_rune (&data);
2519 data.max_pixpos -= data.blank_width;
2521 /* #### urk! Chuck, this shit is bad news. Going around
2522 manipulating invalid positions is guaranteed to result in
2523 trouble sooner or later. */
2524 data.bi_bufpos = BI_BUF_ZV (b) + 1;
2527 /* Calculate left whitespace boundary. */
2531 /* Whitespace past a newline is considered right whitespace. */
2532 while (elt < Dynarr_length (db->runes))
2534 struct rune *rb = Dynarr_atp (db->runes, elt);
2536 if ((rb->type == RUNE_CHAR && rb->object.chr.ch == ' ')
2537 || rb->type == RUNE_BLANK)
2539 dl->bounds.left_white += rb->width;
2543 elt = Dynarr_length (db->runes);
2547 /* Calculate right whitespace boundary. */
2549 int elt = Dynarr_length (db->runes) - 1;
2552 while (!done && elt >= 0)
2554 struct rune *rb = Dynarr_atp (db->runes, elt);
2556 if (!(rb->type == RUNE_CHAR && rb->object.chr.ch < 0x100
2557 && isspace (rb->object.chr.ch))
2558 && !rb->type == RUNE_BLANK)
2560 dl->bounds.right_white = rb->xpos + rb->width;
2568 /* The line is blank so everything is considered to be right
2571 dl->bounds.right_white = dl->bounds.left_in;
2574 /* Set the display blocks bounds. */
2575 db->start_pos = dl->bounds.left_in;
2576 if (Dynarr_length (db->runes))
2578 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
2580 db->end_pos = rb->xpos + rb->width;
2583 db->end_pos = dl->bounds.right_white;
2585 /* update line height parameters */
2586 if (!data.new_ascent && !data.new_descent)
2588 /* We've got a blank line so initialize these values from the default
2590 default_face_font_info (data.window, &data.new_ascent,
2591 &data.new_descent, 0, 0, 0);
2594 if (data.max_pixmap_height)
2596 int height = data.new_ascent + data.new_descent;
2597 int pix_ascent, pix_descent;
2599 pix_descent = data.max_pixmap_height * data.new_descent / height;
2600 pix_ascent = data.max_pixmap_height - pix_descent;
2602 data.new_ascent = max (data.new_ascent, pix_ascent);
2603 data.new_descent = max (data.new_descent, pix_descent);
2606 dl->ascent = data.new_ascent;
2607 dl->descent = data.new_descent;
2610 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
2612 if (dl->ascent < ascent)
2613 dl->ascent = ascent;
2616 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
2618 if (dl->descent < descent)
2619 dl->descent = descent;
2622 dl->cursor_elt = data.cursor_x;
2623 /* #### lossage lossage lossage! Fix this shit! */
2624 if (data.bi_bufpos > BI_BUF_ZV (b))
2625 dl->end_bufpos = BUF_ZV (b);
2627 dl->end_bufpos = bytind_to_bufpos (b, data.bi_bufpos) - 1;
2629 data.dl->num_chars = column_at_point (b, dl->end_bufpos, 0);
2631 /* This doesn't correctly take into account tabs and control
2632 characters but if the window isn't being truncated then this
2633 value isn't going to end up being used anyhow. */
2634 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
2636 /* #### handle horizontally scrolled line with text none of which
2637 was actually laid out. */
2639 /* #### handle any remainder of overlay arrow */
2641 if (*prop == ADD_FAILED)
2644 if (truncate_win && *prop)
2646 Dynarr_free (*prop);
2650 extent_fragment_delete (data.ef);
2652 /* #### If we started at EOB, then make sure we return a value past
2653 it so that regenerate_window will exit properly. This is bogus.
2654 The main loop should get fixed so that it isn't necessary to call
2655 this function if we are already at EOB. */
2657 if (data.bi_bufpos == BI_BUF_ZV (b) && bi_start_pos == BI_BUF_ZV (b))
2658 return data.bi_bufpos + 1; /* Yuck! */
2660 return data.bi_bufpos;
2663 /* Display the overlay arrow at the beginning of the given line. */
2666 create_overlay_glyph_block (struct window *w, struct display_line *dl)
2668 struct frame *f = XFRAME (w->frame);
2669 struct device *d = XDEVICE (f->device);
2672 /* If Voverlay_arrow_string isn't valid then just fail silently. */
2673 if (!STRINGP (Voverlay_arrow_string) && !GLYPHP (Voverlay_arrow_string))
2679 XSETWINDOW (data.window, w);
2680 data.db = get_display_block_from_line (dl, OVERWRITE);
2682 data.pixpos = dl->bounds.left_in;
2683 data.max_pixpos = dl->bounds.right_in;
2684 data.cursor_type = NO_CURSOR;
2686 data.findex = DEFAULT_INDEX;
2687 data.last_charset = Qunbound;
2688 data.last_findex = DEFAULT_INDEX;
2689 data.result_str = Qnil;
2692 Dynarr_reset (data.db->runes);
2694 if (STRINGP (Voverlay_arrow_string))
2696 add_bufbyte_string_runes
2698 XSTRING_DATA (Voverlay_arrow_string),
2699 XSTRING_LENGTH (Voverlay_arrow_string),
2702 else if (GLYPHP (Voverlay_arrow_string))
2704 struct glyph_block gb;
2706 gb.glyph = Voverlay_arrow_string;
2708 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, 0);
2711 if (data.max_pixmap_height)
2713 int height = data.new_ascent + data.new_descent;
2714 int pix_ascent, pix_descent;
2716 pix_descent = data.max_pixmap_height * data.new_descent / height;
2717 pix_ascent = data.max_pixmap_height - pix_descent;
2719 data.new_ascent = max (data.new_ascent, pix_ascent);
2720 data.new_descent = max (data.new_descent, pix_descent);
2723 dl->ascent = data.new_ascent;
2724 dl->descent = data.new_descent;
2726 data.db->start_pos = dl->bounds.left_in;
2727 data.db->end_pos = data.pixpos;
2729 return data.pixpos - dl->bounds.left_in;
2732 /* Add a type of glyph to a margin display block. */
2735 add_margin_runes (struct display_line *dl, struct display_block *db, int start,
2736 int count, enum glyph_layout layout, int side, Lisp_Object window)
2738 glyph_block_dynarr *gbd = (side == LEFT_GLYPHS
2740 : dl->right_glyphs);
2743 struct window *w = XWINDOW (window);
2744 struct frame *f = XFRAME (w->frame);
2745 struct device *d = XDEVICE (f->device);
2750 data.window = window;
2753 data.pixpos = start;
2754 data.cursor_type = NO_CURSOR;
2756 data.last_charset = Qunbound;
2757 data.last_findex = DEFAULT_INDEX;
2758 data.result_str = Qnil;
2760 data.new_ascent = dl->ascent;
2761 data.new_descent = dl->descent;
2763 if ((layout == GL_WHITESPACE && side == LEFT_GLYPHS)
2764 || (layout == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS))
2767 elt = Dynarr_length (gbd) - 1;
2774 end = Dynarr_length (gbd);
2777 while (count && ((!reverse && elt < end) || (reverse && elt >= end)))
2779 struct glyph_block *gb = Dynarr_atp (gbd, elt);
2781 if (NILP (gb->extent))
2782 abort (); /* these should have been handled in add_glyph_rune */
2785 ((side == LEFT_GLYPHS &&
2786 extent_begin_glyph_layout (XEXTENT (gb->extent)) == layout)
2787 || (side == RIGHT_GLYPHS &&
2788 extent_end_glyph_layout (XEXTENT (gb->extent)) == layout)))
2790 data.findex = gb->findex;
2791 data.max_pixpos = data.pixpos + gb->width;
2792 add_glyph_rune (&data, gb, side, 0, NULL);
2797 (reverse ? elt-- : elt++);
2800 if (data.max_pixmap_height)
2802 int height = data.new_ascent + data.new_descent;
2803 int pix_ascent, pix_descent;
2805 pix_descent = data.max_pixmap_height * data.new_descent / height;
2806 pix_ascent = data.max_pixmap_height - pix_descent;
2807 data.new_ascent = max (data.new_ascent, pix_ascent);
2808 data.new_descent = max (data.new_descent, pix_descent);
2811 dl->ascent = data.new_ascent;
2812 dl->descent = data.new_descent;
2817 /* Add a blank to a margin display block. */
2820 add_margin_blank (struct display_line *dl, struct display_block *db,
2821 struct window *w, int xpos, int width, int side)
2825 rb.findex = (side == LEFT_GLYPHS
2826 ? get_builtin_face_cache_index (w, Vleft_margin_face)
2827 : get_builtin_face_cache_index (w, Vright_margin_face));
2832 rb.type = RUNE_BLANK;
2833 rb.cursor_type = CURSOR_OFF;
2835 Dynarr_add (db->runes, rb);
2838 /* Display glyphs in the left outside margin, left inside margin and
2839 left whitespace area. */
2842 create_left_glyph_block (struct window *w, struct display_line *dl,
2847 int use_overflow = (NILP (w->use_left_overflow) ? 0 : 1);
2849 int out_end, in_out_start, in_in_end, white_out_start, white_in_start;
2850 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
2851 int left_in_start = dl->bounds.left_in;
2852 int left_in_end = dl->bounds.left_in + overlay_width;
2854 struct display_block *odb, *idb;
2856 XSETWINDOW (window, w);
2858 /* We have to add the glyphs to the line in the order outside,
2859 inside, whitespace. However the precedence dictates that we
2860 determine how many will fit in the reverse order. */
2862 /* Determine how many whitespace glyphs we can display and where
2863 they should start. */
2864 white_in_start = dl->bounds.left_white;
2865 white_out_start = left_in_start;
2866 white_out_cnt = white_in_cnt = 0;
2869 while (elt < Dynarr_length (dl->left_glyphs))
2871 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2873 if (NILP (gb->extent))
2874 abort (); /* these should have been handled in add_glyph_rune */
2876 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
2880 width = glyph_width (gb->glyph, window);
2882 if (white_in_start - width >= left_in_end)
2885 white_in_start -= width;
2889 else if (use_overflow
2890 && (white_out_start - width > dl->bounds.left_out))
2893 white_out_start -= width;
2904 /* Determine how many inside margin glyphs we can display and where
2905 they should start. The inside margin glyphs get whatever space
2906 is left after the whitespace glyphs have been displayed. These
2907 are tricky to calculate since if we decide to use the overflow
2908 area we basically have to start over. So for these we build up a
2909 list of just the inside margin glyphs and manipulate it to
2910 determine the needed info. */
2912 glyph_block_dynarr *ib;
2913 int avail_in, avail_out;
2916 int used_in, used_out;
2919 used_in = used_out = 0;
2920 ib = Dynarr_new (glyph_block);
2921 while (elt < Dynarr_length (dl->left_glyphs))
2923 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2925 if (NILP (gb->extent))
2926 abort (); /* these should have been handled in add_glyph_rune */
2928 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
2931 gb->width = glyph_width (gb->glyph, window);
2932 used_in += gb->width;
2933 Dynarr_add (ib, *gb);
2943 avail_in = white_in_start - left_in_end;
2951 avail_out = white_out_start - dl->bounds.left_out;
2954 while (!done && marker < Dynarr_length (ib))
2956 int width = Dynarr_atp (ib, marker)->width;
2958 /* If everything now fits in the available inside margin
2959 space, we're done. */
2960 if (used_in <= avail_in)
2964 /* Otherwise see if we have room to move a glyph to the
2966 if (used_out + width <= avail_out)
2979 /* At this point we now know that everything from marker on goes in
2980 the inside margin and everything before it goes in the outside
2981 margin. The stuff going into the outside margin is guaranteed
2982 to fit, but we may have to trim some stuff from the inside. */
2984 in_in_end = left_in_end;
2985 in_out_start = white_out_start;
2986 in_out_cnt = in_in_cnt = 0;
2990 while (elt < Dynarr_length (dl->left_glyphs))
2992 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2994 if (NILP (gb->extent))
2995 abort (); /* these should have been handled in add_glyph_rune */
2997 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3000 int width = glyph_width (gb->glyph, window);
3005 in_out_start -= width;
3010 else if (in_in_end + width < white_in_start)
3025 /* Determine how many outside margin glyphs we can display. They
3026 always start at the left outside margin and can only use the
3027 outside margin space. */
3028 out_end = dl->bounds.left_out;
3032 while (elt < Dynarr_length (dl->left_glyphs))
3034 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3036 if (NILP (gb->extent))
3037 abort (); /* these should have been handled in add_glyph_rune */
3039 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3042 int width = glyph_width (gb->glyph, window);
3044 if (out_end + width <= in_out_start)
3058 /* Now that we know where everything goes, we add the glyphs as
3059 runes to the appropriate display blocks. */
3060 if (out_cnt || in_out_cnt || white_out_cnt)
3062 odb = get_display_block_from_line (dl, LEFT_OUTSIDE_MARGIN);
3063 odb->start_pos = dl->bounds.left_out;
3064 /* #### We should stop adding a blank to account for the space
3065 between the end of the glyphs and the margin and instead set
3066 this accordingly. */
3067 odb->end_pos = dl->bounds.left_in;
3068 Dynarr_reset (odb->runes);
3073 if (in_in_cnt || white_in_cnt)
3075 idb = get_display_block_from_line (dl, LEFT_INSIDE_MARGIN);
3076 idb->start_pos = dl->bounds.left_in;
3077 /* #### See above comment for odb->end_pos */
3078 idb->end_pos = dl->bounds.left_white;
3079 Dynarr_reset (idb->runes);
3084 /* First add the outside margin glyphs. */
3086 end_xpos = add_margin_runes (dl, odb, dl->bounds.left_out, out_cnt,
3087 GL_OUTSIDE_MARGIN, LEFT_GLYPHS, window);
3089 end_xpos = dl->bounds.left_out;
3091 /* There may be blank space between the outside margin glyphs and
3092 the inside margin glyphs. If so, add a blank. */
3093 if (in_out_cnt && (in_out_start - end_xpos))
3095 add_margin_blank (dl, odb, w, end_xpos, in_out_start - end_xpos,
3099 /* Next add the inside margin glyphs which are actually in the
3103 end_xpos = add_margin_runes (dl, odb, in_out_start, in_out_cnt,
3104 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3107 /* If we didn't add any inside margin glyphs to the outside margin,
3108 but are adding whitespace glyphs, then we need to add a blank
3110 if (!in_out_cnt && white_out_cnt && (white_out_start - end_xpos))
3112 add_margin_blank (dl, odb, w, end_xpos, white_out_start - end_xpos,
3116 /* Next add the whitespace margin glyphs which are actually in the
3120 end_xpos = add_margin_runes (dl, odb, white_out_start, white_out_cnt,
3121 GL_WHITESPACE, LEFT_GLYPHS, window);
3124 /* We take care of clearing between the end of the glyphs and the
3125 start of the inside margin for lines which have glyphs. */
3126 if (odb && (left_in_start - end_xpos))
3128 add_margin_blank (dl, odb, w, end_xpos, left_in_start - end_xpos,
3132 /* Next add the inside margin glyphs which are actually in the
3136 end_xpos = add_margin_runes (dl, idb, left_in_end, in_in_cnt,
3137 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3140 end_xpos = left_in_end;
3142 /* Make sure that the area between the end of the inside margin
3143 glyphs and the whitespace glyphs is cleared. */
3144 if (idb && (white_in_start - end_xpos > 0))
3146 add_margin_blank (dl, idb, w, end_xpos, white_in_start - end_xpos,
3150 /* Next add the whitespace margin glyphs which are actually in the
3154 add_margin_runes (dl, idb, white_in_start, white_in_cnt, GL_WHITESPACE,
3155 LEFT_GLYPHS, window);
3158 /* Whitespace glyphs always end right next to the text block so
3159 there is nothing we have to make sure is cleared after them. */
3162 /* Display glyphs in the right outside margin, right inside margin and
3163 right whitespace area. */
3166 create_right_glyph_block (struct window *w, struct display_line *dl)
3170 int use_overflow = (NILP (w->use_right_overflow) ? 0 : 1);
3172 int out_start, in_out_end, in_in_start, white_out_end, white_in_end;
3173 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
3175 struct display_block *odb, *idb;
3177 XSETWINDOW (window, w);
3179 /* We have to add the glyphs to the line in the order outside,
3180 inside, whitespace. However the precedence dictates that we
3181 determine how many will fit in the reverse order. */
3183 /* Determine how many whitespace glyphs we can display and where
3184 they should start. */
3185 white_in_end = dl->bounds.right_white;
3186 white_out_end = dl->bounds.right_in;
3187 white_out_cnt = white_in_cnt = 0;
3190 while (elt < Dynarr_length (dl->right_glyphs))
3192 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3194 if (NILP (gb->extent))
3195 abort (); /* these should have been handled in add_glyph_rune */
3197 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
3199 int width = glyph_width (gb->glyph, window);
3201 if (white_in_end + width <= dl->bounds.right_in)
3204 white_in_end += width;
3208 else if (use_overflow
3209 && (white_out_end + width <= dl->bounds.right_out))
3212 white_out_end += width;
3223 /* Determine how many inside margin glyphs we can display and where
3224 they should start. The inside margin glyphs get whatever space
3225 is left after the whitespace glyphs have been displayed. These
3226 are tricky to calculate since if we decide to use the overflow
3227 area we basically have to start over. So for these we build up a
3228 list of just the inside margin glyphs and manipulate it to
3229 determine the needed info. */
3231 glyph_block_dynarr *ib;
3232 int avail_in, avail_out;
3235 int used_in, used_out;
3238 used_in = used_out = 0;
3239 ib = Dynarr_new (glyph_block);
3240 while (elt < Dynarr_length (dl->right_glyphs))
3242 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3244 if (NILP (gb->extent))
3245 abort (); /* these should have been handled in add_glyph_rune */
3247 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3249 gb->width = glyph_width (gb->glyph, window);
3250 used_in += gb->width;
3251 Dynarr_add (ib, *gb);
3260 avail_in = dl->bounds.right_in - white_in_end;
3265 avail_out = dl->bounds.right_out - white_out_end;
3268 while (!done && marker < Dynarr_length (ib))
3270 int width = Dynarr_atp (ib, marker)->width;
3272 /* If everything now fits in the available inside margin
3273 space, we're done. */
3274 if (used_in <= avail_in)
3278 /* Otherwise see if we have room to move a glyph to the
3280 if (used_out + width <= avail_out)
3293 /* At this point we now know that everything from marker on goes in
3294 the inside margin and everything before it goes in the outside
3295 margin. The stuff going into the outside margin is guaranteed
3296 to fit, but we may have to trim some stuff from the inside. */
3298 in_in_start = dl->bounds.right_in;
3299 in_out_end = dl->bounds.right_in;
3300 in_out_cnt = in_in_cnt = 0;
3304 while (elt < Dynarr_length (dl->right_glyphs))
3306 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3308 if (NILP (gb->extent))
3309 abort (); /* these should have been handled in add_glyph_rune */
3311 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3313 int width = glyph_width (gb->glyph, window);
3318 in_out_end += width;
3323 else if (in_in_start - width >= white_in_end)
3326 in_in_start -= width;
3338 /* Determine how many outside margin glyphs we can display. They
3339 always start at the right outside margin and can only use the
3340 outside margin space. */
3341 out_start = dl->bounds.right_out;
3345 while (elt < Dynarr_length (dl->right_glyphs))
3347 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3349 if (NILP (gb->extent))
3350 abort (); /* these should have been handled in add_glyph_rune */
3352 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_OUTSIDE_MARGIN)
3354 int width = glyph_width (gb->glyph, window);
3356 if (out_start - width >= in_out_end)
3370 /* Now that we now where everything goes, we add the glyphs as runes
3371 to the appropriate display blocks. */
3372 if (out_cnt || in_out_cnt || white_out_cnt)
3374 odb = get_display_block_from_line (dl, RIGHT_OUTSIDE_MARGIN);
3375 /* #### See comments before odb->start_pos init in
3376 create_left_glyph_block */
3377 odb->start_pos = dl->bounds.right_in;
3378 odb->end_pos = dl->bounds.right_out;
3379 Dynarr_reset (odb->runes);
3384 if (in_in_cnt || white_in_cnt)
3386 idb = get_display_block_from_line (dl, RIGHT_INSIDE_MARGIN);
3387 idb->start_pos = dl->bounds.right_white;
3388 /* #### See comments before odb->start_pos init in
3389 create_left_glyph_block */
3390 idb->end_pos = dl->bounds.right_in;
3391 Dynarr_reset (idb->runes);
3396 /* First add the whitespace margin glyphs which are actually in the
3400 end_xpos = add_margin_runes (dl, idb, dl->bounds.right_white,
3401 white_in_cnt, GL_WHITESPACE, RIGHT_GLYPHS,
3405 end_xpos = dl->bounds.right_white;
3407 /* Make sure that the area between the end of the whitespace glyphs
3408 and the inside margin glyphs is cleared. */
3409 if (in_in_cnt && (in_in_start - end_xpos))
3411 add_margin_blank (dl, idb, w, end_xpos, in_in_start - end_xpos,
3415 /* Next add the inside margin glyphs which are actually in the
3419 end_xpos = add_margin_runes (dl, idb, in_in_start, in_in_cnt,
3420 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3423 /* If we didn't add any inside margin glyphs then make sure the rest
3424 of the inside margin area gets cleared. */
3425 if (idb && (dl->bounds.right_in - end_xpos))
3427 add_margin_blank (dl, idb, w, end_xpos, dl->bounds.right_in - end_xpos,
3431 /* Next add any whitespace glyphs in the outside margin. */
3434 end_xpos = add_margin_runes (dl, odb, dl->bounds.right_in, white_out_cnt,
3435 GL_WHITESPACE, RIGHT_GLYPHS, window);
3438 end_xpos = dl->bounds.right_in;
3440 /* Next add any inside margin glyphs in the outside margin. */
3443 end_xpos = add_margin_runes (dl, odb, end_xpos, in_out_cnt,
3444 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3447 /* There may be space between any whitespace or inside margin glyphs
3448 in the outside margin and the actual outside margin glyphs. */
3449 if (odb && (out_start - end_xpos))
3451 add_margin_blank (dl, odb, w, end_xpos, out_start - end_xpos,
3455 /* Finally, add the outside margin glyphs. */
3458 add_margin_runes (dl, odb, out_start, out_cnt, GL_OUTSIDE_MARGIN,
3459 RIGHT_GLYPHS, window);
3464 /***************************************************************************/
3466 /* modeline routines */
3468 /***************************************************************************/
3470 /* This function is also used in frame.c by `generate_title_string' */
3472 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str,
3473 struct window *w, struct display_line *dl,
3474 struct display_block *db, face_index findex,
3475 int min_pixpos, int max_pixpos, int type)
3477 struct frame *f = XFRAME (w->frame);
3478 struct device *d = XDEVICE (f->device);
3482 Charcount offset = 0;
3488 data.findex = findex;
3489 data.pixpos = min_pixpos;
3490 data.max_pixpos = max_pixpos;
3491 data.cursor_type = NO_CURSOR;
3492 data.last_charset = Qunbound;
3493 data.last_findex = DEFAULT_INDEX;
3494 data.result_str = result_str;
3495 data.is_modeline = 1;
3497 XSETWINDOW (data.window, w);
3499 Dynarr_reset (formatted_string_extent_dynarr);
3500 Dynarr_reset (formatted_string_extent_start_dynarr);
3501 Dynarr_reset (formatted_string_extent_end_dynarr);
3503 /* result_str is nil when we're building a frame or icon title. Otherwise,
3504 we're building a modeline, so the offset starts at the modeline
3505 horizontal scrolling ammount */
3506 if (! NILP (result_str))
3507 offset = w->modeline_hscroll;
3508 generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0,
3509 max_pixpos - min_pixpos, findex, type, &offset,
3512 if (Dynarr_length (db->runes))
3515 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
3516 c_pixpos = rb->xpos + rb->width;
3519 c_pixpos = min_pixpos;
3521 /* If we don't reach the right side of the window, add a blank rune
3522 to make up the difference. This usually only occurs if the
3523 modeline face is using a proportional width font or a fixed width
3524 font of a different size from the default face font. */
3526 if (c_pixpos < max_pixpos)
3528 data.pixpos = c_pixpos;
3529 data.blank_width = max_pixpos - data.pixpos;
3531 add_blank_rune (&data, NULL, 0);
3534 /* Now create the result string and frob the extents into it. */
3535 if (!NILP (result_str))
3540 struct buffer *buf = XBUFFER (WINDOW_BUFFER (w));
3542 in_modeline_generation = 1;
3544 detach_all_extents (result_str);
3545 resize_string (XSTRING (result_str), -1,
3546 data.bytepos - XSTRING_LENGTH (result_str));
3548 strdata = XSTRING_DATA (result_str);
3550 for (elt = 0, len = 0; elt < Dynarr_length (db->runes); elt++)
3552 if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR)
3554 len += (set_charptr_emchar
3555 (strdata + len, Dynarr_atp (db->runes,
3556 elt)->object.chr.ch));
3560 for (elt = 0; elt < Dynarr_length (formatted_string_extent_dynarr);
3563 Lisp_Object extent = Qnil;
3566 XSETEXTENT (extent, Dynarr_at (formatted_string_extent_dynarr, elt));
3567 child = Fgethash (extent, buf->modeline_extent_table, Qnil);
3570 child = Fmake_extent (Qnil, Qnil, result_str);
3571 Fputhash (extent, child, buf->modeline_extent_table);
3573 Fset_extent_parent (child, extent);
3574 set_extent_endpoints
3576 Dynarr_at (formatted_string_extent_start_dynarr, elt),
3577 Dynarr_at (formatted_string_extent_end_dynarr, elt),
3581 in_modeline_generation = 0;
3585 /* Ensure that the given display line DL accurately represents the
3586 modeline for the given window. */
3588 generate_modeline (struct window *w, struct display_line *dl, int type)
3590 struct buffer *b = XBUFFER (w->buffer);
3591 struct frame *f = XFRAME (w->frame);
3592 struct device *d = XDEVICE (f->device);
3594 /* Unlike display line and rune pointers, this one can't change underneath
3596 struct display_block *db = get_display_block_from_line (dl, TEXT);
3597 int max_pixpos, min_pixpos, ypos_adj;
3598 Lisp_Object font_inst;
3600 /* This will actually determine incorrect inside boundaries for the
3601 modeline since it ignores the margins. However being aware of this fact
3602 we never use those values anywhere so it doesn't matter. */
3603 dl->bounds = calculate_display_line_boundaries (w, 1);
3605 /* We are generating a modeline. */
3607 dl->cursor_elt = -1;
3609 /* Reset the runes on the modeline. */
3610 Dynarr_reset (db->runes);
3612 if (!WINDOW_HAS_MODELINE_P (w))
3616 /* If there is a horizontal scrollbar, don't add anything. */
3617 if (window_scrollbar_height (w))
3620 dl->ascent = DEVMETH (d, divider_height, ());
3622 /* The modeline is at the bottom of the gutters. */
3623 dl->ypos = WINDOW_BOTTOM (w);
3625 rb.findex = MODELINE_INDEX;
3626 rb.xpos = dl->bounds.left_out;
3627 rb.width = dl->bounds.right_out - dl->bounds.left_out;
3630 rb.type = RUNE_HLINE;
3631 rb.object.hline.thickness = 1;
3632 rb.object.hline.yoffset = 0;
3633 rb.cursor_type = NO_CURSOR;
3635 if (!EQ (Qzero, w->modeline_shadow_thickness)
3638 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3640 dl->ypos -= shadow_thickness;
3641 rb.xpos += shadow_thickness;
3642 rb.width -= 2 * shadow_thickness;
3645 Dynarr_add (db->runes, rb);
3649 /* !!#### not right; needs to compute the max height of
3651 font_inst = WINDOW_FACE_CACHEL_FONT (w, MODELINE_INDEX, Vcharset_ascii);
3653 dl->ascent = XFONT_INSTANCE (font_inst)->ascent;
3654 dl->descent = XFONT_INSTANCE (font_inst)->descent;
3656 min_pixpos = dl->bounds.left_out;
3657 max_pixpos = dl->bounds.right_out;
3659 if (!EQ (Qzero, w->modeline_shadow_thickness) && FRAME_WIN_P (f))
3661 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3663 ypos_adj = shadow_thickness;
3664 min_pixpos += shadow_thickness;
3665 max_pixpos -= shadow_thickness;
3670 generate_formatted_string_db (b->modeline_format,
3671 b->generated_modeline_string, w, dl, db,
3672 MODELINE_INDEX, min_pixpos, max_pixpos, type);
3674 /* The modeline is at the bottom of the gutters. We have to wait to
3675 set this until we've generated the modeline in order to account
3676 for any embedded faces. */
3677 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj;
3681 add_string_to_fstring_db_runes (pos_data *data, const Bufbyte *str,
3682 Charcount pos, Charcount min_pos, Charcount max_pos)
3684 /* This function has been Mule-ized. */
3686 const Bufbyte *cur_pos = str;
3687 struct display_block *db = data->db;
3689 data->blank_width = space_width (XWINDOW (data->window));
3690 while (Dynarr_length (db->runes) < pos)
3691 add_blank_rune (data, NULL, 0);
3693 end = (Dynarr_length (db->runes) +
3694 bytecount_to_charcount (str, strlen ((const char *) str)));
3696 end = min (max_pos, end);
3698 while (pos < end && *cur_pos)
3700 const Bufbyte *old_cur_pos = cur_pos;
3703 data->ch = charptr_emchar (cur_pos);
3704 succeeded = (add_emchar_rune (data) != ADD_FAILED);
3705 INC_CHARPTR (cur_pos);
3709 data->modeline_charpos++;
3710 data->bytepos += cur_pos - old_cur_pos;
3714 while (Dynarr_length (db->runes) < min_pos &&
3715 (data->pixpos + data->blank_width <= data->max_pixpos))
3716 add_blank_rune (data, NULL, 0);
3718 return Dynarr_length (db->runes);
3721 /* #### Urk! Should also handle begin-glyphs and end-glyphs in
3722 modeline extents. */
3724 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph,
3725 Charcount pos, Charcount min_pos,
3726 Charcount max_pos, Lisp_Object extent)
3728 /* This function has been Mule-ized. */
3730 struct display_block *db = data->db;
3731 struct glyph_block gb;
3733 data->blank_width = space_width (XWINDOW (data->window));
3734 while (Dynarr_length (db->runes) < pos)
3735 add_blank_rune (data, NULL, 0);
3737 end = Dynarr_length (db->runes) + 1;
3739 end = min (max_pos, end);
3743 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
3746 while (Dynarr_length (db->runes) < pos &&
3747 (data->pixpos + data->blank_width <= data->max_pixpos))
3748 add_blank_rune (data, NULL, 0);
3750 return Dynarr_length (db->runes);
3753 /* If max_pos is == -1, it is considered to be infinite. The same is
3754 true of max_pixsize. */
3755 #define SET_CURRENT_MODE_CHARS_PIXSIZE \
3756 if (Dynarr_length (data->db->runes)) \
3757 cur_pixsize = data->pixpos - Dynarr_atp (data->db->runes, 0)->xpos; \
3761 /* Note that this function does "positions" in terms of characters and
3762 not in terms of columns. This is necessary to make the formatting
3763 work correctly when proportional width fonts are used in the
3766 generate_fstring_runes (struct window *w, pos_data *data, Charcount pos,
3767 Charcount min_pos, Charcount max_pos,
3768 Lisp_Object elt, int depth, int max_pixsize,
3769 face_index findex, int type, Charcount *offset,
3770 Lisp_Object cur_ext)
3772 /* This function has been Mule-ized. */
3773 /* #### The other losing things in this function are:
3775 -- C zero-terminated-string lossage.
3776 -- Non-printable characters should be converted into something
3777 appropriate (e.g. ^F) instead of blindly being printed anyway.
3788 /* A string. Add to the display line and check for %-constructs
3791 Bufbyte *this = XSTRING_DATA (elt);
3793 while ((pos < max_pos || max_pos == -1) && *this)
3795 Bufbyte *last = this;
3797 while (*this && *this != '%')
3802 /* No %-construct */
3804 bytecount_to_charcount (last, this - last);
3806 if (size <= *offset)
3810 Charcount tmp_max = (max_pos == -1 ? pos + size - *offset :
3811 min (pos + size - *offset, max_pos));
3812 const Bufbyte *tmp_last = charptr_n_addr (last, *offset);
3814 pos = add_string_to_fstring_db_runes (data, tmp_last,
3819 else /* *this == '%' */
3821 Charcount spec_width = 0;
3823 this++; /* skip over '%' */
3825 /* We can't allow -ve args due to the "%-" construct.
3826 * Argument specifies minwidth but not maxwidth
3827 * (maxwidth can be specified by
3828 * (<negative-number> . <stuff>) modeline elements)
3830 while (isdigit (*this))
3832 spec_width = spec_width * 10 + (*this - '0');
3839 pos = generate_fstring_runes (w, data, pos, spec_width,
3840 max_pos, Vglobal_mode_string,
3841 depth, max_pixsize, findex,
3842 type, offset, cur_ext);
3844 else if (*this == '-')
3846 Charcount num_to_add;
3848 if (max_pixsize < 0)
3850 else if (max_pos != -1)
3851 num_to_add = max_pos - pos;
3857 SET_CURRENT_MODE_CHARS_PIXSIZE;
3860 redisplay_text_width_string (w, findex, &ch, Qnil, 0,
3863 num_to_add = (max_pixsize - cur_pixsize) / dash_pixsize;
3867 while (num_to_add--)
3868 pos = add_string_to_fstring_db_runes
3869 (data, (const Bufbyte *) "-", pos, pos, max_pos);
3871 else if (*this != 0)
3873 Emchar ch = charptr_emchar (this);
3877 decode_mode_spec (w, ch, type);
3879 str = Dynarr_atp (mode_spec_bufbyte_string, 0);
3880 size = bytecount_to_charcount
3881 /* Skip the null character added by `decode_mode_spec' */
3882 (str, Dynarr_length (mode_spec_bufbyte_string)) - 1;
3884 if (size <= *offset)
3888 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3890 /* #### NOTE: I don't understand why a tmp_max is not
3891 computed and used here as in the plain string case
3893 pos = add_string_to_fstring_db_runes (data, tmp_str,
3900 /* NOT this++. There could be any sort of character at
3901 the current position. */
3905 if (max_pixsize > 0)
3908 SET_CURRENT_MODE_CHARS_PIXSIZE;
3910 if (cur_pixsize >= max_pixsize)
3915 else if (SYMBOLP (elt))
3917 /* A symbol: process the value of the symbol recursively
3918 as if it appeared here directly. */
3919 Lisp_Object tem = symbol_value_in_buffer (elt, w->buffer);
3921 if (!UNBOUNDP (tem))
3923 /* If value is a string, output that string literally:
3924 don't check for % within it. */
3927 Bufbyte *str = XSTRING_DATA (tem);
3928 Charcount size = XSTRING_CHAR_LENGTH (tem);
3930 if (size <= *offset)
3934 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3936 /* #### NOTE: I don't understand why a tmp_max is not
3937 computed and used here as in the plain string case
3939 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
3944 /* Give up right away for nil or t. */
3945 else if (!EQ (tem, elt))
3952 else if (GENERIC_SPECIFIERP (elt))
3954 Lisp_Object window, tem;
3955 XSETWINDOW (window, w);
3956 tem = specifier_instance_no_quit (elt, Qunbound, window,
3957 ERROR_ME_NOT, 0, Qzero);
3958 if (!UNBOUNDP (tem))
3964 else if (CONSP (elt))
3966 /* A cons cell: four distinct cases.
3967 * - If first element is a string or a cons, process all the elements
3968 * and effectively concatenate them.
3969 * - If first element is a negative number, truncate displaying cdr to
3970 * at most that many characters. If positive, pad (with spaces)
3971 * to at least that many characters.
3972 * - If first element is another symbol, process the cadr or caddr
3973 * recursively according to whether the symbol's value is non-nil or
3975 * - If first element is an extent, process the cdr recursively
3976 * and handle the extent's face.
3979 Lisp_Object car, tem;
3988 tem = symbol_value_in_buffer (car, w->buffer);
3989 /* elt is now the cdr, and we know it is a cons cell.
3990 Use its car if CAR has a non-nil value. */
3991 if (!UNBOUNDP (tem))
3999 /* Symbol's value is nil (or symbol is unbound)
4000 * Get the cddr of the original list
4001 * and if possible find the caddr and use that.
4006 else if (!CONSP (elt))
4014 else if (INTP (car))
4016 Charcount lim = XINT (car);
4022 /* Negative int means reduce maximum width.
4023 * DO NOT change MIN_PIXPOS here!
4024 * (20 -10 . foo) should truncate foo to 10 col
4025 * and then pad to 20.
4028 max_pos = pos - lim;
4030 max_pos = min (max_pos, pos - lim);
4034 /* Padding specified. Don't let it be more than
4038 if (max_pos != -1 && lim > max_pos)
4040 /* If that's more padding than already wanted, queue it.
4041 * But don't reduce padding already specified even if
4042 * that is beyond the current truncation point.
4049 else if (STRINGP (car) || CONSP (car))
4053 /* LIMIT is to protect against circular lists. */
4054 while (CONSP (elt) && --limit > 0
4055 && (pos < max_pos || max_pos == -1))
4057 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4058 XCAR (elt), depth, max_pixsize,
4059 findex, type, offset, cur_ext);
4063 else if (EXTENTP (car))
4065 struct extent *ext = XEXTENT (car);
4067 if (EXTENT_LIVE_P (ext))
4069 face_index old_findex = data->findex;
4071 Lisp_Object font_inst;
4072 face_index new_findex;
4073 Bytecount start = data->bytepos;
4075 face = extent_face (ext);
4078 /* #### needs to merge faces, sigh */
4079 /* #### needs to handle list of faces */
4080 new_findex = get_builtin_face_cache_index (w, face);
4081 /* !!#### not right; needs to compute the max height of
4083 font_inst = WINDOW_FACE_CACHEL_FONT (w, new_findex,
4086 data->dl->ascent = max (data->dl->ascent,
4087 XFONT_INSTANCE (font_inst)->ascent);
4088 data->dl->descent = max (data->dl->descent,
4089 XFONT_INSTANCE (font_inst)->
4093 new_findex = old_findex;
4095 data->findex = new_findex;
4096 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4097 XCDR (elt), depth - 1,
4098 max_pixsize, new_findex, type,
4100 data->findex = old_findex;
4101 Dynarr_add (formatted_string_extent_dynarr, ext);
4102 Dynarr_add (formatted_string_extent_start_dynarr, start);
4103 Dynarr_add (formatted_string_extent_end_dynarr, data->bytepos);
4107 else if (GLYPHP (elt))
4109 /* Glyphs are considered as one character with respect to the modeline
4110 horizontal scrolling facility. -- dv */
4114 pos = add_glyph_to_fstring_db_runes (data, elt, pos, pos, max_pos,
4121 char *str = GETTEXT ("*invalid*");
4122 Charcount size = (Charcount) strlen (str); /* is this ok ?? -- dv */
4124 if (size <= *offset)
4128 const Bufbyte *tmp_str =
4129 charptr_n_addr ((const Bufbyte *) str, *offset);
4131 /* #### NOTE: I don't understand why a tmp_max is not computed and
4132 used here as in the plain string case above. -- dv */
4133 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
4142 add_string_to_fstring_db_runes (data, (const Bufbyte *) "", pos,
4149 /* Update just the modeline. Assumes the desired display structs. If
4150 they do not have a modeline block, it does nothing. */
4152 regenerate_modeline (struct window *w)
4154 display_line_dynarr *dla = window_display_lines (w, DESIRED_DISP);
4156 if (!Dynarr_length (dla) || !Dynarr_atp (dla, 0)->modeline)
4160 generate_modeline (w, Dynarr_atp (dla, 0), DESIRED_DISP);
4161 redisplay_update_line (w, 0, 0, 0);
4165 /* Make sure that modeline display line is present in the given
4166 display structs if the window has a modeline and update that
4167 line. Returns true if a modeline was needed. */
4169 ensure_modeline_generated (struct window *w, int type)
4173 /* minibuffer windows don't have modelines */
4174 if (MINI_WINDOW_P (w))
4176 /* windows which haven't had it turned off do */
4177 else if (WINDOW_HAS_MODELINE_P (w))
4179 /* windows which have it turned off don't have a divider if there is
4180 a horizontal scrollbar */
4181 else if (window_scrollbar_height (w))
4183 /* and in this case there is none */
4189 display_line_dynarr *dla;
4191 dla = window_display_lines (w, type);
4193 /* We don't care if there is a display line which is not
4194 currently a modeline because it is definitely going to become
4195 one if we have gotten to this point. */
4196 if (Dynarr_length (dla) == 0)
4198 if (Dynarr_largest (dla) > 0)
4200 struct display_line *mlp = Dynarr_atp (dla, 0);
4201 Dynarr_add (dla, *mlp);
4205 struct display_line modeline;
4207 Dynarr_add (dla, modeline);
4211 /* If we're adding a new place marker go ahead and generate the
4212 modeline so that it is available for use by
4213 window_modeline_height. */
4214 generate_modeline (w, Dynarr_atp (dla, 0), type);
4217 return need_modeline;
4220 /* #### Kludge or not a kludge. I tend towards the former. */
4222 real_current_modeline_height (struct window *w)
4224 Fset_marker (w->start[CMOTION_DISP], w->start[CURRENT_DISP], w->buffer);
4225 Fset_marker (w->pointm[CMOTION_DISP], w->pointm[CURRENT_DISP], w->buffer);
4227 if (ensure_modeline_generated (w, CMOTION_DISP))
4229 display_line_dynarr *dla = window_display_lines (w, CMOTION_DISP);
4231 if (Dynarr_length (dla))
4233 if (Dynarr_atp (dla, 0)->modeline)
4234 return (Dynarr_atp (dla, 0)->ascent +
4235 Dynarr_atp (dla, 0)->descent);
4242 /***************************************************************************/
4244 /* displayable string routines */
4246 /***************************************************************************/
4248 /* Given a position for a string in a window, ensure that the given
4249 display line DL accurately represents the text on a line starting
4250 at the given position.
4252 Yes, this is duplicating the code of create_text_block, but it
4253 looked just too hard to change create_text_block to handle strings
4254 *and* buffers. We already make a distinction between the two
4255 elsewhere in the code so I think unifying them would require a
4256 complete MULE rewrite. Besides, the other distinction is that these
4257 functions cover text that the user *cannot edit* so we can remove
4258 everything to do with cursors, minibuffers etc. Eventually the
4259 modeline routines should be modified to use this code as it copes
4260 with many more types of display situation. */
4263 create_string_text_block (struct window *w, Lisp_Object disp_string,
4264 struct display_line *dl,
4266 prop_block_dynarr **prop,
4267 face_index default_face)
4269 struct frame *f = XFRAME (w->frame);
4270 /* Note that a lot of the buffer controlled stuff has been left in
4271 because you might well want to make use of it (selective display
4272 etc), its just the buffer text that we do not use. However, it
4273 seems to be possible for buffer to be nil sometimes so protect
4274 against this case. */
4275 struct buffer *b = BUFFERP (w->buffer) ? XBUFFER (w->buffer) : 0;
4276 struct device *d = XDEVICE (f->device);
4277 Lisp_String* s = XSTRING (disp_string);
4279 /* we're working with these a lot so precalculate them */
4280 Bytecount slen = XSTRING_LENGTH (disp_string);
4281 Bytecount bi_string_zv = slen;
4282 Bytind bi_start_pos = charcount_to_bytecount (string_data (s), start_pos);
4286 int truncate_win = b ? window_truncation_on (w) : 0;
4287 int end_glyph_width = 0;
4289 /* we're going to ditch selective display for static text, its an
4290 FSF thing and invisble extents are the way to go
4291 here. Implementing it also relies on a number of buffer-specific
4292 functions that we don't have the luxury of being able to use
4295 /* The variable ctl-arrow allows the user to specify what characters
4296 can actually be displayed and which octal should be used for.
4297 #### This variable should probably have some rethought done to
4300 #### It would also be really nice if you could specify that
4301 the characters come out in hex instead of in octal. Mule
4302 does that by adding a ctl-hexa variable similar to ctl-arrow,
4303 but that's bogus -- we need a more general solution. I
4304 think you need to extend the concept of display tables
4305 into a more general conversion mechanism. Ideally you
4306 could specify a Lisp function that converts characters,
4307 but this violates the Second Golden Rule and besides would
4308 make things way way way way slow.
4310 So instead, we extend the display-table concept, which was
4311 historically limited to 256-byte vectors, to one of the
4314 a) A 256-entry vector, for backward compatibility;
4315 b) char-table, mapping characters to values;
4316 c) range-table, mapping ranges of characters to values;
4317 d) a list of the above.
4319 The (d) option allows you to specify multiple display tables
4320 instead of just one. Each display table can specify conversions
4321 for some characters and leave others unchanged. The way the
4322 character gets displayed is determined by the first display table
4323 with a binding for that character. This way, you could call a
4324 function `enable-hex-display' that adds a hex display-table to
4325 the list of display tables for the current buffer.
4327 #### ...not yet implemented... Also, we extend the concept of
4328 "mapping" to include a printf-like spec. Thus you can make all
4329 extended characters show up as hex with a display table like
4332 #s(range-table data ((256 524288) (format "%x")))
4334 Since more than one display table is possible, you have
4335 great flexibility in mapping ranges of characters. */
4336 Emchar printable_min = b ? (CHAR_OR_CHAR_INTP (b->ctl_arrow)
4337 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
4338 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
4339 ? 255 : 160)) : 255;
4341 Lisp_Object face_dt, window_dt;
4343 /* The text display block for this display line. */
4344 struct display_block *db = get_display_block_from_line (dl, TEXT);
4346 /* The first time through the main loop we need to force the glyph
4347 data to be updated. */
4350 /* Apparently the new extent_fragment_update returns an end position
4351 equal to the position passed in if there are no more runs to be
4353 int no_more_frags = 0;
4355 dl->used_prop_data = 0;
4357 dl->line_continuation = 0;
4359 /* set up faces to use for clearing areas, used by
4360 output_display_line */
4361 dl->default_findex = default_face;
4364 dl->left_margin_findex = default_face;
4365 dl->right_margin_findex = default_face;
4369 dl->left_margin_findex =
4370 get_builtin_face_cache_index (w, Vleft_margin_face);
4371 dl->right_margin_findex =
4372 get_builtin_face_cache_index (w, Vright_margin_face);
4376 data.ef = extent_fragment_new (disp_string, f);
4378 /* These values are used by all of the rune addition routines. We add
4379 them to this structure for ease of passing. */
4381 XSETWINDOW (data.window, w);
4385 data.bi_bufpos = bi_start_pos;
4386 data.pixpos = dl->bounds.left_in;
4387 data.last_charset = Qunbound;
4388 data.last_findex = default_face;
4389 data.result_str = Qnil;
4390 data.string = disp_string;
4392 /* Set the right boundary adjusting it to take into account any end
4393 glyph. Save the width of the end glyph for later use. */
4394 data.max_pixpos = dl->bounds.right_in;
4397 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
4399 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
4401 data.max_pixpos -= end_glyph_width;
4403 data.cursor_type = NO_CURSOR;
4407 /* I don't think we want this, string areas should not scroll with
4409 data.start_col = w->hscroll;
4410 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
4412 data.bi_start_col_enabled = 0;
4413 data.hscroll_glyph_width_adjust = 0;
4415 /* We regenerate the line from the very beginning. */
4416 Dynarr_reset (db->runes);
4418 /* Why is this less than or equal and not just less than? If the
4419 starting position is already equal to the maximum we can't add
4420 anything else, right? Wrong. We might still have a newline to
4421 add. A newline can use the room allocated for an end glyph since
4422 if we add it we know we aren't going to be adding any end
4425 /* #### Chuck -- I think this condition should be while (1).
4426 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
4427 and the begin-glyph ends exactly at the end of the window, the
4428 end-glyph and text might not be displayed. while (1) ensures
4429 that the loop terminates only when either (a) there is
4430 propagation data or (b) the end-of-line or end-of-buffer is hit.
4432 #### Also I think you need to ensure that the operation
4433 "add begin glyphs; add end glyphs; add text" is atomic and
4434 can't get interrupted in the middle. If you run off the end
4435 of the line during that operation, then you keep accumulating
4436 propagation data until you're done. Otherwise, if the (e.g.)
4437 there's a begin glyph at a particular position and attempting
4438 to display that glyph results in window-end being hit and
4439 propagation data being generated, then the character at that
4440 position won't be displayed.
4442 #### See also the comment after the end of this loop, below.
4444 while (data.pixpos <= data.max_pixpos)
4446 /* #### This check probably should not be necessary. */
4447 if (data.bi_bufpos > bi_string_zv)
4449 /* #### urk! More of this lossage! */
4454 /* Check for face changes. */
4455 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
4457 /* Now compute the face and begin/end-glyph information. */
4459 /* Remember that the extent-fragment routines deal in Bytind's. */
4460 extent_fragment_update (w, data.ef, data.bi_bufpos);
4461 /* This is somewhat cheesy but the alternative is to
4462 propagate default_face into extent_fragment_update. */
4463 if (data.findex == DEFAULT_INDEX)
4464 data.findex = default_face;
4466 get_display_tables (w, data.findex, &face_dt, &window_dt);
4468 if (data.bi_bufpos == data.ef->end)
4473 /* Determine what is next to be displayed. We first handle any
4474 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
4475 display then we determine what to do based on the character at the
4476 current buffer position. */
4478 /* If the current position is covered by an invisible extent, do
4479 nothing (except maybe add some ellipses).
4481 #### The behavior of begin and end-glyphs at the edge of an
4482 invisible extent should be investigated further. This is
4483 fairly low priority though. */
4484 if (data.ef->invisible)
4486 /* #### Chuck, perhaps you could look at this code? I don't
4487 really know what I'm doing. */
4490 Dynarr_free (*prop);
4494 /* The extent fragment code only sets this when we should
4495 really display the ellipses. It makes sure the ellipses
4496 don't get displayed more than once in a row. */
4497 if (data.ef->invisible_ellipses)
4499 struct glyph_block gb;
4501 data.ef->invisible_ellipses_already_displayed = 1;
4502 data.ef->invisible_ellipses = 0;
4504 gb.glyph = Vinvisible_text_glyph;
4505 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
4506 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
4507 /* Perhaps they shouldn't propagate if the very next thing
4508 is to display a newline (for compatibility with
4509 selective-display-ellipses)? Maybe that's too
4515 /* #### What if we we're dealing with a display table? */
4519 if (data.bi_bufpos == bi_string_zv)
4522 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4525 /* If there is propagation data, then it represents the current
4526 buffer position being displayed. Add them and advance the
4527 position counter. This might also add the minibuffer
4531 dl->used_prop_data = 1;
4532 *prop = add_propagation_runes (prop, &data);
4535 goto done; /* gee, a really narrow window */
4536 else if (data.bi_bufpos == bi_string_zv)
4538 else if (data.bi_bufpos < 0)
4539 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
4542 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4545 /* If there are end glyphs, add them to the line. These are
4546 the end glyphs for the previous run of text. We add them
4547 here rather than doing them at the end of handling the
4548 previous run so that glyphs at the beginning and end of
4549 a line are handled correctly. */
4550 else if (Dynarr_length (data.ef->end_glyphs) > 0)
4552 *prop = add_glyph_runes (&data, END_GLYPHS);
4557 /* If there are begin glyphs, add them to the line. */
4558 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
4560 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
4565 /* If at end-of-buffer, we've already processed begin and
4566 end-glyphs at this point and there's no text to process,
4568 else if (data.bi_bufpos == bi_string_zv)
4573 Lisp_Object entry = Qnil;
4574 /* Get the character at the current buffer position. */
4575 data.ch = string_char (s, data.bi_bufpos);
4576 if (!NILP (face_dt) || !NILP (window_dt))
4577 entry = display_table_entry (data.ch, face_dt, window_dt);
4579 /* If there is a display table entry for it, hand it off to
4580 add_disp_table_entry_runes and let it worry about it. */
4581 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
4583 *prop = add_disp_table_entry_runes (&data, entry);
4589 /* Check if we have hit a newline character. If so, add a marker
4590 to the line and end this loop. */
4591 else if (data.ch == '\n')
4593 /* We aren't going to be adding an end glyph so give its
4594 space back in order to make sure that the cursor can
4596 data.max_pixpos += end_glyph_width;
4600 /* If the current character is considered to be printable, then
4602 else if (data.ch >= printable_min)
4604 *prop = add_emchar_rune (&data);
4609 /* If the current character is a tab, determine the next tab
4610 starting position and add a blank rune which extends from the
4611 current pixel position to that starting position. */
4612 else if (data.ch == '\t')
4614 int tab_start_pixpos = data.pixpos;
4619 if (data.start_col > 1)
4620 tab_start_pixpos -= (space_width (w) * (data.start_col - 1));
4623 next_tab_position (w, tab_start_pixpos,
4624 dl->bounds.left_in +
4625 data.hscroll_glyph_width_adjust);
4626 if (next_tab_start > data.max_pixpos)
4628 prop_width = next_tab_start - data.max_pixpos;
4629 next_tab_start = data.max_pixpos;
4631 data.blank_width = next_tab_start - data.pixpos;
4633 (next_tab_start - tab_start_pixpos) / space_width (w);
4635 *prop = add_blank_rune (&data, w, char_tab_width);
4637 /* add_blank_rune is only supposed to be called with
4638 sizes guaranteed to fit in the available space. */
4643 struct prop_block pb;
4644 *prop = Dynarr_new (prop_block);
4646 pb.type = PROP_BLANK;
4647 pb.data.p_blank.width = prop_width;
4648 pb.data.p_blank.findex = data.findex;
4649 Dynarr_add (*prop, pb);
4655 /* If character is a control character, pass it off to
4656 add_control_char_runes.
4658 The is_*() routines have undefined results on
4659 arguments outside of the range [-1, 255]. (This
4660 often bites people who carelessly use `char' instead
4661 of `unsigned char'.)
4663 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
4665 *prop = add_control_char_runes (&data, b);
4671 /* If the character is above the ASCII range and we have not
4672 already handled it, then print it as an octal number. */
4673 else if (data.ch >= 0200)
4675 *prop = add_octal_runes (&data);
4681 /* Assume the current character is considered to be printable,
4682 then just add it. */
4685 *prop = add_emchar_rune (&data);
4690 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4696 /* Determine the starting point of the next line if we did not hit the
4697 end of the buffer. */
4698 if (data.bi_bufpos < bi_string_zv)
4700 /* #### This check is not correct. If the line terminated
4701 due to a begin-glyph or end-glyph hitting window-end, then
4702 data.ch will not point to the character at data.bi_bufpos. If
4703 you make the two changes mentioned at the top of this loop,
4704 you should be able to say '(if (*prop))'. That should also
4705 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
4708 /* The common case is that the line ended because we hit a newline.
4709 In that case, the next character is just the next buffer
4711 if (data.ch == '\n')
4713 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4716 /* Otherwise we have a buffer line which cannot fit on one display
4720 struct glyph_block gb;
4721 struct glyph_cachel *cachel;
4723 /* If the line is to be truncated then we actually have to look
4724 for the next newline. We also add the end-of-line glyph which
4725 we know will fit because we adjusted the right border before
4726 we starting laying out the line. */
4727 data.max_pixpos += end_glyph_width;
4728 data.findex = default_face;
4735 /* Now find the start of the next line. */
4736 bi_pos = bi_find_next_emchar_in_string (s, '\n', data.bi_bufpos, 1);
4738 data.cursor_type = NO_CURSOR;
4739 data.bi_bufpos = bi_pos;
4740 gb.glyph = Vtruncation_glyph;
4741 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
4745 /* The cursor can never be on the continuation glyph. */
4746 data.cursor_type = NO_CURSOR;
4748 /* data.bi_bufpos is already at the start of the next line. */
4750 dl->line_continuation = 1;
4751 gb.glyph = Vcontinuation_glyph;
4752 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
4755 if (end_glyph_width)
4756 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
4758 if (truncate_win && data.bi_bufpos == bi_string_zv)
4760 const Bufbyte* endb = charptr_n_addr (string_data (s), bi_string_zv);
4762 if (charptr_emchar (endb) != '\n')
4764 /* #### Damn this losing shit. */
4770 else if (data.bi_bufpos == bi_string_zv)
4772 /* create_text_block () adds a bogus \n marker here which screws
4773 up subwindow display. Since we never have a cursor in the
4774 gutter we can safely ignore it. */
4776 /* Calculate left whitespace boundary. */
4780 /* Whitespace past a newline is considered right whitespace. */
4781 while (elt < Dynarr_length (db->runes))
4783 struct rune *rb = Dynarr_atp (db->runes, elt);
4785 if ((rb->type == RUNE_CHAR && rb->object.chr.ch == ' ')
4786 || rb->type == RUNE_BLANK)
4788 dl->bounds.left_white += rb->width;
4792 elt = Dynarr_length (db->runes);
4796 /* Calculate right whitespace boundary. */
4798 int elt = Dynarr_length (db->runes) - 1;
4801 while (!done && elt >= 0)
4803 struct rune *rb = Dynarr_atp (db->runes, elt);
4805 if (!(rb->type == RUNE_CHAR && rb->object.chr.ch < 0x100
4806 && isspace (rb->object.chr.ch))
4807 && !rb->type == RUNE_BLANK)
4809 dl->bounds.right_white = rb->xpos + rb->width;
4817 /* The line is blank so everything is considered to be right
4820 dl->bounds.right_white = dl->bounds.left_in;
4823 /* Set the display blocks bounds. */
4824 db->start_pos = dl->bounds.left_in;
4825 if (Dynarr_length (db->runes))
4827 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
4829 db->end_pos = rb->xpos + rb->width;
4832 db->end_pos = dl->bounds.right_white;
4834 /* update line height parameters */
4835 if (!data.new_ascent && !data.new_descent)
4837 /* We've got a blank line so initialize these values from the default
4839 default_face_font_info (data.window, &data.new_ascent,
4840 &data.new_descent, 0, 0, 0);
4843 if (data.max_pixmap_height)
4845 int height = data.new_ascent + data.new_descent;
4846 int pix_ascent, pix_descent;
4848 pix_descent = data.max_pixmap_height * data.new_descent / height;
4849 pix_ascent = data.max_pixmap_height - pix_descent;
4851 data.new_ascent = max (data.new_ascent, pix_ascent);
4852 data.new_descent = max (data.new_descent, pix_descent);
4855 dl->ascent = data.new_ascent;
4856 dl->descent = data.new_descent;
4859 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
4861 if (dl->ascent < ascent)
4862 dl->ascent = ascent;
4865 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
4867 if (dl->descent < descent)
4868 dl->descent = descent;
4871 dl->cursor_elt = data.cursor_x;
4872 /* #### lossage lossage lossage! Fix this shit! */
4873 if (data.bi_bufpos > bi_string_zv)
4874 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, bi_string_zv);
4876 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, data.bi_bufpos) - 1;
4878 data.dl->num_chars =
4879 string_column_at_point (s, dl->end_bufpos, b ? XINT (b->tab_width) : 8);
4881 /* This doesn't correctly take into account tabs and control
4882 characters but if the window isn't being truncated then this
4883 value isn't going to end up being used anyhow. */
4884 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
4886 /* #### handle horizontally scrolled line with text none of which
4887 was actually laid out. */
4889 /* #### handle any remainder of overlay arrow */
4891 if (*prop == ADD_FAILED)
4894 if (truncate_win && *prop)
4896 Dynarr_free (*prop);
4900 extent_fragment_delete (data.ef);
4902 /* #### If we started at EOB, then make sure we return a value past
4903 it so that regenerate_window will exit properly. This is bogus.
4904 The main loop should get fixed so that it isn't necessary to call
4905 this function if we are already at EOB. */
4907 if (data.bi_bufpos == bi_string_zv && bi_start_pos == bi_string_zv)
4908 return bytecount_to_charcount (string_data (s), data.bi_bufpos) + 1; /* Yuck! */
4910 return bytecount_to_charcount (string_data (s), data.bi_bufpos);
4913 /* Given a display line and a starting position, ensure that the
4914 contents of the display line accurately represent the visual
4915 representation of the buffer contents starting from the given
4916 position when displayed in the given window. The display line ends
4917 when the contents of the line reach the right boundary of the given
4920 This is very similar to generate_display_line but with the same
4921 limitations as create_string_text_block. I have taken the liberty
4922 of fixing the bytind stuff though.*/
4925 generate_string_display_line (struct window *w, Lisp_Object disp_string,
4926 struct display_line *dl,
4928 prop_block_dynarr **prop,
4929 face_index default_face)
4933 /* you must set bounds before calling this. */
4935 /* Reset what this line is using. */
4936 if (dl->display_blocks)
4937 Dynarr_reset (dl->display_blocks);
4938 if (dl->left_glyphs)
4940 Dynarr_free (dl->left_glyphs);
4941 dl->left_glyphs = 0;
4943 if (dl->right_glyphs)
4945 Dynarr_free (dl->right_glyphs);
4946 dl->right_glyphs = 0;
4949 /* We aren't generating a modeline at the moment. */
4952 /* Create a display block for the text region of the line. */
4953 ret_bufpos = create_string_text_block (w, disp_string, dl, start_pos,
4954 prop, default_face);
4955 dl->bufpos = start_pos;
4956 if (dl->end_bufpos < dl->bufpos)
4957 dl->end_bufpos = dl->bufpos;
4959 /* If there are left glyphs associated with any character in the
4960 text block, then create a display block to handle them. */
4961 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
4962 create_left_glyph_block (w, dl, 0);
4964 /* If there are right glyphs associated with any character in the
4965 text block, then create a display block to handle them. */
4966 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
4967 create_right_glyph_block (w, dl);
4972 /* This is ripped off from regenerate_window. All we want to do is
4973 loop through elements in the string creating display lines until we
4974 have covered the provided area. Simple really. */
4976 generate_displayable_area (struct window *w, Lisp_Object disp_string,
4977 int xpos, int ypos, int width, int height,
4978 display_line_dynarr* dla,
4980 face_index default_face)
4982 int yend = ypos + height;
4985 prop_block_dynarr *prop = 0;
4986 layout_bounds bounds;
4990 /* if there's nothing to do then do nothing. code after this assumes
4991 there is something to do. */
4992 if (NILP (disp_string))
4995 s_zv = XSTRING_CHAR_LENGTH (disp_string);
4997 bounds.left_out = xpos;
4998 bounds.right_out = xpos + width;
4999 /* The inner boundaries mark where the glyph margins are located. */
5000 bounds.left_in = bounds.left_out + window_left_margin_width (w);
5001 bounds.right_in = bounds.right_out - window_right_margin_width (w);
5002 /* We cannot fully calculate the whitespace boundaries as they
5003 depend on the contents of the line being displayed. */
5004 bounds.left_white = bounds.left_in;
5005 bounds.right_white = bounds.right_in;
5009 struct display_line dl;
5010 struct display_line *dlp;
5014 if (Dynarr_length (dla) < Dynarr_largest (dla))
5016 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5027 dlp->bounds = bounds;
5029 next_pos = generate_string_display_line (w, disp_string, dlp, start_pos,
5030 &prop, default_face);
5031 /* we need to make sure that we continue along the line if there
5032 is more left to display otherwise we just end up redisplaying
5033 the same chunk over and over again. */
5034 if (next_pos == start_pos && next_pos < s_zv)
5037 start_pos = next_pos;
5039 dlp->ypos = ypos + dlp->ascent;
5040 ypos = dlp->ypos + dlp->descent;
5044 int visible_height = dlp->ascent + dlp->descent;
5046 dlp->clip = (ypos - yend);
5047 visible_height -= dlp->clip;
5049 if (visible_height < VERTICAL_CLIP (w, 1))
5052 free_display_line (dlp);
5059 Dynarr_add (dla, *dlp);
5061 /* #### This type of check needs to be done down in the
5062 generate_display_line call. */
5063 if (start_pos >= s_zv)
5072 /***************************************************************************/
5074 /* window-regeneration routines */
5076 /***************************************************************************/
5078 /* For a given window and starting position in the buffer it contains,
5079 ensure that the TYPE display lines accurately represent the
5080 presentation of the window. We pass the buffer instead of getting
5081 it from the window since redisplay_window may have temporarily
5082 changed it to the echo area buffer. */
5085 regenerate_window (struct window *w, Bufpos start_pos, Bufpos point, int type)
5087 struct frame *f = XFRAME (w->frame);
5088 struct buffer *b = XBUFFER (w->buffer);
5089 int ypos = WINDOW_TEXT_TOP (w);
5090 int yend; /* set farther down */
5091 int yclip = WINDOW_TEXT_TOP_CLIP (w);
5094 prop_block_dynarr *prop;
5095 layout_bounds bounds;
5096 display_line_dynarr *dla;
5099 /* The lines had better exist by this point. */
5100 if (!(dla = window_display_lines (w, type)))
5103 w->max_line_len = 0;
5105 /* Normally these get updated in redisplay_window but it is possible
5106 for this function to get called from some other points where that
5107 update may not have occurred. This acts as a safety check. */
5108 if (!Dynarr_length (w->face_cachels))
5109 reset_face_cachels (w);
5110 if (!Dynarr_length (w->glyph_cachels))
5111 reset_glyph_cachels (w);
5113 Fset_marker (w->start[type], make_int (start_pos), w->buffer);
5114 Fset_marker (w->pointm[type], make_int (point), w->buffer);
5115 w->last_point_x[type] = -1;
5116 w->last_point_y[type] = -1;
5118 /* Make sure a modeline is in the structs if needed. */
5119 need_modeline = ensure_modeline_generated (w, type);
5121 /* Wait until here to set this so that the structs have a modeline
5122 generated in the case where one didn't exist. */
5123 yend = WINDOW_TEXT_BOTTOM (w);
5125 bounds = calculate_display_line_boundaries (w, 0);
5127 /* 97/3/14 jhod: stuff added here to support pre-prompts (used for input systems) */
5128 if (MINI_WINDOW_P (w)
5129 && (!NILP (Vminibuf_prompt) || !NILP (Vminibuf_preprompt))
5130 && !echo_area_active (f)
5131 && start_pos == BUF_BEGV (b))
5133 struct prop_block pb;
5135 prop = Dynarr_new (prop_block);
5137 string = concat2(Vminibuf_preprompt, Vminibuf_prompt);
5138 pb.type = PROP_MINIBUF_PROMPT;
5139 pb.data.p_string.str = XSTRING_DATA(string);
5140 pb.data.p_string.len = XSTRING_LENGTH(string);
5141 Dynarr_add (prop, pb);
5146 /* When we are computing things for scrolling purposes, make
5147 sure at least one line is always generated */
5148 force = (type == CMOTION_DISP);
5150 /* Make sure this is set always */
5151 /* Note the conversion at end */
5152 w->window_end_pos[type] = start_pos;
5153 while (ypos < yend || force)
5155 struct display_line dl;
5156 struct display_line *dlp;
5159 if (Dynarr_length (dla) < Dynarr_largest (dla))
5161 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5172 dlp->bounds = bounds;
5174 start_pos = generate_display_line (w, dlp, 1, start_pos, &prop, type);
5176 if (yclip > dlp->ascent)
5178 /* this should never happen, but if it does just display the
5183 dlp->ypos = (ypos + dlp->ascent) - yclip;
5184 ypos = dlp->ypos + dlp->descent;
5186 /* See if we've been asked to start midway through a line, for
5187 partial display line scrolling. */
5190 dlp->top_clip = yclip;
5198 int visible_height = dlp->ascent + dlp->descent;
5200 dlp->clip = (ypos - yend);
5201 /* Although this seems strange we could have a single very
5202 tall line visible for which we need to account for both
5203 the top clip and the bottom clip. */
5204 visible_height -= (dlp->clip + dlp->top_clip);
5206 if (visible_height < VERTICAL_CLIP (w, 1) && !force)
5209 free_display_line (dlp);
5216 if (dlp->cursor_elt != -1)
5218 /* #### This check is steaming crap. Have to get things
5219 fixed so when create_text_block hits EOB, we're done,
5221 if (w->last_point_x[type] == -1)
5223 w->last_point_x[type] = dlp->cursor_elt;
5224 w->last_point_y[type] = Dynarr_length (dla);
5228 /* #### This means that we've added a cursor at EOB
5229 twice. Yuck oh yuck. */
5230 struct display_block *db =
5231 get_display_block_from_line (dlp, TEXT);
5233 Dynarr_atp (db->runes, dlp->cursor_elt)->cursor_type = NO_CURSOR;
5234 dlp->cursor_elt = -1;
5238 if (dlp->num_chars > w->max_line_len)
5239 w->max_line_len = dlp->num_chars;
5241 Dynarr_add (dla, *dlp);
5243 /* #### This isn't right, but it is close enough for now. */
5244 w->window_end_pos[type] = start_pos;
5246 /* #### This type of check needs to be done down in the
5247 generate_display_line call. */
5248 if (start_pos > BUF_ZV (b))
5257 /* #### More not quite right, but close enough. */
5258 /* Ben sez: apparently window_end_pos[] is measured
5259 as the number of characters between the window end and the
5260 end of the buffer? This seems rather weirdo. What's
5261 the justification for this?
5263 JV sez: Because BUF_Z (b) would be a good initial value, however
5264 that can change. This representation allows initalizing with 0.
5266 w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type];
5270 /* We know that this is the right thing to use because we put it
5271 there when we first started working in this function. */
5272 generate_modeline (w, Dynarr_atp (dla, 0), type);
5276 #define REGEN_INC_FIND_START_END \
5278 /* Determine start and end of lines. */ \
5279 if (!Dynarr_length (cdla)) \
5283 if (Dynarr_atp (cdla, 0)->modeline && Dynarr_atp (ddla, 0)->modeline) \
5287 else if (!Dynarr_atp (cdla, 0)->modeline \
5288 && !Dynarr_atp (ddla, 0)->modeline) \
5293 abort (); /* structs differ */ \
5295 dla_end = Dynarr_length (cdla) - 1; \
5298 start_pos = (Dynarr_atp (cdla, dla_start)->bufpos \
5299 + Dynarr_atp (cdla, dla_start)->offset); \
5300 /* If this isn't true, then startp has changed and we need to do a \
5302 if (startp != start_pos) \
5305 /* Point is outside the visible region so give up. */ \
5306 if (pointm < start_pos) \
5311 /* This attempts to incrementally update the display structures. It
5312 returns a boolean indicating success or failure. This function is
5313 very similar to regenerate_window_incrementally and is in fact only
5314 called from that function. However, because of the nature of the
5315 changes it deals with it sometimes makes different assumptions
5316 which can lead to success which are much more difficult to make
5317 when dealing with buffer changes. */
5320 regenerate_window_extents_only_changed (struct window *w, Bufpos startp,
5322 Charcount beg_unchanged,
5323 Charcount end_unchanged)
5325 struct buffer *b = XBUFFER (w->buffer);
5326 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5327 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5331 int first_line, last_line;
5333 /* Don't define this in the loop where it is used because we
5334 definitely want its value to survive between passes. */
5335 prop_block_dynarr *prop = NULL;
5337 /* If we don't have any buffer change recorded but the modiff flag has
5338 been incremented, then fail. I'm not sure of the exact circumstances
5339 under which this can happen, but I believe that it is probably a
5340 reasonable happening. */
5341 if (!point_visible (w, pointm, CURRENT_DISP)
5342 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b))
5345 /* If the cursor is moved we attempt to update it. If we succeed we
5346 go ahead and proceed with the optimization attempt. */
5347 if (!EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5348 || pointm != marker_position (w->last_point[CURRENT_DISP]))
5350 struct frame *f = XFRAME (w->frame);
5351 struct device *d = XDEVICE (f->device);
5352 struct frame *sel_f = device_selected_frame (d);
5355 if (w->last_point_x[CURRENT_DISP] != -1
5356 && w->last_point_y[CURRENT_DISP] != -1)
5359 if (redisplay_move_cursor (w, pointm, WINDOW_TTY_P (w)))
5361 /* Always regenerate the modeline in case it is
5362 displaying the current line or column. */
5363 regenerate_modeline (w);
5367 else if (w != XWINDOW (FRAME_SELECTED_WINDOW (sel_f)))
5369 if (f->modeline_changed)
5370 regenerate_modeline (w);
5378 if (beg_unchanged == -1 && end_unchanged == -1)
5381 /* assert: There are no buffer modifications or they are all below the
5382 visible region. We assume that regenerate_window_incrementally has
5383 not called us unless this is true. */
5385 REGEN_INC_FIND_START_END;
5387 /* If the changed are starts before the visible area, give up. */
5388 if (beg_unchanged < startp)
5391 /* Find what display line the extent changes first affect. */
5393 while (line <= dla_end)
5395 struct display_line *dl = Dynarr_atp (cdla, line);
5396 Bufpos lstart = dl->bufpos + dl->offset;
5397 Bufpos lend = dl->end_bufpos + dl->offset;
5399 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5405 /* If the changes are below the visible area then if point hasn't
5406 moved return success otherwise fail in order to be safe. */
5409 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5410 && pointm == marker_position (w->last_point[CURRENT_DISP]))
5416 /* At this point we know what line the changes first affect. We now
5417 begin redrawing lines as long as we are still in the affected
5418 region and the line's size and positioning don't change.
5419 Otherwise we fail. If we fail we will have altered the desired
5420 structs which could lead to an assertion failure. However, if we
5421 fail the next thing that is going to happen is a full regen so we
5422 will actually end up being safe. */
5423 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5424 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5425 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
5426 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
5428 first_line = last_line = line;
5429 while (line <= dla_end)
5431 Bufpos old_start, old_end, new_start;
5432 struct display_line *cdl = Dynarr_atp (cdla, line);
5433 struct display_line *ddl = Dynarr_atp (ddla, line);
5434 struct display_block *db;
5437 assert (cdl->bufpos == ddl->bufpos);
5438 assert (cdl->end_bufpos == ddl->end_bufpos);
5439 assert (cdl->offset == ddl->offset);
5441 db = get_display_block_from_line (ddl, TEXT);
5442 initial_size = Dynarr_length (db->runes);
5443 old_start = ddl->bufpos + ddl->offset;
5444 old_end = ddl->end_bufpos + ddl->offset;
5446 /* If this is the first line being updated and it used
5447 propagation data, fail. Otherwise we'll be okay because
5448 we'll have the necessary propagation data. */
5449 if (line == first_line && ddl->used_prop_data)
5452 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5453 &prop, DESIRED_DISP);
5456 /* #### If there is propagated stuff the fail. We could
5457 probably actually deal with this if the line had propagated
5458 information when originally created by a full
5466 /* If any line position parameters have changed or a
5467 cursor has disappeared or disappeared, fail. */
5468 db = get_display_block_from_line (ddl, TEXT);
5469 if (cdl->ypos != ddl->ypos
5470 || cdl->ascent != ddl->ascent
5471 || cdl->descent != ddl->descent
5472 || cdl->top_clip != ddl->top_clip
5473 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5474 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1)
5475 || old_start != ddl->bufpos
5476 || old_end != ddl->end_bufpos
5477 || initial_size != Dynarr_length (db->runes))
5482 if (ddl->cursor_elt != -1)
5484 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5485 w->last_point_y[DESIRED_DISP] = line;
5490 /* If the extent changes end on the line we just updated then
5491 we're done. Otherwise go on to the next line. */
5492 if (end_unchanged <= ddl->end_bufpos)
5498 redisplay_update_line (w, first_line, last_line, 1);
5502 /* Attempt to update the display data structures based on knowledge of
5503 the changed region in the buffer. Returns a boolean indicating
5504 success or failure. If this function returns a failure then a
5505 regenerate_window _must_ be performed next in order to maintain
5506 invariants located here. */
5509 regenerate_window_incrementally (struct window *w, Bufpos startp,
5512 struct buffer *b = XBUFFER (w->buffer);
5513 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5514 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5515 Charcount beg_unchanged, end_unchanged;
5516 Charcount extent_beg_unchanged, extent_end_unchanged;
5522 /* If this function is called, the current and desired structures
5523 had better be identical. If they are not, then that is a bug. */
5524 assert (Dynarr_length (cdla) == Dynarr_length (ddla));
5526 /* We don't handle minibuffer windows yet. The minibuffer prompt
5528 if (MINI_WINDOW_P (w))
5531 extent_beg_unchanged = BUF_EXTENT_BEGIN_UNCHANGED (b);
5532 extent_end_unchanged = (BUF_EXTENT_END_UNCHANGED (b) == -1
5534 : BUF_Z (b) - BUF_EXTENT_END_UNCHANGED (b));
5536 /* If nothing has changed in the buffer, then make sure point is ok
5538 if (BUF_BEGIN_UNCHANGED (b) == -1 && BUF_END_UNCHANGED (b) == -1)
5539 return regenerate_window_extents_only_changed (w, startp, pointm,
5540 extent_beg_unchanged,
5541 extent_end_unchanged);
5543 /* We can't deal with deleted newlines. */
5544 if (BUF_NEWLINE_WAS_DELETED (b))
5547 beg_unchanged = BUF_BEGIN_UNCHANGED (b);
5548 end_unchanged = (BUF_END_UNCHANGED (b) == -1
5550 : BUF_Z (b) - BUF_END_UNCHANGED (b));
5552 REGEN_INC_FIND_START_END;
5554 /* If the changed area starts before the visible area, give up. */
5555 if (beg_unchanged < startp)
5558 /* Find what display line the buffer changes first affect. */
5560 while (line <= dla_end)
5562 struct display_line *dl = Dynarr_atp (cdla, line);
5563 Bufpos lstart = dl->bufpos + dl->offset;
5564 Bufpos lend = dl->end_bufpos + dl->offset;
5566 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5572 /* If the changes are below the visible area then if point hasn't
5573 moved return success otherwise fail in order to be safe. */
5575 return regenerate_window_extents_only_changed (w, startp, pointm,
5576 extent_beg_unchanged,
5577 extent_end_unchanged);
5579 /* At this point we know what line the changes first affect. We
5580 now redraw that line. If the changes are contained within it
5581 we are going to succeed and can update just that one line.
5582 Otherwise we fail. If we fail we will have altered the desired
5583 structs which could lead to an assertion failure. However, if
5584 we fail the next thing that is going to happen is a full regen
5585 so we will actually end up being safe. */
5588 prop_block_dynarr *prop = NULL;
5589 struct display_line *cdl = Dynarr_atp (cdla, line);
5590 struct display_line *ddl = Dynarr_atp (ddla, line);
5592 assert (cdl->bufpos == ddl->bufpos);
5593 assert (cdl->end_bufpos == ddl->end_bufpos);
5594 assert (cdl->offset == ddl->offset);
5596 /* If the line continues to next display line, fail. */
5597 if (ddl->line_continuation)
5600 /* If the line was generated using propagation data, fail. */
5601 if (ddl->used_prop_data)
5604 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5605 &prop, DESIRED_DISP);
5608 /* If there is propagated stuff then it is pretty much a
5609 guarantee that more than just the one line is affected. */
5616 /* If the line continues to next display line, fail. */
5617 if (ddl->line_continuation)
5620 /* If any line position parameters have changed or a
5621 cursor has disappeared or disappeared, fail. */
5622 if (cdl->ypos != ddl->ypos
5623 || cdl->ascent != ddl->ascent
5624 || cdl->descent != ddl->descent
5625 || cdl->top_clip != ddl->top_clip
5626 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5627 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1))
5632 /* If the changed area also ends on this line, then we may be in
5633 business. Update everything and return success. */
5634 if (end_unchanged >= ddl->bufpos && end_unchanged <= ddl->end_bufpos)
5636 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5637 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5638 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp),
5640 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm),
5643 if (ddl->cursor_elt != -1)
5645 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5646 w->last_point_y[DESIRED_DISP] = line;
5649 redisplay_update_line (w, line, line, 1);
5650 regenerate_modeline (w);
5652 /* #### For now we just flush the cache until this has been
5653 tested. After that is done, this should correct the
5655 Dynarr_reset (w->line_start_cache);
5657 /* Adjust the extent changed boundaries to remove any
5658 overlap with the buffer changes since we've just
5659 successfully updated that area. */
5660 if (extent_beg_unchanged != -1
5661 && extent_beg_unchanged >= beg_unchanged
5662 && extent_beg_unchanged < end_unchanged)
5663 extent_beg_unchanged = end_unchanged;
5665 if (extent_end_unchanged != -1
5666 && extent_end_unchanged >= beg_unchanged
5667 && extent_end_unchanged < end_unchanged)
5668 extent_end_unchanged = beg_unchanged - 1;
5670 if (extent_end_unchanged <= extent_beg_unchanged)
5671 extent_beg_unchanged = extent_end_unchanged = -1;
5673 /* This could lead to odd results if it fails, but since the
5674 buffer changes update succeeded this probably will to.
5675 We already know that the extent changes start at or after
5676 the line because we checked before entering the loop. */
5677 if (extent_beg_unchanged != -1
5678 && extent_end_unchanged != -1
5679 && ((extent_beg_unchanged < ddl->bufpos)
5680 || (extent_end_unchanged > ddl->end_bufpos)))
5681 return regenerate_window_extents_only_changed (w, startp, pointm,
5682 extent_beg_unchanged,
5683 extent_end_unchanged);
5693 /* Given a window and a point, update the given display lines such
5694 that point is displayed in the middle of the window.
5695 Return the window's new start position. */
5698 regenerate_window_point_center (struct window *w, Bufpos point, int type)
5702 /* We need to make sure that the modeline is generated so that the
5703 window height can be calculated correctly. */
5704 ensure_modeline_generated (w, type);
5706 startp = start_with_line_at_pixpos (w, point, window_half_pixpos (w));
5707 regenerate_window (w, startp, point, type);
5708 Fset_marker (w->start[type], make_int (startp), w->buffer);
5713 /* Given a window and a set of display lines, return a boolean
5714 indicating whether the given point is contained within. */
5717 point_visible (struct window *w, Bufpos point, int type)
5719 struct buffer *b = XBUFFER (w->buffer);
5720 display_line_dynarr *dla = window_display_lines (w, type);
5723 if (Dynarr_length (dla) && Dynarr_atp (dla, 0)->modeline)
5728 if (Dynarr_length (dla) > first_line)
5731 struct display_line *dl = Dynarr_atp (dla, first_line);
5734 end = BUF_Z (b) - w->window_end_pos[type] - 1;
5736 if (point >= start && point <= end)
5738 if (!MINI_WINDOW_P (w) && scroll_on_clipped_lines)
5740 dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
5742 if (point >= (dl->bufpos + dl->offset)
5743 && point <= (dl->end_bufpos + dl->offset))
5758 /* Return pixel position the middle of the window, not including the
5759 modeline and any potential horizontal scrollbar. */
5762 window_half_pixpos (struct window *w)
5764 return WINDOW_TEXT_TOP (w) + (WINDOW_TEXT_HEIGHT (w) >> 1);
5767 /* Return the display line which is currently in the middle of the
5768 window W for display lines TYPE. */
5771 line_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5773 display_line_dynarr *dla;
5776 int first_elt = (MINI_WINDOW_P (w) ? 0 : 1);
5778 if (type == CMOTION_DISP)
5779 regenerate_window (w, start, point, type);
5781 dla = window_display_lines (w, type);
5782 half = window_half_pixpos (w);
5784 for (elt = first_elt; elt < Dynarr_length (dla); elt++)
5786 struct display_line *dl = Dynarr_atp (dla, elt);
5787 int line_bot = dl->ypos + dl->descent;
5789 if (line_bot > half)
5793 /* We may not have a line at the middle if the end of the buffer is
5798 /* Return a value for point that would place it at the beginning of
5799 the line which is in the middle of the window. */
5802 point_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5804 /* line_at_center will regenerate the display structures, if necessary. */
5805 int line = line_at_center (w, type, start, point);
5808 return BUF_ZV (XBUFFER (w->buffer));
5811 display_line_dynarr *dla = window_display_lines (w, type);
5812 struct display_line *dl = Dynarr_atp (dla, line);
5818 /* For a given window, ensure that the current visual representation
5822 redisplay_window (Lisp_Object window, int skip_selected)
5824 struct window *w = XWINDOW (window);
5825 struct frame *f = XFRAME (w->frame);
5826 struct device *d = XDEVICE (f->device);
5827 Lisp_Object old_buffer = w->buffer;
5828 Lisp_Object the_buffer = w->buffer;
5830 int echo_active = 0;
5835 int selected_in_its_frame;
5836 int selected_globally;
5837 int skip_output = 0;
5838 int truncation_changed;
5839 int inactive_minibuffer =
5840 (MINI_WINDOW_P (w) &&
5841 (f != device_selected_frame (d)) &&
5842 !is_surrogate_for_selected_frame (f));
5844 /* #### In the new world this function actually does a bunch of
5845 optimizations such as buffer-based scrolling, but none of that is
5848 /* If this is a combination window, do its children; that's all.
5849 The selected window is always a leaf so we don't check for
5850 skip_selected here. */
5851 if (!NILP (w->vchild))
5853 redisplay_windows (w->vchild, skip_selected);
5856 if (!NILP (w->hchild))
5858 redisplay_windows (w->hchild, skip_selected);
5862 /* Is this window the selected window on its frame? */
5863 selected_in_its_frame = (w == XWINDOW (FRAME_SELECTED_WINDOW (f)));
5865 selected_in_its_frame &&
5866 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
5867 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d &&
5868 XFRAME(DEVICE_SELECTED_FRAME(d)) == f;
5869 if (skip_selected && selected_in_its_frame)
5872 /* It is possible that the window is not fully initialized yet. */
5873 if (NILP (w->buffer))
5876 if (MINI_WINDOW_P (w) && echo_area_active (f))
5878 w->buffer = the_buffer = Vecho_area_buffer;
5882 b = XBUFFER (w->buffer);
5886 old_pointm = selected_globally
5888 : marker_position (w->pointm[CURRENT_DISP]);
5893 if (selected_globally)
5895 pointm = BUF_PT (b);
5899 pointm = marker_position (w->pointm[CURRENT_DISP]);
5901 if (pointm < BUF_BEGV (b))
5902 pointm = BUF_BEGV (b);
5903 else if (pointm > BUF_ZV (b))
5904 pointm = BUF_ZV (b);
5907 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm), the_buffer);
5909 /* If the buffer has changed we have to invalidate all of our face
5911 if ((!echo_active && b != window_display_buffer (w))
5912 || !Dynarr_length (w->face_cachels)
5913 || f->faces_changed)
5914 reset_face_cachels (w);
5916 mark_face_cachels_as_not_updated (w);
5918 /* Ditto the glyph cache elements, although we do *not* invalidate
5919 the cache purely because glyphs have changed - this is now
5920 handled by the dirty flag.*/
5921 if ((!echo_active && b != window_display_buffer (w))
5922 || !Dynarr_length (w->glyph_cachels) || f->faces_changed)
5923 reset_glyph_cachels (w);
5925 mark_glyph_cachels_as_not_updated (w);
5927 /* If the marker's buffer is not the window's buffer, then we need
5928 to find a new starting position. */
5929 if (!MINI_WINDOW_P (w)
5930 && !EQ (Fmarker_buffer (w->start[CURRENT_DISP]), w->buffer))
5932 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
5934 goto regeneration_done;
5939 old_startp = marker_position (w->start[CURRENT_DISP]);
5944 startp = marker_position (w->start[CURRENT_DISP]);
5945 if (startp < BUF_BEGV (b))
5946 startp = BUF_BEGV (b);
5947 else if (startp > BUF_ZV (b))
5948 startp = BUF_ZV (b);
5950 Fset_marker (w->start[DESIRED_DISP], make_int (startp), the_buffer);
5952 truncation_changed = (find_window_mirror (w)->truncate_win !=
5953 window_truncation_on (w));
5955 /* If w->force_start is set, then some function set w->start and we
5956 should display from there and change point, if necessary, to
5957 ensure that it is visible. */
5958 if (w->force_start || inactive_minibuffer)
5961 w->last_modified[DESIRED_DISP] = Qzero;
5962 w->last_facechange[DESIRED_DISP] = Qzero;
5964 regenerate_window (w, startp, pointm, DESIRED_DISP);
5966 if (!point_visible (w, pointm, DESIRED_DISP) && !inactive_minibuffer)
5968 pointm = point_at_center (w, DESIRED_DISP, 0, 0);
5970 if (selected_globally)
5971 BUF_SET_PT (b, pointm);
5973 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm),
5976 /* #### BUFU amounts of overkill just to get the cursor
5977 location marked properly. FIX ME FIX ME FIX ME */
5978 regenerate_window (w, startp, pointm, DESIRED_DISP);
5981 goto regeneration_done;
5984 /* If nothing has changed since the last redisplay, then we just
5985 need to make sure that point is still visible. */
5986 if (XINT (w->last_modified[CURRENT_DISP]) >= BUF_MODIFF (b)
5987 && XINT (w->last_facechange[CURRENT_DISP]) >= BUF_FACECHANGE (b)
5989 /* This check is to make sure we restore the minibuffer after a
5990 temporary change to the echo area. */
5991 && !(MINI_WINDOW_P (w) && f->buffers_changed)
5992 && !f->frame_changed
5993 && !truncation_changed
5994 /* check whether start is really at the begining of a line GE */
5995 && (!w->start_at_line_beg || beginning_of_line_p (b, startp))
5998 /* Check if the cursor has actually moved. */
5999 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
6000 && pointm == marker_position (w->last_point[CURRENT_DISP])
6001 && selected_globally
6002 && !w->windows_changed
6004 && !f->extents_changed
6005 && !f->faces_changed
6006 && !f->glyphs_changed
6007 && !f->subwindows_changed
6008 /* && !f->subwindows_state_changed*/
6009 && !f->point_changed
6010 && !f->windows_structure_changed)
6012 /* If not, we're done. */
6013 if (f->modeline_changed)
6014 regenerate_modeline (w);
6017 goto regeneration_done;
6021 /* If the new point is visible in the redisplay structures,
6022 then let the output update routines handle it, otherwise
6023 do things the hard way. */
6024 if (!w->windows_changed
6026 && !f->extents_changed
6027 && !f->faces_changed
6028 && !f->glyphs_changed
6029 && !f->subwindows_changed
6030 /* && !f->subwindows_state_changed*/
6031 && !f->windows_structure_changed)
6033 if (point_visible (w, pointm, CURRENT_DISP)
6034 && w->last_point_x[CURRENT_DISP] != -1
6035 && w->last_point_y[CURRENT_DISP] != -1)
6037 if (redisplay_move_cursor (w, pointm, FRAME_TTY_P (f)))
6039 /* Always regenerate in case it is displaying
6040 the current line or column. */
6041 regenerate_modeline (w);
6044 goto regeneration_done;
6047 else if (!selected_in_its_frame && !f->point_changed)
6049 if (f->modeline_changed)
6050 regenerate_modeline (w);
6053 goto regeneration_done;
6057 /* If we weren't able to take the shortcut method, then use
6058 the brute force method. */
6059 regenerate_window (w, startp, pointm, DESIRED_DISP);
6061 if (point_visible (w, pointm, DESIRED_DISP))
6062 goto regeneration_done;
6066 /* Check if the starting point is no longer at the beginning of a
6067 line, in which case find a new starting point. We also recenter
6068 if our start position is equal to point-max. Otherwise we'll end
6069 up with a blank window. */
6070 else if (((w->start_at_line_beg || MINI_WINDOW_P (w))
6071 && !(startp == BUF_BEGV (b)
6072 || BUF_FETCH_CHAR (b, startp - 1) == '\n'))
6073 || (pointm == startp &&
6074 EQ (Fmarker_buffer (w->last_start[CURRENT_DISP]), w->buffer) &&
6075 startp < marker_position (w->last_start[CURRENT_DISP]))
6076 || (startp == BUF_ZV (b)))
6078 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6080 goto regeneration_done;
6082 /* See if we can update the data structures locally based on
6083 knowledge of what changed in the buffer. */
6084 else if (!w->windows_changed
6086 && !f->faces_changed
6087 && !f->glyphs_changed
6088 && !f->subwindows_changed
6089 /* && !f->subwindows_state_changed*/
6090 && !f->windows_structure_changed
6091 && !f->frame_changed
6092 && !truncation_changed
6094 && regenerate_window_incrementally (w, startp, pointm))
6096 if (f->modeline_changed
6097 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b)
6098 || XINT (w->last_facechange[CURRENT_DISP]) < BUF_FACECHANGE (b))
6099 regenerate_modeline (w);
6102 goto regeneration_done;
6104 /* #### This is where a check for structure based scrolling would go. */
6105 /* If all else fails, try just regenerating and see what happens. */
6108 regenerate_window (w, startp, pointm, DESIRED_DISP);
6110 if (point_visible (w, pointm, DESIRED_DISP))
6111 goto regeneration_done;
6114 /* We still haven't gotten the window regenerated with point
6115 visible. Next we try scrolling a little and see if point comes
6116 back onto the screen. */
6117 if (scroll_step > 0)
6119 int scrolled = scroll_conservatively;
6120 for (; scrolled >= 0; scrolled -= scroll_step)
6122 startp = vmotion (w, startp,
6123 (pointm < startp) ? -scroll_step : scroll_step, 0);
6124 regenerate_window (w, startp, pointm, DESIRED_DISP);
6126 if (point_visible (w, pointm, DESIRED_DISP))
6127 goto regeneration_done;
6131 /* We still haven't managed to get the screen drawn with point on
6132 the screen, so just center it and be done with it. */
6133 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6138 /* If the window's frame is changed then reset the current display
6139 lines in order to force a full repaint. */
6140 if (f->frame_changed)
6142 display_line_dynarr *cla = window_display_lines (w, CURRENT_DISP);
6147 /* Must do this before calling redisplay_output_window because it
6148 sets some markers on the window. */
6151 w->buffer = old_buffer;
6152 Fset_marker (w->pointm[DESIRED_DISP], make_int (old_pointm), old_buffer);
6153 Fset_marker (w->start[DESIRED_DISP], make_int (old_startp), old_buffer);
6156 /* These also have to be set before calling redisplay_output_window
6157 since it sets the CURRENT_DISP values based on them. */
6158 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
6159 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
6160 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
6161 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
6165 Bufpos start = marker_position (w->start[DESIRED_DISP]);
6166 Bufpos end = (w->window_end_pos[DESIRED_DISP] == -1
6168 : BUF_Z (b) - w->window_end_pos[DESIRED_DISP] - 1);
6169 /* Don't pollute the cache if not sure if we are correct */
6170 if (w->start_at_line_beg)
6171 update_line_start_cache (w, start, end, pointm, 1);
6172 redisplay_output_window (w);
6174 * If we just displayed the echo area, the line start cache is
6175 * no longer valid, because the minibuffer window is associated
6176 * with the window now.
6179 w->line_cache_last_updated = make_int (-1);
6182 /* #### This should be dependent on face changes and will need to be
6183 somewhere else once tty updates occur on a per-frame basis. */
6184 mark_face_cachels_as_clean (w);
6186 /* The glyph cachels only get dirty if someone changed something.
6187 Since redisplay has now effectively ended we can reset the dirty
6188 flag since everything must be up-to-date. */
6190 mark_glyph_cachels_as_clean (w);
6192 w->windows_changed = 0;
6195 /* Call buffer_reset_changes for all buffers present in any window
6196 currently visible in all frames on all devices. #### There has to
6197 be a better way to do this. */
6200 reset_buffer_changes_mapfun (struct window *w, void *ignored_closure)
6202 buffer_reset_changes (XBUFFER (w->buffer));
6207 reset_buffer_changes (void)
6209 Lisp_Object frmcons, devcons, concons;
6211 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
6213 struct frame *f = XFRAME (XCAR (frmcons));
6215 if (FRAME_REPAINT_P (f))
6216 map_windows (f, reset_buffer_changes_mapfun, 0);
6220 /* Ensure that all windows underneath the given window in the window
6221 hierarchy are correctly displayed. */
6224 redisplay_windows (Lisp_Object window, int skip_selected)
6226 for (; !NILP (window) ; window = XWINDOW (window)->next)
6228 redisplay_window (window, skip_selected);
6233 call_redisplay_end_triggers (struct window *w, void *closure)
6235 Bufpos lrpos = w->last_redisplay_pos;
6236 w->last_redisplay_pos = 0;
6237 if (!NILP (w->buffer)
6238 && !NILP (w->redisplay_end_trigger)
6243 if (MARKERP (w->redisplay_end_trigger)
6244 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
6245 pos = marker_position (w->redisplay_end_trigger);
6246 else if (INTP (w->redisplay_end_trigger))
6247 pos = XINT (w->redisplay_end_trigger);
6250 w->redisplay_end_trigger = Qnil;
6257 XSETWINDOW (window, w);
6258 va_run_hook_with_args_in_buffer (XBUFFER (w->buffer),
6259 Qredisplay_end_trigger_functions,
6261 w->redisplay_end_trigger);
6262 w->redisplay_end_trigger = Qnil;
6269 /* Ensure that all windows on the given frame are correctly displayed. */
6272 redisplay_frame (struct frame *f, int preemption_check)
6274 struct device *d = XDEVICE (f->device);
6276 if (preemption_check)
6278 /* The preemption check itself takes a lot of time,
6279 so normally don't do it here. We do it if called
6280 from Lisp, though (`redisplay-frame'). */
6283 REDISPLAY_PREEMPTION_CHECK;
6288 if (!internal_equal (f->old_buffer_alist, f->buffer_alist, 0))
6292 f->old_buffer_alist = Freplace_list (f->old_buffer_alist,
6294 XSETFRAME (frame, f);
6295 va_run_hook_with_args (Qbuffer_list_changed_hook, 1, frame);
6298 /* Before we put a hold on frame size changes, attempt to process
6299 any which are already pending. */
6300 if (f->size_change_pending)
6301 change_frame_size (f, f->new_height, f->new_width, 0);
6303 /* If frame size might need to be changed, due to changed size
6304 of toolbars, scrollbars etc, change it now */
6305 if (f->size_slipped)
6307 adjust_frame_size (f);
6308 assert (!f->size_slipped);
6311 /* The menubar, toolbar, and icon updates must be done before
6312 hold_frame_size_changes is called and we are officially
6313 'in_display'. They may eval lisp code which may call Fsignal.
6314 If in_display is set Fsignal will abort. */
6316 #ifdef HAVE_MENUBARS
6317 /* Update the menubar. It is done first since it could change
6318 the menubar's visibility. This way we avoid having flashing
6319 caused by an Expose event generated by the visibility change
6321 update_frame_menubars (f);
6322 #endif /* HAVE_MENUBARS */
6323 #ifdef HAVE_TOOLBARS
6324 /* Update the toolbars. */
6325 update_frame_toolbars (f);
6326 #endif /* HAVE_TOOLBARS */
6327 /* Gutter update proper has to be done inside display when no frame
6328 size changes can occur, thus we separately update the gutter
6329 geometry here if it needs it. */
6330 update_frame_gutter_geometry (f);
6332 /* If we clear the frame we have to force its contents to be redrawn. */
6334 f->frame_changed = 1;
6336 /* Invalidate the subwindow cache. We use subwindows_changed here to
6337 cause subwindows to get instantiated. This is because
6338 subwindows_state_changed is less strict - dealing with things
6339 like the clicked state of button. We have to do this before
6340 redisplaying the gutters as subwindows get unmapped in the
6342 if (f->frame_changed || f->subwindows_changed)
6344 /* we have to do this so the gutter gets regenerated. */
6345 reset_gutter_display_lines (f);
6348 hold_frame_size_changes ();
6350 /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */
6351 /* Within this section, we are defenseless and assume that the
6352 following cannot happen:
6354 1) garbage collection
6355 2) Lisp code evaluation
6356 3) frame size changes
6358 We ensure (3) by calling hold_frame_size_changes(), which
6359 will cause any pending frame size changes to get put on hold
6360 till after the end of the critical section. (1) follows
6361 automatically if (2) is met. #### Unfortunately, there are
6362 some places where Lisp code can be called within this section.
6363 We need to remove them.
6365 If Fsignal() is called during this critical section, we
6368 If garbage collection is called during this critical section,
6369 we simply return. #### We should abort instead.
6371 #### If a frame-size change does occur we should probably
6372 actually be preempting redisplay. */
6374 MAYBE_DEVMETH (d, frame_output_begin, (f));
6376 /* We can now update the gutters, safe in the knowledge that our
6377 efforts won't get undone. */
6379 /* This can call lisp, but redisplay is protected by binding
6380 inhibit_quit. More importantly the code involving display lines
6381 *assumes* that GC will not happen and so does not GCPRO
6382 anything. Since we use this code the whole time with the gutters
6383 we cannot allow GC to happen when manipulating the gutters. */
6384 update_frame_gutters (f);
6386 /* Erase the frame before outputting its contents. */
6389 MAYBE_DEVMETH (d, clear_frame, (f));
6392 /* Do the selected window first. */
6393 redisplay_window (FRAME_SELECTED_WINDOW (f), 0);
6395 /* Then do the rest. */
6396 redisplay_windows (f->root_window, 1);
6398 MAYBE_DEVMETH (d, frame_output_end, (f));
6400 update_frame_title (f);
6402 CLASS_RESET_CHANGED_FLAGS (f);
6403 f->window_face_cache_reset = 0;
6404 f->echo_area_garbaged = 0;
6407 if (!f->size_change_pending)
6408 f->size_changed = 0;
6410 /* ----------------- END CRITICAL REDISPLAY SECTION ---------------- */
6412 /* Allow frame size changes to occur again.
6414 #### what happens if changes to other frames happen? */
6415 unhold_one_frame_size_changes (f);
6417 map_windows (f, call_redisplay_end_triggers, 0);
6421 /* Ensure that all frames on the given device are correctly displayed.
6422 If AUTOMATIC is non-zero, and the device implementation indicates
6423 no automatic redisplay, as printers do, then the device is not
6424 redisplayed. AUTOMATIC is set to zero when called from lisp
6425 functions (redraw-device) and (redisplay-device), and to non-zero
6426 when called from "lazy" redisplay();
6430 redisplay_device (struct device *d, int automatic)
6432 Lisp_Object frame, frmcons;
6434 int size_change_failed = 0;
6438 && (MAYBE_INT_DEVMETH (d, device_implementation_flags, ())
6439 & XDEVIMPF_NO_AUTO_REDISPLAY))
6442 if (DEVICE_STREAM_P (d)) /* nothing to do */
6445 /* It is possible that redisplay has been called before the
6446 device is fully initialized. If so then continue with the
6448 if (NILP (DEVICE_SELECTED_FRAME (d)))
6451 REDISPLAY_PREEMPTION_CHECK;
6455 /* Always do the selected frame first. */
6456 frame = DEVICE_SELECTED_FRAME (d);
6460 if (f->icon_changed || f->windows_changed)
6461 update_frame_icon (f);
6463 if (FRAME_REPAINT_P (f))
6465 if (CLASS_REDISPLAY_FLAGS_CHANGEDP(f))
6467 preempted = redisplay_frame (f, 0);
6473 /* If the frame redisplay did not get preempted, then this flag
6474 should have gotten set to 0. It might be possible for that
6475 not to happen if a size change event were to occur at an odd
6476 time. To make sure we don't miss anything we simply don't
6477 reset the top level flags until the condition ends up being
6478 in the right state. */
6479 if (f->size_changed)
6480 size_change_failed = 1;
6483 DEVICE_FRAME_LOOP (frmcons, d)
6485 f = XFRAME (XCAR (frmcons));
6487 if (f == XFRAME (DEVICE_SELECTED_FRAME (d)))
6490 if (f->icon_changed || f->windows_changed)
6491 update_frame_icon (f);
6493 if (FRAME_REPAINT_P (f))
6495 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (f))
6497 preempted = redisplay_frame (f, 0);
6503 if (f->size_change_pending)
6504 size_change_failed = 1;
6508 /* If we get here then we redisplayed all of our frames without
6509 getting preempted so mark ourselves as clean. */
6510 CLASS_RESET_CHANGED_FLAGS (d);
6512 if (!size_change_failed)
6513 d->size_changed = 0;
6519 restore_profiling_redisplay_flag (Lisp_Object val)
6521 profiling_redisplay_flag = XINT (val);
6525 /* Ensure that all windows on all frames on all devices are displaying
6526 the current contents of their respective buffers. */
6529 redisplay_without_hooks (void)
6531 Lisp_Object devcons, concons;
6532 int size_change_failed = 0;
6533 int count = specpdl_depth ();
6535 if (profiling_active)
6537 record_unwind_protect (restore_profiling_redisplay_flag,
6538 make_int (profiling_redisplay_flag));
6539 profiling_redisplay_flag = 1;
6542 if (asynch_device_change_pending)
6543 handle_asynch_device_change ();
6545 if (!GLOBAL_REDISPLAY_FLAGS_CHANGEDP &&
6546 !disable_preemption && preemption_count < max_preempts)
6549 DEVICE_LOOP_NO_BREAK (devcons, concons)
6551 struct device *d = XDEVICE (XCAR (devcons));
6554 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (d))
6556 preempted = redisplay_device (d, 1);
6561 RESET_CHANGED_SET_FLAGS;
6565 /* See comment in redisplay_device. */
6566 if (d->size_changed)
6567 size_change_failed = 1;
6570 preemption_count = 0;
6572 /* Mark redisplay as accurate */
6573 GLOBAL_RESET_CHANGED_FLAGS;
6574 RESET_CHANGED_SET_FLAGS;
6578 mark_all_faces_as_clean ();
6582 if (!size_change_failed)
6585 reset_buffer_changes ();
6588 unbind_to (count, Qnil);
6594 if (last_display_warning_tick != display_warning_tick &&
6595 !inhibit_warning_display)
6597 /* If an error occurs during this function, oh well.
6598 If we report another warning, we could get stuck in an
6599 infinite loop reporting warnings. */
6600 call0_trapping_errors (0, Qdisplay_warning_buffer);
6601 last_display_warning_tick = display_warning_tick;
6603 /* The run_hook_trapping_errors functions are smart enough not
6604 to do any evalling if the hook function is empty, so there
6605 should not be any significant time loss. All places in the
6606 C code that call redisplay() are prepared to handle GCing,
6607 so we should be OK. */
6608 #ifndef INHIBIT_REDISPLAY_HOOKS
6609 run_hook_trapping_errors ("Error in pre-redisplay-hook",
6610 Qpre_redisplay_hook);
6611 #endif /* INHIBIT_REDISPLAY_HOOKS */
6613 redisplay_without_hooks ();
6615 #ifndef INHIBIT_REDISPLAY_HOOKS
6616 run_hook_trapping_errors ("Error in post-redisplay-hook",
6617 Qpost_redisplay_hook);
6618 #endif /* INHIBIT_REDISPLAY_HOOKS */
6622 static char window_line_number_buf[32];
6624 /* Efficiently determine the window line number, and return a pointer
6625 to its printed representation. Do this regardless of whether
6626 line-number-mode is on. The first line in the buffer is counted as
6627 1. If narrowing is in effect, the lines are counted from the
6628 beginning of the visible portion of the buffer. */
6630 window_line_number (struct window *w, int type)
6632 struct device *d = XDEVICE (XFRAME (w->frame)->device);
6633 struct buffer *b = XBUFFER (w->buffer);
6634 /* Be careful in the order of these tests. The first clause will
6635 fail if DEVICE_SELECTED_FRAME == Qnil (since w->frame cannot be).
6636 This can occur when the frame title is computed really early */
6638 ((EQ(DEVICE_SELECTED_FRAME(d), w->frame) &&
6639 (w == XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame(d)))) &&
6640 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
6641 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d )
6643 : marker_position (w->pointm[type]));
6646 line = buffer_line_number (b, pos, 1);
6648 long_to_string (window_line_number_buf, line + 1);
6650 return window_line_number_buf;
6654 /* Given a character representing an object in a modeline
6655 specification, return a string (stored into the global array
6656 `mode_spec_bufbyte_string') with the information that object
6659 This function is largely unchanged from previous versions of the
6662 Warning! This code is also used for frame titles and can be called
6663 very early in the device/frame update process! JV
6667 decode_mode_spec (struct window *w, Emchar spec, int type)
6669 Lisp_Object obj = Qnil;
6670 const char *str = NULL;
6671 struct buffer *b = XBUFFER (w->buffer);
6673 Dynarr_reset (mode_spec_bufbyte_string);
6677 /* print buffer name */
6682 /* print visited file name */
6687 /* print the current column */
6690 Bufpos pt = (w == XWINDOW (Fselected_window (Qnil)))
6692 : marker_position (w->pointm[type]);
6693 int col = column_at_point (b, pt, 1) + !!column_number_start_at_one;
6696 long_to_string (buf, col);
6698 Dynarr_add_many (mode_spec_bufbyte_string,
6699 (const Bufbyte *) buf, strlen (buf));
6701 goto decode_mode_spec_done;
6703 /* print the file coding system */
6707 Lisp_Object codesys = b->buffer_file_coding_system;
6708 /* Be very careful here not to get an error. */
6709 if (NILP (codesys) || SYMBOLP (codesys) || CODING_SYSTEMP (codesys))
6711 codesys = Ffind_coding_system (codesys);
6712 if (CODING_SYSTEMP (codesys))
6713 obj = XCODING_SYSTEM_MNEMONIC (codesys);
6716 #endif /* FILE_CODING */
6719 /* print the current line number */
6721 str = window_line_number (w, type);
6724 /* print value of mode-name (obsolete) */
6729 /* print hyphen and frame number, if != 1 */
6733 struct frame *f = XFRAME (w->frame);
6734 if (FRAME_TTY_P (f) && f->order_count > 1 && f->order_count <= 99999999)
6736 /* Naughty, naughty */
6737 char * writable_str = alloca_array (char, 10);
6738 sprintf (writable_str, "-%d", f->order_count);
6742 #endif /* HAVE_TTY */
6745 /* print Narrow if appropriate */
6747 if (BUF_BEGV (b) > BUF_BEG (b)
6748 || BUF_ZV (b) < BUF_Z (b))
6752 /* print %, * or hyphen, if buffer is read-only, modified or neither */
6754 str = (!NILP (b->read_only)
6756 : ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6761 /* print * or hyphen -- XEmacs change to allow a buffer to be
6762 read-only but still indicate whether it is modified. */
6764 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6766 : (!NILP (b->read_only)
6771 /* #### defined in 19.29 decode_mode_spec, but not in
6772 modeline-format doc string. */
6773 /* This differs from %* in that it ignores read-only-ness. */
6775 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6780 /* print process status */
6782 obj = Fget_buffer_process (w->buffer);
6784 str = GETTEXT ("no process");
6786 obj = Fsymbol_name (Fprocess_status (obj));
6789 /* Print name of selected frame. */
6791 obj = XFRAME (w->frame)->name;
6794 /* indicate TEXT or BINARY */
6796 /* #### NT does not use this any more. Now what? */
6800 /* print percent of buffer above top of window, or Top, Bot or All */
6803 Bufpos pos = marker_position (w->start[type]);
6805 /* This had better be while the desired lines are being done. */
6806 if (w->window_end_pos[type] <= BUF_Z (b) - BUF_ZV (b))
6808 if (pos <= BUF_BEGV (b))
6813 else if (pos <= BUF_BEGV (b))
6817 /* This hard limit is ok since the string it will hold has a
6818 fixed maximum length of 3. But just to be safe... */
6820 Charcount chars = pos - BUF_BEGV (b);
6821 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6823 /* Avoid overflow on big buffers */
6824 int percent = total > LONG_MAX/200 ?
6825 (chars + total/200) / (total / 100) :
6826 (chars * 100 + total/2) / total;
6828 /* We can't normally display a 3-digit number, so get us a
6829 2-digit number that is close. */
6833 sprintf (buf, "%d%%", percent);
6834 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6837 goto decode_mode_spec_done;
6842 /* print percent of buffer above bottom of window, perhaps plus
6843 Top, or print Bottom or All */
6846 Bufpos toppos = marker_position (w->start[type]);
6847 Bufpos botpos = BUF_Z (b) - w->window_end_pos[type];
6849 /* botpos is only accurate as of the last redisplay, so we can
6850 only treat it as a hint. In particular, after erase-buffer,
6851 botpos may be negative. */
6852 if (botpos < toppos)
6855 if (botpos >= BUF_ZV (b))
6857 if (toppos <= BUF_BEGV (b))
6864 /* This hard limit is ok since the string it will hold has a
6865 fixed maximum length of around 6. But just to be safe... */
6867 Charcount chars = botpos - BUF_BEGV (b);
6868 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6870 /* Avoid overflow on big buffers */
6871 int percent = total > LONG_MAX/200 ?
6872 (chars + total/200) / (total / 100) :
6873 (chars * 100 + total/2) / max (total, 1);
6875 /* We can't normally display a 3-digit number, so get us a
6876 2-digit number that is close. */
6880 if (toppos <= BUF_BEGV (b))
6881 sprintf (buf, "Top%d%%", percent);
6883 sprintf (buf, "%d%%", percent);
6885 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6888 goto decode_mode_spec_done;
6898 /* print one [ for each recursive editing level. */
6903 if (command_loop_level > 5)
6909 for (i = 0; i < command_loop_level; i++)
6910 Dynarr_add (mode_spec_bufbyte_string, '[');
6912 goto decode_mode_spec_done;
6915 /* print one ] for each recursive editing level. */
6920 if (command_loop_level > 5)
6926 for (i = 0; i < command_loop_level; i++)
6927 Dynarr_add (mode_spec_bufbyte_string, ']');
6929 goto decode_mode_spec_done;
6932 /* print infinitely many dashes -- handle at top level now */
6939 Dynarr_add_many (mode_spec_bufbyte_string,
6941 XSTRING_LENGTH (obj));
6943 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) str, strlen (str));
6945 decode_mode_spec_done:
6946 Dynarr_add (mode_spec_bufbyte_string, '\0');
6949 /* Given a display line, free all of its data structures. */
6952 free_display_line (struct display_line *dl)
6956 if (dl->display_blocks)
6958 for (block = 0; block < Dynarr_largest (dl->display_blocks); block++)
6960 struct display_block *db = Dynarr_atp (dl->display_blocks, block);
6962 Dynarr_free (db->runes);
6965 Dynarr_free (dl->display_blocks);
6966 dl->display_blocks = NULL;
6969 if (dl->left_glyphs)
6971 Dynarr_free (dl->left_glyphs);
6972 dl->left_glyphs = NULL;
6975 if (dl->right_glyphs)
6977 Dynarr_free (dl->right_glyphs);
6978 dl->right_glyphs = NULL;
6983 /* Given an array of display lines, free them and all data structures
6984 contained within them. */
6987 free_display_lines (display_line_dynarr *dla)
6991 for (line = 0; line < Dynarr_largest (dla); line++)
6993 free_display_line (Dynarr_atp (dla, line));
6999 /* Call internal free routine for each set of display lines. */
7002 free_display_structs (struct window_mirror *mir)
7004 if (mir->current_display_lines)
7006 free_display_lines (mir->current_display_lines);
7007 mir->current_display_lines = 0;
7010 if (mir->desired_display_lines)
7012 free_display_lines (mir->desired_display_lines);
7013 mir->desired_display_lines = 0;
7019 mark_glyph_block_dynarr (glyph_block_dynarr *gba)
7023 glyph_block *gb = Dynarr_atp (gba, 0);
7024 glyph_block *gb_last = Dynarr_atp (gba, Dynarr_length (gba));
7026 for (; gb < gb_last; gb++)
7028 if (!NILP (gb->glyph))
7029 mark_object (gb->glyph);
7030 if (!NILP (gb->extent))
7031 mark_object (gb->extent);
7036 /* See the comment in image_instantiate_cache_result as to why marking
7037 the glyph will also mark the image_instance. */
7039 mark_redisplay_structs (display_line_dynarr *dla)
7041 display_line *dl = Dynarr_atp (dla, 0);
7042 display_line *dl_last = Dynarr_atp (dla, Dynarr_length (dla));
7044 for (; dl < dl_last; dl++)
7046 display_block_dynarr *dba = dl->display_blocks;
7047 display_block *db = Dynarr_atp (dba, 0);
7048 display_block *db_last = Dynarr_atp (dba, Dynarr_length (dba));
7050 for (; db < db_last; db++)
7052 rune_dynarr *ra = db->runes;
7053 rune *r = Dynarr_atp (ra, 0);
7054 rune *r_last = Dynarr_atp (ra, Dynarr_length (ra));
7056 for (; r < r_last; r++)
7058 if (r->type == RUNE_DGLYPH)
7060 if (!NILP (r->object.dglyph.glyph))
7061 mark_object (r->object.dglyph.glyph);
7062 if (!NILP (r->object.dglyph.extent))
7063 mark_object (r->object.dglyph.extent);
7068 mark_glyph_block_dynarr (dl->left_glyphs);
7069 mark_glyph_block_dynarr (dl->right_glyphs);
7074 mark_window_mirror (struct window_mirror *mir)
7076 mark_redisplay_structs (mir->current_display_lines);
7077 mark_redisplay_structs (mir->desired_display_lines);
7080 mark_window_mirror (mir->next);
7083 mark_window_mirror (mir->hchild);
7084 else if (mir->vchild)
7085 mark_window_mirror (mir->vchild);
7089 mark_redisplay (void)
7091 Lisp_Object frmcons, devcons, concons;
7093 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
7095 struct frame *f = XFRAME (XCAR (frmcons));
7096 update_frame_window_mirror (f);
7097 mark_window_mirror (f->root_mirror);
7102 /*****************************************************************************
7103 Line Start Cache Description and Rationale
7105 The traditional scrolling code in Emacs breaks in a variable height world.
7106 It depends on the key assumption that the number of lines that can be
7107 displayed at any given time is fixed. This led to a complete separation
7108 of the scrolling code from the redisplay code. In order to fully support
7109 variable height lines, the scrolling code must actually be tightly
7110 integrated with redisplay. Only redisplay can determine how many lines
7111 will be displayed on a screen for any given starting point.
7113 What is ideally wanted is a complete list of the starting buffer position
7114 for every possible display line of a buffer along with the height of that
7115 display line. Maintaining such a full list would be very expensive. We
7116 settle for having it include information for all areas which we happen to
7117 generate anyhow (i.e. the region currently being displayed) and for those
7118 areas we need to work with.
7120 In order to ensure that the cache accurately represents what redisplay
7121 would actually show, it is necessary to invalidate it in many situations.
7122 If the buffer changes, the starting positions may no longer be correct.
7123 If a face or an extent has changed then the line heights may have altered.
7124 These events happen frequently enough that the cache can end up being
7125 constantly disabled. With this potentially constant invalidation when is
7126 the cache ever useful?
7128 Even if the cache is invalidated before every single usage, it is
7129 necessary. Scrolling often requires knowledge about display lines which
7130 are actually above or below the visible region. The cache provides a
7131 convenient light-weight method of storing this information for multiple
7132 display regions. This knowledge is necessary for the scrolling code to
7133 always obey the First Golden Rule of Redisplay.
7135 If the cache already contains all of the information that the scrolling
7136 routines happen to need so that it doesn't have to go generate it, then we
7137 are able to obey the Third Golden Rule of Redisplay. The first thing we
7138 do to help out the cache is to always add the displayed region. This
7139 region had to be generated anyway, so the cache ends up getting the
7140 information basically for free. In those cases where a user is simply
7141 scrolling around viewing a buffer there is a high probability that this is
7142 sufficient to always provide the needed information. The second thing we
7143 can do is be smart about invalidating the cache.
7145 TODO -- Be smart about invalidating the cache. Potential places:
7147 + Insertions at end-of-line which don't cause line-wraps do not alter the
7148 starting positions of any display lines. These types of buffer
7149 modifications should not invalidate the cache. This is actually a large
7150 optimization for redisplay speed as well.
7152 + Buffer modifications frequently only affect the display of lines at and
7153 below where they occur. In these situations we should only invalidate
7154 the part of the cache starting at where the modification occurs.
7156 In case you're wondering, the Second Golden Rule of Redisplay is not
7158 ****************************************************************************/
7160 /* This will get used quite a bit so we don't want to be constantly
7161 allocating and freeing it. */
7162 static line_start_cache_dynarr *internal_cache;
7164 /* Makes internal_cache represent the TYPE display structs and only
7165 the TYPE display structs. */
7168 update_internal_cache_list (struct window *w, int type)
7171 display_line_dynarr *dla = window_display_lines (w, type);
7173 Dynarr_reset (internal_cache);
7174 for (line = 0; line < Dynarr_length (dla); line++)
7176 struct display_line *dl = Dynarr_atp (dla, line);
7182 struct line_start_cache lsc;
7184 lsc.start = dl->bufpos;
7185 lsc.end = dl->end_bufpos;
7186 lsc.height = dl->ascent + dl->descent;
7188 Dynarr_add (internal_cache, lsc);
7193 /* Reset the line cache if necessary. This should be run at the
7194 beginning of any function which access the cache. */
7197 validate_line_start_cache (struct window *w)
7199 struct buffer *b = XBUFFER (w->buffer);
7200 struct frame *f = XFRAME (w->frame);
7202 if (!w->line_cache_validation_override)
7204 /* f->extents_changed used to be in here because extent face and
7205 size changes can cause text shifting. However, the extent
7206 covering the region is constantly having its face set and
7207 priority altered by the mouse code. This means that the line
7208 start cache is constantly being invalidated. This is bad
7209 since the mouse code also triggers heavy usage of the cache.
7210 Since it is an unlikely that f->extents being changed
7211 indicates that the cache really needs to be updated and if it
7212 does redisplay will catch it pretty quickly we no longer
7213 invalidate the cache if it is set. This greatly speeds up
7214 dragging out regions with the mouse. */
7215 if (XINT (w->line_cache_last_updated) < BUF_MODIFF (b)
7219 Dynarr_reset (w->line_start_cache);
7224 /* Return the very first buffer position contained in the given
7225 window's cache, or -1 if the cache is empty. Assumes that the
7229 line_start_cache_start (struct window *w)
7231 line_start_cache_dynarr *cache = w->line_start_cache;
7233 if (!Dynarr_length (cache))
7236 return Dynarr_atp (cache, 0)->start;
7239 /* Return the very last buffer position contained in the given
7240 window's cache, or -1 if the cache is empty. Assumes that the
7244 line_start_cache_end (struct window *w)
7246 line_start_cache_dynarr *cache = w->line_start_cache;
7248 if (!Dynarr_length (cache))
7251 return Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
7254 /* Return the index of the line POINT is contained within in window
7255 W's line start cache. It will enlarge the cache or move the cache
7256 window in order to have POINT be present in the cache. MIN_PAST is
7257 a guarantee of the number of entries in the cache present on either
7258 side of POINT (unless a buffer boundary is hit). If MIN_PAST is -1
7259 then it will be treated as 0, but the cache window will not be
7260 allowed to shift. Returns -1 if POINT cannot be found in the cache
7264 point_in_line_start_cache (struct window *w, Bufpos point, int min_past)
7266 struct buffer *b = XBUFFER (w->buffer);
7267 line_start_cache_dynarr *cache = w->line_start_cache;
7268 unsigned int top, bottom, pos;
7270 validate_line_start_cache (w);
7271 w->line_cache_validation_override++;
7273 /* Let functions pass in negative values, but we still treat -1
7275 /* #### bogosity alert */
7276 if (min_past < 0 && min_past != -1)
7277 min_past = -min_past;
7279 if (!Dynarr_length (cache) || line_start_cache_start (w) > point
7280 || line_start_cache_end (w) < point)
7283 int win_char_height = window_char_height (w, 1);
7285 /* Occasionally we get here with a 0 height
7286 window. find_next_newline_no_quit will abort if we pass it a
7287 count of 0 so handle that case. */
7288 if (!win_char_height)
7289 win_char_height = 1;
7291 if (!Dynarr_length (cache))
7293 Bufpos from = find_next_newline_no_quit (b, point, -1);
7294 Bufpos to = find_next_newline_no_quit (b, from, win_char_height);
7296 update_line_start_cache (w, from, to, point, 0);
7298 if (!Dynarr_length (cache))
7300 w->line_cache_validation_override--;
7305 assert (Dynarr_length (cache));
7308 while (line_start_cache_start (w) > point
7309 && (loop < cache_adjustment || min_past == -1))
7313 from = line_start_cache_start (w);
7314 if (from <= BUF_BEGV (b))
7317 from = find_next_newline_no_quit (b, from, -win_char_height);
7318 to = line_start_cache_end (w);
7320 update_line_start_cache (w, from, to, point, 0);
7324 if (line_start_cache_start (w) > point)
7328 from = find_next_newline_no_quit (b, point, -1);
7329 if (from >= BUF_ZV (b))
7331 to = find_next_newline_no_quit (b, from, -win_char_height);
7336 to = find_next_newline_no_quit (b, from, win_char_height);
7338 update_line_start_cache (w, from, to, point, 0);
7342 while (line_start_cache_end (w) < point
7343 && (loop < cache_adjustment || min_past == -1))
7347 to = line_start_cache_end (w);
7348 if (to >= BUF_ZV (b))
7351 from = line_start_cache_end (w);
7352 to = find_next_newline_no_quit (b, from, win_char_height);
7354 update_line_start_cache (w, from, to, point, 0);
7358 if (line_start_cache_end (w) < point)
7362 from = find_next_newline_no_quit (b, point, -1);
7363 if (from >= BUF_ZV (b))
7365 to = find_next_newline_no_quit (b, from, -win_char_height);
7370 to = find_next_newline_no_quit (b, from, win_char_height);
7372 update_line_start_cache (w, from, to, point, 0);
7376 assert (Dynarr_length (cache));
7381 /* This could happen if the buffer is narrowed. */
7382 if (line_start_cache_start (w) > point
7383 || line_start_cache_end (w) < point)
7385 w->line_cache_validation_override--;
7391 top = Dynarr_length (cache) - 1;
7396 unsigned int new_pos;
7399 pos = (bottom + top + 1) >> 1;
7400 start = Dynarr_atp (cache, pos)->start;
7401 end = Dynarr_atp (cache, pos)->end;
7403 if (point >= start && point <= end)
7405 if (pos < min_past && line_start_cache_start (w) > BUF_BEGV (b))
7408 find_next_newline_no_quit (b, line_start_cache_start (w),
7410 Bufpos to = line_start_cache_end (w);
7412 update_line_start_cache (w, from, to, point, 0);
7413 goto find_point_loop;
7415 else if ((Dynarr_length (cache) - pos - 1) < min_past
7416 && line_start_cache_end (w) < BUF_ZV (b))
7418 Bufpos from = line_start_cache_end (w);
7419 Bufpos to = find_next_newline_no_quit (b, from,
7424 update_line_start_cache (w, from, to, point, 0);
7425 goto find_point_loop;
7429 w->line_cache_validation_override--;
7433 else if (point > end)
7435 else if (point < start)
7440 new_pos = (bottom + top + 1) >> 1;
7443 w->line_cache_validation_override--;
7449 /* Return a boolean indicating if POINT would be visible in window W
7450 if display of the window was to begin at STARTP. */
7453 point_would_be_visible (struct window *w, Bufpos startp, Bufpos point)
7455 struct buffer *b = XBUFFER (w->buffer);
7456 int pixpos = -WINDOW_TEXT_TOP_CLIP(w);
7457 int bottom = WINDOW_TEXT_HEIGHT (w);
7460 /* If point is before the intended start it obviously can't be visible. */
7464 /* If point or start are not in the accessible buffer range, then
7466 if (startp < BUF_BEGV (b) || startp > BUF_ZV (b)
7467 || point < BUF_BEGV (b) || point > BUF_ZV (b))
7470 validate_line_start_cache (w);
7471 w->line_cache_validation_override++;
7473 start_elt = point_in_line_start_cache (w, startp, 0);
7474 if (start_elt == -1)
7476 w->line_cache_validation_override--;
7480 assert (line_start_cache_start (w) <= startp
7481 && line_start_cache_end (w) >= startp);
7487 /* Expand the cache if necessary. */
7488 if (start_elt == Dynarr_length (w->line_start_cache))
7491 Dynarr_atp (w->line_start_cache, start_elt - 1)->start;
7493 start_elt = point_in_line_start_cache (w, old_startp,
7494 window_char_height (w, 0));
7496 /* We've already actually processed old_startp, so increment
7500 /* If this happens we didn't add any extra elements. Bummer. */
7501 if (start_elt == Dynarr_length (w->line_start_cache))
7503 w->line_cache_validation_override--;
7508 height = Dynarr_atp (w->line_start_cache, start_elt)->height;
7510 if (pixpos + height > bottom)
7512 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7514 w->line_cache_validation_override--;
7520 if (point <= Dynarr_atp (w->line_start_cache, start_elt)->end)
7522 w->line_cache_validation_override--;
7530 /* For the given window W, if display starts at STARTP, what will be
7531 the buffer position at the beginning or end of the last line
7532 displayed. The end of the last line is also know as the window end
7535 WARNING: It is possible that rediplay failed to layout any lines for the
7536 windows. Under normal circumstances this is rare. However it seems that it
7537 does occur in the following situation: A mouse event has come in and we
7538 need to compute its location in a window. That code (in
7539 pixel_to_glyph_translation) already can handle 0 as an error return value.
7541 #### With a little work this could probably be reworked as just a
7542 call to start_with_line_at_pixpos. */
7545 start_end_of_last_line (struct window *w, Bufpos startp, int end,
7548 struct buffer *b = XBUFFER (w->buffer);
7549 line_start_cache_dynarr *cache = w->line_start_cache;
7551 int bottom = WINDOW_TEXT_HEIGHT (w);
7555 validate_line_start_cache (w);
7556 w->line_cache_validation_override++;
7558 if (startp < BUF_BEGV (b))
7559 startp = BUF_BEGV (b);
7560 else if (startp > BUF_ZV (b))
7561 startp = BUF_ZV (b);
7564 start_elt = point_in_line_start_cache (w, cur_start, 0);
7565 if (start_elt == -1)
7566 return may_error ? 0 : startp;
7570 int height = Dynarr_atp (cache, start_elt)->height;
7572 cur_start = Dynarr_atp (cache, start_elt)->start;
7574 if (pixpos + height > bottom)
7576 /* Adjust for any possible clip. */
7577 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7582 w->line_cache_validation_override--;
7586 return BUF_BEGV (b);
7590 w->line_cache_validation_override--;
7592 return Dynarr_atp (cache, start_elt)->end;
7594 return Dynarr_atp (cache, start_elt)->start;
7600 if (start_elt == Dynarr_length (cache))
7602 Bufpos from = line_start_cache_end (w);
7603 int win_char_height = window_char_height (w, 0);
7604 Bufpos to = find_next_newline_no_quit (b, from,
7609 /* We've hit the end of the bottom so that's what it is. */
7610 if (from >= BUF_ZV (b))
7612 w->line_cache_validation_override--;
7616 update_line_start_cache (w, from, to, BUF_PT (b), 0);
7618 /* Updating the cache invalidates any current indexes. */
7619 start_elt = point_in_line_start_cache (w, cur_start, -1) + 1;
7624 /* For the given window W, if display starts at STARTP, what will be
7625 the buffer position at the beginning of the last line displayed. */
7628 start_of_last_line (struct window *w, Bufpos startp)
7630 return start_end_of_last_line (w, startp, 0 , 0);
7633 /* For the given window W, if display starts at STARTP, what will be
7634 the buffer position at the end of the last line displayed. This is
7635 also know as the window end position. */
7638 end_of_last_line (struct window *w, Bufpos startp)
7640 return start_end_of_last_line (w, startp, 1, 0);
7644 end_of_last_line_may_error (struct window *w, Bufpos startp)
7646 return start_end_of_last_line (w, startp, 1, 1);
7650 /* For window W, what does the starting position have to be so that
7651 the line containing POINT will cover pixel position PIXPOS. */
7654 start_with_line_at_pixpos (struct window *w, Bufpos point, int pixpos)
7656 struct buffer *b = XBUFFER (w->buffer);
7658 Bufpos cur_pos, prev_pos = point;
7659 int point_line_height;
7660 int pixheight = pixpos - WINDOW_TEXT_TOP (w);
7662 validate_line_start_cache (w);
7663 w->line_cache_validation_override++;
7665 cur_elt = point_in_line_start_cache (w, point, 0);
7666 /* #### See comment in update_line_start_cache about big minibuffers. */
7669 w->line_cache_validation_override--;
7673 point_line_height = Dynarr_atp (w->line_start_cache, cur_elt)->height;
7677 cur_pos = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7679 pixheight -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7681 /* Do not take into account the value of vertical_clip here.
7682 That is the responsibility of the calling functions. */
7685 w->line_cache_validation_override--;
7686 if (-pixheight > point_line_height)
7687 /* We can't make the target line cover pixpos, so put it
7688 above pixpos. That way it will at least be visible. */
7698 int win_char_height;
7700 if (cur_pos <= BUF_BEGV (b))
7702 w->line_cache_validation_override--;
7703 return BUF_BEGV (b);
7706 win_char_height = window_char_height (w, 0);
7707 if (!win_char_height)
7708 win_char_height = 1;
7710 from = find_next_newline_no_quit (b, cur_pos, -win_char_height);
7711 to = line_start_cache_end (w);
7712 update_line_start_cache (w, from, to, point, 0);
7714 cur_elt = point_in_line_start_cache (w, cur_pos, 2) - 1;
7715 assert (cur_elt >= -1);
7716 /* This used to be cur_elt>=0 under the assumption that if
7717 point is in the top line and not at BUF_BEGV, then
7718 setting the window_start to a newline before the start of
7719 the first line will always cause scrolling.
7721 However in my (jv) opinion this is wrong. That new line
7722 can be hidden in various ways: invisible extents, an
7723 explicit window-start not at a newline character etc.
7724 The existence of those are indeed known to create crashes
7725 on that assert. So we have no option but to continue the
7726 search if we found point at the top of the line_start_cache
7728 cur_pos = Dynarr_atp (w->line_start_cache,0)->start;
7734 /* For window W, what does the starting position have to be so that
7735 the line containing point is on display line LINE. If LINE is
7736 positive it is considered to be the number of lines from the top of
7737 the window (0 is the top line). If it is negative the number is
7738 considered to be the number of lines from the bottom (-1 is the
7742 start_with_point_on_display_line (struct window *w, Bufpos point, int line)
7744 validate_line_start_cache (w);
7745 w->line_cache_validation_override++;
7749 int cur_elt = point_in_line_start_cache (w, point, line);
7751 if (cur_elt - line < 0)
7752 cur_elt = 0; /* Hit the top */
7756 w->line_cache_validation_override--;
7757 return Dynarr_atp (w->line_start_cache, cur_elt)->start;
7761 /* The calculated value of pixpos is correct for the bottom line
7762 or what we want when line is -1. Therefore we subtract one
7763 because we have already handled one line. */
7764 int new_line = -line - 1;
7765 int cur_elt = point_in_line_start_cache (w, point, new_line);
7766 int pixpos = WINDOW_TEXT_BOTTOM (w);
7767 Bufpos retval, search_point;
7769 /* If scroll_on_clipped_lines is false, the last "visible" line of
7770 the window covers the pixel at WINDOW_TEXT_BOTTOM (w) - 1.
7771 If s_o_c_l is true, then we don't want to count a clipped
7772 line, so back up from the bottom by the height of the line
7773 containing point. */
7774 if (scroll_on_clipped_lines)
7775 pixpos -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7779 if (cur_elt + new_line >= Dynarr_length (w->line_start_cache))
7781 /* Hit the bottom of the buffer. */
7783 (cur_elt + new_line) - Dynarr_length (w->line_start_cache) + 1;
7787 XSETWINDOW (window, w);
7788 default_face_height_and_width (window, &defheight, 0);
7790 cur_elt = Dynarr_length (w->line_start_cache) - 1;
7792 pixpos -= (adjustment * defheight);
7793 if (pixpos < WINDOW_TEXT_TOP (w))
7794 pixpos = WINDOW_TEXT_TOP (w);
7797 cur_elt = cur_elt + new_line;
7799 search_point = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7801 retval = start_with_line_at_pixpos (w, search_point, pixpos);
7802 w->line_cache_validation_override--;
7807 /* This is used to speed up vertical scrolling by caching the known
7808 buffer starting positions for display lines. This allows the
7809 scrolling routines to avoid costly calls to regenerate_window. If
7810 NO_REGEN is true then it will only add the values in the DESIRED
7811 display structs which are in the given range.
7813 Note also that the FROM/TO values are minimums. It is possible
7814 that this function will actually add information outside of the
7815 lines containing those positions. This can't hurt but it could
7818 #### We currently force the cache to have only 1 contiguous region.
7819 It might help to make the cache a dynarr of caches so that we can
7820 cover more areas. This might, however, turn out to be a lot of
7821 overhead for too little gain. */
7824 update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
7825 Bufpos point, int no_regen)
7827 struct buffer *b = XBUFFER (w->buffer);
7828 line_start_cache_dynarr *cache = w->line_start_cache;
7829 Bufpos low_bound, high_bound;
7831 validate_line_start_cache (w);
7832 w->line_cache_validation_override++;
7834 if (from < BUF_BEGV (b))
7835 from = BUF_BEGV (b);
7836 if (to > BUF_ZV (b))
7841 w->line_cache_validation_override--;
7845 if (Dynarr_length (cache))
7847 low_bound = line_start_cache_start (w);
7848 high_bound = line_start_cache_end (w);
7850 /* Check to see if the desired range is already in the cache. */
7851 if (from >= low_bound && to <= high_bound)
7853 w->line_cache_validation_override--;
7857 /* Check to make sure that the desired range is adjacent to the
7858 current cache. If not, invalidate the cache. */
7859 if (to < low_bound || from > high_bound)
7861 Dynarr_reset (cache);
7862 low_bound = high_bound = -1;
7867 low_bound = high_bound = -1;
7870 w->line_cache_last_updated = make_int (BUF_MODIFF (b));
7872 /* This could be integrated into the next two sections, but it is easier
7873 to follow what's going on by having it separate. */
7878 update_internal_cache_list (w, DESIRED_DISP);
7879 if (!Dynarr_length (internal_cache))
7881 w->line_cache_validation_override--;
7885 start = Dynarr_atp (internal_cache, 0)->start;
7887 Dynarr_atp (internal_cache, Dynarr_length (internal_cache) - 1)->end;
7889 /* We aren't allowed to generate additional information to fill in
7890 gaps, so if the DESIRED structs don't overlap the cache, reset the
7892 if (Dynarr_length (cache))
7894 if (end < low_bound || start > high_bound)
7895 Dynarr_reset (cache);
7897 /* #### What should really happen if what we are doing is
7898 extending a line (the last line)? */
7899 if (Dynarr_length (cache) == 1
7900 && Dynarr_length (internal_cache) == 1)
7901 Dynarr_reset (cache);
7904 if (!Dynarr_length (cache))
7906 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7907 Dynarr_length (internal_cache));
7908 w->line_cache_validation_override--;
7912 /* An extra check just in case the calling function didn't pass in
7913 the bounds of the DESIRED structs in the first place. */
7914 if (start >= low_bound && end <= high_bound)
7916 w->line_cache_validation_override--;
7920 /* At this point we know that the internal cache partially overlaps
7922 if (start < low_bound)
7924 int ic_elt = Dynarr_length (internal_cache) - 1;
7927 if (Dynarr_atp (internal_cache, ic_elt)->start < low_bound)
7935 Dynarr_reset (cache);
7936 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7937 Dynarr_length (internal_cache));
7938 w->line_cache_validation_override--;
7942 Dynarr_insert_many_at_start (cache, Dynarr_atp (internal_cache, 0),
7946 if (end > high_bound)
7950 while (ic_elt < Dynarr_length (internal_cache))
7952 if (Dynarr_atp (internal_cache, ic_elt)->start > high_bound)
7958 if (!(ic_elt < Dynarr_length (internal_cache)))
7960 Dynarr_reset (cache);
7961 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7962 Dynarr_length (internal_cache));
7963 w->line_cache_validation_override--;
7967 Dynarr_add_many (cache, Dynarr_atp (internal_cache, ic_elt),
7968 Dynarr_length (internal_cache) - ic_elt);
7971 w->line_cache_validation_override--;
7975 if (!Dynarr_length (cache) || from < low_bound)
7977 Bufpos startp = find_next_newline_no_quit (b, from, -1);
7979 int old_lb = low_bound;
7981 while (startp < old_lb || low_bound == -1)
7986 regenerate_window (w, startp, point, CMOTION_DISP);
7987 update_internal_cache_list (w, CMOTION_DISP);
7989 /* If this assert is triggered then regenerate_window failed
7990 to layout a single line. This is not possible since we
7991 force at least a single line to be layout for CMOTION_DISP */
7992 assert (Dynarr_length (internal_cache));
7993 assert (startp == Dynarr_atp (internal_cache, 0)->start);
7995 ic_elt = Dynarr_length (internal_cache) - 1;
7996 if (low_bound != -1)
8000 if (Dynarr_atp (internal_cache, ic_elt)->start < old_lb)
8006 assert (ic_elt >= 0);
8008 new_startp = Dynarr_atp (internal_cache, ic_elt)->end + 1;
8011 * Handle invisible text properly:
8012 * If the last line we're inserting has the same end as the
8013 * line before which it will be added, merge the two lines.
8015 if (Dynarr_length (cache) &&
8016 Dynarr_atp (internal_cache, ic_elt)->end ==
8017 Dynarr_atp (cache, marker)->end)
8019 Dynarr_atp (cache, marker)->start
8020 = Dynarr_atp (internal_cache, ic_elt)->start;
8021 Dynarr_atp (cache, marker)->height
8022 = Dynarr_atp (internal_cache, ic_elt)->height;
8026 if (ic_elt >= 0) /* we still have lines to add.. */
8028 Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0),
8029 ic_elt + 1, marker);
8030 marker += (ic_elt + 1);
8033 if (startp < low_bound || low_bound == -1)
8035 startp = new_startp;
8036 if (startp > BUF_ZV (b))
8038 w->line_cache_validation_override--;
8044 assert (Dynarr_length (cache));
8045 assert (from >= low_bound);
8047 /* Readjust the high_bound to account for any changes made while
8048 correcting the low_bound. */
8049 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8051 if (to > high_bound)
8053 Bufpos startp = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end + 1;
8057 regenerate_window (w, startp, point, CMOTION_DISP);
8058 update_internal_cache_list (w, CMOTION_DISP);
8060 /* See comment above about regenerate_window failing. */
8061 assert (Dynarr_length (internal_cache));
8063 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
8064 Dynarr_length (internal_cache));
8065 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8066 startp = high_bound + 1;
8068 while (to > high_bound);
8071 w->line_cache_validation_override--;
8072 assert (to <= high_bound);
8076 /* Given x and y coordinates in characters, relative to a window,
8077 return the pixel location corresponding to those coordinates. The
8078 pixel location returned is the center of the given character
8079 position. The pixel values are generated relative to the window,
8082 The modeline is considered to be part of the window. */
8085 glyph_to_pixel_translation (struct window *w, int char_x, int char_y,
8086 int *pix_x, int *pix_y)
8088 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
8089 int num_disp_lines, modeline;
8091 int defheight, defwidth;
8093 XSETWINDOW (window, w);
8094 default_face_height_and_width (window, &defheight, &defwidth);
8096 /* If we get a bogus value indicating somewhere above or to the left of
8097 the window, use the first window line or character position
8104 num_disp_lines = Dynarr_length (dla);
8108 if (Dynarr_atp (dla, 0)->modeline)
8115 /* First check if the y position intersects the display lines. */
8116 if (char_y < num_disp_lines)
8118 struct display_line *dl = Dynarr_atp (dla, char_y + modeline);
8119 struct display_block *db = get_display_block_from_line (dl, TEXT);
8121 *pix_y = (dl->ypos - dl->ascent +
8122 ((unsigned int) (dl->ascent + dl->descent - dl->clip) >> 1));
8124 if (char_x < Dynarr_length (db->runes))
8126 struct rune *rb = Dynarr_atp (db->runes, char_x);
8128 *pix_x = rb->xpos + (rb->width >> 1);
8132 int last_rune = Dynarr_length (db->runes) - 1;
8133 struct rune *rb = Dynarr_atp (db->runes, last_rune);
8135 char_x -= last_rune;
8137 *pix_x = rb->xpos + rb->width;
8138 *pix_x += ((char_x - 1) * defwidth);
8139 *pix_x += (defwidth >> 1);
8144 /* It didn't intersect, so extrapolate. #### For now, we include the
8145 modeline in this since we don't have true character positions in
8148 if (!Dynarr_length (w->face_cachels))
8149 reset_face_cachels (w);
8151 char_y -= num_disp_lines;
8153 if (Dynarr_length (dla))
8155 struct display_line *dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
8156 *pix_y = dl->ypos + dl->descent - dl->clip;
8159 *pix_y = WINDOW_TEXT_TOP (w);
8161 *pix_y += (char_y * defheight);
8162 *pix_y += (defheight >> 1);
8164 *pix_x = WINDOW_TEXT_LEFT (w);
8165 /* Don't adjust by one because this is still the unadjusted value. */
8166 *pix_x += (char_x * defwidth);
8167 *pix_x += (defwidth >> 1);
8170 if (*pix_x > w->pixel_left + w->pixel_width)
8171 *pix_x = w->pixel_left + w->pixel_width;
8172 if (*pix_y > w->pixel_top + w->pixel_height)
8173 *pix_y = w->pixel_top + w->pixel_height;
8175 *pix_x -= w->pixel_left;
8176 *pix_y -= w->pixel_top;
8179 /* Given a display line and a position, determine if there is a glyph
8180 there and return information about it if there is. */
8183 get_position_object (struct display_line *dl, Lisp_Object *obj1,
8184 Lisp_Object *obj2, int x_coord, int *low_x_coord,
8187 struct display_block *db;
8190 get_next_display_block (dl->bounds, dl->display_blocks, x_coord, 0);
8192 /* We use get_next_display_block to get the actual display block
8193 that would be displayed at x_coord. */
8195 if (block == NO_BLOCK)
8198 db = Dynarr_atp (dl->display_blocks, block);
8200 for (elt = 0; elt < Dynarr_length (db->runes); elt++)
8202 struct rune *rb = Dynarr_atp (db->runes, elt);
8204 if (rb->xpos <= x_coord && x_coord < (rb->xpos + rb->width))
8206 if (rb->type == RUNE_DGLYPH)
8208 *obj1 = rb->object.dglyph.glyph;
8209 *obj2 = rb->object.dglyph.extent;
8218 *low_x_coord = rb->xpos;
8220 *high_x_coord = rb->xpos + rb->width;
8227 #define UPDATE_CACHE_RETURN \
8229 d->pixel_to_glyph_cache.valid = 1; \
8230 d->pixel_to_glyph_cache.low_x_coord = low_x_coord; \
8231 d->pixel_to_glyph_cache.high_x_coord = high_x_coord; \
8232 d->pixel_to_glyph_cache.low_y_coord = low_y_coord; \
8233 d->pixel_to_glyph_cache.high_y_coord = high_y_coord; \
8234 d->pixel_to_glyph_cache.frame = f; \
8235 d->pixel_to_glyph_cache.col = *col; \
8236 d->pixel_to_glyph_cache.row = *row; \
8237 d->pixel_to_glyph_cache.obj_x = *obj_x; \
8238 d->pixel_to_glyph_cache.obj_y = *obj_y; \
8239 d->pixel_to_glyph_cache.w = *w; \
8240 d->pixel_to_glyph_cache.bufpos = *bufpos; \
8241 d->pixel_to_glyph_cache.closest = *closest; \
8242 d->pixel_to_glyph_cache.modeline_closest = *modeline_closest; \
8243 d->pixel_to_glyph_cache.obj1 = *obj1; \
8244 d->pixel_to_glyph_cache.obj2 = *obj2; \
8245 d->pixel_to_glyph_cache.retval = position; \
8246 RETURN_SANS_WARNINGS position; \
8249 /* Given x and y coordinates in pixels relative to a frame, return
8250 information about what is located under those coordinates.
8252 The return value will be one of:
8254 OVER_TOOLBAR: over one of the 4 frame toolbars
8255 OVER_MODELINE: over a modeline
8256 OVER_BORDER: over an internal border
8257 OVER_NOTHING: over the text area, but not over text
8258 OVER_OUTSIDE: outside of the frame border
8259 OVER_TEXT: over text in the text area
8265 -- nil if the coordinates are not over a glyph or a toolbar button.
8269 -- an extent, if the coordinates are over a glyph in the text area
8272 If the coordinates are over a glyph, OBJ_X and OBJ_Y give the
8273 equivalent coordinates relative to the upper-left corner of the glyph.
8275 If the coordinates are over a character, OBJ_X and OBJ_Y give the
8276 equivalent coordinates relative to the upper-left corner of the character.
8278 Otherwise, OBJ_X and OBJ_Y are undefined.
8282 pixel_to_glyph_translation (struct frame *f, int x_coord, int y_coord,
8283 int *col, int *row, int *obj_x, int *obj_y,
8284 struct window **w, Bufpos *bufpos,
8285 Bufpos *closest, Charcount *modeline_closest,
8286 Lisp_Object *obj1, Lisp_Object *obj2)
8289 struct pixel_to_glyph_translation_cache *cache;
8291 int frm_left, frm_right, frm_top, frm_bottom;
8292 int low_x_coord, high_x_coord, low_y_coord, high_y_coord;
8293 int position = OVER_NOTHING;
8294 int device_check_failed = 0;
8295 display_line_dynarr *dla;
8297 /* This is a safety valve in case this got called with a frame in
8298 the middle of being deleted. */
8299 if (!DEVICEP (f->device) || !DEVICE_LIVE_P (XDEVICE (f->device)))
8301 device_check_failed = 1;
8302 d = NULL, cache = NULL; /* Warning suppression */
8306 d = XDEVICE (f->device);
8307 cache = &d->pixel_to_glyph_cache;
8310 if (!device_check_failed
8312 && cache->frame == f
8313 && cache->low_x_coord <= x_coord
8314 && cache->high_x_coord > x_coord
8315 && cache->low_y_coord <= y_coord
8316 && cache->high_y_coord > y_coord)
8320 *obj_x = cache->obj_x;
8321 *obj_y = cache->obj_y;
8323 *bufpos = cache->bufpos;
8324 *closest = cache->closest;
8325 *modeline_closest = cache->modeline_closest;
8326 *obj1 = cache->obj1;
8327 *obj2 = cache->obj2;
8329 return cache->retval;
8340 *modeline_closest = -1;
8344 low_x_coord = x_coord;
8345 high_x_coord = x_coord + 1;
8346 low_y_coord = y_coord;
8347 high_y_coord = y_coord + 1;
8350 if (device_check_failed)
8351 return OVER_NOTHING;
8353 frm_left = FRAME_LEFT_BORDER_END (f);
8354 frm_right = FRAME_RIGHT_BORDER_START (f);
8355 frm_top = FRAME_TOP_BORDER_END (f);
8356 frm_bottom = FRAME_BOTTOM_BORDER_START (f);
8358 /* Check if the mouse is outside of the text area actually used by
8360 if (y_coord < frm_top)
8362 if (y_coord >= FRAME_TOP_BORDER_START (f))
8364 low_y_coord = FRAME_TOP_BORDER_START (f);
8365 high_y_coord = frm_top;
8366 position = OVER_BORDER;
8368 else if (y_coord >= 0)
8371 high_y_coord = FRAME_TOP_BORDER_START (f);
8372 position = OVER_TOOLBAR;
8376 low_y_coord = y_coord;
8378 position = OVER_OUTSIDE;
8381 else if (y_coord >= frm_bottom)
8383 if (y_coord < FRAME_BOTTOM_BORDER_END (f))
8385 low_y_coord = frm_bottom;
8386 high_y_coord = FRAME_BOTTOM_BORDER_END (f);
8387 position = OVER_BORDER;
8389 else if (y_coord < FRAME_PIXHEIGHT (f))
8391 low_y_coord = FRAME_BOTTOM_BORDER_END (f);
8392 high_y_coord = FRAME_PIXHEIGHT (f);
8393 position = OVER_TOOLBAR;
8397 low_y_coord = FRAME_PIXHEIGHT (f);
8398 high_y_coord = y_coord;
8399 position = OVER_OUTSIDE;
8403 if (position != OVER_TOOLBAR && position != OVER_BORDER)
8405 if (x_coord < frm_left)
8407 if (x_coord >= FRAME_LEFT_BORDER_START (f))
8409 low_x_coord = FRAME_LEFT_BORDER_START (f);
8410 high_x_coord = frm_left;
8411 position = OVER_BORDER;
8413 else if (x_coord >= 0)
8416 high_x_coord = FRAME_LEFT_BORDER_START (f);
8417 position = OVER_TOOLBAR;
8421 low_x_coord = x_coord;
8423 position = OVER_OUTSIDE;
8426 else if (x_coord >= frm_right)
8428 if (x_coord < FRAME_RIGHT_BORDER_END (f))
8430 low_x_coord = frm_right;
8431 high_x_coord = FRAME_RIGHT_BORDER_END (f);
8432 position = OVER_BORDER;
8434 else if (x_coord < FRAME_PIXWIDTH (f))
8436 low_x_coord = FRAME_RIGHT_BORDER_END (f);
8437 high_x_coord = FRAME_PIXWIDTH (f);
8438 position = OVER_TOOLBAR;
8442 low_x_coord = FRAME_PIXWIDTH (f);
8443 high_x_coord = x_coord;
8444 position = OVER_OUTSIDE;
8449 #ifdef HAVE_TOOLBARS
8450 if (position == OVER_TOOLBAR)
8452 *obj1 = toolbar_button_at_pixpos (f, x_coord, y_coord);
8455 UPDATE_CACHE_RETURN;
8457 #endif /* HAVE_TOOLBARS */
8459 /* We still have to return the window the pointer is next to and its
8460 relative y position even if it is outside the x boundary. */
8461 if (x_coord < frm_left)
8463 else if (x_coord > frm_right)
8464 x_coord = frm_right;
8466 /* Same in reverse. */
8467 if (y_coord < frm_top)
8469 else if (y_coord > frm_bottom)
8470 y_coord = frm_bottom;
8472 /* Find what window the given coordinates are actually in. */
8473 window = f->root_window;
8474 *w = find_window_by_pixel_pos (x_coord, y_coord, window);
8476 /* If we didn't find a window, we're done. */
8479 UPDATE_CACHE_RETURN;
8481 else if (position != OVER_NOTHING)
8484 *modeline_closest = -1;
8486 if (high_y_coord <= frm_top || high_y_coord >= frm_bottom)
8489 UPDATE_CACHE_RETURN;
8493 /* Check if the window is a minibuffer but isn't active. */
8494 if (MINI_WINDOW_P (*w) && !minibuf_level)
8496 /* Must reset the window value since some callers will ignore
8497 the return value if it is set. */
8499 UPDATE_CACHE_RETURN;
8502 /* See if the point is over window vertical divider */
8503 if (window_needs_vertical_divider (*w))
8505 int div_x_high = WINDOW_RIGHT (*w);
8506 int div_x_low = div_x_high - window_divider_width (*w);
8507 int div_y_high = WINDOW_BOTTOM (*w);
8508 int div_y_low = WINDOW_TOP (*w);
8510 if (div_x_low < x_coord && x_coord <= div_x_high &&
8511 div_y_low < y_coord && y_coord <= div_y_high)
8513 low_x_coord = div_x_low;
8514 high_x_coord = div_x_high;
8515 low_y_coord = div_y_low;
8516 high_y_coord = div_y_high;
8517 position = OVER_V_DIVIDER;
8518 UPDATE_CACHE_RETURN;
8522 dla = window_display_lines (*w, CURRENT_DISP);
8524 for (*row = 0; *row < Dynarr_length (dla); (*row)++)
8526 int really_over_nothing = 0;
8527 struct display_line *dl = Dynarr_atp (dla, *row);
8529 if ((int) (dl->ypos - dl->ascent) <= y_coord
8530 && y_coord <= (int) (dl->ypos + dl->descent))
8532 int check_margin_glyphs = 0;
8533 struct display_block *db = get_display_block_from_line (dl, TEXT);
8534 struct rune *rb = 0;
8536 if (x_coord < dl->bounds.left_white
8537 || x_coord >= dl->bounds.right_white)
8538 check_margin_glyphs = 1;
8540 low_y_coord = dl->ypos - dl->ascent;
8541 high_y_coord = dl->ypos + dl->descent + 1;
8543 if (position == OVER_BORDER
8544 || position == OVER_OUTSIDE
8545 || check_margin_glyphs)
8547 int x_check, left_bound;
8549 if (check_margin_glyphs)
8552 left_bound = dl->bounds.left_white;
8556 x_check = high_x_coord;
8557 left_bound = frm_left;
8560 if (Dynarr_length (db->runes))
8562 if (x_check <= left_bound)
8565 *modeline_closest = Dynarr_atp (db->runes, 0)->bufpos;
8567 *closest = Dynarr_atp (db->runes, 0)->bufpos;
8573 Dynarr_atp (db->runes,
8574 Dynarr_length (db->runes) - 1)->bufpos;
8577 Dynarr_atp (db->runes,
8578 Dynarr_length (db->runes) - 1)->bufpos;
8582 *modeline_closest += dl->offset;
8584 *closest += dl->offset;
8588 /* #### What should be here. */
8590 *modeline_closest = 0;
8595 if (check_margin_glyphs)
8597 if (x_coord < dl->bounds.left_in
8598 || x_coord >= dl->bounds.right_in)
8600 /* If we are over the outside margins then we
8601 know the loop over the text block isn't going
8602 to accomplish anything. So we go ahead and
8603 set what information we can right here and
8606 *obj_y = y_coord - (dl->ypos - dl->ascent);
8607 get_position_object (dl, obj1, obj2, x_coord,
8608 &low_x_coord, &high_x_coord);
8610 UPDATE_CACHE_RETURN;
8614 UPDATE_CACHE_RETURN;
8617 for (*col = 0; *col <= Dynarr_length (db->runes); (*col)++)
8619 int past_end = (*col == Dynarr_length (db->runes));
8622 rb = Dynarr_atp (db->runes, *col);
8625 (rb->xpos <= x_coord && x_coord < rb->xpos + rb->width))
8630 rb = Dynarr_atp (db->runes, *col);
8633 *bufpos = rb->bufpos + dl->offset;
8634 low_x_coord = rb->xpos;
8635 high_x_coord = rb->xpos + rb->width;
8637 if (rb->type == RUNE_DGLYPH)
8641 /* Find the first character after the glyph. */
8642 while (elt < Dynarr_length (db->runes))
8644 if (Dynarr_atp (db->runes, elt)->type != RUNE_DGLYPH)
8648 (Dynarr_atp (db->runes, elt)->bufpos +
8652 (Dynarr_atp (db->runes, elt)->bufpos +
8660 /* In this case we failed to find a non-glyph
8661 character so we return the last position
8662 displayed on the line. */
8663 if (elt == Dynarr_length (db->runes))
8666 *modeline_closest = dl->end_bufpos + dl->offset;
8668 *closest = dl->end_bufpos + dl->offset;
8669 really_over_nothing = 1;
8675 *modeline_closest = rb->bufpos + dl->offset;
8677 *closest = rb->bufpos + dl->offset;
8682 *row = window_displayed_height (*w);
8684 if (position == OVER_NOTHING)
8685 position = OVER_MODELINE;
8687 if (rb->type == RUNE_DGLYPH)
8689 *obj1 = rb->object.dglyph.glyph;
8690 *obj2 = rb->object.dglyph.extent;
8692 else if (rb->type == RUNE_CHAR)
8703 UPDATE_CACHE_RETURN;
8706 || (rb->type == RUNE_CHAR
8707 && rb->object.chr.ch == '\n'))
8710 /* At this point we may have glyphs in the right
8712 if (check_margin_glyphs)
8713 get_position_object (dl, obj1, obj2, x_coord,
8714 &low_x_coord, &high_x_coord);
8715 UPDATE_CACHE_RETURN;
8720 if (rb->type == RUNE_DGLYPH)
8722 *obj1 = rb->object.dglyph.glyph;
8723 *obj2 = rb->object.dglyph.extent;
8725 else if (rb->type == RUNE_CHAR)
8736 *obj_x = x_coord - rb->xpos;
8737 *obj_y = y_coord - (dl->ypos - dl->ascent);
8739 /* At this point we may have glyphs in the left
8741 if (check_margin_glyphs)
8742 get_position_object (dl, obj1, obj2, x_coord, 0, 0);
8744 if (position == OVER_NOTHING && !really_over_nothing)
8745 position = OVER_TEXT;
8747 UPDATE_CACHE_RETURN;
8754 *row = Dynarr_length (dla) - 1;
8755 if (FRAME_WIN_P (f))
8757 int bot_elt = Dynarr_length (dla) - 1;
8761 struct display_line *dl = Dynarr_atp (dla, bot_elt);
8762 int adj_area = y_coord - (dl->ypos + dl->descent);
8766 XSETWINDOW (lwin, *w);
8767 default_face_height_and_width (lwin, 0, &defheight);
8769 *row += (adj_area / defheight);
8773 /* #### This should be checked out some more to determine what
8774 should really be going on. */
8775 if (!MARKERP ((*w)->start[CURRENT_DISP]))
8778 *closest = end_of_last_line_may_error (*w,
8779 marker_position ((*w)->start[CURRENT_DISP]));
8781 UPDATE_CACHE_RETURN;
8783 #undef UPDATE_CACHE_RETURN
8786 /***************************************************************************/
8788 /* Lisp functions */
8790 /***************************************************************************/
8792 DEFUN ("redisplay-echo-area", Fredisplay_echo_area, 0, 0, 0, /*
8793 Ensure that all minibuffers are correctly showing the echo area.
8797 Lisp_Object devcons, concons;
8799 DEVICE_LOOP_NO_BREAK (devcons, concons)
8801 struct device *d = XDEVICE (XCAR (devcons));
8802 Lisp_Object frmcons;
8804 DEVICE_FRAME_LOOP (frmcons, d)
8806 struct frame *f = XFRAME (XCAR (frmcons));
8808 if (FRAME_REPAINT_P (f) && FRAME_HAS_MINIBUF_P (f))
8810 Lisp_Object window = FRAME_MINIBUF_WINDOW (f);
8812 MAYBE_DEVMETH (d, frame_output_begin, (f));
8815 * If the frame size has changed, there may be random
8816 * chud on the screen left from previous messages
8817 * because redisplay_frame hasn't been called yet.
8818 * Clear the screen to get rid of the potential mess.
8820 if (f->echo_area_garbaged)
8822 MAYBE_DEVMETH (d, clear_frame, (f));
8823 f->echo_area_garbaged = 0;
8825 redisplay_window (window, 0);
8826 MAYBE_DEVMETH (d, frame_output_end, (f));
8828 call_redisplay_end_triggers (XWINDOW (window), 0);
8837 restore_disable_preemption_value (Lisp_Object value)
8839 disable_preemption = XINT (value);
8843 DEFUN ("redraw-frame", Fredraw_frame, 0, 2, 0, /*
8844 Clear frame FRAME and output again what is supposed to appear on it.
8845 FRAME defaults to the selected frame if omitted.
8846 Normally, redisplay is preempted as normal if input arrives. However,
8847 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8848 input and is guaranteed to proceed to completion.
8850 (frame, no_preempt))
8852 struct frame *f = decode_frame (frame);
8853 int count = specpdl_depth ();
8855 if (!NILP (no_preempt))
8857 record_unwind_protect (restore_disable_preemption_value,
8858 make_int (disable_preemption));
8859 disable_preemption++;
8863 redisplay_frame (f, 1);
8865 /* See the comment in Fredisplay_frame. */
8866 RESET_CHANGED_SET_FLAGS;
8868 return unbind_to (count, Qnil);
8871 DEFUN ("redisplay-frame", Fredisplay_frame, 0, 2, 0, /*
8872 Ensure that FRAME's contents are correctly displayed.
8873 This differs from `redraw-frame' in that it only redraws what needs to
8874 be updated, as opposed to unconditionally clearing and redrawing
8876 FRAME defaults to the selected frame if omitted.
8877 Normally, redisplay is preempted as normal if input arrives. However,
8878 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8879 input and is guaranteed to proceed to completion.
8881 (frame, no_preempt))
8883 struct frame *f = decode_frame (frame);
8884 int count = specpdl_depth ();
8886 if (!NILP (no_preempt))
8888 record_unwind_protect (restore_disable_preemption_value,
8889 make_int (disable_preemption));
8890 disable_preemption++;
8893 redisplay_frame (f, 1);
8895 /* If we don't reset the global redisplay flafs here, subsequent
8896 changes to the display will not get registered by redisplay
8897 because it thinks it already has registered changes. If you
8898 really knew what you were doing you could confuse redisplay by
8899 calling Fredisplay_frame while updating another frame. We assume
8900 that if you know what you are doing you will not be that
8902 RESET_CHANGED_SET_FLAGS;
8904 return unbind_to (count, Qnil);
8907 DEFUN ("redraw-device", Fredraw_device, 0, 2, 0, /*
8908 Clear device DEVICE and output again what is supposed to appear on it.
8909 DEVICE defaults to the selected device if omitted.
8910 Normally, redisplay is preempted as normal if input arrives. However,
8911 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8912 input and is guaranteed to proceed to completion.
8914 (device, no_preempt))
8916 struct device *d = decode_device (device);
8917 Lisp_Object frmcons;
8918 int count = specpdl_depth ();
8920 if (!NILP (no_preempt))
8922 record_unwind_protect (restore_disable_preemption_value,
8923 make_int (disable_preemption));
8924 disable_preemption++;
8927 DEVICE_FRAME_LOOP (frmcons, d)
8929 XFRAME (XCAR (frmcons))->clear = 1;
8931 redisplay_device (d, 0);
8933 /* See the comment in Fredisplay_frame. */
8934 RESET_CHANGED_SET_FLAGS;
8936 return unbind_to (count, Qnil);
8939 DEFUN ("redisplay-device", Fredisplay_device, 0, 2, 0, /*
8940 Ensure that DEVICE's contents are correctly displayed.
8941 This differs from `redraw-device' in that it only redraws what needs to
8942 be updated, as opposed to unconditionally clearing and redrawing
8944 DEVICE defaults to the selected device if omitted.
8945 Normally, redisplay is preempted as normal if input arrives. However,
8946 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8947 input and is guaranteed to proceed to completion.
8949 (device, no_preempt))
8951 struct device *d = decode_device (device);
8952 int count = specpdl_depth ();
8954 if (!NILP (no_preempt))
8956 record_unwind_protect (restore_disable_preemption_value,
8957 make_int (disable_preemption));
8958 disable_preemption++;
8961 redisplay_device (d, 0);
8963 /* See the comment in Fredisplay_frame. */
8964 RESET_CHANGED_SET_FLAGS;
8966 return unbind_to (count, Qnil);
8969 /* Big lie. Big lie. This will force all modelines to be updated
8970 regardless if the all flag is set or not. It remains in existence
8971 solely for backwards compatibility. */
8972 DEFUN ("redraw-modeline", Fredraw_modeline, 0, 1, 0, /*
8973 Force the modeline of the current buffer to be redisplayed.
8974 With optional non-nil ALL, force redisplay of all modelines.
8978 MARK_MODELINE_CHANGED;
8982 DEFUN ("force-cursor-redisplay", Fforce_cursor_redisplay, 0, 1, 0, /*
8983 Force an immediate update of the cursor on FRAME.
8984 FRAME defaults to the selected frame if omitted.
8988 redisplay_redraw_cursor (decode_frame (frame), 1);
8993 /***************************************************************************/
8995 /* Lisp-variable change triggers */
8997 /***************************************************************************/
9000 margin_width_changed_in_frame (Lisp_Object specifier, struct frame *f,
9003 /* Nothing to be done? */
9007 redisplay_variable_changed (Lisp_Object sym, Lisp_Object *val,
9008 Lisp_Object in_object, int flags)
9010 /* #### clip_changed should really be renamed something like
9011 global_redisplay_change. */
9016 /* This is called if the built-in glyphs have their properties
9019 redisplay_glyph_changed (Lisp_Object glyph, Lisp_Object property,
9022 if (WINDOWP (locale))
9024 MARK_FRAME_GLYPHS_CHANGED (XFRAME (WINDOW_FRAME (XWINDOW (locale))));
9026 else if (FRAMEP (locale))
9028 MARK_FRAME_GLYPHS_CHANGED (XFRAME (locale));
9030 else if (DEVICEP (locale))
9032 Lisp_Object frmcons;
9033 DEVICE_FRAME_LOOP (frmcons, XDEVICE (locale))
9034 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9036 else if (CONSOLEP (locale))
9038 Lisp_Object frmcons, devcons;
9039 CONSOLE_FRAME_LOOP_NO_BREAK (frmcons, devcons, XCONSOLE (locale))
9040 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9042 else /* global or buffer */
9044 Lisp_Object frmcons, devcons, concons;
9045 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
9046 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9051 text_cursor_visible_p_changed (Lisp_Object specifier, struct window *w,
9054 if (XFRAME (w->frame)->init_finished)
9055 Fforce_cursor_redisplay (w->frame);
9058 #ifdef MEMORY_USAGE_STATS
9061 /***************************************************************************/
9063 /* memory usage computation */
9065 /***************************************************************************/
9068 compute_rune_dynarr_usage (rune_dynarr *dyn, struct overhead_stats *ovstats)
9070 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9074 compute_display_block_dynarr_usage (display_block_dynarr *dyn,
9075 struct overhead_stats *ovstats)
9082 total = Dynarr_memory_usage (dyn, ovstats);
9083 for (i = 0; i < Dynarr_largest (dyn); i++)
9084 total += compute_rune_dynarr_usage (Dynarr_at (dyn, i).runes, ovstats);
9090 compute_glyph_block_dynarr_usage (glyph_block_dynarr *dyn,
9091 struct overhead_stats *ovstats)
9093 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9097 compute_display_line_dynarr_usage (display_line_dynarr *dyn,
9098 struct overhead_stats *ovstats)
9105 total = Dynarr_memory_usage (dyn, ovstats);
9106 for (i = 0; i < Dynarr_largest (dyn); i++)
9108 struct display_line *dl = &Dynarr_at (dyn, i);
9109 total += compute_display_block_dynarr_usage(dl->display_blocks, ovstats);
9110 total += compute_glyph_block_dynarr_usage (dl->left_glyphs, ovstats);
9111 total += compute_glyph_block_dynarr_usage (dl->right_glyphs, ovstats);
9118 compute_line_start_cache_dynarr_usage (line_start_cache_dynarr *dyn,
9119 struct overhead_stats *ovstats)
9121 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9124 #endif /* MEMORY_USAGE_STATS */
9127 /***************************************************************************/
9129 /* initialization */
9131 /***************************************************************************/
9134 init_redisplay (void)
9136 disable_preemption = 0;
9137 preemption_count = 0;
9138 max_preempts = INIT_MAX_PREEMPTS;
9144 if (!cmotion_display_lines)
9145 cmotion_display_lines = Dynarr_new (display_line);
9146 if (!mode_spec_bufbyte_string)
9147 mode_spec_bufbyte_string = Dynarr_new (Bufbyte);
9148 if (!formatted_string_extent_dynarr)
9149 formatted_string_extent_dynarr = Dynarr_new (EXTENT);
9150 if (!formatted_string_extent_start_dynarr)
9151 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount);
9152 if (!formatted_string_extent_end_dynarr)
9153 formatted_string_extent_end_dynarr = Dynarr_new (Bytecount);
9154 if (!internal_cache)
9155 internal_cache = Dynarr_new (line_start_cache);
9158 /* window system is nil when in -batch mode */
9159 if (!initialized || noninteractive)
9162 /* If the user wants to use a window system, we shouldn't bother
9163 initializing the terminal. This is especially important when the
9164 terminal is so dumb that emacs gives up before and doesn't bother
9165 using the window system.
9167 If the DISPLAY environment variable is set, try to use X, and die
9168 with an error message if that doesn't work. */
9170 #ifdef HAVE_X_WINDOWS
9171 if (!strcmp (display_use, "x"))
9173 /* Some stuff checks this way early. */
9174 Vwindow_system = Qx;
9175 Vinitial_window_system = Qx;
9178 #endif /* HAVE_X_WINDOWS */
9180 #ifdef HAVE_MS_WINDOWS
9181 if (!strcmp (display_use, "mswindows"))
9183 /* Some stuff checks this way early. */
9184 Vwindow_system = Qmswindows;
9185 Vinitial_window_system = Qmswindows;
9188 #endif /* HAVE_MS_WINDOWS */
9191 /* If no window system has been specified, try to use the terminal. */
9194 stderr_out ("XEmacs: standard input is not a tty\n");
9198 /* Look at the TERM variable */
9199 if (!getenv ("TERM"))
9201 stderr_out ("Please set the environment variable TERM; see tset(1).\n");
9205 Vinitial_window_system = Qtty;
9207 #else /* not HAVE_TTY */
9208 /* No DISPLAY specified, and no TTY support. */
9209 stderr_out ("XEmacs: Cannot open display.\n\
9210 Please set the environmental variable DISPLAY to an appropriate value.\n");
9217 syms_of_redisplay (void)
9219 defsymbol (&Qcursor_in_echo_area, "cursor-in-echo-area");
9220 #ifndef INHIBIT_REDISPLAY_HOOKS
9221 defsymbol (&Qpre_redisplay_hook, "pre-redisplay-hook");
9222 defsymbol (&Qpost_redisplay_hook, "post-redisplay-hook");
9223 #endif /* INHIBIT_REDISPLAY_HOOKS */
9224 defsymbol (&Qdisplay_warning_buffer, "display-warning-buffer");
9225 defsymbol (&Qbar_cursor, "bar-cursor");
9226 defsymbol (&Qredisplay_end_trigger_functions,
9227 "redisplay-end-trigger-functions");
9228 defsymbol (&Qtop_bottom, "top-bottom");
9229 defsymbol (&Qbuffer_list_changed_hook, "buffer-list-changed-hook");
9231 DEFSUBR (Fredisplay_echo_area);
9232 DEFSUBR (Fredraw_frame);
9233 DEFSUBR (Fredisplay_frame);
9234 DEFSUBR (Fredraw_device);
9235 DEFSUBR (Fredisplay_device);
9236 DEFSUBR (Fredraw_modeline);
9237 DEFSUBR (Fforce_cursor_redisplay);
9241 vars_of_redisplay (void)
9245 staticpro (&last_arrow_position);
9246 staticpro (&last_arrow_string);
9247 last_arrow_position = Qnil;
9248 last_arrow_string = Qnil;
9251 /* #### Probably temporary */
9252 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /*
9253 \(Temporary) Setting this will impact the performance of the internal
9256 cache_adjustment = 2;
9258 DEFVAR_INT_MAGIC ("pixel-vertical-clip-threshold", &vertical_clip /*
9259 Minimum pixel height for clipped bottom display line.
9260 A clipped line shorter than this won't be displayed.
9262 redisplay_variable_changed);
9265 DEFVAR_INT_MAGIC ("pixel-horizontal-clip-threshold", &horizontal_clip /*
9266 Minimum visible area for clipped glyphs at right boundary.
9267 Clipped glyphs shorter than this won't be displayed.
9268 Only pixmap glyph instances are currently allowed to be clipped.
9270 redisplay_variable_changed);
9271 horizontal_clip = 5;
9273 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string /*
9274 String displayed by modeline-format's "%m" specification.
9276 Vglobal_mode_string = Qnil;
9278 DEFVAR_LISP_MAGIC ("overlay-arrow-position", &Voverlay_arrow_position /*
9279 Marker for where to display an arrow on top of the buffer text.
9280 This must be the beginning of a line in order to work.
9281 See also `overlay-arrow-string'.
9283 redisplay_variable_changed);
9284 Voverlay_arrow_position = Qnil;
9286 DEFVAR_LISP_MAGIC ("overlay-arrow-string", &Voverlay_arrow_string /*
9287 String or glyph to display as an arrow. See also `overlay-arrow-position'.
9288 (Note that despite the name of this variable, it can be set to a glyph as
9291 redisplay_variable_changed);
9292 Voverlay_arrow_string = Qnil;
9294 DEFVAR_INT ("scroll-step", &scroll_step /*
9295 *The number of lines to try scrolling a window by when point moves out.
9296 If that fails to bring point back on frame, point is centered instead.
9297 If this is zero, point is always centered after it moves off screen.
9301 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively /*
9302 *Scroll up to this many lines, to bring point back on screen.
9304 scroll_conservatively = 0;
9306 DEFVAR_BOOL_MAGIC ("truncate-partial-width-windows",
9307 &truncate_partial_width_windows /*
9308 *Non-nil means truncate lines in all windows less than full frame wide.
9310 redisplay_variable_changed);
9311 truncate_partial_width_windows = 1;
9313 DEFVAR_LISP ("visible-bell", &Vvisible_bell /*
9314 *Non-nil substitutes a visual signal for the audible bell.
9316 Default behavior is to flash the whole screen. On some platforms,
9317 special effects are available using the following values:
9319 'display Flash the whole screen (ie, the default behavior).
9320 'top-bottom Flash only the top and bottom lines of the selected frame.
9322 When effects are unavailable on a platform, the visual bell is the
9323 default, whole screen. (Currently only X supports any special effects.)
9325 Vvisible_bell = Qnil;
9327 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter /*
9328 *Non-nil means no need to redraw entire frame after suspending.
9329 A non-nil value is useful if the terminal can automatically preserve
9330 Emacs's frame display when you reenter Emacs.
9331 It is up to you to set this variable if your terminal can do that.
9333 no_redraw_on_reenter = 0;
9335 DEFVAR_LISP ("window-system", &Vwindow_system /*
9336 A symbol naming the window-system under which Emacs is running,
9337 such as `x', or nil if emacs is running on an ordinary terminal.
9339 Do not use this variable, except for GNU Emacs compatibility, as it
9340 gives wrong values in a multi-device environment. Use `console-type'
9343 Vwindow_system = Qnil;
9345 /* #### Temporary shit until window-system is eliminated. */
9346 DEFVAR_CONST_LISP ("initial-window-system", &Vinitial_window_system /*
9349 Vinitial_window_system = Qnil;
9351 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area /*
9352 Non-nil means put cursor in minibuffer, at end of any message there.
9354 cursor_in_echo_area = 0;
9356 /* #### Shouldn't this be generalized as follows:
9358 if nil, use block cursor.
9359 if a number, use a bar cursor of that width.
9360 Otherwise, use a 1-pixel bar cursor.
9362 #### Or better yet, this variable should be trashed entirely
9363 (use a Lisp-magic variable to maintain compatibility)
9364 and a specifier `cursor-shape' added, which allows a block
9365 cursor, a bar cursor, a flashing block or bar cursor,
9366 maybe a caret cursor, etc. */
9368 DEFVAR_LISP ("bar-cursor", &Vbar_cursor /*
9369 Use vertical bar cursor if non-nil. If t width is 1 pixel, otherwise 2.
9373 #ifndef INHIBIT_REDISPLAY_HOOKS
9374 xxDEFVAR_LISP ("pre-redisplay-hook", &Vpre_redisplay_hook /*
9375 Function or functions to run before every redisplay.
9377 Vpre_redisplay_hook = Qnil;
9379 xxDEFVAR_LISP ("post-redisplay-hook", &Vpost_redisplay_hook /*
9380 Function or functions to run after every redisplay.
9382 Vpost_redisplay_hook = Qnil;
9383 #endif /* INHIBIT_REDISPLAY_HOOKS */
9385 DEFVAR_LISP ("buffer-list-changed-hook", &Vbuffer_list_changed_hook /*
9386 Function or functions to call when a frame's buffer list has changed.
9387 This is called during redisplay, before redisplaying each frame.
9388 Functions on this hook are called with one argument, the frame.
9390 Vbuffer_list_changed_hook = Qnil;
9392 DEFVAR_INT ("display-warning-tick", &display_warning_tick /*
9393 Bump this to tell the C code to call `display-warning-buffer'
9394 at next redisplay. You should not normally change this; the function
9395 `display-warning' automatically does this at appropriate times.
9397 display_warning_tick = 0;
9399 DEFVAR_BOOL ("inhibit-warning-display", &inhibit_warning_display /*
9400 Non-nil means inhibit display of warning messages.
9401 You should *bind* this, not set it. Any pending warning messages
9402 will be displayed when the binding no longer applies.
9404 /* reset to 0 by startup.el after the splash screen has displayed.
9405 This way, the warnings don't obliterate the splash screen. */
9406 inhibit_warning_display = 1;
9408 DEFVAR_LISP ("window-size-change-functions",
9409 &Vwindow_size_change_functions /*
9410 Not currently implemented.
9411 Functions called before redisplay, if window sizes have changed.
9412 The value should be a list of functions that take one argument.
9413 Just before redisplay, for each frame, if any of its windows have changed
9414 size since the last redisplay, or have been split or deleted,
9415 all the functions in the list are called, with the frame as argument.
9417 Vwindow_size_change_functions = Qnil;
9419 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions /*
9420 Not currently implemented.
9421 Functions to call before redisplaying a window with scrolling.
9422 Each function is called with two arguments, the window
9423 and its new display-start position. Note that the value of `window-end'
9424 is not valid when these functions are called.
9426 Vwindow_scroll_functions = Qnil;
9428 DEFVAR_LISP ("redisplay-end-trigger-functions",
9429 &Vredisplay_end_trigger_functions /*
9430 See `set-window-redisplay-end-trigger'.
9432 Vredisplay_end_trigger_functions = Qnil;
9434 DEFVAR_BOOL ("column-number-start-at-one", &column_number_start_at_one /*
9435 *Non-nil means column display number starts at 1.
9437 column_number_start_at_one = 0;
9441 specifier_vars_of_redisplay (void)
9443 DEFVAR_SPECIFIER ("left-margin-width", &Vleft_margin_width /*
9444 *Width of left margin.
9445 This is a specifier; use `set-specifier' to change it.
9447 Vleft_margin_width = Fmake_specifier (Qnatnum);
9448 set_specifier_fallback (Vleft_margin_width, list1 (Fcons (Qnil, Qzero)));
9449 set_specifier_caching (Vleft_margin_width,
9450 offsetof (struct window, left_margin_width),
9451 some_window_value_changed,
9452 offsetof (struct frame, left_margin_width),
9453 margin_width_changed_in_frame);
9455 DEFVAR_SPECIFIER ("right-margin-width", &Vright_margin_width /*
9456 *Width of right margin.
9457 This is a specifier; use `set-specifier' to change it.
9459 Vright_margin_width = Fmake_specifier (Qnatnum);
9460 set_specifier_fallback (Vright_margin_width, list1 (Fcons (Qnil, Qzero)));
9461 set_specifier_caching (Vright_margin_width,
9462 offsetof (struct window, right_margin_width),
9463 some_window_value_changed,
9464 offsetof (struct frame, right_margin_width),
9465 margin_width_changed_in_frame);
9467 DEFVAR_SPECIFIER ("minimum-line-ascent", &Vminimum_line_ascent /*
9468 *Minimum ascent height of lines.
9469 This is a specifier; use `set-specifier' to change it.
9471 Vminimum_line_ascent = Fmake_specifier (Qnatnum);
9472 set_specifier_fallback (Vminimum_line_ascent, list1 (Fcons (Qnil, Qzero)));
9473 set_specifier_caching (Vminimum_line_ascent,
9474 offsetof (struct window, minimum_line_ascent),
9475 some_window_value_changed,
9478 DEFVAR_SPECIFIER ("minimum-line-descent", &Vminimum_line_descent /*
9479 *Minimum descent height of lines.
9480 This is a specifier; use `set-specifier' to change it.
9482 Vminimum_line_descent = Fmake_specifier (Qnatnum);
9483 set_specifier_fallback (Vminimum_line_descent, list1 (Fcons (Qnil, Qzero)));
9484 set_specifier_caching (Vminimum_line_descent,
9485 offsetof (struct window, minimum_line_descent),
9486 some_window_value_changed,
9489 DEFVAR_SPECIFIER ("use-left-overflow", &Vuse_left_overflow /*
9490 *Non-nil means use the left outside margin as extra whitespace when
9491 displaying 'whitespace or 'inside-margin glyphs.
9492 This is a specifier; use `set-specifier' to change it.
9494 Vuse_left_overflow = Fmake_specifier (Qboolean);
9495 set_specifier_fallback (Vuse_left_overflow, list1 (Fcons (Qnil, Qnil)));
9496 set_specifier_caching (Vuse_left_overflow,
9497 offsetof (struct window, use_left_overflow),
9498 some_window_value_changed,
9501 DEFVAR_SPECIFIER ("use-right-overflow", &Vuse_right_overflow /*
9502 *Non-nil means use the right outside margin as extra whitespace when
9503 displaying 'whitespace or 'inside-margin glyphs.
9504 This is a specifier; use `set-specifier' to change it.
9506 Vuse_right_overflow = Fmake_specifier (Qboolean);
9507 set_specifier_fallback (Vuse_right_overflow, list1 (Fcons (Qnil, Qnil)));
9508 set_specifier_caching (Vuse_right_overflow,
9509 offsetof (struct window, use_right_overflow),
9510 some_window_value_changed,
9513 DEFVAR_SPECIFIER ("text-cursor-visible-p", &Vtext_cursor_visible_p /*
9514 *Non-nil means the text cursor is visible (this is usually the case).
9515 This is a specifier; use `set-specifier' to change it.
9517 Vtext_cursor_visible_p = Fmake_specifier (Qboolean);
9518 set_specifier_fallback (Vtext_cursor_visible_p, list1 (Fcons (Qnil, Qt)));
9519 set_specifier_caching (Vtext_cursor_visible_p,
9520 offsetof (struct window, text_cursor_visible_p),
9521 text_cursor_visible_p_changed,