1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1994, 1995, 1996 Board of Trustees, University of Illinois.
3 Copyright (C) 1995 Free Software Foundation, Inc.
4 Copyright (C) 1995, 1996 Ben Wing.
5 Copyright (C) 1995 Sun Microsystems, Inc.
6 Copyright (C) 1996 Chuck Thompson.
8 This file is part of XEmacs.
10 XEmacs is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
15 XEmacs is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with XEmacs; see the file COPYING. If not, write to
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
25 /* Synched up with: Not in FSF. */
27 /* Author: Chuck Thompson */
29 /* Fixed up by Ben Wing for Mule */
31 /* This file has been Mule-ized. */
33 /*****************************************************************************
34 The Golden Rules of Redisplay
36 First: It Is Better To Be Correct Than Fast
37 Second: Thou Shalt Not Run Elisp From Within Redisplay
38 Third: It Is Better To Be Fast Than Not To Be
39 ****************************************************************************/
58 #include "redisplay.h"
61 #include "line-number.h"
63 #include "file-coding.h"
69 #include "console-tty.h"
72 /* Note: We have to be careful throughout this code to properly handle
73 and differentiate between Bufbytes and Emchars.
75 Since strings are generally composed of Bufbytes, I've taken the tack
76 that any contiguous set of Bufbytes is called a "string", while
77 any contiguous set of Emchars is called an "array". */
79 /* Return value to indicate a failure by an add_*_rune routine to add
80 a rune, but no propagation information needs to be returned. */
81 #define ADD_FAILED (prop_block_dynarr *) 1
83 #define BEGIN_GLYPHS 0
86 #define RIGHT_GLYPHS 3
88 #define VERTICAL_CLIP(w, display) \
89 ((WINDOW_TTY_P (w) | (!display && scroll_on_clipped_lines)) \
93 /* The following structures are completely private to redisplay.c so
94 we put them here instead of in a header file, for modularity. */
96 /* NOTE: Bytinds not Bufpos's in this structure. */
98 typedef struct position_redisplay_data_type
100 /* This information is normally filled in by the create_*_block
101 routines and is used by the add_*_rune routines. */
103 /* if we are working with strings rather than buffers we need a
104 handle to the string */
107 struct display_block *db;
108 struct display_line *dl;
109 Emchar ch; /* Character that is to be added. This is
110 used to communicate this information to
111 add_emchar_rune(). */
112 Lisp_Object last_charset; /* The charset of the previous character.
113 Used to optimize some lookups -- we
114 only have to do some things when
115 the charset changes. */
116 face_index last_findex; /* The face index of the previous character.
117 Needed to ensure the validity of the
118 last_charset optimization. */
120 int last_char_width; /* The width of the previous character. */
121 int font_is_bogus; /* If true, it means we couldn't instantiate
122 the font for this charset, so we substitute
123 ~'s from the ASCII charset. */
128 int blank_width; /* Width of the blank that is to be added.
129 This is used to communicate this information
132 This is also used rather cheesily to
133 communicate the width of the eol-cursor-size
134 blank that exists at the end of the line.
135 add_emchar_rune() is called cheesily with
136 the non-printing char '\n', which is stuck
137 in the output routines with its width being
139 Bytind bi_cursor_bufpos;/* This stores the buffer position of the cursor. */
140 unsigned int cursor_type :3;
141 int cursor_x; /* rune block cursor is at */
142 int start_col; /* Number of character columns (each column has
143 a width of the default char width) that still
144 need to be skipped. This is used for horizontal
145 scrolling, where a certain number of columns
146 (those off the left side of the screen) need
147 to be skipped before anything is displayed. */
148 Bytind bi_start_col_enabled;
149 int start_col_xoffset; /* Number of pixels that still need to
150 be skipped. This is used for
151 horizontal scrolling of glyphs, where we want
152 to be able to scroll over part of the glyph. */
154 int hscroll_glyph_width_adjust; /* how much the width of the hscroll
155 glyph differs from space_width (w).
156 0 if no hscroll glyph was used,
157 i.e. the window is not scrolled
158 horizontally. Used in tab
161 /* Information about the face the text should be displayed in and
162 any begin-glyphs and end-glyphs. */
163 struct extent_fragment *ef;
166 /* The height of a pixmap may either be predetermined if the user
167 has set a baseline value, or it may be dependent on whatever the
168 line ascent and descent values end up being, based just on font
169 information. In the first case we can immediately update the
170 values, thus their inclusion here. In the last case we cannot
171 determine the actual contribution to the line height until we
172 have finished laying out all text on the line. Thus we propagate
173 the max height of such pixmaps and do a final calculation after
174 all text has been added to the line. */
177 int max_pixmap_height;
179 Lisp_Object result_str; /* String where we put the result of
180 generating a formatted string in the modeline. */
181 int is_modeline; /* Non-zero if we're generating the modeline. */
182 Charcount modeline_charpos; /* Number of chars used in result_str so far;
183 corresponds to bytepos. */
184 Bytecount bytepos; /* Number of bytes used in result_str so far.
185 We don't actually copy the bytes into result_str
186 until the end because we don't know how big the
187 string is going to be until then. */
198 /* Data that should be propagated to the next line. Either a single
199 Emchar or a string of Bufbyte's.
201 The actual data that is propagated ends up as a Dynarr of these
204 #### It's unclean that both Emchars and Bufbytes are here.
207 typedef struct prop_block prop_block;
217 Bytecount len; /* length of the string. */
223 Bytind bi_cursor_bufpos; /* NOTE: is in Bytinds */
224 unsigned int cursor_type :3;
237 Dynarr_declare (prop_block);
241 static Charcount generate_fstring_runes (struct window *w, pos_data *data,
242 Charcount pos, Charcount min_pos,
243 Charcount max_pos, Lisp_Object elt,
244 int depth, int max_pixsize,
245 face_index findex, int type,
247 Lisp_Object cur_ext);
248 static prop_block_dynarr *add_glyph_rune (pos_data *data,
249 struct glyph_block *gb,
250 int pos_type, int allow_cursor,
251 struct glyph_cachel *cachel);
252 static Bytind create_text_block (struct window *w, struct display_line *dl,
253 Bytind bi_start_pos, prop_block_dynarr **prop,
255 static int create_overlay_glyph_block (struct window *w,
256 struct display_line *dl);
257 static void create_left_glyph_block (struct window *w,
258 struct display_line *dl,
260 static void create_right_glyph_block (struct window *w,
261 struct display_line *dl);
262 static void redisplay_windows (Lisp_Object window, int skip_selected);
263 static void decode_mode_spec (struct window *w, Emchar spec, int type);
264 static void free_display_line (struct display_line *dl);
265 static void update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
266 Bufpos point, int no_regen);
267 static int point_visible (struct window *w, Bufpos point, int type);
269 /* This used to be 10 but 30 seems to give much better performance. */
270 #define INIT_MAX_PREEMPTS 30
271 static int max_preempts;
273 #define REDISPLAY_PREEMPTION_CHECK \
276 (!disable_preemption && \
277 ((preemption_count < max_preempts) || !NILP (Vexecuting_macro)) && \
278 (!INTERACTIVE || detect_input_pending ()))))
281 * Redisplay global variables.
284 /* We need a third set of display structures for the cursor motion
285 routines. We used to just give each window a third set. However,
286 we always fully regenerate the structures when needed so there
287 isn't any reason we need more than a single set. */
288 display_line_dynarr *cmotion_display_lines;
290 /* We store the extents that we need to generate in a Dynarr and then
291 frob them all on at the end of generating the string. We do it
292 this way rather than adding them as we generate the string because
293 we don't store the text into the resulting string until we're done
294 (to avoid having to resize the string multiple times), and we don't
295 want to go around adding extents to a string when the extents might
296 stretch off the end of the string. */
297 static EXTENT_dynarr *formatted_string_extent_dynarr;
298 static Bytecount_dynarr *formatted_string_extent_start_dynarr;
299 static Bytecount_dynarr *formatted_string_extent_end_dynarr;
302 /* #### probably temporary */
303 Fixnum cache_adjustment;
305 /* This holds a string representing the text corresponding to a single
307 static Bufbyte_dynarr *mode_spec_bufbyte_string;
309 int in_display; /* 1 if in redisplay. */
311 int disable_preemption; /* Used for debugging redisplay and for
314 /* We only allow max_preempts preemptions before we force a redisplay. */
315 static int preemption_count;
317 /* Minimum pixel height of clipped bottom display line. */
318 Fixnum vertical_clip;
320 /* Minimum visible pixel width of clipped glyphs at right margin. */
321 Fixnum horizontal_clip;
323 /* Nonzero means reading single-character input with prompt
324 so put cursor on minibuffer after the prompt. */
325 int cursor_in_echo_area;
326 Lisp_Object Qcursor_in_echo_area;
328 /* Nonzero means truncate lines in all windows less wide than the frame */
329 int truncate_partial_width_windows;
331 /* non-nil if a buffer has changed since the last time redisplay completed */
333 int buffers_changed_set;
335 /* non-nil if hscroll has changed somewhere or a buffer has been
336 narrowed or widened */
338 int clip_changed_set;
340 /* non-nil if any extent has changed since the last time redisplay completed */
342 int extents_changed_set;
344 /* non-nil if any face has changed since the last time redisplay completed */
347 /* Nonzero means some frames have been marked as garbaged */
350 /* non-zero if any of the builtin display glyphs (continuation,
351 hscroll, control-arrow, etc) is in need of updating
354 int glyphs_changed_set;
356 /* non-zero if any subwindow has been deleted. */
357 int subwindows_changed;
358 int subwindows_changed_set;
360 /* non-zero if any displayed subwindow is in need of updating
362 int subwindows_state_changed;
363 int subwindows_state_changed_set;
365 /* This variable is 1 if the icon has to be updated.
366 It is set to 1 when `frame-icon-glyph' changes. */
368 int icon_changed_set;
370 /* This variable is 1 if the menubar widget has to be updated.
371 It is set to 1 by set-menubar-dirty-flag and cleared when the widget
374 int menubar_changed_set;
376 /* true iff we should redraw the modelines on the next redisplay */
377 int modeline_changed;
378 int modeline_changed_set;
380 /* non-nil if point has changed in some buffer since the last time
381 redisplay completed */
383 int point_changed_set;
385 /* non-nil if some frame has changed its size */
388 /* non-nil if some device has signaled that it wants to change size */
389 int asynch_device_change_pending;
391 /* non-nil if any toolbar has changed */
393 int toolbar_changed_set;
395 /* non-nil if any gutter has changed */
397 int gutter_changed_set;
399 /* non-nil if any window has changed since the last time redisplay completed */
402 /* non-nil if any frame's window structure has changed since the last
403 time redisplay completed */
404 int windows_structure_changed;
406 /* If non-nil, use vertical bar cursor. */
407 Lisp_Object Vbar_cursor;
408 Lisp_Object Qbar_cursor;
410 Lisp_Object Vvisible_bell; /* If true and the terminal will support it
411 then the frame will flash instead of
412 beeping when an error occurs */
414 /* Nonzero means no need to redraw the entire frame on resuming
415 a suspended Emacs. This is useful on terminals with multiple pages,
416 where one page is used for Emacs and another for all else. */
417 int no_redraw_on_reenter;
419 Lisp_Object Vwindow_system; /* nil or a symbol naming the window system
420 under which emacs is running
421 ('x is the only current possibility) */
422 Lisp_Object Vinitial_window_system;
424 Lisp_Object Vglobal_mode_string;
426 /* The number of lines scroll a window by when point leaves the window; if
427 it is <=0 then point is centered in the window */
430 /* Scroll up to this many lines, to bring point back on screen. */
431 Fixnum scroll_conservatively;
433 /* Marker for where to display an arrow on top of the buffer text. */
434 Lisp_Object Voverlay_arrow_position;
435 /* String to display for the arrow. */
436 Lisp_Object Voverlay_arrow_string;
438 Lisp_Object Vwindow_size_change_functions;
439 Lisp_Object Vwindow_scroll_functions;
440 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
442 Lisp_Object Qbuffer_list_changed_hook, Vbuffer_list_changed_hook;
445 #define INHIBIT_REDISPLAY_HOOKS /* #### Until we've thought about
447 #ifndef INHIBIT_REDISPLAY_HOOKS
448 /* #### Chuck says: I think this needs more thought.
449 Think about this for 19.14. */
450 Lisp_Object Vpre_redisplay_hook, Vpost_redisplay_hook;
451 Lisp_Object Qpre_redisplay_hook, Qpost_redisplay_hook;
452 #endif /* INHIBIT_REDISPLAY_HOOKS */
454 static Fixnum last_display_warning_tick;
455 static Fixnum display_warning_tick;
456 Lisp_Object Qdisplay_warning_buffer;
457 int inhibit_warning_display;
459 Lisp_Object Vleft_margin_width, Vright_margin_width;
460 Lisp_Object Vminimum_line_ascent, Vminimum_line_descent;
461 Lisp_Object Vuse_left_overflow, Vuse_right_overflow;
462 Lisp_Object Vtext_cursor_visible_p;
464 int column_number_start_at_one;
466 Lisp_Object Qtop_bottom;
468 #define WINDOW_SCROLLED(w) ((w)->hscroll > 0 || (w)->left_xoffset)
471 /***************************************************************************/
473 /* low-level interfaces onto device routines */
475 /***************************************************************************/
478 redisplay_text_width_charc_string (struct window *w, int findex,
479 Charc *str, Charcount len)
481 Charset_ID charsets[NUM_LEADING_BYTES];
484 find_charsets_in_charc_string (charsets, str, len);
485 XSETWINDOW (window, w);
486 ensure_face_cachel_complete (WINDOW_FACE_CACHEL (w, findex), window,
488 return DEVMETH (XDEVICE (FRAME_DEVICE (XFRAME (WINDOW_FRAME (w)))),
489 text_width, (XFRAME (WINDOW_FRAME (w)),
490 WINDOW_FACE_CACHEL (w, findex), str, len));
493 static Charc_dynarr *rtw_charc_dynarr;
496 redisplay_text_width_string (struct window *w, int findex,
497 Bufbyte *nonreloc, Lisp_Object reloc,
498 Bytecount offset, Bytecount len)
500 if (!rtw_charc_dynarr)
501 rtw_charc_dynarr = Dynarr_new (Charc);
502 Dynarr_reset (rtw_charc_dynarr);
504 fixup_internal_substring (nonreloc, reloc, offset, &len);
506 nonreloc = XSTRING_DATA (reloc);
507 convert_bufbyte_string_into_charc_dynarr (nonreloc, len, rtw_charc_dynarr);
508 return redisplay_text_width_charc_string
509 (w, findex, Dynarr_atp (rtw_charc_dynarr, 0),
510 Dynarr_length (rtw_charc_dynarr));
514 redisplay_frame_text_width_string (struct frame *f, Lisp_Object face,
515 Bufbyte *nonreloc, Lisp_Object reloc,
516 Bytecount offset, Bytecount len)
518 Charset_ID charsets[NUM_LEADING_BYTES];
520 struct face_cachel cachel;
522 if (!rtw_charc_dynarr)
523 rtw_charc_dynarr = Dynarr_new (Charc);
524 Dynarr_reset (rtw_charc_dynarr);
526 fixup_internal_substring (nonreloc, reloc, offset, &len);
528 nonreloc = XSTRING_DATA (reloc);
529 convert_bufbyte_string_into_charc_dynarr (nonreloc, len, rtw_charc_dynarr);
530 find_charsets_in_bufbyte_string (charsets, nonreloc, len);
531 reset_face_cachel (&cachel);
533 XSETFRAME (frame, f);
534 ensure_face_cachel_complete (&cachel, frame, charsets);
535 return DEVMETH (XDEVICE (FRAME_DEVICE (f)),
536 text_width, (f, &cachel, Dynarr_atp (rtw_charc_dynarr, 0),
537 Dynarr_length (rtw_charc_dynarr)));
540 /* Return the display block from DL of the given TYPE. A display line
541 can have only one display block of each possible type. If DL does
542 not have a block of type TYPE, one will be created and added to DL. */
544 struct display_block *
545 get_display_block_from_line (struct display_line *dl, enum display_type type)
548 struct display_block db;
550 /* Check if this display line already has a block of the desired type and
552 if (dl->display_blocks)
554 for (elt = 0; elt < Dynarr_length (dl->display_blocks); elt++)
556 if (Dynarr_at (dl->display_blocks, elt).type == type)
557 return Dynarr_atp (dl->display_blocks, elt);
560 /* There isn't an active block of the desired type, but there
561 might still be allocated blocks we need to reuse. */
562 if (elt < Dynarr_largest (dl->display_blocks))
564 struct display_block *dbp = Dynarr_atp (dl->display_blocks, elt);
566 /* 'add' the block to the list */
567 Dynarr_increment (dl->display_blocks);
569 /* initialize and return */
576 /* This line doesn't have any display blocks, so initialize the display
578 dl->display_blocks = Dynarr_new (display_block);
581 /* The line doesn't have a block of the desired type so go ahead and create
582 one and add it to the line. */
585 db.runes = Dynarr_new (rune);
586 Dynarr_add (dl->display_blocks, db);
588 /* Return the newly added display block. */
589 elt = Dynarr_length (dl->display_blocks) - 1;
591 return Dynarr_atp (dl->display_blocks, elt);
595 tab_char_width (struct window *w)
597 struct buffer *b = XBUFFER (w->buffer);
598 int char_tab_width = XINT (b->tab_width);
600 if (char_tab_width <= 0 || char_tab_width > 1000) char_tab_width = 8;
602 return char_tab_width;
606 space_width (struct window *w)
608 /* While tabs are traditional composed of spaces, for variable-width
609 fonts the space character tends to give too narrow a value. So
610 we use 'n' instead. Except that we don't. We use the default
611 character width for the default face. If this is actually
612 defined by the font then it is probably the best thing to
613 actually use. If it isn't, we have assumed it is 'n' and have
614 already calculated its width. Thus we can avoid a call to
615 XTextWidth on X frames by just querying the default width. */
616 return XFONT_INSTANCE
617 (WINDOW_FACE_CACHEL_FONT (w, DEFAULT_INDEX, Vcharset_ascii))->width;
621 tab_pix_width (struct window *w)
623 return space_width (w) * tab_char_width (w);
626 /* Given a pixel position in a window, return the pixel location of
627 the next tabstop. Tabs are calculated from the left window edge in
628 terms of spaces displayed in the default face. Formerly the space
629 width was determined using the currently active face. That method
630 leads to tabstops which do not line up. */
633 next_tab_position (struct window *w, int start_pixpos, int left_pixpos)
635 int n_pos = left_pixpos;
636 int pix_tab_width = tab_pix_width (w);
638 /* Adjust n_pos for any hscrolling which has happened. */
639 if (WINDOW_SCROLLED (w))
640 n_pos -= space_width (w) * (w->hscroll - 1) + w->left_xoffset;
642 while (n_pos <= start_pixpos)
643 n_pos += pix_tab_width;
648 /* For the given window, calculate the outside and margin boundaries for a
649 display line. The whitespace boundaries must be calculated by the text
653 calculate_display_line_boundaries (struct window *w, int modeline)
655 layout_bounds bounds;
657 /* Set the outermost boundaries which are the boundaries of the
658 window itself minus the gutters (and minus the scrollbars if this
659 is for the modeline). */
662 bounds.left_out = WINDOW_TEXT_LEFT (w);
663 bounds.right_out = WINDOW_TEXT_RIGHT (w);
667 bounds.left_out = WINDOW_MODELINE_LEFT (w);
668 bounds.right_out = WINDOW_MODELINE_RIGHT (w);
671 /* The inner boundaries mark where the glyph margins are located. */
672 bounds.left_in = bounds.left_out + window_left_margin_width (w);
673 bounds.right_in = bounds.right_out - window_right_margin_width (w);
675 /* We cannot fully calculate the whitespace boundaries as they
676 depend on the contents of the line being displayed. */
677 bounds.left_white = bounds.left_in;
678 bounds.right_white = bounds.right_in;
683 /* Given a display line and a starting position, ensure that the
684 contents of the display line accurately represent the visual
685 representation of the buffer contents starting from the given
686 position when displayed in the given window. The display line ends
687 when the contents of the line reach the right boundary of the given
691 generate_display_line (struct window *w, struct display_line *dl, int bounds,
692 Bufpos start_pos, prop_block_dynarr **prop,
697 struct buffer *b = XBUFFER (WINDOW_BUFFER (w));
699 /* If our caller hasn't already set the boundaries, then do so now. */
701 dl->bounds = calculate_display_line_boundaries (w, 0);
703 /* Reset what this line is using. */
704 if (dl->display_blocks)
705 Dynarr_reset (dl->display_blocks);
708 Dynarr_free (dl->left_glyphs);
711 if (dl->right_glyphs)
713 Dynarr_free (dl->right_glyphs);
714 dl->right_glyphs = 0;
717 /* We aren't generating a modeline at the moment. */
720 /* Create a display block for the text region of the line. */
722 /* #### urk urk urk!!! Chuck fix this shit! */
723 Bytind hacked_up_bytind =
724 create_text_block (w, dl, bufpos_to_bytind (b, start_pos),
726 if (hacked_up_bytind > BI_BUF_ZV (b))
727 ret_bufpos = BUF_ZV (b) + 1;
729 ret_bufpos = bytind_to_bufpos (b, hacked_up_bytind);
731 dl->bufpos = start_pos;
732 if (dl->end_bufpos < dl->bufpos)
733 dl->end_bufpos = dl->bufpos;
735 if (MARKERP (Voverlay_arrow_position)
736 && EQ (w->buffer, Fmarker_buffer (Voverlay_arrow_position))
737 && start_pos == marker_position (Voverlay_arrow_position)
738 && (STRINGP (Voverlay_arrow_string)
739 || GLYPHP (Voverlay_arrow_string)))
741 overlay_width = create_overlay_glyph_block (w, dl);
746 /* If there are left glyphs associated with any character in the
747 text block, then create a display block to handle them. */
748 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
749 create_left_glyph_block (w, dl, overlay_width);
751 /* If there are right glyphs associated with any character in the
752 text block, then create a display block to handle them. */
753 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
754 create_right_glyph_block (w, dl);
756 /* In the future additional types of display blocks may be generated
759 w->last_redisplay_pos = ret_bufpos;
764 /* Adds an hscroll glyph to a display block. If this is called, then
765 the block had better be empty.
767 Yes, there are multiple places where this function is called but
768 that is the way it has to be. Each calling function has to deal
769 with bi_start_col_enabled a little differently depending on the
770 object being worked with. */
772 static prop_block_dynarr *
773 add_hscroll_rune (pos_data *data)
775 struct glyph_block gb;
776 prop_block_dynarr *retval;
777 Bytind bi_old_cursor_bufpos = data->bi_cursor_bufpos;
778 unsigned int old_cursor_type = data->cursor_type;
779 Bytind bi_old_bufpos = data->bi_bufpos;
781 if (data->cursor_type == CURSOR_ON
782 && data->bi_cursor_bufpos >= data->bi_start_col_enabled
783 && data->bi_cursor_bufpos <= data->bi_bufpos)
785 data->bi_cursor_bufpos = data->bi_start_col_enabled;
789 data->cursor_type = NO_CURSOR;
792 data->bi_endpos = data->bi_bufpos;
793 data->bi_bufpos = data->bi_start_col_enabled;
796 gb.glyph = Vhscroll_glyph;
798 int oldpixpos = data->pixpos;
799 retval = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0,
800 GLYPH_CACHEL (XWINDOW (data->window),
801 HSCROLL_GLYPH_INDEX));
802 data->hscroll_glyph_width_adjust =
803 data->pixpos - oldpixpos - space_width (XWINDOW (data->window));
806 data->bi_cursor_bufpos = bi_old_cursor_bufpos;
807 data->cursor_type = old_cursor_type;
808 data->bi_bufpos = bi_old_bufpos;
810 data->bi_start_col_enabled = 0;
814 /* Adds a character rune to a display block. If there is not enough
815 room to fit the rune on the display block (as determined by the
816 MAX_PIXPOS) then it adds nothing and returns ADD_FAILED. */
818 static prop_block_dynarr *
819 add_emchar_rune (pos_data *data)
821 struct rune rb, *crb;
833 if (data->bi_start_col_enabled)
835 return add_hscroll_rune (data);
838 if (data->ch == '\n')
840 char_glyph = ASCII_TO_CHARC ('\n');
841 data->font_is_bogus = 0;
842 /* Cheesy end-of-line pseudo-character. */
843 width = data->blank_width;
849 char_glyph = CHAR_TO_CHARC (data->ch);
850 charset = CHARC_CHARSET (char_glyph);
851 if (!EQ (charset, data->last_charset) ||
852 data->findex != data->last_findex)
854 /* OK, we need to do things the hard way. */
855 struct window *w = XWINDOW (data->window);
856 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, data->findex);
857 Lisp_Object font_instance =
858 ensure_face_cachel_contains_charset (cachel, data->window,
860 Lisp_Font_Instance *fi;
862 if (EQ (font_instance, Vthe_null_font_instance))
864 font_instance = FACE_CACHEL_FONT (cachel, Vcharset_ascii);
865 data->font_is_bogus = 1;
868 data->font_is_bogus = 0;
870 fi = XFONT_INSTANCE (font_instance);
871 if (!fi->proportional_p)
872 /* sweetness and light. */
873 data->last_char_width = fi->width;
875 data->last_char_width = -1;
876 data->new_ascent = max (data->new_ascent, (int) fi->ascent);
877 data->new_descent = max (data->new_descent, (int) fi->descent);
878 data->last_charset = charset;
879 data->last_findex = data->findex;
882 width = data->last_char_width;
885 /* bummer. Proportional fonts. */
886 width = redisplay_text_width_charc_string (XWINDOW (data->window),
892 if (data->max_pixpos != -1 && (data->pixpos + width > data->max_pixpos))
897 if (Dynarr_length (data->db->runes) < Dynarr_largest (data->db->runes))
899 crb = Dynarr_atp (data->db->runes, Dynarr_length (data->db->runes));
908 crb->findex = data->findex;
909 crb->xpos = data->pixpos;
913 if (NILP (data->string))
915 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
919 bytecount_to_charcount (XSTRING_DATA (data->string),
922 else if (data->is_modeline)
923 crb->bufpos = data->modeline_charpos;
925 /* Text but not in buffer */
927 crb->type = RUNE_CHAR;
928 crb->object.cglyph = data->font_is_bogus
929 ? ASCII_TO_CHARC ('~')
933 if (data->cursor_type == CURSOR_ON)
935 if (data->bi_bufpos == data->bi_cursor_bufpos)
937 crb->cursor_type = CURSOR_ON;
938 data->cursor_x = Dynarr_length (data->db->runes);
941 crb->cursor_type = CURSOR_OFF;
943 else if (data->cursor_type == NEXT_CURSOR)
945 crb->cursor_type = CURSOR_ON;
946 data->cursor_x = Dynarr_length (data->db->runes);
947 data->cursor_type = NO_CURSOR;
949 else if (data->cursor_type == IGNORE_CURSOR)
950 crb->cursor_type = IGNORE_CURSOR;
952 crb->cursor_type = CURSOR_OFF;
955 Dynarr_add (data->db->runes, *crb);
957 Dynarr_increment (data->db->runes);
959 data->pixpos += width;
964 /* Given a string C_STRING of length C_LENGTH, call add_emchar_rune
965 for each character in the string. Propagate any left-over data
966 unless NO_PROP is non-zero. */
968 static prop_block_dynarr *
969 add_bufbyte_string_runes (pos_data *data, Bufbyte *c_string,
970 Bytecount c_length, int no_prop)
972 Bufbyte *pos, *end = c_string + c_length;
973 prop_block_dynarr *prop;
975 /* #### This function is too simplistic. It needs to do the same
976 sort of character interpretation (display-table lookup,
977 ctl-arrow checking), etc. that create_text_block() does.
978 The functionality to do this in that routine needs to be
981 for (pos = c_string; pos < end;)
983 data->ch = charptr_emchar (pos);
985 prop = add_emchar_rune (data);
993 struct prop_block pb;
994 Bytecount len = end - pos;
995 prop = Dynarr_new (prop_block);
997 pb.type = PROP_STRING;
998 pb.data.p_string.str = xnew_array (Bufbyte, len);
999 strncpy ((char *) pb.data.p_string.str, (char *) pos, len);
1000 pb.data.p_string.len = len;
1002 Dynarr_add (prop, pb);
1007 assert (pos <= end);
1013 /* Add a single rune of the specified width. The area covered by this
1014 rune will be displayed in the foreground color of the associated
1017 static prop_block_dynarr *
1018 add_blank_rune (pos_data *data, struct window *w, int char_tab_width)
1022 /* If data->start_col is not 0 then this call to add_blank_rune must have
1023 been to add it as a tab. */
1024 if (data->start_col)
1026 /* assert (w != NULL) */
1027 prop_block_dynarr *retval;
1029 /* If we have still not fully scrolled horizontally, subtract
1030 the width of this tab and return. */
1031 if (char_tab_width < data->start_col)
1033 data->start_col -= char_tab_width;
1036 else if (char_tab_width == data->start_col)
1037 data->blank_width = 0;
1040 int spcwid = space_width (w);
1042 if (spcwid >= data->blank_width)
1043 data->blank_width = 0;
1045 data->blank_width -= spcwid;
1048 data->start_col = 0;
1049 retval = add_hscroll_rune (data);
1051 /* Could be caused by the handling of the hscroll rune. */
1052 if (retval != NULL || !data->blank_width)
1056 /* Blank runes are always calculated to fit. */
1057 assert (data->pixpos + data->blank_width <= data->max_pixpos);
1059 rb.findex = data->findex;
1060 rb.xpos = data->pixpos;
1061 rb.width = data->blank_width;
1062 if (data->bi_bufpos)
1064 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
1067 /* #### and this is really correct too? */
1070 rb.type = RUNE_BLANK;
1072 if (data->cursor_type == CURSOR_ON)
1074 if (data->bi_bufpos == data->bi_cursor_bufpos)
1076 rb.cursor_type = CURSOR_ON;
1077 data->cursor_x = Dynarr_length (data->db->runes);
1080 rb.cursor_type = CURSOR_OFF;
1082 else if (data->cursor_type == NEXT_CURSOR)
1084 rb.cursor_type = CURSOR_ON;
1085 data->cursor_x = Dynarr_length (data->db->runes);
1086 data->cursor_type = NO_CURSOR;
1089 rb.cursor_type = CURSOR_OFF;
1091 Dynarr_add (data->db->runes, rb);
1092 data->pixpos += data->blank_width;
1097 /* Add runes representing a character in octal. */
1099 #define ADD_NEXT_OCTAL_RUNE_CHAR do \
1101 if (add_failed || (add_failed = add_emchar_rune (data))) \
1103 struct prop_block pb; \
1105 prop = Dynarr_new (prop_block); \
1107 pb.type = PROP_CHAR; \
1108 pb.data.p_char.ch = data->ch; \
1109 pb.data.p_char.cursor_type = data->cursor_type; \
1110 Dynarr_add (prop, pb); \
1114 static prop_block_dynarr *
1115 add_octal_runes (pos_data *data)
1117 prop_block_dynarr *prop, *add_failed;
1118 Emchar orig_char = data->ch;
1119 unsigned int orig_cursor_type = data->cursor_type;
1125 if (data->start_col)
1128 if (!data->start_col)
1130 if (data->bi_start_col_enabled)
1132 add_failed = add_hscroll_rune (data);
1136 struct glyph_block gb;
1137 struct window *w = XWINDOW (data->window);
1140 gb.glyph = Voctal_escape_glyph;
1142 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1143 GLYPH_CACHEL (w, OCT_ESC_GLYPH_INDEX));
1147 /* We only propagate information if the glyph was partially
1152 data->cursor_type = IGNORE_CURSOR;
1154 if (data->ch >= 0x100)
1156 /* If the character is an extended Mule character, it could have
1157 up to 19 bits. For the moment, we treat it as a seven-digit
1158 octal number. This is not that pretty, but whatever. */
1159 data->ch = (7 & (orig_char >> 18)) + '0';
1160 ADD_NEXT_OCTAL_RUNE_CHAR;
1162 data->ch = (7 & (orig_char >> 15)) + '0';
1163 ADD_NEXT_OCTAL_RUNE_CHAR;
1165 data->ch = (7 & (orig_char >> 12)) + '0';
1166 ADD_NEXT_OCTAL_RUNE_CHAR;
1168 data->ch = (7 & (orig_char >> 9)) + '0';
1169 ADD_NEXT_OCTAL_RUNE_CHAR;
1172 data->ch = (7 & (orig_char >> 6)) + '0';
1173 ADD_NEXT_OCTAL_RUNE_CHAR;
1175 data->ch = (7 & (orig_char >> 3)) + '0';
1176 ADD_NEXT_OCTAL_RUNE_CHAR;
1178 data->ch = (7 & orig_char) + '0';
1179 ADD_NEXT_OCTAL_RUNE_CHAR;
1181 data->cursor_type = orig_cursor_type;
1185 #undef ADD_NEXT_OCTAL_RUNE_CHAR
1187 /* Add runes representing a control character to a display block. */
1189 static prop_block_dynarr *
1190 add_control_char_runes (pos_data *data, struct buffer *b)
1192 if (!NILP (b->ctl_arrow))
1194 prop_block_dynarr *prop;
1195 Emchar orig_char = data->ch;
1196 unsigned int old_cursor_type = data->cursor_type;
1201 if (data->start_col)
1204 if (!data->start_col)
1206 if (data->bi_start_col_enabled)
1208 prop_block_dynarr *retval;
1210 retval = add_hscroll_rune (data);
1216 struct glyph_block gb;
1217 struct window *w = XWINDOW (data->window);
1220 gb.glyph = Vcontrol_arrow_glyph;
1222 /* We only propagate information if the glyph was partially
1224 if (add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1225 GLYPH_CACHEL (w, CONTROL_GLYPH_INDEX)))
1230 if (orig_char == 0177)
1233 data->ch = orig_char ^ 0100;
1234 data->cursor_type = IGNORE_CURSOR;
1236 if (add_emchar_rune (data))
1238 struct prop_block pb;
1240 prop = Dynarr_new (prop_block);
1242 pb.type = PROP_CHAR;
1243 pb.data.p_char.ch = data->ch;
1244 pb.data.p_char.cursor_type = data->cursor_type;
1245 Dynarr_add (prop, pb);
1248 data->cursor_type = old_cursor_type;
1253 return add_octal_runes (data);
1257 static prop_block_dynarr *
1258 add_disp_table_entry_runes_1 (pos_data *data, Lisp_Object entry)
1260 prop_block_dynarr *prop = NULL;
1262 if (STRINGP (entry))
1264 prop = add_bufbyte_string_runes (data,
1265 XSTRING_DATA (entry),
1266 XSTRING_LENGTH (entry),
1269 else if (GLYPHP (entry))
1271 if (data->start_col)
1274 if (!data->start_col && data->bi_start_col_enabled)
1276 prop = add_hscroll_rune (data);
1280 struct glyph_block gb;
1284 prop = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
1287 else if (CHAR_OR_CHAR_INTP (entry))
1289 data->ch = XCHAR_OR_CHAR_INT (entry);
1290 prop = add_emchar_rune (data);
1292 else if (CONSP (entry))
1294 if (EQ (XCAR (entry), Qformat)
1295 && CONSP (XCDR (entry))
1296 && STRINGP (XCAR (XCDR (entry))))
1298 Lisp_Object format = XCAR (XCDR (entry));
1299 Bytind len = XSTRING_LENGTH (format);
1300 Bufbyte *src = XSTRING_DATA (format), *end = src + len;
1301 Bufbyte *result = alloca_array (Bufbyte, len);
1302 Bufbyte *dst = result;
1306 Emchar c = charptr_emchar (src);
1308 if (c != '%' || src == end)
1309 dst += set_charptr_emchar (dst, c);
1312 c = charptr_emchar (src);
1317 dst += long_to_string_base ((char *)dst, data->ch, 16);
1320 dst += set_charptr_emchar (dst, '%');
1322 /* #### unimplemented */
1326 prop = add_bufbyte_string_runes (data, result, dst - result, 0);
1330 /* Else blow it off because someone added a bad entry and we don't
1331 have any safe way of signaling an error. */
1335 /* Given a display table entry, call the appropriate functions to
1336 display each element of the entry. */
1338 static prop_block_dynarr *
1339 add_disp_table_entry_runes (pos_data *data, Lisp_Object entry)
1341 prop_block_dynarr *prop = NULL;
1342 if (VECTORP (entry))
1344 Lisp_Vector *de = XVECTOR (entry);
1345 EMACS_INT len = vector_length (de);
1348 for (elt = 0; elt < len; elt++)
1350 if (NILP (vector_data (de)[elt]))
1353 prop = add_disp_table_entry_runes_1 (data, vector_data (de)[elt]);
1354 /* Else blow it off because someone added a bad entry and we
1355 don't have any safe way of signaling an error. Hey, this
1356 comment sounds familiar. */
1358 /* #### Still need to add any remaining elements to the
1359 propagation information. */
1365 prop = add_disp_table_entry_runes_1 (data, entry);
1369 /* Add runes which were propagated from the previous line. */
1371 static prop_block_dynarr *
1372 add_propagation_runes (prop_block_dynarr **prop, pos_data *data)
1374 /* #### Remember to handle start_col parameter of data when the rest of
1375 this is finished. */
1376 /* #### Chuck -- I've redone this function a bit. It looked like the
1377 case of not all the propagation blocks being added was not handled
1379 /* #### Chuck -- I also think the double indirection of PROP is kind
1380 of bogus. A cleaner solution is just to check for
1381 Dynarr_length (prop) > 0. */
1382 /* #### This function also doesn't even pay attention to ADD_FAILED!
1383 This is seriously fucked! Seven ####'s in 130 lines -- is that a
1386 prop_block_dynarr *add_failed;
1387 Bytind bi_old_cursor_bufpos = data->bi_cursor_bufpos;
1388 unsigned int old_cursor_type = data->cursor_type;
1390 for (elt = 0; elt < Dynarr_length (*prop); elt++)
1392 struct prop_block *pb = Dynarr_atp (*prop, elt);
1397 data->ch = pb->data.p_char.ch;
1398 data->bi_cursor_bufpos = pb->data.p_char.bi_cursor_bufpos;
1399 data->cursor_type = pb->data.p_char.cursor_type;
1400 add_failed = add_emchar_rune (data);
1403 goto oops_no_more_space;
1406 if (pb->data.p_string.str)
1407 xfree (pb->data.p_string.str);
1408 /* #### bogus bogus -- this doesn't do anything!
1409 Should probably call add_bufbyte_string_runes(),
1410 once that function is fixed. */
1412 case PROP_MINIBUF_PROMPT:
1414 face_index old_findex = data->findex;
1415 Bytind bi_old_bufpos = data->bi_bufpos;
1417 data->findex = DEFAULT_INDEX;
1418 data->bi_bufpos = 0;
1419 data->cursor_type = NO_CURSOR;
1421 while (pb->data.p_string.len > 0)
1423 data->ch = charptr_emchar (pb->data.p_string.str);
1424 add_failed = add_emchar_rune (data);
1428 data->findex = old_findex;
1429 data->bi_bufpos = bi_old_bufpos;
1430 goto oops_no_more_space;
1434 /* Complicated equivalent of ptr++, len-- */
1435 Bufbyte *oldpos = pb->data.p_string.str;
1436 INC_CHARPTR (pb->data.p_string.str);
1437 pb->data.p_string.len -= pb->data.p_string.str - oldpos;
1441 data->findex = old_findex;
1442 /* ##### FIXME FIXME FIXME -- Upon successful return from
1443 this function, data->bi_bufpos is automatically incremented.
1444 However, we don't want that to happen if we were adding
1445 the minibuffer prompt. */
1447 struct buffer *buf =
1448 XBUFFER (WINDOW_BUFFER (XWINDOW (data->window)));
1449 /* #### Chuck fix this shit or I'm gonna scream! */
1450 if (bi_old_bufpos > BI_BUF_BEGV (buf))
1451 data->bi_bufpos = prev_bytind (buf, bi_old_bufpos);
1453 /* #### is this correct? Does anyone know?
1454 Does anyone care? Is this a cheesy hack or what? */
1455 data->bi_bufpos = BI_BUF_BEGV (buf) - 1;
1461 /* #### I think it's unnecessary and misleading to preserve
1462 the blank_width, as it implies that the value carries
1463 over from one rune to the next, which is wrong. */
1464 int old_width = data->blank_width;
1465 face_index old_findex = data->findex;
1467 data->findex = pb->data.p_blank.findex;
1468 data->blank_width = pb->data.p_blank.width;
1469 data->bi_cursor_bufpos = 0;
1470 data->cursor_type = IGNORE_CURSOR;
1472 if (data->pixpos + data->blank_width > data->max_pixpos)
1473 data->blank_width = data->max_pixpos - data->pixpos;
1475 /* We pass a bogus value of char_tab_width. It shouldn't
1476 matter because unless something is really screwed up
1477 this call won't cause that arg to be used. */
1478 add_failed = add_blank_rune (data, XWINDOW (data->window), 0);
1480 /* This can happen in the case where we have a tab which
1481 is wider than the window. */
1482 if (data->blank_width != pb->data.p_blank.width)
1484 pb->data.p_blank.width -= data->blank_width;
1485 add_failed = ADD_FAILED;
1488 data->findex = old_findex;
1489 data->blank_width = old_width;
1492 goto oops_no_more_space;
1502 data->bi_cursor_bufpos = bi_old_cursor_bufpos;
1503 data->cursor_type = old_cursor_type;
1504 if (elt < Dynarr_length (*prop))
1506 Dynarr_delete_many (*prop, 0, elt);
1511 Dynarr_free (*prop);
1516 /* Add 'text layout glyphs at position POS_TYPE that are contained to
1517 the display block, but add all other types to the appropriate list
1518 of the display line. They will be added later by different
1521 static prop_block_dynarr *
1522 add_glyph_rune (pos_data *data, struct glyph_block *gb, int pos_type,
1523 int allow_cursor, struct glyph_cachel *cachel)
1525 struct window *w = XWINDOW (data->window);
1527 /* If window faces changed, and glyph instance is text, then
1528 glyph sizes might have changed too */
1529 invalidate_glyph_geometry_maybe (gb->glyph, w);
1531 /* This makes sure the glyph is in the cachels.
1533 #### We do this to make sure the glyph is in the glyph cachels,
1534 so that the dirty flag can be reset after redisplay has
1535 finished. We should do this some other way, maybe by iterating
1536 over the window cache of subwindows. */
1537 get_glyph_cachel_index (w, gb->glyph);
1539 /* A nil extent indicates a special glyph (ex. truncator). */
1540 if (NILP (gb->extent)
1541 || (pos_type == BEGIN_GLYPHS &&
1542 extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1543 || (pos_type == END_GLYPHS &&
1544 extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1545 || pos_type == LEFT_GLYPHS || pos_type == RIGHT_GLYPHS)
1550 int ascent, descent;
1551 Lisp_Object baseline;
1553 Lisp_Object instance;
1557 width = cachel->width;
1559 width = glyph_width (gb->glyph, data->window);
1564 if (data->start_col || data->start_col_xoffset)
1566 prop_block_dynarr *retval;
1567 int glyph_char_width = width / space_width (w);
1569 /* If we still have not fully scrolled horizontally after
1570 taking into account the width of the glyph, subtract its
1571 width and return. */
1572 if (glyph_char_width < data->start_col)
1574 data->start_col -= glyph_char_width;
1577 else if (glyph_char_width == data->start_col)
1581 xoffset = space_width (w) * data->start_col;
1584 /* #### Can this happen? */
1589 data->start_col = 0;
1590 retval = add_hscroll_rune (data);
1592 /* Could be caused by the handling of the hscroll rune. */
1593 if (retval != NULL || !width)
1599 if (data->pixpos + width > data->max_pixpos)
1601 /* If this is the first object we are attempting to add to
1602 the line then we ignore the horizontal_clip threshold.
1603 Otherwise we will loop until the bottom of the window
1604 continually failing to add this glyph because it is wider
1605 than the window. We could alternatively just completely
1606 ignore the glyph and proceed from there but I think that
1607 this is a better solution. */
1608 if (Dynarr_length (data->db->runes)
1609 && data->max_pixpos - data->pixpos < horizontal_clip)
1612 width = data->max_pixpos - data->pixpos;
1617 ascent = cachel->ascent;
1618 descent = cachel->descent;
1622 ascent = glyph_ascent (gb->glyph, data->window);
1623 descent = glyph_descent (gb->glyph, data->window);
1626 baseline = glyph_baseline (gb->glyph, data->window);
1628 if (glyph_contrib_p (gb->glyph, data->window))
1630 /* A pixmap that has not had a baseline explicitly set. Its
1631 contribution will be determined later. */
1632 if (NILP (baseline))
1634 int height = ascent + descent;
1635 data->max_pixmap_height = max (data->max_pixmap_height, height);
1638 /* A string so determine contribution normally. */
1639 else if (EQ (baseline, Qt))
1641 data->new_ascent = max (data->new_ascent, ascent);
1642 data->new_descent = max (data->new_descent, descent);
1645 /* A pixmap with an explicitly set baseline. We determine the
1646 contribution here. */
1647 else if (INTP (baseline))
1649 int height = ascent + descent;
1650 int pix_ascent, pix_descent;
1652 pix_ascent = height * XINT (baseline) / 100;
1653 pix_descent = height - pix_ascent;
1655 data->new_ascent = max (data->new_ascent, pix_ascent);
1656 data->new_descent = max (data->new_descent, pix_descent);
1659 /* Otherwise something is screwed up. */
1664 face = glyph_face (gb->glyph, data->window);
1666 findex = data->findex;
1668 findex = get_builtin_face_cache_index (w, face);
1670 instance = glyph_image_instance (gb->glyph, data->window,
1672 if (TEXT_IMAGE_INSTANCEP (instance))
1674 Lisp_Object string = XIMAGE_INSTANCE_TEXT_STRING (instance);
1675 face_index orig_findex = data->findex;
1676 Bytind orig_bufpos = data->bi_bufpos;
1677 Bytind orig_start_col_enabled = data->bi_start_col_enabled;
1679 data->findex = findex;
1680 data->bi_start_col_enabled = 0;
1682 data->bi_bufpos = 0;
1683 add_bufbyte_string_runes (data, XSTRING_DATA (string),
1684 XSTRING_LENGTH (string), 0);
1685 data->findex = orig_findex;
1686 data->bi_bufpos = orig_bufpos;
1687 data->bi_start_col_enabled = orig_start_col_enabled;
1692 rb.xpos = data->pixpos;
1694 rb.bufpos = 0; /* glyphs are never "at" anywhere */
1695 if (data->bi_endpos)
1696 /* #### is this necessary at all? */
1697 rb.endpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1701 rb.type = RUNE_DGLYPH;
1702 rb.object.dglyph.glyph = gb->glyph;
1703 rb.object.dglyph.extent = gb->extent;
1704 rb.object.dglyph.xoffset = xoffset;
1708 rb.bufpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1711 if (data->cursor_type == CURSOR_ON)
1713 if (data->bi_bufpos == data->bi_cursor_bufpos)
1715 rb.cursor_type = CURSOR_ON;
1716 data->cursor_x = Dynarr_length (data->db->runes);
1719 rb.cursor_type = CURSOR_OFF;
1721 else if (data->cursor_type == NEXT_CURSOR)
1723 rb.cursor_type = CURSOR_ON;
1724 data->cursor_x = Dynarr_length (data->db->runes);
1725 data->cursor_type = NO_CURSOR;
1727 else if (data->cursor_type == IGNORE_CURSOR)
1728 rb.cursor_type = IGNORE_CURSOR;
1729 else if (data->cursor_type == NO_CURSOR)
1730 rb.cursor_type = NO_CURSOR;
1732 rb.cursor_type = CURSOR_OFF;
1735 rb.cursor_type = CURSOR_OFF;
1737 Dynarr_add (data->db->runes, rb);
1738 data->pixpos += width;
1744 if (!NILP (glyph_face (gb->glyph, data->window)))
1746 get_builtin_face_cache_index (w, glyph_face (gb->glyph,
1749 gb->findex = data->findex;
1751 if (pos_type == BEGIN_GLYPHS)
1753 if (!data->dl->left_glyphs)
1754 data->dl->left_glyphs = Dynarr_new (glyph_block);
1755 Dynarr_add (data->dl->left_glyphs, *gb);
1758 else if (pos_type == END_GLYPHS)
1760 if (!data->dl->right_glyphs)
1761 data->dl->right_glyphs = Dynarr_new (glyph_block);
1762 Dynarr_add (data->dl->right_glyphs, *gb);
1766 abort (); /* there are no unknown types */
1769 return NULL; /* shut up compiler */
1772 /* Add all glyphs at position POS_TYPE that are contained in the given
1775 static prop_block_dynarr *
1776 add_glyph_runes (pos_data *data, int pos_type)
1778 /* #### This still needs to handle the start_col parameter. Duh, Chuck,
1779 why didn't you just modify add_glyph_rune in the first place? */
1781 glyph_block_dynarr *glyph_arr = (pos_type == BEGIN_GLYPHS
1782 ? data->ef->begin_glyphs
1783 : data->ef->end_glyphs);
1784 prop_block_dynarr *prop;
1786 for (elt = 0; elt < Dynarr_length (glyph_arr); elt++)
1788 prop = add_glyph_rune (data, Dynarr_atp (glyph_arr, elt), pos_type, 0,
1793 /* #### Add some propagation information. */
1798 Dynarr_reset (glyph_arr);
1803 /* Given a position for a buffer in a window, ensure that the given
1804 display line DL accurately represents the text on a line starting
1805 at the given position.
1807 NOTE NOTE NOTE NOTE: This function works with and returns Bytinds.
1808 You must do appropriate conversion. */
1811 create_text_block (struct window *w, struct display_line *dl,
1812 Bytind bi_start_pos, prop_block_dynarr **prop,
1815 struct frame *f = XFRAME (w->frame);
1816 struct buffer *b = XBUFFER (w->buffer);
1817 struct device *d = XDEVICE (f->device);
1821 /* Don't display anything in the minibuffer if this window is not on
1822 a selected frame. We consider all other windows to be active
1823 minibuffers as it simplifies the coding. */
1824 int active_minibuffer = (!MINI_WINDOW_P (w) ||
1825 (f == device_selected_frame (d)) ||
1826 is_surrogate_for_selected_frame (f));
1828 int truncate_win = window_truncation_on (w);
1829 int end_glyph_width;
1831 /* If the buffer's value of selective_display is an integer then
1832 only lines that start with less than selective_display columns of
1833 space will be displayed. If selective_display is t then all text
1834 after a ^M is invisible. */
1835 int selective = (INTP (b->selective_display)
1836 ? XINT (b->selective_display)
1837 : (!NILP (b->selective_display) ? -1 : 0));
1839 /* The variable ctl-arrow allows the user to specify what characters
1840 can actually be displayed and which octal should be used for.
1841 #### This variable should probably have some rethought done to
1844 #### It would also be really nice if you could specify that
1845 the characters come out in hex instead of in octal. Mule
1846 does that by adding a ctl-hexa variable similar to ctl-arrow,
1847 but that's bogus -- we need a more general solution. I
1848 think you need to extend the concept of display tables
1849 into a more general conversion mechanism. Ideally you
1850 could specify a Lisp function that converts characters,
1851 but this violates the Second Golden Rule and besides would
1852 make things way way way way slow.
1854 So instead, we extend the display-table concept, which was
1855 historically limited to 256-byte vectors, to one of the
1858 a) A 256-entry vector, for backward compatibility;
1859 b) char-table, mapping characters to values;
1860 c) range-table, mapping ranges of characters to values;
1861 d) a list of the above.
1863 The (d) option allows you to specify multiple display tables
1864 instead of just one. Each display table can specify conversions
1865 for some characters and leave others unchanged. The way the
1866 character gets displayed is determined by the first display table
1867 with a binding for that character. This way, you could call a
1868 function `enable-hex-display' that adds a hex display-table to
1869 the list of display tables for the current buffer.
1871 #### ...not yet implemented... Also, we extend the concept of
1872 "mapping" to include a printf-like spec. Thus you can make all
1873 extended characters show up as hex with a display table like
1876 #s(range-table data ((256 524288) (format "%x")))
1878 Since more than one display table is possible, you have
1879 great flexibility in mapping ranges of characters. */
1880 Emchar printable_min = (CHAR_OR_CHAR_INTP (b->ctl_arrow)
1881 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
1882 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
1885 Lisp_Object face_dt, window_dt;
1887 /* The text display block for this display line. */
1888 struct display_block *db = get_display_block_from_line (dl, TEXT);
1890 /* The first time through the main loop we need to force the glyph
1891 data to be updated. */
1894 /* Apparently the new extent_fragment_update returns an end position
1895 equal to the position passed in if there are no more runs to be
1897 int no_more_frags = 0;
1899 Lisp_Object synch_minibuffers_value =
1900 symbol_value_in_buffer (Qsynchronize_minibuffers, w->buffer);
1902 dl->used_prop_data = 0;
1904 dl->line_continuation = 0;
1907 data.ef = extent_fragment_new (w->buffer, f);
1909 /* These values are used by all of the rune addition routines. We add
1910 them to this structure for ease of passing. */
1912 XSETWINDOW (data.window, w);
1917 data.bi_bufpos = bi_start_pos;
1918 data.pixpos = dl->bounds.left_in;
1919 data.last_charset = Qunbound;
1920 data.last_findex = DEFAULT_INDEX;
1921 data.result_str = Qnil;
1923 /* Set the right boundary adjusting it to take into account any end
1924 glyph. Save the width of the end glyph for later use. */
1925 data.max_pixpos = dl->bounds.right_in;
1927 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
1929 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
1930 data.max_pixpos -= end_glyph_width;
1932 if (cursor_in_echo_area && MINI_WINDOW_P (w) && echo_area_active (f))
1934 data.bi_cursor_bufpos = BI_BUF_ZV (b);
1935 data.cursor_type = CURSOR_ON;
1937 else if (MINI_WINDOW_P (w) && !active_minibuffer)
1938 data.cursor_type = NO_CURSOR;
1939 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)) &&
1940 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
1941 d == XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d))))&&
1942 f == XFRAME(DEVICE_SELECTED_FRAME(d)))
1944 data.bi_cursor_bufpos = BI_BUF_PT (b);
1945 data.cursor_type = CURSOR_ON;
1947 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)))
1949 data.bi_cursor_bufpos = bi_marker_position (w->pointm[type]);
1950 data.cursor_type = CURSOR_ON;
1953 data.cursor_type = NO_CURSOR;
1956 data.start_col = w->hscroll;
1957 data.start_col_xoffset = w->left_xoffset;
1958 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
1959 data.hscroll_glyph_width_adjust = 0;
1961 /* We regenerate the line from the very beginning. */
1962 Dynarr_reset (db->runes);
1964 /* Why is this less than or equal and not just less than? If the
1965 starting position is already equal to the maximum we can't add
1966 anything else, right? Wrong. We might still have a newline to
1967 add. A newline can use the room allocated for an end glyph since
1968 if we add it we know we aren't going to be adding any end
1971 /* #### Chuck -- I think this condition should be while (1).
1972 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
1973 and the begin-glyph ends exactly at the end of the window, the
1974 end-glyph and text might not be displayed. while (1) ensures
1975 that the loop terminates only when either (a) there is
1976 propagation data or (b) the end-of-line or end-of-buffer is hit.
1978 #### Also I think you need to ensure that the operation
1979 "add begin glyphs; add end glyphs; add text" is atomic and
1980 can't get interrupted in the middle. If you run off the end
1981 of the line during that operation, then you keep accumulating
1982 propagation data until you're done. Otherwise, if the (e.g.)
1983 there's a begin glyph at a particular position and attempting
1984 to display that glyph results in window-end being hit and
1985 propagation data being generated, then the character at that
1986 position won't be displayed.
1988 #### See also the comment after the end of this loop, below.
1990 while (data.pixpos <= data.max_pixpos
1991 && (active_minibuffer || !NILP (synch_minibuffers_value)))
1993 /* #### This check probably should not be necessary. */
1994 if (data.bi_bufpos > BI_BUF_ZV (b))
1996 /* #### urk! More of this lossage! */
2001 /* If selective display was an integer and we aren't working on
2002 a continuation line then find the next line we are actually
2003 supposed to display. */
2005 && (data.bi_bufpos == BI_BUF_BEGV (b)
2006 || BUF_FETCH_CHAR (b, prev_bytind (b, data.bi_bufpos)) == '\n'))
2008 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2011 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2012 if (data.bi_bufpos >= BI_BUF_ZV (b))
2014 data.bi_bufpos = BI_BUF_ZV (b);
2020 /* Check for face changes. */
2021 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
2023 /* Now compute the face and begin/end-glyph information. */
2025 /* Remember that the extent-fragment routines deal in Bytind's. */
2026 extent_fragment_update (w, data.ef, data.bi_bufpos);
2028 get_display_tables (w, data.findex, &face_dt, &window_dt);
2030 if (data.bi_bufpos == data.ef->end)
2035 /* Determine what is next to be displayed. We first handle any
2036 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
2037 display then we determine what to do based on the character at the
2038 current buffer position. */
2040 /* If the current position is covered by an invisible extent, do
2041 nothing (except maybe add some ellipses).
2043 #### The behavior of begin and end-glyphs at the edge of an
2044 invisible extent should be investigated further. This is
2045 fairly low priority though. */
2046 if (data.ef->invisible)
2048 /* #### Chuck, perhaps you could look at this code? I don't
2049 really know what I'm doing. */
2052 Dynarr_free (*prop);
2056 /* The extent fragment code only sets this when we should
2057 really display the ellipses. It makes sure the ellipses
2058 don't get displayed more than once in a row. */
2059 if (data.ef->invisible_ellipses)
2061 struct glyph_block gb;
2063 data.ef->invisible_ellipses_already_displayed = 1;
2064 data.ef->invisible_ellipses = 0;
2066 gb.glyph = Vinvisible_text_glyph;
2067 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2068 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2069 /* Perhaps they shouldn't propagate if the very next thing
2070 is to display a newline (for compatibility with
2071 selective-display-ellipses)? Maybe that's too
2077 /* If point is in an invisible region we place it on the
2078 next visible character. */
2079 if (data.cursor_type == CURSOR_ON
2080 && data.bi_bufpos == data.bi_cursor_bufpos)
2082 data.cursor_type = NEXT_CURSOR;
2085 /* #### What if we we're dealing with a display table? */
2089 if (data.bi_bufpos == BI_BUF_ZV (b))
2092 INC_BYTIND (b, data.bi_bufpos);
2095 /* If there is propagation data, then it represents the current
2096 buffer position being displayed. Add them and advance the
2097 position counter. This might also add the minibuffer
2101 dl->used_prop_data = 1;
2102 *prop = add_propagation_runes (prop, &data);
2105 goto done; /* gee, a really narrow window */
2106 else if (data.bi_bufpos == BI_BUF_ZV (b))
2108 else if (data.bi_bufpos < BI_BUF_BEGV (b))
2109 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
2110 data.bi_bufpos = BI_BUF_BEGV (b);
2112 INC_BYTIND (b, data.bi_bufpos);
2115 /* If there are end glyphs, add them to the line. These are
2116 the end glyphs for the previous run of text. We add them
2117 here rather than doing them at the end of handling the
2118 previous run so that glyphs at the beginning and end of
2119 a line are handled correctly. */
2120 else if (Dynarr_length (data.ef->end_glyphs) > 0)
2122 *prop = add_glyph_runes (&data, END_GLYPHS);
2127 /* If there are begin glyphs, add them to the line. */
2128 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
2130 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
2135 /* If at end-of-buffer, we've already processed begin and
2136 end-glyphs at this point and there's no text to process,
2138 else if (data.bi_bufpos == BI_BUF_ZV (b))
2143 Lisp_Object entry = Qnil;
2144 /* Get the character at the current buffer position. */
2145 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2146 if (!NILP (face_dt) || !NILP (window_dt))
2147 entry = display_table_entry (data.ch, face_dt, window_dt);
2149 /* If there is a display table entry for it, hand it off to
2150 add_disp_table_entry_runes and let it worry about it. */
2151 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
2153 *prop = add_disp_table_entry_runes (&data, entry);
2159 /* Check if we have hit a newline character. If so, add a marker
2160 to the line and end this loop. */
2161 else if (data.ch == '\n')
2163 /* We aren't going to be adding an end glyph so give its
2164 space back in order to make sure that the cursor can
2166 data.max_pixpos += end_glyph_width;
2169 && (bi_spaces_at_point
2170 (b, next_bytind (b, data.bi_bufpos))
2173 if (!NILP (b->selective_display_ellipses))
2175 struct glyph_block gb;
2178 gb.glyph = Vinvisible_text_glyph;
2179 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2180 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2184 /* Cheesy, cheesy, cheesy. We mark the end of the
2185 line with a special "character rune" whose width
2186 is the EOL cursor width and whose character is
2187 the non-printing character '\n'. */
2188 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2189 *prop = add_emchar_rune (&data);
2192 /* We need to set data.bi_bufpos to the start of the
2193 next visible region in order to make this line
2194 appear to contain all of the invisible area.
2195 Otherwise, the line cache won't work
2197 INC_BYTIND (b, data.bi_bufpos);
2198 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2201 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2202 if (data.bi_bufpos >= BI_BUF_ZV (b))
2204 data.bi_bufpos = BI_BUF_ZV (b);
2208 if (BI_BUF_FETCH_CHAR
2209 (b, prev_bytind (b, data.bi_bufpos)) == '\n')
2210 DEC_BYTIND (b, data.bi_bufpos);
2214 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2215 *prop = add_emchar_rune (&data);
2221 /* If the current character is ^M, and selective display is
2222 enabled, then add the invisible-text-glyph if
2223 selective-display-ellipses is set. In any case, this
2225 else if (data.ch == (('M' & 037)) && selective == -1)
2227 Bytind bi_next_bufpos;
2229 /* Find the buffer position at the end of the line. */
2231 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2232 if (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_next_bufpos))
2234 DEC_BYTIND (b, bi_next_bufpos);
2236 /* If the cursor is somewhere in the elided text make
2237 sure that the cursor gets drawn appropriately. */
2238 if (data.cursor_type == CURSOR_ON
2239 && (data.bi_cursor_bufpos >= data.bi_bufpos &&
2240 data.bi_cursor_bufpos < bi_next_bufpos))
2242 data.cursor_type = NEXT_CURSOR;
2245 /* We won't be adding a truncation or continuation glyph
2246 so give up the room allocated for them. */
2247 data.max_pixpos += end_glyph_width;
2249 if (!NILP (b->selective_display_ellipses))
2251 /* We don't propagate anything from the invisible
2252 text glyph if it fails to fit. This is
2254 struct glyph_block gb;
2257 gb.glyph = Vinvisible_text_glyph;
2258 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 1,
2259 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2262 /* Set the buffer position to the end of the line. We
2263 need to do this before potentially adding a newline
2264 so that the cursor flag will get set correctly (if
2266 data.bi_bufpos = bi_next_bufpos;
2268 if (NILP (b->selective_display_ellipses)
2269 || data.bi_cursor_bufpos == bi_next_bufpos)
2271 /* We have to at least add a newline character so
2272 that the cursor shows up properly. */
2274 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2275 data.findex = DEFAULT_INDEX;
2277 data.start_col_xoffset = 0;
2278 data.bi_start_col_enabled = 0;
2280 add_emchar_rune (&data);
2283 /* This had better be a newline but doing it this way
2284 we'll see obvious incorrect results if it isn't. No
2285 need to abort here. */
2286 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2291 /* If the current character is considered to be printable, then
2293 else if (data.ch >= printable_min)
2295 *prop = add_emchar_rune (&data);
2300 /* If the current character is a tab, determine the next tab
2301 starting position and add a blank rune which extends from the
2302 current pixel position to that starting position. */
2303 else if (data.ch == '\t')
2305 int tab_start_pixpos = data.pixpos;
2310 if (data.start_col > 1)
2311 tab_start_pixpos -= (space_width (w) * (data.start_col - 1))
2312 + data.start_col_xoffset;
2315 next_tab_position (w, tab_start_pixpos,
2316 dl->bounds.left_in +
2317 data.hscroll_glyph_width_adjust);
2318 if (next_tab_start > data.max_pixpos)
2320 prop_width = next_tab_start - data.max_pixpos;
2321 next_tab_start = data.max_pixpos;
2323 data.blank_width = next_tab_start - data.pixpos;
2325 (next_tab_start - tab_start_pixpos) / space_width (w);
2327 *prop = add_blank_rune (&data, w, char_tab_width);
2329 /* add_blank_rune is only supposed to be called with
2330 sizes guaranteed to fit in the available space. */
2335 struct prop_block pb;
2336 *prop = Dynarr_new (prop_block);
2338 pb.type = PROP_BLANK;
2339 pb.data.p_blank.width = prop_width;
2340 pb.data.p_blank.findex = data.findex;
2341 Dynarr_add (*prop, pb);
2347 /* If character is a control character, pass it off to
2348 add_control_char_runes.
2350 The is_*() routines have undefined results on
2351 arguments outside of the range [-1, 255]. (This
2352 often bites people who carelessly use `char' instead
2353 of `unsigned char'.)
2355 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
2357 *prop = add_control_char_runes (&data, b);
2363 /* If the character is above the ASCII range and we have not
2364 already handled it, then print it as an octal number. */
2365 else if (data.ch >= 0200)
2367 *prop = add_octal_runes (&data);
2373 /* Assume the current character is considered to be printable,
2374 then just add it. */
2377 *prop = add_emchar_rune (&data);
2382 INC_BYTIND (b, data.bi_bufpos);
2388 /* Determine the starting point of the next line if we did not hit the
2389 end of the buffer. */
2390 if (data.bi_bufpos < BI_BUF_ZV (b)
2391 && (active_minibuffer || !NILP (synch_minibuffers_value)))
2393 /* #### This check is not correct. If the line terminated
2394 due to a begin-glyph or end-glyph hitting window-end, then
2395 data.ch will not point to the character at data.bi_bufpos. If
2396 you make the two changes mentioned at the top of this loop,
2397 you should be able to say '(if (*prop))'. That should also
2398 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
2401 /* The common case is that the line ended because we hit a newline.
2402 In that case, the next character is just the next buffer
2404 if (data.ch == '\n')
2406 /* If data.start_col_enabled is still true, then the window is
2407 scrolled far enough so that nothing on this line is visible.
2408 We need to stick a truncation glyph at the beginning of the
2409 line in that case unless the line is completely blank. */
2410 if (data.bi_start_col_enabled)
2412 if (data.cursor_type == CURSOR_ON)
2414 if (data.bi_cursor_bufpos >= bi_start_pos
2415 && data.bi_cursor_bufpos <= data.bi_bufpos)
2416 data.bi_cursor_bufpos = data.bi_bufpos;
2418 data.findex = DEFAULT_INDEX;
2420 data.bi_start_col_enabled = 0;
2422 if (data.bi_bufpos != bi_start_pos)
2424 struct glyph_block gb;
2427 gb.glyph = Vhscroll_glyph;
2428 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2429 GLYPH_CACHEL (w, HSCROLL_GLYPH_INDEX));
2433 /* This duplicates code down below to add a newline to
2434 the end of an otherwise empty line.*/
2436 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2438 add_emchar_rune (&data);
2442 INC_BYTIND (b, data.bi_bufpos);
2445 /* Otherwise we have a buffer line which cannot fit on one display
2449 struct glyph_block gb;
2450 struct glyph_cachel *cachel;
2452 /* If the line is to be truncated then we actually have to look
2453 for the next newline. We also add the end-of-line glyph which
2454 we know will fit because we adjusted the right border before
2455 we starting laying out the line. */
2456 data.max_pixpos += end_glyph_width;
2457 data.findex = DEFAULT_INDEX;
2464 /* Now find the start of the next line. */
2465 bi_pos = bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2467 /* If the cursor is past the truncation line then we
2468 make it appear on the truncation glyph. If we've hit
2469 the end of the buffer then we also make the cursor
2470 appear unless eob is immediately preceded by a
2471 newline. In that case the cursor should actually
2472 appear on the next line. */
2473 if (data.cursor_type == CURSOR_ON
2474 && data.bi_cursor_bufpos >= data.bi_bufpos
2475 && (data.bi_cursor_bufpos < bi_pos ||
2476 (bi_pos == BI_BUF_ZV (b)
2477 && (bi_pos == BI_BUF_BEGV (b)
2478 || (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_pos))
2480 data.bi_cursor_bufpos = bi_pos;
2482 data.cursor_type = NO_CURSOR;
2484 data.bi_bufpos = bi_pos;
2485 gb.glyph = Vtruncation_glyph;
2486 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
2490 /* The cursor can never be on the continuation glyph. */
2491 data.cursor_type = NO_CURSOR;
2493 /* data.bi_bufpos is already at the start of the next line. */
2495 dl->line_continuation = 1;
2496 gb.glyph = Vcontinuation_glyph;
2497 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
2500 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
2502 if (truncate_win && data.bi_bufpos == BI_BUF_ZV (b)
2503 && BI_BUF_FETCH_CHAR (b, prev_bytind (b, BI_BUF_ZV (b))) != '\n')
2504 /* #### Damn this losing shit. */
2508 else if ((active_minibuffer || !NILP (synch_minibuffers_value))
2509 && (!echo_area_active (f) || data.bi_bufpos == BI_BUF_ZV (b)))
2511 /* We need to add a marker to the end of the line since there is no
2512 newline character in order for the cursor to get drawn. We label
2513 it as a newline so that it gets handled correctly by the
2514 whitespace routines below. */
2517 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2518 data.findex = DEFAULT_INDEX;
2520 data.start_col_xoffset = 0;
2521 data.bi_start_col_enabled = 0;
2523 data.max_pixpos += data.blank_width;
2524 add_emchar_rune (&data);
2525 data.max_pixpos -= data.blank_width;
2527 /* #### urk! Chuck, this shit is bad news. Going around
2528 manipulating invalid positions is guaranteed to result in
2529 trouble sooner or later. */
2530 data.bi_bufpos = BI_BUF_ZV (b) + 1;
2533 /* Calculate left whitespace boundary. */
2537 /* Whitespace past a newline is considered right whitespace. */
2538 while (elt < Dynarr_length (db->runes))
2540 struct rune *rb = Dynarr_atp (db->runes, elt);
2542 if ((rb->type == RUNE_CHAR && CHARC_ASCII_EQ (rb->object.cglyph, ' '))
2543 || rb->type == RUNE_BLANK)
2545 dl->bounds.left_white += rb->width;
2549 elt = Dynarr_length (db->runes);
2553 /* Calculate right whitespace boundary. */
2555 int elt = Dynarr_length (db->runes) - 1;
2558 while (!done && elt >= 0)
2560 struct rune *rb = Dynarr_atp (db->runes, elt);
2562 if (!(rb->type == RUNE_CHAR && CHARC_IS_SPACE (rb->object.cglyph))
2563 && !rb->type == RUNE_BLANK)
2565 dl->bounds.right_white = rb->xpos + rb->width;
2573 /* The line is blank so everything is considered to be right
2576 dl->bounds.right_white = dl->bounds.left_in;
2579 /* Set the display blocks bounds. */
2580 db->start_pos = dl->bounds.left_in;
2581 if (Dynarr_length (db->runes))
2583 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
2585 db->end_pos = rb->xpos + rb->width;
2588 db->end_pos = dl->bounds.right_white;
2590 /* update line height parameters */
2591 if (!data.new_ascent && !data.new_descent)
2593 /* We've got a blank line so initialize these values from the default
2595 default_face_font_info (data.window, &data.new_ascent,
2596 &data.new_descent, 0, 0, 0);
2599 if (data.max_pixmap_height)
2601 int height = data.new_ascent + data.new_descent;
2602 int pix_ascent, pix_descent;
2604 pix_descent = data.max_pixmap_height * data.new_descent / height;
2605 pix_ascent = data.max_pixmap_height - pix_descent;
2607 data.new_ascent = max (data.new_ascent, pix_ascent);
2608 data.new_descent = max (data.new_descent, pix_descent);
2611 dl->ascent = data.new_ascent;
2612 dl->descent = data.new_descent;
2615 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
2617 if (dl->ascent < ascent)
2618 dl->ascent = ascent;
2621 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
2623 if (dl->descent < descent)
2624 dl->descent = descent;
2627 dl->cursor_elt = data.cursor_x;
2628 /* #### lossage lossage lossage! Fix this shit! */
2629 if (data.bi_bufpos > BI_BUF_ZV (b))
2630 dl->end_bufpos = BUF_ZV (b);
2632 dl->end_bufpos = bytind_to_bufpos (b, data.bi_bufpos) - 1;
2634 data.dl->num_chars = column_at_point (b, dl->end_bufpos, 0);
2636 /* This doesn't correctly take into account tabs and control
2637 characters but if the window isn't being truncated then this
2638 value isn't going to end up being used anyhow. */
2639 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
2641 /* #### handle horizontally scrolled line with text none of which
2642 was actually laid out. */
2644 /* #### handle any remainder of overlay arrow */
2646 if (*prop == ADD_FAILED)
2649 if (truncate_win && *prop)
2651 Dynarr_free (*prop);
2655 extent_fragment_delete (data.ef);
2657 /* #### If we started at EOB, then make sure we return a value past
2658 it so that regenerate_window will exit properly. This is bogus.
2659 The main loop should get fixed so that it isn't necessary to call
2660 this function if we are already at EOB. */
2662 if (data.bi_bufpos == BI_BUF_ZV (b) && bi_start_pos == BI_BUF_ZV (b))
2663 return data.bi_bufpos + 1; /* Yuck! */
2665 return data.bi_bufpos;
2668 /* Display the overlay arrow at the beginning of the given line. */
2671 create_overlay_glyph_block (struct window *w, struct display_line *dl)
2673 struct frame *f = XFRAME (w->frame);
2674 struct device *d = XDEVICE (f->device);
2677 /* If Voverlay_arrow_string isn't valid then just fail silently. */
2678 if (!STRINGP (Voverlay_arrow_string) && !GLYPHP (Voverlay_arrow_string))
2684 XSETWINDOW (data.window, w);
2685 data.db = get_display_block_from_line (dl, OVERWRITE);
2687 data.pixpos = dl->bounds.left_in;
2688 data.max_pixpos = dl->bounds.right_in;
2689 data.cursor_type = NO_CURSOR;
2691 data.findex = DEFAULT_INDEX;
2692 data.last_charset = Qunbound;
2693 data.last_findex = DEFAULT_INDEX;
2694 data.result_str = Qnil;
2697 Dynarr_reset (data.db->runes);
2699 if (STRINGP (Voverlay_arrow_string))
2701 add_bufbyte_string_runes
2703 XSTRING_DATA (Voverlay_arrow_string),
2704 XSTRING_LENGTH (Voverlay_arrow_string),
2707 else if (GLYPHP (Voverlay_arrow_string))
2709 struct glyph_block gb;
2711 gb.glyph = Voverlay_arrow_string;
2713 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, 0);
2716 if (data.max_pixmap_height)
2718 int height = data.new_ascent + data.new_descent;
2719 int pix_ascent, pix_descent;
2721 pix_descent = data.max_pixmap_height * data.new_descent / height;
2722 pix_ascent = data.max_pixmap_height - pix_descent;
2724 data.new_ascent = max (data.new_ascent, pix_ascent);
2725 data.new_descent = max (data.new_descent, pix_descent);
2728 dl->ascent = data.new_ascent;
2729 dl->descent = data.new_descent;
2731 data.db->start_pos = dl->bounds.left_in;
2732 data.db->end_pos = data.pixpos;
2734 return data.pixpos - dl->bounds.left_in;
2737 /* Add a type of glyph to a margin display block. */
2740 add_margin_runes (struct display_line *dl, struct display_block *db, int start,
2741 int count, enum glyph_layout layout, int side, Lisp_Object window)
2743 glyph_block_dynarr *gbd = (side == LEFT_GLYPHS
2745 : dl->right_glyphs);
2748 struct window *w = XWINDOW (window);
2749 struct frame *f = XFRAME (w->frame);
2750 struct device *d = XDEVICE (f->device);
2755 data.window = window;
2758 data.pixpos = start;
2759 data.cursor_type = NO_CURSOR;
2761 data.last_charset = Qunbound;
2762 data.last_findex = DEFAULT_INDEX;
2763 data.result_str = Qnil;
2765 data.new_ascent = dl->ascent;
2766 data.new_descent = dl->descent;
2768 if ((layout == GL_WHITESPACE && side == LEFT_GLYPHS)
2769 || (layout == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS))
2772 elt = Dynarr_length (gbd) - 1;
2779 end = Dynarr_length (gbd);
2782 while (count && ((!reverse && elt < end) || (reverse && elt >= end)))
2784 struct glyph_block *gb = Dynarr_atp (gbd, elt);
2786 if (NILP (gb->extent))
2787 abort (); /* these should have been handled in add_glyph_rune */
2790 ((side == LEFT_GLYPHS &&
2791 extent_begin_glyph_layout (XEXTENT (gb->extent)) == layout)
2792 || (side == RIGHT_GLYPHS &&
2793 extent_end_glyph_layout (XEXTENT (gb->extent)) == layout)))
2795 data.findex = gb->findex;
2796 data.max_pixpos = data.pixpos + gb->width;
2797 add_glyph_rune (&data, gb, side, 0, NULL);
2802 (reverse ? elt-- : elt++);
2805 if (data.max_pixmap_height)
2807 int height = data.new_ascent + data.new_descent;
2808 int pix_ascent, pix_descent;
2810 pix_descent = data.max_pixmap_height * data.new_descent / height;
2811 pix_ascent = data.max_pixmap_height - pix_descent;
2812 data.new_ascent = max (data.new_ascent, pix_ascent);
2813 data.new_descent = max (data.new_descent, pix_descent);
2816 dl->ascent = data.new_ascent;
2817 dl->descent = data.new_descent;
2822 /* Add a blank to a margin display block. */
2825 add_margin_blank (struct display_line *dl, struct display_block *db,
2826 struct window *w, int xpos, int width, int side)
2830 rb.findex = (side == LEFT_GLYPHS
2831 ? get_builtin_face_cache_index (w, Vleft_margin_face)
2832 : get_builtin_face_cache_index (w, Vright_margin_face));
2837 rb.type = RUNE_BLANK;
2838 rb.cursor_type = CURSOR_OFF;
2840 Dynarr_add (db->runes, rb);
2843 /* Display glyphs in the left outside margin, left inside margin and
2844 left whitespace area. */
2847 create_left_glyph_block (struct window *w, struct display_line *dl,
2852 int use_overflow = (NILP (w->use_left_overflow) ? 0 : 1);
2854 int out_end, in_out_start, in_in_end, white_out_start, white_in_start;
2855 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
2856 int left_in_start = dl->bounds.left_in;
2857 int left_in_end = dl->bounds.left_in + overlay_width;
2859 struct display_block *odb, *idb;
2861 XSETWINDOW (window, w);
2863 /* We have to add the glyphs to the line in the order outside,
2864 inside, whitespace. However the precedence dictates that we
2865 determine how many will fit in the reverse order. */
2867 /* Determine how many whitespace glyphs we can display and where
2868 they should start. */
2869 white_in_start = dl->bounds.left_white;
2870 white_out_start = left_in_start;
2871 white_out_cnt = white_in_cnt = 0;
2874 while (elt < Dynarr_length (dl->left_glyphs))
2876 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2878 if (NILP (gb->extent))
2879 abort (); /* these should have been handled in add_glyph_rune */
2881 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
2885 width = glyph_width (gb->glyph, window);
2887 if (white_in_start - width >= left_in_end)
2890 white_in_start -= width;
2894 else if (use_overflow
2895 && (white_out_start - width > dl->bounds.left_out))
2898 white_out_start -= width;
2909 /* Determine how many inside margin glyphs we can display and where
2910 they should start. The inside margin glyphs get whatever space
2911 is left after the whitespace glyphs have been displayed. These
2912 are tricky to calculate since if we decide to use the overflow
2913 area we basically have to start over. So for these we build up a
2914 list of just the inside margin glyphs and manipulate it to
2915 determine the needed info. */
2917 glyph_block_dynarr *ib;
2918 int avail_in, avail_out;
2921 int used_in, used_out;
2924 used_in = used_out = 0;
2925 ib = Dynarr_new (glyph_block);
2926 while (elt < Dynarr_length (dl->left_glyphs))
2928 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2930 if (NILP (gb->extent))
2931 abort (); /* these should have been handled in add_glyph_rune */
2933 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
2936 gb->width = glyph_width (gb->glyph, window);
2937 used_in += gb->width;
2938 Dynarr_add (ib, *gb);
2948 avail_in = white_in_start - left_in_end;
2956 avail_out = white_out_start - dl->bounds.left_out;
2959 while (!done && marker < Dynarr_length (ib))
2961 int width = Dynarr_atp (ib, marker)->width;
2963 /* If everything now fits in the available inside margin
2964 space, we're done. */
2965 if (used_in <= avail_in)
2969 /* Otherwise see if we have room to move a glyph to the
2971 if (used_out + width <= avail_out)
2984 /* At this point we now know that everything from marker on goes in
2985 the inside margin and everything before it goes in the outside
2986 margin. The stuff going into the outside margin is guaranteed
2987 to fit, but we may have to trim some stuff from the inside. */
2989 in_in_end = left_in_end;
2990 in_out_start = white_out_start;
2991 in_out_cnt = in_in_cnt = 0;
2995 while (elt < Dynarr_length (dl->left_glyphs))
2997 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2999 if (NILP (gb->extent))
3000 abort (); /* these should have been handled in add_glyph_rune */
3002 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3005 int width = glyph_width (gb->glyph, window);
3010 in_out_start -= width;
3015 else if (in_in_end + width < white_in_start)
3030 /* Determine how many outside margin glyphs we can display. They
3031 always start at the left outside margin and can only use the
3032 outside margin space. */
3033 out_end = dl->bounds.left_out;
3037 while (elt < Dynarr_length (dl->left_glyphs))
3039 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3041 if (NILP (gb->extent))
3042 abort (); /* these should have been handled in add_glyph_rune */
3044 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3047 int width = glyph_width (gb->glyph, window);
3049 if (out_end + width <= in_out_start)
3063 /* Now that we know where everything goes, we add the glyphs as
3064 runes to the appropriate display blocks. */
3065 if (out_cnt || in_out_cnt || white_out_cnt)
3067 odb = get_display_block_from_line (dl, LEFT_OUTSIDE_MARGIN);
3068 odb->start_pos = dl->bounds.left_out;
3069 /* #### We should stop adding a blank to account for the space
3070 between the end of the glyphs and the margin and instead set
3071 this accordingly. */
3072 odb->end_pos = dl->bounds.left_in;
3073 Dynarr_reset (odb->runes);
3078 if (in_in_cnt || white_in_cnt)
3080 idb = get_display_block_from_line (dl, LEFT_INSIDE_MARGIN);
3081 idb->start_pos = dl->bounds.left_in;
3082 /* #### See above comment for odb->end_pos */
3083 idb->end_pos = dl->bounds.left_white;
3084 Dynarr_reset (idb->runes);
3089 /* First add the outside margin glyphs. */
3091 end_xpos = add_margin_runes (dl, odb, dl->bounds.left_out, out_cnt,
3092 GL_OUTSIDE_MARGIN, LEFT_GLYPHS, window);
3094 end_xpos = dl->bounds.left_out;
3096 /* There may be blank space between the outside margin glyphs and
3097 the inside margin glyphs. If so, add a blank. */
3098 if (in_out_cnt && (in_out_start - end_xpos))
3100 add_margin_blank (dl, odb, w, end_xpos, in_out_start - end_xpos,
3104 /* Next add the inside margin glyphs which are actually in the
3108 end_xpos = add_margin_runes (dl, odb, in_out_start, in_out_cnt,
3109 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3112 /* If we didn't add any inside margin glyphs to the outside margin,
3113 but are adding whitespace glyphs, then we need to add a blank
3115 if (!in_out_cnt && white_out_cnt && (white_out_start - end_xpos))
3117 add_margin_blank (dl, odb, w, end_xpos, white_out_start - end_xpos,
3121 /* Next add the whitespace margin glyphs which are actually in the
3125 end_xpos = add_margin_runes (dl, odb, white_out_start, white_out_cnt,
3126 GL_WHITESPACE, LEFT_GLYPHS, window);
3129 /* We take care of clearing between the end of the glyphs and the
3130 start of the inside margin for lines which have glyphs. */
3131 if (odb && (left_in_start - end_xpos))
3133 add_margin_blank (dl, odb, w, end_xpos, left_in_start - end_xpos,
3137 /* Next add the inside margin glyphs which are actually in the
3141 end_xpos = add_margin_runes (dl, idb, left_in_end, in_in_cnt,
3142 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3145 end_xpos = left_in_end;
3147 /* Make sure that the area between the end of the inside margin
3148 glyphs and the whitespace glyphs is cleared. */
3149 if (idb && (white_in_start - end_xpos > 0))
3151 add_margin_blank (dl, idb, w, end_xpos, white_in_start - end_xpos,
3155 /* Next add the whitespace margin glyphs which are actually in the
3159 add_margin_runes (dl, idb, white_in_start, white_in_cnt, GL_WHITESPACE,
3160 LEFT_GLYPHS, window);
3163 /* Whitespace glyphs always end right next to the text block so
3164 there is nothing we have to make sure is cleared after them. */
3167 /* Display glyphs in the right outside margin, right inside margin and
3168 right whitespace area. */
3171 create_right_glyph_block (struct window *w, struct display_line *dl)
3175 int use_overflow = (NILP (w->use_right_overflow) ? 0 : 1);
3177 int out_start, in_out_end, in_in_start, white_out_end, white_in_end;
3178 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
3180 struct display_block *odb, *idb;
3182 XSETWINDOW (window, w);
3184 /* We have to add the glyphs to the line in the order outside,
3185 inside, whitespace. However the precedence dictates that we
3186 determine how many will fit in the reverse order. */
3188 /* Determine how many whitespace glyphs we can display and where
3189 they should start. */
3190 white_in_end = dl->bounds.right_white;
3191 white_out_end = dl->bounds.right_in;
3192 white_out_cnt = white_in_cnt = 0;
3195 while (elt < Dynarr_length (dl->right_glyphs))
3197 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3199 if (NILP (gb->extent))
3200 abort (); /* these should have been handled in add_glyph_rune */
3202 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
3204 int width = glyph_width (gb->glyph, window);
3206 if (white_in_end + width <= dl->bounds.right_in)
3209 white_in_end += width;
3213 else if (use_overflow
3214 && (white_out_end + width <= dl->bounds.right_out))
3217 white_out_end += width;
3228 /* Determine how many inside margin glyphs we can display and where
3229 they should start. The inside margin glyphs get whatever space
3230 is left after the whitespace glyphs have been displayed. These
3231 are tricky to calculate since if we decide to use the overflow
3232 area we basically have to start over. So for these we build up a
3233 list of just the inside margin glyphs and manipulate it to
3234 determine the needed info. */
3236 glyph_block_dynarr *ib;
3237 int avail_in, avail_out;
3240 int used_in, used_out;
3243 used_in = used_out = 0;
3244 ib = Dynarr_new (glyph_block);
3245 while (elt < Dynarr_length (dl->right_glyphs))
3247 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3249 if (NILP (gb->extent))
3250 abort (); /* these should have been handled in add_glyph_rune */
3252 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3254 gb->width = glyph_width (gb->glyph, window);
3255 used_in += gb->width;
3256 Dynarr_add (ib, *gb);
3265 avail_in = dl->bounds.right_in - white_in_end;
3270 avail_out = dl->bounds.right_out - white_out_end;
3273 while (!done && marker < Dynarr_length (ib))
3275 int width = Dynarr_atp (ib, marker)->width;
3277 /* If everything now fits in the available inside margin
3278 space, we're done. */
3279 if (used_in <= avail_in)
3283 /* Otherwise see if we have room to move a glyph to the
3285 if (used_out + width <= avail_out)
3298 /* At this point we now know that everything from marker on goes in
3299 the inside margin and everything before it goes in the outside
3300 margin. The stuff going into the outside margin is guaranteed
3301 to fit, but we may have to trim some stuff from the inside. */
3303 in_in_start = dl->bounds.right_in;
3304 in_out_end = dl->bounds.right_in;
3305 in_out_cnt = in_in_cnt = 0;
3309 while (elt < Dynarr_length (dl->right_glyphs))
3311 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3313 if (NILP (gb->extent))
3314 abort (); /* these should have been handled in add_glyph_rune */
3316 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3318 int width = glyph_width (gb->glyph, window);
3323 in_out_end += width;
3328 else if (in_in_start - width >= white_in_end)
3331 in_in_start -= width;
3343 /* Determine how many outside margin glyphs we can display. They
3344 always start at the right outside margin and can only use the
3345 outside margin space. */
3346 out_start = dl->bounds.right_out;
3350 while (elt < Dynarr_length (dl->right_glyphs))
3352 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3354 if (NILP (gb->extent))
3355 abort (); /* these should have been handled in add_glyph_rune */
3357 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_OUTSIDE_MARGIN)
3359 int width = glyph_width (gb->glyph, window);
3361 if (out_start - width >= in_out_end)
3375 /* Now that we now where everything goes, we add the glyphs as runes
3376 to the appropriate display blocks. */
3377 if (out_cnt || in_out_cnt || white_out_cnt)
3379 odb = get_display_block_from_line (dl, RIGHT_OUTSIDE_MARGIN);
3380 /* #### See comments before odb->start_pos init in
3381 create_left_glyph_block */
3382 odb->start_pos = dl->bounds.right_in;
3383 odb->end_pos = dl->bounds.right_out;
3384 Dynarr_reset (odb->runes);
3389 if (in_in_cnt || white_in_cnt)
3391 idb = get_display_block_from_line (dl, RIGHT_INSIDE_MARGIN);
3392 idb->start_pos = dl->bounds.right_white;
3393 /* #### See comments before odb->start_pos init in
3394 create_left_glyph_block */
3395 idb->end_pos = dl->bounds.right_in;
3396 Dynarr_reset (idb->runes);
3401 /* First add the whitespace margin glyphs which are actually in the
3405 end_xpos = add_margin_runes (dl, idb, dl->bounds.right_white,
3406 white_in_cnt, GL_WHITESPACE, RIGHT_GLYPHS,
3410 end_xpos = dl->bounds.right_white;
3412 /* Make sure that the area between the end of the whitespace glyphs
3413 and the inside margin glyphs is cleared. */
3414 if (in_in_cnt && (in_in_start - end_xpos))
3416 add_margin_blank (dl, idb, w, end_xpos, in_in_start - end_xpos,
3420 /* Next add the inside margin glyphs which are actually in the
3424 end_xpos = add_margin_runes (dl, idb, in_in_start, in_in_cnt,
3425 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3428 /* If we didn't add any inside margin glyphs then make sure the rest
3429 of the inside margin area gets cleared. */
3430 if (idb && (dl->bounds.right_in - end_xpos))
3432 add_margin_blank (dl, idb, w, end_xpos, dl->bounds.right_in - end_xpos,
3436 /* Next add any whitespace glyphs in the outside margin. */
3439 end_xpos = add_margin_runes (dl, odb, dl->bounds.right_in, white_out_cnt,
3440 GL_WHITESPACE, RIGHT_GLYPHS, window);
3443 end_xpos = dl->bounds.right_in;
3445 /* Next add any inside margin glyphs in the outside margin. */
3448 end_xpos = add_margin_runes (dl, odb, end_xpos, in_out_cnt,
3449 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3452 /* There may be space between any whitespace or inside margin glyphs
3453 in the outside margin and the actual outside margin glyphs. */
3454 if (odb && (out_start - end_xpos))
3456 add_margin_blank (dl, odb, w, end_xpos, out_start - end_xpos,
3460 /* Finally, add the outside margin glyphs. */
3463 add_margin_runes (dl, odb, out_start, out_cnt, GL_OUTSIDE_MARGIN,
3464 RIGHT_GLYPHS, window);
3469 /***************************************************************************/
3471 /* modeline routines */
3473 /***************************************************************************/
3475 /* This function is also used in frame.c by `generate_title_string' */
3477 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str,
3478 struct window *w, struct display_line *dl,
3479 struct display_block *db, face_index findex,
3480 int min_pixpos, int max_pixpos, int type)
3482 struct frame *f = XFRAME (w->frame);
3483 struct device *d = XDEVICE (f->device);
3487 Charcount offset = 0;
3493 data.findex = findex;
3494 data.pixpos = min_pixpos;
3495 data.max_pixpos = max_pixpos;
3496 data.cursor_type = NO_CURSOR;
3497 data.last_charset = Qunbound;
3498 data.last_findex = DEFAULT_INDEX;
3499 data.result_str = result_str;
3500 data.is_modeline = 1;
3502 XSETWINDOW (data.window, w);
3504 Dynarr_reset (formatted_string_extent_dynarr);
3505 Dynarr_reset (formatted_string_extent_start_dynarr);
3506 Dynarr_reset (formatted_string_extent_end_dynarr);
3508 /* result_str is nil when we're building a frame or icon title. Otherwise,
3509 we're building a modeline, so the offset starts at the modeline
3510 horizontal scrolling amount */
3511 if (! NILP (result_str))
3512 offset = w->modeline_hscroll;
3513 generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0,
3514 max_pixpos - min_pixpos, findex, type, &offset,
3517 if (Dynarr_length (db->runes))
3520 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
3521 c_pixpos = rb->xpos + rb->width;
3524 c_pixpos = min_pixpos;
3526 /* If we don't reach the right side of the window, add a blank rune
3527 to make up the difference. This usually only occurs if the
3528 modeline face is using a proportional width font or a fixed width
3529 font of a different size from the default face font. */
3531 if (c_pixpos < max_pixpos)
3533 data.pixpos = c_pixpos;
3534 data.blank_width = max_pixpos - data.pixpos;
3536 add_blank_rune (&data, NULL, 0);
3539 /* Now create the result string and frob the extents into it. */
3540 if (!NILP (result_str))
3545 struct buffer *buf = XBUFFER (WINDOW_BUFFER (w));
3547 in_modeline_generation = 1;
3549 detach_all_extents (result_str);
3550 resize_string (XSTRING (result_str), -1,
3551 data.bytepos - XSTRING_LENGTH (result_str));
3553 strdata = XSTRING_DATA (result_str);
3555 for (elt = 0, len = 0; elt < Dynarr_length (db->runes); elt++)
3557 if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR)
3559 len += (set_charptr_emchar
3561 CHARC_TO_CHAR (Dynarr_atp (db->runes,
3562 elt)->object.cglyph)));
3566 for (elt = 0; elt < Dynarr_length (formatted_string_extent_dynarr);
3569 Lisp_Object extent = Qnil;
3572 XSETEXTENT (extent, Dynarr_at (formatted_string_extent_dynarr, elt));
3573 child = Fgethash (extent, buf->modeline_extent_table, Qnil);
3576 child = Fmake_extent (Qnil, Qnil, result_str);
3577 Fputhash (extent, child, buf->modeline_extent_table);
3579 Fset_extent_parent (child, extent);
3580 set_extent_endpoints
3582 Dynarr_at (formatted_string_extent_start_dynarr, elt),
3583 Dynarr_at (formatted_string_extent_end_dynarr, elt),
3587 in_modeline_generation = 0;
3591 /* Ensure that the given display line DL accurately represents the
3592 modeline for the given window. */
3594 generate_modeline (struct window *w, struct display_line *dl, int type)
3596 struct buffer *b = XBUFFER (w->buffer);
3597 struct frame *f = XFRAME (w->frame);
3598 struct device *d = XDEVICE (f->device);
3600 /* Unlike display line and rune pointers, this one can't change underneath
3602 struct display_block *db = get_display_block_from_line (dl, TEXT);
3603 int max_pixpos, min_pixpos, ypos_adj;
3604 Lisp_Object font_inst;
3606 /* This will actually determine incorrect inside boundaries for the
3607 modeline since it ignores the margins. However being aware of this fact
3608 we never use those values anywhere so it doesn't matter. */
3609 dl->bounds = calculate_display_line_boundaries (w, 1);
3611 /* We are generating a modeline. */
3613 dl->cursor_elt = -1;
3615 /* Reset the runes on the modeline. */
3616 Dynarr_reset (db->runes);
3618 if (!WINDOW_HAS_MODELINE_P (w))
3622 /* If there is a horizontal scrollbar, don't add anything. */
3623 if (window_scrollbar_height (w))
3626 dl->ascent = DEVMETH (d, divider_height, ());
3628 /* The modeline is at the bottom of the gutters. */
3629 dl->ypos = WINDOW_BOTTOM (w);
3631 rb.findex = MODELINE_INDEX;
3632 rb.xpos = dl->bounds.left_out;
3633 rb.width = dl->bounds.right_out - dl->bounds.left_out;
3636 rb.type = RUNE_HLINE;
3637 rb.object.hline.thickness = 1;
3638 rb.object.hline.yoffset = 0;
3639 rb.cursor_type = NO_CURSOR;
3641 if (!EQ (Qzero, w->modeline_shadow_thickness)
3644 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3646 dl->ypos -= shadow_thickness;
3647 rb.xpos += shadow_thickness;
3648 rb.width -= 2 * shadow_thickness;
3651 Dynarr_add (db->runes, rb);
3655 /* !!#### not right; needs to compute the max height of
3657 font_inst = WINDOW_FACE_CACHEL_FONT (w, MODELINE_INDEX, Vcharset_ascii);
3659 dl->ascent = XFONT_INSTANCE (font_inst)->ascent;
3660 dl->descent = XFONT_INSTANCE (font_inst)->descent;
3662 min_pixpos = dl->bounds.left_out;
3663 max_pixpos = dl->bounds.right_out;
3665 if (!EQ (Qzero, w->modeline_shadow_thickness) && FRAME_WIN_P (f))
3667 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3669 ypos_adj = shadow_thickness;
3670 min_pixpos += shadow_thickness;
3671 max_pixpos -= shadow_thickness;
3676 generate_formatted_string_db (b->modeline_format,
3677 b->generated_modeline_string, w, dl, db,
3678 MODELINE_INDEX, min_pixpos, max_pixpos, type);
3680 /* The modeline is at the bottom of the gutters. We have to wait to
3681 set this until we've generated the modeline in order to account
3682 for any embedded faces. */
3683 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj;
3687 add_string_to_fstring_db_runes (pos_data *data, const Bufbyte *str,
3688 Charcount pos, Charcount min_pos, Charcount max_pos)
3690 /* This function has been Mule-ized. */
3692 const Bufbyte *cur_pos = str;
3693 struct display_block *db = data->db;
3695 data->blank_width = space_width (XWINDOW (data->window));
3696 while (Dynarr_length (db->runes) < pos)
3697 add_blank_rune (data, NULL, 0);
3699 end = (Dynarr_length (db->runes) +
3700 bytecount_to_charcount (str, strlen ((const char *) str)));
3702 end = min (max_pos, end);
3704 while (pos < end && *cur_pos)
3706 const Bufbyte *old_cur_pos = cur_pos;
3709 data->ch = charptr_emchar (cur_pos);
3710 succeeded = (add_emchar_rune (data) != ADD_FAILED);
3711 INC_CHARPTR (cur_pos);
3715 data->modeline_charpos++;
3716 data->bytepos += cur_pos - old_cur_pos;
3720 while (Dynarr_length (db->runes) < min_pos &&
3721 (data->pixpos + data->blank_width <= data->max_pixpos))
3722 add_blank_rune (data, NULL, 0);
3724 return Dynarr_length (db->runes);
3727 /* #### Urk! Should also handle begin-glyphs and end-glyphs in
3728 modeline extents. */
3730 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph,
3731 Charcount pos, Charcount min_pos,
3732 Charcount max_pos, Lisp_Object extent)
3734 /* This function has been Mule-ized. */
3736 struct display_block *db = data->db;
3737 struct glyph_block gb;
3739 data->blank_width = space_width (XWINDOW (data->window));
3740 while (Dynarr_length (db->runes) < pos)
3741 add_blank_rune (data, NULL, 0);
3743 end = Dynarr_length (db->runes) + 1;
3745 end = min (max_pos, end);
3749 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
3752 while (Dynarr_length (db->runes) < pos &&
3753 (data->pixpos + data->blank_width <= data->max_pixpos))
3754 add_blank_rune (data, NULL, 0);
3756 return Dynarr_length (db->runes);
3759 /* If max_pos is == -1, it is considered to be infinite. The same is
3760 true of max_pixsize. */
3761 #define SET_CURRENT_MODE_CHARS_PIXSIZE \
3762 if (Dynarr_length (data->db->runes)) \
3763 cur_pixsize = data->pixpos - Dynarr_atp (data->db->runes, 0)->xpos; \
3767 /* Note that this function does "positions" in terms of characters and
3768 not in terms of columns. This is necessary to make the formatting
3769 work correctly when proportional width fonts are used in the
3772 generate_fstring_runes (struct window *w, pos_data *data, Charcount pos,
3773 Charcount min_pos, Charcount max_pos,
3774 Lisp_Object elt, int depth, int max_pixsize,
3775 face_index findex, int type, Charcount *offset,
3776 Lisp_Object cur_ext)
3778 /* This function has been Mule-ized. */
3779 /* #### The other losing things in this function are:
3781 -- C zero-terminated-string lossage.
3782 -- Non-printable characters should be converted into something
3783 appropriate (e.g. ^F) instead of blindly being printed anyway.
3794 /* A string. Add to the display line and check for %-constructs
3797 Bufbyte *this = XSTRING_DATA (elt);
3799 while ((pos < max_pos || max_pos == -1) && *this)
3801 Bufbyte *last = this;
3803 while (*this && *this != '%')
3808 /* No %-construct */
3810 bytecount_to_charcount (last, this - last);
3812 if (size <= *offset)
3816 Charcount tmp_max = (max_pos == -1 ? pos + size - *offset :
3817 min (pos + size - *offset, max_pos));
3818 const Bufbyte *tmp_last = charptr_n_addr (last, *offset);
3820 pos = add_string_to_fstring_db_runes (data, tmp_last,
3825 else /* *this == '%' */
3827 Charcount spec_width = 0;
3829 this++; /* skip over '%' */
3831 /* We can't allow -ve args due to the "%-" construct.
3832 * Argument specifies minwidth but not maxwidth
3833 * (maxwidth can be specified by
3834 * (<negative-number> . <stuff>) modeline elements)
3836 while (isdigit (*this))
3838 spec_width = spec_width * 10 + (*this - '0');
3845 pos = generate_fstring_runes (w, data, pos, spec_width,
3846 max_pos, Vglobal_mode_string,
3847 depth, max_pixsize, findex,
3848 type, offset, cur_ext);
3850 else if (*this == '-')
3852 Charcount num_to_add;
3854 if (max_pixsize < 0)
3856 else if (max_pos != -1)
3857 num_to_add = max_pos - pos;
3863 SET_CURRENT_MODE_CHARS_PIXSIZE;
3866 redisplay_text_width_string (w, findex, &ch, Qnil, 0,
3869 num_to_add = (max_pixsize - cur_pixsize) / dash_pixsize;
3873 while (num_to_add--)
3874 pos = add_string_to_fstring_db_runes
3875 (data, (const Bufbyte *) "-", pos, pos, max_pos);
3877 else if (*this != 0)
3879 Emchar ch = charptr_emchar (this);
3883 decode_mode_spec (w, ch, type);
3885 str = Dynarr_atp (mode_spec_bufbyte_string, 0);
3886 size = bytecount_to_charcount
3887 /* Skip the null character added by `decode_mode_spec' */
3888 (str, Dynarr_length (mode_spec_bufbyte_string)) - 1;
3890 if (size <= *offset)
3894 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3896 /* #### NOTE: I don't understand why a tmp_max is not
3897 computed and used here as in the plain string case
3899 pos = add_string_to_fstring_db_runes (data, tmp_str,
3906 /* NOT this++. There could be any sort of character at
3907 the current position. */
3911 if (max_pixsize > 0)
3914 SET_CURRENT_MODE_CHARS_PIXSIZE;
3916 if (cur_pixsize >= max_pixsize)
3921 else if (SYMBOLP (elt))
3923 /* A symbol: process the value of the symbol recursively
3924 as if it appeared here directly. */
3925 Lisp_Object tem = symbol_value_in_buffer (elt, w->buffer);
3927 if (!UNBOUNDP (tem))
3929 /* If value is a string, output that string literally:
3930 don't check for % within it. */
3933 Bufbyte *str = XSTRING_DATA (tem);
3934 Charcount size = XSTRING_CHAR_LENGTH (tem);
3936 if (size <= *offset)
3940 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3942 /* #### NOTE: I don't understand why a tmp_max is not
3943 computed and used here as in the plain string case
3945 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
3950 /* Give up right away for nil or t. */
3951 else if (!EQ (tem, elt))
3958 else if (GENERIC_SPECIFIERP (elt))
3960 Lisp_Object window, tem;
3961 XSETWINDOW (window, w);
3962 tem = specifier_instance_no_quit (elt, Qunbound, window,
3963 ERROR_ME_NOT, 0, Qzero);
3964 if (!UNBOUNDP (tem))
3970 else if (CONSP (elt))
3972 /* A cons cell: four distinct cases.
3973 * - If first element is a string or a cons, process all the elements
3974 * and effectively concatenate them.
3975 * - If first element is a negative number, truncate displaying cdr to
3976 * at most that many characters. If positive, pad (with spaces)
3977 * to at least that many characters.
3978 * - If first element is another symbol, process the cadr or caddr
3979 * recursively according to whether the symbol's value is non-nil or
3981 * - If first element is an extent, process the cdr recursively
3982 * and handle the extent's face.
3985 Lisp_Object car, tem;
3994 tem = symbol_value_in_buffer (car, w->buffer);
3995 /* elt is now the cdr, and we know it is a cons cell.
3996 Use its car if CAR has a non-nil value. */
3997 if (!UNBOUNDP (tem))
4005 /* Symbol's value is nil (or symbol is unbound)
4006 * Get the cddr of the original list
4007 * and if possible find the caddr and use that.
4012 else if (!CONSP (elt))
4020 else if (INTP (car))
4022 Charcount lim = XINT (car);
4028 /* Negative int means reduce maximum width.
4029 * DO NOT change MIN_PIXPOS here!
4030 * (20 -10 . foo) should truncate foo to 10 col
4031 * and then pad to 20.
4034 max_pos = pos - lim;
4036 max_pos = min (max_pos, pos - lim);
4040 /* Padding specified. Don't let it be more than
4044 if (max_pos != -1 && lim > max_pos)
4046 /* If that's more padding than already wanted, queue it.
4047 * But don't reduce padding already specified even if
4048 * that is beyond the current truncation point.
4055 else if (STRINGP (car) || CONSP (car))
4059 /* LIMIT is to protect against circular lists. */
4060 while (CONSP (elt) && --limit > 0
4061 && (pos < max_pos || max_pos == -1))
4063 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4064 XCAR (elt), depth, max_pixsize,
4065 findex, type, offset, cur_ext);
4069 else if (EXTENTP (car))
4071 struct extent *ext = XEXTENT (car);
4073 if (EXTENT_LIVE_P (ext))
4075 face_index old_findex = data->findex;
4077 Lisp_Object font_inst;
4078 face_index new_findex;
4079 Bytecount start = data->bytepos;
4081 face = extent_face (ext);
4084 /* #### needs to merge faces, sigh */
4085 /* #### needs to handle list of faces */
4086 new_findex = get_builtin_face_cache_index (w, face);
4087 /* !!#### not right; needs to compute the max height of
4089 font_inst = WINDOW_FACE_CACHEL_FONT (w, new_findex,
4092 data->dl->ascent = max (data->dl->ascent,
4093 XFONT_INSTANCE (font_inst)->ascent);
4094 data->dl->descent = max (data->dl->descent,
4095 XFONT_INSTANCE (font_inst)->
4099 new_findex = old_findex;
4101 data->findex = new_findex;
4102 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4103 XCDR (elt), depth - 1,
4104 max_pixsize, new_findex, type,
4106 data->findex = old_findex;
4107 Dynarr_add (formatted_string_extent_dynarr, ext);
4108 Dynarr_add (formatted_string_extent_start_dynarr, start);
4109 Dynarr_add (formatted_string_extent_end_dynarr, data->bytepos);
4113 else if (GLYPHP (elt))
4115 /* Glyphs are considered as one character with respect to the modeline
4116 horizontal scrolling facility. -- dv */
4120 pos = add_glyph_to_fstring_db_runes (data, elt, pos, pos, max_pos,
4127 char *str = GETTEXT ("*invalid*");
4128 Charcount size = (Charcount) strlen (str); /* is this ok ?? -- dv */
4130 if (size <= *offset)
4134 const Bufbyte *tmp_str =
4135 charptr_n_addr ((const Bufbyte *) str, *offset);
4137 /* #### NOTE: I don't understand why a tmp_max is not computed and
4138 used here as in the plain string case above. -- dv */
4139 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
4148 add_string_to_fstring_db_runes (data, (const Bufbyte *) "", pos,
4155 /* Update just the modeline. Assumes the desired display structs. If
4156 they do not have a modeline block, it does nothing. */
4158 regenerate_modeline (struct window *w)
4160 display_line_dynarr *dla = window_display_lines (w, DESIRED_DISP);
4162 if (!Dynarr_length (dla) || !Dynarr_atp (dla, 0)->modeline)
4166 generate_modeline (w, Dynarr_atp (dla, 0), DESIRED_DISP);
4167 redisplay_update_line (w, 0, 0, 0);
4171 /* Make sure that modeline display line is present in the given
4172 display structs if the window has a modeline and update that
4173 line. Returns true if a modeline was needed. */
4175 ensure_modeline_generated (struct window *w, int type)
4179 /* minibuffer windows don't have modelines */
4180 if (MINI_WINDOW_P (w))
4182 /* windows which haven't had it turned off do */
4183 else if (WINDOW_HAS_MODELINE_P (w))
4185 /* windows which have it turned off don't have a divider if there is
4186 a horizontal scrollbar */
4187 else if (window_scrollbar_height (w))
4189 /* and in this case there is none */
4195 display_line_dynarr *dla;
4197 dla = window_display_lines (w, type);
4199 /* We don't care if there is a display line which is not
4200 currently a modeline because it is definitely going to become
4201 one if we have gotten to this point. */
4202 if (Dynarr_length (dla) == 0)
4204 if (Dynarr_largest (dla) > 0)
4206 struct display_line *mlp = Dynarr_atp (dla, 0);
4207 Dynarr_add (dla, *mlp);
4211 struct display_line modeline;
4213 Dynarr_add (dla, modeline);
4217 /* If we're adding a new place marker go ahead and generate the
4218 modeline so that it is available for use by
4219 window_modeline_height. */
4220 generate_modeline (w, Dynarr_atp (dla, 0), type);
4223 return need_modeline;
4226 /* #### Kludge or not a kludge. I tend towards the former. */
4228 real_current_modeline_height (struct window *w)
4230 Fset_marker (w->start[CMOTION_DISP], w->start[CURRENT_DISP], w->buffer);
4231 Fset_marker (w->pointm[CMOTION_DISP], w->pointm[CURRENT_DISP], w->buffer);
4233 if (ensure_modeline_generated (w, CMOTION_DISP))
4235 display_line_dynarr *dla = window_display_lines (w, CMOTION_DISP);
4237 if (Dynarr_length (dla))
4239 if (Dynarr_atp (dla, 0)->modeline)
4240 return (Dynarr_atp (dla, 0)->ascent +
4241 Dynarr_atp (dla, 0)->descent);
4248 /***************************************************************************/
4250 /* displayable string routines */
4252 /***************************************************************************/
4254 /* Given a position for a string in a window, ensure that the given
4255 display line DL accurately represents the text on a line starting
4256 at the given position.
4258 Yes, this is duplicating the code of create_text_block, but it
4259 looked just too hard to change create_text_block to handle strings
4260 *and* buffers. We already make a distinction between the two
4261 elsewhere in the code so I think unifying them would require a
4262 complete MULE rewrite. Besides, the other distinction is that these
4263 functions cover text that the user *cannot edit* so we can remove
4264 everything to do with cursors, minibuffers etc. Eventually the
4265 modeline routines should be modified to use this code as it copes
4266 with many more types of display situation. */
4269 create_string_text_block (struct window *w, Lisp_Object disp_string,
4270 struct display_line *dl,
4272 prop_block_dynarr **prop,
4273 face_index default_face)
4275 struct frame *f = XFRAME (w->frame);
4276 /* Note that a lot of the buffer controlled stuff has been left in
4277 because you might well want to make use of it (selective display
4278 etc), its just the buffer text that we do not use. However, it
4279 seems to be possible for buffer to be nil sometimes so protect
4280 against this case. */
4281 struct buffer *b = BUFFERP (w->buffer) ? XBUFFER (w->buffer) : 0;
4282 struct device *d = XDEVICE (f->device);
4283 Lisp_String* s = XSTRING (disp_string);
4285 /* we're working with these a lot so precalculate them */
4286 Bytecount slen = XSTRING_LENGTH (disp_string);
4287 Bytecount bi_string_zv = slen;
4288 Bytind bi_start_pos = charcount_to_bytecount (string_data (s), start_pos);
4292 int truncate_win = b ? window_truncation_on (w) : 0;
4293 int end_glyph_width = 0;
4295 /* We're going to ditch selective display for static text, it's an
4296 FSF thing and invisible extents are the way to go here.
4297 Implementing it also relies on a number of buffer-specific
4298 functions that we don't have the luxury of being able to use
4301 /* The variable ctl-arrow allows the user to specify what characters
4302 can actually be displayed and which octal should be used for.
4303 #### This variable should probably have some rethought done to
4306 #### It would also be really nice if you could specify that
4307 the characters come out in hex instead of in octal. Mule
4308 does that by adding a ctl-hexa variable similar to ctl-arrow,
4309 but that's bogus -- we need a more general solution. I
4310 think you need to extend the concept of display tables
4311 into a more general conversion mechanism. Ideally you
4312 could specify a Lisp function that converts characters,
4313 but this violates the Second Golden Rule and besides would
4314 make things way way way way slow.
4316 So instead, we extend the display-table concept, which was
4317 historically limited to 256-byte vectors, to one of the
4320 a) A 256-entry vector, for backward compatibility;
4321 b) char-table, mapping characters to values;
4322 c) range-table, mapping ranges of characters to values;
4323 d) a list of the above.
4325 The (d) option allows you to specify multiple display tables
4326 instead of just one. Each display table can specify conversions
4327 for some characters and leave others unchanged. The way the
4328 character gets displayed is determined by the first display table
4329 with a binding for that character. This way, you could call a
4330 function `enable-hex-display' that adds a hex display-table to
4331 the list of display tables for the current buffer.
4333 #### ...not yet implemented... Also, we extend the concept of
4334 "mapping" to include a printf-like spec. Thus you can make all
4335 extended characters show up as hex with a display table like
4338 #s(range-table data ((256 524288) (format "%x")))
4340 Since more than one display table is possible, you have
4341 great flexibility in mapping ranges of characters. */
4342 Emchar printable_min = b ? (CHAR_OR_CHAR_INTP (b->ctl_arrow)
4343 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
4344 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
4345 ? 255 : 160)) : 255;
4347 Lisp_Object face_dt, window_dt;
4349 /* The text display block for this display line. */
4350 struct display_block *db = get_display_block_from_line (dl, TEXT);
4352 /* The first time through the main loop we need to force the glyph
4353 data to be updated. */
4356 /* Apparently the new extent_fragment_update returns an end position
4357 equal to the position passed in if there are no more runs to be
4359 int no_more_frags = 0;
4361 dl->used_prop_data = 0;
4363 dl->line_continuation = 0;
4365 /* set up faces to use for clearing areas, used by
4366 output_display_line */
4367 dl->default_findex = default_face;
4370 dl->left_margin_findex = default_face;
4371 dl->right_margin_findex = default_face;
4375 dl->left_margin_findex =
4376 get_builtin_face_cache_index (w, Vleft_margin_face);
4377 dl->right_margin_findex =
4378 get_builtin_face_cache_index (w, Vright_margin_face);
4382 data.ef = extent_fragment_new (disp_string, f);
4384 /* These values are used by all of the rune addition routines. We add
4385 them to this structure for ease of passing. */
4387 XSETWINDOW (data.window, w);
4391 data.bi_bufpos = bi_start_pos;
4392 data.pixpos = dl->bounds.left_in;
4393 data.last_charset = Qunbound;
4394 data.last_findex = default_face;
4395 data.result_str = Qnil;
4396 data.string = disp_string;
4398 /* Set the right boundary adjusting it to take into account any end
4399 glyph. Save the width of the end glyph for later use. */
4400 data.max_pixpos = dl->bounds.right_in;
4403 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
4405 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
4407 data.max_pixpos -= end_glyph_width;
4409 data.cursor_type = NO_CURSOR;
4413 /* I don't think we want this, string areas should not scroll with
4415 data.start_col = w->hscroll;
4416 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
4418 data.bi_start_col_enabled = 0;
4419 data.hscroll_glyph_width_adjust = 0;
4421 /* We regenerate the line from the very beginning. */
4422 Dynarr_reset (db->runes);
4424 /* Why is this less than or equal and not just less than? If the
4425 starting position is already equal to the maximum we can't add
4426 anything else, right? Wrong. We might still have a newline to
4427 add. A newline can use the room allocated for an end glyph since
4428 if we add it we know we aren't going to be adding any end
4431 /* #### Chuck -- I think this condition should be while (1).
4432 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
4433 and the begin-glyph ends exactly at the end of the window, the
4434 end-glyph and text might not be displayed. while (1) ensures
4435 that the loop terminates only when either (a) there is
4436 propagation data or (b) the end-of-line or end-of-buffer is hit.
4438 #### Also I think you need to ensure that the operation
4439 "add begin glyphs; add end glyphs; add text" is atomic and
4440 can't get interrupted in the middle. If you run off the end
4441 of the line during that operation, then you keep accumulating
4442 propagation data until you're done. Otherwise, if the (e.g.)
4443 there's a begin glyph at a particular position and attempting
4444 to display that glyph results in window-end being hit and
4445 propagation data being generated, then the character at that
4446 position won't be displayed.
4448 #### See also the comment after the end of this loop, below.
4450 while (data.pixpos <= data.max_pixpos)
4452 /* #### This check probably should not be necessary. */
4453 if (data.bi_bufpos > bi_string_zv)
4455 /* #### urk! More of this lossage! */
4460 /* Check for face changes. */
4461 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
4463 /* Now compute the face and begin/end-glyph information. */
4465 /* Remember that the extent-fragment routines deal in Bytind's. */
4466 extent_fragment_update (w, data.ef, data.bi_bufpos);
4467 /* This is somewhat cheesy but the alternative is to
4468 propagate default_face into extent_fragment_update. */
4469 if (data.findex == DEFAULT_INDEX)
4470 data.findex = default_face;
4472 get_display_tables (w, data.findex, &face_dt, &window_dt);
4474 if (data.bi_bufpos == data.ef->end)
4479 /* Determine what is next to be displayed. We first handle any
4480 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
4481 display then we determine what to do based on the character at the
4482 current buffer position. */
4484 /* If the current position is covered by an invisible extent, do
4485 nothing (except maybe add some ellipses).
4487 #### The behavior of begin and end-glyphs at the edge of an
4488 invisible extent should be investigated further. This is
4489 fairly low priority though. */
4490 if (data.ef->invisible)
4492 /* #### Chuck, perhaps you could look at this code? I don't
4493 really know what I'm doing. */
4496 Dynarr_free (*prop);
4500 /* The extent fragment code only sets this when we should
4501 really display the ellipses. It makes sure the ellipses
4502 don't get displayed more than once in a row. */
4503 if (data.ef->invisible_ellipses)
4505 struct glyph_block gb;
4507 data.ef->invisible_ellipses_already_displayed = 1;
4508 data.ef->invisible_ellipses = 0;
4510 gb.glyph = Vinvisible_text_glyph;
4511 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
4512 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
4513 /* Perhaps they shouldn't propagate if the very next thing
4514 is to display a newline (for compatibility with
4515 selective-display-ellipses)? Maybe that's too
4521 /* #### What if we we're dealing with a display table? */
4525 if (data.bi_bufpos == bi_string_zv)
4528 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4531 /* If there is propagation data, then it represents the current
4532 buffer position being displayed. Add them and advance the
4533 position counter. This might also add the minibuffer
4537 dl->used_prop_data = 1;
4538 *prop = add_propagation_runes (prop, &data);
4541 goto done; /* gee, a really narrow window */
4542 else if (data.bi_bufpos == bi_string_zv)
4544 else if (data.bi_bufpos < 0)
4545 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
4548 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4551 /* If there are end glyphs, add them to the line. These are
4552 the end glyphs for the previous run of text. We add them
4553 here rather than doing them at the end of handling the
4554 previous run so that glyphs at the beginning and end of
4555 a line are handled correctly. */
4556 else if (Dynarr_length (data.ef->end_glyphs) > 0)
4558 *prop = add_glyph_runes (&data, END_GLYPHS);
4563 /* If there are begin glyphs, add them to the line. */
4564 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
4566 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
4571 /* If at end-of-buffer, we've already processed begin and
4572 end-glyphs at this point and there's no text to process,
4574 else if (data.bi_bufpos == bi_string_zv)
4579 Lisp_Object entry = Qnil;
4580 /* Get the character at the current buffer position. */
4581 data.ch = string_char (s, data.bi_bufpos);
4582 if (!NILP (face_dt) || !NILP (window_dt))
4583 entry = display_table_entry (data.ch, face_dt, window_dt);
4585 /* If there is a display table entry for it, hand it off to
4586 add_disp_table_entry_runes and let it worry about it. */
4587 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
4589 *prop = add_disp_table_entry_runes (&data, entry);
4595 /* Check if we have hit a newline character. If so, add a marker
4596 to the line and end this loop. */
4597 else if (data.ch == '\n')
4599 /* We aren't going to be adding an end glyph so give its
4600 space back in order to make sure that the cursor can
4602 data.max_pixpos += end_glyph_width;
4606 /* If the current character is considered to be printable, then
4608 else if (data.ch >= printable_min)
4610 *prop = add_emchar_rune (&data);
4615 /* If the current character is a tab, determine the next tab
4616 starting position and add a blank rune which extends from the
4617 current pixel position to that starting position. */
4618 else if (data.ch == '\t')
4620 int tab_start_pixpos = data.pixpos;
4625 if (data.start_col > 1)
4626 tab_start_pixpos -= (space_width (w) * (data.start_col - 1));
4629 next_tab_position (w, tab_start_pixpos,
4630 dl->bounds.left_in +
4631 data.hscroll_glyph_width_adjust);
4632 if (next_tab_start > data.max_pixpos)
4634 prop_width = next_tab_start - data.max_pixpos;
4635 next_tab_start = data.max_pixpos;
4637 data.blank_width = next_tab_start - data.pixpos;
4639 (next_tab_start - tab_start_pixpos) / space_width (w);
4641 *prop = add_blank_rune (&data, w, char_tab_width);
4643 /* add_blank_rune is only supposed to be called with
4644 sizes guaranteed to fit in the available space. */
4649 struct prop_block pb;
4650 *prop = Dynarr_new (prop_block);
4652 pb.type = PROP_BLANK;
4653 pb.data.p_blank.width = prop_width;
4654 pb.data.p_blank.findex = data.findex;
4655 Dynarr_add (*prop, pb);
4661 /* If character is a control character, pass it off to
4662 add_control_char_runes.
4664 The is_*() routines have undefined results on
4665 arguments outside of the range [-1, 255]. (This
4666 often bites people who carelessly use `char' instead
4667 of `unsigned char'.)
4669 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
4671 *prop = add_control_char_runes (&data, b);
4677 /* If the character is above the ASCII range and we have not
4678 already handled it, then print it as an octal number. */
4679 else if (data.ch >= 0200)
4681 *prop = add_octal_runes (&data);
4687 /* Assume the current character is considered to be printable,
4688 then just add it. */
4691 *prop = add_emchar_rune (&data);
4696 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4702 /* Determine the starting point of the next line if we did not hit the
4703 end of the buffer. */
4704 if (data.bi_bufpos < bi_string_zv)
4706 /* #### This check is not correct. If the line terminated
4707 due to a begin-glyph or end-glyph hitting window-end, then
4708 data.ch will not point to the character at data.bi_bufpos. If
4709 you make the two changes mentioned at the top of this loop,
4710 you should be able to say '(if (*prop))'. That should also
4711 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
4714 /* The common case is that the line ended because we hit a newline.
4715 In that case, the next character is just the next buffer
4717 if (data.ch == '\n')
4719 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4722 /* Otherwise we have a buffer line which cannot fit on one display
4726 struct glyph_block gb;
4727 struct glyph_cachel *cachel;
4729 /* If the line is to be truncated then we actually have to look
4730 for the next newline. We also add the end-of-line glyph which
4731 we know will fit because we adjusted the right border before
4732 we starting laying out the line. */
4733 data.max_pixpos += end_glyph_width;
4734 data.findex = default_face;
4741 /* Now find the start of the next line. */
4742 bi_pos = bi_find_next_emchar_in_string (s, '\n', data.bi_bufpos, 1);
4744 data.cursor_type = NO_CURSOR;
4745 data.bi_bufpos = bi_pos;
4746 gb.glyph = Vtruncation_glyph;
4747 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
4751 /* The cursor can never be on the continuation glyph. */
4752 data.cursor_type = NO_CURSOR;
4754 /* data.bi_bufpos is already at the start of the next line. */
4756 dl->line_continuation = 1;
4757 gb.glyph = Vcontinuation_glyph;
4758 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
4761 if (end_glyph_width)
4762 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
4764 if (truncate_win && data.bi_bufpos == bi_string_zv)
4766 const Bufbyte* endb = charptr_n_addr (string_data (s), bi_string_zv);
4768 if (charptr_emchar (endb) != '\n')
4770 /* #### Damn this losing shit. */
4776 else if (data.bi_bufpos == bi_string_zv)
4778 /* create_text_block () adds a bogus \n marker here which screws
4779 up subwindow display. Since we never have a cursor in the
4780 gutter we can safely ignore it. */
4782 /* Calculate left whitespace boundary. */
4786 /* Whitespace past a newline is considered right whitespace. */
4787 while (elt < Dynarr_length (db->runes))
4789 struct rune *rb = Dynarr_atp (db->runes, elt);
4791 if ((rb->type == RUNE_CHAR && CHARC_ASCII_EQ (rb->object.cglyph, ' '))
4792 || rb->type == RUNE_BLANK)
4794 dl->bounds.left_white += rb->width;
4798 elt = Dynarr_length (db->runes);
4802 /* Calculate right whitespace boundary. */
4804 int elt = Dynarr_length (db->runes) - 1;
4807 while (!done && elt >= 0)
4809 struct rune *rb = Dynarr_atp (db->runes, elt);
4811 if (!(rb->type == RUNE_CHAR && CHARC_IS_SPACE (rb->object.cglyph))
4812 && !rb->type == RUNE_BLANK)
4814 dl->bounds.right_white = rb->xpos + rb->width;
4822 /* The line is blank so everything is considered to be right
4825 dl->bounds.right_white = dl->bounds.left_in;
4828 /* Set the display blocks bounds. */
4829 db->start_pos = dl->bounds.left_in;
4830 if (Dynarr_length (db->runes))
4832 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
4834 db->end_pos = rb->xpos + rb->width;
4837 db->end_pos = dl->bounds.right_white;
4839 /* update line height parameters */
4840 if (!data.new_ascent && !data.new_descent)
4842 /* We've got a blank line so initialize these values from the default
4844 default_face_font_info (data.window, &data.new_ascent,
4845 &data.new_descent, 0, 0, 0);
4848 if (data.max_pixmap_height)
4850 int height = data.new_ascent + data.new_descent;
4851 int pix_ascent, pix_descent;
4853 pix_descent = data.max_pixmap_height * data.new_descent / height;
4854 pix_ascent = data.max_pixmap_height - pix_descent;
4856 data.new_ascent = max (data.new_ascent, pix_ascent);
4857 data.new_descent = max (data.new_descent, pix_descent);
4860 dl->ascent = data.new_ascent;
4861 dl->descent = data.new_descent;
4864 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
4866 if (dl->ascent < ascent)
4867 dl->ascent = ascent;
4870 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
4872 if (dl->descent < descent)
4873 dl->descent = descent;
4876 dl->cursor_elt = data.cursor_x;
4877 /* #### lossage lossage lossage! Fix this shit! */
4878 if (data.bi_bufpos > bi_string_zv)
4879 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, bi_string_zv);
4881 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, data.bi_bufpos) - 1;
4883 data.dl->num_chars =
4884 string_column_at_point (s, dl->end_bufpos, b ? XINT (b->tab_width) : 8);
4886 /* This doesn't correctly take into account tabs and control
4887 characters but if the window isn't being truncated then this
4888 value isn't going to end up being used anyhow. */
4889 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
4891 /* #### handle horizontally scrolled line with text none of which
4892 was actually laid out. */
4894 /* #### handle any remainder of overlay arrow */
4896 if (*prop == ADD_FAILED)
4899 if (truncate_win && *prop)
4901 Dynarr_free (*prop);
4905 extent_fragment_delete (data.ef);
4907 /* #### If we started at EOB, then make sure we return a value past
4908 it so that regenerate_window will exit properly. This is bogus.
4909 The main loop should get fixed so that it isn't necessary to call
4910 this function if we are already at EOB. */
4912 if (data.bi_bufpos == bi_string_zv && bi_start_pos == bi_string_zv)
4913 return bytecount_to_charcount (string_data (s), data.bi_bufpos) + 1; /* Yuck! */
4915 return bytecount_to_charcount (string_data (s), data.bi_bufpos);
4918 /* Given a display line and a starting position, ensure that the
4919 contents of the display line accurately represent the visual
4920 representation of the buffer contents starting from the given
4921 position when displayed in the given window. The display line ends
4922 when the contents of the line reach the right boundary of the given
4925 This is very similar to generate_display_line but with the same
4926 limitations as create_string_text_block. I have taken the liberty
4927 of fixing the bytind stuff though.*/
4930 generate_string_display_line (struct window *w, Lisp_Object disp_string,
4931 struct display_line *dl,
4933 prop_block_dynarr **prop,
4934 face_index default_face)
4938 /* you must set bounds before calling this. */
4940 /* Reset what this line is using. */
4941 if (dl->display_blocks)
4942 Dynarr_reset (dl->display_blocks);
4943 if (dl->left_glyphs)
4945 Dynarr_free (dl->left_glyphs);
4946 dl->left_glyphs = 0;
4948 if (dl->right_glyphs)
4950 Dynarr_free (dl->right_glyphs);
4951 dl->right_glyphs = 0;
4954 /* We aren't generating a modeline at the moment. */
4957 /* Create a display block for the text region of the line. */
4958 ret_bufpos = create_string_text_block (w, disp_string, dl, start_pos,
4959 prop, default_face);
4960 dl->bufpos = start_pos;
4961 if (dl->end_bufpos < dl->bufpos)
4962 dl->end_bufpos = dl->bufpos;
4964 /* If there are left glyphs associated with any character in the
4965 text block, then create a display block to handle them. */
4966 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
4967 create_left_glyph_block (w, dl, 0);
4969 /* If there are right glyphs associated with any character in the
4970 text block, then create a display block to handle them. */
4971 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
4972 create_right_glyph_block (w, dl);
4977 /* This is ripped off from regenerate_window. All we want to do is
4978 loop through elements in the string creating display lines until we
4979 have covered the provided area. Simple really. */
4981 generate_displayable_area (struct window *w, Lisp_Object disp_string,
4982 int xpos, int ypos, int width, int height,
4983 display_line_dynarr* dla,
4985 face_index default_face)
4987 int yend = ypos + height;
4990 prop_block_dynarr *prop = 0;
4991 layout_bounds bounds;
4995 /* if there's nothing to do then do nothing. code after this assumes
4996 there is something to do. */
4997 if (NILP (disp_string))
5000 s_zv = XSTRING_CHAR_LENGTH (disp_string);
5002 bounds.left_out = xpos;
5003 bounds.right_out = xpos + width;
5004 /* The inner boundaries mark where the glyph margins are located. */
5005 bounds.left_in = bounds.left_out + window_left_margin_width (w);
5006 bounds.right_in = bounds.right_out - window_right_margin_width (w);
5007 /* We cannot fully calculate the whitespace boundaries as they
5008 depend on the contents of the line being displayed. */
5009 bounds.left_white = bounds.left_in;
5010 bounds.right_white = bounds.right_in;
5014 struct display_line dl;
5015 struct display_line *dlp;
5019 if (Dynarr_length (dla) < Dynarr_largest (dla))
5021 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5032 dlp->bounds = bounds;
5034 next_pos = generate_string_display_line (w, disp_string, dlp, start_pos,
5035 &prop, default_face);
5036 /* we need to make sure that we continue along the line if there
5037 is more left to display otherwise we just end up redisplaying
5038 the same chunk over and over again. */
5039 if (next_pos == start_pos && next_pos < s_zv)
5042 start_pos = next_pos;
5044 dlp->ypos = ypos + dlp->ascent;
5045 ypos = dlp->ypos + dlp->descent;
5049 int visible_height = dlp->ascent + dlp->descent;
5051 dlp->clip = (ypos - yend);
5052 visible_height -= dlp->clip;
5054 if (visible_height < VERTICAL_CLIP (w, 1))
5057 free_display_line (dlp);
5064 Dynarr_add (dla, *dlp);
5066 /* #### This type of check needs to be done down in the
5067 generate_display_line call. */
5068 if (start_pos >= s_zv)
5077 /***************************************************************************/
5079 /* window-regeneration routines */
5081 /***************************************************************************/
5083 /* For a given window and starting position in the buffer it contains,
5084 ensure that the TYPE display lines accurately represent the
5085 presentation of the window. We pass the buffer instead of getting
5086 it from the window since redisplay_window may have temporarily
5087 changed it to the echo area buffer. */
5090 regenerate_window (struct window *w, Bufpos start_pos, Bufpos point, int type)
5092 struct frame *f = XFRAME (w->frame);
5093 struct buffer *b = XBUFFER (w->buffer);
5094 int ypos = WINDOW_TEXT_TOP (w);
5095 int yend; /* set farther down */
5096 int yclip = WINDOW_TEXT_TOP_CLIP (w);
5099 prop_block_dynarr *prop;
5100 layout_bounds bounds;
5101 display_line_dynarr *dla;
5104 /* The lines had better exist by this point. */
5105 if (!(dla = window_display_lines (w, type)))
5108 w->max_line_len = 0;
5110 /* Normally these get updated in redisplay_window but it is possible
5111 for this function to get called from some other points where that
5112 update may not have occurred. This acts as a safety check. */
5113 if (!Dynarr_length (w->face_cachels))
5114 reset_face_cachels (w);
5115 if (!Dynarr_length (w->glyph_cachels))
5116 reset_glyph_cachels (w);
5118 Fset_marker (w->start[type], make_int (start_pos), w->buffer);
5119 Fset_marker (w->pointm[type], make_int (point), w->buffer);
5120 w->last_point_x[type] = -1;
5121 w->last_point_y[type] = -1;
5123 /* Make sure a modeline is in the structs if needed. */
5124 need_modeline = ensure_modeline_generated (w, type);
5126 /* Wait until here to set this so that the structs have a modeline
5127 generated in the case where one didn't exist. */
5128 yend = WINDOW_TEXT_BOTTOM (w);
5130 bounds = calculate_display_line_boundaries (w, 0);
5132 /* 97/3/14 jhod: stuff added here to support pre-prompts (used for input systems) */
5133 if (MINI_WINDOW_P (w)
5134 && (!NILP (Vminibuf_prompt) || !NILP (Vminibuf_preprompt))
5135 && !echo_area_active (f)
5136 && start_pos == BUF_BEGV (b))
5138 struct prop_block pb;
5140 prop = Dynarr_new (prop_block);
5142 string = concat2(Vminibuf_preprompt, Vminibuf_prompt);
5143 pb.type = PROP_MINIBUF_PROMPT;
5144 pb.data.p_string.str = XSTRING_DATA(string);
5145 pb.data.p_string.len = XSTRING_LENGTH(string);
5146 Dynarr_add (prop, pb);
5151 /* When we are computing things for scrolling purposes, make
5152 sure at least one line is always generated */
5153 force = (type == CMOTION_DISP);
5155 /* Make sure this is set always */
5156 /* Note the conversion at end */
5157 w->window_end_pos[type] = start_pos;
5158 while (ypos < yend || force)
5160 struct display_line dl;
5161 struct display_line *dlp;
5164 if (Dynarr_length (dla) < Dynarr_largest (dla))
5166 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5177 dlp->bounds = bounds;
5179 start_pos = generate_display_line (w, dlp, 1, start_pos, &prop, type);
5181 if (yclip > dlp->ascent)
5183 /* this should never happen, but if it does just display the
5188 dlp->ypos = (ypos + dlp->ascent) - yclip;
5189 ypos = dlp->ypos + dlp->descent;
5191 /* See if we've been asked to start midway through a line, for
5192 partial display line scrolling. */
5195 dlp->top_clip = yclip;
5203 int visible_height = dlp->ascent + dlp->descent;
5205 dlp->clip = (ypos - yend);
5206 /* Although this seems strange we could have a single very
5207 tall line visible for which we need to account for both
5208 the top clip and the bottom clip. */
5209 visible_height -= (dlp->clip + dlp->top_clip);
5211 if (visible_height < VERTICAL_CLIP (w, 1) && !force)
5214 free_display_line (dlp);
5221 if (dlp->cursor_elt != -1)
5223 /* #### This check is steaming crap. Have to get things
5224 fixed so when create_text_block hits EOB, we're done,
5226 if (w->last_point_x[type] == -1)
5228 w->last_point_x[type] = dlp->cursor_elt;
5229 w->last_point_y[type] = Dynarr_length (dla);
5233 /* #### This means that we've added a cursor at EOB
5234 twice. Yuck oh yuck. */
5235 struct display_block *db =
5236 get_display_block_from_line (dlp, TEXT);
5238 Dynarr_atp (db->runes, dlp->cursor_elt)->cursor_type = NO_CURSOR;
5239 dlp->cursor_elt = -1;
5243 if (dlp->num_chars > w->max_line_len)
5244 w->max_line_len = dlp->num_chars;
5246 Dynarr_add (dla, *dlp);
5248 /* #### This isn't right, but it is close enough for now. */
5249 w->window_end_pos[type] = start_pos;
5251 /* #### This type of check needs to be done down in the
5252 generate_display_line call. */
5253 if (start_pos > BUF_ZV (b))
5262 /* #### More not quite right, but close enough. */
5263 /* Ben sez: apparently window_end_pos[] is measured
5264 as the number of characters between the window end and the
5265 end of the buffer? This seems rather weirdo. What's
5266 the justification for this?
5268 JV sez: Because BUF_Z (b) would be a good initial value, however
5269 that can change. This representation allows initalizing with 0.
5271 w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type];
5275 /* We know that this is the right thing to use because we put it
5276 there when we first started working in this function. */
5277 generate_modeline (w, Dynarr_atp (dla, 0), type);
5281 #define REGEN_INC_FIND_START_END \
5283 /* Determine start and end of lines. */ \
5284 if (!Dynarr_length (cdla)) \
5288 if (Dynarr_atp (cdla, 0)->modeline && Dynarr_atp (ddla, 0)->modeline) \
5292 else if (!Dynarr_atp (cdla, 0)->modeline \
5293 && !Dynarr_atp (ddla, 0)->modeline) \
5298 abort (); /* structs differ */ \
5300 dla_end = Dynarr_length (cdla) - 1; \
5303 start_pos = (Dynarr_atp (cdla, dla_start)->bufpos \
5304 + Dynarr_atp (cdla, dla_start)->offset); \
5305 /* If this isn't true, then startp has changed and we need to do a \
5307 if (startp != start_pos) \
5310 /* Point is outside the visible region so give up. */ \
5311 if (pointm < start_pos) \
5316 /* This attempts to incrementally update the display structures. It
5317 returns a boolean indicating success or failure. This function is
5318 very similar to regenerate_window_incrementally and is in fact only
5319 called from that function. However, because of the nature of the
5320 changes it deals with it sometimes makes different assumptions
5321 which can lead to success which are much more difficult to make
5322 when dealing with buffer changes. */
5325 regenerate_window_extents_only_changed (struct window *w, Bufpos startp,
5327 Charcount beg_unchanged,
5328 Charcount end_unchanged)
5330 struct buffer *b = XBUFFER (w->buffer);
5331 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5332 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5336 int first_line, last_line;
5338 /* Don't define this in the loop where it is used because we
5339 definitely want its value to survive between passes. */
5340 prop_block_dynarr *prop = NULL;
5342 /* If we don't have any buffer change recorded but the modiff flag has
5343 been incremented, then fail. I'm not sure of the exact circumstances
5344 under which this can happen, but I believe that it is probably a
5345 reasonable happening. */
5346 if (!point_visible (w, pointm, CURRENT_DISP)
5347 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b))
5350 /* If the cursor is moved we attempt to update it. If we succeed we
5351 go ahead and proceed with the optimization attempt. */
5352 if (!EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5353 || pointm != marker_position (w->last_point[CURRENT_DISP]))
5355 struct frame *f = XFRAME (w->frame);
5356 struct device *d = XDEVICE (f->device);
5357 struct frame *sel_f = device_selected_frame (d);
5360 if (w->last_point_x[CURRENT_DISP] != -1
5361 && w->last_point_y[CURRENT_DISP] != -1)
5364 if (redisplay_move_cursor (w, pointm, WINDOW_TTY_P (w)))
5366 /* Always regenerate the modeline in case it is
5367 displaying the current line or column. */
5368 regenerate_modeline (w);
5372 else if (w != XWINDOW (FRAME_SELECTED_WINDOW (sel_f)))
5374 if (f->modeline_changed)
5375 regenerate_modeline (w);
5383 if (beg_unchanged == -1 && end_unchanged == -1)
5386 /* assert: There are no buffer modifications or they are all below the
5387 visible region. We assume that regenerate_window_incrementally has
5388 not called us unless this is true. */
5390 REGEN_INC_FIND_START_END;
5392 /* If the changed are starts before the visible area, give up. */
5393 if (beg_unchanged < startp)
5396 /* Find what display line the extent changes first affect. */
5398 while (line <= dla_end)
5400 struct display_line *dl = Dynarr_atp (cdla, line);
5401 Bufpos lstart = dl->bufpos + dl->offset;
5402 Bufpos lend = dl->end_bufpos + dl->offset;
5404 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5410 /* If the changes are below the visible area then if point hasn't
5411 moved return success otherwise fail in order to be safe. */
5414 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5415 && pointm == marker_position (w->last_point[CURRENT_DISP]))
5421 /* At this point we know what line the changes first affect. We now
5422 begin redrawing lines as long as we are still in the affected
5423 region and the line's size and positioning don't change.
5424 Otherwise we fail. If we fail we will have altered the desired
5425 structs which could lead to an assertion failure. However, if we
5426 fail the next thing that is going to happen is a full regen so we
5427 will actually end up being safe. */
5428 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5429 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5430 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
5431 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
5433 first_line = last_line = line;
5434 while (line <= dla_end)
5436 Bufpos old_start, old_end, new_start;
5437 struct display_line *cdl = Dynarr_atp (cdla, line);
5438 struct display_line *ddl = Dynarr_atp (ddla, line);
5439 struct display_block *db;
5442 assert (cdl->bufpos == ddl->bufpos);
5443 assert (cdl->end_bufpos == ddl->end_bufpos);
5444 assert (cdl->offset == ddl->offset);
5446 db = get_display_block_from_line (ddl, TEXT);
5447 initial_size = Dynarr_length (db->runes);
5448 old_start = ddl->bufpos + ddl->offset;
5449 old_end = ddl->end_bufpos + ddl->offset;
5451 /* If this is the first line being updated and it used
5452 propagation data, fail. Otherwise we'll be okay because
5453 we'll have the necessary propagation data. */
5454 if (line == first_line && ddl->used_prop_data)
5457 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5458 &prop, DESIRED_DISP);
5461 /* #### If there is propagated stuff the fail. We could
5462 probably actually deal with this if the line had propagated
5463 information when originally created by a full
5471 /* If any line position parameters have changed or a
5472 cursor has disappeared or disappeared, fail. */
5473 db = get_display_block_from_line (ddl, TEXT);
5474 if (cdl->ypos != ddl->ypos
5475 || cdl->ascent != ddl->ascent
5476 || cdl->descent != ddl->descent
5477 || cdl->top_clip != ddl->top_clip
5478 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5479 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1)
5480 || old_start != ddl->bufpos
5481 || old_end != ddl->end_bufpos
5482 || initial_size != Dynarr_length (db->runes))
5487 if (ddl->cursor_elt != -1)
5489 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5490 w->last_point_y[DESIRED_DISP] = line;
5495 /* If the extent changes end on the line we just updated then
5496 we're done. Otherwise go on to the next line. */
5497 if (end_unchanged <= ddl->end_bufpos)
5503 redisplay_update_line (w, first_line, last_line, 1);
5507 /* Attempt to update the display data structures based on knowledge of
5508 the changed region in the buffer. Returns a boolean indicating
5509 success or failure. If this function returns a failure then a
5510 regenerate_window _must_ be performed next in order to maintain
5511 invariants located here. */
5514 regenerate_window_incrementally (struct window *w, Bufpos startp,
5517 struct buffer *b = XBUFFER (w->buffer);
5518 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5519 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5520 Charcount beg_unchanged, end_unchanged;
5521 Charcount extent_beg_unchanged, extent_end_unchanged;
5527 /* If this function is called, the current and desired structures
5528 had better be identical. If they are not, then that is a bug. */
5529 assert (Dynarr_length (cdla) == Dynarr_length (ddla));
5531 /* We don't handle minibuffer windows yet. The minibuffer prompt
5533 if (MINI_WINDOW_P (w))
5536 extent_beg_unchanged = BUF_EXTENT_BEGIN_UNCHANGED (b);
5537 extent_end_unchanged = (BUF_EXTENT_END_UNCHANGED (b) == -1
5539 : BUF_Z (b) - BUF_EXTENT_END_UNCHANGED (b));
5541 /* If nothing has changed in the buffer, then make sure point is ok
5543 if (BUF_BEGIN_UNCHANGED (b) == -1 && BUF_END_UNCHANGED (b) == -1)
5544 return regenerate_window_extents_only_changed (w, startp, pointm,
5545 extent_beg_unchanged,
5546 extent_end_unchanged);
5548 /* We can't deal with deleted newlines. */
5549 if (BUF_NEWLINE_WAS_DELETED (b))
5552 beg_unchanged = BUF_BEGIN_UNCHANGED (b);
5553 end_unchanged = (BUF_END_UNCHANGED (b) == -1
5555 : BUF_Z (b) - BUF_END_UNCHANGED (b));
5557 REGEN_INC_FIND_START_END;
5559 /* If the changed area starts before the visible area, give up. */
5560 if (beg_unchanged < startp)
5563 /* Find what display line the buffer changes first affect. */
5565 while (line <= dla_end)
5567 struct display_line *dl = Dynarr_atp (cdla, line);
5568 Bufpos lstart = dl->bufpos + dl->offset;
5569 Bufpos lend = dl->end_bufpos + dl->offset;
5571 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5577 /* If the changes are below the visible area then if point hasn't
5578 moved return success otherwise fail in order to be safe. */
5580 return regenerate_window_extents_only_changed (w, startp, pointm,
5581 extent_beg_unchanged,
5582 extent_end_unchanged);
5584 /* At this point we know what line the changes first affect. We
5585 now redraw that line. If the changes are contained within it
5586 we are going to succeed and can update just that one line.
5587 Otherwise we fail. If we fail we will have altered the desired
5588 structs which could lead to an assertion failure. However, if
5589 we fail the next thing that is going to happen is a full regen
5590 so we will actually end up being safe. */
5593 prop_block_dynarr *prop = NULL;
5594 struct display_line *cdl = Dynarr_atp (cdla, line);
5595 struct display_line *ddl = Dynarr_atp (ddla, line);
5597 assert (cdl->bufpos == ddl->bufpos);
5598 assert (cdl->end_bufpos == ddl->end_bufpos);
5599 assert (cdl->offset == ddl->offset);
5601 /* If the line continues to next display line, fail. */
5602 if (ddl->line_continuation)
5605 /* If the line was generated using propagation data, fail. */
5606 if (ddl->used_prop_data)
5609 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5610 &prop, DESIRED_DISP);
5613 /* If there is propagated stuff then it is pretty much a
5614 guarantee that more than just the one line is affected. */
5621 /* If the line continues to next display line, fail. */
5622 if (ddl->line_continuation)
5625 /* If any line position parameters have changed or a
5626 cursor has disappeared or disappeared, fail. */
5627 if (cdl->ypos != ddl->ypos
5628 || cdl->ascent != ddl->ascent
5629 || cdl->descent != ddl->descent
5630 || cdl->top_clip != ddl->top_clip
5631 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5632 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1))
5637 /* If the changed area also ends on this line, then we may be in
5638 business. Update everything and return success. */
5639 if (end_unchanged >= ddl->bufpos && end_unchanged <= ddl->end_bufpos)
5641 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5642 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5643 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp),
5645 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm),
5648 if (ddl->cursor_elt != -1)
5650 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5651 w->last_point_y[DESIRED_DISP] = line;
5654 redisplay_update_line (w, line, line, 1);
5655 regenerate_modeline (w);
5657 /* #### For now we just flush the cache until this has been
5658 tested. After that is done, this should correct the
5660 Dynarr_reset (w->line_start_cache);
5662 /* Adjust the extent changed boundaries to remove any
5663 overlap with the buffer changes since we've just
5664 successfully updated that area. */
5665 if (extent_beg_unchanged != -1
5666 && extent_beg_unchanged >= beg_unchanged
5667 && extent_beg_unchanged < end_unchanged)
5668 extent_beg_unchanged = end_unchanged;
5670 if (extent_end_unchanged != -1
5671 && extent_end_unchanged >= beg_unchanged
5672 && extent_end_unchanged < end_unchanged)
5673 extent_end_unchanged = beg_unchanged - 1;
5675 if (extent_end_unchanged <= extent_beg_unchanged)
5676 extent_beg_unchanged = extent_end_unchanged = -1;
5678 /* This could lead to odd results if it fails, but since the
5679 buffer changes update succeeded this probably will to.
5680 We already know that the extent changes start at or after
5681 the line because we checked before entering the loop. */
5682 if (extent_beg_unchanged != -1
5683 && extent_end_unchanged != -1
5684 && ((extent_beg_unchanged < ddl->bufpos)
5685 || (extent_end_unchanged > ddl->end_bufpos)))
5686 return regenerate_window_extents_only_changed (w, startp, pointm,
5687 extent_beg_unchanged,
5688 extent_end_unchanged);
5698 /* Given a window and a point, update the given display lines such
5699 that point is displayed in the middle of the window.
5700 Return the window's new start position. */
5703 regenerate_window_point_center (struct window *w, Bufpos point, int type)
5707 /* We need to make sure that the modeline is generated so that the
5708 window height can be calculated correctly. */
5709 ensure_modeline_generated (w, type);
5711 startp = start_with_line_at_pixpos (w, point, window_half_pixpos (w));
5712 regenerate_window (w, startp, point, type);
5713 Fset_marker (w->start[type], make_int (startp), w->buffer);
5718 /* Given a window and a set of display lines, return a boolean
5719 indicating whether the given point is contained within. */
5722 point_visible (struct window *w, Bufpos point, int type)
5724 struct buffer *b = XBUFFER (w->buffer);
5725 display_line_dynarr *dla = window_display_lines (w, type);
5728 if (Dynarr_length (dla) && Dynarr_atp (dla, 0)->modeline)
5733 if (Dynarr_length (dla) > first_line)
5736 struct display_line *dl = Dynarr_atp (dla, first_line);
5739 end = BUF_Z (b) - w->window_end_pos[type] - 1;
5741 if (point >= start && point <= end)
5743 if (!MINI_WINDOW_P (w) && scroll_on_clipped_lines)
5745 dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
5747 if (point >= (dl->bufpos + dl->offset)
5748 && point <= (dl->end_bufpos + dl->offset))
5763 /* Return pixel position the middle of the window, not including the
5764 modeline and any potential horizontal scrollbar. */
5767 window_half_pixpos (struct window *w)
5769 return WINDOW_TEXT_TOP (w) + (WINDOW_TEXT_HEIGHT (w) >> 1);
5772 /* Return the display line which is currently in the middle of the
5773 window W for display lines TYPE. */
5776 line_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5778 display_line_dynarr *dla;
5781 int first_elt = (MINI_WINDOW_P (w) ? 0 : 1);
5783 if (type == CMOTION_DISP)
5784 regenerate_window (w, start, point, type);
5786 dla = window_display_lines (w, type);
5787 half = window_half_pixpos (w);
5789 for (elt = first_elt; elt < Dynarr_length (dla); elt++)
5791 struct display_line *dl = Dynarr_atp (dla, elt);
5792 int line_bot = dl->ypos + dl->descent;
5794 if (line_bot > half)
5798 /* We may not have a line at the middle if the end of the buffer is
5803 /* Return a value for point that would place it at the beginning of
5804 the line which is in the middle of the window. */
5807 point_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5809 /* line_at_center will regenerate the display structures, if necessary. */
5810 int line = line_at_center (w, type, start, point);
5813 return BUF_ZV (XBUFFER (w->buffer));
5816 display_line_dynarr *dla = window_display_lines (w, type);
5817 struct display_line *dl = Dynarr_atp (dla, line);
5823 /* For a given window, ensure that the current visual representation
5827 redisplay_window (Lisp_Object window, int skip_selected)
5829 struct window *w = XWINDOW (window);
5830 struct frame *f = XFRAME (w->frame);
5831 struct device *d = XDEVICE (f->device);
5832 Lisp_Object old_buffer = w->buffer;
5833 Lisp_Object the_buffer = w->buffer;
5835 int echo_active = 0;
5840 int selected_in_its_frame;
5841 int selected_globally;
5842 int skip_output = 0;
5843 int truncation_changed;
5844 int inactive_minibuffer =
5845 (MINI_WINDOW_P (w) &&
5846 (f != device_selected_frame (d)) &&
5847 !is_surrogate_for_selected_frame (f));
5849 /* #### In the new world this function actually does a bunch of
5850 optimizations such as buffer-based scrolling, but none of that is
5853 /* If this is a combination window, do its children; that's all.
5854 The selected window is always a leaf so we don't check for
5855 skip_selected here. */
5856 if (!NILP (w->vchild))
5858 redisplay_windows (w->vchild, skip_selected);
5861 if (!NILP (w->hchild))
5863 redisplay_windows (w->hchild, skip_selected);
5867 /* Is this window the selected window on its frame? */
5868 selected_in_its_frame = (w == XWINDOW (FRAME_SELECTED_WINDOW (f)));
5870 selected_in_its_frame &&
5871 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
5872 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d &&
5873 XFRAME(DEVICE_SELECTED_FRAME(d)) == f;
5874 if (skip_selected && selected_in_its_frame)
5877 /* It is possible that the window is not fully initialized yet. */
5878 if (NILP (w->buffer))
5881 if (MINI_WINDOW_P (w) && echo_area_active (f))
5883 w->buffer = the_buffer = Vecho_area_buffer;
5887 b = XBUFFER (w->buffer);
5891 old_pointm = selected_globally
5893 : marker_position (w->pointm[CURRENT_DISP]);
5898 if (selected_globally)
5900 pointm = BUF_PT (b);
5904 pointm = marker_position (w->pointm[CURRENT_DISP]);
5906 if (pointm < BUF_BEGV (b))
5907 pointm = BUF_BEGV (b);
5908 else if (pointm > BUF_ZV (b))
5909 pointm = BUF_ZV (b);
5912 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm), the_buffer);
5914 /* If the buffer has changed we have to invalidate all of our face
5916 if ((!echo_active && b != window_display_buffer (w))
5917 || !Dynarr_length (w->face_cachels)
5918 || f->faces_changed)
5919 reset_face_cachels (w);
5921 mark_face_cachels_as_not_updated (w);
5923 /* Ditto the glyph cache elements, although we do *not* invalidate
5924 the cache purely because glyphs have changed - this is now
5925 handled by the dirty flag.*/
5926 if ((!echo_active && b != window_display_buffer (w))
5927 || !Dynarr_length (w->glyph_cachels) || f->faces_changed)
5928 reset_glyph_cachels (w);
5930 mark_glyph_cachels_as_not_updated (w);
5932 /* If the marker's buffer is not the window's buffer, then we need
5933 to find a new starting position. */
5934 if (!MINI_WINDOW_P (w)
5935 && !EQ (Fmarker_buffer (w->start[CURRENT_DISP]), w->buffer))
5937 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
5939 goto regeneration_done;
5944 old_startp = marker_position (w->start[CURRENT_DISP]);
5949 startp = marker_position (w->start[CURRENT_DISP]);
5950 if (startp < BUF_BEGV (b))
5951 startp = BUF_BEGV (b);
5952 else if (startp > BUF_ZV (b))
5953 startp = BUF_ZV (b);
5955 Fset_marker (w->start[DESIRED_DISP], make_int (startp), the_buffer);
5957 truncation_changed = (find_window_mirror (w)->truncate_win !=
5958 window_truncation_on (w));
5960 /* If w->force_start is set, then some function set w->start and we
5961 should display from there and change point, if necessary, to
5962 ensure that it is visible. */
5963 if (w->force_start || inactive_minibuffer)
5966 w->last_modified[DESIRED_DISP] = Qzero;
5967 w->last_facechange[DESIRED_DISP] = Qzero;
5969 regenerate_window (w, startp, pointm, DESIRED_DISP);
5971 if (!point_visible (w, pointm, DESIRED_DISP) && !inactive_minibuffer)
5973 pointm = point_at_center (w, DESIRED_DISP, 0, 0);
5975 if (selected_globally)
5976 BUF_SET_PT (b, pointm);
5978 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm),
5981 /* #### BUFU amounts of overkill just to get the cursor
5982 location marked properly. FIX ME FIX ME FIX ME */
5983 regenerate_window (w, startp, pointm, DESIRED_DISP);
5986 goto regeneration_done;
5989 /* If nothing has changed since the last redisplay, then we just
5990 need to make sure that point is still visible. */
5991 if (XINT (w->last_modified[CURRENT_DISP]) >= BUF_MODIFF (b)
5992 && XINT (w->last_facechange[CURRENT_DISP]) >= BUF_FACECHANGE (b)
5994 /* This check is to make sure we restore the minibuffer after a
5995 temporary change to the echo area. */
5996 && !(MINI_WINDOW_P (w) && f->buffers_changed)
5997 && !f->frame_changed
5998 && !truncation_changed
5999 /* check whether start is really at the beginning of a line GE */
6000 && (!w->start_at_line_beg || beginning_of_line_p (b, startp))
6003 /* Check if the cursor has actually moved. */
6004 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
6005 && pointm == marker_position (w->last_point[CURRENT_DISP])
6006 && selected_globally
6007 && !w->windows_changed
6009 && !f->extents_changed
6010 && !f->faces_changed
6011 && !f->glyphs_changed
6012 && !f->subwindows_changed
6013 /* && !f->subwindows_state_changed*/
6014 && !f->point_changed
6015 && !f->windows_structure_changed)
6017 /* If not, we're done. */
6018 if (f->modeline_changed)
6019 regenerate_modeline (w);
6022 goto regeneration_done;
6026 /* If the new point is visible in the redisplay structures,
6027 then let the output update routines handle it, otherwise
6028 do things the hard way. */
6029 if (!w->windows_changed
6031 && !f->extents_changed
6032 && !f->faces_changed
6033 && !f->glyphs_changed
6034 && !f->subwindows_changed
6035 /* && !f->subwindows_state_changed*/
6036 && !f->windows_structure_changed)
6038 if (point_visible (w, pointm, CURRENT_DISP)
6039 && w->last_point_x[CURRENT_DISP] != -1
6040 && w->last_point_y[CURRENT_DISP] != -1)
6042 if (redisplay_move_cursor (w, pointm, FRAME_TTY_P (f)))
6044 /* Always regenerate in case it is displaying
6045 the current line or column. */
6046 regenerate_modeline (w);
6049 goto regeneration_done;
6052 else if (!selected_in_its_frame && !f->point_changed)
6054 if (f->modeline_changed)
6055 regenerate_modeline (w);
6058 goto regeneration_done;
6062 /* If we weren't able to take the shortcut method, then use
6063 the brute force method. */
6064 regenerate_window (w, startp, pointm, DESIRED_DISP);
6066 if (point_visible (w, pointm, DESIRED_DISP))
6067 goto regeneration_done;
6071 /* Check if the starting point is no longer at the beginning of a
6072 line, in which case find a new starting point. We also recenter
6073 if our start position is equal to point-max. Otherwise we'll end
6074 up with a blank window. */
6075 else if (((w->start_at_line_beg || MINI_WINDOW_P (w))
6076 && !(startp == BUF_BEGV (b)
6077 || BUF_FETCH_CHAR (b, startp - 1) == '\n'))
6078 || (pointm == startp &&
6079 EQ (Fmarker_buffer (w->last_start[CURRENT_DISP]), w->buffer) &&
6080 startp < marker_position (w->last_start[CURRENT_DISP]))
6081 || (startp == BUF_ZV (b)))
6083 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6085 goto regeneration_done;
6087 /* See if we can update the data structures locally based on
6088 knowledge of what changed in the buffer. */
6089 else if (!w->windows_changed
6091 && !f->faces_changed
6092 && !f->glyphs_changed
6093 && !f->subwindows_changed
6094 /* && !f->subwindows_state_changed*/
6095 && !f->windows_structure_changed
6096 && !f->frame_changed
6097 && !truncation_changed
6099 && regenerate_window_incrementally (w, startp, pointm))
6101 if (f->modeline_changed
6102 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b)
6103 || XINT (w->last_facechange[CURRENT_DISP]) < BUF_FACECHANGE (b))
6104 regenerate_modeline (w);
6107 goto regeneration_done;
6109 /* #### This is where a check for structure based scrolling would go. */
6110 /* If all else fails, try just regenerating and see what happens. */
6113 regenerate_window (w, startp, pointm, DESIRED_DISP);
6115 if (point_visible (w, pointm, DESIRED_DISP))
6116 goto regeneration_done;
6119 /* We still haven't gotten the window regenerated with point
6120 visible. Next we try scrolling a little and see if point comes
6121 back onto the screen. */
6122 if (scroll_step > 0)
6124 int scrolled = scroll_conservatively;
6125 for (; scrolled >= 0; scrolled -= scroll_step)
6127 startp = vmotion (w, startp,
6128 (pointm < startp) ? -scroll_step : scroll_step, 0);
6129 regenerate_window (w, startp, pointm, DESIRED_DISP);
6131 if (point_visible (w, pointm, DESIRED_DISP))
6132 goto regeneration_done;
6136 /* We still haven't managed to get the screen drawn with point on
6137 the screen, so just center it and be done with it. */
6138 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6143 /* If the window's frame is changed then reset the current display
6144 lines in order to force a full repaint. */
6145 if (f->frame_changed)
6147 display_line_dynarr *cla = window_display_lines (w, CURRENT_DISP);
6152 /* Must do this before calling redisplay_output_window because it
6153 sets some markers on the window. */
6156 w->buffer = old_buffer;
6157 Fset_marker (w->pointm[DESIRED_DISP], make_int (old_pointm), old_buffer);
6158 Fset_marker (w->start[DESIRED_DISP], make_int (old_startp), old_buffer);
6161 /* These also have to be set before calling redisplay_output_window
6162 since it sets the CURRENT_DISP values based on them. */
6163 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
6164 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
6165 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
6166 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
6170 Bufpos start = marker_position (w->start[DESIRED_DISP]);
6171 Bufpos end = (w->window_end_pos[DESIRED_DISP] == -1
6173 : BUF_Z (b) - w->window_end_pos[DESIRED_DISP] - 1);
6174 /* Don't pollute the cache if not sure if we are correct */
6175 if (w->start_at_line_beg)
6176 update_line_start_cache (w, start, end, pointm, 1);
6177 redisplay_output_window (w);
6179 * If we just displayed the echo area, the line start cache is
6180 * no longer valid, because the minibuffer window is associated
6181 * with the window now.
6184 w->line_cache_last_updated = make_int (-1);
6187 /* #### This should be dependent on face changes and will need to be
6188 somewhere else once tty updates occur on a per-frame basis. */
6189 mark_face_cachels_as_clean (w);
6191 /* The glyph cachels only get dirty if someone changed something.
6192 Since redisplay has now effectively ended we can reset the dirty
6193 flag since everything must be up-to-date. */
6195 mark_glyph_cachels_as_clean (w);
6197 w->windows_changed = 0;
6200 /* Call buffer_reset_changes for all buffers present in any window
6201 currently visible in all frames on all devices. #### There has to
6202 be a better way to do this. */
6205 reset_buffer_changes_mapfun (struct window *w, void *ignored_closure)
6207 buffer_reset_changes (XBUFFER (w->buffer));
6212 reset_buffer_changes (void)
6214 Lisp_Object frmcons, devcons, concons;
6216 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
6218 struct frame *f = XFRAME (XCAR (frmcons));
6220 if (FRAME_REPAINT_P (f))
6221 map_windows (f, reset_buffer_changes_mapfun, 0);
6225 /* Ensure that all windows underneath the given window in the window
6226 hierarchy are correctly displayed. */
6229 redisplay_windows (Lisp_Object window, int skip_selected)
6231 for (; !NILP (window) ; window = XWINDOW (window)->next)
6233 redisplay_window (window, skip_selected);
6238 call_redisplay_end_triggers (struct window *w, void *closure)
6240 Bufpos lrpos = w->last_redisplay_pos;
6241 w->last_redisplay_pos = 0;
6242 if (!NILP (w->buffer)
6243 && !NILP (w->redisplay_end_trigger)
6248 if (MARKERP (w->redisplay_end_trigger)
6249 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
6250 pos = marker_position (w->redisplay_end_trigger);
6251 else if (INTP (w->redisplay_end_trigger))
6252 pos = XINT (w->redisplay_end_trigger);
6255 w->redisplay_end_trigger = Qnil;
6262 XSETWINDOW (window, w);
6263 va_run_hook_with_args_in_buffer (XBUFFER (w->buffer),
6264 Qredisplay_end_trigger_functions,
6266 w->redisplay_end_trigger);
6267 w->redisplay_end_trigger = Qnil;
6274 /* Ensure that all windows on the given frame are correctly displayed. */
6277 redisplay_frame (struct frame *f, int preemption_check)
6279 struct device *d = XDEVICE (f->device);
6281 if (preemption_check)
6283 /* The preemption check itself takes a lot of time,
6284 so normally don't do it here. We do it if called
6285 from Lisp, though (`redisplay-frame'). */
6288 REDISPLAY_PREEMPTION_CHECK;
6293 if (!internal_equal (f->old_buffer_alist, f->buffer_alist, 0))
6297 f->old_buffer_alist = Freplace_list (f->old_buffer_alist,
6299 XSETFRAME (frame, f);
6300 va_run_hook_with_args (Qbuffer_list_changed_hook, 1, frame);
6303 /* Before we put a hold on frame size changes, attempt to process
6304 any which are already pending. */
6305 if (f->size_change_pending)
6306 change_frame_size (f, f->new_height, f->new_width, 0);
6308 /* If frame size might need to be changed, due to changed size
6309 of toolbars, scrollbars etc, change it now */
6310 if (f->size_slipped)
6312 adjust_frame_size (f);
6313 assert (!f->size_slipped);
6316 /* The menubar, toolbar, and icon updates must be done before
6317 hold_frame_size_changes is called and we are officially
6318 'in_display'. They may eval lisp code which may call Fsignal.
6319 If in_display is set Fsignal will abort. */
6321 #ifdef HAVE_MENUBARS
6322 /* Update the menubar. It is done first since it could change
6323 the menubar's visibility. This way we avoid having flashing
6324 caused by an Expose event generated by the visibility change
6326 update_frame_menubars (f);
6327 #endif /* HAVE_MENUBARS */
6328 #ifdef HAVE_TOOLBARS
6329 /* Update the toolbars. */
6330 update_frame_toolbars (f);
6331 #endif /* HAVE_TOOLBARS */
6332 /* Gutter update proper has to be done inside display when no frame
6333 size changes can occur, thus we separately update the gutter
6334 geometry here if it needs it. */
6335 update_frame_gutter_geometry (f);
6337 /* If we clear the frame we have to force its contents to be redrawn. */
6339 f->frame_changed = 1;
6341 /* Invalidate the subwindow caches. We use subwindows_changed here
6342 to cause subwindows to get instantiated. This is because
6343 subwindows_state_changed is less strict - dealing with things
6344 like the clicked state of button. We have to do this before
6345 redisplaying the gutters as subwindows get unmapped in the
6347 if (f->frame_changed)
6348 reset_frame_subwindow_instance_cache (f);
6350 if (f->frame_changed || f->subwindows_changed)
6352 /* we have to do this so the gutter gets regenerated. */
6353 reset_gutter_display_lines (f);
6356 hold_frame_size_changes ();
6358 /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */
6359 /* Within this section, we are defenseless and assume that the
6360 following cannot happen:
6362 1) garbage collection
6363 2) Lisp code evaluation
6364 3) frame size changes
6366 We ensure (3) by calling hold_frame_size_changes(), which
6367 will cause any pending frame size changes to get put on hold
6368 till after the end of the critical section. (1) follows
6369 automatically if (2) is met. #### Unfortunately, there are
6370 some places where Lisp code can be called within this section.
6371 We need to remove them.
6373 If Fsignal() is called during this critical section, we
6376 If garbage collection is called during this critical section,
6377 we simply return. #### We should abort instead.
6379 #### If a frame-size change does occur we should probably
6380 actually be preempting redisplay. */
6382 MAYBE_DEVMETH (d, frame_output_begin, (f));
6384 /* We can now update the gutters, safe in the knowledge that our
6385 efforts won't get undone. */
6387 /* This can call lisp, but redisplay is protected by binding
6388 inhibit_quit. More importantly the code involving display lines
6389 *assumes* that GC will not happen and so does not GCPRO
6390 anything. Since we use this code the whole time with the gutters
6391 we cannot allow GC to happen when manipulating the gutters. */
6392 update_frame_gutters (f);
6394 /* Erase the frame before outputting its contents. */
6397 MAYBE_DEVMETH (d, clear_frame, (f));
6400 /* Do the selected window first. */
6401 redisplay_window (FRAME_SELECTED_WINDOW (f), 0);
6403 /* Then do the rest. */
6404 redisplay_windows (f->root_window, 1);
6406 MAYBE_DEVMETH (d, frame_output_end, (f));
6408 update_frame_title (f);
6410 CLASS_RESET_CHANGED_FLAGS (f);
6411 f->window_face_cache_reset = 0;
6412 f->echo_area_garbaged = 0;
6415 if (!f->size_change_pending)
6416 f->size_changed = 0;
6418 /* ----------------- END CRITICAL REDISPLAY SECTION ---------------- */
6420 /* Allow frame size changes to occur again.
6422 #### what happens if changes to other frames happen? */
6423 unhold_one_frame_size_changes (f);
6425 map_windows (f, call_redisplay_end_triggers, 0);
6429 /* Ensure that all frames on the given device are correctly displayed.
6430 If AUTOMATIC is non-zero, and the device implementation indicates
6431 no automatic redisplay, as printers do, then the device is not
6432 redisplayed. AUTOMATIC is set to zero when called from lisp
6433 functions (redraw-device) and (redisplay-device), and to non-zero
6434 when called from "lazy" redisplay();
6438 redisplay_device (struct device *d, int automatic)
6440 Lisp_Object frame, frmcons;
6442 int size_change_failed = 0;
6446 && (MAYBE_INT_DEVMETH (d, device_implementation_flags, ())
6447 & XDEVIMPF_NO_AUTO_REDISPLAY))
6450 if (DEVICE_STREAM_P (d)) /* nothing to do */
6453 /* It is possible that redisplay has been called before the
6454 device is fully initialized. If so then continue with the
6456 if (NILP (DEVICE_SELECTED_FRAME (d)))
6459 REDISPLAY_PREEMPTION_CHECK;
6463 /* Always do the selected frame first. */
6464 frame = DEVICE_SELECTED_FRAME (d);
6468 if (f->icon_changed || f->windows_changed)
6469 update_frame_icon (f);
6471 if (FRAME_REPAINT_P (f))
6473 if (CLASS_REDISPLAY_FLAGS_CHANGEDP(f))
6475 preempted = redisplay_frame (f, 0);
6481 /* If the frame redisplay did not get preempted, then this flag
6482 should have gotten set to 0. It might be possible for that
6483 not to happen if a size change event were to occur at an odd
6484 time. To make sure we don't miss anything we simply don't
6485 reset the top level flags until the condition ends up being
6486 in the right state. */
6487 if (f->size_changed)
6488 size_change_failed = 1;
6491 DEVICE_FRAME_LOOP (frmcons, d)
6493 f = XFRAME (XCAR (frmcons));
6495 if (f == XFRAME (DEVICE_SELECTED_FRAME (d)))
6498 if (f->icon_changed || f->windows_changed)
6499 update_frame_icon (f);
6501 if (FRAME_REPAINT_P (f))
6503 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (f))
6505 preempted = redisplay_frame (f, 0);
6511 if (f->size_change_pending)
6512 size_change_failed = 1;
6516 /* If we get here then we redisplayed all of our frames without
6517 getting preempted so mark ourselves as clean. */
6518 CLASS_RESET_CHANGED_FLAGS (d);
6520 if (!size_change_failed)
6521 d->size_changed = 0;
6527 restore_profiling_redisplay_flag (Lisp_Object val)
6529 profiling_redisplay_flag = XINT (val);
6533 /* Ensure that all windows on all frames on all devices are displaying
6534 the current contents of their respective buffers. */
6537 redisplay_without_hooks (void)
6539 Lisp_Object devcons, concons;
6540 int size_change_failed = 0;
6541 int count = specpdl_depth ();
6543 if (profiling_active)
6545 record_unwind_protect (restore_profiling_redisplay_flag,
6546 make_int (profiling_redisplay_flag));
6547 profiling_redisplay_flag = 1;
6550 if (asynch_device_change_pending)
6551 handle_asynch_device_change ();
6553 if (!GLOBAL_REDISPLAY_FLAGS_CHANGEDP &&
6554 !disable_preemption && preemption_count < max_preempts)
6557 DEVICE_LOOP_NO_BREAK (devcons, concons)
6559 struct device *d = XDEVICE (XCAR (devcons));
6562 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (d))
6564 preempted = redisplay_device (d, 1);
6569 RESET_CHANGED_SET_FLAGS;
6573 /* See comment in redisplay_device. */
6574 if (d->size_changed)
6575 size_change_failed = 1;
6578 preemption_count = 0;
6580 /* Mark redisplay as accurate */
6581 GLOBAL_RESET_CHANGED_FLAGS;
6582 RESET_CHANGED_SET_FLAGS;
6586 mark_all_faces_as_clean ();
6590 if (!size_change_failed)
6593 reset_buffer_changes ();
6596 unbind_to (count, Qnil);
6602 if (last_display_warning_tick != display_warning_tick &&
6603 !inhibit_warning_display)
6605 /* If an error occurs during this function, oh well.
6606 If we report another warning, we could get stuck in an
6607 infinite loop reporting warnings. */
6608 call0_trapping_errors (0, Qdisplay_warning_buffer);
6609 last_display_warning_tick = display_warning_tick;
6611 /* The run_hook_trapping_errors functions are smart enough not
6612 to do any evalling if the hook function is empty, so there
6613 should not be any significant time loss. All places in the
6614 C code that call redisplay() are prepared to handle GCing,
6615 so we should be OK. */
6616 #ifndef INHIBIT_REDISPLAY_HOOKS
6617 run_hook_trapping_errors ("Error in pre-redisplay-hook",
6618 Qpre_redisplay_hook);
6619 #endif /* INHIBIT_REDISPLAY_HOOKS */
6621 redisplay_without_hooks ();
6623 #ifndef INHIBIT_REDISPLAY_HOOKS
6624 run_hook_trapping_errors ("Error in post-redisplay-hook",
6625 Qpost_redisplay_hook);
6626 #endif /* INHIBIT_REDISPLAY_HOOKS */
6630 static char window_line_number_buf[32];
6632 /* Efficiently determine the window line number, and return a pointer
6633 to its printed representation. Do this regardless of whether
6634 line-number-mode is on. The first line in the buffer is counted as
6635 1. If narrowing is in effect, the lines are counted from the
6636 beginning of the visible portion of the buffer. */
6638 window_line_number (struct window *w, int type)
6640 struct device *d = XDEVICE (XFRAME (w->frame)->device);
6641 struct buffer *b = XBUFFER (w->buffer);
6642 /* Be careful in the order of these tests. The first clause will
6643 fail if DEVICE_SELECTED_FRAME == Qnil (since w->frame cannot be).
6644 This can occur when the frame title is computed really early */
6646 ((EQ(DEVICE_SELECTED_FRAME(d), w->frame) &&
6647 (w == XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame(d)))) &&
6648 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
6649 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d )
6651 : marker_position (w->pointm[type]));
6654 line = buffer_line_number (b, pos, 1);
6656 long_to_string (window_line_number_buf, line + 1);
6658 return window_line_number_buf;
6662 /* Given a character representing an object in a modeline
6663 specification, return a string (stored into the global array
6664 `mode_spec_bufbyte_string') with the information that object
6667 This function is largely unchanged from previous versions of the
6670 Warning! This code is also used for frame titles and can be called
6671 very early in the device/frame update process! JV
6675 decode_mode_spec (struct window *w, Emchar spec, int type)
6677 Lisp_Object obj = Qnil;
6678 const char *str = NULL;
6679 struct buffer *b = XBUFFER (w->buffer);
6681 Dynarr_reset (mode_spec_bufbyte_string);
6685 /* print buffer name */
6690 /* print visited file name */
6695 /* print the current column */
6698 Bufpos pt = (w == XWINDOW (Fselected_window (Qnil)))
6700 : marker_position (w->pointm[type]);
6701 int col = column_at_point (b, pt, 1) + !!column_number_start_at_one;
6704 long_to_string (buf, col);
6706 Dynarr_add_many (mode_spec_bufbyte_string,
6707 (const Bufbyte *) buf, strlen (buf));
6709 goto decode_mode_spec_done;
6711 /* print the file coding system */
6715 Lisp_Object codesys = b->buffer_file_coding_system;
6716 /* Be very careful here not to get an error. */
6717 if (NILP (codesys) || SYMBOLP (codesys) || CODING_SYSTEMP (codesys))
6719 codesys = Ffind_coding_system (codesys);
6720 if (CODING_SYSTEMP (codesys))
6721 obj = XCODING_SYSTEM_MNEMONIC (codesys);
6724 #endif /* FILE_CODING */
6727 /* print the current line number */
6729 str = window_line_number (w, type);
6732 /* print value of mode-name (obsolete) */
6737 /* print hyphen and frame number, if != 1 */
6741 struct frame *f = XFRAME (w->frame);
6742 if (FRAME_TTY_P (f) && f->order_count > 1 && f->order_count <= 99999999)
6744 /* Naughty, naughty */
6745 char * writable_str = alloca_array (char, 10);
6746 sprintf (writable_str, "-%d", f->order_count);
6750 #endif /* HAVE_TTY */
6753 /* print Narrow if appropriate */
6755 if (BUF_BEGV (b) > BUF_BEG (b)
6756 || BUF_ZV (b) < BUF_Z (b))
6760 /* print %, * or hyphen, if buffer is read-only, modified or neither */
6762 str = (!NILP (b->read_only)
6764 : ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6769 /* print * or hyphen -- XEmacs change to allow a buffer to be
6770 read-only but still indicate whether it is modified. */
6772 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6774 : (!NILP (b->read_only)
6779 /* #### defined in 19.29 decode_mode_spec, but not in
6780 modeline-format doc string. */
6781 /* This differs from %* in that it ignores read-only-ness. */
6783 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6788 /* print process status */
6790 obj = Fget_buffer_process (w->buffer);
6792 str = GETTEXT ("no process");
6794 obj = Fsymbol_name (Fprocess_status (obj));
6797 /* Print name of selected frame. */
6799 obj = XFRAME (w->frame)->name;
6802 /* indicate TEXT or BINARY */
6804 /* #### NT does not use this any more. Now what? */
6808 /* print percent of buffer above top of window, or Top, Bot or All */
6811 Bufpos pos = marker_position (w->start[type]);
6813 /* This had better be while the desired lines are being done. */
6814 if (w->window_end_pos[type] <= BUF_Z (b) - BUF_ZV (b))
6816 if (pos <= BUF_BEGV (b))
6821 else if (pos <= BUF_BEGV (b))
6825 /* This hard limit is ok since the string it will hold has a
6826 fixed maximum length of 3. But just to be safe... */
6828 Charcount chars = pos - BUF_BEGV (b);
6829 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6831 /* Avoid overflow on big buffers */
6832 int percent = total > LONG_MAX/200 ?
6833 (chars + total/200) / (total / 100) :
6834 (chars * 100 + total/2) / total;
6836 /* We can't normally display a 3-digit number, so get us a
6837 2-digit number that is close. */
6841 sprintf (buf, "%d%%", percent);
6842 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6845 goto decode_mode_spec_done;
6850 /* print percent of buffer above bottom of window, perhaps plus
6851 Top, or print Bottom or All */
6854 Bufpos toppos = marker_position (w->start[type]);
6855 Bufpos botpos = BUF_Z (b) - w->window_end_pos[type];
6857 /* botpos is only accurate as of the last redisplay, so we can
6858 only treat it as a hint. In particular, after erase-buffer,
6859 botpos may be negative. */
6860 if (botpos < toppos)
6863 if (botpos >= BUF_ZV (b))
6865 if (toppos <= BUF_BEGV (b))
6872 /* This hard limit is ok since the string it will hold has a
6873 fixed maximum length of around 6. But just to be safe... */
6875 Charcount chars = botpos - BUF_BEGV (b);
6876 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6878 /* Avoid overflow on big buffers */
6879 int percent = total > LONG_MAX/200 ?
6880 (chars + total/200) / (total / 100) :
6881 (chars * 100 + total/2) / max (total, 1);
6883 /* We can't normally display a 3-digit number, so get us a
6884 2-digit number that is close. */
6888 if (toppos <= BUF_BEGV (b))
6889 sprintf (buf, "Top%d%%", percent);
6891 sprintf (buf, "%d%%", percent);
6893 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6896 goto decode_mode_spec_done;
6906 /* print one [ for each recursive editing level. */
6911 if (command_loop_level > 5)
6917 for (i = 0; i < command_loop_level; i++)
6918 Dynarr_add (mode_spec_bufbyte_string, '[');
6920 goto decode_mode_spec_done;
6923 /* print one ] for each recursive editing level. */
6928 if (command_loop_level > 5)
6934 for (i = 0; i < command_loop_level; i++)
6935 Dynarr_add (mode_spec_bufbyte_string, ']');
6937 goto decode_mode_spec_done;
6940 /* print infinitely many dashes -- handle at top level now */
6947 Dynarr_add_many (mode_spec_bufbyte_string,
6949 XSTRING_LENGTH (obj));
6951 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) str, strlen (str));
6953 decode_mode_spec_done:
6954 Dynarr_add (mode_spec_bufbyte_string, '\0');
6957 /* Given a display line, free all of its data structures. */
6960 free_display_line (struct display_line *dl)
6964 if (dl->display_blocks)
6966 for (block = 0; block < Dynarr_largest (dl->display_blocks); block++)
6968 struct display_block *db = Dynarr_atp (dl->display_blocks, block);
6970 Dynarr_free (db->runes);
6973 Dynarr_free (dl->display_blocks);
6974 dl->display_blocks = NULL;
6977 if (dl->left_glyphs)
6979 Dynarr_free (dl->left_glyphs);
6980 dl->left_glyphs = NULL;
6983 if (dl->right_glyphs)
6985 Dynarr_free (dl->right_glyphs);
6986 dl->right_glyphs = NULL;
6991 /* Given an array of display lines, free them and all data structures
6992 contained within them. */
6995 free_display_lines (display_line_dynarr *dla)
6999 for (line = 0; line < Dynarr_largest (dla); line++)
7001 free_display_line (Dynarr_atp (dla, line));
7007 /* Call internal free routine for each set of display lines. */
7010 free_display_structs (struct window_mirror *mir)
7012 if (mir->current_display_lines)
7014 free_display_lines (mir->current_display_lines);
7015 mir->current_display_lines = 0;
7018 if (mir->desired_display_lines)
7020 free_display_lines (mir->desired_display_lines);
7021 mir->desired_display_lines = 0;
7027 mark_glyph_block_dynarr (glyph_block_dynarr *gba)
7031 glyph_block *gb = Dynarr_atp (gba, 0);
7032 glyph_block *gb_last = Dynarr_atp (gba, Dynarr_length (gba));
7034 for (; gb < gb_last; gb++)
7036 if (!NILP (gb->glyph))
7037 mark_object (gb->glyph);
7038 if (!NILP (gb->extent))
7039 mark_object (gb->extent);
7044 /* See the comment in image_instantiate_cache_result as to why marking
7045 the glyph will also mark the image_instance. */
7047 mark_redisplay_structs (display_line_dynarr *dla)
7049 display_line *dl = Dynarr_atp (dla, 0);
7050 display_line *dl_last = Dynarr_atp (dla, Dynarr_length (dla));
7052 for (; dl < dl_last; dl++)
7054 display_block_dynarr *dba = dl->display_blocks;
7055 display_block *db = Dynarr_atp (dba, 0);
7056 display_block *db_last = Dynarr_atp (dba, Dynarr_length (dba));
7058 for (; db < db_last; db++)
7060 rune_dynarr *ra = db->runes;
7061 rune *r = Dynarr_atp (ra, 0);
7062 rune *r_last = Dynarr_atp (ra, Dynarr_length (ra));
7064 for (; r < r_last; r++)
7066 if (r->type == RUNE_DGLYPH)
7068 if (!NILP (r->object.dglyph.glyph))
7069 mark_object (r->object.dglyph.glyph);
7070 if (!NILP (r->object.dglyph.extent))
7071 mark_object (r->object.dglyph.extent);
7076 mark_glyph_block_dynarr (dl->left_glyphs);
7077 mark_glyph_block_dynarr (dl->right_glyphs);
7082 mark_window_mirror (struct window_mirror *mir)
7084 mark_redisplay_structs (mir->current_display_lines);
7085 mark_redisplay_structs (mir->desired_display_lines);
7088 mark_window_mirror (mir->next);
7091 mark_window_mirror (mir->hchild);
7092 else if (mir->vchild)
7093 mark_window_mirror (mir->vchild);
7097 mark_redisplay (void)
7099 Lisp_Object frmcons, devcons, concons;
7101 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
7103 struct frame *f = XFRAME (XCAR (frmcons));
7104 update_frame_window_mirror (f);
7105 mark_window_mirror (f->root_mirror);
7110 /*****************************************************************************
7111 Line Start Cache Description and Rationale
7113 The traditional scrolling code in Emacs breaks in a variable height world.
7114 It depends on the key assumption that the number of lines that can be
7115 displayed at any given time is fixed. This led to a complete separation
7116 of the scrolling code from the redisplay code. In order to fully support
7117 variable height lines, the scrolling code must actually be tightly
7118 integrated with redisplay. Only redisplay can determine how many lines
7119 will be displayed on a screen for any given starting point.
7121 What is ideally wanted is a complete list of the starting buffer position
7122 for every possible display line of a buffer along with the height of that
7123 display line. Maintaining such a full list would be very expensive. We
7124 settle for having it include information for all areas which we happen to
7125 generate anyhow (i.e. the region currently being displayed) and for those
7126 areas we need to work with.
7128 In order to ensure that the cache accurately represents what redisplay
7129 would actually show, it is necessary to invalidate it in many situations.
7130 If the buffer changes, the starting positions may no longer be correct.
7131 If a face or an extent has changed then the line heights may have altered.
7132 These events happen frequently enough that the cache can end up being
7133 constantly disabled. With this potentially constant invalidation when is
7134 the cache ever useful?
7136 Even if the cache is invalidated before every single usage, it is
7137 necessary. Scrolling often requires knowledge about display lines which
7138 are actually above or below the visible region. The cache provides a
7139 convenient light-weight method of storing this information for multiple
7140 display regions. This knowledge is necessary for the scrolling code to
7141 always obey the First Golden Rule of Redisplay.
7143 If the cache already contains all of the information that the scrolling
7144 routines happen to need so that it doesn't have to go generate it, then we
7145 are able to obey the Third Golden Rule of Redisplay. The first thing we
7146 do to help out the cache is to always add the displayed region. This
7147 region had to be generated anyway, so the cache ends up getting the
7148 information basically for free. In those cases where a user is simply
7149 scrolling around viewing a buffer there is a high probability that this is
7150 sufficient to always provide the needed information. The second thing we
7151 can do is be smart about invalidating the cache.
7153 TODO -- Be smart about invalidating the cache. Potential places:
7155 + Insertions at end-of-line which don't cause line-wraps do not alter the
7156 starting positions of any display lines. These types of buffer
7157 modifications should not invalidate the cache. This is actually a large
7158 optimization for redisplay speed as well.
7160 + Buffer modifications frequently only affect the display of lines at and
7161 below where they occur. In these situations we should only invalidate
7162 the part of the cache starting at where the modification occurs.
7164 In case you're wondering, the Second Golden Rule of Redisplay is not
7166 ****************************************************************************/
7168 /* This will get used quite a bit so we don't want to be constantly
7169 allocating and freeing it. */
7170 static line_start_cache_dynarr *internal_cache;
7172 /* Makes internal_cache represent the TYPE display structs and only
7173 the TYPE display structs. */
7176 update_internal_cache_list (struct window *w, int type)
7179 display_line_dynarr *dla = window_display_lines (w, type);
7181 Dynarr_reset (internal_cache);
7182 for (line = 0; line < Dynarr_length (dla); line++)
7184 struct display_line *dl = Dynarr_atp (dla, line);
7190 struct line_start_cache lsc;
7192 lsc.start = dl->bufpos;
7193 lsc.end = dl->end_bufpos;
7194 lsc.height = dl->ascent + dl->descent;
7196 Dynarr_add (internal_cache, lsc);
7201 /* Reset the line cache if necessary. This should be run at the
7202 beginning of any function which access the cache. */
7205 validate_line_start_cache (struct window *w)
7207 struct buffer *b = XBUFFER (w->buffer);
7208 struct frame *f = XFRAME (w->frame);
7210 if (!w->line_cache_validation_override)
7212 /* f->extents_changed used to be in here because extent face and
7213 size changes can cause text shifting. However, the extent
7214 covering the region is constantly having its face set and
7215 priority altered by the mouse code. This means that the line
7216 start cache is constantly being invalidated. This is bad
7217 since the mouse code also triggers heavy usage of the cache.
7218 Since it is an unlikely that f->extents being changed
7219 indicates that the cache really needs to be updated and if it
7220 does redisplay will catch it pretty quickly we no longer
7221 invalidate the cache if it is set. This greatly speeds up
7222 dragging out regions with the mouse. */
7223 if (XINT (w->line_cache_last_updated) < BUF_MODIFF (b)
7227 Dynarr_reset (w->line_start_cache);
7232 /* Return the very first buffer position contained in the given
7233 window's cache, or -1 if the cache is empty. Assumes that the
7237 line_start_cache_start (struct window *w)
7239 line_start_cache_dynarr *cache = w->line_start_cache;
7241 if (!Dynarr_length (cache))
7244 return Dynarr_atp (cache, 0)->start;
7247 /* Return the very last buffer position contained in the given
7248 window's cache, or -1 if the cache is empty. Assumes that the
7252 line_start_cache_end (struct window *w)
7254 line_start_cache_dynarr *cache = w->line_start_cache;
7256 if (!Dynarr_length (cache))
7259 return Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
7262 /* Return the index of the line POINT is contained within in window
7263 W's line start cache. It will enlarge the cache or move the cache
7264 window in order to have POINT be present in the cache. MIN_PAST is
7265 a guarantee of the number of entries in the cache present on either
7266 side of POINT (unless a buffer boundary is hit). If MIN_PAST is -1
7267 then it will be treated as 0, but the cache window will not be
7268 allowed to shift. Returns -1 if POINT cannot be found in the cache
7272 point_in_line_start_cache (struct window *w, Bufpos point, int min_past)
7274 struct buffer *b = XBUFFER (w->buffer);
7275 line_start_cache_dynarr *cache = w->line_start_cache;
7276 unsigned int top, bottom, pos;
7278 validate_line_start_cache (w);
7279 w->line_cache_validation_override++;
7281 /* Let functions pass in negative values, but we still treat -1
7283 /* #### bogosity alert */
7284 if (min_past < 0 && min_past != -1)
7285 min_past = -min_past;
7287 if (!Dynarr_length (cache) || line_start_cache_start (w) > point
7288 || line_start_cache_end (w) < point)
7291 int win_char_height = window_char_height (w, 1);
7293 /* Occasionally we get here with a 0 height
7294 window. find_next_newline_no_quit will abort if we pass it a
7295 count of 0 so handle that case. */
7296 if (!win_char_height)
7297 win_char_height = 1;
7299 if (!Dynarr_length (cache))
7301 Bufpos from = find_next_newline_no_quit (b, point, -1);
7302 Bufpos to = find_next_newline_no_quit (b, from, win_char_height);
7304 update_line_start_cache (w, from, to, point, 0);
7306 if (!Dynarr_length (cache))
7308 w->line_cache_validation_override--;
7313 assert (Dynarr_length (cache));
7316 while (line_start_cache_start (w) > point
7317 && (loop < cache_adjustment || min_past == -1))
7321 from = line_start_cache_start (w);
7322 if (from <= BUF_BEGV (b))
7325 from = find_next_newline_no_quit (b, from, -win_char_height);
7326 to = line_start_cache_end (w);
7328 update_line_start_cache (w, from, to, point, 0);
7332 if (line_start_cache_start (w) > point)
7336 from = find_next_newline_no_quit (b, point, -1);
7337 if (from >= BUF_ZV (b))
7339 to = find_next_newline_no_quit (b, from, -win_char_height);
7344 to = find_next_newline_no_quit (b, from, win_char_height);
7346 update_line_start_cache (w, from, to, point, 0);
7350 while (line_start_cache_end (w) < point
7351 && (loop < cache_adjustment || min_past == -1))
7355 to = line_start_cache_end (w);
7356 if (to >= BUF_ZV (b))
7359 from = line_start_cache_end (w);
7360 to = find_next_newline_no_quit (b, from, win_char_height);
7362 update_line_start_cache (w, from, to, point, 0);
7366 if (line_start_cache_end (w) < point)
7370 from = find_next_newline_no_quit (b, point, -1);
7371 if (from >= BUF_ZV (b))
7373 to = find_next_newline_no_quit (b, from, -win_char_height);
7378 to = find_next_newline_no_quit (b, from, win_char_height);
7380 update_line_start_cache (w, from, to, point, 0);
7384 assert (Dynarr_length (cache));
7389 /* This could happen if the buffer is narrowed. */
7390 if (line_start_cache_start (w) > point
7391 || line_start_cache_end (w) < point)
7393 w->line_cache_validation_override--;
7399 top = Dynarr_length (cache) - 1;
7404 unsigned int new_pos;
7407 pos = (bottom + top + 1) >> 1;
7408 start = Dynarr_atp (cache, pos)->start;
7409 end = Dynarr_atp (cache, pos)->end;
7411 if (point >= start && point <= end)
7413 if (pos < min_past && line_start_cache_start (w) > BUF_BEGV (b))
7416 find_next_newline_no_quit (b, line_start_cache_start (w),
7418 Bufpos to = line_start_cache_end (w);
7420 update_line_start_cache (w, from, to, point, 0);
7421 goto find_point_loop;
7423 else if ((Dynarr_length (cache) - pos - 1) < min_past
7424 && line_start_cache_end (w) < BUF_ZV (b))
7426 Bufpos from = line_start_cache_end (w);
7427 Bufpos to = find_next_newline_no_quit (b, from,
7432 update_line_start_cache (w, from, to, point, 0);
7433 goto find_point_loop;
7437 w->line_cache_validation_override--;
7441 else if (point > end)
7443 else if (point < start)
7448 new_pos = (bottom + top + 1) >> 1;
7451 w->line_cache_validation_override--;
7457 /* Return a boolean indicating if POINT would be visible in window W
7458 if display of the window was to begin at STARTP. */
7461 point_would_be_visible (struct window *w, Bufpos startp, Bufpos point)
7463 struct buffer *b = XBUFFER (w->buffer);
7464 int pixpos = -WINDOW_TEXT_TOP_CLIP(w);
7465 int bottom = WINDOW_TEXT_HEIGHT (w);
7468 /* If point is before the intended start it obviously can't be visible. */
7472 /* If point or start are not in the accessible buffer range, then
7474 if (startp < BUF_BEGV (b) || startp > BUF_ZV (b)
7475 || point < BUF_BEGV (b) || point > BUF_ZV (b))
7478 validate_line_start_cache (w);
7479 w->line_cache_validation_override++;
7481 start_elt = point_in_line_start_cache (w, startp, 0);
7482 if (start_elt == -1)
7484 w->line_cache_validation_override--;
7488 assert (line_start_cache_start (w) <= startp
7489 && line_start_cache_end (w) >= startp);
7495 /* Expand the cache if necessary. */
7496 if (start_elt == Dynarr_length (w->line_start_cache))
7499 Dynarr_atp (w->line_start_cache, start_elt - 1)->start;
7501 start_elt = point_in_line_start_cache (w, old_startp,
7502 window_char_height (w, 0));
7504 /* We've already actually processed old_startp, so increment
7508 /* If this happens we didn't add any extra elements. Bummer. */
7509 if (start_elt == Dynarr_length (w->line_start_cache))
7511 w->line_cache_validation_override--;
7516 height = Dynarr_atp (w->line_start_cache, start_elt)->height;
7518 if (pixpos + height > bottom)
7520 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7522 w->line_cache_validation_override--;
7528 if (point <= Dynarr_atp (w->line_start_cache, start_elt)->end)
7530 w->line_cache_validation_override--;
7538 /* For the given window W, if display starts at STARTP, what will be
7539 the buffer position at the beginning or end of the last line
7540 displayed. The end of the last line is also know as the window end
7543 WARNING: It is possible that redisplay failed to layout any lines for the
7544 windows. Under normal circumstances this is rare. However it seems that it
7545 does occur in the following situation: A mouse event has come in and we
7546 need to compute its location in a window. That code (in
7547 pixel_to_glyph_translation) already can handle 0 as an error return value.
7549 #### With a little work this could probably be reworked as just a
7550 call to start_with_line_at_pixpos. */
7553 start_end_of_last_line (struct window *w, Bufpos startp, int end,
7556 struct buffer *b = XBUFFER (w->buffer);
7557 line_start_cache_dynarr *cache = w->line_start_cache;
7559 int bottom = WINDOW_TEXT_HEIGHT (w);
7563 validate_line_start_cache (w);
7564 w->line_cache_validation_override++;
7566 if (startp < BUF_BEGV (b))
7567 startp = BUF_BEGV (b);
7568 else if (startp > BUF_ZV (b))
7569 startp = BUF_ZV (b);
7572 start_elt = point_in_line_start_cache (w, cur_start, 0);
7573 if (start_elt == -1)
7574 return may_error ? 0 : startp;
7578 int height = Dynarr_atp (cache, start_elt)->height;
7580 cur_start = Dynarr_atp (cache, start_elt)->start;
7582 if (pixpos + height > bottom)
7584 /* Adjust for any possible clip. */
7585 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7590 w->line_cache_validation_override--;
7594 return BUF_BEGV (b);
7598 w->line_cache_validation_override--;
7600 return Dynarr_atp (cache, start_elt)->end;
7602 return Dynarr_atp (cache, start_elt)->start;
7608 if (start_elt == Dynarr_length (cache))
7610 Bufpos from = line_start_cache_end (w);
7611 int win_char_height = window_char_height (w, 0);
7612 Bufpos to = find_next_newline_no_quit (b, from,
7617 /* We've hit the end of the bottom so that's what it is. */
7618 if (from >= BUF_ZV (b))
7620 w->line_cache_validation_override--;
7624 update_line_start_cache (w, from, to, BUF_PT (b), 0);
7626 /* Updating the cache invalidates any current indexes. */
7627 start_elt = point_in_line_start_cache (w, cur_start, -1) + 1;
7632 /* For the given window W, if display starts at STARTP, what will be
7633 the buffer position at the beginning of the last line displayed. */
7636 start_of_last_line (struct window *w, Bufpos startp)
7638 return start_end_of_last_line (w, startp, 0 , 0);
7641 /* For the given window W, if display starts at STARTP, what will be
7642 the buffer position at the end of the last line displayed. This is
7643 also know as the window end position. */
7646 end_of_last_line (struct window *w, Bufpos startp)
7648 return start_end_of_last_line (w, startp, 1, 0);
7652 end_of_last_line_may_error (struct window *w, Bufpos startp)
7654 return start_end_of_last_line (w, startp, 1, 1);
7658 /* For window W, what does the starting position have to be so that
7659 the line containing POINT will cover pixel position PIXPOS. */
7662 start_with_line_at_pixpos (struct window *w, Bufpos point, int pixpos)
7664 struct buffer *b = XBUFFER (w->buffer);
7666 Bufpos cur_pos, prev_pos = point;
7667 int point_line_height;
7668 int pixheight = pixpos - WINDOW_TEXT_TOP (w);
7670 validate_line_start_cache (w);
7671 w->line_cache_validation_override++;
7673 cur_elt = point_in_line_start_cache (w, point, 0);
7674 /* #### See comment in update_line_start_cache about big minibuffers. */
7677 w->line_cache_validation_override--;
7681 point_line_height = Dynarr_atp (w->line_start_cache, cur_elt)->height;
7685 cur_pos = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7687 pixheight -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7689 /* Do not take into account the value of vertical_clip here.
7690 That is the responsibility of the calling functions. */
7693 w->line_cache_validation_override--;
7694 if (-pixheight > point_line_height)
7695 /* We can't make the target line cover pixpos, so put it
7696 above pixpos. That way it will at least be visible. */
7706 int win_char_height;
7708 if (cur_pos <= BUF_BEGV (b))
7710 w->line_cache_validation_override--;
7711 return BUF_BEGV (b);
7714 win_char_height = window_char_height (w, 0);
7715 if (!win_char_height)
7716 win_char_height = 1;
7718 from = find_next_newline_no_quit (b, cur_pos, -win_char_height);
7719 to = line_start_cache_end (w);
7720 update_line_start_cache (w, from, to, point, 0);
7722 cur_elt = point_in_line_start_cache (w, cur_pos, 2) - 1;
7723 assert (cur_elt >= -1);
7724 /* This used to be cur_elt>=0 under the assumption that if
7725 point is in the top line and not at BUF_BEGV, then
7726 setting the window_start to a newline before the start of
7727 the first line will always cause scrolling.
7729 However in my (jv) opinion this is wrong. That new line
7730 can be hidden in various ways: invisible extents, an
7731 explicit window-start not at a newline character etc.
7732 The existence of those are indeed known to create crashes
7733 on that assert. So we have no option but to continue the
7734 search if we found point at the top of the line_start_cache
7736 cur_pos = Dynarr_atp (w->line_start_cache,0)->start;
7742 /* For window W, what does the starting position have to be so that
7743 the line containing point is on display line LINE. If LINE is
7744 positive it is considered to be the number of lines from the top of
7745 the window (0 is the top line). If it is negative the number is
7746 considered to be the number of lines from the bottom (-1 is the
7750 start_with_point_on_display_line (struct window *w, Bufpos point, int line)
7752 validate_line_start_cache (w);
7753 w->line_cache_validation_override++;
7757 int cur_elt = point_in_line_start_cache (w, point, line);
7759 if (cur_elt - line < 0)
7760 cur_elt = 0; /* Hit the top */
7764 w->line_cache_validation_override--;
7765 return Dynarr_atp (w->line_start_cache, cur_elt)->start;
7769 /* The calculated value of pixpos is correct for the bottom line
7770 or what we want when line is -1. Therefore we subtract one
7771 because we have already handled one line. */
7772 int new_line = -line - 1;
7773 int cur_elt = point_in_line_start_cache (w, point, new_line);
7774 int pixpos = WINDOW_TEXT_BOTTOM (w);
7775 Bufpos retval, search_point;
7777 /* If scroll_on_clipped_lines is false, the last "visible" line of
7778 the window covers the pixel at WINDOW_TEXT_BOTTOM (w) - 1.
7779 If s_o_c_l is true, then we don't want to count a clipped
7780 line, so back up from the bottom by the height of the line
7781 containing point. */
7782 if (scroll_on_clipped_lines)
7783 pixpos -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7787 if (cur_elt + new_line >= Dynarr_length (w->line_start_cache))
7789 /* Hit the bottom of the buffer. */
7791 (cur_elt + new_line) - Dynarr_length (w->line_start_cache) + 1;
7795 XSETWINDOW (window, w);
7796 default_face_height_and_width (window, &defheight, 0);
7798 cur_elt = Dynarr_length (w->line_start_cache) - 1;
7800 pixpos -= (adjustment * defheight);
7801 if (pixpos < WINDOW_TEXT_TOP (w))
7802 pixpos = WINDOW_TEXT_TOP (w);
7805 cur_elt = cur_elt + new_line;
7807 search_point = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7809 retval = start_with_line_at_pixpos (w, search_point, pixpos);
7810 w->line_cache_validation_override--;
7815 /* This is used to speed up vertical scrolling by caching the known
7816 buffer starting positions for display lines. This allows the
7817 scrolling routines to avoid costly calls to regenerate_window. If
7818 NO_REGEN is true then it will only add the values in the DESIRED
7819 display structs which are in the given range.
7821 Note also that the FROM/TO values are minimums. It is possible
7822 that this function will actually add information outside of the
7823 lines containing those positions. This can't hurt but it could
7826 #### We currently force the cache to have only 1 contiguous region.
7827 It might help to make the cache a dynarr of caches so that we can
7828 cover more areas. This might, however, turn out to be a lot of
7829 overhead for too little gain. */
7832 update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
7833 Bufpos point, int no_regen)
7835 struct buffer *b = XBUFFER (w->buffer);
7836 line_start_cache_dynarr *cache = w->line_start_cache;
7837 Bufpos low_bound, high_bound;
7839 validate_line_start_cache (w);
7840 w->line_cache_validation_override++;
7842 if (from < BUF_BEGV (b))
7843 from = BUF_BEGV (b);
7844 if (to > BUF_ZV (b))
7849 w->line_cache_validation_override--;
7853 if (Dynarr_length (cache))
7855 low_bound = line_start_cache_start (w);
7856 high_bound = line_start_cache_end (w);
7858 /* Check to see if the desired range is already in the cache. */
7859 if (from >= low_bound && to <= high_bound)
7861 w->line_cache_validation_override--;
7865 /* Check to make sure that the desired range is adjacent to the
7866 current cache. If not, invalidate the cache. */
7867 if (to < low_bound || from > high_bound)
7869 Dynarr_reset (cache);
7870 low_bound = high_bound = -1;
7875 low_bound = high_bound = -1;
7878 w->line_cache_last_updated = make_int (BUF_MODIFF (b));
7880 /* This could be integrated into the next two sections, but it is easier
7881 to follow what's going on by having it separate. */
7886 update_internal_cache_list (w, DESIRED_DISP);
7887 if (!Dynarr_length (internal_cache))
7889 w->line_cache_validation_override--;
7893 start = Dynarr_atp (internal_cache, 0)->start;
7895 Dynarr_atp (internal_cache, Dynarr_length (internal_cache) - 1)->end;
7897 /* We aren't allowed to generate additional information to fill in
7898 gaps, so if the DESIRED structs don't overlap the cache, reset the
7900 if (Dynarr_length (cache))
7902 if (end < low_bound || start > high_bound)
7903 Dynarr_reset (cache);
7905 /* #### What should really happen if what we are doing is
7906 extending a line (the last line)? */
7907 if (Dynarr_length (cache) == 1
7908 && Dynarr_length (internal_cache) == 1)
7909 Dynarr_reset (cache);
7912 if (!Dynarr_length (cache))
7914 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7915 Dynarr_length (internal_cache));
7916 w->line_cache_validation_override--;
7920 /* An extra check just in case the calling function didn't pass in
7921 the bounds of the DESIRED structs in the first place. */
7922 if (start >= low_bound && end <= high_bound)
7924 w->line_cache_validation_override--;
7928 /* At this point we know that the internal cache partially overlaps
7930 if (start < low_bound)
7932 int ic_elt = Dynarr_length (internal_cache) - 1;
7935 if (Dynarr_atp (internal_cache, ic_elt)->start < low_bound)
7943 Dynarr_reset (cache);
7944 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7945 Dynarr_length (internal_cache));
7946 w->line_cache_validation_override--;
7950 Dynarr_insert_many_at_start (cache, Dynarr_atp (internal_cache, 0),
7954 if (end > high_bound)
7958 while (ic_elt < Dynarr_length (internal_cache))
7960 if (Dynarr_atp (internal_cache, ic_elt)->start > high_bound)
7966 if (!(ic_elt < Dynarr_length (internal_cache)))
7968 Dynarr_reset (cache);
7969 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7970 Dynarr_length (internal_cache));
7971 w->line_cache_validation_override--;
7975 Dynarr_add_many (cache, Dynarr_atp (internal_cache, ic_elt),
7976 Dynarr_length (internal_cache) - ic_elt);
7979 w->line_cache_validation_override--;
7983 if (!Dynarr_length (cache) || from < low_bound)
7985 Bufpos startp = find_next_newline_no_quit (b, from, -1);
7987 int old_lb = low_bound;
7989 while (startp < old_lb || low_bound == -1)
7994 regenerate_window (w, startp, point, CMOTION_DISP);
7995 update_internal_cache_list (w, CMOTION_DISP);
7997 /* If this assert is triggered then regenerate_window failed
7998 to layout a single line. This is not possible since we
7999 force at least a single line to be layout for CMOTION_DISP */
8000 assert (Dynarr_length (internal_cache));
8001 assert (startp == Dynarr_atp (internal_cache, 0)->start);
8003 ic_elt = Dynarr_length (internal_cache) - 1;
8004 if (low_bound != -1)
8008 if (Dynarr_atp (internal_cache, ic_elt)->start < old_lb)
8014 assert (ic_elt >= 0);
8016 new_startp = Dynarr_atp (internal_cache, ic_elt)->end + 1;
8019 * Handle invisible text properly:
8020 * If the last line we're inserting has the same end as the
8021 * line before which it will be added, merge the two lines.
8023 if (Dynarr_length (cache) &&
8024 Dynarr_atp (internal_cache, ic_elt)->end ==
8025 Dynarr_atp (cache, marker)->end)
8027 Dynarr_atp (cache, marker)->start
8028 = Dynarr_atp (internal_cache, ic_elt)->start;
8029 Dynarr_atp (cache, marker)->height
8030 = Dynarr_atp (internal_cache, ic_elt)->height;
8034 if (ic_elt >= 0) /* we still have lines to add.. */
8036 Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0),
8037 ic_elt + 1, marker);
8038 marker += (ic_elt + 1);
8041 if (startp < low_bound || low_bound == -1)
8043 startp = new_startp;
8044 if (startp > BUF_ZV (b))
8046 w->line_cache_validation_override--;
8052 assert (Dynarr_length (cache));
8053 assert (from >= low_bound);
8055 /* Readjust the high_bound to account for any changes made while
8056 correcting the low_bound. */
8057 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8059 if (to > high_bound)
8061 Bufpos startp = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end + 1;
8065 regenerate_window (w, startp, point, CMOTION_DISP);
8066 update_internal_cache_list (w, CMOTION_DISP);
8068 /* See comment above about regenerate_window failing. */
8069 assert (Dynarr_length (internal_cache));
8071 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
8072 Dynarr_length (internal_cache));
8073 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8074 startp = high_bound + 1;
8076 while (to > high_bound);
8079 w->line_cache_validation_override--;
8080 assert (to <= high_bound);
8084 /* Given x and y coordinates in characters, relative to a window,
8085 return the pixel location corresponding to those coordinates. The
8086 pixel location returned is the center of the given character
8087 position. The pixel values are generated relative to the window,
8090 The modeline is considered to be part of the window. */
8093 glyph_to_pixel_translation (struct window *w, int char_x, int char_y,
8094 int *pix_x, int *pix_y)
8096 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
8097 int num_disp_lines, modeline;
8099 int defheight, defwidth;
8101 XSETWINDOW (window, w);
8102 default_face_height_and_width (window, &defheight, &defwidth);
8104 /* If we get a bogus value indicating somewhere above or to the left of
8105 the window, use the first window line or character position
8112 num_disp_lines = Dynarr_length (dla);
8116 if (Dynarr_atp (dla, 0)->modeline)
8123 /* First check if the y position intersects the display lines. */
8124 if (char_y < num_disp_lines)
8126 struct display_line *dl = Dynarr_atp (dla, char_y + modeline);
8127 struct display_block *db = get_display_block_from_line (dl, TEXT);
8129 *pix_y = (dl->ypos - dl->ascent +
8130 ((unsigned int) (dl->ascent + dl->descent - dl->clip) >> 1));
8132 if (char_x < Dynarr_length (db->runes))
8134 struct rune *rb = Dynarr_atp (db->runes, char_x);
8136 *pix_x = rb->xpos + (rb->width >> 1);
8140 int last_rune = Dynarr_length (db->runes) - 1;
8141 struct rune *rb = Dynarr_atp (db->runes, last_rune);
8143 char_x -= last_rune;
8145 *pix_x = rb->xpos + rb->width;
8146 *pix_x += ((char_x - 1) * defwidth);
8147 *pix_x += (defwidth >> 1);
8152 /* It didn't intersect, so extrapolate. #### For now, we include the
8153 modeline in this since we don't have true character positions in
8156 if (!Dynarr_length (w->face_cachels))
8157 reset_face_cachels (w);
8159 char_y -= num_disp_lines;
8161 if (Dynarr_length (dla))
8163 struct display_line *dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
8164 *pix_y = dl->ypos + dl->descent - dl->clip;
8167 *pix_y = WINDOW_TEXT_TOP (w);
8169 *pix_y += (char_y * defheight);
8170 *pix_y += (defheight >> 1);
8172 *pix_x = WINDOW_TEXT_LEFT (w);
8173 /* Don't adjust by one because this is still the unadjusted value. */
8174 *pix_x += (char_x * defwidth);
8175 *pix_x += (defwidth >> 1);
8178 if (*pix_x > w->pixel_left + w->pixel_width)
8179 *pix_x = w->pixel_left + w->pixel_width;
8180 if (*pix_y > w->pixel_top + w->pixel_height)
8181 *pix_y = w->pixel_top + w->pixel_height;
8183 *pix_x -= w->pixel_left;
8184 *pix_y -= w->pixel_top;
8187 /* Given a display line and a position, determine if there is a glyph
8188 there and return information about it if there is. */
8191 get_position_object (struct display_line *dl, Lisp_Object *obj1,
8192 Lisp_Object *obj2, int x_coord, int *low_x_coord,
8195 struct display_block *db;
8198 get_next_display_block (dl->bounds, dl->display_blocks, x_coord, 0);
8200 /* We use get_next_display_block to get the actual display block
8201 that would be displayed at x_coord. */
8203 if (block == NO_BLOCK)
8206 db = Dynarr_atp (dl->display_blocks, block);
8208 for (elt = 0; elt < Dynarr_length (db->runes); elt++)
8210 struct rune *rb = Dynarr_atp (db->runes, elt);
8212 if (rb->xpos <= x_coord && x_coord < (rb->xpos + rb->width))
8214 if (rb->type == RUNE_DGLYPH)
8216 *obj1 = rb->object.dglyph.glyph;
8217 *obj2 = rb->object.dglyph.extent;
8226 *low_x_coord = rb->xpos;
8228 *high_x_coord = rb->xpos + rb->width;
8235 #define UPDATE_CACHE_RETURN \
8237 d->pixel_to_glyph_cache.valid = 1; \
8238 d->pixel_to_glyph_cache.low_x_coord = low_x_coord; \
8239 d->pixel_to_glyph_cache.high_x_coord = high_x_coord; \
8240 d->pixel_to_glyph_cache.low_y_coord = low_y_coord; \
8241 d->pixel_to_glyph_cache.high_y_coord = high_y_coord; \
8242 d->pixel_to_glyph_cache.frame = f; \
8243 d->pixel_to_glyph_cache.col = *col; \
8244 d->pixel_to_glyph_cache.row = *row; \
8245 d->pixel_to_glyph_cache.obj_x = *obj_x; \
8246 d->pixel_to_glyph_cache.obj_y = *obj_y; \
8247 d->pixel_to_glyph_cache.w = *w; \
8248 d->pixel_to_glyph_cache.bufpos = *bufpos; \
8249 d->pixel_to_glyph_cache.closest = *closest; \
8250 d->pixel_to_glyph_cache.modeline_closest = *modeline_closest; \
8251 d->pixel_to_glyph_cache.obj1 = *obj1; \
8252 d->pixel_to_glyph_cache.obj2 = *obj2; \
8253 d->pixel_to_glyph_cache.retval = position; \
8254 RETURN_SANS_WARNINGS position; \
8257 /* Given x and y coordinates in pixels relative to a frame, return
8258 information about what is located under those coordinates.
8260 The return value will be one of:
8262 OVER_TOOLBAR: over one of the 4 frame toolbars
8263 OVER_MODELINE: over a modeline
8264 OVER_BORDER: over an internal border
8265 OVER_NOTHING: over the text area, but not over text
8266 OVER_OUTSIDE: outside of the frame border
8267 OVER_TEXT: over text in the text area
8273 -- nil if the coordinates are not over a glyph or a toolbar button.
8277 -- an extent, if the coordinates are over a glyph in the text area
8280 If the coordinates are over a glyph, OBJ_X and OBJ_Y give the
8281 equivalent coordinates relative to the upper-left corner of the glyph.
8283 If the coordinates are over a character, OBJ_X and OBJ_Y give the
8284 equivalent coordinates relative to the upper-left corner of the character.
8286 Otherwise, OBJ_X and OBJ_Y are undefined.
8290 pixel_to_glyph_translation (struct frame *f, int x_coord, int y_coord,
8291 int *col, int *row, int *obj_x, int *obj_y,
8292 struct window **w, Bufpos *bufpos,
8293 Bufpos *closest, Charcount *modeline_closest,
8294 Lisp_Object *obj1, Lisp_Object *obj2)
8297 struct pixel_to_glyph_translation_cache *cache;
8299 int frm_left, frm_right, frm_top, frm_bottom;
8300 int low_x_coord, high_x_coord, low_y_coord, high_y_coord;
8301 int position = OVER_NOTHING;
8302 int device_check_failed = 0;
8303 display_line_dynarr *dla;
8305 /* This is a safety valve in case this got called with a frame in
8306 the middle of being deleted. */
8307 if (!DEVICEP (f->device) || !DEVICE_LIVE_P (XDEVICE (f->device)))
8309 device_check_failed = 1;
8310 d = NULL, cache = NULL; /* Warning suppression */
8314 d = XDEVICE (f->device);
8315 cache = &d->pixel_to_glyph_cache;
8318 if (!device_check_failed
8320 && cache->frame == f
8321 && cache->low_x_coord <= x_coord
8322 && cache->high_x_coord > x_coord
8323 && cache->low_y_coord <= y_coord
8324 && cache->high_y_coord > y_coord)
8328 *obj_x = cache->obj_x;
8329 *obj_y = cache->obj_y;
8331 *bufpos = cache->bufpos;
8332 *closest = cache->closest;
8333 *modeline_closest = cache->modeline_closest;
8334 *obj1 = cache->obj1;
8335 *obj2 = cache->obj2;
8337 return cache->retval;
8348 *modeline_closest = -1;
8352 low_x_coord = x_coord;
8353 high_x_coord = x_coord + 1;
8354 low_y_coord = y_coord;
8355 high_y_coord = y_coord + 1;
8358 if (device_check_failed)
8359 return OVER_NOTHING;
8361 frm_left = FRAME_LEFT_BORDER_END (f);
8362 frm_right = FRAME_RIGHT_BORDER_START (f);
8363 frm_top = FRAME_TOP_BORDER_END (f);
8364 frm_bottom = FRAME_BOTTOM_BORDER_START (f);
8366 /* Check if the mouse is outside of the text area actually used by
8368 if (y_coord < frm_top)
8370 if (y_coord >= FRAME_TOP_BORDER_START (f))
8372 low_y_coord = FRAME_TOP_BORDER_START (f);
8373 high_y_coord = frm_top;
8374 position = OVER_BORDER;
8376 else if (y_coord >= 0)
8379 high_y_coord = FRAME_TOP_BORDER_START (f);
8380 position = OVER_TOOLBAR;
8384 low_y_coord = y_coord;
8386 position = OVER_OUTSIDE;
8389 else if (y_coord >= frm_bottom)
8391 if (y_coord < FRAME_BOTTOM_BORDER_END (f))
8393 low_y_coord = frm_bottom;
8394 high_y_coord = FRAME_BOTTOM_BORDER_END (f);
8395 position = OVER_BORDER;
8397 else if (y_coord < FRAME_PIXHEIGHT (f))
8399 low_y_coord = FRAME_BOTTOM_BORDER_END (f);
8400 high_y_coord = FRAME_PIXHEIGHT (f);
8401 position = OVER_TOOLBAR;
8405 low_y_coord = FRAME_PIXHEIGHT (f);
8406 high_y_coord = y_coord;
8407 position = OVER_OUTSIDE;
8411 if (position != OVER_TOOLBAR && position != OVER_BORDER)
8413 if (x_coord < frm_left)
8415 if (x_coord >= FRAME_LEFT_BORDER_START (f))
8417 low_x_coord = FRAME_LEFT_BORDER_START (f);
8418 high_x_coord = frm_left;
8419 position = OVER_BORDER;
8421 else if (x_coord >= 0)
8424 high_x_coord = FRAME_LEFT_BORDER_START (f);
8425 position = OVER_TOOLBAR;
8429 low_x_coord = x_coord;
8431 position = OVER_OUTSIDE;
8434 else if (x_coord >= frm_right)
8436 if (x_coord < FRAME_RIGHT_BORDER_END (f))
8438 low_x_coord = frm_right;
8439 high_x_coord = FRAME_RIGHT_BORDER_END (f);
8440 position = OVER_BORDER;
8442 else if (x_coord < FRAME_PIXWIDTH (f))
8444 low_x_coord = FRAME_RIGHT_BORDER_END (f);
8445 high_x_coord = FRAME_PIXWIDTH (f);
8446 position = OVER_TOOLBAR;
8450 low_x_coord = FRAME_PIXWIDTH (f);
8451 high_x_coord = x_coord;
8452 position = OVER_OUTSIDE;
8457 #ifdef HAVE_TOOLBARS
8458 if (position == OVER_TOOLBAR)
8460 *obj1 = toolbar_button_at_pixpos (f, x_coord, y_coord);
8463 UPDATE_CACHE_RETURN;
8465 #endif /* HAVE_TOOLBARS */
8467 /* We still have to return the window the pointer is next to and its
8468 relative y position even if it is outside the x boundary. */
8469 if (x_coord < frm_left)
8471 else if (x_coord > frm_right)
8472 x_coord = frm_right;
8474 /* Same in reverse. */
8475 if (y_coord < frm_top)
8477 else if (y_coord > frm_bottom)
8478 y_coord = frm_bottom;
8480 /* Find what window the given coordinates are actually in. */
8481 window = f->root_window;
8482 *w = find_window_by_pixel_pos (x_coord, y_coord, window);
8484 /* If we didn't find a window, we're done. */
8487 UPDATE_CACHE_RETURN;
8489 else if (position != OVER_NOTHING)
8492 *modeline_closest = -1;
8494 if (high_y_coord <= frm_top || high_y_coord >= frm_bottom)
8497 UPDATE_CACHE_RETURN;
8501 /* Check if the window is a minibuffer but isn't active. */
8502 if (MINI_WINDOW_P (*w) && !minibuf_level)
8504 /* Must reset the window value since some callers will ignore
8505 the return value if it is set. */
8507 UPDATE_CACHE_RETURN;
8510 /* See if the point is over window vertical divider */
8511 if (window_needs_vertical_divider (*w))
8513 int div_x_high = WINDOW_RIGHT (*w);
8514 int div_x_low = div_x_high - window_divider_width (*w);
8515 int div_y_high = WINDOW_BOTTOM (*w);
8516 int div_y_low = WINDOW_TOP (*w);
8518 if (div_x_low < x_coord && x_coord <= div_x_high &&
8519 div_y_low < y_coord && y_coord <= div_y_high)
8521 low_x_coord = div_x_low;
8522 high_x_coord = div_x_high;
8523 low_y_coord = div_y_low;
8524 high_y_coord = div_y_high;
8525 position = OVER_V_DIVIDER;
8526 UPDATE_CACHE_RETURN;
8530 dla = window_display_lines (*w, CURRENT_DISP);
8532 for (*row = 0; *row < Dynarr_length (dla); (*row)++)
8534 int really_over_nothing = 0;
8535 struct display_line *dl = Dynarr_atp (dla, *row);
8537 if ((int) (dl->ypos - dl->ascent) <= y_coord
8538 && y_coord <= (int) (dl->ypos + dl->descent))
8540 int check_margin_glyphs = 0;
8541 struct display_block *db = get_display_block_from_line (dl, TEXT);
8542 struct rune *rb = 0;
8544 if (x_coord < dl->bounds.left_white
8545 || x_coord >= dl->bounds.right_white)
8546 check_margin_glyphs = 1;
8548 low_y_coord = dl->ypos - dl->ascent;
8549 high_y_coord = dl->ypos + dl->descent + 1;
8551 if (position == OVER_BORDER
8552 || position == OVER_OUTSIDE
8553 || check_margin_glyphs)
8555 int x_check, left_bound;
8557 if (check_margin_glyphs)
8560 left_bound = dl->bounds.left_white;
8564 x_check = high_x_coord;
8565 left_bound = frm_left;
8568 if (Dynarr_length (db->runes))
8570 if (x_check <= left_bound)
8573 *modeline_closest = Dynarr_atp (db->runes, 0)->bufpos;
8575 *closest = Dynarr_atp (db->runes, 0)->bufpos;
8581 Dynarr_atp (db->runes,
8582 Dynarr_length (db->runes) - 1)->bufpos;
8585 Dynarr_atp (db->runes,
8586 Dynarr_length (db->runes) - 1)->bufpos;
8590 *modeline_closest += dl->offset;
8592 *closest += dl->offset;
8596 /* #### What should be here. */
8598 *modeline_closest = 0;
8603 if (check_margin_glyphs)
8605 if (x_coord < dl->bounds.left_in
8606 || x_coord >= dl->bounds.right_in)
8608 /* If we are over the outside margins then we
8609 know the loop over the text block isn't going
8610 to accomplish anything. So we go ahead and
8611 set what information we can right here and
8614 *obj_y = y_coord - (dl->ypos - dl->ascent);
8615 get_position_object (dl, obj1, obj2, x_coord,
8616 &low_x_coord, &high_x_coord);
8618 UPDATE_CACHE_RETURN;
8622 UPDATE_CACHE_RETURN;
8625 for (*col = 0; *col <= Dynarr_length (db->runes); (*col)++)
8627 int past_end = (*col == Dynarr_length (db->runes));
8630 rb = Dynarr_atp (db->runes, *col);
8633 (rb->xpos <= x_coord && x_coord < rb->xpos + rb->width))
8638 rb = Dynarr_atp (db->runes, *col);
8641 *bufpos = rb->bufpos + dl->offset;
8642 low_x_coord = rb->xpos;
8643 high_x_coord = rb->xpos + rb->width;
8645 if (rb->type == RUNE_DGLYPH)
8649 /* Find the first character after the glyph. */
8650 while (elt < Dynarr_length (db->runes))
8652 if (Dynarr_atp (db->runes, elt)->type != RUNE_DGLYPH)
8656 (Dynarr_atp (db->runes, elt)->bufpos +
8660 (Dynarr_atp (db->runes, elt)->bufpos +
8668 /* In this case we failed to find a non-glyph
8669 character so we return the last position
8670 displayed on the line. */
8671 if (elt == Dynarr_length (db->runes))
8674 *modeline_closest = dl->end_bufpos + dl->offset;
8676 *closest = dl->end_bufpos + dl->offset;
8677 really_over_nothing = 1;
8683 *modeline_closest = rb->bufpos + dl->offset;
8685 *closest = rb->bufpos + dl->offset;
8690 *row = window_displayed_height (*w);
8692 if (position == OVER_NOTHING)
8693 position = OVER_MODELINE;
8695 if (rb->type == RUNE_DGLYPH)
8697 *obj1 = rb->object.dglyph.glyph;
8698 *obj2 = rb->object.dglyph.extent;
8700 else if (rb->type == RUNE_CHAR)
8711 UPDATE_CACHE_RETURN;
8714 || (rb->type == RUNE_CHAR
8715 && CHARC_ASCII_EQ (rb->object.cglyph, '\n')))
8718 /* At this point we may have glyphs in the right
8720 if (check_margin_glyphs)
8721 get_position_object (dl, obj1, obj2, x_coord,
8722 &low_x_coord, &high_x_coord);
8723 UPDATE_CACHE_RETURN;
8728 if (rb->type == RUNE_DGLYPH)
8730 *obj1 = rb->object.dglyph.glyph;
8731 *obj2 = rb->object.dglyph.extent;
8733 else if (rb->type == RUNE_CHAR)
8744 *obj_x = x_coord - rb->xpos;
8745 *obj_y = y_coord - (dl->ypos - dl->ascent);
8747 /* At this point we may have glyphs in the left
8749 if (check_margin_glyphs)
8750 get_position_object (dl, obj1, obj2, x_coord, 0, 0);
8752 if (position == OVER_NOTHING && !really_over_nothing)
8753 position = OVER_TEXT;
8755 UPDATE_CACHE_RETURN;
8762 *row = Dynarr_length (dla) - 1;
8763 if (FRAME_WIN_P (f))
8765 int bot_elt = Dynarr_length (dla) - 1;
8769 struct display_line *dl = Dynarr_atp (dla, bot_elt);
8770 int adj_area = y_coord - (dl->ypos + dl->descent);
8774 XSETWINDOW (lwin, *w);
8775 default_face_height_and_width (lwin, 0, &defheight);
8777 *row += (adj_area / defheight);
8781 /* #### This should be checked out some more to determine what
8782 should really be going on. */
8783 if (!MARKERP ((*w)->start[CURRENT_DISP]))
8786 *closest = end_of_last_line_may_error (*w,
8787 marker_position ((*w)->start[CURRENT_DISP]));
8789 UPDATE_CACHE_RETURN;
8791 #undef UPDATE_CACHE_RETURN
8794 /***************************************************************************/
8796 /* Lisp functions */
8798 /***************************************************************************/
8800 DEFUN ("redisplay-echo-area", Fredisplay_echo_area, 0, 0, 0, /*
8801 Ensure that all minibuffers are correctly showing the echo area.
8805 Lisp_Object devcons, concons;
8807 DEVICE_LOOP_NO_BREAK (devcons, concons)
8809 struct device *d = XDEVICE (XCAR (devcons));
8810 Lisp_Object frmcons;
8812 DEVICE_FRAME_LOOP (frmcons, d)
8814 struct frame *f = XFRAME (XCAR (frmcons));
8816 if (FRAME_REPAINT_P (f) && FRAME_HAS_MINIBUF_P (f))
8818 Lisp_Object window = FRAME_MINIBUF_WINDOW (f);
8820 MAYBE_DEVMETH (d, frame_output_begin, (f));
8823 * If the frame size has changed, there may be random
8824 * chud on the screen left from previous messages
8825 * because redisplay_frame hasn't been called yet.
8826 * Clear the screen to get rid of the potential mess.
8828 if (f->echo_area_garbaged)
8830 MAYBE_DEVMETH (d, clear_frame, (f));
8831 f->echo_area_garbaged = 0;
8833 redisplay_window (window, 0);
8834 MAYBE_DEVMETH (d, frame_output_end, (f));
8836 call_redisplay_end_triggers (XWINDOW (window), 0);
8845 restore_disable_preemption_value (Lisp_Object value)
8847 disable_preemption = XINT (value);
8851 DEFUN ("redraw-frame", Fredraw_frame, 0, 2, 0, /*
8852 Clear frame FRAME and output again what is supposed to appear on it.
8853 FRAME defaults to the selected frame if omitted.
8854 Normally, redisplay is preempted as normal if input arrives. However,
8855 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8856 input and is guaranteed to proceed to completion.
8858 (frame, no_preempt))
8860 struct frame *f = decode_frame (frame);
8861 int count = specpdl_depth ();
8863 if (!NILP (no_preempt))
8865 record_unwind_protect (restore_disable_preemption_value,
8866 make_int (disable_preemption));
8867 disable_preemption++;
8871 redisplay_frame (f, 1);
8873 /* See the comment in Fredisplay_frame. */
8874 RESET_CHANGED_SET_FLAGS;
8876 return unbind_to (count, Qnil);
8879 DEFUN ("redisplay-frame", Fredisplay_frame, 0, 2, 0, /*
8880 Ensure that FRAME's contents are correctly displayed.
8881 This differs from `redraw-frame' in that it only redraws what needs to
8882 be updated, as opposed to unconditionally clearing and redrawing
8884 FRAME defaults to the selected frame if omitted.
8885 Normally, redisplay is preempted as normal if input arrives. However,
8886 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8887 input and is guaranteed to proceed to completion.
8889 (frame, no_preempt))
8891 struct frame *f = decode_frame (frame);
8892 int count = specpdl_depth ();
8894 if (!NILP (no_preempt))
8896 record_unwind_protect (restore_disable_preemption_value,
8897 make_int (disable_preemption));
8898 disable_preemption++;
8901 redisplay_frame (f, 1);
8903 /* If we don't reset the global redisplay flags here, subsequent
8904 changes to the display will not get registered by redisplay
8905 because it thinks it already has registered changes. If you
8906 really knew what you were doing you could confuse redisplay by
8907 calling Fredisplay_frame while updating another frame. We assume
8908 that if you know what you are doing you will not be that
8910 RESET_CHANGED_SET_FLAGS;
8912 return unbind_to (count, Qnil);
8915 DEFUN ("redraw-device", Fredraw_device, 0, 2, 0, /*
8916 Clear device DEVICE and output again what is supposed to appear on it.
8917 DEVICE defaults to the selected device if omitted.
8918 Normally, redisplay is preempted as normal if input arrives. However,
8919 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8920 input and is guaranteed to proceed to completion.
8922 (device, no_preempt))
8924 struct device *d = decode_device (device);
8925 Lisp_Object frmcons;
8926 int count = specpdl_depth ();
8928 if (!NILP (no_preempt))
8930 record_unwind_protect (restore_disable_preemption_value,
8931 make_int (disable_preemption));
8932 disable_preemption++;
8935 DEVICE_FRAME_LOOP (frmcons, d)
8937 XFRAME (XCAR (frmcons))->clear = 1;
8939 redisplay_device (d, 0);
8941 /* See the comment in Fredisplay_frame. */
8942 RESET_CHANGED_SET_FLAGS;
8944 return unbind_to (count, Qnil);
8947 DEFUN ("redisplay-device", Fredisplay_device, 0, 2, 0, /*
8948 Ensure that DEVICE's contents are correctly displayed.
8949 This differs from `redraw-device' in that it only redraws what needs to
8950 be updated, as opposed to unconditionally clearing and redrawing
8952 DEVICE defaults to the selected device if omitted.
8953 Normally, redisplay is preempted as normal if input arrives. However,
8954 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8955 input and is guaranteed to proceed to completion.
8957 (device, no_preempt))
8959 struct device *d = decode_device (device);
8960 int count = specpdl_depth ();
8962 if (!NILP (no_preempt))
8964 record_unwind_protect (restore_disable_preemption_value,
8965 make_int (disable_preemption));
8966 disable_preemption++;
8969 redisplay_device (d, 0);
8971 /* See the comment in Fredisplay_frame. */
8972 RESET_CHANGED_SET_FLAGS;
8974 return unbind_to (count, Qnil);
8977 /* Big lie. Big lie. This will force all modelines to be updated
8978 regardless if the all flag is set or not. It remains in existence
8979 solely for backwards compatibility. */
8980 DEFUN ("redraw-modeline", Fredraw_modeline, 0, 1, 0, /*
8981 Force the modeline of the current buffer to be redisplayed.
8982 With optional non-nil ALL, force redisplay of all modelines.
8986 MARK_MODELINE_CHANGED;
8990 DEFUN ("force-cursor-redisplay", Fforce_cursor_redisplay, 0, 1, 0, /*
8991 Force an immediate update of the cursor on FRAME.
8992 FRAME defaults to the selected frame if omitted.
8996 redisplay_redraw_cursor (decode_frame (frame), 1);
9001 /***************************************************************************/
9003 /* Lisp-variable change triggers */
9005 /***************************************************************************/
9008 margin_width_changed_in_frame (Lisp_Object specifier, struct frame *f,
9011 /* Nothing to be done? */
9015 redisplay_variable_changed (Lisp_Object sym, Lisp_Object *val,
9016 Lisp_Object in_object, int flags)
9018 /* #### clip_changed should really be renamed something like
9019 global_redisplay_change. */
9024 /* This is called if the built-in glyphs have their properties
9027 redisplay_glyph_changed (Lisp_Object glyph, Lisp_Object property,
9030 if (WINDOWP (locale))
9032 MARK_FRAME_GLYPHS_CHANGED (XFRAME (WINDOW_FRAME (XWINDOW (locale))));
9034 else if (FRAMEP (locale))
9036 MARK_FRAME_GLYPHS_CHANGED (XFRAME (locale));
9038 else if (DEVICEP (locale))
9040 Lisp_Object frmcons;
9041 DEVICE_FRAME_LOOP (frmcons, XDEVICE (locale))
9042 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9044 else if (CONSOLEP (locale))
9046 Lisp_Object frmcons, devcons;
9047 CONSOLE_FRAME_LOOP_NO_BREAK (frmcons, devcons, XCONSOLE (locale))
9048 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9050 else /* global or buffer */
9052 Lisp_Object frmcons, devcons, concons;
9053 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
9054 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9059 text_cursor_visible_p_changed (Lisp_Object specifier, struct window *w,
9062 if (XFRAME (w->frame)->init_finished)
9063 Fforce_cursor_redisplay (w->frame);
9066 #ifdef MEMORY_USAGE_STATS
9069 /***************************************************************************/
9071 /* memory usage computation */
9073 /***************************************************************************/
9076 compute_rune_dynarr_usage (rune_dynarr *dyn, struct overhead_stats *ovstats)
9078 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9082 compute_display_block_dynarr_usage (display_block_dynarr *dyn,
9083 struct overhead_stats *ovstats)
9090 total = Dynarr_memory_usage (dyn, ovstats);
9091 for (i = 0; i < Dynarr_largest (dyn); i++)
9092 total += compute_rune_dynarr_usage (Dynarr_at (dyn, i).runes, ovstats);
9098 compute_glyph_block_dynarr_usage (glyph_block_dynarr *dyn,
9099 struct overhead_stats *ovstats)
9101 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9105 compute_display_line_dynarr_usage (display_line_dynarr *dyn,
9106 struct overhead_stats *ovstats)
9113 total = Dynarr_memory_usage (dyn, ovstats);
9114 for (i = 0; i < Dynarr_largest (dyn); i++)
9116 struct display_line *dl = &Dynarr_at (dyn, i);
9117 total += compute_display_block_dynarr_usage(dl->display_blocks, ovstats);
9118 total += compute_glyph_block_dynarr_usage (dl->left_glyphs, ovstats);
9119 total += compute_glyph_block_dynarr_usage (dl->right_glyphs, ovstats);
9126 compute_line_start_cache_dynarr_usage (line_start_cache_dynarr *dyn,
9127 struct overhead_stats *ovstats)
9129 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9132 #endif /* MEMORY_USAGE_STATS */
9135 /***************************************************************************/
9137 /* initialization */
9139 /***************************************************************************/
9142 init_redisplay (void)
9144 disable_preemption = 0;
9145 preemption_count = 0;
9146 max_preempts = INIT_MAX_PREEMPTS;
9152 if (!cmotion_display_lines)
9153 cmotion_display_lines = Dynarr_new (display_line);
9154 if (!mode_spec_bufbyte_string)
9155 mode_spec_bufbyte_string = Dynarr_new (Bufbyte);
9156 if (!formatted_string_extent_dynarr)
9157 formatted_string_extent_dynarr = Dynarr_new (EXTENT);
9158 if (!formatted_string_extent_start_dynarr)
9159 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount);
9160 if (!formatted_string_extent_end_dynarr)
9161 formatted_string_extent_end_dynarr = Dynarr_new (Bytecount);
9162 if (!internal_cache)
9163 internal_cache = Dynarr_new (line_start_cache);
9166 /* window system is nil when in -batch mode */
9167 if (!initialized || noninteractive)
9170 /* If the user wants to use a window system, we shouldn't bother
9171 initializing the terminal. This is especially important when the
9172 terminal is so dumb that emacs gives up before and doesn't bother
9173 using the window system.
9175 If the DISPLAY environment variable is set, try to use X, and die
9176 with an error message if that doesn't work. */
9178 #ifdef HAVE_X_WINDOWS
9179 if (!strcmp (display_use, "x"))
9181 /* Some stuff checks this way early. */
9182 Vwindow_system = Qx;
9183 Vinitial_window_system = Qx;
9186 #endif /* HAVE_X_WINDOWS */
9188 #ifdef HAVE_MS_WINDOWS
9189 if (!strcmp (display_use, "mswindows"))
9191 /* Some stuff checks this way early. */
9192 Vwindow_system = Qmswindows;
9193 Vinitial_window_system = Qmswindows;
9196 #endif /* HAVE_MS_WINDOWS */
9199 /* If no window system has been specified, try to use the terminal. */
9202 stderr_out ("XEmacs: standard input is not a tty\n");
9206 /* Look at the TERM variable */
9207 if (!getenv ("TERM"))
9209 stderr_out ("Please set the environment variable TERM; see tset(1).\n");
9213 Vinitial_window_system = Qtty;
9215 #else /* not HAVE_TTY */
9216 /* No DISPLAY specified, and no TTY support. */
9217 stderr_out ("XEmacs: Cannot open display.\n\
9218 Please set the environmental variable DISPLAY to an appropriate value.\n");
9225 syms_of_redisplay (void)
9227 defsymbol (&Qcursor_in_echo_area, "cursor-in-echo-area");
9228 #ifndef INHIBIT_REDISPLAY_HOOKS
9229 defsymbol (&Qpre_redisplay_hook, "pre-redisplay-hook");
9230 defsymbol (&Qpost_redisplay_hook, "post-redisplay-hook");
9231 #endif /* INHIBIT_REDISPLAY_HOOKS */
9232 defsymbol (&Qdisplay_warning_buffer, "display-warning-buffer");
9233 defsymbol (&Qbar_cursor, "bar-cursor");
9234 defsymbol (&Qredisplay_end_trigger_functions,
9235 "redisplay-end-trigger-functions");
9236 defsymbol (&Qtop_bottom, "top-bottom");
9237 defsymbol (&Qbuffer_list_changed_hook, "buffer-list-changed-hook");
9239 DEFSUBR (Fredisplay_echo_area);
9240 DEFSUBR (Fredraw_frame);
9241 DEFSUBR (Fredisplay_frame);
9242 DEFSUBR (Fredraw_device);
9243 DEFSUBR (Fredisplay_device);
9244 DEFSUBR (Fredraw_modeline);
9245 DEFSUBR (Fforce_cursor_redisplay);
9249 vars_of_redisplay (void)
9253 staticpro (&last_arrow_position);
9254 staticpro (&last_arrow_string);
9255 last_arrow_position = Qnil;
9256 last_arrow_string = Qnil;
9259 /* #### Probably temporary */
9260 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /*
9261 \(Temporary) Setting this will impact the performance of the internal
9264 cache_adjustment = 2;
9266 DEFVAR_INT_MAGIC ("pixel-vertical-clip-threshold", &vertical_clip /*
9267 Minimum pixel height for clipped bottom display line.
9268 A clipped line shorter than this won't be displayed.
9270 redisplay_variable_changed);
9273 DEFVAR_INT_MAGIC ("pixel-horizontal-clip-threshold", &horizontal_clip /*
9274 Minimum visible area for clipped glyphs at right boundary.
9275 Clipped glyphs shorter than this won't be displayed.
9276 Only pixmap glyph instances are currently allowed to be clipped.
9278 redisplay_variable_changed);
9279 horizontal_clip = 5;
9281 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string /*
9282 String displayed by modeline-format's "%m" specification.
9284 Vglobal_mode_string = Qnil;
9286 DEFVAR_LISP_MAGIC ("overlay-arrow-position", &Voverlay_arrow_position /*
9287 Marker for where to display an arrow on top of the buffer text.
9288 This must be the beginning of a line in order to work.
9289 See also `overlay-arrow-string'.
9291 redisplay_variable_changed);
9292 Voverlay_arrow_position = Qnil;
9294 DEFVAR_LISP_MAGIC ("overlay-arrow-string", &Voverlay_arrow_string /*
9295 String or glyph to display as an arrow. See also `overlay-arrow-position'.
9296 \(Note that despite the name of this variable, it can be set to a glyph as
9299 redisplay_variable_changed);
9300 Voverlay_arrow_string = Qnil;
9302 DEFVAR_INT ("scroll-step", &scroll_step /*
9303 *The number of lines to try scrolling a window by when point moves out.
9304 If that fails to bring point back on frame, point is centered instead.
9305 If this is zero, point is always centered after it moves off screen.
9309 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively /*
9310 *Scroll up to this many lines, to bring point back on screen.
9312 scroll_conservatively = 0;
9314 DEFVAR_BOOL_MAGIC ("truncate-partial-width-windows",
9315 &truncate_partial_width_windows /*
9316 *Non-nil means truncate lines in all windows less than full frame wide.
9318 redisplay_variable_changed);
9319 truncate_partial_width_windows = 1;
9321 DEFVAR_LISP ("visible-bell", &Vvisible_bell /*
9322 *Non-nil substitutes a visual signal for the audible bell.
9324 Default behavior is to flash the whole screen. On some platforms,
9325 special effects are available using the following values:
9327 'display Flash the whole screen (ie, the default behavior).
9328 'top-bottom Flash only the top and bottom lines of the selected frame.
9330 When effects are unavailable on a platform, the visual bell is the
9331 default, whole screen. (Currently only X supports any special effects.)
9333 Vvisible_bell = Qnil;
9335 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter /*
9336 *Non-nil means no need to redraw entire frame after suspending.
9337 A non-nil value is useful if the terminal can automatically preserve
9338 Emacs's frame display when you reenter Emacs.
9339 It is up to you to set this variable if your terminal can do that.
9341 no_redraw_on_reenter = 0;
9343 DEFVAR_LISP ("window-system", &Vwindow_system /*
9344 A symbol naming the window-system under which Emacs is running,
9345 such as `x', or nil if emacs is running on an ordinary terminal.
9347 Do not use this variable, except for GNU Emacs compatibility, as it
9348 gives wrong values in a multi-device environment. Use `console-type'
9351 Vwindow_system = Qnil;
9353 /* #### Temporary shit until window-system is eliminated. */
9354 DEFVAR_CONST_LISP ("initial-window-system", &Vinitial_window_system /*
9357 Vinitial_window_system = Qnil;
9359 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area /*
9360 Non-nil means put cursor in minibuffer, at end of any message there.
9362 cursor_in_echo_area = 0;
9364 /* #### Shouldn't this be generalized as follows:
9366 if nil, use block cursor.
9367 if a number, use a bar cursor of that width.
9368 Otherwise, use a 1-pixel bar cursor.
9370 #### Or better yet, this variable should be trashed entirely
9371 (use a Lisp-magic variable to maintain compatibility)
9372 and a specifier `cursor-shape' added, which allows a block
9373 cursor, a bar cursor, a flashing block or bar cursor,
9374 maybe a caret cursor, etc. */
9376 DEFVAR_LISP ("bar-cursor", &Vbar_cursor /*
9377 *Use vertical bar cursor if non-nil. If t width is 1 pixel, otherwise 2.
9381 #ifndef INHIBIT_REDISPLAY_HOOKS
9382 xxDEFVAR_LISP ("pre-redisplay-hook", &Vpre_redisplay_hook /*
9383 Function or functions to run before every redisplay.
9385 Vpre_redisplay_hook = Qnil;
9387 xxDEFVAR_LISP ("post-redisplay-hook", &Vpost_redisplay_hook /*
9388 Function or functions to run after every redisplay.
9390 Vpost_redisplay_hook = Qnil;
9391 #endif /* INHIBIT_REDISPLAY_HOOKS */
9393 DEFVAR_LISP ("buffer-list-changed-hook", &Vbuffer_list_changed_hook /*
9394 Function or functions to call when a frame's buffer list has changed.
9395 This is called during redisplay, before redisplaying each frame.
9396 Functions on this hook are called with one argument, the frame.
9398 Vbuffer_list_changed_hook = Qnil;
9400 DEFVAR_INT ("display-warning-tick", &display_warning_tick /*
9401 Bump this to tell the C code to call `display-warning-buffer'
9402 at next redisplay. You should not normally change this; the function
9403 `display-warning' automatically does this at appropriate times.
9405 display_warning_tick = 0;
9407 DEFVAR_BOOL ("inhibit-warning-display", &inhibit_warning_display /*
9408 Non-nil means inhibit display of warning messages.
9409 You should *bind* this, not set it. Any pending warning messages
9410 will be displayed when the binding no longer applies.
9412 /* reset to 0 by startup.el after the splash screen has displayed.
9413 This way, the warnings don't obliterate the splash screen. */
9414 inhibit_warning_display = 1;
9416 DEFVAR_LISP ("window-size-change-functions",
9417 &Vwindow_size_change_functions /*
9418 Not currently implemented.
9419 Functions called before redisplay, if window sizes have changed.
9420 The value should be a list of functions that take one argument.
9421 Just before redisplay, for each frame, if any of its windows have changed
9422 size since the last redisplay, or have been split or deleted,
9423 all the functions in the list are called, with the frame as argument.
9425 Vwindow_size_change_functions = Qnil;
9427 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions /*
9428 Not currently implemented.
9429 Functions to call before redisplaying a window with scrolling.
9430 Each function is called with two arguments, the window
9431 and its new display-start position. Note that the value of `window-end'
9432 is not valid when these functions are called.
9434 Vwindow_scroll_functions = Qnil;
9436 DEFVAR_LISP ("redisplay-end-trigger-functions",
9437 &Vredisplay_end_trigger_functions /*
9438 See `set-window-redisplay-end-trigger'.
9440 Vredisplay_end_trigger_functions = Qnil;
9442 DEFVAR_BOOL ("column-number-start-at-one", &column_number_start_at_one /*
9443 *Non-nil means column display number starts at 1.
9445 column_number_start_at_one = 0;
9449 specifier_vars_of_redisplay (void)
9451 DEFVAR_SPECIFIER ("left-margin-width", &Vleft_margin_width /*
9452 *Width of left margin.
9453 This is a specifier; use `set-specifier' to change it.
9455 Vleft_margin_width = Fmake_specifier (Qnatnum);
9456 set_specifier_fallback (Vleft_margin_width, list1 (Fcons (Qnil, Qzero)));
9457 set_specifier_caching (Vleft_margin_width,
9458 offsetof (struct window, left_margin_width),
9459 some_window_value_changed,
9460 offsetof (struct frame, left_margin_width),
9461 margin_width_changed_in_frame, 0);
9463 DEFVAR_SPECIFIER ("right-margin-width", &Vright_margin_width /*
9464 *Width of right margin.
9465 This is a specifier; use `set-specifier' to change it.
9467 Vright_margin_width = Fmake_specifier (Qnatnum);
9468 set_specifier_fallback (Vright_margin_width, list1 (Fcons (Qnil, Qzero)));
9469 set_specifier_caching (Vright_margin_width,
9470 offsetof (struct window, right_margin_width),
9471 some_window_value_changed,
9472 offsetof (struct frame, right_margin_width),
9473 margin_width_changed_in_frame, 0);
9475 DEFVAR_SPECIFIER ("minimum-line-ascent", &Vminimum_line_ascent /*
9476 *Minimum ascent height of lines.
9477 This is a specifier; use `set-specifier' to change it.
9479 Vminimum_line_ascent = Fmake_specifier (Qnatnum);
9480 set_specifier_fallback (Vminimum_line_ascent, list1 (Fcons (Qnil, Qzero)));
9481 set_specifier_caching (Vminimum_line_ascent,
9482 offsetof (struct window, minimum_line_ascent),
9483 some_window_value_changed,
9486 DEFVAR_SPECIFIER ("minimum-line-descent", &Vminimum_line_descent /*
9487 *Minimum descent height of lines.
9488 This is a specifier; use `set-specifier' to change it.
9490 Vminimum_line_descent = Fmake_specifier (Qnatnum);
9491 set_specifier_fallback (Vminimum_line_descent, list1 (Fcons (Qnil, Qzero)));
9492 set_specifier_caching (Vminimum_line_descent,
9493 offsetof (struct window, minimum_line_descent),
9494 some_window_value_changed,
9497 DEFVAR_SPECIFIER ("use-left-overflow", &Vuse_left_overflow /*
9498 *Non-nil means use the left outside margin as extra whitespace when
9499 displaying 'whitespace or 'inside-margin glyphs.
9500 This is a specifier; use `set-specifier' to change it.
9502 Vuse_left_overflow = Fmake_specifier (Qboolean);
9503 set_specifier_fallback (Vuse_left_overflow, list1 (Fcons (Qnil, Qnil)));
9504 set_specifier_caching (Vuse_left_overflow,
9505 offsetof (struct window, use_left_overflow),
9506 some_window_value_changed,
9509 DEFVAR_SPECIFIER ("use-right-overflow", &Vuse_right_overflow /*
9510 *Non-nil means use the right outside margin as extra whitespace when
9511 displaying 'whitespace or 'inside-margin glyphs.
9512 This is a specifier; use `set-specifier' to change it.
9514 Vuse_right_overflow = Fmake_specifier (Qboolean);
9515 set_specifier_fallback (Vuse_right_overflow, list1 (Fcons (Qnil, Qnil)));
9516 set_specifier_caching (Vuse_right_overflow,
9517 offsetof (struct window, use_right_overflow),
9518 some_window_value_changed,
9521 DEFVAR_SPECIFIER ("text-cursor-visible-p", &Vtext_cursor_visible_p /*
9522 *Non-nil means the text cursor is visible (this is usually the case).
9523 This is a specifier; use `set-specifier' to change it.
9525 Vtext_cursor_visible_p = Fmake_specifier (Qboolean);
9526 set_specifier_fallback (Vtext_cursor_visible_p, list1 (Fcons (Qnil, Qt)));
9527 set_specifier_caching (Vtext_cursor_visible_p,
9528 offsetof (struct window, text_cursor_visible_p),
9529 text_cursor_visible_p_changed,