1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1994, 1995, 1996 Board of Trustees, University of Illinois.
3 Copyright (C) 1995 Free Software Foundation, Inc.
4 Copyright (C) 1995, 1996 Ben Wing.
5 Copyright (C) 1995 Sun Microsystems, Inc.
6 Copyright (C) 1996 Chuck Thompson.
8 This file is part of XEmacs.
10 XEmacs is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
15 XEmacs is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with XEmacs; see the file COPYING. If not, write to
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
25 /* Synched up with: Not in FSF. */
27 /* Author: Chuck Thompson */
29 /* Fixed up by Ben Wing for Mule */
31 /* This file has been Mule-ized. */
33 /*****************************************************************************
34 The Golden Rules of Redisplay
36 First: It Is Better To Be Correct Than Fast
37 Second: Thou Shalt Not Run Elisp From Within Redisplay
38 Third: It Is Better To Be Fast Than Not To Be
39 ****************************************************************************/
59 #include "redisplay.h"
62 #include "line-number.h"
64 #include "file-coding.h"
68 #include "console-tty.h"
70 #include <unistd.h> /* for isatty() */
74 /* Note: We have to be careful throughout this code to properly handle
75 and differentiate between Bufbytes and Emchars.
77 Since strings are generally composed of Bufbytes, I've taken the tack
78 that any contiguous set of Bufbytes is called a "string", while
79 any contiguous set of Emchars is called an "array". */
81 /* Return value to indicate a failure by an add_*_rune routine to add
82 a rune, but no propagation information needs to be returned. */
83 #define ADD_FAILED (prop_block_dynarr *) 1
85 #define BEGIN_GLYPHS 0
88 #define RIGHT_GLYPHS 3
90 /* Set the vertical clip to 0 if we are currently updating the line
91 start cache. Otherwise for buffers of line height 1 it may fail to
92 be able to work properly because regenerate_window will not layout
94 #define VERTICAL_CLIP(w, display) \
95 (updating_line_start_cache \
97 : ((WINDOW_TTY_P (w) | (!display && scroll_on_clipped_lines)) \
101 /* The following structures are completely private to redisplay.c so
102 we put them here instead of in a header file, for modularity. */
104 /* NOTE: Bytinds not Bufpos's in this structure. */
106 typedef struct position_redisplay_data_type
108 /* This information is normally filled in by the create_*_block
109 routines and is used by the add_*_rune routines. */
111 /* if we are working with strings rather than buffers we need a
112 handle to the string */
115 struct display_block *db;
116 struct display_line *dl;
117 Emchar ch; /* Character that is to be added. This is
118 used to communicate this information to
119 add_emchar_rune(). */
120 Lisp_Object last_charset; /* The charset of the previous character.
121 Used to optimize some lookups -- we
122 only have to do some things when
123 the charset changes. */
124 face_index last_findex; /* The face index of the previous character.
125 Needed to ensure the validity of the
126 last_charset optimization. */
128 int last_char_width; /* The width of the previous character. */
129 int font_is_bogus; /* If true, it means we couldn't instantiate
130 the font for this charset, so we substitute
131 ~'s from the ASCII charset. */
136 int blank_width; /* Width of the blank that is to be added.
137 This is used to communicate this information
140 This is also used rather cheesily to
141 communicate the width of the eol-cursor-size
142 blank that exists at the end of the line.
143 add_emchar_rune() is called cheesily with
144 the non-printing char '\n', which is stuck
145 in the output routines with its width being
147 Bytind bi_cursor_bufpos;/* This stores the buffer position of the cursor. */
148 unsigned int cursor_type :3;
149 int cursor_x; /* rune block cursor is at */
150 int start_col; /* Number of character columns (each column has
151 a width of the default char width) that still
152 need to be skipped. This is used for horizontal
153 scrolling, where a certain number of columns
154 (those off the left side of the screen) need
155 to be skipped before anything is displayed. */
156 Bytind bi_start_col_enabled;
157 int start_col_xoffset; /* Number of pixels that still need to
158 be skipped. This is used for
159 horizontal scrolling of glyphs, where we want
160 to be able to scroll over part of the glyph. */
162 int hscroll_glyph_width_adjust; /* how much the width of the hscroll
163 glyph differs from space_width (w).
164 0 if no hscroll glyph was used,
165 i.e. the window is not scrolled
166 horizontally. Used in tab
169 /* Information about the face the text should be displayed in and
170 any begin-glyphs and end-glyphs. */
171 struct extent_fragment *ef;
174 /* The height of a pixmap may either be predetermined if the user
175 has set a baseline value, or it may be dependent on whatever the
176 line ascent and descent values end up being, based just on font
177 information. In the first case we can immediately update the
178 values, thus their inclusion here. In the last case we cannot
179 determine the actual contribution to the line height until we
180 have finished laying out all text on the line. Thus we propagate
181 the max height of such pixmaps and do a final calculation after
182 all text has been added to the line. */
185 int max_pixmap_height;
187 Lisp_Object result_str; /* String where we put the result of
188 generating a formatted string in the modeline. */
189 int is_modeline; /* Non-zero if we're generating the modeline. */
190 Charcount modeline_charpos; /* Number of chars used in result_str so far;
191 corresponds to bytepos. */
192 Bytecount bytepos; /* Number of bytes used in result_str so far.
193 We don't actually copy the bytes into result_str
194 until the end because we don't know how big the
195 string is going to be until then. */
206 /* Data that should be propagated to the next line. Either a single
207 Emchar or a string of Bufbyte's.
209 The actual data that is propagated ends up as a Dynarr of these
212 #### It's unclean that both Emchars and Bufbytes are here.
215 typedef struct prop_block prop_block;
225 Bytecount len; /* length of the string. */
231 Bytind bi_cursor_bufpos; /* NOTE: is in Bytinds */
232 unsigned int cursor_type :3;
245 Dynarr_declare (prop_block);
249 static Charcount generate_fstring_runes (struct window *w, pos_data *data,
250 Charcount pos, Charcount min_pos,
251 Charcount max_pos, Lisp_Object elt,
252 int depth, int max_pixsize,
253 face_index findex, int type,
255 Lisp_Object cur_ext);
256 static prop_block_dynarr *add_glyph_rune (pos_data *data,
257 struct glyph_block *gb,
258 int pos_type, int allow_cursor,
259 struct glyph_cachel *cachel);
260 static Bytind create_text_block (struct window *w, struct display_line *dl,
261 Bytind bi_start_pos, prop_block_dynarr **prop,
263 static int create_overlay_glyph_block (struct window *w,
264 struct display_line *dl);
265 static void create_left_glyph_block (struct window *w,
266 struct display_line *dl,
268 static void create_right_glyph_block (struct window *w,
269 struct display_line *dl);
270 static void redisplay_windows (Lisp_Object window, int skip_selected);
271 static void decode_mode_spec (struct window *w, Emchar spec, int type);
272 static void free_display_line (struct display_line *dl);
273 static void update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
274 Bufpos point, int no_regen);
275 static int point_visible (struct window *w, Bufpos point, int type);
277 /* This used to be 10 but 30 seems to give much better performance. */
278 #define INIT_MAX_PREEMPTS 30
279 static int max_preempts;
281 #define REDISPLAY_PREEMPTION_CHECK \
284 (!disable_preemption && \
285 ((preemption_count < max_preempts) || !NILP (Vexecuting_macro)) && \
286 (!INTERACTIVE || detect_input_pending ()))))
289 * Redisplay global variables.
292 /* We need a third set of display structures for the cursor motion
293 routines. We used to just give each window a third set. However,
294 we always fully regenerate the structures when needed so there
295 isn't any reason we need more than a single set. */
296 display_line_dynarr *cmotion_display_lines;
298 /* We store the extents that we need to generate in a Dynarr and then
299 frob them all on at the end of generating the string. We do it
300 this way rather than adding them as we generate the string because
301 we don't store the text into the resulting string until we're done
302 (to avoid having to resize the string multiple times), and we don't
303 want to go around adding extents to a string when the extents might
304 stretch off the end of the string. */
305 static EXTENT_dynarr *formatted_string_extent_dynarr;
306 static Bytecount_dynarr *formatted_string_extent_start_dynarr;
307 static Bytecount_dynarr *formatted_string_extent_end_dynarr;
310 /* #### probably temporary */
311 int cache_adjustment;
313 /* This holds a string representing the text corresponding to a single
315 static Bufbyte_dynarr *mode_spec_bufbyte_string;
317 int in_display; /* 1 if in redisplay. */
319 int disable_preemption; /* Used for debugging redisplay and for
322 /* We only allow max_preempts preemptions before we force a redisplay. */
323 static int preemption_count;
325 /* Minimum pixel height of clipped bottom display line. */
328 /* Minimum visible pixel width of clipped glyphs at right margin. */
331 /* Set if currently inside update_line_start_cache. */
332 static int updating_line_start_cache;
334 /* Nonzero means reading single-character input with prompt
335 so put cursor on minibuffer after the prompt. */
336 int cursor_in_echo_area;
337 Lisp_Object Qcursor_in_echo_area;
339 /* Nonzero means truncate lines in all windows less wide than the frame */
340 int truncate_partial_width_windows;
342 /* non-nil if a buffer has changed since the last time redisplay completed */
344 int buffers_changed_set;
346 /* non-nil if hscroll has changed somewhere or a buffer has been
347 narrowed or widened */
349 int clip_changed_set;
351 /* non-nil if any extent has changed since the last time redisplay completed */
353 int extents_changed_set;
355 /* non-nil if any face has changed since the last time redisplay completed */
358 /* Nonzero means some frames have been marked as garbaged */
361 /* non-zero if any of the builtin display glyphs (continuation,
362 hscroll, control-arrow, etc) is in need of updating
365 int glyphs_changed_set;
367 /* non-zero if any displayed subwindow is in need of updating
369 int subwindows_changed;
370 int subwindows_changed_set;
372 /* non-zero if any displayed subwindow is in need of updating
374 int subwindows_state_changed;
375 int subwindows_state_changed_set;
377 /* This variable is 1 if the icon has to be updated.
378 It is set to 1 when `frame-icon-glyph' changes. */
380 int icon_changed_set;
382 /* This variable is 1 if the menubar widget has to be updated.
383 It is set to 1 by set-menubar-dirty-flag and cleared when the widget
386 int menubar_changed_set;
388 /* true iff we should redraw the modelines on the next redisplay */
389 int modeline_changed;
390 int modeline_changed_set;
392 /* non-nil if point has changed in some buffer since the last time
393 redisplay completed */
395 int point_changed_set;
397 /* non-nil if some frame has changed its size */
400 /* non-nil if some device has signaled that it wants to change size */
401 int asynch_device_change_pending;
403 /* non-nil if any toolbar has changed */
405 int toolbar_changed_set;
407 /* non-nil if any gutter has changed */
409 int gutter_changed_set;
411 /* non-nil if any window has changed since the last time redisplay completed */
414 /* non-nil if any frame's window structure has changed since the last
415 time redisplay completed */
416 int windows_structure_changed;
418 /* If non-nil, use vertical bar cursor. */
419 Lisp_Object Vbar_cursor;
420 Lisp_Object Qbar_cursor;
422 int visible_bell; /* If true and the terminal will support it
423 then the frame will flash instead of
424 beeping when an error occurs */
426 /* Nonzero means no need to redraw the entire frame on resuming
427 a suspended Emacs. This is useful on terminals with multiple pages,
428 where one page is used for Emacs and another for all else. */
429 int no_redraw_on_reenter;
431 Lisp_Object Vwindow_system; /* nil or a symbol naming the window system
432 under which emacs is running
433 ('x is the only current possibility) */
434 Lisp_Object Vinitial_window_system;
436 Lisp_Object Vglobal_mode_string;
438 /* The number of lines scroll a window by when point leaves the window; if
439 it is <=0 then point is centered in the window */
442 /* Scroll up to this many lines, to bring point back on screen. */
443 int scroll_conservatively;
445 /* Marker for where to display an arrow on top of the buffer text. */
446 Lisp_Object Voverlay_arrow_position;
447 /* String to display for the arrow. */
448 Lisp_Object Voverlay_arrow_string;
450 Lisp_Object Vwindow_size_change_functions;
451 Lisp_Object Vwindow_scroll_functions;
452 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
454 #define INHIBIT_REDISPLAY_HOOKS /* #### Until we've thought about
456 #ifndef INHIBIT_REDISPLAY_HOOKS
457 /* #### Chuck says: I think this needs more thought.
458 Think about this for 19.14. */
459 Lisp_Object Vpre_redisplay_hook, Vpost_redisplay_hook;
460 Lisp_Object Qpre_redisplay_hook, Qpost_redisplay_hook;
461 #endif /* INHIBIT_REDISPLAY_HOOKS */
463 static int last_display_warning_tick, display_warning_tick;
464 Lisp_Object Qdisplay_warning_buffer;
465 int inhibit_warning_display;
467 Lisp_Object Vleft_margin_width, Vright_margin_width;
468 Lisp_Object Vminimum_line_ascent, Vminimum_line_descent;
469 Lisp_Object Vuse_left_overflow, Vuse_right_overflow;
470 Lisp_Object Vtext_cursor_visible_p;
472 int column_number_start_at_one;
474 #define WINDOW_SCROLLED(w) \
475 (w->hscroll > 0 || w->left_xoffset)
478 /***************************************************************************/
480 /* low-level interfaces onto device routines */
482 /***************************************************************************/
485 redisplay_text_width_emchar_string (struct window *w, int findex,
486 Emchar *str, Charcount len)
488 unsigned char charsets[NUM_LEADING_BYTES];
491 find_charsets_in_emchar_string (charsets, str, len);
492 XSETWINDOW (window, w);
493 ensure_face_cachel_complete (WINDOW_FACE_CACHEL (w, findex), window,
495 return DEVMETH (XDEVICE (FRAME_DEVICE (XFRAME (WINDOW_FRAME (w)))),
496 text_width, (XFRAME (WINDOW_FRAME (w)),
497 WINDOW_FACE_CACHEL (w, findex), str, len));
500 static Emchar_dynarr *rtw_emchar_dynarr;
503 redisplay_text_width_string (struct window *w, int findex,
504 Bufbyte *nonreloc, Lisp_Object reloc,
505 Bytecount offset, Bytecount len)
507 if (!rtw_emchar_dynarr)
508 rtw_emchar_dynarr = Dynarr_new (Emchar);
509 Dynarr_reset (rtw_emchar_dynarr);
511 fixup_internal_substring (nonreloc, reloc, offset, &len);
513 nonreloc = XSTRING_DATA (reloc);
514 convert_bufbyte_string_into_emchar_dynarr (nonreloc, len, rtw_emchar_dynarr);
515 return redisplay_text_width_emchar_string
516 (w, findex, Dynarr_atp (rtw_emchar_dynarr, 0),
517 Dynarr_length (rtw_emchar_dynarr));
521 redisplay_frame_text_width_string (struct frame *f, Lisp_Object face,
522 Bufbyte *nonreloc, Lisp_Object reloc,
523 Bytecount offset, Bytecount len)
525 unsigned char charsets[NUM_LEADING_BYTES];
527 struct face_cachel cachel;
529 if (!rtw_emchar_dynarr)
530 rtw_emchar_dynarr = Dynarr_new (Emchar);
531 Dynarr_reset (rtw_emchar_dynarr);
533 fixup_internal_substring (nonreloc, reloc, offset, &len);
535 nonreloc = XSTRING_DATA (reloc);
536 convert_bufbyte_string_into_emchar_dynarr (nonreloc, len, rtw_emchar_dynarr);
537 find_charsets_in_bufbyte_string (charsets, nonreloc, len);
538 reset_face_cachel (&cachel);
540 XSETFRAME (frame, f);
541 ensure_face_cachel_complete (&cachel, frame, charsets);
542 return DEVMETH (XDEVICE (FRAME_DEVICE (f)),
543 text_width, (f, &cachel, Dynarr_atp (rtw_emchar_dynarr, 0),
544 Dynarr_length (rtw_emchar_dynarr)));
547 /* Return the display block from DL of the given TYPE. A display line
548 can have only one display block of each possible type. If DL does
549 not have a block of type TYPE, one will be created and added to DL. */
551 struct display_block *
552 get_display_block_from_line (struct display_line *dl, enum display_type type)
555 struct display_block db;
557 /* Check if this display line already has a block of the desired type and
559 if (dl->display_blocks)
561 for (elt = 0; elt < Dynarr_length (dl->display_blocks); elt++)
563 if (Dynarr_at (dl->display_blocks, elt).type == type)
564 return Dynarr_atp (dl->display_blocks, elt);
567 /* There isn't an active block of the desired type, but there
568 might still be allocated blocks we need to reuse. */
569 if (elt < Dynarr_largest (dl->display_blocks))
571 struct display_block *dbp = Dynarr_atp (dl->display_blocks, elt);
573 /* 'add' the block to the list */
574 Dynarr_increment (dl->display_blocks);
576 /* initialize and return */
583 /* This line doesn't have any display blocks, so initialize the display
585 dl->display_blocks = Dynarr_new (display_block);
588 /* The line doesn't have a block of the desired type so go ahead and create
589 one and add it to the line. */
592 db.runes = Dynarr_new (rune);
593 Dynarr_add (dl->display_blocks, db);
595 /* Return the newly added display block. */
596 elt = Dynarr_length (dl->display_blocks) - 1;
598 return Dynarr_atp (dl->display_blocks, elt);
602 tab_char_width (struct window *w)
604 struct buffer *b = XBUFFER (w->buffer);
605 int char_tab_width = XINT (b->tab_width);
607 if (char_tab_width <= 0 || char_tab_width > 1000) char_tab_width = 8;
609 return char_tab_width;
613 space_width (struct window *w)
615 /* While tabs are traditional composed of spaces, for variable-width
616 fonts the space character tends to give too narrow a value. So
617 we use 'n' instead. Except that we don't. We use the default
618 character width for the default face. If this is actually
619 defined by the font then it is probably the best thing to
620 actually use. If it isn't, we have assumed it is 'n' and have
621 already calculated its width. Thus we can avoid a call to
622 XTextWidth on X frames by just querying the default width. */
623 return XFONT_INSTANCE
624 (WINDOW_FACE_CACHEL_FONT (w, DEFAULT_INDEX, Vcharset_ascii))->width;
628 tab_pix_width (struct window *w)
630 return space_width (w) * tab_char_width (w);
633 /* Given a pixel position in a window, return the pixel location of
634 the next tabstop. Tabs are calculated from the left window edge in
635 terms of spaces displayed in the default face. Formerly the space
636 width was determined using the currently active face. That method
637 leads to tabstops which do not line up. */
640 next_tab_position (struct window *w, int start_pixpos, int left_pixpos)
642 int n_pos = left_pixpos;
643 int pix_tab_width = tab_pix_width (w);
645 /* Adjust n_pos for any hscrolling which has happened. */
646 if (WINDOW_SCROLLED (w))
647 n_pos -= space_width (w) * (w->hscroll - 1) + w->left_xoffset;
649 while (n_pos <= start_pixpos)
650 n_pos += pix_tab_width;
655 /* For the given window, calculate the outside and margin boundaries for a
656 display line. The whitespace boundaries must be calculated by the text
660 calculate_display_line_boundaries (struct window *w, int modeline)
662 layout_bounds bounds;
664 /* Set the outermost boundaries which are the boundaries of the
665 window itself minus the gutters (and minus the scrollbars if this
666 is for the modeline). */
669 bounds.left_out = WINDOW_TEXT_LEFT (w);
670 bounds.right_out = WINDOW_TEXT_RIGHT (w);
674 bounds.left_out = WINDOW_MODELINE_LEFT (w);
675 bounds.right_out = WINDOW_MODELINE_RIGHT (w);
678 /* The inner boundaries mark where the glyph margins are located. */
679 bounds.left_in = bounds.left_out + window_left_margin_width (w);
680 bounds.right_in = bounds.right_out - window_right_margin_width (w);
682 /* We cannot fully calculate the whitespace boundaries as they
683 depend on the contents of the line being displayed. */
684 bounds.left_white = bounds.left_in;
685 bounds.right_white = bounds.right_in;
690 /* Given a display line and a starting position, ensure that the
691 contents of the display line accurately represent the visual
692 representation of the buffer contents starting from the given
693 position when displayed in the given window. The display line ends
694 when the contents of the line reach the right boundary of the given
698 generate_display_line (struct window *w, struct display_line *dl, int bounds,
699 Bufpos start_pos, prop_block_dynarr **prop,
704 struct buffer *b = XBUFFER (WINDOW_BUFFER (w));
706 /* If our caller hasn't already set the boundaries, then do so now. */
708 dl->bounds = calculate_display_line_boundaries (w, 0);
710 /* Reset what this line is using. */
711 if (dl->display_blocks)
712 Dynarr_reset (dl->display_blocks);
715 Dynarr_free (dl->left_glyphs);
718 if (dl->right_glyphs)
720 Dynarr_free (dl->right_glyphs);
721 dl->right_glyphs = 0;
724 /* We aren't generating a modeline at the moment. */
727 /* Create a display block for the text region of the line. */
729 /* #### urk urk urk!!! Chuck fix this shit! */
730 Bytind hacked_up_bytind =
731 create_text_block (w, dl, bufpos_to_bytind (b, start_pos),
733 if (hacked_up_bytind > BI_BUF_ZV (b))
734 ret_bufpos = BUF_ZV (b) + 1;
736 ret_bufpos = bytind_to_bufpos (b, hacked_up_bytind);
738 dl->bufpos = start_pos;
739 if (dl->end_bufpos < dl->bufpos)
740 dl->end_bufpos = dl->bufpos;
742 if (MARKERP (Voverlay_arrow_position)
743 && EQ (w->buffer, Fmarker_buffer (Voverlay_arrow_position))
744 && start_pos == marker_position (Voverlay_arrow_position)
745 && (STRINGP (Voverlay_arrow_string)
746 || GLYPHP (Voverlay_arrow_string)))
748 overlay_width = create_overlay_glyph_block (w, dl);
753 /* If there are left glyphs associated with any character in the
754 text block, then create a display block to handle them. */
755 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
756 create_left_glyph_block (w, dl, overlay_width);
758 /* If there are right glyphs associated with any character in the
759 text block, then create a display block to handle them. */
760 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
761 create_right_glyph_block (w, dl);
763 /* In the future additional types of display blocks may be generated
766 w->last_redisplay_pos = ret_bufpos;
771 /* Adds an hscroll glyph to a display block. If this is called, then
772 the block had better be empty.
774 Yes, there are multiple places where this function is called but
775 that is the way it has to be. Each calling function has to deal
776 with bi_start_col_enabled a little differently depending on the
777 object being worked with. */
779 static prop_block_dynarr *
780 add_hscroll_rune (pos_data *data)
782 struct glyph_block gb;
783 prop_block_dynarr *retval;
784 Bytind bi_old_cursor_bufpos = data->bi_cursor_bufpos;
785 unsigned int old_cursor_type = data->cursor_type;
786 Bytind bi_old_bufpos = data->bi_bufpos;
788 if (data->cursor_type == CURSOR_ON
789 && data->bi_cursor_bufpos >= data->bi_start_col_enabled
790 && data->bi_cursor_bufpos <= data->bi_bufpos)
792 data->bi_cursor_bufpos = data->bi_start_col_enabled;
796 data->cursor_type = NO_CURSOR;
799 data->bi_endpos = data->bi_bufpos;
800 data->bi_bufpos = data->bi_start_col_enabled;
803 gb.glyph = Vhscroll_glyph;
805 int oldpixpos = data->pixpos;
806 retval = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
807 GLYPH_CACHEL (XWINDOW (data->window),
808 HSCROLL_GLYPH_INDEX));
809 data->hscroll_glyph_width_adjust =
810 data->pixpos - oldpixpos - space_width (XWINDOW (data->window));
813 data->bi_cursor_bufpos = bi_old_cursor_bufpos;
814 data->cursor_type = old_cursor_type;
815 data->bi_bufpos = bi_old_bufpos;
817 data->bi_start_col_enabled = 0;
821 /* Adds a character rune to a display block. If there is not enough
822 room to fit the rune on the display block (as determined by the
823 MAX_PIXPOS) then it adds nothing and returns ADD_FAILED. */
825 static prop_block_dynarr *
826 add_emchar_rune (pos_data *data)
828 struct rune rb, *crb;
839 if (data->bi_start_col_enabled)
841 return add_hscroll_rune (data);
844 if (data->ch == '\n')
846 data->font_is_bogus = 0;
847 /* Cheesy end-of-line pseudo-character. */
848 width = data->blank_width;
852 Lisp_Object charset = CHAR_CHARSET (data->ch);
853 if (!EQ (charset, data->last_charset) ||
854 data->findex != data->last_findex)
856 /* OK, we need to do things the hard way. */
857 struct window *w = XWINDOW (data->window);
858 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, data->findex);
859 Lisp_Object font_instance =
860 ensure_face_cachel_contains_charset (cachel, data->window,
862 Lisp_Font_Instance *fi;
864 if (EQ (font_instance, Vthe_null_font_instance))
866 font_instance = FACE_CACHEL_FONT (cachel, Vcharset_ascii);
867 data->font_is_bogus = 1;
870 data->font_is_bogus = 0;
872 fi = XFONT_INSTANCE (font_instance);
873 if (!fi->proportional_p)
874 /* sweetness and light. */
875 data->last_char_width = fi->width;
877 data->last_char_width = -1;
878 data->new_ascent = max (data->new_ascent, (int) fi->ascent);
879 data->new_descent = max (data->new_descent, (int) fi->descent);
880 data->last_charset = charset;
881 data->last_findex = data->findex;
884 width = data->last_char_width;
887 /* bummer. Proportional fonts. */
888 width = redisplay_text_width_emchar_string (XWINDOW (data->window),
894 if (data->max_pixpos != -1 && (data->pixpos + width > data->max_pixpos))
899 if (Dynarr_length (data->db->runes) < Dynarr_largest (data->db->runes))
901 crb = Dynarr_atp (data->db->runes, Dynarr_length (data->db->runes));
910 crb->findex = data->findex;
911 crb->xpos = data->pixpos;
915 if (NILP (data->string))
917 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
921 bytecount_to_charcount (XSTRING_DATA (data->string), data->bi_bufpos);
923 else if (data->is_modeline)
924 crb->bufpos = data->modeline_charpos;
926 /* fuckme if this shouldn't be an abort. */
927 /* abort (); fuckme harder, this abort gets tripped quite often,
928 in propagation and whatnot. #### fixme */
930 crb->type = RUNE_CHAR;
931 crb->object.chr.ch = data->font_is_bogus ? '~' : data->ch;
934 if (data->cursor_type == CURSOR_ON)
936 if (data->bi_bufpos == data->bi_cursor_bufpos)
938 crb->cursor_type = CURSOR_ON;
939 data->cursor_x = Dynarr_length (data->db->runes);
942 crb->cursor_type = CURSOR_OFF;
944 else if (data->cursor_type == NEXT_CURSOR)
946 crb->cursor_type = CURSOR_ON;
947 data->cursor_x = Dynarr_length (data->db->runes);
948 data->cursor_type = NO_CURSOR;
950 else if (data->cursor_type == IGNORE_CURSOR)
951 crb->cursor_type = IGNORE_CURSOR;
953 crb->cursor_type = CURSOR_OFF;
956 Dynarr_add (data->db->runes, *crb);
958 Dynarr_increment (data->db->runes);
960 data->pixpos += width;
965 /* Given a string C_STRING of length C_LENGTH, call add_emchar_rune
966 for each character in the string. Propagate any left-over data
967 unless NO_PROP is non-zero. */
969 static prop_block_dynarr *
970 add_bufbyte_string_runes (pos_data *data, Bufbyte *c_string,
971 Bytecount c_length, int no_prop)
973 Bufbyte *pos, *end = c_string + c_length;
974 prop_block_dynarr *prop;
976 /* #### This function is too simplistic. It needs to do the same
977 sort of character interpretation (display-table lookup,
978 ctl-arrow checking), etc. that create_text_block() does.
979 The functionality to do this in that routine needs to be
982 for (pos = c_string; pos < end;)
984 data->ch = charptr_emchar (pos);
986 prop = add_emchar_rune (data);
994 struct prop_block pb;
995 Bytecount len = end - pos;
996 prop = Dynarr_new (prop_block);
998 pb.type = PROP_STRING;
999 pb.data.p_string.str = xnew_array (Bufbyte, len);
1000 strncpy ((char *) pb.data.p_string.str, (char *) pos, len);
1001 pb.data.p_string.len = len;
1003 Dynarr_add (prop, pb);
1008 assert (pos <= end);
1014 /* Add a single rune of the specified width. The area covered by this
1015 rune will be displayed in the foreground color of the associated
1018 static prop_block_dynarr *
1019 add_blank_rune (pos_data *data, struct window *w, int char_tab_width)
1023 /* If data->start_col is not 0 then this call to add_blank_rune must have
1024 been to add it as a tab. */
1025 if (data->start_col)
1027 /* assert (w != NULL) */
1028 prop_block_dynarr *retval;
1030 /* If we have still not fully scrolled horizontally, subtract
1031 the width of this tab and return. */
1032 if (char_tab_width < data->start_col)
1034 data->start_col -= char_tab_width;
1037 else if (char_tab_width == data->start_col)
1038 data->blank_width = 0;
1041 int spcwid = space_width (w);
1043 if (spcwid >= data->blank_width)
1044 data->blank_width = 0;
1046 data->blank_width -= spcwid;
1049 data->start_col = 0;
1050 retval = add_hscroll_rune (data);
1052 /* Could be caused by the handling of the hscroll rune. */
1053 if (retval != NULL || !data->blank_width)
1057 /* Blank runes are always calculated to fit. */
1058 assert (data->pixpos + data->blank_width <= data->max_pixpos);
1060 rb.findex = data->findex;
1061 rb.xpos = data->pixpos;
1062 rb.width = data->blank_width;
1063 if (data->bi_bufpos)
1065 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
1068 /* #### and this is really correct too? */
1071 rb.type = RUNE_BLANK;
1073 if (data->cursor_type == CURSOR_ON)
1075 if (data->bi_bufpos == data->bi_cursor_bufpos)
1077 rb.cursor_type = CURSOR_ON;
1078 data->cursor_x = Dynarr_length (data->db->runes);
1081 rb.cursor_type = CURSOR_OFF;
1083 else if (data->cursor_type == NEXT_CURSOR)
1085 rb.cursor_type = CURSOR_ON;
1086 data->cursor_x = Dynarr_length (data->db->runes);
1087 data->cursor_type = NO_CURSOR;
1090 rb.cursor_type = CURSOR_OFF;
1092 Dynarr_add (data->db->runes, rb);
1093 data->pixpos += data->blank_width;
1098 /* Add runes representing a character in octal. */
1100 #define ADD_NEXT_OCTAL_RUNE_CHAR do \
1102 if (add_failed || (add_failed = add_emchar_rune (data))) \
1104 struct prop_block pb; \
1106 prop = Dynarr_new (prop_block); \
1108 pb.type = PROP_CHAR; \
1109 pb.data.p_char.ch = data->ch; \
1110 pb.data.p_char.cursor_type = data->cursor_type; \
1111 Dynarr_add (prop, pb); \
1115 static prop_block_dynarr *
1116 add_octal_runes (pos_data *data)
1118 prop_block_dynarr *prop, *add_failed;
1119 Emchar orig_char = data->ch;
1120 unsigned int orig_cursor_type = data->cursor_type;
1126 if (data->start_col)
1129 if (!data->start_col)
1131 if (data->bi_start_col_enabled)
1133 add_failed = add_hscroll_rune (data);
1137 struct glyph_block gb;
1138 struct window *w = XWINDOW (data->window);
1141 gb.glyph = Voctal_escape_glyph;
1143 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1144 GLYPH_CACHEL (w, OCT_ESC_GLYPH_INDEX));
1148 /* We only propagate information if the glyph was partially
1153 data->cursor_type = IGNORE_CURSOR;
1155 if (data->ch >= 0x100)
1157 /* If the character is an extended Mule character, it could have
1158 up to 19 bits. For the moment, we treat it as a seven-digit
1159 octal number. This is not that pretty, but whatever. */
1160 data->ch = (7 & (orig_char >> 18)) + '0';
1161 ADD_NEXT_OCTAL_RUNE_CHAR;
1163 data->ch = (7 & (orig_char >> 15)) + '0';
1164 ADD_NEXT_OCTAL_RUNE_CHAR;
1166 data->ch = (7 & (orig_char >> 12)) + '0';
1167 ADD_NEXT_OCTAL_RUNE_CHAR;
1169 data->ch = (7 & (orig_char >> 9)) + '0';
1170 ADD_NEXT_OCTAL_RUNE_CHAR;
1173 data->ch = (7 & (orig_char >> 6)) + '0';
1174 ADD_NEXT_OCTAL_RUNE_CHAR;
1176 data->ch = (7 & (orig_char >> 3)) + '0';
1177 ADD_NEXT_OCTAL_RUNE_CHAR;
1179 data->ch = (7 & orig_char) + '0';
1180 ADD_NEXT_OCTAL_RUNE_CHAR;
1182 data->cursor_type = orig_cursor_type;
1186 #undef ADD_NEXT_OCTAL_RUNE_CHAR
1188 /* Add runes representing a control character to a display block. */
1190 static prop_block_dynarr *
1191 add_control_char_runes (pos_data *data, struct buffer *b)
1193 if (!NILP (b->ctl_arrow))
1195 prop_block_dynarr *prop;
1196 Emchar orig_char = data->ch;
1197 unsigned int old_cursor_type = data->cursor_type;
1202 if (data->start_col)
1205 if (!data->start_col)
1207 if (data->bi_start_col_enabled)
1209 prop_block_dynarr *retval;
1211 retval = add_hscroll_rune (data);
1217 struct glyph_block gb;
1218 struct window *w = XWINDOW (data->window);
1221 gb.glyph = Vcontrol_arrow_glyph;
1223 /* We only propagate information if the glyph was partially
1225 if (add_glyph_rune (data, &gb, BEGIN_GLYPHS, 1,
1226 GLYPH_CACHEL (w, CONTROL_GLYPH_INDEX)))
1231 if (orig_char == 0177)
1234 data->ch = orig_char ^ 0100;
1235 data->cursor_type = IGNORE_CURSOR;
1237 if (add_emchar_rune (data))
1239 struct prop_block pb;
1241 prop = Dynarr_new (prop_block);
1243 pb.type = PROP_CHAR;
1244 pb.data.p_char.ch = data->ch;
1245 pb.data.p_char.cursor_type = data->cursor_type;
1246 Dynarr_add (prop, pb);
1249 data->cursor_type = old_cursor_type;
1254 return add_octal_runes (data);
1258 static prop_block_dynarr *
1259 add_disp_table_entry_runes_1 (pos_data *data, Lisp_Object entry)
1261 prop_block_dynarr *prop = NULL;
1263 if (STRINGP (entry))
1265 prop = add_bufbyte_string_runes (data,
1266 XSTRING_DATA (entry),
1267 XSTRING_LENGTH (entry),
1270 else if (GLYPHP (entry))
1272 if (data->start_col)
1275 if (!data->start_col && data->bi_start_col_enabled)
1277 prop = add_hscroll_rune (data);
1281 struct glyph_block gb;
1285 prop = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
1288 else if (CHAR_OR_CHAR_INTP (entry))
1290 data->ch = XCHAR_OR_CHAR_INT (entry);
1291 prop = add_emchar_rune (data);
1293 else if (CONSP (entry))
1295 if (EQ (XCAR (entry), Qformat)
1296 && CONSP (XCDR (entry))
1297 && STRINGP (XCAR (XCDR (entry))))
1299 Lisp_Object format = XCAR (XCDR (entry));
1300 Bytind len = XSTRING_LENGTH (format);
1301 Bufbyte *src = XSTRING_DATA (format), *end = src + len;
1302 Bufbyte *result = alloca_array (Bufbyte, len);
1303 Bufbyte *dst = result;
1307 Emchar c = charptr_emchar (src);
1309 if (c != '%' || src == end)
1310 dst += set_charptr_emchar (dst, c);
1313 c = charptr_emchar (src);
1318 dst += long_to_string_base ((char *)dst, data->ch, 16);
1321 dst += set_charptr_emchar (dst, '%');
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 /* A nil extent indicates a special glyph (ex. truncator). */
1532 if (NILP (gb->extent)
1533 || (pos_type == BEGIN_GLYPHS &&
1534 extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1535 || (pos_type == END_GLYPHS &&
1536 extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT))
1541 int ascent, descent;
1542 Lisp_Object baseline;
1546 width = cachel->width;
1548 width = glyph_width (gb->glyph, data->window);
1553 if (data->start_col || data->start_col_xoffset)
1555 prop_block_dynarr *retval;
1556 int glyph_char_width = width / space_width (w);
1558 /* If we still have not fully scrolled horizontally after
1559 taking into account the width of the glyph, subtract its
1560 width and return. */
1561 if (glyph_char_width < data->start_col)
1563 data->start_col -= glyph_char_width;
1566 else if (glyph_char_width == data->start_col)
1570 xoffset = space_width (w) * data->start_col;
1573 /* #### Can this happen? */
1578 data->start_col = 0;
1579 retval = add_hscroll_rune (data);
1581 /* Could be caused by the handling of the hscroll rune. */
1582 if (retval != NULL || !width)
1588 if (data->pixpos + width > data->max_pixpos)
1590 /* If this is the first object we are attempting to add to
1591 the line then we ignore the horizontal_clip threshold.
1592 Otherwise we will loop until the bottom of the window
1593 continually failing to add this glyph because it is wider
1594 than the window. We could alternatively just completely
1595 ignore the glyph and proceed from there but I think that
1596 this is a better solution. */
1597 if (Dynarr_length (data->db->runes)
1598 && data->max_pixpos - data->pixpos < horizontal_clip)
1601 width = data->max_pixpos - data->pixpos;
1606 ascent = cachel->ascent;
1607 descent = cachel->descent;
1611 ascent = glyph_ascent (gb->glyph, data->window);
1612 descent = glyph_descent (gb->glyph, data->window);
1615 baseline = glyph_baseline (gb->glyph, data->window);
1617 if (glyph_contrib_p (gb->glyph, data->window))
1619 /* A pixmap that has not had a baseline explicitly set. Its
1620 contribution will be determined later. */
1621 if (NILP (baseline))
1623 int height = ascent + descent;
1624 data->max_pixmap_height = max (data->max_pixmap_height, height);
1627 /* A string so determine contribution normally. */
1628 else if (EQ (baseline, Qt))
1630 data->new_ascent = max (data->new_ascent, ascent);
1631 data->new_descent = max (data->new_descent, descent);
1634 /* A pixmap with an explicitly set baseline. We determine the
1635 contribution here. */
1636 else if (INTP (baseline))
1638 int height = ascent + descent;
1639 int pix_ascent, pix_descent;
1641 pix_ascent = height * XINT (baseline) / 100;
1642 pix_descent = height - pix_ascent;
1644 data->new_ascent = max (data->new_ascent, pix_ascent);
1645 data->new_descent = max (data->new_descent, pix_descent);
1648 /* Otherwise something is screwed up. */
1653 face = glyph_face (gb->glyph, data->window);
1655 rb.findex = data->findex;
1657 rb.findex = get_builtin_face_cache_index (w, face);
1659 rb.xpos = data->pixpos;
1661 rb.bufpos = 0; /* glyphs are never "at" anywhere */
1662 if (data->bi_endpos)
1663 /* #### is this necessary at all? */
1664 rb.endpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1668 rb.type = RUNE_DGLYPH;
1669 /* #### Ben sez: this is way bogus if the glyph is a string.
1670 You should not make the output routines have to cope with
1671 this. The string could contain Mule characters, or non-
1672 printable characters, or characters to be passed through
1673 the display table, or non-character objects (when this gets
1674 implemented), etc. Instead, this routine here should parse
1675 the string into a series of runes. */
1676 rb.object.dglyph.glyph = gb->glyph;
1677 rb.object.dglyph.extent = gb->extent;
1678 rb.object.dglyph.xoffset = xoffset;
1682 rb.bufpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1685 if (data->cursor_type == CURSOR_ON)
1687 if (data->bi_bufpos == data->bi_cursor_bufpos)
1689 rb.cursor_type = CURSOR_ON;
1690 data->cursor_x = Dynarr_length (data->db->runes);
1693 rb.cursor_type = CURSOR_OFF;
1695 else if (data->cursor_type == NEXT_CURSOR)
1697 rb.cursor_type = CURSOR_ON;
1698 data->cursor_x = Dynarr_length (data->db->runes);
1699 data->cursor_type = NO_CURSOR;
1701 else if (data->cursor_type == IGNORE_CURSOR)
1702 rb.cursor_type = IGNORE_CURSOR;
1703 else if (data->cursor_type == NO_CURSOR)
1704 rb.cursor_type = NO_CURSOR;
1706 rb.cursor_type = CURSOR_OFF;
1709 rb.cursor_type = CURSOR_OFF;
1711 Dynarr_add (data->db->runes, rb);
1712 data->pixpos += width;
1718 if (!NILP (glyph_face (gb->glyph, data->window)))
1720 get_builtin_face_cache_index (w, glyph_face (gb->glyph,
1723 gb->findex = data->findex;
1725 if (pos_type == BEGIN_GLYPHS)
1727 if (!data->dl->left_glyphs)
1728 data->dl->left_glyphs = Dynarr_new (glyph_block);
1729 Dynarr_add (data->dl->left_glyphs, *gb);
1732 else if (pos_type == END_GLYPHS)
1734 if (!data->dl->right_glyphs)
1735 data->dl->right_glyphs = Dynarr_new (glyph_block);
1736 Dynarr_add (data->dl->right_glyphs, *gb);
1740 abort (); /* there are no unknown types */
1743 return NULL; /* shut up compiler */
1746 /* Add all glyphs at position POS_TYPE that are contained in the given
1749 static prop_block_dynarr *
1750 add_glyph_runes (pos_data *data, int pos_type)
1752 /* #### This still needs to handle the start_col parameter. Duh, Chuck,
1753 why didn't you just modify add_glyph_rune in the first place? */
1755 glyph_block_dynarr *glyph_arr = (pos_type == BEGIN_GLYPHS
1756 ? data->ef->begin_glyphs
1757 : data->ef->end_glyphs);
1758 prop_block_dynarr *prop;
1760 for (elt = 0; elt < Dynarr_length (glyph_arr); elt++)
1762 prop = add_glyph_rune (data, Dynarr_atp (glyph_arr, elt), pos_type, 0,
1767 /* #### Add some propagation information. */
1772 Dynarr_reset (glyph_arr);
1777 /* Given a position for a buffer in a window, ensure that the given
1778 display line DL accurately represents the text on a line starting
1779 at the given position.
1781 NOTE NOTE NOTE NOTE: This function works with and returns Bytinds.
1782 You must do appropriate conversion. */
1785 create_text_block (struct window *w, struct display_line *dl,
1786 Bytind bi_start_pos, prop_block_dynarr **prop,
1789 struct frame *f = XFRAME (w->frame);
1790 struct buffer *b = XBUFFER (w->buffer);
1791 struct device *d = XDEVICE (f->device);
1795 /* Don't display anything in the minibuffer if this window is not on
1796 a selected frame. We consider all other windows to be active
1797 minibuffers as it simplifies the coding. */
1798 int active_minibuffer = (!MINI_WINDOW_P (w) ||
1799 (f == device_selected_frame (d)) ||
1800 is_surrogate_for_selected_frame (f));
1802 int truncate_win = window_truncation_on (w);
1803 int end_glyph_width;
1805 /* If the buffer's value of selective_display is an integer then
1806 only lines that start with less than selective_display columns of
1807 space will be displayed. If selective_display is t then all text
1808 after a ^M is invisible. */
1809 int selective = (INTP (b->selective_display)
1810 ? XINT (b->selective_display)
1811 : (!NILP (b->selective_display) ? -1 : 0));
1813 /* The variable ctl-arrow allows the user to specify what characters
1814 can actually be displayed and which octal should be used for.
1815 #### This variable should probably have some rethought done to
1818 #### It would also be really nice if you could specify that
1819 the characters come out in hex instead of in octal. Mule
1820 does that by adding a ctl-hexa variable similar to ctl-arrow,
1821 but that's bogus -- we need a more general solution. I
1822 think you need to extend the concept of display tables
1823 into a more general conversion mechanism. Ideally you
1824 could specify a Lisp function that converts characters,
1825 but this violates the Second Golden Rule and besides would
1826 make things way way way way slow.
1828 So instead, we extend the display-table concept, which was
1829 historically limited to 256-byte vectors, to one of the
1832 a) A 256-entry vector, for backward compatibility;
1833 b) char-table, mapping characters to values;
1834 c) range-table, mapping ranges of characters to values;
1835 d) a list of the above.
1837 The (d) option allows you to specify multiple display tables
1838 instead of just one. Each display table can specify conversions
1839 for some characters and leave others unchanged. The way the
1840 character gets displayed is determined by the first display table
1841 with a binding for that character. This way, you could call a
1842 function `enable-hex-display' that adds a hex display-table to
1843 the list of display tables for the current buffer.
1845 #### ...not yet implemented... Also, we extend the concept of
1846 "mapping" to include a printf-like spec. Thus you can make all
1847 extended characters show up as hex with a display table like
1850 #s(range-table data ((256 524288) (format "%x")))
1852 Since more than one display table is possible, you have
1853 great flexibility in mapping ranges of characters. */
1854 Emchar printable_min = (CHAR_OR_CHAR_INTP (b->ctl_arrow)
1855 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
1856 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
1859 Lisp_Object face_dt, window_dt;
1861 /* The text display block for this display line. */
1862 struct display_block *db = get_display_block_from_line (dl, TEXT);
1864 /* The first time through the main loop we need to force the glyph
1865 data to be updated. */
1868 /* Apparently the new extent_fragment_update returns an end position
1869 equal to the position passed in if there are no more runs to be
1871 int no_more_frags = 0;
1873 Lisp_Object synch_minibuffers_value =
1874 symbol_value_in_buffer (Qsynchronize_minibuffers, w->buffer);
1876 dl->used_prop_data = 0;
1880 data.ef = extent_fragment_new (w->buffer, f);
1882 /* These values are used by all of the rune addition routines. We add
1883 them to this structure for ease of passing. */
1885 XSETWINDOW (data.window, w);
1890 data.bi_bufpos = bi_start_pos;
1891 data.pixpos = dl->bounds.left_in;
1892 data.last_charset = Qunbound;
1893 data.last_findex = DEFAULT_INDEX;
1894 data.result_str = Qnil;
1896 /* Set the right boundary adjusting it to take into account any end
1897 glyph. Save the width of the end glyph for later use. */
1898 data.max_pixpos = dl->bounds.right_in;
1900 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
1902 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
1903 data.max_pixpos -= end_glyph_width;
1905 if (cursor_in_echo_area && MINI_WINDOW_P (w) && echo_area_active (f))
1907 data.bi_cursor_bufpos = BI_BUF_ZV (b);
1908 data.cursor_type = CURSOR_ON;
1910 else if (MINI_WINDOW_P (w) && !active_minibuffer)
1911 data.cursor_type = NO_CURSOR;
1912 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)) &&
1913 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
1914 d == XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d))))&&
1915 f == XFRAME(DEVICE_SELECTED_FRAME(d)))
1917 data.bi_cursor_bufpos = BI_BUF_PT (b);
1918 data.cursor_type = CURSOR_ON;
1920 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)))
1922 data.bi_cursor_bufpos = bi_marker_position (w->pointm[type]);
1923 data.cursor_type = CURSOR_ON;
1926 data.cursor_type = NO_CURSOR;
1929 data.start_col = w->hscroll;
1930 data.start_col_xoffset = w->left_xoffset;
1931 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
1932 data.hscroll_glyph_width_adjust = 0;
1934 /* We regenerate the line from the very beginning. */
1935 Dynarr_reset (db->runes);
1937 /* Why is this less than or equal and not just less than? If the
1938 starting position is already equal to the maximum we can't add
1939 anything else, right? Wrong. We might still have a newline to
1940 add. A newline can use the room allocated for an end glyph since
1941 if we add it we know we aren't going to be adding any end
1944 /* #### Chuck -- I think this condition should be while (1).
1945 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
1946 and the begin-glyph ends exactly at the end of the window, the
1947 end-glyph and text might not be displayed. while (1) ensures
1948 that the loop terminates only when either (a) there is
1949 propagation data or (b) the end-of-line or end-of-buffer is hit.
1951 #### Also I think you need to ensure that the operation
1952 "add begin glyphs; add end glyphs; add text" is atomic and
1953 can't get interrupted in the middle. If you run off the end
1954 of the line during that operation, then you keep accumulating
1955 propagation data until you're done. Otherwise, if the (e.g.)
1956 there's a begin glyph at a particular position and attempting
1957 to display that glyph results in window-end being hit and
1958 propagation data being generated, then the character at that
1959 position won't be displayed.
1961 #### See also the comment after the end of this loop, below.
1963 while (data.pixpos <= data.max_pixpos
1964 && (active_minibuffer || !NILP (synch_minibuffers_value)))
1966 /* #### This check probably should not be necessary. */
1967 if (data.bi_bufpos > BI_BUF_ZV (b))
1969 /* #### urk! More of this lossage! */
1974 /* If selective display was an integer and we aren't working on
1975 a continuation line then find the next line we are actually
1976 supposed to display. */
1978 && (data.bi_bufpos == BI_BUF_BEGV (b)
1979 || BUF_FETCH_CHAR (b, prev_bytind (b, data.bi_bufpos)) == '\n'))
1981 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
1984 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
1985 if (data.bi_bufpos >= BI_BUF_ZV (b))
1987 data.bi_bufpos = BI_BUF_ZV (b);
1993 /* Check for face changes. */
1994 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
1996 /* Now compute the face and begin/end-glyph information. */
1998 /* Remember that the extent-fragment routines deal in Bytind's. */
1999 extent_fragment_update (w, data.ef, data.bi_bufpos);
2001 get_display_tables (w, data.findex, &face_dt, &window_dt);
2003 if (data.bi_bufpos == data.ef->end)
2008 /* Determine what is next to be displayed. We first handle any
2009 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
2010 display then we determine what to do based on the character at the
2011 current buffer position. */
2013 /* If the current position is covered by an invisible extent, do
2014 nothing (except maybe add some ellipses).
2016 #### The behavior of begin and end-glyphs at the edge of an
2017 invisible extent should be investigated further. This is
2018 fairly low priority though. */
2019 if (data.ef->invisible)
2021 /* #### Chuck, perhaps you could look at this code? I don't
2022 really know what I'm doing. */
2025 Dynarr_free (*prop);
2029 /* The extent fragment code only sets this when we should
2030 really display the ellipses. It makes sure the ellipses
2031 don't get displayed more than once in a row. */
2032 if (data.ef->invisible_ellipses)
2034 struct glyph_block gb;
2036 data.ef->invisible_ellipses_already_displayed = 1;
2037 data.ef->invisible_ellipses = 0;
2039 gb.glyph = Vinvisible_text_glyph;
2040 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2041 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2042 /* Perhaps they shouldn't propagate if the very next thing
2043 is to display a newline (for compatibility with
2044 selective-display-ellipses)? Maybe that's too
2050 /* If point is in an invisible region we place it on the
2051 next visible character. */
2052 if (data.cursor_type == CURSOR_ON
2053 && data.bi_bufpos == data.bi_cursor_bufpos)
2055 data.cursor_type = NEXT_CURSOR;
2058 /* #### What if we we're dealing with a display table? */
2062 if (data.bi_bufpos == BI_BUF_ZV (b))
2065 INC_BYTIND (b, data.bi_bufpos);
2068 /* If there is propagation data, then it represents the current
2069 buffer position being displayed. Add them and advance the
2070 position counter. This might also add the minibuffer
2074 dl->used_prop_data = 1;
2075 *prop = add_propagation_runes (prop, &data);
2078 goto done; /* gee, a really narrow window */
2079 else if (data.bi_bufpos == BI_BUF_ZV (b))
2081 else if (data.bi_bufpos < BI_BUF_BEGV (b))
2082 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
2083 data.bi_bufpos = BI_BUF_BEGV (b);
2085 INC_BYTIND (b, data.bi_bufpos);
2088 /* If there are end glyphs, add them to the line. These are
2089 the end glyphs for the previous run of text. We add them
2090 here rather than doing them at the end of handling the
2091 previous run so that glyphs at the beginning and end of
2092 a line are handled correctly. */
2093 else if (Dynarr_length (data.ef->end_glyphs) > 0)
2095 *prop = add_glyph_runes (&data, END_GLYPHS);
2100 /* If there are begin glyphs, add them to the line. */
2101 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
2103 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
2108 /* If at end-of-buffer, we've already processed begin and
2109 end-glyphs at this point and there's no text to process,
2111 else if (data.bi_bufpos == BI_BUF_ZV (b))
2116 Lisp_Object entry = Qnil;
2117 /* Get the character at the current buffer position. */
2118 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2119 if (!NILP (face_dt) || !NILP (window_dt))
2120 entry = display_table_entry (data.ch, face_dt, window_dt);
2122 /* If there is a display table entry for it, hand it off to
2123 add_disp_table_entry_runes and let it worry about it. */
2124 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
2126 *prop = add_disp_table_entry_runes (&data, entry);
2132 /* Check if we have hit a newline character. If so, add a marker
2133 to the line and end this loop. */
2134 else if (data.ch == '\n')
2136 /* We aren't going to be adding an end glyph so give its
2137 space back in order to make sure that the cursor can
2139 data.max_pixpos += end_glyph_width;
2142 && (bi_spaces_at_point
2143 (b, next_bytind (b, data.bi_bufpos))
2146 if (!NILP (b->selective_display_ellipses))
2148 struct glyph_block gb;
2151 gb.glyph = Vinvisible_text_glyph;
2152 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2153 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2157 /* Cheesy, cheesy, cheesy. We mark the end of the
2158 line with a special "character rune" whose width
2159 is the EOL cursor width and whose character is
2160 the non-printing character '\n'. */
2161 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2162 *prop = add_emchar_rune (&data);
2165 /* We need to set data.bi_bufpos to the start of the
2166 next visible region in order to make this line
2167 appear to contain all of the invisible area.
2168 Otherwise, the line cache won't work
2170 INC_BYTIND (b, data.bi_bufpos);
2171 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2174 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2175 if (data.bi_bufpos >= BI_BUF_ZV (b))
2177 data.bi_bufpos = BI_BUF_ZV (b);
2181 if (BI_BUF_FETCH_CHAR
2182 (b, prev_bytind (b, data.bi_bufpos)) == '\n')
2183 DEC_BYTIND (b, data.bi_bufpos);
2187 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2188 *prop = add_emchar_rune (&data);
2194 /* If the current character is ^M, and selective display is
2195 enabled, then add the invisible-text-glyph if
2196 selective-display-ellipses is set. In any case, this
2198 else if (data.ch == (('M' & 037)) && selective == -1)
2200 Bytind bi_next_bufpos;
2202 /* Find the buffer position at the end of the line. */
2204 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2205 if (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_next_bufpos))
2207 DEC_BYTIND (b, bi_next_bufpos);
2209 /* If the cursor is somewhere in the elided text make
2210 sure that the cursor gets drawn appropriately. */
2211 if (data.cursor_type == CURSOR_ON
2212 && (data.bi_cursor_bufpos >= data.bi_bufpos &&
2213 data.bi_cursor_bufpos < bi_next_bufpos))
2215 data.cursor_type = NEXT_CURSOR;
2218 /* We won't be adding a truncation or continuation glyph
2219 so give up the room allocated for them. */
2220 data.max_pixpos += end_glyph_width;
2222 if (!NILP (b->selective_display_ellipses))
2224 /* We don't propagate anything from the invisible
2225 text glyph if it fails to fit. This is
2227 struct glyph_block gb;
2230 gb.glyph = Vinvisible_text_glyph;
2231 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 1,
2232 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2235 /* Set the buffer position to the end of the line. We
2236 need to do this before potentially adding a newline
2237 so that the cursor flag will get set correctly (if
2239 data.bi_bufpos = bi_next_bufpos;
2241 if (NILP (b->selective_display_ellipses)
2242 || data.bi_cursor_bufpos == bi_next_bufpos)
2244 /* We have to at least add a newline character so
2245 that the cursor shows up properly. */
2247 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2248 data.findex = DEFAULT_INDEX;
2250 data.start_col_xoffset = 0;
2251 data.bi_start_col_enabled = 0;
2253 add_emchar_rune (&data);
2256 /* This had better be a newline but doing it this way
2257 we'll see obvious incorrect results if it isn't. No
2258 need to abort here. */
2259 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2264 /* If the current character is considered to be printable, then
2266 else if (data.ch >= printable_min)
2268 *prop = add_emchar_rune (&data);
2273 /* If the current character is a tab, determine the next tab
2274 starting position and add a blank rune which extends from the
2275 current pixel position to that starting position. */
2276 else if (data.ch == '\t')
2278 int tab_start_pixpos = data.pixpos;
2283 if (data.start_col > 1)
2284 tab_start_pixpos -= (space_width (w) * (data.start_col - 1))
2285 + data.start_col_xoffset;
2288 next_tab_position (w, tab_start_pixpos,
2289 dl->bounds.left_in +
2290 data.hscroll_glyph_width_adjust);
2291 if (next_tab_start > data.max_pixpos)
2293 prop_width = next_tab_start - data.max_pixpos;
2294 next_tab_start = data.max_pixpos;
2296 data.blank_width = next_tab_start - data.pixpos;
2298 (next_tab_start - tab_start_pixpos) / space_width (w);
2300 *prop = add_blank_rune (&data, w, char_tab_width);
2302 /* add_blank_rune is only supposed to be called with
2303 sizes guaranteed to fit in the available space. */
2308 struct prop_block pb;
2309 *prop = Dynarr_new (prop_block);
2311 pb.type = PROP_BLANK;
2312 pb.data.p_blank.width = prop_width;
2313 pb.data.p_blank.findex = data.findex;
2314 Dynarr_add (*prop, pb);
2320 /* If character is a control character, pass it off to
2321 add_control_char_runes.
2323 The is_*() routines have undefined results on
2324 arguments outside of the range [-1, 255]. (This
2325 often bites people who carelessly use `char' instead
2326 of `unsigned char'.)
2328 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
2330 *prop = add_control_char_runes (&data, b);
2336 /* If the character is above the ASCII range and we have not
2337 already handled it, then print it as an octal number. */
2338 else if (data.ch >= 0200)
2340 *prop = add_octal_runes (&data);
2346 /* Assume the current character is considered to be printable,
2347 then just add it. */
2350 *prop = add_emchar_rune (&data);
2355 INC_BYTIND (b, data.bi_bufpos);
2361 /* Determine the starting point of the next line if we did not hit the
2362 end of the buffer. */
2363 if (data.bi_bufpos < BI_BUF_ZV (b)
2364 && (active_minibuffer || !NILP (synch_minibuffers_value)))
2366 /* #### This check is not correct. If the line terminated
2367 due to a begin-glyph or end-glyph hitting window-end, then
2368 data.ch will not point to the character at data.bi_bufpos. If
2369 you make the two changes mentioned at the top of this loop,
2370 you should be able to say '(if (*prop))'. That should also
2371 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
2374 /* The common case is that the line ended because we hit a newline.
2375 In that case, the next character is just the next buffer
2377 if (data.ch == '\n')
2379 /* If data.start_col_enabled is still true, then the window is
2380 scrolled far enough so that nothing on this line is visible.
2381 We need to stick a truncation glyph at the beginning of the
2382 line in that case unless the line is completely blank. */
2383 if (data.bi_start_col_enabled)
2385 if (data.cursor_type == CURSOR_ON)
2387 if (data.bi_cursor_bufpos >= bi_start_pos
2388 && data.bi_cursor_bufpos <= data.bi_bufpos)
2389 data.bi_cursor_bufpos = data.bi_bufpos;
2391 data.findex = DEFAULT_INDEX;
2393 data.bi_start_col_enabled = 0;
2395 if (data.bi_bufpos != bi_start_pos)
2397 struct glyph_block gb;
2400 gb.glyph = Vhscroll_glyph;
2401 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2402 GLYPH_CACHEL (w, HSCROLL_GLYPH_INDEX));
2406 /* This duplicates code down below to add a newline to
2407 the end of an otherwise empty line.*/
2409 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2411 add_emchar_rune (&data);
2415 INC_BYTIND (b, data.bi_bufpos);
2418 /* Otherwise we have a buffer line which cannot fit on one display
2422 struct glyph_block gb;
2423 struct glyph_cachel *cachel;
2425 /* If the line is to be truncated then we actually have to look
2426 for the next newline. We also add the end-of-line glyph which
2427 we know will fit because we adjusted the right border before
2428 we starting laying out the line. */
2429 data.max_pixpos += end_glyph_width;
2430 data.findex = DEFAULT_INDEX;
2437 /* Now find the start of the next line. */
2438 bi_pos = bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2440 /* If the cursor is past the truncation line then we
2441 make it appear on the truncation glyph. If we've hit
2442 the end of the buffer then we also make the cursor
2443 appear unless eob is immediately preceded by a
2444 newline. In that case the cursor should actually
2445 appear on the next line. */
2446 if (data.cursor_type == CURSOR_ON
2447 && data.bi_cursor_bufpos >= data.bi_bufpos
2448 && (data.bi_cursor_bufpos < bi_pos ||
2449 (bi_pos == BI_BUF_ZV (b)
2450 && (bi_pos == BI_BUF_BEGV (b)
2451 || (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_pos))
2453 data.bi_cursor_bufpos = bi_pos;
2455 data.cursor_type = NO_CURSOR;
2457 data.bi_bufpos = bi_pos;
2458 gb.glyph = Vtruncation_glyph;
2459 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
2463 /* The cursor can never be on the continuation glyph. */
2464 data.cursor_type = NO_CURSOR;
2466 /* data.bi_bufpos is already at the start of the next line. */
2468 gb.glyph = Vcontinuation_glyph;
2469 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
2472 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 1, cachel);
2474 if (truncate_win && data.bi_bufpos == BI_BUF_ZV (b)
2475 && BI_BUF_FETCH_CHAR (b, prev_bytind (b, BI_BUF_ZV (b))) != '\n')
2476 /* #### Damn this losing shit. */
2480 else if ((active_minibuffer || !NILP (synch_minibuffers_value))
2481 && (!echo_area_active (f) || data.bi_bufpos == BI_BUF_ZV (b)))
2483 /* We need to add a marker to the end of the line since there is no
2484 newline character in order for the cursor to get drawn. We label
2485 it as a newline so that it gets handled correctly by the
2486 whitespace routines below. */
2489 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2490 data.findex = DEFAULT_INDEX;
2492 data.start_col_xoffset = 0;
2493 data.bi_start_col_enabled = 0;
2495 data.max_pixpos += data.blank_width;
2496 add_emchar_rune (&data);
2497 data.max_pixpos -= data.blank_width;
2499 /* #### urk! Chuck, this shit is bad news. Going around
2500 manipulating invalid positions is guaranteed to result in
2501 trouble sooner or later. */
2502 data.bi_bufpos = BI_BUF_ZV (b) + 1;
2505 /* Calculate left whitespace boundary. */
2509 /* Whitespace past a newline is considered right whitespace. */
2510 while (elt < Dynarr_length (db->runes))
2512 struct rune *rb = Dynarr_atp (db->runes, elt);
2514 if ((rb->type == RUNE_CHAR && rb->object.chr.ch == ' ')
2515 || rb->type == RUNE_BLANK)
2517 dl->bounds.left_white += rb->width;
2521 elt = Dynarr_length (db->runes);
2525 /* Calculate right whitespace boundary. */
2527 int elt = Dynarr_length (db->runes) - 1;
2530 while (!done && elt >= 0)
2532 struct rune *rb = Dynarr_atp (db->runes, elt);
2534 if (!(rb->type == RUNE_CHAR && rb->object.chr.ch < 0x100
2535 && isspace (rb->object.chr.ch))
2536 && !rb->type == RUNE_BLANK)
2538 dl->bounds.right_white = rb->xpos + rb->width;
2546 /* The line is blank so everything is considered to be right
2549 dl->bounds.right_white = dl->bounds.left_in;
2552 /* Set the display blocks bounds. */
2553 db->start_pos = dl->bounds.left_in;
2554 if (Dynarr_length (db->runes))
2556 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
2558 db->end_pos = rb->xpos + rb->width;
2561 db->end_pos = dl->bounds.right_white;
2563 /* update line height parameters */
2564 if (!data.new_ascent && !data.new_descent)
2566 /* We've got a blank line so initialize these values from the default
2568 default_face_font_info (data.window, &data.new_ascent,
2569 &data.new_descent, 0, 0, 0);
2572 if (data.max_pixmap_height)
2574 int height = data.new_ascent + data.new_descent;
2575 int pix_ascent, pix_descent;
2577 pix_descent = data.max_pixmap_height * data.new_descent / height;
2578 pix_ascent = data.max_pixmap_height - pix_descent;
2580 data.new_ascent = max (data.new_ascent, pix_ascent);
2581 data.new_descent = max (data.new_descent, pix_descent);
2584 dl->ascent = data.new_ascent;
2585 dl->descent = data.new_descent;
2588 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
2590 if (dl->ascent < ascent)
2591 dl->ascent = ascent;
2594 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
2596 if (dl->descent < descent)
2597 dl->descent = descent;
2600 dl->cursor_elt = data.cursor_x;
2601 /* #### lossage lossage lossage! Fix this shit! */
2602 if (data.bi_bufpos > BI_BUF_ZV (b))
2603 dl->end_bufpos = BUF_ZV (b);
2605 dl->end_bufpos = bytind_to_bufpos (b, data.bi_bufpos) - 1;
2607 data.dl->num_chars = column_at_point (b, dl->end_bufpos, 0);
2609 /* This doesn't correctly take into account tabs and control
2610 characters but if the window isn't being truncated then this
2611 value isn't going to end up being used anyhow. */
2612 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
2614 /* #### handle horizontally scrolled line with text none of which
2615 was actually laid out. */
2617 /* #### handle any remainder of overlay arrow */
2619 if (*prop == ADD_FAILED)
2622 if (truncate_win && *prop)
2624 Dynarr_free (*prop);
2628 extent_fragment_delete (data.ef);
2630 /* #### If we started at EOB, then make sure we return a value past
2631 it so that regenerate_window will exit properly. This is bogus.
2632 The main loop should get fixed so that it isn't necessary to call
2633 this function if we are already at EOB. */
2635 if (data.bi_bufpos == BI_BUF_ZV (b) && bi_start_pos == BI_BUF_ZV (b))
2636 return data.bi_bufpos + 1; /* Yuck! */
2638 return data.bi_bufpos;
2641 /* Display the overlay arrow at the beginning of the given line. */
2644 create_overlay_glyph_block (struct window *w, struct display_line *dl)
2646 struct frame *f = XFRAME (w->frame);
2647 struct device *d = XDEVICE (f->device);
2650 /* If Voverlay_arrow_string isn't valid then just fail silently. */
2651 if (!STRINGP (Voverlay_arrow_string) && !GLYPHP (Voverlay_arrow_string))
2657 XSETWINDOW (data.window, w);
2658 data.db = get_display_block_from_line (dl, OVERWRITE);
2660 data.pixpos = dl->bounds.left_in;
2661 data.max_pixpos = dl->bounds.right_in;
2662 data.cursor_type = NO_CURSOR;
2664 data.findex = DEFAULT_INDEX;
2665 data.last_charset = Qunbound;
2666 data.last_findex = DEFAULT_INDEX;
2667 data.result_str = Qnil;
2670 Dynarr_reset (data.db->runes);
2672 if (STRINGP (Voverlay_arrow_string))
2674 add_bufbyte_string_runes
2676 XSTRING_DATA (Voverlay_arrow_string),
2677 XSTRING_LENGTH (Voverlay_arrow_string),
2680 else if (GLYPHP (Voverlay_arrow_string))
2682 struct glyph_block gb;
2684 gb.glyph = Voverlay_arrow_string;
2686 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, 0);
2689 if (data.max_pixmap_height)
2691 int height = data.new_ascent + data.new_descent;
2692 int pix_ascent, pix_descent;
2694 pix_descent = data.max_pixmap_height * data.new_descent / height;
2695 pix_ascent = data.max_pixmap_height - pix_descent;
2697 data.new_ascent = max (data.new_ascent, pix_ascent);
2698 data.new_descent = max (data.new_descent, pix_descent);
2701 dl->ascent = data.new_ascent;
2702 dl->descent = data.new_descent;
2704 data.db->start_pos = dl->bounds.left_in;
2705 data.db->end_pos = data.pixpos;
2707 return data.pixpos - dl->bounds.left_in;
2710 /* Add a type of glyph to a margin display block. */
2713 add_margin_runes (struct display_line *dl, struct display_block *db, int start,
2714 int count, enum glyph_layout layout, int side, Lisp_Object window)
2716 glyph_block_dynarr *gbd = (side == LEFT_GLYPHS
2718 : dl->right_glyphs);
2723 if ((layout == GL_WHITESPACE && side == LEFT_GLYPHS)
2724 || (layout == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS))
2727 elt = Dynarr_length (gbd) - 1;
2734 end = Dynarr_length (gbd);
2737 while (count && ((!reverse && elt < end) || (reverse && elt >= end)))
2739 struct glyph_block *gb = Dynarr_atp (gbd, elt);
2741 if (NILP (gb->extent))
2742 abort (); /* these should have been handled in add_glyph_rune */
2745 ((side == LEFT_GLYPHS &&
2746 extent_begin_glyph_layout (XEXTENT (gb->extent)) == layout)
2747 || (side == RIGHT_GLYPHS &&
2748 extent_end_glyph_layout (XEXTENT (gb->extent)) == layout)))
2752 rb.width = gb->width;
2753 rb.findex = gb->findex;
2757 rb.type = RUNE_DGLYPH;
2758 rb.object.dglyph.glyph = gb->glyph;
2759 rb.object.dglyph.extent = gb->extent;
2760 rb.object.dglyph.xoffset = 0;
2761 rb.cursor_type = CURSOR_OFF;
2763 Dynarr_add (db->runes, rb);
2768 if (glyph_contrib_p (gb->glyph, window))
2770 unsigned short ascent, descent;
2771 Lisp_Object baseline = glyph_baseline (gb->glyph, window);
2773 ascent = glyph_ascent (gb->glyph, window);
2774 descent = glyph_descent (gb->glyph, window);
2776 /* A pixmap that has not had a baseline explicitly set.
2777 We use the existing ascent / descent ratio of the
2779 if (NILP (baseline))
2781 int gheight = ascent + descent;
2782 int line_height = dl->ascent + dl->descent;
2783 int pix_ascent, pix_descent;
2785 pix_descent = (int) (gheight * dl->descent) / line_height;
2786 pix_ascent = gheight - pix_descent;
2788 dl->ascent = max ((int) dl->ascent, pix_ascent);
2789 dl->descent = max ((int) dl->descent, pix_descent);
2792 /* A string so determine contribution normally. */
2793 else if (EQ (baseline, Qt))
2795 dl->ascent = max (dl->ascent, ascent);
2796 dl->descent = max (dl->descent, descent);
2799 /* A pixmap with an explicitly set baseline. We determine the
2800 contribution here. */
2801 else if (INTP (baseline))
2803 int height = ascent + descent;
2804 int pix_ascent, pix_descent;
2806 pix_ascent = height * XINT (baseline) / 100;
2807 pix_descent = height - pix_ascent;
2809 dl->ascent = max ((int) dl->ascent, pix_ascent);
2810 dl->descent = max ((int) dl->descent, pix_descent);
2813 /* Otherwise something is screwed up. */
2819 (reverse ? elt-- : elt++);
2825 /* Add a blank to a margin display block. */
2828 add_margin_blank (struct display_line *dl, struct display_block *db,
2829 struct window *w, int xpos, int width, int side)
2833 rb.findex = (side == LEFT_GLYPHS
2834 ? get_builtin_face_cache_index (w, Vleft_margin_face)
2835 : get_builtin_face_cache_index (w, Vright_margin_face));
2840 rb.type = RUNE_BLANK;
2841 rb.cursor_type = CURSOR_OFF;
2843 Dynarr_add (db->runes, rb);
2846 /* Display glyphs in the left outside margin, left inside margin and
2847 left whitespace area. */
2850 create_left_glyph_block (struct window *w, struct display_line *dl,
2855 int use_overflow = (NILP (w->use_left_overflow) ? 0 : 1);
2857 int out_end, in_out_start, in_in_end, white_out_start, white_in_start;
2858 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
2859 int left_in_start = dl->bounds.left_in;
2860 int left_in_end = dl->bounds.left_in + overlay_width;
2862 struct display_block *odb, *idb;
2864 XSETWINDOW (window, w);
2866 /* We have to add the glyphs to the line in the order outside,
2867 inside, whitespace. However the precedence dictates that we
2868 determine how many will fit in the reverse order. */
2870 /* Determine how many whitespace glyphs we can display and where
2871 they should start. */
2872 white_in_start = dl->bounds.left_white;
2873 white_out_start = left_in_start;
2874 white_out_cnt = white_in_cnt = 0;
2877 while (elt < Dynarr_length (dl->left_glyphs))
2879 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2881 if (NILP (gb->extent))
2882 abort (); /* these should have been handled in add_glyph_rune */
2884 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
2888 width = glyph_width (gb->glyph, window);
2890 if (white_in_start - width >= left_in_end)
2893 white_in_start -= width;
2897 else if (use_overflow
2898 && (white_out_start - width > dl->bounds.left_out))
2901 white_out_start -= width;
2912 /* Determine how many inside margin glyphs we can display and where
2913 they should start. The inside margin glyphs get whatever space
2914 is left after the whitespace glyphs have been displayed. These
2915 are tricky to calculate since if we decide to use the overflow
2916 area we basically have to start over. So for these we build up a
2917 list of just the inside margin glyphs and manipulate it to
2918 determine the needed info. */
2920 glyph_block_dynarr *ib;
2921 int avail_in, avail_out;
2924 int used_in, used_out;
2927 used_in = used_out = 0;
2928 ib = Dynarr_new (glyph_block);
2929 while (elt < Dynarr_length (dl->left_glyphs))
2931 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2933 if (NILP (gb->extent))
2934 abort (); /* these should have been handled in add_glyph_rune */
2936 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
2939 gb->width = glyph_width (gb->glyph, window);
2940 used_in += gb->width;
2941 Dynarr_add (ib, *gb);
2951 avail_in = white_in_start - left_in_end;
2959 avail_out = white_out_start - dl->bounds.left_out;
2962 while (!done && marker < Dynarr_length (ib))
2964 int width = Dynarr_atp (ib, marker)->width;
2966 /* If everything now fits in the available inside margin
2967 space, we're done. */
2968 if (used_in <= avail_in)
2972 /* Otherwise see if we have room to move a glyph to the
2974 if (used_out + width <= avail_out)
2987 /* At this point we now know that everything from marker on goes in
2988 the inside margin and everything before it goes in the outside
2989 margin. The stuff going into the outside margin is guaranteed
2990 to fit, but we may have to trim some stuff from the inside. */
2992 in_in_end = left_in_end;
2993 in_out_start = white_out_start;
2994 in_out_cnt = in_in_cnt = 0;
2998 while (elt < Dynarr_length (dl->left_glyphs))
3000 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3002 if (NILP (gb->extent))
3003 abort (); /* these should have been handled in add_glyph_rune */
3005 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3008 int width = glyph_width (gb->glyph, window);
3013 in_out_start -= width;
3018 else if (in_in_end + width < white_in_start)
3033 /* Determine how many outside margin glyphs we can display. They
3034 always start at the left outside margin and can only use the
3035 outside margin space. */
3036 out_end = dl->bounds.left_out;
3040 while (elt < Dynarr_length (dl->left_glyphs))
3042 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3044 if (NILP (gb->extent))
3045 abort (); /* these should have been handled in add_glyph_rune */
3047 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3050 int width = glyph_width (gb->glyph, window);
3052 if (out_end + width <= in_out_start)
3066 /* Now that we know where everything goes, we add the glyphs as
3067 runes to the appropriate display blocks. */
3068 if (out_cnt || in_out_cnt || white_out_cnt)
3070 odb = get_display_block_from_line (dl, LEFT_OUTSIDE_MARGIN);
3071 odb->start_pos = dl->bounds.left_out;
3072 /* #### We should stop adding a blank to account for the space
3073 between the end of the glyphs and the margin and instead set
3074 this accordingly. */
3075 odb->end_pos = dl->bounds.left_in;
3076 Dynarr_reset (odb->runes);
3081 if (in_in_cnt || white_in_cnt)
3083 idb = get_display_block_from_line (dl, LEFT_INSIDE_MARGIN);
3084 idb->start_pos = dl->bounds.left_in;
3085 /* #### See above comment for odb->end_pos */
3086 idb->end_pos = dl->bounds.left_white;
3087 Dynarr_reset (idb->runes);
3092 /* First add the outside margin glyphs. */
3094 end_xpos = add_margin_runes (dl, odb, dl->bounds.left_out, out_cnt,
3095 GL_OUTSIDE_MARGIN, LEFT_GLYPHS, window);
3097 end_xpos = dl->bounds.left_out;
3099 /* There may be blank space between the outside margin glyphs and
3100 the inside margin glyphs. If so, add a blank. */
3101 if (in_out_cnt && (in_out_start - end_xpos))
3103 add_margin_blank (dl, odb, w, end_xpos, in_out_start - end_xpos,
3107 /* Next add the inside margin glyphs which are actually in the
3111 end_xpos = add_margin_runes (dl, odb, in_out_start, in_out_cnt,
3112 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3115 /* If we didn't add any inside margin glyphs to the outside margin,
3116 but are adding whitespace glyphs, then we need to add a blank
3118 if (!in_out_cnt && white_out_cnt && (white_out_start - end_xpos))
3120 add_margin_blank (dl, odb, w, end_xpos, white_out_start - end_xpos,
3124 /* Next add the whitespace margin glyphs which are actually in the
3128 end_xpos = add_margin_runes (dl, odb, white_out_start, white_out_cnt,
3129 GL_WHITESPACE, LEFT_GLYPHS, window);
3132 /* We take care of clearing between the end of the glyphs and the
3133 start of the inside margin for lines which have glyphs. */
3134 if (odb && (left_in_start - end_xpos))
3136 add_margin_blank (dl, odb, w, end_xpos, left_in_start - end_xpos,
3140 /* Next add the inside margin glyphs which are actually in the
3144 end_xpos = add_margin_runes (dl, idb, left_in_end, in_in_cnt,
3145 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3148 end_xpos = left_in_end;
3150 /* Make sure that the area between the end of the inside margin
3151 glyphs and the whitespace glyphs is cleared. */
3152 if (idb && (white_in_start - end_xpos > 0))
3154 add_margin_blank (dl, idb, w, end_xpos, white_in_start - end_xpos,
3158 /* Next add the whitespace margin glyphs which are actually in the
3162 add_margin_runes (dl, idb, white_in_start, white_in_cnt, GL_WHITESPACE,
3163 LEFT_GLYPHS, window);
3166 /* Whitespace glyphs always end right next to the text block so
3167 there is nothing we have to make sure is cleared after them. */
3170 /* Display glyphs in the right outside margin, right inside margin and
3171 right whitespace area. */
3174 create_right_glyph_block (struct window *w, struct display_line *dl)
3178 int use_overflow = (NILP (w->use_right_overflow) ? 0 : 1);
3180 int out_start, in_out_end, in_in_start, white_out_end, white_in_end;
3181 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
3183 struct display_block *odb, *idb;
3185 XSETWINDOW (window, w);
3187 /* We have to add the glyphs to the line in the order outside,
3188 inside, whitespace. However the precedence dictates that we
3189 determine how many will fit in the reverse order. */
3191 /* Determine how many whitespace glyphs we can display and where
3192 they should start. */
3193 white_in_end = dl->bounds.right_white;
3194 white_out_end = dl->bounds.right_in;
3195 white_out_cnt = white_in_cnt = 0;
3198 while (elt < Dynarr_length (dl->right_glyphs))
3200 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3202 if (NILP (gb->extent))
3203 abort (); /* these should have been handled in add_glyph_rune */
3205 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
3207 int width = glyph_width (gb->glyph, window);
3209 if (white_in_end + width <= dl->bounds.right_in)
3212 white_in_end += width;
3216 else if (use_overflow
3217 && (white_out_end + width <= dl->bounds.right_out))
3220 white_out_end += width;
3231 /* Determine how many inside margin glyphs we can display and where
3232 they should start. The inside margin glyphs get whatever space
3233 is left after the whitespace glyphs have been displayed. These
3234 are tricky to calculate since if we decide to use the overflow
3235 area we basically have to start over. So for these we build up a
3236 list of just the inside margin glyphs and manipulate it to
3237 determine the needed info. */
3239 glyph_block_dynarr *ib;
3240 int avail_in, avail_out;
3243 int used_in, used_out;
3246 used_in = used_out = 0;
3247 ib = Dynarr_new (glyph_block);
3248 while (elt < Dynarr_length (dl->right_glyphs))
3250 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3252 if (NILP (gb->extent))
3253 abort (); /* these should have been handled in add_glyph_rune */
3255 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3257 gb->width = glyph_width (gb->glyph, window);
3258 used_in += gb->width;
3259 Dynarr_add (ib, *gb);
3268 avail_in = dl->bounds.right_in - white_in_end;
3273 avail_out = dl->bounds.right_out - white_out_end;
3276 while (!done && marker < Dynarr_length (ib))
3278 int width = Dynarr_atp (ib, marker)->width;
3280 /* If everything now fits in the available inside margin
3281 space, we're done. */
3282 if (used_in <= avail_in)
3286 /* Otherwise see if we have room to move a glyph to the
3288 if (used_out + width <= avail_out)
3301 /* At this point we now know that everything from marker on goes in
3302 the inside margin and everything before it goes in the outside
3303 margin. The stuff going into the outside margin is guaranteed
3304 to fit, but we may have to trim some stuff from the inside. */
3306 in_in_start = dl->bounds.right_in;
3307 in_out_end = dl->bounds.right_in;
3308 in_out_cnt = in_in_cnt = 0;
3312 while (elt < Dynarr_length (dl->right_glyphs))
3314 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3316 if (NILP (gb->extent))
3317 abort (); /* these should have been handled in add_glyph_rune */
3319 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3321 int width = glyph_width (gb->glyph, window);
3326 in_out_end += width;
3331 else if (in_in_start - width >= white_in_end)
3334 in_in_start -= width;
3346 /* Determine how many outside margin glyphs we can display. They
3347 always start at the right outside margin and can only use the
3348 outside margin space. */
3349 out_start = dl->bounds.right_out;
3353 while (elt < Dynarr_length (dl->right_glyphs))
3355 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3357 if (NILP (gb->extent))
3358 abort (); /* these should have been handled in add_glyph_rune */
3360 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_OUTSIDE_MARGIN)
3362 int width = glyph_width (gb->glyph, window);
3364 if (out_start - width >= in_out_end)
3378 /* Now that we now where everything goes, we add the glyphs as runes
3379 to the appropriate display blocks. */
3380 if (out_cnt || in_out_cnt || white_out_cnt)
3382 odb = get_display_block_from_line (dl, RIGHT_OUTSIDE_MARGIN);
3383 /* #### See comments before odb->start_pos init in
3384 create_left_glyph_block */
3385 odb->start_pos = dl->bounds.right_in;
3386 odb->end_pos = dl->bounds.right_out;
3387 Dynarr_reset (odb->runes);
3392 if (in_in_cnt || white_in_cnt)
3394 idb = get_display_block_from_line (dl, RIGHT_INSIDE_MARGIN);
3395 idb->start_pos = dl->bounds.right_white;
3396 /* #### See comments before odb->start_pos init in
3397 create_left_glyph_block */
3398 idb->end_pos = dl->bounds.right_in;
3399 Dynarr_reset (idb->runes);
3404 /* First add the whitespace margin glyphs which are actually in the
3408 end_xpos = add_margin_runes (dl, idb, dl->bounds.right_white,
3409 white_in_cnt, GL_WHITESPACE, RIGHT_GLYPHS,
3413 end_xpos = dl->bounds.right_white;
3415 /* Make sure that the area between the end of the whitespace glyphs
3416 and the inside margin glyphs is cleared. */
3417 if (in_in_cnt && (in_in_start - end_xpos))
3419 add_margin_blank (dl, idb, w, end_xpos, in_in_start - end_xpos,
3423 /* Next add the inside margin glyphs which are actually in the
3427 end_xpos = add_margin_runes (dl, idb, in_in_start, in_in_cnt,
3428 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3431 /* If we didn't add any inside margin glyphs then make sure the rest
3432 of the inside margin area gets cleared. */
3433 if (idb && (dl->bounds.right_in - end_xpos))
3435 add_margin_blank (dl, idb, w, end_xpos, dl->bounds.right_in - end_xpos,
3439 /* Next add any whitespace glyphs in the outside margin. */
3442 end_xpos = add_margin_runes (dl, odb, dl->bounds.right_in, white_out_cnt,
3443 GL_WHITESPACE, RIGHT_GLYPHS, window);
3446 end_xpos = dl->bounds.right_in;
3448 /* Next add any inside margin glyphs in the outside margin. */
3451 end_xpos = add_margin_runes (dl, odb, end_xpos, in_out_cnt,
3452 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3455 /* There may be space between any whitespace or inside margin glyphs
3456 in the outside margin and the actual outside margin glyphs. */
3457 if (odb && (out_start - end_xpos))
3459 add_margin_blank (dl, odb, w, end_xpos, out_start - end_xpos,
3463 /* Finally, add the outside margin glyphs. */
3466 add_margin_runes (dl, odb, out_start, out_cnt, GL_OUTSIDE_MARGIN,
3467 RIGHT_GLYPHS, window);
3472 /***************************************************************************/
3474 /* modeline routines */
3476 /***************************************************************************/
3478 /* This function is also used in frame.c by `generate_title_string' */
3480 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str,
3481 struct window *w, struct display_line *dl,
3482 struct display_block *db, face_index findex,
3483 int min_pixpos, int max_pixpos, int type)
3485 struct frame *f = XFRAME (w->frame);
3486 struct device *d = XDEVICE (f->device);
3490 Charcount offset = 0;
3496 data.findex = findex;
3497 data.pixpos = min_pixpos;
3498 data.max_pixpos = max_pixpos;
3499 data.cursor_type = NO_CURSOR;
3500 data.last_charset = Qunbound;
3501 data.last_findex = DEFAULT_INDEX;
3502 data.result_str = result_str;
3503 data.is_modeline = 1;
3505 XSETWINDOW (data.window, w);
3507 Dynarr_reset (formatted_string_extent_dynarr);
3508 Dynarr_reset (formatted_string_extent_start_dynarr);
3509 Dynarr_reset (formatted_string_extent_end_dynarr);
3511 /* result_str is nil when we're building a frame or icon title. Otherwise,
3512 we're building a modeline, so the offset starts at the modeline
3513 horizontal scrolling ammount */
3514 if (! NILP (result_str))
3515 offset = w->modeline_hscroll;
3516 generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0,
3517 max_pixpos - min_pixpos, findex, type, &offset,
3520 if (Dynarr_length (db->runes))
3523 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
3524 c_pixpos = rb->xpos + rb->width;
3527 c_pixpos = min_pixpos;
3529 /* If we don't reach the right side of the window, add a blank rune
3530 to make up the difference. This usually only occurs if the
3531 modeline face is using a proportional width font or a fixed width
3532 font of a different size from the default face font. */
3534 if (c_pixpos < max_pixpos)
3536 data.pixpos = c_pixpos;
3537 data.blank_width = max_pixpos - data.pixpos;
3539 add_blank_rune (&data, NULL, 0);
3542 /* Now create the result string and frob the extents into it. */
3543 if (!NILP (result_str))
3548 struct buffer *buf = XBUFFER (WINDOW_BUFFER (w));
3550 detach_all_extents (result_str);
3551 resize_string (XSTRING (result_str), -1,
3552 data.bytepos - XSTRING_LENGTH (result_str));
3554 strdata = XSTRING_DATA (result_str);
3556 for (elt = 0, len = 0; elt < Dynarr_length (db->runes); elt++)
3558 if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR)
3560 len += (set_charptr_emchar
3561 (strdata + len, Dynarr_atp (db->runes,
3562 elt)->object.chr.ch));
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),
3589 /* Ensure that the given display line DL accurately represents the
3590 modeline for the given window. */
3592 generate_modeline (struct window *w, struct display_line *dl, int type)
3594 struct buffer *b = XBUFFER (w->buffer);
3595 struct frame *f = XFRAME (w->frame);
3596 struct device *d = XDEVICE (f->device);
3598 /* Unlike display line and rune pointers, this one can't change underneath
3600 struct display_block *db = get_display_block_from_line (dl, TEXT);
3601 int max_pixpos, min_pixpos, ypos_adj;
3602 Lisp_Object font_inst;
3604 /* This will actually determine incorrect inside boundaries for the
3605 modeline since it ignores the margins. However being aware of this fact
3606 we never use those values anywhere so it doesn't matter. */
3607 dl->bounds = calculate_display_line_boundaries (w, 1);
3609 /* We are generating a modeline. */
3611 dl->cursor_elt = -1;
3613 /* Reset the runes on the modeline. */
3614 Dynarr_reset (db->runes);
3616 if (!WINDOW_HAS_MODELINE_P (w))
3620 /* If there is a horizontal scrollbar, don't add anything. */
3621 if (window_scrollbar_height (w))
3624 dl->ascent = DEVMETH (d, divider_height, ());
3626 /* The modeline is at the bottom of the gutters. */
3627 dl->ypos = WINDOW_BOTTOM (w);
3629 /* adjust for the bottom gutter */
3630 if (window_is_lowest (w))
3631 dl->ypos -= FRAME_BOTTOM_GUTTER_BOUNDS (f);
3633 rb.findex = MODELINE_INDEX;
3634 rb.xpos = dl->bounds.left_out;
3635 rb.width = dl->bounds.right_out - dl->bounds.left_out;
3638 rb.type = RUNE_HLINE;
3639 rb.object.hline.thickness = 1;
3640 rb.object.hline.yoffset = 0;
3641 rb.cursor_type = NO_CURSOR;
3643 if (!EQ (Qzero, w->modeline_shadow_thickness)
3646 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3648 dl->ypos -= shadow_thickness;
3649 rb.xpos += shadow_thickness;
3650 rb.width -= 2 * shadow_thickness;
3653 Dynarr_add (db->runes, rb);
3657 /* !!#### not right; needs to compute the max height of
3659 font_inst = WINDOW_FACE_CACHEL_FONT (w, MODELINE_INDEX, Vcharset_ascii);
3661 dl->ascent = XFONT_INSTANCE (font_inst)->ascent;
3662 dl->descent = XFONT_INSTANCE (font_inst)->descent;
3664 min_pixpos = dl->bounds.left_out;
3665 max_pixpos = dl->bounds.right_out;
3667 if (!EQ (Qzero, w->modeline_shadow_thickness) && FRAME_WIN_P (f))
3669 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3671 ypos_adj = shadow_thickness;
3672 min_pixpos += shadow_thickness;
3673 max_pixpos -= shadow_thickness;
3678 generate_formatted_string_db (b->modeline_format,
3679 b->generated_modeline_string, w, dl, db,
3680 MODELINE_INDEX, min_pixpos, max_pixpos, type);
3682 /* The modeline is at the bottom of the gutters. We have to wait to
3683 set this until we've generated the modeline in order to account
3684 for any embedded faces. */
3685 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj;
3686 /* adjust for the bottom gutter */
3687 if (window_is_lowest (w))
3688 dl->ypos -= FRAME_BOTTOM_GUTTER_BOUNDS (f);
3692 add_string_to_fstring_db_runes (pos_data *data, CONST Bufbyte *str,
3693 Charcount pos, Charcount min_pos, Charcount max_pos)
3695 /* This function has been Mule-ized. */
3697 CONST Bufbyte *cur_pos = str;
3698 struct display_block *db = data->db;
3700 data->blank_width = space_width (XWINDOW (data->window));
3701 while (Dynarr_length (db->runes) < pos)
3702 add_blank_rune (data, NULL, 0);
3704 end = (Dynarr_length (db->runes) +
3705 bytecount_to_charcount (str, strlen ((CONST char *) str)));
3707 end = min (max_pos, end);
3709 while (pos < end && *cur_pos)
3711 CONST Bufbyte *old_cur_pos = cur_pos;
3714 data->ch = charptr_emchar (cur_pos);
3715 succeeded = (add_emchar_rune (data) != ADD_FAILED);
3716 INC_CHARPTR (cur_pos);
3720 data->modeline_charpos++;
3721 data->bytepos += cur_pos - old_cur_pos;
3725 while (Dynarr_length (db->runes) < min_pos &&
3726 (data->pixpos + data->blank_width <= data->max_pixpos))
3727 add_blank_rune (data, NULL, 0);
3729 return Dynarr_length (db->runes);
3732 /* #### Urk! Should also handle begin-glyphs and end-glyphs in
3733 modeline extents. */
3735 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph,
3736 Charcount pos, Charcount min_pos,
3737 Charcount max_pos, Lisp_Object extent)
3739 /* This function has been Mule-ized. */
3741 struct display_block *db = data->db;
3742 struct glyph_block gb;
3744 data->blank_width = space_width (XWINDOW (data->window));
3745 while (Dynarr_length (db->runes) < pos)
3746 add_blank_rune (data, NULL, 0);
3748 end = Dynarr_length (db->runes) + 1;
3750 end = min (max_pos, end);
3754 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
3757 while (Dynarr_length (db->runes) < pos &&
3758 (data->pixpos + data->blank_width <= data->max_pixpos))
3759 add_blank_rune (data, NULL, 0);
3761 return Dynarr_length (db->runes);
3764 /* If max_pos is == -1, it is considered to be infinite. The same is
3765 true of max_pixsize. */
3766 #define SET_CURRENT_MODE_CHARS_PIXSIZE \
3767 if (Dynarr_length (data->db->runes)) \
3768 cur_pixsize = data->pixpos - Dynarr_atp (data->db->runes, 0)->xpos; \
3772 /* Note that this function does "positions" in terms of characters and
3773 not in terms of columns. This is necessary to make the formatting
3774 work correctly when proportional width fonts are used in the
3777 generate_fstring_runes (struct window *w, pos_data *data, Charcount pos,
3778 Charcount min_pos, Charcount max_pos,
3779 Lisp_Object elt, int depth, int max_pixsize,
3780 face_index findex, int type, Charcount *offset,
3781 Lisp_Object cur_ext)
3783 /* This function has been Mule-ized. */
3784 /* #### The other losing things in this function are:
3786 -- C zero-terminated-string lossage.
3787 -- Non-printable characters should be converted into something
3788 appropriate (e.g. ^F) instead of blindly being printed anyway.
3799 /* A string. Add to the display line and check for %-constructs
3802 Bufbyte *this = XSTRING_DATA (elt);
3804 while ((pos < max_pos || max_pos == -1) && *this)
3806 Bufbyte *last = this;
3808 while (*this && *this != '%')
3813 /* No %-construct */
3815 bytecount_to_charcount (last, this - last);
3817 if (size <= *offset)
3821 Charcount tmp_max = (max_pos == -1 ? pos + size - *offset :
3822 min (pos + size - *offset, max_pos));
3823 CONST Bufbyte *tmp_last = charptr_n_addr (last, *offset);
3825 pos = add_string_to_fstring_db_runes (data, tmp_last,
3830 else /* *this == '%' */
3832 Charcount spec_width = 0;
3834 this++; /* skip over '%' */
3836 /* We can't allow -ve args due to the "%-" construct.
3837 * Argument specifies minwidth but not maxwidth
3838 * (maxwidth can be specified by
3839 * (<negative-number> . <stuff>) modeline elements)
3841 while (isdigit (*this))
3843 spec_width = spec_width * 10 + (*this - '0');
3850 pos = generate_fstring_runes (w, data, pos, spec_width,
3851 max_pos, Vglobal_mode_string,
3852 depth, max_pixsize, findex,
3853 type, offset, cur_ext);
3855 else if (*this == '-')
3857 Charcount num_to_add;
3859 if (max_pixsize < 0)
3861 else if (max_pos != -1)
3862 num_to_add = max_pos - pos;
3868 SET_CURRENT_MODE_CHARS_PIXSIZE;
3871 redisplay_text_width_string (w, findex, &ch, Qnil, 0,
3874 num_to_add = (max_pixsize - cur_pixsize) / dash_pixsize;
3878 while (num_to_add--)
3879 pos = add_string_to_fstring_db_runes
3880 (data, (CONST Bufbyte *) "-", pos, pos, max_pos);
3882 else if (*this != 0)
3884 Emchar ch = charptr_emchar (this);
3888 decode_mode_spec (w, ch, type);
3890 str = Dynarr_atp (mode_spec_bufbyte_string, 0);
3891 size = bytecount_to_charcount
3892 /* Skip the null character added by `decode_mode_spec' */
3893 (str, Dynarr_length (mode_spec_bufbyte_string)) - 1;
3895 if (size <= *offset)
3899 CONST Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3901 /* #### NOTE: I don't understand why a tmp_max is not
3902 computed and used here as in the plain string case
3904 pos = add_string_to_fstring_db_runes (data, tmp_str,
3911 /* NOT this++. There could be any sort of character at
3912 the current position. */
3916 if (max_pixsize > 0)
3919 SET_CURRENT_MODE_CHARS_PIXSIZE;
3921 if (cur_pixsize >= max_pixsize)
3926 else if (SYMBOLP (elt))
3928 /* A symbol: process the value of the symbol recursively
3929 as if it appeared here directly. */
3930 Lisp_Object tem = symbol_value_in_buffer (elt, w->buffer);
3932 if (!UNBOUNDP (tem))
3934 /* If value is a string, output that string literally:
3935 don't check for % within it. */
3938 Bufbyte *str = XSTRING_DATA (tem);
3939 Charcount size = XSTRING_CHAR_LENGTH (tem);
3941 if (size <= *offset)
3945 CONST Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3947 /* #### NOTE: I don't understand why a tmp_max is not
3948 computed and used here as in the plain string case
3950 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
3955 /* Give up right away for nil or t. */
3956 else if (!EQ (tem, elt))
3963 else if (GENERIC_SPECIFIERP (elt))
3965 Lisp_Object window, tem;
3966 XSETWINDOW (window, w);
3967 tem = specifier_instance_no_quit (elt, Qunbound, window,
3968 ERROR_ME_NOT, 0, Qzero);
3969 if (!UNBOUNDP (tem))
3975 else if (CONSP (elt))
3977 /* A cons cell: four distinct cases.
3978 * - If first element is a string or a cons, process all the elements
3979 * and effectively concatenate them.
3980 * - If first element is a negative number, truncate displaying cdr to
3981 * at most that many characters. If positive, pad (with spaces)
3982 * to at least that many characters.
3983 * - If first element is another symbol, process the cadr or caddr
3984 * recursively according to whether the symbol's value is non-nil or
3986 * - If first element is a face, process the cdr recursively
3987 * without altering the depth.
3990 Lisp_Object car, tem;
3999 tem = symbol_value_in_buffer (car, w->buffer);
4000 /* elt is now the cdr, and we know it is a cons cell.
4001 Use its car if CAR has a non-nil value. */
4002 if (!UNBOUNDP (tem))
4010 /* Symbol's value is nil (or symbol is unbound)
4011 * Get the cddr of the original list
4012 * and if possible find the caddr and use that.
4017 else if (!CONSP (elt))
4025 else if (INTP (car))
4027 Charcount lim = XINT (car);
4033 /* Negative int means reduce maximum width.
4034 * DO NOT change MIN_PIXPOS here!
4035 * (20 -10 . foo) should truncate foo to 10 col
4036 * and then pad to 20.
4039 max_pos = pos - lim;
4041 max_pos = min (max_pos, pos - lim);
4045 /* Padding specified. Don't let it be more than
4049 if (max_pos != -1 && lim > max_pos)
4051 /* If that's more padding than already wanted, queue it.
4052 * But don't reduce padding already specified even if
4053 * that is beyond the current truncation point.
4060 else if (STRINGP (car) || CONSP (car))
4064 /* LIMIT is to protect against circular lists. */
4065 while (CONSP (elt) && --limit > 0
4066 && (pos < max_pos || max_pos == -1))
4068 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4069 XCAR (elt), depth, max_pixsize,
4070 findex, type, offset, cur_ext);
4074 else if (EXTENTP (car))
4076 struct extent *ext = XEXTENT (car);
4078 if (EXTENT_LIVE_P (ext))
4080 face_index old_findex = data->findex;
4082 Lisp_Object font_inst;
4083 face_index new_findex;
4084 Bytecount start = data->bytepos;
4086 face = extent_face (ext);
4089 /* #### needs to merge faces, sigh */
4090 /* #### needs to handle list of faces */
4091 new_findex = get_builtin_face_cache_index (w, face);
4092 /* !!#### not right; needs to compute the max height of
4094 font_inst = WINDOW_FACE_CACHEL_FONT (w, new_findex,
4097 data->dl->ascent = max (data->dl->ascent,
4098 XFONT_INSTANCE (font_inst)->ascent);
4099 data->dl->descent = max (data->dl->descent,
4100 XFONT_INSTANCE (font_inst)->
4104 new_findex = old_findex;
4106 data->findex = new_findex;
4107 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4108 XCDR (elt), depth - 1,
4109 max_pixsize, new_findex, type,
4111 data->findex = old_findex;
4112 Dynarr_add (formatted_string_extent_dynarr, ext);
4113 Dynarr_add (formatted_string_extent_start_dynarr, start);
4114 Dynarr_add (formatted_string_extent_end_dynarr, data->bytepos);
4118 else if (GLYPHP (elt))
4120 /* Glyphs are considered as one character with respect to the modeline
4121 horizontal scrolling facility. -- dv */
4125 pos = add_glyph_to_fstring_db_runes (data, elt, pos, pos, max_pos,
4132 char *str = GETTEXT ("*invalid*");
4133 Charcount size = (Charcount) strlen (str); /* is this ok ?? -- dv */
4135 if (size <= *offset)
4139 CONST Bufbyte *tmp_str =
4140 charptr_n_addr ((CONST Bufbyte *) str, *offset);
4142 /* #### NOTE: I don't understand why a tmp_max is not computed and
4143 used here as in the plain string case above. -- dv */
4144 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
4153 add_string_to_fstring_db_runes (data, (CONST Bufbyte *) "", pos,
4160 /* Update just the modeline. Assumes the desired display structs. If
4161 they do not have a modeline block, it does nothing. */
4163 regenerate_modeline (struct window *w)
4165 display_line_dynarr *dla = window_display_lines (w, DESIRED_DISP);
4167 if (!Dynarr_length (dla) || !Dynarr_atp (dla, 0)->modeline)
4171 generate_modeline (w, Dynarr_atp (dla, 0), DESIRED_DISP);
4172 redisplay_update_line (w, 0, 0, 0);
4176 /* Make sure that modeline display line is present in the given
4177 display structs if the window has a modeline and update that
4178 line. Returns true if a modeline was needed. */
4180 ensure_modeline_generated (struct window *w, int type)
4184 /* minibuffer windows don't have modelines */
4185 if (MINI_WINDOW_P (w))
4187 /* windows which haven't had it turned off do */
4188 else if (WINDOW_HAS_MODELINE_P (w))
4190 /* windows which have it turned off don't have a divider if there is
4191 a horizontal scrollbar */
4192 else if (window_scrollbar_height (w))
4194 /* and in this case there is none */
4200 display_line_dynarr *dla;
4202 dla = window_display_lines (w, type);
4204 /* We don't care if there is a display line which is not
4205 currently a modeline because it is definitely going to become
4206 one if we have gotten to this point. */
4207 if (Dynarr_length (dla) == 0)
4209 if (Dynarr_largest (dla) > 0)
4211 struct display_line *mlp = Dynarr_atp (dla, 0);
4212 Dynarr_add (dla, *mlp);
4216 struct display_line modeline;
4218 Dynarr_add (dla, modeline);
4222 /* If we're adding a new place marker go ahead and generate the
4223 modeline so that it is available for use by
4224 window_modeline_height. */
4225 generate_modeline (w, Dynarr_atp (dla, 0), type);
4228 return need_modeline;
4231 /* #### Kludge or not a kludge. I tend towards the former. */
4233 real_current_modeline_height (struct window *w)
4235 Fset_marker (w->start[CMOTION_DISP], w->start[CURRENT_DISP], w->buffer);
4236 Fset_marker (w->pointm[CMOTION_DISP], w->pointm[CURRENT_DISP], w->buffer);
4238 if (ensure_modeline_generated (w, CMOTION_DISP))
4240 display_line_dynarr *dla = window_display_lines (w, CMOTION_DISP);
4242 if (Dynarr_length (dla))
4244 if (Dynarr_atp (dla, 0)->modeline)
4245 return (Dynarr_atp (dla, 0)->ascent +
4246 Dynarr_atp (dla, 0)->descent);
4253 /***************************************************************************/
4255 /* displayable string routines */
4257 /***************************************************************************/
4259 /* Given a position for a string in a window, ensure that the given
4260 display line DL accurately represents the text on a line starting
4261 at the given position.
4263 Yes, this is duplicating the code of create_text_block, but it
4264 looked just too hard to change create_text_block to handle strings
4265 *and* buffers. We already make a distinction between the two
4266 elsewhere in the code so I think unifying them would require a
4267 complete MULE rewrite. Besides, the other distinction is that these
4268 functions cover text that the user *cannot edit* so we can remove
4269 everything to do with cursors, minibuffers etc. Eventually the
4270 modeline routines should be modified to use this code as it copes
4271 with many more types of display situation. */
4274 create_string_text_block (struct window *w, Lisp_Object disp_string,
4275 struct display_line *dl,
4277 prop_block_dynarr **prop,
4278 face_index default_face)
4280 struct frame *f = XFRAME (w->frame);
4281 /* Note that a lot of the buffer controlled stuff has been left in
4282 because you might well want to make use of it (selective display
4283 etc), its just the buffer text that we do not use. However, it
4284 seems to be possible for buffer to be nil sometimes so protect
4285 against this case. */
4286 struct buffer *b = BUFFERP (w->buffer) ? XBUFFER (w->buffer) : 0;
4287 struct device *d = XDEVICE (f->device);
4288 Lisp_String* s = XSTRING (disp_string);
4290 /* we're working with these a lot so precalculate them */
4291 Bytecount slen = XSTRING_LENGTH (disp_string);
4292 Bytecount bi_string_zv = slen;
4293 Bytind bi_start_pos = charcount_to_bytecount (string_data (s), start_pos);
4297 int truncate_win = b ? window_truncation_on (w) : 0;
4298 int end_glyph_width = 0;
4300 /* we're going to ditch selective display for static text, its an
4301 FSF thing and invisble extents are the way to go
4302 here. Implementing it also relies on a number of buffer-specific
4303 functions that we don't have the luxury of being able to use
4306 /* The variable ctl-arrow allows the user to specify what characters
4307 can actually be displayed and which octal should be used for.
4308 #### This variable should probably have some rethought done to
4311 #### It would also be really nice if you could specify that
4312 the characters come out in hex instead of in octal. Mule
4313 does that by adding a ctl-hexa variable similar to ctl-arrow,
4314 but that's bogus -- we need a more general solution. I
4315 think you need to extend the concept of display tables
4316 into a more general conversion mechanism. Ideally you
4317 could specify a Lisp function that converts characters,
4318 but this violates the Second Golden Rule and besides would
4319 make things way way way way slow.
4321 So instead, we extend the display-table concept, which was
4322 historically limited to 256-byte vectors, to one of the
4325 a) A 256-entry vector, for backward compatibility;
4326 b) char-table, mapping characters to values;
4327 c) range-table, mapping ranges of characters to values;
4328 d) a list of the above.
4330 The (d) option allows you to specify multiple display tables
4331 instead of just one. Each display table can specify conversions
4332 for some characters and leave others unchanged. The way the
4333 character gets displayed is determined by the first display table
4334 with a binding for that character. This way, you could call a
4335 function `enable-hex-display' that adds a hex display-table to
4336 the list of display tables for the current buffer.
4338 #### ...not yet implemented... Also, we extend the concept of
4339 "mapping" to include a printf-like spec. Thus you can make all
4340 extended characters show up as hex with a display table like
4343 #s(range-table data ((256 524288) (format "%x")))
4345 Since more than one display table is possible, you have
4346 great flexibility in mapping ranges of characters. */
4347 Emchar printable_min = b ? (CHAR_OR_CHAR_INTP (b->ctl_arrow)
4348 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
4349 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
4350 ? 255 : 160)) : 255;
4352 Lisp_Object face_dt, window_dt;
4354 /* The text display block for this display line. */
4355 struct display_block *db = get_display_block_from_line (dl, TEXT);
4357 /* The first time through the main loop we need to force the glyph
4358 data to be updated. */
4361 /* Apparently the new extent_fragment_update returns an end position
4362 equal to the position passed in if there are no more runs to be
4364 int no_more_frags = 0;
4366 dl->used_prop_data = 0;
4369 /* set up faces to use for clearing areas, used by
4370 output_display_line */
4371 dl->default_findex = default_face;
4374 dl->left_margin_findex = default_face;
4375 dl->right_margin_findex = default_face;
4379 dl->left_margin_findex =
4380 get_builtin_face_cache_index (w, Vleft_margin_face);
4381 dl->right_margin_findex =
4382 get_builtin_face_cache_index (w, Vright_margin_face);
4386 data.ef = extent_fragment_new (disp_string, f);
4388 /* These values are used by all of the rune addition routines. We add
4389 them to this structure for ease of passing. */
4391 XSETWINDOW (data.window, w);
4395 data.bi_bufpos = bi_start_pos;
4396 data.pixpos = dl->bounds.left_in;
4397 data.last_charset = Qunbound;
4398 data.last_findex = default_face;
4399 data.result_str = Qnil;
4400 data.string = disp_string;
4402 /* Set the right boundary adjusting it to take into account any end
4403 glyph. Save the width of the end glyph for later use. */
4404 data.max_pixpos = dl->bounds.right_in;
4407 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
4409 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
4411 data.max_pixpos -= end_glyph_width;
4413 data.cursor_type = NO_CURSOR;
4417 /* I don't think we want this, string areas should not scroll with
4419 data.start_col = w->hscroll;
4420 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
4422 data.bi_start_col_enabled = 0;
4423 data.hscroll_glyph_width_adjust = 0;
4425 /* We regenerate the line from the very beginning. */
4426 Dynarr_reset (db->runes);
4428 /* Why is this less than or equal and not just less than? If the
4429 starting position is already equal to the maximum we can't add
4430 anything else, right? Wrong. We might still have a newline to
4431 add. A newline can use the room allocated for an end glyph since
4432 if we add it we know we aren't going to be adding any end
4435 /* #### Chuck -- I think this condition should be while (1).
4436 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
4437 and the begin-glyph ends exactly at the end of the window, the
4438 end-glyph and text might not be displayed. while (1) ensures
4439 that the loop terminates only when either (a) there is
4440 propagation data or (b) the end-of-line or end-of-buffer is hit.
4442 #### Also I think you need to ensure that the operation
4443 "add begin glyphs; add end glyphs; add text" is atomic and
4444 can't get interrupted in the middle. If you run off the end
4445 of the line during that operation, then you keep accumulating
4446 propagation data until you're done. Otherwise, if the (e.g.)
4447 there's a begin glyph at a particular position and attempting
4448 to display that glyph results in window-end being hit and
4449 propagation data being generated, then the character at that
4450 position won't be displayed.
4452 #### See also the comment after the end of this loop, below.
4454 while (data.pixpos <= data.max_pixpos)
4456 /* #### This check probably should not be necessary. */
4457 if (data.bi_bufpos > bi_string_zv)
4459 /* #### urk! More of this lossage! */
4464 /* Check for face changes. */
4465 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
4467 /* Now compute the face and begin/end-glyph information. */
4469 /* Remember that the extent-fragment routines deal in Bytind's. */
4470 extent_fragment_update (w, data.ef, data.bi_bufpos);
4471 /* This is somewhat cheesy but the alternative is to
4472 propagate default_face into extent_fragment_update. */
4473 if (data.findex == DEFAULT_INDEX)
4474 data.findex = default_face;
4476 get_display_tables (w, data.findex, &face_dt, &window_dt);
4478 if (data.bi_bufpos == data.ef->end)
4483 /* Determine what is next to be displayed. We first handle any
4484 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
4485 display then we determine what to do based on the character at the
4486 current buffer position. */
4488 /* If the current position is covered by an invisible extent, do
4489 nothing (except maybe add some ellipses).
4491 #### The behavior of begin and end-glyphs at the edge of an
4492 invisible extent should be investigated further. This is
4493 fairly low priority though. */
4494 if (data.ef->invisible)
4496 /* #### Chuck, perhaps you could look at this code? I don't
4497 really know what I'm doing. */
4500 Dynarr_free (*prop);
4504 /* The extent fragment code only sets this when we should
4505 really display the ellipses. It makes sure the ellipses
4506 don't get displayed more than once in a row. */
4507 if (data.ef->invisible_ellipses)
4509 struct glyph_block gb;
4511 data.ef->invisible_ellipses_already_displayed = 1;
4512 data.ef->invisible_ellipses = 0;
4514 gb.glyph = Vinvisible_text_glyph;
4515 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
4516 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
4517 /* Perhaps they shouldn't propagate if the very next thing
4518 is to display a newline (for compatibility with
4519 selective-display-ellipses)? Maybe that's too
4525 /* #### What if we we're dealing with a display table? */
4529 if (data.bi_bufpos == bi_string_zv)
4532 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4535 /* If there is propagation data, then it represents the current
4536 buffer position being displayed. Add them and advance the
4537 position counter. This might also add the minibuffer
4541 dl->used_prop_data = 1;
4542 *prop = add_propagation_runes (prop, &data);
4545 goto done; /* gee, a really narrow window */
4546 else if (data.bi_bufpos == bi_string_zv)
4548 else if (data.bi_bufpos < 0)
4549 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
4552 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4555 /* If there are end glyphs, add them to the line. These are
4556 the end glyphs for the previous run of text. We add them
4557 here rather than doing them at the end of handling the
4558 previous run so that glyphs at the beginning and end of
4559 a line are handled correctly. */
4560 else if (Dynarr_length (data.ef->end_glyphs) > 0)
4562 *prop = add_glyph_runes (&data, END_GLYPHS);
4567 /* If there are begin glyphs, add them to the line. */
4568 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
4570 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
4575 /* If at end-of-buffer, we've already processed begin and
4576 end-glyphs at this point and there's no text to process,
4578 else if (data.bi_bufpos == bi_string_zv)
4583 Lisp_Object entry = Qnil;
4584 /* Get the character at the current buffer position. */
4585 data.ch = string_char (s, data.bi_bufpos);
4586 if (!NILP (face_dt) || !NILP (window_dt))
4587 entry = display_table_entry (data.ch, face_dt, window_dt);
4589 /* If there is a display table entry for it, hand it off to
4590 add_disp_table_entry_runes and let it worry about it. */
4591 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
4593 *prop = add_disp_table_entry_runes (&data, entry);
4599 /* Check if we have hit a newline character. If so, add a marker
4600 to the line and end this loop. */
4601 else if (data.ch == '\n')
4603 /* We aren't going to be adding an end glyph so give its
4604 space back in order to make sure that the cursor can
4606 data.max_pixpos += end_glyph_width;
4610 /* If the current character is considered to be printable, then
4612 else if (data.ch >= printable_min)
4614 *prop = add_emchar_rune (&data);
4619 /* If the current character is a tab, determine the next tab
4620 starting position and add a blank rune which extends from the
4621 current pixel position to that starting position. */
4622 else if (data.ch == '\t')
4624 int tab_start_pixpos = data.pixpos;
4629 if (data.start_col > 1)
4630 tab_start_pixpos -= (space_width (w) * (data.start_col - 1));
4633 next_tab_position (w, tab_start_pixpos,
4634 dl->bounds.left_in +
4635 data.hscroll_glyph_width_adjust);
4636 if (next_tab_start > data.max_pixpos)
4638 prop_width = next_tab_start - data.max_pixpos;
4639 next_tab_start = data.max_pixpos;
4641 data.blank_width = next_tab_start - data.pixpos;
4643 (next_tab_start - tab_start_pixpos) / space_width (w);
4645 *prop = add_blank_rune (&data, w, char_tab_width);
4647 /* add_blank_rune is only supposed to be called with
4648 sizes guaranteed to fit in the available space. */
4653 struct prop_block pb;
4654 *prop = Dynarr_new (prop_block);
4656 pb.type = PROP_BLANK;
4657 pb.data.p_blank.width = prop_width;
4658 pb.data.p_blank.findex = data.findex;
4659 Dynarr_add (*prop, pb);
4665 /* If character is a control character, pass it off to
4666 add_control_char_runes.
4668 The is_*() routines have undefined results on
4669 arguments outside of the range [-1, 255]. (This
4670 often bites people who carelessly use `char' instead
4671 of `unsigned char'.)
4673 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
4675 *prop = add_control_char_runes (&data, b);
4681 /* If the character is above the ASCII range and we have not
4682 already handled it, then print it as an octal number. */
4683 else if (data.ch >= 0200)
4685 *prop = add_octal_runes (&data);
4691 /* Assume the current character is considered to be printable,
4692 then just add it. */
4695 *prop = add_emchar_rune (&data);
4700 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4706 /* Determine the starting point of the next line if we did not hit the
4707 end of the buffer. */
4708 if (data.bi_bufpos < bi_string_zv)
4710 /* #### This check is not correct. If the line terminated
4711 due to a begin-glyph or end-glyph hitting window-end, then
4712 data.ch will not point to the character at data.bi_bufpos. If
4713 you make the two changes mentioned at the top of this loop,
4714 you should be able to say '(if (*prop))'. That should also
4715 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
4718 /* The common case is that the line ended because we hit a newline.
4719 In that case, the next character is just the next buffer
4721 if (data.ch == '\n')
4723 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4726 /* Otherwise we have a buffer line which cannot fit on one display
4730 struct glyph_block gb;
4731 struct glyph_cachel *cachel;
4733 /* If the line is to be truncated then we actually have to look
4734 for the next newline. We also add the end-of-line glyph which
4735 we know will fit because we adjusted the right border before
4736 we starting laying out the line. */
4737 data.max_pixpos += end_glyph_width;
4738 data.findex = default_face;
4745 /* Now find the start of the next line. */
4746 bi_pos = bi_find_next_emchar_in_string (s, '\n', data.bi_bufpos, 1);
4748 data.cursor_type = NO_CURSOR;
4749 data.bi_bufpos = bi_pos;
4750 gb.glyph = Vtruncation_glyph;
4751 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
4755 /* The cursor can never be on the continuation glyph. */
4756 data.cursor_type = NO_CURSOR;
4758 /* data.bi_bufpos is already at the start of the next line. */
4760 gb.glyph = Vcontinuation_glyph;
4761 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
4764 if (end_glyph_width)
4765 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
4767 if (truncate_win && data.bi_bufpos == bi_string_zv)
4769 CONST Bufbyte* endb = charptr_n_addr (string_data (s), bi_string_zv);
4771 if (charptr_emchar (endb) != '\n')
4773 /* #### Damn this losing shit. */
4779 else if (data.bi_bufpos == bi_string_zv)
4781 /* create_text_block () adds a bogus \n marker here which screws
4782 up subwindow display. Since we never have a cursor in the
4783 gutter we can safely ignore it. */
4785 /* Calculate left whitespace boundary. */
4789 /* Whitespace past a newline is considered right whitespace. */
4790 while (elt < Dynarr_length (db->runes))
4792 struct rune *rb = Dynarr_atp (db->runes, elt);
4794 if ((rb->type == RUNE_CHAR && rb->object.chr.ch == ' ')
4795 || rb->type == RUNE_BLANK)
4797 dl->bounds.left_white += rb->width;
4801 elt = Dynarr_length (db->runes);
4805 /* Calculate right whitespace boundary. */
4807 int elt = Dynarr_length (db->runes) - 1;
4810 while (!done && elt >= 0)
4812 struct rune *rb = Dynarr_atp (db->runes, elt);
4814 if (!(rb->type == RUNE_CHAR && rb->object.chr.ch < 0x100
4815 && isspace (rb->object.chr.ch))
4816 && !rb->type == RUNE_BLANK)
4818 dl->bounds.right_white = rb->xpos + rb->width;
4826 /* The line is blank so everything is considered to be right
4829 dl->bounds.right_white = dl->bounds.left_in;
4832 /* Set the display blocks bounds. */
4833 db->start_pos = dl->bounds.left_in;
4834 if (Dynarr_length (db->runes))
4836 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
4838 db->end_pos = rb->xpos + rb->width;
4841 db->end_pos = dl->bounds.right_white;
4843 /* update line height parameters */
4844 if (!data.new_ascent && !data.new_descent)
4846 /* We've got a blank line so initialize these values from the default
4848 default_face_font_info (data.window, &data.new_ascent,
4849 &data.new_descent, 0, 0, 0);
4852 if (data.max_pixmap_height)
4854 int height = data.new_ascent + data.new_descent;
4855 int pix_ascent, pix_descent;
4857 pix_descent = data.max_pixmap_height * data.new_descent / height;
4858 pix_ascent = data.max_pixmap_height - pix_descent;
4860 data.new_ascent = max (data.new_ascent, pix_ascent);
4861 data.new_descent = max (data.new_descent, pix_descent);
4864 dl->ascent = data.new_ascent;
4865 dl->descent = data.new_descent;
4868 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
4870 if (dl->ascent < ascent)
4871 dl->ascent = ascent;
4874 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
4876 if (dl->descent < descent)
4877 dl->descent = descent;
4880 dl->cursor_elt = data.cursor_x;
4881 /* #### lossage lossage lossage! Fix this shit! */
4882 if (data.bi_bufpos > bi_string_zv)
4883 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, bi_string_zv);
4885 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, data.bi_bufpos) - 1;
4887 data.dl->num_chars =
4888 string_column_at_point (s, dl->end_bufpos, b ? XINT (b->tab_width) : 8);
4890 /* This doesn't correctly take into account tabs and control
4891 characters but if the window isn't being truncated then this
4892 value isn't going to end up being used anyhow. */
4893 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
4895 /* #### handle horizontally scrolled line with text none of which
4896 was actually laid out. */
4898 /* #### handle any remainder of overlay arrow */
4900 if (*prop == ADD_FAILED)
4903 if (truncate_win && *prop)
4905 Dynarr_free (*prop);
4909 extent_fragment_delete (data.ef);
4911 /* #### If we started at EOB, then make sure we return a value past
4912 it so that regenerate_window will exit properly. This is bogus.
4913 The main loop should get fixed so that it isn't necessary to call
4914 this function if we are already at EOB. */
4916 if (data.bi_bufpos == bi_string_zv && bi_start_pos == bi_string_zv)
4917 return bytecount_to_charcount (string_data (s), data.bi_bufpos) + 1; /* Yuck! */
4919 return bytecount_to_charcount (string_data (s), data.bi_bufpos);
4922 /* Given a display line and a starting position, ensure that the
4923 contents of the display line accurately represent the visual
4924 representation of the buffer contents starting from the given
4925 position when displayed in the given window. The display line ends
4926 when the contents of the line reach the right boundary of the given
4929 This is very similar to generate_display_line but with the same
4930 limitations as create_string_text_block. I have taken the liberty
4931 of fixing the bytind stuff though.*/
4934 generate_string_display_line (struct window *w, Lisp_Object disp_string,
4935 struct display_line *dl,
4937 prop_block_dynarr **prop,
4938 face_index default_face)
4942 /* you must set bounds before calling this. */
4944 /* Reset what this line is using. */
4945 if (dl->display_blocks)
4946 Dynarr_reset (dl->display_blocks);
4947 if (dl->left_glyphs)
4949 Dynarr_free (dl->left_glyphs);
4950 dl->left_glyphs = 0;
4952 if (dl->right_glyphs)
4954 Dynarr_free (dl->right_glyphs);
4955 dl->right_glyphs = 0;
4958 /* We aren't generating a modeline at the moment. */
4961 /* Create a display block for the text region of the line. */
4962 ret_bufpos = create_string_text_block (w, disp_string, dl, start_pos,
4963 prop, default_face);
4964 dl->bufpos = start_pos;
4965 if (dl->end_bufpos < dl->bufpos)
4966 dl->end_bufpos = dl->bufpos;
4968 /* If there are left glyphs associated with any character in the
4969 text block, then create a display block to handle them. */
4970 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
4971 create_left_glyph_block (w, dl, 0);
4973 /* If there are right glyphs associated with any character in the
4974 text block, then create a display block to handle them. */
4975 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
4976 create_right_glyph_block (w, dl);
4981 /* This is ripped off from regenerate_window. All we want to do is
4982 loop through elements in the string creating display lines until we
4983 have covered the provided area. Simple really. */
4985 generate_displayable_area (struct window *w, Lisp_Object disp_string,
4986 int xpos, int ypos, int width, int height,
4987 display_line_dynarr* dla,
4989 face_index default_face)
4991 int yend = ypos + height;
4994 prop_block_dynarr *prop = 0;
4995 layout_bounds bounds;
4999 /* if there's nothing to do then do nothing. code after this assumes
5000 there is something to do. */
5001 if (NILP (disp_string))
5004 s_zv = XSTRING_CHAR_LENGTH (disp_string);
5006 bounds.left_out = xpos;
5007 bounds.right_out = xpos + width;
5008 /* The inner boundaries mark where the glyph margins are located. */
5009 bounds.left_in = bounds.left_out + window_left_margin_width (w);
5010 bounds.right_in = bounds.right_out - window_right_margin_width (w);
5011 /* We cannot fully calculate the whitespace boundaries as they
5012 depend on the contents of the line being displayed. */
5013 bounds.left_white = bounds.left_in;
5014 bounds.right_white = bounds.right_in;
5018 struct display_line dl;
5019 struct display_line *dlp;
5023 if (Dynarr_length (dla) < Dynarr_largest (dla))
5025 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5036 dlp->bounds = bounds;
5038 next_pos = generate_string_display_line (w, disp_string, dlp, start_pos,
5039 &prop, default_face);
5040 /* we need to make sure that we continue along the line if there
5041 is more left to display otherwise we just end up redisplaying
5042 the same chunk over and over again. */
5043 if (next_pos == start_pos && next_pos < s_zv)
5046 start_pos = next_pos;
5048 dlp->ypos = ypos + dlp->ascent;
5049 ypos = dlp->ypos + dlp->descent;
5053 int visible_height = dlp->ascent + dlp->descent;
5055 dlp->clip = (ypos - yend);
5056 visible_height -= dlp->clip;
5058 if (visible_height < VERTICAL_CLIP (w, 1))
5061 free_display_line (dlp);
5068 Dynarr_add (dla, *dlp);
5070 /* #### This type of check needs to be done down in the
5071 generate_display_line call. */
5072 if (start_pos >= s_zv)
5081 /***************************************************************************/
5083 /* window-regeneration routines */
5085 /***************************************************************************/
5087 /* For a given window and starting position in the buffer it contains,
5088 ensure that the TYPE display lines accurately represent the
5089 presentation of the window. We pass the buffer instead of getting
5090 it from the window since redisplay_window may have temporarily
5091 changed it to the echo area buffer. */
5094 regenerate_window (struct window *w, Bufpos start_pos, Bufpos point, int type)
5096 struct frame *f = XFRAME (w->frame);
5097 struct buffer *b = XBUFFER (w->buffer);
5098 int ypos = WINDOW_TEXT_TOP (w);
5099 int yend; /* set farther down */
5100 int yclip = WINDOW_TEXT_TOP_CLIP (w);
5102 prop_block_dynarr *prop;
5103 layout_bounds bounds;
5104 display_line_dynarr *dla;
5107 /* The lines had better exist by this point. */
5108 if (!(dla = window_display_lines (w, type)))
5111 w->max_line_len = 0;
5113 /* Normally these get updated in redisplay_window but it is possible
5114 for this function to get called from some other points where that
5115 update may not have occurred. This acts as a safety check. */
5116 if (!Dynarr_length (w->face_cachels))
5117 reset_face_cachels (w);
5118 if (!Dynarr_length (w->glyph_cachels))
5119 reset_glyph_cachels (w);
5121 Fset_marker (w->start[type], make_int (start_pos), w->buffer);
5122 Fset_marker (w->pointm[type], make_int (point), w->buffer);
5123 w->last_point_x[type] = -1;
5124 w->last_point_y[type] = -1;
5126 /* Make sure a modeline is in the structs if needed. */
5127 need_modeline = ensure_modeline_generated (w, type);
5129 /* Wait until here to set this so that the structs have a modeline
5130 generated in the case where one didn't exist. */
5131 yend = WINDOW_TEXT_BOTTOM (w);
5133 bounds = calculate_display_line_boundaries (w, 0);
5135 /* 97/3/14 jhod: stuff added here to support pre-prompts (used for input systems) */
5136 if (MINI_WINDOW_P (w)
5137 && (!NILP (Vminibuf_prompt) || !NILP (Vminibuf_preprompt))
5138 && !echo_area_active (f)
5139 && start_pos == BUF_BEGV (b))
5141 struct prop_block pb;
5143 prop = Dynarr_new (prop_block);
5145 string = concat2(Vminibuf_preprompt, Vminibuf_prompt);
5146 pb.type = PROP_MINIBUF_PROMPT;
5147 pb.data.p_string.str = XSTRING_DATA(string);
5148 pb.data.p_string.len = XSTRING_LENGTH(string);
5149 Dynarr_add (prop, pb);
5156 struct display_line dl;
5157 struct display_line *dlp;
5160 if (Dynarr_length (dla) < Dynarr_largest (dla))
5162 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5173 dlp->bounds = bounds;
5175 start_pos = generate_display_line (w, dlp, 1, start_pos, &prop, type);
5177 if (yclip > dlp->ascent)
5179 /* this should never happen, but if it does just display the
5184 dlp->ypos = (ypos + dlp->ascent) - yclip;
5185 ypos = dlp->ypos + dlp->descent;
5187 /* See if we've been asked to start midway through a line, for
5188 partial display line scrolling. */
5191 dlp->top_clip = yclip;
5199 int visible_height = dlp->ascent + dlp->descent;
5201 dlp->clip = (ypos - yend);
5202 /* Although this seems strange we could have a single very
5203 tall line visible for which we need to account for both
5204 the top clip and the bottom clip. */
5205 visible_height -= (dlp->clip + dlp->top_clip);
5207 if (visible_height < VERTICAL_CLIP (w, 1))
5210 free_display_line (dlp);
5217 if (dlp->cursor_elt != -1)
5219 /* #### This check is steaming crap. Have to get things
5220 fixed so when create_text_block hits EOB, we're done,
5222 if (w->last_point_x[type] == -1)
5224 w->last_point_x[type] = dlp->cursor_elt;
5225 w->last_point_y[type] = Dynarr_length (dla);
5229 /* #### This means that we've added a cursor at EOB
5230 twice. Yuck oh yuck. */
5231 struct display_block *db =
5232 get_display_block_from_line (dlp, TEXT);
5234 Dynarr_atp (db->runes, dlp->cursor_elt)->cursor_type = NO_CURSOR;
5235 dlp->cursor_elt = -1;
5239 if (dlp->num_chars > w->max_line_len)
5240 w->max_line_len = dlp->num_chars;
5242 Dynarr_add (dla, *dlp);
5244 /* #### This isn't right, but it is close enough for now. */
5245 w->window_end_pos[type] = start_pos;
5247 /* #### This type of check needs to be done down in the
5248 generate_display_line call. */
5249 if (start_pos > BUF_ZV (b))
5256 /* #### More not quite right, but close enough. */
5257 /* #### Ben sez: apparently window_end_pos[] is measured
5258 as the number of characters between the window end and the
5259 end of the buffer? This seems rather weirdo. What's
5260 the justification for this? */
5261 w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type];
5265 /* We know that this is the right thing to use because we put it
5266 there when we first started working in this function. */
5267 generate_modeline (w, Dynarr_atp (dla, 0), type);
5271 #define REGEN_INC_FIND_START_END \
5273 /* Determine start and end of lines. */ \
5274 if (!Dynarr_length (cdla)) \
5278 if (Dynarr_atp (cdla, 0)->modeline && Dynarr_atp (ddla, 0)->modeline) \
5282 else if (!Dynarr_atp (cdla, 0)->modeline \
5283 && !Dynarr_atp (ddla, 0)->modeline) \
5288 abort (); /* structs differ */ \
5290 dla_end = Dynarr_length (cdla) - 1; \
5293 start_pos = (Dynarr_atp (cdla, dla_start)->bufpos \
5294 + Dynarr_atp (cdla, dla_start)->offset); \
5295 /* If this isn't true, then startp has changed and we need to do a \
5297 if (startp != start_pos) \
5300 /* Point is outside the visible region so give up. */ \
5301 if (pointm < start_pos) \
5306 /* This attempts to incrementally update the display structures. It
5307 returns a boolean indicating success or failure. This function is
5308 very similar to regenerate_window_incrementally and is in fact only
5309 called from that function. However, because of the nature of the
5310 changes it deals with it sometimes makes different assumptions
5311 which can lead to success which are much more difficult to make
5312 when dealing with buffer changes. */
5315 regenerate_window_extents_only_changed (struct window *w, Bufpos startp,
5317 Charcount beg_unchanged,
5318 Charcount end_unchanged)
5320 struct buffer *b = XBUFFER (w->buffer);
5321 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5322 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5326 int first_line, last_line;
5328 /* Don't define this in the loop where it is used because we
5329 definitely want its value to survive between passes. */
5330 prop_block_dynarr *prop = NULL;
5332 /* If we don't have any buffer change recorded but the modiff flag has
5333 been incremented, then fail. I'm not sure of the exact circumstances
5334 under which this can happen, but I believe that it is probably a
5335 reasonable happening. */
5336 if (!point_visible (w, pointm, CURRENT_DISP)
5337 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b))
5340 /* If the cursor is moved we attempt to update it. If we succeed we
5341 go ahead and proceed with the optimization attempt. */
5342 if (!EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5343 || pointm != marker_position (w->last_point[CURRENT_DISP]))
5345 struct frame *f = XFRAME (w->frame);
5346 struct device *d = XDEVICE (f->device);
5347 struct frame *sel_f = device_selected_frame (d);
5350 if (w->last_point_x[CURRENT_DISP] != -1
5351 && w->last_point_y[CURRENT_DISP] != -1)
5354 if (redisplay_move_cursor (w, pointm, WINDOW_TTY_P (w)))
5356 /* Always regenerate the modeline in case it is
5357 displaying the current line or column. */
5358 regenerate_modeline (w);
5362 else if (w != XWINDOW (FRAME_SELECTED_WINDOW (sel_f)))
5364 if (f->modeline_changed)
5365 regenerate_modeline (w);
5373 if (beg_unchanged == -1 && end_unchanged == -1)
5376 /* assert: There are no buffer modifications or they are all below the
5377 visible region. We assume that regenerate_window_incrementally has
5378 not called us unless this is true. */
5380 REGEN_INC_FIND_START_END;
5382 /* If the changed are starts before the visible area, give up. */
5383 if (beg_unchanged < startp)
5386 /* Find what display line the extent changes first affect. */
5388 while (line <= dla_end)
5390 struct display_line *dl = Dynarr_atp (cdla, line);
5391 Bufpos lstart = dl->bufpos + dl->offset;
5392 Bufpos lend = dl->end_bufpos + dl->offset;
5394 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5400 /* If the changes are below the visible area then if point hasn't
5401 moved return success otherwise fail in order to be safe. */
5404 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5405 && pointm == marker_position (w->last_point[CURRENT_DISP]))
5411 /* At this point we know what line the changes first affect. We now
5412 begin redrawing lines as long as we are still in the affected
5413 region and the line's size and positioning don't change.
5414 Otherwise we fail. If we fail we will have altered the desired
5415 structs which could lead to an assertion failure. However, if we
5416 fail the next thing that is going to happen is a full regen so we
5417 will actually end up being safe. */
5418 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5419 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5420 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
5421 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
5423 first_line = last_line = line;
5424 while (line <= dla_end)
5426 Bufpos old_start, old_end, new_start;
5427 struct display_line *cdl = Dynarr_atp (cdla, line);
5428 struct display_line *ddl = Dynarr_atp (ddla, line);
5429 struct display_block *db;
5432 assert (cdl->bufpos == ddl->bufpos);
5433 assert (cdl->end_bufpos == ddl->end_bufpos);
5434 assert (cdl->offset == ddl->offset);
5436 db = get_display_block_from_line (ddl, TEXT);
5437 initial_size = Dynarr_length (db->runes);
5438 old_start = ddl->bufpos + ddl->offset;
5439 old_end = ddl->end_bufpos + ddl->offset;
5441 /* If this is the first line being updated and it used
5442 propagation data, fail. Otherwise we'll be okay because
5443 we'll have the necessary propagation data. */
5444 if (line == first_line && ddl->used_prop_data)
5447 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5448 &prop, DESIRED_DISP);
5451 /* #### If there is propagated stuff the fail. We could
5452 probably actually deal with this if the line had propagated
5453 information when originally created by a full
5461 /* If any line position parameters have changed or a
5462 cursor has disappeared or disappeared, fail. */
5463 db = get_display_block_from_line (ddl, TEXT);
5464 if (cdl->ypos != ddl->ypos
5465 || cdl->ascent != ddl->ascent
5466 || cdl->descent != ddl->descent
5467 || cdl->top_clip != ddl->top_clip
5468 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5469 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1)
5470 || old_start != ddl->bufpos
5471 || old_end != ddl->end_bufpos
5472 || initial_size != Dynarr_length (db->runes))
5477 if (ddl->cursor_elt != -1)
5479 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5480 w->last_point_y[DESIRED_DISP] = line;
5485 /* If the extent changes end on the line we just updated then
5486 we're done. Otherwise go on to the next line. */
5487 if (end_unchanged <= ddl->end_bufpos)
5493 redisplay_update_line (w, first_line, last_line, 1);
5497 /* Attempt to update the display data structures based on knowledge of
5498 the changed region in the buffer. Returns a boolean indicating
5499 success or failure. If this function returns a failure then a
5500 regenerate_window _must_ be performed next in order to maintain
5501 invariants located here. */
5504 regenerate_window_incrementally (struct window *w, Bufpos startp,
5507 struct buffer *b = XBUFFER (w->buffer);
5508 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5509 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5510 Charcount beg_unchanged, end_unchanged;
5511 Charcount extent_beg_unchanged, extent_end_unchanged;
5517 /* If this function is called, the current and desired structures
5518 had better be identical. If they are not, then that is a bug. */
5519 assert (Dynarr_length (cdla) == Dynarr_length (ddla));
5521 /* We don't handle minibuffer windows yet. The minibuffer prompt
5523 if (MINI_WINDOW_P (w))
5526 extent_beg_unchanged = BUF_EXTENT_BEGIN_UNCHANGED (b);
5527 extent_end_unchanged = (BUF_EXTENT_END_UNCHANGED (b) == -1
5529 : BUF_Z (b) - BUF_EXTENT_END_UNCHANGED (b));
5531 /* If nothing has changed in the buffer, then make sure point is ok
5533 if (BUF_BEGIN_UNCHANGED (b) == -1 && BUF_END_UNCHANGED (b) == -1)
5534 return regenerate_window_extents_only_changed (w, startp, pointm,
5535 extent_beg_unchanged,
5536 extent_end_unchanged);
5538 /* We can't deal with deleted newlines. */
5539 if (BUF_NEWLINE_WAS_DELETED (b))
5542 beg_unchanged = BUF_BEGIN_UNCHANGED (b);
5543 end_unchanged = (BUF_END_UNCHANGED (b) == -1
5545 : BUF_Z (b) - BUF_END_UNCHANGED (b));
5547 REGEN_INC_FIND_START_END;
5549 /* If the changed area starts before the visible area, give up. */
5550 if (beg_unchanged < startp)
5553 /* Find what display line the buffer changes first affect. */
5555 while (line <= dla_end)
5557 struct display_line *dl = Dynarr_atp (cdla, line);
5558 Bufpos lstart = dl->bufpos + dl->offset;
5559 Bufpos lend = dl->end_bufpos + dl->offset;
5561 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5567 /* If the changes are below the visible area then if point hasn't
5568 moved return success otherwise fail in order to be safe. */
5570 return regenerate_window_extents_only_changed (w, startp, pointm,
5571 extent_beg_unchanged,
5572 extent_end_unchanged);
5574 /* At this point we know what line the changes first affect. We
5575 now redraw that line. If the changes are contained within it
5576 we are going to succeed and can update just that one line.
5577 Otherwise we fail. If we fail we will have altered the desired
5578 structs which could lead to an assertion failure. However, if
5579 we fail the next thing that is going to happen is a full regen
5580 so we will actually end up being safe. */
5583 prop_block_dynarr *prop = NULL;
5584 struct display_line *cdl = Dynarr_atp (cdla, line);
5585 struct display_line *ddl = Dynarr_atp (ddla, line);
5587 assert (cdl->bufpos == ddl->bufpos);
5588 assert (cdl->end_bufpos == ddl->end_bufpos);
5589 assert (cdl->offset == ddl->offset);
5591 /* If the last rune is already a continuation glyph, fail.
5592 #### We should be able to handle this better. */
5594 struct display_block *db = get_display_block_from_line (ddl, TEXT);
5595 if (Dynarr_length (db->runes))
5598 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
5600 if (rb->type == RUNE_DGLYPH
5601 && EQ (rb->object.dglyph.glyph, Vcontinuation_glyph))
5606 /* If the line was generated using propagation data, fail. */
5607 if (ddl->used_prop_data)
5610 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5611 &prop, DESIRED_DISP);
5614 /* If there is propagated stuff then it is pretty much a
5615 guarantee that more than just the one line is affected. */
5622 /* If the last rune is now a continuation glyph, fail. */
5624 struct display_block *db = get_display_block_from_line (ddl, TEXT);
5625 if (Dynarr_length (db->runes))
5628 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
5630 if (rb->type == RUNE_DGLYPH
5631 && EQ (rb->object.dglyph.glyph, Vcontinuation_glyph))
5636 /* If any line position parameters have changed or a
5637 cursor has disappeared or disappeared, fail. */
5638 if (cdl->ypos != ddl->ypos
5639 || cdl->ascent != ddl->ascent
5640 || cdl->descent != ddl->descent
5641 || cdl->top_clip != ddl->top_clip
5642 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5643 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1))
5648 /* If the changed area also ends on this line, then we may be in
5649 business. Update everything and return success. */
5650 if (end_unchanged >= ddl->bufpos && end_unchanged <= ddl->end_bufpos)
5652 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5653 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5654 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp),
5656 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm),
5659 if (ddl->cursor_elt != -1)
5661 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5662 w->last_point_y[DESIRED_DISP] = line;
5665 redisplay_update_line (w, line, line, 1);
5666 regenerate_modeline (w);
5668 /* #### For now we just flush the cache until this has been
5669 tested. After that is done, this should correct the
5671 Dynarr_reset (w->line_start_cache);
5673 /* Adjust the extent changed boundaries to remove any
5674 overlap with the buffer changes since we've just
5675 successfully updated that area. */
5676 if (extent_beg_unchanged != -1
5677 && extent_beg_unchanged >= beg_unchanged
5678 && extent_beg_unchanged < end_unchanged)
5679 extent_beg_unchanged = end_unchanged;
5681 if (extent_end_unchanged != -1
5682 && extent_end_unchanged >= beg_unchanged
5683 && extent_end_unchanged < end_unchanged)
5684 extent_end_unchanged = beg_unchanged - 1;
5686 if (extent_end_unchanged <= extent_beg_unchanged)
5687 extent_beg_unchanged = extent_end_unchanged = -1;
5689 /* This could lead to odd results if it fails, but since the
5690 buffer changes update succeeded this probably will to.
5691 We already know that the extent changes start at or after
5692 the line because we checked before entering the loop. */
5693 if (extent_beg_unchanged != -1
5694 && extent_end_unchanged != -1
5695 && ((extent_beg_unchanged < ddl->bufpos)
5696 || (extent_end_unchanged > ddl->end_bufpos)))
5697 return regenerate_window_extents_only_changed (w, startp, pointm,
5698 extent_beg_unchanged,
5699 extent_end_unchanged);
5709 /* Given a window and a point, update the given display lines such
5710 that point is displayed in the middle of the window.
5711 Return the window's new start position. */
5714 regenerate_window_point_center (struct window *w, Bufpos point, int type)
5718 /* We need to make sure that the modeline is generated so that the
5719 window height can be calculated correctly. */
5720 ensure_modeline_generated (w, type);
5722 startp = start_with_line_at_pixpos (w, point, window_half_pixpos (w));
5723 regenerate_window (w, startp, point, type);
5724 Fset_marker (w->start[type], make_int (startp), w->buffer);
5729 /* Given a window and a set of display lines, return a boolean
5730 indicating whether the given point is contained within. */
5733 point_visible (struct window *w, Bufpos point, int type)
5735 struct buffer *b = XBUFFER (w->buffer);
5736 display_line_dynarr *dla = window_display_lines (w, type);
5739 if (Dynarr_length (dla) && Dynarr_atp (dla, 0)->modeline)
5744 if (Dynarr_length (dla) > first_line)
5747 struct display_line *dl = Dynarr_atp (dla, first_line);
5750 end = BUF_Z (b) - w->window_end_pos[type] - 1;
5752 if (point >= start && point <= end)
5754 if (!MINI_WINDOW_P (w) && scroll_on_clipped_lines)
5756 dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
5758 if (point >= (dl->bufpos + dl->offset)
5759 && point <= (dl->end_bufpos + dl->offset))
5774 /* Return pixel position the middle of the window, not including the
5775 modeline and any potential horizontal scrollbar. */
5778 window_half_pixpos (struct window *w)
5780 return WINDOW_TEXT_TOP (w) + (WINDOW_TEXT_HEIGHT (w) >> 1);
5783 /* Return the display line which is currently in the middle of the
5784 window W for display lines TYPE. */
5787 line_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5789 display_line_dynarr *dla;
5792 int first_elt = (MINI_WINDOW_P (w) ? 0 : 1);
5794 if (type == CMOTION_DISP)
5795 regenerate_window (w, start, point, type);
5797 dla = window_display_lines (w, type);
5798 half = window_half_pixpos (w);
5800 for (elt = first_elt; elt < Dynarr_length (dla); elt++)
5802 struct display_line *dl = Dynarr_atp (dla, elt);
5803 int line_bot = dl->ypos + dl->descent;
5805 if (line_bot > half)
5809 /* We may not have a line at the middle if the end of the buffer is
5814 /* Return a value for point that would place it at the beginning of
5815 the line which is in the middle of the window. */
5818 point_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5820 /* line_at_center will regenerate the display structures, if necessary. */
5821 int line = line_at_center (w, type, start, point);
5824 return BUF_ZV (XBUFFER (w->buffer));
5827 display_line_dynarr *dla = window_display_lines (w, type);
5828 struct display_line *dl = Dynarr_atp (dla, line);
5834 /* For a given window, ensure that the current visual representation
5838 redisplay_window (Lisp_Object window, int skip_selected)
5840 struct window *w = XWINDOW (window);
5841 struct frame *f = XFRAME (w->frame);
5842 struct device *d = XDEVICE (f->device);
5843 Lisp_Object old_buffer = w->buffer;
5844 Lisp_Object the_buffer = w->buffer;
5846 int echo_active = 0;
5851 int selected_in_its_frame;
5852 int selected_globally;
5853 int skip_output = 0;
5854 int truncation_changed;
5855 int inactive_minibuffer =
5856 (MINI_WINDOW_P (w) &&
5857 (f != device_selected_frame (d)) &&
5858 !is_surrogate_for_selected_frame (f));
5860 /* #### In the new world this function actually does a bunch of
5861 optimizations such as buffer-based scrolling, but none of that is
5864 /* If this is a combination window, do its children; that's all.
5865 The selected window is always a leaf so we don't check for
5866 skip_selected here. */
5867 if (!NILP (w->vchild))
5869 redisplay_windows (w->vchild, skip_selected);
5872 if (!NILP (w->hchild))
5874 redisplay_windows (w->hchild, skip_selected);
5878 /* Is this window the selected window on its frame? */
5879 selected_in_its_frame = (w == XWINDOW (FRAME_SELECTED_WINDOW (f)));
5881 selected_in_its_frame &&
5882 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
5883 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d &&
5884 XFRAME(DEVICE_SELECTED_FRAME(d)) == f;
5885 if (skip_selected && selected_in_its_frame)
5888 /* It is possible that the window is not fully initialized yet. */
5889 if (NILP (w->buffer))
5892 if (MINI_WINDOW_P (w) && echo_area_active (f))
5894 w->buffer = the_buffer = Vecho_area_buffer;
5898 b = XBUFFER (w->buffer);
5902 old_pointm = selected_globally
5904 : marker_position (w->pointm[CURRENT_DISP]);
5909 if (selected_globally)
5911 pointm = BUF_PT (b);
5915 pointm = marker_position (w->pointm[CURRENT_DISP]);
5917 if (pointm < BUF_BEGV (b))
5918 pointm = BUF_BEGV (b);
5919 else if (pointm > BUF_ZV (b))
5920 pointm = BUF_ZV (b);
5923 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm), the_buffer);
5925 /* If the buffer has changed we have to invalidate all of our face
5927 if ((!echo_active && b != window_display_buffer (w))
5928 || !Dynarr_length (w->face_cachels)
5929 || f->faces_changed)
5930 reset_face_cachels (w);
5932 mark_face_cachels_as_not_updated (w);
5934 /* Ditto the glyph cache elements, although we do *not* invalidate
5935 the cache purely because glyphs have changed - this is now
5936 handled by the dirty flag.*/
5937 if ((!echo_active && b != window_display_buffer (w))
5938 || !Dynarr_length (w->glyph_cachels) || f->faces_changed)
5939 reset_glyph_cachels (w);
5941 mark_glyph_cachels_as_not_updated (w);
5943 /* If the marker's buffer is not the window's buffer, then we need
5944 to find a new starting position. */
5945 if (!MINI_WINDOW_P (w)
5946 && !EQ (Fmarker_buffer (w->start[CURRENT_DISP]), w->buffer))
5948 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
5950 goto regeneration_done;
5955 old_startp = marker_position (w->start[CURRENT_DISP]);
5960 startp = marker_position (w->start[CURRENT_DISP]);
5961 if (startp < BUF_BEGV (b))
5962 startp = BUF_BEGV (b);
5963 else if (startp > BUF_ZV (b))
5964 startp = BUF_ZV (b);
5966 Fset_marker (w->start[DESIRED_DISP], make_int (startp), the_buffer);
5968 truncation_changed = (find_window_mirror (w)->truncate_win !=
5969 window_truncation_on (w));
5971 /* If w->force_start is set, then some function set w->start and we
5972 should display from there and change point, if necessary, to
5973 ensure that it is visible. */
5974 if (w->force_start || inactive_minibuffer)
5977 w->last_modified[DESIRED_DISP] = Qzero;
5978 w->last_facechange[DESIRED_DISP] = Qzero;
5980 regenerate_window (w, startp, pointm, DESIRED_DISP);
5982 if (!point_visible (w, pointm, DESIRED_DISP) && !inactive_minibuffer)
5984 pointm = point_at_center (w, DESIRED_DISP, 0, 0);
5986 if (selected_globally)
5987 BUF_SET_PT (b, pointm);
5989 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm),
5992 /* #### BUFU amounts of overkill just to get the cursor
5993 location marked properly. FIX ME FIX ME FIX ME */
5994 regenerate_window (w, startp, pointm, DESIRED_DISP);
5997 goto regeneration_done;
6000 /* If nothing has changed since the last redisplay, then we just
6001 need to make sure that point is still visible. */
6002 if (XINT (w->last_modified[CURRENT_DISP]) >= BUF_MODIFF (b)
6003 && XINT (w->last_facechange[CURRENT_DISP]) >= BUF_FACECHANGE (b)
6005 /* This check is to make sure we restore the minibuffer after a
6006 temporary change to the echo area. */
6007 && !(MINI_WINDOW_P (w) && f->buffers_changed)
6008 && !f->frame_changed
6009 && !truncation_changed
6010 /* check whether start is really at the begining of a line GE */
6011 && (!w->start_at_line_beg || beginning_of_line_p (b, startp))
6014 /* Check if the cursor has actually moved. */
6015 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
6016 && pointm == marker_position (w->last_point[CURRENT_DISP])
6017 && selected_globally
6018 && !w->windows_changed
6020 && !f->extents_changed
6021 && !f->faces_changed
6022 && !f->glyphs_changed
6023 && !f->subwindows_changed
6024 && !f->subwindows_state_changed
6025 && !f->point_changed
6026 && !f->windows_structure_changed)
6028 /* If not, we're done. */
6029 if (f->modeline_changed)
6030 regenerate_modeline (w);
6033 goto regeneration_done;
6037 /* If the new point is visible in the redisplay structures,
6038 then let the output update routines handle it, otherwise
6039 do things the hard way. */
6040 if (!w->windows_changed
6042 && !f->extents_changed
6043 && !f->faces_changed
6044 && !f->glyphs_changed
6045 && !f->subwindows_changed
6046 && !f->subwindows_state_changed
6047 && !f->windows_structure_changed)
6049 if (point_visible (w, pointm, CURRENT_DISP)
6050 && w->last_point_x[CURRENT_DISP] != -1
6051 && w->last_point_y[CURRENT_DISP] != -1)
6053 if (redisplay_move_cursor (w, pointm, FRAME_TTY_P (f)))
6055 /* Always regenerate in case it is displaying
6056 the current line or column. */
6057 regenerate_modeline (w);
6060 goto regeneration_done;
6063 else if (!selected_in_its_frame && !f->point_changed)
6065 if (f->modeline_changed)
6066 regenerate_modeline (w);
6069 goto regeneration_done;
6073 /* If we weren't able to take the shortcut method, then use
6074 the brute force method. */
6075 regenerate_window (w, startp, pointm, DESIRED_DISP);
6077 if (point_visible (w, pointm, DESIRED_DISP))
6078 goto regeneration_done;
6082 /* Check if the starting point is no longer at the beginning of a
6083 line, in which case find a new starting point. We also recenter
6084 if our start position is equal to point-max. Otherwise we'll end
6085 up with a blank window. */
6086 else if (((w->start_at_line_beg || MINI_WINDOW_P (w))
6087 && !(startp == BUF_BEGV (b)
6088 || BUF_FETCH_CHAR (b, startp - 1) == '\n'))
6089 || (pointm == startp &&
6090 EQ (Fmarker_buffer (w->last_start[CURRENT_DISP]), w->buffer) &&
6091 startp < marker_position (w->last_start[CURRENT_DISP]))
6092 || (startp == BUF_ZV (b)))
6094 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6096 goto regeneration_done;
6098 /* See if we can update the data structures locally based on
6099 knowledge of what changed in the buffer. */
6100 else if (!w->windows_changed
6102 && !f->faces_changed
6103 && !f->glyphs_changed
6104 && !f->subwindows_changed
6105 && !f->subwindows_state_changed
6106 && !f->windows_structure_changed
6107 && !f->frame_changed
6108 && !truncation_changed
6110 && regenerate_window_incrementally (w, startp, pointm))
6112 if (f->modeline_changed
6113 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b)
6114 || XINT (w->last_facechange[CURRENT_DISP]) < BUF_FACECHANGE (b))
6115 regenerate_modeline (w);
6118 goto regeneration_done;
6120 /* #### This is where a check for structure based scrolling would go. */
6121 /* If all else fails, try just regenerating and see what happens. */
6124 regenerate_window (w, startp, pointm, DESIRED_DISP);
6126 if (point_visible (w, pointm, DESIRED_DISP))
6127 goto regeneration_done;
6130 /* We still haven't gotten the window regenerated with point
6131 visible. Next we try scrolling a little and see if point comes
6132 back onto the screen. */
6133 if (scroll_step > 0)
6135 int scrolled = scroll_conservatively;
6136 for (; scrolled >= 0; scrolled -= scroll_step)
6138 startp = vmotion (w, startp,
6139 (pointm < startp) ? -scroll_step : scroll_step, 0);
6140 regenerate_window (w, startp, pointm, DESIRED_DISP);
6142 if (point_visible (w, pointm, DESIRED_DISP))
6143 goto regeneration_done;
6147 /* We still haven't managed to get the screen drawn with point on
6148 the screen, so just center it and be done with it. */
6149 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6154 /* If the window's frame is changed then reset the current display
6155 lines in order to force a full repaint. */
6156 if (f->frame_changed)
6158 display_line_dynarr *cla = window_display_lines (w, CURRENT_DISP);
6163 /* Must do this before calling redisplay_output_window because it
6164 sets some markers on the window. */
6167 w->buffer = old_buffer;
6168 Fset_marker (w->pointm[DESIRED_DISP], make_int (old_pointm), old_buffer);
6169 Fset_marker (w->start[DESIRED_DISP], make_int (old_startp), old_buffer);
6172 /* These also have to be set before calling redisplay_output_window
6173 since it sets the CURRENT_DISP values based on them. */
6174 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
6175 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
6176 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
6177 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
6181 Bufpos start = marker_position (w->start[DESIRED_DISP]);
6182 Bufpos end = (w->window_end_pos[DESIRED_DISP] == -1
6184 : BUF_Z (b) - w->window_end_pos[DESIRED_DISP] - 1);
6185 /* Don't pollute the cache if not sure if we are correct */
6186 if (w->start_at_line_beg)
6187 update_line_start_cache (w, start, end, pointm, 1);
6188 redisplay_output_window (w);
6190 * If we just displayed the echo area, the line start cache is
6191 * no longer valid, because the minibuffer window is associated
6192 * with the window now.
6195 w->line_cache_last_updated = make_int (-1);
6198 /* #### This should be dependent on face changes and will need to be
6199 somewhere else once tty updates occur on a per-frame basis. */
6200 mark_face_cachels_as_clean (w);
6202 /* The glyph cachels only get dirty if someone changed something.
6203 Since redisplay has now effectively ended we can reset the dirty
6204 flag since everything must be up-to-date. */
6206 mark_glyph_cachels_as_clean (w);
6208 w->windows_changed = 0;
6211 /* Call buffer_reset_changes for all buffers present in any window
6212 currently visible in all frames on all devices. #### There has to
6213 be a better way to do this. */
6216 reset_buffer_changes_mapfun (struct window *w, void *ignored_closure)
6218 buffer_reset_changes (XBUFFER (w->buffer));
6223 reset_buffer_changes (void)
6225 Lisp_Object frmcons, devcons, concons;
6227 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
6229 struct frame *f = XFRAME (XCAR (frmcons));
6231 if (FRAME_REPAINT_P (f))
6232 map_windows (f, reset_buffer_changes_mapfun, 0);
6236 /* Ensure that all windows underneath the given window in the window
6237 hierarchy are correctly displayed. */
6240 redisplay_windows (Lisp_Object window, int skip_selected)
6242 for (; !NILP (window) ; window = XWINDOW (window)->next)
6244 redisplay_window (window, skip_selected);
6249 call_redisplay_end_triggers (struct window *w, void *closure)
6251 Bufpos lrpos = w->last_redisplay_pos;
6252 w->last_redisplay_pos = 0;
6253 if (!NILP (w->buffer)
6254 && !NILP (w->redisplay_end_trigger)
6259 if (MARKERP (w->redisplay_end_trigger)
6260 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
6261 pos = marker_position (w->redisplay_end_trigger);
6262 else if (INTP (w->redisplay_end_trigger))
6263 pos = XINT (w->redisplay_end_trigger);
6266 w->redisplay_end_trigger = Qnil;
6273 XSETWINDOW (window, w);
6274 va_run_hook_with_args_in_buffer (XBUFFER (w->buffer),
6275 Qredisplay_end_trigger_functions,
6277 w->redisplay_end_trigger);
6278 w->redisplay_end_trigger = Qnil;
6285 /* Ensure that all windows on the given frame are correctly displayed. */
6288 redisplay_frame (struct frame *f, int preemption_check)
6290 struct device *d = XDEVICE (f->device);
6292 if (preemption_check)
6294 /* The preemption check itself takes a lot of time,
6295 so normally don't do it here. We do it if called
6296 from Lisp, though (`redisplay-frame'). */
6299 REDISPLAY_PREEMPTION_CHECK;
6304 /* Before we put a hold on frame size changes, attempt to process
6305 any which are already pending. */
6306 if (f->size_change_pending)
6307 change_frame_size (f, f->new_height, f->new_width, 0);
6309 /* If frame size might need to be changed, due to changed size
6310 of toolbars, scrollbars etc, change it now */
6311 if (f->size_slipped)
6313 adjust_frame_size (f);
6314 assert (!f->size_slipped);
6317 /* The menubar, toolbar, and icon updates must be done before
6318 hold_frame_size_changes is called and we are officially
6319 'in_display'. They may eval lisp code which may call Fsignal.
6320 If in_display is set Fsignal will abort. */
6322 #ifdef HAVE_MENUBARS
6323 /* Update the menubar. It is done first since it could change
6324 the menubar's visibility. This way we avoid having flashing
6325 caused by an Expose event generated by the visibility change
6327 update_frame_menubars (f);
6328 #endif /* HAVE_MENUBARS */
6329 /* widgets are similar to menus in that they can call lisp to
6330 determine activation etc. Therefore update them before we get
6331 into redisplay. This is primarily for connected widgets such as
6333 update_frame_subwindows (f);
6334 #ifdef HAVE_TOOLBARS
6335 /* Update the toolbars. */
6336 update_frame_toolbars (f);
6337 #endif /* HAVE_TOOLBARS */
6339 /* If we clear the frame we have to force its contents to be redrawn. */
6341 f->frame_changed = 1;
6343 /* invalidate the subwindow cache. We use subwindows_changed here to
6344 cause subwindows to get instantiated. This is because
6345 subwindows_state_changed is less strict - dealing with things
6346 like the clicked state of button. We have to do this before
6347 redisplaying the gutters as subwindows get unmapped in the
6349 if (!Dynarr_length (f->subwindow_cachels)
6350 || f->subwindows_changed
6352 || f->frame_changed)
6354 reset_subwindow_cachels (f);
6355 /* we have to do this so the gutter gets regenerated. */
6356 reset_gutter_display_lines (f);
6359 mark_subwindow_cachels_as_not_updated (f);
6360 /* We can now update the gutters, safe in the knowledge that our
6361 efforts won't get undone. */
6362 update_frame_gutters (f);
6364 hold_frame_size_changes ();
6366 /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */
6367 /* Within this section, we are defenseless and assume that the
6368 following cannot happen:
6370 1) garbage collection
6371 2) Lisp code evaluation
6372 3) frame size changes
6374 We ensure (3) by calling hold_frame_size_changes(), which
6375 will cause any pending frame size changes to get put on hold
6376 till after the end of the critical section. (1) follows
6377 automatically if (2) is met. #### Unfortunately, there are
6378 some places where Lisp code can be called within this section.
6379 We need to remove them.
6381 If Fsignal() is called during this critical section, we
6384 If garbage collection is called during this critical section,
6385 we simply return. #### We should abort instead.
6387 #### If a frame-size change does occur we should probably
6388 actually be preempting redisplay. */
6390 /* Erase the frame before outputting its contents. */
6393 DEVMETH (d, clear_frame, (f));
6396 /* Do the selected window first. */
6397 redisplay_window (FRAME_SELECTED_WINDOW (f), 0);
6399 /* Then do the rest. */
6400 redisplay_windows (f->root_window, 1);
6402 /* We now call the output_end routine for tty frames. We delay
6403 doing so in order to avoid cursor flicker. So much for 100%
6405 if (FRAME_TTY_P (f))
6406 DEVMETH (d, output_end, (d));
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);
7045 mark_redisplay_structs (display_line_dynarr *dla)
7047 display_line *dl = Dynarr_atp (dla, 0);
7048 display_line *dl_last = Dynarr_atp (dla, Dynarr_length (dla));
7050 for (; dl < dl_last; dl++)
7052 display_block_dynarr *dba = dl->display_blocks;
7053 display_block *db = Dynarr_atp (dba, 0);
7054 display_block *db_last = Dynarr_atp (dba, Dynarr_length (dba));
7056 for (; db < db_last; db++)
7058 rune_dynarr *ra = db->runes;
7059 rune *r = Dynarr_atp (ra, 0);
7060 rune *r_last = Dynarr_atp (ra, Dynarr_length (ra));
7062 for (; r < r_last; r++)
7064 if (r->type == RUNE_DGLYPH)
7066 if (!NILP (r->object.dglyph.glyph))
7067 mark_object (r->object.dglyph.glyph);
7068 if (!NILP (r->object.dglyph.extent))
7069 mark_object (r->object.dglyph.extent);
7074 mark_glyph_block_dynarr (dl->left_glyphs);
7075 mark_glyph_block_dynarr (dl->right_glyphs);
7080 mark_window_mirror (struct window_mirror *mir)
7082 mark_redisplay_structs (mir->current_display_lines);
7083 mark_redisplay_structs (mir->desired_display_lines);
7086 mark_window_mirror (mir->next);
7089 mark_window_mirror (mir->hchild);
7090 else if (mir->vchild)
7091 mark_window_mirror (mir->vchild);
7095 mark_redisplay (void)
7097 Lisp_Object frmcons, devcons, concons;
7099 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
7101 struct frame *f = XFRAME (XCAR (frmcons));
7102 update_frame_window_mirror (f);
7103 mark_window_mirror (f->root_mirror);
7107 /*****************************************************************************
7108 Line Start Cache Description and Rationale
7110 The traditional scrolling code in Emacs breaks in a variable height world.
7111 It depends on the key assumption that the number of lines that can be
7112 displayed at any given time is fixed. This led to a complete separation
7113 of the scrolling code from the redisplay code. In order to fully support
7114 variable height lines, the scrolling code must actually be tightly
7115 integrated with redisplay. Only redisplay can determine how many lines
7116 will be displayed on a screen for any given starting point.
7118 What is ideally wanted is a complete list of the starting buffer position
7119 for every possible display line of a buffer along with the height of that
7120 display line. Maintaining such a full list would be very expensive. We
7121 settle for having it include information for all areas which we happen to
7122 generate anyhow (i.e. the region currently being displayed) and for those
7123 areas we need to work with.
7125 In order to ensure that the cache accurately represents what redisplay
7126 would actually show, it is necessary to invalidate it in many situations.
7127 If the buffer changes, the starting positions may no longer be correct.
7128 If a face or an extent has changed then the line heights may have altered.
7129 These events happen frequently enough that the cache can end up being
7130 constantly disabled. With this potentially constant invalidation when is
7131 the cache ever useful?
7133 Even if the cache is invalidated before every single usage, it is
7134 necessary. Scrolling often requires knowledge about display lines which
7135 are actually above or below the visible region. The cache provides a
7136 convenient light-weight method of storing this information for multiple
7137 display regions. This knowledge is necessary for the scrolling code to
7138 always obey the First Golden Rule of Redisplay.
7140 If the cache already contains all of the information that the scrolling
7141 routines happen to need so that it doesn't have to go generate it, then we
7142 are able to obey the Third Golden Rule of Redisplay. The first thing we
7143 do to help out the cache is to always add the displayed region. This
7144 region had to be generated anyway, so the cache ends up getting the
7145 information basically for free. In those cases where a user is simply
7146 scrolling around viewing a buffer there is a high probability that this is
7147 sufficient to always provide the needed information. The second thing we
7148 can do is be smart about invalidating the cache.
7150 TODO -- Be smart about invalidating the cache. Potential places:
7152 + Insertions at end-of-line which don't cause line-wraps do not alter the
7153 starting positions of any display lines. These types of buffer
7154 modifications should not invalidate the cache. This is actually a large
7155 optimization for redisplay speed as well.
7157 + Buffer modifications frequently only affect the display of lines at and
7158 below where they occur. In these situations we should only invalidate
7159 the part of the cache starting at where the modification occurs.
7161 In case you're wondering, the Second Golden Rule of Redisplay is not
7163 ****************************************************************************/
7165 /* This will get used quite a bit so we don't want to be constantly
7166 allocating and freeing it. */
7167 static line_start_cache_dynarr *internal_cache;
7169 /* Makes internal_cache represent the TYPE display structs and only
7170 the TYPE display structs. */
7173 update_internal_cache_list (struct window *w, int type)
7176 display_line_dynarr *dla = window_display_lines (w, type);
7178 Dynarr_reset (internal_cache);
7179 for (line = 0; line < Dynarr_length (dla); line++)
7181 struct display_line *dl = Dynarr_atp (dla, line);
7187 struct line_start_cache lsc;
7189 lsc.start = dl->bufpos;
7190 lsc.end = dl->end_bufpos;
7191 lsc.height = dl->ascent + dl->descent;
7193 Dynarr_add (internal_cache, lsc);
7198 /* Reset the line cache if necessary. This should be run at the
7199 beginning of any function which access the cache. */
7202 validate_line_start_cache (struct window *w)
7204 struct buffer *b = XBUFFER (w->buffer);
7205 struct frame *f = XFRAME (w->frame);
7207 if (!w->line_cache_validation_override)
7209 /* f->extents_changed used to be in here because extent face and
7210 size changes can cause text shifting. However, the extent
7211 covering the region is constantly having its face set and
7212 priority altered by the mouse code. This means that the line
7213 start cache is constantly being invalidated. This is bad
7214 since the mouse code also triggers heavy usage of the cache.
7215 Since it is an unlikely that f->extents being changed
7216 indicates that the cache really needs to be updated and if it
7217 does redisplay will catch it pretty quickly we no longer
7218 invalidate the cache if it is set. This greatly speeds up
7219 dragging out regions with the mouse. */
7220 if (XINT (w->line_cache_last_updated) < BUF_MODIFF (b)
7224 Dynarr_reset (w->line_start_cache);
7229 /* Return the very first buffer position contained in the given
7230 window's cache, or -1 if the cache is empty. Assumes that the
7234 line_start_cache_start (struct window *w)
7236 line_start_cache_dynarr *cache = w->line_start_cache;
7238 if (!Dynarr_length (cache))
7241 return Dynarr_atp (cache, 0)->start;
7244 /* Return the very last buffer position contained in the given
7245 window's cache, or -1 if the cache is empty. Assumes that the
7249 line_start_cache_end (struct window *w)
7251 line_start_cache_dynarr *cache = w->line_start_cache;
7253 if (!Dynarr_length (cache))
7256 return Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
7259 /* Return the index of the line POINT is contained within in window
7260 W's line start cache. It will enlarge the cache or move the cache
7261 window in order to have POINT be present in the cache. MIN_PAST is
7262 a guarantee of the number of entries in the cache present on either
7263 side of POINT (unless a buffer boundary is hit). If MIN_PAST is -1
7264 then it will be treated as 0, but the cache window will not be
7265 allowed to shift. Returns -1 if POINT cannot be found in the cache
7269 point_in_line_start_cache (struct window *w, Bufpos point, int min_past)
7271 struct buffer *b = XBUFFER (w->buffer);
7272 line_start_cache_dynarr *cache = w->line_start_cache;
7273 unsigned int top, bottom, pos;
7275 validate_line_start_cache (w);
7276 w->line_cache_validation_override++;
7278 /* Let functions pass in negative values, but we still treat -1
7280 /* #### bogosity alert */
7281 if (min_past < 0 && min_past != -1)
7282 min_past = -min_past;
7284 if (!Dynarr_length (cache) || line_start_cache_start (w) > point
7285 || line_start_cache_end (w) < point)
7288 int win_char_height = window_char_height (w, 1);
7290 /* Occasionally we get here with a 0 height
7291 window. find_next_newline_no_quit will abort if we pass it a
7292 count of 0 so handle that case. */
7293 if (!win_char_height)
7294 win_char_height = 1;
7296 if (!Dynarr_length (cache))
7298 Bufpos from = find_next_newline_no_quit (b, point, -1);
7299 Bufpos to = find_next_newline_no_quit (b, from, win_char_height);
7301 update_line_start_cache (w, from, to, point, 0);
7303 if (!Dynarr_length (cache))
7305 w->line_cache_validation_override--;
7310 assert (Dynarr_length (cache));
7313 while (line_start_cache_start (w) > point
7314 && (loop < cache_adjustment || min_past == -1))
7318 from = line_start_cache_start (w);
7319 if (from <= BUF_BEGV (b))
7322 from = find_next_newline_no_quit (b, from, -win_char_height);
7323 to = line_start_cache_end (w);
7325 update_line_start_cache (w, from, to, point, 0);
7329 if (line_start_cache_start (w) > point)
7333 from = find_next_newline_no_quit (b, point, -1);
7334 if (from >= BUF_ZV (b))
7336 to = find_next_newline_no_quit (b, from, -win_char_height);
7341 to = find_next_newline_no_quit (b, from, win_char_height);
7343 update_line_start_cache (w, from, to, point, 0);
7347 while (line_start_cache_end (w) < point
7348 && (loop < cache_adjustment || min_past == -1))
7352 to = line_start_cache_end (w);
7353 if (to >= BUF_ZV (b))
7356 from = line_start_cache_end (w);
7357 to = find_next_newline_no_quit (b, from, win_char_height);
7359 update_line_start_cache (w, from, to, point, 0);
7363 if (line_start_cache_end (w) < point)
7367 from = find_next_newline_no_quit (b, point, -1);
7368 if (from >= BUF_ZV (b))
7370 to = find_next_newline_no_quit (b, from, -win_char_height);
7375 to = find_next_newline_no_quit (b, from, win_char_height);
7377 update_line_start_cache (w, from, to, point, 0);
7381 assert (Dynarr_length (cache));
7386 /* This could happen if the buffer is narrowed. */
7387 if (line_start_cache_start (w) > point
7388 || line_start_cache_end (w) < point)
7390 w->line_cache_validation_override--;
7396 top = Dynarr_length (cache) - 1;
7401 unsigned int new_pos;
7404 pos = (bottom + top + 1) >> 1;
7405 start = Dynarr_atp (cache, pos)->start;
7406 end = Dynarr_atp (cache, pos)->end;
7408 if (point >= start && point <= end)
7410 if (pos < min_past && line_start_cache_start (w) > BUF_BEGV (b))
7413 find_next_newline_no_quit (b, line_start_cache_start (w),
7415 Bufpos to = line_start_cache_end (w);
7417 update_line_start_cache (w, from, to, point, 0);
7418 goto find_point_loop;
7420 else if ((Dynarr_length (cache) - pos - 1) < min_past
7421 && line_start_cache_end (w) < BUF_ZV (b))
7423 Bufpos from = line_start_cache_end (w);
7424 Bufpos to = find_next_newline_no_quit (b, from,
7429 update_line_start_cache (w, from, to, point, 0);
7430 goto find_point_loop;
7434 w->line_cache_validation_override--;
7438 else if (point > end)
7440 else if (point < start)
7445 new_pos = (bottom + top + 1) >> 1;
7448 w->line_cache_validation_override--;
7454 /* Return a boolean indicating if POINT would be visible in window W
7455 if display of the window was to begin at STARTP. */
7458 point_would_be_visible (struct window *w, Bufpos startp, Bufpos point)
7460 struct buffer *b = XBUFFER (w->buffer);
7461 int pixpos = -WINDOW_TEXT_TOP_CLIP(w);
7462 int bottom = WINDOW_TEXT_HEIGHT (w);
7465 /* If point is before the intended start it obviously can't be visible. */
7469 /* If point or start are not in the accessible buffer range, then
7471 if (startp < BUF_BEGV (b) || startp > BUF_ZV (b)
7472 || point < BUF_BEGV (b) || point > BUF_ZV (b))
7475 validate_line_start_cache (w);
7476 w->line_cache_validation_override++;
7478 start_elt = point_in_line_start_cache (w, startp, 0);
7479 if (start_elt == -1)
7481 w->line_cache_validation_override--;
7485 assert (line_start_cache_start (w) <= startp
7486 && line_start_cache_end (w) >= startp);
7492 /* Expand the cache if necessary. */
7493 if (start_elt == Dynarr_length (w->line_start_cache))
7496 Dynarr_atp (w->line_start_cache, start_elt - 1)->start;
7498 start_elt = point_in_line_start_cache (w, old_startp,
7499 window_char_height (w, 0));
7501 /* We've already actually processed old_startp, so increment
7505 /* If this happens we didn't add any extra elements. Bummer. */
7506 if (start_elt == Dynarr_length (w->line_start_cache))
7508 w->line_cache_validation_override--;
7513 height = Dynarr_atp (w->line_start_cache, start_elt)->height;
7515 if (pixpos + height > bottom)
7517 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7519 w->line_cache_validation_override--;
7525 if (point <= Dynarr_atp (w->line_start_cache, start_elt)->end)
7527 w->line_cache_validation_override--;
7535 /* For the given window W, if display starts at STARTP, what will be
7536 the buffer position at the beginning or end of the last line
7537 displayed. The end of the last line is also know as the window end
7540 #### With a little work this could probably be reworked as just a
7541 call to start_with_line_at_pixpos. */
7544 start_end_of_last_line (struct window *w, Bufpos startp, int end)
7546 struct buffer *b = XBUFFER (w->buffer);
7547 line_start_cache_dynarr *cache = w->line_start_cache;
7549 int bottom = WINDOW_TEXT_HEIGHT (w);
7553 validate_line_start_cache (w);
7554 w->line_cache_validation_override++;
7556 if (startp < BUF_BEGV (b))
7557 startp = BUF_BEGV (b);
7558 else if (startp > BUF_ZV (b))
7559 startp = BUF_ZV (b);
7562 start_elt = point_in_line_start_cache (w, cur_start, 0);
7563 if (start_elt == -1)
7564 abort (); /* this had better never happen */
7568 int height = Dynarr_atp (cache, start_elt)->height;
7570 cur_start = Dynarr_atp (cache, start_elt)->start;
7572 if (pixpos + height > bottom)
7574 /* Adjust for any possible clip. */
7575 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7580 w->line_cache_validation_override--;
7584 return BUF_BEGV (b);
7588 w->line_cache_validation_override--;
7590 return Dynarr_atp (cache, start_elt)->end;
7592 return Dynarr_atp (cache, start_elt)->start;
7598 if (start_elt == Dynarr_length (cache))
7600 Bufpos from = line_start_cache_end (w);
7601 int win_char_height = window_char_height (w, 0);
7602 Bufpos to = find_next_newline_no_quit (b, from,
7607 /* We've hit the end of the bottom so that's what it is. */
7608 if (from >= BUF_ZV (b))
7610 w->line_cache_validation_override--;
7614 update_line_start_cache (w, from, to, BUF_PT (b), 0);
7616 /* Updating the cache invalidates any current indexes. */
7617 start_elt = point_in_line_start_cache (w, cur_start, -1) + 1;
7622 /* For the given window W, if display starts at STARTP, what will be
7623 the buffer position at the beginning of the last line displayed. */
7626 start_of_last_line (struct window *w, Bufpos startp)
7628 return start_end_of_last_line (w, startp, 0);
7631 /* For the given window W, if display starts at STARTP, what will be
7632 the buffer position at the end of the last line displayed. This is
7633 also know as the window end position. */
7636 end_of_last_line (struct window *w, Bufpos startp)
7638 return start_end_of_last_line (w, startp, 1);
7641 /* For window W, what does the starting position have to be so that
7642 the line containing POINT will cover pixel position PIXPOS. */
7645 start_with_line_at_pixpos (struct window *w, Bufpos point, int pixpos)
7647 struct buffer *b = XBUFFER (w->buffer);
7649 Bufpos cur_pos, prev_pos = point;
7650 int point_line_height;
7651 int pixheight = pixpos - WINDOW_TEXT_TOP (w);
7653 validate_line_start_cache (w);
7654 w->line_cache_validation_override++;
7656 cur_elt = point_in_line_start_cache (w, point, 0);
7657 /* #### See comment in update_line_start_cache about big minibuffers. */
7660 w->line_cache_validation_override--;
7664 point_line_height = Dynarr_atp (w->line_start_cache, cur_elt)->height;
7668 cur_pos = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7670 pixheight -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7672 /* Do not take into account the value of vertical_clip here.
7673 That is the responsibility of the calling functions. */
7676 w->line_cache_validation_override--;
7677 if (-pixheight > point_line_height)
7678 /* We can't make the target line cover pixpos, so put it
7679 above pixpos. That way it will at least be visible. */
7689 int win_char_height;
7691 if (cur_pos <= BUF_BEGV (b))
7693 w->line_cache_validation_override--;
7694 return BUF_BEGV (b);
7697 win_char_height = window_char_height (w, 0);
7698 if (!win_char_height)
7699 win_char_height = 1;
7701 from = find_next_newline_no_quit (b, cur_pos, -win_char_height);
7702 to = line_start_cache_end (w);
7703 update_line_start_cache (w, from, to, point, 0);
7705 cur_elt = point_in_line_start_cache (w, cur_pos, 2) - 1;
7706 assert (cur_elt >= -1);
7707 /* This used to be cur_elt>=0 under the assumption that if
7708 point is in the top line and not at BUF_BEGV, then
7709 setting the window_start to a newline before the start of
7710 the first line will always cause scrolling.
7712 However in my (jv) opinion this is wrong. That new line
7713 can be hidden in various ways: invisible extents, an
7714 explicit window-start not at a newline character etc.
7715 The existence of those are indeed known to create crashes
7716 on that assert. So we have no option but to continue the
7717 search if we found point at the top of the line_start_cache
7719 cur_pos = Dynarr_atp (w->line_start_cache,0)->start;
7725 /* For window W, what does the starting position have to be so that
7726 the line containing point is on display line LINE. If LINE is
7727 positive it is considered to be the number of lines from the top of
7728 the window (0 is the top line). If it is negative the number is
7729 considered to be the number of lines from the bottom (-1 is the
7733 start_with_point_on_display_line (struct window *w, Bufpos point, int line)
7735 validate_line_start_cache (w);
7736 w->line_cache_validation_override++;
7740 int cur_elt = point_in_line_start_cache (w, point, line);
7742 if (cur_elt - line < 0)
7743 cur_elt = 0; /* Hit the top */
7747 w->line_cache_validation_override--;
7748 return Dynarr_atp (w->line_start_cache, cur_elt)->start;
7752 /* The calculated value of pixpos is correct for the bottom line
7753 or what we want when line is -1. Therefore we subtract one
7754 because we have already handled one line. */
7755 int new_line = -line - 1;
7756 int cur_elt = point_in_line_start_cache (w, point, new_line);
7757 int pixpos = WINDOW_TEXT_BOTTOM (w);
7758 Bufpos retval, search_point;
7760 /* If scroll_on_clipped_lines is false, the last "visible" line of
7761 the window covers the pixel at WINDOW_TEXT_BOTTOM (w) - 1.
7762 If s_o_c_l is true, then we don't want to count a clipped
7763 line, so back up from the bottom by the height of the line
7764 containing point. */
7765 if (scroll_on_clipped_lines)
7766 pixpos -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7770 if (cur_elt + new_line >= Dynarr_length (w->line_start_cache))
7772 /* Hit the bottom of the buffer. */
7774 (cur_elt + new_line) - Dynarr_length (w->line_start_cache) + 1;
7778 XSETWINDOW (window, w);
7779 default_face_height_and_width (window, &defheight, 0);
7781 cur_elt = Dynarr_length (w->line_start_cache) - 1;
7783 pixpos -= (adjustment * defheight);
7784 if (pixpos < WINDOW_TEXT_TOP (w))
7785 pixpos = WINDOW_TEXT_TOP (w);
7788 cur_elt = cur_elt + new_line;
7790 search_point = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7792 retval = start_with_line_at_pixpos (w, search_point, pixpos);
7793 w->line_cache_validation_override--;
7798 /* This is used to speed up vertical scrolling by caching the known
7799 buffer starting positions for display lines. This allows the
7800 scrolling routines to avoid costly calls to regenerate_window. If
7801 NO_REGEN is true then it will only add the values in the DESIRED
7802 display structs which are in the given range.
7804 Note also that the FROM/TO values are minimums. It is possible
7805 that this function will actually add information outside of the
7806 lines containing those positions. This can't hurt but it could
7809 #### We currently force the cache to have only 1 contiguous region.
7810 It might help to make the cache a dynarr of caches so that we can
7811 cover more areas. This might, however, turn out to be a lot of
7812 overhead for too little gain. */
7815 update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
7816 Bufpos point, int no_regen)
7818 struct buffer *b = XBUFFER (w->buffer);
7819 line_start_cache_dynarr *cache = w->line_start_cache;
7820 Bufpos low_bound, high_bound;
7822 validate_line_start_cache (w);
7823 w->line_cache_validation_override++;
7824 updating_line_start_cache = 1;
7826 if (from < BUF_BEGV (b))
7827 from = BUF_BEGV (b);
7828 if (to > BUF_ZV (b))
7833 updating_line_start_cache = 0;
7834 w->line_cache_validation_override--;
7838 if (Dynarr_length (cache))
7840 low_bound = line_start_cache_start (w);
7841 high_bound = line_start_cache_end (w);
7843 /* Check to see if the desired range is already in the cache. */
7844 if (from >= low_bound && to <= high_bound)
7846 updating_line_start_cache = 0;
7847 w->line_cache_validation_override--;
7851 /* Check to make sure that the desired range is adjacent to the
7852 current cache. If not, invalidate the cache. */
7853 if (to < low_bound || from > high_bound)
7855 Dynarr_reset (cache);
7856 low_bound = high_bound = -1;
7861 low_bound = high_bound = -1;
7864 w->line_cache_last_updated = make_int (BUF_MODIFF (b));
7866 /* This could be integrated into the next two sections, but it is easier
7867 to follow what's going on by having it separate. */
7872 update_internal_cache_list (w, DESIRED_DISP);
7873 if (!Dynarr_length (internal_cache))
7875 updating_line_start_cache = 0;
7876 w->line_cache_validation_override--;
7880 start = Dynarr_atp (internal_cache, 0)->start;
7882 Dynarr_atp (internal_cache, Dynarr_length (internal_cache) - 1)->end;
7884 /* We aren't allowed to generate additional information to fill in
7885 gaps, so if the DESIRED structs don't overlap the cache, reset the
7887 if (Dynarr_length (cache))
7889 if (end < low_bound || start > high_bound)
7890 Dynarr_reset (cache);
7892 /* #### What should really happen if what we are doing is
7893 extending a line (the last line)? */
7894 if (Dynarr_length (cache) == 1
7895 && Dynarr_length (internal_cache) == 1)
7896 Dynarr_reset (cache);
7899 if (!Dynarr_length (cache))
7901 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7902 Dynarr_length (internal_cache));
7903 updating_line_start_cache = 0;
7904 w->line_cache_validation_override--;
7908 /* An extra check just in case the calling function didn't pass in
7909 the bounds of the DESIRED structs in the first place. */
7910 if (start >= low_bound && end <= high_bound)
7912 updating_line_start_cache = 0;
7913 w->line_cache_validation_override--;
7917 /* At this point we know that the internal cache partially overlaps
7919 if (start < low_bound)
7921 int ic_elt = Dynarr_length (internal_cache) - 1;
7924 if (Dynarr_atp (internal_cache, ic_elt)->start < low_bound)
7932 Dynarr_reset (cache);
7933 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7934 Dynarr_length (internal_cache));
7935 updating_line_start_cache = 0;
7936 w->line_cache_validation_override--;
7940 Dynarr_insert_many_at_start (cache, Dynarr_atp (internal_cache, 0),
7944 if (end > high_bound)
7948 while (ic_elt < Dynarr_length (internal_cache))
7950 if (Dynarr_atp (internal_cache, ic_elt)->start > high_bound)
7956 if (!(ic_elt < Dynarr_length (internal_cache)))
7958 Dynarr_reset (cache);
7959 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7960 Dynarr_length (internal_cache));
7961 updating_line_start_cache = 0;
7962 w->line_cache_validation_override--;
7966 Dynarr_add_many (cache, Dynarr_atp (internal_cache, ic_elt),
7967 Dynarr_length (internal_cache) - ic_elt);
7970 updating_line_start_cache = 0;
7971 w->line_cache_validation_override--;
7975 if (!Dynarr_length (cache) || from < low_bound)
7977 Bufpos startp = find_next_newline_no_quit (b, from, -1);
7979 int old_lb = low_bound;
7981 while (startp < old_lb || low_bound == -1)
7986 regenerate_window (w, startp, point, CMOTION_DISP);
7987 update_internal_cache_list (w, CMOTION_DISP);
7989 /* If this assert is triggered then regenerate_window failed
7990 to layout a single line. That is not supposed to be
7991 possible because we impose a minimum height on the buffer
7992 and override vertical clip when we are in here. */
7993 /* #### Ah, but it is because the window may temporarily
7994 exist but not have any lines at all if the minibuffer is
7995 real big. Look into that situation better. */
7996 if (!Dynarr_length (internal_cache))
7998 if (old_lb == -1 && low_bound == -1)
8000 updating_line_start_cache = 0;
8001 w->line_cache_validation_override--;
8005 assert (Dynarr_length (internal_cache));
8007 assert (startp == Dynarr_atp (internal_cache, 0)->start);
8009 ic_elt = Dynarr_length (internal_cache) - 1;
8010 if (low_bound != -1)
8014 if (Dynarr_atp (internal_cache, ic_elt)->start < old_lb)
8020 assert (ic_elt >= 0);
8022 new_startp = Dynarr_atp (internal_cache, ic_elt)->end + 1;
8025 * Handle invisible text properly:
8026 * If the last line we're inserting has the same end as the
8027 * line before which it will be added, merge the two lines.
8029 if (Dynarr_length (cache) &&
8030 Dynarr_atp (internal_cache, ic_elt)->end ==
8031 Dynarr_atp (cache, marker)->end)
8033 Dynarr_atp (cache, marker)->start
8034 = Dynarr_atp (internal_cache, ic_elt)->start;
8035 Dynarr_atp (cache, marker)->height
8036 = Dynarr_atp (internal_cache, ic_elt)->height;
8040 if (ic_elt >= 0) /* we still have lines to add.. */
8042 Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0),
8043 ic_elt + 1, marker);
8044 marker += (ic_elt + 1);
8047 if (startp < low_bound || low_bound == -1)
8049 startp = new_startp;
8050 if (startp > BUF_ZV (b))
8052 updating_line_start_cache = 0;
8053 w->line_cache_validation_override--;
8059 assert (Dynarr_length (cache));
8060 assert (from >= low_bound);
8062 /* Readjust the high_bound to account for any changes made while
8063 correcting the low_bound. */
8064 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8066 if (to > high_bound)
8068 Bufpos startp = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end + 1;
8072 regenerate_window (w, startp, point, CMOTION_DISP);
8073 update_internal_cache_list (w, CMOTION_DISP);
8075 /* See comment above about regenerate_window failing. */
8076 assert (Dynarr_length (internal_cache));
8078 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
8079 Dynarr_length (internal_cache));
8080 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8081 startp = high_bound + 1;
8083 while (to > high_bound);
8086 updating_line_start_cache = 0;
8087 w->line_cache_validation_override--;
8088 assert (to <= high_bound);
8092 /* Given x and y coordinates in characters, relative to a window,
8093 return the pixel location corresponding to those coordinates. The
8094 pixel location returned is the center of the given character
8095 position. The pixel values are generated relative to the window,
8098 The modeline is considered to be part of the window. */
8101 glyph_to_pixel_translation (struct window *w, int char_x, int char_y,
8102 int *pix_x, int *pix_y)
8104 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
8105 int num_disp_lines, modeline;
8107 int defheight, defwidth;
8109 XSETWINDOW (window, w);
8110 default_face_height_and_width (window, &defheight, &defwidth);
8112 /* If we get a bogus value indicating somewhere above or to the left of
8113 the window, use the first window line or character position
8120 num_disp_lines = Dynarr_length (dla);
8124 if (Dynarr_atp (dla, 0)->modeline)
8131 /* First check if the y position intersects the display lines. */
8132 if (char_y < num_disp_lines)
8134 struct display_line *dl = Dynarr_atp (dla, char_y + modeline);
8135 struct display_block *db = get_display_block_from_line (dl, TEXT);
8137 *pix_y = (dl->ypos - dl->ascent +
8138 ((unsigned int) (dl->ascent + dl->descent - dl->clip) >> 1));
8140 if (char_x < Dynarr_length (db->runes))
8142 struct rune *rb = Dynarr_atp (db->runes, char_x);
8144 *pix_x = rb->xpos + (rb->width >> 1);
8148 int last_rune = Dynarr_length (db->runes) - 1;
8149 struct rune *rb = Dynarr_atp (db->runes, last_rune);
8151 char_x -= last_rune;
8153 *pix_x = rb->xpos + rb->width;
8154 *pix_x += ((char_x - 1) * defwidth);
8155 *pix_x += (defwidth >> 1);
8160 /* It didn't intersect, so extrapolate. #### For now, we include the
8161 modeline in this since we don't have true character positions in
8164 if (!Dynarr_length (w->face_cachels))
8165 reset_face_cachels (w);
8167 char_y -= num_disp_lines;
8169 if (Dynarr_length (dla))
8171 struct display_line *dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
8172 *pix_y = dl->ypos + dl->descent - dl->clip;
8175 *pix_y = WINDOW_TEXT_TOP (w);
8177 *pix_y += (char_y * defheight);
8178 *pix_y += (defheight >> 1);
8180 *pix_x = WINDOW_TEXT_LEFT (w);
8181 /* Don't adjust by one because this is still the unadjusted value. */
8182 *pix_x += (char_x * defwidth);
8183 *pix_x += (defwidth >> 1);
8186 if (*pix_x > w->pixel_left + w->pixel_width)
8187 *pix_x = w->pixel_left + w->pixel_width;
8188 if (*pix_y > w->pixel_top + w->pixel_height)
8189 *pix_y = w->pixel_top + w->pixel_height;
8191 *pix_x -= w->pixel_left;
8192 *pix_y -= w->pixel_top;
8195 /* Given a display line and a position, determine if there is a glyph
8196 there and return information about it if there is. */
8199 get_position_object (struct display_line *dl, Lisp_Object *obj1,
8200 Lisp_Object *obj2, int x_coord, int *low_x_coord,
8203 struct display_block *db;
8206 get_next_display_block (dl->bounds, dl->display_blocks, x_coord, 0);
8208 /* We use get_next_display_block to get the actual display block
8209 that would be displayed at x_coord. */
8211 if (block == NO_BLOCK)
8214 db = Dynarr_atp (dl->display_blocks, block);
8216 for (elt = 0; elt < Dynarr_length (db->runes); elt++)
8218 struct rune *rb = Dynarr_atp (db->runes, elt);
8220 if (rb->xpos <= x_coord && x_coord < (rb->xpos + rb->width))
8222 if (rb->type == RUNE_DGLYPH)
8224 *obj1 = rb->object.dglyph.glyph;
8225 *obj2 = rb->object.dglyph.extent;
8234 *low_x_coord = rb->xpos;
8236 *high_x_coord = rb->xpos + rb->width;
8243 #define UPDATE_CACHE_RETURN \
8245 d->pixel_to_glyph_cache.valid = 1; \
8246 d->pixel_to_glyph_cache.low_x_coord = low_x_coord; \
8247 d->pixel_to_glyph_cache.high_x_coord = high_x_coord; \
8248 d->pixel_to_glyph_cache.low_y_coord = low_y_coord; \
8249 d->pixel_to_glyph_cache.high_y_coord = high_y_coord; \
8250 d->pixel_to_glyph_cache.frame = f; \
8251 d->pixel_to_glyph_cache.col = *col; \
8252 d->pixel_to_glyph_cache.row = *row; \
8253 d->pixel_to_glyph_cache.obj_x = *obj_x; \
8254 d->pixel_to_glyph_cache.obj_y = *obj_y; \
8255 d->pixel_to_glyph_cache.w = *w; \
8256 d->pixel_to_glyph_cache.bufpos = *bufpos; \
8257 d->pixel_to_glyph_cache.closest = *closest; \
8258 d->pixel_to_glyph_cache.modeline_closest = *modeline_closest; \
8259 d->pixel_to_glyph_cache.obj1 = *obj1; \
8260 d->pixel_to_glyph_cache.obj2 = *obj2; \
8261 d->pixel_to_glyph_cache.retval = position; \
8262 RETURN_SANS_WARNINGS position; \
8265 /* Given x and y coordinates in pixels relative to a frame, return
8266 information about what is located under those coordinates.
8268 The return value will be one of:
8270 OVER_TOOLBAR: over one of the 4 frame toolbars
8271 OVER_MODELINE: over a modeline
8272 OVER_BORDER: over an internal border
8273 OVER_NOTHING: over the text area, but not over text
8274 OVER_OUTSIDE: outside of the frame border
8275 OVER_TEXT: over text in the text area
8281 -- nil if the coordinates are not over a glyph or a toolbar button.
8285 -- an extent, if the coordinates are over a glyph in the text area
8288 If the coordinates are over a glyph, OBJ_X and OBJ_Y give the
8289 equivalent coordinates relative to the upper-left corner of the glyph.
8291 If the coordinates are over a character, OBJ_X and OBJ_Y give the
8292 equivalent coordinates relative to the upper-left corner of the character.
8294 Otherwise, OBJ_X and OBJ_Y are undefined.
8298 pixel_to_glyph_translation (struct frame *f, int x_coord, int y_coord,
8299 int *col, int *row, int *obj_x, int *obj_y,
8300 struct window **w, Bufpos *bufpos,
8301 Bufpos *closest, Charcount *modeline_closest,
8302 Lisp_Object *obj1, Lisp_Object *obj2)
8305 struct pixel_to_glyph_translation_cache *cache;
8307 int frm_left, frm_right, frm_top, frm_bottom;
8308 int low_x_coord, high_x_coord, low_y_coord, high_y_coord;
8309 int position = OVER_NOTHING;
8310 int device_check_failed = 0;
8311 display_line_dynarr *dla;
8313 /* This is a safety valve in case this got called with a frame in
8314 the middle of being deleted. */
8315 if (!DEVICEP (f->device) || !DEVICE_LIVE_P (XDEVICE (f->device)))
8317 device_check_failed = 1;
8318 d = NULL, cache = NULL; /* Warning suppression */
8322 d = XDEVICE (f->device);
8323 cache = &d->pixel_to_glyph_cache;
8326 if (!device_check_failed
8328 && cache->frame == f
8329 && cache->low_x_coord <= x_coord
8330 && cache->high_x_coord > x_coord
8331 && cache->low_y_coord <= y_coord
8332 && cache->high_y_coord > y_coord)
8336 *obj_x = cache->obj_x;
8337 *obj_y = cache->obj_y;
8339 *bufpos = cache->bufpos;
8340 *closest = cache->closest;
8341 *modeline_closest = cache->modeline_closest;
8342 *obj1 = cache->obj1;
8343 *obj2 = cache->obj2;
8345 return cache->retval;
8356 *modeline_closest = -1;
8360 low_x_coord = x_coord;
8361 high_x_coord = x_coord + 1;
8362 low_y_coord = y_coord;
8363 high_y_coord = y_coord + 1;
8366 if (device_check_failed)
8367 return OVER_NOTHING;
8369 frm_left = FRAME_LEFT_BORDER_END (f);
8370 frm_right = FRAME_RIGHT_BORDER_START (f);
8371 frm_top = FRAME_TOP_BORDER_END (f);
8372 frm_bottom = FRAME_BOTTOM_BORDER_START (f);
8374 /* Check if the mouse is outside of the text area actually used by
8376 if (y_coord < frm_top)
8378 if (y_coord >= FRAME_TOP_BORDER_START (f))
8380 low_y_coord = FRAME_TOP_BORDER_START (f);
8381 high_y_coord = frm_top;
8382 position = OVER_BORDER;
8384 else if (y_coord >= 0)
8387 high_y_coord = FRAME_TOP_BORDER_START (f);
8388 position = OVER_TOOLBAR;
8392 low_y_coord = y_coord;
8394 position = OVER_OUTSIDE;
8397 else if (y_coord >= frm_bottom)
8399 if (y_coord < FRAME_BOTTOM_BORDER_END (f))
8401 low_y_coord = frm_bottom;
8402 high_y_coord = FRAME_BOTTOM_BORDER_END (f);
8403 position = OVER_BORDER;
8405 else if (y_coord < FRAME_PIXHEIGHT (f))
8407 low_y_coord = FRAME_BOTTOM_BORDER_END (f);
8408 high_y_coord = FRAME_PIXHEIGHT (f);
8409 position = OVER_TOOLBAR;
8413 low_y_coord = FRAME_PIXHEIGHT (f);
8414 high_y_coord = y_coord;
8415 position = OVER_OUTSIDE;
8419 if (position != OVER_TOOLBAR && position != OVER_BORDER)
8421 if (x_coord < frm_left)
8423 if (x_coord >= FRAME_LEFT_BORDER_START (f))
8425 low_x_coord = FRAME_LEFT_BORDER_START (f);
8426 high_x_coord = frm_left;
8427 position = OVER_BORDER;
8429 else if (x_coord >= 0)
8432 high_x_coord = FRAME_LEFT_BORDER_START (f);
8433 position = OVER_TOOLBAR;
8437 low_x_coord = x_coord;
8439 position = OVER_OUTSIDE;
8442 else if (x_coord >= frm_right)
8444 if (x_coord < FRAME_RIGHT_BORDER_END (f))
8446 low_x_coord = frm_right;
8447 high_x_coord = FRAME_RIGHT_BORDER_END (f);
8448 position = OVER_BORDER;
8450 else if (x_coord < FRAME_PIXWIDTH (f))
8452 low_x_coord = FRAME_RIGHT_BORDER_END (f);
8453 high_x_coord = FRAME_PIXWIDTH (f);
8454 position = OVER_TOOLBAR;
8458 low_x_coord = FRAME_PIXWIDTH (f);
8459 high_x_coord = x_coord;
8460 position = OVER_OUTSIDE;
8465 #ifdef HAVE_TOOLBARS
8466 if (position == OVER_TOOLBAR)
8468 *obj1 = toolbar_button_at_pixpos (f, x_coord, y_coord);
8471 UPDATE_CACHE_RETURN;
8473 #endif /* HAVE_TOOLBARS */
8475 /* We still have to return the window the pointer is next to and its
8476 relative y position even if it is outside the x boundary. */
8477 if (x_coord < frm_left)
8479 else if (x_coord > frm_right)
8480 x_coord = frm_right;
8482 /* Same in reverse. */
8483 if (y_coord < frm_top)
8485 else if (y_coord > frm_bottom)
8486 y_coord = frm_bottom;
8488 /* Find what window the given coordinates are actually in. */
8489 window = f->root_window;
8490 *w = find_window_by_pixel_pos (x_coord, y_coord, window);
8492 /* If we didn't find a window, we're done. */
8495 UPDATE_CACHE_RETURN;
8497 else if (position != OVER_NOTHING)
8500 *modeline_closest = -1;
8502 if (high_y_coord <= frm_top || high_y_coord >= frm_bottom)
8505 UPDATE_CACHE_RETURN;
8509 /* Check if the window is a minibuffer but isn't active. */
8510 if (MINI_WINDOW_P (*w) && !minibuf_level)
8512 /* Must reset the window value since some callers will ignore
8513 the return value if it is set. */
8515 UPDATE_CACHE_RETURN;
8518 /* See if the point is over window vertical divider */
8519 if (window_needs_vertical_divider (*w))
8521 int div_x_high = WINDOW_RIGHT (*w);
8522 int div_x_low = div_x_high - window_divider_width (*w);
8523 int div_y_high = WINDOW_BOTTOM (*w);
8524 int div_y_low = WINDOW_TOP (*w);
8526 if (div_x_low < x_coord && x_coord <= div_x_high &&
8527 div_y_low < y_coord && y_coord <= div_y_high)
8529 low_x_coord = div_x_low;
8530 high_x_coord = div_x_high;
8531 low_y_coord = div_y_low;
8532 high_y_coord = div_y_high;
8533 position = OVER_V_DIVIDER;
8534 UPDATE_CACHE_RETURN;
8538 dla = window_display_lines (*w, CURRENT_DISP);
8540 for (*row = 0; *row < Dynarr_length (dla); (*row)++)
8542 int really_over_nothing = 0;
8543 struct display_line *dl = Dynarr_atp (dla, *row);
8545 if ((int) (dl->ypos - dl->ascent) <= y_coord
8546 && y_coord <= (int) (dl->ypos + dl->descent))
8548 int check_margin_glyphs = 0;
8549 struct display_block *db = get_display_block_from_line (dl, TEXT);
8550 struct rune *rb = 0;
8552 if (x_coord < dl->bounds.left_white
8553 || x_coord >= dl->bounds.right_white)
8554 check_margin_glyphs = 1;
8556 low_y_coord = dl->ypos - dl->ascent;
8557 high_y_coord = dl->ypos + dl->descent + 1;
8559 if (position == OVER_BORDER
8560 || position == OVER_OUTSIDE
8561 || check_margin_glyphs)
8563 int x_check, left_bound;
8565 if (check_margin_glyphs)
8568 left_bound = dl->bounds.left_white;
8572 x_check = high_x_coord;
8573 left_bound = frm_left;
8576 if (Dynarr_length (db->runes))
8578 if (x_check <= left_bound)
8581 *modeline_closest = Dynarr_atp (db->runes, 0)->bufpos;
8583 *closest = Dynarr_atp (db->runes, 0)->bufpos;
8589 Dynarr_atp (db->runes,
8590 Dynarr_length (db->runes) - 1)->bufpos;
8593 Dynarr_atp (db->runes,
8594 Dynarr_length (db->runes) - 1)->bufpos;
8598 *modeline_closest += dl->offset;
8600 *closest += dl->offset;
8604 /* #### What should be here. */
8606 *modeline_closest = 0;
8611 if (check_margin_glyphs)
8613 if (x_coord < dl->bounds.left_in
8614 || x_coord >= dl->bounds.right_in)
8616 /* If we are over the outside margins then we
8617 know the loop over the text block isn't going
8618 to accomplish anything. So we go ahead and
8619 set what information we can right here and
8622 *obj_y = y_coord - (dl->ypos - dl->ascent);
8623 get_position_object (dl, obj1, obj2, x_coord,
8624 &low_x_coord, &high_x_coord);
8626 UPDATE_CACHE_RETURN;
8630 UPDATE_CACHE_RETURN;
8633 for (*col = 0; *col <= Dynarr_length (db->runes); (*col)++)
8635 int past_end = (*col == Dynarr_length (db->runes));
8638 rb = Dynarr_atp (db->runes, *col);
8641 (rb->xpos <= x_coord && x_coord < rb->xpos + rb->width))
8646 rb = Dynarr_atp (db->runes, *col);
8649 *bufpos = rb->bufpos + dl->offset;
8650 low_x_coord = rb->xpos;
8651 high_x_coord = rb->xpos + rb->width;
8653 if (rb->type == RUNE_DGLYPH)
8657 /* Find the first character after the glyph. */
8658 while (elt < Dynarr_length (db->runes))
8660 if (Dynarr_atp (db->runes, elt)->type != RUNE_DGLYPH)
8664 (Dynarr_atp (db->runes, elt)->bufpos +
8668 (Dynarr_atp (db->runes, elt)->bufpos +
8676 /* In this case we failed to find a non-glyph
8677 character so we return the last position
8678 displayed on the line. */
8679 if (elt == Dynarr_length (db->runes))
8682 *modeline_closest = dl->end_bufpos + dl->offset;
8684 *closest = dl->end_bufpos + dl->offset;
8685 really_over_nothing = 1;
8691 *modeline_closest = rb->bufpos + dl->offset;
8693 *closest = rb->bufpos + dl->offset;
8698 *row = window_displayed_height (*w);
8700 if (position == OVER_NOTHING)
8701 position = OVER_MODELINE;
8703 if (rb->type == RUNE_DGLYPH)
8705 *obj1 = rb->object.dglyph.glyph;
8706 *obj2 = rb->object.dglyph.extent;
8708 else if (rb->type == RUNE_CHAR)
8719 UPDATE_CACHE_RETURN;
8722 || (rb->type == RUNE_CHAR
8723 && rb->object.chr.ch == '\n'))
8726 /* At this point we may have glyphs in the right
8728 if (check_margin_glyphs)
8729 get_position_object (dl, obj1, obj2, x_coord,
8730 &low_x_coord, &high_x_coord);
8731 UPDATE_CACHE_RETURN;
8736 if (rb->type == RUNE_DGLYPH)
8738 *obj1 = rb->object.dglyph.glyph;
8739 *obj2 = rb->object.dglyph.extent;
8741 else if (rb->type == RUNE_CHAR)
8752 *obj_x = x_coord - rb->xpos;
8753 *obj_y = y_coord - (dl->ypos - dl->ascent);
8755 /* At this point we may have glyphs in the left
8757 if (check_margin_glyphs)
8758 get_position_object (dl, obj1, obj2, x_coord, 0, 0);
8760 if (position == OVER_NOTHING && !really_over_nothing)
8761 position = OVER_TEXT;
8763 UPDATE_CACHE_RETURN;
8770 *row = Dynarr_length (dla) - 1;
8771 if (FRAME_WIN_P (f))
8773 int bot_elt = Dynarr_length (dla) - 1;
8777 struct display_line *dl = Dynarr_atp (dla, bot_elt);
8778 int adj_area = y_coord - (dl->ypos + dl->descent);
8782 XSETWINDOW (lwin, *w);
8783 default_face_height_and_width (lwin, 0, &defheight);
8785 *row += (adj_area / defheight);
8789 /* #### This should be checked out some more to determine what
8790 should really be going on. */
8791 if (!MARKERP ((*w)->start[CURRENT_DISP]))
8794 *closest = end_of_last_line (*w,
8795 marker_position ((*w)->start[CURRENT_DISP]));
8797 UPDATE_CACHE_RETURN;
8799 #undef UPDATE_CACHE_RETURN
8802 /***************************************************************************/
8804 /* Lisp functions */
8806 /***************************************************************************/
8808 DEFUN ("redisplay-echo-area", Fredisplay_echo_area, 0, 0, 0, /*
8809 Ensure that all minibuffers are correctly showing the echo area.
8813 Lisp_Object devcons, concons;
8815 DEVICE_LOOP_NO_BREAK (devcons, concons)
8817 struct device *d = XDEVICE (XCAR (devcons));
8818 Lisp_Object frmcons;
8820 DEVICE_FRAME_LOOP (frmcons, d)
8822 struct frame *f = XFRAME (XCAR (frmcons));
8824 if (FRAME_REPAINT_P (f) && FRAME_HAS_MINIBUF_P (f))
8826 Lisp_Object window = FRAME_MINIBUF_WINDOW (f);
8828 * If the frame size has changed, there may be random
8829 * chud on the screen left from previous messages
8830 * because redisplay_frame hasn't been called yet.
8831 * Clear the screen to get rid of the potential mess.
8833 if (f->echo_area_garbaged)
8835 DEVMETH (d, clear_frame, (f));
8836 f->echo_area_garbaged = 0;
8838 redisplay_window (window, 0);
8839 call_redisplay_end_triggers (XWINDOW (window), 0);
8843 /* We now call the output_end routine for tty frames. We delay
8844 doing so in order to avoid cursor flicker. So much for 100%
8846 if (DEVICE_TTY_P (d))
8847 DEVMETH (d, output_end, (d));
8854 restore_disable_preemption_value (Lisp_Object value)
8856 disable_preemption = XINT (value);
8860 DEFUN ("redraw-frame", Fredraw_frame, 0, 2, 0, /*
8861 Clear frame FRAME and output again what is supposed to appear on it.
8862 FRAME defaults to the selected frame if omitted.
8863 Normally, redisplay is preempted as normal if input arrives. However,
8864 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8865 input and is guaranteed to proceed to completion.
8867 (frame, no_preempt))
8869 struct frame *f = decode_frame (frame);
8870 int count = specpdl_depth ();
8872 if (!NILP (no_preempt))
8874 record_unwind_protect (restore_disable_preemption_value,
8875 make_int (disable_preemption));
8876 disable_preemption++;
8880 redisplay_frame (f, 1);
8882 return unbind_to (count, Qnil);
8885 DEFUN ("redisplay-frame", Fredisplay_frame, 0, 2, 0, /*
8886 Ensure that FRAME's contents are correctly displayed.
8887 This differs from `redraw-frame' in that it only redraws what needs to
8888 be updated, as opposed to unconditionally clearing and redrawing
8890 FRAME defaults to the selected frame if omitted.
8891 Normally, redisplay is preempted as normal if input arrives. However,
8892 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8893 input and is guaranteed to proceed to completion.
8895 (frame, no_preempt))
8897 struct frame *f = decode_frame (frame);
8898 int count = specpdl_depth ();
8900 if (!NILP (no_preempt))
8902 record_unwind_protect (restore_disable_preemption_value,
8903 make_int (disable_preemption));
8904 disable_preemption++;
8907 redisplay_frame (f, 1);
8909 return unbind_to (count, Qnil);
8912 DEFUN ("redraw-device", Fredraw_device, 0, 2, 0, /*
8913 Clear device DEVICE and output again what is supposed to appear on it.
8914 DEVICE defaults to the selected device if omitted.
8915 Normally, redisplay is preempted as normal if input arrives. However,
8916 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8917 input and is guaranteed to proceed to completion.
8919 (device, no_preempt))
8921 struct device *d = decode_device (device);
8922 Lisp_Object frmcons;
8923 int count = specpdl_depth ();
8925 if (!NILP (no_preempt))
8927 record_unwind_protect (restore_disable_preemption_value,
8928 make_int (disable_preemption));
8929 disable_preemption++;
8932 DEVICE_FRAME_LOOP (frmcons, d)
8934 XFRAME (XCAR (frmcons))->clear = 1;
8936 redisplay_device (d, 0);
8938 return unbind_to (count, Qnil);
8941 DEFUN ("redisplay-device", Fredisplay_device, 0, 2, 0, /*
8942 Ensure that DEVICE's contents are correctly displayed.
8943 This differs from `redraw-device' in that it only redraws what needs to
8944 be updated, as opposed to unconditionally clearing and redrawing
8946 DEVICE defaults to the selected device if omitted.
8947 Normally, redisplay is preempted as normal if input arrives. However,
8948 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8949 input and is guaranteed to proceed to completion.
8951 (device, no_preempt))
8953 struct device *d = decode_device (device);
8954 int count = specpdl_depth ();
8956 if (!NILP (no_preempt))
8958 record_unwind_protect (restore_disable_preemption_value,
8959 make_int (disable_preemption));
8960 disable_preemption++;
8963 redisplay_device (d, 0);
8965 return unbind_to (count, Qnil);
8968 /* Big lie. Big lie. This will force all modelines to be updated
8969 regardless if the all flag is set or not. It remains in existence
8970 solely for backwards compatibility. */
8971 DEFUN ("redraw-modeline", Fredraw_modeline, 0, 1, 0, /*
8972 Force the modeline of the current buffer to be redisplayed.
8973 With optional non-nil ALL, force redisplay of all modelines.
8977 MARK_MODELINE_CHANGED;
8981 DEFUN ("force-cursor-redisplay", Fforce_cursor_redisplay, 0, 1, 0, /*
8982 Force an immediate update of the cursor on FRAME.
8983 FRAME defaults to the selected frame if omitted.
8987 redisplay_redraw_cursor (decode_frame (frame), 1);
8992 /***************************************************************************/
8994 /* Lisp-variable change triggers */
8996 /***************************************************************************/
8999 margin_width_changed_in_frame (Lisp_Object specifier, struct frame *f,
9002 /* Nothing to be done? */
9006 redisplay_variable_changed (Lisp_Object sym, Lisp_Object *val,
9007 Lisp_Object in_object, int flags)
9009 /* #### clip_changed should really be renamed something like
9010 global_redisplay_change. */
9015 /* This is called if the built-in glyphs have their properties
9018 redisplay_glyph_changed (Lisp_Object glyph, Lisp_Object property,
9021 if (WINDOWP (locale))
9023 MARK_FRAME_GLYPHS_CHANGED (XFRAME (WINDOW_FRAME (XWINDOW (locale))));
9025 else if (FRAMEP (locale))
9027 MARK_FRAME_GLYPHS_CHANGED (XFRAME (locale));
9029 else if (DEVICEP (locale))
9031 Lisp_Object frmcons;
9032 DEVICE_FRAME_LOOP (frmcons, XDEVICE (locale))
9033 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9035 else if (CONSOLEP (locale))
9037 Lisp_Object frmcons, devcons;
9038 CONSOLE_FRAME_LOOP_NO_BREAK (frmcons, devcons, XCONSOLE (locale))
9039 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9041 else /* global or buffer */
9043 Lisp_Object frmcons, devcons, concons;
9044 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
9045 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9050 text_cursor_visible_p_changed (Lisp_Object specifier, struct window *w,
9053 if (XFRAME (w->frame)->init_finished)
9054 Fforce_cursor_redisplay (w->frame);
9057 #ifdef MEMORY_USAGE_STATS
9060 /***************************************************************************/
9062 /* memory usage computation */
9064 /***************************************************************************/
9067 compute_rune_dynarr_usage (rune_dynarr *dyn, struct overhead_stats *ovstats)
9069 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9073 compute_display_block_dynarr_usage (display_block_dynarr *dyn,
9074 struct overhead_stats *ovstats)
9081 total = Dynarr_memory_usage (dyn, ovstats);
9082 for (i = 0; i < Dynarr_largest (dyn); i++)
9083 total += compute_rune_dynarr_usage (Dynarr_at (dyn, i).runes, ovstats);
9089 compute_glyph_block_dynarr_usage (glyph_block_dynarr *dyn,
9090 struct overhead_stats *ovstats)
9092 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9096 compute_display_line_dynarr_usage (display_line_dynarr *dyn,
9097 struct overhead_stats *ovstats)
9104 total = Dynarr_memory_usage (dyn, ovstats);
9105 for (i = 0; i < Dynarr_largest (dyn); i++)
9107 struct display_line *dl = &Dynarr_at (dyn, i);
9108 total += compute_display_block_dynarr_usage(dl->display_blocks, ovstats);
9109 total += compute_glyph_block_dynarr_usage (dl->left_glyphs, ovstats);
9110 total += compute_glyph_block_dynarr_usage (dl->right_glyphs, ovstats);
9117 compute_line_start_cache_dynarr_usage (line_start_cache_dynarr *dyn,
9118 struct overhead_stats *ovstats)
9120 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9123 #endif /* MEMORY_USAGE_STATS */
9126 /***************************************************************************/
9128 /* initialization */
9130 /***************************************************************************/
9133 init_redisplay (void)
9135 disable_preemption = 0;
9136 preemption_count = 0;
9137 max_preempts = INIT_MAX_PREEMPTS;
9143 if (!cmotion_display_lines)
9144 cmotion_display_lines = Dynarr_new (display_line);
9145 if (!mode_spec_bufbyte_string)
9146 mode_spec_bufbyte_string = Dynarr_new (Bufbyte);
9147 if (!formatted_string_extent_dynarr)
9148 formatted_string_extent_dynarr = Dynarr_new (EXTENT);
9149 if (!formatted_string_extent_start_dynarr)
9150 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount);
9151 if (!formatted_string_extent_end_dynarr)
9152 formatted_string_extent_end_dynarr = Dynarr_new (Bytecount);
9153 if (!internal_cache)
9154 internal_cache = Dynarr_new (line_start_cache);
9157 /* window system is nil when in -batch mode */
9158 if (!initialized || noninteractive)
9161 /* If the user wants to use a window system, we shouldn't bother
9162 initializing the terminal. This is especially important when the
9163 terminal is so dumb that emacs gives up before and doesn't bother
9164 using the window system.
9166 If the DISPLAY environment variable is set, try to use X, and die
9167 with an error message if that doesn't work. */
9169 #ifdef HAVE_X_WINDOWS
9170 if (!strcmp (display_use, "x"))
9172 /* Some stuff checks this way early. */
9173 Vwindow_system = Qx;
9174 Vinitial_window_system = Qx;
9177 #endif /* HAVE_X_WINDOWS */
9179 #ifdef HAVE_MS_WINDOWS
9180 if (!strcmp (display_use, "mswindows"))
9182 /* Some stuff checks this way early. */
9183 Vwindow_system = Qmswindows;
9184 Vinitial_window_system = Qmswindows;
9187 #endif /* HAVE_MS_WINDOWS */
9190 /* If no window system has been specified, try to use the terminal. */
9193 stderr_out ("XEmacs: standard input is not a tty\n");
9197 /* Look at the TERM variable */
9198 if (!getenv ("TERM"))
9200 stderr_out ("Please set the environment variable TERM; see tset(1).\n");
9204 Vinitial_window_system = Qtty;
9206 #else /* not HAVE_TTY */
9207 /* No DISPLAY specified, and no TTY support. */
9208 stderr_out ("XEmacs: Cannot open display.\n\
9209 Please set the environmental variable DISPLAY to an appropriate value.\n");
9216 syms_of_redisplay (void)
9218 defsymbol (&Qcursor_in_echo_area, "cursor-in-echo-area");
9219 #ifndef INHIBIT_REDISPLAY_HOOKS
9220 defsymbol (&Qpre_redisplay_hook, "pre-redisplay-hook");
9221 defsymbol (&Qpost_redisplay_hook, "post-redisplay-hook");
9222 #endif /* INHIBIT_REDISPLAY_HOOKS */
9223 defsymbol (&Qdisplay_warning_buffer, "display-warning-buffer");
9224 defsymbol (&Qbar_cursor, "bar-cursor");
9225 defsymbol (&Qredisplay_end_trigger_functions,
9226 "redisplay-end-trigger-functions");
9228 DEFSUBR (Fredisplay_echo_area);
9229 DEFSUBR (Fredraw_frame);
9230 DEFSUBR (Fredisplay_frame);
9231 DEFSUBR (Fredraw_device);
9232 DEFSUBR (Fredisplay_device);
9233 DEFSUBR (Fredraw_modeline);
9234 DEFSUBR (Fforce_cursor_redisplay);
9238 reinit_vars_of_redisplay (void)
9240 updating_line_start_cache = 0;
9244 vars_of_redisplay (void)
9246 reinit_vars_of_redisplay ();
9249 staticpro (&last_arrow_position);
9250 staticpro (&last_arrow_string);
9251 last_arrow_position = Qnil;
9252 last_arrow_string = Qnil;
9255 /* #### Probably temporary */
9256 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /*
9257 \(Temporary) Setting this will impact the performance of the internal
9260 cache_adjustment = 2;
9262 DEFVAR_INT_MAGIC ("pixel-vertical-clip-threshold", &vertical_clip /*
9263 Minimum pixel height for clipped bottom display line.
9264 A clipped line shorter than this won't be displayed.
9266 redisplay_variable_changed);
9269 DEFVAR_INT_MAGIC ("pixel-horizontal-clip-threshold", &horizontal_clip /*
9270 Minimum visible area for clipped glyphs at right boundary.
9271 Clipped glyphs shorter than this won't be displayed.
9272 Only pixmap glyph instances are currently allowed to be clipped.
9274 redisplay_variable_changed);
9275 horizontal_clip = 5;
9277 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string /*
9278 String displayed by modeline-format's "%m" specification.
9280 Vglobal_mode_string = Qnil;
9282 DEFVAR_LISP_MAGIC ("overlay-arrow-position", &Voverlay_arrow_position /*
9283 Marker for where to display an arrow on top of the buffer text.
9284 This must be the beginning of a line in order to work.
9285 See also `overlay-arrow-string'.
9287 redisplay_variable_changed);
9288 Voverlay_arrow_position = Qnil;
9290 DEFVAR_LISP_MAGIC ("overlay-arrow-string", &Voverlay_arrow_string /*
9291 String to display as an arrow. See also `overlay-arrow-position'.
9293 redisplay_variable_changed);
9294 Voverlay_arrow_string = Qnil;
9296 DEFVAR_INT ("scroll-step", &scroll_step /*
9297 *The number of lines to try scrolling a window by when point moves out.
9298 If that fails to bring point back on frame, point is centered instead.
9299 If this is zero, point is always centered after it moves off screen.
9303 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively /*
9304 *Scroll up to this many lines, to bring point back on screen.
9306 scroll_conservatively = 0;
9308 DEFVAR_BOOL_MAGIC ("truncate-partial-width-windows",
9309 &truncate_partial_width_windows /*
9310 *Non-nil means truncate lines in all windows less than full frame wide.
9312 redisplay_variable_changed);
9313 truncate_partial_width_windows = 1;
9315 DEFVAR_BOOL ("visible-bell", &visible_bell /*
9316 *Non-nil means try to flash the frame to represent a bell.
9320 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter /*
9321 *Non-nil means no need to redraw entire frame after suspending.
9322 A non-nil value is useful if the terminal can automatically preserve
9323 Emacs's frame display when you reenter Emacs.
9324 It is up to you to set this variable if your terminal can do that.
9326 no_redraw_on_reenter = 0;
9328 DEFVAR_LISP ("window-system", &Vwindow_system /*
9329 A symbol naming the window-system under which Emacs is running,
9330 such as `x', or nil if emacs is running on an ordinary terminal.
9332 Do not use this variable, except for GNU Emacs compatibility, as it
9333 gives wrong values in a multi-device environment. Use `console-type'
9336 Vwindow_system = Qnil;
9338 /* #### Temporary shit until window-system is eliminated. */
9339 DEFVAR_CONST_LISP ("initial-window-system", &Vinitial_window_system /*
9342 Vinitial_window_system = Qnil;
9344 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area /*
9345 Non-nil means put cursor in minibuffer, at end of any message there.
9347 cursor_in_echo_area = 0;
9349 /* #### Shouldn't this be generalized as follows:
9351 if nil, use block cursor.
9352 if a number, use a bar cursor of that width.
9353 Otherwise, use a 1-pixel bar cursor.
9355 #### Or better yet, this variable should be trashed entirely
9356 (use a Lisp-magic variable to maintain compatibility)
9357 and a specifier `cursor-shape' added, which allows a block
9358 cursor, a bar cursor, a flashing block or bar cursor,
9359 maybe a caret cursor, etc. */
9361 DEFVAR_LISP ("bar-cursor", &Vbar_cursor /*
9362 Use vertical bar cursor if non-nil. If t width is 1 pixel, otherwise 2.
9366 #ifndef INHIBIT_REDISPLAY_HOOKS
9367 xxDEFVAR_LISP ("pre-redisplay-hook", &Vpre_redisplay_hook /*
9368 Function or functions to run before every redisplay.
9369 Functions on this hook must be careful to avoid signalling errors!
9371 Vpre_redisplay_hook = Qnil;
9373 xxDEFVAR_LISP ("post-redisplay-hook", &Vpost_redisplay_hook /*
9374 Function or functions to run after every redisplay.
9375 Functions on this hook must be careful to avoid signalling errors!
9377 Vpost_redisplay_hook = Qnil;
9378 #endif /* INHIBIT_REDISPLAY_HOOKS */
9380 DEFVAR_INT ("display-warning-tick", &display_warning_tick /*
9381 Bump this to tell the C code to call `display-warning-buffer'
9382 at next redisplay. You should not normally change this; the function
9383 `display-warning' automatically does this at appropriate times.
9385 display_warning_tick = 0;
9387 DEFVAR_BOOL ("inhibit-warning-display", &inhibit_warning_display /*
9388 Non-nil means inhibit display of warning messages.
9389 You should *bind* this, not set it. Any pending warning messages
9390 will be displayed when the binding no longer applies.
9392 /* reset to 0 by startup.el after the splash screen has displayed.
9393 This way, the warnings don't obliterate the splash screen. */
9394 inhibit_warning_display = 1;
9396 DEFVAR_LISP ("window-size-change-functions",
9397 &Vwindow_size_change_functions /*
9398 Not currently implemented.
9399 Functions called before redisplay, if window sizes have changed.
9400 The value should be a list of functions that take one argument.
9401 Just before redisplay, for each frame, if any of its windows have changed
9402 size since the last redisplay, or have been split or deleted,
9403 all the functions in the list are called, with the frame as argument.
9405 Vwindow_size_change_functions = Qnil;
9407 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions /*
9408 Not currently implemented.
9409 Functions to call before redisplaying a window with scrolling.
9410 Each function is called with two arguments, the window
9411 and its new display-start position. Note that the value of `window-end'
9412 is not valid when these functions are called.
9414 Vwindow_scroll_functions = Qnil;
9416 DEFVAR_LISP ("redisplay-end-trigger-functions",
9417 &Vredisplay_end_trigger_functions /*
9418 See `set-window-redisplay-end-trigger'.
9420 Vredisplay_end_trigger_functions = Qnil;
9422 DEFVAR_BOOL ("column-number-start-at-one", &column_number_start_at_one /*
9423 *Non-nil means column display number starts at 1.
9425 column_number_start_at_one = 0;
9429 specifier_vars_of_redisplay (void)
9431 DEFVAR_SPECIFIER ("left-margin-width", &Vleft_margin_width /*
9432 *Width of left margin.
9433 This is a specifier; use `set-specifier' to change it.
9435 Vleft_margin_width = Fmake_specifier (Qnatnum);
9436 set_specifier_fallback (Vleft_margin_width, list1 (Fcons (Qnil, Qzero)));
9437 set_specifier_caching (Vleft_margin_width,
9438 offsetof (struct window, left_margin_width),
9439 some_window_value_changed,
9440 offsetof (struct frame, left_margin_width),
9441 margin_width_changed_in_frame);
9443 DEFVAR_SPECIFIER ("right-margin-width", &Vright_margin_width /*
9444 *Width of right margin.
9445 This is a specifier; use `set-specifier' to change it.
9447 Vright_margin_width = Fmake_specifier (Qnatnum);
9448 set_specifier_fallback (Vright_margin_width, list1 (Fcons (Qnil, Qzero)));
9449 set_specifier_caching (Vright_margin_width,
9450 offsetof (struct window, right_margin_width),
9451 some_window_value_changed,
9452 offsetof (struct frame, right_margin_width),
9453 margin_width_changed_in_frame);
9455 DEFVAR_SPECIFIER ("minimum-line-ascent", &Vminimum_line_ascent /*
9456 *Minimum ascent height of lines.
9457 This is a specifier; use `set-specifier' to change it.
9459 Vminimum_line_ascent = Fmake_specifier (Qnatnum);
9460 set_specifier_fallback (Vminimum_line_ascent, list1 (Fcons (Qnil, Qzero)));
9461 set_specifier_caching (Vminimum_line_ascent,
9462 offsetof (struct window, minimum_line_ascent),
9463 some_window_value_changed,
9466 DEFVAR_SPECIFIER ("minimum-line-descent", &Vminimum_line_descent /*
9467 *Minimum descent height of lines.
9468 This is a specifier; use `set-specifier' to change it.
9470 Vminimum_line_descent = Fmake_specifier (Qnatnum);
9471 set_specifier_fallback (Vminimum_line_descent, list1 (Fcons (Qnil, Qzero)));
9472 set_specifier_caching (Vminimum_line_descent,
9473 offsetof (struct window, minimum_line_descent),
9474 some_window_value_changed,
9477 DEFVAR_SPECIFIER ("use-left-overflow", &Vuse_left_overflow /*
9478 *Non-nil means use the left outside margin as extra whitespace when
9479 displaying 'whitespace or 'inside-margin glyphs.
9480 This is a specifier; use `set-specifier' to change it.
9482 Vuse_left_overflow = Fmake_specifier (Qboolean);
9483 set_specifier_fallback (Vuse_left_overflow, list1 (Fcons (Qnil, Qnil)));
9484 set_specifier_caching (Vuse_left_overflow,
9485 offsetof (struct window, use_left_overflow),
9486 some_window_value_changed,
9489 DEFVAR_SPECIFIER ("use-right-overflow", &Vuse_right_overflow /*
9490 *Non-nil means use the right outside margin as extra whitespace when
9491 displaying 'whitespace or 'inside-margin glyphs.
9492 This is a specifier; use `set-specifier' to change it.
9494 Vuse_right_overflow = Fmake_specifier (Qboolean);
9495 set_specifier_fallback (Vuse_right_overflow, list1 (Fcons (Qnil, Qnil)));
9496 set_specifier_caching (Vuse_right_overflow,
9497 offsetof (struct window, use_right_overflow),
9498 some_window_value_changed,
9501 DEFVAR_SPECIFIER ("text-cursor-visible-p", &Vtext_cursor_visible_p /*
9502 *Non-nil means the text cursor is visible (this is usually the case).
9503 This is a specifier; use `set-specifier' to change it.
9505 Vtext_cursor_visible_p = Fmake_specifier (Qboolean);
9506 set_specifier_fallback (Vtext_cursor_visible_p, list1 (Fcons (Qnil, Qt)));
9507 set_specifier_caching (Vtext_cursor_visible_p,
9508 offsetof (struct window, text_cursor_visible_p),
9509 text_cursor_visible_p_changed,