(comment-indent): Save excursion around call to comment-indent-function.
[emacs.git] / src / xdisp.c
blob15e52cde5aa26feb5333c42ffa6ebb4d5ebe83e1
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 98, 99, 2000
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
24 Redisplay.
26 Emacs separates the task of updating the display from code
27 modifying global state, e.g. buffer text. This way functions
28 operating on buffers don't also have to be concerned with updating
29 the display.
31 Updating the display is triggered by the Lisp interpreter when it
32 decides it's time to do it. This is done either automatically for
33 you as part of the interpreter's command loop or as the result of
34 calling Lisp functions like `sit-for'. The C function `redisplay'
35 in xdisp.c is the only entry into the inner redisplay code. (Or,
36 let's say almost---see the the description of direct update
37 operations, below.).
39 The following diagram shows how redisplay code is invoked. As you
40 can see, Lisp calls redisplay and vice versa. Under window systems
41 like X, some portions of the redisplay code are also called
42 asynchronously during mouse movement or expose events. It is very
43 important that these code parts do NOT use the C library (malloc,
44 free) because many C libraries under Unix are not reentrant. They
45 may also NOT call functions of the Lisp interpreter which could
46 change the interpreter's state. If you don't follow these rules,
47 you will encounter bugs which are very hard to explain.
49 (Direct functions, see below)
50 direct_output_for_insert,
51 direct_forward_char (dispnew.c)
52 +---------------------------------+
53 | |
54 | V
55 +--------------+ redisplay() +----------------+
56 | Lisp machine |---------------->| Redisplay code |<--+
57 +--------------+ (xdisp.c) +----------------+ |
58 ^ | |
59 +----------------------------------+ |
60 Don't use this path when called |
61 asynchronously! |
63 expose_window (asynchronous) |
65 X expose events -----+
67 What does redisplay? Obviously, it has to figure out somehow what
68 has been changed since the last time the display has been updated,
69 and to make these changes visible. Preferably it would do that in
70 a moderately intelligent way, i.e. fast.
72 Changes in buffer text can be deduced from window and buffer
73 structures, and from some global variables like `beg_unchanged' and
74 `end_unchanged'. The contents of the display are additionally
75 recorded in a `glyph matrix', a two-dimensional matrix of glyph
76 structures. Each row in such a matrix corresponds to a line on the
77 display, and each glyph in a row corresponds to a column displaying
78 a character, an image, or what else. This matrix is called the
79 `current glyph matrix' or `current matrix' in redisplay
80 terminology.
82 For buffer parts that have been changed since the last update, a
83 second glyph matrix is constructed, the so called `desired glyph
84 matrix' or short `desired matrix'. Current and desired matrix are
85 then compared to find a cheap way to update the display, e.g. by
86 reusing part of the display by scrolling lines.
89 Direct operations.
91 You will find a lot of of redisplay optimizations when you start
92 looking at the innards of redisplay. The overall goal of all these
93 optimizations is to make redisplay fast because it is done
94 frequently.
96 Two optimizations are not found in xdisp.c. These are the direct
97 operations mentioned above. As the name suggests they follow a
98 different principle than the rest of redisplay. Instead of
99 building a desired matrix and then comparing it with the current
100 display, they perform their actions directly on the display and on
101 the current matrix.
103 One direct operation updates the display after one character has
104 been entered. The other one moves the cursor by one position
105 forward or backward. You find these functions under the names
106 `direct_output_for_insert' and `direct_output_forward_char' in
107 dispnew.c.
110 Desired matrices.
112 Desired matrices are always built per Emacs window. The function
113 `display_line' is the central function to look at if you are
114 interested. It constructs one row in a desired matrix given an
115 iterator structure containing both a buffer position and a
116 description of the environment in which the text is to be
117 displayed. But this is too early, read on.
119 Characters and pixmaps displayed for a range of buffer text depend
120 on various settings of buffers and windows, on overlays and text
121 properties, on display tables, on selective display. The good news
122 is that all this hairy stuff is hidden behind a small set of
123 interface functions taking a iterator structure (struct it)
124 argument.
126 Iteration over things to be be displayed is then simple. It is
127 started by initializing an iterator with a call to init_iterator
128 (or init_string_iterator for that matter). Calls to
129 get_next_display_element fill the iterator structure with relevant
130 information about the next thing to display. Calls to
131 set_iterator_to_next move the iterator to the next thing.
133 Besides this, an iterator also contains information about the
134 display environment in which glyphs for display elements are to be
135 produced. It has fields for the width and height of the display,
136 the information whether long lines are truncated or continued, a
137 current X and Y position, and lots of other stuff you can better
138 see in dispextern.h.
140 Glyphs in a desired matrix are normally constructed in a loop
141 calling get_next_display_element and then produce_glyphs. The call
142 to produce_glyphs will fill the iterator structure with pixel
143 information about the element being displayed and at the same time
144 produce glyphs for it. If the display element fits on the line
145 being displayed, set_iterator_to_next is called next, otherwise the
146 glyphs produced are discarded.
149 Frame matrices.
151 That just couldn't be all, could it? What about terminal types not
152 supporting operations on sub-windows of the screen? To update the
153 display on such a terminal, window-based glyph matrices are not
154 well suited. To be able to reuse part of the display (scrolling
155 lines up and down), we must instead have a view of the whole
156 screen. This is what `frame matrices' are for. They are a trick.
158 Frames on terminals like above have a glyph pool. Windows on such
159 a frame sub-allocate their glyph memory from their frame's glyph
160 pool. The frame itself is given its own glyph matrices. By
161 coincidence---or maybe something else---rows in window glyph
162 matrices are slices of corresponding rows in frame matrices. Thus
163 writing to window matrices implicitly updates a frame matrix which
164 provides us with the view of the whole screen that we originally
165 wanted to have without having to move many bytes around. To be
166 honest, there is a little bit more done, but not much more. If you
167 plan to extend that code, take a look at dispnew.c. The function
168 build_frame_matrix is a good starting point. */
170 #include <config.h>
171 #include <stdio.h>
172 #include "lisp.h"
173 #include "keyboard.h"
174 #include "frame.h"
175 #include "window.h"
176 #include "termchar.h"
177 #include "dispextern.h"
178 #include "buffer.h"
179 #include "charset.h"
180 #include "indent.h"
181 #include "commands.h"
182 #include "macros.h"
183 #include "disptab.h"
184 #include "termhooks.h"
185 #include "intervals.h"
186 #include "coding.h"
187 #include "process.h"
188 #include "region-cache.h"
189 #include "fontset.h"
191 #ifdef HAVE_X_WINDOWS
192 #include "xterm.h"
193 #endif
194 #ifdef WINDOWSNT
195 #include "w32term.h"
196 #endif
197 #ifdef macintosh
198 #include "macterm.h"
199 #endif
201 #define min(a, b) ((a) < (b) ? (a) : (b))
202 #define max(a, b) ((a) > (b) ? (a) : (b))
204 #define INFINITY 10000000
206 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (macintosh)
207 extern void set_frame_menubar P_ ((struct frame *f, int, int));
208 extern int pending_menu_activation;
209 #endif
211 extern int interrupt_input;
212 extern int command_loop_level;
214 extern int minibuffer_auto_raise;
216 extern Lisp_Object Qface;
218 extern Lisp_Object Voverriding_local_map;
219 extern Lisp_Object Voverriding_local_map_menu_flag;
220 extern Lisp_Object Qmenu_item;
222 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
223 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
224 Lisp_Object Qredisplay_end_trigger_functions;
225 Lisp_Object Qinhibit_point_motion_hooks;
226 Lisp_Object QCeval, Qwhen, QCfile, QCdata;
227 Lisp_Object Qfontified;
228 Lisp_Object Qgrow_only;
230 /* Functions called to fontify regions of text. */
232 Lisp_Object Vfontification_functions;
233 Lisp_Object Qfontification_functions;
235 /* Non-zero means draw tool bar buttons raised when the mouse moves
236 over them. */
238 int auto_raise_tool_bar_buttons_p;
240 /* Margin around tool bar buttons in pixels. */
242 int tool_bar_button_margin;
244 /* Thickness of shadow to draw around tool bar buttons. */
246 int tool_bar_button_relief;
248 /* Non-zero means automatically resize tool-bars so that all tool-bar
249 items are visible, and no blank lines remain. */
251 int auto_resize_tool_bars_p;
253 /* Non-nil means don't actually do any redisplay. */
255 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
257 /* Names of text properties relevant for redisplay. */
259 Lisp_Object Qdisplay, Qrelative_width, Qalign_to;
260 extern Lisp_Object Qface, Qinvisible, Qimage, Qwidth;
262 /* Symbols used in text property values. */
264 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
265 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
266 Lisp_Object Qmargin;
267 extern Lisp_Object Qheight;
269 /* Non-nil means highlight trailing whitespace. */
271 Lisp_Object Vshow_trailing_whitespace;
273 /* Name of the face used to highlight trailing whitespace. */
275 Lisp_Object Qtrailing_whitespace;
277 /* The symbol `image' which is the car of the lists used to represent
278 images in Lisp. */
280 Lisp_Object Qimage;
282 /* Non-zero means print newline to stdout before next mini-buffer
283 message. */
285 int noninteractive_need_newline;
287 /* Non-zero means print newline to message log before next message. */
289 static int message_log_need_newline;
292 /* The buffer position of the first character appearing entirely or
293 partially on the line of the selected window which contains the
294 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
295 redisplay optimization in redisplay_internal. */
297 static struct text_pos this_line_start_pos;
299 /* Number of characters past the end of the line above, including the
300 terminating newline. */
302 static struct text_pos this_line_end_pos;
304 /* The vertical positions and the height of this line. */
306 static int this_line_vpos;
307 static int this_line_y;
308 static int this_line_pixel_height;
310 /* X position at which this display line starts. Usually zero;
311 negative if first character is partially visible. */
313 static int this_line_start_x;
315 /* Buffer that this_line_.* variables are referring to. */
317 static struct buffer *this_line_buffer;
319 /* Nonzero means truncate lines in all windows less wide than the
320 frame. */
322 int truncate_partial_width_windows;
324 /* A flag to control how to display unibyte 8-bit character. */
326 int unibyte_display_via_language_environment;
328 /* Nonzero means we have more than one non-mini-buffer-only frame.
329 Not guaranteed to be accurate except while parsing
330 frame-title-format. */
332 int multiple_frames;
334 Lisp_Object Vglobal_mode_string;
336 /* Marker for where to display an arrow on top of the buffer text. */
338 Lisp_Object Voverlay_arrow_position;
340 /* String to display for the arrow. Only used on terminal frames. */
342 Lisp_Object Voverlay_arrow_string;
344 /* Values of those variables at last redisplay. However, if
345 Voverlay_arrow_position is a marker, last_arrow_position is its
346 numerical position. */
348 static Lisp_Object last_arrow_position, last_arrow_string;
350 /* Like mode-line-format, but for the title bar on a visible frame. */
352 Lisp_Object Vframe_title_format;
354 /* Like mode-line-format, but for the title bar on an iconified frame. */
356 Lisp_Object Vicon_title_format;
358 /* List of functions to call when a window's size changes. These
359 functions get one arg, a frame on which one or more windows' sizes
360 have changed. */
362 static Lisp_Object Vwindow_size_change_functions;
364 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
366 /* Nonzero if overlay arrow has been displayed once in this window. */
368 static int overlay_arrow_seen;
370 /* Nonzero means highlight the region even in nonselected windows. */
372 int highlight_nonselected_windows;
374 /* If cursor motion alone moves point off frame, try scrolling this
375 many lines up or down if that will bring it back. */
377 static int scroll_step;
379 /* Non-0 means scroll just far enough to bring point back on the
380 screen, when appropriate. */
382 static int scroll_conservatively;
384 /* Recenter the window whenever point gets within this many lines of
385 the top or bottom of the window. This value is translated into a
386 pixel value by multiplying it with CANON_Y_UNIT, which means that
387 there is really a fixed pixel height scroll margin. */
389 int scroll_margin;
391 /* Number of windows showing the buffer of the selected window (or
392 another buffer with the same base buffer). keyboard.c refers to
393 this. */
395 int buffer_shared;
397 /* Vector containing glyphs for an ellipsis `...'. */
399 static Lisp_Object default_invis_vector[3];
401 /* Zero means display the mode-line/header-line/menu-bar in the default face
402 (this slightly odd definition is for compatibility with previous versions
403 of emacs), non-zero means display them using their respective faces.
405 This variable is deprecated. */
407 int mode_line_inverse_video;
409 /* Prompt to display in front of the mini-buffer contents. */
411 Lisp_Object minibuf_prompt;
413 /* Width of current mini-buffer prompt. Only set after display_line
414 of the line that contains the prompt. */
416 int minibuf_prompt_width;
417 int minibuf_prompt_pixel_width;
419 /* This is the window where the echo area message was displayed. It
420 is always a mini-buffer window, but it may not be the same window
421 currently active as a mini-buffer. */
423 Lisp_Object echo_area_window;
425 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
426 pushes the current message and the value of
427 message_enable_multibyte on the stack, the function restore_message
428 pops the stack and displays MESSAGE again. */
430 Lisp_Object Vmessage_stack;
432 /* Nonzero means multibyte characters were enabled when the echo area
433 message was specified. */
435 int message_enable_multibyte;
437 /* True if we should redraw the mode lines on the next redisplay. */
439 int update_mode_lines;
441 /* Nonzero if window sizes or contents have changed since last
442 redisplay that finished */
444 int windows_or_buffers_changed;
446 /* Nonzero after display_mode_line if %l was used and it displayed a
447 line number. */
449 int line_number_displayed;
451 /* Maximum buffer size for which to display line numbers. */
453 Lisp_Object Vline_number_display_limit;
455 /* line width to consider when repostioning for line number display */
457 static int line_number_display_limit_width;
459 /* Number of lines to keep in the message log buffer. t means
460 infinite. nil means don't log at all. */
462 Lisp_Object Vmessage_log_max;
464 /* The name of the *Messages* buffer, a string. */
466 static Lisp_Object Vmessages_buffer_name;
468 /* Current, index 0, and last displayed echo area message. Either
469 buffers from echo_buffers, or nil to indicate no message. */
471 Lisp_Object echo_area_buffer[2];
473 /* The buffers referenced from echo_area_buffer. */
475 static Lisp_Object echo_buffer[2];
477 /* A vector saved used in with_area_buffer to reduce consing. */
479 static Lisp_Object Vwith_echo_area_save_vector;
481 /* Non-zero means display_echo_area should display the last echo area
482 message again. Set by redisplay_preserve_echo_area. */
484 static int display_last_displayed_message_p;
486 /* Nonzero if echo area is being used by print; zero if being used by
487 message. */
489 int message_buf_print;
491 /* Maximum height for resizing mini-windows. Either a float
492 specifying a fraction of the available height, or an integer
493 specifying a number of lines. */
495 Lisp_Object Vmax_mini_window_height;
497 /* Non-zero means messages should be displayed with truncated
498 lines instead of being continued. */
500 int message_truncate_lines;
501 Lisp_Object Qmessage_truncate_lines;
503 /* Non-zero means we want a hollow cursor in windows that are not
504 selected. Zero means there's no cursor in such windows. */
506 int cursor_in_non_selected_windows;
508 /* A scratch glyph row with contents used for generating truncation
509 glyphs. Also used in direct_output_for_insert. */
511 #define MAX_SCRATCH_GLYPHS 100
512 struct glyph_row scratch_glyph_row;
513 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
515 /* Ascent and height of the last line processed by move_it_to. */
517 static int last_max_ascent, last_height;
519 /* Non-zero if there's a help-echo in the echo area. */
521 int help_echo_showing_p;
523 /* If >= 0, computed, exact values of mode-line and header-line height
524 to use in the macros CURRENT_MODE_LINE_HEIGHT and
525 CURRENT_HEADER_LINE_HEIGHT. */
527 int current_mode_line_height, current_header_line_height;
529 /* The maximum distance to look ahead for text properties. Values
530 that are too small let us call compute_char_face and similar
531 functions too often which is expensive. Values that are too large
532 let us call compute_char_face and alike too often because we
533 might not be interested in text properties that far away. */
535 #define TEXT_PROP_DISTANCE_LIMIT 100
537 #if GLYPH_DEBUG
539 /* Non-zero means print traces of redisplay if compiled with
540 GLYPH_DEBUG != 0. */
542 int trace_redisplay_p;
544 #endif /* GLYPH_DEBUG */
546 #ifdef DEBUG_TRACE_MOVE
547 /* Non-zero means trace with TRACE_MOVE to stderr. */
548 int trace_move;
550 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
551 #else
552 #define TRACE_MOVE(x) (void) 0
553 #endif
555 /* Non-zero means automatically scroll windows horizontally to make
556 point visible. */
558 int automatic_hscrolling_p;
560 /* A list of symbols, one for each supported image type. */
562 Lisp_Object Vimage_types;
564 /* The variable `resize-mini-windows'. If nil, don't resize
565 mini-windows. If t, always resize them to fit the text they
566 display. If `grow-only', let mini-windows grow only until they
567 become empty. */
569 Lisp_Object Vresize_mini_windows;
571 /* Value returned from text property handlers (see below). */
573 enum prop_handled
575 HANDLED_NORMALLY,
576 HANDLED_RECOMPUTE_PROPS,
577 HANDLED_OVERLAY_STRING_CONSUMED,
578 HANDLED_RETURN
581 /* A description of text properties that redisplay is interested
582 in. */
584 struct props
586 /* The name of the property. */
587 Lisp_Object *name;
589 /* A unique index for the property. */
590 enum prop_idx idx;
592 /* A handler function called to set up iterator IT from the property
593 at IT's current position. Value is used to steer handle_stop. */
594 enum prop_handled (*handler) P_ ((struct it *it));
597 static enum prop_handled handle_face_prop P_ ((struct it *));
598 static enum prop_handled handle_invisible_prop P_ ((struct it *));
599 static enum prop_handled handle_display_prop P_ ((struct it *));
600 static enum prop_handled handle_composition_prop P_ ((struct it *));
601 static enum prop_handled handle_overlay_change P_ ((struct it *));
602 static enum prop_handled handle_fontified_prop P_ ((struct it *));
604 /* Properties handled by iterators. */
606 static struct props it_props[] =
608 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
609 /* Handle `face' before `display' because some sub-properties of
610 `display' need to know the face. */
611 {&Qface, FACE_PROP_IDX, handle_face_prop},
612 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
613 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
614 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
615 {NULL, 0, NULL}
618 /* Value is the position described by X. If X is a marker, value is
619 the marker_position of X. Otherwise, value is X. */
621 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
623 /* Enumeration returned by some move_it_.* functions internally. */
625 enum move_it_result
627 /* Not used. Undefined value. */
628 MOVE_UNDEFINED,
630 /* Move ended at the requested buffer position or ZV. */
631 MOVE_POS_MATCH_OR_ZV,
633 /* Move ended at the requested X pixel position. */
634 MOVE_X_REACHED,
636 /* Move within a line ended at the end of a line that must be
637 continued. */
638 MOVE_LINE_CONTINUED,
640 /* Move within a line ended at the end of a line that would
641 be displayed truncated. */
642 MOVE_LINE_TRUNCATED,
644 /* Move within a line ended at a line end. */
645 MOVE_NEWLINE_OR_CR
650 /* Function prototypes. */
652 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
653 static int redisplay_mode_lines P_ ((Lisp_Object, int));
654 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
655 static int invisible_text_between_p P_ ((struct it *, int, int));
656 static int next_element_from_ellipsis P_ ((struct it *));
657 static void pint2str P_ ((char *, int, int));
658 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
659 struct text_pos));
660 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
661 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
662 static void store_frame_title_char P_ ((char));
663 static int store_frame_title P_ ((unsigned char *, int, int));
664 static void x_consider_frame_title P_ ((Lisp_Object));
665 static void handle_stop P_ ((struct it *));
666 static int tool_bar_lines_needed P_ ((struct frame *));
667 static int single_display_prop_intangible_p P_ ((Lisp_Object));
668 static void ensure_echo_area_buffers P_ ((void));
669 static struct glyph_row *row_containing_pos P_ ((struct window *, int,
670 struct glyph_row *,
671 struct glyph_row *));
672 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
673 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
674 static int with_echo_area_buffer P_ ((struct window *, int,
675 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
676 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
677 static void clear_garbaged_frames P_ ((void));
678 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
679 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
680 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
681 static int display_echo_area P_ ((struct window *));
682 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
683 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
684 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
685 static int string_char_and_length P_ ((unsigned char *, int, int *));
686 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
687 struct text_pos));
688 static int compute_window_start_on_continuation_line P_ ((struct window *));
689 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
690 static void insert_left_trunc_glyphs P_ ((struct it *));
691 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
692 static void extend_face_to_end_of_line P_ ((struct it *));
693 static int append_space P_ ((struct it *, int));
694 static void make_cursor_line_fully_visible P_ ((struct window *));
695 static int try_scrolling P_ ((Lisp_Object, int, int, int, int));
696 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
697 static int trailing_whitespace_p P_ ((int));
698 static int message_log_check_duplicate P_ ((int, int, int, int));
699 int invisible_p P_ ((Lisp_Object, Lisp_Object));
700 int invisible_ellipsis_p P_ ((Lisp_Object, Lisp_Object));
701 static void push_it P_ ((struct it *));
702 static void pop_it P_ ((struct it *));
703 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
704 static void redisplay_internal P_ ((int));
705 static int echo_area_display P_ ((int));
706 static void redisplay_windows P_ ((Lisp_Object));
707 static void redisplay_window P_ ((Lisp_Object, int));
708 static void update_menu_bar P_ ((struct frame *, int));
709 static int try_window_reusing_current_matrix P_ ((struct window *));
710 static int try_window_id P_ ((struct window *));
711 static int display_line P_ ((struct it *));
712 static int display_mode_lines P_ ((struct window *));
713 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
714 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object));
715 static char *decode_mode_spec P_ ((struct window *, int, int, int));
716 static void display_menu_bar P_ ((struct window *));
717 static int display_count_lines P_ ((int, int, int, int, int *));
718 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
719 int, int, struct it *, int, int, int, int));
720 static void compute_line_metrics P_ ((struct it *));
721 static void run_redisplay_end_trigger_hook P_ ((struct it *));
722 static int get_overlay_strings P_ ((struct it *));
723 static void next_overlay_string P_ ((struct it *));
724 static void reseat P_ ((struct it *, struct text_pos, int));
725 static void reseat_1 P_ ((struct it *, struct text_pos, int));
726 static void back_to_previous_visible_line_start P_ ((struct it *));
727 static void reseat_at_previous_visible_line_start P_ ((struct it *));
728 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
729 static int next_element_from_display_vector P_ ((struct it *));
730 static int next_element_from_string P_ ((struct it *));
731 static int next_element_from_c_string P_ ((struct it *));
732 static int next_element_from_buffer P_ ((struct it *));
733 static int next_element_from_composition P_ ((struct it *));
734 static int next_element_from_image P_ ((struct it *));
735 static int next_element_from_stretch P_ ((struct it *));
736 static void load_overlay_strings P_ ((struct it *));
737 static void init_from_display_pos P_ ((struct it *, struct window *,
738 struct display_pos *));
739 static void reseat_to_string P_ ((struct it *, unsigned char *,
740 Lisp_Object, int, int, int, int));
741 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
742 int, int, int));
743 void move_it_vertically_backward P_ ((struct it *, int));
744 static void init_to_row_start P_ ((struct it *, struct window *,
745 struct glyph_row *));
746 static void init_to_row_end P_ ((struct it *, struct window *,
747 struct glyph_row *));
748 static void back_to_previous_line_start P_ ((struct it *));
749 static int forward_to_next_line_start P_ ((struct it *, int *));
750 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
751 Lisp_Object, int));
752 static struct text_pos string_pos P_ ((int, Lisp_Object));
753 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
754 static int number_of_chars P_ ((unsigned char *, int));
755 static void compute_stop_pos P_ ((struct it *));
756 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
757 Lisp_Object));
758 static int face_before_or_after_it_pos P_ ((struct it *, int));
759 static int next_overlay_change P_ ((int));
760 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
761 Lisp_Object, struct text_pos *));
763 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
764 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
766 #ifdef HAVE_WINDOW_SYSTEM
768 static void update_tool_bar P_ ((struct frame *, int));
769 static void build_desired_tool_bar_string P_ ((struct frame *f));
770 static int redisplay_tool_bar P_ ((struct frame *));
771 static void display_tool_bar_line P_ ((struct it *));
773 #endif /* HAVE_WINDOW_SYSTEM */
776 /***********************************************************************
777 Window display dimensions
778 ***********************************************************************/
780 /* Return the window-relative maximum y + 1 for glyph rows displaying
781 text in window W. This is the height of W minus the height of a
782 mode line, if any. */
784 INLINE int
785 window_text_bottom_y (w)
786 struct window *w;
788 struct frame *f = XFRAME (w->frame);
789 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
791 if (WINDOW_WANTS_MODELINE_P (w))
792 height -= CURRENT_MODE_LINE_HEIGHT (w);
793 return height;
797 /* Return the pixel width of display area AREA of window W. AREA < 0
798 means return the total width of W, not including bitmap areas to
799 the left and right of the window. */
801 INLINE int
802 window_box_width (w, area)
803 struct window *w;
804 int area;
806 struct frame *f = XFRAME (w->frame);
807 int width = XFASTINT (w->width);
809 if (!w->pseudo_window_p)
811 width -= FRAME_SCROLL_BAR_WIDTH (f) + FRAME_FLAGS_AREA_COLS (f);
813 if (area == TEXT_AREA)
815 if (INTEGERP (w->left_margin_width))
816 width -= XFASTINT (w->left_margin_width);
817 if (INTEGERP (w->right_margin_width))
818 width -= XFASTINT (w->right_margin_width);
820 else if (area == LEFT_MARGIN_AREA)
821 width = (INTEGERP (w->left_margin_width)
822 ? XFASTINT (w->left_margin_width) : 0);
823 else if (area == RIGHT_MARGIN_AREA)
824 width = (INTEGERP (w->right_margin_width)
825 ? XFASTINT (w->right_margin_width) : 0);
828 return width * CANON_X_UNIT (f);
832 /* Return the pixel height of the display area of window W, not
833 including mode lines of W, if any.. */
835 INLINE int
836 window_box_height (w)
837 struct window *w;
839 struct frame *f = XFRAME (w->frame);
840 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
842 xassert (height >= 0);
844 if (WINDOW_WANTS_MODELINE_P (w))
845 height -= CURRENT_MODE_LINE_HEIGHT (w);
847 if (WINDOW_WANTS_HEADER_LINE_P (w))
848 height -= CURRENT_HEADER_LINE_HEIGHT (w);
850 return height;
854 /* Return the frame-relative coordinate of the left edge of display
855 area AREA of window W. AREA < 0 means return the left edge of the
856 whole window, to the right of any bitmap area at the left side of
857 W. */
859 INLINE int
860 window_box_left (w, area)
861 struct window *w;
862 int area;
864 struct frame *f = XFRAME (w->frame);
865 int x = FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
867 if (!w->pseudo_window_p)
869 x += (WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f)
870 + FRAME_LEFT_FLAGS_AREA_WIDTH (f));
872 if (area == TEXT_AREA)
873 x += window_box_width (w, LEFT_MARGIN_AREA);
874 else if (area == RIGHT_MARGIN_AREA)
875 x += (window_box_width (w, LEFT_MARGIN_AREA)
876 + window_box_width (w, TEXT_AREA));
879 return x;
883 /* Return the frame-relative coordinate of the right edge of display
884 area AREA of window W. AREA < 0 means return the left edge of the
885 whole window, to the left of any bitmap area at the right side of
886 W. */
888 INLINE int
889 window_box_right (w, area)
890 struct window *w;
891 int area;
893 return window_box_left (w, area) + window_box_width (w, area);
897 /* Get the bounding box of the display area AREA of window W, without
898 mode lines, in frame-relative coordinates. AREA < 0 means the
899 whole window, not including bitmap areas to the left and right of
900 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
901 coordinates of the upper-left corner of the box. Return in
902 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
904 INLINE void
905 window_box (w, area, box_x, box_y, box_width, box_height)
906 struct window *w;
907 int area;
908 int *box_x, *box_y, *box_width, *box_height;
910 struct frame *f = XFRAME (w->frame);
912 *box_width = window_box_width (w, area);
913 *box_height = window_box_height (w);
914 *box_x = window_box_left (w, area);
915 *box_y = (FRAME_INTERNAL_BORDER_WIDTH_SAFE (f)
916 + XFASTINT (w->top) * CANON_Y_UNIT (f));
917 if (WINDOW_WANTS_HEADER_LINE_P (w))
918 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
922 /* Get the bounding box of the display area AREA of window W, without
923 mode lines. AREA < 0 means the whole window, not including bitmap
924 areas to the left and right of the window. Return in *TOP_LEFT_X
925 and TOP_LEFT_Y the frame-relative pixel coordinates of the
926 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
927 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
928 box. */
930 INLINE void
931 window_box_edges (w, area, top_left_x, top_left_y,
932 bottom_right_x, bottom_right_y)
933 struct window *w;
934 int area;
935 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
937 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
938 bottom_right_y);
939 *bottom_right_x += *top_left_x;
940 *bottom_right_y += *top_left_y;
945 /***********************************************************************
946 Utilities
947 ***********************************************************************/
949 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
950 1 if POS is visible and the line containing POS is fully visible.
951 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
952 and header-lines heights. */
955 pos_visible_p (w, charpos, fully, exact_mode_line_heights_p)
956 struct window *w;
957 int charpos, *fully, exact_mode_line_heights_p;
959 struct it it;
960 struct text_pos top;
961 int visible_p;
962 struct buffer *old_buffer = NULL;
964 if (XBUFFER (w->buffer) != current_buffer)
966 old_buffer = current_buffer;
967 set_buffer_internal_1 (XBUFFER (w->buffer));
970 *fully = visible_p = 0;
971 SET_TEXT_POS_FROM_MARKER (top, w->start);
973 /* Compute exact mode line heights, if requested. */
974 if (exact_mode_line_heights_p)
976 if (WINDOW_WANTS_MODELINE_P (w))
977 current_mode_line_height
978 = display_mode_line (w, MODE_LINE_FACE_ID,
979 current_buffer->mode_line_format);
981 if (WINDOW_WANTS_HEADER_LINE_P (w))
982 current_header_line_height
983 = display_mode_line (w, HEADER_LINE_FACE_ID,
984 current_buffer->header_line_format);
987 start_display (&it, w, top);
988 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
989 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
991 if (IT_CHARPOS (it) == charpos)
993 int line_height, line_bottom_y;
994 int line_top_y = it.current_y;
995 int window_top_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
997 line_height = it.max_ascent + it.max_descent;
998 if (line_height == 0)
1000 if (last_height)
1001 line_height = last_height;
1002 else if (charpos < ZV)
1004 move_it_by_lines (&it, 1, 1);
1005 line_height = (it.max_ascent || it.max_descent
1006 ? it.max_ascent + it.max_descent
1007 : last_height);
1009 else
1011 /* Use the default character height. */
1012 it.what = IT_CHARACTER;
1013 it.c = ' ';
1014 it.len = 1;
1015 PRODUCE_GLYPHS (&it);
1016 line_height = it.ascent + it.descent;
1019 line_bottom_y = line_top_y + line_height;
1021 if (line_top_y < window_top_y)
1022 visible_p = line_bottom_y > window_top_y;
1023 else if (line_top_y < it.last_visible_y)
1025 visible_p = 1;
1026 *fully = line_bottom_y <= it.last_visible_y;
1029 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1031 move_it_by_lines (&it, 1, 0);
1032 if (charpos < IT_CHARPOS (it))
1034 visible_p = 1;
1035 *fully = 0;
1039 if (old_buffer)
1040 set_buffer_internal_1 (old_buffer);
1042 current_header_line_height = current_mode_line_height = -1;
1043 return visible_p;
1047 /* Return the next character from STR which is MAXLEN bytes long.
1048 Return in *LEN the length of the character. This is like
1049 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1050 we find one, we return a `?', but with the length of the invalid
1051 character. */
1053 static INLINE int
1054 string_char_and_length (str, maxlen, len)
1055 unsigned char *str;
1056 int maxlen, *len;
1058 int c;
1060 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1061 if (!CHAR_VALID_P (c, 1))
1062 /* We may not change the length here because other places in Emacs
1063 don't use this function, i.e. they silently accept invalid
1064 characters. */
1065 c = '?';
1067 return c;
1072 /* Given a position POS containing a valid character and byte position
1073 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1075 static struct text_pos
1076 string_pos_nchars_ahead (pos, string, nchars)
1077 struct text_pos pos;
1078 Lisp_Object string;
1079 int nchars;
1081 xassert (STRINGP (string) && nchars >= 0);
1083 if (STRING_MULTIBYTE (string))
1085 int rest = STRING_BYTES (XSTRING (string)) - BYTEPOS (pos);
1086 unsigned char *p = XSTRING (string)->data + BYTEPOS (pos);
1087 int len;
1089 while (nchars--)
1091 string_char_and_length (p, rest, &len);
1092 p += len, rest -= len;
1093 xassert (rest >= 0);
1094 CHARPOS (pos) += 1;
1095 BYTEPOS (pos) += len;
1098 else
1099 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1101 return pos;
1105 /* Value is the text position, i.e. character and byte position,
1106 for character position CHARPOS in STRING. */
1108 static INLINE struct text_pos
1109 string_pos (charpos, string)
1110 int charpos;
1111 Lisp_Object string;
1113 struct text_pos pos;
1114 xassert (STRINGP (string));
1115 xassert (charpos >= 0);
1116 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1117 return pos;
1121 /* Value is a text position, i.e. character and byte position, for
1122 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1123 means recognize multibyte characters. */
1125 static struct text_pos
1126 c_string_pos (charpos, s, multibyte_p)
1127 int charpos;
1128 unsigned char *s;
1129 int multibyte_p;
1131 struct text_pos pos;
1133 xassert (s != NULL);
1134 xassert (charpos >= 0);
1136 if (multibyte_p)
1138 int rest = strlen (s), len;
1140 SET_TEXT_POS (pos, 0, 0);
1141 while (charpos--)
1143 string_char_and_length (s, rest, &len);
1144 s += len, rest -= len;
1145 xassert (rest >= 0);
1146 CHARPOS (pos) += 1;
1147 BYTEPOS (pos) += len;
1150 else
1151 SET_TEXT_POS (pos, charpos, charpos);
1153 return pos;
1157 /* Value is the number of characters in C string S. MULTIBYTE_P
1158 non-zero means recognize multibyte characters. */
1160 static int
1161 number_of_chars (s, multibyte_p)
1162 unsigned char *s;
1163 int multibyte_p;
1165 int nchars;
1167 if (multibyte_p)
1169 int rest = strlen (s), len;
1170 unsigned char *p = (unsigned char *) s;
1172 for (nchars = 0; rest > 0; ++nchars)
1174 string_char_and_length (p, rest, &len);
1175 rest -= len, p += len;
1178 else
1179 nchars = strlen (s);
1181 return nchars;
1185 /* Compute byte position NEWPOS->bytepos corresponding to
1186 NEWPOS->charpos. POS is a known position in string STRING.
1187 NEWPOS->charpos must be >= POS.charpos. */
1189 static void
1190 compute_string_pos (newpos, pos, string)
1191 struct text_pos *newpos, pos;
1192 Lisp_Object string;
1194 xassert (STRINGP (string));
1195 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1197 if (STRING_MULTIBYTE (string))
1198 *newpos = string_pos_nchars_ahead (pos, string,
1199 CHARPOS (*newpos) - CHARPOS (pos));
1200 else
1201 BYTEPOS (*newpos) = CHARPOS (*newpos);
1206 /***********************************************************************
1207 Lisp form evaluation
1208 ***********************************************************************/
1210 /* Error handler for safe_eval and safe_call. */
1212 static Lisp_Object
1213 safe_eval_handler (arg)
1214 Lisp_Object arg;
1216 add_to_log ("Error during redisplay: %s", arg, Qnil);
1217 return Qnil;
1221 /* Evaluate SEXPR and return the result, or nil if something went
1222 wrong. */
1224 Lisp_Object
1225 safe_eval (sexpr)
1226 Lisp_Object sexpr;
1228 int count = BINDING_STACK_SIZE ();
1229 struct gcpro gcpro1;
1230 Lisp_Object val;
1232 GCPRO1 (sexpr);
1233 specbind (Qinhibit_redisplay, Qt);
1234 val = internal_condition_case_1 (Feval, sexpr, Qerror, safe_eval_handler);
1235 UNGCPRO;
1236 return unbind_to (count, val);
1240 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1241 Return the result, or nil if something went wrong. */
1243 Lisp_Object
1244 safe_call (nargs, args)
1245 int nargs;
1246 Lisp_Object *args;
1248 int count = BINDING_STACK_SIZE ();
1249 Lisp_Object val;
1250 struct gcpro gcpro1;
1252 GCPRO1 (args[0]);
1253 gcpro1.nvars = nargs;
1254 specbind (Qinhibit_redisplay, Qt);
1255 val = internal_condition_case_2 (Ffuncall, nargs, args, Qerror,
1256 safe_eval_handler);
1257 UNGCPRO;
1258 return unbind_to (count, val);
1262 /* Call function FN with one argument ARG.
1263 Return the result, or nil if something went wrong. */
1265 Lisp_Object
1266 safe_call1 (fn, arg)
1267 Lisp_Object fn, arg;
1269 Lisp_Object args[2];
1270 args[0] = fn;
1271 args[1] = arg;
1272 return safe_call (2, args);
1277 /***********************************************************************
1278 Debugging
1279 ***********************************************************************/
1281 #if 0
1283 /* Define CHECK_IT to perform sanity checks on iterators.
1284 This is for debugging. It is too slow to do unconditionally. */
1286 static void
1287 check_it (it)
1288 struct it *it;
1290 if (it->method == next_element_from_string)
1292 xassert (STRINGP (it->string));
1293 xassert (IT_STRING_CHARPOS (*it) >= 0);
1295 else if (it->method == next_element_from_buffer)
1297 /* Check that character and byte positions agree. */
1298 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1301 if (it->dpvec)
1302 xassert (it->current.dpvec_index >= 0);
1303 else
1304 xassert (it->current.dpvec_index < 0);
1307 #define CHECK_IT(IT) check_it ((IT))
1309 #else /* not 0 */
1311 #define CHECK_IT(IT) (void) 0
1313 #endif /* not 0 */
1316 #if GLYPH_DEBUG
1318 /* Check that the window end of window W is what we expect it
1319 to be---the last row in the current matrix displaying text. */
1321 static void
1322 check_window_end (w)
1323 struct window *w;
1325 if (!MINI_WINDOW_P (w)
1326 && !NILP (w->window_end_valid))
1328 struct glyph_row *row;
1329 xassert ((row = MATRIX_ROW (w->current_matrix,
1330 XFASTINT (w->window_end_vpos)),
1331 !row->enabled_p
1332 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1333 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1337 #define CHECK_WINDOW_END(W) check_window_end ((W))
1339 #else /* not GLYPH_DEBUG */
1341 #define CHECK_WINDOW_END(W) (void) 0
1343 #endif /* not GLYPH_DEBUG */
1347 /***********************************************************************
1348 Iterator initialization
1349 ***********************************************************************/
1351 /* Initialize IT for displaying current_buffer in window W, starting
1352 at character position CHARPOS. CHARPOS < 0 means that no buffer
1353 position is specified which is useful when the iterator is assigned
1354 a position later. BYTEPOS is the byte position corresponding to
1355 CHARPOS. BYTEPOS <= 0 means compute it from CHARPOS.
1357 If ROW is not null, calls to produce_glyphs with IT as parameter
1358 will produce glyphs in that row.
1360 BASE_FACE_ID is the id of a base face to use. It must be one of
1361 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID or
1362 HEADER_LINE_FACE_ID for displaying mode lines, or TOOL_BAR_FACE_ID for
1363 displaying the tool-bar.
1365 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID or
1366 HEADER_LINE_FACE_ID, the iterator will be initialized to use the
1367 corresponding mode line glyph row of the desired matrix of W. */
1369 void
1370 init_iterator (it, w, charpos, bytepos, row, base_face_id)
1371 struct it *it;
1372 struct window *w;
1373 int charpos, bytepos;
1374 struct glyph_row *row;
1375 enum face_id base_face_id;
1377 int highlight_region_p;
1379 /* Some precondition checks. */
1380 xassert (w != NULL && it != NULL);
1381 xassert (charpos < 0 || (charpos > 0 && charpos <= ZV));
1383 /* If face attributes have been changed since the last redisplay,
1384 free realized faces now because they depend on face definitions
1385 that might have changed. */
1386 if (face_change_count)
1388 face_change_count = 0;
1389 free_all_realized_faces (Qnil);
1392 /* Use one of the mode line rows of W's desired matrix if
1393 appropriate. */
1394 if (row == NULL)
1396 if (base_face_id == MODE_LINE_FACE_ID)
1397 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
1398 else if (base_face_id == HEADER_LINE_FACE_ID)
1399 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
1402 /* Clear IT. */
1403 bzero (it, sizeof *it);
1404 it->current.overlay_string_index = -1;
1405 it->current.dpvec_index = -1;
1406 it->base_face_id = base_face_id;
1408 /* The window in which we iterate over current_buffer: */
1409 XSETWINDOW (it->window, w);
1410 it->w = w;
1411 it->f = XFRAME (w->frame);
1413 /* Extra space between lines (on window systems only). */
1414 if (base_face_id == DEFAULT_FACE_ID
1415 && FRAME_WINDOW_P (it->f))
1417 if (NATNUMP (current_buffer->extra_line_spacing))
1418 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
1419 else if (it->f->extra_line_spacing > 0)
1420 it->extra_line_spacing = it->f->extra_line_spacing;
1423 /* If realized faces have been removed, e.g. because of face
1424 attribute changes of named faces, recompute them. */
1425 if (FRAME_FACE_CACHE (it->f)->used == 0)
1426 recompute_basic_faces (it->f);
1428 /* Current value of the `space-width', and 'height' properties. */
1429 it->space_width = Qnil;
1430 it->font_height = Qnil;
1432 /* Are control characters displayed as `^C'? */
1433 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
1435 /* -1 means everything between a CR and the following line end
1436 is invisible. >0 means lines indented more than this value are
1437 invisible. */
1438 it->selective = (INTEGERP (current_buffer->selective_display)
1439 ? XFASTINT (current_buffer->selective_display)
1440 : (!NILP (current_buffer->selective_display)
1441 ? -1 : 0));
1442 it->selective_display_ellipsis_p
1443 = !NILP (current_buffer->selective_display_ellipses);
1445 /* Display table to use. */
1446 it->dp = window_display_table (w);
1448 /* Are multibyte characters enabled in current_buffer? */
1449 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
1451 /* Non-zero if we should highlight the region. */
1452 highlight_region_p
1453 = (!NILP (Vtransient_mark_mode)
1454 && !NILP (current_buffer->mark_active)
1455 && XMARKER (current_buffer->mark)->buffer != 0);
1457 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
1458 start and end of a visible region in window IT->w. Set both to
1459 -1 to indicate no region. */
1460 if (highlight_region_p
1461 /* Maybe highlight only in selected window. */
1462 && (/* Either show region everywhere. */
1463 highlight_nonselected_windows
1464 /* Or show region in the selected window. */
1465 || w == XWINDOW (selected_window)
1466 /* Or show the region if we are in the mini-buffer and W is
1467 the window the mini-buffer refers to. */
1468 || (MINI_WINDOW_P (XWINDOW (selected_window))
1469 && w == XWINDOW (Vminibuf_scroll_window))))
1471 int charpos = marker_position (current_buffer->mark);
1472 it->region_beg_charpos = min (PT, charpos);
1473 it->region_end_charpos = max (PT, charpos);
1475 else
1476 it->region_beg_charpos = it->region_end_charpos = -1;
1478 /* Get the position at which the redisplay_end_trigger hook should
1479 be run, if it is to be run at all. */
1480 if (MARKERP (w->redisplay_end_trigger)
1481 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
1482 it->redisplay_end_trigger_charpos
1483 = marker_position (w->redisplay_end_trigger);
1484 else if (INTEGERP (w->redisplay_end_trigger))
1485 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
1487 /* Correct bogus values of tab_width. */
1488 it->tab_width = XINT (current_buffer->tab_width);
1489 if (it->tab_width <= 0 || it->tab_width > 1000)
1490 it->tab_width = 8;
1492 /* Are lines in the display truncated? */
1493 it->truncate_lines_p
1494 = (base_face_id != DEFAULT_FACE_ID
1495 || XINT (it->w->hscroll)
1496 || (truncate_partial_width_windows
1497 && !WINDOW_FULL_WIDTH_P (it->w))
1498 || !NILP (current_buffer->truncate_lines));
1500 /* Get dimensions of truncation and continuation glyphs. These are
1501 displayed as bitmaps under X, so we don't need them for such
1502 frames. */
1503 if (!FRAME_WINDOW_P (it->f))
1505 if (it->truncate_lines_p)
1507 /* We will need the truncation glyph. */
1508 xassert (it->glyph_row == NULL);
1509 produce_special_glyphs (it, IT_TRUNCATION);
1510 it->truncation_pixel_width = it->pixel_width;
1512 else
1514 /* We will need the continuation glyph. */
1515 xassert (it->glyph_row == NULL);
1516 produce_special_glyphs (it, IT_CONTINUATION);
1517 it->continuation_pixel_width = it->pixel_width;
1520 /* Reset these values to zero becaue the produce_special_glyphs
1521 above has changed them. */
1522 it->pixel_width = it->ascent = it->descent = 0;
1523 it->phys_ascent = it->phys_descent = 0;
1526 /* Set this after getting the dimensions of truncation and
1527 continuation glyphs, so that we don't produce glyphs when calling
1528 produce_special_glyphs, above. */
1529 it->glyph_row = row;
1530 it->area = TEXT_AREA;
1532 /* Get the dimensions of the display area. The display area
1533 consists of the visible window area plus a horizontally scrolled
1534 part to the left of the window. All x-values are relative to the
1535 start of this total display area. */
1536 if (base_face_id != DEFAULT_FACE_ID)
1538 /* Mode lines, menu bar in terminal frames. */
1539 it->first_visible_x = 0;
1540 it->last_visible_x = XFASTINT (w->width) * CANON_X_UNIT (it->f);
1542 else
1544 it->first_visible_x
1545 = XFASTINT (it->w->hscroll) * CANON_X_UNIT (it->f);
1546 it->last_visible_x = (it->first_visible_x
1547 + window_box_width (w, TEXT_AREA));
1549 /* If we truncate lines, leave room for the truncator glyph(s) at
1550 the right margin. Otherwise, leave room for the continuation
1551 glyph(s). Truncation and continuation glyphs are not inserted
1552 for window-based redisplay. */
1553 if (!FRAME_WINDOW_P (it->f))
1555 if (it->truncate_lines_p)
1556 it->last_visible_x -= it->truncation_pixel_width;
1557 else
1558 it->last_visible_x -= it->continuation_pixel_width;
1561 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
1562 it->current_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w) + w->vscroll;
1565 /* Leave room for a border glyph. */
1566 if (!FRAME_WINDOW_P (it->f)
1567 && !WINDOW_RIGHTMOST_P (it->w))
1568 it->last_visible_x -= 1;
1570 it->last_visible_y = window_text_bottom_y (w);
1572 /* For mode lines and alike, arrange for the first glyph having a
1573 left box line if the face specifies a box. */
1574 if (base_face_id != DEFAULT_FACE_ID)
1576 struct face *face;
1578 it->face_id = base_face_id;
1580 /* If we have a boxed mode line, make the first character appear
1581 with a left box line. */
1582 face = FACE_FROM_ID (it->f, base_face_id);
1583 if (face->box != FACE_NO_BOX)
1584 it->start_of_box_run_p = 1;
1587 /* If a buffer position was specified, set the iterator there,
1588 getting overlays and face properties from that position. */
1589 if (charpos > 0)
1591 it->end_charpos = ZV;
1592 it->face_id = -1;
1593 IT_CHARPOS (*it) = charpos;
1595 /* Compute byte position if not specified. */
1596 if (bytepos <= 0)
1597 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
1598 else
1599 IT_BYTEPOS (*it) = bytepos;
1601 /* Compute faces etc. */
1602 reseat (it, it->current.pos, 1);
1605 CHECK_IT (it);
1609 /* Initialize IT for the display of window W with window start POS. */
1611 void
1612 start_display (it, w, pos)
1613 struct it *it;
1614 struct window *w;
1615 struct text_pos pos;
1617 int start_at_line_beg_p;
1618 struct glyph_row *row;
1619 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
1620 int first_y;
1622 row = w->desired_matrix->rows + first_vpos;
1623 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
1624 first_y = it->current_y;
1626 /* If window start is not at a line start, move back to the line
1627 start. This makes sure that we take continuation lines into
1628 account. */
1629 start_at_line_beg_p = (CHARPOS (pos) == BEGV
1630 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
1631 if (!start_at_line_beg_p)
1632 reseat_at_previous_visible_line_start (it);
1634 /* If window start is not at a line start, skip forward to POS to
1635 get the correct continuation_lines_width and current_x. */
1636 if (!start_at_line_beg_p)
1638 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
1640 /* If lines are continued, this line may end in the middle of a
1641 multi-glyph character (e.g. a control character displayed as
1642 \003, or in the middle of an overlay string). In this case
1643 move_it_to above will not have taken us to the start of
1644 the continuation line but to the end of the continued line. */
1645 if (!it->truncate_lines_p)
1647 if (it->current_x > 0)
1649 if (it->current.dpvec_index >= 0
1650 || it->current.overlay_string_index >= 0)
1652 set_iterator_to_next (it, 1);
1653 move_it_in_display_line_to (it, -1, -1, 0);
1656 it->continuation_lines_width += it->current_x;
1659 /* We're starting a new display line, not affected by the
1660 height of the continued line, so clear the appropriate
1661 fields in the iterator structure. */
1662 it->max_ascent = it->max_descent = 0;
1663 it->max_phys_ascent = it->max_phys_descent = 0;
1666 it->current_y = first_y;
1667 it->vpos = 0;
1668 it->current_x = it->hpos = 0;
1671 #if 0 /* Don't assert the following because start_display is sometimes
1672 called intentionally with a window start that is not at a
1673 line start. Please leave this code in as a comment. */
1675 /* Window start should be on a line start, now. */
1676 xassert (it->continuation_lines_width
1677 || IT_CHARPOS (it) == BEGV
1678 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
1679 #endif /* 0 */
1683 /* Initialize IT for stepping through current_buffer in window W,
1684 starting at position POS that includes overlay string and display
1685 vector/ control character translation position information. */
1687 static void
1688 init_from_display_pos (it, w, pos)
1689 struct it *it;
1690 struct window *w;
1691 struct display_pos *pos;
1693 /* Keep in mind: the call to reseat in init_iterator skips invisible
1694 text, so we might end up at a position different from POS. This
1695 is only a problem when POS is a row start after a newline and an
1696 overlay starts there with an after-string, and the overlay has an
1697 invisible property. Since we don't skip invisible text in
1698 display_line and elsewhere immediately after consuming the
1699 newline before the row start, such a POS will not be in a string,
1700 but the call to init_iterator below will move us to the
1701 after-string. */
1702 init_iterator (it, w, CHARPOS (pos->pos), BYTEPOS (pos->pos),
1703 NULL, DEFAULT_FACE_ID);
1705 /* If position is within an overlay string, set up IT to
1706 the right overlay string. */
1707 if (pos->overlay_string_index >= 0)
1709 int relative_index;
1711 /* We already have the first chunk of overlay strings in
1712 IT->overlay_strings. Load more until the one for
1713 pos->overlay_string_index is in IT->overlay_strings. */
1714 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
1716 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
1717 it->current.overlay_string_index = 0;
1718 while (n--)
1720 load_overlay_strings (it);
1721 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
1725 it->current.overlay_string_index = pos->overlay_string_index;
1726 relative_index = (it->current.overlay_string_index
1727 % OVERLAY_STRING_CHUNK_SIZE);
1728 it->string = it->overlay_strings[relative_index];
1729 xassert (STRINGP (it->string));
1730 it->current.string_pos = pos->string_pos;
1731 it->method = next_element_from_string;
1733 else if (it->current.overlay_string_index >= 0)
1735 /* If POS says we're already after an overlay string ending at
1736 POS, make sure to pop the iterator because it will be in
1737 front of that overlay string. When POS is ZV, we've thereby
1738 also ``processed'' overlay strings at ZV. */
1739 pop_it (it);
1740 it->current.overlay_string_index = -1;
1741 it->method = next_element_from_buffer;
1742 if (CHARPOS (pos->pos) == ZV)
1743 it->overlay_strings_at_end_processed_p = 1;
1746 if (CHARPOS (pos->string_pos) >= 0)
1748 /* Recorded position is not in an overlay string, but in another
1749 string. This can only be a string from a `display' property.
1750 IT should already be filled with that string. */
1751 it->current.string_pos = pos->string_pos;
1752 xassert (STRINGP (it->string));
1755 /* Restore position in display vector translations or control
1756 character translations. */
1757 if (pos->dpvec_index >= 0)
1759 /* This fills IT->dpvec. */
1760 get_next_display_element (it);
1761 xassert (it->dpvec && it->current.dpvec_index == 0);
1762 it->current.dpvec_index = pos->dpvec_index;
1765 CHECK_IT (it);
1769 /* Initialize IT for stepping through current_buffer in window W
1770 starting at ROW->start. */
1772 static void
1773 init_to_row_start (it, w, row)
1774 struct it *it;
1775 struct window *w;
1776 struct glyph_row *row;
1778 init_from_display_pos (it, w, &row->start);
1779 it->continuation_lines_width = row->continuation_lines_width;
1780 CHECK_IT (it);
1784 /* Initialize IT for stepping through current_buffer in window W
1785 starting in the line following ROW, i.e. starting at ROW->end. */
1787 static void
1788 init_to_row_end (it, w, row)
1789 struct it *it;
1790 struct window *w;
1791 struct glyph_row *row;
1793 init_from_display_pos (it, w, &row->end);
1795 if (row->continued_p)
1796 it->continuation_lines_width = (row->continuation_lines_width
1797 + row->pixel_width);
1798 CHECK_IT (it);
1804 /***********************************************************************
1805 Text properties
1806 ***********************************************************************/
1808 /* Called when IT reaches IT->stop_charpos. Handle text property and
1809 overlay changes. Set IT->stop_charpos to the next position where
1810 to stop. */
1812 static void
1813 handle_stop (it)
1814 struct it *it;
1816 enum prop_handled handled;
1817 int handle_overlay_change_p = 1;
1818 struct props *p;
1820 it->dpvec = NULL;
1821 it->current.dpvec_index = -1;
1825 handled = HANDLED_NORMALLY;
1827 /* Call text property handlers. */
1828 for (p = it_props; p->handler; ++p)
1830 handled = p->handler (it);
1832 if (handled == HANDLED_RECOMPUTE_PROPS)
1833 break;
1834 else if (handled == HANDLED_RETURN)
1835 return;
1836 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
1837 handle_overlay_change_p = 0;
1840 if (handled != HANDLED_RECOMPUTE_PROPS)
1842 /* Don't check for overlay strings below when set to deliver
1843 characters from a display vector. */
1844 if (it->method == next_element_from_display_vector)
1845 handle_overlay_change_p = 0;
1847 /* Handle overlay changes. */
1848 if (handle_overlay_change_p)
1849 handled = handle_overlay_change (it);
1851 /* Determine where to stop next. */
1852 if (handled == HANDLED_NORMALLY)
1853 compute_stop_pos (it);
1856 while (handled == HANDLED_RECOMPUTE_PROPS);
1860 /* Compute IT->stop_charpos from text property and overlay change
1861 information for IT's current position. */
1863 static void
1864 compute_stop_pos (it)
1865 struct it *it;
1867 register INTERVAL iv, next_iv;
1868 Lisp_Object object, limit, position;
1870 /* If nowhere else, stop at the end. */
1871 it->stop_charpos = it->end_charpos;
1873 if (STRINGP (it->string))
1875 /* Strings are usually short, so don't limit the search for
1876 properties. */
1877 object = it->string;
1878 limit = Qnil;
1879 XSETFASTINT (position, IT_STRING_CHARPOS (*it));
1881 else
1883 int charpos;
1885 /* If next overlay change is in front of the current stop pos
1886 (which is IT->end_charpos), stop there. Note: value of
1887 next_overlay_change is point-max if no overlay change
1888 follows. */
1889 charpos = next_overlay_change (IT_CHARPOS (*it));
1890 if (charpos < it->stop_charpos)
1891 it->stop_charpos = charpos;
1893 /* If showing the region, we have to stop at the region
1894 start or end because the face might change there. */
1895 if (it->region_beg_charpos > 0)
1897 if (IT_CHARPOS (*it) < it->region_beg_charpos)
1898 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
1899 else if (IT_CHARPOS (*it) < it->region_end_charpos)
1900 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
1903 /* Set up variables for computing the stop position from text
1904 property changes. */
1905 XSETBUFFER (object, current_buffer);
1906 XSETFASTINT (limit, IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
1907 XSETFASTINT (position, IT_CHARPOS (*it));
1911 /* Get the interval containing IT's position. Value is a null
1912 interval if there isn't such an interval. */
1913 iv = validate_interval_range (object, &position, &position, 0);
1914 if (!NULL_INTERVAL_P (iv))
1916 Lisp_Object values_here[LAST_PROP_IDX];
1917 struct props *p;
1919 /* Get properties here. */
1920 for (p = it_props; p->handler; ++p)
1921 values_here[p->idx] = textget (iv->plist, *p->name);
1923 /* Look for an interval following iv that has different
1924 properties. */
1925 for (next_iv = next_interval (iv);
1926 (!NULL_INTERVAL_P (next_iv)
1927 && (NILP (limit)
1928 || XFASTINT (limit) > next_iv->position));
1929 next_iv = next_interval (next_iv))
1931 for (p = it_props; p->handler; ++p)
1933 Lisp_Object new_value;
1935 new_value = textget (next_iv->plist, *p->name);
1936 if (!EQ (values_here[p->idx], new_value))
1937 break;
1940 if (p->handler)
1941 break;
1944 if (!NULL_INTERVAL_P (next_iv))
1946 if (INTEGERP (limit)
1947 && next_iv->position >= XFASTINT (limit))
1948 /* No text property change up to limit. */
1949 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
1950 else
1951 /* Text properties change in next_iv. */
1952 it->stop_charpos = min (it->stop_charpos, next_iv->position);
1956 xassert (STRINGP (it->string)
1957 || (it->stop_charpos >= BEGV
1958 && it->stop_charpos >= IT_CHARPOS (*it)));
1962 /* Return the position of the next overlay change after POS in
1963 current_buffer. Value is point-max if no overlay change
1964 follows. This is like `next-overlay-change' but doesn't use
1965 xmalloc. */
1967 static int
1968 next_overlay_change (pos)
1969 int pos;
1971 int noverlays;
1972 int endpos;
1973 Lisp_Object *overlays;
1974 int len;
1975 int i;
1977 /* Get all overlays at the given position. */
1978 len = 10;
1979 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1980 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
1981 if (noverlays > len)
1983 len = noverlays;
1984 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1985 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
1988 /* If any of these overlays ends before endpos,
1989 use its ending point instead. */
1990 for (i = 0; i < noverlays; ++i)
1992 Lisp_Object oend;
1993 int oendpos;
1995 oend = OVERLAY_END (overlays[i]);
1996 oendpos = OVERLAY_POSITION (oend);
1997 endpos = min (endpos, oendpos);
2000 return endpos;
2005 /***********************************************************************
2006 Fontification
2007 ***********************************************************************/
2009 /* Handle changes in the `fontified' property of the current buffer by
2010 calling hook functions from Qfontification_functions to fontify
2011 regions of text. */
2013 static enum prop_handled
2014 handle_fontified_prop (it)
2015 struct it *it;
2017 Lisp_Object prop, pos;
2018 enum prop_handled handled = HANDLED_NORMALLY;
2020 /* Get the value of the `fontified' property at IT's current buffer
2021 position. (The `fontified' property doesn't have a special
2022 meaning in strings.) If the value is nil, call functions from
2023 Qfontification_functions. */
2024 if (!STRINGP (it->string)
2025 && it->s == NULL
2026 && !NILP (Vfontification_functions)
2027 && !NILP (Vrun_hooks)
2028 && (pos = make_number (IT_CHARPOS (*it)),
2029 prop = Fget_char_property (pos, Qfontified, Qnil),
2030 NILP (prop)))
2032 int count = BINDING_STACK_SIZE ();
2033 Lisp_Object val;
2035 val = Vfontification_functions;
2036 specbind (Qfontification_functions, Qnil);
2037 specbind (Qafter_change_functions, Qnil);
2039 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2040 safe_call1 (val, pos);
2041 else
2043 Lisp_Object globals, fn;
2044 struct gcpro gcpro1, gcpro2;
2046 globals = Qnil;
2047 GCPRO2 (val, globals);
2049 for (; CONSP (val); val = XCDR (val))
2051 fn = XCAR (val);
2053 if (EQ (fn, Qt))
2055 /* A value of t indicates this hook has a local
2056 binding; it means to run the global binding too.
2057 In a global value, t should not occur. If it
2058 does, we must ignore it to avoid an endless
2059 loop. */
2060 for (globals = Fdefault_value (Qfontification_functions);
2061 CONSP (globals);
2062 globals = XCDR (globals))
2064 fn = XCAR (globals);
2065 if (!EQ (fn, Qt))
2066 safe_call1 (fn, pos);
2069 else
2070 safe_call1 (fn, pos);
2073 UNGCPRO;
2076 unbind_to (count, Qnil);
2078 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2079 something. This avoids an endless loop if they failed to
2080 fontify the text for which reason ever. */
2081 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2082 handled = HANDLED_RECOMPUTE_PROPS;
2085 return handled;
2090 /***********************************************************************
2091 Faces
2092 ***********************************************************************/
2094 /* Set up iterator IT from face properties at its current position.
2095 Called from handle_stop. */
2097 static enum prop_handled
2098 handle_face_prop (it)
2099 struct it *it;
2101 int new_face_id, next_stop;
2103 if (!STRINGP (it->string))
2105 new_face_id
2106 = face_at_buffer_position (it->w,
2107 IT_CHARPOS (*it),
2108 it->region_beg_charpos,
2109 it->region_end_charpos,
2110 &next_stop,
2111 (IT_CHARPOS (*it)
2112 + TEXT_PROP_DISTANCE_LIMIT),
2115 /* Is this a start of a run of characters with box face?
2116 Caveat: this can be called for a freshly initialized
2117 iterator; face_id is -1 is this case. We know that the new
2118 face will not change until limit, i.e. if the new face has a
2119 box, all characters up to limit will have one. But, as
2120 usual, we don't know whether limit is really the end. */
2121 if (new_face_id != it->face_id)
2123 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2125 /* If new face has a box but old face has not, this is
2126 the start of a run of characters with box, i.e. it has
2127 a shadow on the left side. The value of face_id of the
2128 iterator will be -1 if this is the initial call that gets
2129 the face. In this case, we have to look in front of IT's
2130 position and see whether there is a face != new_face_id. */
2131 it->start_of_box_run_p
2132 = (new_face->box != FACE_NO_BOX
2133 && (it->face_id >= 0
2134 || IT_CHARPOS (*it) == BEG
2135 || new_face_id != face_before_it_pos (it)));
2136 it->face_box_p = new_face->box != FACE_NO_BOX;
2139 else
2141 new_face_id
2142 = face_at_string_position (it->w,
2143 it->string,
2144 IT_STRING_CHARPOS (*it),
2145 (it->current.overlay_string_index >= 0
2146 ? IT_CHARPOS (*it)
2147 : 0),
2148 it->region_beg_charpos,
2149 it->region_end_charpos,
2150 &next_stop,
2151 it->base_face_id);
2153 #if 0 /* This shouldn't be neccessary. Let's check it. */
2154 /* If IT is used to display a mode line we would really like to
2155 use the mode line face instead of the frame's default face. */
2156 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2157 && new_face_id == DEFAULT_FACE_ID)
2158 new_face_id = MODE_LINE_FACE_ID;
2159 #endif
2161 /* Is this a start of a run of characters with box? Caveat:
2162 this can be called for a freshly allocated iterator; face_id
2163 is -1 is this case. We know that the new face will not
2164 change until the next check pos, i.e. if the new face has a
2165 box, all characters up to that position will have a
2166 box. But, as usual, we don't know whether that position
2167 is really the end. */
2168 if (new_face_id != it->face_id)
2170 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2171 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2173 /* If new face has a box but old face hasn't, this is the
2174 start of a run of characters with box, i.e. it has a
2175 shadow on the left side. */
2176 it->start_of_box_run_p
2177 = new_face->box && (old_face == NULL || !old_face->box);
2178 it->face_box_p = new_face->box != FACE_NO_BOX;
2182 it->face_id = new_face_id;
2183 return HANDLED_NORMALLY;
2187 /* Compute the face one character before or after the current position
2188 of IT. BEFORE_P non-zero means get the face in front of IT's
2189 position. Value is the id of the face. */
2191 static int
2192 face_before_or_after_it_pos (it, before_p)
2193 struct it *it;
2194 int before_p;
2196 int face_id, limit;
2197 int next_check_charpos;
2198 struct text_pos pos;
2200 xassert (it->s == NULL);
2202 if (STRINGP (it->string))
2204 /* No face change past the end of the string (for the case
2205 we are padding with spaces). No face change before the
2206 string start. */
2207 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size
2208 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2209 return it->face_id;
2211 /* Set pos to the position before or after IT's current position. */
2212 if (before_p)
2213 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
2214 else
2215 /* For composition, we must check the character after the
2216 composition. */
2217 pos = (it->what == IT_COMPOSITION
2218 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
2219 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
2221 /* Get the face for ASCII, or unibyte. */
2222 face_id
2223 = face_at_string_position (it->w,
2224 it->string,
2225 CHARPOS (pos),
2226 (it->current.overlay_string_index >= 0
2227 ? IT_CHARPOS (*it)
2228 : 0),
2229 it->region_beg_charpos,
2230 it->region_end_charpos,
2231 &next_check_charpos,
2232 it->base_face_id);
2234 /* Correct the face for charsets different from ASCII. Do it
2235 for the multibyte case only. The face returned above is
2236 suitable for unibyte text if IT->string is unibyte. */
2237 if (STRING_MULTIBYTE (it->string))
2239 unsigned char *p = XSTRING (it->string)->data + BYTEPOS (pos);
2240 int rest = STRING_BYTES (XSTRING (it->string)) - BYTEPOS (pos);
2241 int c, len;
2242 struct face *face = FACE_FROM_ID (it->f, face_id);
2244 c = string_char_and_length (p, rest, &len);
2245 face_id = FACE_FOR_CHAR (it->f, face, c);
2248 else
2250 if ((IT_CHARPOS (*it) >= ZV && !before_p)
2251 || (IT_CHARPOS (*it) <= BEGV && before_p))
2252 return it->face_id;
2254 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
2255 pos = it->current.pos;
2257 if (before_p)
2258 DEC_TEXT_POS (pos, it->multibyte_p);
2259 else
2261 if (it->what == IT_COMPOSITION)
2262 /* For composition, we must check the position after the
2263 composition. */
2264 pos.charpos += it->cmp_len, pos.bytepos += it->len;
2265 else
2266 INC_TEXT_POS (pos, it->multibyte_p);
2268 /* Determine face for CHARSET_ASCII, or unibyte. */
2269 face_id = face_at_buffer_position (it->w,
2270 CHARPOS (pos),
2271 it->region_beg_charpos,
2272 it->region_end_charpos,
2273 &next_check_charpos,
2274 limit, 0);
2276 /* Correct the face for charsets different from ASCII. Do it
2277 for the multibyte case only. The face returned above is
2278 suitable for unibyte text if current_buffer is unibyte. */
2279 if (it->multibyte_p)
2281 int c = FETCH_MULTIBYTE_CHAR (CHARPOS (pos));
2282 struct face *face = FACE_FROM_ID (it->f, face_id);
2283 face_id = FACE_FOR_CHAR (it->f, face, c);
2287 return face_id;
2292 /***********************************************************************
2293 Invisible text
2294 ***********************************************************************/
2296 /* Set up iterator IT from invisible properties at its current
2297 position. Called from handle_stop. */
2299 static enum prop_handled
2300 handle_invisible_prop (it)
2301 struct it *it;
2303 enum prop_handled handled = HANDLED_NORMALLY;
2305 if (STRINGP (it->string))
2307 extern Lisp_Object Qinvisible;
2308 Lisp_Object prop, end_charpos, limit, charpos;
2310 /* Get the value of the invisible text property at the
2311 current position. Value will be nil if there is no such
2312 property. */
2313 XSETFASTINT (charpos, IT_STRING_CHARPOS (*it));
2314 prop = Fget_text_property (charpos, Qinvisible, it->string);
2316 if (!NILP (prop)
2317 && IT_STRING_CHARPOS (*it) < it->end_charpos)
2319 handled = HANDLED_RECOMPUTE_PROPS;
2321 /* Get the position at which the next change of the
2322 invisible text property can be found in IT->string.
2323 Value will be nil if the property value is the same for
2324 all the rest of IT->string. */
2325 XSETINT (limit, XSTRING (it->string)->size);
2326 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
2327 it->string, limit);
2329 /* Text at current position is invisible. The next
2330 change in the property is at position end_charpos.
2331 Move IT's current position to that position. */
2332 if (INTEGERP (end_charpos)
2333 && XFASTINT (end_charpos) < XFASTINT (limit))
2335 struct text_pos old;
2336 old = it->current.string_pos;
2337 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
2338 compute_string_pos (&it->current.string_pos, old, it->string);
2340 else
2342 /* The rest of the string is invisible. If this is an
2343 overlay string, proceed with the next overlay string
2344 or whatever comes and return a character from there. */
2345 if (it->current.overlay_string_index >= 0)
2347 next_overlay_string (it);
2348 /* Don't check for overlay strings when we just
2349 finished processing them. */
2350 handled = HANDLED_OVERLAY_STRING_CONSUMED;
2352 else
2354 struct Lisp_String *s = XSTRING (it->string);
2355 IT_STRING_CHARPOS (*it) = s->size;
2356 IT_STRING_BYTEPOS (*it) = STRING_BYTES (s);
2361 else
2363 int visible_p, newpos, next_stop;
2364 Lisp_Object pos, prop;
2366 /* First of all, is there invisible text at this position? */
2367 XSETFASTINT (pos, IT_CHARPOS (*it));
2368 prop = Fget_char_property (pos, Qinvisible, it->window);
2370 /* If we are on invisible text, skip over it. */
2371 if (TEXT_PROP_MEANS_INVISIBLE (prop)
2372 && IT_CHARPOS (*it) < it->end_charpos)
2374 /* Record whether we have to display an ellipsis for the
2375 invisible text. */
2376 int display_ellipsis_p
2377 = TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (prop);
2379 handled = HANDLED_RECOMPUTE_PROPS;
2381 /* Loop skipping over invisible text. The loop is left at
2382 ZV or with IT on the first char being visible again. */
2385 /* Try to skip some invisible text. Return value is the
2386 position reached which can be equal to IT's position
2387 if there is nothing invisible here. This skips both
2388 over invisible text properties and overlays with
2389 invisible property. */
2390 newpos = skip_invisible (IT_CHARPOS (*it),
2391 &next_stop, ZV, it->window);
2393 /* If we skipped nothing at all we weren't at invisible
2394 text in the first place. If everything to the end of
2395 the buffer was skipped, end the loop. */
2396 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
2397 visible_p = 1;
2398 else
2400 /* We skipped some characters but not necessarily
2401 all there are. Check if we ended up on visible
2402 text. Fget_char_property returns the property of
2403 the char before the given position, i.e. if we
2404 get visible_p = 1, this means that the char at
2405 newpos is visible. */
2406 XSETFASTINT (pos, newpos);
2407 prop = Fget_char_property (pos, Qinvisible, it->window);
2408 visible_p = !TEXT_PROP_MEANS_INVISIBLE (prop);
2411 /* If we ended up on invisible text, proceed to
2412 skip starting with next_stop. */
2413 if (!visible_p)
2414 IT_CHARPOS (*it) = next_stop;
2416 while (!visible_p);
2418 /* The position newpos is now either ZV or on visible text. */
2419 IT_CHARPOS (*it) = newpos;
2420 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
2422 /* Maybe return `...' next for the end of the invisible text. */
2423 if (display_ellipsis_p)
2425 if (it->dp
2426 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
2428 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
2429 it->dpvec = v->contents;
2430 it->dpend = v->contents + v->size;
2432 else
2434 /* Default `...'. */
2435 it->dpvec = default_invis_vector;
2436 it->dpend = default_invis_vector + 3;
2439 /* The ellipsis display does not replace the display of
2440 the character at the new position. Indicate this by
2441 setting IT->dpvec_char_len to zero. */
2442 it->dpvec_char_len = 0;
2444 it->current.dpvec_index = 0;
2445 it->method = next_element_from_display_vector;
2450 return handled;
2455 /***********************************************************************
2456 'display' property
2457 ***********************************************************************/
2459 /* Set up iterator IT from `display' property at its current position.
2460 Called from handle_stop. */
2462 static enum prop_handled
2463 handle_display_prop (it)
2464 struct it *it;
2466 Lisp_Object prop, object;
2467 struct text_pos *position;
2468 int space_or_image_found_p;
2470 if (STRINGP (it->string))
2472 object = it->string;
2473 position = &it->current.string_pos;
2475 else
2477 object = Qnil;
2478 position = &it->current.pos;
2481 /* Reset those iterator values set from display property values. */
2482 it->font_height = Qnil;
2483 it->space_width = Qnil;
2484 it->voffset = 0;
2486 /* We don't support recursive `display' properties, i.e. string
2487 values that have a string `display' property, that have a string
2488 `display' property etc. */
2489 if (!it->string_from_display_prop_p)
2490 it->area = TEXT_AREA;
2492 prop = Fget_char_property (make_number (position->charpos),
2493 Qdisplay, object);
2494 if (NILP (prop))
2495 return HANDLED_NORMALLY;
2497 space_or_image_found_p = 0;
2498 if (CONSP (prop)
2499 && CONSP (XCAR (prop))
2500 && !EQ (Qmargin, XCAR (XCAR (prop))))
2502 /* A list of sub-properties. */
2503 while (CONSP (prop))
2505 if (handle_single_display_prop (it, XCAR (prop), object, position))
2506 space_or_image_found_p = 1;
2507 prop = XCDR (prop);
2510 else if (VECTORP (prop))
2512 int i;
2513 for (i = 0; i < XVECTOR (prop)->size; ++i)
2514 if (handle_single_display_prop (it, XVECTOR (prop)->contents[i],
2515 object, position))
2516 space_or_image_found_p = 1;
2518 else
2520 if (handle_single_display_prop (it, prop, object, position))
2521 space_or_image_found_p = 1;
2524 return space_or_image_found_p ? HANDLED_RETURN : HANDLED_NORMALLY;
2528 /* Value is the position of the end of the `display' property starting
2529 at START_POS in OBJECT. */
2531 static struct text_pos
2532 display_prop_end (it, object, start_pos)
2533 struct it *it;
2534 Lisp_Object object;
2535 struct text_pos start_pos;
2537 Lisp_Object end;
2538 struct text_pos end_pos;
2540 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
2541 Qdisplay, object, Qnil);
2542 CHARPOS (end_pos) = XFASTINT (end);
2543 if (STRINGP (object))
2544 compute_string_pos (&end_pos, start_pos, it->string);
2545 else
2546 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
2548 return end_pos;
2552 /* Set up IT from a single `display' sub-property value PROP. OBJECT
2553 is the object in which the `display' property was found. *POSITION
2554 is the position at which it was found.
2556 If PROP is a `space' or `image' sub-property, set *POSITION to the
2557 end position of the `display' property.
2559 Value is non-zero if a `space' or `image' property value was found. */
2561 static int
2562 handle_single_display_prop (it, prop, object, position)
2563 struct it *it;
2564 Lisp_Object prop;
2565 Lisp_Object object;
2566 struct text_pos *position;
2568 Lisp_Object value;
2569 int space_or_image_found_p = 0;
2570 Lisp_Object form;
2572 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
2573 evaluated. If the result is nil, VALUE is ignored. */
2574 form = Qt;
2575 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
2577 prop = XCDR (prop);
2578 if (!CONSP (prop))
2579 return 0;
2580 form = XCAR (prop);
2581 prop = XCDR (prop);
2584 if (!NILP (form) && !EQ (form, Qt))
2586 struct gcpro gcpro1;
2587 struct text_pos end_pos, pt;
2589 GCPRO1 (form);
2590 end_pos = display_prop_end (it, object, *position);
2592 /* Temporarily set point to the end position, and then evaluate
2593 the form. This makes `(eolp)' work as FORM. */
2594 if (BUFFERP (object))
2596 CHARPOS (pt) = PT;
2597 BYTEPOS (pt) = PT_BYTE;
2598 TEMP_SET_PT_BOTH (CHARPOS (end_pos), BYTEPOS (end_pos));
2601 form = safe_eval (form);
2603 if (BUFFERP (object))
2604 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
2605 UNGCPRO;
2608 if (NILP (form))
2609 return 0;
2611 if (CONSP (prop)
2612 && EQ (XCAR (prop), Qheight)
2613 && CONSP (XCDR (prop)))
2615 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2616 return 0;
2618 /* `(height HEIGHT)'. */
2619 it->font_height = XCAR (XCDR (prop));
2620 if (!NILP (it->font_height))
2622 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2623 int new_height = -1;
2625 if (CONSP (it->font_height)
2626 && (EQ (XCAR (it->font_height), Qplus)
2627 || EQ (XCAR (it->font_height), Qminus))
2628 && CONSP (XCDR (it->font_height))
2629 && INTEGERP (XCAR (XCDR (it->font_height))))
2631 /* `(+ N)' or `(- N)' where N is an integer. */
2632 int steps = XINT (XCAR (XCDR (it->font_height)));
2633 if (EQ (XCAR (it->font_height), Qplus))
2634 steps = - steps;
2635 it->face_id = smaller_face (it->f, it->face_id, steps);
2637 else if (FUNCTIONP (it->font_height))
2639 /* Call function with current height as argument.
2640 Value is the new height. */
2641 Lisp_Object height;
2642 height = safe_call1 (it->font_height,
2643 face->lface[LFACE_HEIGHT_INDEX]);
2644 if (NUMBERP (height))
2645 new_height = XFLOATINT (height);
2647 else if (NUMBERP (it->font_height))
2649 /* Value is a multiple of the canonical char height. */
2650 struct face *face;
2652 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
2653 new_height = (XFLOATINT (it->font_height)
2654 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
2656 else
2658 /* Evaluate IT->font_height with `height' bound to the
2659 current specified height to get the new height. */
2660 Lisp_Object value;
2661 int count = BINDING_STACK_SIZE ();
2663 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
2664 value = safe_eval (it->font_height);
2665 unbind_to (count, Qnil);
2667 if (NUMBERP (value))
2668 new_height = XFLOATINT (value);
2671 if (new_height > 0)
2672 it->face_id = face_with_height (it->f, it->face_id, new_height);
2675 else if (CONSP (prop)
2676 && EQ (XCAR (prop), Qspace_width)
2677 && CONSP (XCDR (prop)))
2679 /* `(space_width WIDTH)'. */
2680 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2681 return 0;
2683 value = XCAR (XCDR (prop));
2684 if (NUMBERP (value) && XFLOATINT (value) > 0)
2685 it->space_width = value;
2687 else if (CONSP (prop)
2688 && EQ (XCAR (prop), Qraise)
2689 && CONSP (XCDR (prop)))
2691 /* `(raise FACTOR)'. */
2692 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2693 return 0;
2695 #ifdef HAVE_WINDOW_SYSTEM
2696 value = XCAR (XCDR (prop));
2697 if (NUMBERP (value))
2699 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2700 it->voffset = - (XFLOATINT (value)
2701 * (FONT_HEIGHT (face->font)));
2703 #endif /* HAVE_WINDOW_SYSTEM */
2705 else if (!it->string_from_display_prop_p)
2707 /* `((margin left-margin) VALUE)' or `((margin right-margin)
2708 VALUE) or `((margin nil) VALUE)' or VALUE. */
2709 Lisp_Object location, value;
2710 struct text_pos start_pos;
2711 int valid_p;
2713 /* Characters having this form of property are not displayed, so
2714 we have to find the end of the property. */
2715 start_pos = *position;
2716 *position = display_prop_end (it, object, start_pos);
2717 value = Qnil;
2719 /* Let's stop at the new position and assume that all
2720 text properties change there. */
2721 it->stop_charpos = position->charpos;
2723 location = Qunbound;
2724 if (CONSP (prop) && CONSP (XCAR (prop)))
2726 Lisp_Object tem;
2728 value = XCDR (prop);
2729 if (CONSP (value))
2730 value = XCAR (value);
2732 tem = XCAR (prop);
2733 if (EQ (XCAR (tem), Qmargin)
2734 && (tem = XCDR (tem),
2735 tem = CONSP (tem) ? XCAR (tem) : Qnil,
2736 (NILP (tem)
2737 || EQ (tem, Qleft_margin)
2738 || EQ (tem, Qright_margin))))
2739 location = tem;
2742 if (EQ (location, Qunbound))
2744 location = Qnil;
2745 value = prop;
2748 #ifdef HAVE_WINDOW_SYSTEM
2749 if (FRAME_TERMCAP_P (it->f))
2750 valid_p = STRINGP (value);
2751 else
2752 valid_p = (STRINGP (value)
2753 || (CONSP (value) && EQ (XCAR (value), Qspace))
2754 || valid_image_p (value));
2755 #else /* not HAVE_WINDOW_SYSTEM */
2756 valid_p = STRINGP (value);
2757 #endif /* not HAVE_WINDOW_SYSTEM */
2759 if ((EQ (location, Qleft_margin)
2760 || EQ (location, Qright_margin)
2761 || NILP (location))
2762 && valid_p)
2764 space_or_image_found_p = 1;
2766 /* Save current settings of IT so that we can restore them
2767 when we are finished with the glyph property value. */
2768 push_it (it);
2770 if (NILP (location))
2771 it->area = TEXT_AREA;
2772 else if (EQ (location, Qleft_margin))
2773 it->area = LEFT_MARGIN_AREA;
2774 else
2775 it->area = RIGHT_MARGIN_AREA;
2777 if (STRINGP (value))
2779 it->string = value;
2780 it->multibyte_p = STRING_MULTIBYTE (it->string);
2781 it->current.overlay_string_index = -1;
2782 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
2783 it->end_charpos = it->string_nchars
2784 = XSTRING (it->string)->size;
2785 it->method = next_element_from_string;
2786 it->stop_charpos = 0;
2787 it->string_from_display_prop_p = 1;
2789 else if (CONSP (value) && EQ (XCAR (value), Qspace))
2791 it->method = next_element_from_stretch;
2792 it->object = value;
2793 it->current.pos = it->position = start_pos;
2795 #ifdef HAVE_WINDOW_SYSTEM
2796 else
2798 it->what = IT_IMAGE;
2799 it->image_id = lookup_image (it->f, value);
2800 it->position = start_pos;
2801 it->object = NILP (object) ? it->w->buffer : object;
2802 it->method = next_element_from_image;
2804 /* Say that we haven't consumed the characters with
2805 `display' property yet. The call to pop_it in
2806 set_iterator_to_next will clean this up. */
2807 *position = start_pos;
2809 #endif /* HAVE_WINDOW_SYSTEM */
2811 else
2812 /* Invalid property or property not supported. Restore
2813 the position to what it was before. */
2814 *position = start_pos;
2817 return space_or_image_found_p;
2821 /* Check if PROP is a display sub-property value whose text should be
2822 treated as intangible. */
2824 static int
2825 single_display_prop_intangible_p (prop)
2826 Lisp_Object prop;
2828 /* Skip over `when FORM'. */
2829 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
2831 prop = XCDR (prop);
2832 if (!CONSP (prop))
2833 return 0;
2834 prop = XCDR (prop);
2837 if (!CONSP (prop))
2838 return 0;
2840 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
2841 we don't need to treat text as intangible. */
2842 if (EQ (XCAR (prop), Qmargin))
2844 prop = XCDR (prop);
2845 if (!CONSP (prop))
2846 return 0;
2848 prop = XCDR (prop);
2849 if (!CONSP (prop)
2850 || EQ (XCAR (prop), Qleft_margin)
2851 || EQ (XCAR (prop), Qright_margin))
2852 return 0;
2855 return CONSP (prop) && EQ (XCAR (prop), Qimage);
2859 /* Check if PROP is a display property value whose text should be
2860 treated as intangible. */
2863 display_prop_intangible_p (prop)
2864 Lisp_Object prop;
2866 if (CONSP (prop)
2867 && CONSP (XCAR (prop))
2868 && !EQ (Qmargin, XCAR (XCAR (prop))))
2870 /* A list of sub-properties. */
2871 while (CONSP (prop))
2873 if (single_display_prop_intangible_p (XCAR (prop)))
2874 return 1;
2875 prop = XCDR (prop);
2878 else if (VECTORP (prop))
2880 /* A vector of sub-properties. */
2881 int i;
2882 for (i = 0; i < XVECTOR (prop)->size; ++i)
2883 if (single_display_prop_intangible_p (XVECTOR (prop)->contents[i]))
2884 return 1;
2886 else
2887 return single_display_prop_intangible_p (prop);
2889 return 0;
2893 /***********************************************************************
2894 `composition' property
2895 ***********************************************************************/
2897 /* Set up iterator IT from `composition' property at its current
2898 position. Called from handle_stop. */
2900 static enum prop_handled
2901 handle_composition_prop (it)
2902 struct it *it;
2904 Lisp_Object prop, string;
2905 int pos, pos_byte, end;
2906 enum prop_handled handled = HANDLED_NORMALLY;
2908 if (STRINGP (it->string))
2910 pos = IT_STRING_CHARPOS (*it);
2911 pos_byte = IT_STRING_BYTEPOS (*it);
2912 string = it->string;
2914 else
2916 pos = IT_CHARPOS (*it);
2917 pos_byte = IT_BYTEPOS (*it);
2918 string = Qnil;
2921 /* If there's a valid composition and point is not inside of the
2922 composition (in the case that the composition is from the current
2923 buffer), draw a glyph composed from the composition components. */
2924 if (find_composition (pos, -1, &pos, &end, &prop, string)
2925 && COMPOSITION_VALID_P (pos, end, prop)
2926 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
2928 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
2930 if (id >= 0)
2932 it->method = next_element_from_composition;
2933 it->cmp_id = id;
2934 it->cmp_len = COMPOSITION_LENGTH (prop);
2935 /* For a terminal, draw only the first character of the
2936 components. */
2937 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
2938 it->len = (STRINGP (it->string)
2939 ? string_char_to_byte (it->string, end)
2940 : CHAR_TO_BYTE (end)) - pos_byte;
2941 it->stop_charpos = end;
2942 handled = HANDLED_RETURN;
2946 return handled;
2951 /***********************************************************************
2952 Overlay strings
2953 ***********************************************************************/
2955 /* The following structure is used to record overlay strings for
2956 later sorting in load_overlay_strings. */
2958 struct overlay_entry
2960 Lisp_Object overlay;
2961 Lisp_Object string;
2962 int priority;
2963 int after_string_p;
2967 /* Set up iterator IT from overlay strings at its current position.
2968 Called from handle_stop. */
2970 static enum prop_handled
2971 handle_overlay_change (it)
2972 struct it *it;
2974 if (!STRINGP (it->string) && get_overlay_strings (it))
2975 return HANDLED_RECOMPUTE_PROPS;
2976 else
2977 return HANDLED_NORMALLY;
2981 /* Set up the next overlay string for delivery by IT, if there is an
2982 overlay string to deliver. Called by set_iterator_to_next when the
2983 end of the current overlay string is reached. If there are more
2984 overlay strings to display, IT->string and
2985 IT->current.overlay_string_index are set appropriately here.
2986 Otherwise IT->string is set to nil. */
2988 static void
2989 next_overlay_string (it)
2990 struct it *it;
2992 ++it->current.overlay_string_index;
2993 if (it->current.overlay_string_index == it->n_overlay_strings)
2995 /* No more overlay strings. Restore IT's settings to what
2996 they were before overlay strings were processed, and
2997 continue to deliver from current_buffer. */
2998 pop_it (it);
2999 xassert (it->stop_charpos >= BEGV
3000 && it->stop_charpos <= it->end_charpos);
3001 it->string = Qnil;
3002 it->current.overlay_string_index = -1;
3003 SET_TEXT_POS (it->current.string_pos, -1, -1);
3004 it->n_overlay_strings = 0;
3005 it->method = next_element_from_buffer;
3007 /* If we're at the end of the buffer, record that we have
3008 processed the overlay strings there already, so that
3009 next_element_from_buffer doesn't try it again. */
3010 if (IT_CHARPOS (*it) >= it->end_charpos)
3011 it->overlay_strings_at_end_processed_p = 1;
3013 else
3015 /* There are more overlay strings to process. If
3016 IT->current.overlay_string_index has advanced to a position
3017 where we must load IT->overlay_strings with more strings, do
3018 it. */
3019 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
3021 if (it->current.overlay_string_index && i == 0)
3022 load_overlay_strings (it);
3024 /* Initialize IT to deliver display elements from the overlay
3025 string. */
3026 it->string = it->overlay_strings[i];
3027 it->multibyte_p = STRING_MULTIBYTE (it->string);
3028 SET_TEXT_POS (it->current.string_pos, 0, 0);
3029 it->method = next_element_from_string;
3030 it->stop_charpos = 0;
3033 CHECK_IT (it);
3037 /* Compare two overlay_entry structures E1 and E2. Used as a
3038 comparison function for qsort in load_overlay_strings. Overlay
3039 strings for the same position are sorted so that
3041 1. All after-strings come in front of before-strings, except
3042 when they come from the same overlay.
3044 2. Within after-strings, strings are sorted so that overlay strings
3045 from overlays with higher priorities come first.
3047 2. Within before-strings, strings are sorted so that overlay
3048 strings from overlays with higher priorities come last.
3050 Value is analogous to strcmp. */
3053 static int
3054 compare_overlay_entries (e1, e2)
3055 void *e1, *e2;
3057 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
3058 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
3059 int result;
3061 if (entry1->after_string_p != entry2->after_string_p)
3063 /* Let after-strings appear in front of before-strings if
3064 they come from different overlays. */
3065 if (EQ (entry1->overlay, entry2->overlay))
3066 result = entry1->after_string_p ? 1 : -1;
3067 else
3068 result = entry1->after_string_p ? -1 : 1;
3070 else if (entry1->after_string_p)
3071 /* After-strings sorted in order of decreasing priority. */
3072 result = entry2->priority - entry1->priority;
3073 else
3074 /* Before-strings sorted in order of increasing priority. */
3075 result = entry1->priority - entry2->priority;
3077 return result;
3081 /* Load the vector IT->overlay_strings with overlay strings from IT's
3082 current buffer position. Set IT->n_overlays to the total number of
3083 overlay strings found.
3085 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
3086 a time. On entry into load_overlay_strings,
3087 IT->current.overlay_string_index gives the number of overlay
3088 strings that have already been loaded by previous calls to this
3089 function.
3091 IT->add_overlay_start contains an additional overlay start
3092 position to consider for taking overlay strings from, if non-zero.
3093 This position comes into play when the overlay has an `invisible'
3094 property, and both before and after-strings. When we've skipped to
3095 the end of the overlay, because of its `invisible' property, we
3096 nevertheless want its before-string to appear.
3097 IT->add_overlay_start will contain the overlay start position
3098 in this case.
3100 Overlay strings are sorted so that after-string strings come in
3101 front of before-string strings. Within before and after-strings,
3102 strings are sorted by overlay priority. See also function
3103 compare_overlay_entries. */
3105 static void
3106 load_overlay_strings (it)
3107 struct it *it;
3109 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
3110 Lisp_Object ov, overlay, window, str, invisible;
3111 int start, end;
3112 int size = 20;
3113 int n = 0, i, j, invis_p;
3114 struct overlay_entry *entries
3115 = (struct overlay_entry *) alloca (size * sizeof *entries);
3116 int charpos = IT_CHARPOS (*it);
3118 /* Append the overlay string STRING of overlay OVERLAY to vector
3119 `entries' which has size `size' and currently contains `n'
3120 elements. AFTER_P non-zero means STRING is an after-string of
3121 OVERLAY. */
3122 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
3123 do \
3125 Lisp_Object priority; \
3127 if (n == size) \
3129 int new_size = 2 * size; \
3130 struct overlay_entry *old = entries; \
3131 entries = \
3132 (struct overlay_entry *) alloca (new_size \
3133 * sizeof *entries); \
3134 bcopy (old, entries, size * sizeof *entries); \
3135 size = new_size; \
3138 entries[n].string = (STRING); \
3139 entries[n].overlay = (OVERLAY); \
3140 priority = Foverlay_get ((OVERLAY), Qpriority); \
3141 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
3142 entries[n].after_string_p = (AFTER_P); \
3143 ++n; \
3145 while (0)
3147 /* Process overlay before the overlay center. */
3148 for (ov = current_buffer->overlays_before; CONSP (ov); ov = XCDR (ov))
3150 overlay = XCAR (ov);
3151 xassert (OVERLAYP (overlay));
3152 start = OVERLAY_POSITION (OVERLAY_START (overlay));
3153 end = OVERLAY_POSITION (OVERLAY_END (overlay));
3155 if (end < charpos)
3156 break;
3158 /* Skip this overlay if it doesn't start or end at IT's current
3159 position. */
3160 if (end != charpos && start != charpos)
3161 continue;
3163 /* Skip this overlay if it doesn't apply to IT->w. */
3164 window = Foverlay_get (overlay, Qwindow);
3165 if (WINDOWP (window) && XWINDOW (window) != it->w)
3166 continue;
3168 /* If the text ``under'' the overlay is invisible, both before-
3169 and after-strings from this overlay are visible; start and
3170 end position are indistinguishable. */
3171 invisible = Foverlay_get (overlay, Qinvisible);
3172 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
3174 /* If overlay has a non-empty before-string, record it. */
3175 if ((start == charpos || (end == charpos && invis_p))
3176 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
3177 && XSTRING (str)->size)
3178 RECORD_OVERLAY_STRING (overlay, str, 0);
3180 /* If overlay has a non-empty after-string, record it. */
3181 if ((end == charpos || (start == charpos && invis_p))
3182 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
3183 && XSTRING (str)->size)
3184 RECORD_OVERLAY_STRING (overlay, str, 1);
3187 /* Process overlays after the overlay center. */
3188 for (ov = current_buffer->overlays_after; CONSP (ov); ov = XCDR (ov))
3190 overlay = XCAR (ov);
3191 xassert (OVERLAYP (overlay));
3192 start = OVERLAY_POSITION (OVERLAY_START (overlay));
3193 end = OVERLAY_POSITION (OVERLAY_END (overlay));
3195 if (start > charpos)
3196 break;
3198 /* Skip this overlay if it doesn't start or end at IT's current
3199 position. */
3200 if (end != charpos && start != charpos)
3201 continue;
3203 /* Skip this overlay if it doesn't apply to IT->w. */
3204 window = Foverlay_get (overlay, Qwindow);
3205 if (WINDOWP (window) && XWINDOW (window) != it->w)
3206 continue;
3208 /* If the text ``under'' the overlay is invisible, it has a zero
3209 dimension, and both before- and after-strings apply. */
3210 invisible = Foverlay_get (overlay, Qinvisible);
3211 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
3213 /* If overlay has a non-empty before-string, record it. */
3214 if ((start == charpos || (end == charpos && invis_p))
3215 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
3216 && XSTRING (str)->size)
3217 RECORD_OVERLAY_STRING (overlay, str, 0);
3219 /* If overlay has a non-empty after-string, record it. */
3220 if ((end == charpos || (start == charpos && invis_p))
3221 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
3222 && XSTRING (str)->size)
3223 RECORD_OVERLAY_STRING (overlay, str, 1);
3226 #undef RECORD_OVERLAY_STRING
3228 /* Sort entries. */
3229 if (n > 1)
3230 qsort (entries, n, sizeof *entries, compare_overlay_entries);
3232 /* Record the total number of strings to process. */
3233 it->n_overlay_strings = n;
3235 /* IT->current.overlay_string_index is the number of overlay strings
3236 that have already been consumed by IT. Copy some of the
3237 remaining overlay strings to IT->overlay_strings. */
3238 i = 0;
3239 j = it->current.overlay_string_index;
3240 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
3241 it->overlay_strings[i++] = entries[j++].string;
3243 CHECK_IT (it);
3247 /* Get the first chunk of overlay strings at IT's current buffer
3248 position. Value is non-zero if at least one overlay string was
3249 found. */
3251 static int
3252 get_overlay_strings (it)
3253 struct it *it;
3255 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
3256 process. This fills IT->overlay_strings with strings, and sets
3257 IT->n_overlay_strings to the total number of strings to process.
3258 IT->pos.overlay_string_index has to be set temporarily to zero
3259 because load_overlay_strings needs this; it must be set to -1
3260 when no overlay strings are found because a zero value would
3261 indicate a position in the first overlay string. */
3262 it->current.overlay_string_index = 0;
3263 load_overlay_strings (it);
3265 /* If we found overlay strings, set up IT to deliver display
3266 elements from the first one. Otherwise set up IT to deliver
3267 from current_buffer. */
3268 if (it->n_overlay_strings)
3270 /* Make sure we know settings in current_buffer, so that we can
3271 restore meaningful values when we're done with the overlay
3272 strings. */
3273 compute_stop_pos (it);
3274 xassert (it->face_id >= 0);
3276 /* Save IT's settings. They are restored after all overlay
3277 strings have been processed. */
3278 xassert (it->sp == 0);
3279 push_it (it);
3281 /* Set up IT to deliver display elements from the first overlay
3282 string. */
3283 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3284 it->stop_charpos = 0;
3285 it->string = it->overlay_strings[0];
3286 it->multibyte_p = STRING_MULTIBYTE (it->string);
3287 xassert (STRINGP (it->string));
3288 it->method = next_element_from_string;
3290 else
3292 it->string = Qnil;
3293 it->current.overlay_string_index = -1;
3294 it->method = next_element_from_buffer;
3297 CHECK_IT (it);
3299 /* Value is non-zero if we found at least one overlay string. */
3300 return STRINGP (it->string);
3305 /***********************************************************************
3306 Saving and restoring state
3307 ***********************************************************************/
3309 /* Save current settings of IT on IT->stack. Called, for example,
3310 before setting up IT for an overlay string, to be able to restore
3311 IT's settings to what they were after the overlay string has been
3312 processed. */
3314 static void
3315 push_it (it)
3316 struct it *it;
3318 struct iterator_stack_entry *p;
3320 xassert (it->sp < 2);
3321 p = it->stack + it->sp;
3323 p->stop_charpos = it->stop_charpos;
3324 xassert (it->face_id >= 0);
3325 p->face_id = it->face_id;
3326 p->string = it->string;
3327 p->pos = it->current;
3328 p->end_charpos = it->end_charpos;
3329 p->string_nchars = it->string_nchars;
3330 p->area = it->area;
3331 p->multibyte_p = it->multibyte_p;
3332 p->space_width = it->space_width;
3333 p->font_height = it->font_height;
3334 p->voffset = it->voffset;
3335 p->string_from_display_prop_p = it->string_from_display_prop_p;
3336 ++it->sp;
3340 /* Restore IT's settings from IT->stack. Called, for example, when no
3341 more overlay strings must be processed, and we return to delivering
3342 display elements from a buffer, or when the end of a string from a
3343 `display' property is reached and we return to delivering display
3344 elements from an overlay string, or from a buffer. */
3346 static void
3347 pop_it (it)
3348 struct it *it;
3350 struct iterator_stack_entry *p;
3352 xassert (it->sp > 0);
3353 --it->sp;
3354 p = it->stack + it->sp;
3355 it->stop_charpos = p->stop_charpos;
3356 it->face_id = p->face_id;
3357 it->string = p->string;
3358 it->current = p->pos;
3359 it->end_charpos = p->end_charpos;
3360 it->string_nchars = p->string_nchars;
3361 it->area = p->area;
3362 it->multibyte_p = p->multibyte_p;
3363 it->space_width = p->space_width;
3364 it->font_height = p->font_height;
3365 it->voffset = p->voffset;
3366 it->string_from_display_prop_p = p->string_from_display_prop_p;
3371 /***********************************************************************
3372 Moving over lines
3373 ***********************************************************************/
3375 /* Set IT's current position to the previous line start. */
3377 static void
3378 back_to_previous_line_start (it)
3379 struct it *it;
3381 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
3382 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
3386 /* Move IT to the next line start.
3388 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
3389 we skipped over part of the text (as opposed to moving the iterator
3390 continuously over the text). Otherwise, don't change the value
3391 of *SKIPPED_P.
3393 Newlines may come from buffer text, overlay strings, or strings
3394 displayed via the `display' property. That's the reason we can't
3395 simply use find_next_newline_no_quit.
3397 Note that this function may not skip over invisible text that is so
3398 because of text properties and immediately follows a newline. If
3399 it would, function reseat_at_next_visible_line_start, when called
3400 from set_iterator_to_next, would effectively make invisible
3401 characters following a newline part of the wrong glyph row, which
3402 leads to wrong cursor motion. */
3404 static int
3405 forward_to_next_line_start (it, skipped_p)
3406 struct it *it;
3407 int *skipped_p;
3409 int old_selective, newline_found_p, n;
3410 const int MAX_NEWLINE_DISTANCE = 500;
3412 /* If already on a newline, just consume it to avoid unintended
3413 skipping over invisible text below. */
3414 if (it->what == IT_CHARACTER && it->c == '\n')
3416 set_iterator_to_next (it, 0);
3417 return 1;
3420 /* Don't handle selective display in the following. It's (a)
3421 unnecessary because it's done by the caller, and (b) leads to an
3422 infinite recursion because next_element_from_ellipsis indirectly
3423 calls this function. */
3424 old_selective = it->selective;
3425 it->selective = 0;
3427 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
3428 from buffer text. */
3429 n = newline_found_p = 0;
3430 while (n < MAX_NEWLINE_DISTANCE
3431 && get_next_display_element (it)
3432 && !newline_found_p)
3434 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
3435 set_iterator_to_next (it, 0);
3436 if (!STRINGP (it->string))
3437 ++n;
3440 /* If we didn't find a newline near enough, see if we can use a
3441 short-cut. */
3442 if (!newline_found_p && n == MAX_NEWLINE_DISTANCE)
3444 int start = IT_CHARPOS (*it);
3445 int limit = find_next_newline_no_quit (start, 1);
3446 Lisp_Object pos;
3448 xassert (!STRINGP (it->string));
3450 /* If there isn't any `display' property in sight, and no
3451 overlays, we can just use the position of the newline in
3452 buffer text. */
3453 if (it->stop_charpos >= limit
3454 || ((pos = Fnext_single_property_change (make_number (start),
3455 Qdisplay,
3456 Qnil, make_number (limit)),
3457 NILP (pos))
3458 && next_overlay_change (start) == ZV))
3460 IT_CHARPOS (*it) = limit;
3461 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
3462 *skipped_p = newline_found_p = 1;
3464 else
3466 while (get_next_display_element (it)
3467 && !newline_found_p)
3469 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
3470 set_iterator_to_next (it, 0);
3475 it->selective = old_selective;
3476 return newline_found_p;
3480 /* Set IT's current position to the previous visible line start. Skip
3481 invisible text that is so either due to text properties or due to
3482 selective display. Caution: this does not change IT->current_x and
3483 IT->hpos. */
3485 static void
3486 back_to_previous_visible_line_start (it)
3487 struct it *it;
3489 int visible_p = 0;
3491 /* Go back one newline if not on BEGV already. */
3492 if (IT_CHARPOS (*it) > BEGV)
3493 back_to_previous_line_start (it);
3495 /* Move over lines that are invisible because of selective display
3496 or text properties. */
3497 while (IT_CHARPOS (*it) > BEGV
3498 && !visible_p)
3500 visible_p = 1;
3502 /* If selective > 0, then lines indented more than that values
3503 are invisible. */
3504 if (it->selective > 0
3505 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
3506 it->selective))
3507 visible_p = 0;
3508 else
3510 Lisp_Object prop;
3512 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
3513 Qinvisible, it->window);
3514 if (TEXT_PROP_MEANS_INVISIBLE (prop))
3515 visible_p = 0;
3518 /* Back one more newline if the current one is invisible. */
3519 if (!visible_p)
3520 back_to_previous_line_start (it);
3523 xassert (IT_CHARPOS (*it) >= BEGV);
3524 xassert (IT_CHARPOS (*it) == BEGV
3525 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
3526 CHECK_IT (it);
3530 /* Reseat iterator IT at the previous visible line start. Skip
3531 invisible text that is so either due to text properties or due to
3532 selective display. At the end, update IT's overlay information,
3533 face information etc. */
3535 static void
3536 reseat_at_previous_visible_line_start (it)
3537 struct it *it;
3539 back_to_previous_visible_line_start (it);
3540 reseat (it, it->current.pos, 1);
3541 CHECK_IT (it);
3545 /* Reseat iterator IT on the next visible line start in the current
3546 buffer. ON_NEWLINE_P non-zero means position IT on the newline
3547 preceding the line start. Skip over invisible text that is so
3548 because of selective display. Compute faces, overlays etc at the
3549 new position. Note that this function does not skip over text that
3550 is invisible because of text properties. */
3552 static void
3553 reseat_at_next_visible_line_start (it, on_newline_p)
3554 struct it *it;
3555 int on_newline_p;
3557 int newline_found_p, skipped_p = 0;
3559 newline_found_p = forward_to_next_line_start (it, &skipped_p);
3561 /* Skip over lines that are invisible because they are indented
3562 more than the value of IT->selective. */
3563 if (it->selective > 0)
3564 while (IT_CHARPOS (*it) < ZV
3565 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
3566 it->selective))
3567 newline_found_p = forward_to_next_line_start (it, &skipped_p);
3569 /* Position on the newline if that's what's requested. */
3570 if (on_newline_p && newline_found_p)
3572 if (STRINGP (it->string))
3574 if (IT_STRING_CHARPOS (*it) > 0)
3576 --IT_STRING_CHARPOS (*it);
3577 --IT_STRING_BYTEPOS (*it);
3580 else if (IT_CHARPOS (*it) > BEGV)
3582 --IT_CHARPOS (*it);
3583 --IT_BYTEPOS (*it);
3584 reseat (it, it->current.pos, 0);
3587 else if (skipped_p)
3588 reseat (it, it->current.pos, 0);
3590 CHECK_IT (it);
3595 /***********************************************************************
3596 Changing an iterator's position
3597 ***********************************************************************/
3599 /* Change IT's current position to POS in current_buffer. If FORCE_P
3600 is non-zero, always check for text properties at the new position.
3601 Otherwise, text properties are only looked up if POS >=
3602 IT->check_charpos of a property. */
3604 static void
3605 reseat (it, pos, force_p)
3606 struct it *it;
3607 struct text_pos pos;
3608 int force_p;
3610 int original_pos = IT_CHARPOS (*it);
3612 reseat_1 (it, pos, 0);
3614 /* Determine where to check text properties. Avoid doing it
3615 where possible because text property lookup is very expensive. */
3616 if (force_p
3617 || CHARPOS (pos) > it->stop_charpos
3618 || CHARPOS (pos) < original_pos)
3619 handle_stop (it);
3621 CHECK_IT (it);
3625 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
3626 IT->stop_pos to POS, also. */
3628 static void
3629 reseat_1 (it, pos, set_stop_p)
3630 struct it *it;
3631 struct text_pos pos;
3632 int set_stop_p;
3634 /* Don't call this function when scanning a C string. */
3635 xassert (it->s == NULL);
3637 /* POS must be a reasonable value. */
3638 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
3640 it->current.pos = it->position = pos;
3641 XSETBUFFER (it->object, current_buffer);
3642 it->dpvec = NULL;
3643 it->current.dpvec_index = -1;
3644 it->current.overlay_string_index = -1;
3645 IT_STRING_CHARPOS (*it) = -1;
3646 IT_STRING_BYTEPOS (*it) = -1;
3647 it->string = Qnil;
3648 it->method = next_element_from_buffer;
3649 it->sp = 0;
3651 if (set_stop_p)
3652 it->stop_charpos = CHARPOS (pos);
3656 /* Set up IT for displaying a string, starting at CHARPOS in window W.
3657 If S is non-null, it is a C string to iterate over. Otherwise,
3658 STRING gives a Lisp string to iterate over.
3660 If PRECISION > 0, don't return more then PRECISION number of
3661 characters from the string.
3663 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
3664 characters have been returned. FIELD_WIDTH < 0 means an infinite
3665 field width.
3667 MULTIBYTE = 0 means disable processing of multibyte characters,
3668 MULTIBYTE > 0 means enable it,
3669 MULTIBYTE < 0 means use IT->multibyte_p.
3671 IT must be initialized via a prior call to init_iterator before
3672 calling this function. */
3674 static void
3675 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
3676 struct it *it;
3677 unsigned char *s;
3678 Lisp_Object string;
3679 int charpos;
3680 int precision, field_width, multibyte;
3682 /* No region in strings. */
3683 it->region_beg_charpos = it->region_end_charpos = -1;
3685 /* No text property checks performed by default, but see below. */
3686 it->stop_charpos = -1;
3688 /* Set iterator position and end position. */
3689 bzero (&it->current, sizeof it->current);
3690 it->current.overlay_string_index = -1;
3691 it->current.dpvec_index = -1;
3692 xassert (charpos >= 0);
3694 /* Use the setting of MULTIBYTE if specified. */
3695 if (multibyte >= 0)
3696 it->multibyte_p = multibyte > 0;
3698 if (s == NULL)
3700 xassert (STRINGP (string));
3701 it->string = string;
3702 it->s = NULL;
3703 it->end_charpos = it->string_nchars = XSTRING (string)->size;
3704 it->method = next_element_from_string;
3705 it->current.string_pos = string_pos (charpos, string);
3707 else
3709 it->s = s;
3710 it->string = Qnil;
3712 /* Note that we use IT->current.pos, not it->current.string_pos,
3713 for displaying C strings. */
3714 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
3715 if (it->multibyte_p)
3717 it->current.pos = c_string_pos (charpos, s, 1);
3718 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
3720 else
3722 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
3723 it->end_charpos = it->string_nchars = strlen (s);
3726 it->method = next_element_from_c_string;
3729 /* PRECISION > 0 means don't return more than PRECISION characters
3730 from the string. */
3731 if (precision > 0 && it->end_charpos - charpos > precision)
3732 it->end_charpos = it->string_nchars = charpos + precision;
3734 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
3735 characters have been returned. FIELD_WIDTH == 0 means don't pad,
3736 FIELD_WIDTH < 0 means infinite field width. This is useful for
3737 padding with `-' at the end of a mode line. */
3738 if (field_width < 0)
3739 field_width = INFINITY;
3740 if (field_width > it->end_charpos - charpos)
3741 it->end_charpos = charpos + field_width;
3743 /* Use the standard display table for displaying strings. */
3744 if (DISP_TABLE_P (Vstandard_display_table))
3745 it->dp = XCHAR_TABLE (Vstandard_display_table);
3747 it->stop_charpos = charpos;
3748 CHECK_IT (it);
3753 /***********************************************************************
3754 Iteration
3755 ***********************************************************************/
3757 /* Load IT's display element fields with information about the next
3758 display element from the current position of IT. Value is zero if
3759 end of buffer (or C string) is reached. */
3762 get_next_display_element (it)
3763 struct it *it;
3765 /* Non-zero means that we found an display element. Zero means that
3766 we hit the end of what we iterate over. Performance note: the
3767 function pointer `method' used here turns out to be faster than
3768 using a sequence of if-statements. */
3769 int success_p = (*it->method) (it);
3771 if (it->what == IT_CHARACTER)
3773 /* Map via display table or translate control characters.
3774 IT->c, IT->len etc. have been set to the next character by
3775 the function call above. If we have a display table, and it
3776 contains an entry for IT->c, translate it. Don't do this if
3777 IT->c itself comes from a display table, otherwise we could
3778 end up in an infinite recursion. (An alternative could be to
3779 count the recursion depth of this function and signal an
3780 error when a certain maximum depth is reached.) Is it worth
3781 it? */
3782 if (success_p && it->dpvec == NULL)
3784 Lisp_Object dv;
3786 if (it->dp
3787 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
3788 VECTORP (dv)))
3790 struct Lisp_Vector *v = XVECTOR (dv);
3792 /* Return the first character from the display table
3793 entry, if not empty. If empty, don't display the
3794 current character. */
3795 if (v->size)
3797 it->dpvec_char_len = it->len;
3798 it->dpvec = v->contents;
3799 it->dpend = v->contents + v->size;
3800 it->current.dpvec_index = 0;
3801 it->method = next_element_from_display_vector;
3804 success_p = get_next_display_element (it);
3807 /* Translate control characters into `\003' or `^C' form.
3808 Control characters coming from a display table entry are
3809 currently not translated because we use IT->dpvec to hold
3810 the translation. This could easily be changed but I
3811 don't believe that it is worth doing.
3813 Non-printable multibyte characters are also translated
3814 octal form. */
3815 else if ((it->c < ' '
3816 && (it->area != TEXT_AREA
3817 || (it->c != '\n' && it->c != '\t')))
3818 || (it->c >= 127
3819 && it->len == 1)
3820 || !CHAR_PRINTABLE_P (it->c))
3822 /* IT->c is a control character which must be displayed
3823 either as '\003' or as `^C' where the '\\' and '^'
3824 can be defined in the display table. Fill
3825 IT->ctl_chars with glyphs for what we have to
3826 display. Then, set IT->dpvec to these glyphs. */
3827 GLYPH g;
3829 if (it->c < 128 && it->ctl_arrow_p)
3831 /* Set IT->ctl_chars[0] to the glyph for `^'. */
3832 if (it->dp
3833 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
3834 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
3835 g = XINT (DISP_CTRL_GLYPH (it->dp));
3836 else
3837 g = FAST_MAKE_GLYPH ('^', 0);
3838 XSETINT (it->ctl_chars[0], g);
3840 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
3841 XSETINT (it->ctl_chars[1], g);
3843 /* Set up IT->dpvec and return first character from it. */
3844 it->dpvec_char_len = it->len;
3845 it->dpvec = it->ctl_chars;
3846 it->dpend = it->dpvec + 2;
3847 it->current.dpvec_index = 0;
3848 it->method = next_element_from_display_vector;
3849 get_next_display_element (it);
3851 else
3853 unsigned char str[MAX_MULTIBYTE_LENGTH];
3854 int len;
3855 int i;
3856 GLYPH escape_glyph;
3858 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
3859 if (it->dp
3860 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
3861 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
3862 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
3863 else
3864 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
3866 if (SINGLE_BYTE_CHAR_P (it->c))
3867 str[0] = it->c, len = 1;
3868 else
3869 len = CHAR_STRING (it->c, str);
3871 for (i = 0; i < len; i++)
3873 XSETINT (it->ctl_chars[i * 4], escape_glyph);
3874 /* Insert three more glyphs into IT->ctl_chars for
3875 the octal display of the character. */
3876 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
3877 XSETINT (it->ctl_chars[i * 4 + 1], g);
3878 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
3879 XSETINT (it->ctl_chars[i * 4 + 2], g);
3880 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
3881 XSETINT (it->ctl_chars[i * 4 + 3], g);
3884 /* Set up IT->dpvec and return the first character
3885 from it. */
3886 it->dpvec_char_len = it->len;
3887 it->dpvec = it->ctl_chars;
3888 it->dpend = it->dpvec + len * 4;
3889 it->current.dpvec_index = 0;
3890 it->method = next_element_from_display_vector;
3891 get_next_display_element (it);
3896 /* Adjust face id for a multibyte character. There are no
3897 multibyte character in unibyte text. */
3898 if (it->multibyte_p
3899 && success_p
3900 && FRAME_WINDOW_P (it->f))
3902 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3903 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
3907 /* Is this character the last one of a run of characters with
3908 box? If yes, set IT->end_of_box_run_p to 1. */
3909 if (it->face_box_p
3910 && it->s == NULL)
3912 int face_id;
3913 struct face *face;
3915 it->end_of_box_run_p
3916 = ((face_id = face_after_it_pos (it),
3917 face_id != it->face_id)
3918 && (face = FACE_FROM_ID (it->f, face_id),
3919 face->box == FACE_NO_BOX));
3922 /* Value is 0 if end of buffer or string reached. */
3923 return success_p;
3927 /* Move IT to the next display element.
3929 RESEAT_P non-zero means if called on a newline in buffer text,
3930 skip to the next visible line start.
3932 Functions get_next_display_element and set_iterator_to_next are
3933 separate because I find this arrangement easier to handle than a
3934 get_next_display_element function that also increments IT's
3935 position. The way it is we can first look at an iterator's current
3936 display element, decide whether it fits on a line, and if it does,
3937 increment the iterator position. The other way around we probably
3938 would either need a flag indicating whether the iterator has to be
3939 incremented the next time, or we would have to implement a
3940 decrement position function which would not be easy to write. */
3942 void
3943 set_iterator_to_next (it, reseat_p)
3944 struct it *it;
3945 int reseat_p;
3947 /* Reset flags indicating start and end of a sequence of characters
3948 with box. Reset them at the start of this function because
3949 moving the iterator to a new position might set them. */
3950 it->start_of_box_run_p = it->end_of_box_run_p = 0;
3952 if (it->method == next_element_from_buffer)
3954 /* The current display element of IT is a character from
3955 current_buffer. Advance in the buffer, and maybe skip over
3956 invisible lines that are so because of selective display. */
3957 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
3958 reseat_at_next_visible_line_start (it, 0);
3959 else
3961 xassert (it->len != 0);
3962 IT_BYTEPOS (*it) += it->len;
3963 IT_CHARPOS (*it) += 1;
3964 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
3967 else if (it->method == next_element_from_composition)
3969 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
3970 if (STRINGP (it->string))
3972 IT_STRING_BYTEPOS (*it) += it->len;
3973 IT_STRING_CHARPOS (*it) += it->cmp_len;
3974 it->method = next_element_from_string;
3975 goto consider_string_end;
3977 else
3979 IT_BYTEPOS (*it) += it->len;
3980 IT_CHARPOS (*it) += it->cmp_len;
3981 it->method = next_element_from_buffer;
3984 else if (it->method == next_element_from_c_string)
3986 /* Current display element of IT is from a C string. */
3987 IT_BYTEPOS (*it) += it->len;
3988 IT_CHARPOS (*it) += 1;
3990 else if (it->method == next_element_from_display_vector)
3992 /* Current display element of IT is from a display table entry.
3993 Advance in the display table definition. Reset it to null if
3994 end reached, and continue with characters from buffers/
3995 strings. */
3996 ++it->current.dpvec_index;
3998 /* Restore face of the iterator to what they were before the
3999 display vector entry (these entries may contain faces). */
4000 it->face_id = it->saved_face_id;
4002 if (it->dpvec + it->current.dpvec_index == it->dpend)
4004 if (it->s)
4005 it->method = next_element_from_c_string;
4006 else if (STRINGP (it->string))
4007 it->method = next_element_from_string;
4008 else
4009 it->method = next_element_from_buffer;
4011 it->dpvec = NULL;
4012 it->current.dpvec_index = -1;
4014 /* Skip over characters which were displayed via IT->dpvec. */
4015 if (it->dpvec_char_len < 0)
4016 reseat_at_next_visible_line_start (it, 1);
4017 else if (it->dpvec_char_len > 0)
4019 it->len = it->dpvec_char_len;
4020 set_iterator_to_next (it, reseat_p);
4024 else if (it->method == next_element_from_string)
4026 /* Current display element is a character from a Lisp string. */
4027 xassert (it->s == NULL && STRINGP (it->string));
4028 IT_STRING_BYTEPOS (*it) += it->len;
4029 IT_STRING_CHARPOS (*it) += 1;
4031 consider_string_end:
4033 if (it->current.overlay_string_index >= 0)
4035 /* IT->string is an overlay string. Advance to the
4036 next, if there is one. */
4037 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
4038 next_overlay_string (it);
4040 else
4042 /* IT->string is not an overlay string. If we reached
4043 its end, and there is something on IT->stack, proceed
4044 with what is on the stack. This can be either another
4045 string, this time an overlay string, or a buffer. */
4046 if (IT_STRING_CHARPOS (*it) == XSTRING (it->string)->size
4047 && it->sp > 0)
4049 pop_it (it);
4050 if (!STRINGP (it->string))
4051 it->method = next_element_from_buffer;
4055 else if (it->method == next_element_from_image
4056 || it->method == next_element_from_stretch)
4058 /* The position etc with which we have to proceed are on
4059 the stack. The position may be at the end of a string,
4060 if the `display' property takes up the whole string. */
4061 pop_it (it);
4062 it->image_id = 0;
4063 if (STRINGP (it->string))
4065 it->method = next_element_from_string;
4066 goto consider_string_end;
4068 else
4069 it->method = next_element_from_buffer;
4071 else
4072 /* There are no other methods defined, so this should be a bug. */
4073 abort ();
4075 xassert (it->method != next_element_from_string
4076 || (STRINGP (it->string)
4077 && IT_STRING_CHARPOS (*it) >= 0));
4081 /* Load IT's display element fields with information about the next
4082 display element which comes from a display table entry or from the
4083 result of translating a control character to one of the forms `^C'
4084 or `\003'. IT->dpvec holds the glyphs to return as characters. */
4086 static int
4087 next_element_from_display_vector (it)
4088 struct it *it;
4090 /* Precondition. */
4091 xassert (it->dpvec && it->current.dpvec_index >= 0);
4093 /* Remember the current face id in case glyphs specify faces.
4094 IT's face is restored in set_iterator_to_next. */
4095 it->saved_face_id = it->face_id;
4097 if (INTEGERP (*it->dpvec)
4098 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
4100 int lface_id;
4101 GLYPH g;
4103 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
4104 it->c = FAST_GLYPH_CHAR (g);
4105 it->len = CHAR_BYTES (it->c);
4107 /* The entry may contain a face id to use. Such a face id is
4108 the id of a Lisp face, not a realized face. A face id of
4109 zero means no face is specified. */
4110 lface_id = FAST_GLYPH_FACE (g);
4111 if (lface_id)
4113 /* The function returns -1 if lface_id is invalid. */
4114 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
4115 if (face_id >= 0)
4116 it->face_id = face_id;
4119 else
4120 /* Display table entry is invalid. Return a space. */
4121 it->c = ' ', it->len = 1;
4123 /* Don't change position and object of the iterator here. They are
4124 still the values of the character that had this display table
4125 entry or was translated, and that's what we want. */
4126 it->what = IT_CHARACTER;
4127 return 1;
4131 /* Load IT with the next display element from Lisp string IT->string.
4132 IT->current.string_pos is the current position within the string.
4133 If IT->current.overlay_string_index >= 0, the Lisp string is an
4134 overlay string. */
4136 static int
4137 next_element_from_string (it)
4138 struct it *it;
4140 struct text_pos position;
4142 xassert (STRINGP (it->string));
4143 xassert (IT_STRING_CHARPOS (*it) >= 0);
4144 position = it->current.string_pos;
4146 /* Time to check for invisible text? */
4147 if (IT_STRING_CHARPOS (*it) < it->end_charpos
4148 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
4150 handle_stop (it);
4152 /* Since a handler may have changed IT->method, we must
4153 recurse here. */
4154 return get_next_display_element (it);
4157 if (it->current.overlay_string_index >= 0)
4159 /* Get the next character from an overlay string. In overlay
4160 strings, There is no field width or padding with spaces to
4161 do. */
4162 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
4164 it->what = IT_EOB;
4165 return 0;
4167 else if (STRING_MULTIBYTE (it->string))
4169 int remaining = (STRING_BYTES (XSTRING (it->string))
4170 - IT_STRING_BYTEPOS (*it));
4171 unsigned char *s = (XSTRING (it->string)->data
4172 + IT_STRING_BYTEPOS (*it));
4173 it->c = string_char_and_length (s, remaining, &it->len);
4175 else
4177 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
4178 it->len = 1;
4181 else
4183 /* Get the next character from a Lisp string that is not an
4184 overlay string. Such strings come from the mode line, for
4185 example. We may have to pad with spaces, or truncate the
4186 string. See also next_element_from_c_string. */
4187 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
4189 it->what = IT_EOB;
4190 return 0;
4192 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
4194 /* Pad with spaces. */
4195 it->c = ' ', it->len = 1;
4196 CHARPOS (position) = BYTEPOS (position) = -1;
4198 else if (STRING_MULTIBYTE (it->string))
4200 int maxlen = (STRING_BYTES (XSTRING (it->string))
4201 - IT_STRING_BYTEPOS (*it));
4202 unsigned char *s = (XSTRING (it->string)->data
4203 + IT_STRING_BYTEPOS (*it));
4204 it->c = string_char_and_length (s, maxlen, &it->len);
4206 else
4208 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
4209 it->len = 1;
4213 /* Record what we have and where it came from. Note that we store a
4214 buffer position in IT->position although it could arguably be a
4215 string position. */
4216 it->what = IT_CHARACTER;
4217 it->object = it->string;
4218 it->position = position;
4219 return 1;
4223 /* Load IT with next display element from C string IT->s.
4224 IT->string_nchars is the maximum number of characters to return
4225 from the string. IT->end_charpos may be greater than
4226 IT->string_nchars when this function is called, in which case we
4227 may have to return padding spaces. Value is zero if end of string
4228 reached, including padding spaces. */
4230 static int
4231 next_element_from_c_string (it)
4232 struct it *it;
4234 int success_p = 1;
4236 xassert (it->s);
4237 it->what = IT_CHARACTER;
4238 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
4239 it->object = Qnil;
4241 /* IT's position can be greater IT->string_nchars in case a field
4242 width or precision has been specified when the iterator was
4243 initialized. */
4244 if (IT_CHARPOS (*it) >= it->end_charpos)
4246 /* End of the game. */
4247 it->what = IT_EOB;
4248 success_p = 0;
4250 else if (IT_CHARPOS (*it) >= it->string_nchars)
4252 /* Pad with spaces. */
4253 it->c = ' ', it->len = 1;
4254 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
4256 else if (it->multibyte_p)
4258 /* Implementation note: The calls to strlen apparently aren't a
4259 performance problem because there is no noticeable performance
4260 difference between Emacs running in unibyte or multibyte mode. */
4261 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
4262 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
4263 maxlen, &it->len);
4265 else
4266 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
4268 return success_p;
4272 /* Set up IT to return characters from an ellipsis, if appropriate.
4273 The definition of the ellipsis glyphs may come from a display table
4274 entry. This function Fills IT with the first glyph from the
4275 ellipsis if an ellipsis is to be displayed. */
4277 static int
4278 next_element_from_ellipsis (it)
4279 struct it *it;
4281 if (it->selective_display_ellipsis_p)
4283 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4285 /* Use the display table definition for `...'. Invalid glyphs
4286 will be handled by the method returning elements from dpvec. */
4287 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4288 it->dpvec_char_len = it->len;
4289 it->dpvec = v->contents;
4290 it->dpend = v->contents + v->size;
4291 it->current.dpvec_index = 0;
4292 it->method = next_element_from_display_vector;
4294 else
4296 /* Use default `...' which is stored in default_invis_vector. */
4297 it->dpvec_char_len = it->len;
4298 it->dpvec = default_invis_vector;
4299 it->dpend = default_invis_vector + 3;
4300 it->current.dpvec_index = 0;
4301 it->method = next_element_from_display_vector;
4304 else
4306 it->method = next_element_from_buffer;
4307 reseat_at_next_visible_line_start (it, 1);
4310 return get_next_display_element (it);
4314 /* Deliver an image display element. The iterator IT is already
4315 filled with image information (done in handle_display_prop). Value
4316 is always 1. */
4319 static int
4320 next_element_from_image (it)
4321 struct it *it;
4323 it->what = IT_IMAGE;
4324 return 1;
4328 /* Fill iterator IT with next display element from a stretch glyph
4329 property. IT->object is the value of the text property. Value is
4330 always 1. */
4332 static int
4333 next_element_from_stretch (it)
4334 struct it *it;
4336 it->what = IT_STRETCH;
4337 return 1;
4341 /* Load IT with the next display element from current_buffer. Value
4342 is zero if end of buffer reached. IT->stop_charpos is the next
4343 position at which to stop and check for text properties or buffer
4344 end. */
4346 static int
4347 next_element_from_buffer (it)
4348 struct it *it;
4350 int success_p = 1;
4352 /* Check this assumption, otherwise, we would never enter the
4353 if-statement, below. */
4354 xassert (IT_CHARPOS (*it) >= BEGV
4355 && IT_CHARPOS (*it) <= it->stop_charpos);
4357 if (IT_CHARPOS (*it) >= it->stop_charpos)
4359 if (IT_CHARPOS (*it) >= it->end_charpos)
4361 int overlay_strings_follow_p;
4363 /* End of the game, except when overlay strings follow that
4364 haven't been returned yet. */
4365 if (it->overlay_strings_at_end_processed_p)
4366 overlay_strings_follow_p = 0;
4367 else
4369 it->overlay_strings_at_end_processed_p = 1;
4370 overlay_strings_follow_p = get_overlay_strings (it);
4373 if (overlay_strings_follow_p)
4374 success_p = get_next_display_element (it);
4375 else
4377 it->what = IT_EOB;
4378 it->position = it->current.pos;
4379 success_p = 0;
4382 else
4384 handle_stop (it);
4385 return get_next_display_element (it);
4388 else
4390 /* No face changes, overlays etc. in sight, so just return a
4391 character from current_buffer. */
4392 unsigned char *p;
4394 /* Maybe run the redisplay end trigger hook. Performance note:
4395 This doesn't seem to cost measurable time. */
4396 if (it->redisplay_end_trigger_charpos
4397 && it->glyph_row
4398 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
4399 run_redisplay_end_trigger_hook (it);
4401 /* Get the next character, maybe multibyte. */
4402 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
4403 if (it->multibyte_p && !ASCII_BYTE_P (*p))
4405 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
4406 - IT_BYTEPOS (*it));
4407 it->c = string_char_and_length (p, maxlen, &it->len);
4409 else
4410 it->c = *p, it->len = 1;
4412 /* Record what we have and where it came from. */
4413 it->what = IT_CHARACTER;;
4414 it->object = it->w->buffer;
4415 it->position = it->current.pos;
4417 /* Normally we return the character found above, except when we
4418 really want to return an ellipsis for selective display. */
4419 if (it->selective)
4421 if (it->c == '\n')
4423 /* A value of selective > 0 means hide lines indented more
4424 than that number of columns. */
4425 if (it->selective > 0
4426 && IT_CHARPOS (*it) + 1 < ZV
4427 && indented_beyond_p (IT_CHARPOS (*it) + 1,
4428 IT_BYTEPOS (*it) + 1,
4429 it->selective))
4431 success_p = next_element_from_ellipsis (it);
4432 it->dpvec_char_len = -1;
4435 else if (it->c == '\r' && it->selective == -1)
4437 /* A value of selective == -1 means that everything from the
4438 CR to the end of the line is invisible, with maybe an
4439 ellipsis displayed for it. */
4440 success_p = next_element_from_ellipsis (it);
4441 it->dpvec_char_len = -1;
4446 /* Value is zero if end of buffer reached. */
4447 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
4448 return success_p;
4452 /* Run the redisplay end trigger hook for IT. */
4454 static void
4455 run_redisplay_end_trigger_hook (it)
4456 struct it *it;
4458 Lisp_Object args[3];
4460 /* IT->glyph_row should be non-null, i.e. we should be actually
4461 displaying something, or otherwise we should not run the hook. */
4462 xassert (it->glyph_row);
4464 /* Set up hook arguments. */
4465 args[0] = Qredisplay_end_trigger_functions;
4466 args[1] = it->window;
4467 XSETINT (args[2], it->redisplay_end_trigger_charpos);
4468 it->redisplay_end_trigger_charpos = 0;
4470 /* Since we are *trying* to run these functions, don't try to run
4471 them again, even if they get an error. */
4472 it->w->redisplay_end_trigger = Qnil;
4473 Frun_hook_with_args (3, args);
4475 /* Notice if it changed the face of the character we are on. */
4476 handle_face_prop (it);
4480 /* Deliver a composition display element. The iterator IT is already
4481 filled with composition information (done in
4482 handle_composition_prop). Value is always 1. */
4484 static int
4485 next_element_from_composition (it)
4486 struct it *it;
4488 it->what = IT_COMPOSITION;
4489 it->position = (STRINGP (it->string)
4490 ? it->current.string_pos
4491 : it->current.pos);
4492 return 1;
4497 /***********************************************************************
4498 Moving an iterator without producing glyphs
4499 ***********************************************************************/
4501 /* Move iterator IT to a specified buffer or X position within one
4502 line on the display without producing glyphs.
4504 Begin to skip at IT's current position. Skip to TO_CHARPOS or TO_X
4505 whichever is reached first.
4507 TO_CHARPOS <= 0 means no TO_CHARPOS is specified.
4509 TO_X < 0 means that no TO_X is specified. TO_X is normally a value
4510 0 <= TO_X <= IT->last_visible_x. This means in particular, that
4511 TO_X includes the amount by which a window is horizontally
4512 scrolled.
4514 Value is
4516 MOVE_POS_MATCH_OR_ZV
4517 - when TO_POS or ZV was reached.
4519 MOVE_X_REACHED
4520 -when TO_X was reached before TO_POS or ZV were reached.
4522 MOVE_LINE_CONTINUED
4523 - when we reached the end of the display area and the line must
4524 be continued.
4526 MOVE_LINE_TRUNCATED
4527 - when we reached the end of the display area and the line is
4528 truncated.
4530 MOVE_NEWLINE_OR_CR
4531 - when we stopped at a line end, i.e. a newline or a CR and selective
4532 display is on. */
4534 static enum move_it_result
4535 move_it_in_display_line_to (it, to_charpos, to_x, op)
4536 struct it *it;
4537 int to_charpos, to_x, op;
4539 enum move_it_result result = MOVE_UNDEFINED;
4540 struct glyph_row *saved_glyph_row;
4542 /* Don't produce glyphs in produce_glyphs. */
4543 saved_glyph_row = it->glyph_row;
4544 it->glyph_row = NULL;
4546 while (1)
4548 int x, i, ascent = 0, descent = 0;
4550 /* Stop when ZV or TO_CHARPOS reached. */
4551 if (!get_next_display_element (it)
4552 || ((op & MOVE_TO_POS) != 0
4553 && BUFFERP (it->object)
4554 && IT_CHARPOS (*it) >= to_charpos))
4556 result = MOVE_POS_MATCH_OR_ZV;
4557 break;
4560 /* The call to produce_glyphs will get the metrics of the
4561 display element IT is loaded with. We record in x the
4562 x-position before this display element in case it does not
4563 fit on the line. */
4564 x = it->current_x;
4566 /* Remember the line height so far in case the next element doesn't
4567 fit on the line. */
4568 if (!it->truncate_lines_p)
4570 ascent = it->max_ascent;
4571 descent = it->max_descent;
4574 PRODUCE_GLYPHS (it);
4576 if (it->area != TEXT_AREA)
4578 set_iterator_to_next (it, 1);
4579 continue;
4582 /* The number of glyphs we get back in IT->nglyphs will normally
4583 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
4584 character on a terminal frame, or (iii) a line end. For the
4585 second case, IT->nglyphs - 1 padding glyphs will be present
4586 (on X frames, there is only one glyph produced for a
4587 composite character.
4589 The behavior implemented below means, for continuation lines,
4590 that as many spaces of a TAB as fit on the current line are
4591 displayed there. For terminal frames, as many glyphs of a
4592 multi-glyph character are displayed in the current line, too.
4593 This is what the old redisplay code did, and we keep it that
4594 way. Under X, the whole shape of a complex character must
4595 fit on the line or it will be completely displayed in the
4596 next line.
4598 Note that both for tabs and padding glyphs, all glyphs have
4599 the same width. */
4600 if (it->nglyphs)
4602 /* More than one glyph or glyph doesn't fit on line. All
4603 glyphs have the same width. */
4604 int single_glyph_width = it->pixel_width / it->nglyphs;
4605 int new_x;
4607 for (i = 0; i < it->nglyphs; ++i, x = new_x)
4609 new_x = x + single_glyph_width;
4611 /* We want to leave anything reaching TO_X to the caller. */
4612 if ((op & MOVE_TO_X) && new_x > to_x)
4614 it->current_x = x;
4615 result = MOVE_X_REACHED;
4616 break;
4618 else if (/* Lines are continued. */
4619 !it->truncate_lines_p
4620 && (/* And glyph doesn't fit on the line. */
4621 new_x > it->last_visible_x
4622 /* Or it fits exactly and we're on a window
4623 system frame. */
4624 || (new_x == it->last_visible_x
4625 && FRAME_WINDOW_P (it->f))))
4627 if (/* IT->hpos == 0 means the very first glyph
4628 doesn't fit on the line, e.g. a wide image. */
4629 it->hpos == 0
4630 || (new_x == it->last_visible_x
4631 && FRAME_WINDOW_P (it->f)))
4633 ++it->hpos;
4634 it->current_x = new_x;
4635 if (i == it->nglyphs - 1)
4636 set_iterator_to_next (it, 1);
4638 else
4640 it->current_x = x;
4641 it->max_ascent = ascent;
4642 it->max_descent = descent;
4645 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
4646 IT_CHARPOS (*it)));
4647 result = MOVE_LINE_CONTINUED;
4648 break;
4650 else if (new_x > it->first_visible_x)
4652 /* Glyph is visible. Increment number of glyphs that
4653 would be displayed. */
4654 ++it->hpos;
4656 else
4658 /* Glyph is completely off the left margin of the display
4659 area. Nothing to do. */
4663 if (result != MOVE_UNDEFINED)
4664 break;
4666 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
4668 /* Stop when TO_X specified and reached. This check is
4669 necessary here because of lines consisting of a line end,
4670 only. The line end will not produce any glyphs and we
4671 would never get MOVE_X_REACHED. */
4672 xassert (it->nglyphs == 0);
4673 result = MOVE_X_REACHED;
4674 break;
4677 /* Is this a line end? If yes, we're done. */
4678 if (ITERATOR_AT_END_OF_LINE_P (it))
4680 result = MOVE_NEWLINE_OR_CR;
4681 break;
4684 /* The current display element has been consumed. Advance
4685 to the next. */
4686 set_iterator_to_next (it, 1);
4688 /* Stop if lines are truncated and IT's current x-position is
4689 past the right edge of the window now. */
4690 if (it->truncate_lines_p
4691 && it->current_x >= it->last_visible_x)
4693 result = MOVE_LINE_TRUNCATED;
4694 break;
4698 /* Restore the iterator settings altered at the beginning of this
4699 function. */
4700 it->glyph_row = saved_glyph_row;
4701 return result;
4705 /* Move IT forward to a specified buffer position TO_CHARPOS, TO_X,
4706 TO_Y, TO_VPOS. OP is a bit-mask that specifies where to stop. See
4707 the description of enum move_operation_enum.
4709 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
4710 screen line, this function will set IT to the next position >
4711 TO_CHARPOS. */
4713 void
4714 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
4715 struct it *it;
4716 int to_charpos, to_x, to_y, to_vpos;
4717 int op;
4719 enum move_it_result skip, skip2 = MOVE_X_REACHED;
4720 int line_height;
4721 int reached = 0;
4723 for (;;)
4725 if (op & MOVE_TO_VPOS)
4727 /* If no TO_CHARPOS and no TO_X specified, stop at the
4728 start of the line TO_VPOS. */
4729 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
4731 if (it->vpos == to_vpos)
4733 reached = 1;
4734 break;
4736 else
4737 skip = move_it_in_display_line_to (it, -1, -1, 0);
4739 else
4741 /* TO_VPOS >= 0 means stop at TO_X in the line at
4742 TO_VPOS, or at TO_POS, whichever comes first. */
4743 if (it->vpos == to_vpos)
4745 reached = 2;
4746 break;
4749 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
4751 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
4753 reached = 3;
4754 break;
4756 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
4758 /* We have reached TO_X but not in the line we want. */
4759 skip = move_it_in_display_line_to (it, to_charpos,
4760 -1, MOVE_TO_POS);
4761 if (skip == MOVE_POS_MATCH_OR_ZV)
4763 reached = 4;
4764 break;
4769 else if (op & MOVE_TO_Y)
4771 struct it it_backup;
4773 /* TO_Y specified means stop at TO_X in the line containing
4774 TO_Y---or at TO_CHARPOS if this is reached first. The
4775 problem is that we can't really tell whether the line
4776 contains TO_Y before we have completely scanned it, and
4777 this may skip past TO_X. What we do is to first scan to
4778 TO_X.
4780 If TO_X is not specified, use a TO_X of zero. The reason
4781 is to make the outcome of this function more predictable.
4782 If we didn't use TO_X == 0, we would stop at the end of
4783 the line which is probably not what a caller would expect
4784 to happen. */
4785 skip = move_it_in_display_line_to (it, to_charpos,
4786 ((op & MOVE_TO_X)
4787 ? to_x : 0),
4788 (MOVE_TO_X
4789 | (op & MOVE_TO_POS)));
4791 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
4792 if (skip == MOVE_POS_MATCH_OR_ZV)
4794 reached = 5;
4795 break;
4798 /* If TO_X was reached, we would like to know whether TO_Y
4799 is in the line. This can only be said if we know the
4800 total line height which requires us to scan the rest of
4801 the line. */
4802 if (skip == MOVE_X_REACHED)
4804 it_backup = *it;
4805 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
4806 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
4807 op & MOVE_TO_POS);
4808 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
4811 /* Now, decide whether TO_Y is in this line. */
4812 line_height = it->max_ascent + it->max_descent;
4813 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
4815 if (to_y >= it->current_y
4816 && to_y < it->current_y + line_height)
4818 if (skip == MOVE_X_REACHED)
4819 /* If TO_Y is in this line and TO_X was reached above,
4820 we scanned too far. We have to restore IT's settings
4821 to the ones before skipping. */
4822 *it = it_backup;
4823 reached = 6;
4825 else if (skip == MOVE_X_REACHED)
4827 skip = skip2;
4828 if (skip == MOVE_POS_MATCH_OR_ZV)
4829 reached = 7;
4832 if (reached)
4833 break;
4835 else
4836 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
4838 switch (skip)
4840 case MOVE_POS_MATCH_OR_ZV:
4841 reached = 8;
4842 goto out;
4844 case MOVE_NEWLINE_OR_CR:
4845 set_iterator_to_next (it, 1);
4846 it->continuation_lines_width = 0;
4847 break;
4849 case MOVE_LINE_TRUNCATED:
4850 it->continuation_lines_width = 0;
4851 reseat_at_next_visible_line_start (it, 0);
4852 if ((op & MOVE_TO_POS) != 0
4853 && IT_CHARPOS (*it) > to_charpos)
4855 reached = 9;
4856 goto out;
4858 break;
4860 case MOVE_LINE_CONTINUED:
4861 it->continuation_lines_width += it->current_x;
4862 break;
4864 default:
4865 abort ();
4868 /* Reset/increment for the next run. */
4869 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
4870 it->current_x = it->hpos = 0;
4871 it->current_y += it->max_ascent + it->max_descent;
4872 ++it->vpos;
4873 last_height = it->max_ascent + it->max_descent;
4874 last_max_ascent = it->max_ascent;
4875 it->max_ascent = it->max_descent = 0;
4878 out:
4880 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
4884 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
4886 If DY > 0, move IT backward at least that many pixels. DY = 0
4887 means move IT backward to the preceding line start or BEGV. This
4888 function may move over more than DY pixels if IT->current_y - DY
4889 ends up in the middle of a line; in this case IT->current_y will be
4890 set to the top of the line moved to. */
4892 void
4893 move_it_vertically_backward (it, dy)
4894 struct it *it;
4895 int dy;
4897 int nlines, h, line_height;
4898 struct it it2;
4899 int start_pos = IT_CHARPOS (*it);
4901 xassert (dy >= 0);
4903 /* Estimate how many newlines we must move back. */
4904 nlines = max (1, dy / CANON_Y_UNIT (it->f));
4906 /* Set the iterator's position that many lines back. */
4907 while (nlines-- && IT_CHARPOS (*it) > BEGV)
4908 back_to_previous_visible_line_start (it);
4910 /* Reseat the iterator here. When moving backward, we don't want
4911 reseat to skip forward over invisible text, set up the iterator
4912 to deliver from overlay strings at the new position etc. So,
4913 use reseat_1 here. */
4914 reseat_1 (it, it->current.pos, 1);
4916 /* We are now surely at a line start. */
4917 it->current_x = it->hpos = 0;
4919 /* Move forward and see what y-distance we moved. First move to the
4920 start of the next line so that we get its height. We need this
4921 height to be able to tell whether we reached the specified
4922 y-distance. */
4923 it2 = *it;
4924 it2.max_ascent = it2.max_descent = 0;
4925 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
4926 MOVE_TO_POS | MOVE_TO_VPOS);
4927 xassert (IT_CHARPOS (*it) >= BEGV);
4928 line_height = it2.max_ascent + it2.max_descent;
4930 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
4931 xassert (IT_CHARPOS (*it) >= BEGV);
4932 h = it2.current_y - it->current_y;
4933 nlines = it2.vpos - it->vpos;
4935 /* Correct IT's y and vpos position. */
4936 it->vpos -= nlines;
4937 it->current_y -= h;
4939 if (dy == 0)
4941 /* DY == 0 means move to the start of the screen line. The
4942 value of nlines is > 0 if continuation lines were involved. */
4943 if (nlines > 0)
4944 move_it_by_lines (it, nlines, 1);
4945 xassert (IT_CHARPOS (*it) <= start_pos);
4947 else if (nlines)
4949 /* The y-position we try to reach. Note that h has been
4950 subtracted in front of the if-statement. */
4951 int target_y = it->current_y + h - dy;
4953 /* If we did not reach target_y, try to move further backward if
4954 we can. If we moved too far backward, try to move forward. */
4955 if (target_y < it->current_y
4956 && IT_CHARPOS (*it) > BEGV)
4958 move_it_vertically (it, target_y - it->current_y);
4959 xassert (IT_CHARPOS (*it) >= BEGV);
4961 else if (target_y >= it->current_y + line_height
4962 && IT_CHARPOS (*it) < ZV)
4964 move_it_vertically (it, target_y - (it->current_y + line_height));
4965 xassert (IT_CHARPOS (*it) >= BEGV);
4971 /* Move IT by a specified amount of pixel lines DY. DY negative means
4972 move backwards. DY = 0 means move to start of screen line. At the
4973 end, IT will be on the start of a screen line. */
4975 void
4976 move_it_vertically (it, dy)
4977 struct it *it;
4978 int dy;
4980 if (dy <= 0)
4981 move_it_vertically_backward (it, -dy);
4982 else if (dy > 0)
4984 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
4985 move_it_to (it, ZV, -1, it->current_y + dy, -1,
4986 MOVE_TO_POS | MOVE_TO_Y);
4987 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
4989 /* If buffer ends in ZV without a newline, move to the start of
4990 the line to satisfy the post-condition. */
4991 if (IT_CHARPOS (*it) == ZV
4992 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
4993 move_it_by_lines (it, 0, 0);
4998 /* Return non-zero if some text between buffer positions START_CHARPOS
4999 and END_CHARPOS is invisible. IT->window is the window for text
5000 property lookup. */
5002 static int
5003 invisible_text_between_p (it, start_charpos, end_charpos)
5004 struct it *it;
5005 int start_charpos, end_charpos;
5007 Lisp_Object prop, limit;
5008 int invisible_found_p;
5010 xassert (it != NULL && start_charpos <= end_charpos);
5012 /* Is text at START invisible? */
5013 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
5014 it->window);
5015 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5016 invisible_found_p = 1;
5017 else
5019 limit = Fnext_single_char_property_change (make_number (start_charpos),
5020 Qinvisible, Qnil,
5021 make_number (end_charpos));
5022 invisible_found_p = XFASTINT (limit) < end_charpos;
5025 return invisible_found_p;
5029 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
5030 negative means move up. DVPOS == 0 means move to the start of the
5031 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
5032 NEED_Y_P is zero, IT->current_y will be left unchanged.
5034 Further optimization ideas: If we would know that IT->f doesn't use
5035 a face with proportional font, we could be faster for
5036 truncate-lines nil. */
5038 void
5039 move_it_by_lines (it, dvpos, need_y_p)
5040 struct it *it;
5041 int dvpos, need_y_p;
5043 struct position pos;
5045 if (!FRAME_WINDOW_P (it->f))
5047 struct text_pos textpos;
5049 /* We can use vmotion on frames without proportional fonts. */
5050 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
5051 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
5052 reseat (it, textpos, 1);
5053 it->vpos += pos.vpos;
5054 it->current_y += pos.vpos;
5056 else if (dvpos == 0)
5058 /* DVPOS == 0 means move to the start of the screen line. */
5059 move_it_vertically_backward (it, 0);
5060 xassert (it->current_x == 0 && it->hpos == 0);
5062 else if (dvpos > 0)
5064 /* If there are no continuation lines, and if there is no
5065 selective display, try the simple method of moving forward
5066 DVPOS newlines, then see where we are. */
5067 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
5069 int shortage = 0, charpos;
5071 if (FETCH_BYTE (IT_BYTEPOS (*it) == '\n'))
5072 charpos = IT_CHARPOS (*it) + 1;
5073 else
5074 charpos = scan_buffer ('\n', IT_CHARPOS (*it), 0, dvpos,
5075 &shortage, 0);
5077 if (!invisible_text_between_p (it, IT_CHARPOS (*it), charpos))
5079 struct text_pos pos;
5080 CHARPOS (pos) = charpos;
5081 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
5082 reseat (it, pos, 1);
5083 it->vpos += dvpos - shortage;
5084 it->hpos = it->current_x = 0;
5085 return;
5089 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
5091 else
5093 struct it it2;
5094 int start_charpos, i;
5096 /* If there are no continuation lines, and if there is no
5097 selective display, try the simple method of moving backward
5098 -DVPOS newlines. */
5099 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
5101 int shortage;
5102 int charpos = IT_CHARPOS (*it);
5103 int bytepos = IT_BYTEPOS (*it);
5105 /* If in the middle of a line, go to its start. */
5106 if (charpos > BEGV && FETCH_BYTE (bytepos - 1) != '\n')
5108 charpos = find_next_newline_no_quit (charpos, -1);
5109 bytepos = CHAR_TO_BYTE (charpos);
5112 if (charpos == BEGV)
5114 struct text_pos pos;
5115 CHARPOS (pos) = charpos;
5116 BYTEPOS (pos) = bytepos;
5117 reseat (it, pos, 1);
5118 it->hpos = it->current_x = 0;
5119 return;
5121 else
5123 charpos = scan_buffer ('\n', charpos - 1, 0, dvpos, &shortage, 0);
5124 if (!invisible_text_between_p (it, charpos, IT_CHARPOS (*it)))
5126 struct text_pos pos;
5127 CHARPOS (pos) = charpos;
5128 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
5129 reseat (it, pos, 1);
5130 it->vpos += dvpos + (shortage ? shortage - 1 : 0);
5131 it->hpos = it->current_x = 0;
5132 return;
5137 /* Go back -DVPOS visible lines and reseat the iterator there. */
5138 start_charpos = IT_CHARPOS (*it);
5139 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
5140 back_to_previous_visible_line_start (it);
5141 reseat (it, it->current.pos, 1);
5142 it->current_x = it->hpos = 0;
5144 /* Above call may have moved too far if continuation lines
5145 are involved. Scan forward and see if it did. */
5146 it2 = *it;
5147 it2.vpos = it2.current_y = 0;
5148 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
5149 it->vpos -= it2.vpos;
5150 it->current_y -= it2.current_y;
5151 it->current_x = it->hpos = 0;
5153 /* If we moved too far, move IT some lines forward. */
5154 if (it2.vpos > -dvpos)
5156 int delta = it2.vpos + dvpos;
5157 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
5164 /***********************************************************************
5165 Messages
5166 ***********************************************************************/
5169 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
5170 to *Messages*. */
5172 void
5173 add_to_log (format, arg1, arg2)
5174 char *format;
5175 Lisp_Object arg1, arg2;
5177 Lisp_Object args[3];
5178 Lisp_Object msg, fmt;
5179 char *buffer;
5180 int len;
5181 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
5183 fmt = msg = Qnil;
5184 GCPRO4 (fmt, msg, arg1, arg2);
5186 args[0] = fmt = build_string (format);
5187 args[1] = arg1;
5188 args[2] = arg2;
5189 msg = Fformat (3, args);
5191 len = STRING_BYTES (XSTRING (msg)) + 1;
5192 buffer = (char *) alloca (len);
5193 strcpy (buffer, XSTRING (msg)->data);
5195 message_dolog (buffer, len - 1, 1, 0);
5196 UNGCPRO;
5200 /* Output a newline in the *Messages* buffer if "needs" one. */
5202 void
5203 message_log_maybe_newline ()
5205 if (message_log_need_newline)
5206 message_dolog ("", 0, 1, 0);
5210 /* Add a string M of length LEN to the message log, optionally
5211 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
5212 nonzero, means interpret the contents of M as multibyte. This
5213 function calls low-level routines in order to bypass text property
5214 hooks, etc. which might not be safe to run. */
5216 void
5217 message_dolog (m, len, nlflag, multibyte)
5218 char *m;
5219 int len, nlflag, multibyte;
5221 if (!NILP (Vmessage_log_max))
5223 struct buffer *oldbuf;
5224 Lisp_Object oldpoint, oldbegv, oldzv;
5225 int old_windows_or_buffers_changed = windows_or_buffers_changed;
5226 int point_at_end = 0;
5227 int zv_at_end = 0;
5228 Lisp_Object old_deactivate_mark, tem;
5229 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
5231 old_deactivate_mark = Vdeactivate_mark;
5232 oldbuf = current_buffer;
5233 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
5234 current_buffer->undo_list = Qt;
5236 oldpoint = Fpoint_marker ();
5237 oldbegv = Fpoint_min_marker ();
5238 oldzv = Fpoint_max_marker ();
5239 GCPRO4 (oldpoint, oldbegv, oldzv, old_deactivate_mark);
5241 if (PT == Z)
5242 point_at_end = 1;
5243 if (ZV == Z)
5244 zv_at_end = 1;
5246 BEGV = BEG;
5247 BEGV_BYTE = BEG_BYTE;
5248 ZV = Z;
5249 ZV_BYTE = Z_BYTE;
5250 TEMP_SET_PT_BOTH (Z, Z_BYTE);
5252 /* Insert the string--maybe converting multibyte to single byte
5253 or vice versa, so that all the text fits the buffer. */
5254 if (multibyte
5255 && NILP (current_buffer->enable_multibyte_characters))
5257 int i, c, nbytes;
5258 unsigned char work[1];
5260 /* Convert a multibyte string to single-byte
5261 for the *Message* buffer. */
5262 for (i = 0; i < len; i += nbytes)
5264 c = string_char_and_length (m + i, len - i, &nbytes);
5265 work[0] = (SINGLE_BYTE_CHAR_P (c)
5267 : multibyte_char_to_unibyte (c, Qnil));
5268 insert_1_both (work, 1, 1, 1, 0, 0);
5271 else if (! multibyte
5272 && ! NILP (current_buffer->enable_multibyte_characters))
5274 int i, c, nbytes;
5275 unsigned char *msg = (unsigned char *) m;
5276 unsigned char str[MAX_MULTIBYTE_LENGTH];
5277 /* Convert a single-byte string to multibyte
5278 for the *Message* buffer. */
5279 for (i = 0; i < len; i++)
5281 c = unibyte_char_to_multibyte (msg[i]);
5282 nbytes = CHAR_STRING (c, str);
5283 insert_1_both (str, 1, nbytes, 1, 0, 0);
5286 else if (len)
5287 insert_1 (m, len, 1, 0, 0);
5289 if (nlflag)
5291 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
5292 insert_1 ("\n", 1, 1, 0, 0);
5294 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
5295 this_bol = PT;
5296 this_bol_byte = PT_BYTE;
5298 if (this_bol > BEG)
5300 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
5301 prev_bol = PT;
5302 prev_bol_byte = PT_BYTE;
5304 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
5305 this_bol, this_bol_byte);
5306 if (dup)
5308 del_range_both (prev_bol, prev_bol_byte,
5309 this_bol, this_bol_byte, 0);
5310 if (dup > 1)
5312 char dupstr[40];
5313 int duplen;
5315 /* If you change this format, don't forget to also
5316 change message_log_check_duplicate. */
5317 sprintf (dupstr, " [%d times]", dup);
5318 duplen = strlen (dupstr);
5319 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
5320 insert_1 (dupstr, duplen, 1, 0, 1);
5325 if (NATNUMP (Vmessage_log_max))
5327 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
5328 -XFASTINT (Vmessage_log_max) - 1, 0);
5329 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
5332 BEGV = XMARKER (oldbegv)->charpos;
5333 BEGV_BYTE = marker_byte_position (oldbegv);
5335 if (zv_at_end)
5337 ZV = Z;
5338 ZV_BYTE = Z_BYTE;
5340 else
5342 ZV = XMARKER (oldzv)->charpos;
5343 ZV_BYTE = marker_byte_position (oldzv);
5346 if (point_at_end)
5347 TEMP_SET_PT_BOTH (Z, Z_BYTE);
5348 else
5349 /* We can't do Fgoto_char (oldpoint) because it will run some
5350 Lisp code. */
5351 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
5352 XMARKER (oldpoint)->bytepos);
5354 UNGCPRO;
5355 free_marker (oldpoint);
5356 free_marker (oldbegv);
5357 free_marker (oldzv);
5359 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
5360 set_buffer_internal (oldbuf);
5361 if (NILP (tem))
5362 windows_or_buffers_changed = old_windows_or_buffers_changed;
5363 message_log_need_newline = !nlflag;
5364 Vdeactivate_mark = old_deactivate_mark;
5369 /* We are at the end of the buffer after just having inserted a newline.
5370 (Note: We depend on the fact we won't be crossing the gap.)
5371 Check to see if the most recent message looks a lot like the previous one.
5372 Return 0 if different, 1 if the new one should just replace it, or a
5373 value N > 1 if we should also append " [N times]". */
5375 static int
5376 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
5377 int prev_bol, this_bol;
5378 int prev_bol_byte, this_bol_byte;
5380 int i;
5381 int len = Z_BYTE - 1 - this_bol_byte;
5382 int seen_dots = 0;
5383 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
5384 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
5386 for (i = 0; i < len; i++)
5388 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
5389 seen_dots = 1;
5390 if (p1[i] != p2[i])
5391 return seen_dots;
5393 p1 += len;
5394 if (*p1 == '\n')
5395 return 2;
5396 if (*p1++ == ' ' && *p1++ == '[')
5398 int n = 0;
5399 while (*p1 >= '0' && *p1 <= '9')
5400 n = n * 10 + *p1++ - '0';
5401 if (strncmp (p1, " times]\n", 8) == 0)
5402 return n+1;
5404 return 0;
5408 /* Display an echo area message M with a specified length of LEN
5409 chars. The string may include null characters. If M is 0, clear
5410 out any existing message, and let the mini-buffer text show through.
5412 The buffer M must continue to exist until after the echo area gets
5413 cleared or some other message gets displayed there. This means do
5414 not pass text that is stored in a Lisp string; do not pass text in
5415 a buffer that was alloca'd. */
5417 void
5418 message2 (m, len, multibyte)
5419 char *m;
5420 int len;
5421 int multibyte;
5423 /* First flush out any partial line written with print. */
5424 message_log_maybe_newline ();
5425 if (m)
5426 message_dolog (m, len, 1, multibyte);
5427 message2_nolog (m, len, multibyte);
5431 /* The non-logging counterpart of message2. */
5433 void
5434 message2_nolog (m, len, multibyte)
5435 char *m;
5436 int len;
5438 struct frame *sf = SELECTED_FRAME ();
5439 message_enable_multibyte = multibyte;
5441 if (noninteractive)
5443 if (noninteractive_need_newline)
5444 putc ('\n', stderr);
5445 noninteractive_need_newline = 0;
5446 if (m)
5447 fwrite (m, len, 1, stderr);
5448 if (cursor_in_echo_area == 0)
5449 fprintf (stderr, "\n");
5450 fflush (stderr);
5452 /* A null message buffer means that the frame hasn't really been
5453 initialized yet. Error messages get reported properly by
5454 cmd_error, so this must be just an informative message; toss it. */
5455 else if (INTERACTIVE
5456 && sf->glyphs_initialized_p
5457 && FRAME_MESSAGE_BUF (sf))
5459 Lisp_Object mini_window;
5460 struct frame *f;
5462 /* Get the frame containing the mini-buffer
5463 that the selected frame is using. */
5464 mini_window = FRAME_MINIBUF_WINDOW (sf);
5465 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5467 FRAME_SAMPLE_VISIBILITY (f);
5468 if (FRAME_VISIBLE_P (sf)
5469 && ! FRAME_VISIBLE_P (f))
5470 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
5472 if (m)
5474 set_message (m, Qnil, len, multibyte);
5475 if (minibuffer_auto_raise)
5476 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
5478 else
5479 clear_message (1, 1);
5481 do_pending_window_change (0);
5482 echo_area_display (1);
5483 do_pending_window_change (0);
5484 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
5485 (*frame_up_to_date_hook) (f);
5490 /* Display an echo area message M with a specified length of NBYTES
5491 bytes. The string may include null characters. If M is not a
5492 string, clear out any existing message, and let the mini-buffer
5493 text show through. */
5495 void
5496 message3 (m, nbytes, multibyte)
5497 Lisp_Object m;
5498 int nbytes;
5499 int multibyte;
5501 struct gcpro gcpro1;
5503 GCPRO1 (m);
5505 /* First flush out any partial line written with print. */
5506 message_log_maybe_newline ();
5507 if (STRINGP (m))
5508 message_dolog (XSTRING (m)->data, nbytes, 1, multibyte);
5509 message3_nolog (m, nbytes, multibyte);
5511 UNGCPRO;
5515 /* The non-logging version of message3. */
5517 void
5518 message3_nolog (m, nbytes, multibyte)
5519 Lisp_Object m;
5520 int nbytes, multibyte;
5522 struct frame *sf = SELECTED_FRAME ();
5523 message_enable_multibyte = multibyte;
5525 if (noninteractive)
5527 if (noninteractive_need_newline)
5528 putc ('\n', stderr);
5529 noninteractive_need_newline = 0;
5530 if (STRINGP (m))
5531 fwrite (XSTRING (m)->data, nbytes, 1, stderr);
5532 if (cursor_in_echo_area == 0)
5533 fprintf (stderr, "\n");
5534 fflush (stderr);
5536 /* A null message buffer means that the frame hasn't really been
5537 initialized yet. Error messages get reported properly by
5538 cmd_error, so this must be just an informative message; toss it. */
5539 else if (INTERACTIVE
5540 && sf->glyphs_initialized_p
5541 && FRAME_MESSAGE_BUF (sf))
5543 Lisp_Object mini_window;
5544 Lisp_Object frame;
5545 struct frame *f;
5547 /* Get the frame containing the mini-buffer
5548 that the selected frame is using. */
5549 mini_window = FRAME_MINIBUF_WINDOW (sf);
5550 frame = XWINDOW (mini_window)->frame;
5551 f = XFRAME (frame);
5553 FRAME_SAMPLE_VISIBILITY (f);
5554 if (FRAME_VISIBLE_P (sf)
5555 && !FRAME_VISIBLE_P (f))
5556 Fmake_frame_visible (frame);
5558 if (STRINGP (m) && XSTRING (m)->size)
5560 set_message (NULL, m, nbytes, multibyte);
5561 if (minibuffer_auto_raise)
5562 Fraise_frame (frame);
5564 else
5565 clear_message (1, 1);
5567 do_pending_window_change (0);
5568 echo_area_display (1);
5569 do_pending_window_change (0);
5570 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
5571 (*frame_up_to_date_hook) (f);
5576 /* Display a null-terminated echo area message M. If M is 0, clear
5577 out any existing message, and let the mini-buffer text show through.
5579 The buffer M must continue to exist until after the echo area gets
5580 cleared or some other message gets displayed there. Do not pass
5581 text that is stored in a Lisp string. Do not pass text in a buffer
5582 that was alloca'd. */
5584 void
5585 message1 (m)
5586 char *m;
5588 message2 (m, (m ? strlen (m) : 0), 0);
5592 /* The non-logging counterpart of message1. */
5594 void
5595 message1_nolog (m)
5596 char *m;
5598 message2_nolog (m, (m ? strlen (m) : 0), 0);
5601 /* Display a message M which contains a single %s
5602 which gets replaced with STRING. */
5604 void
5605 message_with_string (m, string, log)
5606 char *m;
5607 Lisp_Object string;
5608 int log;
5610 if (noninteractive)
5612 if (m)
5614 if (noninteractive_need_newline)
5615 putc ('\n', stderr);
5616 noninteractive_need_newline = 0;
5617 fprintf (stderr, m, XSTRING (string)->data);
5618 if (cursor_in_echo_area == 0)
5619 fprintf (stderr, "\n");
5620 fflush (stderr);
5623 else if (INTERACTIVE)
5625 /* The frame whose minibuffer we're going to display the message on.
5626 It may be larger than the selected frame, so we need
5627 to use its buffer, not the selected frame's buffer. */
5628 Lisp_Object mini_window;
5629 struct frame *f, *sf = SELECTED_FRAME ();
5631 /* Get the frame containing the minibuffer
5632 that the selected frame is using. */
5633 mini_window = FRAME_MINIBUF_WINDOW (sf);
5634 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5636 /* A null message buffer means that the frame hasn't really been
5637 initialized yet. Error messages get reported properly by
5638 cmd_error, so this must be just an informative message; toss it. */
5639 if (FRAME_MESSAGE_BUF (f))
5641 int len;
5642 char *a[1];
5643 a[0] = (char *) XSTRING (string)->data;
5645 len = doprnt (FRAME_MESSAGE_BUF (f),
5646 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5648 if (log)
5649 message2 (FRAME_MESSAGE_BUF (f), len,
5650 STRING_MULTIBYTE (string));
5651 else
5652 message2_nolog (FRAME_MESSAGE_BUF (f), len,
5653 STRING_MULTIBYTE (string));
5655 /* Print should start at the beginning of the message
5656 buffer next time. */
5657 message_buf_print = 0;
5663 /* Dump an informative message to the minibuf. If M is 0, clear out
5664 any existing message, and let the mini-buffer text show through. */
5666 /* VARARGS 1 */
5667 void
5668 message (m, a1, a2, a3)
5669 char *m;
5670 EMACS_INT a1, a2, a3;
5672 if (noninteractive)
5674 if (m)
5676 if (noninteractive_need_newline)
5677 putc ('\n', stderr);
5678 noninteractive_need_newline = 0;
5679 fprintf (stderr, m, a1, a2, a3);
5680 if (cursor_in_echo_area == 0)
5681 fprintf (stderr, "\n");
5682 fflush (stderr);
5685 else if (INTERACTIVE)
5687 /* The frame whose mini-buffer we're going to display the message
5688 on. It may be larger than the selected frame, so we need to
5689 use its buffer, not the selected frame's buffer. */
5690 Lisp_Object mini_window;
5691 struct frame *f, *sf = SELECTED_FRAME ();
5693 /* Get the frame containing the mini-buffer
5694 that the selected frame is using. */
5695 mini_window = FRAME_MINIBUF_WINDOW (sf);
5696 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5698 /* A null message buffer means that the frame hasn't really been
5699 initialized yet. Error messages get reported properly by
5700 cmd_error, so this must be just an informative message; toss
5701 it. */
5702 if (FRAME_MESSAGE_BUF (f))
5704 if (m)
5706 int len;
5707 #ifdef NO_ARG_ARRAY
5708 char *a[3];
5709 a[0] = (char *) a1;
5710 a[1] = (char *) a2;
5711 a[2] = (char *) a3;
5713 len = doprnt (FRAME_MESSAGE_BUF (f),
5714 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5715 #else
5716 len = doprnt (FRAME_MESSAGE_BUF (f),
5717 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
5718 (char **) &a1);
5719 #endif /* NO_ARG_ARRAY */
5721 message2 (FRAME_MESSAGE_BUF (f), len, 0);
5723 else
5724 message1 (0);
5726 /* Print should start at the beginning of the message
5727 buffer next time. */
5728 message_buf_print = 0;
5734 /* The non-logging version of message. */
5736 void
5737 message_nolog (m, a1, a2, a3)
5738 char *m;
5739 EMACS_INT a1, a2, a3;
5741 Lisp_Object old_log_max;
5742 old_log_max = Vmessage_log_max;
5743 Vmessage_log_max = Qnil;
5744 message (m, a1, a2, a3);
5745 Vmessage_log_max = old_log_max;
5749 /* Display the current message in the current mini-buffer. This is
5750 only called from error handlers in process.c, and is not time
5751 critical. */
5753 void
5754 update_echo_area ()
5756 if (!NILP (echo_area_buffer[0]))
5758 Lisp_Object string;
5759 string = Fcurrent_message ();
5760 message3 (string, XSTRING (string)->size,
5761 !NILP (current_buffer->enable_multibyte_characters));
5766 /* Make sure echo area buffers in echo_buffers[] are life. If they
5767 aren't, make new ones. */
5769 static void
5770 ensure_echo_area_buffers ()
5772 int i;
5774 for (i = 0; i < 2; ++i)
5775 if (!BUFFERP (echo_buffer[i])
5776 || NILP (XBUFFER (echo_buffer[i])->name))
5778 char name[30];
5779 Lisp_Object old_buffer;
5780 int j;
5782 old_buffer = echo_buffer[i];
5783 sprintf (name, " *Echo Area %d*", i);
5784 echo_buffer[i] = Fget_buffer_create (build_string (name));
5785 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
5787 for (j = 0; j < 2; ++j)
5788 if (EQ (old_buffer, echo_area_buffer[j]))
5789 echo_area_buffer[j] = echo_buffer[i];
5794 /* Call FN with args A1..A4 with either the current or last displayed
5795 echo_area_buffer as current buffer.
5797 WHICH zero means use the current message buffer
5798 echo_area_buffer[0]. If that is nil, choose a suitable buffer
5799 from echo_buffer[] and clear it.
5801 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
5802 suitable buffer from echo_buffer[] and clear it.
5804 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
5805 that the current message becomes the last displayed one, make
5806 choose a suitable buffer for echo_area_buffer[0], and clear it.
5808 Value is what FN returns. */
5810 static int
5811 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
5812 struct window *w;
5813 int which;
5814 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
5815 EMACS_INT a1;
5816 Lisp_Object a2;
5817 EMACS_INT a3, a4;
5819 Lisp_Object buffer;
5820 int this_one, the_other, clear_buffer_p, rc;
5821 int count = BINDING_STACK_SIZE ();
5823 /* If buffers aren't life, make new ones. */
5824 ensure_echo_area_buffers ();
5826 clear_buffer_p = 0;
5828 if (which == 0)
5829 this_one = 0, the_other = 1;
5830 else if (which > 0)
5831 this_one = 1, the_other = 0;
5832 else
5834 this_one = 0, the_other = 1;
5835 clear_buffer_p = 1;
5837 /* We need a fresh one in case the current echo buffer equals
5838 the one containing the last displayed echo area message. */
5839 if (!NILP (echo_area_buffer[this_one])
5840 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
5841 echo_area_buffer[this_one] = Qnil;
5844 /* Choose a suitable buffer from echo_buffer[] is we don't
5845 have one. */
5846 if (NILP (echo_area_buffer[this_one]))
5848 echo_area_buffer[this_one]
5849 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
5850 ? echo_buffer[the_other]
5851 : echo_buffer[this_one]);
5852 clear_buffer_p = 1;
5855 buffer = echo_area_buffer[this_one];
5857 record_unwind_protect (unwind_with_echo_area_buffer,
5858 with_echo_area_buffer_unwind_data (w));
5860 /* Make the echo area buffer current. Note that for display
5861 purposes, it is not necessary that the displayed window's buffer
5862 == current_buffer, except for text property lookup. So, let's
5863 only set that buffer temporarily here without doing a full
5864 Fset_window_buffer. We must also change w->pointm, though,
5865 because otherwise an assertions in unshow_buffer fails, and Emacs
5866 aborts. */
5867 set_buffer_internal_1 (XBUFFER (buffer));
5868 if (w)
5870 w->buffer = buffer;
5871 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
5874 current_buffer->undo_list = Qt;
5875 current_buffer->read_only = Qnil;
5877 if (clear_buffer_p && Z > BEG)
5878 del_range (BEG, Z);
5880 xassert (BEGV >= BEG);
5881 xassert (ZV <= Z && ZV >= BEGV);
5883 rc = fn (a1, a2, a3, a4);
5885 xassert (BEGV >= BEG);
5886 xassert (ZV <= Z && ZV >= BEGV);
5888 unbind_to (count, Qnil);
5889 return rc;
5893 /* Save state that should be preserved around the call to the function
5894 FN called in with_echo_area_buffer. */
5896 static Lisp_Object
5897 with_echo_area_buffer_unwind_data (w)
5898 struct window *w;
5900 int i = 0;
5901 Lisp_Object vector;
5903 /* Reduce consing by keeping one vector in
5904 Vwith_echo_area_save_vector. */
5905 vector = Vwith_echo_area_save_vector;
5906 Vwith_echo_area_save_vector = Qnil;
5908 if (NILP (vector))
5909 vector = Fmake_vector (make_number (7), Qnil);
5911 XSETBUFFER (XVECTOR (vector)->contents[i], current_buffer); ++i;
5912 XVECTOR (vector)->contents[i++] = Vdeactivate_mark;
5913 XVECTOR (vector)->contents[i++] = make_number (windows_or_buffers_changed);
5915 if (w)
5917 XSETWINDOW (XVECTOR (vector)->contents[i], w); ++i;
5918 XVECTOR (vector)->contents[i++] = w->buffer;
5919 XVECTOR (vector)->contents[i++]
5920 = make_number (XMARKER (w->pointm)->charpos);
5921 XVECTOR (vector)->contents[i++]
5922 = make_number (XMARKER (w->pointm)->bytepos);
5924 else
5926 int end = i + 4;
5927 while (i < end)
5928 XVECTOR (vector)->contents[i++] = Qnil;
5931 xassert (i == XVECTOR (vector)->size);
5932 return vector;
5936 /* Restore global state from VECTOR which was created by
5937 with_echo_area_buffer_unwind_data. */
5939 static Lisp_Object
5940 unwind_with_echo_area_buffer (vector)
5941 Lisp_Object vector;
5943 int i = 0;
5945 set_buffer_internal_1 (XBUFFER (XVECTOR (vector)->contents[i])); ++i;
5946 Vdeactivate_mark = XVECTOR (vector)->contents[i]; ++i;
5947 windows_or_buffers_changed = XFASTINT (XVECTOR (vector)->contents[i]); ++i;
5949 if (WINDOWP (XVECTOR (vector)->contents[i]))
5951 struct window *w;
5952 Lisp_Object buffer, charpos, bytepos;
5954 w = XWINDOW (XVECTOR (vector)->contents[i]); ++i;
5955 buffer = XVECTOR (vector)->contents[i]; ++i;
5956 charpos = XVECTOR (vector)->contents[i]; ++i;
5957 bytepos = XVECTOR (vector)->contents[i]; ++i;
5959 w->buffer = buffer;
5960 set_marker_both (w->pointm, buffer,
5961 XFASTINT (charpos), XFASTINT (bytepos));
5964 Vwith_echo_area_save_vector = vector;
5965 return Qnil;
5969 /* Set up the echo area for use by print functions. MULTIBYTE_P
5970 non-zero means we will print multibyte. */
5972 void
5973 setup_echo_area_for_printing (multibyte_p)
5974 int multibyte_p;
5976 ensure_echo_area_buffers ();
5978 if (!message_buf_print)
5980 /* A message has been output since the last time we printed.
5981 Choose a fresh echo area buffer. */
5982 if (EQ (echo_area_buffer[1], echo_buffer[0]))
5983 echo_area_buffer[0] = echo_buffer[1];
5984 else
5985 echo_area_buffer[0] = echo_buffer[0];
5987 /* Switch to that buffer and clear it. */
5988 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
5989 if (Z > BEG)
5990 del_range (BEG, Z);
5991 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
5993 /* Set up the buffer for the multibyteness we need. */
5994 if (multibyte_p
5995 != !NILP (current_buffer->enable_multibyte_characters))
5996 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
5998 /* Raise the frame containing the echo area. */
5999 if (minibuffer_auto_raise)
6001 struct frame *sf = SELECTED_FRAME ();
6002 Lisp_Object mini_window;
6003 mini_window = FRAME_MINIBUF_WINDOW (sf);
6004 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6007 message_log_maybe_newline ();
6008 message_buf_print = 1;
6010 else
6012 if (NILP (echo_area_buffer[0]))
6014 if (EQ (echo_area_buffer[1], echo_buffer[0]))
6015 echo_area_buffer[0] = echo_buffer[1];
6016 else
6017 echo_area_buffer[0] = echo_buffer[0];
6020 if (current_buffer != XBUFFER (echo_area_buffer[0]))
6021 /* Someone switched buffers between print requests. */
6022 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
6027 /* Display an echo area message in window W. Value is non-zero if W's
6028 height is changed. If display_last_displayed_message_p is
6029 non-zero, display the message that was last displayed, otherwise
6030 display the current message. */
6032 static int
6033 display_echo_area (w)
6034 struct window *w;
6036 int i, no_message_p, window_height_changed_p, count;
6038 /* Temporarily disable garbage collections while displaying the echo
6039 area. This is done because a GC can print a message itself.
6040 That message would modify the echo area buffer's contents while a
6041 redisplay of the buffer is going on, and seriously confuse
6042 redisplay. */
6043 count = inhibit_garbage_collection ();
6045 /* If there is no message, we must call display_echo_area_1
6046 nevertheless because it resizes the window. But we will have to
6047 reset the echo_area_buffer in question to nil at the end because
6048 with_echo_area_buffer will sets it to an empty buffer. */
6049 i = display_last_displayed_message_p ? 1 : 0;
6050 no_message_p = NILP (echo_area_buffer[i]);
6052 window_height_changed_p
6053 = with_echo_area_buffer (w, display_last_displayed_message_p,
6054 display_echo_area_1,
6055 (EMACS_INT) w, Qnil, 0, 0);
6057 if (no_message_p)
6058 echo_area_buffer[i] = Qnil;
6060 unbind_to (count, Qnil);
6061 return window_height_changed_p;
6065 /* Helper for display_echo_area. Display the current buffer which
6066 contains the current echo area message in window W, a mini-window,
6067 a pointer to which is passed in A1. A2..A4 are currently not used.
6068 Change the height of W so that all of the message is displayed.
6069 Value is non-zero if height of W was changed. */
6071 static int
6072 display_echo_area_1 (a1, a2, a3, a4)
6073 EMACS_INT a1;
6074 Lisp_Object a2;
6075 EMACS_INT a3, a4;
6077 struct window *w = (struct window *) a1;
6078 Lisp_Object window;
6079 struct text_pos start;
6080 int window_height_changed_p = 0;
6082 /* Do this before displaying, so that we have a large enough glyph
6083 matrix for the display. */
6084 window_height_changed_p = resize_mini_window (w, 0);
6086 /* Display. */
6087 clear_glyph_matrix (w->desired_matrix);
6088 XSETWINDOW (window, w);
6089 SET_TEXT_POS (start, BEG, BEG_BYTE);
6090 try_window (window, start);
6092 return window_height_changed_p;
6096 /* Resize the echo area window to exactly the size needed for the
6097 currently displayed message, if there is one. */
6099 void
6100 resize_echo_area_axactly ()
6102 if (BUFFERP (echo_area_buffer[0])
6103 && WINDOWP (echo_area_window))
6105 struct window *w = XWINDOW (echo_area_window);
6106 int resized_p;
6108 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
6109 (EMACS_INT) w, Qnil, 0, 0);
6110 if (resized_p)
6112 ++windows_or_buffers_changed;
6113 ++update_mode_lines;
6114 redisplay_internal (0);
6120 /* Callback function for with_echo_area_buffer, when used from
6121 resize_echo_area_axactly. A1 contains a pointer to the window to
6122 resize, A2 to A4 are not used. Value is what resize_mini_window
6123 returns. */
6125 static int
6126 resize_mini_window_1 (a1, a2, a3, a4)
6127 EMACS_INT a1;
6128 Lisp_Object a2;
6129 EMACS_INT a3, a4;
6131 return resize_mini_window ((struct window *) a1, 1);
6135 /* Resize mini-window W to fit the size of its contents. EXACT:P
6136 means size the window exactly to the size needed. Otherwise, it's
6137 only enlarged until W's buffer is empty. Value is non-zero if
6138 the window height has been changed. */
6141 resize_mini_window (w, exact_p)
6142 struct window *w;
6143 int exact_p;
6145 struct frame *f = XFRAME (w->frame);
6146 int window_height_changed_p = 0;
6148 xassert (MINI_WINDOW_P (w));
6150 /* Nil means don't try to resize. */
6151 if (NILP (Vresize_mini_windows)
6152 || (FRAME_X_P (f) && f->output_data.x == NULL))
6153 return 0;
6155 if (!FRAME_MINIBUF_ONLY_P (f))
6157 struct it it;
6158 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
6159 int total_height = XFASTINT (root->height) + XFASTINT (w->height);
6160 int height, max_height;
6161 int unit = CANON_Y_UNIT (f);
6162 struct text_pos start;
6163 struct buffer *old_current_buffer = NULL;
6165 if (current_buffer != XBUFFER (w->buffer))
6167 old_current_buffer = current_buffer;
6168 set_buffer_internal (XBUFFER (w->buffer));
6171 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
6173 /* Compute the max. number of lines specified by the user. */
6174 if (FLOATP (Vmax_mini_window_height))
6175 max_height = XFLOATINT (Vmax_mini_window_height) * total_height;
6176 else if (INTEGERP (Vmax_mini_window_height))
6177 max_height = XINT (Vmax_mini_window_height);
6178 else
6179 max_height = total_height / 4;
6181 /* Correct that max. height if it's bogus. */
6182 max_height = max (1, max_height);
6183 max_height = min (total_height, max_height);
6185 /* Find out the height of the text in the window. */
6186 if (it.truncate_lines_p)
6187 height = 1;
6188 else
6190 last_height = 0;
6191 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
6192 if (it.max_ascent == 0 && it.max_descent == 0)
6193 height = it.current_y + last_height;
6194 else
6195 height = it.current_y + it.max_ascent + it.max_descent;
6196 height -= it.extra_line_spacing;
6197 height = (height + unit - 1) / unit;
6200 /* Compute a suitable window start. */
6201 if (height > max_height)
6203 height = max_height;
6204 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
6205 move_it_vertically_backward (&it, (height - 1) * unit);
6206 start = it.current.pos;
6208 else
6209 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
6210 SET_MARKER_FROM_TEXT_POS (w->start, start);
6212 if (EQ (Vresize_mini_windows, Qgrow_only))
6214 /* Let it grow only, until we display an empty message, in which
6215 case the window shrinks again. */
6216 if (height > XFASTINT (w->height))
6218 int old_height = XFASTINT (w->height);
6219 freeze_window_starts (f, 1);
6220 grow_mini_window (w, height - XFASTINT (w->height));
6221 window_height_changed_p = XFASTINT (w->height) != old_height;
6223 else if (height < XFASTINT (w->height)
6224 && (exact_p || BEGV == ZV))
6226 int old_height = XFASTINT (w->height);
6227 freeze_window_starts (f, 0);
6228 shrink_mini_window (w);
6229 window_height_changed_p = XFASTINT (w->height) != old_height;
6232 else
6234 /* Always resize to exact size needed. */
6235 if (height > XFASTINT (w->height))
6237 int old_height = XFASTINT (w->height);
6238 freeze_window_starts (f, 1);
6239 grow_mini_window (w, height - XFASTINT (w->height));
6240 window_height_changed_p = XFASTINT (w->height) != old_height;
6242 else if (height < XFASTINT (w->height))
6244 int old_height = XFASTINT (w->height);
6245 freeze_window_starts (f, 0);
6246 shrink_mini_window (w);
6248 if (height)
6250 freeze_window_starts (f, 1);
6251 grow_mini_window (w, height - XFASTINT (w->height));
6254 window_height_changed_p = XFASTINT (w->height) != old_height;
6258 if (old_current_buffer)
6259 set_buffer_internal (old_current_buffer);
6262 return window_height_changed_p;
6266 /* Value is the current message, a string, or nil if there is no
6267 current message. */
6269 Lisp_Object
6270 current_message ()
6272 Lisp_Object msg;
6274 if (NILP (echo_area_buffer[0]))
6275 msg = Qnil;
6276 else
6278 with_echo_area_buffer (0, 0, current_message_1,
6279 (EMACS_INT) &msg, Qnil, 0, 0);
6280 if (NILP (msg))
6281 echo_area_buffer[0] = Qnil;
6284 return msg;
6288 static int
6289 current_message_1 (a1, a2, a3, a4)
6290 EMACS_INT a1;
6291 Lisp_Object a2;
6292 EMACS_INT a3, a4;
6294 Lisp_Object *msg = (Lisp_Object *) a1;
6296 if (Z > BEG)
6297 *msg = make_buffer_string (BEG, Z, 1);
6298 else
6299 *msg = Qnil;
6300 return 0;
6304 /* Push the current message on Vmessage_stack for later restauration
6305 by restore_message. Value is non-zero if the current message isn't
6306 empty. This is a relatively infrequent operation, so it's not
6307 worth optimizing. */
6310 push_message ()
6312 Lisp_Object msg;
6313 msg = current_message ();
6314 Vmessage_stack = Fcons (msg, Vmessage_stack);
6315 return STRINGP (msg);
6319 /* Restore message display from the top of Vmessage_stack. */
6321 void
6322 restore_message ()
6324 Lisp_Object msg;
6326 xassert (CONSP (Vmessage_stack));
6327 msg = XCAR (Vmessage_stack);
6328 if (STRINGP (msg))
6329 message3_nolog (msg, STRING_BYTES (XSTRING (msg)), STRING_MULTIBYTE (msg));
6330 else
6331 message3_nolog (msg, 0, 0);
6335 /* Pop the top-most entry off Vmessage_stack. */
6337 void
6338 pop_message ()
6340 xassert (CONSP (Vmessage_stack));
6341 Vmessage_stack = XCDR (Vmessage_stack);
6345 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
6346 exits. If the stack is not empty, we have a missing pop_message
6347 somewhere. */
6349 void
6350 check_message_stack ()
6352 if (!NILP (Vmessage_stack))
6353 abort ();
6357 /* Truncate to NCHARS what will be displayed in the echo area the next
6358 time we display it---but don't redisplay it now. */
6360 void
6361 truncate_echo_area (nchars)
6362 int nchars;
6364 if (nchars == 0)
6365 echo_area_buffer[0] = Qnil;
6366 /* A null message buffer means that the frame hasn't really been
6367 initialized yet. Error messages get reported properly by
6368 cmd_error, so this must be just an informative message; toss it. */
6369 else if (!noninteractive
6370 && INTERACTIVE
6371 && !NILP (echo_area_buffer[0]))
6373 struct frame *sf = SELECTED_FRAME ();
6374 if (FRAME_MESSAGE_BUF (sf))
6375 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
6380 /* Helper function for truncate_echo_area. Truncate the current
6381 message to at most NCHARS characters. */
6383 static int
6384 truncate_message_1 (nchars, a2, a3, a4)
6385 EMACS_INT nchars;
6386 Lisp_Object a2;
6387 EMACS_INT a3, a4;
6389 if (BEG + nchars < Z)
6390 del_range (BEG + nchars, Z);
6391 if (Z == BEG)
6392 echo_area_buffer[0] = Qnil;
6393 return 0;
6397 /* Set the current message to a substring of S or STRING.
6399 If STRING is a Lisp string, set the message to the first NBYTES
6400 bytes from STRING. NBYTES zero means use the whole string. If
6401 STRING is multibyte, the message will be displayed multibyte.
6403 If S is not null, set the message to the first LEN bytes of S. LEN
6404 zero means use the whole string. MULTIBYTE_P non-zero means S is
6405 multibyte. Display the message multibyte in that case. */
6407 void
6408 set_message (s, string, nbytes, multibyte_p)
6409 char *s;
6410 Lisp_Object string;
6411 int nbytes;
6413 message_enable_multibyte
6414 = ((s && multibyte_p)
6415 || (STRINGP (string) && STRING_MULTIBYTE (string)));
6417 with_echo_area_buffer (0, -1, set_message_1,
6418 (EMACS_INT) s, string, nbytes, multibyte_p);
6419 message_buf_print = 0;
6420 help_echo_showing_p = 0;
6424 /* Helper function for set_message. Arguments have the same meaning
6425 as there, with A1 corresponding to S and A2 corresponding to STRING
6426 This function is called with the echo area buffer being
6427 current. */
6429 static int
6430 set_message_1 (a1, a2, nbytes, multibyte_p)
6431 EMACS_INT a1;
6432 Lisp_Object a2;
6433 EMACS_INT nbytes, multibyte_p;
6435 char *s = (char *) a1;
6436 Lisp_Object string = a2;
6438 xassert (BEG == Z);
6440 /* Change multibyteness of the echo buffer appropriately. */
6441 if (message_enable_multibyte
6442 != !NILP (current_buffer->enable_multibyte_characters))
6443 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
6445 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
6447 /* Insert new message at BEG. */
6448 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
6450 if (STRINGP (string))
6452 int nchars;
6454 if (nbytes == 0)
6455 nbytes = XSTRING (string)->size_byte;
6456 nchars = string_byte_to_char (string, nbytes);
6458 /* This function takes care of single/multibyte conversion. We
6459 just have to ensure that the echo area buffer has the right
6460 setting of enable_multibyte_characters. */
6461 insert_from_string (string, 0, 0, nchars, nbytes, 1);
6463 else if (s)
6465 if (nbytes == 0)
6466 nbytes = strlen (s);
6468 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
6470 /* Convert from multi-byte to single-byte. */
6471 int i, c, n;
6472 unsigned char work[1];
6474 /* Convert a multibyte string to single-byte. */
6475 for (i = 0; i < nbytes; i += n)
6477 c = string_char_and_length (s + i, nbytes - i, &n);
6478 work[0] = (SINGLE_BYTE_CHAR_P (c)
6480 : multibyte_char_to_unibyte (c, Qnil));
6481 insert_1_both (work, 1, 1, 1, 0, 0);
6484 else if (!multibyte_p
6485 && !NILP (current_buffer->enable_multibyte_characters))
6487 /* Convert from single-byte to multi-byte. */
6488 int i, c, n;
6489 unsigned char *msg = (unsigned char *) s;
6490 unsigned char str[MAX_MULTIBYTE_LENGTH];
6492 /* Convert a single-byte string to multibyte. */
6493 for (i = 0; i < nbytes; i++)
6495 c = unibyte_char_to_multibyte (msg[i]);
6496 n = CHAR_STRING (c, str);
6497 insert_1_both (str, 1, n, 1, 0, 0);
6500 else
6501 insert_1 (s, nbytes, 1, 0, 0);
6504 return 0;
6508 /* Clear messages. CURRENT_P non-zero means clear the current
6509 message. LAST_DISPLAYED_P non-zero means clear the message
6510 last displayed. */
6512 void
6513 clear_message (current_p, last_displayed_p)
6514 int current_p, last_displayed_p;
6516 if (current_p)
6517 echo_area_buffer[0] = Qnil;
6519 if (last_displayed_p)
6520 echo_area_buffer[1] = Qnil;
6522 message_buf_print = 0;
6525 /* Clear garbaged frames.
6527 This function is used where the old redisplay called
6528 redraw_garbaged_frames which in turn called redraw_frame which in
6529 turn called clear_frame. The call to clear_frame was a source of
6530 flickering. I believe a clear_frame is not necessary. It should
6531 suffice in the new redisplay to invalidate all current matrices,
6532 and ensure a complete redisplay of all windows. */
6534 static void
6535 clear_garbaged_frames ()
6537 if (frame_garbaged)
6539 Lisp_Object tail, frame;
6541 FOR_EACH_FRAME (tail, frame)
6543 struct frame *f = XFRAME (frame);
6545 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
6547 clear_current_matrices (f);
6548 f->garbaged = 0;
6552 frame_garbaged = 0;
6553 ++windows_or_buffers_changed;
6558 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
6559 is non-zero update selected_frame. Value is non-zero if the
6560 mini-windows height has been changed. */
6562 static int
6563 echo_area_display (update_frame_p)
6564 int update_frame_p;
6566 Lisp_Object mini_window;
6567 struct window *w;
6568 struct frame *f;
6569 int window_height_changed_p = 0;
6570 struct frame *sf = SELECTED_FRAME ();
6572 mini_window = FRAME_MINIBUF_WINDOW (sf);
6573 w = XWINDOW (mini_window);
6574 f = XFRAME (WINDOW_FRAME (w));
6576 /* Don't display if frame is invisible or not yet initialized. */
6577 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
6578 return 0;
6580 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
6581 #ifndef macintosh
6582 #ifdef HAVE_WINDOW_SYSTEM
6583 /* When Emacs starts, selected_frame may be a visible terminal
6584 frame, even if we run under a window system. If we let this
6585 through, a message would be displayed on the terminal. */
6586 if (EQ (selected_frame, Vterminal_frame)
6587 && !NILP (Vwindow_system))
6588 return 0;
6589 #endif /* HAVE_WINDOW_SYSTEM */
6590 #endif
6592 /* Redraw garbaged frames. */
6593 if (frame_garbaged)
6594 clear_garbaged_frames ();
6596 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
6598 echo_area_window = mini_window;
6599 window_height_changed_p = display_echo_area (w);
6600 w->must_be_updated_p = 1;
6602 /* Update the display, unless called from redisplay_internal.
6603 Also don't update the screen during redisplay itself. The
6604 update will happen at the end of redisplay, and an update
6605 here could cause confusion. */
6606 if (update_frame_p && !redisplaying_p)
6608 int n = 0;
6610 /* If the display update has been interrupted by pending
6611 input, update mode lines in the frame. Due to the
6612 pending input, it might have been that redisplay hasn't
6613 been called, so that mode lines above the echo area are
6614 garbaged. This looks odd, so we prevent it here. */
6615 if (!display_completed)
6616 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
6618 if (window_height_changed_p)
6620 /* Must update other windows. */
6621 windows_or_buffers_changed = 1;
6622 redisplay_internal (0);
6624 else if (FRAME_WINDOW_P (f) && n == 0)
6626 /* Window configuration is the same as before.
6627 Can do with a display update of the echo area,
6628 unless we displayed some mode lines. */
6629 update_single_window (w, 1);
6630 rif->flush_display (f);
6632 else
6633 update_frame (f, 1, 1);
6636 else if (!EQ (mini_window, selected_window))
6637 windows_or_buffers_changed++;
6639 /* Last displayed message is now the current message. */
6640 echo_area_buffer[1] = echo_area_buffer[0];
6642 /* Prevent redisplay optimization in redisplay_internal by resetting
6643 this_line_start_pos. This is done because the mini-buffer now
6644 displays the message instead of its buffer text. */
6645 if (EQ (mini_window, selected_window))
6646 CHARPOS (this_line_start_pos) = 0;
6648 return window_height_changed_p;
6653 /***********************************************************************
6654 Frame Titles
6655 ***********************************************************************/
6658 #ifdef HAVE_WINDOW_SYSTEM
6660 /* A buffer for constructing frame titles in it; allocated from the
6661 heap in init_xdisp and resized as needed in store_frame_title_char. */
6663 static char *frame_title_buf;
6665 /* The buffer's end, and a current output position in it. */
6667 static char *frame_title_buf_end;
6668 static char *frame_title_ptr;
6671 /* Store a single character C for the frame title in frame_title_buf.
6672 Re-allocate frame_title_buf if necessary. */
6674 static void
6675 store_frame_title_char (c)
6676 char c;
6678 /* If output position has reached the end of the allocated buffer,
6679 double the buffer's size. */
6680 if (frame_title_ptr == frame_title_buf_end)
6682 int len = frame_title_ptr - frame_title_buf;
6683 int new_size = 2 * len * sizeof *frame_title_buf;
6684 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
6685 frame_title_buf_end = frame_title_buf + new_size;
6686 frame_title_ptr = frame_title_buf + len;
6689 *frame_title_ptr++ = c;
6693 /* Store part of a frame title in frame_title_buf, beginning at
6694 frame_title_ptr. STR is the string to store. Do not copy more
6695 than PRECISION number of bytes from STR; PRECISION <= 0 means copy
6696 the whole string. Pad with spaces until FIELD_WIDTH number of
6697 characters have been copied; FIELD_WIDTH <= 0 means don't pad.
6698 Called from display_mode_element when it is used to build a frame
6699 title. */
6701 static int
6702 store_frame_title (str, field_width, precision)
6703 unsigned char *str;
6704 int field_width, precision;
6706 int n = 0;
6708 /* Copy at most PRECISION chars from STR. */
6709 while ((precision <= 0 || n < precision)
6710 && *str)
6712 store_frame_title_char (*str++);
6713 ++n;
6716 /* Fill up with spaces until FIELD_WIDTH reached. */
6717 while (field_width > 0
6718 && n < field_width)
6720 store_frame_title_char (' ');
6721 ++n;
6724 return n;
6728 /* Set the title of FRAME, if it has changed. The title format is
6729 Vicon_title_format if FRAME is iconified, otherwise it is
6730 frame_title_format. */
6732 static void
6733 x_consider_frame_title (frame)
6734 Lisp_Object frame;
6736 struct frame *f = XFRAME (frame);
6738 if (FRAME_WINDOW_P (f)
6739 || FRAME_MINIBUF_ONLY_P (f)
6740 || f->explicit_name)
6742 /* Do we have more than one visible frame on this X display? */
6743 Lisp_Object tail;
6744 Lisp_Object fmt;
6745 struct buffer *obuf;
6746 int len;
6747 struct it it;
6749 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
6751 struct frame *tf = XFRAME (XCAR (tail));
6753 if (tf != f
6754 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
6755 && !FRAME_MINIBUF_ONLY_P (tf)
6756 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
6757 break;
6760 /* Set global variable indicating that multiple frames exist. */
6761 multiple_frames = CONSP (tail);
6763 /* Switch to the buffer of selected window of the frame. Set up
6764 frame_title_ptr so that display_mode_element will output into it;
6765 then display the title. */
6766 obuf = current_buffer;
6767 Fset_buffer (XWINDOW (f->selected_window)->buffer);
6768 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
6769 frame_title_ptr = frame_title_buf;
6770 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
6771 NULL, DEFAULT_FACE_ID);
6772 len = display_mode_element (&it, 0, -1, -1, fmt);
6773 frame_title_ptr = NULL;
6774 set_buffer_internal (obuf);
6776 /* Set the title only if it's changed. This avoids consing in
6777 the common case where it hasn't. (If it turns out that we've
6778 already wasted too much time by walking through the list with
6779 display_mode_element, then we might need to optimize at a
6780 higher level than this.) */
6781 if (! STRINGP (f->name)
6782 || STRING_BYTES (XSTRING (f->name)) != len
6783 || bcmp (frame_title_buf, XSTRING (f->name)->data, len) != 0)
6784 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
6788 #else /* not HAVE_WINDOW_SYSTEM */
6790 #define frame_title_ptr ((char *)0)
6791 #define store_frame_title(str, mincol, maxcol) 0
6793 #endif /* not HAVE_WINDOW_SYSTEM */
6798 /***********************************************************************
6799 Menu Bars
6800 ***********************************************************************/
6803 /* Prepare for redisplay by updating menu-bar item lists when
6804 appropriate. This can call eval. */
6806 void
6807 prepare_menu_bars ()
6809 int all_windows;
6810 struct gcpro gcpro1, gcpro2;
6811 struct frame *f;
6812 struct frame *tooltip_frame;
6814 #ifdef HAVE_X_WINDOWS
6815 tooltip_frame = tip_frame;
6816 #else
6817 tooltip_frame = NULL;
6818 #endif
6820 /* Update all frame titles based on their buffer names, etc. We do
6821 this before the menu bars so that the buffer-menu will show the
6822 up-to-date frame titles. */
6823 #ifdef HAVE_WINDOW_SYSTEM
6824 if (windows_or_buffers_changed || update_mode_lines)
6826 Lisp_Object tail, frame;
6828 FOR_EACH_FRAME (tail, frame)
6830 f = XFRAME (frame);
6831 if (f != tooltip_frame
6832 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
6833 x_consider_frame_title (frame);
6836 #endif /* HAVE_WINDOW_SYSTEM */
6838 /* Update the menu bar item lists, if appropriate. This has to be
6839 done before any actual redisplay or generation of display lines. */
6840 all_windows = (update_mode_lines
6841 || buffer_shared > 1
6842 || windows_or_buffers_changed);
6843 if (all_windows)
6845 Lisp_Object tail, frame;
6846 int count = BINDING_STACK_SIZE ();
6848 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6850 FOR_EACH_FRAME (tail, frame)
6852 f = XFRAME (frame);
6854 /* Ignore tooltip frame. */
6855 if (f == tooltip_frame)
6856 continue;
6858 /* If a window on this frame changed size, report that to
6859 the user and clear the size-change flag. */
6860 if (FRAME_WINDOW_SIZES_CHANGED (f))
6862 Lisp_Object functions;
6864 /* Clear flag first in case we get an error below. */
6865 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
6866 functions = Vwindow_size_change_functions;
6867 GCPRO2 (tail, functions);
6869 while (CONSP (functions))
6871 call1 (XCAR (functions), frame);
6872 functions = XCDR (functions);
6874 UNGCPRO;
6877 GCPRO1 (tail);
6878 update_menu_bar (f, 0);
6879 #ifdef HAVE_WINDOW_SYSTEM
6880 update_tool_bar (f, 0);
6881 #endif
6882 UNGCPRO;
6885 unbind_to (count, Qnil);
6887 else
6889 struct frame *sf = SELECTED_FRAME ();
6890 update_menu_bar (sf, 1);
6891 #ifdef HAVE_WINDOW_SYSTEM
6892 update_tool_bar (sf, 1);
6893 #endif
6896 /* Motif needs this. See comment in xmenu.c. Turn it off when
6897 pending_menu_activation is not defined. */
6898 #ifdef USE_X_TOOLKIT
6899 pending_menu_activation = 0;
6900 #endif
6904 /* Update the menu bar item list for frame F. This has to be done
6905 before we start to fill in any display lines, because it can call
6906 eval.
6908 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
6910 static void
6911 update_menu_bar (f, save_match_data)
6912 struct frame *f;
6913 int save_match_data;
6915 Lisp_Object window;
6916 register struct window *w;
6918 window = FRAME_SELECTED_WINDOW (f);
6919 w = XWINDOW (window);
6921 if (update_mode_lines)
6922 w->update_mode_line = Qt;
6924 if (FRAME_WINDOW_P (f)
6926 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (macintosh)
6927 FRAME_EXTERNAL_MENU_BAR (f)
6928 #else
6929 FRAME_MENU_BAR_LINES (f) > 0
6930 #endif
6931 : FRAME_MENU_BAR_LINES (f) > 0)
6933 /* If the user has switched buffers or windows, we need to
6934 recompute to reflect the new bindings. But we'll
6935 recompute when update_mode_lines is set too; that means
6936 that people can use force-mode-line-update to request
6937 that the menu bar be recomputed. The adverse effect on
6938 the rest of the redisplay algorithm is about the same as
6939 windows_or_buffers_changed anyway. */
6940 if (windows_or_buffers_changed
6941 || !NILP (w->update_mode_line)
6942 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
6943 < BUF_MODIFF (XBUFFER (w->buffer)))
6944 != !NILP (w->last_had_star))
6945 || ((!NILP (Vtransient_mark_mode)
6946 && !NILP (XBUFFER (w->buffer)->mark_active))
6947 != !NILP (w->region_showing)))
6949 struct buffer *prev = current_buffer;
6950 int count = BINDING_STACK_SIZE ();
6952 set_buffer_internal_1 (XBUFFER (w->buffer));
6953 if (save_match_data)
6954 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6955 if (NILP (Voverriding_local_map_menu_flag))
6957 specbind (Qoverriding_terminal_local_map, Qnil);
6958 specbind (Qoverriding_local_map, Qnil);
6961 /* Run the Lucid hook. */
6962 call1 (Vrun_hooks, Qactivate_menubar_hook);
6964 /* If it has changed current-menubar from previous value,
6965 really recompute the menu-bar from the value. */
6966 if (! NILP (Vlucid_menu_bar_dirty_flag))
6967 call0 (Qrecompute_lucid_menubar);
6969 safe_run_hooks (Qmenu_bar_update_hook);
6970 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
6972 /* Redisplay the menu bar in case we changed it. */
6973 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (macintosh)
6974 if (FRAME_WINDOW_P (f)
6975 #if defined (macintosh)
6976 /* All frames on Mac OS share the same menubar. So only the
6977 selected frame should be allowed to set it. */
6978 && f == SELECTED_FRAME ()
6979 #endif
6981 set_frame_menubar (f, 0, 0);
6982 else
6983 /* On a terminal screen, the menu bar is an ordinary screen
6984 line, and this makes it get updated. */
6985 w->update_mode_line = Qt;
6986 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
6987 /* In the non-toolkit version, the menu bar is an ordinary screen
6988 line, and this makes it get updated. */
6989 w->update_mode_line = Qt;
6990 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
6992 unbind_to (count, Qnil);
6993 set_buffer_internal_1 (prev);
7000 /***********************************************************************
7001 Tool-bars
7002 ***********************************************************************/
7004 #ifdef HAVE_WINDOW_SYSTEM
7006 /* Update the tool-bar item list for frame F. This has to be done
7007 before we start to fill in any display lines. Called from
7008 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
7009 and restore it here. */
7011 static void
7012 update_tool_bar (f, save_match_data)
7013 struct frame *f;
7014 int save_match_data;
7016 if (WINDOWP (f->tool_bar_window)
7017 && XFASTINT (XWINDOW (f->tool_bar_window)->height) > 0)
7019 Lisp_Object window;
7020 struct window *w;
7022 window = FRAME_SELECTED_WINDOW (f);
7023 w = XWINDOW (window);
7025 /* If the user has switched buffers or windows, we need to
7026 recompute to reflect the new bindings. But we'll
7027 recompute when update_mode_lines is set too; that means
7028 that people can use force-mode-line-update to request
7029 that the menu bar be recomputed. The adverse effect on
7030 the rest of the redisplay algorithm is about the same as
7031 windows_or_buffers_changed anyway. */
7032 if (windows_or_buffers_changed
7033 || !NILP (w->update_mode_line)
7034 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
7035 < BUF_MODIFF (XBUFFER (w->buffer)))
7036 != !NILP (w->last_had_star))
7037 || ((!NILP (Vtransient_mark_mode)
7038 && !NILP (XBUFFER (w->buffer)->mark_active))
7039 != !NILP (w->region_showing)))
7041 struct buffer *prev = current_buffer;
7042 int count = BINDING_STACK_SIZE ();
7044 /* Set current_buffer to the buffer of the selected
7045 window of the frame, so that we get the right local
7046 keymaps. */
7047 set_buffer_internal_1 (XBUFFER (w->buffer));
7049 /* Save match data, if we must. */
7050 if (save_match_data)
7051 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
7053 /* Make sure that we don't accidentally use bogus keymaps. */
7054 if (NILP (Voverriding_local_map_menu_flag))
7056 specbind (Qoverriding_terminal_local_map, Qnil);
7057 specbind (Qoverriding_local_map, Qnil);
7060 /* Build desired tool-bar items from keymaps. */
7061 f->tool_bar_items
7062 = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
7064 /* Redisplay the tool-bar in case we changed it. */
7065 w->update_mode_line = Qt;
7067 unbind_to (count, Qnil);
7068 set_buffer_internal_1 (prev);
7074 /* Set F->desired_tool_bar_string to a Lisp string representing frame
7075 F's desired tool-bar contents. F->tool_bar_items must have
7076 been set up previously by calling prepare_menu_bars. */
7078 static void
7079 build_desired_tool_bar_string (f)
7080 struct frame *f;
7082 int i, size, size_needed, string_idx;
7083 struct gcpro gcpro1, gcpro2, gcpro3;
7084 Lisp_Object image, plist, props;
7086 image = plist = props = Qnil;
7087 GCPRO3 (image, plist, props);
7089 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
7090 Otherwise, make a new string. */
7092 /* The size of the string we might be able to reuse. */
7093 size = (STRINGP (f->desired_tool_bar_string)
7094 ? XSTRING (f->desired_tool_bar_string)->size
7095 : 0);
7097 /* Each image in the string we build is preceded by a space,
7098 and there is a space at the end. */
7099 size_needed = f->n_tool_bar_items + 1;
7101 /* Reuse f->desired_tool_bar_string, if possible. */
7102 if (size < size_needed)
7103 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
7104 make_number (' '));
7105 else
7107 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
7108 Fremove_text_properties (make_number (0), make_number (size),
7109 props, f->desired_tool_bar_string);
7112 /* Put a `display' property on the string for the images to display,
7113 put a `menu_item' property on tool-bar items with a value that
7114 is the index of the item in F's tool-bar item vector. */
7115 for (i = 0, string_idx = 0;
7116 i < f->n_tool_bar_items;
7117 ++i, string_idx += 1)
7119 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
7121 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
7122 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
7123 int margin, relief, idx;
7124 extern Lisp_Object QCrelief, QCmargin, QCalgorithm, Qimage;
7125 extern Lisp_Object Qlaplace;
7127 /* If image is a vector, choose the image according to the
7128 button state. */
7129 image = PROP (TOOL_BAR_ITEM_IMAGES);
7130 if (VECTORP (image))
7132 if (enabled_p)
7133 idx = (selected_p
7134 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
7135 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
7136 else
7137 idx = (selected_p
7138 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
7139 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
7141 xassert (ASIZE (image) >= idx);
7142 image = AREF (image, idx);
7144 else
7145 idx = -1;
7147 /* Ignore invalid image specifications. */
7148 if (!valid_image_p (image))
7149 continue;
7151 /* Display the tool-bar button pressed, or depressed. */
7152 plist = Fcopy_sequence (XCDR (image));
7154 /* Compute margin and relief to draw. */
7155 relief = tool_bar_button_relief > 0 ? tool_bar_button_relief : 3;
7156 margin = relief + max (0, tool_bar_button_margin);
7158 if (auto_raise_tool_bar_buttons_p)
7160 /* Add a `:relief' property to the image spec if the item is
7161 selected. */
7162 if (selected_p)
7164 plist = Fplist_put (plist, QCrelief, make_number (-relief));
7165 margin -= relief;
7168 else
7170 /* If image is selected, display it pressed, i.e. with a
7171 negative relief. If it's not selected, display it with a
7172 raised relief. */
7173 plist = Fplist_put (plist, QCrelief,
7174 (selected_p
7175 ? make_number (-relief)
7176 : make_number (relief)));
7177 margin -= relief;
7180 /* Put a margin around the image. */
7181 if (margin)
7182 plist = Fplist_put (plist, QCmargin, make_number (margin));
7184 /* If button is not enabled, and we don't have special images
7185 for the disabled state, make the image appear disabled by
7186 applying an appropriate algorithm to it. */
7187 if (!enabled_p && idx < 0)
7188 plist = Fplist_put (plist, QCalgorithm, Qdisabled);
7190 /* Put a `display' text property on the string for the image to
7191 display. Put a `menu-item' property on the string that gives
7192 the start of this item's properties in the tool-bar items
7193 vector. */
7194 image = Fcons (Qimage, plist);
7195 props = list4 (Qdisplay, image,
7196 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS)),
7197 Fadd_text_properties (make_number (string_idx),
7198 make_number (string_idx + 1),
7199 props, f->desired_tool_bar_string);
7200 #undef PROP
7203 UNGCPRO;
7207 /* Display one line of the tool-bar of frame IT->f. */
7209 static void
7210 display_tool_bar_line (it)
7211 struct it *it;
7213 struct glyph_row *row = it->glyph_row;
7214 int max_x = it->last_visible_x;
7215 struct glyph *last;
7217 prepare_desired_row (row);
7218 row->y = it->current_y;
7220 while (it->current_x < max_x)
7222 int x_before, x, n_glyphs_before, i, nglyphs;
7224 /* Get the next display element. */
7225 if (!get_next_display_element (it))
7226 break;
7228 /* Produce glyphs. */
7229 x_before = it->current_x;
7230 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
7231 PRODUCE_GLYPHS (it);
7233 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
7234 i = 0;
7235 x = x_before;
7236 while (i < nglyphs)
7238 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
7240 if (x + glyph->pixel_width > max_x)
7242 /* Glyph doesn't fit on line. */
7243 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
7244 it->current_x = x;
7245 goto out;
7248 ++it->hpos;
7249 x += glyph->pixel_width;
7250 ++i;
7253 /* Stop at line ends. */
7254 if (ITERATOR_AT_END_OF_LINE_P (it))
7255 break;
7257 set_iterator_to_next (it, 1);
7260 out:;
7262 row->displays_text_p = row->used[TEXT_AREA] != 0;
7263 extend_face_to_end_of_line (it);
7264 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
7265 last->right_box_line_p = 1;
7266 compute_line_metrics (it);
7268 /* If line is empty, make it occupy the rest of the tool-bar. */
7269 if (!row->displays_text_p)
7271 row->height = row->phys_height = it->last_visible_y - row->y;
7272 row->ascent = row->phys_ascent = 0;
7275 row->full_width_p = 1;
7276 row->continued_p = 0;
7277 row->truncated_on_left_p = 0;
7278 row->truncated_on_right_p = 0;
7280 it->current_x = it->hpos = 0;
7281 it->current_y += row->height;
7282 ++it->vpos;
7283 ++it->glyph_row;
7287 /* Value is the number of screen lines needed to make all tool-bar
7288 items of frame F visible. */
7290 static int
7291 tool_bar_lines_needed (f)
7292 struct frame *f;
7294 struct window *w = XWINDOW (f->tool_bar_window);
7295 struct it it;
7297 /* Initialize an iterator for iteration over
7298 F->desired_tool_bar_string in the tool-bar window of frame F. */
7299 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
7300 it.first_visible_x = 0;
7301 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
7302 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
7304 while (!ITERATOR_AT_END_P (&it))
7306 it.glyph_row = w->desired_matrix->rows;
7307 clear_glyph_row (it.glyph_row);
7308 display_tool_bar_line (&it);
7311 return (it.current_y + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);
7315 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
7316 height should be changed. */
7318 static int
7319 redisplay_tool_bar (f)
7320 struct frame *f;
7322 struct window *w;
7323 struct it it;
7324 struct glyph_row *row;
7325 int change_height_p = 0;
7327 /* If frame hasn't a tool-bar window or if it is zero-height, don't
7328 do anything. This means you must start with tool-bar-lines
7329 non-zero to get the auto-sizing effect. Or in other words, you
7330 can turn off tool-bars by specifying tool-bar-lines zero. */
7331 if (!WINDOWP (f->tool_bar_window)
7332 || (w = XWINDOW (f->tool_bar_window),
7333 XFASTINT (w->height) == 0))
7334 return 0;
7336 /* Set up an iterator for the tool-bar window. */
7337 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
7338 it.first_visible_x = 0;
7339 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
7340 row = it.glyph_row;
7342 /* Build a string that represents the contents of the tool-bar. */
7343 build_desired_tool_bar_string (f);
7344 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
7346 /* Display as many lines as needed to display all tool-bar items. */
7347 while (it.current_y < it.last_visible_y)
7348 display_tool_bar_line (&it);
7350 /* It doesn't make much sense to try scrolling in the tool-bar
7351 window, so don't do it. */
7352 w->desired_matrix->no_scrolling_p = 1;
7353 w->must_be_updated_p = 1;
7355 if (auto_resize_tool_bars_p)
7357 int nlines;
7359 /* If there are blank lines at the end, except for a partially
7360 visible blank line at the end that is smaller than
7361 CANON_Y_UNIT, change the tool-bar's height. */
7362 row = it.glyph_row - 1;
7363 if (!row->displays_text_p
7364 && row->height >= CANON_Y_UNIT (f))
7365 change_height_p = 1;
7367 /* If row displays tool-bar items, but is partially visible,
7368 change the tool-bar's height. */
7369 if (row->displays_text_p
7370 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
7371 change_height_p = 1;
7373 /* Resize windows as needed by changing the `tool-bar-lines'
7374 frame parameter. */
7375 if (change_height_p
7376 && (nlines = tool_bar_lines_needed (f),
7377 nlines != XFASTINT (w->height)))
7379 extern Lisp_Object Qtool_bar_lines;
7380 Lisp_Object frame;
7381 int old_height = XFASTINT (w->height);
7383 XSETFRAME (frame, f);
7384 clear_glyph_matrix (w->desired_matrix);
7385 Fmodify_frame_parameters (frame,
7386 Fcons (Fcons (Qtool_bar_lines,
7387 make_number (nlines)),
7388 Qnil));
7389 if (XFASTINT (w->height) != old_height)
7390 fonts_changed_p = 1;
7394 return change_height_p;
7398 /* Get information about the tool-bar item which is displayed in GLYPH
7399 on frame F. Return in *PROP_IDX the index where tool-bar item
7400 properties start in F->tool_bar_items. Value is zero if
7401 GLYPH doesn't display a tool-bar item. */
7404 tool_bar_item_info (f, glyph, prop_idx)
7405 struct frame *f;
7406 struct glyph *glyph;
7407 int *prop_idx;
7409 Lisp_Object prop;
7410 int success_p;
7412 /* Get the text property `menu-item' at pos. The value of that
7413 property is the start index of this item's properties in
7414 F->tool_bar_items. */
7415 prop = Fget_text_property (make_number (glyph->charpos),
7416 Qmenu_item, f->current_tool_bar_string);
7417 if (INTEGERP (prop))
7419 *prop_idx = XINT (prop);
7420 success_p = 1;
7422 else
7423 success_p = 0;
7425 return success_p;
7428 #endif /* HAVE_WINDOW_SYSTEM */
7432 /************************************************************************
7433 Horizontal scrolling
7434 ************************************************************************/
7436 static int hscroll_window_tree P_ ((Lisp_Object));
7437 static int hscroll_windows P_ ((Lisp_Object));
7439 /* For all leaf windows in the window tree rooted at WINDOW, set their
7440 hscroll value so that PT is (i) visible in the window, and (ii) so
7441 that it is not within a certain margin at the window's left and
7442 right border. Value is non-zero if any window's hscroll has been
7443 changed. */
7445 static int
7446 hscroll_window_tree (window)
7447 Lisp_Object window;
7449 int hscrolled_p = 0;
7451 while (WINDOWP (window))
7453 struct window *w = XWINDOW (window);
7455 if (WINDOWP (w->hchild))
7456 hscrolled_p |= hscroll_window_tree (w->hchild);
7457 else if (WINDOWP (w->vchild))
7458 hscrolled_p |= hscroll_window_tree (w->vchild);
7459 else if (w->cursor.vpos >= 0)
7461 int hscroll_margin, text_area_x, text_area_y;
7462 int text_area_width, text_area_height;
7463 struct glyph_row *current_cursor_row
7464 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
7465 struct glyph_row *desired_cursor_row
7466 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
7467 struct glyph_row *cursor_row
7468 = (desired_cursor_row->enabled_p
7469 ? desired_cursor_row
7470 : current_cursor_row);
7472 window_box (w, TEXT_AREA, &text_area_x, &text_area_y,
7473 &text_area_width, &text_area_height);
7475 /* Scroll when cursor is inside this scroll margin. */
7476 hscroll_margin = 5 * CANON_X_UNIT (XFRAME (w->frame));
7478 if ((XFASTINT (w->hscroll)
7479 && w->cursor.x < hscroll_margin)
7480 || (cursor_row->enabled_p
7481 && cursor_row->truncated_on_right_p
7482 && (w->cursor.x > text_area_width - hscroll_margin)))
7484 struct it it;
7485 int hscroll;
7486 struct buffer *saved_current_buffer;
7487 int pt;
7489 /* Find point in a display of infinite width. */
7490 saved_current_buffer = current_buffer;
7491 current_buffer = XBUFFER (w->buffer);
7493 if (w == XWINDOW (selected_window))
7494 pt = BUF_PT (current_buffer);
7495 else
7497 pt = marker_position (w->pointm);
7498 pt = max (BEGV, pt);
7499 pt = min (ZV, pt);
7502 /* Move iterator to pt starting at cursor_row->start in
7503 a line with infinite width. */
7504 init_to_row_start (&it, w, cursor_row);
7505 it.last_visible_x = INFINITY;
7506 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
7507 current_buffer = saved_current_buffer;
7509 /* Center cursor in window. */
7510 hscroll = (max (0, it.current_x - text_area_width / 2)
7511 / CANON_X_UNIT (it.f));
7513 /* Don't call Fset_window_hscroll if value hasn't
7514 changed because it will prevent redisplay
7515 optimizations. */
7516 if (XFASTINT (w->hscroll) != hscroll)
7518 Fset_window_hscroll (window, make_number (hscroll));
7519 hscrolled_p = 1;
7524 window = w->next;
7527 /* Value is non-zero if hscroll of any leaf window has been changed. */
7528 return hscrolled_p;
7532 /* Set hscroll so that cursor is visible and not inside horizontal
7533 scroll margins for all windows in the tree rooted at WINDOW. See
7534 also hscroll_window_tree above. Value is non-zero if any window's
7535 hscroll has been changed. If it has, desired matrices on the frame
7536 of WINDOW are cleared. */
7538 static int
7539 hscroll_windows (window)
7540 Lisp_Object window;
7542 int hscrolled_p;
7544 if (automatic_hscrolling_p)
7546 hscrolled_p = hscroll_window_tree (window);
7547 if (hscrolled_p)
7548 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
7550 else
7551 hscrolled_p = 0;
7552 return hscrolled_p;
7557 /************************************************************************
7558 Redisplay
7559 ************************************************************************/
7561 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
7562 to a non-zero value. This is sometimes handy to have in a debugger
7563 session. */
7565 #if GLYPH_DEBUG
7567 /* First and last unchanged row for try_window_id. */
7569 int debug_first_unchanged_at_end_vpos;
7570 int debug_last_unchanged_at_beg_vpos;
7572 /* Delta vpos and y. */
7574 int debug_dvpos, debug_dy;
7576 /* Delta in characters and bytes for try_window_id. */
7578 int debug_delta, debug_delta_bytes;
7580 /* Values of window_end_pos and window_end_vpos at the end of
7581 try_window_id. */
7583 int debug_end_pos, debug_end_vpos;
7585 /* Append a string to W->desired_matrix->method. FMT is a printf
7586 format string. A1...A9 are a supplement for a variable-length
7587 argument list. If trace_redisplay_p is non-zero also printf the
7588 resulting string to stderr. */
7590 static void
7591 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
7592 struct window *w;
7593 char *fmt;
7594 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
7596 char buffer[512];
7597 char *method = w->desired_matrix->method;
7598 int len = strlen (method);
7599 int size = sizeof w->desired_matrix->method;
7600 int remaining = size - len - 1;
7602 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
7603 if (len && remaining)
7605 method[len] = '|';
7606 --remaining, ++len;
7609 strncpy (method + len, buffer, remaining);
7611 if (trace_redisplay_p)
7612 fprintf (stderr, "%p (%s): %s\n",
7614 ((BUFFERP (w->buffer)
7615 && STRINGP (XBUFFER (w->buffer)->name))
7616 ? (char *) XSTRING (XBUFFER (w->buffer)->name)->data
7617 : "no buffer"),
7618 buffer);
7621 #endif /* GLYPH_DEBUG */
7624 /* This counter is used to clear the face cache every once in a while
7625 in redisplay_internal. It is incremented for each redisplay.
7626 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
7627 cleared. */
7629 #define CLEAR_FACE_CACHE_COUNT 10000
7630 static int clear_face_cache_count;
7632 /* Record the previous terminal frame we displayed. */
7634 static struct frame *previous_terminal_frame;
7636 /* Non-zero while redisplay_internal is in progress. */
7638 int redisplaying_p;
7641 /* Value is non-zero if all changes in window W, which displays
7642 current_buffer, are in the text between START and END. START is a
7643 buffer position, END is given as a distance from Z. Used in
7644 redisplay_internal for display optimization. */
7646 static INLINE int
7647 text_outside_line_unchanged_p (w, start, end)
7648 struct window *w;
7649 int start, end;
7651 int unchanged_p = 1;
7653 /* If text or overlays have changed, see where. */
7654 if (XFASTINT (w->last_modified) < MODIFF
7655 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
7657 /* Gap in the line? */
7658 if (GPT < start || Z - GPT < end)
7659 unchanged_p = 0;
7661 /* Changes start in front of the line, or end after it? */
7662 if (unchanged_p
7663 && (BEG_UNCHANGED < start - 1
7664 || END_UNCHANGED < end))
7665 unchanged_p = 0;
7667 /* If selective display, can't optimize if changes start at the
7668 beginning of the line. */
7669 if (unchanged_p
7670 && INTEGERP (current_buffer->selective_display)
7671 && XINT (current_buffer->selective_display) > 0
7672 && (BEG_UNCHANGED < start || GPT <= start))
7673 unchanged_p = 0;
7676 return unchanged_p;
7680 /* Do a frame update, taking possible shortcuts into account. This is
7681 the main external entry point for redisplay.
7683 If the last redisplay displayed an echo area message and that message
7684 is no longer requested, we clear the echo area or bring back the
7685 mini-buffer if that is in use. */
7687 void
7688 redisplay ()
7690 redisplay_internal (0);
7693 /* Return 1 if point moved out of or into a composition. Otherwise
7694 return 0. PREV_BUF and PREV_PT are the last point buffer and
7695 position. BUF and PT are the current point buffer and position. */
7698 check_point_in_composition (prev_buf, prev_pt, buf, pt)
7699 struct buffer *prev_buf, *buf;
7700 int prev_pt, pt;
7702 int start, end;
7703 Lisp_Object prop;
7704 Lisp_Object buffer;
7706 XSETBUFFER (buffer, buf);
7707 /* Check a composition at the last point if point moved within the
7708 same buffer. */
7709 if (prev_buf == buf)
7711 if (prev_pt == pt)
7712 /* Point didn't move. */
7713 return 0;
7715 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
7716 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
7717 && COMPOSITION_VALID_P (start, end, prop)
7718 && start < prev_pt && end > prev_pt)
7719 /* The last point was within the composition. Return 1 iff
7720 point moved out of the composition. */
7721 return (pt <= start || pt >= end);
7724 /* Check a composition at the current point. */
7725 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
7726 && find_composition (pt, -1, &start, &end, &prop, buffer)
7727 && COMPOSITION_VALID_P (start, end, prop)
7728 && start < pt && end > pt);
7731 /* Reconsider the setting of B->clip_changed which is displayed
7732 in window W. */
7734 static INLINE void
7735 reconsider_clip_changes (w, b)
7736 struct window *w;
7737 struct buffer *b;
7739 if (b->prevent_redisplay_optimizations_p)
7740 b->clip_changed = 1;
7741 else if (b->clip_changed
7742 && !NILP (w->window_end_valid)
7743 && w->current_matrix->buffer == b
7744 && w->current_matrix->zv == BUF_ZV (b)
7745 && w->current_matrix->begv == BUF_BEGV (b))
7746 b->clip_changed = 0;
7748 /* If display wasn't paused, and W is not a tool bar window, see if
7749 point has been moved into or out of a composition. In that case,
7750 we set b->clip_changed to 1 to force updating the screen. If
7751 b->clip_changed has already been set to 1, we can skip this
7752 check. */
7753 if (!b->clip_changed
7754 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
7756 int pt;
7758 if (w == XWINDOW (selected_window))
7759 pt = BUF_PT (current_buffer);
7760 else
7761 pt = marker_position (w->pointm);
7763 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
7764 || pt != XINT (w->last_point))
7765 && check_point_in_composition (w->current_matrix->buffer,
7766 XINT (w->last_point),
7767 XBUFFER (w->buffer), pt))
7768 b->clip_changed = 1;
7773 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
7774 response to any user action; therefore, we should preserve the echo
7775 area. (Actually, our caller does that job.) Perhaps in the future
7776 avoid recentering windows if it is not necessary; currently that
7777 causes some problems. */
7779 static void
7780 redisplay_internal (preserve_echo_area)
7781 int preserve_echo_area;
7783 struct window *w = XWINDOW (selected_window);
7784 struct frame *f = XFRAME (w->frame);
7785 int pause;
7786 int must_finish = 0;
7787 struct text_pos tlbufpos, tlendpos;
7788 int number_of_visible_frames;
7789 int count;
7790 struct frame *sf = SELECTED_FRAME ();
7792 /* Non-zero means redisplay has to consider all windows on all
7793 frames. Zero means, only selected_window is considered. */
7794 int consider_all_windows_p;
7796 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
7798 /* No redisplay if running in batch mode or frame is not yet fully
7799 initialized, or redisplay is explicitly turned off by setting
7800 Vinhibit_redisplay. */
7801 if (noninteractive
7802 || !NILP (Vinhibit_redisplay)
7803 || !f->glyphs_initialized_p)
7804 return;
7806 /* The flag redisplay_performed_directly_p is set by
7807 direct_output_for_insert when it already did the whole screen
7808 update necessary. */
7809 if (redisplay_performed_directly_p)
7811 redisplay_performed_directly_p = 0;
7812 if (!hscroll_windows (selected_window))
7813 return;
7816 #ifdef USE_X_TOOLKIT
7817 if (popup_activated ())
7818 return;
7819 #endif
7821 /* I don't think this happens but let's be paranoid. */
7822 if (redisplaying_p)
7823 return;
7825 /* Record a function that resets redisplaying_p to its old value
7826 when we leave this function. */
7827 count = BINDING_STACK_SIZE ();
7828 record_unwind_protect (unwind_redisplay, make_number (redisplaying_p));
7829 ++redisplaying_p;
7831 retry:
7832 pause = 0;
7833 reconsider_clip_changes (w, current_buffer);
7835 /* If new fonts have been loaded that make a glyph matrix adjustment
7836 necessary, do it. */
7837 if (fonts_changed_p)
7839 adjust_glyphs (NULL);
7840 ++windows_or_buffers_changed;
7841 fonts_changed_p = 0;
7844 if (! FRAME_WINDOW_P (sf)
7845 && previous_terminal_frame != sf)
7847 /* Since frames on an ASCII terminal share the same display
7848 area, displaying a different frame means redisplay the whole
7849 thing. */
7850 windows_or_buffers_changed++;
7851 SET_FRAME_GARBAGED (sf);
7852 XSETFRAME (Vterminal_frame, sf);
7854 previous_terminal_frame = sf;
7856 /* Set the visible flags for all frames. Do this before checking
7857 for resized or garbaged frames; they want to know if their frames
7858 are visible. See the comment in frame.h for
7859 FRAME_SAMPLE_VISIBILITY. */
7861 Lisp_Object tail, frame;
7863 number_of_visible_frames = 0;
7865 FOR_EACH_FRAME (tail, frame)
7867 struct frame *f = XFRAME (frame);
7869 FRAME_SAMPLE_VISIBILITY (f);
7870 if (FRAME_VISIBLE_P (f))
7871 ++number_of_visible_frames;
7872 clear_desired_matrices (f);
7876 /* Notice any pending interrupt request to change frame size. */
7877 do_pending_window_change (1);
7879 /* Clear frames marked as garbaged. */
7880 if (frame_garbaged)
7881 clear_garbaged_frames ();
7883 /* Build menubar and tool-bar items. */
7884 prepare_menu_bars ();
7886 if (windows_or_buffers_changed)
7887 update_mode_lines++;
7889 /* Detect case that we need to write or remove a star in the mode line. */
7890 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
7892 w->update_mode_line = Qt;
7893 if (buffer_shared > 1)
7894 update_mode_lines++;
7897 /* If %c is in the mode line, update it if needed. */
7898 if (!NILP (w->column_number_displayed)
7899 /* This alternative quickly identifies a common case
7900 where no change is needed. */
7901 && !(PT == XFASTINT (w->last_point)
7902 && XFASTINT (w->last_modified) >= MODIFF
7903 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
7904 && XFASTINT (w->column_number_displayed) != current_column ())
7905 w->update_mode_line = Qt;
7907 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
7909 /* The variable buffer_shared is set in redisplay_window and
7910 indicates that we redisplay a buffer in different windows. See
7911 there. */
7912 consider_all_windows_p = update_mode_lines || buffer_shared > 1;
7914 /* If specs for an arrow have changed, do thorough redisplay
7915 to ensure we remove any arrow that should no longer exist. */
7916 if (! EQ (COERCE_MARKER (Voverlay_arrow_position), last_arrow_position)
7917 || ! EQ (Voverlay_arrow_string, last_arrow_string))
7918 consider_all_windows_p = windows_or_buffers_changed = 1;
7920 /* Normally the message* functions will have already displayed and
7921 updated the echo area, but the frame may have been trashed, or
7922 the update may have been preempted, so display the echo area
7923 again here. Checking both message buffers captures the case that
7924 the echo area should be cleared. */
7925 if (!NILP (echo_area_buffer[0]) || !NILP (echo_area_buffer[1]))
7927 int window_height_changed_p = echo_area_display (0);
7928 must_finish = 1;
7930 if (fonts_changed_p)
7931 goto retry;
7932 else if (window_height_changed_p)
7934 consider_all_windows_p = 1;
7935 ++update_mode_lines;
7936 ++windows_or_buffers_changed;
7938 /* If window configuration was changed, frames may have been
7939 marked garbaged. Clear them or we will experience
7940 surprises wrt scrolling. */
7941 if (frame_garbaged)
7942 clear_garbaged_frames ();
7945 else if (EQ (selected_window, minibuf_window)
7946 && (current_buffer->clip_changed
7947 || XFASTINT (w->last_modified) < MODIFF
7948 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
7949 && resize_mini_window (w, 0))
7951 /* Resized active mini-window to fit the size of what it is
7952 showing if its contents might have changed. */
7953 must_finish = 1;
7954 consider_all_windows_p = 1;
7955 ++windows_or_buffers_changed;
7956 ++update_mode_lines;
7958 /* If window configuration was changed, frames may have been
7959 marked garbaged. Clear them or we will experience
7960 surprises wrt scrolling. */
7961 if (frame_garbaged)
7962 clear_garbaged_frames ();
7966 /* If showing the region, and mark has changed, we must redisplay
7967 the whole window. The assignment to this_line_start_pos prevents
7968 the optimization directly below this if-statement. */
7969 if (((!NILP (Vtransient_mark_mode)
7970 && !NILP (XBUFFER (w->buffer)->mark_active))
7971 != !NILP (w->region_showing))
7972 || (!NILP (w->region_showing)
7973 && !EQ (w->region_showing,
7974 Fmarker_position (XBUFFER (w->buffer)->mark))))
7975 CHARPOS (this_line_start_pos) = 0;
7977 /* Optimize the case that only the line containing the cursor in the
7978 selected window has changed. Variables starting with this_ are
7979 set in display_line and record information about the line
7980 containing the cursor. */
7981 tlbufpos = this_line_start_pos;
7982 tlendpos = this_line_end_pos;
7983 if (!consider_all_windows_p
7984 && CHARPOS (tlbufpos) > 0
7985 && NILP (w->update_mode_line)
7986 && !current_buffer->clip_changed
7987 && FRAME_VISIBLE_P (XFRAME (w->frame))
7988 && !FRAME_OBSCURED_P (XFRAME (w->frame))
7989 /* Make sure recorded data applies to current buffer, etc. */
7990 && this_line_buffer == current_buffer
7991 && current_buffer == XBUFFER (w->buffer)
7992 && NILP (w->force_start)
7993 /* Point must be on the line that we have info recorded about. */
7994 && PT >= CHARPOS (tlbufpos)
7995 && PT <= Z - CHARPOS (tlendpos)
7996 /* All text outside that line, including its final newline,
7997 must be unchanged */
7998 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
7999 CHARPOS (tlendpos)))
8001 if (CHARPOS (tlbufpos) > BEGV
8002 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
8003 && (CHARPOS (tlbufpos) == ZV
8004 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
8005 /* Former continuation line has disappeared by becoming empty */
8006 goto cancel;
8007 else if (XFASTINT (w->last_modified) < MODIFF
8008 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
8009 || MINI_WINDOW_P (w))
8011 /* We have to handle the case of continuation around a
8012 wide-column character (See the comment in indent.c around
8013 line 885).
8015 For instance, in the following case:
8017 -------- Insert --------
8018 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
8019 J_I_ ==> J_I_ `^^' are cursors.
8020 ^^ ^^
8021 -------- --------
8023 As we have to redraw the line above, we should goto cancel. */
8025 struct it it;
8026 int line_height_before = this_line_pixel_height;
8028 /* Note that start_display will handle the case that the
8029 line starting at tlbufpos is a continuation lines. */
8030 start_display (&it, w, tlbufpos);
8032 /* Implementation note: It this still necessary? */
8033 if (it.current_x != this_line_start_x)
8034 goto cancel;
8036 TRACE ((stderr, "trying display optimization 1\n"));
8037 w->cursor.vpos = -1;
8038 overlay_arrow_seen = 0;
8039 it.vpos = this_line_vpos;
8040 it.current_y = this_line_y;
8041 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
8042 display_line (&it);
8044 /* If line contains point, is not continued,
8045 and ends at same distance from eob as before, we win */
8046 if (w->cursor.vpos >= 0
8047 /* Line is not continued, otherwise this_line_start_pos
8048 would have been set to 0 in display_line. */
8049 && CHARPOS (this_line_start_pos)
8050 /* Line ends as before. */
8051 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
8052 /* Line has same height as before. Otherwise other lines
8053 would have to be shifted up or down. */
8054 && this_line_pixel_height == line_height_before)
8056 /* If this is not the window's last line, we must adjust
8057 the charstarts of the lines below. */
8058 if (it.current_y < it.last_visible_y)
8060 struct glyph_row *row
8061 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
8062 int delta, delta_bytes;
8064 if (Z - CHARPOS (tlendpos) == ZV)
8066 /* This line ends at end of (accessible part of)
8067 buffer. There is no newline to count. */
8068 delta = (Z
8069 - CHARPOS (tlendpos)
8070 - MATRIX_ROW_START_CHARPOS (row));
8071 delta_bytes = (Z_BYTE
8072 - BYTEPOS (tlendpos)
8073 - MATRIX_ROW_START_BYTEPOS (row));
8075 else
8077 /* This line ends in a newline. Must take
8078 account of the newline and the rest of the
8079 text that follows. */
8080 delta = (Z
8081 - CHARPOS (tlendpos)
8082 - MATRIX_ROW_START_CHARPOS (row));
8083 delta_bytes = (Z_BYTE
8084 - BYTEPOS (tlendpos)
8085 - MATRIX_ROW_START_BYTEPOS (row));
8088 increment_matrix_positions (w->current_matrix,
8089 this_line_vpos + 1,
8090 w->current_matrix->nrows,
8091 delta, delta_bytes);
8094 /* If this row displays text now but previously didn't,
8095 or vice versa, w->window_end_vpos may have to be
8096 adjusted. */
8097 if ((it.glyph_row - 1)->displays_text_p)
8099 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
8100 XSETINT (w->window_end_vpos, this_line_vpos);
8102 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
8103 && this_line_vpos > 0)
8104 XSETINT (w->window_end_vpos, this_line_vpos - 1);
8105 w->window_end_valid = Qnil;
8107 /* Update hint: No need to try to scroll in update_window. */
8108 w->desired_matrix->no_scrolling_p = 1;
8110 #if GLYPH_DEBUG
8111 *w->desired_matrix->method = 0;
8112 debug_method_add (w, "optimization 1");
8113 #endif
8114 goto update;
8116 else
8117 goto cancel;
8119 else if (/* Cursor position hasn't changed. */
8120 PT == XFASTINT (w->last_point)
8121 /* Make sure the cursor was last displayed
8122 in this window. Otherwise we have to reposition it. */
8123 && 0 <= w->cursor.vpos
8124 && XINT (w->height) > w->cursor.vpos)
8126 if (!must_finish)
8128 do_pending_window_change (1);
8130 /* We used to always goto end_of_redisplay here, but this
8131 isn't enough if we have a blinking cursor. */
8132 if (w->cursor_off_p == w->last_cursor_off_p)
8133 goto end_of_redisplay;
8135 goto update;
8137 /* If highlighting the region, or if the cursor is in the echo area,
8138 then we can't just move the cursor. */
8139 else if (! (!NILP (Vtransient_mark_mode)
8140 && !NILP (current_buffer->mark_active))
8141 && (EQ (selected_window, current_buffer->last_selected_window)
8142 || highlight_nonselected_windows)
8143 && NILP (w->region_showing)
8144 && NILP (Vshow_trailing_whitespace)
8145 && !cursor_in_echo_area)
8147 struct it it;
8148 struct glyph_row *row;
8150 /* Skip from tlbufpos to PT and see where it is. Note that
8151 PT may be in invisible text. If so, we will end at the
8152 next visible position. */
8153 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
8154 NULL, DEFAULT_FACE_ID);
8155 it.current_x = this_line_start_x;
8156 it.current_y = this_line_y;
8157 it.vpos = this_line_vpos;
8159 /* The call to move_it_to stops in front of PT, but
8160 moves over before-strings. */
8161 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
8163 if (it.vpos == this_line_vpos
8164 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
8165 row->enabled_p))
8167 xassert (this_line_vpos == it.vpos);
8168 xassert (this_line_y == it.current_y);
8169 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
8170 goto update;
8172 else
8173 goto cancel;
8176 cancel:
8177 /* Text changed drastically or point moved off of line. */
8178 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
8181 CHARPOS (this_line_start_pos) = 0;
8182 consider_all_windows_p |= buffer_shared > 1;
8183 ++clear_face_cache_count;
8186 /* Build desired matrices, and update the display. If
8187 consider_all_windows_p is non-zero, do it for all windows on all
8188 frames. Otherwise do it for selected_window, only. */
8190 if (consider_all_windows_p)
8192 Lisp_Object tail, frame;
8194 /* Clear the face cache eventually. */
8195 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
8197 clear_face_cache (0);
8198 clear_face_cache_count = 0;
8201 /* Recompute # windows showing selected buffer. This will be
8202 incremented each time such a window is displayed. */
8203 buffer_shared = 0;
8205 FOR_EACH_FRAME (tail, frame)
8207 struct frame *f = XFRAME (frame);
8209 if (FRAME_WINDOW_P (f) || f == sf)
8211 /* Mark all the scroll bars to be removed; we'll redeem
8212 the ones we want when we redisplay their windows. */
8213 if (condemn_scroll_bars_hook)
8214 (*condemn_scroll_bars_hook) (f);
8216 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
8217 redisplay_windows (FRAME_ROOT_WINDOW (f));
8219 /* Any scroll bars which redisplay_windows should have
8220 nuked should now go away. */
8221 if (judge_scroll_bars_hook)
8222 (*judge_scroll_bars_hook) (f);
8224 /* If fonts changed, display again. */
8225 if (fonts_changed_p)
8226 goto retry;
8228 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
8230 /* See if we have to hscroll. */
8231 if (hscroll_windows (f->root_window))
8232 goto retry;
8234 /* Prevent various kinds of signals during display
8235 update. stdio is not robust about handling
8236 signals, which can cause an apparent I/O
8237 error. */
8238 if (interrupt_input)
8239 unrequest_sigio ();
8240 stop_polling ();
8242 /* Update the display. */
8243 set_window_update_flags (XWINDOW (f->root_window), 1);
8244 pause |= update_frame (f, 0, 0);
8245 if (pause)
8246 break;
8248 mark_window_display_accurate (f->root_window, 1);
8249 if (frame_up_to_date_hook)
8250 frame_up_to_date_hook (f);
8255 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
8257 Lisp_Object mini_window;
8258 struct frame *mini_frame;
8260 redisplay_window (selected_window, 1);
8262 /* Compare desired and current matrices, perform output. */
8263 update:
8265 /* If fonts changed, display again. */
8266 if (fonts_changed_p)
8267 goto retry;
8269 /* Prevent various kinds of signals during display update.
8270 stdio is not robust about handling signals,
8271 which can cause an apparent I/O error. */
8272 if (interrupt_input)
8273 unrequest_sigio ();
8274 stop_polling ();
8276 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
8278 if (hscroll_windows (selected_window))
8279 goto retry;
8281 XWINDOW (selected_window)->must_be_updated_p = 1;
8282 pause = update_frame (sf, 0, 0);
8285 /* We may have called echo_area_display at the top of this
8286 function. If the echo area is on another frame, that may
8287 have put text on a frame other than the selected one, so the
8288 above call to update_frame would not have caught it. Catch
8289 it here. */
8290 mini_window = FRAME_MINIBUF_WINDOW (sf);
8291 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8293 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
8295 XWINDOW (mini_window)->must_be_updated_p = 1;
8296 pause |= update_frame (mini_frame, 0, 0);
8297 if (!pause && hscroll_windows (mini_window))
8298 goto retry;
8302 /* If display was paused because of pending input, make sure we do a
8303 thorough update the next time. */
8304 if (pause)
8306 /* Prevent the optimization at the beginning of
8307 redisplay_internal that tries a single-line update of the
8308 line containing the cursor in the selected window. */
8309 CHARPOS (this_line_start_pos) = 0;
8311 /* Let the overlay arrow be updated the next time. */
8312 if (!NILP (last_arrow_position))
8314 last_arrow_position = Qt;
8315 last_arrow_string = Qt;
8318 /* If we pause after scrolling, some rows in the current
8319 matrices of some windows are not valid. */
8320 if (!WINDOW_FULL_WIDTH_P (w)
8321 && !FRAME_WINDOW_P (XFRAME (w->frame)))
8322 update_mode_lines = 1;
8325 /* Now text on frame agrees with windows, so put info into the
8326 windows for partial redisplay to follow. */
8327 if (!pause)
8329 register struct buffer *b = XBUFFER (w->buffer);
8331 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
8332 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
8333 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
8334 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
8336 if (consider_all_windows_p)
8337 mark_window_display_accurate (FRAME_ROOT_WINDOW (sf), 1);
8338 else
8340 XSETFASTINT (w->last_point, BUF_PT (b));
8341 w->last_cursor = w->cursor;
8342 w->last_cursor_off_p = w->cursor_off_p;
8344 b->clip_changed = 0;
8345 b->prevent_redisplay_optimizations_p = 0;
8346 w->update_mode_line = Qnil;
8347 XSETFASTINT (w->last_modified, BUF_MODIFF (b));
8348 XSETFASTINT (w->last_overlay_modified, BUF_OVERLAY_MODIFF (b));
8349 w->last_had_star
8350 = (BUF_MODIFF (XBUFFER (w->buffer)) > BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8351 ? Qt : Qnil);
8353 /* Record if we are showing a region, so can make sure to
8354 update it fully at next redisplay. */
8355 w->region_showing = (!NILP (Vtransient_mark_mode)
8356 && (EQ (selected_window,
8357 current_buffer->last_selected_window)
8358 || highlight_nonselected_windows)
8359 && !NILP (XBUFFER (w->buffer)->mark_active)
8360 ? Fmarker_position (XBUFFER (w->buffer)->mark)
8361 : Qnil);
8363 w->window_end_valid = w->buffer;
8364 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
8365 last_arrow_string = Voverlay_arrow_string;
8366 if (frame_up_to_date_hook != 0)
8367 (*frame_up_to_date_hook) (sf);
8369 w->current_matrix->buffer = b;
8370 w->current_matrix->begv = BUF_BEGV (b);
8371 w->current_matrix->zv = BUF_ZV (b);
8374 update_mode_lines = 0;
8375 windows_or_buffers_changed = 0;
8378 /* Start SIGIO interrupts coming again. Having them off during the
8379 code above makes it less likely one will discard output, but not
8380 impossible, since there might be stuff in the system buffer here.
8381 But it is much hairier to try to do anything about that. */
8382 if (interrupt_input)
8383 request_sigio ();
8384 start_polling ();
8386 /* If a frame has become visible which was not before, redisplay
8387 again, so that we display it. Expose events for such a frame
8388 (which it gets when becoming visible) don't call the parts of
8389 redisplay constructing glyphs, so simply exposing a frame won't
8390 display anything in this case. So, we have to display these
8391 frames here explicitly. */
8392 if (!pause)
8394 Lisp_Object tail, frame;
8395 int new_count = 0;
8397 FOR_EACH_FRAME (tail, frame)
8399 int this_is_visible = 0;
8401 if (XFRAME (frame)->visible)
8402 this_is_visible = 1;
8403 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
8404 if (XFRAME (frame)->visible)
8405 this_is_visible = 1;
8407 if (this_is_visible)
8408 new_count++;
8411 if (new_count != number_of_visible_frames)
8412 windows_or_buffers_changed++;
8415 /* Change frame size now if a change is pending. */
8416 do_pending_window_change (1);
8418 /* If we just did a pending size change, or have additional
8419 visible frames, redisplay again. */
8420 if (windows_or_buffers_changed && !pause)
8421 goto retry;
8423 end_of_redisplay:;
8425 unbind_to (count, Qnil);
8429 /* Redisplay, but leave alone any recent echo area message unless
8430 another message has been requested in its place.
8432 This is useful in situations where you need to redisplay but no
8433 user action has occurred, making it inappropriate for the message
8434 area to be cleared. See tracking_off and
8435 wait_reading_process_input for examples of these situations. */
8437 void
8438 redisplay_preserve_echo_area ()
8440 if (!NILP (echo_area_buffer[1]))
8442 /* We have a previously displayed message, but no current
8443 message. Redisplay the previous message. */
8444 display_last_displayed_message_p = 1;
8445 redisplay_internal (1);
8446 display_last_displayed_message_p = 0;
8448 else
8449 redisplay_internal (1);
8453 /* Function registered with record_unwind_protect in
8454 redisplay_internal. Clears the flag indicating that a redisplay is
8455 in progress. */
8457 static Lisp_Object
8458 unwind_redisplay (old_redisplaying_p)
8459 Lisp_Object old_redisplaying_p;
8461 redisplaying_p = XFASTINT (old_redisplaying_p);
8462 return Qnil;
8466 /* Mark the display of windows in the window tree rooted at WINDOW as
8467 accurate or inaccurate. If FLAG is non-zero mark display of WINDOW
8468 as accurate. If FLAG is zero arrange for WINDOW to be redisplayed
8469 the next time redisplay_internal is called. */
8471 void
8472 mark_window_display_accurate (window, accurate_p)
8473 Lisp_Object window;
8474 int accurate_p;
8476 struct window *w;
8478 for (; !NILP (window); window = w->next)
8480 w = XWINDOW (window);
8482 if (BUFFERP (w->buffer))
8484 struct buffer *b = XBUFFER (w->buffer);
8486 XSETFASTINT (w->last_modified,
8487 accurate_p ? BUF_MODIFF (b) : 0);
8488 XSETFASTINT (w->last_overlay_modified,
8489 accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
8490 w->last_had_star = (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b)
8491 ? Qt : Qnil);
8493 #if 0 /* I don't think this is necessary because display_line does it.
8494 Let's check it. */
8495 /* Record if we are showing a region, so can make sure to
8496 update it fully at next redisplay. */
8497 w->region_showing
8498 = (!NILP (Vtransient_mark_mode)
8499 && (w == XWINDOW (current_buffer->last_selected_window)
8500 || highlight_nonselected_windows)
8501 && (!NILP (b->mark_active)
8502 ? Fmarker_position (b->mark)
8503 : Qnil));
8504 #endif
8506 if (accurate_p)
8508 b->clip_changed = 0;
8509 b->prevent_redisplay_optimizations_p = 0;
8510 w->current_matrix->buffer = b;
8511 w->current_matrix->begv = BUF_BEGV (b);
8512 w->current_matrix->zv = BUF_ZV (b);
8513 w->last_cursor = w->cursor;
8514 w->last_cursor_off_p = w->cursor_off_p;
8515 if (w == XWINDOW (selected_window))
8516 w->last_point = make_number (BUF_PT (b));
8517 else
8518 w->last_point = make_number (XMARKER (w->pointm)->charpos);
8522 w->window_end_valid = w->buffer;
8523 w->update_mode_line = Qnil;
8525 if (!NILP (w->vchild))
8526 mark_window_display_accurate (w->vchild, accurate_p);
8527 if (!NILP (w->hchild))
8528 mark_window_display_accurate (w->hchild, accurate_p);
8531 if (accurate_p)
8533 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
8534 last_arrow_string = Voverlay_arrow_string;
8536 else
8538 /* Force a thorough redisplay the next time by setting
8539 last_arrow_position and last_arrow_string to t, which is
8540 unequal to any useful value of Voverlay_arrow_... */
8541 last_arrow_position = Qt;
8542 last_arrow_string = Qt;
8547 /* Return value in display table DP (Lisp_Char_Table *) for character
8548 C. Since a display table doesn't have any parent, we don't have to
8549 follow parent. Do not call this function directly but use the
8550 macro DISP_CHAR_VECTOR. */
8552 Lisp_Object
8553 disp_char_vector (dp, c)
8554 struct Lisp_Char_Table *dp;
8555 int c;
8557 int code[4], i;
8558 Lisp_Object val;
8560 if (SINGLE_BYTE_CHAR_P (c))
8561 return (dp->contents[c]);
8563 SPLIT_CHAR (c, code[0], code[1], code[2]);
8564 if (code[1] < 32)
8565 code[1] = -1;
8566 else if (code[2] < 32)
8567 code[2] = -1;
8569 /* Here, the possible range of code[0] (== charset ID) is
8570 128..max_charset. Since the top level char table contains data
8571 for multibyte characters after 256th element, we must increment
8572 code[0] by 128 to get a correct index. */
8573 code[0] += 128;
8574 code[3] = -1; /* anchor */
8576 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
8578 val = dp->contents[code[i]];
8579 if (!SUB_CHAR_TABLE_P (val))
8580 return (NILP (val) ? dp->defalt : val);
8583 /* Here, val is a sub char table. We return the default value of
8584 it. */
8585 return (dp->defalt);
8590 /***********************************************************************
8591 Window Redisplay
8592 ***********************************************************************/
8594 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
8596 static void
8597 redisplay_windows (window)
8598 Lisp_Object window;
8600 while (!NILP (window))
8602 struct window *w = XWINDOW (window);
8604 if (!NILP (w->hchild))
8605 redisplay_windows (w->hchild);
8606 else if (!NILP (w->vchild))
8607 redisplay_windows (w->vchild);
8608 else
8609 redisplay_window (window, 0);
8611 window = w->next;
8616 /* Set cursor position of W. PT is assumed to be displayed in ROW.
8617 DELTA is the number of bytes by which positions recorded in ROW
8618 differ from current buffer positions. */
8620 void
8621 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
8622 struct window *w;
8623 struct glyph_row *row;
8624 struct glyph_matrix *matrix;
8625 int delta, delta_bytes, dy, dvpos;
8627 struct glyph *glyph = row->glyphs[TEXT_AREA];
8628 struct glyph *end = glyph + row->used[TEXT_AREA];
8629 int x = row->x;
8630 int pt_old = PT - delta;
8632 /* Skip over glyphs not having an object at the start of the row.
8633 These are special glyphs like truncation marks on terminal
8634 frames. */
8635 if (row->displays_text_p)
8636 while (glyph < end
8637 && INTEGERP (glyph->object)
8638 && glyph->charpos < 0)
8640 x += glyph->pixel_width;
8641 ++glyph;
8644 while (glyph < end
8645 && !INTEGERP (glyph->object)
8646 && (!BUFFERP (glyph->object)
8647 || glyph->charpos < pt_old))
8649 x += glyph->pixel_width;
8650 ++glyph;
8653 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
8654 w->cursor.x = x;
8655 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
8656 w->cursor.y = row->y + dy;
8658 if (w == XWINDOW (selected_window))
8660 if (!row->continued_p
8661 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
8662 && row->x == 0)
8664 this_line_buffer = XBUFFER (w->buffer);
8666 CHARPOS (this_line_start_pos)
8667 = MATRIX_ROW_START_CHARPOS (row) + delta;
8668 BYTEPOS (this_line_start_pos)
8669 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
8671 CHARPOS (this_line_end_pos)
8672 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
8673 BYTEPOS (this_line_end_pos)
8674 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
8676 this_line_y = w->cursor.y;
8677 this_line_pixel_height = row->height;
8678 this_line_vpos = w->cursor.vpos;
8679 this_line_start_x = row->x;
8681 else
8682 CHARPOS (this_line_start_pos) = 0;
8687 /* Run window scroll functions, if any, for WINDOW with new window
8688 start STARTP. Sets the window start of WINDOW to that position.
8690 We assume that the window's buffer is really current. */
8692 static INLINE struct text_pos
8693 run_window_scroll_functions (window, startp)
8694 Lisp_Object window;
8695 struct text_pos startp;
8697 struct window *w = XWINDOW (window);
8698 SET_MARKER_FROM_TEXT_POS (w->start, startp);
8700 if (current_buffer != XBUFFER (w->buffer))
8701 abort ();
8703 if (!NILP (Vwindow_scroll_functions))
8705 run_hook_with_args_2 (Qwindow_scroll_functions, window,
8706 make_number (CHARPOS (startp)));
8707 SET_TEXT_POS_FROM_MARKER (startp, w->start);
8708 /* In case the hook functions switch buffers. */
8709 if (current_buffer != XBUFFER (w->buffer))
8710 set_buffer_internal_1 (XBUFFER (w->buffer));
8713 return startp;
8717 /* Modify the desired matrix of window W and W->vscroll so that the
8718 line containing the cursor is fully visible. */
8720 static void
8721 make_cursor_line_fully_visible (w)
8722 struct window *w;
8724 struct glyph_matrix *matrix;
8725 struct glyph_row *row;
8726 int window_height, header_line_height;
8728 /* It's not always possible to find the cursor, e.g, when a window
8729 is full of overlay strings. Don't do anything in that case. */
8730 if (w->cursor.vpos < 0)
8731 return;
8733 matrix = w->desired_matrix;
8734 row = MATRIX_ROW (matrix, w->cursor.vpos);
8736 /* If the cursor row is not partially visible, there's nothing
8737 to do. */
8738 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
8739 return;
8741 /* If the row the cursor is in is taller than the window's height,
8742 it's not clear what to do, so do nothing. */
8743 window_height = window_box_height (w);
8744 if (row->height >= window_height)
8745 return;
8747 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
8749 int dy = row->height - row->visible_height;
8750 w->vscroll = 0;
8751 w->cursor.y += dy;
8752 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
8754 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
8756 int dy = - (row->height - row->visible_height);
8757 w->vscroll = dy;
8758 w->cursor.y += dy;
8759 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
8762 /* When we change the cursor y-position of the selected window,
8763 change this_line_y as well so that the display optimization for
8764 the cursor line of the selected window in redisplay_internal uses
8765 the correct y-position. */
8766 if (w == XWINDOW (selected_window))
8767 this_line_y = w->cursor.y;
8771 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
8772 non-zero means only WINDOW is redisplayed in redisplay_internal.
8773 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
8774 in redisplay_window to bring a partially visible line into view in
8775 the case that only the cursor has moved.
8777 Value is
8779 1 if scrolling succeeded
8781 0 if scrolling didn't find point.
8783 -1 if new fonts have been loaded so that we must interrupt
8784 redisplay, adjust glyph matrices, and try again. */
8786 static int
8787 try_scrolling (window, just_this_one_p, scroll_conservatively,
8788 scroll_step, temp_scroll_step)
8789 Lisp_Object window;
8790 int just_this_one_p;
8791 int scroll_conservatively, scroll_step;
8792 int temp_scroll_step;
8794 struct window *w = XWINDOW (window);
8795 struct frame *f = XFRAME (w->frame);
8796 struct text_pos scroll_margin_pos;
8797 struct text_pos pos;
8798 struct text_pos startp;
8799 struct it it;
8800 Lisp_Object window_end;
8801 int this_scroll_margin;
8802 int dy = 0;
8803 int scroll_max;
8804 int rc;
8805 int amount_to_scroll = 0;
8806 Lisp_Object aggressive;
8807 int height;
8809 #if GLYPH_DEBUG
8810 debug_method_add (w, "try_scrolling");
8811 #endif
8813 SET_TEXT_POS_FROM_MARKER (startp, w->start);
8815 /* Compute scroll margin height in pixels. We scroll when point is
8816 within this distance from the top or bottom of the window. */
8817 if (scroll_margin > 0)
8819 this_scroll_margin = min (scroll_margin, XINT (w->height) / 4);
8820 this_scroll_margin *= CANON_Y_UNIT (f);
8822 else
8823 this_scroll_margin = 0;
8825 /* Compute how much we should try to scroll maximally to bring point
8826 into view. */
8827 if (scroll_step || scroll_conservatively || temp_scroll_step)
8828 scroll_max = max (scroll_step,
8829 max (scroll_conservatively, temp_scroll_step));
8830 else if (NUMBERP (current_buffer->scroll_down_aggressively)
8831 || NUMBERP (current_buffer->scroll_up_aggressively))
8832 /* We're trying to scroll because of aggressive scrolling
8833 but no scroll_step is set. Choose an arbitrary one. Maybe
8834 there should be a variable for this. */
8835 scroll_max = 10;
8836 else
8837 scroll_max = 0;
8838 scroll_max *= CANON_Y_UNIT (f);
8840 /* Decide whether we have to scroll down. Start at the window end
8841 and move this_scroll_margin up to find the position of the scroll
8842 margin. */
8843 window_end = Fwindow_end (window, Qt);
8844 CHARPOS (scroll_margin_pos) = XINT (window_end);
8845 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
8846 if (this_scroll_margin)
8848 start_display (&it, w, scroll_margin_pos);
8849 move_it_vertically (&it, - this_scroll_margin);
8850 scroll_margin_pos = it.current.pos;
8853 if (PT >= CHARPOS (scroll_margin_pos))
8855 int y0;
8856 #if 0
8857 int line_height;
8858 #endif
8860 /* Point is in the scroll margin at the bottom of the window, or
8861 below. Compute a new window start that makes point visible. */
8863 /* Compute the distance from the scroll margin to PT.
8864 Give up if the distance is greater than scroll_max. */
8865 start_display (&it, w, scroll_margin_pos);
8866 y0 = it.current_y;
8867 move_it_to (&it, PT, 0, it.last_visible_y, -1,
8868 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
8869 #if 0 /* Taking the line's height into account here looks wrong. */
8870 line_height = (it.max_ascent + it.max_descent
8871 ? it.max_ascent + it.max_descent
8872 : last_height);
8873 dy = it.current_y + line_height - y0;
8874 #else
8875 /* With a scroll_margin of 0, scroll_margin_pos is at the window
8876 end, which is one line below the window. The iterator's
8877 current_y will be same as y0 in that case, but we have to
8878 scroll a line to make PT visible. That's the reason why 1 is
8879 added below. */
8880 dy = 1 + it.current_y - y0;
8881 #endif
8883 if (dy > scroll_max)
8884 return 0;
8886 /* Move the window start down. If scrolling conservatively,
8887 move it just enough down to make point visible. If
8888 scroll_step is set, move it down by scroll_step. */
8889 start_display (&it, w, startp);
8891 if (scroll_conservatively)
8892 amount_to_scroll =
8893 max (dy, CANON_Y_UNIT (f) * max (scroll_step, temp_scroll_step));
8894 else if (scroll_step || temp_scroll_step)
8895 amount_to_scroll = scroll_max;
8896 else
8898 aggressive = current_buffer->scroll_down_aggressively;
8899 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
8900 - WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w));
8901 if (NUMBERP (aggressive))
8902 amount_to_scroll = XFLOATINT (aggressive) * height;
8905 if (amount_to_scroll <= 0)
8906 return 0;
8908 move_it_vertically (&it, amount_to_scroll);
8909 startp = it.current.pos;
8911 else
8913 /* See if point is inside the scroll margin at the top of the
8914 window. */
8915 scroll_margin_pos = startp;
8916 if (this_scroll_margin)
8918 start_display (&it, w, startp);
8919 move_it_vertically (&it, this_scroll_margin);
8920 scroll_margin_pos = it.current.pos;
8923 if (PT < CHARPOS (scroll_margin_pos))
8925 /* Point is in the scroll margin at the top of the window or
8926 above what is displayed in the window. */
8927 int y0;
8929 /* Compute the vertical distance from PT to the scroll
8930 margin position. Give up if distance is greater than
8931 scroll_max. */
8932 SET_TEXT_POS (pos, PT, PT_BYTE);
8933 start_display (&it, w, pos);
8934 y0 = it.current_y;
8935 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
8936 it.last_visible_y, -1,
8937 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
8938 dy = it.current_y - y0;
8939 if (dy > scroll_max)
8940 return 0;
8942 /* Compute new window start. */
8943 start_display (&it, w, startp);
8945 if (scroll_conservatively)
8946 amount_to_scroll =
8947 max (dy, CANON_Y_UNIT (f) * max (scroll_step, temp_scroll_step));
8948 else if (scroll_step || temp_scroll_step)
8949 amount_to_scroll = scroll_max;
8950 else
8952 aggressive = current_buffer->scroll_up_aggressively;
8953 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
8954 - WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w));
8955 if (NUMBERP (aggressive))
8956 amount_to_scroll = XFLOATINT (aggressive) * height;
8959 if (amount_to_scroll <= 0)
8960 return 0;
8962 move_it_vertically (&it, - amount_to_scroll);
8963 startp = it.current.pos;
8967 /* Run window scroll functions. */
8968 startp = run_window_scroll_functions (window, startp);
8970 /* Display the window. Give up if new fonts are loaded, or if point
8971 doesn't appear. */
8972 if (!try_window (window, startp))
8973 rc = -1;
8974 else if (w->cursor.vpos < 0)
8976 clear_glyph_matrix (w->desired_matrix);
8977 rc = 0;
8979 else
8981 /* Maybe forget recorded base line for line number display. */
8982 if (!just_this_one_p
8983 || current_buffer->clip_changed
8984 || BEG_UNCHANGED < CHARPOS (startp))
8985 w->base_line_number = Qnil;
8987 /* If cursor ends up on a partially visible line, shift display
8988 lines up or down. */
8989 make_cursor_line_fully_visible (w);
8990 rc = 1;
8993 return rc;
8997 /* Compute a suitable window start for window W if display of W starts
8998 on a continuation line. Value is non-zero if a new window start
8999 was computed.
9001 The new window start will be computed, based on W's width, starting
9002 from the start of the continued line. It is the start of the
9003 screen line with the minimum distance from the old start W->start. */
9005 static int
9006 compute_window_start_on_continuation_line (w)
9007 struct window *w;
9009 struct text_pos pos, start_pos;
9010 int window_start_changed_p = 0;
9012 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
9014 /* If window start is on a continuation line... Window start may be
9015 < BEGV in case there's invisible text at the start of the
9016 buffer (M-x rmail, for example). */
9017 if (CHARPOS (start_pos) > BEGV
9018 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
9020 struct it it;
9021 struct glyph_row *row;
9023 /* Handle the case that the window start is out of range. */
9024 if (CHARPOS (start_pos) < BEGV)
9025 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
9026 else if (CHARPOS (start_pos) > ZV)
9027 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
9029 /* Find the start of the continued line. This should be fast
9030 because scan_buffer is fast (newline cache). */
9031 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
9032 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
9033 row, DEFAULT_FACE_ID);
9034 reseat_at_previous_visible_line_start (&it);
9036 /* If the line start is "too far" away from the window start,
9037 say it takes too much time to compute a new window start. */
9038 if (CHARPOS (start_pos) - IT_CHARPOS (it)
9039 < XFASTINT (w->height) * XFASTINT (w->width))
9041 int min_distance, distance;
9043 /* Move forward by display lines to find the new window
9044 start. If window width was enlarged, the new start can
9045 be expected to be > the old start. If window width was
9046 decreased, the new window start will be < the old start.
9047 So, we're looking for the display line start with the
9048 minimum distance from the old window start. */
9049 pos = it.current.pos;
9050 min_distance = INFINITY;
9051 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
9052 distance < min_distance)
9054 min_distance = distance;
9055 pos = it.current.pos;
9056 move_it_by_lines (&it, 1, 0);
9059 /* Set the window start there. */
9060 SET_MARKER_FROM_TEXT_POS (w->start, pos);
9061 window_start_changed_p = 1;
9065 return window_start_changed_p;
9069 /* Try cursor movement in case text has not changes in window WINDOW,
9070 with window start STARTP. Value is
9072 1 if successful
9074 0 if this method cannot be used
9076 -1 if we know we have to scroll the display. *SCROLL_STEP is
9077 set to 1, under certain circumstances, if we want to scroll as
9078 if scroll-step were set to 1. See the code. */
9080 static int
9081 try_cursor_movement (window, startp, scroll_step)
9082 Lisp_Object window;
9083 struct text_pos startp;
9084 int *scroll_step;
9086 struct window *w = XWINDOW (window);
9087 struct frame *f = XFRAME (w->frame);
9088 int rc = 0;
9090 /* Handle case where text has not changed, only point, and it has
9091 not moved off the frame. */
9092 if (/* Point may be in this window. */
9093 PT >= CHARPOS (startp)
9094 /* If we don't check this, we are called to move the cursor in a
9095 horizontally split window with a current matrix that doesn't
9096 fit the display. */
9097 && !windows_or_buffers_changed
9098 /* Selective display hasn't changed. */
9099 && !current_buffer->clip_changed
9100 /* If force-mode-line-update was called, really redisplay;
9101 that's how redisplay is forced after e.g. changing
9102 buffer-invisibility-spec. */
9103 && NILP (w->update_mode_line)
9104 /* Can't use this case if highlighting a region. When a
9105 region exists, cursor movement has to do more than just
9106 set the cursor. */
9107 && !(!NILP (Vtransient_mark_mode)
9108 && !NILP (current_buffer->mark_active))
9109 && NILP (w->region_showing)
9110 && NILP (Vshow_trailing_whitespace)
9111 /* Right after splitting windows, last_point may be nil. */
9112 && INTEGERP (w->last_point)
9113 /* This code is not used for mini-buffer for the sake of the case
9114 of redisplaying to replace an echo area message; since in
9115 that case the mini-buffer contents per se are usually
9116 unchanged. This code is of no real use in the mini-buffer
9117 since the handling of this_line_start_pos, etc., in redisplay
9118 handles the same cases. */
9119 && !EQ (window, minibuf_window)
9120 /* When splitting windows or for new windows, it happens that
9121 redisplay is called with a nil window_end_vpos or one being
9122 larger than the window. This should really be fixed in
9123 window.c. I don't have this on my list, now, so we do
9124 approximately the same as the old redisplay code. --gerd. */
9125 && INTEGERP (w->window_end_vpos)
9126 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
9127 && (FRAME_WINDOW_P (f)
9128 || !MARKERP (Voverlay_arrow_position)
9129 || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
9131 int this_scroll_margin;
9132 struct glyph_row *row;
9134 #if GLYPH_DEBUG
9135 debug_method_add (w, "cursor movement");
9136 #endif
9138 /* Scroll if point within this distance from the top or bottom
9139 of the window. This is a pixel value. */
9140 this_scroll_margin = max (0, scroll_margin);
9141 this_scroll_margin = min (this_scroll_margin, XFASTINT (w->height) / 4);
9142 this_scroll_margin *= CANON_Y_UNIT (f);
9144 /* Start with the row the cursor was displayed during the last
9145 not paused redisplay. Give up if that row is not valid. */
9146 if (w->last_cursor.vpos < 0
9147 || w->last_cursor.vpos >= w->current_matrix->nrows)
9148 rc = -1;
9149 else
9151 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
9152 if (row->mode_line_p)
9153 ++row;
9154 if (!row->enabled_p)
9155 rc = -1;
9158 if (rc == 0)
9160 int scroll_p = 0;
9161 int last_y = window_text_bottom_y (w) - this_scroll_margin;
9164 if (PT > XFASTINT (w->last_point))
9166 /* Point has moved forward. */
9167 while (MATRIX_ROW_END_CHARPOS (row) < PT
9168 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
9170 xassert (row->enabled_p);
9171 ++row;
9174 /* The end position of a row equals the start position
9175 of the next row. If PT is there, we would rather
9176 display it in the next line. */
9177 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
9178 && MATRIX_ROW_END_CHARPOS (row) == PT
9179 && !cursor_row_p (w, row))
9180 ++row;
9182 /* If within the scroll margin, scroll. Note that
9183 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
9184 the next line would be drawn, and that
9185 this_scroll_margin can be zero. */
9186 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
9187 || PT > MATRIX_ROW_END_CHARPOS (row)
9188 /* Line is completely visible last line in window
9189 and PT is to be set in the next line. */
9190 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
9191 && PT == MATRIX_ROW_END_CHARPOS (row)
9192 && !row->ends_at_zv_p
9193 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
9194 scroll_p = 1;
9196 else if (PT < XFASTINT (w->last_point))
9198 /* Cursor has to be moved backward. Note that PT >=
9199 CHARPOS (startp) because of the outer
9200 if-statement. */
9201 while (!row->mode_line_p
9202 && (MATRIX_ROW_START_CHARPOS (row) > PT
9203 || (MATRIX_ROW_START_CHARPOS (row) == PT
9204 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
9205 && (row->y > this_scroll_margin
9206 || CHARPOS (startp) == BEGV))
9208 xassert (row->enabled_p);
9209 --row;
9212 /* Consider the following case: Window starts at BEGV,
9213 there is invisible, intangible text at BEGV, so that
9214 display starts at some point START > BEGV. It can
9215 happen that we are called with PT somewhere between
9216 BEGV and START. Try to handle that case. */
9217 if (row < w->current_matrix->rows
9218 || row->mode_line_p)
9220 row = w->current_matrix->rows;
9221 if (row->mode_line_p)
9222 ++row;
9225 /* Due to newlines in overlay strings, we may have to
9226 skip forward over overlay strings. */
9227 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
9228 && MATRIX_ROW_END_CHARPOS (row) == PT
9229 && !cursor_row_p (w, row))
9230 ++row;
9232 /* If within the scroll margin, scroll. */
9233 if (row->y < this_scroll_margin
9234 && CHARPOS (startp) != BEGV)
9235 scroll_p = 1;
9238 if (PT < MATRIX_ROW_START_CHARPOS (row)
9239 || PT > MATRIX_ROW_END_CHARPOS (row))
9241 /* if PT is not in the glyph row, give up. */
9242 rc = -1;
9244 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
9246 /* If we end up in a partially visible line, let's make it
9247 fully visible, except when it's taller than the window,
9248 in which case we can't do much about it. */
9249 if (row->height > window_box_height (w))
9251 *scroll_step = 1;
9252 rc = -1;
9254 else
9256 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
9257 try_window (window, startp);
9258 make_cursor_line_fully_visible (w);
9259 rc = 1;
9262 else if (scroll_p)
9263 rc = -1;
9264 else
9266 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
9267 rc = 1;
9272 return rc;
9276 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
9277 selected_window is redisplayed. */
9279 static void
9280 redisplay_window (window, just_this_one_p)
9281 Lisp_Object window;
9282 int just_this_one_p;
9284 struct window *w = XWINDOW (window);
9285 struct frame *f = XFRAME (w->frame);
9286 struct buffer *buffer = XBUFFER (w->buffer);
9287 struct buffer *old = current_buffer;
9288 struct text_pos lpoint, opoint, startp;
9289 int update_mode_line;
9290 int tem;
9291 struct it it;
9292 /* Record it now because it's overwritten. */
9293 int current_matrix_up_to_date_p = 0;
9294 int temp_scroll_step = 0;
9295 int count = BINDING_STACK_SIZE ();
9296 int rc;
9298 SET_TEXT_POS (lpoint, PT, PT_BYTE);
9299 opoint = lpoint;
9301 /* W must be a leaf window here. */
9302 xassert (!NILP (w->buffer));
9303 #if GLYPH_DEBUG
9304 *w->desired_matrix->method = 0;
9305 #endif
9307 specbind (Qinhibit_point_motion_hooks, Qt);
9309 reconsider_clip_changes (w, buffer);
9311 /* Has the mode line to be updated? */
9312 update_mode_line = (!NILP (w->update_mode_line)
9313 || update_mode_lines
9314 || buffer->clip_changed);
9316 if (MINI_WINDOW_P (w))
9318 if (w == XWINDOW (echo_area_window)
9319 && !NILP (echo_area_buffer[0]))
9321 if (update_mode_line)
9322 /* We may have to update a tty frame's menu bar or a
9323 tool-bar. Example `M-x C-h C-h C-g'. */
9324 goto finish_menu_bars;
9325 else
9326 /* We've already displayed the echo area glyphs in this window. */
9327 goto finish_scroll_bars;
9329 else if (w != XWINDOW (minibuf_window))
9331 /* W is a mini-buffer window, but it's not the currently
9332 active one, so clear it. */
9333 int yb = window_text_bottom_y (w);
9334 struct glyph_row *row;
9335 int y;
9337 for (y = 0, row = w->desired_matrix->rows;
9338 y < yb;
9339 y += row->height, ++row)
9340 blank_row (w, row, y);
9341 goto finish_scroll_bars;
9345 /* Otherwise set up data on this window; select its buffer and point
9346 value. */
9347 /* Really select the buffer, for the sake of buffer-local
9348 variables. */
9349 set_buffer_internal_1 (XBUFFER (w->buffer));
9350 SET_TEXT_POS (opoint, PT, PT_BYTE);
9352 current_matrix_up_to_date_p
9353 = (!NILP (w->window_end_valid)
9354 && !current_buffer->clip_changed
9355 && XFASTINT (w->last_modified) >= MODIFF
9356 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
9358 /* When windows_or_buffers_changed is non-zero, we can't rely on
9359 the window end being valid, so set it to nil there. */
9360 if (windows_or_buffers_changed)
9362 /* If window starts on a continuation line, maybe adjust the
9363 window start in case the window's width changed. */
9364 if (XMARKER (w->start)->buffer == current_buffer)
9365 compute_window_start_on_continuation_line (w);
9367 w->window_end_valid = Qnil;
9370 /* Some sanity checks. */
9371 CHECK_WINDOW_END (w);
9372 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
9373 abort ();
9374 if (BYTEPOS (opoint) < CHARPOS (opoint))
9375 abort ();
9377 /* If %c is in mode line, update it if needed. */
9378 if (!NILP (w->column_number_displayed)
9379 /* This alternative quickly identifies a common case
9380 where no change is needed. */
9381 && !(PT == XFASTINT (w->last_point)
9382 && XFASTINT (w->last_modified) >= MODIFF
9383 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9384 && XFASTINT (w->column_number_displayed) != current_column ())
9385 update_mode_line = 1;
9387 /* Count number of windows showing the selected buffer. An indirect
9388 buffer counts as its base buffer. */
9389 if (!just_this_one_p)
9391 struct buffer *current_base, *window_base;
9392 current_base = current_buffer;
9393 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
9394 if (current_base->base_buffer)
9395 current_base = current_base->base_buffer;
9396 if (window_base->base_buffer)
9397 window_base = window_base->base_buffer;
9398 if (current_base == window_base)
9399 buffer_shared++;
9402 /* Point refers normally to the selected window. For any other
9403 window, set up appropriate value. */
9404 if (!EQ (window, selected_window))
9406 int new_pt = XMARKER (w->pointm)->charpos;
9407 int new_pt_byte = marker_byte_position (w->pointm);
9408 if (new_pt < BEGV)
9410 new_pt = BEGV;
9411 new_pt_byte = BEGV_BYTE;
9412 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
9414 else if (new_pt > (ZV - 1))
9416 new_pt = ZV;
9417 new_pt_byte = ZV_BYTE;
9418 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
9421 /* We don't use SET_PT so that the point-motion hooks don't run. */
9422 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
9425 /* If any of the character widths specified in the display table
9426 have changed, invalidate the width run cache. It's true that
9427 this may be a bit late to catch such changes, but the rest of
9428 redisplay goes (non-fatally) haywire when the display table is
9429 changed, so why should we worry about doing any better? */
9430 if (current_buffer->width_run_cache)
9432 struct Lisp_Char_Table *disptab = buffer_display_table ();
9434 if (! disptab_matches_widthtab (disptab,
9435 XVECTOR (current_buffer->width_table)))
9437 invalidate_region_cache (current_buffer,
9438 current_buffer->width_run_cache,
9439 BEG, Z);
9440 recompute_width_table (current_buffer, disptab);
9444 /* If window-start is screwed up, choose a new one. */
9445 if (XMARKER (w->start)->buffer != current_buffer)
9446 goto recenter;
9448 SET_TEXT_POS_FROM_MARKER (startp, w->start);
9450 /* If someone specified a new starting point but did not insist,
9451 check whether it can be used. */
9452 if (!NILP (w->optional_new_start)
9453 && CHARPOS (startp) >= BEGV
9454 && CHARPOS (startp) <= ZV)
9456 w->optional_new_start = Qnil;
9457 start_display (&it, w, startp);
9458 move_it_to (&it, PT, 0, it.last_visible_y, -1,
9459 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
9460 if (IT_CHARPOS (it) == PT)
9461 w->force_start = Qt;
9464 /* Handle case where place to start displaying has been specified,
9465 unless the specified location is outside the accessible range. */
9466 if (!NILP (w->force_start)
9467 || w->frozen_window_start_p)
9469 w->force_start = Qnil;
9470 w->vscroll = 0;
9471 w->window_end_valid = Qnil;
9473 /* Forget any recorded base line for line number display. */
9474 if (!current_matrix_up_to_date_p
9475 || current_buffer->clip_changed)
9476 w->base_line_number = Qnil;
9478 /* Redisplay the mode line. Select the buffer properly for that.
9479 Also, run the hook window-scroll-functions
9480 because we have scrolled. */
9481 /* Note, we do this after clearing force_start because
9482 if there's an error, it is better to forget about force_start
9483 than to get into an infinite loop calling the hook functions
9484 and having them get more errors. */
9485 if (!update_mode_line
9486 || ! NILP (Vwindow_scroll_functions))
9488 update_mode_line = 1;
9489 w->update_mode_line = Qt;
9490 startp = run_window_scroll_functions (window, startp);
9493 XSETFASTINT (w->last_modified, 0);
9494 XSETFASTINT (w->last_overlay_modified, 0);
9495 if (CHARPOS (startp) < BEGV)
9496 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
9497 else if (CHARPOS (startp) > ZV)
9498 SET_TEXT_POS (startp, ZV, ZV_BYTE);
9500 /* Redisplay, then check if cursor has been set during the
9501 redisplay. Give up if new fonts were loaded. */
9502 if (!try_window (window, startp))
9504 w->force_start = Qt;
9505 clear_glyph_matrix (w->desired_matrix);
9506 goto restore_buffers;
9509 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
9511 /* If point does not appear, try to move point so it does
9512 appear. The desired matrix has been built above, so we
9513 can use it here. */
9514 int window_height;
9515 struct glyph_row *row;
9517 window_height = window_box_height (w) / 2;
9518 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
9519 while (MATRIX_ROW_BOTTOM_Y (row) < window_height)
9520 ++row;
9522 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
9523 MATRIX_ROW_START_BYTEPOS (row));
9525 if (w != XWINDOW (selected_window))
9526 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
9527 else if (current_buffer == old)
9528 SET_TEXT_POS (lpoint, PT, PT_BYTE);
9530 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
9532 /* If we are highlighting the region, then we just changed
9533 the region, so redisplay to show it. */
9534 if (!NILP (Vtransient_mark_mode)
9535 && !NILP (current_buffer->mark_active))
9537 clear_glyph_matrix (w->desired_matrix);
9538 if (!try_window (window, startp))
9539 goto restore_buffers;
9543 make_cursor_line_fully_visible (w);
9544 #if GLYPH_DEBUG
9545 debug_method_add (w, "forced window start");
9546 #endif
9547 goto done;
9550 /* Handle case where text has not changed, only point, and it has
9551 not moved off the frame. */
9552 if (current_matrix_up_to_date_p
9553 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
9554 rc != 0))
9556 if (rc == -1)
9557 goto try_to_scroll;
9558 else
9559 goto done;
9561 /* If current starting point was originally the beginning of a line
9562 but no longer is, find a new starting point. */
9563 else if (!NILP (w->start_at_line_beg)
9564 && !(CHARPOS (startp) <= BEGV
9565 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
9567 #if GLYPH_DEBUG
9568 debug_method_add (w, "recenter 1");
9569 #endif
9570 goto recenter;
9573 /* Try scrolling with try_window_id. */
9574 else if (/* Windows and buffers haven't changed. */
9575 !windows_or_buffers_changed
9576 /* Window must be either use window-based redisplay or
9577 be full width. */
9578 && (FRAME_WINDOW_P (f)
9579 || (line_ins_del_ok && WINDOW_FULL_WIDTH_P (w)))
9580 && !MINI_WINDOW_P (w)
9581 /* Point is not known NOT to appear in window. */
9582 && PT >= CHARPOS (startp)
9583 && XFASTINT (w->last_modified)
9584 /* Window is not hscrolled. */
9585 && XFASTINT (w->hscroll) == 0
9586 /* Selective display has not changed. */
9587 && !current_buffer->clip_changed
9588 /* Current matrix is up to date. */
9589 && !NILP (w->window_end_valid)
9590 /* Can't use this case if highlighting a region because
9591 a cursor movement will do more than just set the cursor. */
9592 && !(!NILP (Vtransient_mark_mode)
9593 && !NILP (current_buffer->mark_active))
9594 && NILP (w->region_showing)
9595 && NILP (Vshow_trailing_whitespace)
9596 /* Overlay arrow position and string not changed. */
9597 && EQ (last_arrow_position, COERCE_MARKER (Voverlay_arrow_position))
9598 && EQ (last_arrow_string, Voverlay_arrow_string)
9599 /* Value is > 0 if update has been done, it is -1 if we
9600 know that the same window start will not work. It is 0
9601 if unsuccessful for some other reason. */
9602 && (tem = try_window_id (w)) != 0)
9604 #if GLYPH_DEBUG
9605 debug_method_add (w, "try_window_id %d", tem);
9606 #endif
9608 if (fonts_changed_p)
9609 goto restore_buffers;
9610 if (tem > 0)
9611 goto done;
9613 /* Otherwise try_window_id has returned -1 which means that we
9614 don't want the alternative below this comment to execute. */
9616 else if (CHARPOS (startp) >= BEGV
9617 && CHARPOS (startp) <= ZV
9618 && PT >= CHARPOS (startp)
9619 && (CHARPOS (startp) < ZV
9620 /* Avoid starting at end of buffer. */
9621 || CHARPOS (startp) == BEGV
9622 || (XFASTINT (w->last_modified) >= MODIFF
9623 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
9625 #if GLYPH_DEBUG
9626 debug_method_add (w, "same window start");
9627 #endif
9629 /* Try to redisplay starting at same place as before.
9630 If point has not moved off frame, accept the results. */
9631 if (!current_matrix_up_to_date_p
9632 /* Don't use try_window_reusing_current_matrix in this case
9633 because a window scroll function can have changed the
9634 buffer. */
9635 || !NILP (Vwindow_scroll_functions)
9636 || MINI_WINDOW_P (w)
9637 || !try_window_reusing_current_matrix (w))
9639 IF_DEBUG (debug_method_add (w, "1"));
9640 try_window (window, startp);
9643 if (fonts_changed_p)
9644 goto restore_buffers;
9646 if (w->cursor.vpos >= 0)
9648 if (!just_this_one_p
9649 || current_buffer->clip_changed
9650 || BEG_UNCHANGED < CHARPOS (startp))
9651 /* Forget any recorded base line for line number display. */
9652 w->base_line_number = Qnil;
9654 make_cursor_line_fully_visible (w);
9655 goto done;
9657 else
9658 clear_glyph_matrix (w->desired_matrix);
9661 try_to_scroll:
9663 XSETFASTINT (w->last_modified, 0);
9664 XSETFASTINT (w->last_overlay_modified, 0);
9666 /* Redisplay the mode line. Select the buffer properly for that. */
9667 if (!update_mode_line)
9669 update_mode_line = 1;
9670 w->update_mode_line = Qt;
9673 /* Try to scroll by specified few lines. */
9674 if ((scroll_conservatively
9675 || scroll_step
9676 || temp_scroll_step
9677 || NUMBERP (current_buffer->scroll_up_aggressively)
9678 || NUMBERP (current_buffer->scroll_down_aggressively))
9679 && !current_buffer->clip_changed
9680 && CHARPOS (startp) >= BEGV
9681 && CHARPOS (startp) <= ZV)
9683 /* The function returns -1 if new fonts were loaded, 1 if
9684 successful, 0 if not successful. */
9685 int rc = try_scrolling (window, just_this_one_p,
9686 scroll_conservatively,
9687 scroll_step,
9688 temp_scroll_step);
9689 if (rc > 0)
9690 goto done;
9691 else if (rc < 0)
9692 goto restore_buffers;
9695 /* Finally, just choose place to start which centers point */
9697 recenter:
9699 #if GLYPH_DEBUG
9700 debug_method_add (w, "recenter");
9701 #endif
9703 /* w->vscroll = 0; */
9705 /* Forget any previously recorded base line for line number display. */
9706 if (!current_matrix_up_to_date_p
9707 || current_buffer->clip_changed)
9708 w->base_line_number = Qnil;
9710 /* Move backward half the height of the window. */
9711 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
9712 it.current_y = it.last_visible_y;
9713 move_it_vertically_backward (&it, it.last_visible_y / 2);
9714 xassert (IT_CHARPOS (it) >= BEGV);
9716 /* The function move_it_vertically_backward may move over more
9717 than the specified y-distance. If it->w is small, e.g. a
9718 mini-buffer window, we may end up in front of the window's
9719 display area. Start displaying at the start of the line
9720 containing PT in this case. */
9721 if (it.current_y <= 0)
9723 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
9724 move_it_vertically (&it, 0);
9725 xassert (IT_CHARPOS (it) <= PT);
9726 it.current_y = 0;
9729 it.current_x = it.hpos = 0;
9731 /* Set startp here explicitly in case that helps avoid an infinite loop
9732 in case the window-scroll-functions functions get errors. */
9733 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
9735 /* Run scroll hooks. */
9736 startp = run_window_scroll_functions (window, it.current.pos);
9738 /* Redisplay the window. */
9739 if (!current_matrix_up_to_date_p
9740 || windows_or_buffers_changed
9741 /* Don't use try_window_reusing_current_matrix in this case
9742 because it can have changed the buffer. */
9743 || !NILP (Vwindow_scroll_functions)
9744 || !just_this_one_p
9745 || MINI_WINDOW_P (w)
9746 || !try_window_reusing_current_matrix (w))
9747 try_window (window, startp);
9749 /* If new fonts have been loaded (due to fontsets), give up. We
9750 have to start a new redisplay since we need to re-adjust glyph
9751 matrices. */
9752 if (fonts_changed_p)
9753 goto restore_buffers;
9755 /* If cursor did not appear assume that the middle of the window is
9756 in the first line of the window. Do it again with the next line.
9757 (Imagine a window of height 100, displaying two lines of height
9758 60. Moving back 50 from it->last_visible_y will end in the first
9759 line.) */
9760 if (w->cursor.vpos < 0)
9762 if (!NILP (w->window_end_valid)
9763 && PT >= Z - XFASTINT (w->window_end_pos))
9765 clear_glyph_matrix (w->desired_matrix);
9766 move_it_by_lines (&it, 1, 0);
9767 try_window (window, it.current.pos);
9769 else if (PT < IT_CHARPOS (it))
9771 clear_glyph_matrix (w->desired_matrix);
9772 move_it_by_lines (&it, -1, 0);
9773 try_window (window, it.current.pos);
9775 else
9777 /* Not much we can do about it. */
9781 /* Consider the following case: Window starts at BEGV, there is
9782 invisible, intangible text at BEGV, so that display starts at
9783 some point START > BEGV. It can happen that we are called with
9784 PT somewhere between BEGV and START. Try to handle that case. */
9785 if (w->cursor.vpos < 0)
9787 struct glyph_row *row = w->current_matrix->rows;
9788 if (row->mode_line_p)
9789 ++row;
9790 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
9793 make_cursor_line_fully_visible (w);
9795 done:
9797 SET_TEXT_POS_FROM_MARKER (startp, w->start);
9798 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
9799 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
9800 ? Qt : Qnil);
9802 /* Display the mode line, if we must. */
9803 if ((update_mode_line
9804 /* If window not full width, must redo its mode line
9805 if (a) the window to its side is being redone and
9806 (b) we do a frame-based redisplay. This is a consequence
9807 of how inverted lines are drawn in frame-based redisplay. */
9808 || (!just_this_one_p
9809 && !FRAME_WINDOW_P (f)
9810 && !WINDOW_FULL_WIDTH_P (w))
9811 /* Line number to display. */
9812 || INTEGERP (w->base_line_pos)
9813 /* Column number is displayed and different from the one displayed. */
9814 || (!NILP (w->column_number_displayed)
9815 && XFASTINT (w->column_number_displayed) != current_column ()))
9816 /* This means that the window has a mode line. */
9817 && (WINDOW_WANTS_MODELINE_P (w)
9818 || WINDOW_WANTS_HEADER_LINE_P (w)))
9820 Lisp_Object old_selected_frame;
9822 old_selected_frame = selected_frame;
9824 XSETFRAME (selected_frame, f);
9825 display_mode_lines (w);
9826 selected_frame = old_selected_frame;
9828 /* If mode line height has changed, arrange for a thorough
9829 immediate redisplay using the correct mode line height. */
9830 if (WINDOW_WANTS_MODELINE_P (w)
9831 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
9833 fonts_changed_p = 1;
9834 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
9835 = DESIRED_MODE_LINE_HEIGHT (w);
9838 /* If top line height has changed, arrange for a thorough
9839 immediate redisplay using the correct mode line height. */
9840 if (WINDOW_WANTS_HEADER_LINE_P (w)
9841 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
9843 fonts_changed_p = 1;
9844 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
9845 = DESIRED_HEADER_LINE_HEIGHT (w);
9848 if (fonts_changed_p)
9849 goto restore_buffers;
9852 if (!line_number_displayed
9853 && !BUFFERP (w->base_line_pos))
9855 w->base_line_pos = Qnil;
9856 w->base_line_number = Qnil;
9859 finish_menu_bars:
9861 /* When we reach a frame's selected window, redo the frame's menu bar. */
9862 if (update_mode_line
9863 && EQ (FRAME_SELECTED_WINDOW (f), window))
9865 int redisplay_menu_p = 0;
9867 if (FRAME_WINDOW_P (f))
9869 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (macintosh)
9870 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
9871 #else
9872 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
9873 #endif
9875 else
9876 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
9878 if (redisplay_menu_p)
9879 display_menu_bar (w);
9881 #ifdef HAVE_WINDOW_SYSTEM
9882 if (WINDOWP (f->tool_bar_window)
9883 && (FRAME_TOOL_BAR_LINES (f) > 0
9884 || auto_resize_tool_bars_p))
9885 redisplay_tool_bar (f);
9886 #endif
9889 finish_scroll_bars:
9891 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
9893 int start, end, whole;
9895 /* Calculate the start and end positions for the current window.
9896 At some point, it would be nice to choose between scrollbars
9897 which reflect the whole buffer size, with special markers
9898 indicating narrowing, and scrollbars which reflect only the
9899 visible region.
9901 Note that mini-buffers sometimes aren't displaying any text. */
9902 if (!MINI_WINDOW_P (w)
9903 || (w == XWINDOW (minibuf_window)
9904 && NILP (echo_area_buffer[0])))
9906 whole = ZV - BEGV;
9907 start = marker_position (w->start) - BEGV;
9908 /* I don't think this is guaranteed to be right. For the
9909 moment, we'll pretend it is. */
9910 end = (Z - XFASTINT (w->window_end_pos)) - BEGV;
9912 if (end < start)
9913 end = start;
9914 if (whole < (end - start))
9915 whole = end - start;
9917 else
9918 start = end = whole = 0;
9920 /* Indicate what this scroll bar ought to be displaying now. */
9921 (*set_vertical_scroll_bar_hook) (w, end - start, whole, start);
9923 /* Note that we actually used the scroll bar attached to this
9924 window, so it shouldn't be deleted at the end of redisplay. */
9925 (*redeem_scroll_bar_hook) (w);
9928 restore_buffers:
9930 /* Restore current_buffer and value of point in it. */
9931 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
9932 set_buffer_internal_1 (old);
9933 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
9935 unbind_to (count, Qnil);
9939 /* Build the complete desired matrix of WINDOW with a window start
9940 buffer position POS. Value is non-zero if successful. It is zero
9941 if fonts were loaded during redisplay which makes re-adjusting
9942 glyph matrices necessary. */
9945 try_window (window, pos)
9946 Lisp_Object window;
9947 struct text_pos pos;
9949 struct window *w = XWINDOW (window);
9950 struct it it;
9951 struct glyph_row *last_text_row = NULL;
9953 /* Make POS the new window start. */
9954 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
9956 /* Mark cursor position as unknown. No overlay arrow seen. */
9957 w->cursor.vpos = -1;
9958 overlay_arrow_seen = 0;
9960 /* Initialize iterator and info to start at POS. */
9961 start_display (&it, w, pos);
9963 /* Display all lines of W. */
9964 while (it.current_y < it.last_visible_y)
9966 if (display_line (&it))
9967 last_text_row = it.glyph_row - 1;
9968 if (fonts_changed_p)
9969 return 0;
9972 /* If bottom moved off end of frame, change mode line percentage. */
9973 if (XFASTINT (w->window_end_pos) <= 0
9974 && Z != IT_CHARPOS (it))
9975 w->update_mode_line = Qt;
9977 /* Set window_end_pos to the offset of the last character displayed
9978 on the window from the end of current_buffer. Set
9979 window_end_vpos to its row number. */
9980 if (last_text_row)
9982 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
9983 w->window_end_bytepos
9984 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9985 XSETFASTINT (w->window_end_pos,
9986 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9987 XSETFASTINT (w->window_end_vpos,
9988 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
9989 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
9990 ->displays_text_p);
9992 else
9994 w->window_end_bytepos = 0;
9995 XSETFASTINT (w->window_end_pos, 0);
9996 XSETFASTINT (w->window_end_vpos, 0);
9999 /* But that is not valid info until redisplay finishes. */
10000 w->window_end_valid = Qnil;
10001 return 1;
10006 /************************************************************************
10007 Window redisplay reusing current matrix when buffer has not changed
10008 ************************************************************************/
10010 /* Try redisplay of window W showing an unchanged buffer with a
10011 different window start than the last time it was displayed by
10012 reusing its current matrix. Value is non-zero if successful.
10013 W->start is the new window start. */
10015 static int
10016 try_window_reusing_current_matrix (w)
10017 struct window *w;
10019 struct frame *f = XFRAME (w->frame);
10020 struct glyph_row *row, *bottom_row;
10021 struct it it;
10022 struct run run;
10023 struct text_pos start, new_start;
10024 int nrows_scrolled, i;
10025 struct glyph_row *last_text_row;
10026 struct glyph_row *last_reused_text_row;
10027 struct glyph_row *start_row;
10028 int start_vpos, min_y, max_y;
10030 if (/* This function doesn't handle terminal frames. */
10031 !FRAME_WINDOW_P (f)
10032 /* Don't try to reuse the display if windows have been split
10033 or such. */
10034 || windows_or_buffers_changed)
10035 return 0;
10037 /* Can't do this if region may have changed. */
10038 if ((!NILP (Vtransient_mark_mode)
10039 && !NILP (current_buffer->mark_active))
10040 || !NILP (w->region_showing)
10041 || !NILP (Vshow_trailing_whitespace))
10042 return 0;
10044 /* If top-line visibility has changed, give up. */
10045 if (WINDOW_WANTS_HEADER_LINE_P (w)
10046 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
10047 return 0;
10049 /* Give up if old or new display is scrolled vertically. We could
10050 make this function handle this, but right now it doesn't. */
10051 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
10052 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
10053 return 0;
10055 /* The variable new_start now holds the new window start. The old
10056 start `start' can be determined from the current matrix. */
10057 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
10058 start = start_row->start.pos;
10059 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
10061 /* Clear the desired matrix for the display below. */
10062 clear_glyph_matrix (w->desired_matrix);
10064 if (CHARPOS (new_start) <= CHARPOS (start))
10066 int first_row_y;
10068 IF_DEBUG (debug_method_add (w, "twu1"));
10070 /* Display up to a row that can be reused. The variable
10071 last_text_row is set to the last row displayed that displays
10072 text. Note that it.vpos == 0 if or if not there is a
10073 header-line; it's not the same as the MATRIX_ROW_VPOS! */
10074 start_display (&it, w, new_start);
10075 first_row_y = it.current_y;
10076 w->cursor.vpos = -1;
10077 last_text_row = last_reused_text_row = NULL;
10079 while (it.current_y < it.last_visible_y
10080 && IT_CHARPOS (it) < CHARPOS (start)
10081 && !fonts_changed_p)
10082 if (display_line (&it))
10083 last_text_row = it.glyph_row - 1;
10085 /* A value of current_y < last_visible_y means that we stopped
10086 at the previous window start, which in turn means that we
10087 have at least one reusable row. */
10088 if (it.current_y < it.last_visible_y)
10090 /* IT.vpos always starts from 0; it counts text lines. */
10091 nrows_scrolled = it.vpos;
10093 /* Find PT if not already found in the lines displayed. */
10094 if (w->cursor.vpos < 0)
10096 int dy = it.current_y - first_row_y;
10098 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
10099 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
10101 if (PT >= MATRIX_ROW_START_CHARPOS (row)
10102 && PT < MATRIX_ROW_END_CHARPOS (row))
10104 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
10105 dy, nrows_scrolled);
10106 break;
10109 if (MATRIX_ROW_BOTTOM_Y (row) + dy >= it.last_visible_y)
10110 break;
10112 ++row;
10115 /* Give up if point was not found. This shouldn't
10116 happen often; not more often than with try_window
10117 itself. */
10118 if (w->cursor.vpos < 0)
10120 clear_glyph_matrix (w->desired_matrix);
10121 return 0;
10125 /* Scroll the display. Do it before the current matrix is
10126 changed. The problem here is that update has not yet
10127 run, i.e. part of the current matrix is not up to date.
10128 scroll_run_hook will clear the cursor, and use the
10129 current matrix to get the height of the row the cursor is
10130 in. */
10131 run.current_y = first_row_y;
10132 run.desired_y = it.current_y;
10133 run.height = it.last_visible_y - it.current_y;
10135 if (run.height > 0 && run.current_y != run.desired_y)
10137 update_begin (f);
10138 rif->update_window_begin_hook (w);
10139 rif->clear_mouse_face (w);
10140 rif->scroll_run_hook (w, &run);
10141 rif->update_window_end_hook (w, 0, 0);
10142 update_end (f);
10145 /* Shift current matrix down by nrows_scrolled lines. */
10146 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
10147 rotate_matrix (w->current_matrix,
10148 start_vpos,
10149 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
10150 nrows_scrolled);
10152 /* Disable lines not reused. */
10153 for (i = 0; i < it.vpos; ++i)
10154 (start_row + i)->enabled_p = 0;
10156 /* Re-compute Y positions. */
10157 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
10158 max_y = it.last_visible_y;
10159 for (row = start_row + nrows_scrolled;
10160 row < bottom_row;
10161 ++row)
10163 row->y = it.current_y;
10165 if (row->y < min_y)
10166 row->visible_height = row->height - (min_y - row->y);
10167 else if (row->y + row->height > max_y)
10168 row->visible_height
10169 = row->height - (row->y + row->height - max_y);
10170 else
10171 row->visible_height = row->height;
10173 it.current_y += row->height;
10175 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
10176 last_reused_text_row = row;
10177 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
10178 break;
10182 /* Update window_end_pos etc.; last_reused_text_row is the last
10183 reused row from the current matrix containing text, if any.
10184 The value of last_text_row is the last displayed line
10185 containing text. */
10186 if (last_reused_text_row)
10188 w->window_end_bytepos
10189 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
10190 XSETFASTINT (w->window_end_pos,
10191 Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
10192 XSETFASTINT (w->window_end_vpos,
10193 MATRIX_ROW_VPOS (last_reused_text_row,
10194 w->current_matrix));
10196 else if (last_text_row)
10198 w->window_end_bytepos
10199 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
10200 XSETFASTINT (w->window_end_pos,
10201 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
10202 XSETFASTINT (w->window_end_vpos,
10203 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
10205 else
10207 /* This window must be completely empty. */
10208 w->window_end_bytepos = 0;
10209 XSETFASTINT (w->window_end_pos, 0);
10210 XSETFASTINT (w->window_end_vpos, 0);
10212 w->window_end_valid = Qnil;
10214 /* Update hint: don't try scrolling again in update_window. */
10215 w->desired_matrix->no_scrolling_p = 1;
10217 #if GLYPH_DEBUG
10218 debug_method_add (w, "try_window_reusing_current_matrix 1");
10219 #endif
10220 return 1;
10222 else if (CHARPOS (new_start) > CHARPOS (start))
10224 struct glyph_row *pt_row, *row;
10225 struct glyph_row *first_reusable_row;
10226 struct glyph_row *first_row_to_display;
10227 int dy;
10228 int yb = window_text_bottom_y (w);
10230 IF_DEBUG (debug_method_add (w, "twu2"));
10232 /* Find the row starting at new_start, if there is one. Don't
10233 reuse a partially visible line at the end. */
10234 first_reusable_row = start_row;
10235 while (first_reusable_row->enabled_p
10236 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
10237 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
10238 < CHARPOS (new_start)))
10239 ++first_reusable_row;
10241 /* Give up if there is no row to reuse. */
10242 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
10243 || !first_reusable_row->enabled_p
10244 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
10245 != CHARPOS (new_start)))
10246 return 0;
10248 /* We can reuse fully visible rows beginning with
10249 first_reusable_row to the end of the window. Set
10250 first_row_to_display to the first row that cannot be reused.
10251 Set pt_row to the row containing point, if there is any. */
10252 first_row_to_display = first_reusable_row;
10253 pt_row = NULL;
10254 while (MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb)
10256 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
10257 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
10258 pt_row = first_row_to_display;
10260 ++first_row_to_display;
10263 /* Start displaying at the start of first_row_to_display. */
10264 xassert (first_row_to_display->y < yb);
10265 init_to_row_start (&it, w, first_row_to_display);
10266 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
10267 - start_vpos);
10268 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
10269 - nrows_scrolled);
10270 it.current_y = (first_row_to_display->y - first_reusable_row->y
10271 + WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w));
10273 /* Display lines beginning with first_row_to_display in the
10274 desired matrix. Set last_text_row to the last row displayed
10275 that displays text. */
10276 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
10277 if (pt_row == NULL)
10278 w->cursor.vpos = -1;
10279 last_text_row = NULL;
10280 while (it.current_y < it.last_visible_y && !fonts_changed_p)
10281 if (display_line (&it))
10282 last_text_row = it.glyph_row - 1;
10284 /* Give up If point isn't in a row displayed or reused. */
10285 if (w->cursor.vpos < 0)
10287 clear_glyph_matrix (w->desired_matrix);
10288 return 0;
10291 /* If point is in a reused row, adjust y and vpos of the cursor
10292 position. */
10293 if (pt_row)
10295 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
10296 w->current_matrix);
10297 w->cursor.y -= first_reusable_row->y;
10300 /* Scroll the display. */
10301 run.current_y = first_reusable_row->y;
10302 run.desired_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
10303 run.height = it.last_visible_y - run.current_y;
10304 dy = run.current_y - run.desired_y;
10306 if (run.height)
10308 struct frame *f = XFRAME (WINDOW_FRAME (w));
10309 update_begin (f);
10310 rif->update_window_begin_hook (w);
10311 rif->clear_mouse_face (w);
10312 rif->scroll_run_hook (w, &run);
10313 rif->update_window_end_hook (w, 0, 0);
10314 update_end (f);
10317 /* Adjust Y positions of reused rows. */
10318 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
10319 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
10320 max_y = it.last_visible_y;
10321 for (row = first_reusable_row; row < first_row_to_display; ++row)
10323 row->y -= dy;
10324 if (row->y < min_y)
10325 row->visible_height = row->height - (min_y - row->y);
10326 else if (row->y + row->height > max_y)
10327 row->visible_height
10328 = row->height - (row->y + row->height - max_y);
10329 else
10330 row->visible_height = row->height;
10333 /* Disable rows not reused. */
10334 while (row < bottom_row)
10336 row->enabled_p = 0;
10337 ++row;
10340 /* Scroll the current matrix. */
10341 xassert (nrows_scrolled > 0);
10342 rotate_matrix (w->current_matrix,
10343 start_vpos,
10344 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
10345 -nrows_scrolled);
10347 /* Adjust window end. A null value of last_text_row means that
10348 the window end is in reused rows which in turn means that
10349 only its vpos can have changed. */
10350 if (last_text_row)
10352 w->window_end_bytepos
10353 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
10354 XSETFASTINT (w->window_end_pos,
10355 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
10356 XSETFASTINT (w->window_end_vpos,
10357 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
10359 else
10361 XSETFASTINT (w->window_end_vpos,
10362 XFASTINT (w->window_end_vpos) - nrows_scrolled);
10365 w->window_end_valid = Qnil;
10366 w->desired_matrix->no_scrolling_p = 1;
10368 #if GLYPH_DEBUG
10369 debug_method_add (w, "try_window_reusing_current_matrix 2");
10370 #endif
10371 return 1;
10374 return 0;
10379 /************************************************************************
10380 Window redisplay reusing current matrix when buffer has changed
10381 ************************************************************************/
10383 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
10384 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
10385 int *, int *));
10386 static struct glyph_row *
10387 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
10388 struct glyph_row *));
10391 /* Return the last row in MATRIX displaying text. If row START is
10392 non-null, start searching with that row. IT gives the dimensions
10393 of the display. Value is null if matrix is empty; otherwise it is
10394 a pointer to the row found. */
10396 static struct glyph_row *
10397 find_last_row_displaying_text (matrix, it, start)
10398 struct glyph_matrix *matrix;
10399 struct it *it;
10400 struct glyph_row *start;
10402 struct glyph_row *row, *row_found;
10404 /* Set row_found to the last row in IT->w's current matrix
10405 displaying text. The loop looks funny but think of partially
10406 visible lines. */
10407 row_found = NULL;
10408 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
10409 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
10411 xassert (row->enabled_p);
10412 row_found = row;
10413 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
10414 break;
10415 ++row;
10418 return row_found;
10422 /* Return the last row in the current matrix of W that is not affected
10423 by changes at the start of current_buffer that occurred since the
10424 last time W was redisplayed. Value is null if no such row exists.
10426 The global variable beg_unchanged has to contain the number of
10427 bytes unchanged at the start of current_buffer. BEG +
10428 beg_unchanged is the buffer position of the first changed byte in
10429 current_buffer. Characters at positions < BEG + beg_unchanged are
10430 at the same buffer positions as they were when the current matrix
10431 was built. */
10433 static struct glyph_row *
10434 find_last_unchanged_at_beg_row (w)
10435 struct window *w;
10437 int first_changed_pos = BEG + BEG_UNCHANGED;
10438 struct glyph_row *row;
10439 struct glyph_row *row_found = NULL;
10440 int yb = window_text_bottom_y (w);
10442 /* Find the last row displaying unchanged text. */
10443 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
10444 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
10445 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
10447 if (/* If row ends before first_changed_pos, it is unchanged,
10448 except in some case. */
10449 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
10450 /* When row ends in ZV and we write at ZV it is not
10451 unchanged. */
10452 && !row->ends_at_zv_p
10453 /* When first_changed_pos is the end of a continued line,
10454 row is not unchanged because it may be no longer
10455 continued. */
10456 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
10457 && row->continued_p))
10458 row_found = row;
10460 /* Stop if last visible row. */
10461 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
10462 break;
10464 ++row;
10467 return row_found;
10471 /* Find the first glyph row in the current matrix of W that is not
10472 affected by changes at the end of current_buffer since the last
10473 time the window was redisplayed. Return in *DELTA the number of
10474 chars by which buffer positions in unchanged text at the end of
10475 current_buffer must be adjusted. Return in *DELTA_BYTES the
10476 corresponding number of bytes. Value is null if no such row
10477 exists, i.e. all rows are affected by changes. */
10479 static struct glyph_row *
10480 find_first_unchanged_at_end_row (w, delta, delta_bytes)
10481 struct window *w;
10482 int *delta, *delta_bytes;
10484 struct glyph_row *row;
10485 struct glyph_row *row_found = NULL;
10487 *delta = *delta_bytes = 0;
10489 /* Display must not have been paused, otherwise the current matrix
10490 is not up to date. */
10491 if (NILP (w->window_end_valid))
10492 abort ();
10494 /* A value of window_end_pos >= END_UNCHANGED means that the window
10495 end is in the range of changed text. If so, there is no
10496 unchanged row at the end of W's current matrix. */
10497 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
10498 return NULL;
10500 /* Set row to the last row in W's current matrix displaying text. */
10501 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
10503 /* If matrix is entirely empty, no unchanged row exists. */
10504 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
10506 /* The value of row is the last glyph row in the matrix having a
10507 meaningful buffer position in it. The end position of row
10508 corresponds to window_end_pos. This allows us to translate
10509 buffer positions in the current matrix to current buffer
10510 positions for characters not in changed text. */
10511 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
10512 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
10513 int last_unchanged_pos, last_unchanged_pos_old;
10514 struct glyph_row *first_text_row
10515 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
10517 *delta = Z - Z_old;
10518 *delta_bytes = Z_BYTE - Z_BYTE_old;
10520 /* Set last_unchanged_pos to the buffer position of the last
10521 character in the buffer that has not been changed. Z is the
10522 index + 1 of the last byte in current_buffer, i.e. by
10523 subtracting end_unchanged we get the index of the last
10524 unchanged character, and we have to add BEG to get its buffer
10525 position. */
10526 last_unchanged_pos = Z - END_UNCHANGED + BEG;
10527 last_unchanged_pos_old = last_unchanged_pos - *delta;
10529 /* Search backward from ROW for a row displaying a line that
10530 starts at a minimum position >= last_unchanged_pos_old. */
10531 for (; row > first_text_row; --row)
10533 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
10534 abort ();
10536 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
10537 row_found = row;
10541 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
10542 abort ();
10544 return row_found;
10548 /* Make sure that glyph rows in the current matrix of window W
10549 reference the same glyph memory as corresponding rows in the
10550 frame's frame matrix. This function is called after scrolling W's
10551 current matrix on a terminal frame in try_window_id and
10552 try_window_reusing_current_matrix. */
10554 static void
10555 sync_frame_with_window_matrix_rows (w)
10556 struct window *w;
10558 struct frame *f = XFRAME (w->frame);
10559 struct glyph_row *window_row, *window_row_end, *frame_row;
10561 /* Preconditions: W must be a leaf window and full-width. Its frame
10562 must have a frame matrix. */
10563 xassert (NILP (w->hchild) && NILP (w->vchild));
10564 xassert (WINDOW_FULL_WIDTH_P (w));
10565 xassert (!FRAME_WINDOW_P (f));
10567 /* If W is a full-width window, glyph pointers in W's current matrix
10568 have, by definition, to be the same as glyph pointers in the
10569 corresponding frame matrix. */
10570 window_row = w->current_matrix->rows;
10571 window_row_end = window_row + w->current_matrix->nrows;
10572 frame_row = f->current_matrix->rows + XFASTINT (w->top);
10573 while (window_row < window_row_end)
10575 int area;
10577 for (area = LEFT_MARGIN_AREA; area <= LAST_AREA; ++area)
10578 frame_row->glyphs[area] = window_row->glyphs[area];
10580 /* Disable frame rows whose corresponding window rows have
10581 been disabled in try_window_id. */
10582 if (!window_row->enabled_p)
10583 frame_row->enabled_p = 0;
10585 ++window_row, ++frame_row;
10590 /* Find the glyph row in window W containing CHARPOS. Consider all
10591 rows between START and END (not inclusive). END null means search
10592 all rows to the end of the display area of W. Value is the row
10593 containing CHARPOS or null. */
10595 static struct glyph_row *
10596 row_containing_pos (w, charpos, start, end)
10597 struct window *w;
10598 int charpos;
10599 struct glyph_row *start, *end;
10601 struct glyph_row *row = start;
10602 int last_y;
10604 /* If we happen to start on a header-line, skip that. */
10605 if (row->mode_line_p)
10606 ++row;
10608 if ((end && row >= end) || !row->enabled_p)
10609 return NULL;
10611 last_y = window_text_bottom_y (w);
10613 while ((end == NULL || row < end)
10614 && (MATRIX_ROW_END_CHARPOS (row) < charpos
10615 /* The end position of a row equals the start
10616 position of the next row. If CHARPOS is there, we
10617 would rather display it in the next line, except
10618 when this line ends in ZV. */
10619 || (MATRIX_ROW_END_CHARPOS (row) == charpos
10620 && (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
10621 || !row->ends_at_zv_p)))
10622 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
10623 ++row;
10625 /* Give up if CHARPOS not found. */
10626 if ((end && row >= end)
10627 || charpos < MATRIX_ROW_START_CHARPOS (row)
10628 || charpos > MATRIX_ROW_END_CHARPOS (row))
10629 row = NULL;
10631 return row;
10635 /* Try to redisplay window W by reusing its existing display. W's
10636 current matrix must be up to date when this function is called,
10637 i.e. window_end_valid must not be nil.
10639 Value is
10641 1 if display has been updated
10642 0 if otherwise unsuccessful
10643 -1 if redisplay with same window start is known not to succeed
10645 The following steps are performed:
10647 1. Find the last row in the current matrix of W that is not
10648 affected by changes at the start of current_buffer. If no such row
10649 is found, give up.
10651 2. Find the first row in W's current matrix that is not affected by
10652 changes at the end of current_buffer. Maybe there is no such row.
10654 3. Display lines beginning with the row + 1 found in step 1 to the
10655 row found in step 2 or, if step 2 didn't find a row, to the end of
10656 the window.
10658 4. If cursor is not known to appear on the window, give up.
10660 5. If display stopped at the row found in step 2, scroll the
10661 display and current matrix as needed.
10663 6. Maybe display some lines at the end of W, if we must. This can
10664 happen under various circumstances, like a partially visible line
10665 becoming fully visible, or because newly displayed lines are displayed
10666 in smaller font sizes.
10668 7. Update W's window end information. */
10670 /* Check that window end is what we expect it to be. */
10672 static int
10673 try_window_id (w)
10674 struct window *w;
10676 struct frame *f = XFRAME (w->frame);
10677 struct glyph_matrix *current_matrix = w->current_matrix;
10678 struct glyph_matrix *desired_matrix = w->desired_matrix;
10679 struct glyph_row *last_unchanged_at_beg_row;
10680 struct glyph_row *first_unchanged_at_end_row;
10681 struct glyph_row *row;
10682 struct glyph_row *bottom_row;
10683 int bottom_vpos;
10684 struct it it;
10685 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
10686 struct text_pos start_pos;
10687 struct run run;
10688 int first_unchanged_at_end_vpos = 0;
10689 struct glyph_row *last_text_row, *last_text_row_at_end;
10690 struct text_pos start;
10692 SET_TEXT_POS_FROM_MARKER (start, w->start);
10694 /* Check pre-conditions. Window end must be valid, otherwise
10695 the current matrix would not be up to date. */
10696 xassert (!NILP (w->window_end_valid));
10697 xassert (FRAME_WINDOW_P (XFRAME (w->frame))
10698 || (line_ins_del_ok && WINDOW_FULL_WIDTH_P (w)));
10700 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
10701 only if buffer has really changed. The reason is that the gap is
10702 initially at Z for freshly visited files. The code below would
10703 set end_unchanged to 0 in that case. */
10704 if (MODIFF > SAVE_MODIFF
10705 /* This seems to happen sometimes after saving a buffer. */
10706 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
10708 if (GPT - BEG < BEG_UNCHANGED)
10709 BEG_UNCHANGED = GPT - BEG;
10710 if (Z - GPT < END_UNCHANGED)
10711 END_UNCHANGED = Z - GPT;
10714 /* If window starts after a line end, and the last change is in
10715 front of that newline, then changes don't affect the display.
10716 This case happens with stealth-fontification. Note that although
10717 the display is unchanged, glyph positions in the matrix have to
10718 be adjusted, of course. */
10719 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
10720 if (CHARPOS (start) > BEGV
10721 && Z - END_UNCHANGED < CHARPOS (start) - 1
10722 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n'
10723 && PT < MATRIX_ROW_END_CHARPOS (row))
10725 struct glyph_row *r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
10726 int delta = CHARPOS (start) - MATRIX_ROW_START_CHARPOS (r0);
10728 if (delta)
10730 struct glyph_row *r1 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
10731 int delta_bytes = BYTEPOS (start) - MATRIX_ROW_START_BYTEPOS (r0);
10733 increment_matrix_positions (w->current_matrix,
10734 MATRIX_ROW_VPOS (r0, current_matrix),
10735 MATRIX_ROW_VPOS (r1, current_matrix),
10736 delta, delta_bytes);
10739 #if 0 /* If changes are all in front of the window start, the
10740 distance of the last displayed glyph from Z hasn't
10741 changed. */
10742 w->window_end_pos
10743 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
10744 w->window_end_bytepos
10745 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
10746 #endif
10748 return 1;
10751 /* Return quickly if changes are all below what is displayed in the
10752 window, and if PT is in the window. */
10753 if (BEG_UNCHANGED > MATRIX_ROW_END_CHARPOS (row)
10754 && PT < MATRIX_ROW_END_CHARPOS (row))
10756 /* We have to update window end positions because the buffer's
10757 size has changed. */
10758 w->window_end_pos
10759 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
10760 w->window_end_bytepos
10761 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
10763 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
10764 row = row_containing_pos (w, PT, row, NULL);
10765 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10766 return 2;
10769 /* Check that window start agrees with the start of the first glyph
10770 row in its current matrix. Check this after we know the window
10771 start is not in changed text, otherwise positions would not be
10772 comparable. */
10773 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
10774 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
10775 return 0;
10777 /* Compute the position at which we have to start displaying new
10778 lines. Some of the lines at the top of the window might be
10779 reusable because they are not displaying changed text. Find the
10780 last row in W's current matrix not affected by changes at the
10781 start of current_buffer. Value is null if changes start in the
10782 first line of window. */
10783 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
10784 if (last_unchanged_at_beg_row)
10786 /* Avoid starting to display in the moddle of a character, a TAB
10787 for instance. This is easier than to set up the iterator
10788 exactly, and it's not a frequent case, so the additional
10789 effort wouldn't really pay off. */
10790 while (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
10791 && last_unchanged_at_beg_row > w->current_matrix->rows)
10792 --last_unchanged_at_beg_row;
10794 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
10795 return 0;
10797 init_to_row_end (&it, w, last_unchanged_at_beg_row);
10798 start_pos = it.current.pos;
10800 /* Start displaying new lines in the desired matrix at the same
10801 vpos we would use in the current matrix, i.e. below
10802 last_unchanged_at_beg_row. */
10803 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
10804 current_matrix);
10805 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
10806 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
10808 xassert (it.hpos == 0 && it.current_x == 0);
10810 else
10812 /* There are no reusable lines at the start of the window.
10813 Start displaying in the first line. */
10814 start_display (&it, w, start);
10815 start_pos = it.current.pos;
10818 /* Find the first row that is not affected by changes at the end of
10819 the buffer. Value will be null if there is no unchanged row, in
10820 which case we must redisplay to the end of the window. delta
10821 will be set to the value by which buffer positions beginning with
10822 first_unchanged_at_end_row have to be adjusted due to text
10823 changes. */
10824 first_unchanged_at_end_row
10825 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
10826 IF_DEBUG (debug_delta = delta);
10827 IF_DEBUG (debug_delta_bytes = delta_bytes);
10829 /* Set stop_pos to the buffer position up to which we will have to
10830 display new lines. If first_unchanged_at_end_row != NULL, this
10831 is the buffer position of the start of the line displayed in that
10832 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
10833 that we don't stop at a buffer position. */
10834 stop_pos = 0;
10835 if (first_unchanged_at_end_row)
10837 xassert (last_unchanged_at_beg_row == NULL
10838 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
10840 /* If this is a continuation line, move forward to the next one
10841 that isn't. Changes in lines above affect this line.
10842 Caution: this may move first_unchanged_at_end_row to a row
10843 not displaying text. */
10844 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
10845 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
10846 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
10847 < it.last_visible_y))
10848 ++first_unchanged_at_end_row;
10850 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
10851 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
10852 >= it.last_visible_y))
10853 first_unchanged_at_end_row = NULL;
10854 else
10856 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
10857 + delta);
10858 first_unchanged_at_end_vpos
10859 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
10860 xassert (stop_pos >= Z - END_UNCHANGED);
10863 else if (last_unchanged_at_beg_row == NULL)
10864 return 0;
10867 #if GLYPH_DEBUG
10869 /* Either there is no unchanged row at the end, or the one we have
10870 now displays text. This is a necessary condition for the window
10871 end pos calculation at the end of this function. */
10872 xassert (first_unchanged_at_end_row == NULL
10873 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
10875 debug_last_unchanged_at_beg_vpos
10876 = (last_unchanged_at_beg_row
10877 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
10878 : -1);
10879 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
10881 #endif /* GLYPH_DEBUG != 0 */
10884 /* Display new lines. Set last_text_row to the last new line
10885 displayed which has text on it, i.e. might end up as being the
10886 line where the window_end_vpos is. */
10887 w->cursor.vpos = -1;
10888 last_text_row = NULL;
10889 overlay_arrow_seen = 0;
10890 while (it.current_y < it.last_visible_y
10891 && !fonts_changed_p
10892 && (first_unchanged_at_end_row == NULL
10893 || IT_CHARPOS (it) < stop_pos))
10895 if (display_line (&it))
10896 last_text_row = it.glyph_row - 1;
10899 if (fonts_changed_p)
10900 return -1;
10903 /* Compute differences in buffer positions, y-positions etc. for
10904 lines reused at the bottom of the window. Compute what we can
10905 scroll. */
10906 if (first_unchanged_at_end_row
10907 /* No lines reused because we displayed everything up to the
10908 bottom of the window. */
10909 && it.current_y < it.last_visible_y)
10911 dvpos = (it.vpos
10912 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
10913 current_matrix));
10914 dy = it.current_y - first_unchanged_at_end_row->y;
10915 run.current_y = first_unchanged_at_end_row->y;
10916 run.desired_y = run.current_y + dy;
10917 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
10919 else
10921 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
10922 first_unchanged_at_end_row = NULL;
10924 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
10927 /* Find the cursor if not already found. We have to decide whether
10928 PT will appear on this window (it sometimes doesn't, but this is
10929 not a very frequent case.) This decision has to be made before
10930 the current matrix is altered. A value of cursor.vpos < 0 means
10931 that PT is either in one of the lines beginning at
10932 first_unchanged_at_end_row or below the window. Don't care for
10933 lines that might be displayed later at the window end; as
10934 mentioned, this is not a frequent case. */
10935 if (w->cursor.vpos < 0)
10937 /* Cursor in unchanged rows at the top? */
10938 if (PT < CHARPOS (start_pos)
10939 && last_unchanged_at_beg_row)
10941 row = row_containing_pos (w, PT,
10942 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
10943 last_unchanged_at_beg_row + 1);
10944 if (row)
10945 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10948 /* Start from first_unchanged_at_end_row looking for PT. */
10949 else if (first_unchanged_at_end_row)
10951 row = row_containing_pos (w, PT - delta,
10952 first_unchanged_at_end_row, NULL);
10953 if (row)
10954 set_cursor_from_row (w, row, w->current_matrix, delta,
10955 delta_bytes, dy, dvpos);
10958 /* Give up if cursor was not found. */
10959 if (w->cursor.vpos < 0)
10961 clear_glyph_matrix (w->desired_matrix);
10962 return -1;
10966 /* Don't let the cursor end in the scroll margins. */
10968 int this_scroll_margin, cursor_height;
10970 this_scroll_margin = max (0, scroll_margin);
10971 this_scroll_margin = min (this_scroll_margin,
10972 XFASTINT (w->height) / 4);
10973 this_scroll_margin *= CANON_Y_UNIT (it.f);
10974 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
10976 if ((w->cursor.y < this_scroll_margin
10977 && CHARPOS (start) > BEGV)
10978 /* Don't take scroll margin into account at the bottom because
10979 old redisplay didn't do it either. */
10980 || w->cursor.y + cursor_height > it.last_visible_y)
10982 w->cursor.vpos = -1;
10983 clear_glyph_matrix (w->desired_matrix);
10984 return -1;
10988 /* Scroll the display. Do it before changing the current matrix so
10989 that xterm.c doesn't get confused about where the cursor glyph is
10990 found. */
10991 if (dy && run.height)
10993 update_begin (f);
10995 if (FRAME_WINDOW_P (f))
10997 rif->update_window_begin_hook (w);
10998 rif->clear_mouse_face (w);
10999 rif->scroll_run_hook (w, &run);
11000 rif->update_window_end_hook (w, 0, 0);
11002 else
11004 /* Terminal frame. In this case, dvpos gives the number of
11005 lines to scroll by; dvpos < 0 means scroll up. */
11006 int first_unchanged_at_end_vpos
11007 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
11008 int from = XFASTINT (w->top) + first_unchanged_at_end_vpos;
11009 int end = XFASTINT (w->top) + window_internal_height (w);
11011 /* Perform the operation on the screen. */
11012 if (dvpos > 0)
11014 /* Scroll last_unchanged_at_beg_row to the end of the
11015 window down dvpos lines. */
11016 set_terminal_window (end);
11018 /* On dumb terminals delete dvpos lines at the end
11019 before inserting dvpos empty lines. */
11020 if (!scroll_region_ok)
11021 ins_del_lines (end - dvpos, -dvpos);
11023 /* Insert dvpos empty lines in front of
11024 last_unchanged_at_beg_row. */
11025 ins_del_lines (from, dvpos);
11027 else if (dvpos < 0)
11029 /* Scroll up last_unchanged_at_beg_vpos to the end of
11030 the window to last_unchanged_at_beg_vpos - |dvpos|. */
11031 set_terminal_window (end);
11033 /* Delete dvpos lines in front of
11034 last_unchanged_at_beg_vpos. ins_del_lines will set
11035 the cursor to the given vpos and emit |dvpos| delete
11036 line sequences. */
11037 ins_del_lines (from + dvpos, dvpos);
11039 /* On a dumb terminal insert dvpos empty lines at the
11040 end. */
11041 if (!scroll_region_ok)
11042 ins_del_lines (end + dvpos, -dvpos);
11045 set_terminal_window (0);
11048 update_end (f);
11051 /* Shift reused rows of the current matrix to the right position.
11052 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
11053 text. */
11054 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
11055 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
11056 if (dvpos < 0)
11058 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
11059 bottom_vpos, dvpos);
11060 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
11061 bottom_vpos, 0);
11063 else if (dvpos > 0)
11065 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
11066 bottom_vpos, dvpos);
11067 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
11068 first_unchanged_at_end_vpos + dvpos, 0);
11071 /* For frame-based redisplay, make sure that current frame and window
11072 matrix are in sync with respect to glyph memory. */
11073 if (!FRAME_WINDOW_P (f))
11074 sync_frame_with_window_matrix_rows (w);
11076 /* Adjust buffer positions in reused rows. */
11077 if (delta)
11078 increment_matrix_positions (current_matrix,
11079 first_unchanged_at_end_vpos + dvpos,
11080 bottom_vpos, delta, delta_bytes);
11082 /* Adjust Y positions. */
11083 if (dy)
11084 shift_glyph_matrix (w, current_matrix,
11085 first_unchanged_at_end_vpos + dvpos,
11086 bottom_vpos, dy);
11088 if (first_unchanged_at_end_row)
11089 first_unchanged_at_end_row += dvpos;
11091 /* If scrolling up, there may be some lines to display at the end of
11092 the window. */
11093 last_text_row_at_end = NULL;
11094 if (dy < 0)
11096 /* Set last_row to the glyph row in the current matrix where the
11097 window end line is found. It has been moved up or down in
11098 the matrix by dvpos. */
11099 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
11100 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
11102 /* If last_row is the window end line, it should display text. */
11103 xassert (last_row->displays_text_p);
11105 /* If window end line was partially visible before, begin
11106 displaying at that line. Otherwise begin displaying with the
11107 line following it. */
11108 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
11110 init_to_row_start (&it, w, last_row);
11111 it.vpos = last_vpos;
11112 it.current_y = last_row->y;
11114 else
11116 init_to_row_end (&it, w, last_row);
11117 it.vpos = 1 + last_vpos;
11118 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
11119 ++last_row;
11122 /* We may start in a continuation line. If so, we have to get
11123 the right continuation_lines_width and current_x. */
11124 it.continuation_lines_width = last_row->continuation_lines_width;
11125 it.hpos = it.current_x = 0;
11127 /* Display the rest of the lines at the window end. */
11128 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
11129 while (it.current_y < it.last_visible_y
11130 && !fonts_changed_p)
11132 /* Is it always sure that the display agrees with lines in
11133 the current matrix? I don't think so, so we mark rows
11134 displayed invalid in the current matrix by setting their
11135 enabled_p flag to zero. */
11136 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
11137 if (display_line (&it))
11138 last_text_row_at_end = it.glyph_row - 1;
11142 /* Update window_end_pos and window_end_vpos. */
11143 if (first_unchanged_at_end_row
11144 && first_unchanged_at_end_row->y < it.last_visible_y
11145 && !last_text_row_at_end)
11147 /* Window end line if one of the preserved rows from the current
11148 matrix. Set row to the last row displaying text in current
11149 matrix starting at first_unchanged_at_end_row, after
11150 scrolling. */
11151 xassert (first_unchanged_at_end_row->displays_text_p);
11152 row = find_last_row_displaying_text (w->current_matrix, &it,
11153 first_unchanged_at_end_row);
11154 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
11156 XSETFASTINT (w->window_end_pos, Z - MATRIX_ROW_END_CHARPOS (row));
11157 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
11158 XSETFASTINT (w->window_end_vpos,
11159 MATRIX_ROW_VPOS (row, w->current_matrix));
11161 else if (last_text_row_at_end)
11163 XSETFASTINT (w->window_end_pos,
11164 Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
11165 w->window_end_bytepos
11166 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
11167 XSETFASTINT (w->window_end_vpos,
11168 MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
11170 else if (last_text_row)
11172 /* We have displayed either to the end of the window or at the
11173 end of the window, i.e. the last row with text is to be found
11174 in the desired matrix. */
11175 XSETFASTINT (w->window_end_pos,
11176 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
11177 w->window_end_bytepos
11178 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
11179 XSETFASTINT (w->window_end_vpos,
11180 MATRIX_ROW_VPOS (last_text_row, desired_matrix));
11182 else if (first_unchanged_at_end_row == NULL
11183 && last_text_row == NULL
11184 && last_text_row_at_end == NULL)
11186 /* Displayed to end of window, but no line containing text was
11187 displayed. Lines were deleted at the end of the window. */
11188 int vpos;
11189 int header_line_p = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
11191 for (vpos = XFASTINT (w->window_end_vpos); vpos > 0; --vpos)
11192 if ((w->desired_matrix->rows[vpos + header_line_p].enabled_p
11193 && w->desired_matrix->rows[vpos + header_line_p].displays_text_p)
11194 || (!w->desired_matrix->rows[vpos + header_line_p].enabled_p
11195 && w->current_matrix->rows[vpos + header_line_p].displays_text_p))
11196 break;
11198 w->window_end_vpos = make_number (vpos);
11200 else
11201 abort ();
11203 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
11204 debug_end_vpos = XFASTINT (w->window_end_vpos));
11206 /* Record that display has not been completed. */
11207 w->window_end_valid = Qnil;
11208 w->desired_matrix->no_scrolling_p = 1;
11209 return 3;
11214 /***********************************************************************
11215 More debugging support
11216 ***********************************************************************/
11218 #if GLYPH_DEBUG
11220 void dump_glyph_row P_ ((struct glyph_matrix *, int, int));
11221 static void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
11224 /* Dump the contents of glyph matrix MATRIX on stderr. If
11225 WITH_GLYPHS_P is non-zero, dump glyph contents as well. */
11227 static void
11228 dump_glyph_matrix (matrix, with_glyphs_p)
11229 struct glyph_matrix *matrix;
11230 int with_glyphs_p;
11232 int i;
11233 for (i = 0; i < matrix->nrows; ++i)
11234 dump_glyph_row (matrix, i, with_glyphs_p);
11238 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
11239 WITH_GLYPH_SP non-zero means dump glyph contents, too. */
11241 void
11242 dump_glyph_row (matrix, vpos, with_glyphs_p)
11243 struct glyph_matrix *matrix;
11244 int vpos, with_glyphs_p;
11246 struct glyph_row *row;
11248 if (vpos < 0 || vpos >= matrix->nrows)
11249 return;
11251 row = MATRIX_ROW (matrix, vpos);
11253 fprintf (stderr, "Row Start End Used oEI><O\\CTZFes X Y W H V A P\n");
11254 fprintf (stderr, "=======================================================================\n");
11256 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d\
11257 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
11258 row - matrix->rows,
11259 MATRIX_ROW_START_CHARPOS (row),
11260 MATRIX_ROW_END_CHARPOS (row),
11261 row->used[TEXT_AREA],
11262 row->contains_overlapping_glyphs_p,
11263 row->enabled_p,
11264 row->inverse_p,
11265 row->truncated_on_left_p,
11266 row->truncated_on_right_p,
11267 row->overlay_arrow_p,
11268 row->continued_p,
11269 MATRIX_ROW_CONTINUATION_LINE_P (row),
11270 row->displays_text_p,
11271 row->ends_at_zv_p,
11272 row->fill_line_p,
11273 row->ends_in_middle_of_char_p,
11274 row->starts_in_middle_of_char_p,
11275 row->x,
11276 row->y,
11277 row->pixel_width,
11278 row->height,
11279 row->visible_height,
11280 row->ascent,
11281 row->phys_ascent);
11282 fprintf (stderr, "%9d %5d\n", row->start.overlay_string_index,
11283 row->end.overlay_string_index);
11284 fprintf (stderr, "%9d %5d\n",
11285 CHARPOS (row->start.string_pos),
11286 CHARPOS (row->end.string_pos));
11287 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
11288 row->end.dpvec_index);
11290 if (with_glyphs_p)
11292 struct glyph *glyph, *glyph_end;
11293 int prev_had_glyphs_p;
11295 glyph = row->glyphs[TEXT_AREA];
11296 glyph_end = glyph + row->used[TEXT_AREA];
11298 /* Glyph for a line end in text. */
11299 if (glyph == glyph_end && glyph->charpos > 0)
11300 ++glyph_end;
11302 if (glyph < glyph_end)
11304 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
11305 prev_had_glyphs_p = 1;
11307 else
11308 prev_had_glyphs_p = 0;
11310 while (glyph < glyph_end)
11312 if (glyph->type == CHAR_GLYPH)
11314 fprintf (stderr,
11315 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
11316 glyph - row->glyphs[TEXT_AREA],
11317 'C',
11318 glyph->charpos,
11319 (BUFFERP (glyph->object)
11320 ? 'B'
11321 : (STRINGP (glyph->object)
11322 ? 'S'
11323 : '-')),
11324 glyph->pixel_width,
11325 glyph->u.ch,
11326 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
11327 ? glyph->u.ch
11328 : '.'),
11329 glyph->face_id,
11330 glyph->left_box_line_p,
11331 glyph->right_box_line_p);
11333 else if (glyph->type == STRETCH_GLYPH)
11335 fprintf (stderr,
11336 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
11337 glyph - row->glyphs[TEXT_AREA],
11338 'S',
11339 glyph->charpos,
11340 (BUFFERP (glyph->object)
11341 ? 'B'
11342 : (STRINGP (glyph->object)
11343 ? 'S'
11344 : '-')),
11345 glyph->pixel_width,
11347 '.',
11348 glyph->face_id,
11349 glyph->left_box_line_p,
11350 glyph->right_box_line_p);
11352 else if (glyph->type == IMAGE_GLYPH)
11354 fprintf (stderr,
11355 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
11356 glyph - row->glyphs[TEXT_AREA],
11357 'I',
11358 glyph->charpos,
11359 (BUFFERP (glyph->object)
11360 ? 'B'
11361 : (STRINGP (glyph->object)
11362 ? 'S'
11363 : '-')),
11364 glyph->pixel_width,
11365 glyph->u.img_id,
11366 '.',
11367 glyph->face_id,
11368 glyph->left_box_line_p,
11369 glyph->right_box_line_p);
11371 ++glyph;
11377 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
11378 Sdump_glyph_matrix, 0, 1, "p",
11379 "Dump the current matrix of the selected window to stderr.\n\
11380 Shows contents of glyph row structures. With non-nil optional\n\
11381 parameter WITH-GLYPHS-P, dump glyphs as well.")
11382 (with_glyphs_p)
11383 Lisp_Object with_glyphs_p;
11385 struct window *w = XWINDOW (selected_window);
11386 struct buffer *buffer = XBUFFER (w->buffer);
11388 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
11389 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
11390 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
11391 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
11392 fprintf (stderr, "=============================================\n");
11393 dump_glyph_matrix (w->current_matrix, !NILP (with_glyphs_p));
11394 return Qnil;
11398 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 1, "",
11399 "Dump glyph row ROW to stderr.")
11400 (row)
11401 Lisp_Object row;
11403 CHECK_NUMBER (row, 0);
11404 dump_glyph_row (XWINDOW (selected_window)->current_matrix, XINT (row), 1);
11405 return Qnil;
11409 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row,
11410 0, 0, "", "")
11413 struct frame *sf = SELECTED_FRAME ();
11414 struct glyph_matrix *m = (XWINDOW (sf->tool_bar_window)
11415 ->current_matrix);
11416 dump_glyph_row (m, 0, 1);
11417 return Qnil;
11421 DEFUN ("trace-redisplay-toggle", Ftrace_redisplay_toggle,
11422 Strace_redisplay_toggle, 0, 0, "",
11423 "Toggle tracing of redisplay.")
11426 trace_redisplay_p = !trace_redisplay_p;
11427 return Qnil;
11431 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, 1, "",
11432 "Print STRING to stderr.")
11433 (string)
11434 Lisp_Object string;
11436 CHECK_STRING (string, 0);
11437 fprintf (stderr, "%s", XSTRING (string)->data);
11438 return Qnil;
11441 #endif /* GLYPH_DEBUG */
11445 /***********************************************************************
11446 Building Desired Matrix Rows
11447 ***********************************************************************/
11449 /* Return a temporary glyph row holding the glyphs of an overlay
11450 arrow. Only used for non-window-redisplay windows. */
11452 static struct glyph_row *
11453 get_overlay_arrow_glyph_row (w)
11454 struct window *w;
11456 struct frame *f = XFRAME (WINDOW_FRAME (w));
11457 struct buffer *buffer = XBUFFER (w->buffer);
11458 struct buffer *old = current_buffer;
11459 unsigned char *arrow_string = XSTRING (Voverlay_arrow_string)->data;
11460 int arrow_len = XSTRING (Voverlay_arrow_string)->size;
11461 unsigned char *arrow_end = arrow_string + arrow_len;
11462 unsigned char *p;
11463 struct it it;
11464 int multibyte_p;
11465 int n_glyphs_before;
11467 set_buffer_temp (buffer);
11468 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
11469 it.glyph_row->used[TEXT_AREA] = 0;
11470 SET_TEXT_POS (it.position, 0, 0);
11472 multibyte_p = !NILP (buffer->enable_multibyte_characters);
11473 p = arrow_string;
11474 while (p < arrow_end)
11476 Lisp_Object face, ilisp;
11478 /* Get the next character. */
11479 if (multibyte_p)
11480 it.c = string_char_and_length (p, arrow_len, &it.len);
11481 else
11482 it.c = *p, it.len = 1;
11483 p += it.len;
11485 /* Get its face. */
11486 XSETFASTINT (ilisp, p - arrow_string);
11487 face = Fget_text_property (ilisp, Qface, Voverlay_arrow_string);
11488 it.face_id = compute_char_face (f, it.c, face);
11490 /* Compute its width, get its glyphs. */
11491 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
11492 SET_TEXT_POS (it.position, -1, -1);
11493 PRODUCE_GLYPHS (&it);
11495 /* If this character doesn't fit any more in the line, we have
11496 to remove some glyphs. */
11497 if (it.current_x > it.last_visible_x)
11499 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
11500 break;
11504 set_buffer_temp (old);
11505 return it.glyph_row;
11509 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
11510 glyphs are only inserted for terminal frames since we can't really
11511 win with truncation glyphs when partially visible glyphs are
11512 involved. Which glyphs to insert is determined by
11513 produce_special_glyphs. */
11515 static void
11516 insert_left_trunc_glyphs (it)
11517 struct it *it;
11519 struct it truncate_it;
11520 struct glyph *from, *end, *to, *toend;
11522 xassert (!FRAME_WINDOW_P (it->f));
11524 /* Get the truncation glyphs. */
11525 truncate_it = *it;
11526 truncate_it.current_x = 0;
11527 truncate_it.face_id = DEFAULT_FACE_ID;
11528 truncate_it.glyph_row = &scratch_glyph_row;
11529 truncate_it.glyph_row->used[TEXT_AREA] = 0;
11530 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
11531 truncate_it.object = make_number (0);
11532 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
11534 /* Overwrite glyphs from IT with truncation glyphs. */
11535 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
11536 end = from + truncate_it.glyph_row->used[TEXT_AREA];
11537 to = it->glyph_row->glyphs[TEXT_AREA];
11538 toend = to + it->glyph_row->used[TEXT_AREA];
11540 while (from < end)
11541 *to++ = *from++;
11543 /* There may be padding glyphs left over. Remove them. */
11544 from = to;
11545 while (from < toend && CHAR_GLYPH_PADDING_P (*from))
11546 ++from;
11547 while (from < toend)
11548 *to++ = *from++;
11550 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
11554 /* Compute the pixel height and width of IT->glyph_row.
11556 Most of the time, ascent and height of a display line will be equal
11557 to the max_ascent and max_height values of the display iterator
11558 structure. This is not the case if
11560 1. We hit ZV without displaying anything. In this case, max_ascent
11561 and max_height will be zero.
11563 2. We have some glyphs that don't contribute to the line height.
11564 (The glyph row flag contributes_to_line_height_p is for future
11565 pixmap extensions).
11567 The first case is easily covered by using default values because in
11568 these cases, the line height does not really matter, except that it
11569 must not be zero. */
11571 static void
11572 compute_line_metrics (it)
11573 struct it *it;
11575 struct glyph_row *row = it->glyph_row;
11576 int area, i;
11578 if (FRAME_WINDOW_P (it->f))
11580 int i, header_line_height;
11582 /* The line may consist of one space only, that was added to
11583 place the cursor on it. If so, the row's height hasn't been
11584 computed yet. */
11585 if (row->height == 0)
11587 if (it->max_ascent + it->max_descent == 0)
11588 it->max_descent = it->max_phys_descent = CANON_Y_UNIT (it->f);
11589 row->ascent = it->max_ascent;
11590 row->height = it->max_ascent + it->max_descent;
11591 row->phys_ascent = it->max_phys_ascent;
11592 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
11595 /* Compute the width of this line. */
11596 row->pixel_width = row->x;
11597 for (i = 0; i < row->used[TEXT_AREA]; ++i)
11598 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
11600 xassert (row->pixel_width >= 0);
11601 xassert (row->ascent >= 0 && row->height > 0);
11603 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
11604 || MATRIX_ROW_OVERLAPS_PRED_P (row));
11606 /* If first line's physical ascent is larger than its logical
11607 ascent, use the physical ascent, and make the row taller.
11608 This makes accented characters fully visible. */
11609 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
11610 && row->phys_ascent > row->ascent)
11612 row->height += row->phys_ascent - row->ascent;
11613 row->ascent = row->phys_ascent;
11616 /* Compute how much of the line is visible. */
11617 row->visible_height = row->height;
11619 header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (it->w);
11620 if (row->y < header_line_height)
11621 row->visible_height -= header_line_height - row->y;
11622 else
11624 int max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (it->w);
11625 if (row->y + row->height > max_y)
11626 row->visible_height -= row->y + row->height - max_y;
11629 else
11631 row->pixel_width = row->used[TEXT_AREA];
11632 row->ascent = row->phys_ascent = 0;
11633 row->height = row->phys_height = row->visible_height = 1;
11636 /* Compute a hash code for this row. */
11637 row->hash = 0;
11638 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
11639 for (i = 0; i < row->used[area]; ++i)
11640 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
11641 + row->glyphs[area][i].u.val
11642 + row->glyphs[area][i].face_id
11643 + row->glyphs[area][i].padding_p
11644 + (row->glyphs[area][i].type << 2));
11646 it->max_ascent = it->max_descent = 0;
11647 it->max_phys_ascent = it->max_phys_descent = 0;
11651 /* Append one space to the glyph row of iterator IT if doing a
11652 window-based redisplay. DEFAULT_FACE_P non-zero means let the
11653 space have the default face, otherwise let it have the same face as
11654 IT->face_id. Value is non-zero if a space was added.
11656 This function is called to make sure that there is always one glyph
11657 at the end of a glyph row that the cursor can be set on under
11658 window-systems. (If there weren't such a glyph we would not know
11659 how wide and tall a box cursor should be displayed).
11661 At the same time this space let's a nicely handle clearing to the
11662 end of the line if the row ends in italic text. */
11664 static int
11665 append_space (it, default_face_p)
11666 struct it *it;
11667 int default_face_p;
11669 if (FRAME_WINDOW_P (it->f))
11671 int n = it->glyph_row->used[TEXT_AREA];
11673 if (it->glyph_row->glyphs[TEXT_AREA] + n
11674 < it->glyph_row->glyphs[1 + TEXT_AREA])
11676 /* Save some values that must not be changed.
11677 Must save IT->c and IT->len because otherwise
11678 ITERATOR_AT_END_P wouldn't work anymore after
11679 append_space has been called. */
11680 int saved_what = it->what;
11681 int saved_c = it->c, saved_len = it->len;
11682 int saved_x = it->current_x;
11683 int saved_face_id = it->face_id;
11684 struct text_pos saved_pos;
11685 Lisp_Object saved_object;
11686 struct face *face;
11688 saved_object = it->object;
11689 saved_pos = it->position;
11691 it->what = IT_CHARACTER;
11692 bzero (&it->position, sizeof it->position);
11693 it->object = make_number (0);
11694 it->c = ' ';
11695 it->len = 1;
11697 if (default_face_p)
11698 it->face_id = DEFAULT_FACE_ID;
11699 face = FACE_FROM_ID (it->f, it->face_id);
11700 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
11702 PRODUCE_GLYPHS (it);
11704 it->current_x = saved_x;
11705 it->object = saved_object;
11706 it->position = saved_pos;
11707 it->what = saved_what;
11708 it->face_id = saved_face_id;
11709 it->len = saved_len;
11710 it->c = saved_c;
11711 return 1;
11715 return 0;
11719 /* Extend the face of the last glyph in the text area of IT->glyph_row
11720 to the end of the display line. Called from display_line.
11721 If the glyph row is empty, add a space glyph to it so that we
11722 know the face to draw. Set the glyph row flag fill_line_p. */
11724 static void
11725 extend_face_to_end_of_line (it)
11726 struct it *it;
11728 struct face *face;
11729 struct frame *f = it->f;
11731 /* If line is already filled, do nothing. */
11732 if (it->current_x >= it->last_visible_x)
11733 return;
11735 /* Face extension extends the background and box of IT->face_id
11736 to the end of the line. If the background equals the background
11737 of the frame, we haven't to do anything. */
11738 face = FACE_FROM_ID (f, it->face_id);
11739 if (FRAME_WINDOW_P (f)
11740 && face->box == FACE_NO_BOX
11741 && face->background == FRAME_BACKGROUND_PIXEL (f)
11742 && !face->stipple)
11743 return;
11745 /* Set the glyph row flag indicating that the face of the last glyph
11746 in the text area has to be drawn to the end of the text area. */
11747 it->glyph_row->fill_line_p = 1;
11749 /* If current character of IT is not ASCII, make sure we have the
11750 ASCII face. This will be automatically undone the next time
11751 get_next_display_element returns a multibyte character. Note
11752 that the character will always be single byte in unibyte text. */
11753 if (!SINGLE_BYTE_CHAR_P (it->c))
11755 it->face_id = FACE_FOR_CHAR (f, face, 0);
11758 if (FRAME_WINDOW_P (f))
11760 /* If the row is empty, add a space with the current face of IT,
11761 so that we know which face to draw. */
11762 if (it->glyph_row->used[TEXT_AREA] == 0)
11764 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
11765 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
11766 it->glyph_row->used[TEXT_AREA] = 1;
11769 else
11771 /* Save some values that must not be changed. */
11772 int saved_x = it->current_x;
11773 struct text_pos saved_pos;
11774 Lisp_Object saved_object;
11775 int saved_what = it->what;
11777 saved_object = it->object;
11778 saved_pos = it->position;
11780 it->what = IT_CHARACTER;
11781 bzero (&it->position, sizeof it->position);
11782 it->object = make_number (0);
11783 it->c = ' ';
11784 it->len = 1;
11786 PRODUCE_GLYPHS (it);
11788 while (it->current_x <= it->last_visible_x)
11789 PRODUCE_GLYPHS (it);
11791 /* Don't count these blanks really. It would let us insert a left
11792 truncation glyph below and make us set the cursor on them, maybe. */
11793 it->current_x = saved_x;
11794 it->object = saved_object;
11795 it->position = saved_pos;
11796 it->what = saved_what;
11801 /* Value is non-zero if text starting at CHARPOS in current_buffer is
11802 trailing whitespace. */
11804 static int
11805 trailing_whitespace_p (charpos)
11806 int charpos;
11808 int bytepos = CHAR_TO_BYTE (charpos);
11809 int c = 0;
11811 while (bytepos < ZV_BYTE
11812 && (c = FETCH_CHAR (bytepos),
11813 c == ' ' || c == '\t'))
11814 ++bytepos;
11816 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
11818 if (bytepos != PT_BYTE)
11819 return 1;
11821 return 0;
11825 /* Highlight trailing whitespace, if any, in ROW. */
11827 void
11828 highlight_trailing_whitespace (f, row)
11829 struct frame *f;
11830 struct glyph_row *row;
11832 int used = row->used[TEXT_AREA];
11834 if (used)
11836 struct glyph *start = row->glyphs[TEXT_AREA];
11837 struct glyph *glyph = start + used - 1;
11839 /* Skip over the space glyph inserted to display the
11840 cursor at the end of a line. */
11841 if (glyph->type == CHAR_GLYPH
11842 && glyph->u.ch == ' '
11843 && INTEGERP (glyph->object))
11844 --glyph;
11846 /* If last glyph is a space or stretch, and it's trailing
11847 whitespace, set the face of all trailing whitespace glyphs in
11848 IT->glyph_row to `trailing-whitespace'. */
11849 if (glyph >= start
11850 && BUFFERP (glyph->object)
11851 && (glyph->type == STRETCH_GLYPH
11852 || (glyph->type == CHAR_GLYPH
11853 && glyph->u.ch == ' '))
11854 && trailing_whitespace_p (glyph->charpos))
11856 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
11858 while (glyph >= start
11859 && BUFFERP (glyph->object)
11860 && (glyph->type == STRETCH_GLYPH
11861 || (glyph->type == CHAR_GLYPH
11862 && glyph->u.ch == ' ')))
11863 (glyph--)->face_id = face_id;
11869 /* Value is non-zero if glyph row ROW in window W should be
11870 used to hold the cursor. */
11872 static int
11873 cursor_row_p (w, row)
11874 struct window *w;
11875 struct glyph_row *row;
11877 int cursor_row_p = 1;
11879 if (PT == MATRIX_ROW_END_CHARPOS (row))
11881 /* If the row ends with a newline from a string, we don't want
11882 the cursor there (if the row is continued it doesn't end in a
11883 newline). */
11884 if (CHARPOS (row->end.string_pos) >= 0
11885 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11886 cursor_row_p = row->continued_p;
11888 /* If the row ends at ZV, display the cursor at the end of that
11889 row instead of at the start of the row below. */
11890 else if (row->ends_at_zv_p)
11891 cursor_row_p = 1;
11892 else
11893 cursor_row_p = 0;
11896 return cursor_row_p;
11900 /* Construct the glyph row IT->glyph_row in the desired matrix of
11901 IT->w from text at the current position of IT. See dispextern.h
11902 for an overview of struct it. Value is non-zero if
11903 IT->glyph_row displays text, as opposed to a line displaying ZV
11904 only. */
11906 static int
11907 display_line (it)
11908 struct it *it;
11910 struct glyph_row *row = it->glyph_row;
11912 /* We always start displaying at hpos zero even if hscrolled. */
11913 xassert (it->hpos == 0 && it->current_x == 0);
11915 /* We must not display in a row that's not a text row. */
11916 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
11917 < it->w->desired_matrix->nrows);
11919 /* Is IT->w showing the region? */
11920 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
11922 /* Clear the result glyph row and enable it. */
11923 prepare_desired_row (row);
11925 row->y = it->current_y;
11926 row->start = it->current;
11927 row->continuation_lines_width = it->continuation_lines_width;
11928 row->displays_text_p = 1;
11929 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
11930 it->starts_in_middle_of_char_p = 0;
11932 /* Arrange the overlays nicely for our purposes. Usually, we call
11933 display_line on only one line at a time, in which case this
11934 can't really hurt too much, or we call it on lines which appear
11935 one after another in the buffer, in which case all calls to
11936 recenter_overlay_lists but the first will be pretty cheap. */
11937 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
11939 /* Move over display elements that are not visible because we are
11940 hscrolled. This may stop at an x-position < IT->first_visible_x
11941 if the first glyph is partially visible or if we hit a line end. */
11942 if (it->current_x < it->first_visible_x)
11943 move_it_in_display_line_to (it, ZV, it->first_visible_x,
11944 MOVE_TO_POS | MOVE_TO_X);
11946 /* Get the initial row height. This is either the height of the
11947 text hscrolled, if there is any, or zero. */
11948 row->ascent = it->max_ascent;
11949 row->height = it->max_ascent + it->max_descent;
11950 row->phys_ascent = it->max_phys_ascent;
11951 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
11953 /* Loop generating characters. The loop is left with IT on the next
11954 character to display. */
11955 while (1)
11957 int n_glyphs_before, hpos_before, x_before;
11958 int x, i, nglyphs;
11959 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
11961 /* Retrieve the next thing to display. Value is zero if end of
11962 buffer reached. */
11963 if (!get_next_display_element (it))
11965 /* Maybe add a space at the end of this line that is used to
11966 display the cursor there under X. Set the charpos of the
11967 first glyph of blank lines not corresponding to any text
11968 to -1. */
11969 if ((append_space (it, 1) && row->used[TEXT_AREA] == 1)
11970 || row->used[TEXT_AREA] == 0)
11972 row->glyphs[TEXT_AREA]->charpos = -1;
11973 row->displays_text_p = 0;
11975 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines))
11976 row->indicate_empty_line_p = 1;
11979 it->continuation_lines_width = 0;
11980 row->ends_at_zv_p = 1;
11981 break;
11984 /* Now, get the metrics of what we want to display. This also
11985 generates glyphs in `row' (which is IT->glyph_row). */
11986 n_glyphs_before = row->used[TEXT_AREA];
11987 x = it->current_x;
11989 /* Remember the line height so far in case the next element doesn't
11990 fit on the line. */
11991 if (!it->truncate_lines_p)
11993 ascent = it->max_ascent;
11994 descent = it->max_descent;
11995 phys_ascent = it->max_phys_ascent;
11996 phys_descent = it->max_phys_descent;
11999 PRODUCE_GLYPHS (it);
12001 /* If this display element was in marginal areas, continue with
12002 the next one. */
12003 if (it->area != TEXT_AREA)
12005 row->ascent = max (row->ascent, it->max_ascent);
12006 row->height = max (row->height, it->max_ascent + it->max_descent);
12007 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
12008 row->phys_height = max (row->phys_height,
12009 it->max_phys_ascent + it->max_phys_descent);
12010 set_iterator_to_next (it, 1);
12011 continue;
12014 /* Does the display element fit on the line? If we truncate
12015 lines, we should draw past the right edge of the window. If
12016 we don't truncate, we want to stop so that we can display the
12017 continuation glyph before the right margin. If lines are
12018 continued, there are two possible strategies for characters
12019 resulting in more than 1 glyph (e.g. tabs): Display as many
12020 glyphs as possible in this line and leave the rest for the
12021 continuation line, or display the whole element in the next
12022 line. Original redisplay did the former, so we do it also. */
12023 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
12024 hpos_before = it->hpos;
12025 x_before = x;
12027 if (nglyphs == 1
12028 && it->current_x < it->last_visible_x)
12030 ++it->hpos;
12031 row->ascent = max (row->ascent, it->max_ascent);
12032 row->height = max (row->height, it->max_ascent + it->max_descent);
12033 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
12034 row->phys_height = max (row->phys_height,
12035 it->max_phys_ascent + it->max_phys_descent);
12036 if (it->current_x - it->pixel_width < it->first_visible_x)
12037 row->x = x - it->first_visible_x;
12039 else
12041 int new_x;
12042 struct glyph *glyph;
12044 for (i = 0; i < nglyphs; ++i, x = new_x)
12046 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
12047 new_x = x + glyph->pixel_width;
12049 if (/* Lines are continued. */
12050 !it->truncate_lines_p
12051 && (/* Glyph doesn't fit on the line. */
12052 new_x > it->last_visible_x
12053 /* Or it fits exactly on a window system frame. */
12054 || (new_x == it->last_visible_x
12055 && FRAME_WINDOW_P (it->f))))
12057 /* End of a continued line. */
12059 if (it->hpos == 0
12060 || (new_x == it->last_visible_x
12061 && FRAME_WINDOW_P (it->f)))
12063 /* Current glyph is the only one on the line or
12064 fits exactly on the line. We must continue
12065 the line because we can't draw the cursor
12066 after the glyph. */
12067 row->continued_p = 1;
12068 it->current_x = new_x;
12069 it->continuation_lines_width += new_x;
12070 ++it->hpos;
12071 if (i == nglyphs - 1)
12072 set_iterator_to_next (it, 1);
12074 else if (CHAR_GLYPH_PADDING_P (*glyph)
12075 && !FRAME_WINDOW_P (it->f))
12077 /* A padding glyph that doesn't fit on this line.
12078 This means the whole character doesn't fit
12079 on the line. */
12080 row->used[TEXT_AREA] = n_glyphs_before;
12082 /* Fill the rest of the row with continuation
12083 glyphs like in 20.x. */
12084 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
12085 < row->glyphs[1 + TEXT_AREA])
12086 produce_special_glyphs (it, IT_CONTINUATION);
12088 row->continued_p = 1;
12089 it->current_x = x_before;
12090 it->continuation_lines_width += x_before;
12092 /* Restore the height to what it was before the
12093 element not fitting on the line. */
12094 it->max_ascent = ascent;
12095 it->max_descent = descent;
12096 it->max_phys_ascent = phys_ascent;
12097 it->max_phys_descent = phys_descent;
12099 else
12101 /* Display element draws past the right edge of
12102 the window. Restore positions to values
12103 before the element. The next line starts
12104 with current_x before the glyph that could
12105 not be displayed, so that TAB works right. */
12106 row->used[TEXT_AREA] = n_glyphs_before + i;
12108 /* Display continuation glyphs. */
12109 if (!FRAME_WINDOW_P (it->f))
12110 produce_special_glyphs (it, IT_CONTINUATION);
12111 row->continued_p = 1;
12113 it->current_x = x;
12114 it->continuation_lines_width += x;
12115 if (nglyphs > 1 && i > 0)
12117 row->ends_in_middle_of_char_p = 1;
12118 it->starts_in_middle_of_char_p = 1;
12121 /* Restore the height to what it was before the
12122 element not fitting on the line. */
12123 it->max_ascent = ascent;
12124 it->max_descent = descent;
12125 it->max_phys_ascent = phys_ascent;
12126 it->max_phys_descent = phys_descent;
12129 break;
12131 else if (new_x > it->first_visible_x)
12133 /* Increment number of glyphs actually displayed. */
12134 ++it->hpos;
12136 if (x < it->first_visible_x)
12137 /* Glyph is partially visible, i.e. row starts at
12138 negative X position. */
12139 row->x = x - it->first_visible_x;
12141 else
12143 /* Glyph is completely off the left margin of the
12144 window. This should not happen because of the
12145 move_it_in_display_line at the start of
12146 this function. */
12147 abort ();
12151 row->ascent = max (row->ascent, it->max_ascent);
12152 row->height = max (row->height, it->max_ascent + it->max_descent);
12153 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
12154 row->phys_height = max (row->phys_height,
12155 it->max_phys_ascent + it->max_phys_descent);
12157 /* End of this display line if row is continued. */
12158 if (row->continued_p)
12159 break;
12162 /* Is this a line end? If yes, we're also done, after making
12163 sure that a non-default face is extended up to the right
12164 margin of the window. */
12165 if (ITERATOR_AT_END_OF_LINE_P (it))
12167 int used_before = row->used[TEXT_AREA];
12169 /* Add a space at the end of the line that is used to
12170 display the cursor there. */
12171 append_space (it, 0);
12173 /* Extend the face to the end of the line. */
12174 extend_face_to_end_of_line (it);
12176 /* Make sure we have the position. */
12177 if (used_before == 0)
12178 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
12180 /* Consume the line end. This skips over invisible lines. */
12181 set_iterator_to_next (it, 1);
12182 it->continuation_lines_width = 0;
12183 break;
12186 /* Proceed with next display element. Note that this skips
12187 over lines invisible because of selective display. */
12188 set_iterator_to_next (it, 1);
12190 /* If we truncate lines, we are done when the last displayed
12191 glyphs reach past the right margin of the window. */
12192 if (it->truncate_lines_p
12193 && (FRAME_WINDOW_P (it->f)
12194 ? (it->current_x >= it->last_visible_x)
12195 : (it->current_x > it->last_visible_x)))
12197 /* Maybe add truncation glyphs. */
12198 if (!FRAME_WINDOW_P (it->f))
12200 --it->glyph_row->used[TEXT_AREA];
12201 produce_special_glyphs (it, IT_TRUNCATION);
12204 row->truncated_on_right_p = 1;
12205 it->continuation_lines_width = 0;
12206 reseat_at_next_visible_line_start (it, 0);
12207 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
12208 it->hpos = hpos_before;
12209 it->current_x = x_before;
12210 break;
12214 /* If line is not empty and hscrolled, maybe insert truncation glyphs
12215 at the left window margin. */
12216 if (it->first_visible_x
12217 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
12219 if (!FRAME_WINDOW_P (it->f))
12220 insert_left_trunc_glyphs (it);
12221 row->truncated_on_left_p = 1;
12224 /* If the start of this line is the overlay arrow-position, then
12225 mark this glyph row as the one containing the overlay arrow.
12226 This is clearly a mess with variable size fonts. It would be
12227 better to let it be displayed like cursors under X. */
12228 if (MARKERP (Voverlay_arrow_position)
12229 && current_buffer == XMARKER (Voverlay_arrow_position)->buffer
12230 && (MATRIX_ROW_START_CHARPOS (row)
12231 == marker_position (Voverlay_arrow_position))
12232 && STRINGP (Voverlay_arrow_string)
12233 && ! overlay_arrow_seen)
12235 /* Overlay arrow in window redisplay is a bitmap. */
12236 if (!FRAME_WINDOW_P (it->f))
12238 struct glyph_row *arrow_row = get_overlay_arrow_glyph_row (it->w);
12239 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
12240 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
12241 struct glyph *p = row->glyphs[TEXT_AREA];
12242 struct glyph *p2, *end;
12244 /* Copy the arrow glyphs. */
12245 while (glyph < arrow_end)
12246 *p++ = *glyph++;
12248 /* Throw away padding glyphs. */
12249 p2 = p;
12250 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
12251 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
12252 ++p2;
12253 if (p2 > p)
12255 while (p2 < end)
12256 *p++ = *p2++;
12257 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
12261 overlay_arrow_seen = 1;
12262 row->overlay_arrow_p = 1;
12265 /* Compute pixel dimensions of this line. */
12266 compute_line_metrics (it);
12268 /* Remember the position at which this line ends. */
12269 row->end = it->current;
12271 /* Maybe set the cursor. */
12272 if (it->w->cursor.vpos < 0
12273 && PT >= MATRIX_ROW_START_CHARPOS (row)
12274 && PT <= MATRIX_ROW_END_CHARPOS (row)
12275 && cursor_row_p (it->w, row))
12276 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
12278 /* Highlight trailing whitespace. */
12279 if (!NILP (Vshow_trailing_whitespace))
12280 highlight_trailing_whitespace (it->f, it->glyph_row);
12282 /* Prepare for the next line. This line starts horizontally at (X
12283 HPOS) = (0 0). Vertical positions are incremented. As a
12284 convenience for the caller, IT->glyph_row is set to the next
12285 row to be used. */
12286 it->current_x = it->hpos = 0;
12287 it->current_y += row->height;
12288 ++it->vpos;
12289 ++it->glyph_row;
12290 return row->displays_text_p;
12295 /***********************************************************************
12296 Menu Bar
12297 ***********************************************************************/
12299 /* Redisplay the menu bar in the frame for window W.
12301 The menu bar of X frames that don't have X toolkit support is
12302 displayed in a special window W->frame->menu_bar_window.
12304 The menu bar of terminal frames is treated specially as far as
12305 glyph matrices are concerned. Menu bar lines are not part of
12306 windows, so the update is done directly on the frame matrix rows
12307 for the menu bar. */
12309 static void
12310 display_menu_bar (w)
12311 struct window *w;
12313 struct frame *f = XFRAME (WINDOW_FRAME (w));
12314 struct it it;
12315 Lisp_Object items;
12316 int i;
12318 /* Don't do all this for graphical frames. */
12319 #ifdef HAVE_NTGUI
12320 if (!NILP (Vwindow_system))
12321 return;
12322 #endif
12323 #ifdef USE_X_TOOLKIT
12324 if (FRAME_X_P (f))
12325 return;
12326 #endif
12327 #ifdef macintosh
12328 if (FRAME_MAC_P (f))
12329 return;
12330 #endif
12332 #ifdef USE_X_TOOLKIT
12333 xassert (!FRAME_WINDOW_P (f));
12334 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
12335 it.first_visible_x = 0;
12336 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
12337 #else /* not USE_X_TOOLKIT */
12338 if (FRAME_WINDOW_P (f))
12340 /* Menu bar lines are displayed in the desired matrix of the
12341 dummy window menu_bar_window. */
12342 struct window *menu_w;
12343 xassert (WINDOWP (f->menu_bar_window));
12344 menu_w = XWINDOW (f->menu_bar_window);
12345 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
12346 MENU_FACE_ID);
12347 it.first_visible_x = 0;
12348 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
12350 else
12352 /* This is a TTY frame, i.e. character hpos/vpos are used as
12353 pixel x/y. */
12354 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
12355 MENU_FACE_ID);
12356 it.first_visible_x = 0;
12357 it.last_visible_x = FRAME_WIDTH (f);
12359 #endif /* not USE_X_TOOLKIT */
12361 if (! mode_line_inverse_video)
12362 /* Force the menu-bar to be displayed in the default face. */
12363 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
12365 /* Clear all rows of the menu bar. */
12366 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
12368 struct glyph_row *row = it.glyph_row + i;
12369 clear_glyph_row (row);
12370 row->enabled_p = 1;
12371 row->full_width_p = 1;
12374 /* Display all items of the menu bar. */
12375 items = FRAME_MENU_BAR_ITEMS (it.f);
12376 for (i = 0; i < XVECTOR (items)->size; i += 4)
12378 Lisp_Object string;
12380 /* Stop at nil string. */
12381 string = XVECTOR (items)->contents[i + 1];
12382 if (NILP (string))
12383 break;
12385 /* Remember where item was displayed. */
12386 XSETFASTINT (XVECTOR (items)->contents[i + 3], it.hpos);
12388 /* Display the item, pad with one space. */
12389 if (it.current_x < it.last_visible_x)
12390 display_string (NULL, string, Qnil, 0, 0, &it,
12391 XSTRING (string)->size + 1, 0, 0, -1);
12394 /* Fill out the line with spaces. */
12395 if (it.current_x < it.last_visible_x)
12396 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
12398 /* Compute the total height of the lines. */
12399 compute_line_metrics (&it);
12404 /***********************************************************************
12405 Mode Line
12406 ***********************************************************************/
12408 /* Redisplay mode lines in the window tree whose root is WINDOW. If
12409 FORCE is non-zero, redisplay mode lines unconditionally.
12410 Otherwise, redisplay only mode lines that are garbaged. Value is
12411 the number of windows whose mode lines were redisplayed. */
12413 static int
12414 redisplay_mode_lines (window, force)
12415 Lisp_Object window;
12416 int force;
12418 int nwindows = 0;
12420 while (!NILP (window))
12422 struct window *w = XWINDOW (window);
12424 if (WINDOWP (w->hchild))
12425 nwindows += redisplay_mode_lines (w->hchild, force);
12426 else if (WINDOWP (w->vchild))
12427 nwindows += redisplay_mode_lines (w->vchild, force);
12428 else if (force
12429 || FRAME_GARBAGED_P (XFRAME (w->frame))
12430 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
12432 Lisp_Object old_selected_frame;
12433 struct text_pos lpoint;
12434 struct buffer *old = current_buffer;
12436 /* Set the window's buffer for the mode line display. */
12437 SET_TEXT_POS (lpoint, PT, PT_BYTE);
12438 set_buffer_internal_1 (XBUFFER (w->buffer));
12440 /* Point refers normally to the selected window. For any
12441 other window, set up appropriate value. */
12442 if (!EQ (window, selected_window))
12444 struct text_pos pt;
12446 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
12447 if (CHARPOS (pt) < BEGV)
12448 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
12449 else if (CHARPOS (pt) > (ZV - 1))
12450 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
12451 else
12452 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
12455 /* Temporarily set up the selected frame. */
12456 old_selected_frame = selected_frame;
12457 selected_frame = w->frame;
12459 /* Display mode lines. */
12460 clear_glyph_matrix (w->desired_matrix);
12461 if (display_mode_lines (w))
12463 ++nwindows;
12464 w->must_be_updated_p = 1;
12467 /* Restore old settings. */
12468 selected_frame = old_selected_frame;
12469 set_buffer_internal_1 (old);
12470 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12473 window = w->next;
12476 return nwindows;
12480 /* Display the mode and/or top line of window W. Value is the number
12481 of mode lines displayed. */
12483 static int
12484 display_mode_lines (w)
12485 struct window *w;
12487 int n = 0;
12489 /* These will be set while the mode line specs are processed. */
12490 line_number_displayed = 0;
12491 w->column_number_displayed = Qnil;
12493 if (WINDOW_WANTS_MODELINE_P (w))
12495 display_mode_line (w, MODE_LINE_FACE_ID,
12496 current_buffer->mode_line_format);
12497 ++n;
12500 if (WINDOW_WANTS_HEADER_LINE_P (w))
12502 display_mode_line (w, HEADER_LINE_FACE_ID,
12503 current_buffer->header_line_format);
12504 ++n;
12507 return n;
12511 /* Display mode or top line of window W. FACE_ID specifies which line
12512 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
12513 FORMAT is the mode line format to display. Value is the pixel
12514 height of the mode line displayed. */
12516 static int
12517 display_mode_line (w, face_id, format)
12518 struct window *w;
12519 enum face_id face_id;
12520 Lisp_Object format;
12522 struct it it;
12523 struct face *face;
12525 init_iterator (&it, w, -1, -1, NULL, face_id);
12526 prepare_desired_row (it.glyph_row);
12528 if (! mode_line_inverse_video)
12529 /* Force the mode-line to be displayed in the default face. */
12530 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
12532 /* Temporarily make frame's keyboard the current kboard so that
12533 kboard-local variables in the mode_line_format will get the right
12534 values. */
12535 push_frame_kboard (it.f);
12536 display_mode_element (&it, 0, 0, 0, format);
12537 pop_frame_kboard ();
12539 /* Fill up with spaces. */
12540 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
12542 compute_line_metrics (&it);
12543 it.glyph_row->full_width_p = 1;
12544 it.glyph_row->mode_line_p = 1;
12545 it.glyph_row->inverse_p = 0;
12546 it.glyph_row->continued_p = 0;
12547 it.glyph_row->truncated_on_left_p = 0;
12548 it.glyph_row->truncated_on_right_p = 0;
12550 /* Make a 3D mode-line have a shadow at its right end. */
12551 face = FACE_FROM_ID (it.f, face_id);
12552 extend_face_to_end_of_line (&it);
12553 if (face->box != FACE_NO_BOX)
12555 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
12556 + it.glyph_row->used[TEXT_AREA] - 1);
12557 last->right_box_line_p = 1;
12560 return it.glyph_row->height;
12564 /* Contribute ELT to the mode line for window IT->w. How it
12565 translates into text depends on its data type.
12567 IT describes the display environment in which we display, as usual.
12569 DEPTH is the depth in recursion. It is used to prevent
12570 infinite recursion here.
12572 FIELD_WIDTH is the number of characters the display of ELT should
12573 occupy in the mode line, and PRECISION is the maximum number of
12574 characters to display from ELT's representation. See
12575 display_string for details. *
12577 Returns the hpos of the end of the text generated by ELT. */
12579 static int
12580 display_mode_element (it, depth, field_width, precision, elt)
12581 struct it *it;
12582 int depth;
12583 int field_width, precision;
12584 Lisp_Object elt;
12586 int n = 0, field, prec;
12588 tail_recurse:
12589 if (depth > 10)
12590 goto invalid;
12592 depth++;
12594 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
12596 case Lisp_String:
12598 /* A string: output it and check for %-constructs within it. */
12599 unsigned char c;
12600 unsigned char *this = XSTRING (elt)->data;
12601 unsigned char *lisp_string = this;
12603 while ((precision <= 0 || n < precision)
12604 && *this
12605 && (frame_title_ptr
12606 || it->current_x < it->last_visible_x))
12608 unsigned char *last = this;
12610 /* Advance to end of string or next format specifier. */
12611 while ((c = *this++) != '\0' && c != '%')
12614 if (this - 1 != last)
12616 /* Output to end of string or up to '%'. Field width
12617 is length of string. Don't output more than
12618 PRECISION allows us. */
12619 prec = --this - last;
12620 if (precision > 0 && prec > precision - n)
12621 prec = precision - n;
12623 if (frame_title_ptr)
12624 n += store_frame_title (last, prec, prec);
12625 else
12626 n += display_string (NULL, elt, Qnil, 0, last - lisp_string,
12627 it, 0, prec, 0, -1);
12629 else /* c == '%' */
12631 unsigned char *percent_position = this;
12633 /* Get the specified minimum width. Zero means
12634 don't pad. */
12635 field = 0;
12636 while ((c = *this++) >= '0' && c <= '9')
12637 field = field * 10 + c - '0';
12639 /* Don't pad beyond the total padding allowed. */
12640 if (field_width - n > 0 && field > field_width - n)
12641 field = field_width - n;
12643 /* Note that either PRECISION <= 0 or N < PRECISION. */
12644 prec = precision - n;
12646 if (c == 'M')
12647 n += display_mode_element (it, depth, field, prec,
12648 Vglobal_mode_string);
12649 else if (c != 0)
12651 unsigned char *spec
12652 = decode_mode_spec (it->w, c, field, prec);
12654 if (frame_title_ptr)
12655 n += store_frame_title (spec, field, prec);
12656 else
12658 int nglyphs_before
12659 = it->glyph_row->used[TEXT_AREA];
12660 int charpos
12661 = percent_position - XSTRING (elt)->data;
12662 int nwritten
12663 = display_string (spec, Qnil, elt, charpos, 0, it,
12664 field, prec, 0, -1);
12666 /* Assign to the glyphs written above the
12667 string where the `%x' came from, position
12668 of the `%'. */
12669 if (nwritten > 0)
12671 struct glyph *glyph
12672 = (it->glyph_row->glyphs[TEXT_AREA]
12673 + nglyphs_before);
12674 int i;
12676 for (i = 0; i < nwritten; ++i)
12678 glyph[i].object = elt;
12679 glyph[i].charpos = charpos;
12682 n += nwritten;
12689 break;
12691 case Lisp_Symbol:
12692 /* A symbol: process the value of the symbol recursively
12693 as if it appeared here directly. Avoid error if symbol void.
12694 Special case: if value of symbol is a string, output the string
12695 literally. */
12697 register Lisp_Object tem;
12698 tem = Fboundp (elt);
12699 if (!NILP (tem))
12701 tem = Fsymbol_value (elt);
12702 /* If value is a string, output that string literally:
12703 don't check for % within it. */
12704 if (STRINGP (tem))
12706 prec = XSTRING (tem)->size;
12707 if (precision > 0 && prec > precision - n)
12708 prec = precision - n;
12709 if (frame_title_ptr)
12710 n += store_frame_title (XSTRING (tem)->data, -1, prec);
12711 else
12712 n += display_string (NULL, tem, Qnil, 0, 0, it,
12713 0, prec, 0, -1);
12715 else if (!EQ (tem, elt))
12717 /* Give up right away for nil or t. */
12718 elt = tem;
12719 goto tail_recurse;
12723 break;
12725 case Lisp_Cons:
12727 register Lisp_Object car, tem;
12729 /* A cons cell: three distinct cases.
12730 If first element is a string or a cons, process all the elements
12731 and effectively concatenate them.
12732 If first element is a negative number, truncate displaying cdr to
12733 at most that many characters. If positive, pad (with spaces)
12734 to at least that many characters.
12735 If first element is a symbol, process the cadr or caddr recursively
12736 according to whether the symbol's value is non-nil or nil. */
12737 car = XCAR (elt);
12738 if (EQ (car, QCeval) && CONSP (XCDR (elt)))
12740 /* An element of the form (:eval FORM) means evaluate FORM
12741 and use the result as mode line elements. */
12742 struct gcpro gcpro1;
12743 Lisp_Object spec;
12745 spec = safe_eval (XCAR (XCDR (elt)));
12746 GCPRO1 (spec);
12747 n += display_mode_element (it, depth, field_width - n,
12748 precision - n, spec);
12749 UNGCPRO;
12751 else if (SYMBOLP (car))
12753 tem = Fboundp (car);
12754 elt = XCDR (elt);
12755 if (!CONSP (elt))
12756 goto invalid;
12757 /* elt is now the cdr, and we know it is a cons cell.
12758 Use its car if CAR has a non-nil value. */
12759 if (!NILP (tem))
12761 tem = Fsymbol_value (car);
12762 if (!NILP (tem))
12764 elt = XCAR (elt);
12765 goto tail_recurse;
12768 /* Symbol's value is nil (or symbol is unbound)
12769 Get the cddr of the original list
12770 and if possible find the caddr and use that. */
12771 elt = XCDR (elt);
12772 if (NILP (elt))
12773 break;
12774 else if (!CONSP (elt))
12775 goto invalid;
12776 elt = XCAR (elt);
12777 goto tail_recurse;
12779 else if (INTEGERP (car))
12781 register int lim = XINT (car);
12782 elt = XCDR (elt);
12783 if (lim < 0)
12785 /* Negative int means reduce maximum width. */
12786 if (precision <= 0)
12787 precision = -lim;
12788 else
12789 precision = min (precision, -lim);
12791 else if (lim > 0)
12793 /* Padding specified. Don't let it be more than
12794 current maximum. */
12795 if (precision > 0)
12796 lim = min (precision, lim);
12798 /* If that's more padding than already wanted, queue it.
12799 But don't reduce padding already specified even if
12800 that is beyond the current truncation point. */
12801 field_width = max (lim, field_width);
12803 goto tail_recurse;
12805 else if (STRINGP (car) || CONSP (car))
12807 register int limit = 50;
12808 /* Limit is to protect against circular lists. */
12809 while (CONSP (elt)
12810 && --limit > 0
12811 && (precision <= 0 || n < precision))
12813 n += display_mode_element (it, depth, field_width - n,
12814 precision - n, XCAR (elt));
12815 elt = XCDR (elt);
12819 break;
12821 default:
12822 invalid:
12823 if (frame_title_ptr)
12824 n += store_frame_title ("*invalid*", 0, precision - n);
12825 else
12826 n += display_string ("*invalid*", Qnil, Qnil, 0, 0, it, 0,
12827 precision - n, 0, 0);
12828 return n;
12831 /* Pad to FIELD_WIDTH. */
12832 if (field_width > 0 && n < field_width)
12834 if (frame_title_ptr)
12835 n += store_frame_title ("", field_width - n, 0);
12836 else
12837 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
12838 0, 0, 0);
12841 return n;
12845 /* Write a null-terminated, right justified decimal representation of
12846 the positive integer D to BUF using a minimal field width WIDTH. */
12848 static void
12849 pint2str (buf, width, d)
12850 register char *buf;
12851 register int width;
12852 register int d;
12854 register char *p = buf;
12856 if (d <= 0)
12857 *p++ = '0';
12858 else
12860 while (d > 0)
12862 *p++ = d % 10 + '0';
12863 d /= 10;
12867 for (width -= (int) (p - buf); width > 0; --width)
12868 *p++ = ' ';
12869 *p-- = '\0';
12870 while (p > buf)
12872 d = *buf;
12873 *buf++ = *p;
12874 *p-- = d;
12878 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
12879 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
12880 type of CODING_SYSTEM. Return updated pointer into BUF. */
12882 static unsigned char invalid_eol_type[] = "(*invalid*)";
12884 static char *
12885 decode_mode_spec_coding (coding_system, buf, eol_flag)
12886 Lisp_Object coding_system;
12887 register char *buf;
12888 int eol_flag;
12890 Lisp_Object val;
12891 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
12892 unsigned char *eol_str;
12893 int eol_str_len;
12894 /* The EOL conversion we are using. */
12895 Lisp_Object eoltype;
12897 val = Fget (coding_system, Qcoding_system);
12898 eoltype = Qnil;
12900 if (!VECTORP (val)) /* Not yet decided. */
12902 if (multibyte)
12903 *buf++ = '-';
12904 if (eol_flag)
12905 eoltype = eol_mnemonic_undecided;
12906 /* Don't mention EOL conversion if it isn't decided. */
12908 else
12910 Lisp_Object eolvalue;
12912 eolvalue = Fget (coding_system, Qeol_type);
12914 if (multibyte)
12915 *buf++ = XFASTINT (XVECTOR (val)->contents[1]);
12917 if (eol_flag)
12919 /* The EOL conversion that is normal on this system. */
12921 if (NILP (eolvalue)) /* Not yet decided. */
12922 eoltype = eol_mnemonic_undecided;
12923 else if (VECTORP (eolvalue)) /* Not yet decided. */
12924 eoltype = eol_mnemonic_undecided;
12925 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
12926 eoltype = (XFASTINT (eolvalue) == 0
12927 ? eol_mnemonic_unix
12928 : (XFASTINT (eolvalue) == 1
12929 ? eol_mnemonic_dos : eol_mnemonic_mac));
12933 if (eol_flag)
12935 /* Mention the EOL conversion if it is not the usual one. */
12936 if (STRINGP (eoltype))
12938 eol_str = XSTRING (eoltype)->data;
12939 eol_str_len = XSTRING (eoltype)->size;
12941 else if (INTEGERP (eoltype)
12942 && CHAR_VALID_P (XINT (eoltype), 0))
12944 eol_str = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
12945 eol_str_len = CHAR_STRING (XINT (eoltype), eol_str);
12947 else
12949 eol_str = invalid_eol_type;
12950 eol_str_len = sizeof (invalid_eol_type) - 1;
12952 bcopy (eol_str, buf, eol_str_len);
12953 buf += eol_str_len;
12956 return buf;
12959 /* Return a string for the output of a mode line %-spec for window W,
12960 generated by character C. PRECISION >= 0 means don't return a
12961 string longer than that value. FIELD_WIDTH > 0 means pad the
12962 string returned with spaces to that value. */
12964 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
12966 static char *
12967 decode_mode_spec (w, c, field_width, precision)
12968 struct window *w;
12969 register int c;
12970 int field_width, precision;
12972 Lisp_Object obj;
12973 struct frame *f = XFRAME (WINDOW_FRAME (w));
12974 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
12975 struct buffer *b = XBUFFER (w->buffer);
12977 obj = Qnil;
12979 switch (c)
12981 case '*':
12982 if (!NILP (b->read_only))
12983 return "%";
12984 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
12985 return "*";
12986 return "-";
12988 case '+':
12989 /* This differs from %* only for a modified read-only buffer. */
12990 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
12991 return "*";
12992 if (!NILP (b->read_only))
12993 return "%";
12994 return "-";
12996 case '&':
12997 /* This differs from %* in ignoring read-only-ness. */
12998 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
12999 return "*";
13000 return "-";
13002 case '%':
13003 return "%";
13005 case '[':
13007 int i;
13008 char *p;
13010 if (command_loop_level > 5)
13011 return "[[[... ";
13012 p = decode_mode_spec_buf;
13013 for (i = 0; i < command_loop_level; i++)
13014 *p++ = '[';
13015 *p = 0;
13016 return decode_mode_spec_buf;
13019 case ']':
13021 int i;
13022 char *p;
13024 if (command_loop_level > 5)
13025 return " ...]]]";
13026 p = decode_mode_spec_buf;
13027 for (i = 0; i < command_loop_level; i++)
13028 *p++ = ']';
13029 *p = 0;
13030 return decode_mode_spec_buf;
13033 case '-':
13035 register int i;
13037 /* Let lots_of_dashes be a string of infinite length. */
13038 if (field_width <= 0
13039 || field_width > sizeof (lots_of_dashes))
13041 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
13042 decode_mode_spec_buf[i] = '-';
13043 decode_mode_spec_buf[i] = '\0';
13044 return decode_mode_spec_buf;
13046 else
13047 return lots_of_dashes;
13050 case 'b':
13051 obj = b->name;
13052 break;
13054 case 'c':
13056 int col = current_column ();
13057 XSETFASTINT (w->column_number_displayed, col);
13058 pint2str (decode_mode_spec_buf, field_width, col);
13059 return decode_mode_spec_buf;
13062 case 'F':
13063 /* %F displays the frame name. */
13064 if (!NILP (f->title))
13065 return (char *) XSTRING (f->title)->data;
13066 if (f->explicit_name || ! FRAME_WINDOW_P (f))
13067 return (char *) XSTRING (f->name)->data;
13068 return "Emacs";
13070 case 'f':
13071 obj = b->filename;
13072 break;
13074 case 'l':
13076 int startpos = XMARKER (w->start)->charpos;
13077 int startpos_byte = marker_byte_position (w->start);
13078 int line, linepos, linepos_byte, topline;
13079 int nlines, junk;
13080 int height = XFASTINT (w->height);
13082 /* If we decided that this buffer isn't suitable for line numbers,
13083 don't forget that too fast. */
13084 if (EQ (w->base_line_pos, w->buffer))
13085 goto no_value;
13086 /* But do forget it, if the window shows a different buffer now. */
13087 else if (BUFFERP (w->base_line_pos))
13088 w->base_line_pos = Qnil;
13090 /* If the buffer is very big, don't waste time. */
13091 if (INTEGERP (Vline_number_display_limit)
13092 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
13094 w->base_line_pos = Qnil;
13095 w->base_line_number = Qnil;
13096 goto no_value;
13099 if (!NILP (w->base_line_number)
13100 && !NILP (w->base_line_pos)
13101 && XFASTINT (w->base_line_pos) <= startpos)
13103 line = XFASTINT (w->base_line_number);
13104 linepos = XFASTINT (w->base_line_pos);
13105 linepos_byte = buf_charpos_to_bytepos (b, linepos);
13107 else
13109 line = 1;
13110 linepos = BUF_BEGV (b);
13111 linepos_byte = BUF_BEGV_BYTE (b);
13114 /* Count lines from base line to window start position. */
13115 nlines = display_count_lines (linepos, linepos_byte,
13116 startpos_byte,
13117 startpos, &junk);
13119 topline = nlines + line;
13121 /* Determine a new base line, if the old one is too close
13122 or too far away, or if we did not have one.
13123 "Too close" means it's plausible a scroll-down would
13124 go back past it. */
13125 if (startpos == BUF_BEGV (b))
13127 XSETFASTINT (w->base_line_number, topline);
13128 XSETFASTINT (w->base_line_pos, BUF_BEGV (b));
13130 else if (nlines < height + 25 || nlines > height * 3 + 50
13131 || linepos == BUF_BEGV (b))
13133 int limit = BUF_BEGV (b);
13134 int limit_byte = BUF_BEGV_BYTE (b);
13135 int position;
13136 int distance = (height * 2 + 30) * line_number_display_limit_width;
13138 if (startpos - distance > limit)
13140 limit = startpos - distance;
13141 limit_byte = CHAR_TO_BYTE (limit);
13144 nlines = display_count_lines (startpos, startpos_byte,
13145 limit_byte,
13146 - (height * 2 + 30),
13147 &position);
13148 /* If we couldn't find the lines we wanted within
13149 line_number_display_limit_width chars per line,
13150 give up on line numbers for this window. */
13151 if (position == limit_byte && limit == startpos - distance)
13153 w->base_line_pos = w->buffer;
13154 w->base_line_number = Qnil;
13155 goto no_value;
13158 XSETFASTINT (w->base_line_number, topline - nlines);
13159 XSETFASTINT (w->base_line_pos, BYTE_TO_CHAR (position));
13162 /* Now count lines from the start pos to point. */
13163 nlines = display_count_lines (startpos, startpos_byte,
13164 PT_BYTE, PT, &junk);
13166 /* Record that we did display the line number. */
13167 line_number_displayed = 1;
13169 /* Make the string to show. */
13170 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
13171 return decode_mode_spec_buf;
13172 no_value:
13174 char* p = decode_mode_spec_buf;
13175 int pad = field_width - 2;
13176 while (pad-- > 0)
13177 *p++ = ' ';
13178 *p++ = '?';
13179 *p++ = '?';
13180 *p = '\0';
13181 return decode_mode_spec_buf;
13184 break;
13186 case 'm':
13187 obj = b->mode_name;
13188 break;
13190 case 'n':
13191 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
13192 return " Narrow";
13193 break;
13195 case 'p':
13197 int pos = marker_position (w->start);
13198 int total = BUF_ZV (b) - BUF_BEGV (b);
13200 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
13202 if (pos <= BUF_BEGV (b))
13203 return "All";
13204 else
13205 return "Bottom";
13207 else if (pos <= BUF_BEGV (b))
13208 return "Top";
13209 else
13211 if (total > 1000000)
13212 /* Do it differently for a large value, to avoid overflow. */
13213 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
13214 else
13215 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
13216 /* We can't normally display a 3-digit number,
13217 so get us a 2-digit number that is close. */
13218 if (total == 100)
13219 total = 99;
13220 sprintf (decode_mode_spec_buf, "%2d%%", total);
13221 return decode_mode_spec_buf;
13225 /* Display percentage of size above the bottom of the screen. */
13226 case 'P':
13228 int toppos = marker_position (w->start);
13229 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
13230 int total = BUF_ZV (b) - BUF_BEGV (b);
13232 if (botpos >= BUF_ZV (b))
13234 if (toppos <= BUF_BEGV (b))
13235 return "All";
13236 else
13237 return "Bottom";
13239 else
13241 if (total > 1000000)
13242 /* Do it differently for a large value, to avoid overflow. */
13243 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
13244 else
13245 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
13246 /* We can't normally display a 3-digit number,
13247 so get us a 2-digit number that is close. */
13248 if (total == 100)
13249 total = 99;
13250 if (toppos <= BUF_BEGV (b))
13251 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
13252 else
13253 sprintf (decode_mode_spec_buf, "%2d%%", total);
13254 return decode_mode_spec_buf;
13258 case 's':
13259 /* status of process */
13260 obj = Fget_buffer_process (w->buffer);
13261 if (NILP (obj))
13262 return "no process";
13263 #ifdef subprocesses
13264 obj = Fsymbol_name (Fprocess_status (obj));
13265 #endif
13266 break;
13268 case 't': /* indicate TEXT or BINARY */
13269 #ifdef MODE_LINE_BINARY_TEXT
13270 return MODE_LINE_BINARY_TEXT (b);
13271 #else
13272 return "T";
13273 #endif
13275 case 'z':
13276 /* coding-system (not including end-of-line format) */
13277 case 'Z':
13278 /* coding-system (including end-of-line type) */
13280 int eol_flag = (c == 'Z');
13281 char *p = decode_mode_spec_buf;
13283 if (! FRAME_WINDOW_P (f))
13285 /* No need to mention EOL here--the terminal never needs
13286 to do EOL conversion. */
13287 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
13288 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
13290 p = decode_mode_spec_coding (b->buffer_file_coding_system,
13291 p, eol_flag);
13293 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
13294 #ifdef subprocesses
13295 obj = Fget_buffer_process (Fcurrent_buffer ());
13296 if (PROCESSP (obj))
13298 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
13299 p, eol_flag);
13300 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
13301 p, eol_flag);
13303 #endif /* subprocesses */
13304 #endif /* 0 */
13305 *p = 0;
13306 return decode_mode_spec_buf;
13310 if (STRINGP (obj))
13311 return (char *) XSTRING (obj)->data;
13312 else
13313 return "";
13317 /* Count up to COUNT lines starting from START / START_BYTE.
13318 But don't go beyond LIMIT_BYTE.
13319 Return the number of lines thus found (always nonnegative).
13321 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
13323 static int
13324 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
13325 int start, start_byte, limit_byte, count;
13326 int *byte_pos_ptr;
13328 register unsigned char *cursor;
13329 unsigned char *base;
13331 register int ceiling;
13332 register unsigned char *ceiling_addr;
13333 int orig_count = count;
13335 /* If we are not in selective display mode,
13336 check only for newlines. */
13337 int selective_display = (!NILP (current_buffer->selective_display)
13338 && !INTEGERP (current_buffer->selective_display));
13340 if (count > 0)
13342 while (start_byte < limit_byte)
13344 ceiling = BUFFER_CEILING_OF (start_byte);
13345 ceiling = min (limit_byte - 1, ceiling);
13346 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
13347 base = (cursor = BYTE_POS_ADDR (start_byte));
13348 while (1)
13350 if (selective_display)
13351 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
13353 else
13354 while (*cursor != '\n' && ++cursor != ceiling_addr)
13357 if (cursor != ceiling_addr)
13359 if (--count == 0)
13361 start_byte += cursor - base + 1;
13362 *byte_pos_ptr = start_byte;
13363 return orig_count;
13365 else
13366 if (++cursor == ceiling_addr)
13367 break;
13369 else
13370 break;
13372 start_byte += cursor - base;
13375 else
13377 while (start_byte > limit_byte)
13379 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
13380 ceiling = max (limit_byte, ceiling);
13381 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
13382 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
13383 while (1)
13385 if (selective_display)
13386 while (--cursor != ceiling_addr
13387 && *cursor != '\n' && *cursor != 015)
13389 else
13390 while (--cursor != ceiling_addr && *cursor != '\n')
13393 if (cursor != ceiling_addr)
13395 if (++count == 0)
13397 start_byte += cursor - base + 1;
13398 *byte_pos_ptr = start_byte;
13399 /* When scanning backwards, we should
13400 not count the newline posterior to which we stop. */
13401 return - orig_count - 1;
13404 else
13405 break;
13407 /* Here we add 1 to compensate for the last decrement
13408 of CURSOR, which took it past the valid range. */
13409 start_byte += cursor - base + 1;
13413 *byte_pos_ptr = limit_byte;
13415 if (count < 0)
13416 return - orig_count + count;
13417 return orig_count - count;
13423 /***********************************************************************
13424 Displaying strings
13425 ***********************************************************************/
13427 /* Display a NUL-terminated string, starting with index START.
13429 If STRING is non-null, display that C string. Otherwise, the Lisp
13430 string LISP_STRING is displayed.
13432 If FACE_STRING is not nil, FACE_STRING_POS is a position in
13433 FACE_STRING. Display STRING or LISP_STRING with the face at
13434 FACE_STRING_POS in FACE_STRING:
13436 Display the string in the environment given by IT, but use the
13437 standard display table, temporarily.
13439 FIELD_WIDTH is the minimum number of output glyphs to produce.
13440 If STRING has fewer characters than FIELD_WIDTH, pad to the right
13441 with spaces. If STRING has more characters, more than FIELD_WIDTH
13442 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
13444 PRECISION is the maximum number of characters to output from
13445 STRING. PRECISION < 0 means don't truncate the string.
13447 This is roughly equivalent to printf format specifiers:
13449 FIELD_WIDTH PRECISION PRINTF
13450 ----------------------------------------
13451 -1 -1 %s
13452 -1 10 %.10s
13453 10 -1 %10s
13454 20 10 %20.10s
13456 MULTIBYTE zero means do not display multibyte chars, > 0 means do
13457 display them, and < 0 means obey the current buffer's value of
13458 enable_multibyte_characters.
13460 Value is the number of glyphs produced. */
13462 static int
13463 display_string (string, lisp_string, face_string, face_string_pos,
13464 start, it, field_width, precision, max_x, multibyte)
13465 unsigned char *string;
13466 Lisp_Object lisp_string;
13467 Lisp_Object face_string;
13468 int face_string_pos;
13469 int start;
13470 struct it *it;
13471 int field_width, precision, max_x;
13472 int multibyte;
13474 int hpos_at_start = it->hpos;
13475 int saved_face_id = it->face_id;
13476 struct glyph_row *row = it->glyph_row;
13478 /* Initialize the iterator IT for iteration over STRING beginning
13479 with index START. We assume that IT may be modified here (which
13480 means that display_line has to do something when displaying a
13481 mini-buffer prompt, which it does). */
13482 reseat_to_string (it, string, lisp_string, start,
13483 precision, field_width, multibyte);
13485 /* If displaying STRING, set up the face of the iterator
13486 from LISP_STRING, if that's given. */
13487 if (STRINGP (face_string))
13489 int endptr;
13490 struct face *face;
13492 it->face_id
13493 = face_at_string_position (it->w, face_string, face_string_pos,
13494 0, it->region_beg_charpos,
13495 it->region_end_charpos,
13496 &endptr, it->base_face_id);
13497 face = FACE_FROM_ID (it->f, it->face_id);
13498 it->face_box_p = face->box != FACE_NO_BOX;
13501 /* Set max_x to the maximum allowed X position. Don't let it go
13502 beyond the right edge of the window. */
13503 if (max_x <= 0)
13504 max_x = it->last_visible_x;
13505 else
13506 max_x = min (max_x, it->last_visible_x);
13508 /* Skip over display elements that are not visible. because IT->w is
13509 hscrolled. */
13510 if (it->current_x < it->first_visible_x)
13511 move_it_in_display_line_to (it, 100000, it->first_visible_x,
13512 MOVE_TO_POS | MOVE_TO_X);
13514 row->ascent = it->max_ascent;
13515 row->height = it->max_ascent + it->max_descent;
13516 row->phys_ascent = it->max_phys_ascent;
13517 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
13519 /* This condition is for the case that we are called with current_x
13520 past last_visible_x. */
13521 while (it->current_x < max_x)
13523 int x_before, x, n_glyphs_before, i, nglyphs;
13525 /* Get the next display element. */
13526 if (!get_next_display_element (it))
13527 break;
13529 /* Produce glyphs. */
13530 x_before = it->current_x;
13531 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
13532 PRODUCE_GLYPHS (it);
13534 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
13535 i = 0;
13536 x = x_before;
13537 while (i < nglyphs)
13539 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
13541 if (!it->truncate_lines_p
13542 && x + glyph->pixel_width > max_x)
13544 /* End of continued line or max_x reached. */
13545 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
13546 it->current_x = x;
13547 break;
13549 else if (x + glyph->pixel_width > it->first_visible_x)
13551 /* Glyph is at least partially visible. */
13552 ++it->hpos;
13553 if (x < it->first_visible_x)
13554 it->glyph_row->x = x - it->first_visible_x;
13556 else
13558 /* Glyph is off the left margin of the display area.
13559 Should not happen. */
13560 abort ();
13563 row->ascent = max (row->ascent, it->max_ascent);
13564 row->height = max (row->height, it->max_ascent + it->max_descent);
13565 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
13566 row->phys_height = max (row->phys_height,
13567 it->max_phys_ascent + it->max_phys_descent);
13568 x += glyph->pixel_width;
13569 ++i;
13572 /* Stop if max_x reached. */
13573 if (i < nglyphs)
13574 break;
13576 /* Stop at line ends. */
13577 if (ITERATOR_AT_END_OF_LINE_P (it))
13579 it->continuation_lines_width = 0;
13580 break;
13583 set_iterator_to_next (it, 1);
13585 /* Stop if truncating at the right edge. */
13586 if (it->truncate_lines_p
13587 && it->current_x >= it->last_visible_x)
13589 /* Add truncation mark, but don't do it if the line is
13590 truncated at a padding space. */
13591 if (IT_CHARPOS (*it) < it->string_nchars)
13593 if (!FRAME_WINDOW_P (it->f))
13594 produce_special_glyphs (it, IT_TRUNCATION);
13595 it->glyph_row->truncated_on_right_p = 1;
13597 break;
13601 /* Maybe insert a truncation at the left. */
13602 if (it->first_visible_x
13603 && IT_CHARPOS (*it) > 0)
13605 if (!FRAME_WINDOW_P (it->f))
13606 insert_left_trunc_glyphs (it);
13607 it->glyph_row->truncated_on_left_p = 1;
13610 it->face_id = saved_face_id;
13612 /* Value is number of columns displayed. */
13613 return it->hpos - hpos_at_start;
13618 /* This is like a combination of memq and assq. Return 1 if PROPVAL
13619 appears as an element of LIST or as the car of an element of LIST.
13620 If PROPVAL is a list, compare each element against LIST in that
13621 way, and return 1 if any element of PROPVAL is found in LIST.
13622 Otherwise return 0. This function cannot quit. */
13625 invisible_p (propval, list)
13626 register Lisp_Object propval;
13627 Lisp_Object list;
13629 register Lisp_Object tail, proptail;
13631 for (tail = list; CONSP (tail); tail = XCDR (tail))
13633 register Lisp_Object tem;
13634 tem = XCAR (tail);
13635 if (EQ (propval, tem))
13636 return 1;
13637 if (CONSP (tem) && EQ (propval, XCAR (tem)))
13638 return 1;
13641 if (CONSP (propval))
13643 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
13645 Lisp_Object propelt;
13646 propelt = XCAR (proptail);
13647 for (tail = list; CONSP (tail); tail = XCDR (tail))
13649 register Lisp_Object tem;
13650 tem = XCAR (tail);
13651 if (EQ (propelt, tem))
13652 return 1;
13653 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
13654 return 1;
13659 return 0;
13663 /* Return 1 if PROPVAL appears as the car of an element of LIST and
13664 the cdr of that element is non-nil. If PROPVAL is a list, check
13665 each element of PROPVAL in that way, and the first time some
13666 element is found, return 1 if the cdr of that element is non-nil.
13667 Otherwise return 0. This function cannot quit. */
13670 invisible_ellipsis_p (propval, list)
13671 register Lisp_Object propval;
13672 Lisp_Object list;
13674 register Lisp_Object tail, proptail;
13676 for (tail = list; CONSP (tail); tail = XCDR (tail))
13678 register Lisp_Object tem;
13679 tem = XCAR (tail);
13680 if (CONSP (tem) && EQ (propval, XCAR (tem)))
13681 return ! NILP (XCDR (tem));
13684 if (CONSP (propval))
13685 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
13687 Lisp_Object propelt;
13688 propelt = XCAR (proptail);
13689 for (tail = list; CONSP (tail); tail = XCDR (tail))
13691 register Lisp_Object tem;
13692 tem = XCAR (tail);
13693 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
13694 return ! NILP (XCDR (tem));
13698 return 0;
13703 /***********************************************************************
13704 Initialization
13705 ***********************************************************************/
13707 void
13708 syms_of_xdisp ()
13710 Vwith_echo_area_save_vector = Qnil;
13711 staticpro (&Vwith_echo_area_save_vector);
13713 Vmessage_stack = Qnil;
13714 staticpro (&Vmessage_stack);
13716 Qinhibit_redisplay = intern ("inhibit-redisplay");
13717 staticpro (&Qinhibit_redisplay);
13719 #if GLYPH_DEBUG
13720 defsubr (&Sdump_glyph_matrix);
13721 defsubr (&Sdump_glyph_row);
13722 defsubr (&Sdump_tool_bar_row);
13723 defsubr (&Strace_redisplay_toggle);
13724 defsubr (&Strace_to_stderr);
13725 #endif
13727 staticpro (&Qmenu_bar_update_hook);
13728 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
13730 staticpro (&Qoverriding_terminal_local_map);
13731 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
13733 staticpro (&Qoverriding_local_map);
13734 Qoverriding_local_map = intern ("overriding-local-map");
13736 staticpro (&Qwindow_scroll_functions);
13737 Qwindow_scroll_functions = intern ("window-scroll-functions");
13739 staticpro (&Qredisplay_end_trigger_functions);
13740 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
13742 staticpro (&Qinhibit_point_motion_hooks);
13743 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
13745 QCdata = intern (":data");
13746 staticpro (&QCdata);
13747 Qdisplay = intern ("display");
13748 staticpro (&Qdisplay);
13749 Qspace_width = intern ("space-width");
13750 staticpro (&Qspace_width);
13751 Qraise = intern ("raise");
13752 staticpro (&Qraise);
13753 Qspace = intern ("space");
13754 staticpro (&Qspace);
13755 Qmargin = intern ("margin");
13756 staticpro (&Qmargin);
13757 Qleft_margin = intern ("left-margin");
13758 staticpro (&Qleft_margin);
13759 Qright_margin = intern ("right-margin");
13760 staticpro (&Qright_margin);
13761 Qalign_to = intern ("align-to");
13762 staticpro (&Qalign_to);
13763 QCalign_to = intern (":align-to");
13764 staticpro (&QCalign_to);
13765 Qrelative_width = intern ("relative-width");
13766 staticpro (&Qrelative_width);
13767 QCrelative_width = intern (":relative-width");
13768 staticpro (&QCrelative_width);
13769 QCrelative_height = intern (":relative-height");
13770 staticpro (&QCrelative_height);
13771 QCeval = intern (":eval");
13772 staticpro (&QCeval);
13773 Qwhen = intern ("when");
13774 staticpro (&Qwhen);
13775 QCfile = intern (":file");
13776 staticpro (&QCfile);
13777 Qfontified = intern ("fontified");
13778 staticpro (&Qfontified);
13779 Qfontification_functions = intern ("fontification-functions");
13780 staticpro (&Qfontification_functions);
13781 Qtrailing_whitespace = intern ("trailing-whitespace");
13782 staticpro (&Qtrailing_whitespace);
13783 Qimage = intern ("image");
13784 staticpro (&Qimage);
13785 Qmessage_truncate_lines = intern ("message-truncate-lines");
13786 staticpro (&Qmessage_truncate_lines);
13787 Qgrow_only = intern ("grow-only");
13788 staticpro (&Qgrow_only);
13790 last_arrow_position = Qnil;
13791 last_arrow_string = Qnil;
13792 staticpro (&last_arrow_position);
13793 staticpro (&last_arrow_string);
13795 echo_buffer[0] = echo_buffer[1] = Qnil;
13796 staticpro (&echo_buffer[0]);
13797 staticpro (&echo_buffer[1]);
13799 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
13800 staticpro (&echo_area_buffer[0]);
13801 staticpro (&echo_area_buffer[1]);
13803 Vmessages_buffer_name = build_string ("*Messages*");
13804 staticpro (&Vmessages_buffer_name);
13806 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
13807 "Non-nil means highlight trailing whitespace.\n\
13808 The face used for trailing whitespace is `trailing-whitespace'.");
13809 Vshow_trailing_whitespace = Qnil;
13811 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
13812 "Non-nil means don't actually do any redisplay.\n\
13813 This is used for internal purposes.");
13814 Vinhibit_redisplay = Qnil;
13816 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
13817 "String (or mode line construct) included (normally) in `mode-line-format'.");
13818 Vglobal_mode_string = Qnil;
13820 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
13821 "Marker for where to display an arrow on top of the buffer text.\n\
13822 This must be the beginning of a line in order to work.\n\
13823 See also `overlay-arrow-string'.");
13824 Voverlay_arrow_position = Qnil;
13826 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
13827 "String to display as an arrow. See also `overlay-arrow-position'.");
13828 Voverlay_arrow_string = Qnil;
13830 DEFVAR_INT ("scroll-step", &scroll_step,
13831 "*The number of lines to try scrolling a window by when point moves out.\n\
13832 If that fails to bring point back on frame, point is centered instead.\n\
13833 If this is zero, point is always centered after it moves off frame.\n\
13834 If you want scrolling to always be a line at a time, you should set\n\
13835 `scroll-conservatively' to a large value rather than set this to 1.");
13837 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
13838 "*Scroll up to this many lines, to bring point back on screen.\n\
13839 A value of zero means to scroll the text to center point vertically\n\
13840 in the window.");
13841 scroll_conservatively = 0;
13843 DEFVAR_INT ("scroll-margin", &scroll_margin,
13844 "*Number of lines of margin at the top and bottom of a window.\n\
13845 Recenter the window whenever point gets within this many lines\n\
13846 of the top or bottom of the window.");
13847 scroll_margin = 0;
13849 #if GLYPH_DEBUG
13850 DEFVAR_INT ("debug-end-pos", &debug_end_pos, "Don't ask");
13851 #endif
13853 DEFVAR_BOOL ("truncate-partial-width-windows",
13854 &truncate_partial_width_windows,
13855 "*Non-nil means truncate lines in all windows less than full frame wide.");
13856 truncate_partial_width_windows = 1;
13858 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
13859 "nil means display the mode-line/header-line/menu-bar in the default face.\n\
13860 Any other value means to use the appropriate face, `mode-line',\n\
13861 `header-line', or `menu' respectively.\n\
13863 This variable is deprecated; please change the above faces instead.");
13864 mode_line_inverse_video = 1;
13866 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
13867 "*Maximum buffer size for which line number should be displayed.\n\
13868 If the buffer is bigger than this, the line number does not appear\n\
13869 in the mode line. A value of nil means no limit.");
13870 Vline_number_display_limit = Qnil;
13872 DEFVAR_INT ("line-number-display-limit-width",
13873 &line_number_display_limit_width,
13874 "*Maximum line width (in characters) for line number display.\n\
13875 If the average length of the lines near point is bigger than this, then the\n\
13876 line number may be omitted from the mode line.");
13877 line_number_display_limit_width = 200;
13879 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
13880 "*Non-nil means highlight region even in nonselected windows.");
13881 highlight_nonselected_windows = 0;
13883 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
13884 "Non-nil if more than one frame is visible on this display.\n\
13885 Minibuffer-only frames don't count, but iconified frames do.\n\
13886 This variable is not guaranteed to be accurate except while processing\n\
13887 `frame-title-format' and `icon-title-format'.");
13889 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
13890 "Template for displaying the title bar of visible frames.\n\
13891 \(Assuming the window manager supports this feature.)\n\
13892 This variable has the same structure as `mode-line-format' (which see),\n\
13893 and is used only on frames for which no explicit name has been set\n\
13894 \(see `modify-frame-parameters').");
13895 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
13896 "Template for displaying the title bar of an iconified frame.\n\
13897 \(Assuming the window manager supports this feature.)\n\
13898 This variable has the same structure as `mode-line-format' (which see),\n\
13899 and is used only on frames for which no explicit name has been set\n\
13900 \(see `modify-frame-parameters').");
13901 Vicon_title_format
13902 = Vframe_title_format
13903 = Fcons (intern ("multiple-frames"),
13904 Fcons (build_string ("%b"),
13905 Fcons (Fcons (build_string (""),
13906 Fcons (intern ("invocation-name"),
13907 Fcons (build_string ("@"),
13908 Fcons (intern ("system-name"),
13909 Qnil)))),
13910 Qnil)));
13912 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
13913 "Maximum number of lines to keep in the message log buffer.\n\
13914 If nil, disable message logging. If t, log messages but don't truncate\n\
13915 the buffer when it becomes large.");
13916 XSETFASTINT (Vmessage_log_max, 50);
13918 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
13919 "Functions called before redisplay, if window sizes have changed.\n\
13920 The value should be a list of functions that take one argument.\n\
13921 Just before redisplay, for each frame, if any of its windows have changed\n\
13922 size since the last redisplay, or have been split or deleted,\n\
13923 all the functions in the list are called, with the frame as argument.");
13924 Vwindow_size_change_functions = Qnil;
13926 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
13927 "List of Functions to call before redisplaying a window with scrolling.\n\
13928 Each function is called with two arguments, the window\n\
13929 and its new display-start position. Note that the value of `window-end'\n\
13930 is not valid when these functions are called.");
13931 Vwindow_scroll_functions = Qnil;
13933 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
13934 "*Non-nil means automatically resize tool-bars.\n\
13935 This increases a tool-bar's height if not all tool-bar items are visible.\n\
13936 It decreases a tool-bar's height when it would display blank lines\n\
13937 otherwise.");
13938 auto_resize_tool_bars_p = 1;
13940 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
13941 "*Non-nil means raise tool-bar buttons when the mouse moves over them.");
13942 auto_raise_tool_bar_buttons_p = 1;
13944 DEFVAR_INT ("tool-bar-button-margin", &tool_bar_button_margin,
13945 "*Margin around tool-bar buttons in pixels.");
13946 tool_bar_button_margin = 1;
13948 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
13949 "Relief thickness of tool-bar buttons.");
13950 tool_bar_button_relief = 3;
13952 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
13953 "List of functions to call to fontify regions of text.\n\
13954 Each function is called with one argument POS. Functions must\n\
13955 fontify a region starting at POS in the current buffer, and give\n\
13956 fontified regions the property `fontified'.\n\
13957 This variable automatically becomes buffer-local when set.");
13958 Vfontification_functions = Qnil;
13959 Fmake_variable_buffer_local (Qfontification_functions);
13961 DEFVAR_BOOL ("unibyte-display-via-language-environment",
13962 &unibyte_display_via_language_environment,
13963 "*Non-nil means display unibyte text according to language environment.\n\
13964 Specifically this means that unibyte non-ASCII characters\n\
13965 are displayed by converting them to the equivalent multibyte characters\n\
13966 according to the current language environment. As a result, they are\n\
13967 displayed according to the current fontset.");
13968 unibyte_display_via_language_environment = 0;
13970 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
13971 "*Maximum height for resizing mini-windows.\n\
13972 If a float, it specifies a fraction of the mini-window frame's height.\n\
13973 If an integer, it specifies a number of lines.");
13974 Vmax_mini_window_height = make_float (0.25);
13976 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
13977 "*How to resize the mini-window.\n\
13978 A value of nil means don't automatically resize mini-windows.\n\
13979 A value of t means resize it to fit the text displayed in it.\n\
13980 A value of `grow-only', the default, means let mini-windows grow\n\
13981 only, until the its display becomes empty, at which point the mini-window\n\
13982 goes back to its normal size.");
13983 Vresize_mini_windows = Qgrow_only;
13985 DEFVAR_BOOL ("cursor-in-non-selected-windows",
13986 &cursor_in_non_selected_windows,
13987 "*Non-nil means display a hollow cursor in non-selected windows.\n\
13988 Nil means don't display a cursor there.");
13989 cursor_in_non_selected_windows = 1;
13991 DEFVAR_BOOL ("automatic-hscrolling", &automatic_hscrolling_p,
13992 "*Non-nil means scroll the display automatically to make point visible.");
13993 automatic_hscrolling_p = 1;
13995 DEFVAR_LISP ("image-types", &Vimage_types,
13996 "List of supported image types.\n\
13997 Each element of the list is a symbol for a supported image type.");
13998 Vimage_types = Qnil;
14000 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
14001 "If non-nil, messages are truncated instead of resizing the echo area.\n\
14002 Bind this around calls to `message' to let it take effect.");
14003 message_truncate_lines = 0;
14005 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
14006 "Normal hook run for clicks on menu bar, before displaying a submenu.\n\
14007 Can be used to update submenus whose contents should vary.");
14008 Vmenu_bar_update_hook = Qnil;
14012 /* Initialize this module when Emacs starts. */
14014 void
14015 init_xdisp ()
14017 Lisp_Object root_window;
14018 struct window *mini_w;
14020 current_header_line_height = current_mode_line_height = -1;
14022 CHARPOS (this_line_start_pos) = 0;
14024 mini_w = XWINDOW (minibuf_window);
14025 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
14027 if (!noninteractive)
14029 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
14030 int i;
14032 XSETFASTINT (XWINDOW (root_window)->top, FRAME_TOP_MARGIN (f));
14033 set_window_height (root_window,
14034 FRAME_HEIGHT (f) - 1 - FRAME_TOP_MARGIN (f),
14036 XSETFASTINT (mini_w->top, FRAME_HEIGHT (f) - 1);
14037 set_window_height (minibuf_window, 1, 0);
14039 XSETFASTINT (XWINDOW (root_window)->width, FRAME_WIDTH (f));
14040 XSETFASTINT (mini_w->width, FRAME_WIDTH (f));
14042 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
14043 scratch_glyph_row.glyphs[TEXT_AREA + 1]
14044 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
14046 /* The default ellipsis glyphs `...'. */
14047 for (i = 0; i < 3; ++i)
14048 XSETFASTINT (default_invis_vector[i], '.');
14051 #ifdef HAVE_WINDOW_SYSTEM
14053 /* Allocate the buffer for frame titles. */
14054 int size = 100;
14055 frame_title_buf = (char *) xmalloc (size);
14056 frame_title_buf_end = frame_title_buf + size;
14057 frame_title_ptr = NULL;
14059 #endif /* HAVE_WINDOW_SYSTEM */
14061 help_echo_showing_p = 0;