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 /* This makes sure the glyph is in the cachels.
1533 #### We need to change this so that we hold onto the glyph_index
1534 here, not the glyph itself. */
1535 get_glyph_cachel_index (w, gb->glyph);
1537 /* A nil extent indicates a special glyph (ex. truncator). */
1538 if (NILP (gb->extent)
1539 || (pos_type == BEGIN_GLYPHS &&
1540 extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT)
1541 || (pos_type == END_GLYPHS &&
1542 extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_TEXT))
1547 int ascent, descent;
1548 Lisp_Object baseline;
1552 width = cachel->width;
1554 width = glyph_width (gb->glyph, data->window);
1559 if (data->start_col || data->start_col_xoffset)
1561 prop_block_dynarr *retval;
1562 int glyph_char_width = width / space_width (w);
1564 /* If we still have not fully scrolled horizontally after
1565 taking into account the width of the glyph, subtract its
1566 width and return. */
1567 if (glyph_char_width < data->start_col)
1569 data->start_col -= glyph_char_width;
1572 else if (glyph_char_width == data->start_col)
1576 xoffset = space_width (w) * data->start_col;
1579 /* #### Can this happen? */
1584 data->start_col = 0;
1585 retval = add_hscroll_rune (data);
1587 /* Could be caused by the handling of the hscroll rune. */
1588 if (retval != NULL || !width)
1594 if (data->pixpos + width > data->max_pixpos)
1596 /* If this is the first object we are attempting to add to
1597 the line then we ignore the horizontal_clip threshold.
1598 Otherwise we will loop until the bottom of the window
1599 continually failing to add this glyph because it is wider
1600 than the window. We could alternatively just completely
1601 ignore the glyph and proceed from there but I think that
1602 this is a better solution. */
1603 if (Dynarr_length (data->db->runes)
1604 && data->max_pixpos - data->pixpos < horizontal_clip)
1607 width = data->max_pixpos - data->pixpos;
1612 ascent = cachel->ascent;
1613 descent = cachel->descent;
1617 ascent = glyph_ascent (gb->glyph, data->window);
1618 descent = glyph_descent (gb->glyph, data->window);
1621 baseline = glyph_baseline (gb->glyph, data->window);
1623 if (glyph_contrib_p (gb->glyph, data->window))
1625 /* A pixmap that has not had a baseline explicitly set. Its
1626 contribution will be determined later. */
1627 if (NILP (baseline))
1629 int height = ascent + descent;
1630 data->max_pixmap_height = max (data->max_pixmap_height, height);
1633 /* A string so determine contribution normally. */
1634 else if (EQ (baseline, Qt))
1636 data->new_ascent = max (data->new_ascent, ascent);
1637 data->new_descent = max (data->new_descent, descent);
1640 /* A pixmap with an explicitly set baseline. We determine the
1641 contribution here. */
1642 else if (INTP (baseline))
1644 int height = ascent + descent;
1645 int pix_ascent, pix_descent;
1647 pix_ascent = height * XINT (baseline) / 100;
1648 pix_descent = height - pix_ascent;
1650 data->new_ascent = max (data->new_ascent, pix_ascent);
1651 data->new_descent = max (data->new_descent, pix_descent);
1654 /* Otherwise something is screwed up. */
1659 face = glyph_face (gb->glyph, data->window);
1661 rb.findex = data->findex;
1663 rb.findex = get_builtin_face_cache_index (w, face);
1665 rb.xpos = data->pixpos;
1667 rb.bufpos = 0; /* glyphs are never "at" anywhere */
1668 if (data->bi_endpos)
1669 /* #### is this necessary at all? */
1670 rb.endpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1674 rb.type = RUNE_DGLYPH;
1675 /* #### Ben sez: this is way bogus if the glyph is a string.
1676 You should not make the output routines have to cope with
1677 this. The string could contain Mule characters, or non-
1678 printable characters, or characters to be passed through
1679 the display table, or non-character objects (when this gets
1680 implemented), etc. Instead, this routine here should parse
1681 the string into a series of runes. */
1682 rb.object.dglyph.glyph = gb->glyph;
1683 rb.object.dglyph.extent = gb->extent;
1684 rb.object.dglyph.xoffset = xoffset;
1688 rb.bufpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)),
1691 if (data->cursor_type == CURSOR_ON)
1693 if (data->bi_bufpos == data->bi_cursor_bufpos)
1695 rb.cursor_type = CURSOR_ON;
1696 data->cursor_x = Dynarr_length (data->db->runes);
1699 rb.cursor_type = CURSOR_OFF;
1701 else if (data->cursor_type == NEXT_CURSOR)
1703 rb.cursor_type = CURSOR_ON;
1704 data->cursor_x = Dynarr_length (data->db->runes);
1705 data->cursor_type = NO_CURSOR;
1707 else if (data->cursor_type == IGNORE_CURSOR)
1708 rb.cursor_type = IGNORE_CURSOR;
1709 else if (data->cursor_type == NO_CURSOR)
1710 rb.cursor_type = NO_CURSOR;
1712 rb.cursor_type = CURSOR_OFF;
1715 rb.cursor_type = CURSOR_OFF;
1717 Dynarr_add (data->db->runes, rb);
1718 data->pixpos += width;
1724 if (!NILP (glyph_face (gb->glyph, data->window)))
1726 get_builtin_face_cache_index (w, glyph_face (gb->glyph,
1729 gb->findex = data->findex;
1731 if (pos_type == BEGIN_GLYPHS)
1733 if (!data->dl->left_glyphs)
1734 data->dl->left_glyphs = Dynarr_new (glyph_block);
1735 Dynarr_add (data->dl->left_glyphs, *gb);
1738 else if (pos_type == END_GLYPHS)
1740 if (!data->dl->right_glyphs)
1741 data->dl->right_glyphs = Dynarr_new (glyph_block);
1742 Dynarr_add (data->dl->right_glyphs, *gb);
1746 abort (); /* there are no unknown types */
1749 return NULL; /* shut up compiler */
1752 /* Add all glyphs at position POS_TYPE that are contained in the given
1755 static prop_block_dynarr *
1756 add_glyph_runes (pos_data *data, int pos_type)
1758 /* #### This still needs to handle the start_col parameter. Duh, Chuck,
1759 why didn't you just modify add_glyph_rune in the first place? */
1761 glyph_block_dynarr *glyph_arr = (pos_type == BEGIN_GLYPHS
1762 ? data->ef->begin_glyphs
1763 : data->ef->end_glyphs);
1764 prop_block_dynarr *prop;
1766 for (elt = 0; elt < Dynarr_length (glyph_arr); elt++)
1768 prop = add_glyph_rune (data, Dynarr_atp (glyph_arr, elt), pos_type, 0,
1773 /* #### Add some propagation information. */
1778 Dynarr_reset (glyph_arr);
1783 /* Given a position for a buffer in a window, ensure that the given
1784 display line DL accurately represents the text on a line starting
1785 at the given position.
1787 NOTE NOTE NOTE NOTE: This function works with and returns Bytinds.
1788 You must do appropriate conversion. */
1791 create_text_block (struct window *w, struct display_line *dl,
1792 Bytind bi_start_pos, prop_block_dynarr **prop,
1795 struct frame *f = XFRAME (w->frame);
1796 struct buffer *b = XBUFFER (w->buffer);
1797 struct device *d = XDEVICE (f->device);
1801 /* Don't display anything in the minibuffer if this window is not on
1802 a selected frame. We consider all other windows to be active
1803 minibuffers as it simplifies the coding. */
1804 int active_minibuffer = (!MINI_WINDOW_P (w) ||
1805 (f == device_selected_frame (d)) ||
1806 is_surrogate_for_selected_frame (f));
1808 int truncate_win = window_truncation_on (w);
1809 int end_glyph_width;
1811 /* If the buffer's value of selective_display is an integer then
1812 only lines that start with less than selective_display columns of
1813 space will be displayed. If selective_display is t then all text
1814 after a ^M is invisible. */
1815 int selective = (INTP (b->selective_display)
1816 ? XINT (b->selective_display)
1817 : (!NILP (b->selective_display) ? -1 : 0));
1819 /* The variable ctl-arrow allows the user to specify what characters
1820 can actually be displayed and which octal should be used for.
1821 #### This variable should probably have some rethought done to
1824 #### It would also be really nice if you could specify that
1825 the characters come out in hex instead of in octal. Mule
1826 does that by adding a ctl-hexa variable similar to ctl-arrow,
1827 but that's bogus -- we need a more general solution. I
1828 think you need to extend the concept of display tables
1829 into a more general conversion mechanism. Ideally you
1830 could specify a Lisp function that converts characters,
1831 but this violates the Second Golden Rule and besides would
1832 make things way way way way slow.
1834 So instead, we extend the display-table concept, which was
1835 historically limited to 256-byte vectors, to one of the
1838 a) A 256-entry vector, for backward compatibility;
1839 b) char-table, mapping characters to values;
1840 c) range-table, mapping ranges of characters to values;
1841 d) a list of the above.
1843 The (d) option allows you to specify multiple display tables
1844 instead of just one. Each display table can specify conversions
1845 for some characters and leave others unchanged. The way the
1846 character gets displayed is determined by the first display table
1847 with a binding for that character. This way, you could call a
1848 function `enable-hex-display' that adds a hex display-table to
1849 the list of display tables for the current buffer.
1851 #### ...not yet implemented... Also, we extend the concept of
1852 "mapping" to include a printf-like spec. Thus you can make all
1853 extended characters show up as hex with a display table like
1856 #s(range-table data ((256 524288) (format "%x")))
1858 Since more than one display table is possible, you have
1859 great flexibility in mapping ranges of characters. */
1860 Emchar printable_min = (CHAR_OR_CHAR_INTP (b->ctl_arrow)
1861 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
1862 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
1865 Lisp_Object face_dt, window_dt;
1867 /* The text display block for this display line. */
1868 struct display_block *db = get_display_block_from_line (dl, TEXT);
1870 /* The first time through the main loop we need to force the glyph
1871 data to be updated. */
1874 /* Apparently the new extent_fragment_update returns an end position
1875 equal to the position passed in if there are no more runs to be
1877 int no_more_frags = 0;
1879 Lisp_Object synch_minibuffers_value =
1880 symbol_value_in_buffer (Qsynchronize_minibuffers, w->buffer);
1882 dl->used_prop_data = 0;
1886 data.ef = extent_fragment_new (w->buffer, f);
1888 /* These values are used by all of the rune addition routines. We add
1889 them to this structure for ease of passing. */
1891 XSETWINDOW (data.window, w);
1896 data.bi_bufpos = bi_start_pos;
1897 data.pixpos = dl->bounds.left_in;
1898 data.last_charset = Qunbound;
1899 data.last_findex = DEFAULT_INDEX;
1900 data.result_str = Qnil;
1902 /* Set the right boundary adjusting it to take into account any end
1903 glyph. Save the width of the end glyph for later use. */
1904 data.max_pixpos = dl->bounds.right_in;
1906 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
1908 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
1909 data.max_pixpos -= end_glyph_width;
1911 if (cursor_in_echo_area && MINI_WINDOW_P (w) && echo_area_active (f))
1913 data.bi_cursor_bufpos = BI_BUF_ZV (b);
1914 data.cursor_type = CURSOR_ON;
1916 else if (MINI_WINDOW_P (w) && !active_minibuffer)
1917 data.cursor_type = NO_CURSOR;
1918 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)) &&
1919 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
1920 d == XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d))))&&
1921 f == XFRAME(DEVICE_SELECTED_FRAME(d)))
1923 data.bi_cursor_bufpos = BI_BUF_PT (b);
1924 data.cursor_type = CURSOR_ON;
1926 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)))
1928 data.bi_cursor_bufpos = bi_marker_position (w->pointm[type]);
1929 data.cursor_type = CURSOR_ON;
1932 data.cursor_type = NO_CURSOR;
1935 data.start_col = w->hscroll;
1936 data.start_col_xoffset = w->left_xoffset;
1937 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
1938 data.hscroll_glyph_width_adjust = 0;
1940 /* We regenerate the line from the very beginning. */
1941 Dynarr_reset (db->runes);
1943 /* Why is this less than or equal and not just less than? If the
1944 starting position is already equal to the maximum we can't add
1945 anything else, right? Wrong. We might still have a newline to
1946 add. A newline can use the room allocated for an end glyph since
1947 if we add it we know we aren't going to be adding any end
1950 /* #### Chuck -- I think this condition should be while (1).
1951 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
1952 and the begin-glyph ends exactly at the end of the window, the
1953 end-glyph and text might not be displayed. while (1) ensures
1954 that the loop terminates only when either (a) there is
1955 propagation data or (b) the end-of-line or end-of-buffer is hit.
1957 #### Also I think you need to ensure that the operation
1958 "add begin glyphs; add end glyphs; add text" is atomic and
1959 can't get interrupted in the middle. If you run off the end
1960 of the line during that operation, then you keep accumulating
1961 propagation data until you're done. Otherwise, if the (e.g.)
1962 there's a begin glyph at a particular position and attempting
1963 to display that glyph results in window-end being hit and
1964 propagation data being generated, then the character at that
1965 position won't be displayed.
1967 #### See also the comment after the end of this loop, below.
1969 while (data.pixpos <= data.max_pixpos
1970 && (active_minibuffer || !NILP (synch_minibuffers_value)))
1972 /* #### This check probably should not be necessary. */
1973 if (data.bi_bufpos > BI_BUF_ZV (b))
1975 /* #### urk! More of this lossage! */
1980 /* If selective display was an integer and we aren't working on
1981 a continuation line then find the next line we are actually
1982 supposed to display. */
1984 && (data.bi_bufpos == BI_BUF_BEGV (b)
1985 || BUF_FETCH_CHAR (b, prev_bytind (b, data.bi_bufpos)) == '\n'))
1987 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
1990 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
1991 if (data.bi_bufpos >= BI_BUF_ZV (b))
1993 data.bi_bufpos = BI_BUF_ZV (b);
1999 /* Check for face changes. */
2000 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
2002 /* Now compute the face and begin/end-glyph information. */
2004 /* Remember that the extent-fragment routines deal in Bytind's. */
2005 extent_fragment_update (w, data.ef, data.bi_bufpos);
2007 get_display_tables (w, data.findex, &face_dt, &window_dt);
2009 if (data.bi_bufpos == data.ef->end)
2014 /* Determine what is next to be displayed. We first handle any
2015 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
2016 display then we determine what to do based on the character at the
2017 current buffer position. */
2019 /* If the current position is covered by an invisible extent, do
2020 nothing (except maybe add some ellipses).
2022 #### The behavior of begin and end-glyphs at the edge of an
2023 invisible extent should be investigated further. This is
2024 fairly low priority though. */
2025 if (data.ef->invisible)
2027 /* #### Chuck, perhaps you could look at this code? I don't
2028 really know what I'm doing. */
2031 Dynarr_free (*prop);
2035 /* The extent fragment code only sets this when we should
2036 really display the ellipses. It makes sure the ellipses
2037 don't get displayed more than once in a row. */
2038 if (data.ef->invisible_ellipses)
2040 struct glyph_block gb;
2042 data.ef->invisible_ellipses_already_displayed = 1;
2043 data.ef->invisible_ellipses = 0;
2045 gb.glyph = Vinvisible_text_glyph;
2046 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2047 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2048 /* Perhaps they shouldn't propagate if the very next thing
2049 is to display a newline (for compatibility with
2050 selective-display-ellipses)? Maybe that's too
2056 /* If point is in an invisible region we place it on the
2057 next visible character. */
2058 if (data.cursor_type == CURSOR_ON
2059 && data.bi_bufpos == data.bi_cursor_bufpos)
2061 data.cursor_type = NEXT_CURSOR;
2064 /* #### What if we we're dealing with a display table? */
2068 if (data.bi_bufpos == BI_BUF_ZV (b))
2071 INC_BYTIND (b, data.bi_bufpos);
2074 /* If there is propagation data, then it represents the current
2075 buffer position being displayed. Add them and advance the
2076 position counter. This might also add the minibuffer
2080 dl->used_prop_data = 1;
2081 *prop = add_propagation_runes (prop, &data);
2084 goto done; /* gee, a really narrow window */
2085 else if (data.bi_bufpos == BI_BUF_ZV (b))
2087 else if (data.bi_bufpos < BI_BUF_BEGV (b))
2088 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
2089 data.bi_bufpos = BI_BUF_BEGV (b);
2091 INC_BYTIND (b, data.bi_bufpos);
2094 /* If there are end glyphs, add them to the line. These are
2095 the end glyphs for the previous run of text. We add them
2096 here rather than doing them at the end of handling the
2097 previous run so that glyphs at the beginning and end of
2098 a line are handled correctly. */
2099 else if (Dynarr_length (data.ef->end_glyphs) > 0)
2101 *prop = add_glyph_runes (&data, END_GLYPHS);
2106 /* If there are begin glyphs, add them to the line. */
2107 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
2109 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
2114 /* If at end-of-buffer, we've already processed begin and
2115 end-glyphs at this point and there's no text to process,
2117 else if (data.bi_bufpos == BI_BUF_ZV (b))
2122 Lisp_Object entry = Qnil;
2123 /* Get the character at the current buffer position. */
2124 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2125 if (!NILP (face_dt) || !NILP (window_dt))
2126 entry = display_table_entry (data.ch, face_dt, window_dt);
2128 /* If there is a display table entry for it, hand it off to
2129 add_disp_table_entry_runes and let it worry about it. */
2130 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
2132 *prop = add_disp_table_entry_runes (&data, entry);
2138 /* Check if we have hit a newline character. If so, add a marker
2139 to the line and end this loop. */
2140 else if (data.ch == '\n')
2142 /* We aren't going to be adding an end glyph so give its
2143 space back in order to make sure that the cursor can
2145 data.max_pixpos += end_glyph_width;
2148 && (bi_spaces_at_point
2149 (b, next_bytind (b, data.bi_bufpos))
2152 if (!NILP (b->selective_display_ellipses))
2154 struct glyph_block gb;
2157 gb.glyph = Vinvisible_text_glyph;
2158 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2159 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2163 /* Cheesy, cheesy, cheesy. We mark the end of the
2164 line with a special "character rune" whose width
2165 is the EOL cursor width and whose character is
2166 the non-printing character '\n'. */
2167 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2168 *prop = add_emchar_rune (&data);
2171 /* We need to set data.bi_bufpos to the start of the
2172 next visible region in order to make this line
2173 appear to contain all of the invisible area.
2174 Otherwise, the line cache won't work
2176 INC_BYTIND (b, data.bi_bufpos);
2177 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective)
2180 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2181 if (data.bi_bufpos >= BI_BUF_ZV (b))
2183 data.bi_bufpos = BI_BUF_ZV (b);
2187 if (BI_BUF_FETCH_CHAR
2188 (b, prev_bytind (b, data.bi_bufpos)) == '\n')
2189 DEC_BYTIND (b, data.bi_bufpos);
2193 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2194 *prop = add_emchar_rune (&data);
2200 /* If the current character is ^M, and selective display is
2201 enabled, then add the invisible-text-glyph if
2202 selective-display-ellipses is set. In any case, this
2204 else if (data.ch == (('M' & 037)) && selective == -1)
2206 Bytind bi_next_bufpos;
2208 /* Find the buffer position at the end of the line. */
2210 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2211 if (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_next_bufpos))
2213 DEC_BYTIND (b, bi_next_bufpos);
2215 /* If the cursor is somewhere in the elided text make
2216 sure that the cursor gets drawn appropriately. */
2217 if (data.cursor_type == CURSOR_ON
2218 && (data.bi_cursor_bufpos >= data.bi_bufpos &&
2219 data.bi_cursor_bufpos < bi_next_bufpos))
2221 data.cursor_type = NEXT_CURSOR;
2224 /* We won't be adding a truncation or continuation glyph
2225 so give up the room allocated for them. */
2226 data.max_pixpos += end_glyph_width;
2228 if (!NILP (b->selective_display_ellipses))
2230 /* We don't propagate anything from the invisible
2231 text glyph if it fails to fit. This is
2233 struct glyph_block gb;
2236 gb.glyph = Vinvisible_text_glyph;
2237 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 1,
2238 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2241 /* Set the buffer position to the end of the line. We
2242 need to do this before potentially adding a newline
2243 so that the cursor flag will get set correctly (if
2245 data.bi_bufpos = bi_next_bufpos;
2247 if (NILP (b->selective_display_ellipses)
2248 || data.bi_cursor_bufpos == bi_next_bufpos)
2250 /* We have to at least add a newline character so
2251 that the cursor shows up properly. */
2253 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2254 data.findex = DEFAULT_INDEX;
2256 data.start_col_xoffset = 0;
2257 data.bi_start_col_enabled = 0;
2259 add_emchar_rune (&data);
2262 /* This had better be a newline but doing it this way
2263 we'll see obvious incorrect results if it isn't. No
2264 need to abort here. */
2265 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
2270 /* If the current character is considered to be printable, then
2272 else if (data.ch >= printable_min)
2274 *prop = add_emchar_rune (&data);
2279 /* If the current character is a tab, determine the next tab
2280 starting position and add a blank rune which extends from the
2281 current pixel position to that starting position. */
2282 else if (data.ch == '\t')
2284 int tab_start_pixpos = data.pixpos;
2289 if (data.start_col > 1)
2290 tab_start_pixpos -= (space_width (w) * (data.start_col - 1))
2291 + data.start_col_xoffset;
2294 next_tab_position (w, tab_start_pixpos,
2295 dl->bounds.left_in +
2296 data.hscroll_glyph_width_adjust);
2297 if (next_tab_start > data.max_pixpos)
2299 prop_width = next_tab_start - data.max_pixpos;
2300 next_tab_start = data.max_pixpos;
2302 data.blank_width = next_tab_start - data.pixpos;
2304 (next_tab_start - tab_start_pixpos) / space_width (w);
2306 *prop = add_blank_rune (&data, w, char_tab_width);
2308 /* add_blank_rune is only supposed to be called with
2309 sizes guaranteed to fit in the available space. */
2314 struct prop_block pb;
2315 *prop = Dynarr_new (prop_block);
2317 pb.type = PROP_BLANK;
2318 pb.data.p_blank.width = prop_width;
2319 pb.data.p_blank.findex = data.findex;
2320 Dynarr_add (*prop, pb);
2326 /* If character is a control character, pass it off to
2327 add_control_char_runes.
2329 The is_*() routines have undefined results on
2330 arguments outside of the range [-1, 255]. (This
2331 often bites people who carelessly use `char' instead
2332 of `unsigned char'.)
2334 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
2336 *prop = add_control_char_runes (&data, b);
2342 /* If the character is above the ASCII range and we have not
2343 already handled it, then print it as an octal number. */
2344 else if (data.ch >= 0200)
2346 *prop = add_octal_runes (&data);
2352 /* Assume the current character is considered to be printable,
2353 then just add it. */
2356 *prop = add_emchar_rune (&data);
2361 INC_BYTIND (b, data.bi_bufpos);
2367 /* Determine the starting point of the next line if we did not hit the
2368 end of the buffer. */
2369 if (data.bi_bufpos < BI_BUF_ZV (b)
2370 && (active_minibuffer || !NILP (synch_minibuffers_value)))
2372 /* #### This check is not correct. If the line terminated
2373 due to a begin-glyph or end-glyph hitting window-end, then
2374 data.ch will not point to the character at data.bi_bufpos. If
2375 you make the two changes mentioned at the top of this loop,
2376 you should be able to say '(if (*prop))'. That should also
2377 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
2380 /* The common case is that the line ended because we hit a newline.
2381 In that case, the next character is just the next buffer
2383 if (data.ch == '\n')
2385 /* If data.start_col_enabled is still true, then the window is
2386 scrolled far enough so that nothing on this line is visible.
2387 We need to stick a truncation glyph at the beginning of the
2388 line in that case unless the line is completely blank. */
2389 if (data.bi_start_col_enabled)
2391 if (data.cursor_type == CURSOR_ON)
2393 if (data.bi_cursor_bufpos >= bi_start_pos
2394 && data.bi_cursor_bufpos <= data.bi_bufpos)
2395 data.bi_cursor_bufpos = data.bi_bufpos;
2397 data.findex = DEFAULT_INDEX;
2399 data.bi_start_col_enabled = 0;
2401 if (data.bi_bufpos != bi_start_pos)
2403 struct glyph_block gb;
2406 gb.glyph = Vhscroll_glyph;
2407 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
2408 GLYPH_CACHEL (w, HSCROLL_GLYPH_INDEX));
2412 /* This duplicates code down below to add a newline to
2413 the end of an otherwise empty line.*/
2415 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2417 add_emchar_rune (&data);
2421 INC_BYTIND (b, data.bi_bufpos);
2424 /* Otherwise we have a buffer line which cannot fit on one display
2428 struct glyph_block gb;
2429 struct glyph_cachel *cachel;
2431 /* If the line is to be truncated then we actually have to look
2432 for the next newline. We also add the end-of-line glyph which
2433 we know will fit because we adjusted the right border before
2434 we starting laying out the line. */
2435 data.max_pixpos += end_glyph_width;
2436 data.findex = DEFAULT_INDEX;
2443 /* Now find the start of the next line. */
2444 bi_pos = bi_find_next_newline_no_quit (b, data.bi_bufpos, 1);
2446 /* If the cursor is past the truncation line then we
2447 make it appear on the truncation glyph. If we've hit
2448 the end of the buffer then we also make the cursor
2449 appear unless eob is immediately preceded by a
2450 newline. In that case the cursor should actually
2451 appear on the next line. */
2452 if (data.cursor_type == CURSOR_ON
2453 && data.bi_cursor_bufpos >= data.bi_bufpos
2454 && (data.bi_cursor_bufpos < bi_pos ||
2455 (bi_pos == BI_BUF_ZV (b)
2456 && (bi_pos == BI_BUF_BEGV (b)
2457 || (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_pos))
2459 data.bi_cursor_bufpos = bi_pos;
2461 data.cursor_type = NO_CURSOR;
2463 data.bi_bufpos = bi_pos;
2464 gb.glyph = Vtruncation_glyph;
2465 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
2469 /* The cursor can never be on the continuation glyph. */
2470 data.cursor_type = NO_CURSOR;
2472 /* data.bi_bufpos is already at the start of the next line. */
2474 gb.glyph = Vcontinuation_glyph;
2475 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
2478 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 1, cachel);
2480 if (truncate_win && data.bi_bufpos == BI_BUF_ZV (b)
2481 && BI_BUF_FETCH_CHAR (b, prev_bytind (b, BI_BUF_ZV (b))) != '\n')
2482 /* #### Damn this losing shit. */
2486 else if ((active_minibuffer || !NILP (synch_minibuffers_value))
2487 && (!echo_area_active (f) || data.bi_bufpos == BI_BUF_ZV (b)))
2489 /* We need to add a marker to the end of the line since there is no
2490 newline character in order for the cursor to get drawn. We label
2491 it as a newline so that it gets handled correctly by the
2492 whitespace routines below. */
2495 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2496 data.findex = DEFAULT_INDEX;
2498 data.start_col_xoffset = 0;
2499 data.bi_start_col_enabled = 0;
2501 data.max_pixpos += data.blank_width;
2502 add_emchar_rune (&data);
2503 data.max_pixpos -= data.blank_width;
2505 /* #### urk! Chuck, this shit is bad news. Going around
2506 manipulating invalid positions is guaranteed to result in
2507 trouble sooner or later. */
2508 data.bi_bufpos = BI_BUF_ZV (b) + 1;
2511 /* Calculate left whitespace boundary. */
2515 /* Whitespace past a newline is considered right whitespace. */
2516 while (elt < Dynarr_length (db->runes))
2518 struct rune *rb = Dynarr_atp (db->runes, elt);
2520 if ((rb->type == RUNE_CHAR && rb->object.chr.ch == ' ')
2521 || rb->type == RUNE_BLANK)
2523 dl->bounds.left_white += rb->width;
2527 elt = Dynarr_length (db->runes);
2531 /* Calculate right whitespace boundary. */
2533 int elt = Dynarr_length (db->runes) - 1;
2536 while (!done && elt >= 0)
2538 struct rune *rb = Dynarr_atp (db->runes, elt);
2540 if (!(rb->type == RUNE_CHAR && rb->object.chr.ch < 0x100
2541 && isspace (rb->object.chr.ch))
2542 && !rb->type == RUNE_BLANK)
2544 dl->bounds.right_white = rb->xpos + rb->width;
2552 /* The line is blank so everything is considered to be right
2555 dl->bounds.right_white = dl->bounds.left_in;
2558 /* Set the display blocks bounds. */
2559 db->start_pos = dl->bounds.left_in;
2560 if (Dynarr_length (db->runes))
2562 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
2564 db->end_pos = rb->xpos + rb->width;
2567 db->end_pos = dl->bounds.right_white;
2569 /* update line height parameters */
2570 if (!data.new_ascent && !data.new_descent)
2572 /* We've got a blank line so initialize these values from the default
2574 default_face_font_info (data.window, &data.new_ascent,
2575 &data.new_descent, 0, 0, 0);
2578 if (data.max_pixmap_height)
2580 int height = data.new_ascent + data.new_descent;
2581 int pix_ascent, pix_descent;
2583 pix_descent = data.max_pixmap_height * data.new_descent / height;
2584 pix_ascent = data.max_pixmap_height - pix_descent;
2586 data.new_ascent = max (data.new_ascent, pix_ascent);
2587 data.new_descent = max (data.new_descent, pix_descent);
2590 dl->ascent = data.new_ascent;
2591 dl->descent = data.new_descent;
2594 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
2596 if (dl->ascent < ascent)
2597 dl->ascent = ascent;
2600 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
2602 if (dl->descent < descent)
2603 dl->descent = descent;
2606 dl->cursor_elt = data.cursor_x;
2607 /* #### lossage lossage lossage! Fix this shit! */
2608 if (data.bi_bufpos > BI_BUF_ZV (b))
2609 dl->end_bufpos = BUF_ZV (b);
2611 dl->end_bufpos = bytind_to_bufpos (b, data.bi_bufpos) - 1;
2613 data.dl->num_chars = column_at_point (b, dl->end_bufpos, 0);
2615 /* This doesn't correctly take into account tabs and control
2616 characters but if the window isn't being truncated then this
2617 value isn't going to end up being used anyhow. */
2618 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
2620 /* #### handle horizontally scrolled line with text none of which
2621 was actually laid out. */
2623 /* #### handle any remainder of overlay arrow */
2625 if (*prop == ADD_FAILED)
2628 if (truncate_win && *prop)
2630 Dynarr_free (*prop);
2634 extent_fragment_delete (data.ef);
2636 /* #### If we started at EOB, then make sure we return a value past
2637 it so that regenerate_window will exit properly. This is bogus.
2638 The main loop should get fixed so that it isn't necessary to call
2639 this function if we are already at EOB. */
2641 if (data.bi_bufpos == BI_BUF_ZV (b) && bi_start_pos == BI_BUF_ZV (b))
2642 return data.bi_bufpos + 1; /* Yuck! */
2644 return data.bi_bufpos;
2647 /* Display the overlay arrow at the beginning of the given line. */
2650 create_overlay_glyph_block (struct window *w, struct display_line *dl)
2652 struct frame *f = XFRAME (w->frame);
2653 struct device *d = XDEVICE (f->device);
2656 /* If Voverlay_arrow_string isn't valid then just fail silently. */
2657 if (!STRINGP (Voverlay_arrow_string) && !GLYPHP (Voverlay_arrow_string))
2663 XSETWINDOW (data.window, w);
2664 data.db = get_display_block_from_line (dl, OVERWRITE);
2666 data.pixpos = dl->bounds.left_in;
2667 data.max_pixpos = dl->bounds.right_in;
2668 data.cursor_type = NO_CURSOR;
2670 data.findex = DEFAULT_INDEX;
2671 data.last_charset = Qunbound;
2672 data.last_findex = DEFAULT_INDEX;
2673 data.result_str = Qnil;
2676 Dynarr_reset (data.db->runes);
2678 if (STRINGP (Voverlay_arrow_string))
2680 add_bufbyte_string_runes
2682 XSTRING_DATA (Voverlay_arrow_string),
2683 XSTRING_LENGTH (Voverlay_arrow_string),
2686 else if (GLYPHP (Voverlay_arrow_string))
2688 struct glyph_block gb;
2690 gb.glyph = Voverlay_arrow_string;
2692 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, 0);
2695 if (data.max_pixmap_height)
2697 int height = data.new_ascent + data.new_descent;
2698 int pix_ascent, pix_descent;
2700 pix_descent = data.max_pixmap_height * data.new_descent / height;
2701 pix_ascent = data.max_pixmap_height - pix_descent;
2703 data.new_ascent = max (data.new_ascent, pix_ascent);
2704 data.new_descent = max (data.new_descent, pix_descent);
2707 dl->ascent = data.new_ascent;
2708 dl->descent = data.new_descent;
2710 data.db->start_pos = dl->bounds.left_in;
2711 data.db->end_pos = data.pixpos;
2713 return data.pixpos - dl->bounds.left_in;
2716 /* Add a type of glyph to a margin display block. */
2719 add_margin_runes (struct display_line *dl, struct display_block *db, int start,
2720 int count, enum glyph_layout layout, int side, Lisp_Object window)
2722 glyph_block_dynarr *gbd = (side == LEFT_GLYPHS
2724 : dl->right_glyphs);
2729 if ((layout == GL_WHITESPACE && side == LEFT_GLYPHS)
2730 || (layout == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS))
2733 elt = Dynarr_length (gbd) - 1;
2740 end = Dynarr_length (gbd);
2743 while (count && ((!reverse && elt < end) || (reverse && elt >= end)))
2745 struct glyph_block *gb = Dynarr_atp (gbd, elt);
2747 if (NILP (gb->extent))
2748 abort (); /* these should have been handled in add_glyph_rune */
2751 ((side == LEFT_GLYPHS &&
2752 extent_begin_glyph_layout (XEXTENT (gb->extent)) == layout)
2753 || (side == RIGHT_GLYPHS &&
2754 extent_end_glyph_layout (XEXTENT (gb->extent)) == layout)))
2758 rb.width = gb->width;
2759 rb.findex = gb->findex;
2763 rb.type = RUNE_DGLYPH;
2764 rb.object.dglyph.glyph = gb->glyph;
2765 rb.object.dglyph.extent = gb->extent;
2766 rb.object.dglyph.xoffset = 0;
2767 rb.cursor_type = CURSOR_OFF;
2769 Dynarr_add (db->runes, rb);
2774 if (glyph_contrib_p (gb->glyph, window))
2776 unsigned short ascent, descent;
2777 Lisp_Object baseline = glyph_baseline (gb->glyph, window);
2779 ascent = glyph_ascent (gb->glyph, window);
2780 descent = glyph_descent (gb->glyph, window);
2782 /* A pixmap that has not had a baseline explicitly set.
2783 We use the existing ascent / descent ratio of the
2785 if (NILP (baseline))
2787 int gheight = ascent + descent;
2788 int line_height = dl->ascent + dl->descent;
2789 int pix_ascent, pix_descent;
2791 pix_descent = (int) (gheight * dl->descent) / line_height;
2792 pix_ascent = gheight - pix_descent;
2794 dl->ascent = max ((int) dl->ascent, pix_ascent);
2795 dl->descent = max ((int) dl->descent, pix_descent);
2798 /* A string so determine contribution normally. */
2799 else if (EQ (baseline, Qt))
2801 dl->ascent = max (dl->ascent, ascent);
2802 dl->descent = max (dl->descent, descent);
2805 /* A pixmap with an explicitly set baseline. We determine the
2806 contribution here. */
2807 else if (INTP (baseline))
2809 int height = ascent + descent;
2810 int pix_ascent, pix_descent;
2812 pix_ascent = height * XINT (baseline) / 100;
2813 pix_descent = height - pix_ascent;
2815 dl->ascent = max ((int) dl->ascent, pix_ascent);
2816 dl->descent = max ((int) dl->descent, pix_descent);
2819 /* Otherwise something is screwed up. */
2825 (reverse ? elt-- : elt++);
2831 /* Add a blank to a margin display block. */
2834 add_margin_blank (struct display_line *dl, struct display_block *db,
2835 struct window *w, int xpos, int width, int side)
2839 rb.findex = (side == LEFT_GLYPHS
2840 ? get_builtin_face_cache_index (w, Vleft_margin_face)
2841 : get_builtin_face_cache_index (w, Vright_margin_face));
2846 rb.type = RUNE_BLANK;
2847 rb.cursor_type = CURSOR_OFF;
2849 Dynarr_add (db->runes, rb);
2852 /* Display glyphs in the left outside margin, left inside margin and
2853 left whitespace area. */
2856 create_left_glyph_block (struct window *w, struct display_line *dl,
2861 int use_overflow = (NILP (w->use_left_overflow) ? 0 : 1);
2863 int out_end, in_out_start, in_in_end, white_out_start, white_in_start;
2864 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
2865 int left_in_start = dl->bounds.left_in;
2866 int left_in_end = dl->bounds.left_in + overlay_width;
2868 struct display_block *odb, *idb;
2870 XSETWINDOW (window, w);
2872 /* We have to add the glyphs to the line in the order outside,
2873 inside, whitespace. However the precedence dictates that we
2874 determine how many will fit in the reverse order. */
2876 /* Determine how many whitespace glyphs we can display and where
2877 they should start. */
2878 white_in_start = dl->bounds.left_white;
2879 white_out_start = left_in_start;
2880 white_out_cnt = white_in_cnt = 0;
2883 while (elt < Dynarr_length (dl->left_glyphs))
2885 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2887 if (NILP (gb->extent))
2888 abort (); /* these should have been handled in add_glyph_rune */
2890 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
2894 width = glyph_width (gb->glyph, window);
2896 if (white_in_start - width >= left_in_end)
2899 white_in_start -= width;
2903 else if (use_overflow
2904 && (white_out_start - width > dl->bounds.left_out))
2907 white_out_start -= width;
2918 /* Determine how many inside margin glyphs we can display and where
2919 they should start. The inside margin glyphs get whatever space
2920 is left after the whitespace glyphs have been displayed. These
2921 are tricky to calculate since if we decide to use the overflow
2922 area we basically have to start over. So for these we build up a
2923 list of just the inside margin glyphs and manipulate it to
2924 determine the needed info. */
2926 glyph_block_dynarr *ib;
2927 int avail_in, avail_out;
2930 int used_in, used_out;
2933 used_in = used_out = 0;
2934 ib = Dynarr_new (glyph_block);
2935 while (elt < Dynarr_length (dl->left_glyphs))
2937 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
2939 if (NILP (gb->extent))
2940 abort (); /* these should have been handled in add_glyph_rune */
2942 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
2945 gb->width = glyph_width (gb->glyph, window);
2946 used_in += gb->width;
2947 Dynarr_add (ib, *gb);
2957 avail_in = white_in_start - left_in_end;
2965 avail_out = white_out_start - dl->bounds.left_out;
2968 while (!done && marker < Dynarr_length (ib))
2970 int width = Dynarr_atp (ib, marker)->width;
2972 /* If everything now fits in the available inside margin
2973 space, we're done. */
2974 if (used_in <= avail_in)
2978 /* Otherwise see if we have room to move a glyph to the
2980 if (used_out + width <= avail_out)
2993 /* At this point we now know that everything from marker on goes in
2994 the inside margin and everything before it goes in the outside
2995 margin. The stuff going into the outside margin is guaranteed
2996 to fit, but we may have to trim some stuff from the inside. */
2998 in_in_end = left_in_end;
2999 in_out_start = white_out_start;
3000 in_out_cnt = in_in_cnt = 0;
3004 while (elt < Dynarr_length (dl->left_glyphs))
3006 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3008 if (NILP (gb->extent))
3009 abort (); /* these should have been handled in add_glyph_rune */
3011 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3014 int width = glyph_width (gb->glyph, window);
3019 in_out_start -= width;
3024 else if (in_in_end + width < white_in_start)
3039 /* Determine how many outside margin glyphs we can display. They
3040 always start at the left outside margin and can only use the
3041 outside margin space. */
3042 out_end = dl->bounds.left_out;
3046 while (elt < Dynarr_length (dl->left_glyphs))
3048 struct glyph_block *gb = Dynarr_atp (dl->left_glyphs, elt);
3050 if (NILP (gb->extent))
3051 abort (); /* these should have been handled in add_glyph_rune */
3053 if (extent_begin_glyph_layout (XEXTENT (gb->extent)) ==
3056 int width = glyph_width (gb->glyph, window);
3058 if (out_end + width <= in_out_start)
3072 /* Now that we know where everything goes, we add the glyphs as
3073 runes to the appropriate display blocks. */
3074 if (out_cnt || in_out_cnt || white_out_cnt)
3076 odb = get_display_block_from_line (dl, LEFT_OUTSIDE_MARGIN);
3077 odb->start_pos = dl->bounds.left_out;
3078 /* #### We should stop adding a blank to account for the space
3079 between the end of the glyphs and the margin and instead set
3080 this accordingly. */
3081 odb->end_pos = dl->bounds.left_in;
3082 Dynarr_reset (odb->runes);
3087 if (in_in_cnt || white_in_cnt)
3089 idb = get_display_block_from_line (dl, LEFT_INSIDE_MARGIN);
3090 idb->start_pos = dl->bounds.left_in;
3091 /* #### See above comment for odb->end_pos */
3092 idb->end_pos = dl->bounds.left_white;
3093 Dynarr_reset (idb->runes);
3098 /* First add the outside margin glyphs. */
3100 end_xpos = add_margin_runes (dl, odb, dl->bounds.left_out, out_cnt,
3101 GL_OUTSIDE_MARGIN, LEFT_GLYPHS, window);
3103 end_xpos = dl->bounds.left_out;
3105 /* There may be blank space between the outside margin glyphs and
3106 the inside margin glyphs. If so, add a blank. */
3107 if (in_out_cnt && (in_out_start - end_xpos))
3109 add_margin_blank (dl, odb, w, end_xpos, in_out_start - end_xpos,
3113 /* Next add the inside margin glyphs which are actually in the
3117 end_xpos = add_margin_runes (dl, odb, in_out_start, in_out_cnt,
3118 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3121 /* If we didn't add any inside margin glyphs to the outside margin,
3122 but are adding whitespace glyphs, then we need to add a blank
3124 if (!in_out_cnt && white_out_cnt && (white_out_start - end_xpos))
3126 add_margin_blank (dl, odb, w, end_xpos, white_out_start - end_xpos,
3130 /* Next add the whitespace margin glyphs which are actually in the
3134 end_xpos = add_margin_runes (dl, odb, white_out_start, white_out_cnt,
3135 GL_WHITESPACE, LEFT_GLYPHS, window);
3138 /* We take care of clearing between the end of the glyphs and the
3139 start of the inside margin for lines which have glyphs. */
3140 if (odb && (left_in_start - end_xpos))
3142 add_margin_blank (dl, odb, w, end_xpos, left_in_start - end_xpos,
3146 /* Next add the inside margin glyphs which are actually in the
3150 end_xpos = add_margin_runes (dl, idb, left_in_end, in_in_cnt,
3151 GL_INSIDE_MARGIN, LEFT_GLYPHS, window);
3154 end_xpos = left_in_end;
3156 /* Make sure that the area between the end of the inside margin
3157 glyphs and the whitespace glyphs is cleared. */
3158 if (idb && (white_in_start - end_xpos > 0))
3160 add_margin_blank (dl, idb, w, end_xpos, white_in_start - end_xpos,
3164 /* Next add the whitespace margin glyphs which are actually in the
3168 add_margin_runes (dl, idb, white_in_start, white_in_cnt, GL_WHITESPACE,
3169 LEFT_GLYPHS, window);
3172 /* Whitespace glyphs always end right next to the text block so
3173 there is nothing we have to make sure is cleared after them. */
3176 /* Display glyphs in the right outside margin, right inside margin and
3177 right whitespace area. */
3180 create_right_glyph_block (struct window *w, struct display_line *dl)
3184 int use_overflow = (NILP (w->use_right_overflow) ? 0 : 1);
3186 int out_start, in_out_end, in_in_start, white_out_end, white_in_end;
3187 int out_cnt, in_out_cnt, in_in_cnt, white_out_cnt, white_in_cnt;
3189 struct display_block *odb, *idb;
3191 XSETWINDOW (window, w);
3193 /* We have to add the glyphs to the line in the order outside,
3194 inside, whitespace. However the precedence dictates that we
3195 determine how many will fit in the reverse order. */
3197 /* Determine how many whitespace glyphs we can display and where
3198 they should start. */
3199 white_in_end = dl->bounds.right_white;
3200 white_out_end = dl->bounds.right_in;
3201 white_out_cnt = white_in_cnt = 0;
3204 while (elt < Dynarr_length (dl->right_glyphs))
3206 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3208 if (NILP (gb->extent))
3209 abort (); /* these should have been handled in add_glyph_rune */
3211 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_WHITESPACE)
3213 int width = glyph_width (gb->glyph, window);
3215 if (white_in_end + width <= dl->bounds.right_in)
3218 white_in_end += width;
3222 else if (use_overflow
3223 && (white_out_end + width <= dl->bounds.right_out))
3226 white_out_end += width;
3237 /* Determine how many inside margin glyphs we can display and where
3238 they should start. The inside margin glyphs get whatever space
3239 is left after the whitespace glyphs have been displayed. These
3240 are tricky to calculate since if we decide to use the overflow
3241 area we basically have to start over. So for these we build up a
3242 list of just the inside margin glyphs and manipulate it to
3243 determine the needed info. */
3245 glyph_block_dynarr *ib;
3246 int avail_in, avail_out;
3249 int used_in, used_out;
3252 used_in = used_out = 0;
3253 ib = Dynarr_new (glyph_block);
3254 while (elt < Dynarr_length (dl->right_glyphs))
3256 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3258 if (NILP (gb->extent))
3259 abort (); /* these should have been handled in add_glyph_rune */
3261 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3263 gb->width = glyph_width (gb->glyph, window);
3264 used_in += gb->width;
3265 Dynarr_add (ib, *gb);
3274 avail_in = dl->bounds.right_in - white_in_end;
3279 avail_out = dl->bounds.right_out - white_out_end;
3282 while (!done && marker < Dynarr_length (ib))
3284 int width = Dynarr_atp (ib, marker)->width;
3286 /* If everything now fits in the available inside margin
3287 space, we're done. */
3288 if (used_in <= avail_in)
3292 /* Otherwise see if we have room to move a glyph to the
3294 if (used_out + width <= avail_out)
3307 /* At this point we now know that everything from marker on goes in
3308 the inside margin and everything before it goes in the outside
3309 margin. The stuff going into the outside margin is guaranteed
3310 to fit, but we may have to trim some stuff from the inside. */
3312 in_in_start = dl->bounds.right_in;
3313 in_out_end = dl->bounds.right_in;
3314 in_out_cnt = in_in_cnt = 0;
3318 while (elt < Dynarr_length (dl->right_glyphs))
3320 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3322 if (NILP (gb->extent))
3323 abort (); /* these should have been handled in add_glyph_rune */
3325 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_INSIDE_MARGIN)
3327 int width = glyph_width (gb->glyph, window);
3332 in_out_end += width;
3337 else if (in_in_start - width >= white_in_end)
3340 in_in_start -= width;
3352 /* Determine how many outside margin glyphs we can display. They
3353 always start at the right outside margin and can only use the
3354 outside margin space. */
3355 out_start = dl->bounds.right_out;
3359 while (elt < Dynarr_length (dl->right_glyphs))
3361 struct glyph_block *gb = Dynarr_atp (dl->right_glyphs, elt);
3363 if (NILP (gb->extent))
3364 abort (); /* these should have been handled in add_glyph_rune */
3366 if (extent_end_glyph_layout (XEXTENT (gb->extent)) == GL_OUTSIDE_MARGIN)
3368 int width = glyph_width (gb->glyph, window);
3370 if (out_start - width >= in_out_end)
3384 /* Now that we now where everything goes, we add the glyphs as runes
3385 to the appropriate display blocks. */
3386 if (out_cnt || in_out_cnt || white_out_cnt)
3388 odb = get_display_block_from_line (dl, RIGHT_OUTSIDE_MARGIN);
3389 /* #### See comments before odb->start_pos init in
3390 create_left_glyph_block */
3391 odb->start_pos = dl->bounds.right_in;
3392 odb->end_pos = dl->bounds.right_out;
3393 Dynarr_reset (odb->runes);
3398 if (in_in_cnt || white_in_cnt)
3400 idb = get_display_block_from_line (dl, RIGHT_INSIDE_MARGIN);
3401 idb->start_pos = dl->bounds.right_white;
3402 /* #### See comments before odb->start_pos init in
3403 create_left_glyph_block */
3404 idb->end_pos = dl->bounds.right_in;
3405 Dynarr_reset (idb->runes);
3410 /* First add the whitespace margin glyphs which are actually in the
3414 end_xpos = add_margin_runes (dl, idb, dl->bounds.right_white,
3415 white_in_cnt, GL_WHITESPACE, RIGHT_GLYPHS,
3419 end_xpos = dl->bounds.right_white;
3421 /* Make sure that the area between the end of the whitespace glyphs
3422 and the inside margin glyphs is cleared. */
3423 if (in_in_cnt && (in_in_start - end_xpos))
3425 add_margin_blank (dl, idb, w, end_xpos, in_in_start - end_xpos,
3429 /* Next add the inside margin glyphs which are actually in the
3433 end_xpos = add_margin_runes (dl, idb, in_in_start, in_in_cnt,
3434 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3437 /* If we didn't add any inside margin glyphs then make sure the rest
3438 of the inside margin area gets cleared. */
3439 if (idb && (dl->bounds.right_in - end_xpos))
3441 add_margin_blank (dl, idb, w, end_xpos, dl->bounds.right_in - end_xpos,
3445 /* Next add any whitespace glyphs in the outside margin. */
3448 end_xpos = add_margin_runes (dl, odb, dl->bounds.right_in, white_out_cnt,
3449 GL_WHITESPACE, RIGHT_GLYPHS, window);
3452 end_xpos = dl->bounds.right_in;
3454 /* Next add any inside margin glyphs in the outside margin. */
3457 end_xpos = add_margin_runes (dl, odb, end_xpos, in_out_cnt,
3458 GL_INSIDE_MARGIN, RIGHT_GLYPHS, window);
3461 /* There may be space between any whitespace or inside margin glyphs
3462 in the outside margin and the actual outside margin glyphs. */
3463 if (odb && (out_start - end_xpos))
3465 add_margin_blank (dl, odb, w, end_xpos, out_start - end_xpos,
3469 /* Finally, add the outside margin glyphs. */
3472 add_margin_runes (dl, odb, out_start, out_cnt, GL_OUTSIDE_MARGIN,
3473 RIGHT_GLYPHS, window);
3478 /***************************************************************************/
3480 /* modeline routines */
3482 /***************************************************************************/
3484 /* This function is also used in frame.c by `generate_title_string' */
3486 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str,
3487 struct window *w, struct display_line *dl,
3488 struct display_block *db, face_index findex,
3489 int min_pixpos, int max_pixpos, int type)
3491 struct frame *f = XFRAME (w->frame);
3492 struct device *d = XDEVICE (f->device);
3496 Charcount offset = 0;
3502 data.findex = findex;
3503 data.pixpos = min_pixpos;
3504 data.max_pixpos = max_pixpos;
3505 data.cursor_type = NO_CURSOR;
3506 data.last_charset = Qunbound;
3507 data.last_findex = DEFAULT_INDEX;
3508 data.result_str = result_str;
3509 data.is_modeline = 1;
3511 XSETWINDOW (data.window, w);
3513 Dynarr_reset (formatted_string_extent_dynarr);
3514 Dynarr_reset (formatted_string_extent_start_dynarr);
3515 Dynarr_reset (formatted_string_extent_end_dynarr);
3517 /* result_str is nil when we're building a frame or icon title. Otherwise,
3518 we're building a modeline, so the offset starts at the modeline
3519 horizontal scrolling ammount */
3520 if (! NILP (result_str))
3521 offset = w->modeline_hscroll;
3522 generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0,
3523 max_pixpos - min_pixpos, findex, type, &offset,
3526 if (Dynarr_length (db->runes))
3529 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
3530 c_pixpos = rb->xpos + rb->width;
3533 c_pixpos = min_pixpos;
3535 /* If we don't reach the right side of the window, add a blank rune
3536 to make up the difference. This usually only occurs if the
3537 modeline face is using a proportional width font or a fixed width
3538 font of a different size from the default face font. */
3540 if (c_pixpos < max_pixpos)
3542 data.pixpos = c_pixpos;
3543 data.blank_width = max_pixpos - data.pixpos;
3545 add_blank_rune (&data, NULL, 0);
3548 /* Now create the result string and frob the extents into it. */
3549 if (!NILP (result_str))
3554 struct buffer *buf = XBUFFER (WINDOW_BUFFER (w));
3556 detach_all_extents (result_str);
3557 resize_string (XSTRING (result_str), -1,
3558 data.bytepos - XSTRING_LENGTH (result_str));
3560 strdata = XSTRING_DATA (result_str);
3562 for (elt = 0, len = 0; elt < Dynarr_length (db->runes); elt++)
3564 if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR)
3566 len += (set_charptr_emchar
3567 (strdata + len, Dynarr_atp (db->runes,
3568 elt)->object.chr.ch));
3572 for (elt = 0; elt < Dynarr_length (formatted_string_extent_dynarr);
3575 Lisp_Object extent = Qnil;
3578 XSETEXTENT (extent, Dynarr_at (formatted_string_extent_dynarr, elt));
3579 child = Fgethash (extent, buf->modeline_extent_table, Qnil);
3582 child = Fmake_extent (Qnil, Qnil, result_str);
3583 Fputhash (extent, child, buf->modeline_extent_table);
3585 Fset_extent_parent (child, extent);
3586 set_extent_endpoints
3588 Dynarr_at (formatted_string_extent_start_dynarr, elt),
3589 Dynarr_at (formatted_string_extent_end_dynarr, elt),
3595 /* Ensure that the given display line DL accurately represents the
3596 modeline for the given window. */
3598 generate_modeline (struct window *w, struct display_line *dl, int type)
3600 struct buffer *b = XBUFFER (w->buffer);
3601 struct frame *f = XFRAME (w->frame);
3602 struct device *d = XDEVICE (f->device);
3604 /* Unlike display line and rune pointers, this one can't change underneath
3606 struct display_block *db = get_display_block_from_line (dl, TEXT);
3607 int max_pixpos, min_pixpos, ypos_adj;
3608 Lisp_Object font_inst;
3610 /* This will actually determine incorrect inside boundaries for the
3611 modeline since it ignores the margins. However being aware of this fact
3612 we never use those values anywhere so it doesn't matter. */
3613 dl->bounds = calculate_display_line_boundaries (w, 1);
3615 /* We are generating a modeline. */
3617 dl->cursor_elt = -1;
3619 /* Reset the runes on the modeline. */
3620 Dynarr_reset (db->runes);
3622 if (!WINDOW_HAS_MODELINE_P (w))
3626 /* If there is a horizontal scrollbar, don't add anything. */
3627 if (window_scrollbar_height (w))
3630 dl->ascent = DEVMETH (d, divider_height, ());
3632 /* The modeline is at the bottom of the gutters. */
3633 dl->ypos = WINDOW_BOTTOM (w);
3635 /* adjust for the bottom gutter */
3636 if (window_is_lowest (w))
3637 dl->ypos -= FRAME_BOTTOM_GUTTER_BOUNDS (f);
3639 rb.findex = MODELINE_INDEX;
3640 rb.xpos = dl->bounds.left_out;
3641 rb.width = dl->bounds.right_out - dl->bounds.left_out;
3644 rb.type = RUNE_HLINE;
3645 rb.object.hline.thickness = 1;
3646 rb.object.hline.yoffset = 0;
3647 rb.cursor_type = NO_CURSOR;
3649 if (!EQ (Qzero, w->modeline_shadow_thickness)
3652 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3654 dl->ypos -= shadow_thickness;
3655 rb.xpos += shadow_thickness;
3656 rb.width -= 2 * shadow_thickness;
3659 Dynarr_add (db->runes, rb);
3663 /* !!#### not right; needs to compute the max height of
3665 font_inst = WINDOW_FACE_CACHEL_FONT (w, MODELINE_INDEX, Vcharset_ascii);
3667 dl->ascent = XFONT_INSTANCE (font_inst)->ascent;
3668 dl->descent = XFONT_INSTANCE (font_inst)->descent;
3670 min_pixpos = dl->bounds.left_out;
3671 max_pixpos = dl->bounds.right_out;
3673 if (!EQ (Qzero, w->modeline_shadow_thickness) && FRAME_WIN_P (f))
3675 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
3677 ypos_adj = shadow_thickness;
3678 min_pixpos += shadow_thickness;
3679 max_pixpos -= shadow_thickness;
3684 generate_formatted_string_db (b->modeline_format,
3685 b->generated_modeline_string, w, dl, db,
3686 MODELINE_INDEX, min_pixpos, max_pixpos, type);
3688 /* The modeline is at the bottom of the gutters. We have to wait to
3689 set this until we've generated the modeline in order to account
3690 for any embedded faces. */
3691 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj;
3692 /* adjust for the bottom gutter */
3693 if (window_is_lowest (w))
3694 dl->ypos -= FRAME_BOTTOM_GUTTER_BOUNDS (f);
3698 add_string_to_fstring_db_runes (pos_data *data, const Bufbyte *str,
3699 Charcount pos, Charcount min_pos, Charcount max_pos)
3701 /* This function has been Mule-ized. */
3703 const Bufbyte *cur_pos = str;
3704 struct display_block *db = data->db;
3706 data->blank_width = space_width (XWINDOW (data->window));
3707 while (Dynarr_length (db->runes) < pos)
3708 add_blank_rune (data, NULL, 0);
3710 end = (Dynarr_length (db->runes) +
3711 bytecount_to_charcount (str, strlen ((const char *) str)));
3713 end = min (max_pos, end);
3715 while (pos < end && *cur_pos)
3717 const Bufbyte *old_cur_pos = cur_pos;
3720 data->ch = charptr_emchar (cur_pos);
3721 succeeded = (add_emchar_rune (data) != ADD_FAILED);
3722 INC_CHARPTR (cur_pos);
3726 data->modeline_charpos++;
3727 data->bytepos += cur_pos - old_cur_pos;
3731 while (Dynarr_length (db->runes) < min_pos &&
3732 (data->pixpos + data->blank_width <= data->max_pixpos))
3733 add_blank_rune (data, NULL, 0);
3735 return Dynarr_length (db->runes);
3738 /* #### Urk! Should also handle begin-glyphs and end-glyphs in
3739 modeline extents. */
3741 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph,
3742 Charcount pos, Charcount min_pos,
3743 Charcount max_pos, Lisp_Object extent)
3745 /* This function has been Mule-ized. */
3747 struct display_block *db = data->db;
3748 struct glyph_block gb;
3750 data->blank_width = space_width (XWINDOW (data->window));
3751 while (Dynarr_length (db->runes) < pos)
3752 add_blank_rune (data, NULL, 0);
3754 end = Dynarr_length (db->runes) + 1;
3756 end = min (max_pos, end);
3760 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
3763 while (Dynarr_length (db->runes) < pos &&
3764 (data->pixpos + data->blank_width <= data->max_pixpos))
3765 add_blank_rune (data, NULL, 0);
3767 return Dynarr_length (db->runes);
3770 /* If max_pos is == -1, it is considered to be infinite. The same is
3771 true of max_pixsize. */
3772 #define SET_CURRENT_MODE_CHARS_PIXSIZE \
3773 if (Dynarr_length (data->db->runes)) \
3774 cur_pixsize = data->pixpos - Dynarr_atp (data->db->runes, 0)->xpos; \
3778 /* Note that this function does "positions" in terms of characters and
3779 not in terms of columns. This is necessary to make the formatting
3780 work correctly when proportional width fonts are used in the
3783 generate_fstring_runes (struct window *w, pos_data *data, Charcount pos,
3784 Charcount min_pos, Charcount max_pos,
3785 Lisp_Object elt, int depth, int max_pixsize,
3786 face_index findex, int type, Charcount *offset,
3787 Lisp_Object cur_ext)
3789 /* This function has been Mule-ized. */
3790 /* #### The other losing things in this function are:
3792 -- C zero-terminated-string lossage.
3793 -- Non-printable characters should be converted into something
3794 appropriate (e.g. ^F) instead of blindly being printed anyway.
3805 /* A string. Add to the display line and check for %-constructs
3808 Bufbyte *this = XSTRING_DATA (elt);
3810 while ((pos < max_pos || max_pos == -1) && *this)
3812 Bufbyte *last = this;
3814 while (*this && *this != '%')
3819 /* No %-construct */
3821 bytecount_to_charcount (last, this - last);
3823 if (size <= *offset)
3827 Charcount tmp_max = (max_pos == -1 ? pos + size - *offset :
3828 min (pos + size - *offset, max_pos));
3829 const Bufbyte *tmp_last = charptr_n_addr (last, *offset);
3831 pos = add_string_to_fstring_db_runes (data, tmp_last,
3836 else /* *this == '%' */
3838 Charcount spec_width = 0;
3840 this++; /* skip over '%' */
3842 /* We can't allow -ve args due to the "%-" construct.
3843 * Argument specifies minwidth but not maxwidth
3844 * (maxwidth can be specified by
3845 * (<negative-number> . <stuff>) modeline elements)
3847 while (isdigit (*this))
3849 spec_width = spec_width * 10 + (*this - '0');
3856 pos = generate_fstring_runes (w, data, pos, spec_width,
3857 max_pos, Vglobal_mode_string,
3858 depth, max_pixsize, findex,
3859 type, offset, cur_ext);
3861 else if (*this == '-')
3863 Charcount num_to_add;
3865 if (max_pixsize < 0)
3867 else if (max_pos != -1)
3868 num_to_add = max_pos - pos;
3874 SET_CURRENT_MODE_CHARS_PIXSIZE;
3877 redisplay_text_width_string (w, findex, &ch, Qnil, 0,
3880 num_to_add = (max_pixsize - cur_pixsize) / dash_pixsize;
3884 while (num_to_add--)
3885 pos = add_string_to_fstring_db_runes
3886 (data, (const Bufbyte *) "-", pos, pos, max_pos);
3888 else if (*this != 0)
3890 Emchar ch = charptr_emchar (this);
3894 decode_mode_spec (w, ch, type);
3896 str = Dynarr_atp (mode_spec_bufbyte_string, 0);
3897 size = bytecount_to_charcount
3898 /* Skip the null character added by `decode_mode_spec' */
3899 (str, Dynarr_length (mode_spec_bufbyte_string)) - 1;
3901 if (size <= *offset)
3905 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3907 /* #### NOTE: I don't understand why a tmp_max is not
3908 computed and used here as in the plain string case
3910 pos = add_string_to_fstring_db_runes (data, tmp_str,
3917 /* NOT this++. There could be any sort of character at
3918 the current position. */
3922 if (max_pixsize > 0)
3925 SET_CURRENT_MODE_CHARS_PIXSIZE;
3927 if (cur_pixsize >= max_pixsize)
3932 else if (SYMBOLP (elt))
3934 /* A symbol: process the value of the symbol recursively
3935 as if it appeared here directly. */
3936 Lisp_Object tem = symbol_value_in_buffer (elt, w->buffer);
3938 if (!UNBOUNDP (tem))
3940 /* If value is a string, output that string literally:
3941 don't check for % within it. */
3944 Bufbyte *str = XSTRING_DATA (tem);
3945 Charcount size = XSTRING_CHAR_LENGTH (tem);
3947 if (size <= *offset)
3951 const Bufbyte *tmp_str = charptr_n_addr (str, *offset);
3953 /* #### NOTE: I don't understand why a tmp_max is not
3954 computed and used here as in the plain string case
3956 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
3961 /* Give up right away for nil or t. */
3962 else if (!EQ (tem, elt))
3969 else if (GENERIC_SPECIFIERP (elt))
3971 Lisp_Object window, tem;
3972 XSETWINDOW (window, w);
3973 tem = specifier_instance_no_quit (elt, Qunbound, window,
3974 ERROR_ME_NOT, 0, Qzero);
3975 if (!UNBOUNDP (tem))
3981 else if (CONSP (elt))
3983 /* A cons cell: four distinct cases.
3984 * - If first element is a string or a cons, process all the elements
3985 * and effectively concatenate them.
3986 * - If first element is a negative number, truncate displaying cdr to
3987 * at most that many characters. If positive, pad (with spaces)
3988 * to at least that many characters.
3989 * - If first element is another symbol, process the cadr or caddr
3990 * recursively according to whether the symbol's value is non-nil or
3992 * - If first element is a face, process the cdr recursively
3993 * without altering the depth.
3996 Lisp_Object car, tem;
4005 tem = symbol_value_in_buffer (car, w->buffer);
4006 /* elt is now the cdr, and we know it is a cons cell.
4007 Use its car if CAR has a non-nil value. */
4008 if (!UNBOUNDP (tem))
4016 /* Symbol's value is nil (or symbol is unbound)
4017 * Get the cddr of the original list
4018 * and if possible find the caddr and use that.
4023 else if (!CONSP (elt))
4031 else if (INTP (car))
4033 Charcount lim = XINT (car);
4039 /* Negative int means reduce maximum width.
4040 * DO NOT change MIN_PIXPOS here!
4041 * (20 -10 . foo) should truncate foo to 10 col
4042 * and then pad to 20.
4045 max_pos = pos - lim;
4047 max_pos = min (max_pos, pos - lim);
4051 /* Padding specified. Don't let it be more than
4055 if (max_pos != -1 && lim > max_pos)
4057 /* If that's more padding than already wanted, queue it.
4058 * But don't reduce padding already specified even if
4059 * that is beyond the current truncation point.
4066 else if (STRINGP (car) || CONSP (car))
4070 /* LIMIT is to protect against circular lists. */
4071 while (CONSP (elt) && --limit > 0
4072 && (pos < max_pos || max_pos == -1))
4074 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4075 XCAR (elt), depth, max_pixsize,
4076 findex, type, offset, cur_ext);
4080 else if (EXTENTP (car))
4082 struct extent *ext = XEXTENT (car);
4084 if (EXTENT_LIVE_P (ext))
4086 face_index old_findex = data->findex;
4088 Lisp_Object font_inst;
4089 face_index new_findex;
4090 Bytecount start = data->bytepos;
4092 face = extent_face (ext);
4095 /* #### needs to merge faces, sigh */
4096 /* #### needs to handle list of faces */
4097 new_findex = get_builtin_face_cache_index (w, face);
4098 /* !!#### not right; needs to compute the max height of
4100 font_inst = WINDOW_FACE_CACHEL_FONT (w, new_findex,
4103 data->dl->ascent = max (data->dl->ascent,
4104 XFONT_INSTANCE (font_inst)->ascent);
4105 data->dl->descent = max (data->dl->descent,
4106 XFONT_INSTANCE (font_inst)->
4110 new_findex = old_findex;
4112 data->findex = new_findex;
4113 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4114 XCDR (elt), depth - 1,
4115 max_pixsize, new_findex, type,
4117 data->findex = old_findex;
4118 Dynarr_add (formatted_string_extent_dynarr, ext);
4119 Dynarr_add (formatted_string_extent_start_dynarr, start);
4120 Dynarr_add (formatted_string_extent_end_dynarr, data->bytepos);
4124 else if (GLYPHP (elt))
4126 /* Glyphs are considered as one character with respect to the modeline
4127 horizontal scrolling facility. -- dv */
4131 pos = add_glyph_to_fstring_db_runes (data, elt, pos, pos, max_pos,
4138 char *str = GETTEXT ("*invalid*");
4139 Charcount size = (Charcount) strlen (str); /* is this ok ?? -- dv */
4141 if (size <= *offset)
4145 const Bufbyte *tmp_str =
4146 charptr_n_addr ((const Bufbyte *) str, *offset);
4148 /* #### NOTE: I don't understand why a tmp_max is not computed and
4149 used here as in the plain string case above. -- dv */
4150 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
4159 add_string_to_fstring_db_runes (data, (const Bufbyte *) "", pos,
4166 /* Update just the modeline. Assumes the desired display structs. If
4167 they do not have a modeline block, it does nothing. */
4169 regenerate_modeline (struct window *w)
4171 display_line_dynarr *dla = window_display_lines (w, DESIRED_DISP);
4173 if (!Dynarr_length (dla) || !Dynarr_atp (dla, 0)->modeline)
4177 generate_modeline (w, Dynarr_atp (dla, 0), DESIRED_DISP);
4178 redisplay_update_line (w, 0, 0, 0);
4182 /* Make sure that modeline display line is present in the given
4183 display structs if the window has a modeline and update that
4184 line. Returns true if a modeline was needed. */
4186 ensure_modeline_generated (struct window *w, int type)
4190 /* minibuffer windows don't have modelines */
4191 if (MINI_WINDOW_P (w))
4193 /* windows which haven't had it turned off do */
4194 else if (WINDOW_HAS_MODELINE_P (w))
4196 /* windows which have it turned off don't have a divider if there is
4197 a horizontal scrollbar */
4198 else if (window_scrollbar_height (w))
4200 /* and in this case there is none */
4206 display_line_dynarr *dla;
4208 dla = window_display_lines (w, type);
4210 /* We don't care if there is a display line which is not
4211 currently a modeline because it is definitely going to become
4212 one if we have gotten to this point. */
4213 if (Dynarr_length (dla) == 0)
4215 if (Dynarr_largest (dla) > 0)
4217 struct display_line *mlp = Dynarr_atp (dla, 0);
4218 Dynarr_add (dla, *mlp);
4222 struct display_line modeline;
4224 Dynarr_add (dla, modeline);
4228 /* If we're adding a new place marker go ahead and generate the
4229 modeline so that it is available for use by
4230 window_modeline_height. */
4231 generate_modeline (w, Dynarr_atp (dla, 0), type);
4234 return need_modeline;
4237 /* #### Kludge or not a kludge. I tend towards the former. */
4239 real_current_modeline_height (struct window *w)
4241 Fset_marker (w->start[CMOTION_DISP], w->start[CURRENT_DISP], w->buffer);
4242 Fset_marker (w->pointm[CMOTION_DISP], w->pointm[CURRENT_DISP], w->buffer);
4244 if (ensure_modeline_generated (w, CMOTION_DISP))
4246 display_line_dynarr *dla = window_display_lines (w, CMOTION_DISP);
4248 if (Dynarr_length (dla))
4250 if (Dynarr_atp (dla, 0)->modeline)
4251 return (Dynarr_atp (dla, 0)->ascent +
4252 Dynarr_atp (dla, 0)->descent);
4259 /***************************************************************************/
4261 /* displayable string routines */
4263 /***************************************************************************/
4265 /* Given a position for a string in a window, ensure that the given
4266 display line DL accurately represents the text on a line starting
4267 at the given position.
4269 Yes, this is duplicating the code of create_text_block, but it
4270 looked just too hard to change create_text_block to handle strings
4271 *and* buffers. We already make a distinction between the two
4272 elsewhere in the code so I think unifying them would require a
4273 complete MULE rewrite. Besides, the other distinction is that these
4274 functions cover text that the user *cannot edit* so we can remove
4275 everything to do with cursors, minibuffers etc. Eventually the
4276 modeline routines should be modified to use this code as it copes
4277 with many more types of display situation. */
4280 create_string_text_block (struct window *w, Lisp_Object disp_string,
4281 struct display_line *dl,
4283 prop_block_dynarr **prop,
4284 face_index default_face)
4286 struct frame *f = XFRAME (w->frame);
4287 /* Note that a lot of the buffer controlled stuff has been left in
4288 because you might well want to make use of it (selective display
4289 etc), its just the buffer text that we do not use. However, it
4290 seems to be possible for buffer to be nil sometimes so protect
4291 against this case. */
4292 struct buffer *b = BUFFERP (w->buffer) ? XBUFFER (w->buffer) : 0;
4293 struct device *d = XDEVICE (f->device);
4294 Lisp_String* s = XSTRING (disp_string);
4296 /* we're working with these a lot so precalculate them */
4297 Bytecount slen = XSTRING_LENGTH (disp_string);
4298 Bytecount bi_string_zv = slen;
4299 Bytind bi_start_pos = charcount_to_bytecount (string_data (s), start_pos);
4303 int truncate_win = b ? window_truncation_on (w) : 0;
4304 int end_glyph_width = 0;
4306 /* we're going to ditch selective display for static text, its an
4307 FSF thing and invisble extents are the way to go
4308 here. Implementing it also relies on a number of buffer-specific
4309 functions that we don't have the luxury of being able to use
4312 /* The variable ctl-arrow allows the user to specify what characters
4313 can actually be displayed and which octal should be used for.
4314 #### This variable should probably have some rethought done to
4317 #### It would also be really nice if you could specify that
4318 the characters come out in hex instead of in octal. Mule
4319 does that by adding a ctl-hexa variable similar to ctl-arrow,
4320 but that's bogus -- we need a more general solution. I
4321 think you need to extend the concept of display tables
4322 into a more general conversion mechanism. Ideally you
4323 could specify a Lisp function that converts characters,
4324 but this violates the Second Golden Rule and besides would
4325 make things way way way way slow.
4327 So instead, we extend the display-table concept, which was
4328 historically limited to 256-byte vectors, to one of the
4331 a) A 256-entry vector, for backward compatibility;
4332 b) char-table, mapping characters to values;
4333 c) range-table, mapping ranges of characters to values;
4334 d) a list of the above.
4336 The (d) option allows you to specify multiple display tables
4337 instead of just one. Each display table can specify conversions
4338 for some characters and leave others unchanged. The way the
4339 character gets displayed is determined by the first display table
4340 with a binding for that character. This way, you could call a
4341 function `enable-hex-display' that adds a hex display-table to
4342 the list of display tables for the current buffer.
4344 #### ...not yet implemented... Also, we extend the concept of
4345 "mapping" to include a printf-like spec. Thus you can make all
4346 extended characters show up as hex with a display table like
4349 #s(range-table data ((256 524288) (format "%x")))
4351 Since more than one display table is possible, you have
4352 great flexibility in mapping ranges of characters. */
4353 Emchar printable_min = b ? (CHAR_OR_CHAR_INTP (b->ctl_arrow)
4354 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
4355 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
4356 ? 255 : 160)) : 255;
4358 Lisp_Object face_dt, window_dt;
4360 /* The text display block for this display line. */
4361 struct display_block *db = get_display_block_from_line (dl, TEXT);
4363 /* The first time through the main loop we need to force the glyph
4364 data to be updated. */
4367 /* Apparently the new extent_fragment_update returns an end position
4368 equal to the position passed in if there are no more runs to be
4370 int no_more_frags = 0;
4372 dl->used_prop_data = 0;
4375 /* set up faces to use for clearing areas, used by
4376 output_display_line */
4377 dl->default_findex = default_face;
4380 dl->left_margin_findex = default_face;
4381 dl->right_margin_findex = default_face;
4385 dl->left_margin_findex =
4386 get_builtin_face_cache_index (w, Vleft_margin_face);
4387 dl->right_margin_findex =
4388 get_builtin_face_cache_index (w, Vright_margin_face);
4392 data.ef = extent_fragment_new (disp_string, f);
4394 /* These values are used by all of the rune addition routines. We add
4395 them to this structure for ease of passing. */
4397 XSETWINDOW (data.window, w);
4401 data.bi_bufpos = bi_start_pos;
4402 data.pixpos = dl->bounds.left_in;
4403 data.last_charset = Qunbound;
4404 data.last_findex = default_face;
4405 data.result_str = Qnil;
4406 data.string = disp_string;
4408 /* Set the right boundary adjusting it to take into account any end
4409 glyph. Save the width of the end glyph for later use. */
4410 data.max_pixpos = dl->bounds.right_in;
4413 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
4415 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
4417 data.max_pixpos -= end_glyph_width;
4419 data.cursor_type = NO_CURSOR;
4423 /* I don't think we want this, string areas should not scroll with
4425 data.start_col = w->hscroll;
4426 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
4428 data.bi_start_col_enabled = 0;
4429 data.hscroll_glyph_width_adjust = 0;
4431 /* We regenerate the line from the very beginning. */
4432 Dynarr_reset (db->runes);
4434 /* Why is this less than or equal and not just less than? If the
4435 starting position is already equal to the maximum we can't add
4436 anything else, right? Wrong. We might still have a newline to
4437 add. A newline can use the room allocated for an end glyph since
4438 if we add it we know we aren't going to be adding any end
4441 /* #### Chuck -- I think this condition should be while (1).
4442 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
4443 and the begin-glyph ends exactly at the end of the window, the
4444 end-glyph and text might not be displayed. while (1) ensures
4445 that the loop terminates only when either (a) there is
4446 propagation data or (b) the end-of-line or end-of-buffer is hit.
4448 #### Also I think you need to ensure that the operation
4449 "add begin glyphs; add end glyphs; add text" is atomic and
4450 can't get interrupted in the middle. If you run off the end
4451 of the line during that operation, then you keep accumulating
4452 propagation data until you're done. Otherwise, if the (e.g.)
4453 there's a begin glyph at a particular position and attempting
4454 to display that glyph results in window-end being hit and
4455 propagation data being generated, then the character at that
4456 position won't be displayed.
4458 #### See also the comment after the end of this loop, below.
4460 while (data.pixpos <= data.max_pixpos)
4462 /* #### This check probably should not be necessary. */
4463 if (data.bi_bufpos > bi_string_zv)
4465 /* #### urk! More of this lossage! */
4470 /* Check for face changes. */
4471 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
4473 /* Now compute the face and begin/end-glyph information. */
4475 /* Remember that the extent-fragment routines deal in Bytind's. */
4476 extent_fragment_update (w, data.ef, data.bi_bufpos);
4477 /* This is somewhat cheesy but the alternative is to
4478 propagate default_face into extent_fragment_update. */
4479 if (data.findex == DEFAULT_INDEX)
4480 data.findex = default_face;
4482 get_display_tables (w, data.findex, &face_dt, &window_dt);
4484 if (data.bi_bufpos == data.ef->end)
4489 /* Determine what is next to be displayed. We first handle any
4490 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
4491 display then we determine what to do based on the character at the
4492 current buffer position. */
4494 /* If the current position is covered by an invisible extent, do
4495 nothing (except maybe add some ellipses).
4497 #### The behavior of begin and end-glyphs at the edge of an
4498 invisible extent should be investigated further. This is
4499 fairly low priority though. */
4500 if (data.ef->invisible)
4502 /* #### Chuck, perhaps you could look at this code? I don't
4503 really know what I'm doing. */
4506 Dynarr_free (*prop);
4510 /* The extent fragment code only sets this when we should
4511 really display the ellipses. It makes sure the ellipses
4512 don't get displayed more than once in a row. */
4513 if (data.ef->invisible_ellipses)
4515 struct glyph_block gb;
4517 data.ef->invisible_ellipses_already_displayed = 1;
4518 data.ef->invisible_ellipses = 0;
4520 gb.glyph = Vinvisible_text_glyph;
4521 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
4522 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
4523 /* Perhaps they shouldn't propagate if the very next thing
4524 is to display a newline (for compatibility with
4525 selective-display-ellipses)? Maybe that's too
4531 /* #### What if we we're dealing with a display table? */
4535 if (data.bi_bufpos == bi_string_zv)
4538 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4541 /* If there is propagation data, then it represents the current
4542 buffer position being displayed. Add them and advance the
4543 position counter. This might also add the minibuffer
4547 dl->used_prop_data = 1;
4548 *prop = add_propagation_runes (prop, &data);
4551 goto done; /* gee, a really narrow window */
4552 else if (data.bi_bufpos == bi_string_zv)
4554 else if (data.bi_bufpos < 0)
4555 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
4558 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4561 /* If there are end glyphs, add them to the line. These are
4562 the end glyphs for the previous run of text. We add them
4563 here rather than doing them at the end of handling the
4564 previous run so that glyphs at the beginning and end of
4565 a line are handled correctly. */
4566 else if (Dynarr_length (data.ef->end_glyphs) > 0)
4568 *prop = add_glyph_runes (&data, END_GLYPHS);
4573 /* If there are begin glyphs, add them to the line. */
4574 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
4576 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
4581 /* If at end-of-buffer, we've already processed begin and
4582 end-glyphs at this point and there's no text to process,
4584 else if (data.bi_bufpos == bi_string_zv)
4589 Lisp_Object entry = Qnil;
4590 /* Get the character at the current buffer position. */
4591 data.ch = string_char (s, data.bi_bufpos);
4592 if (!NILP (face_dt) || !NILP (window_dt))
4593 entry = display_table_entry (data.ch, face_dt, window_dt);
4595 /* If there is a display table entry for it, hand it off to
4596 add_disp_table_entry_runes and let it worry about it. */
4597 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
4599 *prop = add_disp_table_entry_runes (&data, entry);
4605 /* Check if we have hit a newline character. If so, add a marker
4606 to the line and end this loop. */
4607 else if (data.ch == '\n')
4609 /* We aren't going to be adding an end glyph so give its
4610 space back in order to make sure that the cursor can
4612 data.max_pixpos += end_glyph_width;
4616 /* If the current character is considered to be printable, then
4618 else if (data.ch >= printable_min)
4620 *prop = add_emchar_rune (&data);
4625 /* If the current character is a tab, determine the next tab
4626 starting position and add a blank rune which extends from the
4627 current pixel position to that starting position. */
4628 else if (data.ch == '\t')
4630 int tab_start_pixpos = data.pixpos;
4635 if (data.start_col > 1)
4636 tab_start_pixpos -= (space_width (w) * (data.start_col - 1));
4639 next_tab_position (w, tab_start_pixpos,
4640 dl->bounds.left_in +
4641 data.hscroll_glyph_width_adjust);
4642 if (next_tab_start > data.max_pixpos)
4644 prop_width = next_tab_start - data.max_pixpos;
4645 next_tab_start = data.max_pixpos;
4647 data.blank_width = next_tab_start - data.pixpos;
4649 (next_tab_start - tab_start_pixpos) / space_width (w);
4651 *prop = add_blank_rune (&data, w, char_tab_width);
4653 /* add_blank_rune is only supposed to be called with
4654 sizes guaranteed to fit in the available space. */
4659 struct prop_block pb;
4660 *prop = Dynarr_new (prop_block);
4662 pb.type = PROP_BLANK;
4663 pb.data.p_blank.width = prop_width;
4664 pb.data.p_blank.findex = data.findex;
4665 Dynarr_add (*prop, pb);
4671 /* If character is a control character, pass it off to
4672 add_control_char_runes.
4674 The is_*() routines have undefined results on
4675 arguments outside of the range [-1, 255]. (This
4676 often bites people who carelessly use `char' instead
4677 of `unsigned char'.)
4679 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
4681 *prop = add_control_char_runes (&data, b);
4687 /* If the character is above the ASCII range and we have not
4688 already handled it, then print it as an octal number. */
4689 else if (data.ch >= 0200)
4691 *prop = add_octal_runes (&data);
4697 /* Assume the current character is considered to be printable,
4698 then just add it. */
4701 *prop = add_emchar_rune (&data);
4706 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4712 /* Determine the starting point of the next line if we did not hit the
4713 end of the buffer. */
4714 if (data.bi_bufpos < bi_string_zv)
4716 /* #### This check is not correct. If the line terminated
4717 due to a begin-glyph or end-glyph hitting window-end, then
4718 data.ch will not point to the character at data.bi_bufpos. If
4719 you make the two changes mentioned at the top of this loop,
4720 you should be able to say '(if (*prop))'. That should also
4721 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
4724 /* The common case is that the line ended because we hit a newline.
4725 In that case, the next character is just the next buffer
4727 if (data.ch == '\n')
4729 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4732 /* Otherwise we have a buffer line which cannot fit on one display
4736 struct glyph_block gb;
4737 struct glyph_cachel *cachel;
4739 /* If the line is to be truncated then we actually have to look
4740 for the next newline. We also add the end-of-line glyph which
4741 we know will fit because we adjusted the right border before
4742 we starting laying out the line. */
4743 data.max_pixpos += end_glyph_width;
4744 data.findex = default_face;
4751 /* Now find the start of the next line. */
4752 bi_pos = bi_find_next_emchar_in_string (s, '\n', data.bi_bufpos, 1);
4754 data.cursor_type = NO_CURSOR;
4755 data.bi_bufpos = bi_pos;
4756 gb.glyph = Vtruncation_glyph;
4757 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
4761 /* The cursor can never be on the continuation glyph. */
4762 data.cursor_type = NO_CURSOR;
4764 /* data.bi_bufpos is already at the start of the next line. */
4766 gb.glyph = Vcontinuation_glyph;
4767 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
4770 if (end_glyph_width)
4771 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
4773 if (truncate_win && data.bi_bufpos == bi_string_zv)
4775 const Bufbyte* endb = charptr_n_addr (string_data (s), bi_string_zv);
4777 if (charptr_emchar (endb) != '\n')
4779 /* #### Damn this losing shit. */
4785 else if (data.bi_bufpos == bi_string_zv)
4787 /* create_text_block () adds a bogus \n marker here which screws
4788 up subwindow display. Since we never have a cursor in the
4789 gutter we can safely ignore it. */
4791 /* Calculate left whitespace boundary. */
4795 /* Whitespace past a newline is considered right whitespace. */
4796 while (elt < Dynarr_length (db->runes))
4798 struct rune *rb = Dynarr_atp (db->runes, elt);
4800 if ((rb->type == RUNE_CHAR && rb->object.chr.ch == ' ')
4801 || rb->type == RUNE_BLANK)
4803 dl->bounds.left_white += rb->width;
4807 elt = Dynarr_length (db->runes);
4811 /* Calculate right whitespace boundary. */
4813 int elt = Dynarr_length (db->runes) - 1;
4816 while (!done && elt >= 0)
4818 struct rune *rb = Dynarr_atp (db->runes, elt);
4820 if (!(rb->type == RUNE_CHAR && rb->object.chr.ch < 0x100
4821 && isspace (rb->object.chr.ch))
4822 && !rb->type == RUNE_BLANK)
4824 dl->bounds.right_white = rb->xpos + rb->width;
4832 /* The line is blank so everything is considered to be right
4835 dl->bounds.right_white = dl->bounds.left_in;
4838 /* Set the display blocks bounds. */
4839 db->start_pos = dl->bounds.left_in;
4840 if (Dynarr_length (db->runes))
4842 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
4844 db->end_pos = rb->xpos + rb->width;
4847 db->end_pos = dl->bounds.right_white;
4849 /* update line height parameters */
4850 if (!data.new_ascent && !data.new_descent)
4852 /* We've got a blank line so initialize these values from the default
4854 default_face_font_info (data.window, &data.new_ascent,
4855 &data.new_descent, 0, 0, 0);
4858 if (data.max_pixmap_height)
4860 int height = data.new_ascent + data.new_descent;
4861 int pix_ascent, pix_descent;
4863 pix_descent = data.max_pixmap_height * data.new_descent / height;
4864 pix_ascent = data.max_pixmap_height - pix_descent;
4866 data.new_ascent = max (data.new_ascent, pix_ascent);
4867 data.new_descent = max (data.new_descent, pix_descent);
4870 dl->ascent = data.new_ascent;
4871 dl->descent = data.new_descent;
4874 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
4876 if (dl->ascent < ascent)
4877 dl->ascent = ascent;
4880 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
4882 if (dl->descent < descent)
4883 dl->descent = descent;
4886 dl->cursor_elt = data.cursor_x;
4887 /* #### lossage lossage lossage! Fix this shit! */
4888 if (data.bi_bufpos > bi_string_zv)
4889 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, bi_string_zv);
4891 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, data.bi_bufpos) - 1;
4893 data.dl->num_chars =
4894 string_column_at_point (s, dl->end_bufpos, b ? XINT (b->tab_width) : 8);
4896 /* This doesn't correctly take into account tabs and control
4897 characters but if the window isn't being truncated then this
4898 value isn't going to end up being used anyhow. */
4899 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
4901 /* #### handle horizontally scrolled line with text none of which
4902 was actually laid out. */
4904 /* #### handle any remainder of overlay arrow */
4906 if (*prop == ADD_FAILED)
4909 if (truncate_win && *prop)
4911 Dynarr_free (*prop);
4915 extent_fragment_delete (data.ef);
4917 /* #### If we started at EOB, then make sure we return a value past
4918 it so that regenerate_window will exit properly. This is bogus.
4919 The main loop should get fixed so that it isn't necessary to call
4920 this function if we are already at EOB. */
4922 if (data.bi_bufpos == bi_string_zv && bi_start_pos == bi_string_zv)
4923 return bytecount_to_charcount (string_data (s), data.bi_bufpos) + 1; /* Yuck! */
4925 return bytecount_to_charcount (string_data (s), data.bi_bufpos);
4928 /* Given a display line and a starting position, ensure that the
4929 contents of the display line accurately represent the visual
4930 representation of the buffer contents starting from the given
4931 position when displayed in the given window. The display line ends
4932 when the contents of the line reach the right boundary of the given
4935 This is very similar to generate_display_line but with the same
4936 limitations as create_string_text_block. I have taken the liberty
4937 of fixing the bytind stuff though.*/
4940 generate_string_display_line (struct window *w, Lisp_Object disp_string,
4941 struct display_line *dl,
4943 prop_block_dynarr **prop,
4944 face_index default_face)
4948 /* you must set bounds before calling this. */
4950 /* Reset what this line is using. */
4951 if (dl->display_blocks)
4952 Dynarr_reset (dl->display_blocks);
4953 if (dl->left_glyphs)
4955 Dynarr_free (dl->left_glyphs);
4956 dl->left_glyphs = 0;
4958 if (dl->right_glyphs)
4960 Dynarr_free (dl->right_glyphs);
4961 dl->right_glyphs = 0;
4964 /* We aren't generating a modeline at the moment. */
4967 /* Create a display block for the text region of the line. */
4968 ret_bufpos = create_string_text_block (w, disp_string, dl, start_pos,
4969 prop, default_face);
4970 dl->bufpos = start_pos;
4971 if (dl->end_bufpos < dl->bufpos)
4972 dl->end_bufpos = dl->bufpos;
4974 /* If there are left glyphs associated with any character in the
4975 text block, then create a display block to handle them. */
4976 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
4977 create_left_glyph_block (w, dl, 0);
4979 /* If there are right glyphs associated with any character in the
4980 text block, then create a display block to handle them. */
4981 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
4982 create_right_glyph_block (w, dl);
4987 /* This is ripped off from regenerate_window. All we want to do is
4988 loop through elements in the string creating display lines until we
4989 have covered the provided area. Simple really. */
4991 generate_displayable_area (struct window *w, Lisp_Object disp_string,
4992 int xpos, int ypos, int width, int height,
4993 display_line_dynarr* dla,
4995 face_index default_face)
4997 int yend = ypos + height;
5000 prop_block_dynarr *prop = 0;
5001 layout_bounds bounds;
5005 /* if there's nothing to do then do nothing. code after this assumes
5006 there is something to do. */
5007 if (NILP (disp_string))
5010 s_zv = XSTRING_CHAR_LENGTH (disp_string);
5012 bounds.left_out = xpos;
5013 bounds.right_out = xpos + width;
5014 /* The inner boundaries mark where the glyph margins are located. */
5015 bounds.left_in = bounds.left_out + window_left_margin_width (w);
5016 bounds.right_in = bounds.right_out - window_right_margin_width (w);
5017 /* We cannot fully calculate the whitespace boundaries as they
5018 depend on the contents of the line being displayed. */
5019 bounds.left_white = bounds.left_in;
5020 bounds.right_white = bounds.right_in;
5024 struct display_line dl;
5025 struct display_line *dlp;
5029 if (Dynarr_length (dla) < Dynarr_largest (dla))
5031 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5042 dlp->bounds = bounds;
5044 next_pos = generate_string_display_line (w, disp_string, dlp, start_pos,
5045 &prop, default_face);
5046 /* we need to make sure that we continue along the line if there
5047 is more left to display otherwise we just end up redisplaying
5048 the same chunk over and over again. */
5049 if (next_pos == start_pos && next_pos < s_zv)
5052 start_pos = next_pos;
5054 dlp->ypos = ypos + dlp->ascent;
5055 ypos = dlp->ypos + dlp->descent;
5059 int visible_height = dlp->ascent + dlp->descent;
5061 dlp->clip = (ypos - yend);
5062 visible_height -= dlp->clip;
5064 if (visible_height < VERTICAL_CLIP (w, 1))
5067 free_display_line (dlp);
5074 Dynarr_add (dla, *dlp);
5076 /* #### This type of check needs to be done down in the
5077 generate_display_line call. */
5078 if (start_pos >= s_zv)
5087 /***************************************************************************/
5089 /* window-regeneration routines */
5091 /***************************************************************************/
5093 /* For a given window and starting position in the buffer it contains,
5094 ensure that the TYPE display lines accurately represent the
5095 presentation of the window. We pass the buffer instead of getting
5096 it from the window since redisplay_window may have temporarily
5097 changed it to the echo area buffer. */
5100 regenerate_window (struct window *w, Bufpos start_pos, Bufpos point, int type)
5102 struct frame *f = XFRAME (w->frame);
5103 struct buffer *b = XBUFFER (w->buffer);
5104 int ypos = WINDOW_TEXT_TOP (w);
5105 int yend; /* set farther down */
5106 int yclip = WINDOW_TEXT_TOP_CLIP (w);
5108 prop_block_dynarr *prop;
5109 layout_bounds bounds;
5110 display_line_dynarr *dla;
5113 /* The lines had better exist by this point. */
5114 if (!(dla = window_display_lines (w, type)))
5117 w->max_line_len = 0;
5119 /* Normally these get updated in redisplay_window but it is possible
5120 for this function to get called from some other points where that
5121 update may not have occurred. This acts as a safety check. */
5122 if (!Dynarr_length (w->face_cachels))
5123 reset_face_cachels (w);
5124 if (!Dynarr_length (w->glyph_cachels))
5125 reset_glyph_cachels (w);
5127 Fset_marker (w->start[type], make_int (start_pos), w->buffer);
5128 Fset_marker (w->pointm[type], make_int (point), w->buffer);
5129 w->last_point_x[type] = -1;
5130 w->last_point_y[type] = -1;
5132 /* Make sure a modeline is in the structs if needed. */
5133 need_modeline = ensure_modeline_generated (w, type);
5135 /* Wait until here to set this so that the structs have a modeline
5136 generated in the case where one didn't exist. */
5137 yend = WINDOW_TEXT_BOTTOM (w);
5139 bounds = calculate_display_line_boundaries (w, 0);
5141 /* 97/3/14 jhod: stuff added here to support pre-prompts (used for input systems) */
5142 if (MINI_WINDOW_P (w)
5143 && (!NILP (Vminibuf_prompt) || !NILP (Vminibuf_preprompt))
5144 && !echo_area_active (f)
5145 && start_pos == BUF_BEGV (b))
5147 struct prop_block pb;
5149 prop = Dynarr_new (prop_block);
5151 string = concat2(Vminibuf_preprompt, Vminibuf_prompt);
5152 pb.type = PROP_MINIBUF_PROMPT;
5153 pb.data.p_string.str = XSTRING_DATA(string);
5154 pb.data.p_string.len = XSTRING_LENGTH(string);
5155 Dynarr_add (prop, pb);
5162 struct display_line dl;
5163 struct display_line *dlp;
5166 if (Dynarr_length (dla) < Dynarr_largest (dla))
5168 dlp = Dynarr_atp (dla, Dynarr_length (dla));
5179 dlp->bounds = bounds;
5181 start_pos = generate_display_line (w, dlp, 1, start_pos, &prop, type);
5183 if (yclip > dlp->ascent)
5185 /* this should never happen, but if it does just display the
5190 dlp->ypos = (ypos + dlp->ascent) - yclip;
5191 ypos = dlp->ypos + dlp->descent;
5193 /* See if we've been asked to start midway through a line, for
5194 partial display line scrolling. */
5197 dlp->top_clip = yclip;
5205 int visible_height = dlp->ascent + dlp->descent;
5207 dlp->clip = (ypos - yend);
5208 /* Although this seems strange we could have a single very
5209 tall line visible for which we need to account for both
5210 the top clip and the bottom clip. */
5211 visible_height -= (dlp->clip + dlp->top_clip);
5213 if (visible_height < VERTICAL_CLIP (w, 1))
5216 free_display_line (dlp);
5223 if (dlp->cursor_elt != -1)
5225 /* #### This check is steaming crap. Have to get things
5226 fixed so when create_text_block hits EOB, we're done,
5228 if (w->last_point_x[type] == -1)
5230 w->last_point_x[type] = dlp->cursor_elt;
5231 w->last_point_y[type] = Dynarr_length (dla);
5235 /* #### This means that we've added a cursor at EOB
5236 twice. Yuck oh yuck. */
5237 struct display_block *db =
5238 get_display_block_from_line (dlp, TEXT);
5240 Dynarr_atp (db->runes, dlp->cursor_elt)->cursor_type = NO_CURSOR;
5241 dlp->cursor_elt = -1;
5245 if (dlp->num_chars > w->max_line_len)
5246 w->max_line_len = dlp->num_chars;
5248 Dynarr_add (dla, *dlp);
5250 /* #### This isn't right, but it is close enough for now. */
5251 w->window_end_pos[type] = start_pos;
5253 /* #### This type of check needs to be done down in the
5254 generate_display_line call. */
5255 if (start_pos > BUF_ZV (b))
5262 /* #### More not quite right, but close enough. */
5263 /* #### Ben sez: apparently window_end_pos[] is measured
5264 as the number of characters between the window end and the
5265 end of the buffer? This seems rather weirdo. What's
5266 the justification for this? */
5267 w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type];
5271 /* We know that this is the right thing to use because we put it
5272 there when we first started working in this function. */
5273 generate_modeline (w, Dynarr_atp (dla, 0), type);
5277 #define REGEN_INC_FIND_START_END \
5279 /* Determine start and end of lines. */ \
5280 if (!Dynarr_length (cdla)) \
5284 if (Dynarr_atp (cdla, 0)->modeline && Dynarr_atp (ddla, 0)->modeline) \
5288 else if (!Dynarr_atp (cdla, 0)->modeline \
5289 && !Dynarr_atp (ddla, 0)->modeline) \
5294 abort (); /* structs differ */ \
5296 dla_end = Dynarr_length (cdla) - 1; \
5299 start_pos = (Dynarr_atp (cdla, dla_start)->bufpos \
5300 + Dynarr_atp (cdla, dla_start)->offset); \
5301 /* If this isn't true, then startp has changed and we need to do a \
5303 if (startp != start_pos) \
5306 /* Point is outside the visible region so give up. */ \
5307 if (pointm < start_pos) \
5312 /* This attempts to incrementally update the display structures. It
5313 returns a boolean indicating success or failure. This function is
5314 very similar to regenerate_window_incrementally and is in fact only
5315 called from that function. However, because of the nature of the
5316 changes it deals with it sometimes makes different assumptions
5317 which can lead to success which are much more difficult to make
5318 when dealing with buffer changes. */
5321 regenerate_window_extents_only_changed (struct window *w, Bufpos startp,
5323 Charcount beg_unchanged,
5324 Charcount end_unchanged)
5326 struct buffer *b = XBUFFER (w->buffer);
5327 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5328 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5332 int first_line, last_line;
5334 /* Don't define this in the loop where it is used because we
5335 definitely want its value to survive between passes. */
5336 prop_block_dynarr *prop = NULL;
5338 /* If we don't have any buffer change recorded but the modiff flag has
5339 been incremented, then fail. I'm not sure of the exact circumstances
5340 under which this can happen, but I believe that it is probably a
5341 reasonable happening. */
5342 if (!point_visible (w, pointm, CURRENT_DISP)
5343 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b))
5346 /* If the cursor is moved we attempt to update it. If we succeed we
5347 go ahead and proceed with the optimization attempt. */
5348 if (!EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5349 || pointm != marker_position (w->last_point[CURRENT_DISP]))
5351 struct frame *f = XFRAME (w->frame);
5352 struct device *d = XDEVICE (f->device);
5353 struct frame *sel_f = device_selected_frame (d);
5356 if (w->last_point_x[CURRENT_DISP] != -1
5357 && w->last_point_y[CURRENT_DISP] != -1)
5360 if (redisplay_move_cursor (w, pointm, WINDOW_TTY_P (w)))
5362 /* Always regenerate the modeline in case it is
5363 displaying the current line or column. */
5364 regenerate_modeline (w);
5368 else if (w != XWINDOW (FRAME_SELECTED_WINDOW (sel_f)))
5370 if (f->modeline_changed)
5371 regenerate_modeline (w);
5379 if (beg_unchanged == -1 && end_unchanged == -1)
5382 /* assert: There are no buffer modifications or they are all below the
5383 visible region. We assume that regenerate_window_incrementally has
5384 not called us unless this is true. */
5386 REGEN_INC_FIND_START_END;
5388 /* If the changed are starts before the visible area, give up. */
5389 if (beg_unchanged < startp)
5392 /* Find what display line the extent changes first affect. */
5394 while (line <= dla_end)
5396 struct display_line *dl = Dynarr_atp (cdla, line);
5397 Bufpos lstart = dl->bufpos + dl->offset;
5398 Bufpos lend = dl->end_bufpos + dl->offset;
5400 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5406 /* If the changes are below the visible area then if point hasn't
5407 moved return success otherwise fail in order to be safe. */
5410 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
5411 && pointm == marker_position (w->last_point[CURRENT_DISP]))
5417 /* At this point we know what line the changes first affect. We now
5418 begin redrawing lines as long as we are still in the affected
5419 region and the line's size and positioning don't change.
5420 Otherwise we fail. If we fail we will have altered the desired
5421 structs which could lead to an assertion failure. However, if we
5422 fail the next thing that is going to happen is a full regen so we
5423 will actually end up being safe. */
5424 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5425 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5426 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
5427 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
5429 first_line = last_line = line;
5430 while (line <= dla_end)
5432 Bufpos old_start, old_end, new_start;
5433 struct display_line *cdl = Dynarr_atp (cdla, line);
5434 struct display_line *ddl = Dynarr_atp (ddla, line);
5435 struct display_block *db;
5438 assert (cdl->bufpos == ddl->bufpos);
5439 assert (cdl->end_bufpos == ddl->end_bufpos);
5440 assert (cdl->offset == ddl->offset);
5442 db = get_display_block_from_line (ddl, TEXT);
5443 initial_size = Dynarr_length (db->runes);
5444 old_start = ddl->bufpos + ddl->offset;
5445 old_end = ddl->end_bufpos + ddl->offset;
5447 /* If this is the first line being updated and it used
5448 propagation data, fail. Otherwise we'll be okay because
5449 we'll have the necessary propagation data. */
5450 if (line == first_line && ddl->used_prop_data)
5453 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5454 &prop, DESIRED_DISP);
5457 /* #### If there is propagated stuff the fail. We could
5458 probably actually deal with this if the line had propagated
5459 information when originally created by a full
5467 /* If any line position parameters have changed or a
5468 cursor has disappeared or disappeared, fail. */
5469 db = get_display_block_from_line (ddl, TEXT);
5470 if (cdl->ypos != ddl->ypos
5471 || cdl->ascent != ddl->ascent
5472 || cdl->descent != ddl->descent
5473 || cdl->top_clip != ddl->top_clip
5474 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5475 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1)
5476 || old_start != ddl->bufpos
5477 || old_end != ddl->end_bufpos
5478 || initial_size != Dynarr_length (db->runes))
5483 if (ddl->cursor_elt != -1)
5485 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5486 w->last_point_y[DESIRED_DISP] = line;
5491 /* If the extent changes end on the line we just updated then
5492 we're done. Otherwise go on to the next line. */
5493 if (end_unchanged <= ddl->end_bufpos)
5499 redisplay_update_line (w, first_line, last_line, 1);
5503 /* Attempt to update the display data structures based on knowledge of
5504 the changed region in the buffer. Returns a boolean indicating
5505 success or failure. If this function returns a failure then a
5506 regenerate_window _must_ be performed next in order to maintain
5507 invariants located here. */
5510 regenerate_window_incrementally (struct window *w, Bufpos startp,
5513 struct buffer *b = XBUFFER (w->buffer);
5514 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
5515 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
5516 Charcount beg_unchanged, end_unchanged;
5517 Charcount extent_beg_unchanged, extent_end_unchanged;
5523 /* If this function is called, the current and desired structures
5524 had better be identical. If they are not, then that is a bug. */
5525 assert (Dynarr_length (cdla) == Dynarr_length (ddla));
5527 /* We don't handle minibuffer windows yet. The minibuffer prompt
5529 if (MINI_WINDOW_P (w))
5532 extent_beg_unchanged = BUF_EXTENT_BEGIN_UNCHANGED (b);
5533 extent_end_unchanged = (BUF_EXTENT_END_UNCHANGED (b) == -1
5535 : BUF_Z (b) - BUF_EXTENT_END_UNCHANGED (b));
5537 /* If nothing has changed in the buffer, then make sure point is ok
5539 if (BUF_BEGIN_UNCHANGED (b) == -1 && BUF_END_UNCHANGED (b) == -1)
5540 return regenerate_window_extents_only_changed (w, startp, pointm,
5541 extent_beg_unchanged,
5542 extent_end_unchanged);
5544 /* We can't deal with deleted newlines. */
5545 if (BUF_NEWLINE_WAS_DELETED (b))
5548 beg_unchanged = BUF_BEGIN_UNCHANGED (b);
5549 end_unchanged = (BUF_END_UNCHANGED (b) == -1
5551 : BUF_Z (b) - BUF_END_UNCHANGED (b));
5553 REGEN_INC_FIND_START_END;
5555 /* If the changed area starts before the visible area, give up. */
5556 if (beg_unchanged < startp)
5559 /* Find what display line the buffer changes first affect. */
5561 while (line <= dla_end)
5563 struct display_line *dl = Dynarr_atp (cdla, line);
5564 Bufpos lstart = dl->bufpos + dl->offset;
5565 Bufpos lend = dl->end_bufpos + dl->offset;
5567 if (beg_unchanged >= lstart && beg_unchanged <= lend)
5573 /* If the changes are below the visible area then if point hasn't
5574 moved return success otherwise fail in order to be safe. */
5576 return regenerate_window_extents_only_changed (w, startp, pointm,
5577 extent_beg_unchanged,
5578 extent_end_unchanged);
5580 /* At this point we know what line the changes first affect. We
5581 now redraw that line. If the changes are contained within it
5582 we are going to succeed and can update just that one line.
5583 Otherwise we fail. If we fail we will have altered the desired
5584 structs which could lead to an assertion failure. However, if
5585 we fail the next thing that is going to happen is a full regen
5586 so we will actually end up being safe. */
5589 prop_block_dynarr *prop = NULL;
5590 struct display_line *cdl = Dynarr_atp (cdla, line);
5591 struct display_line *ddl = Dynarr_atp (ddla, line);
5593 assert (cdl->bufpos == ddl->bufpos);
5594 assert (cdl->end_bufpos == ddl->end_bufpos);
5595 assert (cdl->offset == ddl->offset);
5597 /* If the last rune is already a continuation glyph, fail.
5598 #### We should be able to handle this better. */
5600 struct display_block *db = get_display_block_from_line (ddl, TEXT);
5601 if (Dynarr_length (db->runes))
5604 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
5606 if (rb->type == RUNE_DGLYPH
5607 && EQ (rb->object.dglyph.glyph, Vcontinuation_glyph))
5612 /* If the line was generated using propagation data, fail. */
5613 if (ddl->used_prop_data)
5616 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
5617 &prop, DESIRED_DISP);
5620 /* If there is propagated stuff then it is pretty much a
5621 guarantee that more than just the one line is affected. */
5628 /* If the last rune is now a continuation glyph, fail. */
5630 struct display_block *db = get_display_block_from_line (ddl, TEXT);
5631 if (Dynarr_length (db->runes))
5634 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
5636 if (rb->type == RUNE_DGLYPH
5637 && EQ (rb->object.dglyph.glyph, Vcontinuation_glyph))
5642 /* If any line position parameters have changed or a
5643 cursor has disappeared or disappeared, fail. */
5644 if (cdl->ypos != ddl->ypos
5645 || cdl->ascent != ddl->ascent
5646 || cdl->descent != ddl->descent
5647 || cdl->top_clip != ddl->top_clip
5648 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5649 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1))
5654 /* If the changed area also ends on this line, then we may be in
5655 business. Update everything and return success. */
5656 if (end_unchanged >= ddl->bufpos && end_unchanged <= ddl->end_bufpos)
5658 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
5659 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
5660 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp),
5662 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm),
5665 if (ddl->cursor_elt != -1)
5667 w->last_point_x[DESIRED_DISP] = ddl->cursor_elt;
5668 w->last_point_y[DESIRED_DISP] = line;
5671 redisplay_update_line (w, line, line, 1);
5672 regenerate_modeline (w);
5674 /* #### For now we just flush the cache until this has been
5675 tested. After that is done, this should correct the
5677 Dynarr_reset (w->line_start_cache);
5679 /* Adjust the extent changed boundaries to remove any
5680 overlap with the buffer changes since we've just
5681 successfully updated that area. */
5682 if (extent_beg_unchanged != -1
5683 && extent_beg_unchanged >= beg_unchanged
5684 && extent_beg_unchanged < end_unchanged)
5685 extent_beg_unchanged = end_unchanged;
5687 if (extent_end_unchanged != -1
5688 && extent_end_unchanged >= beg_unchanged
5689 && extent_end_unchanged < end_unchanged)
5690 extent_end_unchanged = beg_unchanged - 1;
5692 if (extent_end_unchanged <= extent_beg_unchanged)
5693 extent_beg_unchanged = extent_end_unchanged = -1;
5695 /* This could lead to odd results if it fails, but since the
5696 buffer changes update succeeded this probably will to.
5697 We already know that the extent changes start at or after
5698 the line because we checked before entering the loop. */
5699 if (extent_beg_unchanged != -1
5700 && extent_end_unchanged != -1
5701 && ((extent_beg_unchanged < ddl->bufpos)
5702 || (extent_end_unchanged > ddl->end_bufpos)))
5703 return regenerate_window_extents_only_changed (w, startp, pointm,
5704 extent_beg_unchanged,
5705 extent_end_unchanged);
5715 /* Given a window and a point, update the given display lines such
5716 that point is displayed in the middle of the window.
5717 Return the window's new start position. */
5720 regenerate_window_point_center (struct window *w, Bufpos point, int type)
5724 /* We need to make sure that the modeline is generated so that the
5725 window height can be calculated correctly. */
5726 ensure_modeline_generated (w, type);
5728 startp = start_with_line_at_pixpos (w, point, window_half_pixpos (w));
5729 regenerate_window (w, startp, point, type);
5730 Fset_marker (w->start[type], make_int (startp), w->buffer);
5735 /* Given a window and a set of display lines, return a boolean
5736 indicating whether the given point is contained within. */
5739 point_visible (struct window *w, Bufpos point, int type)
5741 struct buffer *b = XBUFFER (w->buffer);
5742 display_line_dynarr *dla = window_display_lines (w, type);
5745 if (Dynarr_length (dla) && Dynarr_atp (dla, 0)->modeline)
5750 if (Dynarr_length (dla) > first_line)
5753 struct display_line *dl = Dynarr_atp (dla, first_line);
5756 end = BUF_Z (b) - w->window_end_pos[type] - 1;
5758 if (point >= start && point <= end)
5760 if (!MINI_WINDOW_P (w) && scroll_on_clipped_lines)
5762 dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
5764 if (point >= (dl->bufpos + dl->offset)
5765 && point <= (dl->end_bufpos + dl->offset))
5780 /* Return pixel position the middle of the window, not including the
5781 modeline and any potential horizontal scrollbar. */
5784 window_half_pixpos (struct window *w)
5786 return WINDOW_TEXT_TOP (w) + (WINDOW_TEXT_HEIGHT (w) >> 1);
5789 /* Return the display line which is currently in the middle of the
5790 window W for display lines TYPE. */
5793 line_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5795 display_line_dynarr *dla;
5798 int first_elt = (MINI_WINDOW_P (w) ? 0 : 1);
5800 if (type == CMOTION_DISP)
5801 regenerate_window (w, start, point, type);
5803 dla = window_display_lines (w, type);
5804 half = window_half_pixpos (w);
5806 for (elt = first_elt; elt < Dynarr_length (dla); elt++)
5808 struct display_line *dl = Dynarr_atp (dla, elt);
5809 int line_bot = dl->ypos + dl->descent;
5811 if (line_bot > half)
5815 /* We may not have a line at the middle if the end of the buffer is
5820 /* Return a value for point that would place it at the beginning of
5821 the line which is in the middle of the window. */
5824 point_at_center (struct window *w, int type, Bufpos start, Bufpos point)
5826 /* line_at_center will regenerate the display structures, if necessary. */
5827 int line = line_at_center (w, type, start, point);
5830 return BUF_ZV (XBUFFER (w->buffer));
5833 display_line_dynarr *dla = window_display_lines (w, type);
5834 struct display_line *dl = Dynarr_atp (dla, line);
5840 /* For a given window, ensure that the current visual representation
5844 redisplay_window (Lisp_Object window, int skip_selected)
5846 struct window *w = XWINDOW (window);
5847 struct frame *f = XFRAME (w->frame);
5848 struct device *d = XDEVICE (f->device);
5849 Lisp_Object old_buffer = w->buffer;
5850 Lisp_Object the_buffer = w->buffer;
5852 int echo_active = 0;
5857 int selected_in_its_frame;
5858 int selected_globally;
5859 int skip_output = 0;
5860 int truncation_changed;
5861 int inactive_minibuffer =
5862 (MINI_WINDOW_P (w) &&
5863 (f != device_selected_frame (d)) &&
5864 !is_surrogate_for_selected_frame (f));
5866 /* #### In the new world this function actually does a bunch of
5867 optimizations such as buffer-based scrolling, but none of that is
5870 /* If this is a combination window, do its children; that's all.
5871 The selected window is always a leaf so we don't check for
5872 skip_selected here. */
5873 if (!NILP (w->vchild))
5875 redisplay_windows (w->vchild, skip_selected);
5878 if (!NILP (w->hchild))
5880 redisplay_windows (w->hchild, skip_selected);
5884 /* Is this window the selected window on its frame? */
5885 selected_in_its_frame = (w == XWINDOW (FRAME_SELECTED_WINDOW (f)));
5887 selected_in_its_frame &&
5888 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
5889 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d &&
5890 XFRAME(DEVICE_SELECTED_FRAME(d)) == f;
5891 if (skip_selected && selected_in_its_frame)
5894 /* It is possible that the window is not fully initialized yet. */
5895 if (NILP (w->buffer))
5898 if (MINI_WINDOW_P (w) && echo_area_active (f))
5900 w->buffer = the_buffer = Vecho_area_buffer;
5904 b = XBUFFER (w->buffer);
5908 old_pointm = selected_globally
5910 : marker_position (w->pointm[CURRENT_DISP]);
5915 if (selected_globally)
5917 pointm = BUF_PT (b);
5921 pointm = marker_position (w->pointm[CURRENT_DISP]);
5923 if (pointm < BUF_BEGV (b))
5924 pointm = BUF_BEGV (b);
5925 else if (pointm > BUF_ZV (b))
5926 pointm = BUF_ZV (b);
5929 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm), the_buffer);
5931 /* If the buffer has changed we have to invalidate all of our face
5933 if ((!echo_active && b != window_display_buffer (w))
5934 || !Dynarr_length (w->face_cachels)
5935 || f->faces_changed)
5936 reset_face_cachels (w);
5938 mark_face_cachels_as_not_updated (w);
5940 /* Ditto the glyph cache elements, although we do *not* invalidate
5941 the cache purely because glyphs have changed - this is now
5942 handled by the dirty flag.*/
5943 if ((!echo_active && b != window_display_buffer (w))
5944 || !Dynarr_length (w->glyph_cachels) || f->faces_changed)
5945 reset_glyph_cachels (w);
5947 mark_glyph_cachels_as_not_updated (w);
5949 /* If the marker's buffer is not the window's buffer, then we need
5950 to find a new starting position. */
5951 if (!MINI_WINDOW_P (w)
5952 && !EQ (Fmarker_buffer (w->start[CURRENT_DISP]), w->buffer))
5954 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
5956 goto regeneration_done;
5961 old_startp = marker_position (w->start[CURRENT_DISP]);
5966 startp = marker_position (w->start[CURRENT_DISP]);
5967 if (startp < BUF_BEGV (b))
5968 startp = BUF_BEGV (b);
5969 else if (startp > BUF_ZV (b))
5970 startp = BUF_ZV (b);
5972 Fset_marker (w->start[DESIRED_DISP], make_int (startp), the_buffer);
5974 truncation_changed = (find_window_mirror (w)->truncate_win !=
5975 window_truncation_on (w));
5977 /* If w->force_start is set, then some function set w->start and we
5978 should display from there and change point, if necessary, to
5979 ensure that it is visible. */
5980 if (w->force_start || inactive_minibuffer)
5983 w->last_modified[DESIRED_DISP] = Qzero;
5984 w->last_facechange[DESIRED_DISP] = Qzero;
5986 regenerate_window (w, startp, pointm, DESIRED_DISP);
5988 if (!point_visible (w, pointm, DESIRED_DISP) && !inactive_minibuffer)
5990 pointm = point_at_center (w, DESIRED_DISP, 0, 0);
5992 if (selected_globally)
5993 BUF_SET_PT (b, pointm);
5995 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm),
5998 /* #### BUFU amounts of overkill just to get the cursor
5999 location marked properly. FIX ME FIX ME FIX ME */
6000 regenerate_window (w, startp, pointm, DESIRED_DISP);
6003 goto regeneration_done;
6006 /* If nothing has changed since the last redisplay, then we just
6007 need to make sure that point is still visible. */
6008 if (XINT (w->last_modified[CURRENT_DISP]) >= BUF_MODIFF (b)
6009 && XINT (w->last_facechange[CURRENT_DISP]) >= BUF_FACECHANGE (b)
6011 /* This check is to make sure we restore the minibuffer after a
6012 temporary change to the echo area. */
6013 && !(MINI_WINDOW_P (w) && f->buffers_changed)
6014 && !f->frame_changed
6015 && !truncation_changed
6016 /* check whether start is really at the begining of a line GE */
6017 && (!w->start_at_line_beg || beginning_of_line_p (b, startp))
6020 /* Check if the cursor has actually moved. */
6021 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
6022 && pointm == marker_position (w->last_point[CURRENT_DISP])
6023 && selected_globally
6024 && !w->windows_changed
6026 && !f->extents_changed
6027 && !f->faces_changed
6028 && !f->glyphs_changed
6029 && !f->subwindows_changed
6030 /* && !f->subwindows_state_changed*/
6031 && !f->point_changed
6032 && !f->windows_structure_changed)
6034 /* If not, we're done. */
6035 if (f->modeline_changed)
6036 regenerate_modeline (w);
6039 goto regeneration_done;
6043 /* If the new point is visible in the redisplay structures,
6044 then let the output update routines handle it, otherwise
6045 do things the hard way. */
6046 if (!w->windows_changed
6048 && !f->extents_changed
6049 && !f->faces_changed
6050 && !f->glyphs_changed
6051 && !f->subwindows_changed
6052 /* && !f->subwindows_state_changed*/
6053 && !f->windows_structure_changed)
6055 if (point_visible (w, pointm, CURRENT_DISP)
6056 && w->last_point_x[CURRENT_DISP] != -1
6057 && w->last_point_y[CURRENT_DISP] != -1)
6059 if (redisplay_move_cursor (w, pointm, FRAME_TTY_P (f)))
6061 /* Always regenerate in case it is displaying
6062 the current line or column. */
6063 regenerate_modeline (w);
6066 goto regeneration_done;
6069 else if (!selected_in_its_frame && !f->point_changed)
6071 if (f->modeline_changed)
6072 regenerate_modeline (w);
6075 goto regeneration_done;
6079 /* If we weren't able to take the shortcut method, then use
6080 the brute force method. */
6081 regenerate_window (w, startp, pointm, DESIRED_DISP);
6083 if (point_visible (w, pointm, DESIRED_DISP))
6084 goto regeneration_done;
6088 /* Check if the starting point is no longer at the beginning of a
6089 line, in which case find a new starting point. We also recenter
6090 if our start position is equal to point-max. Otherwise we'll end
6091 up with a blank window. */
6092 else if (((w->start_at_line_beg || MINI_WINDOW_P (w))
6093 && !(startp == BUF_BEGV (b)
6094 || BUF_FETCH_CHAR (b, startp - 1) == '\n'))
6095 || (pointm == startp &&
6096 EQ (Fmarker_buffer (w->last_start[CURRENT_DISP]), w->buffer) &&
6097 startp < marker_position (w->last_start[CURRENT_DISP]))
6098 || (startp == BUF_ZV (b)))
6100 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6102 goto regeneration_done;
6104 /* See if we can update the data structures locally based on
6105 knowledge of what changed in the buffer. */
6106 else if (!w->windows_changed
6108 && !f->faces_changed
6109 && !f->glyphs_changed
6110 && !f->subwindows_changed
6111 /* && !f->subwindows_state_changed*/
6112 && !f->windows_structure_changed
6113 && !f->frame_changed
6114 && !truncation_changed
6116 && regenerate_window_incrementally (w, startp, pointm))
6118 if (f->modeline_changed
6119 || XINT (w->last_modified[CURRENT_DISP]) < BUF_MODIFF (b)
6120 || XINT (w->last_facechange[CURRENT_DISP]) < BUF_FACECHANGE (b))
6121 regenerate_modeline (w);
6124 goto regeneration_done;
6126 /* #### This is where a check for structure based scrolling would go. */
6127 /* If all else fails, try just regenerating and see what happens. */
6130 regenerate_window (w, startp, pointm, DESIRED_DISP);
6132 if (point_visible (w, pointm, DESIRED_DISP))
6133 goto regeneration_done;
6136 /* We still haven't gotten the window regenerated with point
6137 visible. Next we try scrolling a little and see if point comes
6138 back onto the screen. */
6139 if (scroll_step > 0)
6141 int scrolled = scroll_conservatively;
6142 for (; scrolled >= 0; scrolled -= scroll_step)
6144 startp = vmotion (w, startp,
6145 (pointm < startp) ? -scroll_step : scroll_step, 0);
6146 regenerate_window (w, startp, pointm, DESIRED_DISP);
6148 if (point_visible (w, pointm, DESIRED_DISP))
6149 goto regeneration_done;
6153 /* We still haven't managed to get the screen drawn with point on
6154 the screen, so just center it and be done with it. */
6155 startp = regenerate_window_point_center (w, pointm, DESIRED_DISP);
6160 /* If the window's frame is changed then reset the current display
6161 lines in order to force a full repaint. */
6162 if (f->frame_changed)
6164 display_line_dynarr *cla = window_display_lines (w, CURRENT_DISP);
6169 /* Must do this before calling redisplay_output_window because it
6170 sets some markers on the window. */
6173 w->buffer = old_buffer;
6174 Fset_marker (w->pointm[DESIRED_DISP], make_int (old_pointm), old_buffer);
6175 Fset_marker (w->start[DESIRED_DISP], make_int (old_startp), old_buffer);
6178 /* These also have to be set before calling redisplay_output_window
6179 since it sets the CURRENT_DISP values based on them. */
6180 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
6181 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
6182 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer);
6183 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer);
6187 Bufpos start = marker_position (w->start[DESIRED_DISP]);
6188 Bufpos end = (w->window_end_pos[DESIRED_DISP] == -1
6190 : BUF_Z (b) - w->window_end_pos[DESIRED_DISP] - 1);
6191 /* Don't pollute the cache if not sure if we are correct */
6192 if (w->start_at_line_beg)
6193 update_line_start_cache (w, start, end, pointm, 1);
6194 redisplay_output_window (w);
6196 * If we just displayed the echo area, the line start cache is
6197 * no longer valid, because the minibuffer window is associated
6198 * with the window now.
6201 w->line_cache_last_updated = make_int (-1);
6204 /* #### This should be dependent on face changes and will need to be
6205 somewhere else once tty updates occur on a per-frame basis. */
6206 mark_face_cachels_as_clean (w);
6208 /* The glyph cachels only get dirty if someone changed something.
6209 Since redisplay has now effectively ended we can reset the dirty
6210 flag since everything must be up-to-date. */
6212 mark_glyph_cachels_as_clean (w);
6214 w->windows_changed = 0;
6217 /* Call buffer_reset_changes for all buffers present in any window
6218 currently visible in all frames on all devices. #### There has to
6219 be a better way to do this. */
6222 reset_buffer_changes_mapfun (struct window *w, void *ignored_closure)
6224 buffer_reset_changes (XBUFFER (w->buffer));
6229 reset_buffer_changes (void)
6231 Lisp_Object frmcons, devcons, concons;
6233 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
6235 struct frame *f = XFRAME (XCAR (frmcons));
6237 if (FRAME_REPAINT_P (f))
6238 map_windows (f, reset_buffer_changes_mapfun, 0);
6242 /* Ensure that all windows underneath the given window in the window
6243 hierarchy are correctly displayed. */
6246 redisplay_windows (Lisp_Object window, int skip_selected)
6248 for (; !NILP (window) ; window = XWINDOW (window)->next)
6250 redisplay_window (window, skip_selected);
6255 call_redisplay_end_triggers (struct window *w, void *closure)
6257 Bufpos lrpos = w->last_redisplay_pos;
6258 w->last_redisplay_pos = 0;
6259 if (!NILP (w->buffer)
6260 && !NILP (w->redisplay_end_trigger)
6265 if (MARKERP (w->redisplay_end_trigger)
6266 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
6267 pos = marker_position (w->redisplay_end_trigger);
6268 else if (INTP (w->redisplay_end_trigger))
6269 pos = XINT (w->redisplay_end_trigger);
6272 w->redisplay_end_trigger = Qnil;
6279 XSETWINDOW (window, w);
6280 va_run_hook_with_args_in_buffer (XBUFFER (w->buffer),
6281 Qredisplay_end_trigger_functions,
6283 w->redisplay_end_trigger);
6284 w->redisplay_end_trigger = Qnil;
6291 /* Ensure that all windows on the given frame are correctly displayed. */
6294 redisplay_frame (struct frame *f, int preemption_check)
6296 struct device *d = XDEVICE (f->device);
6298 if (preemption_check)
6300 /* The preemption check itself takes a lot of time,
6301 so normally don't do it here. We do it if called
6302 from Lisp, though (`redisplay-frame'). */
6305 REDISPLAY_PREEMPTION_CHECK;
6310 /* Before we put a hold on frame size changes, attempt to process
6311 any which are already pending. */
6312 if (f->size_change_pending)
6313 change_frame_size (f, f->new_height, f->new_width, 0);
6315 /* If frame size might need to be changed, due to changed size
6316 of toolbars, scrollbars etc, change it now */
6317 if (f->size_slipped)
6319 adjust_frame_size (f);
6320 assert (!f->size_slipped);
6323 /* The menubar, toolbar, and icon updates must be done before
6324 hold_frame_size_changes is called and we are officially
6325 'in_display'. They may eval lisp code which may call Fsignal.
6326 If in_display is set Fsignal will abort. */
6328 #ifdef HAVE_MENUBARS
6329 /* Update the menubar. It is done first since it could change
6330 the menubar's visibility. This way we avoid having flashing
6331 caused by an Expose event generated by the visibility change
6333 update_frame_menubars (f);
6334 #endif /* HAVE_MENUBARS */
6335 /* widgets are similar to menus in that they can call lisp to
6336 determine activation etc. Therefore update them before we get
6337 into redisplay. This is primarily for connected widgets such as
6339 update_frame_subwindows (f);
6340 #ifdef HAVE_TOOLBARS
6341 /* Update the toolbars. */
6342 update_frame_toolbars (f);
6343 #endif /* HAVE_TOOLBARS */
6345 /* If we clear the frame we have to force its contents to be redrawn. */
6347 f->frame_changed = 1;
6349 /* invalidate the subwindow cache. We use subwindows_changed here to
6350 cause subwindows to get instantiated. This is because
6351 subwindows_state_changed is less strict - dealing with things
6352 like the clicked state of button. We have to do this before
6353 redisplaying the gutters as subwindows get unmapped in the
6355 if (!Dynarr_length (f->subwindow_cachels)
6356 || f->subwindows_changed
6358 || f->frame_changed)
6360 reset_subwindow_cachels (f);
6361 /* we have to do this so the gutter gets regenerated. */
6362 reset_gutter_display_lines (f);
6365 mark_subwindow_cachels_as_not_updated (f);
6367 /* We can now update the gutters, safe in the knowledge that our
6368 efforts won't get undone. */
6370 /* #### This can call lisp, it may be that if the subwindow cachels
6371 have been reset there are no remaining references to the
6372 displayed glyphs and so they get garbage collected. We should
6373 consider putting this call inside the critical redisplay
6375 update_frame_gutters (f);
6377 hold_frame_size_changes ();
6379 /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */
6380 /* Within this section, we are defenseless and assume that the
6381 following cannot happen:
6383 1) garbage collection
6384 2) Lisp code evaluation
6385 3) frame size changes
6387 We ensure (3) by calling hold_frame_size_changes(), which
6388 will cause any pending frame size changes to get put on hold
6389 till after the end of the critical section. (1) follows
6390 automatically if (2) is met. #### Unfortunately, there are
6391 some places where Lisp code can be called within this section.
6392 We need to remove them.
6394 If Fsignal() is called during this critical section, we
6397 If garbage collection is called during this critical section,
6398 we simply return. #### We should abort instead.
6400 #### If a frame-size change does occur we should probably
6401 actually be preempting redisplay. */
6403 /* Erase the frame before outputting its contents. */
6406 DEVMETH (d, clear_frame, (f));
6409 /* Do the selected window first. */
6410 redisplay_window (FRAME_SELECTED_WINDOW (f), 0);
6412 /* Then do the rest. */
6413 redisplay_windows (f->root_window, 1);
6415 /* We now call the output_end routine for tty frames. We delay
6416 doing so in order to avoid cursor flicker. So much for 100%
6418 if (FRAME_TTY_P (f))
6419 DEVMETH (d, output_end, (d));
6421 update_frame_title (f);
6423 CLASS_RESET_CHANGED_FLAGS (f);
6424 f->window_face_cache_reset = 0;
6425 f->echo_area_garbaged = 0;
6428 if (!f->size_change_pending)
6429 f->size_changed = 0;
6431 /* ----------------- END CRITICAL REDISPLAY SECTION ---------------- */
6433 /* Allow frame size changes to occur again.
6435 #### what happens if changes to other frames happen? */
6436 unhold_one_frame_size_changes (f);
6438 map_windows (f, call_redisplay_end_triggers, 0);
6442 /* Ensure that all frames on the given device are correctly displayed.
6443 If AUTOMATIC is non-zero, and the device implementation indicates
6444 no automatic redisplay, as printers do, then the device is not
6445 redisplayed. AUTOMATIC is set to zero when called from lisp
6446 functions (redraw-device) and (redisplay-device), and to non-zero
6447 when called from "lazy" redisplay();
6451 redisplay_device (struct device *d, int automatic)
6453 Lisp_Object frame, frmcons;
6455 int size_change_failed = 0;
6459 && (MAYBE_INT_DEVMETH (d, device_implementation_flags, ())
6460 & XDEVIMPF_NO_AUTO_REDISPLAY))
6463 if (DEVICE_STREAM_P (d)) /* nothing to do */
6466 /* It is possible that redisplay has been called before the
6467 device is fully initialized. If so then continue with the
6469 if (NILP (DEVICE_SELECTED_FRAME (d)))
6472 REDISPLAY_PREEMPTION_CHECK;
6476 /* Always do the selected frame first. */
6477 frame = DEVICE_SELECTED_FRAME (d);
6481 if (f->icon_changed || f->windows_changed)
6482 update_frame_icon (f);
6484 if (FRAME_REPAINT_P (f))
6486 if (CLASS_REDISPLAY_FLAGS_CHANGEDP(f))
6488 preempted = redisplay_frame (f, 0);
6494 /* If the frame redisplay did not get preempted, then this flag
6495 should have gotten set to 0. It might be possible for that
6496 not to happen if a size change event were to occur at an odd
6497 time. To make sure we don't miss anything we simply don't
6498 reset the top level flags until the condition ends up being
6499 in the right state. */
6500 if (f->size_changed)
6501 size_change_failed = 1;
6504 DEVICE_FRAME_LOOP (frmcons, d)
6506 f = XFRAME (XCAR (frmcons));
6508 if (f == XFRAME (DEVICE_SELECTED_FRAME (d)))
6511 if (f->icon_changed || f->windows_changed)
6512 update_frame_icon (f);
6514 if (FRAME_REPAINT_P (f))
6516 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (f))
6518 preempted = redisplay_frame (f, 0);
6524 if (f->size_change_pending)
6525 size_change_failed = 1;
6529 /* If we get here then we redisplayed all of our frames without
6530 getting preempted so mark ourselves as clean. */
6531 CLASS_RESET_CHANGED_FLAGS (d);
6533 if (!size_change_failed)
6534 d->size_changed = 0;
6540 restore_profiling_redisplay_flag (Lisp_Object val)
6542 profiling_redisplay_flag = XINT (val);
6546 /* Ensure that all windows on all frames on all devices are displaying
6547 the current contents of their respective buffers. */
6550 redisplay_without_hooks (void)
6552 Lisp_Object devcons, concons;
6553 int size_change_failed = 0;
6554 int count = specpdl_depth ();
6556 if (profiling_active)
6558 record_unwind_protect (restore_profiling_redisplay_flag,
6559 make_int (profiling_redisplay_flag));
6560 profiling_redisplay_flag = 1;
6563 if (asynch_device_change_pending)
6564 handle_asynch_device_change ();
6566 if (!GLOBAL_REDISPLAY_FLAGS_CHANGEDP &&
6567 !disable_preemption && preemption_count < max_preempts)
6570 DEVICE_LOOP_NO_BREAK (devcons, concons)
6572 struct device *d = XDEVICE (XCAR (devcons));
6575 if (CLASS_REDISPLAY_FLAGS_CHANGEDP (d))
6577 preempted = redisplay_device (d, 1);
6582 RESET_CHANGED_SET_FLAGS;
6586 /* See comment in redisplay_device. */
6587 if (d->size_changed)
6588 size_change_failed = 1;
6591 preemption_count = 0;
6593 /* Mark redisplay as accurate */
6594 GLOBAL_RESET_CHANGED_FLAGS;
6595 RESET_CHANGED_SET_FLAGS;
6599 mark_all_faces_as_clean ();
6603 if (!size_change_failed)
6606 reset_buffer_changes ();
6609 unbind_to (count, Qnil);
6615 if (last_display_warning_tick != display_warning_tick &&
6616 !inhibit_warning_display)
6618 /* If an error occurs during this function, oh well.
6619 If we report another warning, we could get stuck in an
6620 infinite loop reporting warnings. */
6621 call0_trapping_errors (0, Qdisplay_warning_buffer);
6622 last_display_warning_tick = display_warning_tick;
6624 /* The run_hook_trapping_errors functions are smart enough not
6625 to do any evalling if the hook function is empty, so there
6626 should not be any significant time loss. All places in the
6627 C code that call redisplay() are prepared to handle GCing,
6628 so we should be OK. */
6629 #ifndef INHIBIT_REDISPLAY_HOOKS
6630 run_hook_trapping_errors ("Error in pre-redisplay-hook",
6631 Qpre_redisplay_hook);
6632 #endif /* INHIBIT_REDISPLAY_HOOKS */
6634 redisplay_without_hooks ();
6636 #ifndef INHIBIT_REDISPLAY_HOOKS
6637 run_hook_trapping_errors ("Error in post-redisplay-hook",
6638 Qpost_redisplay_hook);
6639 #endif /* INHIBIT_REDISPLAY_HOOKS */
6643 static char window_line_number_buf[32];
6645 /* Efficiently determine the window line number, and return a pointer
6646 to its printed representation. Do this regardless of whether
6647 line-number-mode is on. The first line in the buffer is counted as
6648 1. If narrowing is in effect, the lines are counted from the
6649 beginning of the visible portion of the buffer. */
6651 window_line_number (struct window *w, int type)
6653 struct device *d = XDEVICE (XFRAME (w->frame)->device);
6654 struct buffer *b = XBUFFER (w->buffer);
6655 /* Be careful in the order of these tests. The first clause will
6656 fail if DEVICE_SELECTED_FRAME == Qnil (since w->frame cannot be).
6657 This can occur when the frame title is computed really early */
6659 ((EQ(DEVICE_SELECTED_FRAME(d), w->frame) &&
6660 (w == XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame(d)))) &&
6661 EQ(DEVICE_CONSOLE(d), Vselected_console) &&
6662 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d )
6664 : marker_position (w->pointm[type]));
6667 line = buffer_line_number (b, pos, 1);
6669 long_to_string (window_line_number_buf, line + 1);
6671 return window_line_number_buf;
6675 /* Given a character representing an object in a modeline
6676 specification, return a string (stored into the global array
6677 `mode_spec_bufbyte_string') with the information that object
6680 This function is largely unchanged from previous versions of the
6683 Warning! This code is also used for frame titles and can be called
6684 very early in the device/frame update process! JV
6688 decode_mode_spec (struct window *w, Emchar spec, int type)
6690 Lisp_Object obj = Qnil;
6691 const char *str = NULL;
6692 struct buffer *b = XBUFFER (w->buffer);
6694 Dynarr_reset (mode_spec_bufbyte_string);
6698 /* print buffer name */
6703 /* print visited file name */
6708 /* print the current column */
6711 Bufpos pt = (w == XWINDOW (Fselected_window (Qnil)))
6713 : marker_position (w->pointm[type]);
6714 int col = column_at_point (b, pt, 1) + !!column_number_start_at_one;
6717 long_to_string (buf, col);
6719 Dynarr_add_many (mode_spec_bufbyte_string,
6720 (const Bufbyte *) buf, strlen (buf));
6722 goto decode_mode_spec_done;
6724 /* print the file coding system */
6728 Lisp_Object codesys = b->buffer_file_coding_system;
6729 /* Be very careful here not to get an error. */
6730 if (NILP (codesys) || SYMBOLP (codesys) || CODING_SYSTEMP (codesys))
6732 codesys = Ffind_coding_system (codesys);
6733 if (CODING_SYSTEMP (codesys))
6734 obj = XCODING_SYSTEM_MNEMONIC (codesys);
6737 #endif /* FILE_CODING */
6740 /* print the current line number */
6742 str = window_line_number (w, type);
6745 /* print value of mode-name (obsolete) */
6750 /* print hyphen and frame number, if != 1 */
6754 struct frame *f = XFRAME (w->frame);
6755 if (FRAME_TTY_P (f) && f->order_count > 1 && f->order_count <= 99999999)
6757 /* Naughty, naughty */
6758 char * writable_str = alloca_array (char, 10);
6759 sprintf (writable_str, "-%d", f->order_count);
6763 #endif /* HAVE_TTY */
6766 /* print Narrow if appropriate */
6768 if (BUF_BEGV (b) > BUF_BEG (b)
6769 || BUF_ZV (b) < BUF_Z (b))
6773 /* print %, * or hyphen, if buffer is read-only, modified or neither */
6775 str = (!NILP (b->read_only)
6777 : ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6782 /* print * or hyphen -- XEmacs change to allow a buffer to be
6783 read-only but still indicate whether it is modified. */
6785 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6787 : (!NILP (b->read_only)
6792 /* #### defined in 19.29 decode_mode_spec, but not in
6793 modeline-format doc string. */
6794 /* This differs from %* in that it ignores read-only-ness. */
6796 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
6801 /* print process status */
6803 obj = Fget_buffer_process (w->buffer);
6805 str = GETTEXT ("no process");
6807 obj = Fsymbol_name (Fprocess_status (obj));
6810 /* Print name of selected frame. */
6812 obj = XFRAME (w->frame)->name;
6815 /* indicate TEXT or BINARY */
6817 /* #### NT does not use this any more. Now what? */
6821 /* print percent of buffer above top of window, or Top, Bot or All */
6824 Bufpos pos = marker_position (w->start[type]);
6826 /* This had better be while the desired lines are being done. */
6827 if (w->window_end_pos[type] <= BUF_Z (b) - BUF_ZV (b))
6829 if (pos <= BUF_BEGV (b))
6834 else if (pos <= BUF_BEGV (b))
6838 /* This hard limit is ok since the string it will hold has a
6839 fixed maximum length of 3. But just to be safe... */
6841 Charcount chars = pos - BUF_BEGV (b);
6842 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6844 /* Avoid overflow on big buffers */
6845 int percent = total > LONG_MAX/200 ?
6846 (chars + total/200) / (total / 100) :
6847 (chars * 100 + total/2) / total;
6849 /* We can't normally display a 3-digit number, so get us a
6850 2-digit number that is close. */
6854 sprintf (buf, "%d%%", percent);
6855 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6858 goto decode_mode_spec_done;
6863 /* print percent of buffer above bottom of window, perhaps plus
6864 Top, or print Bottom or All */
6867 Bufpos toppos = marker_position (w->start[type]);
6868 Bufpos botpos = BUF_Z (b) - w->window_end_pos[type];
6870 /* botpos is only accurate as of the last redisplay, so we can
6871 only treat it as a hint. In particular, after erase-buffer,
6872 botpos may be negative. */
6873 if (botpos < toppos)
6876 if (botpos >= BUF_ZV (b))
6878 if (toppos <= BUF_BEGV (b))
6885 /* This hard limit is ok since the string it will hold has a
6886 fixed maximum length of around 6. But just to be safe... */
6888 Charcount chars = botpos - BUF_BEGV (b);
6889 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
6891 /* Avoid overflow on big buffers */
6892 int percent = total > LONG_MAX/200 ?
6893 (chars + total/200) / (total / 100) :
6894 (chars * 100 + total/2) / max (total, 1);
6896 /* We can't normally display a 3-digit number, so get us a
6897 2-digit number that is close. */
6901 if (toppos <= BUF_BEGV (b))
6902 sprintf (buf, "Top%d%%", percent);
6904 sprintf (buf, "%d%%", percent);
6906 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
6909 goto decode_mode_spec_done;
6919 /* print one [ for each recursive editing level. */
6924 if (command_loop_level > 5)
6930 for (i = 0; i < command_loop_level; i++)
6931 Dynarr_add (mode_spec_bufbyte_string, '[');
6933 goto decode_mode_spec_done;
6936 /* print one ] for each recursive editing level. */
6941 if (command_loop_level > 5)
6947 for (i = 0; i < command_loop_level; i++)
6948 Dynarr_add (mode_spec_bufbyte_string, ']');
6950 goto decode_mode_spec_done;
6953 /* print infinitely many dashes -- handle at top level now */
6960 Dynarr_add_many (mode_spec_bufbyte_string,
6962 XSTRING_LENGTH (obj));
6964 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) str, strlen (str));
6966 decode_mode_spec_done:
6967 Dynarr_add (mode_spec_bufbyte_string, '\0');
6970 /* Given a display line, free all of its data structures. */
6973 free_display_line (struct display_line *dl)
6977 if (dl->display_blocks)
6979 for (block = 0; block < Dynarr_largest (dl->display_blocks); block++)
6981 struct display_block *db = Dynarr_atp (dl->display_blocks, block);
6983 Dynarr_free (db->runes);
6986 Dynarr_free (dl->display_blocks);
6987 dl->display_blocks = NULL;
6990 if (dl->left_glyphs)
6992 Dynarr_free (dl->left_glyphs);
6993 dl->left_glyphs = NULL;
6996 if (dl->right_glyphs)
6998 Dynarr_free (dl->right_glyphs);
6999 dl->right_glyphs = NULL;
7004 /* Given an array of display lines, free them and all data structures
7005 contained within them. */
7008 free_display_lines (display_line_dynarr *dla)
7012 for (line = 0; line < Dynarr_largest (dla); line++)
7014 free_display_line (Dynarr_atp (dla, line));
7020 /* Call internal free routine for each set of display lines. */
7023 free_display_structs (struct window_mirror *mir)
7025 if (mir->current_display_lines)
7027 free_display_lines (mir->current_display_lines);
7028 mir->current_display_lines = 0;
7031 if (mir->desired_display_lines)
7033 free_display_lines (mir->desired_display_lines);
7034 mir->desired_display_lines = 0;
7040 mark_glyph_block_dynarr (glyph_block_dynarr *gba)
7044 glyph_block *gb = Dynarr_atp (gba, 0);
7045 glyph_block *gb_last = Dynarr_atp (gba, Dynarr_length (gba));
7047 for (; gb < gb_last; gb++)
7049 if (!NILP (gb->glyph))
7050 mark_object (gb->glyph);
7051 if (!NILP (gb->extent))
7052 mark_object (gb->extent);
7057 /* See the comment in image_instantiate_cache_result as to why marking
7058 the glyph will also mark the image_instance. */
7060 mark_redisplay_structs (display_line_dynarr *dla)
7062 display_line *dl = Dynarr_atp (dla, 0);
7063 display_line *dl_last = Dynarr_atp (dla, Dynarr_length (dla));
7065 for (; dl < dl_last; dl++)
7067 display_block_dynarr *dba = dl->display_blocks;
7068 display_block *db = Dynarr_atp (dba, 0);
7069 display_block *db_last = Dynarr_atp (dba, Dynarr_length (dba));
7071 for (; db < db_last; db++)
7073 rune_dynarr *ra = db->runes;
7074 rune *r = Dynarr_atp (ra, 0);
7075 rune *r_last = Dynarr_atp (ra, Dynarr_length (ra));
7077 for (; r < r_last; r++)
7079 if (r->type == RUNE_DGLYPH)
7081 if (!NILP (r->object.dglyph.glyph))
7082 mark_object (r->object.dglyph.glyph);
7083 if (!NILP (r->object.dglyph.extent))
7084 mark_object (r->object.dglyph.extent);
7089 mark_glyph_block_dynarr (dl->left_glyphs);
7090 mark_glyph_block_dynarr (dl->right_glyphs);
7095 mark_window_mirror (struct window_mirror *mir)
7097 mark_redisplay_structs (mir->current_display_lines);
7098 mark_redisplay_structs (mir->desired_display_lines);
7101 mark_window_mirror (mir->next);
7104 mark_window_mirror (mir->hchild);
7105 else if (mir->vchild)
7106 mark_window_mirror (mir->vchild);
7110 mark_redisplay (void)
7112 Lisp_Object frmcons, devcons, concons;
7114 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
7116 struct frame *f = XFRAME (XCAR (frmcons));
7117 update_frame_window_mirror (f);
7118 mark_window_mirror (f->root_mirror);
7123 /*****************************************************************************
7124 Line Start Cache Description and Rationale
7126 The traditional scrolling code in Emacs breaks in a variable height world.
7127 It depends on the key assumption that the number of lines that can be
7128 displayed at any given time is fixed. This led to a complete separation
7129 of the scrolling code from the redisplay code. In order to fully support
7130 variable height lines, the scrolling code must actually be tightly
7131 integrated with redisplay. Only redisplay can determine how many lines
7132 will be displayed on a screen for any given starting point.
7134 What is ideally wanted is a complete list of the starting buffer position
7135 for every possible display line of a buffer along with the height of that
7136 display line. Maintaining such a full list would be very expensive. We
7137 settle for having it include information for all areas which we happen to
7138 generate anyhow (i.e. the region currently being displayed) and for those
7139 areas we need to work with.
7141 In order to ensure that the cache accurately represents what redisplay
7142 would actually show, it is necessary to invalidate it in many situations.
7143 If the buffer changes, the starting positions may no longer be correct.
7144 If a face or an extent has changed then the line heights may have altered.
7145 These events happen frequently enough that the cache can end up being
7146 constantly disabled. With this potentially constant invalidation when is
7147 the cache ever useful?
7149 Even if the cache is invalidated before every single usage, it is
7150 necessary. Scrolling often requires knowledge about display lines which
7151 are actually above or below the visible region. The cache provides a
7152 convenient light-weight method of storing this information for multiple
7153 display regions. This knowledge is necessary for the scrolling code to
7154 always obey the First Golden Rule of Redisplay.
7156 If the cache already contains all of the information that the scrolling
7157 routines happen to need so that it doesn't have to go generate it, then we
7158 are able to obey the Third Golden Rule of Redisplay. The first thing we
7159 do to help out the cache is to always add the displayed region. This
7160 region had to be generated anyway, so the cache ends up getting the
7161 information basically for free. In those cases where a user is simply
7162 scrolling around viewing a buffer there is a high probability that this is
7163 sufficient to always provide the needed information. The second thing we
7164 can do is be smart about invalidating the cache.
7166 TODO -- Be smart about invalidating the cache. Potential places:
7168 + Insertions at end-of-line which don't cause line-wraps do not alter the
7169 starting positions of any display lines. These types of buffer
7170 modifications should not invalidate the cache. This is actually a large
7171 optimization for redisplay speed as well.
7173 + Buffer modifications frequently only affect the display of lines at and
7174 below where they occur. In these situations we should only invalidate
7175 the part of the cache starting at where the modification occurs.
7177 In case you're wondering, the Second Golden Rule of Redisplay is not
7179 ****************************************************************************/
7181 /* This will get used quite a bit so we don't want to be constantly
7182 allocating and freeing it. */
7183 static line_start_cache_dynarr *internal_cache;
7185 /* Makes internal_cache represent the TYPE display structs and only
7186 the TYPE display structs. */
7189 update_internal_cache_list (struct window *w, int type)
7192 display_line_dynarr *dla = window_display_lines (w, type);
7194 Dynarr_reset (internal_cache);
7195 for (line = 0; line < Dynarr_length (dla); line++)
7197 struct display_line *dl = Dynarr_atp (dla, line);
7203 struct line_start_cache lsc;
7205 lsc.start = dl->bufpos;
7206 lsc.end = dl->end_bufpos;
7207 lsc.height = dl->ascent + dl->descent;
7209 Dynarr_add (internal_cache, lsc);
7214 /* Reset the line cache if necessary. This should be run at the
7215 beginning of any function which access the cache. */
7218 validate_line_start_cache (struct window *w)
7220 struct buffer *b = XBUFFER (w->buffer);
7221 struct frame *f = XFRAME (w->frame);
7223 if (!w->line_cache_validation_override)
7225 /* f->extents_changed used to be in here because extent face and
7226 size changes can cause text shifting. However, the extent
7227 covering the region is constantly having its face set and
7228 priority altered by the mouse code. This means that the line
7229 start cache is constantly being invalidated. This is bad
7230 since the mouse code also triggers heavy usage of the cache.
7231 Since it is an unlikely that f->extents being changed
7232 indicates that the cache really needs to be updated and if it
7233 does redisplay will catch it pretty quickly we no longer
7234 invalidate the cache if it is set. This greatly speeds up
7235 dragging out regions with the mouse. */
7236 if (XINT (w->line_cache_last_updated) < BUF_MODIFF (b)
7240 Dynarr_reset (w->line_start_cache);
7245 /* Return the very first buffer position contained in the given
7246 window's cache, or -1 if the cache is empty. Assumes that the
7250 line_start_cache_start (struct window *w)
7252 line_start_cache_dynarr *cache = w->line_start_cache;
7254 if (!Dynarr_length (cache))
7257 return Dynarr_atp (cache, 0)->start;
7260 /* Return the very last buffer position contained in the given
7261 window's cache, or -1 if the cache is empty. Assumes that the
7265 line_start_cache_end (struct window *w)
7267 line_start_cache_dynarr *cache = w->line_start_cache;
7269 if (!Dynarr_length (cache))
7272 return Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
7275 /* Return the index of the line POINT is contained within in window
7276 W's line start cache. It will enlarge the cache or move the cache
7277 window in order to have POINT be present in the cache. MIN_PAST is
7278 a guarantee of the number of entries in the cache present on either
7279 side of POINT (unless a buffer boundary is hit). If MIN_PAST is -1
7280 then it will be treated as 0, but the cache window will not be
7281 allowed to shift. Returns -1 if POINT cannot be found in the cache
7285 point_in_line_start_cache (struct window *w, Bufpos point, int min_past)
7287 struct buffer *b = XBUFFER (w->buffer);
7288 line_start_cache_dynarr *cache = w->line_start_cache;
7289 unsigned int top, bottom, pos;
7291 validate_line_start_cache (w);
7292 w->line_cache_validation_override++;
7294 /* Let functions pass in negative values, but we still treat -1
7296 /* #### bogosity alert */
7297 if (min_past < 0 && min_past != -1)
7298 min_past = -min_past;
7300 if (!Dynarr_length (cache) || line_start_cache_start (w) > point
7301 || line_start_cache_end (w) < point)
7304 int win_char_height = window_char_height (w, 1);
7306 /* Occasionally we get here with a 0 height
7307 window. find_next_newline_no_quit will abort if we pass it a
7308 count of 0 so handle that case. */
7309 if (!win_char_height)
7310 win_char_height = 1;
7312 if (!Dynarr_length (cache))
7314 Bufpos from = find_next_newline_no_quit (b, point, -1);
7315 Bufpos to = find_next_newline_no_quit (b, from, win_char_height);
7317 update_line_start_cache (w, from, to, point, 0);
7319 if (!Dynarr_length (cache))
7321 w->line_cache_validation_override--;
7326 assert (Dynarr_length (cache));
7329 while (line_start_cache_start (w) > point
7330 && (loop < cache_adjustment || min_past == -1))
7334 from = line_start_cache_start (w);
7335 if (from <= BUF_BEGV (b))
7338 from = find_next_newline_no_quit (b, from, -win_char_height);
7339 to = line_start_cache_end (w);
7341 update_line_start_cache (w, from, to, point, 0);
7345 if (line_start_cache_start (w) > point)
7349 from = find_next_newline_no_quit (b, point, -1);
7350 if (from >= BUF_ZV (b))
7352 to = find_next_newline_no_quit (b, from, -win_char_height);
7357 to = find_next_newline_no_quit (b, from, win_char_height);
7359 update_line_start_cache (w, from, to, point, 0);
7363 while (line_start_cache_end (w) < point
7364 && (loop < cache_adjustment || min_past == -1))
7368 to = line_start_cache_end (w);
7369 if (to >= BUF_ZV (b))
7372 from = line_start_cache_end (w);
7373 to = find_next_newline_no_quit (b, from, win_char_height);
7375 update_line_start_cache (w, from, to, point, 0);
7379 if (line_start_cache_end (w) < point)
7383 from = find_next_newline_no_quit (b, point, -1);
7384 if (from >= BUF_ZV (b))
7386 to = find_next_newline_no_quit (b, from, -win_char_height);
7391 to = find_next_newline_no_quit (b, from, win_char_height);
7393 update_line_start_cache (w, from, to, point, 0);
7397 assert (Dynarr_length (cache));
7402 /* This could happen if the buffer is narrowed. */
7403 if (line_start_cache_start (w) > point
7404 || line_start_cache_end (w) < point)
7406 w->line_cache_validation_override--;
7412 top = Dynarr_length (cache) - 1;
7417 unsigned int new_pos;
7420 pos = (bottom + top + 1) >> 1;
7421 start = Dynarr_atp (cache, pos)->start;
7422 end = Dynarr_atp (cache, pos)->end;
7424 if (point >= start && point <= end)
7426 if (pos < min_past && line_start_cache_start (w) > BUF_BEGV (b))
7429 find_next_newline_no_quit (b, line_start_cache_start (w),
7431 Bufpos to = line_start_cache_end (w);
7433 update_line_start_cache (w, from, to, point, 0);
7434 goto find_point_loop;
7436 else if ((Dynarr_length (cache) - pos - 1) < min_past
7437 && line_start_cache_end (w) < BUF_ZV (b))
7439 Bufpos from = line_start_cache_end (w);
7440 Bufpos to = find_next_newline_no_quit (b, from,
7445 update_line_start_cache (w, from, to, point, 0);
7446 goto find_point_loop;
7450 w->line_cache_validation_override--;
7454 else if (point > end)
7456 else if (point < start)
7461 new_pos = (bottom + top + 1) >> 1;
7464 w->line_cache_validation_override--;
7470 /* Return a boolean indicating if POINT would be visible in window W
7471 if display of the window was to begin at STARTP. */
7474 point_would_be_visible (struct window *w, Bufpos startp, Bufpos point)
7476 struct buffer *b = XBUFFER (w->buffer);
7477 int pixpos = -WINDOW_TEXT_TOP_CLIP(w);
7478 int bottom = WINDOW_TEXT_HEIGHT (w);
7481 /* If point is before the intended start it obviously can't be visible. */
7485 /* If point or start are not in the accessible buffer range, then
7487 if (startp < BUF_BEGV (b) || startp > BUF_ZV (b)
7488 || point < BUF_BEGV (b) || point > BUF_ZV (b))
7491 validate_line_start_cache (w);
7492 w->line_cache_validation_override++;
7494 start_elt = point_in_line_start_cache (w, startp, 0);
7495 if (start_elt == -1)
7497 w->line_cache_validation_override--;
7501 assert (line_start_cache_start (w) <= startp
7502 && line_start_cache_end (w) >= startp);
7508 /* Expand the cache if necessary. */
7509 if (start_elt == Dynarr_length (w->line_start_cache))
7512 Dynarr_atp (w->line_start_cache, start_elt - 1)->start;
7514 start_elt = point_in_line_start_cache (w, old_startp,
7515 window_char_height (w, 0));
7517 /* We've already actually processed old_startp, so increment
7521 /* If this happens we didn't add any extra elements. Bummer. */
7522 if (start_elt == Dynarr_length (w->line_start_cache))
7524 w->line_cache_validation_override--;
7529 height = Dynarr_atp (w->line_start_cache, start_elt)->height;
7531 if (pixpos + height > bottom)
7533 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7535 w->line_cache_validation_override--;
7541 if (point <= Dynarr_atp (w->line_start_cache, start_elt)->end)
7543 w->line_cache_validation_override--;
7551 /* For the given window W, if display starts at STARTP, what will be
7552 the buffer position at the beginning or end of the last line
7553 displayed. The end of the last line is also know as the window end
7556 #### With a little work this could probably be reworked as just a
7557 call to start_with_line_at_pixpos. */
7560 start_end_of_last_line (struct window *w, Bufpos startp, int end)
7562 struct buffer *b = XBUFFER (w->buffer);
7563 line_start_cache_dynarr *cache = w->line_start_cache;
7565 int bottom = WINDOW_TEXT_HEIGHT (w);
7569 validate_line_start_cache (w);
7570 w->line_cache_validation_override++;
7572 if (startp < BUF_BEGV (b))
7573 startp = BUF_BEGV (b);
7574 else if (startp > BUF_ZV (b))
7575 startp = BUF_ZV (b);
7578 start_elt = point_in_line_start_cache (w, cur_start, 0);
7579 if (start_elt == -1)
7580 abort (); /* this had better never happen */
7584 int height = Dynarr_atp (cache, start_elt)->height;
7586 cur_start = Dynarr_atp (cache, start_elt)->start;
7588 if (pixpos + height > bottom)
7590 /* Adjust for any possible clip. */
7591 if (bottom - pixpos < VERTICAL_CLIP (w, 0))
7596 w->line_cache_validation_override--;
7600 return BUF_BEGV (b);
7604 w->line_cache_validation_override--;
7606 return Dynarr_atp (cache, start_elt)->end;
7608 return Dynarr_atp (cache, start_elt)->start;
7614 if (start_elt == Dynarr_length (cache))
7616 Bufpos from = line_start_cache_end (w);
7617 int win_char_height = window_char_height (w, 0);
7618 Bufpos to = find_next_newline_no_quit (b, from,
7623 /* We've hit the end of the bottom so that's what it is. */
7624 if (from >= BUF_ZV (b))
7626 w->line_cache_validation_override--;
7630 update_line_start_cache (w, from, to, BUF_PT (b), 0);
7632 /* Updating the cache invalidates any current indexes. */
7633 start_elt = point_in_line_start_cache (w, cur_start, -1) + 1;
7638 /* For the given window W, if display starts at STARTP, what will be
7639 the buffer position at the beginning of the last line displayed. */
7642 start_of_last_line (struct window *w, Bufpos startp)
7644 return start_end_of_last_line (w, startp, 0);
7647 /* For the given window W, if display starts at STARTP, what will be
7648 the buffer position at the end of the last line displayed. This is
7649 also know as the window end position. */
7652 end_of_last_line (struct window *w, Bufpos startp)
7654 return start_end_of_last_line (w, startp, 1);
7657 /* For window W, what does the starting position have to be so that
7658 the line containing POINT will cover pixel position PIXPOS. */
7661 start_with_line_at_pixpos (struct window *w, Bufpos point, int pixpos)
7663 struct buffer *b = XBUFFER (w->buffer);
7665 Bufpos cur_pos, prev_pos = point;
7666 int point_line_height;
7667 int pixheight = pixpos - WINDOW_TEXT_TOP (w);
7669 validate_line_start_cache (w);
7670 w->line_cache_validation_override++;
7672 cur_elt = point_in_line_start_cache (w, point, 0);
7673 /* #### See comment in update_line_start_cache about big minibuffers. */
7676 w->line_cache_validation_override--;
7680 point_line_height = Dynarr_atp (w->line_start_cache, cur_elt)->height;
7684 cur_pos = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7686 pixheight -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7688 /* Do not take into account the value of vertical_clip here.
7689 That is the responsibility of the calling functions. */
7692 w->line_cache_validation_override--;
7693 if (-pixheight > point_line_height)
7694 /* We can't make the target line cover pixpos, so put it
7695 above pixpos. That way it will at least be visible. */
7705 int win_char_height;
7707 if (cur_pos <= BUF_BEGV (b))
7709 w->line_cache_validation_override--;
7710 return BUF_BEGV (b);
7713 win_char_height = window_char_height (w, 0);
7714 if (!win_char_height)
7715 win_char_height = 1;
7717 from = find_next_newline_no_quit (b, cur_pos, -win_char_height);
7718 to = line_start_cache_end (w);
7719 update_line_start_cache (w, from, to, point, 0);
7721 cur_elt = point_in_line_start_cache (w, cur_pos, 2) - 1;
7722 assert (cur_elt >= -1);
7723 /* This used to be cur_elt>=0 under the assumption that if
7724 point is in the top line and not at BUF_BEGV, then
7725 setting the window_start to a newline before the start of
7726 the first line will always cause scrolling.
7728 However in my (jv) opinion this is wrong. That new line
7729 can be hidden in various ways: invisible extents, an
7730 explicit window-start not at a newline character etc.
7731 The existence of those are indeed known to create crashes
7732 on that assert. So we have no option but to continue the
7733 search if we found point at the top of the line_start_cache
7735 cur_pos = Dynarr_atp (w->line_start_cache,0)->start;
7741 /* For window W, what does the starting position have to be so that
7742 the line containing point is on display line LINE. If LINE is
7743 positive it is considered to be the number of lines from the top of
7744 the window (0 is the top line). If it is negative the number is
7745 considered to be the number of lines from the bottom (-1 is the
7749 start_with_point_on_display_line (struct window *w, Bufpos point, int line)
7751 validate_line_start_cache (w);
7752 w->line_cache_validation_override++;
7756 int cur_elt = point_in_line_start_cache (w, point, line);
7758 if (cur_elt - line < 0)
7759 cur_elt = 0; /* Hit the top */
7763 w->line_cache_validation_override--;
7764 return Dynarr_atp (w->line_start_cache, cur_elt)->start;
7768 /* The calculated value of pixpos is correct for the bottom line
7769 or what we want when line is -1. Therefore we subtract one
7770 because we have already handled one line. */
7771 int new_line = -line - 1;
7772 int cur_elt = point_in_line_start_cache (w, point, new_line);
7773 int pixpos = WINDOW_TEXT_BOTTOM (w);
7774 Bufpos retval, search_point;
7776 /* If scroll_on_clipped_lines is false, the last "visible" line of
7777 the window covers the pixel at WINDOW_TEXT_BOTTOM (w) - 1.
7778 If s_o_c_l is true, then we don't want to count a clipped
7779 line, so back up from the bottom by the height of the line
7780 containing point. */
7781 if (scroll_on_clipped_lines)
7782 pixpos -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
7786 if (cur_elt + new_line >= Dynarr_length (w->line_start_cache))
7788 /* Hit the bottom of the buffer. */
7790 (cur_elt + new_line) - Dynarr_length (w->line_start_cache) + 1;
7794 XSETWINDOW (window, w);
7795 default_face_height_and_width (window, &defheight, 0);
7797 cur_elt = Dynarr_length (w->line_start_cache) - 1;
7799 pixpos -= (adjustment * defheight);
7800 if (pixpos < WINDOW_TEXT_TOP (w))
7801 pixpos = WINDOW_TEXT_TOP (w);
7804 cur_elt = cur_elt + new_line;
7806 search_point = Dynarr_atp (w->line_start_cache, cur_elt)->start;
7808 retval = start_with_line_at_pixpos (w, search_point, pixpos);
7809 w->line_cache_validation_override--;
7814 /* This is used to speed up vertical scrolling by caching the known
7815 buffer starting positions for display lines. This allows the
7816 scrolling routines to avoid costly calls to regenerate_window. If
7817 NO_REGEN is true then it will only add the values in the DESIRED
7818 display structs which are in the given range.
7820 Note also that the FROM/TO values are minimums. It is possible
7821 that this function will actually add information outside of the
7822 lines containing those positions. This can't hurt but it could
7825 #### We currently force the cache to have only 1 contiguous region.
7826 It might help to make the cache a dynarr of caches so that we can
7827 cover more areas. This might, however, turn out to be a lot of
7828 overhead for too little gain. */
7831 update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
7832 Bufpos point, int no_regen)
7834 struct buffer *b = XBUFFER (w->buffer);
7835 line_start_cache_dynarr *cache = w->line_start_cache;
7836 Bufpos low_bound, high_bound;
7838 validate_line_start_cache (w);
7839 w->line_cache_validation_override++;
7840 updating_line_start_cache = 1;
7842 if (from < BUF_BEGV (b))
7843 from = BUF_BEGV (b);
7844 if (to > BUF_ZV (b))
7849 updating_line_start_cache = 0;
7850 w->line_cache_validation_override--;
7854 if (Dynarr_length (cache))
7856 low_bound = line_start_cache_start (w);
7857 high_bound = line_start_cache_end (w);
7859 /* Check to see if the desired range is already in the cache. */
7860 if (from >= low_bound && to <= high_bound)
7862 updating_line_start_cache = 0;
7863 w->line_cache_validation_override--;
7867 /* Check to make sure that the desired range is adjacent to the
7868 current cache. If not, invalidate the cache. */
7869 if (to < low_bound || from > high_bound)
7871 Dynarr_reset (cache);
7872 low_bound = high_bound = -1;
7877 low_bound = high_bound = -1;
7880 w->line_cache_last_updated = make_int (BUF_MODIFF (b));
7882 /* This could be integrated into the next two sections, but it is easier
7883 to follow what's going on by having it separate. */
7888 update_internal_cache_list (w, DESIRED_DISP);
7889 if (!Dynarr_length (internal_cache))
7891 updating_line_start_cache = 0;
7892 w->line_cache_validation_override--;
7896 start = Dynarr_atp (internal_cache, 0)->start;
7898 Dynarr_atp (internal_cache, Dynarr_length (internal_cache) - 1)->end;
7900 /* We aren't allowed to generate additional information to fill in
7901 gaps, so if the DESIRED structs don't overlap the cache, reset the
7903 if (Dynarr_length (cache))
7905 if (end < low_bound || start > high_bound)
7906 Dynarr_reset (cache);
7908 /* #### What should really happen if what we are doing is
7909 extending a line (the last line)? */
7910 if (Dynarr_length (cache) == 1
7911 && Dynarr_length (internal_cache) == 1)
7912 Dynarr_reset (cache);
7915 if (!Dynarr_length (cache))
7917 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7918 Dynarr_length (internal_cache));
7919 updating_line_start_cache = 0;
7920 w->line_cache_validation_override--;
7924 /* An extra check just in case the calling function didn't pass in
7925 the bounds of the DESIRED structs in the first place. */
7926 if (start >= low_bound && end <= high_bound)
7928 updating_line_start_cache = 0;
7929 w->line_cache_validation_override--;
7933 /* At this point we know that the internal cache partially overlaps
7935 if (start < low_bound)
7937 int ic_elt = Dynarr_length (internal_cache) - 1;
7940 if (Dynarr_atp (internal_cache, ic_elt)->start < low_bound)
7948 Dynarr_reset (cache);
7949 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7950 Dynarr_length (internal_cache));
7951 updating_line_start_cache = 0;
7952 w->line_cache_validation_override--;
7956 Dynarr_insert_many_at_start (cache, Dynarr_atp (internal_cache, 0),
7960 if (end > high_bound)
7964 while (ic_elt < Dynarr_length (internal_cache))
7966 if (Dynarr_atp (internal_cache, ic_elt)->start > high_bound)
7972 if (!(ic_elt < Dynarr_length (internal_cache)))
7974 Dynarr_reset (cache);
7975 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
7976 Dynarr_length (internal_cache));
7977 updating_line_start_cache = 0;
7978 w->line_cache_validation_override--;
7982 Dynarr_add_many (cache, Dynarr_atp (internal_cache, ic_elt),
7983 Dynarr_length (internal_cache) - ic_elt);
7986 updating_line_start_cache = 0;
7987 w->line_cache_validation_override--;
7991 if (!Dynarr_length (cache) || from < low_bound)
7993 Bufpos startp = find_next_newline_no_quit (b, from, -1);
7995 int old_lb = low_bound;
7997 while (startp < old_lb || low_bound == -1)
8002 regenerate_window (w, startp, point, CMOTION_DISP);
8003 update_internal_cache_list (w, CMOTION_DISP);
8005 /* If this assert is triggered then regenerate_window failed
8006 to layout a single line. That is not supposed to be
8007 possible because we impose a minimum height on the buffer
8008 and override vertical clip when we are in here. */
8009 /* #### Ah, but it is because the window may temporarily
8010 exist but not have any lines at all if the minibuffer is
8011 real big. Look into that situation better. */
8012 if (!Dynarr_length (internal_cache))
8014 if (old_lb == -1 && low_bound == -1)
8016 updating_line_start_cache = 0;
8017 w->line_cache_validation_override--;
8021 assert (Dynarr_length (internal_cache));
8023 assert (startp == Dynarr_atp (internal_cache, 0)->start);
8025 ic_elt = Dynarr_length (internal_cache) - 1;
8026 if (low_bound != -1)
8030 if (Dynarr_atp (internal_cache, ic_elt)->start < old_lb)
8036 assert (ic_elt >= 0);
8038 new_startp = Dynarr_atp (internal_cache, ic_elt)->end + 1;
8041 * Handle invisible text properly:
8042 * If the last line we're inserting has the same end as the
8043 * line before which it will be added, merge the two lines.
8045 if (Dynarr_length (cache) &&
8046 Dynarr_atp (internal_cache, ic_elt)->end ==
8047 Dynarr_atp (cache, marker)->end)
8049 Dynarr_atp (cache, marker)->start
8050 = Dynarr_atp (internal_cache, ic_elt)->start;
8051 Dynarr_atp (cache, marker)->height
8052 = Dynarr_atp (internal_cache, ic_elt)->height;
8056 if (ic_elt >= 0) /* we still have lines to add.. */
8058 Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0),
8059 ic_elt + 1, marker);
8060 marker += (ic_elt + 1);
8063 if (startp < low_bound || low_bound == -1)
8065 startp = new_startp;
8066 if (startp > BUF_ZV (b))
8068 updating_line_start_cache = 0;
8069 w->line_cache_validation_override--;
8075 assert (Dynarr_length (cache));
8076 assert (from >= low_bound);
8078 /* Readjust the high_bound to account for any changes made while
8079 correcting the low_bound. */
8080 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8082 if (to > high_bound)
8084 Bufpos startp = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end + 1;
8088 regenerate_window (w, startp, point, CMOTION_DISP);
8089 update_internal_cache_list (w, CMOTION_DISP);
8091 /* See comment above about regenerate_window failing. */
8092 assert (Dynarr_length (internal_cache));
8094 Dynarr_add_many (cache, Dynarr_atp (internal_cache, 0),
8095 Dynarr_length (internal_cache));
8096 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end;
8097 startp = high_bound + 1;
8099 while (to > high_bound);
8102 updating_line_start_cache = 0;
8103 w->line_cache_validation_override--;
8104 assert (to <= high_bound);
8108 /* Given x and y coordinates in characters, relative to a window,
8109 return the pixel location corresponding to those coordinates. The
8110 pixel location returned is the center of the given character
8111 position. The pixel values are generated relative to the window,
8114 The modeline is considered to be part of the window. */
8117 glyph_to_pixel_translation (struct window *w, int char_x, int char_y,
8118 int *pix_x, int *pix_y)
8120 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
8121 int num_disp_lines, modeline;
8123 int defheight, defwidth;
8125 XSETWINDOW (window, w);
8126 default_face_height_and_width (window, &defheight, &defwidth);
8128 /* If we get a bogus value indicating somewhere above or to the left of
8129 the window, use the first window line or character position
8136 num_disp_lines = Dynarr_length (dla);
8140 if (Dynarr_atp (dla, 0)->modeline)
8147 /* First check if the y position intersects the display lines. */
8148 if (char_y < num_disp_lines)
8150 struct display_line *dl = Dynarr_atp (dla, char_y + modeline);
8151 struct display_block *db = get_display_block_from_line (dl, TEXT);
8153 *pix_y = (dl->ypos - dl->ascent +
8154 ((unsigned int) (dl->ascent + dl->descent - dl->clip) >> 1));
8156 if (char_x < Dynarr_length (db->runes))
8158 struct rune *rb = Dynarr_atp (db->runes, char_x);
8160 *pix_x = rb->xpos + (rb->width >> 1);
8164 int last_rune = Dynarr_length (db->runes) - 1;
8165 struct rune *rb = Dynarr_atp (db->runes, last_rune);
8167 char_x -= last_rune;
8169 *pix_x = rb->xpos + rb->width;
8170 *pix_x += ((char_x - 1) * defwidth);
8171 *pix_x += (defwidth >> 1);
8176 /* It didn't intersect, so extrapolate. #### For now, we include the
8177 modeline in this since we don't have true character positions in
8180 if (!Dynarr_length (w->face_cachels))
8181 reset_face_cachels (w);
8183 char_y -= num_disp_lines;
8185 if (Dynarr_length (dla))
8187 struct display_line *dl = Dynarr_atp (dla, Dynarr_length (dla) - 1);
8188 *pix_y = dl->ypos + dl->descent - dl->clip;
8191 *pix_y = WINDOW_TEXT_TOP (w);
8193 *pix_y += (char_y * defheight);
8194 *pix_y += (defheight >> 1);
8196 *pix_x = WINDOW_TEXT_LEFT (w);
8197 /* Don't adjust by one because this is still the unadjusted value. */
8198 *pix_x += (char_x * defwidth);
8199 *pix_x += (defwidth >> 1);
8202 if (*pix_x > w->pixel_left + w->pixel_width)
8203 *pix_x = w->pixel_left + w->pixel_width;
8204 if (*pix_y > w->pixel_top + w->pixel_height)
8205 *pix_y = w->pixel_top + w->pixel_height;
8207 *pix_x -= w->pixel_left;
8208 *pix_y -= w->pixel_top;
8211 /* Given a display line and a position, determine if there is a glyph
8212 there and return information about it if there is. */
8215 get_position_object (struct display_line *dl, Lisp_Object *obj1,
8216 Lisp_Object *obj2, int x_coord, int *low_x_coord,
8219 struct display_block *db;
8222 get_next_display_block (dl->bounds, dl->display_blocks, x_coord, 0);
8224 /* We use get_next_display_block to get the actual display block
8225 that would be displayed at x_coord. */
8227 if (block == NO_BLOCK)
8230 db = Dynarr_atp (dl->display_blocks, block);
8232 for (elt = 0; elt < Dynarr_length (db->runes); elt++)
8234 struct rune *rb = Dynarr_atp (db->runes, elt);
8236 if (rb->xpos <= x_coord && x_coord < (rb->xpos + rb->width))
8238 if (rb->type == RUNE_DGLYPH)
8240 *obj1 = rb->object.dglyph.glyph;
8241 *obj2 = rb->object.dglyph.extent;
8250 *low_x_coord = rb->xpos;
8252 *high_x_coord = rb->xpos + rb->width;
8259 #define UPDATE_CACHE_RETURN \
8261 d->pixel_to_glyph_cache.valid = 1; \
8262 d->pixel_to_glyph_cache.low_x_coord = low_x_coord; \
8263 d->pixel_to_glyph_cache.high_x_coord = high_x_coord; \
8264 d->pixel_to_glyph_cache.low_y_coord = low_y_coord; \
8265 d->pixel_to_glyph_cache.high_y_coord = high_y_coord; \
8266 d->pixel_to_glyph_cache.frame = f; \
8267 d->pixel_to_glyph_cache.col = *col; \
8268 d->pixel_to_glyph_cache.row = *row; \
8269 d->pixel_to_glyph_cache.obj_x = *obj_x; \
8270 d->pixel_to_glyph_cache.obj_y = *obj_y; \
8271 d->pixel_to_glyph_cache.w = *w; \
8272 d->pixel_to_glyph_cache.bufpos = *bufpos; \
8273 d->pixel_to_glyph_cache.closest = *closest; \
8274 d->pixel_to_glyph_cache.modeline_closest = *modeline_closest; \
8275 d->pixel_to_glyph_cache.obj1 = *obj1; \
8276 d->pixel_to_glyph_cache.obj2 = *obj2; \
8277 d->pixel_to_glyph_cache.retval = position; \
8278 RETURN_SANS_WARNINGS position; \
8281 /* Given x and y coordinates in pixels relative to a frame, return
8282 information about what is located under those coordinates.
8284 The return value will be one of:
8286 OVER_TOOLBAR: over one of the 4 frame toolbars
8287 OVER_MODELINE: over a modeline
8288 OVER_BORDER: over an internal border
8289 OVER_NOTHING: over the text area, but not over text
8290 OVER_OUTSIDE: outside of the frame border
8291 OVER_TEXT: over text in the text area
8297 -- nil if the coordinates are not over a glyph or a toolbar button.
8301 -- an extent, if the coordinates are over a glyph in the text area
8304 If the coordinates are over a glyph, OBJ_X and OBJ_Y give the
8305 equivalent coordinates relative to the upper-left corner of the glyph.
8307 If the coordinates are over a character, OBJ_X and OBJ_Y give the
8308 equivalent coordinates relative to the upper-left corner of the character.
8310 Otherwise, OBJ_X and OBJ_Y are undefined.
8314 pixel_to_glyph_translation (struct frame *f, int x_coord, int y_coord,
8315 int *col, int *row, int *obj_x, int *obj_y,
8316 struct window **w, Bufpos *bufpos,
8317 Bufpos *closest, Charcount *modeline_closest,
8318 Lisp_Object *obj1, Lisp_Object *obj2)
8321 struct pixel_to_glyph_translation_cache *cache;
8323 int frm_left, frm_right, frm_top, frm_bottom;
8324 int low_x_coord, high_x_coord, low_y_coord, high_y_coord;
8325 int position = OVER_NOTHING;
8326 int device_check_failed = 0;
8327 display_line_dynarr *dla;
8329 /* This is a safety valve in case this got called with a frame in
8330 the middle of being deleted. */
8331 if (!DEVICEP (f->device) || !DEVICE_LIVE_P (XDEVICE (f->device)))
8333 device_check_failed = 1;
8334 d = NULL, cache = NULL; /* Warning suppression */
8338 d = XDEVICE (f->device);
8339 cache = &d->pixel_to_glyph_cache;
8342 if (!device_check_failed
8344 && cache->frame == f
8345 && cache->low_x_coord <= x_coord
8346 && cache->high_x_coord > x_coord
8347 && cache->low_y_coord <= y_coord
8348 && cache->high_y_coord > y_coord)
8352 *obj_x = cache->obj_x;
8353 *obj_y = cache->obj_y;
8355 *bufpos = cache->bufpos;
8356 *closest = cache->closest;
8357 *modeline_closest = cache->modeline_closest;
8358 *obj1 = cache->obj1;
8359 *obj2 = cache->obj2;
8361 return cache->retval;
8372 *modeline_closest = -1;
8376 low_x_coord = x_coord;
8377 high_x_coord = x_coord + 1;
8378 low_y_coord = y_coord;
8379 high_y_coord = y_coord + 1;
8382 if (device_check_failed)
8383 return OVER_NOTHING;
8385 frm_left = FRAME_LEFT_BORDER_END (f);
8386 frm_right = FRAME_RIGHT_BORDER_START (f);
8387 frm_top = FRAME_TOP_BORDER_END (f);
8388 frm_bottom = FRAME_BOTTOM_BORDER_START (f);
8390 /* Check if the mouse is outside of the text area actually used by
8392 if (y_coord < frm_top)
8394 if (y_coord >= FRAME_TOP_BORDER_START (f))
8396 low_y_coord = FRAME_TOP_BORDER_START (f);
8397 high_y_coord = frm_top;
8398 position = OVER_BORDER;
8400 else if (y_coord >= 0)
8403 high_y_coord = FRAME_TOP_BORDER_START (f);
8404 position = OVER_TOOLBAR;
8408 low_y_coord = y_coord;
8410 position = OVER_OUTSIDE;
8413 else if (y_coord >= frm_bottom)
8415 if (y_coord < FRAME_BOTTOM_BORDER_END (f))
8417 low_y_coord = frm_bottom;
8418 high_y_coord = FRAME_BOTTOM_BORDER_END (f);
8419 position = OVER_BORDER;
8421 else if (y_coord < FRAME_PIXHEIGHT (f))
8423 low_y_coord = FRAME_BOTTOM_BORDER_END (f);
8424 high_y_coord = FRAME_PIXHEIGHT (f);
8425 position = OVER_TOOLBAR;
8429 low_y_coord = FRAME_PIXHEIGHT (f);
8430 high_y_coord = y_coord;
8431 position = OVER_OUTSIDE;
8435 if (position != OVER_TOOLBAR && position != OVER_BORDER)
8437 if (x_coord < frm_left)
8439 if (x_coord >= FRAME_LEFT_BORDER_START (f))
8441 low_x_coord = FRAME_LEFT_BORDER_START (f);
8442 high_x_coord = frm_left;
8443 position = OVER_BORDER;
8445 else if (x_coord >= 0)
8448 high_x_coord = FRAME_LEFT_BORDER_START (f);
8449 position = OVER_TOOLBAR;
8453 low_x_coord = x_coord;
8455 position = OVER_OUTSIDE;
8458 else if (x_coord >= frm_right)
8460 if (x_coord < FRAME_RIGHT_BORDER_END (f))
8462 low_x_coord = frm_right;
8463 high_x_coord = FRAME_RIGHT_BORDER_END (f);
8464 position = OVER_BORDER;
8466 else if (x_coord < FRAME_PIXWIDTH (f))
8468 low_x_coord = FRAME_RIGHT_BORDER_END (f);
8469 high_x_coord = FRAME_PIXWIDTH (f);
8470 position = OVER_TOOLBAR;
8474 low_x_coord = FRAME_PIXWIDTH (f);
8475 high_x_coord = x_coord;
8476 position = OVER_OUTSIDE;
8481 #ifdef HAVE_TOOLBARS
8482 if (position == OVER_TOOLBAR)
8484 *obj1 = toolbar_button_at_pixpos (f, x_coord, y_coord);
8487 UPDATE_CACHE_RETURN;
8489 #endif /* HAVE_TOOLBARS */
8491 /* We still have to return the window the pointer is next to and its
8492 relative y position even if it is outside the x boundary. */
8493 if (x_coord < frm_left)
8495 else if (x_coord > frm_right)
8496 x_coord = frm_right;
8498 /* Same in reverse. */
8499 if (y_coord < frm_top)
8501 else if (y_coord > frm_bottom)
8502 y_coord = frm_bottom;
8504 /* Find what window the given coordinates are actually in. */
8505 window = f->root_window;
8506 *w = find_window_by_pixel_pos (x_coord, y_coord, window);
8508 /* If we didn't find a window, we're done. */
8511 UPDATE_CACHE_RETURN;
8513 else if (position != OVER_NOTHING)
8516 *modeline_closest = -1;
8518 if (high_y_coord <= frm_top || high_y_coord >= frm_bottom)
8521 UPDATE_CACHE_RETURN;
8525 /* Check if the window is a minibuffer but isn't active. */
8526 if (MINI_WINDOW_P (*w) && !minibuf_level)
8528 /* Must reset the window value since some callers will ignore
8529 the return value if it is set. */
8531 UPDATE_CACHE_RETURN;
8534 /* See if the point is over window vertical divider */
8535 if (window_needs_vertical_divider (*w))
8537 int div_x_high = WINDOW_RIGHT (*w);
8538 int div_x_low = div_x_high - window_divider_width (*w);
8539 int div_y_high = WINDOW_BOTTOM (*w);
8540 int div_y_low = WINDOW_TOP (*w);
8542 if (div_x_low < x_coord && x_coord <= div_x_high &&
8543 div_y_low < y_coord && y_coord <= div_y_high)
8545 low_x_coord = div_x_low;
8546 high_x_coord = div_x_high;
8547 low_y_coord = div_y_low;
8548 high_y_coord = div_y_high;
8549 position = OVER_V_DIVIDER;
8550 UPDATE_CACHE_RETURN;
8554 dla = window_display_lines (*w, CURRENT_DISP);
8556 for (*row = 0; *row < Dynarr_length (dla); (*row)++)
8558 int really_over_nothing = 0;
8559 struct display_line *dl = Dynarr_atp (dla, *row);
8561 if ((int) (dl->ypos - dl->ascent) <= y_coord
8562 && y_coord <= (int) (dl->ypos + dl->descent))
8564 int check_margin_glyphs = 0;
8565 struct display_block *db = get_display_block_from_line (dl, TEXT);
8566 struct rune *rb = 0;
8568 if (x_coord < dl->bounds.left_white
8569 || x_coord >= dl->bounds.right_white)
8570 check_margin_glyphs = 1;
8572 low_y_coord = dl->ypos - dl->ascent;
8573 high_y_coord = dl->ypos + dl->descent + 1;
8575 if (position == OVER_BORDER
8576 || position == OVER_OUTSIDE
8577 || check_margin_glyphs)
8579 int x_check, left_bound;
8581 if (check_margin_glyphs)
8584 left_bound = dl->bounds.left_white;
8588 x_check = high_x_coord;
8589 left_bound = frm_left;
8592 if (Dynarr_length (db->runes))
8594 if (x_check <= left_bound)
8597 *modeline_closest = Dynarr_atp (db->runes, 0)->bufpos;
8599 *closest = Dynarr_atp (db->runes, 0)->bufpos;
8605 Dynarr_atp (db->runes,
8606 Dynarr_length (db->runes) - 1)->bufpos;
8609 Dynarr_atp (db->runes,
8610 Dynarr_length (db->runes) - 1)->bufpos;
8614 *modeline_closest += dl->offset;
8616 *closest += dl->offset;
8620 /* #### What should be here. */
8622 *modeline_closest = 0;
8627 if (check_margin_glyphs)
8629 if (x_coord < dl->bounds.left_in
8630 || x_coord >= dl->bounds.right_in)
8632 /* If we are over the outside margins then we
8633 know the loop over the text block isn't going
8634 to accomplish anything. So we go ahead and
8635 set what information we can right here and
8638 *obj_y = y_coord - (dl->ypos - dl->ascent);
8639 get_position_object (dl, obj1, obj2, x_coord,
8640 &low_x_coord, &high_x_coord);
8642 UPDATE_CACHE_RETURN;
8646 UPDATE_CACHE_RETURN;
8649 for (*col = 0; *col <= Dynarr_length (db->runes); (*col)++)
8651 int past_end = (*col == Dynarr_length (db->runes));
8654 rb = Dynarr_atp (db->runes, *col);
8657 (rb->xpos <= x_coord && x_coord < rb->xpos + rb->width))
8662 rb = Dynarr_atp (db->runes, *col);
8665 *bufpos = rb->bufpos + dl->offset;
8666 low_x_coord = rb->xpos;
8667 high_x_coord = rb->xpos + rb->width;
8669 if (rb->type == RUNE_DGLYPH)
8673 /* Find the first character after the glyph. */
8674 while (elt < Dynarr_length (db->runes))
8676 if (Dynarr_atp (db->runes, elt)->type != RUNE_DGLYPH)
8680 (Dynarr_atp (db->runes, elt)->bufpos +
8684 (Dynarr_atp (db->runes, elt)->bufpos +
8692 /* In this case we failed to find a non-glyph
8693 character so we return the last position
8694 displayed on the line. */
8695 if (elt == Dynarr_length (db->runes))
8698 *modeline_closest = dl->end_bufpos + dl->offset;
8700 *closest = dl->end_bufpos + dl->offset;
8701 really_over_nothing = 1;
8707 *modeline_closest = rb->bufpos + dl->offset;
8709 *closest = rb->bufpos + dl->offset;
8714 *row = window_displayed_height (*w);
8716 if (position == OVER_NOTHING)
8717 position = OVER_MODELINE;
8719 if (rb->type == RUNE_DGLYPH)
8721 *obj1 = rb->object.dglyph.glyph;
8722 *obj2 = rb->object.dglyph.extent;
8724 else if (rb->type == RUNE_CHAR)
8735 UPDATE_CACHE_RETURN;
8738 || (rb->type == RUNE_CHAR
8739 && rb->object.chr.ch == '\n'))
8742 /* At this point we may have glyphs in the right
8744 if (check_margin_glyphs)
8745 get_position_object (dl, obj1, obj2, x_coord,
8746 &low_x_coord, &high_x_coord);
8747 UPDATE_CACHE_RETURN;
8752 if (rb->type == RUNE_DGLYPH)
8754 *obj1 = rb->object.dglyph.glyph;
8755 *obj2 = rb->object.dglyph.extent;
8757 else if (rb->type == RUNE_CHAR)
8768 *obj_x = x_coord - rb->xpos;
8769 *obj_y = y_coord - (dl->ypos - dl->ascent);
8771 /* At this point we may have glyphs in the left
8773 if (check_margin_glyphs)
8774 get_position_object (dl, obj1, obj2, x_coord, 0, 0);
8776 if (position == OVER_NOTHING && !really_over_nothing)
8777 position = OVER_TEXT;
8779 UPDATE_CACHE_RETURN;
8786 *row = Dynarr_length (dla) - 1;
8787 if (FRAME_WIN_P (f))
8789 int bot_elt = Dynarr_length (dla) - 1;
8793 struct display_line *dl = Dynarr_atp (dla, bot_elt);
8794 int adj_area = y_coord - (dl->ypos + dl->descent);
8798 XSETWINDOW (lwin, *w);
8799 default_face_height_and_width (lwin, 0, &defheight);
8801 *row += (adj_area / defheight);
8805 /* #### This should be checked out some more to determine what
8806 should really be going on. */
8807 if (!MARKERP ((*w)->start[CURRENT_DISP]))
8810 *closest = end_of_last_line (*w,
8811 marker_position ((*w)->start[CURRENT_DISP]));
8813 UPDATE_CACHE_RETURN;
8815 #undef UPDATE_CACHE_RETURN
8818 /***************************************************************************/
8820 /* Lisp functions */
8822 /***************************************************************************/
8824 DEFUN ("redisplay-echo-area", Fredisplay_echo_area, 0, 0, 0, /*
8825 Ensure that all minibuffers are correctly showing the echo area.
8829 Lisp_Object devcons, concons;
8831 DEVICE_LOOP_NO_BREAK (devcons, concons)
8833 struct device *d = XDEVICE (XCAR (devcons));
8834 Lisp_Object frmcons;
8836 DEVICE_FRAME_LOOP (frmcons, d)
8838 struct frame *f = XFRAME (XCAR (frmcons));
8840 if (FRAME_REPAINT_P (f) && FRAME_HAS_MINIBUF_P (f))
8842 Lisp_Object window = FRAME_MINIBUF_WINDOW (f);
8844 * If the frame size has changed, there may be random
8845 * chud on the screen left from previous messages
8846 * because redisplay_frame hasn't been called yet.
8847 * Clear the screen to get rid of the potential mess.
8849 if (f->echo_area_garbaged)
8851 DEVMETH (d, clear_frame, (f));
8852 f->echo_area_garbaged = 0;
8854 redisplay_window (window, 0);
8855 call_redisplay_end_triggers (XWINDOW (window), 0);
8859 /* We now call the output_end routine for tty frames. We delay
8860 doing so in order to avoid cursor flicker. So much for 100%
8862 if (DEVICE_TTY_P (d))
8863 DEVMETH (d, output_end, (d));
8870 restore_disable_preemption_value (Lisp_Object value)
8872 disable_preemption = XINT (value);
8876 DEFUN ("redraw-frame", Fredraw_frame, 0, 2, 0, /*
8877 Clear frame FRAME and output again what is supposed to appear on it.
8878 FRAME defaults to the selected frame if omitted.
8879 Normally, redisplay is preempted as normal if input arrives. However,
8880 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8881 input and is guaranteed to proceed to completion.
8883 (frame, no_preempt))
8885 struct frame *f = decode_frame (frame);
8886 int count = specpdl_depth ();
8888 if (!NILP (no_preempt))
8890 record_unwind_protect (restore_disable_preemption_value,
8891 make_int (disable_preemption));
8892 disable_preemption++;
8896 redisplay_frame (f, 1);
8898 return unbind_to (count, Qnil);
8901 DEFUN ("redisplay-frame", Fredisplay_frame, 0, 2, 0, /*
8902 Ensure that FRAME's contents are correctly displayed.
8903 This differs from `redraw-frame' in that it only redraws what needs to
8904 be updated, as opposed to unconditionally clearing and redrawing
8906 FRAME defaults to the selected frame if omitted.
8907 Normally, redisplay is preempted as normal if input arrives. However,
8908 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8909 input and is guaranteed to proceed to completion.
8911 (frame, no_preempt))
8913 struct frame *f = decode_frame (frame);
8914 int count = specpdl_depth ();
8916 if (!NILP (no_preempt))
8918 record_unwind_protect (restore_disable_preemption_value,
8919 make_int (disable_preemption));
8920 disable_preemption++;
8923 redisplay_frame (f, 1);
8925 return unbind_to (count, Qnil);
8928 DEFUN ("redraw-device", Fredraw_device, 0, 2, 0, /*
8929 Clear device DEVICE and output again what is supposed to appear on it.
8930 DEVICE defaults to the selected device if omitted.
8931 Normally, redisplay is preempted as normal if input arrives. However,
8932 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8933 input and is guaranteed to proceed to completion.
8935 (device, no_preempt))
8937 struct device *d = decode_device (device);
8938 Lisp_Object frmcons;
8939 int count = specpdl_depth ();
8941 if (!NILP (no_preempt))
8943 record_unwind_protect (restore_disable_preemption_value,
8944 make_int (disable_preemption));
8945 disable_preemption++;
8948 DEVICE_FRAME_LOOP (frmcons, d)
8950 XFRAME (XCAR (frmcons))->clear = 1;
8952 redisplay_device (d, 0);
8954 return unbind_to (count, Qnil);
8957 DEFUN ("redisplay-device", Fredisplay_device, 0, 2, 0, /*
8958 Ensure that DEVICE's contents are correctly displayed.
8959 This differs from `redraw-device' in that it only redraws what needs to
8960 be updated, as opposed to unconditionally clearing and redrawing
8962 DEVICE defaults to the selected device if omitted.
8963 Normally, redisplay is preempted as normal if input arrives. However,
8964 if optional second arg NO-PREEMPT is non-nil, redisplay will not stop for
8965 input and is guaranteed to proceed to completion.
8967 (device, no_preempt))
8969 struct device *d = decode_device (device);
8970 int count = specpdl_depth ();
8972 if (!NILP (no_preempt))
8974 record_unwind_protect (restore_disable_preemption_value,
8975 make_int (disable_preemption));
8976 disable_preemption++;
8979 redisplay_device (d, 0);
8981 return unbind_to (count, Qnil);
8984 /* Big lie. Big lie. This will force all modelines to be updated
8985 regardless if the all flag is set or not. It remains in existence
8986 solely for backwards compatibility. */
8987 DEFUN ("redraw-modeline", Fredraw_modeline, 0, 1, 0, /*
8988 Force the modeline of the current buffer to be redisplayed.
8989 With optional non-nil ALL, force redisplay of all modelines.
8993 MARK_MODELINE_CHANGED;
8997 DEFUN ("force-cursor-redisplay", Fforce_cursor_redisplay, 0, 1, 0, /*
8998 Force an immediate update of the cursor on FRAME.
8999 FRAME defaults to the selected frame if omitted.
9003 redisplay_redraw_cursor (decode_frame (frame), 1);
9008 /***************************************************************************/
9010 /* Lisp-variable change triggers */
9012 /***************************************************************************/
9015 margin_width_changed_in_frame (Lisp_Object specifier, struct frame *f,
9018 /* Nothing to be done? */
9022 redisplay_variable_changed (Lisp_Object sym, Lisp_Object *val,
9023 Lisp_Object in_object, int flags)
9025 /* #### clip_changed should really be renamed something like
9026 global_redisplay_change. */
9031 /* This is called if the built-in glyphs have their properties
9034 redisplay_glyph_changed (Lisp_Object glyph, Lisp_Object property,
9037 if (WINDOWP (locale))
9039 MARK_FRAME_GLYPHS_CHANGED (XFRAME (WINDOW_FRAME (XWINDOW (locale))));
9041 else if (FRAMEP (locale))
9043 MARK_FRAME_GLYPHS_CHANGED (XFRAME (locale));
9045 else if (DEVICEP (locale))
9047 Lisp_Object frmcons;
9048 DEVICE_FRAME_LOOP (frmcons, XDEVICE (locale))
9049 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9051 else if (CONSOLEP (locale))
9053 Lisp_Object frmcons, devcons;
9054 CONSOLE_FRAME_LOOP_NO_BREAK (frmcons, devcons, XCONSOLE (locale))
9055 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9057 else /* global or buffer */
9059 Lisp_Object frmcons, devcons, concons;
9060 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
9061 MARK_FRAME_GLYPHS_CHANGED (XFRAME (XCAR (frmcons)));
9066 text_cursor_visible_p_changed (Lisp_Object specifier, struct window *w,
9069 if (XFRAME (w->frame)->init_finished)
9070 Fforce_cursor_redisplay (w->frame);
9073 #ifdef MEMORY_USAGE_STATS
9076 /***************************************************************************/
9078 /* memory usage computation */
9080 /***************************************************************************/
9083 compute_rune_dynarr_usage (rune_dynarr *dyn, struct overhead_stats *ovstats)
9085 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9089 compute_display_block_dynarr_usage (display_block_dynarr *dyn,
9090 struct overhead_stats *ovstats)
9097 total = Dynarr_memory_usage (dyn, ovstats);
9098 for (i = 0; i < Dynarr_largest (dyn); i++)
9099 total += compute_rune_dynarr_usage (Dynarr_at (dyn, i).runes, ovstats);
9105 compute_glyph_block_dynarr_usage (glyph_block_dynarr *dyn,
9106 struct overhead_stats *ovstats)
9108 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9112 compute_display_line_dynarr_usage (display_line_dynarr *dyn,
9113 struct overhead_stats *ovstats)
9120 total = Dynarr_memory_usage (dyn, ovstats);
9121 for (i = 0; i < Dynarr_largest (dyn); i++)
9123 struct display_line *dl = &Dynarr_at (dyn, i);
9124 total += compute_display_block_dynarr_usage(dl->display_blocks, ovstats);
9125 total += compute_glyph_block_dynarr_usage (dl->left_glyphs, ovstats);
9126 total += compute_glyph_block_dynarr_usage (dl->right_glyphs, ovstats);
9133 compute_line_start_cache_dynarr_usage (line_start_cache_dynarr *dyn,
9134 struct overhead_stats *ovstats)
9136 return dyn ? Dynarr_memory_usage (dyn, ovstats) : 0;
9139 #endif /* MEMORY_USAGE_STATS */
9142 /***************************************************************************/
9144 /* initialization */
9146 /***************************************************************************/
9149 init_redisplay (void)
9151 disable_preemption = 0;
9152 preemption_count = 0;
9153 max_preempts = INIT_MAX_PREEMPTS;
9159 if (!cmotion_display_lines)
9160 cmotion_display_lines = Dynarr_new (display_line);
9161 if (!mode_spec_bufbyte_string)
9162 mode_spec_bufbyte_string = Dynarr_new (Bufbyte);
9163 if (!formatted_string_extent_dynarr)
9164 formatted_string_extent_dynarr = Dynarr_new (EXTENT);
9165 if (!formatted_string_extent_start_dynarr)
9166 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount);
9167 if (!formatted_string_extent_end_dynarr)
9168 formatted_string_extent_end_dynarr = Dynarr_new (Bytecount);
9169 if (!internal_cache)
9170 internal_cache = Dynarr_new (line_start_cache);
9173 /* window system is nil when in -batch mode */
9174 if (!initialized || noninteractive)
9177 /* If the user wants to use a window system, we shouldn't bother
9178 initializing the terminal. This is especially important when the
9179 terminal is so dumb that emacs gives up before and doesn't bother
9180 using the window system.
9182 If the DISPLAY environment variable is set, try to use X, and die
9183 with an error message if that doesn't work. */
9185 #ifdef HAVE_X_WINDOWS
9186 if (!strcmp (display_use, "x"))
9188 /* Some stuff checks this way early. */
9189 Vwindow_system = Qx;
9190 Vinitial_window_system = Qx;
9193 #endif /* HAVE_X_WINDOWS */
9195 #ifdef HAVE_MS_WINDOWS
9196 if (!strcmp (display_use, "mswindows"))
9198 /* Some stuff checks this way early. */
9199 Vwindow_system = Qmswindows;
9200 Vinitial_window_system = Qmswindows;
9203 #endif /* HAVE_MS_WINDOWS */
9206 /* If no window system has been specified, try to use the terminal. */
9209 stderr_out ("XEmacs: standard input is not a tty\n");
9213 /* Look at the TERM variable */
9214 if (!getenv ("TERM"))
9216 stderr_out ("Please set the environment variable TERM; see tset(1).\n");
9220 Vinitial_window_system = Qtty;
9222 #else /* not HAVE_TTY */
9223 /* No DISPLAY specified, and no TTY support. */
9224 stderr_out ("XEmacs: Cannot open display.\n\
9225 Please set the environmental variable DISPLAY to an appropriate value.\n");
9232 syms_of_redisplay (void)
9234 defsymbol (&Qcursor_in_echo_area, "cursor-in-echo-area");
9235 #ifndef INHIBIT_REDISPLAY_HOOKS
9236 defsymbol (&Qpre_redisplay_hook, "pre-redisplay-hook");
9237 defsymbol (&Qpost_redisplay_hook, "post-redisplay-hook");
9238 #endif /* INHIBIT_REDISPLAY_HOOKS */
9239 defsymbol (&Qdisplay_warning_buffer, "display-warning-buffer");
9240 defsymbol (&Qbar_cursor, "bar-cursor");
9241 defsymbol (&Qredisplay_end_trigger_functions,
9242 "redisplay-end-trigger-functions");
9244 DEFSUBR (Fredisplay_echo_area);
9245 DEFSUBR (Fredraw_frame);
9246 DEFSUBR (Fredisplay_frame);
9247 DEFSUBR (Fredraw_device);
9248 DEFSUBR (Fredisplay_device);
9249 DEFSUBR (Fredraw_modeline);
9250 DEFSUBR (Fforce_cursor_redisplay);
9254 reinit_vars_of_redisplay (void)
9256 updating_line_start_cache = 0;
9260 vars_of_redisplay (void)
9262 reinit_vars_of_redisplay ();
9265 staticpro (&last_arrow_position);
9266 staticpro (&last_arrow_string);
9267 last_arrow_position = Qnil;
9268 last_arrow_string = Qnil;
9271 /* #### Probably temporary */
9272 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /*
9273 \(Temporary) Setting this will impact the performance of the internal
9276 cache_adjustment = 2;
9278 DEFVAR_INT_MAGIC ("pixel-vertical-clip-threshold", &vertical_clip /*
9279 Minimum pixel height for clipped bottom display line.
9280 A clipped line shorter than this won't be displayed.
9282 redisplay_variable_changed);
9285 DEFVAR_INT_MAGIC ("pixel-horizontal-clip-threshold", &horizontal_clip /*
9286 Minimum visible area for clipped glyphs at right boundary.
9287 Clipped glyphs shorter than this won't be displayed.
9288 Only pixmap glyph instances are currently allowed to be clipped.
9290 redisplay_variable_changed);
9291 horizontal_clip = 5;
9293 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string /*
9294 String displayed by modeline-format's "%m" specification.
9296 Vglobal_mode_string = Qnil;
9298 DEFVAR_LISP_MAGIC ("overlay-arrow-position", &Voverlay_arrow_position /*
9299 Marker for where to display an arrow on top of the buffer text.
9300 This must be the beginning of a line in order to work.
9301 See also `overlay-arrow-string'.
9303 redisplay_variable_changed);
9304 Voverlay_arrow_position = Qnil;
9306 DEFVAR_LISP_MAGIC ("overlay-arrow-string", &Voverlay_arrow_string /*
9307 String to display as an arrow. See also `overlay-arrow-position'.
9309 redisplay_variable_changed);
9310 Voverlay_arrow_string = Qnil;
9312 DEFVAR_INT ("scroll-step", &scroll_step /*
9313 *The number of lines to try scrolling a window by when point moves out.
9314 If that fails to bring point back on frame, point is centered instead.
9315 If this is zero, point is always centered after it moves off screen.
9319 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively /*
9320 *Scroll up to this many lines, to bring point back on screen.
9322 scroll_conservatively = 0;
9324 DEFVAR_BOOL_MAGIC ("truncate-partial-width-windows",
9325 &truncate_partial_width_windows /*
9326 *Non-nil means truncate lines in all windows less than full frame wide.
9328 redisplay_variable_changed);
9329 truncate_partial_width_windows = 1;
9331 DEFVAR_BOOL ("visible-bell", &visible_bell /*
9332 *Non-nil means try to flash the frame to represent a bell.
9336 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter /*
9337 *Non-nil means no need to redraw entire frame after suspending.
9338 A non-nil value is useful if the terminal can automatically preserve
9339 Emacs's frame display when you reenter Emacs.
9340 It is up to you to set this variable if your terminal can do that.
9342 no_redraw_on_reenter = 0;
9344 DEFVAR_LISP ("window-system", &Vwindow_system /*
9345 A symbol naming the window-system under which Emacs is running,
9346 such as `x', or nil if emacs is running on an ordinary terminal.
9348 Do not use this variable, except for GNU Emacs compatibility, as it
9349 gives wrong values in a multi-device environment. Use `console-type'
9352 Vwindow_system = Qnil;
9354 /* #### Temporary shit until window-system is eliminated. */
9355 DEFVAR_CONST_LISP ("initial-window-system", &Vinitial_window_system /*
9358 Vinitial_window_system = Qnil;
9360 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area /*
9361 Non-nil means put cursor in minibuffer, at end of any message there.
9363 cursor_in_echo_area = 0;
9365 /* #### Shouldn't this be generalized as follows:
9367 if nil, use block cursor.
9368 if a number, use a bar cursor of that width.
9369 Otherwise, use a 1-pixel bar cursor.
9371 #### Or better yet, this variable should be trashed entirely
9372 (use a Lisp-magic variable to maintain compatibility)
9373 and a specifier `cursor-shape' added, which allows a block
9374 cursor, a bar cursor, a flashing block or bar cursor,
9375 maybe a caret cursor, etc. */
9377 DEFVAR_LISP ("bar-cursor", &Vbar_cursor /*
9378 Use vertical bar cursor if non-nil. If t width is 1 pixel, otherwise 2.
9382 #ifndef INHIBIT_REDISPLAY_HOOKS
9383 xxDEFVAR_LISP ("pre-redisplay-hook", &Vpre_redisplay_hook /*
9384 Function or functions to run before every redisplay.
9385 Functions on this hook must be careful to avoid signalling errors!
9387 Vpre_redisplay_hook = Qnil;
9389 xxDEFVAR_LISP ("post-redisplay-hook", &Vpost_redisplay_hook /*
9390 Function or functions to run after every redisplay.
9391 Functions on this hook must be careful to avoid signalling errors!
9393 Vpost_redisplay_hook = Qnil;
9394 #endif /* INHIBIT_REDISPLAY_HOOKS */
9396 DEFVAR_INT ("display-warning-tick", &display_warning_tick /*
9397 Bump this to tell the C code to call `display-warning-buffer'
9398 at next redisplay. You should not normally change this; the function
9399 `display-warning' automatically does this at appropriate times.
9401 display_warning_tick = 0;
9403 DEFVAR_BOOL ("inhibit-warning-display", &inhibit_warning_display /*
9404 Non-nil means inhibit display of warning messages.
9405 You should *bind* this, not set it. Any pending warning messages
9406 will be displayed when the binding no longer applies.
9408 /* reset to 0 by startup.el after the splash screen has displayed.
9409 This way, the warnings don't obliterate the splash screen. */
9410 inhibit_warning_display = 1;
9412 DEFVAR_LISP ("window-size-change-functions",
9413 &Vwindow_size_change_functions /*
9414 Not currently implemented.
9415 Functions called before redisplay, if window sizes have changed.
9416 The value should be a list of functions that take one argument.
9417 Just before redisplay, for each frame, if any of its windows have changed
9418 size since the last redisplay, or have been split or deleted,
9419 all the functions in the list are called, with the frame as argument.
9421 Vwindow_size_change_functions = Qnil;
9423 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions /*
9424 Not currently implemented.
9425 Functions to call before redisplaying a window with scrolling.
9426 Each function is called with two arguments, the window
9427 and its new display-start position. Note that the value of `window-end'
9428 is not valid when these functions are called.
9430 Vwindow_scroll_functions = Qnil;
9432 DEFVAR_LISP ("redisplay-end-trigger-functions",
9433 &Vredisplay_end_trigger_functions /*
9434 See `set-window-redisplay-end-trigger'.
9436 Vredisplay_end_trigger_functions = Qnil;
9438 DEFVAR_BOOL ("column-number-start-at-one", &column_number_start_at_one /*
9439 *Non-nil means column display number starts at 1.
9441 column_number_start_at_one = 0;
9445 specifier_vars_of_redisplay (void)
9447 DEFVAR_SPECIFIER ("left-margin-width", &Vleft_margin_width /*
9448 *Width of left margin.
9449 This is a specifier; use `set-specifier' to change it.
9451 Vleft_margin_width = Fmake_specifier (Qnatnum);
9452 set_specifier_fallback (Vleft_margin_width, list1 (Fcons (Qnil, Qzero)));
9453 set_specifier_caching (Vleft_margin_width,
9454 offsetof (struct window, left_margin_width),
9455 some_window_value_changed,
9456 offsetof (struct frame, left_margin_width),
9457 margin_width_changed_in_frame);
9459 DEFVAR_SPECIFIER ("right-margin-width", &Vright_margin_width /*
9460 *Width of right margin.
9461 This is a specifier; use `set-specifier' to change it.
9463 Vright_margin_width = Fmake_specifier (Qnatnum);
9464 set_specifier_fallback (Vright_margin_width, list1 (Fcons (Qnil, Qzero)));
9465 set_specifier_caching (Vright_margin_width,
9466 offsetof (struct window, right_margin_width),
9467 some_window_value_changed,
9468 offsetof (struct frame, right_margin_width),
9469 margin_width_changed_in_frame);
9471 DEFVAR_SPECIFIER ("minimum-line-ascent", &Vminimum_line_ascent /*
9472 *Minimum ascent height of lines.
9473 This is a specifier; use `set-specifier' to change it.
9475 Vminimum_line_ascent = Fmake_specifier (Qnatnum);
9476 set_specifier_fallback (Vminimum_line_ascent, list1 (Fcons (Qnil, Qzero)));
9477 set_specifier_caching (Vminimum_line_ascent,
9478 offsetof (struct window, minimum_line_ascent),
9479 some_window_value_changed,
9482 DEFVAR_SPECIFIER ("minimum-line-descent", &Vminimum_line_descent /*
9483 *Minimum descent height of lines.
9484 This is a specifier; use `set-specifier' to change it.
9486 Vminimum_line_descent = Fmake_specifier (Qnatnum);
9487 set_specifier_fallback (Vminimum_line_descent, list1 (Fcons (Qnil, Qzero)));
9488 set_specifier_caching (Vminimum_line_descent,
9489 offsetof (struct window, minimum_line_descent),
9490 some_window_value_changed,
9493 DEFVAR_SPECIFIER ("use-left-overflow", &Vuse_left_overflow /*
9494 *Non-nil means use the left outside margin as extra whitespace when
9495 displaying 'whitespace or 'inside-margin glyphs.
9496 This is a specifier; use `set-specifier' to change it.
9498 Vuse_left_overflow = Fmake_specifier (Qboolean);
9499 set_specifier_fallback (Vuse_left_overflow, list1 (Fcons (Qnil, Qnil)));
9500 set_specifier_caching (Vuse_left_overflow,
9501 offsetof (struct window, use_left_overflow),
9502 some_window_value_changed,
9505 DEFVAR_SPECIFIER ("use-right-overflow", &Vuse_right_overflow /*
9506 *Non-nil means use the right outside margin as extra whitespace when
9507 displaying 'whitespace or 'inside-margin glyphs.
9508 This is a specifier; use `set-specifier' to change it.
9510 Vuse_right_overflow = Fmake_specifier (Qboolean);
9511 set_specifier_fallback (Vuse_right_overflow, list1 (Fcons (Qnil, Qnil)));
9512 set_specifier_caching (Vuse_right_overflow,
9513 offsetof (struct window, use_right_overflow),
9514 some_window_value_changed,
9517 DEFVAR_SPECIFIER ("text-cursor-visible-p", &Vtext_cursor_visible_p /*
9518 *Non-nil means the text cursor is visible (this is usually the case).
9519 This is a specifier; use `set-specifier' to change it.
9521 Vtext_cursor_visible_p = Fmake_specifier (Qboolean);
9522 set_specifier_fallback (Vtext_cursor_visible_p, list1 (Fcons (Qnil, Qt)));
9523 set_specifier_caching (Vtext_cursor_visible_p,
9524 offsetof (struct window, text_cursor_visible_p),
9525 text_cursor_visible_p_changed,