("latin-8-prefix", "latin-9-prefix"): New.
[emacs.git] / src / xdisp.c
blobc50131134a271c84325c5e376aff589560b6ebaf
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
198 #define min(a, b) ((a) < (b) ? (a) : (b))
199 #define max(a, b) ((a) > (b) ? (a) : (b))
201 #define INFINITY 10000000
203 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
204 extern void set_frame_menubar P_ ((struct frame *f, int, int));
205 extern int pending_menu_activation;
206 #endif
208 extern int interrupt_input;
209 extern int command_loop_level;
211 extern int minibuffer_auto_raise;
213 extern Lisp_Object Qface;
215 extern Lisp_Object Voverriding_local_map;
216 extern Lisp_Object Voverriding_local_map_menu_flag;
217 extern Lisp_Object Qmenu_item;
219 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
220 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
221 Lisp_Object Qredisplay_end_trigger_functions;
222 Lisp_Object Qinhibit_point_motion_hooks;
223 Lisp_Object QCeval, Qwhen, QCfile, QCdata;
224 Lisp_Object Qfontified;
226 /* Functions called to fontify regions of text. */
228 Lisp_Object Vfontification_functions;
229 Lisp_Object Qfontification_functions;
231 /* Non-zero means draw tool bar buttons raised when the mouse moves
232 over them. */
234 int auto_raise_tool_bar_buttons_p;
236 /* Margin around tool bar buttons in pixels. */
238 int tool_bar_button_margin;
240 /* Thickness of shadow to draw around tool bar buttons. */
242 int tool_bar_button_relief;
244 /* Non-zero means automatically resize tool-bars so that all tool-bar
245 items are visible, and no blank lines remain. */
247 int auto_resize_tool_bars_p;
249 /* Non-nil means don't actually do any redisplay. */
251 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
253 /* Names of text properties relevant for redisplay. */
255 Lisp_Object Qdisplay, Qrelative_width, Qalign_to;
256 extern Lisp_Object Qface, Qinvisible, Qimage, Qwidth;
258 /* Symbols used in text property values. */
260 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
261 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
262 Lisp_Object Qmargin;
263 extern Lisp_Object Qheight;
265 /* Non-nil means highlight trailing whitespace. */
267 Lisp_Object Vshow_trailing_whitespace;
269 /* Name of the face used to highlight trailing whitespace. */
271 Lisp_Object Qtrailing_whitespace;
273 /* The symbol `image' which is the car of the lists used to represent
274 images in Lisp. */
276 Lisp_Object Qimage;
278 /* Non-zero means print newline to stdout before next mini-buffer
279 message. */
281 int noninteractive_need_newline;
283 /* Non-zero means print newline to message log before next message. */
285 static int message_log_need_newline;
288 /* The buffer position of the first character appearing entirely or
289 partially on the line of the selected window which contains the
290 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
291 redisplay optimization in redisplay_internal. */
293 static struct text_pos this_line_start_pos;
295 /* Number of characters past the end of the line above, including the
296 terminating newline. */
298 static struct text_pos this_line_end_pos;
300 /* The vertical positions and the height of this line. */
302 static int this_line_vpos;
303 static int this_line_y;
304 static int this_line_pixel_height;
306 /* X position at which this display line starts. Usually zero;
307 negative if first character is partially visible. */
309 static int this_line_start_x;
311 /* Buffer that this_line_.* variables are referring to. */
313 static struct buffer *this_line_buffer;
315 /* Nonzero means truncate lines in all windows less wide than the
316 frame. */
318 int truncate_partial_width_windows;
320 /* A flag to control how to display unibyte 8-bit character. */
322 int unibyte_display_via_language_environment;
324 /* Nonzero means we have more than one non-mini-buffer-only frame.
325 Not guaranteed to be accurate except while parsing
326 frame-title-format. */
328 int multiple_frames;
330 Lisp_Object Vglobal_mode_string;
332 /* Marker for where to display an arrow on top of the buffer text. */
334 Lisp_Object Voverlay_arrow_position;
336 /* String to display for the arrow. Only used on terminal frames. */
338 Lisp_Object Voverlay_arrow_string;
340 /* Values of those variables at last redisplay. However, if
341 Voverlay_arrow_position is a marker, last_arrow_position is its
342 numerical position. */
344 static Lisp_Object last_arrow_position, last_arrow_string;
346 /* Like mode-line-format, but for the title bar on a visible frame. */
348 Lisp_Object Vframe_title_format;
350 /* Like mode-line-format, but for the title bar on an iconified frame. */
352 Lisp_Object Vicon_title_format;
354 /* List of functions to call when a window's size changes. These
355 functions get one arg, a frame on which one or more windows' sizes
356 have changed. */
358 static Lisp_Object Vwindow_size_change_functions;
360 Lisp_Object Qmenu_bar_update_hook;
362 /* Nonzero if overlay arrow has been displayed once in this window. */
364 static int overlay_arrow_seen;
366 /* Nonzero means highlight the region even in nonselected windows. */
368 int highlight_nonselected_windows;
370 /* If cursor motion alone moves point off frame, try scrolling this
371 many lines up or down if that will bring it back. */
373 static int scroll_step;
375 /* Non-0 means scroll just far enough to bring point back on the
376 screen, when appropriate. */
378 static int scroll_conservatively;
380 /* Recenter the window whenever point gets within this many lines of
381 the top or bottom of the window. This value is translated into a
382 pixel value by multiplying it with CANON_Y_UNIT, which means that
383 there is really a fixed pixel height scroll margin. */
385 int scroll_margin;
387 /* Number of windows showing the buffer of the selected window (or
388 another buffer with the same base buffer). keyboard.c refers to
389 this. */
391 int buffer_shared;
393 /* Vector containing glyphs for an ellipsis `...'. */
395 static Lisp_Object default_invis_vector[3];
397 /* Nonzero means display mode line highlighted. */
399 int mode_line_inverse_video;
401 /* Prompt to display in front of the mini-buffer contents. */
403 Lisp_Object minibuf_prompt;
405 /* Width of current mini-buffer prompt. Only set after display_line
406 of the line that contains the prompt. */
408 int minibuf_prompt_width;
409 int minibuf_prompt_pixel_width;
411 /* This is the window where the echo area message was displayed. It
412 is always a mini-buffer window, but it may not be the same window
413 currently active as a mini-buffer. */
415 Lisp_Object echo_area_window;
417 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
418 pushes the current message and the value of
419 message_enable_multibyte on the stack, the function restore_message
420 pops the stack and displays MESSAGE again. */
422 Lisp_Object Vmessage_stack;
424 /* Nonzero means multibyte characters were enabled when the echo area
425 message was specified. */
427 int message_enable_multibyte;
429 /* True if we should redraw the mode lines on the next redisplay. */
431 int update_mode_lines;
433 /* Nonzero if window sizes or contents have changed since last
434 redisplay that finished */
436 int windows_or_buffers_changed;
438 /* Nonzero after display_mode_line if %l was used and it displayed a
439 line number. */
441 int line_number_displayed;
443 /* Maximum buffer size for which to display line numbers. */
445 Lisp_Object Vline_number_display_limit;
447 /* line width to consider when repostioning for line number display */
449 static int line_number_display_limit_width;
451 /* Number of lines to keep in the message log buffer. t means
452 infinite. nil means don't log at all. */
454 Lisp_Object Vmessage_log_max;
456 /* The name of the *Messages* buffer, a string. */
458 static Lisp_Object Vmessages_buffer_name;
460 /* Current, index 0, and last displayed echo area message. Either
461 buffers from echo_buffers, or nil to indicate no message. */
463 Lisp_Object echo_area_buffer[2];
465 /* The buffers referenced from echo_area_buffer. */
467 static Lisp_Object echo_buffer[2];
469 /* A vector saved used in with_area_buffer to reduce consing. */
471 static Lisp_Object Vwith_echo_area_save_vector;
473 /* Non-zero means display_echo_area should display the last echo area
474 message again. Set by redisplay_preserve_echo_area. */
476 static int display_last_displayed_message_p;
478 /* Nonzero if echo area is being used by print; zero if being used by
479 message. */
481 int message_buf_print;
483 /* Maximum height for resizing mini-windows. Either a float
484 specifying a fraction of the available height, or an integer
485 specifying a number of lines. */
487 Lisp_Object Vmax_mini_window_height;
489 /* Non-zero means messages should be displayed with truncated
490 lines instead of being continued. */
492 int message_truncate_lines;
493 Lisp_Object Qmessage_truncate_lines;
495 /* Non-zero means we want a hollow cursor in windows that are not
496 selected. Zero means there's no cursor in such windows. */
498 int cursor_in_non_selected_windows;
500 /* A scratch glyph row with contents used for generating truncation
501 glyphs. Also used in direct_output_for_insert. */
503 #define MAX_SCRATCH_GLYPHS 100
504 struct glyph_row scratch_glyph_row;
505 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
507 /* Ascent and height of the last line processed by move_it_to. */
509 static int last_max_ascent, last_height;
511 /* The maximum distance to look ahead for text properties. Values
512 that are too small let us call compute_char_face and similar
513 functions too often which is expensive. Values that are too large
514 let us call compute_char_face and alike too often because we
515 might not be interested in text properties that far away. */
517 #define TEXT_PROP_DISTANCE_LIMIT 100
519 #if GLYPH_DEBUG
521 /* Non-zero means print traces of redisplay if compiled with
522 GLYPH_DEBUG != 0. */
524 int trace_redisplay_p;
526 #endif /* GLYPH_DEBUG */
528 #ifdef DEBUG_TRACE_MOVE
529 /* Non-zero means trace with TRACE_MOVE to stderr. */
530 int trace_move;
532 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
533 #else
534 #define TRACE_MOVE(x) (void) 0
535 #endif
537 /* Non-zero means automatically scroll windows horizontally to make
538 point visible. */
540 int automatic_hscrolling_p;
542 /* A list of symbols, one for each supported image type. */
544 Lisp_Object Vimage_types;
546 /* Value returned from text property handlers (see below). */
548 enum prop_handled
550 HANDLED_NORMALLY,
551 HANDLED_RECOMPUTE_PROPS,
552 HANDLED_OVERLAY_STRING_CONSUMED,
553 HANDLED_RETURN
556 /* A description of text properties that redisplay is interested
557 in. */
559 struct props
561 /* The name of the property. */
562 Lisp_Object *name;
564 /* A unique index for the property. */
565 enum prop_idx idx;
567 /* A handler function called to set up iterator IT from the property
568 at IT's current position. Value is used to steer handle_stop. */
569 enum prop_handled (*handler) P_ ((struct it *it));
572 static enum prop_handled handle_face_prop P_ ((struct it *));
573 static enum prop_handled handle_invisible_prop P_ ((struct it *));
574 static enum prop_handled handle_display_prop P_ ((struct it *));
575 static enum prop_handled handle_composition_prop P_ ((struct it *));
576 static enum prop_handled handle_overlay_change P_ ((struct it *));
577 static enum prop_handled handle_fontified_prop P_ ((struct it *));
579 /* Properties handled by iterators. */
581 static struct props it_props[] =
583 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
584 /* Handle `face' before `display' because some sub-properties of
585 `display' need to know the face. */
586 {&Qface, FACE_PROP_IDX, handle_face_prop},
587 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
588 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
589 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
590 {NULL, 0, NULL}
593 /* Value is the position described by X. If X is a marker, value is
594 the marker_position of X. Otherwise, value is X. */
596 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
598 /* Enumeration returned by some move_it_.* functions internally. */
600 enum move_it_result
602 /* Not used. Undefined value. */
603 MOVE_UNDEFINED,
605 /* Move ended at the requested buffer position or ZV. */
606 MOVE_POS_MATCH_OR_ZV,
608 /* Move ended at the requested X pixel position. */
609 MOVE_X_REACHED,
611 /* Move within a line ended at the end of a line that must be
612 continued. */
613 MOVE_LINE_CONTINUED,
615 /* Move within a line ended at the end of a line that would
616 be displayed truncated. */
617 MOVE_LINE_TRUNCATED,
619 /* Move within a line ended at a line end. */
620 MOVE_NEWLINE_OR_CR
625 /* Function prototypes. */
627 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
628 static int invisible_text_between_p P_ ((struct it *, int, int));
629 static int next_element_from_ellipsis P_ ((struct it *));
630 static void pint2str P_ ((char *, int, int));
631 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
632 struct text_pos));
633 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
634 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
635 static void store_frame_title_char P_ ((char));
636 static int store_frame_title P_ ((unsigned char *, int, int));
637 static void x_consider_frame_title P_ ((Lisp_Object));
638 static void handle_stop P_ ((struct it *));
639 static int tool_bar_lines_needed P_ ((struct frame *));
640 static int single_display_prop_intangible_p P_ ((Lisp_Object));
641 static void ensure_echo_area_buffers P_ ((void));
642 static struct glyph_row *row_containing_pos P_ ((struct window *, int,
643 struct glyph_row *,
644 struct glyph_row *));
645 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
646 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
647 static int with_echo_area_buffer P_ ((struct window *, int,
648 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
649 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
650 static void clear_garbaged_frames P_ ((void));
651 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
652 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
653 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
654 static int display_echo_area P_ ((struct window *));
655 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
656 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
657 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
658 static int string_char_and_length P_ ((unsigned char *, int, int *));
659 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
660 struct text_pos));
661 static int compute_window_start_on_continuation_line P_ ((struct window *));
662 static Lisp_Object eval_handler P_ ((Lisp_Object));
663 static void insert_left_trunc_glyphs P_ ((struct it *));
664 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
665 static void extend_face_to_end_of_line P_ ((struct it *));
666 static int append_space P_ ((struct it *, int));
667 static void make_cursor_line_fully_visible P_ ((struct window *));
668 static int try_scrolling P_ ((Lisp_Object, int, int, int, int));
669 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
670 static int trailing_whitespace_p P_ ((int));
671 static int message_log_check_duplicate P_ ((int, int, int, int));
672 int invisible_p P_ ((Lisp_Object, Lisp_Object));
673 int invisible_ellipsis_p P_ ((Lisp_Object, Lisp_Object));
674 static void push_it P_ ((struct it *));
675 static void pop_it P_ ((struct it *));
676 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
677 static void redisplay_internal P_ ((int));
678 static int echo_area_display P_ ((int));
679 static void redisplay_windows P_ ((Lisp_Object));
680 static void redisplay_window P_ ((Lisp_Object, int));
681 static void update_menu_bar P_ ((struct frame *, int));
682 static int try_window_reusing_current_matrix P_ ((struct window *));
683 static int try_window_id P_ ((struct window *));
684 static int display_line P_ ((struct it *));
685 static void display_mode_lines P_ ((struct window *));
686 static void display_mode_line P_ ((struct window *, enum face_id,
687 Lisp_Object));
688 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object));
689 static char *decode_mode_spec P_ ((struct window *, int, int, int));
690 static void display_menu_bar P_ ((struct window *));
691 static int display_count_lines P_ ((int, int, int, int, int *));
692 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
693 int, int, struct it *, int, int, int, int));
694 static void compute_line_metrics P_ ((struct it *));
695 static void run_redisplay_end_trigger_hook P_ ((struct it *));
696 static int get_overlay_strings P_ ((struct it *));
697 static void next_overlay_string P_ ((struct it *));
698 void set_iterator_to_next P_ ((struct it *));
699 static void reseat P_ ((struct it *, struct text_pos, int));
700 static void reseat_1 P_ ((struct it *, struct text_pos, int));
701 static void back_to_previous_visible_line_start P_ ((struct it *));
702 static void reseat_at_previous_visible_line_start P_ ((struct it *));
703 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
704 static int next_element_from_display_vector P_ ((struct it *));
705 static int next_element_from_string P_ ((struct it *));
706 static int next_element_from_c_string P_ ((struct it *));
707 static int next_element_from_buffer P_ ((struct it *));
708 static int next_element_from_composition P_ ((struct it *));
709 static int next_element_from_image P_ ((struct it *));
710 static int next_element_from_stretch P_ ((struct it *));
711 static void load_overlay_strings P_ ((struct it *));
712 static void init_from_display_pos P_ ((struct it *, struct window *,
713 struct display_pos *));
714 static void reseat_to_string P_ ((struct it *, unsigned char *,
715 Lisp_Object, int, int, int, int));
716 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
717 int, int, int));
718 void move_it_vertically_backward P_ ((struct it *, int));
719 static void init_to_row_start P_ ((struct it *, struct window *,
720 struct glyph_row *));
721 static void init_to_row_end P_ ((struct it *, struct window *,
722 struct glyph_row *));
723 static void back_to_previous_line_start P_ ((struct it *));
724 static void forward_to_next_line_start P_ ((struct it *));
725 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
726 Lisp_Object, int));
727 static struct text_pos string_pos P_ ((int, Lisp_Object));
728 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
729 static int number_of_chars P_ ((unsigned char *, int));
730 static void compute_stop_pos P_ ((struct it *));
731 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
732 Lisp_Object));
733 static int face_before_or_after_it_pos P_ ((struct it *, int));
734 static int next_overlay_change P_ ((int));
735 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
736 Lisp_Object, struct text_pos *));
738 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
739 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
741 #ifdef HAVE_WINDOW_SYSTEM
743 static void update_tool_bar P_ ((struct frame *, int));
744 static void build_desired_tool_bar_string P_ ((struct frame *f));
745 static int redisplay_tool_bar P_ ((struct frame *));
746 static void display_tool_bar_line P_ ((struct it *));
748 #endif /* HAVE_WINDOW_SYSTEM */
751 /***********************************************************************
752 Window display dimensions
753 ***********************************************************************/
755 /* Return the window-relative maximum y + 1 for glyph rows displaying
756 text in window W. This is the height of W minus the height of a
757 mode line, if any. */
759 INLINE int
760 window_text_bottom_y (w)
761 struct window *w;
763 struct frame *f = XFRAME (w->frame);
764 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
766 if (WINDOW_WANTS_MODELINE_P (w))
767 height -= CURRENT_MODE_LINE_HEIGHT (w);
768 return height;
772 /* Return the pixel width of display area AREA of window W. AREA < 0
773 means return the total width of W, not including bitmap areas to
774 the left and right of the window. */
776 INLINE int
777 window_box_width (w, area)
778 struct window *w;
779 int area;
781 struct frame *f = XFRAME (w->frame);
782 int width = XFASTINT (w->width);
784 if (!w->pseudo_window_p)
786 width -= FRAME_SCROLL_BAR_WIDTH (f) + FRAME_FLAGS_AREA_COLS (f);
788 if (area == TEXT_AREA)
790 if (INTEGERP (w->left_margin_width))
791 width -= XFASTINT (w->left_margin_width);
792 if (INTEGERP (w->right_margin_width))
793 width -= XFASTINT (w->right_margin_width);
795 else if (area == LEFT_MARGIN_AREA)
796 width = (INTEGERP (w->left_margin_width)
797 ? XFASTINT (w->left_margin_width) : 0);
798 else if (area == RIGHT_MARGIN_AREA)
799 width = (INTEGERP (w->right_margin_width)
800 ? XFASTINT (w->right_margin_width) : 0);
803 return width * CANON_X_UNIT (f);
807 /* Return the pixel height of the display area of window W, not
808 including mode lines of W, if any.. */
810 INLINE int
811 window_box_height (w)
812 struct window *w;
814 struct frame *f = XFRAME (w->frame);
815 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
817 if (WINDOW_WANTS_MODELINE_P (w))
818 height -= CURRENT_MODE_LINE_HEIGHT (w);
820 if (WINDOW_WANTS_HEADER_LINE_P (w))
821 height -= CURRENT_HEADER_LINE_HEIGHT (w);
823 return height;
827 /* Return the frame-relative coordinate of the left edge of display
828 area AREA of window W. AREA < 0 means return the left edge of the
829 whole window, to the right of any bitmap area at the left side of
830 W. */
832 INLINE int
833 window_box_left (w, area)
834 struct window *w;
835 int area;
837 struct frame *f = XFRAME (w->frame);
838 int x = FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
840 if (!w->pseudo_window_p)
842 x += (WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f)
843 + FRAME_LEFT_FLAGS_AREA_WIDTH (f));
845 if (area == TEXT_AREA)
846 x += window_box_width (w, LEFT_MARGIN_AREA);
847 else if (area == RIGHT_MARGIN_AREA)
848 x += (window_box_width (w, LEFT_MARGIN_AREA)
849 + window_box_width (w, TEXT_AREA));
852 return x;
856 /* Return the frame-relative coordinate of the right edge of display
857 area AREA of window W. AREA < 0 means return the left edge of the
858 whole window, to the left of any bitmap area at the right side of
859 W. */
861 INLINE int
862 window_box_right (w, area)
863 struct window *w;
864 int area;
866 return window_box_left (w, area) + window_box_width (w, area);
870 /* Get the bounding box of the display area AREA of window W, without
871 mode lines, in frame-relative coordinates. AREA < 0 means the
872 whole window, not including bitmap areas to the left and right of
873 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
874 coordinates of the upper-left corner of the box. Return in
875 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
877 INLINE void
878 window_box (w, area, box_x, box_y, box_width, box_height)
879 struct window *w;
880 int area;
881 int *box_x, *box_y, *box_width, *box_height;
883 struct frame *f = XFRAME (w->frame);
885 *box_width = window_box_width (w, area);
886 *box_height = window_box_height (w);
887 *box_x = window_box_left (w, area);
888 *box_y = (FRAME_INTERNAL_BORDER_WIDTH_SAFE (f)
889 + XFASTINT (w->top) * CANON_Y_UNIT (f));
890 if (WINDOW_WANTS_HEADER_LINE_P (w))
891 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
895 /* Get the bounding box of the display area AREA of window W, without
896 mode lines. AREA < 0 means the whole window, not including bitmap
897 areas to the left and right of the window. Return in *TOP_LEFT_X
898 and TOP_LEFT_Y the frame-relative pixel coordinates of the
899 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
900 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
901 box. */
903 INLINE void
904 window_box_edges (w, area, top_left_x, top_left_y,
905 bottom_right_x, bottom_right_y)
906 struct window *w;
907 int area;
908 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
910 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
911 bottom_right_y);
912 *bottom_right_x += *top_left_x;
913 *bottom_right_y += *top_left_y;
918 /***********************************************************************
919 Utilities
920 ***********************************************************************/
922 /* Return the next character from STR which is MAXLEN bytes long.
923 Return in *LEN the length of the character. This is like
924 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
925 we find one, we return a `?', but with the length of the invalid
926 character. */
928 static INLINE int
929 string_char_and_length (str, maxlen, len)
930 unsigned char *str;
931 int maxlen, *len;
933 int c;
935 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
936 if (!CHAR_VALID_P (c, 1))
937 /* We may not change the length here because other places in Emacs
938 don't use this function, i.e. they silently accept invalid
939 characters. */
940 c = '?';
942 return c;
947 /* Given a position POS containing a valid character and byte position
948 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
950 static struct text_pos
951 string_pos_nchars_ahead (pos, string, nchars)
952 struct text_pos pos;
953 Lisp_Object string;
954 int nchars;
956 xassert (STRINGP (string) && nchars >= 0);
958 if (STRING_MULTIBYTE (string))
960 int rest = STRING_BYTES (XSTRING (string)) - BYTEPOS (pos);
961 unsigned char *p = XSTRING (string)->data + BYTEPOS (pos);
962 int len;
964 while (nchars--)
966 string_char_and_length (p, rest, &len);
967 p += len, rest -= len;
968 xassert (rest >= 0);
969 CHARPOS (pos) += 1;
970 BYTEPOS (pos) += len;
973 else
974 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
976 return pos;
980 /* Value is the text position, i.e. character and byte position,
981 for character position CHARPOS in STRING. */
983 static INLINE struct text_pos
984 string_pos (charpos, string)
985 int charpos;
986 Lisp_Object string;
988 struct text_pos pos;
989 xassert (STRINGP (string));
990 xassert (charpos >= 0);
991 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
992 return pos;
996 /* Value is a text position, i.e. character and byte position, for
997 character position CHARPOS in C string S. MULTIBYTE_P non-zero
998 means recognize multibyte characters. */
1000 static struct text_pos
1001 c_string_pos (charpos, s, multibyte_p)
1002 int charpos;
1003 unsigned char *s;
1004 int multibyte_p;
1006 struct text_pos pos;
1008 xassert (s != NULL);
1009 xassert (charpos >= 0);
1011 if (multibyte_p)
1013 int rest = strlen (s), len;
1015 SET_TEXT_POS (pos, 0, 0);
1016 while (charpos--)
1018 string_char_and_length (s, rest, &len);
1019 s += len, rest -= len;
1020 xassert (rest >= 0);
1021 CHARPOS (pos) += 1;
1022 BYTEPOS (pos) += len;
1025 else
1026 SET_TEXT_POS (pos, charpos, charpos);
1028 return pos;
1032 /* Value is the number of characters in C string S. MULTIBYTE_P
1033 non-zero means recognize multibyte characters. */
1035 static int
1036 number_of_chars (s, multibyte_p)
1037 unsigned char *s;
1038 int multibyte_p;
1040 int nchars;
1042 if (multibyte_p)
1044 int rest = strlen (s), len;
1045 unsigned char *p = (unsigned char *) s;
1047 for (nchars = 0; rest > 0; ++nchars)
1049 string_char_and_length (p, rest, &len);
1050 rest -= len, p += len;
1053 else
1054 nchars = strlen (s);
1056 return nchars;
1060 /* Compute byte position NEWPOS->bytepos corresponding to
1061 NEWPOS->charpos. POS is a known position in string STRING.
1062 NEWPOS->charpos must be >= POS.charpos. */
1064 static void
1065 compute_string_pos (newpos, pos, string)
1066 struct text_pos *newpos, pos;
1067 Lisp_Object string;
1069 xassert (STRINGP (string));
1070 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1072 if (STRING_MULTIBYTE (string))
1073 *newpos = string_pos_nchars_ahead (pos, string,
1074 CHARPOS (*newpos) - CHARPOS (pos));
1075 else
1076 BYTEPOS (*newpos) = CHARPOS (*newpos);
1081 /***********************************************************************
1082 Lisp form evaluation
1083 ***********************************************************************/
1085 /* Error handler for eval_form and call_function. */
1087 static Lisp_Object
1088 eval_handler (arg)
1089 Lisp_Object arg;
1091 return Qnil;
1095 /* Evaluate SEXPR and return the result, or nil if something went
1096 wrong. */
1098 Lisp_Object
1099 eval_form (sexpr)
1100 Lisp_Object sexpr;
1102 int count = specpdl_ptr - specpdl;
1103 struct gcpro gcpro1;
1104 Lisp_Object val;
1106 GCPRO1 (sexpr);
1107 specbind (Qinhibit_redisplay, Qt);
1108 val = internal_condition_case_1 (Feval, sexpr, Qerror, eval_handler);
1109 UNGCPRO;
1110 return unbind_to (count, val);
1114 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1115 Return the result, or nil if something went wrong. */
1117 Lisp_Object
1118 call_function (nargs, args)
1119 int nargs;
1120 Lisp_Object *args;
1122 int count = specpdl_ptr - specpdl;
1123 Lisp_Object val;
1124 struct gcpro gcpro1;
1126 GCPRO1 (args[0]);
1127 gcpro1.nvars = nargs;
1128 specbind (Qinhibit_redisplay, Qt);
1129 val = internal_condition_case_2 (Ffuncall, nargs, args, Qerror,
1130 eval_handler);
1131 UNGCPRO;
1132 return unbind_to (count, val);
1137 /***********************************************************************
1138 Debugging
1139 ***********************************************************************/
1141 #if 0
1143 /* Define CHECK_IT to perform sanity checks on iterators.
1144 This is for debugging. It is too slow to do unconditionally. */
1146 static void
1147 check_it (it)
1148 struct it *it;
1150 if (it->method == next_element_from_string)
1152 xassert (STRINGP (it->string));
1153 xassert (IT_STRING_CHARPOS (*it) >= 0);
1155 else if (it->method == next_element_from_buffer)
1157 /* Check that character and byte positions agree. */
1158 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1161 if (it->dpvec)
1162 xassert (it->current.dpvec_index >= 0);
1163 else
1164 xassert (it->current.dpvec_index < 0);
1167 #define CHECK_IT(IT) check_it ((IT))
1169 #else /* not 0 */
1171 #define CHECK_IT(IT) (void) 0
1173 #endif /* not 0 */
1176 #if GLYPH_DEBUG
1178 /* Check that the window end of window W is what we expect it
1179 to be---the last row in the current matrix displaying text. */
1181 static void
1182 check_window_end (w)
1183 struct window *w;
1185 if (!MINI_WINDOW_P (w)
1186 && !NILP (w->window_end_valid))
1188 struct glyph_row *row;
1189 xassert ((row = MATRIX_ROW (w->current_matrix,
1190 XFASTINT (w->window_end_vpos)),
1191 !row->enabled_p
1192 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1193 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1197 #define CHECK_WINDOW_END(W) check_window_end ((W))
1199 #else /* not GLYPH_DEBUG */
1201 #define CHECK_WINDOW_END(W) (void) 0
1203 #endif /* not GLYPH_DEBUG */
1207 /***********************************************************************
1208 Iterator initialization
1209 ***********************************************************************/
1211 /* Initialize IT for displaying current_buffer in window W, starting
1212 at character position CHARPOS. CHARPOS < 0 means that no buffer
1213 position is specified which is useful when the iterator is assigned
1214 a position later. BYTEPOS is the byte position corresponding to
1215 CHARPOS. BYTEPOS <= 0 means compute it from CHARPOS.
1217 If ROW is not null, calls to produce_glyphs with IT as parameter
1218 will produce glyphs in that row.
1220 BASE_FACE_ID is the id of a base face to use. It must be one of
1221 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID or
1222 HEADER_LINE_FACE_ID for displaying mode lines, or TOOL_BAR_FACE_ID for
1223 displaying the tool-bar.
1225 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID or
1226 HEADER_LINE_FACE_ID, the iterator will be initialized to use the
1227 corresponding mode line glyph row of the desired matrix of W. */
1229 void
1230 init_iterator (it, w, charpos, bytepos, row, base_face_id)
1231 struct it *it;
1232 struct window *w;
1233 int charpos, bytepos;
1234 struct glyph_row *row;
1235 enum face_id base_face_id;
1237 int highlight_region_p;
1239 /* Some precondition checks. */
1240 xassert (w != NULL && it != NULL);
1241 xassert (charpos < 0 || (charpos > 0 && charpos <= ZV));
1243 /* If face attributes have been changed since the last redisplay,
1244 free realized faces now because they depend on face definitions
1245 that might have changed. */
1246 if (face_change_count)
1248 face_change_count = 0;
1249 free_all_realized_faces (Qnil);
1252 /* Use one of the mode line rows of W's desired matrix if
1253 appropriate. */
1254 if (row == NULL)
1256 if (base_face_id == MODE_LINE_FACE_ID)
1257 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
1258 else if (base_face_id == HEADER_LINE_FACE_ID)
1259 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
1262 /* Clear IT. */
1263 bzero (it, sizeof *it);
1264 it->current.overlay_string_index = -1;
1265 it->current.dpvec_index = -1;
1266 it->base_face_id = base_face_id;
1268 /* The window in which we iterate over current_buffer: */
1269 XSETWINDOW (it->window, w);
1270 it->w = w;
1271 it->f = XFRAME (w->frame);
1273 /* Extra space between lines (on window systems only). */
1274 if (base_face_id == DEFAULT_FACE_ID
1275 && FRAME_WINDOW_P (it->f))
1277 if (NATNUMP (current_buffer->extra_line_spacing))
1278 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
1279 else if (it->f->extra_line_spacing > 0)
1280 it->extra_line_spacing = it->f->extra_line_spacing;
1283 /* If realized faces have been removed, e.g. because of face
1284 attribute changes of named faces, recompute them. */
1285 if (FRAME_FACE_CACHE (it->f)->used == 0)
1286 recompute_basic_faces (it->f);
1288 /* Current value of the `space-width', and 'height' properties. */
1289 it->space_width = Qnil;
1290 it->font_height = Qnil;
1292 /* Are control characters displayed as `^C'? */
1293 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
1295 /* -1 means everything between a CR and the following line end
1296 is invisible. >0 means lines indented more than this value are
1297 invisible. */
1298 it->selective = (INTEGERP (current_buffer->selective_display)
1299 ? XFASTINT (current_buffer->selective_display)
1300 : (!NILP (current_buffer->selective_display)
1301 ? -1 : 0));
1302 it->selective_display_ellipsis_p
1303 = !NILP (current_buffer->selective_display_ellipses);
1305 /* Display table to use. */
1306 it->dp = window_display_table (w);
1308 /* Are multibyte characters enabled in current_buffer? */
1309 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
1311 /* Non-zero if we should highlight the region. */
1312 highlight_region_p
1313 = (!NILP (Vtransient_mark_mode)
1314 && !NILP (current_buffer->mark_active)
1315 && XMARKER (current_buffer->mark)->buffer != 0);
1317 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
1318 start and end of a visible region in window IT->w. Set both to
1319 -1 to indicate no region. */
1320 if (highlight_region_p
1321 /* Maybe highlight only in selected window. */
1322 && (/* Either show region everywhere. */
1323 highlight_nonselected_windows
1324 /* Or show region in the selected window. */
1325 || w == XWINDOW (selected_window)
1326 /* Or show the region if we are in the mini-buffer and W is
1327 the window the mini-buffer refers to. */
1328 || (MINI_WINDOW_P (XWINDOW (selected_window))
1329 && w == XWINDOW (Vminibuf_scroll_window))))
1331 int charpos = marker_position (current_buffer->mark);
1332 it->region_beg_charpos = min (PT, charpos);
1333 it->region_end_charpos = max (PT, charpos);
1335 else
1336 it->region_beg_charpos = it->region_end_charpos = -1;
1338 /* Get the position at which the redisplay_end_trigger hook should
1339 be run, if it is to be run at all. */
1340 if (MARKERP (w->redisplay_end_trigger)
1341 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
1342 it->redisplay_end_trigger_charpos
1343 = marker_position (w->redisplay_end_trigger);
1344 else if (INTEGERP (w->redisplay_end_trigger))
1345 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
1347 /* Correct bogus values of tab_width. */
1348 it->tab_width = XINT (current_buffer->tab_width);
1349 if (it->tab_width <= 0 || it->tab_width > 1000)
1350 it->tab_width = 8;
1352 /* Are lines in the display truncated? */
1353 it->truncate_lines_p
1354 = (base_face_id != DEFAULT_FACE_ID
1355 || XINT (it->w->hscroll)
1356 || (truncate_partial_width_windows
1357 && !WINDOW_FULL_WIDTH_P (it->w))
1358 || !NILP (current_buffer->truncate_lines));
1360 /* Get dimensions of truncation and continuation glyphs. These are
1361 displayed as bitmaps under X, so we don't need them for such
1362 frames. */
1363 if (!FRAME_WINDOW_P (it->f))
1365 if (it->truncate_lines_p)
1367 /* We will need the truncation glyph. */
1368 xassert (it->glyph_row == NULL);
1369 produce_special_glyphs (it, IT_TRUNCATION);
1370 it->truncation_pixel_width = it->pixel_width;
1372 else
1374 /* We will need the continuation glyph. */
1375 xassert (it->glyph_row == NULL);
1376 produce_special_glyphs (it, IT_CONTINUATION);
1377 it->continuation_pixel_width = it->pixel_width;
1380 /* Reset these values to zero becaue the produce_special_glyphs
1381 above has changed them. */
1382 it->pixel_width = it->ascent = it->descent = 0;
1383 it->phys_ascent = it->phys_descent = 0;
1386 /* Set this after getting the dimensions of truncation and
1387 continuation glyphs, so that we don't produce glyphs when calling
1388 produce_special_glyphs, above. */
1389 it->glyph_row = row;
1390 it->area = TEXT_AREA;
1392 /* Get the dimensions of the display area. The display area
1393 consists of the visible window area plus a horizontally scrolled
1394 part to the left of the window. All x-values are relative to the
1395 start of this total display area. */
1396 if (base_face_id != DEFAULT_FACE_ID)
1398 /* Mode lines, menu bar in terminal frames. */
1399 it->first_visible_x = 0;
1400 it->last_visible_x = XFASTINT (w->width) * CANON_X_UNIT (it->f);
1402 else
1404 it->first_visible_x
1405 = XFASTINT (it->w->hscroll) * CANON_X_UNIT (it->f);
1406 it->last_visible_x = (it->first_visible_x
1407 + window_box_width (w, TEXT_AREA));
1409 /* If we truncate lines, leave room for the truncator glyph(s) at
1410 the right margin. Otherwise, leave room for the continuation
1411 glyph(s). Truncation and continuation glyphs are not inserted
1412 for window-based redisplay. */
1413 if (!FRAME_WINDOW_P (it->f))
1415 if (it->truncate_lines_p)
1416 it->last_visible_x -= it->truncation_pixel_width;
1417 else
1418 it->last_visible_x -= it->continuation_pixel_width;
1421 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
1422 it->current_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w) + w->vscroll;
1425 /* Leave room for a border glyph. */
1426 if (!FRAME_WINDOW_P (it->f)
1427 && !WINDOW_RIGHTMOST_P (it->w))
1428 it->last_visible_x -= 1;
1430 it->last_visible_y = window_text_bottom_y (w);
1432 /* For mode lines and alike, arrange for the first glyph having a
1433 left box line if the face specifies a box. */
1434 if (base_face_id != DEFAULT_FACE_ID)
1436 struct face *face;
1438 it->face_id = base_face_id;
1440 /* If we have a boxed mode line, make the first character appear
1441 with a left box line. */
1442 face = FACE_FROM_ID (it->f, base_face_id);
1443 if (face->box != FACE_NO_BOX)
1444 it->start_of_box_run_p = 1;
1447 /* If a buffer position was specified, set the iterator there,
1448 getting overlays and face properties from that position. */
1449 if (charpos > 0)
1451 it->end_charpos = ZV;
1452 it->face_id = -1;
1453 IT_CHARPOS (*it) = charpos;
1455 /* Compute byte position if not specified. */
1456 if (bytepos <= 0)
1457 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
1458 else
1459 IT_BYTEPOS (*it) = bytepos;
1461 /* Compute faces etc. */
1462 reseat (it, it->current.pos, 1);
1465 CHECK_IT (it);
1469 /* Initialize IT for the display of window W with window start POS. */
1471 void
1472 start_display (it, w, pos)
1473 struct it *it;
1474 struct window *w;
1475 struct text_pos pos;
1477 int start_at_line_beg_p;
1478 struct glyph_row *row;
1479 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
1480 int first_y;
1482 row = w->desired_matrix->rows + first_vpos;
1483 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
1484 first_y = it->current_y;
1486 /* If window start is not at a line start, move back to the line
1487 start. This makes sure that we take continuation lines into
1488 account. */
1489 start_at_line_beg_p = (CHARPOS (pos) == BEGV
1490 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
1491 if (!start_at_line_beg_p)
1492 reseat_at_previous_visible_line_start (it);
1494 /* If window start is not at a line start, skip forward to POS to
1495 get the correct continuation_lines_width and current_x. */
1496 if (!start_at_line_beg_p)
1498 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
1500 /* If lines are continued, this line may end in the middle of a
1501 multi-glyph character (e.g. a control character displayed as
1502 \003, or in the middle of an overlay string). In this case
1503 move_it_to above will not have taken us to the start of
1504 the continuation line but to the end of the continued line. */
1505 if (!it->truncate_lines_p)
1507 if (it->current_x > 0)
1509 if (it->current.dpvec_index >= 0
1510 || it->current.overlay_string_index >= 0)
1512 set_iterator_to_next (it);
1513 move_it_in_display_line_to (it, -1, -1, 0);
1516 it->continuation_lines_width += it->current_x;
1519 /* We're starting a new display line, not affected by the
1520 height of the continued line, so clear the appropriate
1521 fields in the iterator structure. */
1522 it->max_ascent = it->max_descent = 0;
1523 it->max_phys_ascent = it->max_phys_descent = 0;
1526 it->current_y = first_y;
1527 it->vpos = 0;
1528 it->current_x = it->hpos = 0;
1531 #if 0 /* Don't assert the following because start_display is sometimes
1532 called intentionally with a window start that is not at a
1533 line start. Please leave this code in as a comment. */
1535 /* Window start should be on a line start, now. */
1536 xassert (it->continuation_lines_width
1537 || IT_CHARPOS (it) == BEGV
1538 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
1539 #endif /* 0 */
1543 /* Initialize IT for stepping through current_buffer in window W,
1544 starting at position POS that includes overlay string and display
1545 vector/ control character translation position information. */
1547 static void
1548 init_from_display_pos (it, w, pos)
1549 struct it *it;
1550 struct window *w;
1551 struct display_pos *pos;
1553 /* Keep in mind: the call to reseat in init_iterator skips invisible
1554 text, so we might end up at a position different from POS. This
1555 is only a problem when POS is a row start after a newline and an
1556 overlay starts there with an after-string, and the overlay has an
1557 invisible property. Since we don't skip invisible text in
1558 display_line and elsewhere immediately after consuming the
1559 newline before the row start, such a POS will not be in a string,
1560 but the call to init_iterator below will move us to the
1561 after-string. */
1562 init_iterator (it, w, CHARPOS (pos->pos), BYTEPOS (pos->pos),
1563 NULL, DEFAULT_FACE_ID);
1565 /* If position is within an overlay string, set up IT to
1566 the right overlay string. */
1567 if (pos->overlay_string_index >= 0)
1569 int relative_index;
1571 /* We already have the first chunk of overlay strings in
1572 IT->overlay_strings. Load more until the one for
1573 pos->overlay_string_index is in IT->overlay_strings. */
1574 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
1576 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
1577 it->current.overlay_string_index = 0;
1578 while (n--)
1580 load_overlay_strings (it);
1581 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
1585 it->current.overlay_string_index = pos->overlay_string_index;
1586 relative_index = (it->current.overlay_string_index
1587 % OVERLAY_STRING_CHUNK_SIZE);
1588 it->string = it->overlay_strings[relative_index];
1589 it->current.string_pos = pos->string_pos;
1590 it->method = next_element_from_string;
1592 else if (CHARPOS (pos->string_pos) >= 0)
1594 /* Recorded position is not in an overlay string, but in another
1595 string. This can only be a string from a `display' property.
1596 IT should already be filled with that string. */
1597 it->current.string_pos = pos->string_pos;
1598 xassert (STRINGP (it->string));
1601 /* Restore position in display vector translations or control
1602 character translations. */
1603 if (pos->dpvec_index >= 0)
1605 /* This fills IT->dpvec. */
1606 get_next_display_element (it);
1607 xassert (it->dpvec && it->current.dpvec_index == 0);
1608 it->current.dpvec_index = pos->dpvec_index;
1611 CHECK_IT (it);
1615 /* Initialize IT for stepping through current_buffer in window W
1616 starting at ROW->start. */
1618 static void
1619 init_to_row_start (it, w, row)
1620 struct it *it;
1621 struct window *w;
1622 struct glyph_row *row;
1624 init_from_display_pos (it, w, &row->start);
1625 it->continuation_lines_width = row->continuation_lines_width;
1626 CHECK_IT (it);
1630 /* Initialize IT for stepping through current_buffer in window W
1631 starting in the line following ROW, i.e. starting at ROW->end. */
1633 static void
1634 init_to_row_end (it, w, row)
1635 struct it *it;
1636 struct window *w;
1637 struct glyph_row *row;
1639 init_from_display_pos (it, w, &row->end);
1641 if (row->continued_p)
1642 it->continuation_lines_width = (row->continuation_lines_width
1643 + row->pixel_width);
1644 CHECK_IT (it);
1650 /***********************************************************************
1651 Text properties
1652 ***********************************************************************/
1654 /* Called when IT reaches IT->stop_charpos. Handle text property and
1655 overlay changes. Set IT->stop_charpos to the next position where
1656 to stop. */
1658 static void
1659 handle_stop (it)
1660 struct it *it;
1662 enum prop_handled handled;
1663 int handle_overlay_change_p = 1;
1664 struct props *p;
1666 it->dpvec = NULL;
1667 it->current.dpvec_index = -1;
1668 it->add_overlay_start = 0;
1672 handled = HANDLED_NORMALLY;
1674 /* Call text property handlers. */
1675 for (p = it_props; p->handler; ++p)
1677 handled = p->handler (it);
1679 if (handled == HANDLED_RECOMPUTE_PROPS)
1680 break;
1681 else if (handled == HANDLED_RETURN)
1682 return;
1683 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
1684 handle_overlay_change_p = 0;
1687 if (handled != HANDLED_RECOMPUTE_PROPS)
1689 /* Don't check for overlay strings below when set to deliver
1690 characters from a display vector. */
1691 if (it->method == next_element_from_display_vector)
1692 handle_overlay_change_p = 0;
1694 /* Handle overlay changes. */
1695 if (handle_overlay_change_p)
1696 handled = handle_overlay_change (it);
1698 /* Determine where to stop next. */
1699 if (handled == HANDLED_NORMALLY)
1700 compute_stop_pos (it);
1703 while (handled == HANDLED_RECOMPUTE_PROPS);
1707 /* Compute IT->stop_charpos from text property and overlay change
1708 information for IT's current position. */
1710 static void
1711 compute_stop_pos (it)
1712 struct it *it;
1714 register INTERVAL iv, next_iv;
1715 Lisp_Object object, limit, position;
1717 /* If nowhere else, stop at the end. */
1718 it->stop_charpos = it->end_charpos;
1720 if (STRINGP (it->string))
1722 /* Strings are usually short, so don't limit the search for
1723 properties. */
1724 object = it->string;
1725 limit = Qnil;
1726 XSETFASTINT (position, IT_STRING_CHARPOS (*it));
1728 else
1730 int charpos;
1732 /* If next overlay change is in front of the current stop pos
1733 (which is IT->end_charpos), stop there. Note: value of
1734 next_overlay_change is point-max if no overlay change
1735 follows. */
1736 charpos = next_overlay_change (IT_CHARPOS (*it));
1737 if (charpos < it->stop_charpos)
1738 it->stop_charpos = charpos;
1740 /* If showing the region, we have to stop at the region
1741 start or end because the face might change there. */
1742 if (it->region_beg_charpos > 0)
1744 if (IT_CHARPOS (*it) < it->region_beg_charpos)
1745 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
1746 else if (IT_CHARPOS (*it) < it->region_end_charpos)
1747 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
1750 /* Set up variables for computing the stop position from text
1751 property changes. */
1752 XSETBUFFER (object, current_buffer);
1753 XSETFASTINT (limit, IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
1754 XSETFASTINT (position, IT_CHARPOS (*it));
1758 /* Get the interval containing IT's position. Value is a null
1759 interval if there isn't such an interval. */
1760 iv = validate_interval_range (object, &position, &position, 0);
1761 if (!NULL_INTERVAL_P (iv))
1763 Lisp_Object values_here[LAST_PROP_IDX];
1764 struct props *p;
1766 /* Get properties here. */
1767 for (p = it_props; p->handler; ++p)
1768 values_here[p->idx] = textget (iv->plist, *p->name);
1770 /* Look for an interval following iv that has different
1771 properties. */
1772 for (next_iv = next_interval (iv);
1773 (!NULL_INTERVAL_P (next_iv)
1774 && (NILP (limit)
1775 || XFASTINT (limit) > next_iv->position));
1776 next_iv = next_interval (next_iv))
1778 for (p = it_props; p->handler; ++p)
1780 Lisp_Object new_value;
1782 new_value = textget (next_iv->plist, *p->name);
1783 if (!EQ (values_here[p->idx], new_value))
1784 break;
1787 if (p->handler)
1788 break;
1791 if (!NULL_INTERVAL_P (next_iv))
1793 if (INTEGERP (limit)
1794 && next_iv->position >= XFASTINT (limit))
1795 /* No text property change up to limit. */
1796 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
1797 else
1798 /* Text properties change in next_iv. */
1799 it->stop_charpos = min (it->stop_charpos, next_iv->position);
1803 xassert (STRINGP (it->string)
1804 || (it->stop_charpos >= BEGV
1805 && it->stop_charpos >= IT_CHARPOS (*it)));
1809 /* Return the position of the next overlay change after POS in
1810 current_buffer. Value is point-max if no overlay change
1811 follows. This is like `next-overlay-change' but doesn't use
1812 xmalloc. */
1814 static int
1815 next_overlay_change (pos)
1816 int pos;
1818 int noverlays;
1819 int endpos;
1820 Lisp_Object *overlays;
1821 int len;
1822 int i;
1824 /* Get all overlays at the given position. */
1825 len = 10;
1826 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1827 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
1828 if (noverlays > len)
1830 len = noverlays;
1831 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1832 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
1835 /* If any of these overlays ends before endpos,
1836 use its ending point instead. */
1837 for (i = 0; i < noverlays; ++i)
1839 Lisp_Object oend;
1840 int oendpos;
1842 oend = OVERLAY_END (overlays[i]);
1843 oendpos = OVERLAY_POSITION (oend);
1844 endpos = min (endpos, oendpos);
1847 return endpos;
1852 /***********************************************************************
1853 Fontification
1854 ***********************************************************************/
1856 /* Handle changes in the `fontified' property of the current buffer by
1857 calling hook functions from Qfontification_functions to fontify
1858 regions of text. */
1860 static enum prop_handled
1861 handle_fontified_prop (it)
1862 struct it *it;
1864 Lisp_Object prop, pos;
1865 enum prop_handled handled = HANDLED_NORMALLY;
1867 /* Get the value of the `fontified' property at IT's current buffer
1868 position. (The `fontified' property doesn't have a special
1869 meaning in strings.) If the value is nil, call functions from
1870 Qfontification_functions. */
1871 if (!STRINGP (it->string)
1872 && it->s == NULL
1873 && !NILP (Vfontification_functions)
1874 && (pos = make_number (IT_CHARPOS (*it)),
1875 prop = Fget_char_property (pos, Qfontified, Qnil),
1876 NILP (prop)))
1878 Lisp_Object args[2];
1880 /* Run the hook functions. */
1881 args[0] = Qfontification_functions;
1882 args[1] = pos;
1883 Frun_hook_with_args (2, args);
1885 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
1886 something. This avoids an endless loop if they failed to
1887 fontify the text for which reason ever. */
1888 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
1889 handled = HANDLED_RECOMPUTE_PROPS;
1892 return handled;
1897 /***********************************************************************
1898 Faces
1899 ***********************************************************************/
1901 /* Set up iterator IT from face properties at its current position.
1902 Called from handle_stop. */
1904 static enum prop_handled
1905 handle_face_prop (it)
1906 struct it *it;
1908 int new_face_id, next_stop;
1910 if (!STRINGP (it->string))
1912 new_face_id
1913 = face_at_buffer_position (it->w,
1914 IT_CHARPOS (*it),
1915 it->region_beg_charpos,
1916 it->region_end_charpos,
1917 &next_stop,
1918 (IT_CHARPOS (*it)
1919 + TEXT_PROP_DISTANCE_LIMIT),
1922 /* Is this a start of a run of characters with box face?
1923 Caveat: this can be called for a freshly initialized
1924 iterator; face_id is -1 is this case. We know that the new
1925 face will not change until limit, i.e. if the new face has a
1926 box, all characters up to limit will have one. But, as
1927 usual, we don't know whether limit is really the end. */
1928 if (new_face_id != it->face_id)
1930 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
1932 /* If new face has a box but old face has not, this is
1933 the start of a run of characters with box, i.e. it has
1934 a shadow on the left side. The value of face_id of the
1935 iterator will be -1 if this is the initial call that gets
1936 the face. In this case, we have to look in front of IT's
1937 position and see whether there is a face != new_face_id. */
1938 it->start_of_box_run_p
1939 = (new_face->box != FACE_NO_BOX
1940 && (it->face_id >= 0
1941 || IT_CHARPOS (*it) == BEG
1942 || new_face_id != face_before_it_pos (it)));
1943 it->face_box_p = new_face->box != FACE_NO_BOX;
1946 else
1948 new_face_id
1949 = face_at_string_position (it->w,
1950 it->string,
1951 IT_STRING_CHARPOS (*it),
1952 (it->current.overlay_string_index >= 0
1953 ? IT_CHARPOS (*it)
1954 : 0),
1955 it->region_beg_charpos,
1956 it->region_end_charpos,
1957 &next_stop,
1958 it->base_face_id);
1960 #if 0 /* This shouldn't be neccessary. Let's check it. */
1961 /* If IT is used to display a mode line we would really like to
1962 use the mode line face instead of the frame's default face. */
1963 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
1964 && new_face_id == DEFAULT_FACE_ID)
1965 new_face_id = MODE_LINE_FACE_ID;
1966 #endif
1968 /* Is this a start of a run of characters with box? Caveat:
1969 this can be called for a freshly allocated iterator; face_id
1970 is -1 is this case. We know that the new face will not
1971 change until the next check pos, i.e. if the new face has a
1972 box, all characters up to that position will have a
1973 box. But, as usual, we don't know whether that position
1974 is really the end. */
1975 if (new_face_id != it->face_id)
1977 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
1978 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
1980 /* If new face has a box but old face hasn't, this is the
1981 start of a run of characters with box, i.e. it has a
1982 shadow on the left side. */
1983 it->start_of_box_run_p
1984 = new_face->box && (old_face == NULL || !old_face->box);
1985 it->face_box_p = new_face->box != FACE_NO_BOX;
1989 it->face_id = new_face_id;
1990 return HANDLED_NORMALLY;
1994 /* Compute the face one character before or after the current position
1995 of IT. BEFORE_P non-zero means get the face in front of IT's
1996 position. Value is the id of the face. */
1998 static int
1999 face_before_or_after_it_pos (it, before_p)
2000 struct it *it;
2001 int before_p;
2003 int face_id, limit;
2004 int next_check_charpos;
2005 struct text_pos pos;
2007 xassert (it->s == NULL);
2009 if (STRINGP (it->string))
2011 /* No face change past the end of the string (for the case
2012 we are padding with spaces). No face change before the
2013 string start. */
2014 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size
2015 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2016 return it->face_id;
2018 /* Set pos to the position before or after IT's current position. */
2019 if (before_p)
2020 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
2021 else
2022 /* For composition, we must check the character after the
2023 composition. */
2024 pos = (it->what == IT_COMPOSITION
2025 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
2026 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
2028 /* Get the face for ASCII, or unibyte. */
2029 face_id
2030 = face_at_string_position (it->w,
2031 it->string,
2032 CHARPOS (pos),
2033 (it->current.overlay_string_index >= 0
2034 ? IT_CHARPOS (*it)
2035 : 0),
2036 it->region_beg_charpos,
2037 it->region_end_charpos,
2038 &next_check_charpos,
2039 it->base_face_id);
2041 /* Correct the face for charsets different from ASCII. Do it
2042 for the multibyte case only. The face returned above is
2043 suitable for unibyte text if IT->string is unibyte. */
2044 if (STRING_MULTIBYTE (it->string))
2046 unsigned char *p = XSTRING (it->string)->data + BYTEPOS (pos);
2047 int rest = STRING_BYTES (XSTRING (it->string)) - BYTEPOS (pos);
2048 int c, len;
2049 struct face *face = FACE_FROM_ID (it->f, face_id);
2051 c = string_char_and_length (p, rest, &len);
2052 face_id = FACE_FOR_CHAR (it->f, face, c);
2055 else
2057 if ((IT_CHARPOS (*it) >= ZV && !before_p)
2058 || (IT_CHARPOS (*it) <= BEGV && before_p))
2059 return it->face_id;
2061 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
2062 pos = it->current.pos;
2064 if (before_p)
2065 DEC_TEXT_POS (pos, it->multibyte_p);
2066 else
2068 if (it->what == IT_COMPOSITION)
2069 /* For composition, we must check the position after the
2070 composition. */
2071 pos.charpos += it->cmp_len, pos.bytepos += it->len;
2072 else
2073 INC_TEXT_POS (pos, it->multibyte_p);
2075 /* Determine face for CHARSET_ASCII, or unibyte. */
2076 face_id = face_at_buffer_position (it->w,
2077 CHARPOS (pos),
2078 it->region_beg_charpos,
2079 it->region_end_charpos,
2080 &next_check_charpos,
2081 limit, 0);
2083 /* Correct the face for charsets different from ASCII. Do it
2084 for the multibyte case only. The face returned above is
2085 suitable for unibyte text if current_buffer is unibyte. */
2086 if (it->multibyte_p)
2088 int c = FETCH_MULTIBYTE_CHAR (CHARPOS (pos));
2089 struct face *face = FACE_FROM_ID (it->f, face_id);
2090 face_id = FACE_FOR_CHAR (it->f, face, c);
2094 return face_id;
2099 /***********************************************************************
2100 Invisible text
2101 ***********************************************************************/
2103 /* Set up iterator IT from invisible properties at its current
2104 position. Called from handle_stop. */
2106 static enum prop_handled
2107 handle_invisible_prop (it)
2108 struct it *it;
2110 enum prop_handled handled = HANDLED_NORMALLY;
2112 if (STRINGP (it->string))
2114 extern Lisp_Object Qinvisible;
2115 Lisp_Object prop, end_charpos, limit, charpos;
2117 /* Get the value of the invisible text property at the
2118 current position. Value will be nil if there is no such
2119 property. */
2120 XSETFASTINT (charpos, IT_STRING_CHARPOS (*it));
2121 prop = Fget_text_property (charpos, Qinvisible, it->string);
2123 if (!NILP (prop)
2124 && IT_STRING_CHARPOS (*it) < it->end_charpos)
2126 handled = HANDLED_RECOMPUTE_PROPS;
2128 /* Get the position at which the next change of the
2129 invisible text property can be found in IT->string.
2130 Value will be nil if the property value is the same for
2131 all the rest of IT->string. */
2132 XSETINT (limit, XSTRING (it->string)->size);
2133 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
2134 it->string, limit);
2136 /* Text at current position is invisible. The next
2137 change in the property is at position end_charpos.
2138 Move IT's current position to that position. */
2139 if (INTEGERP (end_charpos)
2140 && XFASTINT (end_charpos) < XFASTINT (limit))
2142 struct text_pos old;
2143 old = it->current.string_pos;
2144 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
2145 compute_string_pos (&it->current.string_pos, old, it->string);
2147 else
2149 /* The rest of the string is invisible. If this is an
2150 overlay string, proceed with the next overlay string
2151 or whatever comes and return a character from there. */
2152 if (it->current.overlay_string_index >= 0)
2154 next_overlay_string (it);
2155 /* Don't check for overlay strings when we just
2156 finished processing them. */
2157 handled = HANDLED_OVERLAY_STRING_CONSUMED;
2159 else
2161 struct Lisp_String *s = XSTRING (it->string);
2162 IT_STRING_CHARPOS (*it) = s->size;
2163 IT_STRING_BYTEPOS (*it) = STRING_BYTES (s);
2168 else
2170 int visible_p, newpos, next_stop;
2171 Lisp_Object pos, prop;
2173 /* First of all, is there invisible text at this position? */
2174 XSETFASTINT (pos, IT_CHARPOS (*it));
2175 prop = Fget_char_property (pos, Qinvisible, it->window);
2177 /* If we are on invisible text, skip over it. */
2178 if (TEXT_PROP_MEANS_INVISIBLE (prop)
2179 && IT_CHARPOS (*it) < it->end_charpos)
2181 /* Record whether we have to display an ellipsis for the
2182 invisible text. */
2183 int display_ellipsis_p
2184 = TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (prop);
2186 handled = HANDLED_RECOMPUTE_PROPS;
2187 it->add_overlay_start = IT_CHARPOS (*it);
2189 /* Loop skipping over invisible text. The loop is left at
2190 ZV or with IT on the first char being visible again. */
2193 /* Try to skip some invisible text. Return value is the
2194 position reached which can be equal to IT's position
2195 if there is nothing invisible here. This skips both
2196 over invisible text properties and overlays with
2197 invisible property. */
2198 newpos = skip_invisible (IT_CHARPOS (*it),
2199 &next_stop, ZV, it->window);
2201 /* If we skipped nothing at all we weren't at invisible
2202 text in the first place. If everything to the end of
2203 the buffer was skipped, end the loop. */
2204 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
2205 visible_p = 1;
2206 else
2208 /* We skipped some characters but not necessarily
2209 all there are. Check if we ended up on visible
2210 text. Fget_char_property returns the property of
2211 the char before the given position, i.e. if we
2212 get visible_p = 1, this means that the char at
2213 newpos is visible. */
2214 XSETFASTINT (pos, newpos);
2215 prop = Fget_char_property (pos, Qinvisible, it->window);
2216 visible_p = !TEXT_PROP_MEANS_INVISIBLE (prop);
2219 /* If we ended up on invisible text, proceed to
2220 skip starting with next_stop. */
2221 if (!visible_p)
2222 IT_CHARPOS (*it) = next_stop;
2224 while (!visible_p);
2226 /* The position newpos is now either ZV or on visible text. */
2227 IT_CHARPOS (*it) = newpos;
2228 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
2230 /* Maybe return `...' next for the end of the invisible text. */
2231 if (display_ellipsis_p)
2233 if (it->dp
2234 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
2236 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
2237 it->dpvec = v->contents;
2238 it->dpend = v->contents + v->size;
2240 else
2242 /* Default `...'. */
2243 it->dpvec = default_invis_vector;
2244 it->dpend = default_invis_vector + 3;
2247 /* The ellipsis display does not replace the display of
2248 the character at the new position. Indicate this by
2249 setting IT->dpvec_char_len to zero. */
2250 it->dpvec_char_len = 0;
2252 it->current.dpvec_index = 0;
2253 it->method = next_element_from_display_vector;
2258 return handled;
2263 /***********************************************************************
2264 'display' property
2265 ***********************************************************************/
2267 /* Set up iterator IT from `display' property at its current position.
2268 Called from handle_stop. */
2270 static enum prop_handled
2271 handle_display_prop (it)
2272 struct it *it;
2274 Lisp_Object prop, object;
2275 struct text_pos *position;
2276 int space_or_image_found_p;
2278 if (STRINGP (it->string))
2280 object = it->string;
2281 position = &it->current.string_pos;
2283 else
2285 object = Qnil;
2286 position = &it->current.pos;
2289 /* Reset those iterator values set from display property values. */
2290 it->font_height = Qnil;
2291 it->space_width = Qnil;
2292 it->voffset = 0;
2294 /* We don't support recursive `display' properties, i.e. string
2295 values that have a string `display' property, that have a string
2296 `display' property etc. */
2297 if (!it->string_from_display_prop_p)
2298 it->area = TEXT_AREA;
2300 prop = Fget_char_property (make_number (position->charpos),
2301 Qdisplay, object);
2302 if (NILP (prop))
2303 return HANDLED_NORMALLY;
2305 space_or_image_found_p = 0;
2306 if (CONSP (prop)
2307 && CONSP (XCAR (prop))
2308 && !EQ (Qmargin, XCAR (XCAR (prop))))
2310 /* A list of sub-properties. */
2311 while (CONSP (prop))
2313 if (handle_single_display_prop (it, XCAR (prop), object, position))
2314 space_or_image_found_p = 1;
2315 prop = XCDR (prop);
2318 else if (VECTORP (prop))
2320 int i;
2321 for (i = 0; i < XVECTOR (prop)->size; ++i)
2322 if (handle_single_display_prop (it, XVECTOR (prop)->contents[i],
2323 object, position))
2324 space_or_image_found_p = 1;
2326 else
2328 if (handle_single_display_prop (it, prop, object, position))
2329 space_or_image_found_p = 1;
2332 return space_or_image_found_p ? HANDLED_RETURN : HANDLED_NORMALLY;
2336 /* Value is the position of the end of the `display' property starting
2337 at START_POS in OBJECT. */
2339 static struct text_pos
2340 display_prop_end (it, object, start_pos)
2341 struct it *it;
2342 Lisp_Object object;
2343 struct text_pos start_pos;
2345 Lisp_Object end;
2346 struct text_pos end_pos;
2348 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
2349 Qdisplay, object, Qnil);
2350 CHARPOS (end_pos) = XFASTINT (end);
2351 if (STRINGP (object))
2352 compute_string_pos (&end_pos, start_pos, it->string);
2353 else
2354 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
2356 return end_pos;
2360 /* Set up IT from a single `display' sub-property value PROP. OBJECT
2361 is the object in which the `display' property was found. *POSITION
2362 is the position at which it was found.
2364 If PROP is a `space' or `image' sub-property, set *POSITION to the
2365 end position of the `display' property.
2367 Value is non-zero if a `space' or `image' property value was found. */
2369 static int
2370 handle_single_display_prop (it, prop, object, position)
2371 struct it *it;
2372 Lisp_Object prop;
2373 Lisp_Object object;
2374 struct text_pos *position;
2376 Lisp_Object value;
2377 int space_or_image_found_p = 0;
2378 Lisp_Object form;
2380 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
2381 evaluated. If the result is nil, VALUE is ignored. */
2382 form = Qt;
2383 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
2385 prop = XCDR (prop);
2386 if (!CONSP (prop))
2387 return 0;
2388 form = XCAR (prop);
2389 prop = XCDR (prop);
2392 if (!NILP (form) && !EQ (form, Qt))
2394 struct gcpro gcpro1;
2395 struct text_pos end_pos, pt;
2397 GCPRO1 (form);
2398 end_pos = display_prop_end (it, object, *position);
2400 /* Temporarily set point to the end position, and then evaluate
2401 the form. This makes `(eolp)' work as FORM. */
2402 if (BUFFERP (object))
2404 CHARPOS (pt) = PT;
2405 BYTEPOS (pt) = PT_BYTE;
2406 TEMP_SET_PT_BOTH (CHARPOS (end_pos), BYTEPOS (end_pos));
2409 form = eval_form (form);
2411 if (BUFFERP (object))
2412 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
2413 UNGCPRO;
2416 if (NILP (form))
2417 return 0;
2419 if (CONSP (prop)
2420 && EQ (XCAR (prop), Qheight)
2421 && CONSP (XCDR (prop)))
2423 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2424 return 0;
2426 /* `(height HEIGHT)'. */
2427 it->font_height = XCAR (XCDR (prop));
2428 if (!NILP (it->font_height))
2430 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2431 int new_height = -1;
2433 if (CONSP (it->font_height)
2434 && (EQ (XCAR (it->font_height), Qplus)
2435 || EQ (XCAR (it->font_height), Qminus))
2436 && CONSP (XCDR (it->font_height))
2437 && INTEGERP (XCAR (XCDR (it->font_height))))
2439 /* `(+ N)' or `(- N)' where N is an integer. */
2440 int steps = XINT (XCAR (XCDR (it->font_height)));
2441 if (EQ (XCAR (it->font_height), Qplus))
2442 steps = - steps;
2443 it->face_id = smaller_face (it->f, it->face_id, steps);
2445 else if (FUNCTIONP (it->font_height))
2447 /* Call function with current height as argument.
2448 Value is the new height. */
2449 Lisp_Object args[2], height;
2451 args[0] = it->font_height;
2452 args[1] = face->lface[LFACE_HEIGHT_INDEX];
2453 height = call_function (2, args);
2455 if (NUMBERP (height))
2456 new_height = XFLOATINT (height);
2458 else if (NUMBERP (it->font_height))
2460 /* Value is a multiple of the canonical char height. */
2461 struct face *face;
2463 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
2464 new_height = (XFLOATINT (it->font_height)
2465 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
2467 else
2469 /* Evaluate IT->font_height with `height' bound to the
2470 current specified height to get the new height. */
2471 Lisp_Object value;
2472 int count = specpdl_ptr - specpdl;
2474 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
2475 value = eval_form (it->font_height);
2476 unbind_to (count, Qnil);
2478 if (NUMBERP (value))
2479 new_height = XFLOATINT (value);
2482 if (new_height > 0)
2483 it->face_id = face_with_height (it->f, it->face_id, new_height);
2486 else if (CONSP (prop)
2487 && EQ (XCAR (prop), Qspace_width)
2488 && CONSP (XCDR (prop)))
2490 /* `(space_width WIDTH)'. */
2491 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2492 return 0;
2494 value = XCAR (XCDR (prop));
2495 if (NUMBERP (value) && XFLOATINT (value) > 0)
2496 it->space_width = value;
2498 else if (CONSP (prop)
2499 && EQ (XCAR (prop), Qraise)
2500 && CONSP (XCDR (prop)))
2502 /* `(raise FACTOR)'. */
2503 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2504 return 0;
2506 #ifdef HAVE_WINDOW_SYSTEM
2507 value = XCAR (XCDR (prop));
2508 if (NUMBERP (value))
2510 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2511 it->voffset = - (XFLOATINT (value)
2512 * (FONT_HEIGHT (face->font)));
2514 #endif /* HAVE_WINDOW_SYSTEM */
2516 else if (!it->string_from_display_prop_p)
2518 /* `((margin left-margin) VALUE)' or `((margin right-margin)
2519 VALUE) or `((margin nil) VALUE)' or VALUE. */
2520 Lisp_Object location, value;
2521 struct text_pos start_pos;
2522 int valid_p;
2524 /* Characters having this form of property are not displayed, so
2525 we have to find the end of the property. */
2526 start_pos = *position;
2527 *position = display_prop_end (it, object, start_pos);
2528 value = Qnil;
2530 /* Let's stop at the new position and assume that all
2531 text properties change there. */
2532 it->stop_charpos = position->charpos;
2534 location = Qunbound;
2535 if (CONSP (prop) && CONSP (XCAR (prop)))
2537 Lisp_Object tem;
2539 value = XCDR (prop);
2540 if (CONSP (value))
2541 value = XCAR (value);
2543 tem = XCAR (prop);
2544 if (EQ (XCAR (tem), Qmargin)
2545 && (tem = XCDR (tem),
2546 tem = CONSP (tem) ? XCAR (tem) : Qnil,
2547 (NILP (tem)
2548 || EQ (tem, Qleft_margin)
2549 || EQ (tem, Qright_margin))))
2550 location = tem;
2553 if (EQ (location, Qunbound))
2555 location = Qnil;
2556 value = prop;
2559 #ifdef HAVE_WINDOW_SYSTEM
2560 if (FRAME_TERMCAP_P (it->f))
2561 valid_p = STRINGP (value);
2562 else
2563 valid_p = (STRINGP (value)
2564 || (CONSP (value) && EQ (XCAR (value), Qspace))
2565 || valid_image_p (value));
2566 #else /* not HAVE_WINDOW_SYSTEM */
2567 valid_p = STRINGP (value);
2568 #endif /* not HAVE_WINDOW_SYSTEM */
2570 if ((EQ (location, Qleft_margin)
2571 || EQ (location, Qright_margin)
2572 || NILP (location))
2573 && valid_p)
2575 space_or_image_found_p = 1;
2577 /* Save current settings of IT so that we can restore them
2578 when we are finished with the glyph property value. */
2579 push_it (it);
2581 if (NILP (location))
2582 it->area = TEXT_AREA;
2583 else if (EQ (location, Qleft_margin))
2584 it->area = LEFT_MARGIN_AREA;
2585 else
2586 it->area = RIGHT_MARGIN_AREA;
2588 if (STRINGP (value))
2590 it->string = value;
2591 it->multibyte_p = STRING_MULTIBYTE (it->string);
2592 it->current.overlay_string_index = -1;
2593 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
2594 it->end_charpos = it->string_nchars
2595 = XSTRING (it->string)->size;
2596 it->method = next_element_from_string;
2597 it->stop_charpos = 0;
2598 it->string_from_display_prop_p = 1;
2600 else if (CONSP (value) && EQ (XCAR (value), Qspace))
2602 it->method = next_element_from_stretch;
2603 it->object = value;
2604 it->current.pos = it->position = start_pos;
2606 #ifdef HAVE_WINDOW_SYSTEM
2607 else
2609 it->what = IT_IMAGE;
2610 it->image_id = lookup_image (it->f, value);
2611 it->position = start_pos;
2612 it->object = NILP (object) ? it->w->buffer : object;
2613 it->method = next_element_from_image;
2615 /* Say that we haven't consumed the characters with
2616 `display' property yet. The call to pop_it in
2617 set_iterator_to_next will clean this up. */
2618 *position = start_pos;
2620 #endif /* HAVE_WINDOW_SYSTEM */
2622 else
2623 /* Invalid property or property not supported. Restore
2624 the position to what it was before. */
2625 *position = start_pos;
2628 return space_or_image_found_p;
2632 /* Check if PROP is a display sub-property value whose text should be
2633 treated as intangible. */
2635 static int
2636 single_display_prop_intangible_p (prop)
2637 Lisp_Object prop;
2639 /* Skip over `when FORM'. */
2640 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
2642 prop = XCDR (prop);
2643 if (!CONSP (prop))
2644 return 0;
2645 prop = XCDR (prop);
2648 if (!CONSP (prop))
2649 return 0;
2651 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
2652 we don't need to treat text as intangible. */
2653 if (EQ (XCAR (prop), Qmargin))
2655 prop = XCDR (prop);
2656 if (!CONSP (prop))
2657 return 0;
2659 prop = XCDR (prop);
2660 if (!CONSP (prop)
2661 || EQ (XCAR (prop), Qleft_margin)
2662 || EQ (XCAR (prop), Qright_margin))
2663 return 0;
2666 return CONSP (prop) && EQ (XCAR (prop), Qimage);
2670 /* Check if PROP is a display property value whose text should be
2671 treated as intangible. */
2674 display_prop_intangible_p (prop)
2675 Lisp_Object prop;
2677 if (CONSP (prop)
2678 && CONSP (XCAR (prop))
2679 && !EQ (Qmargin, XCAR (XCAR (prop))))
2681 /* A list of sub-properties. */
2682 while (CONSP (prop))
2684 if (single_display_prop_intangible_p (XCAR (prop)))
2685 return 1;
2686 prop = XCDR (prop);
2689 else if (VECTORP (prop))
2691 /* A vector of sub-properties. */
2692 int i;
2693 for (i = 0; i < XVECTOR (prop)->size; ++i)
2694 if (single_display_prop_intangible_p (XVECTOR (prop)->contents[i]))
2695 return 1;
2697 else
2698 return single_display_prop_intangible_p (prop);
2700 return 0;
2704 /***********************************************************************
2705 `composition' property
2706 ***********************************************************************/
2708 /* Set up iterator IT from `composition' property at its current
2709 position. Called from handle_stop. */
2711 static enum prop_handled
2712 handle_composition_prop (it)
2713 struct it *it;
2715 Lisp_Object prop, string;
2716 int pos, pos_byte, end;
2717 enum prop_handled handled = HANDLED_NORMALLY;
2719 if (STRINGP (it->string))
2721 pos = IT_STRING_CHARPOS (*it);
2722 pos_byte = IT_STRING_BYTEPOS (*it);
2723 string = it->string;
2725 else
2727 pos = IT_CHARPOS (*it);
2728 pos_byte = IT_BYTEPOS (*it);
2729 string = Qnil;
2732 /* If there's a valid composition and point is not inside of the
2733 composition (in the case that the composition is from the current
2734 buffer), draw a glyph composed from the composition components. */
2735 if (find_composition (pos, -1, &pos, &end, &prop, string)
2736 && COMPOSITION_VALID_P (pos, end, prop)
2737 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
2739 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
2741 if (id >= 0)
2743 it->method = next_element_from_composition;
2744 it->cmp_id = id;
2745 it->cmp_len = COMPOSITION_LENGTH (prop);
2746 /* For a terminal, draw only the first character of the
2747 components. */
2748 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
2749 it->len = (STRINGP (it->string)
2750 ? string_char_to_byte (it->string, end)
2751 : CHAR_TO_BYTE (end)) - pos_byte;
2752 it->stop_charpos = end;
2753 handled = HANDLED_RETURN;
2757 return handled;
2762 /***********************************************************************
2763 Overlay strings
2764 ***********************************************************************/
2766 /* The following structure is used to record overlay strings for
2767 later sorting in load_overlay_strings. */
2769 struct overlay_entry
2771 Lisp_Object overlay;
2772 Lisp_Object string;
2773 int priority;
2774 int after_string_p;
2778 /* Set up iterator IT from overlay strings at its current position.
2779 Called from handle_stop. */
2781 static enum prop_handled
2782 handle_overlay_change (it)
2783 struct it *it;
2785 if (!STRINGP (it->string) && get_overlay_strings (it))
2786 return HANDLED_RECOMPUTE_PROPS;
2787 else
2788 return HANDLED_NORMALLY;
2792 /* Set up the next overlay string for delivery by IT, if there is an
2793 overlay string to deliver. Called by set_iterator_to_next when the
2794 end of the current overlay string is reached. If there are more
2795 overlay strings to display, IT->string and
2796 IT->current.overlay_string_index are set appropriately here.
2797 Otherwise IT->string is set to nil. */
2799 static void
2800 next_overlay_string (it)
2801 struct it *it;
2803 ++it->current.overlay_string_index;
2804 if (it->current.overlay_string_index == it->n_overlay_strings)
2806 /* No more overlay strings. Restore IT's settings to what
2807 they were before overlay strings were processed, and
2808 continue to deliver from current_buffer. */
2809 pop_it (it);
2810 xassert (it->stop_charpos >= BEGV
2811 && it->stop_charpos <= it->end_charpos);
2812 it->string = Qnil;
2813 it->current.overlay_string_index = -1;
2814 SET_TEXT_POS (it->current.string_pos, -1, -1);
2815 it->n_overlay_strings = 0;
2816 it->method = next_element_from_buffer;
2818 /* If we're at the end of the buffer, record that we have
2819 processed the overlay strings there already, so that
2820 next_element_from_buffer doesn't try it again. */
2821 if (IT_CHARPOS (*it) >= it->end_charpos)
2822 it->overlay_strings_at_end_processed_p = 1;
2824 else
2826 /* There are more overlay strings to process. If
2827 IT->current.overlay_string_index has advanced to a position
2828 where we must load IT->overlay_strings with more strings, do
2829 it. */
2830 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
2832 if (it->current.overlay_string_index && i == 0)
2833 load_overlay_strings (it);
2835 /* Initialize IT to deliver display elements from the overlay
2836 string. */
2837 it->string = it->overlay_strings[i];
2838 it->multibyte_p = STRING_MULTIBYTE (it->string);
2839 SET_TEXT_POS (it->current.string_pos, 0, 0);
2840 it->method = next_element_from_string;
2841 it->stop_charpos = 0;
2844 CHECK_IT (it);
2848 /* Compare two overlay_entry structures E1 and E2. Used as a
2849 comparison function for qsort in load_overlay_strings. Overlay
2850 strings for the same position are sorted so that
2852 1. All after-strings come in front of before-strings, except
2853 when they come from the same overlay.
2855 2. Within after-strings, strings are sorted so that overlay strings
2856 from overlays with higher priorities come first.
2858 2. Within before-strings, strings are sorted so that overlay
2859 strings from overlays with higher priorities come last.
2861 Value is analogous to strcmp. */
2864 static int
2865 compare_overlay_entries (e1, e2)
2866 void *e1, *e2;
2868 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
2869 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
2870 int result;
2872 if (entry1->after_string_p != entry2->after_string_p)
2874 /* Let after-strings appear in front of before-strings if
2875 they come from different overlays. */
2876 if (EQ (entry1->overlay, entry2->overlay))
2877 result = entry1->after_string_p ? 1 : -1;
2878 else
2879 result = entry1->after_string_p ? -1 : 1;
2881 else if (entry1->after_string_p)
2882 /* After-strings sorted in order of decreasing priority. */
2883 result = entry2->priority - entry1->priority;
2884 else
2885 /* Before-strings sorted in order of increasing priority. */
2886 result = entry1->priority - entry2->priority;
2888 return result;
2892 /* Load the vector IT->overlay_strings with overlay strings from IT's
2893 current buffer position. Set IT->n_overlays to the total number of
2894 overlay strings found.
2896 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
2897 a time. On entry into load_overlay_strings,
2898 IT->current.overlay_string_index gives the number of overlay
2899 strings that have already been loaded by previous calls to this
2900 function.
2902 IT->add_overlay_start contains an additional overlay start
2903 position to consider for taking overlay strings from, if non-zero.
2904 This position comes into play when the overlay has an `invisible'
2905 property, and both before and after-strings. When we've skipped to
2906 the end of the overlay, because of its `invisible' property, we
2907 nevertheless want its before-string to appear.
2908 IT->add_overlay_start will contain the overlay start position
2909 in this case.
2911 Overlay strings are sorted so that after-string strings come in
2912 front of before-string strings. Within before and after-strings,
2913 strings are sorted by overlay priority. See also function
2914 compare_overlay_entries. */
2916 static void
2917 load_overlay_strings (it)
2918 struct it *it;
2920 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
2921 Lisp_Object ov, overlay, window, str;
2922 int start, end;
2923 int size = 20;
2924 int n = 0, i, j;
2925 struct overlay_entry *entries
2926 = (struct overlay_entry *) alloca (size * sizeof *entries);
2928 /* Append the overlay string STRING of overlay OVERLAY to vector
2929 `entries' which has size `size' and currently contains `n'
2930 elements. AFTER_P non-zero means STRING is an after-string of
2931 OVERLAY. */
2932 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
2933 do \
2935 Lisp_Object priority; \
2937 if (n == size) \
2939 int new_size = 2 * size; \
2940 struct overlay_entry *old = entries; \
2941 entries = \
2942 (struct overlay_entry *) alloca (new_size \
2943 * sizeof *entries); \
2944 bcopy (old, entries, size * sizeof *entries); \
2945 size = new_size; \
2948 entries[n].string = (STRING); \
2949 entries[n].overlay = (OVERLAY); \
2950 priority = Foverlay_get ((OVERLAY), Qpriority); \
2951 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
2952 entries[n].after_string_p = (AFTER_P); \
2953 ++n; \
2955 while (0)
2957 /* Process overlay before the overlay center. */
2958 for (ov = current_buffer->overlays_before; CONSP (ov); ov = XCDR (ov))
2960 overlay = XCAR (ov);
2961 xassert (OVERLAYP (overlay));
2962 start = OVERLAY_POSITION (OVERLAY_START (overlay));
2963 end = OVERLAY_POSITION (OVERLAY_END (overlay));
2965 if (end < IT_CHARPOS (*it))
2966 break;
2968 /* Skip this overlay if it doesn't start or end at IT's current
2969 position. */
2970 if (end != IT_CHARPOS (*it)
2971 && start != IT_CHARPOS (*it)
2972 && it->add_overlay_start != IT_CHARPOS (*it))
2973 continue;
2975 /* Skip this overlay if it doesn't apply to IT->w. */
2976 window = Foverlay_get (overlay, Qwindow);
2977 if (WINDOWP (window) && XWINDOW (window) != it->w)
2978 continue;
2980 /* If overlay has a non-empty before-string, record it. */
2981 if ((start == IT_CHARPOS (*it)
2982 || start == it->add_overlay_start)
2983 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
2984 && XSTRING (str)->size)
2985 RECORD_OVERLAY_STRING (overlay, str, 0);
2987 /* If overlay has a non-empty after-string, record it. */
2988 if (end == IT_CHARPOS (*it)
2989 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
2990 && XSTRING (str)->size)
2991 RECORD_OVERLAY_STRING (overlay, str, 1);
2994 /* Process overlays after the overlay center. */
2995 for (ov = current_buffer->overlays_after; CONSP (ov); ov = XCDR (ov))
2997 overlay = XCAR (ov);
2998 xassert (OVERLAYP (overlay));
2999 start = OVERLAY_POSITION (OVERLAY_START (overlay));
3000 end = OVERLAY_POSITION (OVERLAY_END (overlay));
3002 if (start > IT_CHARPOS (*it))
3003 break;
3005 /* Skip this overlay if it doesn't start or end at IT's current
3006 position. */
3007 if (end != IT_CHARPOS (*it)
3008 && start != IT_CHARPOS (*it)
3009 && it->add_overlay_start != IT_CHARPOS (*it))
3010 continue;
3012 /* Skip this overlay if it doesn't apply to IT->w. */
3013 window = Foverlay_get (overlay, Qwindow);
3014 if (WINDOWP (window) && XWINDOW (window) != it->w)
3015 continue;
3017 /* If overlay has a non-empty before-string, record it. */
3018 if ((start == IT_CHARPOS (*it)
3019 || start == it->add_overlay_start)
3020 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
3021 && XSTRING (str)->size)
3022 RECORD_OVERLAY_STRING (overlay, str, 0);
3024 /* If overlay has a non-empty after-string, record it. */
3025 if (end == IT_CHARPOS (*it)
3026 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
3027 && XSTRING (str)->size)
3028 RECORD_OVERLAY_STRING (overlay, str, 1);
3031 #undef RECORD_OVERLAY_STRING
3033 /* Sort entries. */
3034 if (n)
3035 qsort (entries, n, sizeof *entries, compare_overlay_entries);
3037 /* Record the total number of strings to process. */
3038 it->n_overlay_strings = n;
3040 /* IT->current.overlay_string_index is the number of overlay strings
3041 that have already been consumed by IT. Copy some of the
3042 remaining overlay strings to IT->overlay_strings. */
3043 i = 0;
3044 j = it->current.overlay_string_index;
3045 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
3046 it->overlay_strings[i++] = entries[j++].string;
3048 CHECK_IT (it);
3052 /* Get the first chunk of overlay strings at IT's current buffer
3053 position. Value is non-zero if at least one overlay string was
3054 found. */
3056 static int
3057 get_overlay_strings (it)
3058 struct it *it;
3060 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
3061 process. This fills IT->overlay_strings with strings, and sets
3062 IT->n_overlay_strings to the total number of strings to process.
3063 IT->pos.overlay_string_index has to be set temporarily to zero
3064 because load_overlay_strings needs this; it must be set to -1
3065 when no overlay strings are found because a zero value would
3066 indicate a position in the first overlay string. */
3067 it->current.overlay_string_index = 0;
3068 load_overlay_strings (it);
3070 /* If we found overlay strings, set up IT to deliver display
3071 elements from the first one. Otherwise set up IT to deliver
3072 from current_buffer. */
3073 if (it->n_overlay_strings)
3075 /* Make sure we know settings in current_buffer, so that we can
3076 restore meaningful values when we're done with the overlay
3077 strings. */
3078 compute_stop_pos (it);
3079 xassert (it->face_id >= 0);
3081 /* Save IT's settings. They are restored after all overlay
3082 strings have been processed. */
3083 xassert (it->sp == 0);
3084 push_it (it);
3086 /* Set up IT to deliver display elements from the first overlay
3087 string. */
3088 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3089 it->stop_charpos = 0;
3090 it->string = it->overlay_strings[0];
3091 it->multibyte_p = STRING_MULTIBYTE (it->string);
3092 xassert (STRINGP (it->string));
3093 it->method = next_element_from_string;
3095 else
3097 it->string = Qnil;
3098 it->current.overlay_string_index = -1;
3099 it->method = next_element_from_buffer;
3102 CHECK_IT (it);
3104 /* Value is non-zero if we found at least one overlay string. */
3105 return STRINGP (it->string);
3110 /***********************************************************************
3111 Saving and restoring state
3112 ***********************************************************************/
3114 /* Save current settings of IT on IT->stack. Called, for example,
3115 before setting up IT for an overlay string, to be able to restore
3116 IT's settings to what they were after the overlay string has been
3117 processed. */
3119 static void
3120 push_it (it)
3121 struct it *it;
3123 struct iterator_stack_entry *p;
3125 xassert (it->sp < 2);
3126 p = it->stack + it->sp;
3128 p->stop_charpos = it->stop_charpos;
3129 xassert (it->face_id >= 0);
3130 p->face_id = it->face_id;
3131 p->string = it->string;
3132 p->pos = it->current;
3133 p->end_charpos = it->end_charpos;
3134 p->string_nchars = it->string_nchars;
3135 p->area = it->area;
3136 p->multibyte_p = it->multibyte_p;
3137 p->space_width = it->space_width;
3138 p->font_height = it->font_height;
3139 p->voffset = it->voffset;
3140 p->string_from_display_prop_p = it->string_from_display_prop_p;
3141 ++it->sp;
3145 /* Restore IT's settings from IT->stack. Called, for example, when no
3146 more overlay strings must be processed, and we return to delivering
3147 display elements from a buffer, or when the end of a string from a
3148 `display' property is reached and we return to delivering display
3149 elements from an overlay string, or from a buffer. */
3151 static void
3152 pop_it (it)
3153 struct it *it;
3155 struct iterator_stack_entry *p;
3157 xassert (it->sp > 0);
3158 --it->sp;
3159 p = it->stack + it->sp;
3160 it->stop_charpos = p->stop_charpos;
3161 it->face_id = p->face_id;
3162 it->string = p->string;
3163 it->current = p->pos;
3164 it->end_charpos = p->end_charpos;
3165 it->string_nchars = p->string_nchars;
3166 it->area = p->area;
3167 it->multibyte_p = p->multibyte_p;
3168 it->space_width = p->space_width;
3169 it->font_height = p->font_height;
3170 it->voffset = p->voffset;
3171 it->string_from_display_prop_p = p->string_from_display_prop_p;
3176 /***********************************************************************
3177 Moving over lines
3178 ***********************************************************************/
3180 /* Set IT's current position to the previous line start. */
3182 static void
3183 back_to_previous_line_start (it)
3184 struct it *it;
3186 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
3187 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
3191 /* Set IT's current position to the next line start. */
3193 static void
3194 forward_to_next_line_start (it)
3195 struct it *it;
3197 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), 1);
3198 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
3202 /* Set IT's current position to the previous visible line start. Skip
3203 invisible text that is so either due to text properties or due to
3204 selective display. Caution: this does not change IT->current_x and
3205 IT->hpos. */
3207 static void
3208 back_to_previous_visible_line_start (it)
3209 struct it *it;
3211 int visible_p = 0;
3213 /* Go back one newline if not on BEGV already. */
3214 if (IT_CHARPOS (*it) > BEGV)
3215 back_to_previous_line_start (it);
3217 /* Move over lines that are invisible because of selective display
3218 or text properties. */
3219 while (IT_CHARPOS (*it) > BEGV
3220 && !visible_p)
3222 visible_p = 1;
3224 /* If selective > 0, then lines indented more than that values
3225 are invisible. */
3226 if (it->selective > 0
3227 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
3228 it->selective))
3229 visible_p = 0;
3230 else
3232 Lisp_Object prop;
3234 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
3235 Qinvisible, it->window);
3236 if (TEXT_PROP_MEANS_INVISIBLE (prop))
3237 visible_p = 0;
3240 /* Back one more newline if the current one is invisible. */
3241 if (!visible_p)
3242 back_to_previous_line_start (it);
3245 xassert (IT_CHARPOS (*it) >= BEGV);
3246 xassert (IT_CHARPOS (*it) == BEGV
3247 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
3248 CHECK_IT (it);
3252 /* Reseat iterator IT at the previous visible line start. Skip
3253 invisible text that is so either due to text properties or due to
3254 selective display. At the end, update IT's overlay information,
3255 face information etc. */
3257 static void
3258 reseat_at_previous_visible_line_start (it)
3259 struct it *it;
3261 back_to_previous_visible_line_start (it);
3262 reseat (it, it->current.pos, 1);
3263 CHECK_IT (it);
3267 /* Reseat iterator IT on the next visible line start in the current
3268 buffer. ON_NEWLINE_P non-zero means position IT on the newline
3269 preceding the line start. Skip over invisible text that is so
3270 because of selective display. Compute faces, overlays etc at the
3271 new position. Note that this function does not skip over text that
3272 is invisible because of text properties. */
3274 static void
3275 reseat_at_next_visible_line_start (it, on_newline_p)
3276 struct it *it;
3277 int on_newline_p;
3279 /* Restore the buffer position when currently not delivering display
3280 elements from the current buffer. This is the case, for example,
3281 when called at the end of a truncated overlay string. */
3282 while (it->sp)
3283 pop_it (it);
3284 it->method = next_element_from_buffer;
3286 /* Otherwise, scan_buffer would not work. */
3287 if (IT_CHARPOS (*it) < ZV)
3289 /* If on a newline, advance past it. Otherwise, find the next
3290 newline which automatically gives us the position following
3291 the newline. */
3292 if (FETCH_BYTE (IT_BYTEPOS (*it)) == '\n')
3294 ++IT_CHARPOS (*it);
3295 ++IT_BYTEPOS (*it);
3297 else
3298 forward_to_next_line_start (it);
3300 /* We must either have reached the end of the buffer or end up
3301 after a newline. */
3302 xassert (IT_CHARPOS (*it) == ZV
3303 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
3305 /* Skip over lines that are invisible because they are indented
3306 more than the value of IT->selective. */
3307 if (it->selective > 0)
3308 while (IT_CHARPOS (*it) < ZV
3309 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
3310 it->selective))
3311 forward_to_next_line_start (it);
3313 /* Position on the newline if we should. */
3314 if (on_newline_p
3315 && IT_CHARPOS (*it) > BEGV
3316 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n')
3318 --IT_CHARPOS (*it);
3319 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
3322 /* Set the iterator there. The 0 as the last parameter of
3323 reseat means don't force a text property lookup. The lookup
3324 is then only done if we've skipped past the iterator's
3325 check_charpos'es. This optimization is important because
3326 text property lookups tend to be expensive. */
3327 reseat (it, it->current.pos, 0);
3330 CHECK_IT (it);
3335 /***********************************************************************
3336 Changing an iterator's position
3337 ***********************************************************************/
3339 /* Change IT's current position to POS in current_buffer. If FORCE_P
3340 is non-zero, always check for text properties at the new position.
3341 Otherwise, text properties are only looked up if POS >=
3342 IT->check_charpos of a property. */
3344 static void
3345 reseat (it, pos, force_p)
3346 struct it *it;
3347 struct text_pos pos;
3348 int force_p;
3350 int original_pos = IT_CHARPOS (*it);
3352 reseat_1 (it, pos, 0);
3354 /* Determine where to check text properties. Avoid doing it
3355 where possible because text property lookup is very expensive. */
3356 if (force_p
3357 || CHARPOS (pos) > it->stop_charpos
3358 || CHARPOS (pos) < original_pos)
3359 handle_stop (it);
3361 CHECK_IT (it);
3365 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
3366 IT->stop_pos to POS, also. */
3368 static void
3369 reseat_1 (it, pos, set_stop_p)
3370 struct it *it;
3371 struct text_pos pos;
3372 int set_stop_p;
3374 /* Don't call this function when scanning a C string. */
3375 xassert (it->s == NULL);
3377 /* POS must be a reasonable value. */
3378 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
3380 it->current.pos = it->position = pos;
3381 XSETBUFFER (it->object, current_buffer);
3382 it->dpvec = NULL;
3383 it->current.dpvec_index = -1;
3384 it->current.overlay_string_index = -1;
3385 IT_STRING_CHARPOS (*it) = -1;
3386 IT_STRING_BYTEPOS (*it) = -1;
3387 it->string = Qnil;
3388 it->method = next_element_from_buffer;
3389 it->sp = 0;
3391 if (set_stop_p)
3392 it->stop_charpos = CHARPOS (pos);
3396 /* Set up IT for displaying a string, starting at CHARPOS in window W.
3397 If S is non-null, it is a C string to iterate over. Otherwise,
3398 STRING gives a Lisp string to iterate over.
3400 If PRECISION > 0, don't return more then PRECISION number of
3401 characters from the string.
3403 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
3404 characters have been returned. FIELD_WIDTH < 0 means an infinite
3405 field width.
3407 MULTIBYTE = 0 means disable processing of multibyte characters,
3408 MULTIBYTE > 0 means enable it,
3409 MULTIBYTE < 0 means use IT->multibyte_p.
3411 IT must be initialized via a prior call to init_iterator before
3412 calling this function. */
3414 static void
3415 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
3416 struct it *it;
3417 unsigned char *s;
3418 Lisp_Object string;
3419 int charpos;
3420 int precision, field_width, multibyte;
3422 /* No region in strings. */
3423 it->region_beg_charpos = it->region_end_charpos = -1;
3425 /* No text property checks performed by default, but see below. */
3426 it->stop_charpos = -1;
3428 /* Set iterator position and end position. */
3429 bzero (&it->current, sizeof it->current);
3430 it->current.overlay_string_index = -1;
3431 it->current.dpvec_index = -1;
3432 xassert (charpos >= 0);
3434 /* Use the setting of MULTIBYTE if specified. */
3435 if (multibyte >= 0)
3436 it->multibyte_p = multibyte > 0;
3438 if (s == NULL)
3440 xassert (STRINGP (string));
3441 it->string = string;
3442 it->s = NULL;
3443 it->end_charpos = it->string_nchars = XSTRING (string)->size;
3444 it->method = next_element_from_string;
3445 it->current.string_pos = string_pos (charpos, string);
3447 else
3449 it->s = s;
3450 it->string = Qnil;
3452 /* Note that we use IT->current.pos, not it->current.string_pos,
3453 for displaying C strings. */
3454 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
3455 if (it->multibyte_p)
3457 it->current.pos = c_string_pos (charpos, s, 1);
3458 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
3460 else
3462 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
3463 it->end_charpos = it->string_nchars = strlen (s);
3466 it->method = next_element_from_c_string;
3469 /* PRECISION > 0 means don't return more than PRECISION characters
3470 from the string. */
3471 if (precision > 0 && it->end_charpos - charpos > precision)
3472 it->end_charpos = it->string_nchars = charpos + precision;
3474 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
3475 characters have been returned. FIELD_WIDTH == 0 means don't pad,
3476 FIELD_WIDTH < 0 means infinite field width. This is useful for
3477 padding with `-' at the end of a mode line. */
3478 if (field_width < 0)
3479 field_width = INFINITY;
3480 if (field_width > it->end_charpos - charpos)
3481 it->end_charpos = charpos + field_width;
3483 /* Use the standard display table for displaying strings. */
3484 if (DISP_TABLE_P (Vstandard_display_table))
3485 it->dp = XCHAR_TABLE (Vstandard_display_table);
3487 it->stop_charpos = charpos;
3488 CHECK_IT (it);
3493 /***********************************************************************
3494 Iteration
3495 ***********************************************************************/
3497 /* Load IT's display element fields with information about the next
3498 display element from the current position of IT. Value is zero if
3499 end of buffer (or C string) is reached. */
3502 get_next_display_element (it)
3503 struct it *it;
3505 /* Non-zero means that we found an display element. Zero means that
3506 we hit the end of what we iterate over. Performance note: the
3507 function pointer `method' used here turns out to be faster than
3508 using a sequence of if-statements. */
3509 int success_p = (*it->method) (it);
3511 if (it->what == IT_CHARACTER)
3513 /* Map via display table or translate control characters.
3514 IT->c, IT->len etc. have been set to the next character by
3515 the function call above. If we have a display table, and it
3516 contains an entry for IT->c, translate it. Don't do this if
3517 IT->c itself comes from a display table, otherwise we could
3518 end up in an infinite recursion. (An alternative could be to
3519 count the recursion depth of this function and signal an
3520 error when a certain maximum depth is reached.) Is it worth
3521 it? */
3522 if (success_p && it->dpvec == NULL)
3524 Lisp_Object dv;
3526 if (it->dp
3527 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
3528 VECTORP (dv)))
3530 struct Lisp_Vector *v = XVECTOR (dv);
3532 /* Return the first character from the display table
3533 entry, if not empty. If empty, don't display the
3534 current character. */
3535 if (v->size)
3537 it->dpvec_char_len = it->len;
3538 it->dpvec = v->contents;
3539 it->dpend = v->contents + v->size;
3540 it->current.dpvec_index = 0;
3541 it->method = next_element_from_display_vector;
3544 success_p = get_next_display_element (it);
3547 /* Translate control characters into `\003' or `^C' form.
3548 Control characters coming from a display table entry are
3549 currently not translated because we use IT->dpvec to hold
3550 the translation. This could easily be changed but I
3551 don't believe that it is worth doing.
3553 Non-printable multibyte characters are also translated
3554 octal form. */
3555 else if ((it->c < ' '
3556 && (it->area != TEXT_AREA
3557 || (it->c != '\n' && it->c != '\t')))
3558 || (it->c >= 127
3559 && it->len == 1)
3560 || !CHAR_PRINTABLE_P (it->c))
3562 /* IT->c is a control character which must be displayed
3563 either as '\003' or as `^C' where the '\\' and '^'
3564 can be defined in the display table. Fill
3565 IT->ctl_chars with glyphs for what we have to
3566 display. Then, set IT->dpvec to these glyphs. */
3567 GLYPH g;
3569 if (it->c < 128 && it->ctl_arrow_p)
3571 /* Set IT->ctl_chars[0] to the glyph for `^'. */
3572 if (it->dp
3573 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
3574 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
3575 g = XINT (DISP_CTRL_GLYPH (it->dp));
3576 else
3577 g = FAST_MAKE_GLYPH ('^', 0);
3578 XSETINT (it->ctl_chars[0], g);
3580 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
3581 XSETINT (it->ctl_chars[1], g);
3583 /* Set up IT->dpvec and return first character from it. */
3584 it->dpvec_char_len = it->len;
3585 it->dpvec = it->ctl_chars;
3586 it->dpend = it->dpvec + 2;
3587 it->current.dpvec_index = 0;
3588 it->method = next_element_from_display_vector;
3589 get_next_display_element (it);
3591 else
3593 unsigned char str[MAX_MULTIBYTE_LENGTH];
3594 int len;
3595 int i;
3596 GLYPH escape_glyph;
3598 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
3599 if (it->dp
3600 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
3601 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
3602 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
3603 else
3604 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
3606 if (SINGLE_BYTE_CHAR_P (it->c))
3607 str[0] = it->c, len = 1;
3608 else
3609 len = CHAR_STRING (it->c, str);
3611 for (i = 0; i < len; i++)
3613 XSETINT (it->ctl_chars[i * 4], escape_glyph);
3614 /* Insert three more glyphs into IT->ctl_chars for
3615 the octal display of the character. */
3616 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
3617 XSETINT (it->ctl_chars[i * 4 + 1], g);
3618 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
3619 XSETINT (it->ctl_chars[i * 4 + 2], g);
3620 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
3621 XSETINT (it->ctl_chars[i * 4 + 3], g);
3624 /* Set up IT->dpvec and return the first character
3625 from it. */
3626 it->dpvec_char_len = it->len;
3627 it->dpvec = it->ctl_chars;
3628 it->dpend = it->dpvec + len * 4;
3629 it->current.dpvec_index = 0;
3630 it->method = next_element_from_display_vector;
3631 get_next_display_element (it);
3636 /* Adjust face id for a multibyte character. There are no
3637 multibyte character in unibyte text. */
3638 if (it->multibyte_p
3639 && success_p
3640 && FRAME_WINDOW_P (it->f))
3642 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3643 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
3647 /* Is this character the last one of a run of characters with
3648 box? If yes, set IT->end_of_box_run_p to 1. */
3649 if (it->face_box_p
3650 && it->s == NULL)
3652 int face_id;
3653 struct face *face;
3655 it->end_of_box_run_p
3656 = ((face_id = face_after_it_pos (it),
3657 face_id != it->face_id)
3658 && (face = FACE_FROM_ID (it->f, face_id),
3659 face->box == FACE_NO_BOX));
3662 /* Value is 0 if end of buffer or string reached. */
3663 return success_p;
3667 /* Move IT to the next display element.
3669 Functions get_next_display_element and set_iterator_to_next are
3670 separate because I find this arrangement easier to handle than a
3671 get_next_display_element function that also increments IT's
3672 position. The way it is we can first look at an iterator's current
3673 display element, decide whether it fits on a line, and if it does,
3674 increment the iterator position. The other way around we probably
3675 would either need a flag indicating whether the iterator has to be
3676 incremented the next time, or we would have to implement a
3677 decrement position function which would not be easy to write. */
3679 void
3680 set_iterator_to_next (it)
3681 struct it *it;
3683 if (it->method == next_element_from_buffer)
3685 /* The current display element of IT is a character from
3686 current_buffer. Advance in the buffer, and maybe skip over
3687 invisible lines that are so because of selective display. */
3688 if (ITERATOR_AT_END_OF_LINE_P (it))
3689 reseat_at_next_visible_line_start (it, 0);
3690 else
3692 xassert (it->len != 0);
3693 IT_BYTEPOS (*it) += it->len;
3694 IT_CHARPOS (*it) += 1;
3695 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
3698 else if (it->method == next_element_from_composition)
3700 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
3701 if (STRINGP (it->string))
3703 IT_STRING_BYTEPOS (*it) += it->len;
3704 IT_STRING_CHARPOS (*it) += it->cmp_len;
3705 it->method = next_element_from_string;
3706 goto consider_string_end;
3708 else
3710 IT_BYTEPOS (*it) += it->len;
3711 IT_CHARPOS (*it) += it->cmp_len;
3712 it->method = next_element_from_buffer;
3715 else if (it->method == next_element_from_c_string)
3717 /* Current display element of IT is from a C string. */
3718 IT_BYTEPOS (*it) += it->len;
3719 IT_CHARPOS (*it) += 1;
3721 else if (it->method == next_element_from_display_vector)
3723 /* Current display element of IT is from a display table entry.
3724 Advance in the display table definition. Reset it to null if
3725 end reached, and continue with characters from buffers/
3726 strings. */
3727 ++it->current.dpvec_index;
3729 /* Restore face of the iterator to what they were before the
3730 display vector entry (these entries may contain faces). */
3731 it->face_id = it->saved_face_id;
3733 if (it->dpvec + it->current.dpvec_index == it->dpend)
3735 if (it->s)
3736 it->method = next_element_from_c_string;
3737 else if (STRINGP (it->string))
3738 it->method = next_element_from_string;
3739 else
3740 it->method = next_element_from_buffer;
3742 it->dpvec = NULL;
3743 it->current.dpvec_index = -1;
3745 /* Skip over characters which were displayed via IT->dpvec. */
3746 if (it->dpvec_char_len < 0)
3747 reseat_at_next_visible_line_start (it, 1);
3748 else if (it->dpvec_char_len > 0)
3750 it->len = it->dpvec_char_len;
3751 set_iterator_to_next (it);
3755 else if (it->method == next_element_from_string)
3757 /* Current display element is a character from a Lisp string. */
3758 xassert (it->s == NULL && STRINGP (it->string));
3759 IT_STRING_BYTEPOS (*it) += it->len;
3760 IT_STRING_CHARPOS (*it) += 1;
3762 consider_string_end:
3764 if (it->current.overlay_string_index >= 0)
3766 /* IT->string is an overlay string. Advance to the
3767 next, if there is one. */
3768 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
3769 next_overlay_string (it);
3771 else
3773 /* IT->string is not an overlay string. If we reached
3774 its end, and there is something on IT->stack, proceed
3775 with what is on the stack. This can be either another
3776 string, this time an overlay string, or a buffer. */
3777 if (IT_STRING_CHARPOS (*it) == XSTRING (it->string)->size
3778 && it->sp > 0)
3780 pop_it (it);
3781 if (!STRINGP (it->string))
3782 it->method = next_element_from_buffer;
3786 else if (it->method == next_element_from_image
3787 || it->method == next_element_from_stretch)
3789 /* The position etc with which we have to proceed are on
3790 the stack. The position may be at the end of a string,
3791 if the `display' property takes up the whole string. */
3792 pop_it (it);
3793 it->image_id = 0;
3794 if (STRINGP (it->string))
3796 it->method = next_element_from_string;
3797 goto consider_string_end;
3799 else
3800 it->method = next_element_from_buffer;
3802 else
3803 /* There are no other methods defined, so this should be a bug. */
3804 abort ();
3806 /* Reset flags indicating start and end of a sequence of
3807 characters with box. */
3808 it->start_of_box_run_p = it->end_of_box_run_p = 0;
3810 xassert (it->method != next_element_from_string
3811 || (STRINGP (it->string)
3812 && IT_STRING_CHARPOS (*it) >= 0));
3816 /* Load IT's display element fields with information about the next
3817 display element which comes from a display table entry or from the
3818 result of translating a control character to one of the forms `^C'
3819 or `\003'. IT->dpvec holds the glyphs to return as characters. */
3821 static int
3822 next_element_from_display_vector (it)
3823 struct it *it;
3825 /* Precondition. */
3826 xassert (it->dpvec && it->current.dpvec_index >= 0);
3828 /* Remember the current face id in case glyphs specify faces.
3829 IT's face is restored in set_iterator_to_next. */
3830 it->saved_face_id = it->face_id;
3832 if (INTEGERP (*it->dpvec)
3833 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
3835 int lface_id;
3836 GLYPH g;
3838 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
3839 it->c = FAST_GLYPH_CHAR (g);
3840 it->len = CHAR_BYTES (it->c);
3842 /* The entry may contain a face id to use. Such a face id is
3843 the id of a Lisp face, not a realized face. A face id of
3844 zero means no face is specified. */
3845 lface_id = FAST_GLYPH_FACE (g);
3846 if (lface_id)
3848 /* The function returns -1 if lface_id is invalid. */
3849 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
3850 if (face_id >= 0)
3851 it->face_id = face_id;
3854 else
3855 /* Display table entry is invalid. Return a space. */
3856 it->c = ' ', it->len = 1;
3858 /* Don't change position and object of the iterator here. They are
3859 still the values of the character that had this display table
3860 entry or was translated, and that's what we want. */
3861 it->what = IT_CHARACTER;
3862 return 1;
3866 /* Load IT with the next display element from Lisp string IT->string.
3867 IT->current.string_pos is the current position within the string.
3868 If IT->current.overlay_string_index >= 0, the Lisp string is an
3869 overlay string. */
3871 static int
3872 next_element_from_string (it)
3873 struct it *it;
3875 struct text_pos position;
3877 xassert (STRINGP (it->string));
3878 xassert (IT_STRING_CHARPOS (*it) >= 0);
3879 position = it->current.string_pos;
3881 /* Time to check for invisible text? */
3882 if (IT_STRING_CHARPOS (*it) < it->end_charpos
3883 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
3885 handle_stop (it);
3887 /* Since a handler may have changed IT->method, we must
3888 recurse here. */
3889 return get_next_display_element (it);
3892 if (it->current.overlay_string_index >= 0)
3894 /* Get the next character from an overlay string. In overlay
3895 strings, There is no field width or padding with spaces to
3896 do. */
3897 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
3899 it->what = IT_EOB;
3900 return 0;
3902 else if (STRING_MULTIBYTE (it->string))
3904 int remaining = (STRING_BYTES (XSTRING (it->string))
3905 - IT_STRING_BYTEPOS (*it));
3906 unsigned char *s = (XSTRING (it->string)->data
3907 + IT_STRING_BYTEPOS (*it));
3908 it->c = string_char_and_length (s, remaining, &it->len);
3910 else
3912 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
3913 it->len = 1;
3916 else
3918 /* Get the next character from a Lisp string that is not an
3919 overlay string. Such strings come from the mode line, for
3920 example. We may have to pad with spaces, or truncate the
3921 string. See also next_element_from_c_string. */
3922 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
3924 it->what = IT_EOB;
3925 return 0;
3927 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
3929 /* Pad with spaces. */
3930 it->c = ' ', it->len = 1;
3931 CHARPOS (position) = BYTEPOS (position) = -1;
3933 else if (STRING_MULTIBYTE (it->string))
3935 int maxlen = (STRING_BYTES (XSTRING (it->string))
3936 - IT_STRING_BYTEPOS (*it));
3937 unsigned char *s = (XSTRING (it->string)->data
3938 + IT_STRING_BYTEPOS (*it));
3939 it->c = string_char_and_length (s, maxlen, &it->len);
3941 else
3943 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
3944 it->len = 1;
3948 /* Record what we have and where it came from. Note that we store a
3949 buffer position in IT->position although it could arguably be a
3950 string position. */
3951 it->what = IT_CHARACTER;
3952 it->object = it->string;
3953 it->position = position;
3954 return 1;
3958 /* Load IT with next display element from C string IT->s.
3959 IT->string_nchars is the maximum number of characters to return
3960 from the string. IT->end_charpos may be greater than
3961 IT->string_nchars when this function is called, in which case we
3962 may have to return padding spaces. Value is zero if end of string
3963 reached, including padding spaces. */
3965 static int
3966 next_element_from_c_string (it)
3967 struct it *it;
3969 int success_p = 1;
3971 xassert (it->s);
3972 it->what = IT_CHARACTER;
3973 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
3974 it->object = Qnil;
3976 /* IT's position can be greater IT->string_nchars in case a field
3977 width or precision has been specified when the iterator was
3978 initialized. */
3979 if (IT_CHARPOS (*it) >= it->end_charpos)
3981 /* End of the game. */
3982 it->what = IT_EOB;
3983 success_p = 0;
3985 else if (IT_CHARPOS (*it) >= it->string_nchars)
3987 /* Pad with spaces. */
3988 it->c = ' ', it->len = 1;
3989 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
3991 else if (it->multibyte_p)
3993 /* Implementation note: The calls to strlen apparently aren't a
3994 performance problem because there is no noticeable performance
3995 difference between Emacs running in unibyte or multibyte mode. */
3996 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
3997 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
3998 maxlen, &it->len);
4000 else
4001 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
4003 return success_p;
4007 /* Set up IT to return characters from an ellipsis, if appropriate.
4008 The definition of the ellipsis glyphs may come from a display table
4009 entry. This function Fills IT with the first glyph from the
4010 ellipsis if an ellipsis is to be displayed. */
4012 static int
4013 next_element_from_ellipsis (it)
4014 struct it *it;
4016 if (it->selective_display_ellipsis_p)
4018 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4020 /* Use the display table definition for `...'. Invalid glyphs
4021 will be handled by the method returning elements from dpvec. */
4022 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4023 it->dpvec_char_len = it->len;
4024 it->dpvec = v->contents;
4025 it->dpend = v->contents + v->size;
4026 it->current.dpvec_index = 0;
4027 it->method = next_element_from_display_vector;
4029 else
4031 /* Use default `...' which is stored in default_invis_vector. */
4032 it->dpvec_char_len = it->len;
4033 it->dpvec = default_invis_vector;
4034 it->dpend = default_invis_vector + 3;
4035 it->current.dpvec_index = 0;
4036 it->method = next_element_from_display_vector;
4039 else
4040 reseat_at_next_visible_line_start (it, 1);
4042 return get_next_display_element (it);
4046 /* Deliver an image display element. The iterator IT is already
4047 filled with image information (done in handle_display_prop). Value
4048 is always 1. */
4051 static int
4052 next_element_from_image (it)
4053 struct it *it;
4055 it->what = IT_IMAGE;
4056 return 1;
4060 /* Fill iterator IT with next display element from a stretch glyph
4061 property. IT->object is the value of the text property. Value is
4062 always 1. */
4064 static int
4065 next_element_from_stretch (it)
4066 struct it *it;
4068 it->what = IT_STRETCH;
4069 return 1;
4073 /* Load IT with the next display element from current_buffer. Value
4074 is zero if end of buffer reached. IT->stop_charpos is the next
4075 position at which to stop and check for text properties or buffer
4076 end. */
4078 static int
4079 next_element_from_buffer (it)
4080 struct it *it;
4082 int success_p = 1;
4084 /* Check this assumption, otherwise, we would never enter the
4085 if-statement, below. */
4086 xassert (IT_CHARPOS (*it) >= BEGV
4087 && IT_CHARPOS (*it) <= it->stop_charpos);
4089 if (IT_CHARPOS (*it) >= it->stop_charpos)
4091 if (IT_CHARPOS (*it) >= it->end_charpos)
4093 int overlay_strings_follow_p;
4095 /* End of the game, except when overlay strings follow that
4096 haven't been returned yet. */
4097 if (it->overlay_strings_at_end_processed_p)
4098 overlay_strings_follow_p = 0;
4099 else
4101 it->overlay_strings_at_end_processed_p = 1;
4102 overlay_strings_follow_p = get_overlay_strings (it);
4105 if (overlay_strings_follow_p)
4106 success_p = get_next_display_element (it);
4107 else
4109 it->what = IT_EOB;
4110 it->position = it->current.pos;
4111 success_p = 0;
4114 else
4116 handle_stop (it);
4117 return get_next_display_element (it);
4120 else
4122 /* No face changes, overlays etc. in sight, so just return a
4123 character from current_buffer. */
4124 unsigned char *p;
4126 /* Maybe run the redisplay end trigger hook. Performance note:
4127 This doesn't seem to cost measurable time. */
4128 if (it->redisplay_end_trigger_charpos
4129 && it->glyph_row
4130 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
4131 run_redisplay_end_trigger_hook (it);
4133 /* Get the next character, maybe multibyte. */
4134 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
4135 if (it->multibyte_p && !ASCII_BYTE_P (*p))
4137 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
4138 - IT_BYTEPOS (*it));
4139 it->c = string_char_and_length (p, maxlen, &it->len);
4141 else
4142 it->c = *p, it->len = 1;
4144 /* Record what we have and where it came from. */
4145 it->what = IT_CHARACTER;;
4146 it->object = it->w->buffer;
4147 it->position = it->current.pos;
4149 /* Normally we return the character found above, except when we
4150 really want to return an ellipsis for selective display. */
4151 if (it->selective)
4153 if (it->c == '\n')
4155 /* A value of selective > 0 means hide lines indented more
4156 than that number of columns. */
4157 if (it->selective > 0
4158 && IT_CHARPOS (*it) + 1 < ZV
4159 && indented_beyond_p (IT_CHARPOS (*it) + 1,
4160 IT_BYTEPOS (*it) + 1,
4161 it->selective))
4163 success_p = next_element_from_ellipsis (it);
4164 it->dpvec_char_len = -1;
4167 else if (it->c == '\r' && it->selective == -1)
4169 /* A value of selective == -1 means that everything from the
4170 CR to the end of the line is invisible, with maybe an
4171 ellipsis displayed for it. */
4172 success_p = next_element_from_ellipsis (it);
4173 it->dpvec_char_len = -1;
4178 /* Value is zero if end of buffer reached. */
4179 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
4180 return success_p;
4184 /* Run the redisplay end trigger hook for IT. */
4186 static void
4187 run_redisplay_end_trigger_hook (it)
4188 struct it *it;
4190 Lisp_Object args[3];
4192 /* IT->glyph_row should be non-null, i.e. we should be actually
4193 displaying something, or otherwise we should not run the hook. */
4194 xassert (it->glyph_row);
4196 /* Set up hook arguments. */
4197 args[0] = Qredisplay_end_trigger_functions;
4198 args[1] = it->window;
4199 XSETINT (args[2], it->redisplay_end_trigger_charpos);
4200 it->redisplay_end_trigger_charpos = 0;
4202 /* Since we are *trying* to run these functions, don't try to run
4203 them again, even if they get an error. */
4204 it->w->redisplay_end_trigger = Qnil;
4205 Frun_hook_with_args (3, args);
4207 /* Notice if it changed the face of the character we are on. */
4208 handle_face_prop (it);
4212 /* Deliver a composition display element. The iterator IT is already
4213 filled with composition information (done in
4214 handle_composition_prop). Value is always 1. */
4216 static int
4217 next_element_from_composition (it)
4218 struct it *it;
4220 it->what = IT_COMPOSITION;
4221 it->position = (STRINGP (it->string)
4222 ? it->current.string_pos
4223 : it->current.pos);
4224 return 1;
4229 /***********************************************************************
4230 Moving an iterator without producing glyphs
4231 ***********************************************************************/
4233 /* Move iterator IT to a specified buffer or X position within one
4234 line on the display without producing glyphs.
4236 Begin to skip at IT's current position. Skip to TO_CHARPOS or TO_X
4237 whichever is reached first.
4239 TO_CHARPOS <= 0 means no TO_CHARPOS is specified.
4241 TO_X < 0 means that no TO_X is specified. TO_X is normally a value
4242 0 <= TO_X <= IT->last_visible_x. This means in particular, that
4243 TO_X includes the amount by which a window is horizontally
4244 scrolled.
4246 Value is
4248 MOVE_POS_MATCH_OR_ZV
4249 - when TO_POS or ZV was reached.
4251 MOVE_X_REACHED
4252 -when TO_X was reached before TO_POS or ZV were reached.
4254 MOVE_LINE_CONTINUED
4255 - when we reached the end of the display area and the line must
4256 be continued.
4258 MOVE_LINE_TRUNCATED
4259 - when we reached the end of the display area and the line is
4260 truncated.
4262 MOVE_NEWLINE_OR_CR
4263 - when we stopped at a line end, i.e. a newline or a CR and selective
4264 display is on. */
4266 static enum move_it_result
4267 move_it_in_display_line_to (it, to_charpos, to_x, op)
4268 struct it *it;
4269 int to_charpos, to_x, op;
4271 enum move_it_result result = MOVE_UNDEFINED;
4272 struct glyph_row *saved_glyph_row;
4274 /* Don't produce glyphs in produce_glyphs. */
4275 saved_glyph_row = it->glyph_row;
4276 it->glyph_row = NULL;
4278 while (1)
4280 int x, i, ascent, descent;
4282 /* Stop when ZV or TO_CHARPOS reached. */
4283 if (!get_next_display_element (it)
4284 || ((op & MOVE_TO_POS) != 0
4285 && BUFFERP (it->object)
4286 && IT_CHARPOS (*it) >= to_charpos))
4288 result = MOVE_POS_MATCH_OR_ZV;
4289 break;
4292 /* The call to produce_glyphs will get the metrics of the
4293 display element IT is loaded with. We record in x the
4294 x-position before this display element in case it does not
4295 fit on the line. */
4296 x = it->current_x;
4298 /* Remember the line height so far in case the next element doesn't
4299 fit on the line. */
4300 if (!it->truncate_lines_p)
4302 ascent = it->max_ascent;
4303 descent = it->max_descent;
4306 PRODUCE_GLYPHS (it);
4308 if (it->area != TEXT_AREA)
4310 set_iterator_to_next (it);
4311 continue;
4314 /* The number of glyphs we get back in IT->nglyphs will normally
4315 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
4316 character on a terminal frame, or (iii) a line end. For the
4317 second case, IT->nglyphs - 1 padding glyphs will be present
4318 (on X frames, there is only one glyph produced for a
4319 composite character.
4321 The behavior implemented below means, for continuation lines,
4322 that as many spaces of a TAB as fit on the current line are
4323 displayed there. For terminal frames, as many glyphs of a
4324 multi-glyph character are displayed in the current line, too.
4325 This is what the old redisplay code did, and we keep it that
4326 way. Under X, the whole shape of a complex character must
4327 fit on the line or it will be completely displayed in the
4328 next line.
4330 Note that both for tabs and padding glyphs, all glyphs have
4331 the same width. */
4332 if (it->nglyphs)
4334 /* More than one glyph or glyph doesn't fit on line. All
4335 glyphs have the same width. */
4336 int single_glyph_width = it->pixel_width / it->nglyphs;
4337 int new_x;
4339 for (i = 0; i < it->nglyphs; ++i, x = new_x)
4341 new_x = x + single_glyph_width;
4343 /* We want to leave anything reaching TO_X to the caller. */
4344 if ((op & MOVE_TO_X) && new_x > to_x)
4346 it->current_x = x;
4347 result = MOVE_X_REACHED;
4348 break;
4350 else if (/* Lines are continued. */
4351 !it->truncate_lines_p
4352 && (/* And glyph doesn't fit on the line. */
4353 new_x > it->last_visible_x
4354 /* Or it fits exactly and we're on a window
4355 system frame. */
4356 || (new_x == it->last_visible_x
4357 && FRAME_WINDOW_P (it->f))))
4359 if (/* IT->hpos == 0 means the very first glyph
4360 doesn't fit on the line, e.g. a wide image. */
4361 it->hpos == 0
4362 || (new_x == it->last_visible_x
4363 && FRAME_WINDOW_P (it->f)))
4365 ++it->hpos;
4366 it->current_x = new_x;
4367 if (i == it->nglyphs - 1)
4368 set_iterator_to_next (it);
4370 else
4372 it->current_x = x;
4373 it->max_ascent = ascent;
4374 it->max_descent = descent;
4377 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
4378 IT_CHARPOS (*it)));
4379 result = MOVE_LINE_CONTINUED;
4380 break;
4382 else if (new_x > it->first_visible_x)
4384 /* Glyph is visible. Increment number of glyphs that
4385 would be displayed. */
4386 ++it->hpos;
4388 else
4390 /* Glyph is completely off the left margin of the display
4391 area. Nothing to do. */
4395 if (result != MOVE_UNDEFINED)
4396 break;
4398 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
4400 /* Stop when TO_X specified and reached. This check is
4401 necessary here because of lines consisting of a line end,
4402 only. The line end will not produce any glyphs and we
4403 would never get MOVE_X_REACHED. */
4404 xassert (it->nglyphs == 0);
4405 result = MOVE_X_REACHED;
4406 break;
4409 /* Is this a line end? If yes, we're done. */
4410 if (ITERATOR_AT_END_OF_LINE_P (it))
4412 result = MOVE_NEWLINE_OR_CR;
4413 break;
4416 /* The current display element has been consumed. Advance
4417 to the next. */
4418 set_iterator_to_next (it);
4420 /* Stop if lines are truncated and IT's current x-position is
4421 past the right edge of the window now. */
4422 if (it->truncate_lines_p
4423 && it->current_x >= it->last_visible_x)
4425 result = MOVE_LINE_TRUNCATED;
4426 break;
4430 /* Restore the iterator settings altered at the beginning of this
4431 function. */
4432 it->glyph_row = saved_glyph_row;
4433 return result;
4437 /* Move IT forward to a specified buffer position TO_CHARPOS, TO_X,
4438 TO_Y, TO_VPOS. OP is a bit-mask that specifies where to stop. See
4439 the description of enum move_operation_enum.
4441 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
4442 screen line, this function will set IT to the next position >
4443 TO_CHARPOS. */
4445 void
4446 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
4447 struct it *it;
4448 int to_charpos, to_x, to_y, to_vpos;
4449 int op;
4451 enum move_it_result skip, skip2 = MOVE_X_REACHED;
4452 int line_height;
4453 int reached = 0;
4455 for (;;)
4457 if (op & MOVE_TO_VPOS)
4459 /* If no TO_CHARPOS and no TO_X specified, stop at the
4460 start of the line TO_VPOS. */
4461 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
4463 if (it->vpos == to_vpos)
4465 reached = 1;
4466 break;
4468 else
4469 skip = move_it_in_display_line_to (it, -1, -1, 0);
4471 else
4473 /* TO_VPOS >= 0 means stop at TO_X in the line at
4474 TO_VPOS, or at TO_POS, whichever comes first. */
4475 if (it->vpos == to_vpos)
4477 reached = 2;
4478 break;
4481 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
4483 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
4485 reached = 3;
4486 break;
4488 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
4490 /* We have reached TO_X but not in the line we want. */
4491 skip = move_it_in_display_line_to (it, to_charpos,
4492 -1, MOVE_TO_POS);
4493 if (skip == MOVE_POS_MATCH_OR_ZV)
4495 reached = 4;
4496 break;
4501 else if (op & MOVE_TO_Y)
4503 struct it it_backup;
4505 /* TO_Y specified means stop at TO_X in the line containing
4506 TO_Y---or at TO_CHARPOS if this is reached first. The
4507 problem is that we can't really tell whether the line
4508 contains TO_Y before we have completely scanned it, and
4509 this may skip past TO_X. What we do is to first scan to
4510 TO_X.
4512 If TO_X is not specified, use a TO_X of zero. The reason
4513 is to make the outcome of this function more predictable.
4514 If we didn't use TO_X == 0, we would stop at the end of
4515 the line which is probably not what a caller would expect
4516 to happen. */
4517 skip = move_it_in_display_line_to (it, to_charpos,
4518 ((op & MOVE_TO_X)
4519 ? to_x : 0),
4520 (MOVE_TO_X
4521 | (op & MOVE_TO_POS)));
4523 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
4524 if (skip == MOVE_POS_MATCH_OR_ZV)
4526 reached = 5;
4527 break;
4530 /* If TO_X was reached, we would like to know whether TO_Y
4531 is in the line. This can only be said if we know the
4532 total line height which requires us to scan the rest of
4533 the line. */
4534 if (skip == MOVE_X_REACHED)
4536 it_backup = *it;
4537 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
4538 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
4539 op & MOVE_TO_POS);
4540 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
4543 /* Now, decide whether TO_Y is in this line. */
4544 line_height = it->max_ascent + it->max_descent;
4545 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
4547 if (to_y >= it->current_y
4548 && to_y < it->current_y + line_height)
4550 if (skip == MOVE_X_REACHED)
4551 /* If TO_Y is in this line and TO_X was reached above,
4552 we scanned too far. We have to restore IT's settings
4553 to the ones before skipping. */
4554 *it = it_backup;
4555 reached = 6;
4557 else if (skip == MOVE_X_REACHED)
4559 skip = skip2;
4560 if (skip == MOVE_POS_MATCH_OR_ZV)
4561 reached = 7;
4564 if (reached)
4565 break;
4567 else
4568 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
4570 switch (skip)
4572 case MOVE_POS_MATCH_OR_ZV:
4573 reached = 8;
4574 goto out;
4576 case MOVE_NEWLINE_OR_CR:
4577 set_iterator_to_next (it);
4578 it->continuation_lines_width = 0;
4579 break;
4581 case MOVE_LINE_TRUNCATED:
4582 it->continuation_lines_width = 0;
4583 reseat_at_next_visible_line_start (it, 0);
4584 if ((op & MOVE_TO_POS) != 0
4585 && IT_CHARPOS (*it) > to_charpos)
4587 reached = 9;
4588 goto out;
4590 break;
4592 case MOVE_LINE_CONTINUED:
4593 it->continuation_lines_width += it->current_x;
4594 break;
4596 default:
4597 abort ();
4600 /* Reset/increment for the next run. */
4601 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
4602 it->current_x = it->hpos = 0;
4603 it->current_y += it->max_ascent + it->max_descent;
4604 ++it->vpos;
4605 last_height = it->max_ascent + it->max_descent;
4606 last_max_ascent = it->max_ascent;
4607 it->max_ascent = it->max_descent = 0;
4610 out:
4612 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
4616 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
4618 If DY > 0, move IT backward at least that many pixels. DY = 0
4619 means move IT backward to the preceding line start or BEGV. This
4620 function may move over more than DY pixels if IT->current_y - DY
4621 ends up in the middle of a line; in this case IT->current_y will be
4622 set to the top of the line moved to. */
4624 void
4625 move_it_vertically_backward (it, dy)
4626 struct it *it;
4627 int dy;
4629 int nlines, h, line_height;
4630 struct it it2;
4631 int start_pos = IT_CHARPOS (*it);
4633 xassert (dy >= 0);
4635 /* Estimate how many newlines we must move back. */
4636 nlines = max (1, dy / CANON_Y_UNIT (it->f));
4638 /* Set the iterator's position that many lines back. */
4639 while (nlines-- && IT_CHARPOS (*it) > BEGV)
4640 back_to_previous_visible_line_start (it);
4642 /* Reseat the iterator here. When moving backward, we don't want
4643 reseat to skip forward over invisible text, set up the iterator
4644 to deliver from overlay strings at the new position etc. So,
4645 use reseat_1 here. */
4646 reseat_1 (it, it->current.pos, 1);
4648 /* We are now surely at a line start. */
4649 it->current_x = it->hpos = 0;
4651 /* Move forward and see what y-distance we moved. First move to the
4652 start of the next line so that we get its height. We need this
4653 height to be able to tell whether we reached the specified
4654 y-distance. */
4655 it2 = *it;
4656 it2.max_ascent = it2.max_descent = 0;
4657 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
4658 MOVE_TO_POS | MOVE_TO_VPOS);
4659 xassert (IT_CHARPOS (*it) >= BEGV);
4660 line_height = it2.max_ascent + it2.max_descent;
4662 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
4663 xassert (IT_CHARPOS (*it) >= BEGV);
4664 h = it2.current_y - it->current_y;
4665 nlines = it2.vpos - it->vpos;
4667 /* Correct IT's y and vpos position. */
4668 it->vpos -= nlines;
4669 it->current_y -= h;
4671 if (dy == 0)
4673 /* DY == 0 means move to the start of the screen line. The
4674 value of nlines is > 0 if continuation lines were involved. */
4675 if (nlines > 0)
4676 move_it_by_lines (it, nlines, 1);
4677 xassert (IT_CHARPOS (*it) <= start_pos);
4679 else if (nlines)
4681 /* The y-position we try to reach. Note that h has been
4682 subtracted in front of the if-statement. */
4683 int target_y = it->current_y + h - dy;
4685 /* If we did not reach target_y, try to move further backward if
4686 we can. If we moved too far backward, try to move forward. */
4687 if (target_y < it->current_y
4688 && IT_CHARPOS (*it) > BEGV)
4690 move_it_vertically (it, target_y - it->current_y);
4691 xassert (IT_CHARPOS (*it) >= BEGV);
4693 else if (target_y >= it->current_y + line_height
4694 && IT_CHARPOS (*it) < ZV)
4696 move_it_vertically (it, target_y - (it->current_y + line_height));
4697 xassert (IT_CHARPOS (*it) >= BEGV);
4703 /* Move IT by a specified amount of pixel lines DY. DY negative means
4704 move backwards. DY = 0 means move to start of screen line. At the
4705 end, IT will be on the start of a screen line. */
4707 void
4708 move_it_vertically (it, dy)
4709 struct it *it;
4710 int dy;
4712 if (dy <= 0)
4713 move_it_vertically_backward (it, -dy);
4714 else if (dy > 0)
4716 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
4717 move_it_to (it, ZV, -1, it->current_y + dy, -1,
4718 MOVE_TO_POS | MOVE_TO_Y);
4719 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
4721 /* If buffer ends in ZV without a newline, move to the start of
4722 the line to satisfy the post-condition. */
4723 if (IT_CHARPOS (*it) == ZV
4724 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
4725 move_it_by_lines (it, 0, 0);
4730 /* Return non-zero if some text between buffer positions START_CHARPOS
4731 and END_CHARPOS is invisible. IT->window is the window for text
4732 property lookup. */
4734 static int
4735 invisible_text_between_p (it, start_charpos, end_charpos)
4736 struct it *it;
4737 int start_charpos, end_charpos;
4739 Lisp_Object prop, limit;
4740 int invisible_found_p;
4742 xassert (it != NULL && start_charpos <= end_charpos);
4744 /* Is text at START invisible? */
4745 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
4746 it->window);
4747 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4748 invisible_found_p = 1;
4749 else
4751 limit = Fnext_single_char_property_change (make_number (start_charpos),
4752 Qinvisible, Qnil,
4753 make_number (end_charpos));
4754 invisible_found_p = XFASTINT (limit) < end_charpos;
4757 return invisible_found_p;
4761 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
4762 negative means move up. DVPOS == 0 means move to the start of the
4763 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
4764 NEED_Y_P is zero, IT->current_y will be left unchanged.
4766 Further optimization ideas: If we would know that IT->f doesn't use
4767 a face with proportional font, we could be faster for
4768 truncate-lines nil. */
4770 void
4771 move_it_by_lines (it, dvpos, need_y_p)
4772 struct it *it;
4773 int dvpos, need_y_p;
4775 struct position pos;
4777 if (!FRAME_WINDOW_P (it->f))
4779 struct text_pos textpos;
4781 /* We can use vmotion on frames without proportional fonts. */
4782 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
4783 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
4784 reseat (it, textpos, 1);
4785 it->vpos += pos.vpos;
4786 it->current_y += pos.vpos;
4788 else if (dvpos == 0)
4790 /* DVPOS == 0 means move to the start of the screen line. */
4791 move_it_vertically_backward (it, 0);
4792 xassert (it->current_x == 0 && it->hpos == 0);
4794 else if (dvpos > 0)
4796 /* If there are no continuation lines, and if there is no
4797 selective display, try the simple method of moving forward
4798 DVPOS newlines, then see where we are. */
4799 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
4801 int shortage = 0, charpos;
4803 if (FETCH_BYTE (IT_BYTEPOS (*it) == '\n'))
4804 charpos = IT_CHARPOS (*it) + 1;
4805 else
4806 charpos = scan_buffer ('\n', IT_CHARPOS (*it), 0, dvpos,
4807 &shortage, 0);
4809 if (!invisible_text_between_p (it, IT_CHARPOS (*it), charpos))
4811 struct text_pos pos;
4812 CHARPOS (pos) = charpos;
4813 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
4814 reseat (it, pos, 1);
4815 it->vpos += dvpos - shortage;
4816 it->hpos = it->current_x = 0;
4817 return;
4821 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
4823 else
4825 struct it it2;
4826 int start_charpos, i;
4828 /* If there are no continuation lines, and if there is no
4829 selective display, try the simple method of moving backward
4830 -DVPOS newlines. */
4831 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
4833 int shortage;
4834 int charpos = IT_CHARPOS (*it);
4835 int bytepos = IT_BYTEPOS (*it);
4837 /* If in the middle of a line, go to its start. */
4838 if (charpos > BEGV && FETCH_BYTE (bytepos - 1) != '\n')
4840 charpos = find_next_newline_no_quit (charpos, -1);
4841 bytepos = CHAR_TO_BYTE (charpos);
4844 if (charpos == BEGV)
4846 struct text_pos pos;
4847 CHARPOS (pos) = charpos;
4848 BYTEPOS (pos) = bytepos;
4849 reseat (it, pos, 1);
4850 it->hpos = it->current_x = 0;
4851 return;
4853 else
4855 charpos = scan_buffer ('\n', charpos - 1, 0, dvpos, &shortage, 0);
4856 if (!invisible_text_between_p (it, charpos, IT_CHARPOS (*it)))
4858 struct text_pos pos;
4859 CHARPOS (pos) = charpos;
4860 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
4861 reseat (it, pos, 1);
4862 it->vpos += dvpos + (shortage ? shortage - 1 : 0);
4863 it->hpos = it->current_x = 0;
4864 return;
4869 /* Go back -DVPOS visible lines and reseat the iterator there. */
4870 start_charpos = IT_CHARPOS (*it);
4871 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
4872 back_to_previous_visible_line_start (it);
4873 reseat (it, it->current.pos, 1);
4874 it->current_x = it->hpos = 0;
4876 /* Above call may have moved too far if continuation lines
4877 are involved. Scan forward and see if it did. */
4878 it2 = *it;
4879 it2.vpos = it2.current_y = 0;
4880 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
4881 it->vpos -= it2.vpos;
4882 it->current_y -= it2.current_y;
4883 it->current_x = it->hpos = 0;
4885 /* If we moved too far, move IT some lines forward. */
4886 if (it2.vpos > -dvpos)
4888 int delta = it2.vpos + dvpos;
4889 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
4896 /***********************************************************************
4897 Messages
4898 ***********************************************************************/
4901 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
4902 to *Messages*. */
4904 void
4905 add_to_log (format, arg1, arg2)
4906 char *format;
4907 Lisp_Object arg1, arg2;
4909 Lisp_Object args[3];
4910 Lisp_Object msg, fmt;
4911 char *buffer;
4912 int len;
4913 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4915 fmt = msg = Qnil;
4916 GCPRO4 (fmt, msg, arg1, arg2);
4918 args[0] = fmt = build_string (format);
4919 args[1] = arg1;
4920 args[2] = arg2;
4921 msg = Fformat (3, args);
4923 len = STRING_BYTES (XSTRING (msg)) + 1;
4924 buffer = (char *) alloca (len);
4925 strcpy (buffer, XSTRING (msg)->data);
4927 message_dolog (buffer, len - 1, 1, 0);
4928 UNGCPRO;
4932 /* Output a newline in the *Messages* buffer if "needs" one. */
4934 void
4935 message_log_maybe_newline ()
4937 if (message_log_need_newline)
4938 message_dolog ("", 0, 1, 0);
4942 /* Add a string M of length LEN to the message log, optionally
4943 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
4944 nonzero, means interpret the contents of M as multibyte. This
4945 function calls low-level routines in order to bypass text property
4946 hooks, etc. which might not be safe to run. */
4948 void
4949 message_dolog (m, len, nlflag, multibyte)
4950 char *m;
4951 int len, nlflag, multibyte;
4953 if (!NILP (Vmessage_log_max))
4955 struct buffer *oldbuf;
4956 Lisp_Object oldpoint, oldbegv, oldzv;
4957 int old_windows_or_buffers_changed = windows_or_buffers_changed;
4958 int point_at_end = 0;
4959 int zv_at_end = 0;
4960 Lisp_Object old_deactivate_mark, tem;
4961 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4963 old_deactivate_mark = Vdeactivate_mark;
4964 oldbuf = current_buffer;
4965 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
4966 current_buffer->undo_list = Qt;
4968 oldpoint = Fpoint_marker ();
4969 oldbegv = Fpoint_min_marker ();
4970 oldzv = Fpoint_max_marker ();
4971 GCPRO4 (oldpoint, oldbegv, oldzv, old_deactivate_mark);
4973 if (PT == Z)
4974 point_at_end = 1;
4975 if (ZV == Z)
4976 zv_at_end = 1;
4978 BEGV = BEG;
4979 BEGV_BYTE = BEG_BYTE;
4980 ZV = Z;
4981 ZV_BYTE = Z_BYTE;
4982 TEMP_SET_PT_BOTH (Z, Z_BYTE);
4984 /* Insert the string--maybe converting multibyte to single byte
4985 or vice versa, so that all the text fits the buffer. */
4986 if (multibyte
4987 && NILP (current_buffer->enable_multibyte_characters))
4989 int i, c, nbytes;
4990 unsigned char work[1];
4992 /* Convert a multibyte string to single-byte
4993 for the *Message* buffer. */
4994 for (i = 0; i < len; i += nbytes)
4996 c = string_char_and_length (m + i, len - i, &nbytes);
4997 work[0] = (SINGLE_BYTE_CHAR_P (c)
4999 : multibyte_char_to_unibyte (c, Qnil));
5000 insert_1_both (work, 1, 1, 1, 0, 0);
5003 else if (! multibyte
5004 && ! NILP (current_buffer->enable_multibyte_characters))
5006 int i, c, nbytes;
5007 unsigned char *msg = (unsigned char *) m;
5008 unsigned char str[MAX_MULTIBYTE_LENGTH];
5009 /* Convert a single-byte string to multibyte
5010 for the *Message* buffer. */
5011 for (i = 0; i < len; i++)
5013 c = unibyte_char_to_multibyte (msg[i]);
5014 nbytes = CHAR_STRING (c, str);
5015 insert_1_both (str, 1, nbytes, 1, 0, 0);
5018 else if (len)
5019 insert_1 (m, len, 1, 0, 0);
5021 if (nlflag)
5023 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
5024 insert_1 ("\n", 1, 1, 0, 0);
5026 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
5027 this_bol = PT;
5028 this_bol_byte = PT_BYTE;
5030 if (this_bol > BEG)
5032 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
5033 prev_bol = PT;
5034 prev_bol_byte = PT_BYTE;
5036 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
5037 this_bol, this_bol_byte);
5038 if (dup)
5040 del_range_both (prev_bol, prev_bol_byte,
5041 this_bol, this_bol_byte, 0);
5042 if (dup > 1)
5044 char dupstr[40];
5045 int duplen;
5047 /* If you change this format, don't forget to also
5048 change message_log_check_duplicate. */
5049 sprintf (dupstr, " [%d times]", dup);
5050 duplen = strlen (dupstr);
5051 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
5052 insert_1 (dupstr, duplen, 1, 0, 1);
5057 if (NATNUMP (Vmessage_log_max))
5059 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
5060 -XFASTINT (Vmessage_log_max) - 1, 0);
5061 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
5064 BEGV = XMARKER (oldbegv)->charpos;
5065 BEGV_BYTE = marker_byte_position (oldbegv);
5067 if (zv_at_end)
5069 ZV = Z;
5070 ZV_BYTE = Z_BYTE;
5072 else
5074 ZV = XMARKER (oldzv)->charpos;
5075 ZV_BYTE = marker_byte_position (oldzv);
5078 if (point_at_end)
5079 TEMP_SET_PT_BOTH (Z, Z_BYTE);
5080 else
5081 /* We can't do Fgoto_char (oldpoint) because it will run some
5082 Lisp code. */
5083 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
5084 XMARKER (oldpoint)->bytepos);
5086 UNGCPRO;
5087 free_marker (oldpoint);
5088 free_marker (oldbegv);
5089 free_marker (oldzv);
5091 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
5092 set_buffer_internal (oldbuf);
5093 if (NILP (tem))
5094 windows_or_buffers_changed = old_windows_or_buffers_changed;
5095 message_log_need_newline = !nlflag;
5096 Vdeactivate_mark = old_deactivate_mark;
5101 /* We are at the end of the buffer after just having inserted a newline.
5102 (Note: We depend on the fact we won't be crossing the gap.)
5103 Check to see if the most recent message looks a lot like the previous one.
5104 Return 0 if different, 1 if the new one should just replace it, or a
5105 value N > 1 if we should also append " [N times]". */
5107 static int
5108 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
5109 int prev_bol, this_bol;
5110 int prev_bol_byte, this_bol_byte;
5112 int i;
5113 int len = Z_BYTE - 1 - this_bol_byte;
5114 int seen_dots = 0;
5115 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
5116 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
5118 for (i = 0; i < len; i++)
5120 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.'
5121 && p1[i] != '\n')
5122 seen_dots = 1;
5123 if (p1[i] != p2[i])
5124 return seen_dots;
5126 p1 += len;
5127 if (*p1 == '\n')
5128 return 2;
5129 if (*p1++ == ' ' && *p1++ == '[')
5131 int n = 0;
5132 while (*p1 >= '0' && *p1 <= '9')
5133 n = n * 10 + *p1++ - '0';
5134 if (strncmp (p1, " times]\n", 8) == 0)
5135 return n+1;
5137 return 0;
5141 /* Display an echo area message M with a specified length of LEN
5142 chars. The string may include null characters. If M is 0, clear
5143 out any existing message, and let the mini-buffer text show through.
5145 The buffer M must continue to exist until after the echo area gets
5146 cleared or some other message gets displayed there. This means do
5147 not pass text that is stored in a Lisp string; do not pass text in
5148 a buffer that was alloca'd. */
5150 void
5151 message2 (m, len, multibyte)
5152 char *m;
5153 int len;
5154 int multibyte;
5156 /* First flush out any partial line written with print. */
5157 message_log_maybe_newline ();
5158 if (m)
5159 message_dolog (m, len, 1, multibyte);
5160 message2_nolog (m, len, multibyte);
5164 /* The non-logging counterpart of message2. */
5166 void
5167 message2_nolog (m, len, multibyte)
5168 char *m;
5169 int len;
5171 struct frame *sf = SELECTED_FRAME ();
5172 message_enable_multibyte = multibyte;
5174 if (noninteractive)
5176 if (noninteractive_need_newline)
5177 putc ('\n', stderr);
5178 noninteractive_need_newline = 0;
5179 if (m)
5180 fwrite (m, len, 1, stderr);
5181 if (cursor_in_echo_area == 0)
5182 fprintf (stderr, "\n");
5183 fflush (stderr);
5185 /* A null message buffer means that the frame hasn't really been
5186 initialized yet. Error messages get reported properly by
5187 cmd_error, so this must be just an informative message; toss it. */
5188 else if (INTERACTIVE
5189 && sf->glyphs_initialized_p
5190 && FRAME_MESSAGE_BUF (sf))
5192 Lisp_Object mini_window;
5193 struct frame *f;
5195 /* Get the frame containing the mini-buffer
5196 that the selected frame is using. */
5197 mini_window = FRAME_MINIBUF_WINDOW (sf);
5198 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5200 FRAME_SAMPLE_VISIBILITY (f);
5201 if (FRAME_VISIBLE_P (sf)
5202 && ! FRAME_VISIBLE_P (f))
5203 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
5205 if (m)
5207 set_message (m, Qnil, len, multibyte);
5208 if (minibuffer_auto_raise)
5209 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
5211 else
5212 clear_message (1, 1);
5214 do_pending_window_change (0);
5215 echo_area_display (1);
5216 do_pending_window_change (0);
5217 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
5218 (*frame_up_to_date_hook) (f);
5223 /* Display an echo area message M with a specified length of NBYTES
5224 bytes. The string may include null characters. If M is not a
5225 string, clear out any existing message, and let the mini-buffer
5226 text show through. */
5228 void
5229 message3 (m, nbytes, multibyte)
5230 Lisp_Object m;
5231 int nbytes;
5232 int multibyte;
5234 struct gcpro gcpro1;
5236 GCPRO1 (m);
5238 /* First flush out any partial line written with print. */
5239 message_log_maybe_newline ();
5240 if (STRINGP (m))
5241 message_dolog (XSTRING (m)->data, nbytes, 1, multibyte);
5242 message3_nolog (m, nbytes, multibyte);
5244 UNGCPRO;
5248 /* The non-logging version of message3. */
5250 void
5251 message3_nolog (m, nbytes, multibyte)
5252 Lisp_Object m;
5253 int nbytes, multibyte;
5255 struct frame *sf = SELECTED_FRAME ();
5256 message_enable_multibyte = multibyte;
5258 if (noninteractive)
5260 if (noninteractive_need_newline)
5261 putc ('\n', stderr);
5262 noninteractive_need_newline = 0;
5263 if (STRINGP (m))
5264 fwrite (XSTRING (m)->data, nbytes, 1, stderr);
5265 if (cursor_in_echo_area == 0)
5266 fprintf (stderr, "\n");
5267 fflush (stderr);
5269 /* A null message buffer means that the frame hasn't really been
5270 initialized yet. Error messages get reported properly by
5271 cmd_error, so this must be just an informative message; toss it. */
5272 else if (INTERACTIVE
5273 && sf->glyphs_initialized_p
5274 && FRAME_MESSAGE_BUF (sf))
5276 Lisp_Object mini_window;
5277 Lisp_Object frame;
5278 struct frame *f;
5280 /* Get the frame containing the mini-buffer
5281 that the selected frame is using. */
5282 mini_window = FRAME_MINIBUF_WINDOW (sf);
5283 frame = XWINDOW (mini_window)->frame;
5284 f = XFRAME (frame);
5286 FRAME_SAMPLE_VISIBILITY (f);
5287 if (FRAME_VISIBLE_P (sf)
5288 && !FRAME_VISIBLE_P (f))
5289 Fmake_frame_visible (frame);
5291 if (STRINGP (m) && XSTRING (m)->size)
5293 set_message (NULL, m, nbytes, multibyte);
5294 if (minibuffer_auto_raise)
5295 Fraise_frame (frame);
5297 else
5298 clear_message (1, 1);
5300 do_pending_window_change (0);
5301 echo_area_display (1);
5302 do_pending_window_change (0);
5303 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
5304 (*frame_up_to_date_hook) (f);
5309 /* Display a null-terminated echo area message M. If M is 0, clear
5310 out any existing message, and let the mini-buffer text show through.
5312 The buffer M must continue to exist until after the echo area gets
5313 cleared or some other message gets displayed there. Do not pass
5314 text that is stored in a Lisp string. Do not pass text in a buffer
5315 that was alloca'd. */
5317 void
5318 message1 (m)
5319 char *m;
5321 message2 (m, (m ? strlen (m) : 0), 0);
5325 /* The non-logging counterpart of message1. */
5327 void
5328 message1_nolog (m)
5329 char *m;
5331 message2_nolog (m, (m ? strlen (m) : 0), 0);
5334 /* Display a message M which contains a single %s
5335 which gets replaced with STRING. */
5337 void
5338 message_with_string (m, string, log)
5339 char *m;
5340 Lisp_Object string;
5341 int log;
5343 if (noninteractive)
5345 if (m)
5347 if (noninteractive_need_newline)
5348 putc ('\n', stderr);
5349 noninteractive_need_newline = 0;
5350 fprintf (stderr, m, XSTRING (string)->data);
5351 if (cursor_in_echo_area == 0)
5352 fprintf (stderr, "\n");
5353 fflush (stderr);
5356 else if (INTERACTIVE)
5358 /* The frame whose minibuffer we're going to display the message on.
5359 It may be larger than the selected frame, so we need
5360 to use its buffer, not the selected frame's buffer. */
5361 Lisp_Object mini_window;
5362 struct frame *f, *sf = SELECTED_FRAME ();
5364 /* Get the frame containing the minibuffer
5365 that the selected frame is using. */
5366 mini_window = FRAME_MINIBUF_WINDOW (sf);
5367 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5369 /* A null message buffer means that the frame hasn't really been
5370 initialized yet. Error messages get reported properly by
5371 cmd_error, so this must be just an informative message; toss it. */
5372 if (FRAME_MESSAGE_BUF (f))
5374 int len;
5375 char *a[1];
5376 a[0] = (char *) XSTRING (string)->data;
5378 len = doprnt (FRAME_MESSAGE_BUF (f),
5379 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5381 if (log)
5382 message2 (FRAME_MESSAGE_BUF (f), len,
5383 STRING_MULTIBYTE (string));
5384 else
5385 message2_nolog (FRAME_MESSAGE_BUF (f), len,
5386 STRING_MULTIBYTE (string));
5388 /* Print should start at the beginning of the message
5389 buffer next time. */
5390 message_buf_print = 0;
5396 /* Dump an informative message to the minibuf. If M is 0, clear out
5397 any existing message, and let the mini-buffer text show through. */
5399 /* VARARGS 1 */
5400 void
5401 message (m, a1, a2, a3)
5402 char *m;
5403 EMACS_INT a1, a2, a3;
5405 if (noninteractive)
5407 if (m)
5409 if (noninteractive_need_newline)
5410 putc ('\n', stderr);
5411 noninteractive_need_newline = 0;
5412 fprintf (stderr, m, a1, a2, a3);
5413 if (cursor_in_echo_area == 0)
5414 fprintf (stderr, "\n");
5415 fflush (stderr);
5418 else if (INTERACTIVE)
5420 /* The frame whose mini-buffer we're going to display the message
5421 on. It may be larger than the selected frame, so we need to
5422 use its buffer, not the selected frame's buffer. */
5423 Lisp_Object mini_window;
5424 struct frame *f, *sf = SELECTED_FRAME ();
5426 /* Get the frame containing the mini-buffer
5427 that the selected frame is using. */
5428 mini_window = FRAME_MINIBUF_WINDOW (sf);
5429 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5431 /* A null message buffer means that the frame hasn't really been
5432 initialized yet. Error messages get reported properly by
5433 cmd_error, so this must be just an informative message; toss
5434 it. */
5435 if (FRAME_MESSAGE_BUF (f))
5437 if (m)
5439 int len;
5440 #ifdef NO_ARG_ARRAY
5441 char *a[3];
5442 a[0] = (char *) a1;
5443 a[1] = (char *) a2;
5444 a[2] = (char *) a3;
5446 len = doprnt (FRAME_MESSAGE_BUF (f),
5447 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5448 #else
5449 len = doprnt (FRAME_MESSAGE_BUF (f),
5450 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
5451 (char **) &a1);
5452 #endif /* NO_ARG_ARRAY */
5454 message2 (FRAME_MESSAGE_BUF (f), len, 0);
5456 else
5457 message1 (0);
5459 /* Print should start at the beginning of the message
5460 buffer next time. */
5461 message_buf_print = 0;
5467 /* The non-logging version of message. */
5469 void
5470 message_nolog (m, a1, a2, a3)
5471 char *m;
5472 EMACS_INT a1, a2, a3;
5474 Lisp_Object old_log_max;
5475 old_log_max = Vmessage_log_max;
5476 Vmessage_log_max = Qnil;
5477 message (m, a1, a2, a3);
5478 Vmessage_log_max = old_log_max;
5482 /* Display the current message in the current mini-buffer. This is
5483 only called from error handlers in process.c, and is not time
5484 critical. */
5486 void
5487 update_echo_area ()
5489 if (!NILP (echo_area_buffer[0]))
5491 Lisp_Object string;
5492 string = Fcurrent_message ();
5493 message3 (string, XSTRING (string)->size,
5494 !NILP (current_buffer->enable_multibyte_characters));
5499 /* Make sure echo area buffers in echo_buffers[] are life. If they
5500 aren't, make new ones. */
5502 static void
5503 ensure_echo_area_buffers ()
5505 int i;
5507 for (i = 0; i < 2; ++i)
5508 if (!BUFFERP (echo_buffer[i])
5509 || NILP (XBUFFER (echo_buffer[i])->name))
5511 char name[30];
5512 Lisp_Object old_buffer;
5513 int j;
5515 old_buffer = echo_buffer[i];
5516 sprintf (name, " *Echo Area %d*", i);
5517 echo_buffer[i] = Fget_buffer_create (build_string (name));
5518 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
5520 for (j = 0; j < 2; ++j)
5521 if (EQ (old_buffer, echo_area_buffer[j]))
5522 echo_area_buffer[j] = echo_buffer[i];
5527 /* Call FN with args A1..A4 with either the current or last displayed
5528 echo_area_buffer as current buffer.
5530 WHICH zero means use the current message buffer
5531 echo_area_buffer[0]. If that is nil, choose a suitable buffer
5532 from echo_buffer[] and clear it.
5534 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
5535 suitable buffer from echo_buffer[] and clear it.
5537 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
5538 that the current message becomes the last displayed one, make
5539 choose a suitable buffer for echo_area_buffer[0], and clear it.
5541 Value is what FN returns. */
5543 static int
5544 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
5545 struct window *w;
5546 int which;
5547 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
5548 EMACS_INT a1;
5549 Lisp_Object a2;
5550 EMACS_INT a3, a4;
5552 Lisp_Object buffer;
5553 int this_one, the_other, clear_buffer_p, rc;
5554 int count = specpdl_ptr - specpdl;
5556 /* If buffers aren't life, make new ones. */
5557 ensure_echo_area_buffers ();
5559 clear_buffer_p = 0;
5561 if (which == 0)
5562 this_one = 0, the_other = 1;
5563 else if (which > 0)
5564 this_one = 1, the_other = 0;
5565 else
5567 this_one = 0, the_other = 1;
5568 clear_buffer_p = 1;
5570 /* We need a fresh one in case the current echo buffer equals
5571 the one containing the last displayed echo area message. */
5572 if (!NILP (echo_area_buffer[this_one])
5573 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
5574 echo_area_buffer[this_one] = Qnil;
5577 /* Choose a suitable buffer from echo_buffer[] is we don't
5578 have one. */
5579 if (NILP (echo_area_buffer[this_one]))
5581 echo_area_buffer[this_one]
5582 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
5583 ? echo_buffer[the_other]
5584 : echo_buffer[this_one]);
5585 clear_buffer_p = 1;
5588 buffer = echo_area_buffer[this_one];
5590 record_unwind_protect (unwind_with_echo_area_buffer,
5591 with_echo_area_buffer_unwind_data (w));
5593 /* Make the echo area buffer current. Note that for display
5594 purposes, it is not necessary that the displayed window's buffer
5595 == current_buffer, except for text property lookup. So, let's
5596 only set that buffer temporarily here without doing a full
5597 Fset_window_buffer. We must also change w->pointm, though,
5598 because otherwise an assertions in unshow_buffer fails, and Emacs
5599 aborts. */
5600 set_buffer_internal_1 (XBUFFER (buffer));
5601 if (w)
5603 w->buffer = buffer;
5604 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
5607 current_buffer->undo_list = Qt;
5608 current_buffer->read_only = Qnil;
5610 if (clear_buffer_p && Z > BEG)
5611 del_range (BEG, Z);
5613 xassert (BEGV >= BEG);
5614 xassert (ZV <= Z && ZV >= BEGV);
5616 rc = fn (a1, a2, a3, a4);
5618 xassert (BEGV >= BEG);
5619 xassert (ZV <= Z && ZV >= BEGV);
5621 unbind_to (count, Qnil);
5622 return rc;
5626 /* Save state that should be preserved around the call to the function
5627 FN called in with_echo_area_buffer. */
5629 static Lisp_Object
5630 with_echo_area_buffer_unwind_data (w)
5631 struct window *w;
5633 int i = 0;
5634 Lisp_Object vector;
5636 /* Reduce consing by keeping one vector in
5637 Vwith_echo_area_save_vector. */
5638 vector = Vwith_echo_area_save_vector;
5639 Vwith_echo_area_save_vector = Qnil;
5641 if (NILP (vector))
5642 vector = Fmake_vector (make_number (7), Qnil);
5644 XSETBUFFER (XVECTOR (vector)->contents[i], current_buffer); ++i;
5645 XVECTOR (vector)->contents[i++] = Vdeactivate_mark;
5646 XVECTOR (vector)->contents[i++] = make_number (windows_or_buffers_changed);
5648 if (w)
5650 XSETWINDOW (XVECTOR (vector)->contents[i], w); ++i;
5651 XVECTOR (vector)->contents[i++] = w->buffer;
5652 XVECTOR (vector)->contents[i++]
5653 = make_number (XMARKER (w->pointm)->charpos);
5654 XVECTOR (vector)->contents[i++]
5655 = make_number (XMARKER (w->pointm)->bytepos);
5657 else
5659 int end = i + 4;
5660 while (i < end)
5661 XVECTOR (vector)->contents[i++] = Qnil;
5664 xassert (i == XVECTOR (vector)->size);
5665 return vector;
5669 /* Restore global state from VECTOR which was created by
5670 with_echo_area_buffer_unwind_data. */
5672 static Lisp_Object
5673 unwind_with_echo_area_buffer (vector)
5674 Lisp_Object vector;
5676 int i = 0;
5678 set_buffer_internal_1 (XBUFFER (XVECTOR (vector)->contents[i])); ++i;
5679 Vdeactivate_mark = XVECTOR (vector)->contents[i]; ++i;
5680 windows_or_buffers_changed = XFASTINT (XVECTOR (vector)->contents[i]); ++i;
5682 if (WINDOWP (XVECTOR (vector)->contents[i]))
5684 struct window *w;
5685 Lisp_Object buffer, charpos, bytepos;
5687 w = XWINDOW (XVECTOR (vector)->contents[i]); ++i;
5688 buffer = XVECTOR (vector)->contents[i]; ++i;
5689 charpos = XVECTOR (vector)->contents[i]; ++i;
5690 bytepos = XVECTOR (vector)->contents[i]; ++i;
5692 w->buffer = buffer;
5693 set_marker_both (w->pointm, buffer,
5694 XFASTINT (charpos), XFASTINT (bytepos));
5697 Vwith_echo_area_save_vector = vector;
5698 return Qnil;
5702 /* Set up the echo area for use by print functions. MULTIBYTE_P
5703 non-zero means we will print multibyte. */
5705 void
5706 setup_echo_area_for_printing (multibyte_p)
5707 int multibyte_p;
5709 ensure_echo_area_buffers ();
5711 if (!message_buf_print)
5713 /* A message has been output since the last time we printed.
5714 Choose a fresh echo area buffer. */
5715 if (EQ (echo_area_buffer[1], echo_buffer[0]))
5716 echo_area_buffer[0] = echo_buffer[1];
5717 else
5718 echo_area_buffer[0] = echo_buffer[0];
5720 /* Switch to that buffer and clear it. */
5721 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
5722 if (Z > BEG)
5723 del_range (BEG, Z);
5724 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
5726 /* Set up the buffer for the multibyteness we need. */
5727 if (multibyte_p
5728 != !NILP (current_buffer->enable_multibyte_characters))
5729 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
5731 /* Raise the frame containing the echo area. */
5732 if (minibuffer_auto_raise)
5734 struct frame *sf = SELECTED_FRAME ();
5735 Lisp_Object mini_window;
5736 mini_window = FRAME_MINIBUF_WINDOW (sf);
5737 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
5740 message_log_maybe_newline ();
5741 message_buf_print = 1;
5743 else
5745 if (NILP (echo_area_buffer[0]))
5747 if (EQ (echo_area_buffer[1], echo_buffer[0]))
5748 echo_area_buffer[0] = echo_buffer[1];
5749 else
5750 echo_area_buffer[0] = echo_buffer[0];
5753 if (current_buffer != XBUFFER (echo_area_buffer[0]))
5754 /* Someone switched buffers between print requests. */
5755 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
5760 /* Display an echo area message in window W. Value is non-zero if W's
5761 height is changed. If display_last_displayed_message_p is
5762 non-zero, display the message that was last displayed, otherwise
5763 display the current message. */
5765 static int
5766 display_echo_area (w)
5767 struct window *w;
5769 int i, no_message_p, window_height_changed_p, count;
5771 /* Temporarily disable garbage collections while displaying the echo
5772 area. This is done because a GC can print a message itself.
5773 That message would modify the echo area buffer's contents while a
5774 redisplay of the buffer is going on, and seriously confuse
5775 redisplay. */
5776 count = inhibit_garbage_collection ();
5778 /* If there is no message, we must call display_echo_area_1
5779 nevertheless because it resizes the window. But we will have to
5780 reset the echo_area_buffer in question to nil at the end because
5781 with_echo_area_buffer will sets it to an empty buffer. */
5782 i = display_last_displayed_message_p ? 1 : 0;
5783 no_message_p = NILP (echo_area_buffer[i]);
5785 window_height_changed_p
5786 = with_echo_area_buffer (w, display_last_displayed_message_p,
5787 display_echo_area_1,
5788 (EMACS_INT) w, Qnil, 0, 0);
5790 if (no_message_p)
5791 echo_area_buffer[i] = Qnil;
5793 unbind_to (count, Qnil);
5794 return window_height_changed_p;
5798 /* Helper for display_echo_area. Display the current buffer which
5799 contains the current echo area message in window W, a mini-window,
5800 a pointer to which is passed in A1. A2..A4 are currently not used.
5801 Change the height of W so that all of the message is displayed.
5802 Value is non-zero if height of W was changed. */
5804 static int
5805 display_echo_area_1 (a1, a2, a3, a4)
5806 EMACS_INT a1;
5807 Lisp_Object a2;
5808 EMACS_INT a3, a4;
5810 struct window *w = (struct window *) a1;
5811 Lisp_Object window;
5812 struct text_pos start;
5813 int window_height_changed_p = 0;
5815 /* Do this before displaying, so that we have a large enough glyph
5816 matrix for the display. */
5817 window_height_changed_p = resize_mini_window (w, 0);
5819 /* Display. */
5820 clear_glyph_matrix (w->desired_matrix);
5821 XSETWINDOW (window, w);
5822 SET_TEXT_POS (start, BEG, BEG_BYTE);
5823 try_window (window, start);
5825 return window_height_changed_p;
5829 /* Resize the echo area window to exactly the size needed for the
5830 currently displayed message, if there is one. */
5832 void
5833 resize_echo_area_axactly ()
5835 if (BUFFERP (echo_area_buffer[0])
5836 && WINDOWP (echo_area_window))
5838 struct window *w = XWINDOW (echo_area_window);
5839 int resized_p;
5841 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
5842 (EMACS_INT) w, Qnil, 0, 0);
5843 if (resized_p)
5845 ++windows_or_buffers_changed;
5846 ++update_mode_lines;
5847 redisplay_internal (0);
5853 /* Callback function for with_echo_area_buffer, when used from
5854 resize_echo_area_axactly. A1 contains a pointer to the window to
5855 resize, A2 to A4 are not used. Value is what resize_mini_window
5856 returns. */
5858 static int
5859 resize_mini_window_1 (a1, a2, a3, a4)
5860 EMACS_INT a1;
5861 Lisp_Object a2;
5862 EMACS_INT a3, a4;
5864 return resize_mini_window ((struct window *) a1, 1);
5868 /* Resize mini-window W to fit the size of its contents. EXACT:P
5869 means size the window exactly to the size needed. Otherwise, it's
5870 only enlarged until W's buffer is empty. Value is non-zero if
5871 the window height has been changed. */
5874 resize_mini_window (w, exact_p)
5875 struct window *w;
5876 int exact_p;
5878 struct frame *f = XFRAME (w->frame);
5879 int window_height_changed_p = 0;
5881 xassert (MINI_WINDOW_P (w));
5883 /* Nil means don't try to resize. */
5884 if (NILP (Vmax_mini_window_height)
5885 || (FRAME_X_P (f) && f->output_data.x == NULL))
5886 return 0;
5888 if (!FRAME_MINIBUF_ONLY_P (f))
5890 struct it it;
5891 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
5892 int total_height = XFASTINT (root->height) + XFASTINT (w->height);
5893 int height, max_height;
5894 int unit = CANON_Y_UNIT (f);
5895 struct text_pos start;
5897 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
5899 /* Compute the max. number of lines specified by the user. */
5900 if (FLOATP (Vmax_mini_window_height))
5901 max_height = XFLOATINT (Vmax_mini_window_height) * total_height;
5902 else if (INTEGERP (Vmax_mini_window_height))
5903 max_height = XINT (Vmax_mini_window_height);
5904 else
5905 max_height = total_height / 4;
5907 /* Correct that max. height if it's bogus. */
5908 max_height = max (1, max_height);
5909 max_height = min (total_height, max_height);
5911 /* Find out the height of the text in the window. */
5912 if (it.truncate_lines_p)
5913 height = 1;
5914 else
5916 last_height = 0;
5917 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
5918 if (it.max_ascent == 0 && it.max_descent == 0)
5919 height = it.current_y + last_height;
5920 else
5921 height = it.current_y + it.max_ascent + it.max_descent;
5922 height -= it.extra_line_spacing;
5923 height = (height + unit - 1) / unit;
5926 /* Compute a suitable window start. */
5927 if (height > max_height)
5929 height = max_height;
5930 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
5931 move_it_vertically_backward (&it, (height - 1) * unit);
5932 start = it.current.pos;
5934 else
5935 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
5936 SET_MARKER_FROM_TEXT_POS (w->start, start);
5938 /* Let it grow only, until we display an empty message, in which
5939 case the window shrinks again. */
5940 if (height > XFASTINT (w->height))
5942 int old_height = XFASTINT (w->height);
5943 freeze_window_starts (f, 1);
5944 grow_mini_window (w, height - XFASTINT (w->height));
5945 window_height_changed_p = XFASTINT (w->height) != old_height;
5947 else if (height < XFASTINT (w->height)
5948 && (exact_p || BEGV == ZV))
5950 int old_height = XFASTINT (w->height);
5951 freeze_window_starts (f, 0);
5952 shrink_mini_window (w);
5953 window_height_changed_p = XFASTINT (w->height) != old_height;
5957 return window_height_changed_p;
5961 /* Value is the current message, a string, or nil if there is no
5962 current message. */
5964 Lisp_Object
5965 current_message ()
5967 Lisp_Object msg;
5969 if (NILP (echo_area_buffer[0]))
5970 msg = Qnil;
5971 else
5973 with_echo_area_buffer (0, 0, current_message_1,
5974 (EMACS_INT) &msg, Qnil, 0, 0);
5975 if (NILP (msg))
5976 echo_area_buffer[0] = Qnil;
5979 return msg;
5983 static int
5984 current_message_1 (a1, a2, a3, a4)
5985 EMACS_INT a1;
5986 Lisp_Object a2;
5987 EMACS_INT a3, a4;
5989 Lisp_Object *msg = (Lisp_Object *) a1;
5991 if (Z > BEG)
5992 *msg = make_buffer_string (BEG, Z, 1);
5993 else
5994 *msg = Qnil;
5995 return 0;
5999 /* Push the current message on Vmessage_stack for later restauration
6000 by restore_message. Value is non-zero if the current message isn't
6001 empty. This is a relatively infrequent operation, so it's not
6002 worth optimizing. */
6005 push_message ()
6007 Lisp_Object msg;
6008 msg = current_message ();
6009 Vmessage_stack = Fcons (msg, Vmessage_stack);
6010 return STRINGP (msg);
6014 /* Restore message display from the top of Vmessage_stack. */
6016 void
6017 restore_message ()
6019 Lisp_Object msg;
6021 xassert (CONSP (Vmessage_stack));
6022 msg = XCAR (Vmessage_stack);
6023 if (STRINGP (msg))
6024 message3_nolog (msg, STRING_BYTES (XSTRING (msg)), STRING_MULTIBYTE (msg));
6025 else
6026 message3_nolog (msg, 0, 0);
6030 /* Pop the top-most entry off Vmessage_stack. */
6032 void
6033 pop_message ()
6035 xassert (CONSP (Vmessage_stack));
6036 Vmessage_stack = XCDR (Vmessage_stack);
6040 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
6041 exits. If the stack is not empty, we have a missing pop_message
6042 somewhere. */
6044 void
6045 check_message_stack ()
6047 if (!NILP (Vmessage_stack))
6048 abort ();
6052 /* Truncate to NCHARS what will be displayed in the echo area the next
6053 time we display it---but don't redisplay it now. */
6055 void
6056 truncate_echo_area (nchars)
6057 int nchars;
6059 if (nchars == 0)
6060 echo_area_buffer[0] = Qnil;
6061 /* A null message buffer means that the frame hasn't really been
6062 initialized yet. Error messages get reported properly by
6063 cmd_error, so this must be just an informative message; toss it. */
6064 else if (!noninteractive
6065 && INTERACTIVE
6066 && !NILP (echo_area_buffer[0]))
6068 struct frame *sf = SELECTED_FRAME ();
6069 if (FRAME_MESSAGE_BUF (sf))
6070 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
6075 /* Helper function for truncate_echo_area. Truncate the current
6076 message to at most NCHARS characters. */
6078 static int
6079 truncate_message_1 (nchars, a2, a3, a4)
6080 EMACS_INT nchars;
6081 Lisp_Object a2;
6082 EMACS_INT a3, a4;
6084 if (BEG + nchars < Z)
6085 del_range (BEG + nchars, Z);
6086 if (Z == BEG)
6087 echo_area_buffer[0] = Qnil;
6088 return 0;
6092 /* Set the current message to a substring of S or STRING.
6094 If STRING is a Lisp string, set the message to the first NBYTES
6095 bytes from STRING. NBYTES zero means use the whole string. If
6096 STRING is multibyte, the message will be displayed multibyte.
6098 If S is not null, set the message to the first LEN bytes of S. LEN
6099 zero means use the whole string. MULTIBYTE_P non-zero means S is
6100 multibyte. Display the message multibyte in that case. */
6102 void
6103 set_message (s, string, nbytes, multibyte_p)
6104 char *s;
6105 Lisp_Object string;
6106 int nbytes;
6108 message_enable_multibyte
6109 = ((s && multibyte_p)
6110 || (STRINGP (string) && STRING_MULTIBYTE (string)));
6112 with_echo_area_buffer (0, -1, set_message_1,
6113 (EMACS_INT) s, string, nbytes, multibyte_p);
6114 message_buf_print = 0;
6118 /* Helper function for set_message. Arguments have the same meaning
6119 as there, with A1 corresponding to S and A2 corresponding to STRING
6120 This function is called with the echo area buffer being
6121 current. */
6123 static int
6124 set_message_1 (a1, a2, nbytes, multibyte_p)
6125 EMACS_INT a1;
6126 Lisp_Object a2;
6127 EMACS_INT nbytes, multibyte_p;
6129 char *s = (char *) a1;
6130 Lisp_Object string = a2;
6132 xassert (BEG == Z);
6134 /* Change multibyteness of the echo buffer appropriately. */
6135 if (message_enable_multibyte
6136 != !NILP (current_buffer->enable_multibyte_characters))
6137 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
6139 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
6141 /* Insert new message at BEG. */
6142 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
6144 if (STRINGP (string))
6146 int nchars;
6148 if (nbytes == 0)
6149 nbytes = XSTRING (string)->size_byte;
6150 nchars = string_byte_to_char (string, nbytes);
6152 /* This function takes care of single/multibyte conversion. We
6153 just have to ensure that the echo area buffer has the right
6154 setting of enable_multibyte_characters. */
6155 insert_from_string (string, 0, 0, nchars, nbytes, 1);
6157 else if (s)
6159 if (nbytes == 0)
6160 nbytes = strlen (s);
6162 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
6164 /* Convert from multi-byte to single-byte. */
6165 int i, c, n;
6166 unsigned char work[1];
6168 /* Convert a multibyte string to single-byte. */
6169 for (i = 0; i < nbytes; i += n)
6171 c = string_char_and_length (s + i, nbytes - i, &n);
6172 work[0] = (SINGLE_BYTE_CHAR_P (c)
6174 : multibyte_char_to_unibyte (c, Qnil));
6175 insert_1_both (work, 1, 1, 1, 0, 0);
6178 else if (!multibyte_p
6179 && !NILP (current_buffer->enable_multibyte_characters))
6181 /* Convert from single-byte to multi-byte. */
6182 int i, c, n;
6183 unsigned char *msg = (unsigned char *) s;
6184 unsigned char str[MAX_MULTIBYTE_LENGTH];
6186 /* Convert a single-byte string to multibyte. */
6187 for (i = 0; i < nbytes; i++)
6189 c = unibyte_char_to_multibyte (msg[i]);
6190 n = CHAR_STRING (c, str);
6191 insert_1_both (str, 1, n, 1, 0, 0);
6194 else
6195 insert_1 (s, nbytes, 1, 0, 0);
6198 return 0;
6202 /* Clear messages. CURRENT_P non-zero means clear the current
6203 message. LAST_DISPLAYED_P non-zero means clear the message
6204 last displayed. */
6206 void
6207 clear_message (current_p, last_displayed_p)
6208 int current_p, last_displayed_p;
6210 if (current_p)
6211 echo_area_buffer[0] = Qnil;
6213 if (last_displayed_p)
6214 echo_area_buffer[1] = Qnil;
6216 message_buf_print = 0;
6219 /* Clear garbaged frames.
6221 This function is used where the old redisplay called
6222 redraw_garbaged_frames which in turn called redraw_frame which in
6223 turn called clear_frame. The call to clear_frame was a source of
6224 flickering. I believe a clear_frame is not necessary. It should
6225 suffice in the new redisplay to invalidate all current matrices,
6226 and ensure a complete redisplay of all windows. */
6228 static void
6229 clear_garbaged_frames ()
6231 if (frame_garbaged)
6233 Lisp_Object tail, frame;
6235 FOR_EACH_FRAME (tail, frame)
6237 struct frame *f = XFRAME (frame);
6239 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
6241 clear_current_matrices (f);
6242 f->garbaged = 0;
6246 frame_garbaged = 0;
6247 ++windows_or_buffers_changed;
6252 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
6253 is non-zero update selected_frame. Value is non-zero if the
6254 mini-windows height has been changed. */
6256 static int
6257 echo_area_display (update_frame_p)
6258 int update_frame_p;
6260 Lisp_Object mini_window;
6261 struct window *w;
6262 struct frame *f;
6263 int window_height_changed_p = 0;
6264 struct frame *sf = SELECTED_FRAME ();
6266 mini_window = FRAME_MINIBUF_WINDOW (sf);
6267 w = XWINDOW (mini_window);
6268 f = XFRAME (WINDOW_FRAME (w));
6270 /* Don't display if frame is invisible or not yet initialized. */
6271 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
6272 return 0;
6274 #ifdef HAVE_WINDOW_SYSTEM
6275 /* When Emacs starts, selected_frame may be a visible terminal
6276 frame, even if we run under a window system. If we let this
6277 through, a message would be displayed on the terminal. */
6278 if (EQ (selected_frame, Vterminal_frame)
6279 && !NILP (Vwindow_system))
6280 return 0;
6281 #endif /* HAVE_WINDOW_SYSTEM */
6283 /* Redraw garbaged frames. */
6284 if (frame_garbaged)
6285 clear_garbaged_frames ();
6287 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
6289 echo_area_window = mini_window;
6290 window_height_changed_p = display_echo_area (w);
6291 w->must_be_updated_p = 1;
6293 if (update_frame_p)
6295 /* Not called from redisplay_internal. If we changed window
6296 configuration, we must redisplay thoroughly, of course.
6298 Likewise if input is pending, because the pending input
6299 can have interrupted a previous redisplay, or redisplay
6300 wasn't called because of the pending input (see
6301 keyboard.c). In both cases, we would display the message
6302 fine, but the rest of the display would be garbage.
6304 Otherwise, we can do with updating just what we displayed
6305 above. */
6307 if (window_height_changed_p || detect_input_pending ())
6309 int count = specpdl_ptr - specpdl;
6311 specbind (Qredisplay_dont_pause, Qt);
6312 ++windows_or_buffers_changed;
6313 ++update_mode_lines;
6314 redisplay_internal (0);
6315 unbind_to (count, Qnil);
6317 else if (FRAME_WINDOW_P (f))
6319 update_single_window (w, 1);
6320 rif->flush_display (f);
6322 else
6323 update_frame (f, 1, 1);
6326 else if (!EQ (mini_window, selected_window))
6327 windows_or_buffers_changed++;
6329 /* Last displayed message is now the current message. */
6330 echo_area_buffer[1] = echo_area_buffer[0];
6332 /* Prevent redisplay optimization in redisplay_internal by resetting
6333 this_line_start_pos. This is done because the mini-buffer now
6334 displays the message instead of its buffer text. */
6335 if (EQ (mini_window, selected_window))
6336 CHARPOS (this_line_start_pos) = 0;
6338 return window_height_changed_p;
6343 /***********************************************************************
6344 Frame Titles
6345 ***********************************************************************/
6348 #ifdef HAVE_WINDOW_SYSTEM
6350 /* A buffer for constructing frame titles in it; allocated from the
6351 heap in init_xdisp and resized as needed in store_frame_title_char. */
6353 static char *frame_title_buf;
6355 /* The buffer's end, and a current output position in it. */
6357 static char *frame_title_buf_end;
6358 static char *frame_title_ptr;
6361 /* Store a single character C for the frame title in frame_title_buf.
6362 Re-allocate frame_title_buf if necessary. */
6364 static void
6365 store_frame_title_char (c)
6366 char c;
6368 /* If output position has reached the end of the allocated buffer,
6369 double the buffer's size. */
6370 if (frame_title_ptr == frame_title_buf_end)
6372 int len = frame_title_ptr - frame_title_buf;
6373 int new_size = 2 * len * sizeof *frame_title_buf;
6374 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
6375 frame_title_buf_end = frame_title_buf + new_size;
6376 frame_title_ptr = frame_title_buf + len;
6379 *frame_title_ptr++ = c;
6383 /* Store part of a frame title in frame_title_buf, beginning at
6384 frame_title_ptr. STR is the string to store. Do not copy more
6385 than PRECISION number of bytes from STR; PRECISION <= 0 means copy
6386 the whole string. Pad with spaces until FIELD_WIDTH number of
6387 characters have been copied; FIELD_WIDTH <= 0 means don't pad.
6388 Called from display_mode_element when it is used to build a frame
6389 title. */
6391 static int
6392 store_frame_title (str, field_width, precision)
6393 unsigned char *str;
6394 int field_width, precision;
6396 int n = 0;
6398 /* Copy at most PRECISION chars from STR. */
6399 while ((precision <= 0 || n < precision)
6400 && *str)
6402 store_frame_title_char (*str++);
6403 ++n;
6406 /* Fill up with spaces until FIELD_WIDTH reached. */
6407 while (field_width > 0
6408 && n < field_width)
6410 store_frame_title_char (' ');
6411 ++n;
6414 return n;
6418 /* Set the title of FRAME, if it has changed. The title format is
6419 Vicon_title_format if FRAME is iconified, otherwise it is
6420 frame_title_format. */
6422 static void
6423 x_consider_frame_title (frame)
6424 Lisp_Object frame;
6426 struct frame *f = XFRAME (frame);
6428 if (FRAME_WINDOW_P (f)
6429 || FRAME_MINIBUF_ONLY_P (f)
6430 || f->explicit_name)
6432 /* Do we have more than one visible frame on this X display? */
6433 Lisp_Object tail;
6434 Lisp_Object fmt;
6435 struct buffer *obuf;
6436 int len;
6437 struct it it;
6439 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
6441 struct frame *tf = XFRAME (XCAR (tail));
6443 if (tf != f
6444 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
6445 && !FRAME_MINIBUF_ONLY_P (tf)
6446 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
6447 break;
6450 /* Set global variable indicating that multiple frames exist. */
6451 multiple_frames = CONSP (tail);
6453 /* Switch to the buffer of selected window of the frame. Set up
6454 frame_title_ptr so that display_mode_element will output into it;
6455 then display the title. */
6456 obuf = current_buffer;
6457 Fset_buffer (XWINDOW (f->selected_window)->buffer);
6458 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
6459 frame_title_ptr = frame_title_buf;
6460 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
6461 NULL, DEFAULT_FACE_ID);
6462 len = display_mode_element (&it, 0, -1, -1, fmt);
6463 frame_title_ptr = NULL;
6464 set_buffer_internal (obuf);
6466 /* Set the title only if it's changed. This avoids consing in
6467 the common case where it hasn't. (If it turns out that we've
6468 already wasted too much time by walking through the list with
6469 display_mode_element, then we might need to optimize at a
6470 higher level than this.) */
6471 if (! STRINGP (f->name)
6472 || STRING_BYTES (XSTRING (f->name)) != len
6473 || bcmp (frame_title_buf, XSTRING (f->name)->data, len) != 0)
6474 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
6478 #else /* not HAVE_WINDOW_SYSTEM */
6480 #define frame_title_ptr ((char *)0)
6481 #define store_frame_title(str, mincol, maxcol) 0
6483 #endif /* not HAVE_WINDOW_SYSTEM */
6488 /***********************************************************************
6489 Menu Bars
6490 ***********************************************************************/
6493 /* Prepare for redisplay by updating menu-bar item lists when
6494 appropriate. This can call eval. */
6496 void
6497 prepare_menu_bars ()
6499 int all_windows;
6500 struct gcpro gcpro1, gcpro2;
6501 struct frame *f;
6502 struct frame *tooltip_frame;
6504 #ifdef HAVE_X_WINDOWS
6505 tooltip_frame = tip_frame;
6506 #else
6507 tooltip_frame = NULL;
6508 #endif
6510 /* Update all frame titles based on their buffer names, etc. We do
6511 this before the menu bars so that the buffer-menu will show the
6512 up-to-date frame titles. */
6513 #ifdef HAVE_WINDOW_SYSTEM
6514 if (windows_or_buffers_changed || update_mode_lines)
6516 Lisp_Object tail, frame;
6518 FOR_EACH_FRAME (tail, frame)
6520 f = XFRAME (frame);
6521 if (f != tooltip_frame
6522 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
6523 x_consider_frame_title (frame);
6526 #endif /* HAVE_WINDOW_SYSTEM */
6528 /* Update the menu bar item lists, if appropriate. This has to be
6529 done before any actual redisplay or generation of display lines. */
6530 all_windows = (update_mode_lines
6531 || buffer_shared > 1
6532 || windows_or_buffers_changed);
6533 if (all_windows)
6535 Lisp_Object tail, frame;
6536 int count = specpdl_ptr - specpdl;
6538 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6540 FOR_EACH_FRAME (tail, frame)
6542 f = XFRAME (frame);
6544 /* Ignore tooltip frame. */
6545 if (f == tooltip_frame)
6546 continue;
6548 /* If a window on this frame changed size, report that to
6549 the user and clear the size-change flag. */
6550 if (FRAME_WINDOW_SIZES_CHANGED (f))
6552 Lisp_Object functions;
6554 /* Clear flag first in case we get an error below. */
6555 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
6556 functions = Vwindow_size_change_functions;
6557 GCPRO2 (tail, functions);
6559 while (CONSP (functions))
6561 call1 (XCAR (functions), frame);
6562 functions = XCDR (functions);
6564 UNGCPRO;
6567 GCPRO1 (tail);
6568 update_menu_bar (f, 0);
6569 #ifdef HAVE_WINDOW_SYSTEM
6570 update_tool_bar (f, 0);
6571 #endif
6572 UNGCPRO;
6575 unbind_to (count, Qnil);
6577 else
6579 struct frame *sf = SELECTED_FRAME ();
6580 update_menu_bar (sf, 1);
6581 #ifdef HAVE_WINDOW_SYSTEM
6582 update_tool_bar (sf, 1);
6583 #endif
6586 /* Motif needs this. See comment in xmenu.c. Turn it off when
6587 pending_menu_activation is not defined. */
6588 #ifdef USE_X_TOOLKIT
6589 pending_menu_activation = 0;
6590 #endif
6594 /* Update the menu bar item list for frame F. This has to be done
6595 before we start to fill in any display lines, because it can call
6596 eval.
6598 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
6600 static void
6601 update_menu_bar (f, save_match_data)
6602 struct frame *f;
6603 int save_match_data;
6605 Lisp_Object window;
6606 register struct window *w;
6608 window = FRAME_SELECTED_WINDOW (f);
6609 w = XWINDOW (window);
6611 if (update_mode_lines)
6612 w->update_mode_line = Qt;
6614 if (FRAME_WINDOW_P (f)
6616 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
6617 FRAME_EXTERNAL_MENU_BAR (f)
6618 #else
6619 FRAME_MENU_BAR_LINES (f) > 0
6620 #endif
6621 : FRAME_MENU_BAR_LINES (f) > 0)
6623 /* If the user has switched buffers or windows, we need to
6624 recompute to reflect the new bindings. But we'll
6625 recompute when update_mode_lines is set too; that means
6626 that people can use force-mode-line-update to request
6627 that the menu bar be recomputed. The adverse effect on
6628 the rest of the redisplay algorithm is about the same as
6629 windows_or_buffers_changed anyway. */
6630 if (windows_or_buffers_changed
6631 || !NILP (w->update_mode_line)
6632 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
6633 < BUF_MODIFF (XBUFFER (w->buffer)))
6634 != !NILP (w->last_had_star))
6635 || ((!NILP (Vtransient_mark_mode)
6636 && !NILP (XBUFFER (w->buffer)->mark_active))
6637 != !NILP (w->region_showing)))
6639 struct buffer *prev = current_buffer;
6640 int count = specpdl_ptr - specpdl;
6642 set_buffer_internal_1 (XBUFFER (w->buffer));
6643 if (save_match_data)
6644 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6645 if (NILP (Voverriding_local_map_menu_flag))
6647 specbind (Qoverriding_terminal_local_map, Qnil);
6648 specbind (Qoverriding_local_map, Qnil);
6651 /* Run the Lucid hook. */
6652 call1 (Vrun_hooks, Qactivate_menubar_hook);
6654 /* If it has changed current-menubar from previous value,
6655 really recompute the menu-bar from the value. */
6656 if (! NILP (Vlucid_menu_bar_dirty_flag))
6657 call0 (Qrecompute_lucid_menubar);
6659 safe_run_hooks (Qmenu_bar_update_hook);
6660 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
6662 /* Redisplay the menu bar in case we changed it. */
6663 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
6664 if (FRAME_WINDOW_P (f))
6665 set_frame_menubar (f, 0, 0);
6666 else
6667 /* On a terminal screen, the menu bar is an ordinary screen
6668 line, and this makes it get updated. */
6669 w->update_mode_line = Qt;
6670 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
6671 /* In the non-toolkit version, the menu bar is an ordinary screen
6672 line, and this makes it get updated. */
6673 w->update_mode_line = Qt;
6674 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
6676 unbind_to (count, Qnil);
6677 set_buffer_internal_1 (prev);
6684 /***********************************************************************
6685 Tool-bars
6686 ***********************************************************************/
6688 #ifdef HAVE_WINDOW_SYSTEM
6690 /* Update the tool-bar item list for frame F. This has to be done
6691 before we start to fill in any display lines. Called from
6692 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
6693 and restore it here. */
6695 static void
6696 update_tool_bar (f, save_match_data)
6697 struct frame *f;
6698 int save_match_data;
6700 if (WINDOWP (f->tool_bar_window)
6701 && XFASTINT (XWINDOW (f->tool_bar_window)->height) > 0)
6703 Lisp_Object window;
6704 struct window *w;
6706 window = FRAME_SELECTED_WINDOW (f);
6707 w = XWINDOW (window);
6709 /* If the user has switched buffers or windows, we need to
6710 recompute to reflect the new bindings. But we'll
6711 recompute when update_mode_lines is set too; that means
6712 that people can use force-mode-line-update to request
6713 that the menu bar be recomputed. The adverse effect on
6714 the rest of the redisplay algorithm is about the same as
6715 windows_or_buffers_changed anyway. */
6716 if (windows_or_buffers_changed
6717 || !NILP (w->update_mode_line)
6718 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
6719 < BUF_MODIFF (XBUFFER (w->buffer)))
6720 != !NILP (w->last_had_star))
6721 || ((!NILP (Vtransient_mark_mode)
6722 && !NILP (XBUFFER (w->buffer)->mark_active))
6723 != !NILP (w->region_showing)))
6725 struct buffer *prev = current_buffer;
6726 int count = specpdl_ptr - specpdl;
6728 /* Set current_buffer to the buffer of the selected
6729 window of the frame, so that we get the right local
6730 keymaps. */
6731 set_buffer_internal_1 (XBUFFER (w->buffer));
6733 /* Save match data, if we must. */
6734 if (save_match_data)
6735 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6737 /* Make sure that we don't accidentally use bogus keymaps. */
6738 if (NILP (Voverriding_local_map_menu_flag))
6740 specbind (Qoverriding_terminal_local_map, Qnil);
6741 specbind (Qoverriding_local_map, Qnil);
6744 /* Build desired tool-bar items from keymaps. */
6745 f->desired_tool_bar_items
6746 = tool_bar_items (f->desired_tool_bar_items,
6747 &f->n_desired_tool_bar_items);
6749 /* Redisplay the tool-bar in case we changed it. */
6750 w->update_mode_line = Qt;
6752 unbind_to (count, Qnil);
6753 set_buffer_internal_1 (prev);
6759 /* Set F->desired_tool_bar_string to a Lisp string representing frame
6760 F's desired tool-bar contents. F->desired_tool_bar_items must have
6761 been set up previously by calling prepare_menu_bars. */
6763 static void
6764 build_desired_tool_bar_string (f)
6765 struct frame *f;
6767 int i, size, size_needed, string_idx;
6768 struct gcpro gcpro1, gcpro2, gcpro3;
6769 Lisp_Object image, plist, props;
6771 image = plist = props = Qnil;
6772 GCPRO3 (image, plist, props);
6774 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
6775 Otherwise, make a new string. */
6777 /* The size of the string we might be able to reuse. */
6778 size = (STRINGP (f->desired_tool_bar_string)
6779 ? XSTRING (f->desired_tool_bar_string)->size
6780 : 0);
6782 /* Each image in the string we build is preceded by a space,
6783 and there is a space at the end. */
6784 size_needed = f->n_desired_tool_bar_items + 1;
6786 /* Reuse f->desired_tool_bar_string, if possible. */
6787 if (size < size_needed)
6788 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
6789 make_number (' '));
6790 else
6792 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
6793 Fremove_text_properties (make_number (0), make_number (size),
6794 props, f->desired_tool_bar_string);
6797 /* Put a `display' property on the string for the images to display,
6798 put a `menu_item' property on tool-bar items with a value that
6799 is the index of the item in F's tool-bar item vector. */
6800 for (i = 0, string_idx = 0;
6801 i < f->n_desired_tool_bar_items;
6802 ++i, string_idx += 1)
6804 #define PROP(IDX) \
6805 (XVECTOR (f->desired_tool_bar_items) \
6806 ->contents[i * TOOL_BAR_ITEM_NSLOTS + (IDX)])
6808 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
6809 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
6810 int margin, relief;
6811 extern Lisp_Object QCrelief, QCmargin, QCalgorithm, Qimage;
6812 extern Lisp_Object Qlaplace;
6814 /* If image is a vector, choose the image according to the
6815 button state. */
6816 image = PROP (TOOL_BAR_ITEM_IMAGES);
6817 if (VECTORP (image))
6819 enum tool_bar_item_image idx;
6821 if (enabled_p)
6822 idx = (selected_p
6823 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
6824 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
6825 else
6826 idx = (selected_p
6827 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
6828 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
6830 xassert (XVECTOR (image)->size >= idx);
6831 image = XVECTOR (image)->contents[idx];
6834 /* Ignore invalid image specifications. */
6835 if (!valid_image_p (image))
6836 continue;
6838 /* Display the tool-bar button pressed, or depressed. */
6839 plist = Fcopy_sequence (XCDR (image));
6841 /* Compute margin and relief to draw. */
6842 relief = tool_bar_button_relief > 0 ? tool_bar_button_relief : 3;
6843 margin = relief + max (0, tool_bar_button_margin);
6845 if (auto_raise_tool_bar_buttons_p)
6847 /* Add a `:relief' property to the image spec if the item is
6848 selected. */
6849 if (selected_p)
6851 plist = Fplist_put (plist, QCrelief, make_number (-relief));
6852 margin -= relief;
6855 else
6857 /* If image is selected, display it pressed, i.e. with a
6858 negative relief. If it's not selected, display it with a
6859 raised relief. */
6860 plist = Fplist_put (plist, QCrelief,
6861 (selected_p
6862 ? make_number (-relief)
6863 : make_number (relief)));
6864 margin -= relief;
6867 /* Put a margin around the image. */
6868 if (margin)
6869 plist = Fplist_put (plist, QCmargin, make_number (margin));
6871 /* If button is not enabled, make the image appear disabled by
6872 applying an appropriate algorithm to it. */
6873 if (!enabled_p)
6874 plist = Fplist_put (plist, QCalgorithm, Qlaplace);
6876 /* Put a `display' text property on the string for the image to
6877 display. Put a `menu-item' property on the string that gives
6878 the start of this item's properties in the tool-bar items
6879 vector. */
6880 image = Fcons (Qimage, plist);
6881 props = list4 (Qdisplay, image,
6882 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS)),
6883 Fadd_text_properties (make_number (string_idx),
6884 make_number (string_idx + 1),
6885 props, f->desired_tool_bar_string);
6886 #undef PROP
6889 UNGCPRO;
6893 /* Display one line of the tool-bar of frame IT->f. */
6895 static void
6896 display_tool_bar_line (it)
6897 struct it *it;
6899 struct glyph_row *row = it->glyph_row;
6900 int max_x = it->last_visible_x;
6901 struct glyph *last;
6903 prepare_desired_row (row);
6904 row->y = it->current_y;
6906 while (it->current_x < max_x)
6908 int x_before, x, n_glyphs_before, i, nglyphs;
6910 /* Get the next display element. */
6911 if (!get_next_display_element (it))
6912 break;
6914 /* Produce glyphs. */
6915 x_before = it->current_x;
6916 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
6917 PRODUCE_GLYPHS (it);
6919 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
6920 i = 0;
6921 x = x_before;
6922 while (i < nglyphs)
6924 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
6926 if (x + glyph->pixel_width > max_x)
6928 /* Glyph doesn't fit on line. */
6929 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
6930 it->current_x = x;
6931 goto out;
6934 ++it->hpos;
6935 x += glyph->pixel_width;
6936 ++i;
6939 /* Stop at line ends. */
6940 if (ITERATOR_AT_END_OF_LINE_P (it))
6941 break;
6943 set_iterator_to_next (it);
6946 out:;
6948 row->displays_text_p = row->used[TEXT_AREA] != 0;
6949 extend_face_to_end_of_line (it);
6950 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
6951 last->right_box_line_p = 1;
6952 compute_line_metrics (it);
6954 /* If line is empty, make it occupy the rest of the tool-bar. */
6955 if (!row->displays_text_p)
6957 row->height = row->phys_height = it->last_visible_y - row->y;
6958 row->ascent = row->phys_ascent = 0;
6961 row->full_width_p = 1;
6962 row->continued_p = 0;
6963 row->truncated_on_left_p = 0;
6964 row->truncated_on_right_p = 0;
6966 it->current_x = it->hpos = 0;
6967 it->current_y += row->height;
6968 ++it->vpos;
6969 ++it->glyph_row;
6973 /* Value is the number of screen lines needed to make all tool-bar
6974 items of frame F visible. */
6976 static int
6977 tool_bar_lines_needed (f)
6978 struct frame *f;
6980 struct window *w = XWINDOW (f->tool_bar_window);
6981 struct it it;
6983 /* Initialize an iterator for iteration over
6984 F->desired_tool_bar_string in the tool-bar window of frame F. */
6985 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
6986 it.first_visible_x = 0;
6987 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
6988 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
6990 while (!ITERATOR_AT_END_P (&it))
6992 it.glyph_row = w->desired_matrix->rows;
6993 clear_glyph_row (it.glyph_row);
6994 display_tool_bar_line (&it);
6997 return (it.current_y + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);
7001 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
7002 height should be changed. */
7004 static int
7005 redisplay_tool_bar (f)
7006 struct frame *f;
7008 struct window *w;
7009 struct it it;
7010 struct glyph_row *row;
7011 int change_height_p = 0;
7013 /* If frame hasn't a tool-bar window or if it is zero-height, don't
7014 do anything. This means you must start with tool-bar-lines
7015 non-zero to get the auto-sizing effect. Or in other words, you
7016 can turn off tool-bars by specifying tool-bar-lines zero. */
7017 if (!WINDOWP (f->tool_bar_window)
7018 || (w = XWINDOW (f->tool_bar_window),
7019 XFASTINT (w->height) == 0))
7020 return 0;
7022 /* Set up an iterator for the tool-bar window. */
7023 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
7024 it.first_visible_x = 0;
7025 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
7026 row = it.glyph_row;
7028 /* Build a string that represents the contents of the tool-bar. */
7029 build_desired_tool_bar_string (f);
7030 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
7032 /* Display as many lines as needed to display all tool-bar items. */
7033 while (it.current_y < it.last_visible_y)
7034 display_tool_bar_line (&it);
7036 /* It doesn't make much sense to try scrolling in the tool-bar
7037 window, so don't do it. */
7038 w->desired_matrix->no_scrolling_p = 1;
7039 w->must_be_updated_p = 1;
7041 if (auto_resize_tool_bars_p)
7043 int nlines;
7045 /* If there are blank lines at the end, except for a partially
7046 visible blank line at the end that is smaller than
7047 CANON_Y_UNIT, change the tool-bar's height. */
7048 row = it.glyph_row - 1;
7049 if (!row->displays_text_p
7050 && row->height >= CANON_Y_UNIT (f))
7051 change_height_p = 1;
7053 /* If row displays tool-bar items, but is partially visible,
7054 change the tool-bar's height. */
7055 if (row->displays_text_p
7056 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
7057 change_height_p = 1;
7059 /* Resize windows as needed by changing the `tool-bar-lines'
7060 frame parameter. */
7061 if (change_height_p
7062 && (nlines = tool_bar_lines_needed (f),
7063 nlines != XFASTINT (w->height)))
7065 extern Lisp_Object Qtool_bar_lines;
7066 Lisp_Object frame;
7068 XSETFRAME (frame, f);
7069 clear_glyph_matrix (w->desired_matrix);
7070 Fmodify_frame_parameters (frame,
7071 Fcons (Fcons (Qtool_bar_lines,
7072 make_number (nlines)),
7073 Qnil));
7074 fonts_changed_p = 1;
7078 return change_height_p;
7082 /* Get information about the tool-bar item which is displayed in GLYPH
7083 on frame F. Return in *PROP_IDX the index where tool-bar item
7084 properties start in F->current_tool_bar_items. Value is zero if
7085 GLYPH doesn't display a tool-bar item. */
7088 tool_bar_item_info (f, glyph, prop_idx)
7089 struct frame *f;
7090 struct glyph *glyph;
7091 int *prop_idx;
7093 Lisp_Object prop;
7094 int success_p;
7096 /* Get the text property `menu-item' at pos. The value of that
7097 property is the start index of this item's properties in
7098 F->current_tool_bar_items. */
7099 prop = Fget_text_property (make_number (glyph->charpos),
7100 Qmenu_item, f->current_tool_bar_string);
7101 if (INTEGERP (prop))
7103 *prop_idx = XINT (prop);
7104 success_p = 1;
7106 else
7107 success_p = 0;
7109 return success_p;
7112 #endif /* HAVE_WINDOW_SYSTEM */
7116 /************************************************************************
7117 Horizontal scrolling
7118 ************************************************************************/
7120 static int hscroll_window_tree P_ ((Lisp_Object));
7121 static int hscroll_windows P_ ((Lisp_Object));
7123 /* For all leaf windows in the window tree rooted at WINDOW, set their
7124 hscroll value so that PT is (i) visible in the window, and (ii) so
7125 that it is not within a certain margin at the window's left and
7126 right border. Value is non-zero if any window's hscroll has been
7127 changed. */
7129 static int
7130 hscroll_window_tree (window)
7131 Lisp_Object window;
7133 int hscrolled_p = 0;
7135 while (WINDOWP (window))
7137 struct window *w = XWINDOW (window);
7139 if (WINDOWP (w->hchild))
7140 hscrolled_p |= hscroll_window_tree (w->hchild);
7141 else if (WINDOWP (w->vchild))
7142 hscrolled_p |= hscroll_window_tree (w->vchild);
7143 else if (w->cursor.vpos >= 0)
7145 int hscroll_margin, text_area_x, text_area_y;
7146 int text_area_width, text_area_height;
7147 struct glyph_row *current_cursor_row
7148 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
7149 struct glyph_row *desired_cursor_row
7150 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
7151 struct glyph_row *cursor_row
7152 = (desired_cursor_row->enabled_p
7153 ? desired_cursor_row
7154 : current_cursor_row);
7156 window_box (w, TEXT_AREA, &text_area_x, &text_area_y,
7157 &text_area_width, &text_area_height);
7159 /* Scroll when cursor is inside this scroll margin. */
7160 hscroll_margin = 5 * CANON_X_UNIT (XFRAME (w->frame));
7162 if ((XFASTINT (w->hscroll)
7163 && w->cursor.x < hscroll_margin)
7164 || (cursor_row->enabled_p
7165 && cursor_row->truncated_on_right_p
7166 && (w->cursor.x > text_area_width - hscroll_margin)))
7168 struct it it;
7169 int hscroll;
7170 struct buffer *saved_current_buffer;
7171 int pt;
7173 /* Find point in a display of infinite width. */
7174 saved_current_buffer = current_buffer;
7175 current_buffer = XBUFFER (w->buffer);
7177 if (w == XWINDOW (selected_window))
7178 pt = BUF_PT (current_buffer);
7179 else
7181 pt = marker_position (w->pointm);
7182 pt = max (BEGV, pt);
7183 pt = min (ZV, pt);
7186 /* Move iterator to pt starting at cursor_row->start in
7187 a line with infinite width. */
7188 init_to_row_start (&it, w, cursor_row);
7189 it.last_visible_x = INFINITY;
7190 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
7191 current_buffer = saved_current_buffer;
7193 /* Center cursor in window. */
7194 hscroll = (max (0, it.current_x - text_area_width / 2)
7195 / CANON_X_UNIT (it.f));
7197 /* Don't call Fset_window_hscroll if value hasn't
7198 changed because it will prevent redisplay
7199 optimizations. */
7200 if (XFASTINT (w->hscroll) != hscroll)
7202 Fset_window_hscroll (window, make_number (hscroll));
7203 hscrolled_p = 1;
7208 window = w->next;
7211 /* Value is non-zero if hscroll of any leaf window has been changed. */
7212 return hscrolled_p;
7216 /* Set hscroll so that cursor is visible and not inside horizontal
7217 scroll margins for all windows in the tree rooted at WINDOW. See
7218 also hscroll_window_tree above. Value is non-zero if any window's
7219 hscroll has been changed. If it has, desired matrices on the frame
7220 of WINDOW are cleared. */
7222 static int
7223 hscroll_windows (window)
7224 Lisp_Object window;
7226 int hscrolled_p;
7228 if (automatic_hscrolling_p)
7230 hscrolled_p = hscroll_window_tree (window);
7231 if (hscrolled_p)
7232 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
7234 else
7235 hscrolled_p = 0;
7236 return hscrolled_p;
7241 /************************************************************************
7242 Redisplay
7243 ************************************************************************/
7245 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
7246 to a non-zero value. This is sometimes handy to have in a debugger
7247 session. */
7249 #if GLYPH_DEBUG
7251 /* First and last unchanged row for try_window_id. */
7253 int debug_first_unchanged_at_end_vpos;
7254 int debug_last_unchanged_at_beg_vpos;
7256 /* Delta vpos and y. */
7258 int debug_dvpos, debug_dy;
7260 /* Delta in characters and bytes for try_window_id. */
7262 int debug_delta, debug_delta_bytes;
7264 /* Values of window_end_pos and window_end_vpos at the end of
7265 try_window_id. */
7267 int debug_end_pos, debug_end_vpos;
7269 /* Append a string to W->desired_matrix->method. FMT is a printf
7270 format string. A1...A9 are a supplement for a variable-length
7271 argument list. If trace_redisplay_p is non-zero also printf the
7272 resulting string to stderr. */
7274 static void
7275 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
7276 struct window *w;
7277 char *fmt;
7278 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
7280 char buffer[512];
7281 char *method = w->desired_matrix->method;
7282 int len = strlen (method);
7283 int size = sizeof w->desired_matrix->method;
7284 int remaining = size - len - 1;
7286 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
7287 if (len && remaining)
7289 method[len] = '|';
7290 --remaining, ++len;
7293 strncpy (method + len, buffer, remaining);
7295 if (trace_redisplay_p)
7296 fprintf (stderr, "%p (%s): %s\n",
7298 ((BUFFERP (w->buffer)
7299 && STRINGP (XBUFFER (w->buffer)->name))
7300 ? (char *) XSTRING (XBUFFER (w->buffer)->name)->data
7301 : "no buffer"),
7302 buffer);
7305 #endif /* GLYPH_DEBUG */
7308 /* This counter is used to clear the face cache every once in a while
7309 in redisplay_internal. It is incremented for each redisplay.
7310 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
7311 cleared. */
7313 #define CLEAR_FACE_CACHE_COUNT 10000
7314 static int clear_face_cache_count;
7316 /* Record the previous terminal frame we displayed. */
7318 static struct frame *previous_terminal_frame;
7320 /* Non-zero while redisplay_internal is in progress. */
7322 int redisplaying_p;
7325 /* Value is non-zero if all changes in window W, which displays
7326 current_buffer, are in the text between START and END. START is a
7327 buffer position, END is given as a distance from Z. Used in
7328 redisplay_internal for display optimization. */
7330 static INLINE int
7331 text_outside_line_unchanged_p (w, start, end)
7332 struct window *w;
7333 int start, end;
7335 int unchanged_p = 1;
7337 /* If text or overlays have changed, see where. */
7338 if (XFASTINT (w->last_modified) < MODIFF
7339 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
7341 /* Gap in the line? */
7342 if (GPT < start || Z - GPT < end)
7343 unchanged_p = 0;
7345 /* Changes start in front of the line, or end after it? */
7346 if (unchanged_p
7347 && (BEG_UNCHANGED < start - 1
7348 || END_UNCHANGED < end))
7349 unchanged_p = 0;
7351 /* If selective display, can't optimize if changes start at the
7352 beginning of the line. */
7353 if (unchanged_p
7354 && INTEGERP (current_buffer->selective_display)
7355 && XINT (current_buffer->selective_display) > 0
7356 && (BEG_UNCHANGED < start || GPT <= start))
7357 unchanged_p = 0;
7360 return unchanged_p;
7364 /* Do a frame update, taking possible shortcuts into account. This is
7365 the main external entry point for redisplay.
7367 If the last redisplay displayed an echo area message and that message
7368 is no longer requested, we clear the echo area or bring back the
7369 mini-buffer if that is in use. */
7371 void
7372 redisplay ()
7374 redisplay_internal (0);
7377 /* Return 1 if point moved out of or into a composition. Otherwise
7378 return 0. PREV_BUF and PREV_PT are the last point buffer and
7379 position. BUF and PT are the current point buffer and position. */
7382 check_point_in_composition (prev_buf, prev_pt, buf, pt)
7383 struct buffer *prev_buf, *buf;
7384 int prev_pt, pt;
7386 int start, end;
7387 Lisp_Object prop;
7388 Lisp_Object buffer;
7390 XSETBUFFER (buffer, buf);
7391 /* Check a composition at the last point if point moved within the
7392 same buffer. */
7393 if (prev_buf == buf)
7395 if (prev_pt == pt)
7396 /* Point didn't move. */
7397 return 0;
7399 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
7400 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
7401 && COMPOSITION_VALID_P (start, end, prop)
7402 && start < prev_pt && end > prev_pt)
7403 /* The last point was within the composition. Return 1 iff
7404 point moved out of the composition. */
7405 return (pt <= start || pt >= end);
7408 /* Check a composition at the current point. */
7409 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
7410 && find_composition (pt, -1, &start, &end, &prop, buffer)
7411 && COMPOSITION_VALID_P (start, end, prop)
7412 && start < pt && end > pt);
7415 /* Reconsider the setting of B->clip_changed which is displayed
7416 in window W. */
7418 static INLINE void
7419 reconsider_clip_changes (w, b)
7420 struct window *w;
7421 struct buffer *b;
7423 if (b->prevent_redisplay_optimizations_p)
7424 b->clip_changed = 1;
7425 else if (b->clip_changed
7426 && !NILP (w->window_end_valid)
7427 && w->current_matrix->buffer == b
7428 && w->current_matrix->zv == BUF_ZV (b)
7429 && w->current_matrix->begv == BUF_BEGV (b))
7430 b->clip_changed = 0;
7432 /* If display wasn't paused, and W is not a tool bar window, see if
7433 point has been moved into or out of a composition. In that case,
7434 we set b->clip_changed to 1 to force updating the screen. If
7435 b->clip_changed has already been set to 1, we can skip this
7436 check. */
7437 if (!b->clip_changed
7438 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
7440 int pt;
7442 if (w == XWINDOW (selected_window))
7443 pt = BUF_PT (current_buffer);
7444 else
7445 pt = marker_position (w->pointm);
7447 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
7448 || pt != XINT (w->last_point))
7449 && check_point_in_composition (w->current_matrix->buffer,
7450 XINT (w->last_point),
7451 XBUFFER (w->buffer), pt))
7452 b->clip_changed = 1;
7457 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
7458 response to any user action; therefore, we should preserve the echo
7459 area. (Actually, our caller does that job.) Perhaps in the future
7460 avoid recentering windows if it is not necessary; currently that
7461 causes some problems. */
7463 static void
7464 redisplay_internal (preserve_echo_area)
7465 int preserve_echo_area;
7467 struct window *w = XWINDOW (selected_window);
7468 struct frame *f = XFRAME (w->frame);
7469 int pause;
7470 int must_finish = 0;
7471 struct text_pos tlbufpos, tlendpos;
7472 int number_of_visible_frames;
7473 int count;
7474 struct frame *sf = SELECTED_FRAME ();
7476 /* Non-zero means redisplay has to consider all windows on all
7477 frames. Zero means, only selected_window is considered. */
7478 int consider_all_windows_p;
7480 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
7482 /* No redisplay if running in batch mode or frame is not yet fully
7483 initialized, or redisplay is explicitly turned off by setting
7484 Vinhibit_redisplay. */
7485 if (noninteractive
7486 || !NILP (Vinhibit_redisplay)
7487 || !f->glyphs_initialized_p)
7488 return;
7490 /* The flag redisplay_performed_directly_p is set by
7491 direct_output_for_insert when it already did the whole screen
7492 update necessary. */
7493 if (redisplay_performed_directly_p)
7495 redisplay_performed_directly_p = 0;
7496 if (!hscroll_windows (selected_window))
7497 return;
7500 #ifdef USE_X_TOOLKIT
7501 if (popup_activated ())
7502 return;
7503 #endif
7505 /* I don't think this happens but let's be paranoid. */
7506 if (redisplaying_p)
7507 return;
7509 /* Record a function that resets redisplaying_p to its old value
7510 when we leave this function. */
7511 count = specpdl_ptr - specpdl;
7512 record_unwind_protect (unwind_redisplay, make_number (redisplaying_p));
7513 ++redisplaying_p;
7515 retry:
7517 reconsider_clip_changes (w, current_buffer);
7519 /* If new fonts have been loaded that make a glyph matrix adjustment
7520 necessary, do it. */
7521 if (fonts_changed_p)
7523 adjust_glyphs (NULL);
7524 ++windows_or_buffers_changed;
7525 fonts_changed_p = 0;
7528 if (! FRAME_WINDOW_P (sf)
7529 && previous_terminal_frame != sf)
7531 /* Since frames on an ASCII terminal share the same display
7532 area, displaying a different frame means redisplay the whole
7533 thing. */
7534 windows_or_buffers_changed++;
7535 SET_FRAME_GARBAGED (sf);
7536 XSETFRAME (Vterminal_frame, sf);
7538 previous_terminal_frame = sf;
7540 /* Set the visible flags for all frames. Do this before checking
7541 for resized or garbaged frames; they want to know if their frames
7542 are visible. See the comment in frame.h for
7543 FRAME_SAMPLE_VISIBILITY. */
7545 Lisp_Object tail, frame;
7547 number_of_visible_frames = 0;
7549 FOR_EACH_FRAME (tail, frame)
7551 struct frame *f = XFRAME (frame);
7553 FRAME_SAMPLE_VISIBILITY (f);
7554 if (FRAME_VISIBLE_P (f))
7555 ++number_of_visible_frames;
7556 clear_desired_matrices (f);
7560 /* Notice any pending interrupt request to change frame size. */
7561 do_pending_window_change (1);
7563 /* Clear frames marked as garbaged. */
7564 if (frame_garbaged)
7565 clear_garbaged_frames ();
7567 /* Build menubar and tool-bar items. */
7568 prepare_menu_bars ();
7570 if (windows_or_buffers_changed)
7571 update_mode_lines++;
7573 /* Detect case that we need to write or remove a star in the mode line. */
7574 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
7576 w->update_mode_line = Qt;
7577 if (buffer_shared > 1)
7578 update_mode_lines++;
7581 /* If %c is in the mode line, update it if needed. */
7582 if (!NILP (w->column_number_displayed)
7583 /* This alternative quickly identifies a common case
7584 where no change is needed. */
7585 && !(PT == XFASTINT (w->last_point)
7586 && XFASTINT (w->last_modified) >= MODIFF
7587 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
7588 && XFASTINT (w->column_number_displayed) != current_column ())
7589 w->update_mode_line = Qt;
7591 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
7593 /* The variable buffer_shared is set in redisplay_window and
7594 indicates that we redisplay a buffer in different windows. See
7595 there. */
7596 consider_all_windows_p = update_mode_lines || buffer_shared > 1;
7598 /* If specs for an arrow have changed, do thorough redisplay
7599 to ensure we remove any arrow that should no longer exist. */
7600 if (! EQ (COERCE_MARKER (Voverlay_arrow_position), last_arrow_position)
7601 || ! EQ (Voverlay_arrow_string, last_arrow_string))
7602 consider_all_windows_p = windows_or_buffers_changed = 1;
7604 /* Normally the message* functions will have already displayed and
7605 updated the echo area, but the frame may have been trashed, or
7606 the update may have been preempted, so display the echo area
7607 again here. Checking both message buffers captures the case that
7608 the echo area should be cleared. */
7609 if (!NILP (echo_area_buffer[0]) || !NILP (echo_area_buffer[1]))
7611 int window_height_changed_p = echo_area_display (0);
7612 must_finish = 1;
7614 if (fonts_changed_p)
7615 goto retry;
7616 else if (window_height_changed_p)
7618 consider_all_windows_p = 1;
7619 ++update_mode_lines;
7620 ++windows_or_buffers_changed;
7622 /* If window configuration was changed, frames may have been
7623 marked garbaged. Clear them or we will experience
7624 surprises wrt scrolling. */
7625 if (frame_garbaged)
7626 clear_garbaged_frames ();
7629 else if (EQ (selected_window, minibuf_window)
7630 && (current_buffer->clip_changed
7631 || XFASTINT (w->last_modified) < MODIFF
7632 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
7633 && resize_mini_window (w, 0))
7635 /* Resized active mini-window to fit the size of what it is
7636 showing if its contents might have changed. */
7637 must_finish = 1;
7638 consider_all_windows_p = 1;
7639 ++windows_or_buffers_changed;
7640 ++update_mode_lines;
7642 /* If window configuration was changed, frames may have been
7643 marked garbaged. Clear them or we will experience
7644 surprises wrt scrolling. */
7645 if (frame_garbaged)
7646 clear_garbaged_frames ();
7650 /* If showing the region, and mark has changed, we must redisplay
7651 the whole window. The assignment to this_line_start_pos prevents
7652 the optimization directly below this if-statement. */
7653 if (((!NILP (Vtransient_mark_mode)
7654 && !NILP (XBUFFER (w->buffer)->mark_active))
7655 != !NILP (w->region_showing))
7656 || (!NILP (w->region_showing)
7657 && !EQ (w->region_showing,
7658 Fmarker_position (XBUFFER (w->buffer)->mark))))
7659 CHARPOS (this_line_start_pos) = 0;
7661 /* Optimize the case that only the line containing the cursor in the
7662 selected window has changed. Variables starting with this_ are
7663 set in display_line and record information about the line
7664 containing the cursor. */
7665 tlbufpos = this_line_start_pos;
7666 tlendpos = this_line_end_pos;
7667 if (!consider_all_windows_p
7668 && CHARPOS (tlbufpos) > 0
7669 && NILP (w->update_mode_line)
7670 && !current_buffer->clip_changed
7671 && FRAME_VISIBLE_P (XFRAME (w->frame))
7672 && !FRAME_OBSCURED_P (XFRAME (w->frame))
7673 /* Make sure recorded data applies to current buffer, etc. */
7674 && this_line_buffer == current_buffer
7675 && current_buffer == XBUFFER (w->buffer)
7676 && NILP (w->force_start)
7677 /* Point must be on the line that we have info recorded about. */
7678 && PT >= CHARPOS (tlbufpos)
7679 && PT <= Z - CHARPOS (tlendpos)
7680 /* All text outside that line, including its final newline,
7681 must be unchanged */
7682 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
7683 CHARPOS (tlendpos)))
7685 if (CHARPOS (tlbufpos) > BEGV
7686 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
7687 && (CHARPOS (tlbufpos) == ZV
7688 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
7689 /* Former continuation line has disappeared by becoming empty */
7690 goto cancel;
7691 else if (XFASTINT (w->last_modified) < MODIFF
7692 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
7693 || MINI_WINDOW_P (w))
7695 /* We have to handle the case of continuation around a
7696 wide-column character (See the comment in indent.c around
7697 line 885).
7699 For instance, in the following case:
7701 -------- Insert --------
7702 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
7703 J_I_ ==> J_I_ `^^' are cursors.
7704 ^^ ^^
7705 -------- --------
7707 As we have to redraw the line above, we should goto cancel. */
7709 struct it it;
7710 int line_height_before = this_line_pixel_height;
7712 /* Note that start_display will handle the case that the
7713 line starting at tlbufpos is a continuation lines. */
7714 start_display (&it, w, tlbufpos);
7716 /* Implementation note: It this still necessary? */
7717 if (it.current_x != this_line_start_x)
7718 goto cancel;
7720 TRACE ((stderr, "trying display optimization 1\n"));
7721 w->cursor.vpos = -1;
7722 overlay_arrow_seen = 0;
7723 it.vpos = this_line_vpos;
7724 it.current_y = this_line_y;
7725 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
7726 display_line (&it);
7728 /* If line contains point, is not continued,
7729 and ends at same distance from eob as before, we win */
7730 if (w->cursor.vpos >= 0
7731 /* Line is not continued, otherwise this_line_start_pos
7732 would have been set to 0 in display_line. */
7733 && CHARPOS (this_line_start_pos)
7734 /* Line ends as before. */
7735 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
7736 /* Line has same height as before. Otherwise other lines
7737 would have to be shifted up or down. */
7738 && this_line_pixel_height == line_height_before)
7740 /* If this is not the window's last line, we must adjust
7741 the charstarts of the lines below. */
7742 if (it.current_y < it.last_visible_y)
7744 struct glyph_row *row
7745 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
7746 int delta, delta_bytes;
7748 if (Z - CHARPOS (tlendpos) == ZV)
7750 /* This line ends at end of (accessible part of)
7751 buffer. There is no newline to count. */
7752 delta = (Z
7753 - CHARPOS (tlendpos)
7754 - MATRIX_ROW_START_CHARPOS (row));
7755 delta_bytes = (Z_BYTE
7756 - BYTEPOS (tlendpos)
7757 - MATRIX_ROW_START_BYTEPOS (row));
7759 else
7761 /* This line ends in a newline. Must take
7762 account of the newline and the rest of the
7763 text that follows. */
7764 delta = (Z
7765 - CHARPOS (tlendpos)
7766 - MATRIX_ROW_START_CHARPOS (row));
7767 delta_bytes = (Z_BYTE
7768 - BYTEPOS (tlendpos)
7769 - MATRIX_ROW_START_BYTEPOS (row));
7772 increment_matrix_positions (w->current_matrix,
7773 this_line_vpos + 1,
7774 w->current_matrix->nrows,
7775 delta, delta_bytes);
7778 /* If this row displays text now but previously didn't,
7779 or vice versa, w->window_end_vpos may have to be
7780 adjusted. */
7781 if ((it.glyph_row - 1)->displays_text_p)
7783 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
7784 XSETINT (w->window_end_vpos, this_line_vpos);
7786 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
7787 && this_line_vpos > 0)
7788 XSETINT (w->window_end_vpos, this_line_vpos - 1);
7789 w->window_end_valid = Qnil;
7791 /* Update hint: No need to try to scroll in update_window. */
7792 w->desired_matrix->no_scrolling_p = 1;
7794 #if GLYPH_DEBUG
7795 *w->desired_matrix->method = 0;
7796 debug_method_add (w, "optimization 1");
7797 #endif
7798 goto update;
7800 else
7801 goto cancel;
7803 else if (/* Cursor position hasn't changed. */
7804 PT == XFASTINT (w->last_point)
7805 /* Make sure the cursor was last displayed
7806 in this window. Otherwise we have to reposition it. */
7807 && 0 <= w->cursor.vpos
7808 && XINT (w->height) > w->cursor.vpos)
7810 if (!must_finish)
7812 do_pending_window_change (1);
7814 /* We used to always goto end_of_redisplay here, but this
7815 isn't enough if we have a blinking cursor. */
7816 if (w->cursor_off_p == w->last_cursor_off_p)
7817 goto end_of_redisplay;
7819 goto update;
7821 /* If highlighting the region, or if the cursor is in the echo area,
7822 then we can't just move the cursor. */
7823 else if (! (!NILP (Vtransient_mark_mode)
7824 && !NILP (current_buffer->mark_active))
7825 && (EQ (selected_window, current_buffer->last_selected_window)
7826 || highlight_nonselected_windows)
7827 && NILP (w->region_showing)
7828 && NILP (Vshow_trailing_whitespace)
7829 && !cursor_in_echo_area)
7831 struct it it;
7832 struct glyph_row *row;
7834 /* Skip from tlbufpos to PT and see where it is. Note that
7835 PT may be in invisible text. If so, we will end at the
7836 next visible position. */
7837 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
7838 NULL, DEFAULT_FACE_ID);
7839 it.current_x = this_line_start_x;
7840 it.current_y = this_line_y;
7841 it.vpos = this_line_vpos;
7843 /* The call to move_it_to stops in front of PT, but
7844 moves over before-strings. */
7845 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
7847 if (it.vpos == this_line_vpos
7848 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
7849 row->enabled_p))
7851 xassert (this_line_vpos == it.vpos);
7852 xassert (this_line_y == it.current_y);
7853 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
7854 goto update;
7856 else
7857 goto cancel;
7860 cancel:
7861 /* Text changed drastically or point moved off of line. */
7862 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
7865 CHARPOS (this_line_start_pos) = 0;
7866 consider_all_windows_p |= buffer_shared > 1;
7867 ++clear_face_cache_count;
7870 /* Build desired matrices. If consider_all_windows_p is non-zero,
7871 do it for all windows on all frames. Otherwise do it for
7872 selected_window, only. */
7874 if (consider_all_windows_p)
7876 Lisp_Object tail, frame;
7878 /* Clear the face cache eventually. */
7879 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
7881 clear_face_cache (0);
7882 clear_face_cache_count = 0;
7885 /* Recompute # windows showing selected buffer. This will be
7886 incremented each time such a window is displayed. */
7887 buffer_shared = 0;
7889 FOR_EACH_FRAME (tail, frame)
7891 struct frame *f = XFRAME (frame);
7892 if (FRAME_WINDOW_P (f) || f == sf)
7894 /* Mark all the scroll bars to be removed; we'll redeem
7895 the ones we want when we redisplay their windows. */
7896 if (condemn_scroll_bars_hook)
7897 (*condemn_scroll_bars_hook) (f);
7899 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
7900 redisplay_windows (FRAME_ROOT_WINDOW (f));
7902 /* Any scroll bars which redisplay_windows should have
7903 nuked should now go away. */
7904 if (judge_scroll_bars_hook)
7905 (*judge_scroll_bars_hook) (f);
7909 else if (FRAME_VISIBLE_P (sf)
7910 && !FRAME_OBSCURED_P (sf))
7911 redisplay_window (selected_window, 1);
7914 /* Compare desired and current matrices, perform output. */
7916 update:
7918 /* If fonts changed, display again. */
7919 if (fonts_changed_p)
7920 goto retry;
7922 /* Prevent various kinds of signals during display update.
7923 stdio is not robust about handling signals,
7924 which can cause an apparent I/O error. */
7925 if (interrupt_input)
7926 unrequest_sigio ();
7927 stop_polling ();
7929 if (consider_all_windows_p)
7931 Lisp_Object tail;
7932 struct frame *f;
7933 int hscrolled_p;
7935 pause = 0;
7936 hscrolled_p = 0;
7938 /* See if we have to hscroll. */
7939 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
7940 if (FRAMEP (XCAR (tail)))
7942 f = XFRAME (XCAR (tail));
7944 if ((FRAME_WINDOW_P (f)
7945 || f == sf)
7946 && FRAME_VISIBLE_P (f)
7947 && !FRAME_OBSCURED_P (f)
7948 && hscroll_windows (f->root_window))
7949 hscrolled_p = 1;
7952 if (hscrolled_p)
7953 goto retry;
7955 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
7957 if (!FRAMEP (XCAR (tail)))
7958 continue;
7960 f = XFRAME (XCAR (tail));
7962 if ((FRAME_WINDOW_P (f) || f == sf)
7963 && FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
7965 /* Mark all windows as to be updated. */
7966 set_window_update_flags (XWINDOW (f->root_window), 1);
7967 pause |= update_frame (f, 0, 0);
7968 if (!pause)
7970 mark_window_display_accurate (f->root_window, 1);
7971 if (frame_up_to_date_hook != 0)
7972 (*frame_up_to_date_hook) (f);
7977 else
7979 if (FRAME_VISIBLE_P (sf)
7980 && !FRAME_OBSCURED_P (sf))
7982 if (hscroll_windows (selected_window))
7983 goto retry;
7985 XWINDOW (selected_window)->must_be_updated_p = 1;
7986 pause = update_frame (sf, 0, 0);
7988 else
7989 pause = 0;
7991 /* We may have called echo_area_display at the top of this
7992 function. If the echo area is on another frame, that may
7993 have put text on a frame other than the selected one, so the
7994 above call to update_frame would not have caught it. Catch
7995 it here. */
7997 Lisp_Object mini_window;
7998 struct frame *mini_frame;
8000 mini_window = FRAME_MINIBUF_WINDOW (sf);
8001 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8003 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
8005 XWINDOW (mini_window)->must_be_updated_p = 1;
8006 pause |= update_frame (mini_frame, 0, 0);
8007 if (!pause && hscroll_windows (mini_window))
8008 goto retry;
8013 /* If display was paused because of pending input, make sure we do a
8014 thorough update the next time. */
8015 if (pause)
8017 /* Prevent the optimization at the beginning of
8018 redisplay_internal that tries a single-line update of the
8019 line containing the cursor in the selected window. */
8020 CHARPOS (this_line_start_pos) = 0;
8022 /* Let the overlay arrow be updated the next time. */
8023 if (!NILP (last_arrow_position))
8025 last_arrow_position = Qt;
8026 last_arrow_string = Qt;
8029 /* If we pause after scrolling, some rows in the current
8030 matrices of some windows are not valid. */
8031 if (!WINDOW_FULL_WIDTH_P (w)
8032 && !FRAME_WINDOW_P (XFRAME (w->frame)))
8033 update_mode_lines = 1;
8036 /* Now text on frame agrees with windows, so put info into the
8037 windows for partial redisplay to follow. */
8038 if (!pause)
8040 register struct buffer *b = XBUFFER (w->buffer);
8042 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
8043 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
8044 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
8045 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
8047 if (consider_all_windows_p)
8048 mark_window_display_accurate (FRAME_ROOT_WINDOW (sf), 1);
8049 else
8051 XSETFASTINT (w->last_point, BUF_PT (b));
8052 w->last_cursor = w->cursor;
8053 w->last_cursor_off_p = w->cursor_off_p;
8055 b->clip_changed = 0;
8056 b->prevent_redisplay_optimizations_p = 0;
8057 w->update_mode_line = Qnil;
8058 XSETFASTINT (w->last_modified, BUF_MODIFF (b));
8059 XSETFASTINT (w->last_overlay_modified, BUF_OVERLAY_MODIFF (b));
8060 w->last_had_star
8061 = (BUF_MODIFF (XBUFFER (w->buffer)) > BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8062 ? Qt : Qnil);
8064 /* Record if we are showing a region, so can make sure to
8065 update it fully at next redisplay. */
8066 w->region_showing = (!NILP (Vtransient_mark_mode)
8067 && (EQ (selected_window,
8068 current_buffer->last_selected_window)
8069 || highlight_nonselected_windows)
8070 && !NILP (XBUFFER (w->buffer)->mark_active)
8071 ? Fmarker_position (XBUFFER (w->buffer)->mark)
8072 : Qnil);
8074 w->window_end_valid = w->buffer;
8075 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
8076 last_arrow_string = Voverlay_arrow_string;
8077 if (frame_up_to_date_hook != 0)
8078 (*frame_up_to_date_hook) (sf);
8080 w->current_matrix->buffer = b;
8081 w->current_matrix->begv = BUF_BEGV (b);
8082 w->current_matrix->zv = BUF_ZV (b);
8085 update_mode_lines = 0;
8086 windows_or_buffers_changed = 0;
8089 /* Start SIGIO interrupts coming again. Having them off during the
8090 code above makes it less likely one will discard output, but not
8091 impossible, since there might be stuff in the system buffer here.
8092 But it is much hairier to try to do anything about that. */
8093 if (interrupt_input)
8094 request_sigio ();
8095 start_polling ();
8097 /* If a frame has become visible which was not before, redisplay
8098 again, so that we display it. Expose events for such a frame
8099 (which it gets when becoming visible) don't call the parts of
8100 redisplay constructing glyphs, so simply exposing a frame won't
8101 display anything in this case. So, we have to display these
8102 frames here explicitly. */
8103 if (!pause)
8105 Lisp_Object tail, frame;
8106 int new_count = 0;
8108 FOR_EACH_FRAME (tail, frame)
8110 int this_is_visible = 0;
8112 if (XFRAME (frame)->visible)
8113 this_is_visible = 1;
8114 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
8115 if (XFRAME (frame)->visible)
8116 this_is_visible = 1;
8118 if (this_is_visible)
8119 new_count++;
8122 if (new_count != number_of_visible_frames)
8123 windows_or_buffers_changed++;
8126 /* Change frame size now if a change is pending. */
8127 do_pending_window_change (1);
8129 /* If we just did a pending size change, or have additional
8130 visible frames, redisplay again. */
8131 if (windows_or_buffers_changed && !pause)
8132 goto retry;
8134 end_of_redisplay:;
8136 unbind_to (count, Qnil);
8140 /* Redisplay, but leave alone any recent echo area message unless
8141 another message has been requested in its place.
8143 This is useful in situations where you need to redisplay but no
8144 user action has occurred, making it inappropriate for the message
8145 area to be cleared. See tracking_off and
8146 wait_reading_process_input for examples of these situations. */
8148 void
8149 redisplay_preserve_echo_area ()
8151 if (!NILP (echo_area_buffer[1]))
8153 /* We have a previously displayed message, but no current
8154 message. Redisplay the previous message. */
8155 display_last_displayed_message_p = 1;
8156 redisplay_internal (1);
8157 display_last_displayed_message_p = 0;
8159 else
8160 redisplay_internal (1);
8164 /* Function registered with record_unwind_protect in
8165 redisplay_internal. Clears the flag indicating that a redisplay is
8166 in progress. */
8168 static Lisp_Object
8169 unwind_redisplay (old_redisplaying_p)
8170 Lisp_Object old_redisplaying_p;
8172 redisplaying_p = XFASTINT (old_redisplaying_p);
8173 return Qnil;
8177 /* Mark the display of windows in the window tree rooted at WINDOW as
8178 accurate or inaccurate. If FLAG is non-zero mark display of WINDOW
8179 as accurate. If FLAG is zero arrange for WINDOW to be redisplayed
8180 the next time redisplay_internal is called. */
8182 void
8183 mark_window_display_accurate (window, accurate_p)
8184 Lisp_Object window;
8185 int accurate_p;
8187 struct window *w;
8189 for (; !NILP (window); window = w->next)
8191 w = XWINDOW (window);
8193 if (BUFFERP (w->buffer))
8195 struct buffer *b = XBUFFER (w->buffer);
8197 XSETFASTINT (w->last_modified,
8198 accurate_p ? BUF_MODIFF (b) : 0);
8199 XSETFASTINT (w->last_overlay_modified,
8200 accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
8201 w->last_had_star = (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b)
8202 ? Qt : Qnil);
8204 #if 0 /* I don't think this is necessary because display_line does it.
8205 Let's check it. */
8206 /* Record if we are showing a region, so can make sure to
8207 update it fully at next redisplay. */
8208 w->region_showing
8209 = (!NILP (Vtransient_mark_mode)
8210 && (w == XWINDOW (current_buffer->last_selected_window)
8211 || highlight_nonselected_windows)
8212 && (!NILP (b->mark_active)
8213 ? Fmarker_position (b->mark)
8214 : Qnil));
8215 #endif
8217 if (accurate_p)
8219 b->clip_changed = 0;
8220 b->prevent_redisplay_optimizations_p = 0;
8221 w->current_matrix->buffer = b;
8222 w->current_matrix->begv = BUF_BEGV (b);
8223 w->current_matrix->zv = BUF_ZV (b);
8224 w->last_cursor = w->cursor;
8225 w->last_cursor_off_p = w->cursor_off_p;
8226 if (w == XWINDOW (selected_window))
8227 w->last_point = make_number (BUF_PT (b));
8228 else
8229 w->last_point = make_number (XMARKER (w->pointm)->charpos);
8233 w->window_end_valid = w->buffer;
8234 w->update_mode_line = Qnil;
8236 if (!NILP (w->vchild))
8237 mark_window_display_accurate (w->vchild, accurate_p);
8238 if (!NILP (w->hchild))
8239 mark_window_display_accurate (w->hchild, accurate_p);
8242 if (accurate_p)
8244 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
8245 last_arrow_string = Voverlay_arrow_string;
8247 else
8249 /* Force a thorough redisplay the next time by setting
8250 last_arrow_position and last_arrow_string to t, which is
8251 unequal to any useful value of Voverlay_arrow_... */
8252 last_arrow_position = Qt;
8253 last_arrow_string = Qt;
8258 /* Return value in display table DP (Lisp_Char_Table *) for character
8259 C. Since a display table doesn't have any parent, we don't have to
8260 follow parent. Do not call this function directly but use the
8261 macro DISP_CHAR_VECTOR. */
8263 Lisp_Object
8264 disp_char_vector (dp, c)
8265 struct Lisp_Char_Table *dp;
8266 int c;
8268 int code[4], i;
8269 Lisp_Object val;
8271 if (SINGLE_BYTE_CHAR_P (c))
8272 return (dp->contents[c]);
8274 SPLIT_CHAR (c, code[0], code[1], code[2]);
8275 if (code[1] < 32)
8276 code[1] = -1;
8277 else if (code[2] < 32)
8278 code[2] = -1;
8280 /* Here, the possible range of code[0] (== charset ID) is
8281 128..max_charset. Since the top level char table contains data
8282 for multibyte characters after 256th element, we must increment
8283 code[0] by 128 to get a correct index. */
8284 code[0] += 128;
8285 code[3] = -1; /* anchor */
8287 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
8289 val = dp->contents[code[i]];
8290 if (!SUB_CHAR_TABLE_P (val))
8291 return (NILP (val) ? dp->defalt : val);
8294 /* Here, val is a sub char table. We return the default value of
8295 it. */
8296 return (dp->defalt);
8301 /***********************************************************************
8302 Window Redisplay
8303 ***********************************************************************/
8305 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
8307 static void
8308 redisplay_windows (window)
8309 Lisp_Object window;
8311 while (!NILP (window))
8313 struct window *w = XWINDOW (window);
8315 if (!NILP (w->hchild))
8316 redisplay_windows (w->hchild);
8317 else if (!NILP (w->vchild))
8318 redisplay_windows (w->vchild);
8319 else
8320 redisplay_window (window, 0);
8322 window = w->next;
8327 /* Set cursor position of W. PT is assumed to be displayed in ROW.
8328 DELTA is the number of bytes by which positions recorded in ROW
8329 differ from current buffer positions. */
8331 void
8332 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
8333 struct window *w;
8334 struct glyph_row *row;
8335 struct glyph_matrix *matrix;
8336 int delta, delta_bytes, dy, dvpos;
8338 struct glyph *glyph = row->glyphs[TEXT_AREA];
8339 struct glyph *end = glyph + row->used[TEXT_AREA];
8340 int x = row->x;
8341 int pt_old = PT - delta;
8343 /* Skip over glyphs not having an object at the start of the row.
8344 These are special glyphs like truncation marks on terminal
8345 frames. */
8346 if (row->displays_text_p)
8347 while (glyph < end
8348 && INTEGERP (glyph->object)
8349 && glyph->charpos < 0)
8351 x += glyph->pixel_width;
8352 ++glyph;
8355 while (glyph < end
8356 && !INTEGERP (glyph->object)
8357 && (!BUFFERP (glyph->object)
8358 || glyph->charpos < pt_old))
8360 x += glyph->pixel_width;
8361 ++glyph;
8364 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
8365 w->cursor.x = x;
8366 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
8367 w->cursor.y = row->y + dy;
8369 if (w == XWINDOW (selected_window))
8371 if (!row->continued_p
8372 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
8373 && row->x == 0)
8375 this_line_buffer = XBUFFER (w->buffer);
8377 CHARPOS (this_line_start_pos)
8378 = MATRIX_ROW_START_CHARPOS (row) + delta;
8379 BYTEPOS (this_line_start_pos)
8380 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
8382 CHARPOS (this_line_end_pos)
8383 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
8384 BYTEPOS (this_line_end_pos)
8385 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
8387 this_line_y = w->cursor.y;
8388 this_line_pixel_height = row->height;
8389 this_line_vpos = w->cursor.vpos;
8390 this_line_start_x = row->x;
8392 else
8393 CHARPOS (this_line_start_pos) = 0;
8398 /* Run window scroll functions, if any, for WINDOW with new window
8399 start STARTP. Sets the window start of WINDOW to that position.
8401 We assume that the window's buffer is really current. */
8403 static INLINE struct text_pos
8404 run_window_scroll_functions (window, startp)
8405 Lisp_Object window;
8406 struct text_pos startp;
8408 struct window *w = XWINDOW (window);
8409 SET_MARKER_FROM_TEXT_POS (w->start, startp);
8411 if (current_buffer != XBUFFER (w->buffer))
8412 abort ();
8414 if (!NILP (Vwindow_scroll_functions))
8416 run_hook_with_args_2 (Qwindow_scroll_functions, window,
8417 make_number (CHARPOS (startp)));
8418 SET_TEXT_POS_FROM_MARKER (startp, w->start);
8419 /* In case the hook functions switch buffers. */
8420 if (current_buffer != XBUFFER (w->buffer))
8421 set_buffer_internal_1 (XBUFFER (w->buffer));
8424 return startp;
8428 /* Modify the desired matrix of window W and W->vscroll so that the
8429 line containing the cursor is fully visible. */
8431 static void
8432 make_cursor_line_fully_visible (w)
8433 struct window *w;
8435 struct glyph_matrix *matrix;
8436 struct glyph_row *row;
8437 int window_height, header_line_height;
8439 /* It's not always possible to find the cursor, e.g, when a window
8440 is full of overlay strings. Don't do anything in that case. */
8441 if (w->cursor.vpos < 0)
8442 return;
8444 matrix = w->desired_matrix;
8445 row = MATRIX_ROW (matrix, w->cursor.vpos);
8447 /* If the cursor row is not partially visible, there's nothing
8448 to do. */
8449 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
8450 return;
8452 /* If the row the cursor is in is taller than the window's height,
8453 it's not clear what to do, so do nothing. */
8454 window_height = window_box_height (w);
8455 if (row->height >= window_height)
8456 return;
8458 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
8460 int dy = row->height - row->visible_height;
8461 w->vscroll = 0;
8462 w->cursor.y += dy;
8463 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
8465 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
8467 int dy = - (row->height - row->visible_height);
8468 w->vscroll = dy;
8469 w->cursor.y += dy;
8470 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
8473 /* When we change the cursor y-position of the selected window,
8474 change this_line_y as well so that the display optimization for
8475 the cursor line of the selected window in redisplay_internal uses
8476 the correct y-position. */
8477 if (w == XWINDOW (selected_window))
8478 this_line_y = w->cursor.y;
8482 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
8483 non-zero means only WINDOW is redisplayed in redisplay_internal.
8484 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
8485 in redisplay_window to bring a partially visible line into view in
8486 the case that only the cursor has moved.
8488 Value is
8490 1 if scrolling succeeded
8492 0 if scrolling didn't find point.
8494 -1 if new fonts have been loaded so that we must interrupt
8495 redisplay, adjust glyph matrices, and try again. */
8497 static int
8498 try_scrolling (window, just_this_one_p, scroll_conservatively,
8499 scroll_step, temp_scroll_step)
8500 Lisp_Object window;
8501 int just_this_one_p;
8502 int scroll_conservatively, scroll_step;
8503 int temp_scroll_step;
8505 struct window *w = XWINDOW (window);
8506 struct frame *f = XFRAME (w->frame);
8507 struct text_pos scroll_margin_pos;
8508 struct text_pos pos;
8509 struct text_pos startp;
8510 struct it it;
8511 Lisp_Object window_end;
8512 int this_scroll_margin;
8513 int dy = 0;
8514 int scroll_max;
8515 int line_height, rc;
8516 int amount_to_scroll = 0;
8517 Lisp_Object aggressive;
8518 int height;
8520 #if GLYPH_DEBUG
8521 debug_method_add (w, "try_scrolling");
8522 #endif
8524 SET_TEXT_POS_FROM_MARKER (startp, w->start);
8526 /* Compute scroll margin height in pixels. We scroll when point is
8527 within this distance from the top or bottom of the window. */
8528 if (scroll_margin > 0)
8530 this_scroll_margin = min (scroll_margin, XINT (w->height) / 4);
8531 this_scroll_margin *= CANON_Y_UNIT (f);
8533 else
8534 this_scroll_margin = 0;
8536 /* Compute how much we should try to scroll maximally to bring point
8537 into view. */
8538 if (scroll_step)
8539 scroll_max = scroll_step;
8540 else if (scroll_conservatively)
8541 scroll_max = scroll_conservatively;
8542 else if (temp_scroll_step)
8543 scroll_max = temp_scroll_step;
8544 else if (NUMBERP (current_buffer->scroll_down_aggressively)
8545 || NUMBERP (current_buffer->scroll_up_aggressively))
8546 /* We're trying to scroll because of aggressive scrolling
8547 but no scroll_step is set. Choose an arbitrary one. Maybe
8548 there should be a variable for this. */
8549 scroll_max = 10;
8550 else
8551 scroll_max = 0;
8552 scroll_max *= CANON_Y_UNIT (f);
8554 /* Decide whether we have to scroll down. Start at the window end
8555 and move this_scroll_margin up to find the position of the scroll
8556 margin. */
8557 window_end = Fwindow_end (window, Qt);
8558 CHARPOS (scroll_margin_pos) = XINT (window_end);
8559 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
8560 if (this_scroll_margin)
8562 start_display (&it, w, scroll_margin_pos);
8563 move_it_vertically (&it, - this_scroll_margin);
8564 scroll_margin_pos = it.current.pos;
8567 if (PT >= CHARPOS (scroll_margin_pos))
8569 int y0;
8571 /* Point is in the scroll margin at the bottom of the window, or
8572 below. Compute a new window start that makes point visible. */
8574 /* Compute the distance from the scroll margin to PT.
8575 Give up if the distance is greater than scroll_max. */
8576 start_display (&it, w, scroll_margin_pos);
8577 y0 = it.current_y;
8578 move_it_to (&it, PT, 0, it.last_visible_y, -1,
8579 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
8580 line_height = (it.max_ascent + it.max_descent
8581 ? it.max_ascent + it.max_descent
8582 : last_height);
8583 dy = it.current_y + line_height - y0;
8585 if (dy > scroll_max)
8586 return 0;
8588 /* Move the window start down. If scrolling conservatively,
8589 move it just enough down to make point visible. If
8590 scroll_step is set, move it down by scroll_step. */
8591 start_display (&it, w, startp);
8593 if (scroll_conservatively)
8594 amount_to_scroll = dy;
8595 else if (scroll_step || temp_scroll_step)
8596 amount_to_scroll = scroll_max;
8597 else
8599 aggressive = current_buffer->scroll_down_aggressively;
8600 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
8601 - WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w));
8602 if (NUMBERP (aggressive))
8603 amount_to_scroll = XFLOATINT (aggressive) * height;
8606 if (amount_to_scroll <= 0)
8607 return 0;
8609 move_it_vertically (&it, amount_to_scroll);
8610 startp = it.current.pos;
8612 else
8614 /* See if point is inside the scroll margin at the top of the
8615 window. */
8616 scroll_margin_pos = startp;
8617 if (this_scroll_margin)
8619 start_display (&it, w, startp);
8620 move_it_vertically (&it, this_scroll_margin);
8621 scroll_margin_pos = it.current.pos;
8624 if (PT < CHARPOS (scroll_margin_pos))
8626 /* Point is in the scroll margin at the top of the window or
8627 above what is displayed in the window. */
8628 int y0;
8630 /* Compute the vertical distance from PT to the scroll
8631 margin position. Give up if distance is greater than
8632 scroll_max. */
8633 SET_TEXT_POS (pos, PT, PT_BYTE);
8634 start_display (&it, w, pos);
8635 y0 = it.current_y;
8636 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
8637 it.last_visible_y, -1,
8638 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
8639 dy = it.current_y - y0;
8640 if (dy > scroll_max)
8641 return 0;
8643 /* Compute new window start. */
8644 start_display (&it, w, startp);
8646 if (scroll_conservatively)
8647 amount_to_scroll = dy;
8648 else if (scroll_step || temp_scroll_step)
8649 amount_to_scroll = scroll_max;
8650 else
8652 aggressive = current_buffer->scroll_up_aggressively;
8653 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
8654 - WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w));
8655 if (NUMBERP (aggressive))
8656 amount_to_scroll = XFLOATINT (aggressive) * height;
8659 if (amount_to_scroll <= 0)
8660 return 0;
8662 move_it_vertically (&it, - amount_to_scroll);
8663 startp = it.current.pos;
8667 /* Run window scroll functions. */
8668 startp = run_window_scroll_functions (window, startp);
8670 /* Display the window. Give up if new fonts are loaded, or if point
8671 doesn't appear. */
8672 if (!try_window (window, startp))
8673 rc = -1;
8674 else if (w->cursor.vpos < 0)
8676 clear_glyph_matrix (w->desired_matrix);
8677 rc = 0;
8679 else
8681 /* Maybe forget recorded base line for line number display. */
8682 if (!just_this_one_p
8683 || current_buffer->clip_changed
8684 || BEG_UNCHANGED < CHARPOS (startp))
8685 w->base_line_number = Qnil;
8687 /* If cursor ends up on a partially visible line, shift display
8688 lines up or down. */
8689 make_cursor_line_fully_visible (w);
8690 rc = 1;
8693 return rc;
8697 /* Compute a suitable window start for window W if display of W starts
8698 on a continuation line. Value is non-zero if a new window start
8699 was computed.
8701 The new window start will be computed, based on W's width, starting
8702 from the start of the continued line. It is the start of the
8703 screen line with the minimum distance from the old start W->start. */
8705 static int
8706 compute_window_start_on_continuation_line (w)
8707 struct window *w;
8709 struct text_pos pos, start_pos;
8710 int window_start_changed_p = 0;
8712 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
8714 /* If window start is on a continuation line... Window start may be
8715 < BEGV in case there's invisible text at the start of the
8716 buffer (M-x rmail, for example). */
8717 if (CHARPOS (start_pos) > BEGV
8718 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
8720 struct it it;
8721 struct glyph_row *row;
8723 /* Handle the case that the window start is out of range. */
8724 if (CHARPOS (start_pos) < BEGV)
8725 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
8726 else if (CHARPOS (start_pos) > ZV)
8727 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
8729 /* Find the start of the continued line. This should be fast
8730 because scan_buffer is fast (newline cache). */
8731 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
8732 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
8733 row, DEFAULT_FACE_ID);
8734 reseat_at_previous_visible_line_start (&it);
8736 /* If the line start is "too far" away from the window start,
8737 say it takes too much time to compute a new window start. */
8738 if (CHARPOS (start_pos) - IT_CHARPOS (it)
8739 < XFASTINT (w->height) * XFASTINT (w->width))
8741 int min_distance, distance;
8743 /* Move forward by display lines to find the new window
8744 start. If window width was enlarged, the new start can
8745 be expected to be > the old start. If window width was
8746 decreased, the new window start will be < the old start.
8747 So, we're looking for the display line start with the
8748 minimum distance from the old window start. */
8749 pos = it.current.pos;
8750 min_distance = INFINITY;
8751 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
8752 distance < min_distance)
8754 min_distance = distance;
8755 pos = it.current.pos;
8756 move_it_by_lines (&it, 1, 0);
8759 /* Set the window start there. */
8760 SET_MARKER_FROM_TEXT_POS (w->start, pos);
8761 window_start_changed_p = 1;
8765 return window_start_changed_p;
8769 /* Try cursor movement in case text has not changes in window WINDOW,
8770 with window start STARTP. Value is
8772 1 if successful
8774 0 if this method cannot be used
8776 -1 if we know we have to scroll the display. *SCROLL_STEP is
8777 set to 1, under certain circumstances, if we want to scroll as
8778 if scroll-step were set to 1. See the code. */
8780 static int
8781 try_cursor_movement (window, startp, scroll_step)
8782 Lisp_Object window;
8783 struct text_pos startp;
8784 int *scroll_step;
8786 struct window *w = XWINDOW (window);
8787 struct frame *f = XFRAME (w->frame);
8788 int rc = 0;
8790 /* Handle case where text has not changed, only point, and it has
8791 not moved off the frame. */
8792 if (/* Point may be in this window. */
8793 PT >= CHARPOS (startp)
8794 /* If we don't check this, we are called to move the cursor in a
8795 horizontally split window with a current matrix that doesn't
8796 fit the display. */
8797 && !windows_or_buffers_changed
8798 /* Selective display hasn't changed. */
8799 && !current_buffer->clip_changed
8800 /* If force-mode-line-update was called, really redisplay;
8801 that's how redisplay is forced after e.g. changing
8802 buffer-invisibility-spec. */
8803 && NILP (w->update_mode_line)
8804 /* Can't use this case if highlighting a region. When a
8805 region exists, cursor movement has to do more than just
8806 set the cursor. */
8807 && !(!NILP (Vtransient_mark_mode)
8808 && !NILP (current_buffer->mark_active))
8809 && NILP (w->region_showing)
8810 && NILP (Vshow_trailing_whitespace)
8811 /* Right after splitting windows, last_point may be nil. */
8812 && INTEGERP (w->last_point)
8813 /* This code is not used for mini-buffer for the sake of the case
8814 of redisplaying to replace an echo area message; since in
8815 that case the mini-buffer contents per se are usually
8816 unchanged. This code is of no real use in the mini-buffer
8817 since the handling of this_line_start_pos, etc., in redisplay
8818 handles the same cases. */
8819 && !EQ (window, minibuf_window)
8820 /* When splitting windows or for new windows, it happens that
8821 redisplay is called with a nil window_end_vpos or one being
8822 larger than the window. This should really be fixed in
8823 window.c. I don't have this on my list, now, so we do
8824 approximately the same as the old redisplay code. --gerd. */
8825 && INTEGERP (w->window_end_vpos)
8826 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
8827 && (FRAME_WINDOW_P (f)
8828 || !MARKERP (Voverlay_arrow_position)
8829 || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
8831 int this_scroll_margin;
8832 struct glyph_row *row;
8834 #if GLYPH_DEBUG
8835 debug_method_add (w, "cursor movement");
8836 #endif
8838 /* Scroll if point within this distance from the top or bottom
8839 of the window. This is a pixel value. */
8840 this_scroll_margin = max (0, scroll_margin);
8841 this_scroll_margin = min (this_scroll_margin, XFASTINT (w->height) / 4);
8842 this_scroll_margin *= CANON_Y_UNIT (f);
8844 /* Start with the row the cursor was displayed during the last
8845 not paused redisplay. Give up if that row is not valid. */
8846 if (w->last_cursor.vpos >= w->current_matrix->nrows)
8847 rc = -1;
8848 else
8850 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
8851 if (row->mode_line_p)
8852 ++row;
8853 if (!row->enabled_p)
8854 rc = -1;
8857 if (rc == 0)
8859 int scroll_p = 0;
8861 if (PT > XFASTINT (w->last_point))
8863 /* Point has moved forward. */
8864 int last_y = window_text_bottom_y (w) - this_scroll_margin;
8866 while (MATRIX_ROW_END_CHARPOS (row) < PT
8867 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
8869 xassert (row->enabled_p);
8870 ++row;
8873 /* The end position of a row equals the start position
8874 of the next row. If PT is there, we would rather
8875 display it in the next line. Exceptions are when the
8876 row ends in the middle of a character, or ends in
8877 ZV. */
8878 if (MATRIX_ROW_BOTTOM_Y (row) < last_y
8879 && MATRIX_ROW_END_CHARPOS (row) == PT
8880 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
8881 && !row->ends_at_zv_p)
8883 xassert (row->enabled_p);
8884 ++row;
8887 /* If within the scroll margin, scroll. Note that
8888 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
8889 the next line would be drawn, and that
8890 this_scroll_margin can be zero. */
8891 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
8892 || PT > MATRIX_ROW_END_CHARPOS (row)
8893 /* Line is completely visible last line in window
8894 and PT is to be set in the next line. */
8895 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
8896 && PT == MATRIX_ROW_END_CHARPOS (row)
8897 && !row->ends_at_zv_p
8898 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
8899 scroll_p = 1;
8901 else if (PT < XFASTINT (w->last_point))
8903 /* Cursor has to be moved backward. Note that PT >=
8904 CHARPOS (startp) because of the outer
8905 if-statement. */
8906 while (!row->mode_line_p
8907 && (MATRIX_ROW_START_CHARPOS (row) > PT
8908 || (MATRIX_ROW_START_CHARPOS (row) == PT
8909 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
8910 && (row->y > this_scroll_margin
8911 || CHARPOS (startp) == BEGV))
8913 xassert (row->enabled_p);
8914 --row;
8917 /* Consider the following case: Window starts at BEGV,
8918 there is invisible, intangible text at BEGV, so that
8919 display starts at some point START > BEGV. It can
8920 happen that we are called with PT somewhere between
8921 BEGV and START. Try to handle that case. */
8922 if (row < w->current_matrix->rows
8923 || row->mode_line_p)
8925 row = w->current_matrix->rows;
8926 if (row->mode_line_p)
8927 ++row;
8930 /* Due to newlines in overlay strings, we may have to
8931 skip forward over overlay strings. */
8932 while (MATRIX_ROW_END_CHARPOS (row) == PT
8933 && MATRIX_ROW_ENDS_IN_OVERLAY_STRING_P (row)
8934 && !row->ends_at_zv_p)
8935 ++row;
8937 /* If within the scroll margin, scroll. */
8938 if (row->y < this_scroll_margin
8939 && CHARPOS (startp) != BEGV)
8940 scroll_p = 1;
8943 if (PT < MATRIX_ROW_START_CHARPOS (row)
8944 || PT > MATRIX_ROW_END_CHARPOS (row))
8946 /* if PT is not in the glyph row, give up. */
8947 rc = -1;
8949 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
8951 /* If we end up in a partially visible line, let's make it
8952 fully visible, except when it's taller than the window,
8953 in which case we can't do much about it. */
8954 if (row->height > window_box_height (w))
8956 *scroll_step = 1;
8957 rc = -1;
8959 else
8961 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
8962 try_window (window, startp);
8963 make_cursor_line_fully_visible (w);
8964 rc = 1;
8967 else if (scroll_p)
8968 rc = -1;
8969 else
8971 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
8972 rc = 1;
8977 return rc;
8981 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
8982 selected_window is redisplayed. */
8984 static void
8985 redisplay_window (window, just_this_one_p)
8986 Lisp_Object window;
8987 int just_this_one_p;
8989 struct window *w = XWINDOW (window);
8990 struct frame *f = XFRAME (w->frame);
8991 struct buffer *buffer = XBUFFER (w->buffer);
8992 struct buffer *old = current_buffer;
8993 struct text_pos lpoint, opoint, startp;
8994 int update_mode_line;
8995 int tem;
8996 struct it it;
8997 /* Record it now because it's overwritten. */
8998 int current_matrix_up_to_date_p = 0;
8999 int temp_scroll_step = 0;
9000 int count = specpdl_ptr - specpdl;
9001 int rc;
9003 SET_TEXT_POS (lpoint, PT, PT_BYTE);
9004 opoint = lpoint;
9006 /* W must be a leaf window here. */
9007 xassert (!NILP (w->buffer));
9008 #if GLYPH_DEBUG
9009 *w->desired_matrix->method = 0;
9010 #endif
9012 specbind (Qinhibit_point_motion_hooks, Qt);
9014 reconsider_clip_changes (w, buffer);
9016 /* Has the mode line to be updated? */
9017 update_mode_line = (!NILP (w->update_mode_line)
9018 || update_mode_lines
9019 || buffer->clip_changed);
9021 if (MINI_WINDOW_P (w))
9023 if (w == XWINDOW (echo_area_window)
9024 && !NILP (echo_area_buffer[0]))
9026 if (update_mode_line)
9027 /* We may have to update a tty frame's menu bar or a
9028 tool-bar. Example `M-x C-h C-h C-g'. */
9029 goto finish_menu_bars;
9030 else
9031 /* We've already displayed the echo area glyphs in this window. */
9032 goto finish_scroll_bars;
9034 else if (w != XWINDOW (minibuf_window))
9036 /* W is a mini-buffer window, but it's not the currently
9037 active one, so clear it. */
9038 int yb = window_text_bottom_y (w);
9039 struct glyph_row *row;
9040 int y;
9042 for (y = 0, row = w->desired_matrix->rows;
9043 y < yb;
9044 y += row->height, ++row)
9045 blank_row (w, row, y);
9046 goto finish_scroll_bars;
9050 /* Otherwise set up data on this window; select its buffer and point
9051 value. */
9052 /* Really select the buffer, for the sake of buffer-local
9053 variables. */
9054 set_buffer_internal_1 (XBUFFER (w->buffer));
9055 SET_TEXT_POS (opoint, PT, PT_BYTE);
9057 current_matrix_up_to_date_p
9058 = (!NILP (w->window_end_valid)
9059 && !current_buffer->clip_changed
9060 && XFASTINT (w->last_modified) >= MODIFF
9061 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
9063 /* When windows_or_buffers_changed is non-zero, we can't rely on
9064 the window end being valid, so set it to nil there. */
9065 if (windows_or_buffers_changed)
9067 /* If window starts on a continuation line, maybe adjust the
9068 window start in case the window's width changed. */
9069 if (XMARKER (w->start)->buffer == current_buffer)
9070 compute_window_start_on_continuation_line (w);
9072 w->window_end_valid = Qnil;
9075 /* Some sanity checks. */
9076 CHECK_WINDOW_END (w);
9077 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
9078 abort ();
9079 if (BYTEPOS (opoint) < CHARPOS (opoint))
9080 abort ();
9082 /* If %c is in mode line, update it if needed. */
9083 if (!NILP (w->column_number_displayed)
9084 /* This alternative quickly identifies a common case
9085 where no change is needed. */
9086 && !(PT == XFASTINT (w->last_point)
9087 && XFASTINT (w->last_modified) >= MODIFF
9088 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9089 && XFASTINT (w->column_number_displayed) != current_column ())
9090 update_mode_line = 1;
9092 /* Count number of windows showing the selected buffer. An indirect
9093 buffer counts as its base buffer. */
9094 if (!just_this_one_p)
9096 struct buffer *current_base, *window_base;
9097 current_base = current_buffer;
9098 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
9099 if (current_base->base_buffer)
9100 current_base = current_base->base_buffer;
9101 if (window_base->base_buffer)
9102 window_base = window_base->base_buffer;
9103 if (current_base == window_base)
9104 buffer_shared++;
9107 /* Point refers normally to the selected window. For any other
9108 window, set up appropriate value. */
9109 if (!EQ (window, selected_window))
9111 int new_pt = XMARKER (w->pointm)->charpos;
9112 int new_pt_byte = marker_byte_position (w->pointm);
9113 if (new_pt < BEGV)
9115 new_pt = BEGV;
9116 new_pt_byte = BEGV_BYTE;
9117 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
9119 else if (new_pt > (ZV - 1))
9121 new_pt = ZV;
9122 new_pt_byte = ZV_BYTE;
9123 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
9126 /* We don't use SET_PT so that the point-motion hooks don't run. */
9127 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
9130 /* If any of the character widths specified in the display table
9131 have changed, invalidate the width run cache. It's true that
9132 this may be a bit late to catch such changes, but the rest of
9133 redisplay goes (non-fatally) haywire when the display table is
9134 changed, so why should we worry about doing any better? */
9135 if (current_buffer->width_run_cache)
9137 struct Lisp_Char_Table *disptab = buffer_display_table ();
9139 if (! disptab_matches_widthtab (disptab,
9140 XVECTOR (current_buffer->width_table)))
9142 invalidate_region_cache (current_buffer,
9143 current_buffer->width_run_cache,
9144 BEG, Z);
9145 recompute_width_table (current_buffer, disptab);
9149 /* If window-start is screwed up, choose a new one. */
9150 if (XMARKER (w->start)->buffer != current_buffer)
9151 goto recenter;
9153 SET_TEXT_POS_FROM_MARKER (startp, w->start);
9155 /* If someone specified a new starting point but did not insist,
9156 check whether it can be used. */
9157 if (!NILP (w->optional_new_start)
9158 && CHARPOS (startp) >= BEGV
9159 && CHARPOS (startp) <= ZV)
9161 w->optional_new_start = Qnil;
9162 start_display (&it, w, startp);
9163 move_it_to (&it, PT, 0, it.last_visible_y, -1,
9164 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
9165 if (IT_CHARPOS (it) == PT)
9166 w->force_start = Qt;
9169 /* Handle case where place to start displaying has been specified,
9170 unless the specified location is outside the accessible range. */
9171 if (!NILP (w->force_start)
9172 || w->frozen_window_start_p)
9174 w->force_start = Qnil;
9175 w->vscroll = 0;
9176 w->window_end_valid = Qnil;
9178 /* Forget any recorded base line for line number display. */
9179 if (!current_matrix_up_to_date_p
9180 || current_buffer->clip_changed)
9181 w->base_line_number = Qnil;
9183 /* Redisplay the mode line. Select the buffer properly for that.
9184 Also, run the hook window-scroll-functions
9185 because we have scrolled. */
9186 /* Note, we do this after clearing force_start because
9187 if there's an error, it is better to forget about force_start
9188 than to get into an infinite loop calling the hook functions
9189 and having them get more errors. */
9190 if (!update_mode_line
9191 || ! NILP (Vwindow_scroll_functions))
9193 update_mode_line = 1;
9194 w->update_mode_line = Qt;
9195 startp = run_window_scroll_functions (window, startp);
9198 XSETFASTINT (w->last_modified, 0);
9199 XSETFASTINT (w->last_overlay_modified, 0);
9200 if (CHARPOS (startp) < BEGV)
9201 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
9202 else if (CHARPOS (startp) > ZV)
9203 SET_TEXT_POS (startp, ZV, ZV_BYTE);
9205 /* Redisplay, then check if cursor has been set during the
9206 redisplay. Give up if new fonts were loaded. */
9207 if (!try_window (window, startp))
9209 w->force_start = Qt;
9210 clear_glyph_matrix (w->desired_matrix);
9211 goto restore_buffers;
9214 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
9216 /* If point does not appear, try to move point so it does
9217 appear. The desired matrix has been built above, so we
9218 can use it here. */
9219 int window_height;
9220 struct glyph_row *row;
9222 window_height = window_box_height (w) / 2;
9223 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
9224 while (MATRIX_ROW_BOTTOM_Y (row) < window_height)
9225 ++row;
9227 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
9228 MATRIX_ROW_START_BYTEPOS (row));
9230 if (w != XWINDOW (selected_window))
9231 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
9232 else if (current_buffer == old)
9233 SET_TEXT_POS (lpoint, PT, PT_BYTE);
9235 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
9237 /* If we are highlighting the region, then we just changed
9238 the region, so redisplay to show it. */
9239 if (!NILP (Vtransient_mark_mode)
9240 && !NILP (current_buffer->mark_active))
9242 clear_glyph_matrix (w->desired_matrix);
9243 if (!try_window (window, startp))
9244 goto restore_buffers;
9248 make_cursor_line_fully_visible (w);
9249 #if GLYPH_DEBUG
9250 debug_method_add (w, "forced window start");
9251 #endif
9252 goto done;
9255 /* Handle case where text has not changed, only point, and it has
9256 not moved off the frame. */
9257 if (current_matrix_up_to_date_p
9258 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
9259 rc != 0))
9261 if (rc == -1)
9262 goto try_to_scroll;
9263 else
9264 goto done;
9266 /* If current starting point was originally the beginning of a line
9267 but no longer is, find a new starting point. */
9268 else if (!NILP (w->start_at_line_beg)
9269 && !(CHARPOS (startp) <= BEGV
9270 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
9272 #if GLYPH_DEBUG
9273 debug_method_add (w, "recenter 1");
9274 #endif
9275 goto recenter;
9278 /* Try scrolling with try_window_id. */
9279 else if (/* Windows and buffers haven't changed. */
9280 !windows_or_buffers_changed
9281 /* Window must be either use window-based redisplay or
9282 be full width. */
9283 && (FRAME_WINDOW_P (f)
9284 || (line_ins_del_ok && WINDOW_FULL_WIDTH_P (w)))
9285 && !MINI_WINDOW_P (w)
9286 /* Point is not known NOT to appear in window. */
9287 && PT >= CHARPOS (startp)
9288 && XFASTINT (w->last_modified)
9289 /* Window is not hscrolled. */
9290 && XFASTINT (w->hscroll) == 0
9291 /* Selective display has not changed. */
9292 && !current_buffer->clip_changed
9293 /* Current matrix is up to date. */
9294 && !NILP (w->window_end_valid)
9295 /* Can't use this case if highlighting a region because
9296 a cursor movement will do more than just set the cursor. */
9297 && !(!NILP (Vtransient_mark_mode)
9298 && !NILP (current_buffer->mark_active))
9299 && NILP (w->region_showing)
9300 && NILP (Vshow_trailing_whitespace)
9301 /* Overlay arrow position and string not changed. */
9302 && EQ (last_arrow_position, COERCE_MARKER (Voverlay_arrow_position))
9303 && EQ (last_arrow_string, Voverlay_arrow_string)
9304 /* Value is > 0 if update has been done, it is -1 if we
9305 know that the same window start will not work. It is 0
9306 if unsuccessful for some other reason. */
9307 && (tem = try_window_id (w)) != 0)
9309 #if GLYPH_DEBUG
9310 debug_method_add (w, "try_window_id %d", tem);
9311 #endif
9313 if (fonts_changed_p)
9314 goto restore_buffers;
9315 if (tem > 0)
9316 goto done;
9318 /* Otherwise try_window_id has returned -1 which means that we
9319 don't want the alternative below this comment to execute. */
9321 else if (CHARPOS (startp) >= BEGV
9322 && CHARPOS (startp) <= ZV
9323 && PT >= CHARPOS (startp)
9324 && (CHARPOS (startp) < ZV
9325 /* Avoid starting at end of buffer. */
9326 || CHARPOS (startp) == BEGV
9327 || (XFASTINT (w->last_modified) >= MODIFF
9328 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
9330 #if GLYPH_DEBUG
9331 debug_method_add (w, "same window start");
9332 #endif
9334 /* Try to redisplay starting at same place as before.
9335 If point has not moved off frame, accept the results. */
9336 if (!current_matrix_up_to_date_p
9337 /* Don't use try_window_reusing_current_matrix in this case
9338 because a window scroll function can have changed the
9339 buffer. */
9340 || !NILP (Vwindow_scroll_functions)
9341 || MINI_WINDOW_P (w)
9342 || !try_window_reusing_current_matrix (w))
9344 IF_DEBUG (debug_method_add (w, "1"));
9345 try_window (window, startp);
9348 if (fonts_changed_p)
9349 goto restore_buffers;
9351 if (w->cursor.vpos >= 0)
9353 if (!just_this_one_p
9354 || current_buffer->clip_changed
9355 || BEG_UNCHANGED < CHARPOS (startp))
9356 /* Forget any recorded base line for line number display. */
9357 w->base_line_number = Qnil;
9359 make_cursor_line_fully_visible (w);
9360 goto done;
9362 else
9363 clear_glyph_matrix (w->desired_matrix);
9366 try_to_scroll:
9368 XSETFASTINT (w->last_modified, 0);
9369 XSETFASTINT (w->last_overlay_modified, 0);
9371 /* Redisplay the mode line. Select the buffer properly for that. */
9372 if (!update_mode_line)
9374 update_mode_line = 1;
9375 w->update_mode_line = Qt;
9378 /* Try to scroll by specified few lines. */
9379 if ((scroll_conservatively
9380 || scroll_step
9381 || temp_scroll_step
9382 || NUMBERP (current_buffer->scroll_up_aggressively)
9383 || NUMBERP (current_buffer->scroll_down_aggressively))
9384 && !current_buffer->clip_changed
9385 && CHARPOS (startp) >= BEGV
9386 && CHARPOS (startp) <= ZV)
9388 /* The function returns -1 if new fonts were loaded, 1 if
9389 successful, 0 if not successful. */
9390 int rc = try_scrolling (window, just_this_one_p,
9391 scroll_conservatively,
9392 scroll_step,
9393 temp_scroll_step);
9394 if (rc > 0)
9395 goto done;
9396 else if (rc < 0)
9397 goto restore_buffers;
9400 /* Finally, just choose place to start which centers point */
9402 recenter:
9404 #if GLYPH_DEBUG
9405 debug_method_add (w, "recenter");
9406 #endif
9408 /* w->vscroll = 0; */
9410 /* Forget any previously recorded base line for line number display. */
9411 if (!current_matrix_up_to_date_p
9412 || current_buffer->clip_changed)
9413 w->base_line_number = Qnil;
9415 /* Move backward half the height of the window. */
9416 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
9417 it.current_y = it.last_visible_y;
9418 move_it_vertically_backward (&it, it.last_visible_y / 2);
9419 xassert (IT_CHARPOS (it) >= BEGV);
9421 /* The function move_it_vertically_backward may move over more
9422 than the specified y-distance. If it->w is small, e.g. a
9423 mini-buffer window, we may end up in front of the window's
9424 display area. Start displaying at the start of the line
9425 containing PT in this case. */
9426 if (it.current_y <= 0)
9428 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
9429 move_it_vertically (&it, 0);
9430 xassert (IT_CHARPOS (it) <= PT);
9431 it.current_y = 0;
9434 it.current_x = it.hpos = 0;
9436 /* Set startp here explicitly in case that helps avoid an infinite loop
9437 in case the window-scroll-functions functions get errors. */
9438 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
9440 /* Run scroll hooks. */
9441 startp = run_window_scroll_functions (window, it.current.pos);
9443 /* Redisplay the window. */
9444 if (!current_matrix_up_to_date_p
9445 || windows_or_buffers_changed
9446 /* Don't use try_window_reusing_current_matrix in this case
9447 because it can have changed the buffer. */
9448 || !NILP (Vwindow_scroll_functions)
9449 || !just_this_one_p
9450 || MINI_WINDOW_P (w)
9451 || !try_window_reusing_current_matrix (w))
9452 try_window (window, startp);
9454 /* If new fonts have been loaded (due to fontsets), give up. We
9455 have to start a new redisplay since we need to re-adjust glyph
9456 matrices. */
9457 if (fonts_changed_p)
9458 goto restore_buffers;
9460 /* If cursor did not appear assume that the middle of the window is
9461 in the first line of the window. Do it again with the next line.
9462 (Imagine a window of height 100, displaying two lines of height
9463 60. Moving back 50 from it->last_visible_y will end in the first
9464 line.) */
9465 if (w->cursor.vpos < 0)
9467 if (!NILP (w->window_end_valid)
9468 && PT >= Z - XFASTINT (w->window_end_pos))
9470 clear_glyph_matrix (w->desired_matrix);
9471 move_it_by_lines (&it, 1, 0);
9472 try_window (window, it.current.pos);
9474 else if (PT < IT_CHARPOS (it))
9476 clear_glyph_matrix (w->desired_matrix);
9477 move_it_by_lines (&it, -1, 0);
9478 try_window (window, it.current.pos);
9480 else
9482 /* Not much we can do about it. */
9486 /* Consider the following case: Window starts at BEGV, there is
9487 invisible, intangible text at BEGV, so that display starts at
9488 some point START > BEGV. It can happen that we are called with
9489 PT somewhere between BEGV and START. Try to handle that case. */
9490 if (w->cursor.vpos < 0)
9492 struct glyph_row *row = w->current_matrix->rows;
9493 if (row->mode_line_p)
9494 ++row;
9495 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
9498 make_cursor_line_fully_visible (w);
9500 done:
9502 SET_TEXT_POS_FROM_MARKER (startp, w->start);
9503 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
9504 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
9505 ? Qt : Qnil);
9507 /* Display the mode line, if we must. */
9508 if ((update_mode_line
9509 /* If window not full width, must redo its mode line
9510 if (a) the window to its side is being redone and
9511 (b) we do a frame-based redisplay. This is a consequence
9512 of how inverted lines are drawn in frame-based redisplay. */
9513 || (!just_this_one_p
9514 && !FRAME_WINDOW_P (f)
9515 && !WINDOW_FULL_WIDTH_P (w))
9516 /* Line number to display. */
9517 || INTEGERP (w->base_line_pos)
9518 /* Column number is displayed and different from the one displayed. */
9519 || (!NILP (w->column_number_displayed)
9520 && XFASTINT (w->column_number_displayed) != current_column ()))
9521 /* This means that the window has a mode line. */
9522 && (WINDOW_WANTS_MODELINE_P (w)
9523 || WINDOW_WANTS_HEADER_LINE_P (w)))
9525 Lisp_Object old_selected_frame;
9527 old_selected_frame = selected_frame;
9529 XSETFRAME (selected_frame, f);
9530 display_mode_lines (w);
9531 selected_frame = old_selected_frame;
9533 /* If mode line height has changed, arrange for a thorough
9534 immediate redisplay using the correct mode line height. */
9535 if (WINDOW_WANTS_MODELINE_P (w)
9536 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
9538 fonts_changed_p = 1;
9539 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
9540 = DESIRED_MODE_LINE_HEIGHT (w);
9543 /* If top line height has changed, arrange for a thorough
9544 immediate redisplay using the correct mode line height. */
9545 if (WINDOW_WANTS_HEADER_LINE_P (w)
9546 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
9548 fonts_changed_p = 1;
9549 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
9550 = DESIRED_HEADER_LINE_HEIGHT (w);
9553 if (fonts_changed_p)
9554 goto restore_buffers;
9557 if (!line_number_displayed
9558 && !BUFFERP (w->base_line_pos))
9560 w->base_line_pos = Qnil;
9561 w->base_line_number = Qnil;
9564 finish_menu_bars:
9566 /* When we reach a frame's selected window, redo the frame's menu bar. */
9567 if (update_mode_line
9568 && EQ (FRAME_SELECTED_WINDOW (f), window))
9570 int redisplay_menu_p = 0;
9572 if (FRAME_WINDOW_P (f))
9574 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
9575 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
9576 #else
9577 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
9578 #endif
9580 else
9581 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
9583 if (redisplay_menu_p)
9584 display_menu_bar (w);
9586 #ifdef HAVE_WINDOW_SYSTEM
9587 if (WINDOWP (f->tool_bar_window)
9588 && (FRAME_TOOL_BAR_LINES (f) > 0
9589 || auto_resize_tool_bars_p))
9590 redisplay_tool_bar (f);
9591 #endif
9594 finish_scroll_bars:
9596 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
9598 int start, end, whole;
9600 /* Calculate the start and end positions for the current window.
9601 At some point, it would be nice to choose between scrollbars
9602 which reflect the whole buffer size, with special markers
9603 indicating narrowing, and scrollbars which reflect only the
9604 visible region.
9606 Note that mini-buffers sometimes aren't displaying any text. */
9607 if (!MINI_WINDOW_P (w)
9608 || (w == XWINDOW (minibuf_window)
9609 && NILP (echo_area_buffer[0])))
9611 whole = ZV - BEGV;
9612 start = marker_position (w->start) - BEGV;
9613 /* I don't think this is guaranteed to be right. For the
9614 moment, we'll pretend it is. */
9615 end = (Z - XFASTINT (w->window_end_pos)) - BEGV;
9617 if (end < start)
9618 end = start;
9619 if (whole < (end - start))
9620 whole = end - start;
9622 else
9623 start = end = whole = 0;
9625 /* Indicate what this scroll bar ought to be displaying now. */
9626 (*set_vertical_scroll_bar_hook) (w, end - start, whole, start);
9628 /* Note that we actually used the scroll bar attached to this
9629 window, so it shouldn't be deleted at the end of redisplay. */
9630 (*redeem_scroll_bar_hook) (w);
9633 restore_buffers:
9635 /* Restore current_buffer and value of point in it. */
9636 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
9637 set_buffer_internal_1 (old);
9638 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
9640 unbind_to (count, Qnil);
9644 /* Build the complete desired matrix of WINDOW with a window start
9645 buffer position POS. Value is non-zero if successful. It is zero
9646 if fonts were loaded during redisplay which makes re-adjusting
9647 glyph matrices necessary. */
9650 try_window (window, pos)
9651 Lisp_Object window;
9652 struct text_pos pos;
9654 struct window *w = XWINDOW (window);
9655 struct it it;
9656 struct glyph_row *last_text_row = NULL;
9658 /* Make POS the new window start. */
9659 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
9661 /* Mark cursor position as unknown. No overlay arrow seen. */
9662 w->cursor.vpos = -1;
9663 overlay_arrow_seen = 0;
9665 /* Initialize iterator and info to start at POS. */
9666 start_display (&it, w, pos);
9668 /* Display all lines of W. */
9669 while (it.current_y < it.last_visible_y)
9671 if (display_line (&it))
9672 last_text_row = it.glyph_row - 1;
9673 if (fonts_changed_p)
9674 return 0;
9677 /* If bottom moved off end of frame, change mode line percentage. */
9678 if (XFASTINT (w->window_end_pos) <= 0
9679 && Z != IT_CHARPOS (it))
9680 w->update_mode_line = Qt;
9682 /* Set window_end_pos to the offset of the last character displayed
9683 on the window from the end of current_buffer. Set
9684 window_end_vpos to its row number. */
9685 if (last_text_row)
9687 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
9688 w->window_end_bytepos
9689 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9690 XSETFASTINT (w->window_end_pos,
9691 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9692 XSETFASTINT (w->window_end_vpos,
9693 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
9694 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
9695 ->displays_text_p);
9697 else
9699 w->window_end_bytepos = 0;
9700 XSETFASTINT (w->window_end_pos, 0);
9701 XSETFASTINT (w->window_end_vpos, 0);
9704 /* But that is not valid info until redisplay finishes. */
9705 w->window_end_valid = Qnil;
9706 return 1;
9711 /************************************************************************
9712 Window redisplay reusing current matrix when buffer has not changed
9713 ************************************************************************/
9715 /* Try redisplay of window W showing an unchanged buffer with a
9716 different window start than the last time it was displayed by
9717 reusing its current matrix. Value is non-zero if successful.
9718 W->start is the new window start. */
9720 static int
9721 try_window_reusing_current_matrix (w)
9722 struct window *w;
9724 struct frame *f = XFRAME (w->frame);
9725 struct glyph_row *row, *bottom_row;
9726 struct it it;
9727 struct run run;
9728 struct text_pos start, new_start;
9729 int nrows_scrolled, i;
9730 struct glyph_row *last_text_row;
9731 struct glyph_row *last_reused_text_row;
9732 struct glyph_row *start_row;
9733 int start_vpos, min_y, max_y;
9736 if (/* This function doesn't handle terminal frames. */
9737 !FRAME_WINDOW_P (f)
9738 /* Don't try to reuse the display if windows have been split
9739 or such. */
9740 || windows_or_buffers_changed)
9741 return 0;
9743 /* Can't do this if region may have changed. */
9744 if ((!NILP (Vtransient_mark_mode)
9745 && !NILP (current_buffer->mark_active))
9746 || !NILP (w->region_showing)
9747 || !NILP (Vshow_trailing_whitespace))
9748 return 0;
9750 /* If top-line visibility has changed, give up. */
9751 if (WINDOW_WANTS_HEADER_LINE_P (w)
9752 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
9753 return 0;
9755 /* Give up if old or new display is scrolled vertically. We could
9756 make this function handle this, but right now it doesn't. */
9757 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9758 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
9759 return 0;
9761 /* The variable new_start now holds the new window start. The old
9762 start `start' can be determined from the current matrix. */
9763 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
9764 start = start_row->start.pos;
9765 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
9767 /* Clear the desired matrix for the display below. */
9768 clear_glyph_matrix (w->desired_matrix);
9770 if (CHARPOS (new_start) <= CHARPOS (start))
9772 int first_row_y;
9774 IF_DEBUG (debug_method_add (w, "twu1"));
9776 /* Display up to a row that can be reused. The variable
9777 last_text_row is set to the last row displayed that displays
9778 text. */
9779 start_display (&it, w, new_start);
9780 first_row_y = it.current_y;
9781 w->cursor.vpos = -1;
9782 last_text_row = last_reused_text_row = NULL;
9783 while (it.current_y < it.last_visible_y
9784 && IT_CHARPOS (it) < CHARPOS (start)
9785 && !fonts_changed_p)
9786 if (display_line (&it))
9787 last_text_row = it.glyph_row - 1;
9789 /* A value of current_y < last_visible_y means that we stopped
9790 at the previous window start, which in turn means that we
9791 have at least one reusable row. */
9792 if (it.current_y < it.last_visible_y)
9794 nrows_scrolled = it.vpos;
9796 /* Find PT if not already found in the lines displayed. */
9797 if (w->cursor.vpos < 0)
9799 int dy = it.current_y - first_row_y;
9801 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9802 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9804 if (PT >= MATRIX_ROW_START_CHARPOS (row)
9805 && PT < MATRIX_ROW_END_CHARPOS (row))
9807 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
9808 dy, nrows_scrolled);
9809 break;
9812 if (MATRIX_ROW_BOTTOM_Y (row) + dy >= it.last_visible_y)
9813 break;
9815 ++row;
9818 /* Give up if point was not found. This shouldn't
9819 happen often; not more often than with try_window
9820 itself. */
9821 if (w->cursor.vpos < 0)
9823 clear_glyph_matrix (w->desired_matrix);
9824 return 0;
9828 /* Scroll the display. Do it before the current matrix is
9829 changed. The problem here is that update has not yet
9830 run, i.e. part of the current matrix is not up to date.
9831 scroll_run_hook will clear the cursor, and use the
9832 current matrix to get the height of the row the cursor is
9833 in. */
9834 run.current_y = first_row_y;
9835 run.desired_y = it.current_y;
9836 run.height = it.last_visible_y - it.current_y;
9837 if (run.height > 0
9838 && run.current_y != run.desired_y)
9840 update_begin (f);
9841 rif->update_window_begin_hook (w);
9842 rif->clear_mouse_face (w);
9843 rif->scroll_run_hook (w, &run);
9844 rif->update_window_end_hook (w, 0, 0);
9845 update_end (f);
9848 /* Shift current matrix down by nrows_scrolled lines. */
9849 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
9850 rotate_matrix (w->current_matrix,
9851 start_vpos,
9852 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
9853 nrows_scrolled);
9855 /* Disable lines not reused. */
9856 for (i = 0; i < it.vpos; ++i)
9857 MATRIX_ROW (w->current_matrix, i)->enabled_p = 0;
9859 /* Re-compute Y positions. */
9860 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix) + nrows_scrolled;
9861 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
9862 max_y = it.last_visible_y;
9863 while (row < bottom_row)
9865 row->y = it.current_y;
9867 if (row->y < min_y)
9868 row->visible_height = row->height - (min_y - row->y);
9869 else if (row->y + row->height > max_y)
9870 row->visible_height
9871 = row->height - (row->y + row->height - max_y);
9872 else
9873 row->visible_height = row->height;
9875 it.current_y += row->height;
9876 ++it.vpos;
9878 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9879 last_reused_text_row = row;
9880 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
9881 break;
9882 ++row;
9886 /* Update window_end_pos etc.; last_reused_text_row is the last
9887 reused row from the current matrix containing text, if any.
9888 The value of last_text_row is the last displayed line
9889 containing text. */
9890 if (last_reused_text_row)
9892 w->window_end_bytepos
9893 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
9894 XSETFASTINT (w->window_end_pos,
9895 Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
9896 XSETFASTINT (w->window_end_vpos,
9897 MATRIX_ROW_VPOS (last_reused_text_row,
9898 w->current_matrix));
9900 else if (last_text_row)
9902 w->window_end_bytepos
9903 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9904 XSETFASTINT (w->window_end_pos,
9905 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9906 XSETFASTINT (w->window_end_vpos,
9907 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
9909 else
9911 /* This window must be completely empty. */
9912 w->window_end_bytepos = 0;
9913 XSETFASTINT (w->window_end_pos, 0);
9914 XSETFASTINT (w->window_end_vpos, 0);
9916 w->window_end_valid = Qnil;
9918 /* Update hint: don't try scrolling again in update_window. */
9919 w->desired_matrix->no_scrolling_p = 1;
9921 #if GLYPH_DEBUG
9922 debug_method_add (w, "try_window_reusing_current_matrix 1");
9923 #endif
9924 return 1;
9926 else if (CHARPOS (new_start) > CHARPOS (start))
9928 struct glyph_row *pt_row, *row;
9929 struct glyph_row *first_reusable_row;
9930 struct glyph_row *first_row_to_display;
9931 int dy;
9932 int yb = window_text_bottom_y (w);
9934 IF_DEBUG (debug_method_add (w, "twu2"));
9936 /* Find the row starting at new_start, if there is one. Don't
9937 reuse a partially visible line at the end. */
9938 first_reusable_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9939 while (first_reusable_row->enabled_p
9940 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
9941 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
9942 < CHARPOS (new_start)))
9943 ++first_reusable_row;
9945 /* Give up if there is no row to reuse. */
9946 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
9947 || !first_reusable_row->enabled_p
9948 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
9949 != CHARPOS (new_start)))
9950 return 0;
9952 /* We can reuse fully visible rows beginning with
9953 first_reusable_row to the end of the window. Set
9954 first_row_to_display to the first row that cannot be reused.
9955 Set pt_row to the row containing point, if there is any. */
9956 first_row_to_display = first_reusable_row;
9957 pt_row = NULL;
9958 while (MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb)
9960 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
9961 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
9962 pt_row = first_row_to_display;
9964 ++first_row_to_display;
9967 /* Start displaying at the start of first_row_to_display. */
9968 xassert (first_row_to_display->y < yb);
9969 init_to_row_start (&it, w, first_row_to_display);
9970 nrows_scrolled = MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix);
9971 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
9972 - nrows_scrolled);
9973 it.current_y = first_row_to_display->y - first_reusable_row->y;
9975 /* Display lines beginning with first_row_to_display in the
9976 desired matrix. Set last_text_row to the last row displayed
9977 that displays text. */
9978 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
9979 if (pt_row == NULL)
9980 w->cursor.vpos = -1;
9981 last_text_row = NULL;
9982 while (it.current_y < it.last_visible_y && !fonts_changed_p)
9983 if (display_line (&it))
9984 last_text_row = it.glyph_row - 1;
9986 /* Give up If point isn't in a row displayed or reused. */
9987 if (w->cursor.vpos < 0)
9989 clear_glyph_matrix (w->desired_matrix);
9990 return 0;
9993 /* If point is in a reused row, adjust y and vpos of the cursor
9994 position. */
9995 if (pt_row)
9997 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
9998 w->current_matrix);
9999 w->cursor.y -= first_reusable_row->y;
10002 /* Scroll the display. */
10003 run.current_y = first_reusable_row->y;
10004 run.desired_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
10005 run.height = it.last_visible_y - run.current_y;
10006 if (run.height)
10008 struct frame *f = XFRAME (WINDOW_FRAME (w));
10009 update_begin (f);
10010 rif->update_window_begin_hook (w);
10011 rif->clear_mouse_face (w);
10012 rif->scroll_run_hook (w, &run);
10013 rif->update_window_end_hook (w, 0, 0);
10014 update_end (f);
10017 /* Adjust Y positions of reused rows. */
10018 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
10019 row = first_reusable_row;
10020 dy = first_reusable_row->y;
10021 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
10022 max_y = it.last_visible_y;
10023 while (row < first_row_to_display)
10025 row->y -= dy;
10026 if (row->y < min_y)
10027 row->visible_height = row->height - (min_y - row->y);
10028 else if (row->y + row->height > max_y)
10029 row->visible_height
10030 = row->height - (row->y + row->height - max_y);
10031 else
10032 row->visible_height = row->height;
10033 ++row;
10036 /* Disable rows not reused. */
10037 while (row < bottom_row)
10039 row->enabled_p = 0;
10040 ++row;
10043 /* Scroll the current matrix. */
10044 xassert (nrows_scrolled > 0);
10045 rotate_matrix (w->current_matrix,
10046 start_vpos,
10047 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
10048 -nrows_scrolled);
10050 /* Adjust window end. A null value of last_text_row means that
10051 the window end is in reused rows which in turn means that
10052 only its vpos can have changed. */
10053 if (last_text_row)
10055 w->window_end_bytepos
10056 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
10057 XSETFASTINT (w->window_end_pos,
10058 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
10059 XSETFASTINT (w->window_end_vpos,
10060 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
10062 else
10064 XSETFASTINT (w->window_end_vpos,
10065 XFASTINT (w->window_end_vpos) - nrows_scrolled);
10068 w->window_end_valid = Qnil;
10069 w->desired_matrix->no_scrolling_p = 1;
10071 #if GLYPH_DEBUG
10072 debug_method_add (w, "try_window_reusing_current_matrix 2");
10073 #endif
10074 return 1;
10077 return 0;
10082 /************************************************************************
10083 Window redisplay reusing current matrix when buffer has changed
10084 ************************************************************************/
10086 static struct glyph_row *get_last_unchanged_at_beg_row P_ ((struct window *));
10087 static struct glyph_row *get_first_unchanged_at_end_row P_ ((struct window *,
10088 int *, int *));
10089 static struct glyph_row *
10090 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
10091 struct glyph_row *));
10094 /* Return the last row in MATRIX displaying text. If row START is
10095 non-null, start searching with that row. IT gives the dimensions
10096 of the display. Value is null if matrix is empty; otherwise it is
10097 a pointer to the row found. */
10099 static struct glyph_row *
10100 find_last_row_displaying_text (matrix, it, start)
10101 struct glyph_matrix *matrix;
10102 struct it *it;
10103 struct glyph_row *start;
10105 struct glyph_row *row, *row_found;
10107 /* Set row_found to the last row in IT->w's current matrix
10108 displaying text. The loop looks funny but think of partially
10109 visible lines. */
10110 row_found = NULL;
10111 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
10112 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
10114 xassert (row->enabled_p);
10115 row_found = row;
10116 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
10117 break;
10118 ++row;
10121 return row_found;
10125 /* Return the last row in the current matrix of W that is not affected
10126 by changes at the start of current_buffer that occurred since the
10127 last time W was redisplayed. Value is null if no such row exists.
10129 The global variable beg_unchanged has to contain the number of
10130 bytes unchanged at the start of current_buffer. BEG +
10131 beg_unchanged is the buffer position of the first changed byte in
10132 current_buffer. Characters at positions < BEG + beg_unchanged are
10133 at the same buffer positions as they were when the current matrix
10134 was built. */
10136 static struct glyph_row *
10137 get_last_unchanged_at_beg_row (w)
10138 struct window *w;
10140 int first_changed_pos = BEG + BEG_UNCHANGED;
10141 struct glyph_row *row;
10142 struct glyph_row *row_found = NULL;
10143 int yb = window_text_bottom_y (w);
10145 /* Find the last row displaying unchanged text. */
10146 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
10147 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
10148 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
10150 if (/* If row ends before first_changed_pos, it is unchanged,
10151 except in some case. */
10152 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
10153 /* When row ends in ZV and we write at ZV it is not
10154 unchanged. */
10155 && !row->ends_at_zv_p
10156 /* When first_changed_pos is the end of a continued line,
10157 row is not unchanged because it may be no longer
10158 continued. */
10159 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
10160 && row->continued_p))
10161 row_found = row;
10163 /* Stop if last visible row. */
10164 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
10165 break;
10167 ++row;
10170 return row_found;
10174 /* Find the first glyph row in the current matrix of W that is not
10175 affected by changes at the end of current_buffer since the last
10176 time the window was redisplayed. Return in *DELTA the number of
10177 chars by which buffer positions in unchanged text at the end of
10178 current_buffer must be adjusted. Return in *DELTA_BYTES the
10179 corresponding number of bytes. Value is null if no such row
10180 exists, i.e. all rows are affected by changes. */
10182 static struct glyph_row *
10183 get_first_unchanged_at_end_row (w, delta, delta_bytes)
10184 struct window *w;
10185 int *delta, *delta_bytes;
10187 struct glyph_row *row;
10188 struct glyph_row *row_found = NULL;
10190 *delta = *delta_bytes = 0;
10192 /* A value of window_end_pos >= end_unchanged means that the window
10193 end is in the range of changed text. If so, there is no
10194 unchanged row at the end of W's current matrix. */
10195 xassert (!NILP (w->window_end_valid));
10196 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
10197 return NULL;
10199 /* Set row to the last row in W's current matrix displaying text. */
10200 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
10202 /* If matrix is entirely empty, no unchanged row exists. */
10203 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
10205 /* The value of row is the last glyph row in the matrix having a
10206 meaningful buffer position in it. The end position of row
10207 corresponds to window_end_pos. This allows us to translate
10208 buffer positions in the current matrix to current buffer
10209 positions for characters not in changed text. */
10210 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
10211 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
10212 int last_unchanged_pos, last_unchanged_pos_old;
10213 struct glyph_row *first_text_row
10214 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
10216 *delta = Z - Z_old;
10217 *delta_bytes = Z_BYTE - Z_BYTE_old;
10219 /* Set last_unchanged_pos to the buffer position of the last
10220 character in the buffer that has not been changed. Z is the
10221 index + 1 of the last byte in current_buffer, i.e. by
10222 subtracting end_unchanged we get the index of the last
10223 unchanged character, and we have to add BEG to get its buffer
10224 position. */
10225 last_unchanged_pos = Z - END_UNCHANGED + BEG;
10226 last_unchanged_pos_old = last_unchanged_pos - *delta;
10228 /* Search backward from ROW for a row displaying a line that
10229 starts at a minimum position >= last_unchanged_pos_old. */
10230 while (row >= first_text_row)
10232 xassert (row->enabled_p);
10233 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (row));
10235 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
10236 row_found = row;
10237 --row;
10241 xassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
10242 return row_found;
10246 /* Make sure that glyph rows in the current matrix of window W
10247 reference the same glyph memory as corresponding rows in the
10248 frame's frame matrix. This function is called after scrolling W's
10249 current matrix on a terminal frame in try_window_id and
10250 try_window_reusing_current_matrix. */
10252 static void
10253 sync_frame_with_window_matrix_rows (w)
10254 struct window *w;
10256 struct frame *f = XFRAME (w->frame);
10257 struct glyph_row *window_row, *window_row_end, *frame_row;
10259 /* Preconditions: W must be a leaf window and full-width. Its frame
10260 must have a frame matrix. */
10261 xassert (NILP (w->hchild) && NILP (w->vchild));
10262 xassert (WINDOW_FULL_WIDTH_P (w));
10263 xassert (!FRAME_WINDOW_P (f));
10265 /* If W is a full-width window, glyph pointers in W's current matrix
10266 have, by definition, to be the same as glyph pointers in the
10267 corresponding frame matrix. */
10268 window_row = w->current_matrix->rows;
10269 window_row_end = window_row + w->current_matrix->nrows;
10270 frame_row = f->current_matrix->rows + XFASTINT (w->top);
10271 while (window_row < window_row_end)
10273 int area;
10275 for (area = LEFT_MARGIN_AREA; area <= LAST_AREA; ++area)
10276 frame_row->glyphs[area] = window_row->glyphs[area];
10278 /* Disable frame rows whose corresponding window rows have
10279 been disabled in try_window_id. */
10280 if (!window_row->enabled_p)
10281 frame_row->enabled_p = 0;
10283 ++window_row, ++frame_row;
10288 /* Find the glyph row in window W containing CHARPOS. Consider all
10289 rows between START and END (not inclusive). END null means search
10290 all rows to the end of the display area of W. Value is the row
10291 containing CHARPOS or null. */
10293 static struct glyph_row *
10294 row_containing_pos (w, charpos, start, end)
10295 struct window *w;
10296 int charpos;
10297 struct glyph_row *start, *end;
10299 struct glyph_row *row = start;
10300 int last_y;
10302 /* If we happen to start on a header-line, skip that. */
10303 if (row->mode_line_p)
10304 ++row;
10306 if ((end && row >= end) || !row->enabled_p)
10307 return NULL;
10309 last_y = window_text_bottom_y (w);
10311 while ((end == NULL || row < end)
10312 && (MATRIX_ROW_END_CHARPOS (row) < charpos
10313 /* The end position of a row equals the start
10314 position of the next row. If CHARPOS is there, we
10315 would rather display it in the next line, except
10316 when this line ends in ZV. */
10317 || (MATRIX_ROW_END_CHARPOS (row) == charpos
10318 && (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
10319 || !row->ends_at_zv_p)))
10320 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
10321 ++row;
10323 /* Give up if CHARPOS not found. */
10324 if ((end && row >= end)
10325 || charpos < MATRIX_ROW_START_CHARPOS (row)
10326 || charpos > MATRIX_ROW_END_CHARPOS (row))
10327 row = NULL;
10329 return row;
10333 /* Try to redisplay window W by reusing its existing display. W's
10334 current matrix must be up to date when this function is called,
10335 i.e. window_end_valid must not be nil.
10337 Value is
10339 1 if display has been updated
10340 0 if otherwise unsuccessful
10341 -1 if redisplay with same window start is known not to succeed
10343 The following steps are performed:
10345 1. Find the last row in the current matrix of W that is not
10346 affected by changes at the start of current_buffer. If no such row
10347 is found, give up.
10349 2. Find the first row in W's current matrix that is not affected by
10350 changes at the end of current_buffer. Maybe there is no such row.
10352 3. Display lines beginning with the row + 1 found in step 1 to the
10353 row found in step 2 or, if step 2 didn't find a row, to the end of
10354 the window.
10356 4. If cursor is not known to appear on the window, give up.
10358 5. If display stopped at the row found in step 2, scroll the
10359 display and current matrix as needed.
10361 6. Maybe display some lines at the end of W, if we must. This can
10362 happen under various circumstances, like a partially visible line
10363 becoming fully visible, or because newly displayed lines are displayed
10364 in smaller font sizes.
10366 7. Update W's window end information. */
10368 /* Check that window end is what we expect it to be. */
10370 static int
10371 try_window_id (w)
10372 struct window *w;
10374 struct frame *f = XFRAME (w->frame);
10375 struct glyph_matrix *current_matrix = w->current_matrix;
10376 struct glyph_matrix *desired_matrix = w->desired_matrix;
10377 struct glyph_row *last_unchanged_at_beg_row;
10378 struct glyph_row *first_unchanged_at_end_row;
10379 struct glyph_row *row;
10380 struct glyph_row *bottom_row;
10381 int bottom_vpos;
10382 struct it it;
10383 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
10384 struct text_pos start_pos;
10385 struct run run;
10386 int first_unchanged_at_end_vpos = 0;
10387 struct glyph_row *last_text_row, *last_text_row_at_end;
10388 struct text_pos start;
10390 SET_TEXT_POS_FROM_MARKER (start, w->start);
10392 /* Check pre-conditions. Window end must be valid, otherwise
10393 the current matrix would not be up to date. */
10394 xassert (!NILP (w->window_end_valid));
10395 xassert (FRAME_WINDOW_P (XFRAME (w->frame))
10396 || (line_ins_del_ok && WINDOW_FULL_WIDTH_P (w)));
10398 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
10399 only if buffer has really changed. The reason is that the gap is
10400 initially at Z for freshly visited files. The code below would
10401 set end_unchanged to 0 in that case. */
10402 if (MODIFF > SAVE_MODIFF
10403 /* This seems to happen sometimes after saving a buffer. */
10404 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
10406 if (GPT - BEG < BEG_UNCHANGED)
10407 BEG_UNCHANGED = GPT - BEG;
10408 if (Z - GPT < END_UNCHANGED)
10409 END_UNCHANGED = Z - GPT;
10412 /* If window starts after a line end, and the last change is in
10413 front of that newline, then changes don't affect the display.
10414 This case happens with stealth-fontification. Note that although
10415 the display is unchanged, glyph positions in the matrix have to
10416 be adjusted, of course. */
10417 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
10418 if (CHARPOS (start) > BEGV
10419 && Z - END_UNCHANGED < CHARPOS (start) - 1
10420 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n'
10421 && PT < MATRIX_ROW_END_CHARPOS (row))
10423 struct glyph_row *r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
10424 int delta = CHARPOS (start) - MATRIX_ROW_START_CHARPOS (r0);
10426 if (delta)
10428 struct glyph_row *r1 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
10429 int delta_bytes = BYTEPOS (start) - MATRIX_ROW_START_BYTEPOS (r0);
10431 increment_matrix_positions (w->current_matrix,
10432 MATRIX_ROW_VPOS (r0, current_matrix),
10433 MATRIX_ROW_VPOS (r1, current_matrix),
10434 delta, delta_bytes);
10437 #if 0 /* If changes are all in front of the window start, the
10438 distance of the last displayed glyph from Z hasn't
10439 changed. */
10440 w->window_end_pos
10441 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
10442 w->window_end_bytepos
10443 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
10444 #endif
10446 return 1;
10449 /* Return quickly if changes are all below what is displayed in the
10450 window, and if PT is in the window. */
10451 if (BEG_UNCHANGED > MATRIX_ROW_END_CHARPOS (row)
10452 && PT < MATRIX_ROW_END_CHARPOS (row))
10454 /* We have to update window end positions because the buffer's
10455 size has changed. */
10456 w->window_end_pos
10457 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
10458 w->window_end_bytepos
10459 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
10461 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
10462 row = row_containing_pos (w, PT, row, NULL);
10463 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10464 return 2;
10467 /* Check that window start agrees with the start of the first glyph
10468 row in its current matrix. Check this after we know the window
10469 start is not in changed text, otherwise positions would not be
10470 comparable. */
10471 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
10472 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
10473 return 0;
10475 /* Compute the position at which we have to start displaying new
10476 lines. Some of the lines at the top of the window might be
10477 reusable because they are not displaying changed text. Find the
10478 last row in W's current matrix not affected by changes at the
10479 start of current_buffer. Value is null if changes start in the
10480 first line of window. */
10481 last_unchanged_at_beg_row = get_last_unchanged_at_beg_row (w);
10482 if (last_unchanged_at_beg_row)
10484 init_to_row_end (&it, w, last_unchanged_at_beg_row);
10485 start_pos = it.current.pos;
10487 /* Start displaying new lines in the desired matrix at the same
10488 vpos we would use in the current matrix, i.e. below
10489 last_unchanged_at_beg_row. */
10490 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
10491 current_matrix);
10492 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
10493 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
10495 xassert (it.hpos == 0 && it.current_x == 0);
10497 else
10499 /* There are no reusable lines at the start of the window.
10500 Start displaying in the first line. */
10501 start_display (&it, w, start);
10502 start_pos = it.current.pos;
10505 /* Find the first row that is not affected by changes at the end of
10506 the buffer. Value will be null if there is no unchanged row, in
10507 which case we must redisplay to the end of the window. delta
10508 will be set to the value by which buffer positions beginning with
10509 first_unchanged_at_end_row have to be adjusted due to text
10510 changes. */
10511 first_unchanged_at_end_row
10512 = get_first_unchanged_at_end_row (w, &delta, &delta_bytes);
10513 IF_DEBUG (debug_delta = delta);
10514 IF_DEBUG (debug_delta_bytes = delta_bytes);
10516 /* Set stop_pos to the buffer position up to which we will have to
10517 display new lines. If first_unchanged_at_end_row != NULL, this
10518 is the buffer position of the start of the line displayed in that
10519 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
10520 that we don't stop at a buffer position. */
10521 stop_pos = 0;
10522 if (first_unchanged_at_end_row)
10524 xassert (last_unchanged_at_beg_row == NULL
10525 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
10527 /* If this is a continuation line, move forward to the next one
10528 that isn't. Changes in lines above affect this line.
10529 Caution: this may move first_unchanged_at_end_row to a row
10530 not displaying text. */
10531 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
10532 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
10533 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
10534 < it.last_visible_y))
10535 ++first_unchanged_at_end_row;
10537 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
10538 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
10539 >= it.last_visible_y))
10540 first_unchanged_at_end_row = NULL;
10541 else
10543 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
10544 + delta);
10545 first_unchanged_at_end_vpos
10546 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
10547 xassert (stop_pos >= Z - END_UNCHANGED);
10550 else if (last_unchanged_at_beg_row == NULL)
10551 return 0;
10554 #if GLYPH_DEBUG
10556 /* Either there is no unchanged row at the end, or the one we have
10557 now displays text. This is a necessary condition for the window
10558 end pos calculation at the end of this function. */
10559 xassert (first_unchanged_at_end_row == NULL
10560 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
10562 debug_last_unchanged_at_beg_vpos
10563 = (last_unchanged_at_beg_row
10564 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
10565 : -1);
10566 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
10568 #endif /* GLYPH_DEBUG != 0 */
10571 /* Display new lines. Set last_text_row to the last new line
10572 displayed which has text on it, i.e. might end up as being the
10573 line where the window_end_vpos is. */
10574 w->cursor.vpos = -1;
10575 last_text_row = NULL;
10576 overlay_arrow_seen = 0;
10577 while (it.current_y < it.last_visible_y
10578 && !fonts_changed_p
10579 && (first_unchanged_at_end_row == NULL
10580 || IT_CHARPOS (it) < stop_pos))
10582 if (display_line (&it))
10583 last_text_row = it.glyph_row - 1;
10586 if (fonts_changed_p)
10587 return -1;
10590 /* Compute differences in buffer positions, y-positions etc. for
10591 lines reused at the bottom of the window. Compute what we can
10592 scroll. */
10593 if (first_unchanged_at_end_row
10594 /* No lines reused because we displayed everything up to the
10595 bottom of the window. */
10596 && it.current_y < it.last_visible_y)
10598 dvpos = (it.vpos
10599 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
10600 current_matrix));
10601 dy = it.current_y - first_unchanged_at_end_row->y;
10602 run.current_y = first_unchanged_at_end_row->y;
10603 run.desired_y = run.current_y + dy;
10604 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
10606 else
10608 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
10609 first_unchanged_at_end_row = NULL;
10611 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
10614 /* Find the cursor if not already found. We have to decide whether
10615 PT will appear on this window (it sometimes doesn't, but this is
10616 not a very frequent case.) This decision has to be made before
10617 the current matrix is altered. A value of cursor.vpos < 0 means
10618 that PT is either in one of the lines beginning at
10619 first_unchanged_at_end_row or below the window. Don't care for
10620 lines that might be displayed later at the window end; as
10621 mentioned, this is not a frequent case. */
10622 if (w->cursor.vpos < 0)
10624 /* Cursor in unchanged rows at the top? */
10625 if (PT < CHARPOS (start_pos)
10626 && last_unchanged_at_beg_row)
10628 row = row_containing_pos (w, PT,
10629 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
10630 last_unchanged_at_beg_row + 1);
10631 xassert (row && row <= last_unchanged_at_beg_row);
10632 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10635 /* Start from first_unchanged_at_end_row looking for PT. */
10636 else if (first_unchanged_at_end_row)
10638 row = row_containing_pos (w, PT - delta,
10639 first_unchanged_at_end_row, NULL);
10640 if (row)
10641 set_cursor_from_row (w, row, w->current_matrix, delta,
10642 delta_bytes, dy, dvpos);
10645 /* Give up if cursor was not found. */
10646 if (w->cursor.vpos < 0)
10648 clear_glyph_matrix (w->desired_matrix);
10649 return -1;
10653 /* Don't let the cursor end in the scroll margins. */
10655 int this_scroll_margin, cursor_height;
10657 this_scroll_margin = max (0, scroll_margin);
10658 this_scroll_margin = min (this_scroll_margin,
10659 XFASTINT (w->height) / 4);
10660 this_scroll_margin *= CANON_Y_UNIT (it.f);
10661 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
10663 if ((w->cursor.y < this_scroll_margin
10664 && CHARPOS (start) > BEGV)
10665 /* Don't take scroll margin into account at the bottom because
10666 old redisplay didn't do it either. */
10667 || w->cursor.y + cursor_height > it.last_visible_y)
10669 w->cursor.vpos = -1;
10670 clear_glyph_matrix (w->desired_matrix);
10671 return -1;
10675 /* Scroll the display. Do it before changing the current matrix so
10676 that xterm.c doesn't get confused about where the cursor glyph is
10677 found. */
10678 if (dy && run.height)
10680 update_begin (f);
10682 if (FRAME_WINDOW_P (f))
10684 rif->update_window_begin_hook (w);
10685 rif->clear_mouse_face (w);
10686 rif->scroll_run_hook (w, &run);
10687 rif->update_window_end_hook (w, 0, 0);
10689 else
10691 /* Terminal frame. In this case, dvpos gives the number of
10692 lines to scroll by; dvpos < 0 means scroll up. */
10693 int first_unchanged_at_end_vpos
10694 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
10695 int from = XFASTINT (w->top) + first_unchanged_at_end_vpos;
10696 int end = XFASTINT (w->top) + window_internal_height (w);
10698 /* Perform the operation on the screen. */
10699 if (dvpos > 0)
10701 /* Scroll last_unchanged_at_beg_row to the end of the
10702 window down dvpos lines. */
10703 set_terminal_window (end);
10705 /* On dumb terminals delete dvpos lines at the end
10706 before inserting dvpos empty lines. */
10707 if (!scroll_region_ok)
10708 ins_del_lines (end - dvpos, -dvpos);
10710 /* Insert dvpos empty lines in front of
10711 last_unchanged_at_beg_row. */
10712 ins_del_lines (from, dvpos);
10714 else if (dvpos < 0)
10716 /* Scroll up last_unchanged_at_beg_vpos to the end of
10717 the window to last_unchanged_at_beg_vpos - |dvpos|. */
10718 set_terminal_window (end);
10720 /* Delete dvpos lines in front of
10721 last_unchanged_at_beg_vpos. ins_del_lines will set
10722 the cursor to the given vpos and emit |dvpos| delete
10723 line sequences. */
10724 ins_del_lines (from + dvpos, dvpos);
10726 /* On a dumb terminal insert dvpos empty lines at the
10727 end. */
10728 if (!scroll_region_ok)
10729 ins_del_lines (end + dvpos, -dvpos);
10732 set_terminal_window (0);
10735 update_end (f);
10738 /* Shift reused rows of the current matrix to the right position.
10739 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
10740 text. */
10741 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
10742 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
10743 if (dvpos < 0)
10745 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
10746 bottom_vpos, dvpos);
10747 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
10748 bottom_vpos, 0);
10750 else if (dvpos > 0)
10752 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
10753 bottom_vpos, dvpos);
10754 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
10755 first_unchanged_at_end_vpos + dvpos, 0);
10758 /* For frame-based redisplay, make sure that current frame and window
10759 matrix are in sync with respect to glyph memory. */
10760 if (!FRAME_WINDOW_P (f))
10761 sync_frame_with_window_matrix_rows (w);
10763 /* Adjust buffer positions in reused rows. */
10764 if (delta)
10765 increment_matrix_positions (current_matrix,
10766 first_unchanged_at_end_vpos + dvpos,
10767 bottom_vpos, delta, delta_bytes);
10769 /* Adjust Y positions. */
10770 if (dy)
10771 shift_glyph_matrix (w, current_matrix,
10772 first_unchanged_at_end_vpos + dvpos,
10773 bottom_vpos, dy);
10775 if (first_unchanged_at_end_row)
10776 first_unchanged_at_end_row += dvpos;
10778 /* If scrolling up, there may be some lines to display at the end of
10779 the window. */
10780 last_text_row_at_end = NULL;
10781 if (dy < 0)
10783 /* Set last_row to the glyph row in the current matrix where the
10784 window end line is found. It has been moved up or down in
10785 the matrix by dvpos. */
10786 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
10787 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
10789 /* If last_row is the window end line, it should display text. */
10790 xassert (last_row->displays_text_p);
10792 /* If window end line was partially visible before, begin
10793 displaying at that line. Otherwise begin displaying with the
10794 line following it. */
10795 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
10797 init_to_row_start (&it, w, last_row);
10798 it.vpos = last_vpos;
10799 it.current_y = last_row->y;
10801 else
10803 init_to_row_end (&it, w, last_row);
10804 it.vpos = 1 + last_vpos;
10805 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
10806 ++last_row;
10809 /* We may start in a continuation line. If so, we have to get
10810 the right continuation_lines_width and current_x. */
10811 it.continuation_lines_width = last_row->continuation_lines_width;
10812 it.hpos = it.current_x = 0;
10814 /* Display the rest of the lines at the window end. */
10815 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
10816 while (it.current_y < it.last_visible_y
10817 && !fonts_changed_p)
10819 /* Is it always sure that the display agrees with lines in
10820 the current matrix? I don't think so, so we mark rows
10821 displayed invalid in the current matrix by setting their
10822 enabled_p flag to zero. */
10823 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
10824 if (display_line (&it))
10825 last_text_row_at_end = it.glyph_row - 1;
10829 /* Update window_end_pos and window_end_vpos. */
10830 if (first_unchanged_at_end_row
10831 && first_unchanged_at_end_row->y < it.last_visible_y
10832 && !last_text_row_at_end)
10834 /* Window end line if one of the preserved rows from the current
10835 matrix. Set row to the last row displaying text in current
10836 matrix starting at first_unchanged_at_end_row, after
10837 scrolling. */
10838 xassert (first_unchanged_at_end_row->displays_text_p);
10839 row = find_last_row_displaying_text (w->current_matrix, &it,
10840 first_unchanged_at_end_row);
10841 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
10843 XSETFASTINT (w->window_end_pos, Z - MATRIX_ROW_END_CHARPOS (row));
10844 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
10845 XSETFASTINT (w->window_end_vpos,
10846 MATRIX_ROW_VPOS (row, w->current_matrix));
10848 else if (last_text_row_at_end)
10850 XSETFASTINT (w->window_end_pos,
10851 Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
10852 w->window_end_bytepos
10853 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
10854 XSETFASTINT (w->window_end_vpos,
10855 MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
10857 else if (last_text_row)
10859 /* We have displayed either to the end of the window or at the
10860 end of the window, i.e. the last row with text is to be found
10861 in the desired matrix. */
10862 XSETFASTINT (w->window_end_pos,
10863 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
10864 w->window_end_bytepos
10865 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
10866 XSETFASTINT (w->window_end_vpos,
10867 MATRIX_ROW_VPOS (last_text_row, desired_matrix));
10869 else if (first_unchanged_at_end_row == NULL
10870 && last_text_row == NULL
10871 && last_text_row_at_end == NULL)
10873 /* Displayed to end of window, but no line containing text was
10874 displayed. Lines were deleted at the end of the window. */
10875 int vpos;
10876 int header_line_p = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
10878 for (vpos = XFASTINT (w->window_end_vpos); vpos > 0; --vpos)
10879 if ((w->desired_matrix->rows[vpos + header_line_p].enabled_p
10880 && w->desired_matrix->rows[vpos + header_line_p].displays_text_p)
10881 || (!w->desired_matrix->rows[vpos + header_line_p].enabled_p
10882 && w->current_matrix->rows[vpos + header_line_p].displays_text_p))
10883 break;
10885 w->window_end_vpos = make_number (vpos);
10887 else
10888 abort ();
10890 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
10891 debug_end_vpos = XFASTINT (w->window_end_vpos));
10893 /* Record that display has not been completed. */
10894 w->window_end_valid = Qnil;
10895 w->desired_matrix->no_scrolling_p = 1;
10896 return 3;
10901 /***********************************************************************
10902 More debugging support
10903 ***********************************************************************/
10905 #if GLYPH_DEBUG
10907 void dump_glyph_row P_ ((struct glyph_matrix *, int, int));
10908 static void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
10911 /* Dump the contents of glyph matrix MATRIX on stderr. If
10912 WITH_GLYPHS_P is non-zero, dump glyph contents as well. */
10914 static void
10915 dump_glyph_matrix (matrix, with_glyphs_p)
10916 struct glyph_matrix *matrix;
10917 int with_glyphs_p;
10919 int i;
10920 for (i = 0; i < matrix->nrows; ++i)
10921 dump_glyph_row (matrix, i, with_glyphs_p);
10925 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
10926 WITH_GLYPH_SP non-zero means dump glyph contents, too. */
10928 void
10929 dump_glyph_row (matrix, vpos, with_glyphs_p)
10930 struct glyph_matrix *matrix;
10931 int vpos, with_glyphs_p;
10933 struct glyph_row *row;
10935 if (vpos < 0 || vpos >= matrix->nrows)
10936 return;
10938 row = MATRIX_ROW (matrix, vpos);
10940 fprintf (stderr, "Row Start End Used oEI><O\\CTZFes X Y W H V A P\n");
10941 fprintf (stderr, "=======================================================================\n");
10943 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1 \
10944 1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
10945 row - matrix->rows,
10946 MATRIX_ROW_START_CHARPOS (row),
10947 MATRIX_ROW_END_CHARPOS (row),
10948 row->used[TEXT_AREA],
10949 row->contains_overlapping_glyphs_p,
10950 row->enabled_p,
10951 row->inverse_p,
10952 row->truncated_on_left_p,
10953 row->truncated_on_right_p,
10954 row->overlay_arrow_p,
10955 row->continued_p,
10956 MATRIX_ROW_CONTINUATION_LINE_P (row),
10957 row->displays_text_p,
10958 row->ends_at_zv_p,
10959 row->fill_line_p,
10960 row->ends_in_middle_of_char_p,
10961 row->starts_in_middle_of_char_p,
10962 row->x,
10963 row->y,
10964 row->pixel_width,
10965 row->height,
10966 row->visible_height,
10967 row->ascent,
10968 row->phys_ascent);
10969 fprintf (stderr, "%9d %5d\n", row->start.overlay_string_index,
10970 row->end.overlay_string_index);
10971 fprintf (stderr, "%9d %5d\n",
10972 CHARPOS (row->start.string_pos),
10973 CHARPOS (row->end.string_pos));
10974 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
10975 row->end.dpvec_index);
10977 if (with_glyphs_p)
10979 struct glyph *glyph, *glyph_end;
10980 int prev_had_glyphs_p;
10982 glyph = row->glyphs[TEXT_AREA];
10983 glyph_end = glyph + row->used[TEXT_AREA];
10985 /* Glyph for a line end in text. */
10986 if (glyph == glyph_end && glyph->charpos > 0)
10987 ++glyph_end;
10989 if (glyph < glyph_end)
10991 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
10992 prev_had_glyphs_p = 1;
10994 else
10995 prev_had_glyphs_p = 0;
10997 while (glyph < glyph_end)
10999 if (glyph->type == CHAR_GLYPH)
11001 fprintf (stderr,
11002 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
11003 glyph - row->glyphs[TEXT_AREA],
11004 'C',
11005 glyph->charpos,
11006 (BUFFERP (glyph->object)
11007 ? 'B'
11008 : (STRINGP (glyph->object)
11009 ? 'S'
11010 : '-')),
11011 glyph->pixel_width,
11012 glyph->u.ch,
11013 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
11014 ? glyph->u.ch
11015 : '.'),
11016 glyph->face_id,
11017 glyph->left_box_line_p,
11018 glyph->right_box_line_p);
11020 else if (glyph->type == STRETCH_GLYPH)
11022 fprintf (stderr,
11023 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
11024 glyph - row->glyphs[TEXT_AREA],
11025 'S',
11026 glyph->charpos,
11027 (BUFFERP (glyph->object)
11028 ? 'B'
11029 : (STRINGP (glyph->object)
11030 ? 'S'
11031 : '-')),
11032 glyph->pixel_width,
11034 '.',
11035 glyph->face_id,
11036 glyph->left_box_line_p,
11037 glyph->right_box_line_p);
11039 else if (glyph->type == IMAGE_GLYPH)
11041 fprintf (stderr,
11042 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
11043 glyph - row->glyphs[TEXT_AREA],
11044 'I',
11045 glyph->charpos,
11046 (BUFFERP (glyph->object)
11047 ? 'B'
11048 : (STRINGP (glyph->object)
11049 ? 'S'
11050 : '-')),
11051 glyph->pixel_width,
11052 glyph->u.img_id,
11053 '.',
11054 glyph->face_id,
11055 glyph->left_box_line_p,
11056 glyph->right_box_line_p);
11058 ++glyph;
11064 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
11065 Sdump_glyph_matrix, 0, 1, "p",
11066 "Dump the current matrix of the selected window to stderr.\n\
11067 Shows contents of glyph row structures. With non-nil optional\n\
11068 parameter WITH-GLYPHS-P, dump glyphs as well.")
11069 (with_glyphs_p)
11070 Lisp_Object with_glyphs_p;
11072 struct window *w = XWINDOW (selected_window);
11073 struct buffer *buffer = XBUFFER (w->buffer);
11075 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
11076 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
11077 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
11078 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
11079 fprintf (stderr, "=============================================\n");
11080 dump_glyph_matrix (w->current_matrix, !NILP (with_glyphs_p));
11081 return Qnil;
11085 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 1, "",
11086 "Dump glyph row ROW to stderr.")
11087 (row)
11088 Lisp_Object row;
11090 CHECK_NUMBER (row, 0);
11091 dump_glyph_row (XWINDOW (selected_window)->current_matrix, XINT (row), 1);
11092 return Qnil;
11096 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row,
11097 0, 0, "", "")
11100 struct frame *sf = SELECTED_FRAME ();
11101 struct glyph_matrix *m = (XWINDOW (sf->tool_bar_window)
11102 ->current_matrix);
11103 dump_glyph_row (m, 0, 1);
11104 return Qnil;
11108 DEFUN ("trace-redisplay-toggle", Ftrace_redisplay_toggle,
11109 Strace_redisplay_toggle, 0, 0, "",
11110 "Toggle tracing of redisplay.")
11113 trace_redisplay_p = !trace_redisplay_p;
11114 return Qnil;
11118 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, 1, "",
11119 "Print STRING to stderr.")
11120 (string)
11121 Lisp_Object string;
11123 CHECK_STRING (string, 0);
11124 fprintf (stderr, "%s", XSTRING (string)->data);
11125 return Qnil;
11128 #endif /* GLYPH_DEBUG */
11132 /***********************************************************************
11133 Building Desired Matrix Rows
11134 ***********************************************************************/
11136 /* Return a temporary glyph row holding the glyphs of an overlay
11137 arrow. Only used for non-window-redisplay windows. */
11139 static struct glyph_row *
11140 get_overlay_arrow_glyph_row (w)
11141 struct window *w;
11143 struct frame *f = XFRAME (WINDOW_FRAME (w));
11144 struct buffer *buffer = XBUFFER (w->buffer);
11145 struct buffer *old = current_buffer;
11146 unsigned char *arrow_string = XSTRING (Voverlay_arrow_string)->data;
11147 int arrow_len = XSTRING (Voverlay_arrow_string)->size;
11148 unsigned char *arrow_end = arrow_string + arrow_len;
11149 unsigned char *p;
11150 struct it it;
11151 int multibyte_p;
11152 int n_glyphs_before;
11154 set_buffer_temp (buffer);
11155 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
11156 it.glyph_row->used[TEXT_AREA] = 0;
11157 SET_TEXT_POS (it.position, 0, 0);
11159 multibyte_p = !NILP (buffer->enable_multibyte_characters);
11160 p = arrow_string;
11161 while (p < arrow_end)
11163 Lisp_Object face, ilisp;
11165 /* Get the next character. */
11166 if (multibyte_p)
11167 it.c = string_char_and_length (p, arrow_len, &it.len);
11168 else
11169 it.c = *p, it.len = 1;
11170 p += it.len;
11172 /* Get its face. */
11173 XSETFASTINT (ilisp, p - arrow_string);
11174 face = Fget_text_property (ilisp, Qface, Voverlay_arrow_string);
11175 it.face_id = compute_char_face (f, it.c, face);
11177 /* Compute its width, get its glyphs. */
11178 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
11179 SET_TEXT_POS (it.position, -1, -1);
11180 PRODUCE_GLYPHS (&it);
11182 /* If this character doesn't fit any more in the line, we have
11183 to remove some glyphs. */
11184 if (it.current_x > it.last_visible_x)
11186 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
11187 break;
11191 set_buffer_temp (old);
11192 return it.glyph_row;
11196 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
11197 glyphs are only inserted for terminal frames since we can't really
11198 win with truncation glyphs when partially visible glyphs are
11199 involved. Which glyphs to insert is determined by
11200 produce_special_glyphs. */
11202 static void
11203 insert_left_trunc_glyphs (it)
11204 struct it *it;
11206 struct it truncate_it;
11207 struct glyph *from, *end, *to, *toend;
11209 xassert (!FRAME_WINDOW_P (it->f));
11211 /* Get the truncation glyphs. */
11212 truncate_it = *it;
11213 truncate_it.current_x = 0;
11214 truncate_it.face_id = DEFAULT_FACE_ID;
11215 truncate_it.glyph_row = &scratch_glyph_row;
11216 truncate_it.glyph_row->used[TEXT_AREA] = 0;
11217 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
11218 truncate_it.object = make_number (0);
11219 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
11221 /* Overwrite glyphs from IT with truncation glyphs. */
11222 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
11223 end = from + truncate_it.glyph_row->used[TEXT_AREA];
11224 to = it->glyph_row->glyphs[TEXT_AREA];
11225 toend = to + it->glyph_row->used[TEXT_AREA];
11227 while (from < end)
11228 *to++ = *from++;
11230 /* There may be padding glyphs left over. Remove them. */
11231 from = to;
11232 while (from < toend && CHAR_GLYPH_PADDING_P (*from))
11233 ++from;
11234 while (from < toend)
11235 *to++ = *from++;
11237 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
11241 /* Compute the pixel height and width of IT->glyph_row.
11243 Most of the time, ascent and height of a display line will be equal
11244 to the max_ascent and max_height values of the display iterator
11245 structure. This is not the case if
11247 1. We hit ZV without displaying anything. In this case, max_ascent
11248 and max_height will be zero.
11250 2. We have some glyphs that don't contribute to the line height.
11251 (The glyph row flag contributes_to_line_height_p is for future
11252 pixmap extensions).
11254 The first case is easily covered by using default values because in
11255 these cases, the line height does not really matter, except that it
11256 must not be zero. */
11258 static void
11259 compute_line_metrics (it)
11260 struct it *it;
11262 struct glyph_row *row = it->glyph_row;
11263 int area, i;
11265 if (FRAME_WINDOW_P (it->f))
11267 int i, header_line_height;
11269 /* The line may consist of one space only, that was added to
11270 place the cursor on it. If so, the row's height hasn't been
11271 computed yet. */
11272 if (row->height == 0)
11274 if (it->max_ascent + it->max_descent == 0)
11275 it->max_descent = it->max_phys_descent = CANON_Y_UNIT (it->f);
11276 row->ascent = it->max_ascent;
11277 row->height = it->max_ascent + it->max_descent;
11278 row->phys_ascent = it->max_phys_ascent;
11279 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
11282 /* Compute the width of this line. */
11283 row->pixel_width = row->x;
11284 for (i = 0; i < row->used[TEXT_AREA]; ++i)
11285 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
11287 xassert (row->pixel_width >= 0);
11288 xassert (row->ascent >= 0 && row->height > 0);
11290 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
11291 || MATRIX_ROW_OVERLAPS_PRED_P (row));
11293 /* If first line's physical ascent is larger than its logical
11294 ascent, use the physical ascent, and make the row taller.
11295 This makes accented characters fully visible. */
11296 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
11297 && row->phys_ascent > row->ascent)
11299 row->height += row->phys_ascent - row->ascent;
11300 row->ascent = row->phys_ascent;
11303 /* Compute how much of the line is visible. */
11304 row->visible_height = row->height;
11306 header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (it->w);
11307 if (row->y < header_line_height)
11308 row->visible_height -= header_line_height - row->y;
11309 else
11311 int max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (it->w);
11312 if (row->y + row->height > max_y)
11313 row->visible_height -= row->y + row->height - max_y;
11316 else
11318 row->pixel_width = row->used[TEXT_AREA];
11319 row->ascent = row->phys_ascent = 0;
11320 row->height = row->phys_height = row->visible_height = 1;
11323 /* Compute a hash code for this row. */
11324 row->hash = 0;
11325 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
11326 for (i = 0; i < row->used[area]; ++i)
11327 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
11328 + row->glyphs[area][i].u.val
11329 + row->glyphs[area][i].face_id
11330 + row->glyphs[area][i].padding_p
11331 + (row->glyphs[area][i].type << 2));
11333 it->max_ascent = it->max_descent = 0;
11334 it->max_phys_ascent = it->max_phys_descent = 0;
11338 /* Append one space to the glyph row of iterator IT if doing a
11339 window-based redisplay. DEFAULT_FACE_P non-zero means let the
11340 space have the default face, otherwise let it have the same face as
11341 IT->face_id. Value is non-zero if a space was added.
11343 This function is called to make sure that there is always one glyph
11344 at the end of a glyph row that the cursor can be set on under
11345 window-systems. (If there weren't such a glyph we would not know
11346 how wide and tall a box cursor should be displayed).
11348 At the same time this space let's a nicely handle clearing to the
11349 end of the line if the row ends in italic text. */
11351 static int
11352 append_space (it, default_face_p)
11353 struct it *it;
11354 int default_face_p;
11356 if (FRAME_WINDOW_P (it->f))
11358 int n = it->glyph_row->used[TEXT_AREA];
11360 if (it->glyph_row->glyphs[TEXT_AREA] + n
11361 < it->glyph_row->glyphs[1 + TEXT_AREA])
11363 /* Save some values that must not be changed. */
11364 int saved_x = it->current_x;
11365 struct text_pos saved_pos;
11366 int saved_what = it->what;
11367 int saved_face_id = it->face_id;
11368 Lisp_Object saved_object;
11369 struct face *face;
11371 saved_object = it->object;
11372 saved_pos = it->position;
11374 it->what = IT_CHARACTER;
11375 bzero (&it->position, sizeof it->position);
11376 it->object = make_number (0);
11377 it->c = ' ';
11378 it->len = 1;
11380 if (default_face_p)
11381 it->face_id = DEFAULT_FACE_ID;
11382 face = FACE_FROM_ID (it->f, it->face_id);
11383 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
11385 PRODUCE_GLYPHS (it);
11387 it->current_x = saved_x;
11388 it->object = saved_object;
11389 it->position = saved_pos;
11390 it->what = saved_what;
11391 it->face_id = saved_face_id;
11392 return 1;
11396 return 0;
11400 /* Extend the face of the last glyph in the text area of IT->glyph_row
11401 to the end of the display line. Called from display_line.
11402 If the glyph row is empty, add a space glyph to it so that we
11403 know the face to draw. Set the glyph row flag fill_line_p. */
11405 static void
11406 extend_face_to_end_of_line (it)
11407 struct it *it;
11409 struct face *face;
11410 struct frame *f = it->f;
11412 /* If line is already filled, do nothing. */
11413 if (it->current_x >= it->last_visible_x)
11414 return;
11416 /* Face extension extends the background and box of IT->face_id
11417 to the end of the line. If the background equals the background
11418 of the frame, we haven't to do anything. */
11419 face = FACE_FROM_ID (f, it->face_id);
11420 if (FRAME_WINDOW_P (f)
11421 && face->box == FACE_NO_BOX
11422 && face->background == FRAME_BACKGROUND_PIXEL (f)
11423 && !face->stipple)
11424 return;
11426 /* Set the glyph row flag indicating that the face of the last glyph
11427 in the text area has to be drawn to the end of the text area. */
11428 it->glyph_row->fill_line_p = 1;
11430 /* If current character of IT is not ASCII, make sure we have the
11431 ASCII face. This will be automatically undone the next time
11432 get_next_display_element returns a multibyte character. Note
11433 that the character will always be single byte in unibyte text. */
11434 if (!SINGLE_BYTE_CHAR_P (it->c))
11436 it->face_id = FACE_FOR_CHAR (f, face, 0);
11439 if (FRAME_WINDOW_P (f))
11441 /* If the row is empty, add a space with the current face of IT,
11442 so that we know which face to draw. */
11443 if (it->glyph_row->used[TEXT_AREA] == 0)
11445 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
11446 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
11447 it->glyph_row->used[TEXT_AREA] = 1;
11450 else
11452 /* Save some values that must not be changed. */
11453 int saved_x = it->current_x;
11454 struct text_pos saved_pos;
11455 Lisp_Object saved_object;
11456 int saved_what = it->what;
11458 saved_object = it->object;
11459 saved_pos = it->position;
11461 it->what = IT_CHARACTER;
11462 bzero (&it->position, sizeof it->position);
11463 it->object = make_number (0);
11464 it->c = ' ';
11465 it->len = 1;
11467 PRODUCE_GLYPHS (it);
11469 while (it->current_x <= it->last_visible_x)
11470 PRODUCE_GLYPHS (it);
11472 /* Don't count these blanks really. It would let us insert a left
11473 truncation glyph below and make us set the cursor on them, maybe. */
11474 it->current_x = saved_x;
11475 it->object = saved_object;
11476 it->position = saved_pos;
11477 it->what = saved_what;
11482 /* Value is non-zero if text starting at CHARPOS in current_buffer is
11483 trailing whitespace. */
11485 static int
11486 trailing_whitespace_p (charpos)
11487 int charpos;
11489 int bytepos = CHAR_TO_BYTE (charpos);
11490 int c = 0;
11492 while (bytepos < ZV_BYTE
11493 && (c = FETCH_CHAR (bytepos),
11494 c == ' ' || c == '\t'))
11495 ++bytepos;
11497 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
11499 if (bytepos != PT_BYTE)
11500 return 1;
11502 return 0;
11506 /* Highlight trailing whitespace, if any, in ROW. */
11508 void
11509 highlight_trailing_whitespace (f, row)
11510 struct frame *f;
11511 struct glyph_row *row;
11513 int used = row->used[TEXT_AREA];
11515 if (used)
11517 struct glyph *start = row->glyphs[TEXT_AREA];
11518 struct glyph *glyph = start + used - 1;
11520 /* Skip over the space glyph inserted to display the
11521 cursor at the end of a line. */
11522 if (glyph->type == CHAR_GLYPH
11523 && glyph->u.ch == ' '
11524 && INTEGERP (glyph->object))
11525 --glyph;
11527 /* If last glyph is a space or stretch, and it's trailing
11528 whitespace, set the face of all trailing whitespace glyphs in
11529 IT->glyph_row to `trailing-whitespace'. */
11530 if (glyph >= start
11531 && BUFFERP (glyph->object)
11532 && (glyph->type == STRETCH_GLYPH
11533 || (glyph->type == CHAR_GLYPH
11534 && glyph->u.ch == ' '))
11535 && trailing_whitespace_p (glyph->charpos))
11537 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
11539 while (glyph >= start
11540 && BUFFERP (glyph->object)
11541 && (glyph->type == STRETCH_GLYPH
11542 || (glyph->type == CHAR_GLYPH
11543 && glyph->u.ch == ' ')))
11544 (glyph--)->face_id = face_id;
11550 /* Construct the glyph row IT->glyph_row in the desired matrix of
11551 IT->w from text at the current position of IT. See dispextern.h
11552 for an overview of struct it. Value is non-zero if
11553 IT->glyph_row displays text, as opposed to a line displaying ZV
11554 only. */
11556 static int
11557 display_line (it)
11558 struct it *it;
11560 struct glyph_row *row = it->glyph_row;
11562 /* We always start displaying at hpos zero even if hscrolled. */
11563 xassert (it->hpos == 0 && it->current_x == 0);
11565 /* We must not display in a row that's not a text row. */
11566 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
11567 < it->w->desired_matrix->nrows);
11569 /* Is IT->w showing the region? */
11570 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
11572 /* Clear the result glyph row and enable it. */
11573 prepare_desired_row (row);
11575 row->y = it->current_y;
11576 row->start = it->current;
11577 row->continuation_lines_width = it->continuation_lines_width;
11578 row->displays_text_p = 1;
11579 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
11580 it->starts_in_middle_of_char_p = 0;
11582 /* Arrange the overlays nicely for our purposes. Usually, we call
11583 display_line on only one line at a time, in which case this
11584 can't really hurt too much, or we call it on lines which appear
11585 one after another in the buffer, in which case all calls to
11586 recenter_overlay_lists but the first will be pretty cheap. */
11587 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
11589 /* Move over display elements that are not visible because we are
11590 hscrolled. This may stop at an x-position < IT->first_visible_x
11591 if the first glyph is partially visible or if we hit a line end. */
11592 if (it->current_x < it->first_visible_x)
11593 move_it_in_display_line_to (it, ZV, it->first_visible_x,
11594 MOVE_TO_POS | MOVE_TO_X);
11596 /* Get the initial row height. This is either the height of the
11597 text hscrolled, if there is any, or zero. */
11598 row->ascent = it->max_ascent;
11599 row->height = it->max_ascent + it->max_descent;
11600 row->phys_ascent = it->max_phys_ascent;
11601 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
11603 /* Loop generating characters. The loop is left with IT on the next
11604 character to display. */
11605 while (1)
11607 int n_glyphs_before, hpos_before, x_before;
11608 int x, i, nglyphs;
11609 int ascent, descent, phys_ascent, phys_descent;
11611 /* Retrieve the next thing to display. Value is zero if end of
11612 buffer reached. */
11613 if (!get_next_display_element (it))
11615 /* Maybe add a space at the end of this line that is used to
11616 display the cursor there under X. Set the charpos of the
11617 first glyph of blank lines not corresponding to any text
11618 to -1. */
11619 if ((append_space (it, 1) && row->used[TEXT_AREA] == 1)
11620 || row->used[TEXT_AREA] == 0)
11622 row->glyphs[TEXT_AREA]->charpos = -1;
11623 row->displays_text_p = 0;
11625 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines))
11626 row->indicate_empty_line_p = 1;
11629 it->continuation_lines_width = 0;
11630 row->ends_at_zv_p = 1;
11631 break;
11634 /* Now, get the metrics of what we want to display. This also
11635 generates glyphs in `row' (which is IT->glyph_row). */
11636 n_glyphs_before = row->used[TEXT_AREA];
11637 x = it->current_x;
11639 /* Remember the line height so far in case the next element doesn't
11640 fit on the line. */
11641 if (!it->truncate_lines_p)
11643 ascent = it->max_ascent;
11644 descent = it->max_descent;
11645 phys_ascent = it->max_phys_ascent;
11646 phys_descent = it->max_phys_descent;
11649 PRODUCE_GLYPHS (it);
11651 /* If this display element was in marginal areas, continue with
11652 the next one. */
11653 if (it->area != TEXT_AREA)
11655 row->ascent = max (row->ascent, it->max_ascent);
11656 row->height = max (row->height, it->max_ascent + it->max_descent);
11657 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
11658 row->phys_height = max (row->phys_height,
11659 it->max_phys_ascent + it->max_phys_descent);
11660 set_iterator_to_next (it);
11661 continue;
11664 /* Does the display element fit on the line? If we truncate
11665 lines, we should draw past the right edge of the window. If
11666 we don't truncate, we want to stop so that we can display the
11667 continuation glyph before the right margin. If lines are
11668 continued, there are two possible strategies for characters
11669 resulting in more than 1 glyph (e.g. tabs): Display as many
11670 glyphs as possible in this line and leave the rest for the
11671 continuation line, or display the whole element in the next
11672 line. Original redisplay did the former, so we do it also. */
11673 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
11674 hpos_before = it->hpos;
11675 x_before = x;
11677 if (nglyphs == 1
11678 && it->current_x < it->last_visible_x)
11680 ++it->hpos;
11681 row->ascent = max (row->ascent, it->max_ascent);
11682 row->height = max (row->height, it->max_ascent + it->max_descent);
11683 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
11684 row->phys_height = max (row->phys_height,
11685 it->max_phys_ascent + it->max_phys_descent);
11686 if (it->current_x - it->pixel_width < it->first_visible_x)
11687 row->x = x - it->first_visible_x;
11689 else
11691 int new_x;
11692 struct glyph *glyph;
11694 for (i = 0; i < nglyphs; ++i, x = new_x)
11696 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11697 new_x = x + glyph->pixel_width;
11699 if (/* Lines are continued. */
11700 !it->truncate_lines_p
11701 && (/* Glyph doesn't fit on the line. */
11702 new_x > it->last_visible_x
11703 /* Or it fits exactly on a window system frame. */
11704 || (new_x == it->last_visible_x
11705 && FRAME_WINDOW_P (it->f))))
11707 /* End of a continued line. */
11709 if (it->hpos == 0
11710 || (new_x == it->last_visible_x
11711 && FRAME_WINDOW_P (it->f)))
11713 /* Current glyph is the only one on the line or
11714 fits exactly on the line. We must continue
11715 the line because we can't draw the cursor
11716 after the glyph. */
11717 row->continued_p = 1;
11718 it->current_x = new_x;
11719 it->continuation_lines_width += new_x;
11720 ++it->hpos;
11721 if (i == nglyphs - 1)
11722 set_iterator_to_next (it);
11724 else if (CHAR_GLYPH_PADDING_P (*glyph)
11725 && !FRAME_WINDOW_P (it->f))
11727 /* A padding glyph that doesn't fit on this line.
11728 This means the whole character doesn't fit
11729 on the line. */
11730 row->used[TEXT_AREA] = n_glyphs_before;
11732 /* Fill the rest of the row with continuation
11733 glyphs like in 20.x. */
11734 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
11735 < row->glyphs[1 + TEXT_AREA])
11736 produce_special_glyphs (it, IT_CONTINUATION);
11738 row->continued_p = 1;
11739 it->current_x = x_before;
11740 it->continuation_lines_width += x_before;
11742 /* Restore the height to what it was before the
11743 element not fitting on the line. */
11744 it->max_ascent = ascent;
11745 it->max_descent = descent;
11746 it->max_phys_ascent = phys_ascent;
11747 it->max_phys_descent = phys_descent;
11749 else
11751 /* Display element draws past the right edge of
11752 the window. Restore positions to values
11753 before the element. The next line starts
11754 with current_x before the glyph that could
11755 not be displayed, so that TAB works right. */
11756 row->used[TEXT_AREA] = n_glyphs_before + i;
11758 /* Display continuation glyphs. */
11759 if (!FRAME_WINDOW_P (it->f))
11760 produce_special_glyphs (it, IT_CONTINUATION);
11761 row->continued_p = 1;
11763 it->current_x = x;
11764 it->continuation_lines_width += x;
11765 if (nglyphs > 1 && i > 0)
11767 row->ends_in_middle_of_char_p = 1;
11768 it->starts_in_middle_of_char_p = 1;
11771 /* Restore the height to what it was before the
11772 element not fitting on the line. */
11773 it->max_ascent = ascent;
11774 it->max_descent = descent;
11775 it->max_phys_ascent = phys_ascent;
11776 it->max_phys_descent = phys_descent;
11779 break;
11781 else if (new_x > it->first_visible_x)
11783 /* Increment number of glyphs actually displayed. */
11784 ++it->hpos;
11786 if (x < it->first_visible_x)
11787 /* Glyph is partially visible, i.e. row starts at
11788 negative X position. */
11789 row->x = x - it->first_visible_x;
11791 else
11793 /* Glyph is completely off the left margin of the
11794 window. This should not happen because of the
11795 move_it_in_display_line at the start of
11796 this function. */
11797 abort ();
11801 row->ascent = max (row->ascent, it->max_ascent);
11802 row->height = max (row->height, it->max_ascent + it->max_descent);
11803 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
11804 row->phys_height = max (row->phys_height,
11805 it->max_phys_ascent + it->max_phys_descent);
11807 /* End of this display line if row is continued. */
11808 if (row->continued_p)
11809 break;
11812 /* Is this a line end? If yes, we're also done, after making
11813 sure that a non-default face is extended up to the right
11814 margin of the window. */
11815 if (ITERATOR_AT_END_OF_LINE_P (it))
11817 int used_before = row->used[TEXT_AREA];
11819 /* Add a space at the end of the line that is used to
11820 display the cursor there. */
11821 append_space (it, 0);
11823 /* Extend the face to the end of the line. */
11824 extend_face_to_end_of_line (it);
11826 /* Make sure we have the position. */
11827 if (used_before == 0)
11828 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
11830 /* Consume the line end. This skips over invisible lines. */
11831 set_iterator_to_next (it);
11832 it->continuation_lines_width = 0;
11833 break;
11836 /* Proceed with next display element. Note that this skips
11837 over lines invisible because of selective display. */
11838 set_iterator_to_next (it);
11840 /* If we truncate lines, we are done when the last displayed
11841 glyphs reach past the right margin of the window. */
11842 if (it->truncate_lines_p
11843 && (FRAME_WINDOW_P (it->f)
11844 ? (it->current_x >= it->last_visible_x)
11845 : (it->current_x > it->last_visible_x)))
11847 /* Maybe add truncation glyphs. */
11848 if (!FRAME_WINDOW_P (it->f))
11850 --it->glyph_row->used[TEXT_AREA];
11851 produce_special_glyphs (it, IT_TRUNCATION);
11854 row->truncated_on_right_p = 1;
11855 it->continuation_lines_width = 0;
11856 reseat_at_next_visible_line_start (it, 0);
11857 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
11858 it->hpos = hpos_before;
11859 it->current_x = x_before;
11860 break;
11864 /* If line is not empty and hscrolled, maybe insert truncation glyphs
11865 at the left window margin. */
11866 if (it->first_visible_x
11867 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
11869 if (!FRAME_WINDOW_P (it->f))
11870 insert_left_trunc_glyphs (it);
11871 row->truncated_on_left_p = 1;
11874 /* If the start of this line is the overlay arrow-position, then
11875 mark this glyph row as the one containing the overlay arrow.
11876 This is clearly a mess with variable size fonts. It would be
11877 better to let it be displayed like cursors under X. */
11878 if (MARKERP (Voverlay_arrow_position)
11879 && current_buffer == XMARKER (Voverlay_arrow_position)->buffer
11880 && (MATRIX_ROW_START_CHARPOS (row)
11881 == marker_position (Voverlay_arrow_position))
11882 && STRINGP (Voverlay_arrow_string)
11883 && ! overlay_arrow_seen)
11885 /* Overlay arrow in window redisplay is a bitmap. */
11886 if (!FRAME_WINDOW_P (it->f))
11888 struct glyph_row *arrow_row = get_overlay_arrow_glyph_row (it->w);
11889 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
11890 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
11891 struct glyph *p = row->glyphs[TEXT_AREA];
11892 struct glyph *p2, *end;
11894 /* Copy the arrow glyphs. */
11895 while (glyph < arrow_end)
11896 *p++ = *glyph++;
11898 /* Throw away padding glyphs. */
11899 p2 = p;
11900 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
11901 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
11902 ++p2;
11903 if (p2 > p)
11905 while (p2 < end)
11906 *p++ = *p2++;
11907 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
11911 overlay_arrow_seen = 1;
11912 row->overlay_arrow_p = 1;
11915 /* Compute pixel dimensions of this line. */
11916 compute_line_metrics (it);
11918 /* Remember the position at which this line ends. */
11919 row->end = it->current;
11921 /* Maybe set the cursor. */
11922 if (it->w->cursor.vpos < 0
11923 && PT >= MATRIX_ROW_START_CHARPOS (row)
11924 && PT <= MATRIX_ROW_END_CHARPOS (row))
11926 /* Also see redisplay_window, case cursor movement in unchanged
11927 window. */
11928 if (MATRIX_ROW_END_CHARPOS (row) == PT
11929 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
11930 && !row->ends_at_zv_p)
11932 else
11933 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
11936 /* Highlight trailing whitespace. */
11937 if (!NILP (Vshow_trailing_whitespace))
11938 highlight_trailing_whitespace (it->f, it->glyph_row);
11940 /* Prepare for the next line. This line starts horizontally at (X
11941 HPOS) = (0 0). Vertical positions are incremented. As a
11942 convenience for the caller, IT->glyph_row is set to the next
11943 row to be used. */
11944 it->current_x = it->hpos = 0;
11945 it->current_y += row->height;
11946 ++it->vpos;
11947 ++it->glyph_row;
11948 return row->displays_text_p;
11953 /***********************************************************************
11954 Menu Bar
11955 ***********************************************************************/
11957 /* Redisplay the menu bar in the frame for window W.
11959 The menu bar of X frames that don't have X toolkit support is
11960 displayed in a special window W->frame->menu_bar_window.
11962 The menu bar of terminal frames is treated specially as far as
11963 glyph matrices are concerned. Menu bar lines are not part of
11964 windows, so the update is done directly on the frame matrix rows
11965 for the menu bar. */
11967 static void
11968 display_menu_bar (w)
11969 struct window *w;
11971 struct frame *f = XFRAME (WINDOW_FRAME (w));
11972 struct it it;
11973 Lisp_Object items;
11974 int i;
11976 /* Don't do all this for graphical frames. */
11977 #ifdef HAVE_NTGUI
11978 if (!NILP (Vwindow_system))
11979 return;
11980 #endif
11981 #ifdef USE_X_TOOLKIT
11982 if (FRAME_X_P (f))
11983 return;
11984 #endif
11986 #ifdef USE_X_TOOLKIT
11987 xassert (!FRAME_WINDOW_P (f));
11988 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
11989 it.first_visible_x = 0;
11990 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
11991 #else /* not USE_X_TOOLKIT */
11992 if (FRAME_WINDOW_P (f))
11994 /* Menu bar lines are displayed in the desired matrix of the
11995 dummy window menu_bar_window. */
11996 struct window *menu_w;
11997 xassert (WINDOWP (f->menu_bar_window));
11998 menu_w = XWINDOW (f->menu_bar_window);
11999 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
12000 MENU_FACE_ID);
12001 it.first_visible_x = 0;
12002 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
12004 else
12006 /* This is a TTY frame, i.e. character hpos/vpos are used as
12007 pixel x/y. */
12008 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
12009 MENU_FACE_ID);
12010 it.first_visible_x = 0;
12011 it.last_visible_x = FRAME_WIDTH (f);
12013 #endif /* not USE_X_TOOLKIT */
12015 /* Clear all rows of the menu bar. */
12016 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
12018 struct glyph_row *row = it.glyph_row + i;
12019 clear_glyph_row (row);
12020 row->enabled_p = 1;
12021 row->full_width_p = 1;
12024 /* Make the first line of the menu bar appear in reverse video. */
12025 it.glyph_row->inverse_p = mode_line_inverse_video != 0;
12027 /* Display all items of the menu bar. */
12028 items = FRAME_MENU_BAR_ITEMS (it.f);
12029 for (i = 0; i < XVECTOR (items)->size; i += 4)
12031 Lisp_Object string;
12033 /* Stop at nil string. */
12034 string = XVECTOR (items)->contents[i + 1];
12035 if (NILP (string))
12036 break;
12038 /* Remember where item was displayed. */
12039 XSETFASTINT (XVECTOR (items)->contents[i + 3], it.hpos);
12041 /* Display the item, pad with one space. */
12042 if (it.current_x < it.last_visible_x)
12043 display_string (NULL, string, Qnil, 0, 0, &it,
12044 XSTRING (string)->size + 1, 0, 0, -1);
12047 /* Fill out the line with spaces. */
12048 if (it.current_x < it.last_visible_x)
12049 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
12051 /* Compute the total height of the lines. */
12052 compute_line_metrics (&it);
12057 /***********************************************************************
12058 Mode Line
12059 ***********************************************************************/
12061 /* Display the mode and/or top line of window W. */
12063 static void
12064 display_mode_lines (w)
12065 struct window *w;
12067 /* These will be set while the mode line specs are processed. */
12068 line_number_displayed = 0;
12069 w->column_number_displayed = Qnil;
12071 if (WINDOW_WANTS_MODELINE_P (w))
12072 display_mode_line (w, MODE_LINE_FACE_ID,
12073 current_buffer->mode_line_format);
12075 if (WINDOW_WANTS_HEADER_LINE_P (w))
12076 display_mode_line (w, HEADER_LINE_FACE_ID,
12077 current_buffer->header_line_format);
12081 /* Display mode or top line of window W. FACE_ID specifies which line
12082 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
12083 FORMAT is the mode line format to display. */
12085 static void
12086 display_mode_line (w, face_id, format)
12087 struct window *w;
12088 enum face_id face_id;
12089 Lisp_Object format;
12091 struct it it;
12092 struct face *face;
12094 init_iterator (&it, w, -1, -1, NULL, face_id);
12095 prepare_desired_row (it.glyph_row);
12097 /* Temporarily make frame's keyboard the current kboard so that
12098 kboard-local variables in the mode_line_format will get the right
12099 values. */
12100 push_frame_kboard (it.f);
12101 display_mode_element (&it, 0, 0, 0, format);
12102 pop_frame_kboard ();
12104 /* Fill up with spaces. */
12105 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
12107 compute_line_metrics (&it);
12108 it.glyph_row->full_width_p = 1;
12109 it.glyph_row->mode_line_p = 1;
12110 it.glyph_row->inverse_p = mode_line_inverse_video != 0;
12111 it.glyph_row->continued_p = 0;
12112 it.glyph_row->truncated_on_left_p = 0;
12113 it.glyph_row->truncated_on_right_p = 0;
12115 /* Make a 3D mode-line have a shadow at its right end. */
12116 face = FACE_FROM_ID (it.f, face_id);
12117 extend_face_to_end_of_line (&it);
12118 if (face->box != FACE_NO_BOX)
12120 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
12121 + it.glyph_row->used[TEXT_AREA] - 1);
12122 last->right_box_line_p = 1;
12127 /* Contribute ELT to the mode line for window IT->w. How it
12128 translates into text depends on its data type.
12130 IT describes the display environment in which we display, as usual.
12132 DEPTH is the depth in recursion. It is used to prevent
12133 infinite recursion here.
12135 FIELD_WIDTH is the number of characters the display of ELT should
12136 occupy in the mode line, and PRECISION is the maximum number of
12137 characters to display from ELT's representation. See
12138 display_string for details. *
12140 Returns the hpos of the end of the text generated by ELT. */
12142 static int
12143 display_mode_element (it, depth, field_width, precision, elt)
12144 struct it *it;
12145 int depth;
12146 int field_width, precision;
12147 Lisp_Object elt;
12149 int n = 0, field, prec;
12151 tail_recurse:
12152 if (depth > 10)
12153 goto invalid;
12155 depth++;
12157 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
12159 case Lisp_String:
12161 /* A string: output it and check for %-constructs within it. */
12162 unsigned char c;
12163 unsigned char *this = XSTRING (elt)->data;
12164 unsigned char *lisp_string = this;
12166 while ((precision <= 0 || n < precision)
12167 && *this
12168 && (frame_title_ptr
12169 || it->current_x < it->last_visible_x))
12171 unsigned char *last = this;
12173 /* Advance to end of string or next format specifier. */
12174 while ((c = *this++) != '\0' && c != '%')
12177 if (this - 1 != last)
12179 /* Output to end of string or up to '%'. Field width
12180 is length of string. Don't output more than
12181 PRECISION allows us. */
12182 prec = --this - last;
12183 if (precision > 0 && prec > precision - n)
12184 prec = precision - n;
12186 if (frame_title_ptr)
12187 n += store_frame_title (last, prec, prec);
12188 else
12189 n += display_string (NULL, elt, Qnil, 0, last - lisp_string,
12190 it, 0, prec, 0, -1);
12192 else /* c == '%' */
12194 unsigned char *percent_position = this;
12196 /* Get the specified minimum width. Zero means
12197 don't pad. */
12198 field = 0;
12199 while ((c = *this++) >= '0' && c <= '9')
12200 field = field * 10 + c - '0';
12202 /* Don't pad beyond the total padding allowed. */
12203 if (field_width - n > 0 && field > field_width - n)
12204 field = field_width - n;
12206 /* Note that either PRECISION <= 0 or N < PRECISION. */
12207 prec = precision - n;
12209 if (c == 'M')
12210 n += display_mode_element (it, depth, field, prec,
12211 Vglobal_mode_string);
12212 else if (c != 0)
12214 unsigned char *spec
12215 = decode_mode_spec (it->w, c, field, prec);
12217 if (frame_title_ptr)
12218 n += store_frame_title (spec, field, prec);
12219 else
12221 int nglyphs_before
12222 = it->glyph_row->used[TEXT_AREA];
12223 int charpos
12224 = percent_position - XSTRING (elt)->data;
12225 int nwritten
12226 = display_string (spec, Qnil, elt, charpos, 0, it,
12227 field, prec, 0, -1);
12229 /* Assign to the glyphs written above the
12230 string where the `%x' came from, position
12231 of the `%'. */
12232 if (nwritten > 0)
12234 struct glyph *glyph
12235 = (it->glyph_row->glyphs[TEXT_AREA]
12236 + nglyphs_before);
12237 int i;
12239 for (i = 0; i < nwritten; ++i)
12241 glyph[i].object = elt;
12242 glyph[i].charpos = charpos;
12245 n += nwritten;
12252 break;
12254 case Lisp_Symbol:
12255 /* A symbol: process the value of the symbol recursively
12256 as if it appeared here directly. Avoid error if symbol void.
12257 Special case: if value of symbol is a string, output the string
12258 literally. */
12260 register Lisp_Object tem;
12261 tem = Fboundp (elt);
12262 if (!NILP (tem))
12264 tem = Fsymbol_value (elt);
12265 /* If value is a string, output that string literally:
12266 don't check for % within it. */
12267 if (STRINGP (tem))
12269 prec = XSTRING (tem)->size;
12270 if (precision > 0 && prec > precision - n)
12271 prec = precision - n;
12272 if (frame_title_ptr)
12273 n += store_frame_title (XSTRING (tem)->data, -1, prec);
12274 else
12275 n += display_string (NULL, tem, Qnil, 0, 0, it,
12276 0, prec, 0, -1);
12278 else if (!EQ (tem, elt))
12280 /* Give up right away for nil or t. */
12281 elt = tem;
12282 goto tail_recurse;
12286 break;
12288 case Lisp_Cons:
12290 register Lisp_Object car, tem;
12292 /* A cons cell: three distinct cases.
12293 If first element is a string or a cons, process all the elements
12294 and effectively concatenate them.
12295 If first element is a negative number, truncate displaying cdr to
12296 at most that many characters. If positive, pad (with spaces)
12297 to at least that many characters.
12298 If first element is a symbol, process the cadr or caddr recursively
12299 according to whether the symbol's value is non-nil or nil. */
12300 car = XCAR (elt);
12301 if (EQ (car, QCeval) && CONSP (XCDR (elt)))
12303 /* An element of the form (:eval FORM) means evaluate FORM
12304 and use the result as mode line elements. */
12305 struct gcpro gcpro1;
12306 Lisp_Object spec;
12308 spec = eval_form (XCAR (XCDR (elt)));
12309 GCPRO1 (spec);
12310 n += display_mode_element (it, depth, field_width - n,
12311 precision - n, spec);
12312 UNGCPRO;
12314 else if (SYMBOLP (car))
12316 tem = Fboundp (car);
12317 elt = XCDR (elt);
12318 if (!CONSP (elt))
12319 goto invalid;
12320 /* elt is now the cdr, and we know it is a cons cell.
12321 Use its car if CAR has a non-nil value. */
12322 if (!NILP (tem))
12324 tem = Fsymbol_value (car);
12325 if (!NILP (tem))
12327 elt = XCAR (elt);
12328 goto tail_recurse;
12331 /* Symbol's value is nil (or symbol is unbound)
12332 Get the cddr of the original list
12333 and if possible find the caddr and use that. */
12334 elt = XCDR (elt);
12335 if (NILP (elt))
12336 break;
12337 else if (!CONSP (elt))
12338 goto invalid;
12339 elt = XCAR (elt);
12340 goto tail_recurse;
12342 else if (INTEGERP (car))
12344 register int lim = XINT (car);
12345 elt = XCDR (elt);
12346 if (lim < 0)
12348 /* Negative int means reduce maximum width. */
12349 if (precision <= 0)
12350 precision = -lim;
12351 else
12352 precision = min (precision, -lim);
12354 else if (lim > 0)
12356 /* Padding specified. Don't let it be more than
12357 current maximum. */
12358 if (precision > 0)
12359 lim = min (precision, lim);
12361 /* If that's more padding than already wanted, queue it.
12362 But don't reduce padding already specified even if
12363 that is beyond the current truncation point. */
12364 field_width = max (lim, field_width);
12366 goto tail_recurse;
12368 else if (STRINGP (car) || CONSP (car))
12370 register int limit = 50;
12371 /* Limit is to protect against circular lists. */
12372 while (CONSP (elt)
12373 && --limit > 0
12374 && (precision <= 0 || n < precision))
12376 n += display_mode_element (it, depth, field_width - n,
12377 precision - n, XCAR (elt));
12378 elt = XCDR (elt);
12382 break;
12384 default:
12385 invalid:
12386 if (frame_title_ptr)
12387 n += store_frame_title ("*invalid*", 0, precision - n);
12388 else
12389 n += display_string ("*invalid*", Qnil, Qnil, 0, 0, it, 0,
12390 precision - n, 0, 0);
12391 return n;
12394 /* Pad to FIELD_WIDTH. */
12395 if (field_width > 0 && n < field_width)
12397 if (frame_title_ptr)
12398 n += store_frame_title ("", field_width - n, 0);
12399 else
12400 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
12401 0, 0, 0);
12404 return n;
12408 /* Write a null-terminated, right justified decimal representation of
12409 the positive integer D to BUF using a minimal field width WIDTH. */
12411 static void
12412 pint2str (buf, width, d)
12413 register char *buf;
12414 register int width;
12415 register int d;
12417 register char *p = buf;
12419 if (d <= 0)
12420 *p++ = '0';
12421 else
12423 while (d > 0)
12425 *p++ = d % 10 + '0';
12426 d /= 10;
12430 for (width -= (int) (p - buf); width > 0; --width)
12431 *p++ = ' ';
12432 *p-- = '\0';
12433 while (p > buf)
12435 d = *buf;
12436 *buf++ = *p;
12437 *p-- = d;
12441 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
12442 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
12443 type of CODING_SYSTEM. Return updated pointer into BUF. */
12445 static unsigned char invalid_eol_type[] = "(*invalid*)";
12447 static char *
12448 decode_mode_spec_coding (coding_system, buf, eol_flag)
12449 Lisp_Object coding_system;
12450 register char *buf;
12451 int eol_flag;
12453 Lisp_Object val;
12454 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
12455 unsigned char *eol_str;
12456 int eol_str_len;
12457 /* The EOL conversion we are using. */
12458 Lisp_Object eoltype;
12460 val = Fget (coding_system, Qcoding_system);
12462 if (!VECTORP (val)) /* Not yet decided. */
12464 if (multibyte)
12465 *buf++ = '-';
12466 if (eol_flag)
12467 eoltype = eol_mnemonic_undecided;
12468 /* Don't mention EOL conversion if it isn't decided. */
12470 else
12472 Lisp_Object eolvalue;
12474 eolvalue = Fget (coding_system, Qeol_type);
12476 if (multibyte)
12477 *buf++ = XFASTINT (XVECTOR (val)->contents[1]);
12479 if (eol_flag)
12481 /* The EOL conversion that is normal on this system. */
12483 if (NILP (eolvalue)) /* Not yet decided. */
12484 eoltype = eol_mnemonic_undecided;
12485 else if (VECTORP (eolvalue)) /* Not yet decided. */
12486 eoltype = eol_mnemonic_undecided;
12487 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
12488 eoltype = (XFASTINT (eolvalue) == 0
12489 ? eol_mnemonic_unix
12490 : (XFASTINT (eolvalue) == 1
12491 ? eol_mnemonic_dos : eol_mnemonic_mac));
12495 if (eol_flag)
12497 /* Mention the EOL conversion if it is not the usual one. */
12498 if (STRINGP (eoltype))
12500 eol_str = XSTRING (eoltype)->data;
12501 eol_str_len = XSTRING (eoltype)->size;
12503 else if (INTEGERP (eoltype)
12504 && CHAR_VALID_P (XINT (eoltype), 0))
12506 eol_str = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
12507 eol_str_len = CHAR_STRING (XINT (eoltype), eol_str);
12509 else
12511 eol_str = invalid_eol_type;
12512 eol_str_len = sizeof (invalid_eol_type) - 1;
12514 bcopy (eol_str, buf, eol_str_len);
12515 buf += eol_str_len;
12518 return buf;
12521 /* Return a string for the output of a mode line %-spec for window W,
12522 generated by character C. PRECISION >= 0 means don't return a
12523 string longer than that value. FIELD_WIDTH > 0 means pad the
12524 string returned with spaces to that value. */
12526 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
12528 static char *
12529 decode_mode_spec (w, c, field_width, precision)
12530 struct window *w;
12531 register int c;
12532 int field_width, precision;
12534 Lisp_Object obj;
12535 struct frame *f = XFRAME (WINDOW_FRAME (w));
12536 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
12537 struct buffer *b = XBUFFER (w->buffer);
12539 obj = Qnil;
12541 switch (c)
12543 case '*':
12544 if (!NILP (b->read_only))
12545 return "%";
12546 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
12547 return "*";
12548 return "-";
12550 case '+':
12551 /* This differs from %* only for a modified read-only buffer. */
12552 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
12553 return "*";
12554 if (!NILP (b->read_only))
12555 return "%";
12556 return "-";
12558 case '&':
12559 /* This differs from %* in ignoring read-only-ness. */
12560 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
12561 return "*";
12562 return "-";
12564 case '%':
12565 return "%";
12567 case '[':
12569 int i;
12570 char *p;
12572 if (command_loop_level > 5)
12573 return "[[[... ";
12574 p = decode_mode_spec_buf;
12575 for (i = 0; i < command_loop_level; i++)
12576 *p++ = '[';
12577 *p = 0;
12578 return decode_mode_spec_buf;
12581 case ']':
12583 int i;
12584 char *p;
12586 if (command_loop_level > 5)
12587 return " ...]]]";
12588 p = decode_mode_spec_buf;
12589 for (i = 0; i < command_loop_level; i++)
12590 *p++ = ']';
12591 *p = 0;
12592 return decode_mode_spec_buf;
12595 case '-':
12597 register int i;
12599 /* Let lots_of_dashes be a string of infinite length. */
12600 if (field_width <= 0
12601 || field_width > sizeof (lots_of_dashes))
12603 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
12604 decode_mode_spec_buf[i] = '-';
12605 decode_mode_spec_buf[i] = '\0';
12606 return decode_mode_spec_buf;
12608 else
12609 return lots_of_dashes;
12612 case 'b':
12613 obj = b->name;
12614 break;
12616 case 'c':
12618 int col = current_column ();
12619 XSETFASTINT (w->column_number_displayed, col);
12620 pint2str (decode_mode_spec_buf, field_width, col);
12621 return decode_mode_spec_buf;
12624 case 'F':
12625 /* %F displays the frame name. */
12626 if (!NILP (f->title))
12627 return (char *) XSTRING (f->title)->data;
12628 if (f->explicit_name || ! FRAME_WINDOW_P (f))
12629 return (char *) XSTRING (f->name)->data;
12630 return "Emacs";
12632 case 'f':
12633 obj = b->filename;
12634 break;
12636 case 'l':
12638 int startpos = XMARKER (w->start)->charpos;
12639 int startpos_byte = marker_byte_position (w->start);
12640 int line, linepos, linepos_byte, topline;
12641 int nlines, junk;
12642 int height = XFASTINT (w->height);
12644 /* If we decided that this buffer isn't suitable for line numbers,
12645 don't forget that too fast. */
12646 if (EQ (w->base_line_pos, w->buffer))
12647 goto no_value;
12648 /* But do forget it, if the window shows a different buffer now. */
12649 else if (BUFFERP (w->base_line_pos))
12650 w->base_line_pos = Qnil;
12652 /* If the buffer is very big, don't waste time. */
12653 if (INTEGERP (Vline_number_display_limit)
12654 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
12656 w->base_line_pos = Qnil;
12657 w->base_line_number = Qnil;
12658 goto no_value;
12661 if (!NILP (w->base_line_number)
12662 && !NILP (w->base_line_pos)
12663 && XFASTINT (w->base_line_pos) <= startpos)
12665 line = XFASTINT (w->base_line_number);
12666 linepos = XFASTINT (w->base_line_pos);
12667 linepos_byte = buf_charpos_to_bytepos (b, linepos);
12669 else
12671 line = 1;
12672 linepos = BUF_BEGV (b);
12673 linepos_byte = BUF_BEGV_BYTE (b);
12676 /* Count lines from base line to window start position. */
12677 nlines = display_count_lines (linepos, linepos_byte,
12678 startpos_byte,
12679 startpos, &junk);
12681 topline = nlines + line;
12683 /* Determine a new base line, if the old one is too close
12684 or too far away, or if we did not have one.
12685 "Too close" means it's plausible a scroll-down would
12686 go back past it. */
12687 if (startpos == BUF_BEGV (b))
12689 XSETFASTINT (w->base_line_number, topline);
12690 XSETFASTINT (w->base_line_pos, BUF_BEGV (b));
12692 else if (nlines < height + 25 || nlines > height * 3 + 50
12693 || linepos == BUF_BEGV (b))
12695 int limit = BUF_BEGV (b);
12696 int limit_byte = BUF_BEGV_BYTE (b);
12697 int position;
12698 int distance = (height * 2 + 30) * line_number_display_limit_width;
12700 if (startpos - distance > limit)
12702 limit = startpos - distance;
12703 limit_byte = CHAR_TO_BYTE (limit);
12706 nlines = display_count_lines (startpos, startpos_byte,
12707 limit_byte,
12708 - (height * 2 + 30),
12709 &position);
12710 /* If we couldn't find the lines we wanted within
12711 line_number_display_limit_width chars per line,
12712 give up on line numbers for this window. */
12713 if (position == limit_byte && limit == startpos - distance)
12715 w->base_line_pos = w->buffer;
12716 w->base_line_number = Qnil;
12717 goto no_value;
12720 XSETFASTINT (w->base_line_number, topline - nlines);
12721 XSETFASTINT (w->base_line_pos, BYTE_TO_CHAR (position));
12724 /* Now count lines from the start pos to point. */
12725 nlines = display_count_lines (startpos, startpos_byte,
12726 PT_BYTE, PT, &junk);
12728 /* Record that we did display the line number. */
12729 line_number_displayed = 1;
12731 /* Make the string to show. */
12732 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
12733 return decode_mode_spec_buf;
12734 no_value:
12736 char* p = decode_mode_spec_buf;
12737 int pad = field_width - 2;
12738 while (pad-- > 0)
12739 *p++ = ' ';
12740 *p++ = '?';
12741 *p++ = '?';
12742 *p = '\0';
12743 return decode_mode_spec_buf;
12746 break;
12748 case 'm':
12749 obj = b->mode_name;
12750 break;
12752 case 'n':
12753 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
12754 return " Narrow";
12755 break;
12757 case 'p':
12759 int pos = marker_position (w->start);
12760 int total = BUF_ZV (b) - BUF_BEGV (b);
12762 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
12764 if (pos <= BUF_BEGV (b))
12765 return "All";
12766 else
12767 return "Bottom";
12769 else if (pos <= BUF_BEGV (b))
12770 return "Top";
12771 else
12773 if (total > 1000000)
12774 /* Do it differently for a large value, to avoid overflow. */
12775 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
12776 else
12777 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
12778 /* We can't normally display a 3-digit number,
12779 so get us a 2-digit number that is close. */
12780 if (total == 100)
12781 total = 99;
12782 sprintf (decode_mode_spec_buf, "%2d%%", total);
12783 return decode_mode_spec_buf;
12787 /* Display percentage of size above the bottom of the screen. */
12788 case 'P':
12790 int toppos = marker_position (w->start);
12791 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
12792 int total = BUF_ZV (b) - BUF_BEGV (b);
12794 if (botpos >= BUF_ZV (b))
12796 if (toppos <= BUF_BEGV (b))
12797 return "All";
12798 else
12799 return "Bottom";
12801 else
12803 if (total > 1000000)
12804 /* Do it differently for a large value, to avoid overflow. */
12805 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
12806 else
12807 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
12808 /* We can't normally display a 3-digit number,
12809 so get us a 2-digit number that is close. */
12810 if (total == 100)
12811 total = 99;
12812 if (toppos <= BUF_BEGV (b))
12813 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
12814 else
12815 sprintf (decode_mode_spec_buf, "%2d%%", total);
12816 return decode_mode_spec_buf;
12820 case 's':
12821 /* status of process */
12822 obj = Fget_buffer_process (w->buffer);
12823 if (NILP (obj))
12824 return "no process";
12825 #ifdef subprocesses
12826 obj = Fsymbol_name (Fprocess_status (obj));
12827 #endif
12828 break;
12830 case 't': /* indicate TEXT or BINARY */
12831 #ifdef MODE_LINE_BINARY_TEXT
12832 return MODE_LINE_BINARY_TEXT (b);
12833 #else
12834 return "T";
12835 #endif
12837 case 'z':
12838 /* coding-system (not including end-of-line format) */
12839 case 'Z':
12840 /* coding-system (including end-of-line type) */
12842 int eol_flag = (c == 'Z');
12843 char *p = decode_mode_spec_buf;
12845 if (! FRAME_WINDOW_P (f))
12847 /* No need to mention EOL here--the terminal never needs
12848 to do EOL conversion. */
12849 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
12850 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
12852 p = decode_mode_spec_coding (b->buffer_file_coding_system,
12853 p, eol_flag);
12855 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
12856 #ifdef subprocesses
12857 obj = Fget_buffer_process (Fcurrent_buffer ());
12858 if (PROCESSP (obj))
12860 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
12861 p, eol_flag);
12862 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
12863 p, eol_flag);
12865 #endif /* subprocesses */
12866 #endif /* 0 */
12867 *p = 0;
12868 return decode_mode_spec_buf;
12872 if (STRINGP (obj))
12873 return (char *) XSTRING (obj)->data;
12874 else
12875 return "";
12879 /* Count up to COUNT lines starting from START / START_BYTE.
12880 But don't go beyond LIMIT_BYTE.
12881 Return the number of lines thus found (always nonnegative).
12883 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
12885 static int
12886 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
12887 int start, start_byte, limit_byte, count;
12888 int *byte_pos_ptr;
12890 register unsigned char *cursor;
12891 unsigned char *base;
12893 register int ceiling;
12894 register unsigned char *ceiling_addr;
12895 int orig_count = count;
12897 /* If we are not in selective display mode,
12898 check only for newlines. */
12899 int selective_display = (!NILP (current_buffer->selective_display)
12900 && !INTEGERP (current_buffer->selective_display));
12902 if (count > 0)
12904 while (start_byte < limit_byte)
12906 ceiling = BUFFER_CEILING_OF (start_byte);
12907 ceiling = min (limit_byte - 1, ceiling);
12908 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
12909 base = (cursor = BYTE_POS_ADDR (start_byte));
12910 while (1)
12912 if (selective_display)
12913 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
12915 else
12916 while (*cursor != '\n' && ++cursor != ceiling_addr)
12919 if (cursor != ceiling_addr)
12921 if (--count == 0)
12923 start_byte += cursor - base + 1;
12924 *byte_pos_ptr = start_byte;
12925 return orig_count;
12927 else
12928 if (++cursor == ceiling_addr)
12929 break;
12931 else
12932 break;
12934 start_byte += cursor - base;
12937 else
12939 while (start_byte > limit_byte)
12941 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
12942 ceiling = max (limit_byte, ceiling);
12943 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
12944 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
12945 while (1)
12947 if (selective_display)
12948 while (--cursor != ceiling_addr
12949 && *cursor != '\n' && *cursor != 015)
12951 else
12952 while (--cursor != ceiling_addr && *cursor != '\n')
12955 if (cursor != ceiling_addr)
12957 if (++count == 0)
12959 start_byte += cursor - base + 1;
12960 *byte_pos_ptr = start_byte;
12961 /* When scanning backwards, we should
12962 not count the newline posterior to which we stop. */
12963 return - orig_count - 1;
12966 else
12967 break;
12969 /* Here we add 1 to compensate for the last decrement
12970 of CURSOR, which took it past the valid range. */
12971 start_byte += cursor - base + 1;
12975 *byte_pos_ptr = limit_byte;
12977 if (count < 0)
12978 return - orig_count + count;
12979 return orig_count - count;
12985 /***********************************************************************
12986 Displaying strings
12987 ***********************************************************************/
12989 /* Display a NUL-terminated string, starting with index START.
12991 If STRING is non-null, display that C string. Otherwise, the Lisp
12992 string LISP_STRING is displayed.
12994 If FACE_STRING is not nil, FACE_STRING_POS is a position in
12995 FACE_STRING. Display STRING or LISP_STRING with the face at
12996 FACE_STRING_POS in FACE_STRING:
12998 Display the string in the environment given by IT, but use the
12999 standard display table, temporarily.
13001 FIELD_WIDTH is the minimum number of output glyphs to produce.
13002 If STRING has fewer characters than FIELD_WIDTH, pad to the right
13003 with spaces. If STRING has more characters, more than FIELD_WIDTH
13004 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
13006 PRECISION is the maximum number of characters to output from
13007 STRING. PRECISION < 0 means don't truncate the string.
13009 This is roughly equivalent to printf format specifiers:
13011 FIELD_WIDTH PRECISION PRINTF
13012 ----------------------------------------
13013 -1 -1 %s
13014 -1 10 %.10s
13015 10 -1 %10s
13016 20 10 %20.10s
13018 MULTIBYTE zero means do not display multibyte chars, > 0 means do
13019 display them, and < 0 means obey the current buffer's value of
13020 enable_multibyte_characters.
13022 Value is the number of glyphs produced. */
13024 static int
13025 display_string (string, lisp_string, face_string, face_string_pos,
13026 start, it, field_width, precision, max_x, multibyte)
13027 unsigned char *string;
13028 Lisp_Object lisp_string;
13029 Lisp_Object face_string;
13030 int face_string_pos;
13031 int start;
13032 struct it *it;
13033 int field_width, precision, max_x;
13034 int multibyte;
13036 int hpos_at_start = it->hpos;
13037 int saved_face_id = it->face_id;
13038 struct glyph_row *row = it->glyph_row;
13040 /* Initialize the iterator IT for iteration over STRING beginning
13041 with index START. We assume that IT may be modified here (which
13042 means that display_line has to do something when displaying a
13043 mini-buffer prompt, which it does). */
13044 reseat_to_string (it, string, lisp_string, start,
13045 precision, field_width, multibyte);
13047 /* If displaying STRING, set up the face of the iterator
13048 from LISP_STRING, if that's given. */
13049 if (STRINGP (face_string))
13051 int endptr;
13052 struct face *face;
13054 it->face_id
13055 = face_at_string_position (it->w, face_string, face_string_pos,
13056 0, it->region_beg_charpos,
13057 it->region_end_charpos,
13058 &endptr, it->base_face_id);
13059 face = FACE_FROM_ID (it->f, it->face_id);
13060 it->face_box_p = face->box != FACE_NO_BOX;
13063 /* Set max_x to the maximum allowed X position. Don't let it go
13064 beyond the right edge of the window. */
13065 if (max_x <= 0)
13066 max_x = it->last_visible_x;
13067 else
13068 max_x = min (max_x, it->last_visible_x);
13070 /* Skip over display elements that are not visible. because IT->w is
13071 hscrolled. */
13072 if (it->current_x < it->first_visible_x)
13073 move_it_in_display_line_to (it, 100000, it->first_visible_x,
13074 MOVE_TO_POS | MOVE_TO_X);
13076 row->ascent = it->max_ascent;
13077 row->height = it->max_ascent + it->max_descent;
13078 row->phys_ascent = it->max_phys_ascent;
13079 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
13081 /* This condition is for the case that we are called with current_x
13082 past last_visible_x. */
13083 while (it->current_x < max_x)
13085 int x_before, x, n_glyphs_before, i, nglyphs;
13087 /* Get the next display element. */
13088 if (!get_next_display_element (it))
13089 break;
13091 /* Produce glyphs. */
13092 x_before = it->current_x;
13093 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
13094 PRODUCE_GLYPHS (it);
13096 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
13097 i = 0;
13098 x = x_before;
13099 while (i < nglyphs)
13101 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
13103 if (!it->truncate_lines_p
13104 && x + glyph->pixel_width > max_x)
13106 /* End of continued line or max_x reached. */
13107 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
13108 it->current_x = x;
13109 break;
13111 else if (x + glyph->pixel_width > it->first_visible_x)
13113 /* Glyph is at least partially visible. */
13114 ++it->hpos;
13115 if (x < it->first_visible_x)
13116 it->glyph_row->x = x - it->first_visible_x;
13118 else
13120 /* Glyph is off the left margin of the display area.
13121 Should not happen. */
13122 abort ();
13125 row->ascent = max (row->ascent, it->max_ascent);
13126 row->height = max (row->height, it->max_ascent + it->max_descent);
13127 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
13128 row->phys_height = max (row->phys_height,
13129 it->max_phys_ascent + it->max_phys_descent);
13130 x += glyph->pixel_width;
13131 ++i;
13134 /* Stop if max_x reached. */
13135 if (i < nglyphs)
13136 break;
13138 /* Stop at line ends. */
13139 if (ITERATOR_AT_END_OF_LINE_P (it))
13141 it->continuation_lines_width = 0;
13142 break;
13145 set_iterator_to_next (it);
13147 /* Stop if truncating at the right edge. */
13148 if (it->truncate_lines_p
13149 && it->current_x >= it->last_visible_x)
13151 /* Add truncation mark, but don't do it if the line is
13152 truncated at a padding space. */
13153 if (IT_CHARPOS (*it) < it->string_nchars)
13155 if (!FRAME_WINDOW_P (it->f))
13156 produce_special_glyphs (it, IT_TRUNCATION);
13157 it->glyph_row->truncated_on_right_p = 1;
13159 break;
13163 /* Maybe insert a truncation at the left. */
13164 if (it->first_visible_x
13165 && IT_CHARPOS (*it) > 0)
13167 if (!FRAME_WINDOW_P (it->f))
13168 insert_left_trunc_glyphs (it);
13169 it->glyph_row->truncated_on_left_p = 1;
13172 it->face_id = saved_face_id;
13174 /* Value is number of columns displayed. */
13175 return it->hpos - hpos_at_start;
13180 /* This is like a combination of memq and assq. Return 1 if PROPVAL
13181 appears as an element of LIST or as the car of an element of LIST.
13182 If PROPVAL is a list, compare each element against LIST in that
13183 way, and return 1 if any element of PROPVAL is found in LIST.
13184 Otherwise return 0. This function cannot quit. */
13187 invisible_p (propval, list)
13188 register Lisp_Object propval;
13189 Lisp_Object list;
13191 register Lisp_Object tail, proptail;
13192 for (tail = list; CONSP (tail); tail = XCDR (tail))
13194 register Lisp_Object tem;
13195 tem = XCAR (tail);
13196 if (EQ (propval, tem))
13197 return 1;
13198 if (CONSP (tem) && EQ (propval, XCAR (tem)))
13199 return 1;
13201 if (CONSP (propval))
13202 for (proptail = propval; CONSP (proptail);
13203 proptail = XCDR (proptail))
13205 Lisp_Object propelt;
13206 propelt = XCAR (proptail);
13207 for (tail = list; CONSP (tail); tail = XCDR (tail))
13209 register Lisp_Object tem;
13210 tem = XCAR (tail);
13211 if (EQ (propelt, tem))
13212 return 1;
13213 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
13214 return 1;
13217 return 0;
13221 /* Return 1 if PROPVAL appears as the car of an element of LIST and
13222 the cdr of that element is non-nil. If PROPVAL is a list, check
13223 each element of PROPVAL in that way, and the first time some
13224 element is found, return 1 if the cdr of that element is non-nil.
13225 Otherwise return 0. This function cannot quit. */
13228 invisible_ellipsis_p (propval, list)
13229 register Lisp_Object propval;
13230 Lisp_Object list;
13232 register Lisp_Object tail, proptail;
13234 for (tail = list; CONSP (tail); tail = XCDR (tail))
13236 register Lisp_Object tem;
13237 tem = XCAR (tail);
13238 if (CONSP (tem) && EQ (propval, XCAR (tem)))
13239 return ! NILP (XCDR (tem));
13242 if (CONSP (propval))
13243 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
13245 Lisp_Object propelt;
13246 propelt = XCAR (proptail);
13247 for (tail = list; CONSP (tail); tail = XCDR (tail))
13249 register Lisp_Object tem;
13250 tem = XCAR (tail);
13251 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
13252 return ! NILP (XCDR (tem));
13256 return 0;
13261 /***********************************************************************
13262 Initialization
13263 ***********************************************************************/
13265 void
13266 syms_of_xdisp ()
13268 Vwith_echo_area_save_vector = Qnil;
13269 staticpro (&Vwith_echo_area_save_vector);
13271 Vmessage_stack = Qnil;
13272 staticpro (&Vmessage_stack);
13274 Qinhibit_redisplay = intern ("inhibit-redisplay");
13275 staticpro (&Qinhibit_redisplay);
13277 #if GLYPH_DEBUG
13278 defsubr (&Sdump_glyph_matrix);
13279 defsubr (&Sdump_glyph_row);
13280 defsubr (&Sdump_tool_bar_row);
13281 defsubr (&Strace_redisplay_toggle);
13282 defsubr (&Strace_to_stderr);
13283 #endif
13285 staticpro (&Qmenu_bar_update_hook);
13286 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
13288 staticpro (&Qoverriding_terminal_local_map);
13289 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
13291 staticpro (&Qoverriding_local_map);
13292 Qoverriding_local_map = intern ("overriding-local-map");
13294 staticpro (&Qwindow_scroll_functions);
13295 Qwindow_scroll_functions = intern ("window-scroll-functions");
13297 staticpro (&Qredisplay_end_trigger_functions);
13298 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
13300 staticpro (&Qinhibit_point_motion_hooks);
13301 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
13303 QCdata = intern (":data");
13304 staticpro (&QCdata);
13305 Qdisplay = intern ("display");
13306 staticpro (&Qdisplay);
13307 Qspace_width = intern ("space-width");
13308 staticpro (&Qspace_width);
13309 Qraise = intern ("raise");
13310 staticpro (&Qraise);
13311 Qspace = intern ("space");
13312 staticpro (&Qspace);
13313 Qmargin = intern ("margin");
13314 staticpro (&Qmargin);
13315 Qleft_margin = intern ("left-margin");
13316 staticpro (&Qleft_margin);
13317 Qright_margin = intern ("right-margin");
13318 staticpro (&Qright_margin);
13319 Qalign_to = intern ("align-to");
13320 staticpro (&Qalign_to);
13321 QCalign_to = intern (":align-to");
13322 staticpro (&QCalign_to);
13323 Qrelative_width = intern ("relative-width");
13324 staticpro (&Qrelative_width);
13325 QCrelative_width = intern (":relative-width");
13326 staticpro (&QCrelative_width);
13327 QCrelative_height = intern (":relative-height");
13328 staticpro (&QCrelative_height);
13329 QCeval = intern (":eval");
13330 staticpro (&QCeval);
13331 Qwhen = intern ("when");
13332 staticpro (&Qwhen);
13333 QCfile = intern (":file");
13334 staticpro (&QCfile);
13335 Qfontified = intern ("fontified");
13336 staticpro (&Qfontified);
13337 Qfontification_functions = intern ("fontification-functions");
13338 staticpro (&Qfontification_functions);
13339 Qtrailing_whitespace = intern ("trailing-whitespace");
13340 staticpro (&Qtrailing_whitespace);
13341 Qimage = intern ("image");
13342 staticpro (&Qimage);
13343 Qmessage_truncate_lines = intern ("message-truncate-lines");
13344 staticpro (&Qmessage_truncate_lines);
13346 last_arrow_position = Qnil;
13347 last_arrow_string = Qnil;
13348 staticpro (&last_arrow_position);
13349 staticpro (&last_arrow_string);
13351 echo_buffer[0] = echo_buffer[1] = Qnil;
13352 staticpro (&echo_buffer[0]);
13353 staticpro (&echo_buffer[1]);
13355 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
13356 staticpro (&echo_area_buffer[0]);
13357 staticpro (&echo_area_buffer[1]);
13359 Vmessages_buffer_name = build_string ("*Messages*");
13360 staticpro (&Vmessages_buffer_name);
13362 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
13363 "Non-nil means highlight trailing whitespace.\n\
13364 The face used for trailing whitespace is `trailing-whitespace'.");
13365 Vshow_trailing_whitespace = Qnil;
13367 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
13368 "Non-nil means don't actually do any redisplay.\n\
13369 This is used for internal purposes.");
13370 Vinhibit_redisplay = Qnil;
13372 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
13373 "String (or mode line construct) included (normally) in `mode-line-format'.");
13374 Vglobal_mode_string = Qnil;
13376 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
13377 "Marker for where to display an arrow on top of the buffer text.\n\
13378 This must be the beginning of a line in order to work.\n\
13379 See also `overlay-arrow-string'.");
13380 Voverlay_arrow_position = Qnil;
13382 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
13383 "String to display as an arrow. See also `overlay-arrow-position'.");
13384 Voverlay_arrow_string = Qnil;
13386 DEFVAR_INT ("scroll-step", &scroll_step,
13387 "*The number of lines to try scrolling a window by when point moves out.\n\
13388 If that fails to bring point back on frame, point is centered instead.\n\
13389 If this is zero, point is always centered after it moves off frame.");
13391 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
13392 "*Scroll up to this many lines, to bring point back on screen.\n\
13393 A value of zero means to scroll the text to center point vertically\n\
13394 in the window.");
13395 scroll_conservatively = 0;
13397 DEFVAR_INT ("scroll-margin", &scroll_margin,
13398 "*Number of lines of margin at the top and bottom of a window.\n\
13399 Recenter the window whenever point gets within this many lines\n\
13400 of the top or bottom of the window.");
13401 scroll_margin = 0;
13403 #if GLYPH_DEBUG
13404 DEFVAR_INT ("debug-end-pos", &debug_end_pos, "Don't ask");
13405 #endif
13407 DEFVAR_BOOL ("truncate-partial-width-windows",
13408 &truncate_partial_width_windows,
13409 "*Non-nil means truncate lines in all windows less than full frame wide.");
13410 truncate_partial_width_windows = 1;
13412 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
13413 "*Non-nil means use inverse video for the mode line.");
13414 mode_line_inverse_video = 1;
13416 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
13417 "*Maximum buffer size for which line number should be displayed.\n\
13418 If the buffer is bigger than this, the line number does not appear\n\
13419 in the mode line. A value of nil means no limit.");
13420 Vline_number_display_limit = Qnil;
13422 DEFVAR_INT ("line-number-display-limit-width",
13423 &line_number_display_limit_width,
13424 "*Maximum line width (in characters) for line number display.\n\
13425 If the average length of the lines near point is bigger than this, then the\n\
13426 line number may be omitted from the mode line.");
13427 line_number_display_limit_width = 200;
13429 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
13430 "*Non-nil means highlight region even in nonselected windows.");
13431 highlight_nonselected_windows = 0;
13433 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
13434 "Non-nil if more than one frame is visible on this display.\n\
13435 Minibuffer-only frames don't count, but iconified frames do.\n\
13436 This variable is not guaranteed to be accurate except while processing\n\
13437 `frame-title-format' and `icon-title-format'.");
13439 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
13440 "Template for displaying the title bar of visible frames.\n\
13441 \(Assuming the window manager supports this feature.)\n\
13442 This variable has the same structure as `mode-line-format' (which see),\n\
13443 and is used only on frames for which no explicit name has been set\n\
13444 \(see `modify-frame-parameters').");
13445 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
13446 "Template for displaying the title bar of an iconified frame.\n\
13447 \(Assuming the window manager supports this feature.)\n\
13448 This variable has the same structure as `mode-line-format' (which see),\n\
13449 and is used only on frames for which no explicit name has been set\n\
13450 \(see `modify-frame-parameters').");
13451 Vicon_title_format
13452 = Vframe_title_format
13453 = Fcons (intern ("multiple-frames"),
13454 Fcons (build_string ("%b"),
13455 Fcons (Fcons (build_string (""),
13456 Fcons (intern ("invocation-name"),
13457 Fcons (build_string ("@"),
13458 Fcons (intern ("system-name"),
13459 Qnil)))),
13460 Qnil)));
13462 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
13463 "Maximum number of lines to keep in the message log buffer.\n\
13464 If nil, disable message logging. If t, log messages but don't truncate\n\
13465 the buffer when it becomes large.");
13466 XSETFASTINT (Vmessage_log_max, 50);
13468 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
13469 "Functions called before redisplay, if window sizes have changed.\n\
13470 The value should be a list of functions that take one argument.\n\
13471 Just before redisplay, for each frame, if any of its windows have changed\n\
13472 size since the last redisplay, or have been split or deleted,\n\
13473 all the functions in the list are called, with the frame as argument.");
13474 Vwindow_size_change_functions = Qnil;
13476 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
13477 "List of Functions to call before redisplaying a window with scrolling.\n\
13478 Each function is called with two arguments, the window\n\
13479 and its new display-start position. Note that the value of `window-end'\n\
13480 is not valid when these functions are called.");
13481 Vwindow_scroll_functions = Qnil;
13483 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
13484 "*Non-nil means automatically resize tool-bars.\n\
13485 This increases a tool-bar's height if not all tool-bar items are visible.\n\
13486 It decreases a tool-bar's height when it would display blank lines\n\
13487 otherwise.");
13488 auto_resize_tool_bars_p = 1;
13490 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
13491 "*Non-nil means raise tool-bar buttons when the mouse moves over them.");
13492 auto_raise_tool_bar_buttons_p = 1;
13494 DEFVAR_INT ("tool-bar-button-margin", &tool_bar_button_margin,
13495 "*Margin around tool-bar buttons in pixels.");
13496 tool_bar_button_margin = 1;
13498 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
13499 "Relief thickness of tool-bar buttons.");
13500 tool_bar_button_relief = 3;
13502 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
13503 "List of functions to call to fontify regions of text.\n\
13504 Each function is called with one argument POS. Functions must\n\
13505 fontify a region starting at POS in the current buffer, and give\n\
13506 fontified regions the property `fontified'.\n\
13507 This variable automatically becomes buffer-local when set.");
13508 Vfontification_functions = Qnil;
13509 Fmake_local_variable (Qfontification_functions);
13511 DEFVAR_BOOL ("unibyte-display-via-language-environment",
13512 &unibyte_display_via_language_environment,
13513 "*Non-nil means display unibyte text according to language environment.\n\
13514 Specifically this means that unibyte non-ASCII characters\n\
13515 are displayed by converting them to the equivalent multibyte characters\n\
13516 according to the current language environment. As a result, they are\n\
13517 displayed according to the current fontset.");
13518 unibyte_display_via_language_environment = 0;
13520 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
13521 "*Maximum height for resizing mini-windows.\n\
13522 If a float, it specifies a fraction of the mini-window frame's height.\n\
13523 If an integer, it specifies a number of lines.\n\
13524 If nil, don't resize.");
13525 Vmax_mini_window_height = make_float (0.25);
13527 DEFVAR_BOOL ("cursor-in-non-selected-windows",
13528 &cursor_in_non_selected_windows,
13529 "*Non-nil means display a hollow cursor in non-selected windows.\n\
13530 Nil means don't display a cursor there.");
13531 cursor_in_non_selected_windows = 1;
13533 DEFVAR_BOOL ("automatic-hscrolling", &automatic_hscrolling_p,
13534 "*Non-nil means scroll the display automatically to make point visible.");
13535 automatic_hscrolling_p = 1;
13537 DEFVAR_LISP ("image-types", &Vimage_types,
13538 "List of supported image types.\n\
13539 Each element of the list is a symbol for a supported image type.");
13540 Vimage_types = Qnil;
13542 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
13543 "If non-nil, messages are truncated instead of resizing the echo area.\n\
13544 Bind this around calls to `message' to let it take effect.");
13545 message_truncate_lines = 0;
13549 /* Initialize this module when Emacs starts. */
13551 void
13552 init_xdisp ()
13554 Lisp_Object root_window;
13555 struct window *mini_w;
13557 CHARPOS (this_line_start_pos) = 0;
13559 mini_w = XWINDOW (minibuf_window);
13560 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
13562 if (!noninteractive)
13564 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
13565 int i;
13567 XSETFASTINT (XWINDOW (root_window)->top, FRAME_TOP_MARGIN (f));
13568 set_window_height (root_window,
13569 FRAME_HEIGHT (f) - 1 - FRAME_TOP_MARGIN (f),
13571 XSETFASTINT (mini_w->top, FRAME_HEIGHT (f) - 1);
13572 set_window_height (minibuf_window, 1, 0);
13574 XSETFASTINT (XWINDOW (root_window)->width, FRAME_WIDTH (f));
13575 XSETFASTINT (mini_w->width, FRAME_WIDTH (f));
13577 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
13578 scratch_glyph_row.glyphs[TEXT_AREA + 1]
13579 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
13581 /* The default ellipsis glyphs `...'. */
13582 for (i = 0; i < 3; ++i)
13583 XSETFASTINT (default_invis_vector[i], '.');
13586 #ifdef HAVE_WINDOW_SYSTEM
13588 /* Allocate the buffer for frame titles. */
13589 int size = 100;
13590 frame_title_buf = (char *) xmalloc (size);
13591 frame_title_buf_end = frame_title_buf + size;
13592 frame_title_ptr = NULL;
13594 #endif /* HAVE_WINDOW_SYSTEM */