Include errno.h, string.h, unistd.h. Don't declare errno, strerror.
[emacs.git] / src / xdisp.c
blob4f0449383c61e04b23f9e59e5152aaadd9129924
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 98, 99
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 "frame.h"
174 #include "window.h"
175 #include "termchar.h"
176 #include "dispextern.h"
177 #include "buffer.h"
178 #include "charset.h"
179 #include "indent.h"
180 #include "commands.h"
181 #include "macros.h"
182 #include "disptab.h"
183 #include "termhooks.h"
184 #include "intervals.h"
185 #include "keyboard.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 ();
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 /* Current, index 0, and last displayed echo area message. Either
457 buffers from echo_buffers, or nil to indicate no message. */
459 Lisp_Object echo_area_buffer[2];
461 /* The buffers referenced from echo_area_buffer. */
463 static Lisp_Object echo_buffer[2];
465 /* A vector saved used in with_area_buffer to reduce consing. */
467 static Lisp_Object Vwith_echo_area_save_vector;
469 /* Non-zero means display_echo_area should display the last echo area
470 message again. Set by redisplay_preserve_echo_area. */
472 static int display_last_displayed_message_p;
474 /* Nonzero if echo area is being used by print; zero if being used by
475 message. */
477 int message_buf_print;
479 /* Maximum height for resizing mini-windows. Either a float
480 specifying a fraction of the available height, or an integer
481 specifying a number of lines. */
483 Lisp_Object Vmax_mini_window_height;
485 /* Non-zero means messages should be displayed with truncated
486 lines instead of being continued. */
488 int message_truncate_lines;
489 Lisp_Object Qmessage_truncate_lines;
491 /* Non-zero means we want a hollow cursor in windows that are not
492 selected. Zero means there's no cursor in such windows. */
494 int cursor_in_non_selected_windows;
496 /* A scratch glyph row with contents used for generating truncation
497 glyphs. Also used in direct_output_for_insert. */
499 #define MAX_SCRATCH_GLYPHS 100
500 struct glyph_row scratch_glyph_row;
501 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
503 /* Ascent and height of the last line processed by move_it_to. */
505 static int last_max_ascent, last_height;
507 /* The maximum distance to look ahead for text properties. Values
508 that are too small let us call compute_char_face and similar
509 functions too often which is expensive. Values that are too large
510 let us call compute_char_face and alike too often because we
511 might not be interested in text properties that far away. */
513 #define TEXT_PROP_DISTANCE_LIMIT 100
515 /* Non-zero means print traces of redisplay if compiled with
516 GLYPH_DEBUG != 0. */
518 #if GLYPH_DEBUG
519 int trace_redisplay_p;
520 #endif
522 /* Non-zero means automatically scroll windows horizontally to make
523 point visible. */
525 int automatic_hscrolling_p;
527 /* A list of symbols, one for each supported image type. */
529 Lisp_Object Vimage_types;
531 /* Value returned from text property handlers (see below). */
533 enum prop_handled
535 HANDLED_NORMALLY,
536 HANDLED_RECOMPUTE_PROPS,
537 HANDLED_OVERLAY_STRING_CONSUMED,
538 HANDLED_RETURN
541 /* A description of text properties that redisplay is interested
542 in. */
544 struct props
546 /* The name of the property. */
547 Lisp_Object *name;
549 /* A unique index for the property. */
550 enum prop_idx idx;
552 /* A handler function called to set up iterator IT from the property
553 at IT's current position. Value is used to steer handle_stop. */
554 enum prop_handled (*handler) P_ ((struct it *it));
557 static enum prop_handled handle_face_prop P_ ((struct it *));
558 static enum prop_handled handle_invisible_prop P_ ((struct it *));
559 static enum prop_handled handle_display_prop P_ ((struct it *));
560 static enum prop_handled handle_composition_prop P_ ((struct it *));
561 static enum prop_handled handle_overlay_change P_ ((struct it *));
562 static enum prop_handled handle_fontified_prop P_ ((struct it *));
564 /* Properties handled by iterators. */
566 static struct props it_props[] =
568 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
569 /* Handle `face' before `display' because some sub-properties of
570 `display' need to know the face. */
571 {&Qface, FACE_PROP_IDX, handle_face_prop},
572 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
573 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
574 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
575 {NULL, 0, NULL}
578 /* Value is the position described by X. If X is a marker, value is
579 the marker_position of X. Otherwise, value is X. */
581 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
583 /* Enumeration returned by some move_it_.* functions internally. */
585 enum move_it_result
587 /* Not used. Undefined value. */
588 MOVE_UNDEFINED,
590 /* Move ended at the requested buffer position or ZV. */
591 MOVE_POS_MATCH_OR_ZV,
593 /* Move ended at the requested X pixel position. */
594 MOVE_X_REACHED,
596 /* Move within a line ended at the end of a line that must be
597 continued. */
598 MOVE_LINE_CONTINUED,
600 /* Move within a line ended at the end of a line that would
601 be displayed truncated. */
602 MOVE_LINE_TRUNCATED,
604 /* Move within a line ended at a line end. */
605 MOVE_NEWLINE_OR_CR
610 /* Function prototypes. */
612 static void ensure_echo_area_buffers P_ ((void));
613 static struct glyph_row *row_containing_pos P_ ((struct window *, int,
614 struct glyph_row *,
615 struct glyph_row *));
616 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
617 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
618 static void clear_garbaged_frames P_ ((void));
619 static int current_message_1 P_ ((Lisp_Object *));
620 static int truncate_message_1 P_ ((int));
621 static int set_message_1 P_ ((char *s, Lisp_Object, int, int));
622 static int display_echo_area P_ ((struct window *));
623 static int display_echo_area_1 P_ ((struct window *));
624 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
625 static int string_char_and_length P_ ((unsigned char *, int, int *));
626 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
627 struct text_pos));
628 static int compute_window_start_on_continuation_line P_ ((struct window *));
629 static Lisp_Object eval_handler P_ ((Lisp_Object));
630 static Lisp_Object eval_form P_ ((Lisp_Object));
631 static void insert_left_trunc_glyphs P_ ((struct it *));
632 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
633 static void extend_face_to_end_of_line P_ ((struct it *));
634 static int append_space P_ ((struct it *, int));
635 static void make_cursor_line_fully_visible P_ ((struct window *));
636 static int try_scrolling P_ ((Lisp_Object, int, int, int, int));
637 static int trailing_whitespace_p P_ ((int));
638 static int message_log_check_duplicate P_ ((int, int, int, int));
639 int invisible_p P_ ((Lisp_Object, Lisp_Object));
640 int invisible_ellipsis_p P_ ((Lisp_Object, Lisp_Object));
641 static void push_it P_ ((struct it *));
642 static void pop_it P_ ((struct it *));
643 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
644 static void redisplay_internal P_ ((int));
645 static int echo_area_display P_ ((int));
646 static void redisplay_windows P_ ((Lisp_Object));
647 static void redisplay_window P_ ((Lisp_Object, int));
648 static void update_menu_bar P_ ((struct frame *, int));
649 static int try_window_reusing_current_matrix P_ ((struct window *));
650 static int try_window_id P_ ((struct window *));
651 static int display_line P_ ((struct it *));
652 static void display_mode_lines P_ ((struct window *));
653 static void display_mode_line P_ ((struct window *, enum face_id,
654 Lisp_Object));
655 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object));
656 static char *decode_mode_spec P_ ((struct window *, int, int, int));
657 static void display_menu_bar P_ ((struct window *));
658 static int display_count_lines P_ ((int, int, int, int, int *));
659 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
660 int, int, struct it *, int, int, int, int));
661 static void compute_line_metrics P_ ((struct it *));
662 static void run_redisplay_end_trigger_hook P_ ((struct it *));
663 static int get_overlay_strings P_ ((struct it *));
664 static void next_overlay_string P_ ((struct it *));
665 void set_iterator_to_next P_ ((struct it *));
666 static void reseat P_ ((struct it *, struct text_pos, int));
667 static void reseat_1 P_ ((struct it *, struct text_pos, int));
668 static void back_to_previous_visible_line_start P_ ((struct it *));
669 static void reseat_at_previous_visible_line_start P_ ((struct it *));
670 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
671 static int next_element_from_display_vector P_ ((struct it *));
672 static int next_element_from_string P_ ((struct it *));
673 static int next_element_from_c_string P_ ((struct it *));
674 static int next_element_from_buffer P_ ((struct it *));
675 static int next_element_from_composition P_ ((struct it *));
676 static int next_element_from_image P_ ((struct it *));
677 static int next_element_from_stretch P_ ((struct it *));
678 static void load_overlay_strings P_ ((struct it *));
679 static void init_from_display_pos P_ ((struct it *, struct window *,
680 struct display_pos *));
681 static void reseat_to_string P_ ((struct it *, unsigned char *,
682 Lisp_Object, int, int, int, int));
683 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
684 int, int, int));
685 void move_it_vertically_backward P_ ((struct it *, int));
686 static void init_to_row_start P_ ((struct it *, struct window *,
687 struct glyph_row *));
688 static void init_to_row_end P_ ((struct it *, struct window *,
689 struct glyph_row *));
690 static void back_to_previous_line_start P_ ((struct it *));
691 static void forward_to_next_line_start P_ ((struct it *));
692 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
693 Lisp_Object, int));
694 static struct text_pos string_pos P_ ((int, Lisp_Object));
695 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
696 static int number_of_chars P_ ((unsigned char *, int));
697 static void compute_stop_pos P_ ((struct it *));
698 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
699 Lisp_Object));
700 static int face_before_or_after_it_pos P_ ((struct it *, int));
701 static int next_overlay_change P_ ((int));
702 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
703 Lisp_Object, struct text_pos *));
705 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
706 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
708 #ifdef HAVE_WINDOW_SYSTEM
710 static void update_tool_bar P_ ((struct frame *, int));
711 static void build_desired_tool_bar_string P_ ((struct frame *f));
712 static int redisplay_tool_bar P_ ((struct frame *));
713 static void display_tool_bar_line P_ ((struct it *));
715 #endif /* HAVE_WINDOW_SYSTEM */
718 /***********************************************************************
719 Window display dimensions
720 ***********************************************************************/
722 /* Return the window-relative maximum y + 1 for glyph rows displaying
723 text in window W. This is the height of W minus the height of a
724 mode line, if any. */
726 INLINE int
727 window_text_bottom_y (w)
728 struct window *w;
730 struct frame *f = XFRAME (w->frame);
731 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
733 if (WINDOW_WANTS_MODELINE_P (w))
734 height -= CURRENT_MODE_LINE_HEIGHT (w);
735 return height;
739 /* Return the pixel width of display area AREA of window W. AREA < 0
740 means return the total width of W, not including bitmap areas to
741 the left and right of the window. */
743 INLINE int
744 window_box_width (w, area)
745 struct window *w;
746 int area;
748 struct frame *f = XFRAME (w->frame);
749 int width = XFASTINT (w->width);
751 if (!w->pseudo_window_p)
753 width -= FRAME_SCROLL_BAR_WIDTH (f) + FRAME_FLAGS_AREA_COLS (f);
755 if (area == TEXT_AREA)
757 if (INTEGERP (w->left_margin_width))
758 width -= XFASTINT (w->left_margin_width);
759 if (INTEGERP (w->right_margin_width))
760 width -= XFASTINT (w->right_margin_width);
762 else if (area == LEFT_MARGIN_AREA)
763 width = (INTEGERP (w->left_margin_width)
764 ? XFASTINT (w->left_margin_width) : 0);
765 else if (area == RIGHT_MARGIN_AREA)
766 width = (INTEGERP (w->right_margin_width)
767 ? XFASTINT (w->right_margin_width) : 0);
770 return width * CANON_X_UNIT (f);
774 /* Return the pixel height of the display area of window W, not
775 including mode lines of W, if any.. */
777 INLINE int
778 window_box_height (w)
779 struct window *w;
781 struct frame *f = XFRAME (w->frame);
782 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
784 if (WINDOW_WANTS_MODELINE_P (w))
785 height -= CURRENT_MODE_LINE_HEIGHT (w);
787 if (WINDOW_WANTS_HEADER_LINE_P (w))
788 height -= CURRENT_HEADER_LINE_HEIGHT (w);
790 return height;
794 /* Return the frame-relative coordinate of the left edge of display
795 area AREA of window W. AREA < 0 means return the left edge of the
796 whole window, to the right of any bitmap area at the left side of
797 W. */
799 INLINE int
800 window_box_left (w, area)
801 struct window *w;
802 int area;
804 struct frame *f = XFRAME (w->frame);
805 int x = FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
807 if (!w->pseudo_window_p)
809 x += (WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f)
810 + FRAME_LEFT_FLAGS_AREA_WIDTH (f));
812 if (area == TEXT_AREA)
813 x += window_box_width (w, LEFT_MARGIN_AREA);
814 else if (area == RIGHT_MARGIN_AREA)
815 x += (window_box_width (w, LEFT_MARGIN_AREA)
816 + window_box_width (w, TEXT_AREA));
819 return x;
823 /* Return the frame-relative coordinate of the right edge of display
824 area AREA of window W. AREA < 0 means return the left edge of the
825 whole window, to the left of any bitmap area at the right side of
826 W. */
828 INLINE int
829 window_box_right (w, area)
830 struct window *w;
831 int area;
833 return window_box_left (w, area) + window_box_width (w, area);
837 /* Get the bounding box of the display area AREA of window W, without
838 mode lines, in frame-relative coordinates. AREA < 0 means the
839 whole window, not including bitmap areas to the left and right of
840 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
841 coordinates of the upper-left corner of the box. Return in
842 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
844 INLINE void
845 window_box (w, area, box_x, box_y, box_width, box_height)
846 struct window *w;
847 int area;
848 int *box_x, *box_y, *box_width, *box_height;
850 struct frame *f = XFRAME (w->frame);
852 *box_width = window_box_width (w, area);
853 *box_height = window_box_height (w);
854 *box_x = window_box_left (w, area);
855 *box_y = (FRAME_INTERNAL_BORDER_WIDTH_SAFE (f)
856 + XFASTINT (w->top) * CANON_Y_UNIT (f));
857 if (WINDOW_WANTS_HEADER_LINE_P (w))
858 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
862 /* Get the bounding box of the display area AREA of window W, without
863 mode lines. AREA < 0 means the whole window, not including bitmap
864 areas to the left and right of the window. Return in *TOP_LEFT_X
865 and TOP_LEFT_Y the frame-relative pixel coordinates of the
866 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
867 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
868 box. */
870 INLINE void
871 window_box_edges (w, area, top_left_x, top_left_y,
872 bottom_right_x, bottom_right_y)
873 struct window *w;
874 int area;
875 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
877 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
878 bottom_right_y);
879 *bottom_right_x += *top_left_x;
880 *bottom_right_y += *top_left_y;
885 /***********************************************************************
886 Utilities
887 ***********************************************************************/
889 /* Return the next character from STR which is MAXLEN bytes long.
890 Return in *LEN the length of the character. This is like
891 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
892 we find one, we return a `?', but with the length of the invalid
893 character. */
895 static INLINE int
896 string_char_and_length (str, maxlen, len)
897 unsigned char *str;
898 int maxlen, *len;
900 int c;
902 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
903 if (!CHAR_VALID_P (c, 1))
904 /* We may not change the length here because other places in Emacs
905 don't use this function, i.e. they silently accept invalid
906 characters. */
907 c = '?';
909 return c;
914 /* Given a position POS containing a valid character and byte position
915 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
917 static struct text_pos
918 string_pos_nchars_ahead (pos, string, nchars)
919 struct text_pos pos;
920 Lisp_Object string;
921 int nchars;
923 xassert (STRINGP (string) && nchars >= 0);
925 if (STRING_MULTIBYTE (string))
927 int rest = STRING_BYTES (XSTRING (string)) - BYTEPOS (pos);
928 unsigned char *p = XSTRING (string)->data + BYTEPOS (pos);
929 int len;
931 while (nchars--)
933 string_char_and_length (p, rest, &len);
934 p += len, rest -= len;
935 xassert (rest >= 0);
936 CHARPOS (pos) += 1;
937 BYTEPOS (pos) += len;
940 else
941 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
943 return pos;
947 /* Value is the text position, i.e. character and byte position,
948 for character position CHARPOS in STRING. */
950 static INLINE struct text_pos
951 string_pos (charpos, string)
952 int charpos;
953 Lisp_Object string;
955 struct text_pos pos;
956 xassert (STRINGP (string));
957 xassert (charpos >= 0);
958 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
959 return pos;
963 /* Value is a text position, i.e. character and byte position, for
964 character position CHARPOS in C string S. MULTIBYTE_P non-zero
965 means recognize multibyte characters. */
967 static struct text_pos
968 c_string_pos (charpos, s, multibyte_p)
969 int charpos;
970 unsigned char *s;
971 int multibyte_p;
973 struct text_pos pos;
975 xassert (s != NULL);
976 xassert (charpos >= 0);
978 if (multibyte_p)
980 int rest = strlen (s), len;
982 SET_TEXT_POS (pos, 0, 0);
983 while (charpos--)
985 string_char_and_length (s, rest, &len);
986 s += len, rest -= len;
987 xassert (rest >= 0);
988 CHARPOS (pos) += 1;
989 BYTEPOS (pos) += len;
992 else
993 SET_TEXT_POS (pos, charpos, charpos);
995 return pos;
999 /* Value is the number of characters in C string S. MULTIBYTE_P
1000 non-zero means recognize multibyte characters. */
1002 static int
1003 number_of_chars (s, multibyte_p)
1004 unsigned char *s;
1005 int multibyte_p;
1007 int nchars;
1009 if (multibyte_p)
1011 int rest = strlen (s), len;
1012 unsigned char *p = (unsigned char *) s;
1014 for (nchars = 0; rest > 0; ++nchars)
1016 string_char_and_length (p, rest, &len);
1017 rest -= len, p += len;
1020 else
1021 nchars = strlen (s);
1023 return nchars;
1027 /* Compute byte position NEWPOS->bytepos corresponding to
1028 NEWPOS->charpos. POS is a known position in string STRING.
1029 NEWPOS->charpos must be >= POS.charpos. */
1031 static void
1032 compute_string_pos (newpos, pos, string)
1033 struct text_pos *newpos, pos;
1034 Lisp_Object string;
1036 xassert (STRINGP (string));
1037 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1039 if (STRING_MULTIBYTE (string))
1040 *newpos = string_pos_nchars_ahead (pos, string,
1041 CHARPOS (*newpos) - CHARPOS (pos));
1042 else
1043 BYTEPOS (*newpos) = CHARPOS (*newpos);
1048 /***********************************************************************
1049 Lisp form evaluation
1050 ***********************************************************************/
1052 /* Error handler for eval_form. */
1054 static Lisp_Object
1055 eval_handler (arg)
1056 Lisp_Object arg;
1058 return Qnil;
1062 /* Evaluate SEXPR and return the result, or nil if something went
1063 wrong. */
1065 static Lisp_Object
1066 eval_form (sexpr)
1067 Lisp_Object sexpr;
1069 int count = specpdl_ptr - specpdl;
1070 Lisp_Object val;
1071 specbind (Qinhibit_redisplay, Qt);
1072 val = internal_condition_case_1 (Feval, sexpr, Qerror, eval_handler);
1073 return unbind_to (count, val);
1078 /***********************************************************************
1079 Debugging
1080 ***********************************************************************/
1082 #if 0
1084 /* Define CHECK_IT to perform sanity checks on iterators.
1085 This is for debugging. It is too slow to do unconditionally. */
1087 static void
1088 check_it (it)
1089 struct it *it;
1091 if (it->method == next_element_from_string)
1093 xassert (STRINGP (it->string));
1094 xassert (IT_STRING_CHARPOS (*it) >= 0);
1096 else if (it->method == next_element_from_buffer)
1098 /* Check that character and byte positions agree. */
1099 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1102 if (it->dpvec)
1103 xassert (it->current.dpvec_index >= 0);
1104 else
1105 xassert (it->current.dpvec_index < 0);
1108 #define CHECK_IT(IT) check_it ((IT))
1110 #else /* not 0 */
1112 #define CHECK_IT(IT) (void) 0
1114 #endif /* not 0 */
1117 #if GLYPH_DEBUG
1119 /* Check that the window end of window W is what we expect it
1120 to be---the last row in the current matrix displaying text. */
1122 static void
1123 check_window_end (w)
1124 struct window *w;
1126 if (!MINI_WINDOW_P (w)
1127 && !NILP (w->window_end_valid))
1129 struct glyph_row *row;
1130 xassert ((row = MATRIX_ROW (w->current_matrix,
1131 XFASTINT (w->window_end_vpos)),
1132 !row->enabled_p
1133 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1134 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1138 #define CHECK_WINDOW_END(W) check_window_end ((W))
1140 #else /* not GLYPH_DEBUG */
1142 #define CHECK_WINDOW_END(W) (void) 0
1144 #endif /* not GLYPH_DEBUG */
1148 /***********************************************************************
1149 Iterator initialization
1150 ***********************************************************************/
1152 /* Initialize IT for displaying current_buffer in window W, starting
1153 at character position CHARPOS. CHARPOS < 0 means that no buffer
1154 position is specified which is useful when the iterator is assigned
1155 a position later. BYTEPOS is the byte position corresponding to
1156 CHARPOS. BYTEPOS <= 0 means compute it from CHARPOS.
1158 If ROW is not null, calls to produce_glyphs with IT as parameter
1159 will produce glyphs in that row.
1161 BASE_FACE_ID is the id of a base face to use. It must be one of
1162 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID or
1163 HEADER_LINE_FACE_ID for displaying mode lines, or TOOL_BAR_FACE_ID for
1164 displaying the tool-bar.
1166 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID or
1167 HEADER_LINE_FACE_ID, the iterator will be initialized to use the
1168 corresponding mode line glyph row of the desired matrix of W. */
1170 void
1171 init_iterator (it, w, charpos, bytepos, row, base_face_id)
1172 struct it *it;
1173 struct window *w;
1174 int charpos, bytepos;
1175 struct glyph_row *row;
1176 enum face_id base_face_id;
1178 int highlight_region_p;
1180 /* Some precondition checks. */
1181 xassert (w != NULL && it != NULL);
1182 xassert (charpos < 0 || (charpos > 0 && charpos <= ZV));
1184 /* If face attributes have been changed since the last redisplay,
1185 free realized faces now because they depend on face definitions
1186 that might have changed. */
1187 if (face_change_count)
1189 face_change_count = 0;
1190 free_all_realized_faces (Qnil);
1193 /* Use one of the mode line rows of W's desired matrix if
1194 appropriate. */
1195 if (row == NULL)
1197 if (base_face_id == MODE_LINE_FACE_ID)
1198 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
1199 else if (base_face_id == HEADER_LINE_FACE_ID)
1200 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
1203 /* Clear IT. */
1204 bzero (it, sizeof *it);
1205 it->current.overlay_string_index = -1;
1206 it->current.dpvec_index = -1;
1207 it->base_face_id = base_face_id;
1209 /* The window in which we iterate over current_buffer: */
1210 XSETWINDOW (it->window, w);
1211 it->w = w;
1212 it->f = XFRAME (w->frame);
1214 /* Extra space between lines (on window systems only). */
1215 if (base_face_id == DEFAULT_FACE_ID
1216 && FRAME_WINDOW_P (it->f))
1218 if (NATNUMP (current_buffer->extra_line_spacing))
1219 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
1220 else if (it->f->extra_line_spacing > 0)
1221 it->extra_line_spacing = it->f->extra_line_spacing;
1224 /* If realized faces have been removed, e.g. because of face
1225 attribute changes of named faces, recompute them. */
1226 if (FRAME_FACE_CACHE (it->f)->used == 0)
1227 recompute_basic_faces (it->f);
1229 /* Current value of the `space-width', and 'height' properties. */
1230 it->space_width = Qnil;
1231 it->font_height = Qnil;
1233 /* Are control characters displayed as `^C'? */
1234 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
1236 /* -1 means everything between a CR and the following line end
1237 is invisible. >0 means lines indented more than this value are
1238 invisible. */
1239 it->selective = (INTEGERP (current_buffer->selective_display)
1240 ? XFASTINT (current_buffer->selective_display)
1241 : (!NILP (current_buffer->selective_display)
1242 ? -1 : 0));
1243 it->selective_display_ellipsis_p
1244 = !NILP (current_buffer->selective_display_ellipses);
1246 /* Display table to use. */
1247 it->dp = window_display_table (w);
1249 /* Are multibyte characters enabled in current_buffer? */
1250 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
1252 /* Non-zero if we should highlight the region. */
1253 highlight_region_p
1254 = (!NILP (Vtransient_mark_mode)
1255 && !NILP (current_buffer->mark_active)
1256 && XMARKER (current_buffer->mark)->buffer != 0);
1258 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
1259 start and end of a visible region in window IT->w. Set both to
1260 -1 to indicate no region. */
1261 if (highlight_region_p
1262 /* Maybe highlight only in selected window. */
1263 && (/* Either show region everywhere. */
1264 highlight_nonselected_windows
1265 /* Or show region in the selected window. */
1266 || w == XWINDOW (selected_window)
1267 /* Or show the region if we are in the mini-buffer and W is
1268 the window the mini-buffer refers to. */
1269 || (MINI_WINDOW_P (XWINDOW (selected_window))
1270 && w == XWINDOW (Vminibuf_scroll_window))))
1272 int charpos = marker_position (current_buffer->mark);
1273 it->region_beg_charpos = min (PT, charpos);
1274 it->region_end_charpos = max (PT, charpos);
1276 else
1277 it->region_beg_charpos = it->region_end_charpos = -1;
1279 /* Get the position at which the redisplay_end_trigger hook should
1280 be run, if it is to be run at all. */
1281 if (MARKERP (w->redisplay_end_trigger)
1282 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
1283 it->redisplay_end_trigger_charpos
1284 = marker_position (w->redisplay_end_trigger);
1285 else if (INTEGERP (w->redisplay_end_trigger))
1286 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
1288 /* Correct bogus values of tab_width. */
1289 it->tab_width = XINT (current_buffer->tab_width);
1290 if (it->tab_width <= 0 || it->tab_width > 1000)
1291 it->tab_width = 8;
1293 /* Are lines in the display truncated? */
1294 it->truncate_lines_p
1295 = (base_face_id != DEFAULT_FACE_ID
1296 || XINT (it->w->hscroll)
1297 || (truncate_partial_width_windows
1298 && !WINDOW_FULL_WIDTH_P (it->w))
1299 || !NILP (current_buffer->truncate_lines));
1301 /* Get dimensions of truncation and continuation glyphs. These are
1302 displayed as bitmaps under X, so we don't need them for such
1303 frames. */
1304 if (!FRAME_WINDOW_P (it->f))
1306 if (it->truncate_lines_p)
1308 /* We will need the truncation glyph. */
1309 xassert (it->glyph_row == NULL);
1310 produce_special_glyphs (it, IT_TRUNCATION);
1311 it->truncation_pixel_width = it->pixel_width;
1313 else
1315 /* We will need the continuation glyph. */
1316 xassert (it->glyph_row == NULL);
1317 produce_special_glyphs (it, IT_CONTINUATION);
1318 it->continuation_pixel_width = it->pixel_width;
1321 /* Reset these values to zero becaue the produce_special_glyphs
1322 above has changed them. */
1323 it->pixel_width = it->ascent = it->descent = 0;
1324 it->phys_ascent = it->phys_descent = 0;
1327 /* Set this after getting the dimensions of truncation and
1328 continuation glyphs, so that we don't produce glyphs when calling
1329 produce_special_glyphs, above. */
1330 it->glyph_row = row;
1331 it->area = TEXT_AREA;
1333 /* Get the dimensions of the display area. The display area
1334 consists of the visible window area plus a horizontally scrolled
1335 part to the left of the window. All x-values are relative to the
1336 start of this total display area. */
1337 if (base_face_id != DEFAULT_FACE_ID)
1339 /* Mode lines, menu bar in terminal frames. */
1340 it->first_visible_x = 0;
1341 it->last_visible_x = XFASTINT (w->width) * CANON_X_UNIT (it->f);
1343 else
1345 it->first_visible_x
1346 = XFASTINT (it->w->hscroll) * CANON_X_UNIT (it->f);
1347 it->last_visible_x = (it->first_visible_x
1348 + window_box_width (w, TEXT_AREA));
1350 /* If we truncate lines, leave room for the truncator glyph(s) at
1351 the right margin. Otherwise, leave room for the continuation
1352 glyph(s). Truncation and continuation glyphs are not inserted
1353 for window-based redisplay. */
1354 if (!FRAME_WINDOW_P (it->f))
1356 if (it->truncate_lines_p)
1357 it->last_visible_x -= it->truncation_pixel_width;
1358 else
1359 it->last_visible_x -= it->continuation_pixel_width;
1362 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
1363 it->current_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w) + w->vscroll;
1366 /* Leave room for a border glyph. */
1367 if (!FRAME_WINDOW_P (it->f)
1368 && !WINDOW_RIGHTMOST_P (it->w))
1369 it->last_visible_x -= 1;
1371 it->last_visible_y = window_text_bottom_y (w);
1373 /* For mode lines and alike, arrange for the first glyph having a
1374 left box line if the face specifies a box. */
1375 if (base_face_id != DEFAULT_FACE_ID)
1377 struct face *face;
1379 it->face_id = base_face_id;
1381 /* If we have a boxed mode line, make the first character appear
1382 with a left box line. */
1383 face = FACE_FROM_ID (it->f, base_face_id);
1384 if (face->box != FACE_NO_BOX)
1385 it->start_of_box_run_p = 1;
1388 /* If a buffer position was specified, set the iterator there,
1389 getting overlays and face properties from that position. */
1390 if (charpos > 0)
1392 it->end_charpos = ZV;
1393 it->face_id = -1;
1394 IT_CHARPOS (*it) = charpos;
1396 /* Compute byte position if not specified. */
1397 if (bytepos <= 0)
1398 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
1399 else
1400 IT_BYTEPOS (*it) = bytepos;
1402 /* Compute faces etc. */
1403 reseat (it, it->current.pos, 1);
1406 CHECK_IT (it);
1410 /* Initialize IT for the display of window W with window start POS. */
1412 void
1413 start_display (it, w, pos)
1414 struct it *it;
1415 struct window *w;
1416 struct text_pos pos;
1418 int start_at_line_beg_p;
1419 struct glyph_row *row;
1420 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
1421 int first_y;
1423 row = w->desired_matrix->rows + first_vpos;
1424 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
1425 first_y = it->current_y;
1427 /* If window start is not at a line start, move back to the line
1428 start. This makes sure that we take continuation lines into
1429 account. */
1430 start_at_line_beg_p = (CHARPOS (pos) == BEGV
1431 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
1432 if (!start_at_line_beg_p)
1433 reseat_at_previous_visible_line_start (it);
1435 /* If window start is not at a line start, skip forward to POS to
1436 get the correct continuation_lines_width and current_x. */
1437 if (!start_at_line_beg_p)
1439 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
1441 /* If lines are continued, this line may end in the middle of a
1442 multi-glyph character (e.g. a control character displayed as
1443 \003, or in the middle of an overlay string). In this case
1444 move_it_to above will not have taken us to the start of
1445 the continuation line but to the end of the continued line. */
1446 if (!it->truncate_lines_p && it->current_x > 0)
1448 if (it->current.dpvec_index >= 0
1449 || it->current.overlay_string_index >= 0)
1451 set_iterator_to_next (it);
1452 move_it_in_display_line_to (it, -1, -1, 0);
1454 it->continuation_lines_width += it->current_x;
1457 it->current_y = first_y;
1458 it->vpos = 0;
1459 it->current_x = it->hpos = 0;
1462 #if 0 /* Don't assert the following because start_display is sometimes
1463 called intentionally with a window start that is not at a
1464 line start. Please leave this code in as a comment. */
1466 /* Window start should be on a line start, now. */
1467 xassert (it->continuation_lines_width
1468 || IT_CHARPOS (it) == BEGV
1469 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
1470 #endif /* 0 */
1474 /* Initialize IT for stepping through current_buffer in window W,
1475 starting at position POS that includes overlay string and display
1476 vector/ control character translation position information. */
1478 static void
1479 init_from_display_pos (it, w, pos)
1480 struct it *it;
1481 struct window *w;
1482 struct display_pos *pos;
1484 /* Keep in mind: the call to reseat in init_iterator skips invisible
1485 text, so we might end up at a position different from POS. This
1486 is only a problem when POS is a row start after a newline and an
1487 overlay starts there with an after-string, and the overlay has an
1488 invisible property. Since we don't skip invisible text in
1489 display_line and elsewhere immediately after consuming the
1490 newline before the row start, such a POS will not be in a string,
1491 but the call to init_iterator below will move us to the
1492 after-string. */
1493 init_iterator (it, w, CHARPOS (pos->pos), BYTEPOS (pos->pos),
1494 NULL, DEFAULT_FACE_ID);
1496 /* If position is within an overlay string, set up IT to
1497 the right overlay string. */
1498 if (pos->overlay_string_index >= 0)
1500 int relative_index;
1502 /* We already have the first chunk of overlay strings in
1503 IT->overlay_strings. Load more until the one for
1504 pos->overlay_string_index is in IT->overlay_strings. */
1505 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
1507 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
1508 it->current.overlay_string_index = 0;
1509 while (n--)
1511 load_overlay_strings (it);
1512 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
1516 it->current.overlay_string_index = pos->overlay_string_index;
1517 relative_index = (it->current.overlay_string_index
1518 % OVERLAY_STRING_CHUNK_SIZE);
1519 it->string = it->overlay_strings[relative_index];
1520 it->current.string_pos = pos->string_pos;
1521 it->method = next_element_from_string;
1523 else if (CHARPOS (pos->string_pos) >= 0)
1525 /* Recorded position is not in an overlay string, but in another
1526 string. This can only be a string from a `display' property.
1527 IT should already be filled with that string. */
1528 it->current.string_pos = pos->string_pos;
1529 xassert (STRINGP (it->string));
1532 /* Restore position in display vector translations or control
1533 character translations. */
1534 if (pos->dpvec_index >= 0)
1536 /* This fills IT->dpvec. */
1537 get_next_display_element (it);
1538 xassert (it->dpvec && it->current.dpvec_index == 0);
1539 it->current.dpvec_index = pos->dpvec_index;
1542 CHECK_IT (it);
1546 /* Initialize IT for stepping through current_buffer in window W
1547 starting at ROW->start. */
1549 static void
1550 init_to_row_start (it, w, row)
1551 struct it *it;
1552 struct window *w;
1553 struct glyph_row *row;
1555 init_from_display_pos (it, w, &row->start);
1556 it->continuation_lines_width = row->continuation_lines_width;
1557 CHECK_IT (it);
1561 /* Initialize IT for stepping through current_buffer in window W
1562 starting in the line following ROW, i.e. starting at ROW->end. */
1564 static void
1565 init_to_row_end (it, w, row)
1566 struct it *it;
1567 struct window *w;
1568 struct glyph_row *row;
1570 init_from_display_pos (it, w, &row->end);
1572 if (row->continued_p)
1573 it->continuation_lines_width = (row->continuation_lines_width
1574 + row->pixel_width);
1575 CHECK_IT (it);
1581 /***********************************************************************
1582 Text properties
1583 ***********************************************************************/
1585 /* Called when IT reaches IT->stop_charpos. Handle text property and
1586 overlay changes. Set IT->stop_charpos to the next position where
1587 to stop. */
1589 static void
1590 handle_stop (it)
1591 struct it *it;
1593 enum prop_handled handled;
1594 int handle_overlay_change_p = 1;
1595 struct props *p;
1597 it->dpvec = NULL;
1598 it->current.dpvec_index = -1;
1602 handled = HANDLED_NORMALLY;
1604 /* Call text property handlers. */
1605 for (p = it_props; p->handler; ++p)
1607 handled = p->handler (it);
1609 if (handled == HANDLED_RECOMPUTE_PROPS)
1610 break;
1611 else if (handled == HANDLED_RETURN)
1612 return;
1613 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
1614 handle_overlay_change_p = 0;
1617 if (handled != HANDLED_RECOMPUTE_PROPS)
1619 /* Don't check for overlay strings below when set to deliver
1620 characters from a display vector. */
1621 if (it->method == next_element_from_display_vector)
1622 handle_overlay_change_p = 0;
1624 /* Handle overlay changes. */
1625 if (handle_overlay_change_p)
1626 handled = handle_overlay_change (it);
1628 /* Determine where to stop next. */
1629 if (handled == HANDLED_NORMALLY)
1630 compute_stop_pos (it);
1633 while (handled == HANDLED_RECOMPUTE_PROPS);
1637 /* Compute IT->stop_charpos from text property and overlay change
1638 information for IT's current position. */
1640 static void
1641 compute_stop_pos (it)
1642 struct it *it;
1644 register INTERVAL iv, next_iv;
1645 Lisp_Object object, limit, position;
1647 /* If nowhere else, stop at the end. */
1648 it->stop_charpos = it->end_charpos;
1650 if (STRINGP (it->string))
1652 /* Strings are usually short, so don't limit the search for
1653 properties. */
1654 object = it->string;
1655 limit = Qnil;
1656 XSETFASTINT (position, IT_STRING_CHARPOS (*it));
1658 else
1660 int charpos;
1662 /* If next overlay change is in front of the current stop pos
1663 (which is IT->end_charpos), stop there. Note: value of
1664 next_overlay_change is point-max if no overlay change
1665 follows. */
1666 charpos = next_overlay_change (IT_CHARPOS (*it));
1667 if (charpos < it->stop_charpos)
1668 it->stop_charpos = charpos;
1670 /* If showing the region, we have to stop at the region
1671 start or end because the face might change there. */
1672 if (it->region_beg_charpos > 0)
1674 if (IT_CHARPOS (*it) < it->region_beg_charpos)
1675 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
1676 else if (IT_CHARPOS (*it) < it->region_end_charpos)
1677 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
1680 /* Set up variables for computing the stop position from text
1681 property changes. */
1682 XSETBUFFER (object, current_buffer);
1683 XSETFASTINT (limit, IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
1684 XSETFASTINT (position, IT_CHARPOS (*it));
1688 /* Get the interval containing IT's position. Value is a null
1689 interval if there isn't such an interval. */
1690 iv = validate_interval_range (object, &position, &position, 0);
1691 if (!NULL_INTERVAL_P (iv))
1693 Lisp_Object values_here[LAST_PROP_IDX];
1694 struct props *p;
1696 /* Get properties here. */
1697 for (p = it_props; p->handler; ++p)
1698 values_here[p->idx] = textget (iv->plist, *p->name);
1700 /* Look for an interval following iv that has different
1701 properties. */
1702 for (next_iv = next_interval (iv);
1703 (!NULL_INTERVAL_P (next_iv)
1704 && (NILP (limit)
1705 || XFASTINT (limit) > next_iv->position));
1706 next_iv = next_interval (next_iv))
1708 for (p = it_props; p->handler; ++p)
1710 Lisp_Object new_value;
1712 new_value = textget (next_iv->plist, *p->name);
1713 if (!EQ (values_here[p->idx], new_value))
1714 break;
1717 if (p->handler)
1718 break;
1721 if (!NULL_INTERVAL_P (next_iv))
1723 if (INTEGERP (limit)
1724 && next_iv->position >= XFASTINT (limit))
1725 /* No text property change up to limit. */
1726 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
1727 else
1728 /* Text properties change in next_iv. */
1729 it->stop_charpos = min (it->stop_charpos, next_iv->position);
1733 xassert (STRINGP (it->string)
1734 || (it->stop_charpos >= BEGV
1735 && it->stop_charpos >= IT_CHARPOS (*it)));
1739 /* Return the position of the next overlay change after POS in
1740 current_buffer. Value is point-max if no overlay change
1741 follows. This is like `next-overlay-change' but doesn't use
1742 xmalloc. */
1744 static int
1745 next_overlay_change (pos)
1746 int pos;
1748 int noverlays;
1749 int endpos;
1750 Lisp_Object *overlays;
1751 int len;
1752 int i;
1754 /* Get all overlays at the given position. */
1755 len = 10;
1756 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1757 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL);
1758 if (noverlays > len)
1760 len = noverlays;
1761 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1762 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL);
1765 /* If any of these overlays ends before endpos,
1766 use its ending point instead. */
1767 for (i = 0; i < noverlays; ++i)
1769 Lisp_Object oend;
1770 int oendpos;
1772 oend = OVERLAY_END (overlays[i]);
1773 oendpos = OVERLAY_POSITION (oend);
1774 endpos = min (endpos, oendpos);
1777 return endpos;
1782 /***********************************************************************
1783 Fontification
1784 ***********************************************************************/
1786 /* Handle changes in the `fontified' property of the current buffer by
1787 calling hook functions from Qfontification_functions to fontify
1788 regions of text. */
1790 static enum prop_handled
1791 handle_fontified_prop (it)
1792 struct it *it;
1794 Lisp_Object prop, pos;
1795 enum prop_handled handled = HANDLED_NORMALLY;
1797 /* Get the value of the `fontified' property at IT's current buffer
1798 position. (The `fontified' property doesn't have a special
1799 meaning in strings.) If the value is nil, call functions from
1800 Qfontification_functions. */
1801 if (!STRINGP (it->string)
1802 && it->s == NULL
1803 && !NILP (Vfontification_functions)
1804 && (pos = make_number (IT_CHARPOS (*it)),
1805 prop = Fget_char_property (pos, Qfontified, Qnil),
1806 NILP (prop)))
1808 Lisp_Object args[2];
1810 /* Run the hook functions. */
1811 args[0] = Qfontification_functions;
1812 args[1] = pos;
1813 Frun_hook_with_args (2, args);
1815 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
1816 something. This avoids an endless loop if they failed to
1817 fontify the text for which reason ever. */
1818 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
1819 handled = HANDLED_RECOMPUTE_PROPS;
1822 return handled;
1827 /***********************************************************************
1828 Faces
1829 ***********************************************************************/
1831 /* Set up iterator IT from face properties at its current position.
1832 Called from handle_stop. */
1834 static enum prop_handled
1835 handle_face_prop (it)
1836 struct it *it;
1838 int new_face_id, next_stop;
1840 if (!STRINGP (it->string))
1842 new_face_id
1843 = face_at_buffer_position (it->w,
1844 IT_CHARPOS (*it),
1845 it->region_beg_charpos,
1846 it->region_end_charpos,
1847 &next_stop,
1848 (IT_CHARPOS (*it)
1849 + TEXT_PROP_DISTANCE_LIMIT),
1852 /* Is this a start of a run of characters with box face?
1853 Caveat: this can be called for a freshly initialized
1854 iterator; face_id is -1 is this case. We know that the new
1855 face will not change until limit, i.e. if the new face has a
1856 box, all characters up to limit will have one. But, as
1857 usual, we don't know whether limit is really the end. */
1858 if (new_face_id != it->face_id)
1860 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
1862 /* If new face has a box but old face has not, this is
1863 the start of a run of characters with box, i.e. it has
1864 a shadow on the left side. The value of face_id of the
1865 iterator will be -1 if this is the initial call that gets
1866 the face. In this case, we have to look in front of IT's
1867 position and see whether there is a face != new_face_id. */
1868 it->start_of_box_run_p
1869 = (new_face->box != FACE_NO_BOX
1870 && (it->face_id >= 0
1871 || IT_CHARPOS (*it) == BEG
1872 || new_face_id != face_before_it_pos (it)));
1873 it->face_box_p = new_face->box != FACE_NO_BOX;
1876 else
1878 new_face_id
1879 = face_at_string_position (it->w,
1880 it->string,
1881 IT_STRING_CHARPOS (*it),
1882 (it->current.overlay_string_index >= 0
1883 ? IT_CHARPOS (*it)
1884 : 0),
1885 it->region_beg_charpos,
1886 it->region_end_charpos,
1887 &next_stop,
1888 it->base_face_id);
1890 #if 0 /* This shouldn't be neccessary. Let's check it. */
1891 /* If IT is used to display a mode line we would really like to
1892 use the mode line face instead of the frame's default face. */
1893 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
1894 && new_face_id == DEFAULT_FACE_ID)
1895 new_face_id = MODE_LINE_FACE_ID;
1896 #endif
1898 /* Is this a start of a run of characters with box? Caveat:
1899 this can be called for a freshly allocated iterator; face_id
1900 is -1 is this case. We know that the new face will not
1901 change until the next check pos, i.e. if the new face has a
1902 box, all characters up to that position will have a
1903 box. But, as usual, we don't know whether that position
1904 is really the end. */
1905 if (new_face_id != it->face_id)
1907 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
1908 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
1910 /* If new face has a box but old face hasn't, this is the
1911 start of a run of characters with box, i.e. it has a
1912 shadow on the left side. */
1913 it->start_of_box_run_p
1914 = new_face->box && (old_face == NULL || !old_face->box);
1915 it->face_box_p = new_face->box != FACE_NO_BOX;
1919 it->face_id = new_face_id;
1920 return HANDLED_NORMALLY;
1924 /* Compute the face one character before or after the current position
1925 of IT. BEFORE_P non-zero means get the face in front of IT's
1926 position. Value is the id of the face. */
1928 static int
1929 face_before_or_after_it_pos (it, before_p)
1930 struct it *it;
1931 int before_p;
1933 int face_id, limit;
1934 int next_check_charpos;
1935 struct text_pos pos;
1937 xassert (it->s == NULL);
1939 if (STRINGP (it->string))
1941 /* No face change past the end of the string (for the case
1942 we are padding with spaces). No face change before the
1943 string start. */
1944 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size
1945 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
1946 return it->face_id;
1948 /* Set pos to the position before or after IT's current position. */
1949 if (before_p)
1950 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
1951 else
1952 /* For composition, we must check the character after the
1953 composition. */
1954 pos = (it->what == IT_COMPOSITION
1955 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
1956 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
1958 /* Get the face for ASCII, or unibyte. */
1959 face_id
1960 = face_at_string_position (it->w,
1961 it->string,
1962 CHARPOS (pos),
1963 (it->current.overlay_string_index >= 0
1964 ? IT_CHARPOS (*it)
1965 : 0),
1966 it->region_beg_charpos,
1967 it->region_end_charpos,
1968 &next_check_charpos,
1969 it->base_face_id);
1971 /* Correct the face for charsets different from ASCII. Do it
1972 for the multibyte case only. The face returned above is
1973 suitable for unibyte text if IT->string is unibyte. */
1974 if (STRING_MULTIBYTE (it->string))
1976 unsigned char *p = XSTRING (it->string)->data + BYTEPOS (pos);
1977 int rest = STRING_BYTES (XSTRING (it->string)) - BYTEPOS (pos);
1978 int c, len;
1979 struct face *face = FACE_FROM_ID (it->f, face_id);
1981 c = string_char_and_length (p, rest, &len);
1982 face_id = FACE_FOR_CHAR (it->f, face, c);
1985 else
1987 if ((IT_CHARPOS (*it) >= ZV && !before_p)
1988 || (IT_CHARPOS (*it) <= BEGV && before_p))
1989 return it->face_id;
1991 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
1992 pos = it->current.pos;
1994 if (before_p)
1995 DEC_TEXT_POS (pos, it->multibyte_p);
1996 else
1998 if (it->what == IT_COMPOSITION)
1999 /* For composition, we must check the position after the
2000 composition. */
2001 pos.charpos += it->cmp_len, pos.bytepos += it->len;
2002 else
2003 INC_TEXT_POS (pos, it->multibyte_p);
2005 /* Determine face for CHARSET_ASCII, or unibyte. */
2006 face_id = face_at_buffer_position (it->w,
2007 CHARPOS (pos),
2008 it->region_beg_charpos,
2009 it->region_end_charpos,
2010 &next_check_charpos,
2011 limit, 0);
2013 /* Correct the face for charsets different from ASCII. Do it
2014 for the multibyte case only. The face returned above is
2015 suitable for unibyte text if current_buffer is unibyte. */
2016 if (it->multibyte_p)
2018 int c = FETCH_MULTIBYTE_CHAR (CHARPOS (pos));
2019 struct face *face = FACE_FROM_ID (it->f, face_id);
2020 face_id = FACE_FOR_CHAR (it->f, face, c);
2024 return face_id;
2029 /***********************************************************************
2030 Invisible text
2031 ***********************************************************************/
2033 /* Set up iterator IT from invisible properties at its current
2034 position. Called from handle_stop. */
2036 static enum prop_handled
2037 handle_invisible_prop (it)
2038 struct it *it;
2040 enum prop_handled handled = HANDLED_NORMALLY;
2042 if (STRINGP (it->string))
2044 extern Lisp_Object Qinvisible;
2045 Lisp_Object prop, end_charpos, limit, charpos;
2047 /* Get the value of the invisible text property at the
2048 current position. Value will be nil if there is no such
2049 property. */
2050 XSETFASTINT (charpos, IT_STRING_CHARPOS (*it));
2051 prop = Fget_text_property (charpos, Qinvisible, it->string);
2053 if (!NILP (prop)
2054 && IT_STRING_CHARPOS (*it) < it->end_charpos)
2056 handled = HANDLED_RECOMPUTE_PROPS;
2058 /* Get the position at which the next change of the
2059 invisible text property can be found in IT->string.
2060 Value will be nil if the property value is the same for
2061 all the rest of IT->string. */
2062 XSETINT (limit, XSTRING (it->string)->size);
2063 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
2064 it->string, limit);
2066 /* Text at current position is invisible. The next
2067 change in the property is at position end_charpos.
2068 Move IT's current position to that position. */
2069 if (INTEGERP (end_charpos)
2070 && XFASTINT (end_charpos) < XFASTINT (limit))
2072 struct text_pos old;
2073 old = it->current.string_pos;
2074 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
2075 compute_string_pos (&it->current.string_pos, old, it->string);
2077 else
2079 /* The rest of the string is invisible. If this is an
2080 overlay string, proceed with the next overlay string
2081 or whatever comes and return a character from there. */
2082 if (it->current.overlay_string_index >= 0)
2084 next_overlay_string (it);
2085 /* Don't check for overlay strings when we just
2086 finished processing them. */
2087 handled = HANDLED_OVERLAY_STRING_CONSUMED;
2089 else
2091 struct Lisp_String *s = XSTRING (it->string);
2092 IT_STRING_CHARPOS (*it) = s->size;
2093 IT_STRING_BYTEPOS (*it) = STRING_BYTES (s);
2098 else
2100 int visible_p, newpos, next_stop;
2101 Lisp_Object pos, prop;
2103 /* First of all, is there invisible text at this position? */
2104 XSETFASTINT (pos, IT_CHARPOS (*it));
2105 prop = Fget_char_property (pos, Qinvisible, it->window);
2107 /* If we are on invisible text, skip over it. */
2108 if (TEXT_PROP_MEANS_INVISIBLE (prop)
2109 && IT_CHARPOS (*it) < it->end_charpos)
2111 /* Record whether we have to display an ellipsis for the
2112 invisible text. */
2113 int display_ellipsis_p
2114 = TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (prop);
2116 handled = HANDLED_RECOMPUTE_PROPS;
2118 /* Loop skipping over invisible text. The loop is left at
2119 ZV or with IT on the first char being visible again. */
2122 /* Try to skip some invisible text. Return value is the
2123 position reached which can be equal to IT's position
2124 if there is nothing invisible here. This skips both
2125 over invisible text properties and overlays with
2126 invisible property. */
2127 newpos = skip_invisible (IT_CHARPOS (*it),
2128 &next_stop, ZV, it->window);
2130 /* If we skipped nothing at all we weren't at invisible
2131 text in the first place. If everything to the end of
2132 the buffer was skipped, end the loop. */
2133 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
2134 visible_p = 1;
2135 else
2137 /* We skipped some characters but not necessarily
2138 all there are. Check if we ended up on visible
2139 text. Fget_char_property returns the property of
2140 the char before the given position, i.e. if we
2141 get visible_p = 1, this means that the char at
2142 newpos is visible. */
2143 XSETFASTINT (pos, newpos);
2144 prop = Fget_char_property (pos, Qinvisible, it->window);
2145 visible_p = !TEXT_PROP_MEANS_INVISIBLE (prop);
2148 /* If we ended up on invisible text, proceed to
2149 skip starting with next_stop. */
2150 if (!visible_p)
2151 IT_CHARPOS (*it) = next_stop;
2153 while (!visible_p);
2155 /* The position newpos is now either ZV or on visible text. */
2156 IT_CHARPOS (*it) = newpos;
2157 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
2159 /* Maybe return `...' next for the end of the invisible text. */
2160 if (display_ellipsis_p)
2162 if (it->dp
2163 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
2165 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
2166 it->dpvec = v->contents;
2167 it->dpend = v->contents + v->size;
2169 else
2171 /* Default `...'. */
2172 it->dpvec = default_invis_vector;
2173 it->dpend = default_invis_vector + 3;
2176 /* The ellipsis display does not replace the display of
2177 the character at the new position. Indicate this by
2178 setting IT->dpvec_char_len to zero. */
2179 it->dpvec_char_len = 0;
2181 it->current.dpvec_index = 0;
2182 it->method = next_element_from_display_vector;
2187 return handled;
2192 /***********************************************************************
2193 'display' property
2194 ***********************************************************************/
2196 /* Set up iterator IT from `display' property at its current position.
2197 Called from handle_stop. */
2199 static enum prop_handled
2200 handle_display_prop (it)
2201 struct it *it;
2203 Lisp_Object prop, object;
2204 struct text_pos *position;
2205 int space_or_image_found_p;
2207 if (STRINGP (it->string))
2209 object = it->string;
2210 position = &it->current.string_pos;
2212 else
2214 object = Qnil;
2215 position = &it->current.pos;
2218 /* Reset those iterator values set from display property values. */
2219 it->font_height = Qnil;
2220 it->space_width = Qnil;
2221 it->voffset = 0;
2223 /* We don't support recursive `display' properties, i.e. string
2224 values that have a string `display' property, that have a string
2225 `display' property etc. */
2226 if (!it->string_from_display_prop_p)
2227 it->area = TEXT_AREA;
2229 prop = Fget_char_property (make_number (position->charpos),
2230 Qdisplay, object);
2231 if (NILP (prop))
2232 return HANDLED_NORMALLY;
2234 space_or_image_found_p = 0;
2235 if (CONSP (prop)
2236 && CONSP (XCAR (prop))
2237 && !EQ (Qmargin, XCAR (XCAR (prop))))
2239 /* A list of sub-properties. */
2240 while (CONSP (prop))
2242 if (handle_single_display_prop (it, XCAR (prop), object, position))
2243 space_or_image_found_p = 1;
2244 prop = XCDR (prop);
2247 else if (VECTORP (prop))
2249 int i;
2250 for (i = 0; i < XVECTOR (prop)->size; ++i)
2251 if (handle_single_display_prop (it, XVECTOR (prop)->contents[i],
2252 object, position))
2253 space_or_image_found_p = 1;
2255 else
2257 if (handle_single_display_prop (it, prop, object, position))
2258 space_or_image_found_p = 1;
2261 return space_or_image_found_p ? HANDLED_RETURN : HANDLED_NORMALLY;
2265 /* Value is the position of the end of the `display' property starting
2266 at START_POS in OBJECT. */
2268 static struct text_pos
2269 display_prop_end (it, object, start_pos)
2270 struct it *it;
2271 Lisp_Object object;
2272 struct text_pos start_pos;
2274 Lisp_Object end;
2275 struct text_pos end_pos;
2277 end = next_single_char_property_change (make_number (CHARPOS (start_pos)),
2278 Qdisplay, object, Qnil);
2279 CHARPOS (end_pos) = XFASTINT (end);
2280 if (STRINGP (object))
2281 compute_string_pos (&end_pos, start_pos, it->string);
2282 else
2283 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
2285 return end_pos;
2289 /* Set up IT from a single `display' sub-property value PROP. OBJECT
2290 is the object in which the `display' property was found. *POSITION
2291 is the position at which it was found.
2293 If PROP is a `space' or `image' sub-property, set *POSITION to the
2294 end position of the `display' property.
2296 Value is non-zero if a `space' or `image' property value was found. */
2298 static int
2299 handle_single_display_prop (it, prop, object, position)
2300 struct it *it;
2301 Lisp_Object prop;
2302 Lisp_Object object;
2303 struct text_pos *position;
2305 Lisp_Object value;
2306 int space_or_image_found_p = 0;
2308 Lisp_Object form;
2310 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
2311 evaluated. If the result is nil, VALUE is ignored. */
2312 form = Qt;
2313 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
2315 prop = XCDR (prop);
2316 if (!CONSP (prop))
2317 return 0;
2318 form = XCAR (prop);
2319 prop = XCDR (prop);
2322 if (!NILP (form) && !EQ (form, Qt))
2324 struct gcpro gcpro1;
2325 struct text_pos end_pos, pt;
2327 GCPRO1 (form);
2328 end_pos = display_prop_end (it, object, *position);
2330 /* Temporarily set point to the end position, and then evaluate
2331 the form. This makes `(eolp)' work as FORM. */
2332 if (BUFFERP (object))
2334 CHARPOS (pt) = PT;
2335 BYTEPOS (pt) = PT_BYTE;
2336 TEMP_SET_PT_BOTH (CHARPOS (end_pos), BYTEPOS (end_pos));
2339 form = eval_form (form);
2341 if (BUFFERP (object))
2342 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
2343 UNGCPRO;
2346 if (NILP (form))
2347 return 0;
2349 if (CONSP (prop)
2350 && EQ (XCAR (prop), Qheight)
2351 && CONSP (XCDR (prop)))
2353 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2354 return 0;
2356 /* `(height HEIGHT)'. */
2357 it->font_height = XCAR (XCDR (prop));
2358 if (!NILP (it->font_height))
2360 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2361 int new_height = -1;
2363 if (CONSP (it->font_height)
2364 && (EQ (XCAR (it->font_height), Qplus)
2365 || EQ (XCAR (it->font_height), Qminus))
2366 && CONSP (XCDR (it->font_height))
2367 && INTEGERP (XCAR (XCDR (it->font_height))))
2369 /* `(+ N)' or `(- N)' where N is an integer. */
2370 int steps = XINT (XCAR (XCDR (it->font_height)));
2371 if (EQ (XCAR (it->font_height), Qplus))
2372 steps = - steps;
2373 it->face_id = smaller_face (it->f, it->face_id, steps);
2375 else if (SYMBOLP (it->font_height))
2377 /* Call function with current height as argument.
2378 Value is the new height. */
2379 Lisp_Object form, height;
2380 struct gcpro gcpro1;
2382 height = face->lface[LFACE_HEIGHT_INDEX];
2383 form = Fcons (it->font_height, Fcons (height, Qnil));
2384 GCPRO1 (form);
2385 height = eval_form (form);
2386 if (NUMBERP (height))
2387 new_height = XFLOATINT (height);
2388 UNGCPRO;
2390 else if (NUMBERP (it->font_height))
2392 /* Value is a multiple of the canonical char height. */
2393 struct face *face;
2395 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
2396 new_height = (XFLOATINT (it->font_height)
2397 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
2399 else
2401 /* Evaluate IT->font_height with `height' bound to the
2402 current specified height to get the new height. */
2403 Lisp_Object value;
2404 int count = specpdl_ptr - specpdl;
2406 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
2407 value = eval_form (it->font_height);
2408 unbind_to (count, Qnil);
2410 if (NUMBERP (value))
2411 new_height = XFLOATINT (value);
2414 if (new_height > 0)
2415 it->face_id = face_with_height (it->f, it->face_id, new_height);
2418 else if (CONSP (prop)
2419 && EQ (XCAR (prop), Qspace_width)
2420 && CONSP (XCDR (prop)))
2422 /* `(space_width WIDTH)'. */
2423 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2424 return 0;
2426 value = XCAR (XCDR (prop));
2427 if (NUMBERP (value) && XFLOATINT (value) > 0)
2428 it->space_width = value;
2430 else if (CONSP (prop)
2431 && EQ (XCAR (prop), Qraise)
2432 && CONSP (XCDR (prop)))
2434 /* `(raise FACTOR)'. */
2435 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2436 return 0;
2438 #ifdef HAVE_WINDOW_SYSTEM
2439 value = XCAR (XCDR (prop));
2440 if (NUMBERP (value))
2442 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2443 it->voffset = - (XFLOATINT (value)
2444 * (FONT_HEIGHT (face->font)));
2446 #endif /* HAVE_WINDOW_SYSTEM */
2448 else if (!it->string_from_display_prop_p)
2450 /* `((margin left-margin) VALUE)' or `((margin right-margin)
2451 VALUE) or `((margin nil) VALUE)' or VALUE. */
2452 Lisp_Object location, value;
2453 struct text_pos start_pos;
2454 int valid_p;
2456 /* Characters having this form of property are not displayed, so
2457 we have to find the end of the property. */
2458 start_pos = *position;
2459 *position = display_prop_end (it, object, start_pos);
2460 value = Qnil;
2462 /* Let's stop at the new position and assume that all
2463 text properties change there. */
2464 it->stop_charpos = position->charpos;
2466 location = Qunbound;
2467 if (CONSP (prop) && CONSP (XCAR (prop)))
2469 Lisp_Object tem;
2471 value = XCDR (prop);
2472 if (CONSP (value))
2473 value = XCAR (value);
2475 tem = XCAR (prop);
2476 if (EQ (XCAR (tem), Qmargin)
2477 && (tem = XCDR (tem),
2478 tem = CONSP (tem) ? XCAR (tem) : Qnil,
2479 (NILP (tem)
2480 || EQ (tem, Qleft_margin)
2481 || EQ (tem, Qright_margin))))
2482 location = tem;
2485 if (EQ (location, Qunbound))
2487 location = Qnil;
2488 value = prop;
2491 #ifdef HAVE_WINDOW_SYSTEM
2492 if (FRAME_TERMCAP_P (it->f))
2493 valid_p = STRINGP (value);
2494 else
2495 valid_p = (STRINGP (value)
2496 || (CONSP (value) && EQ (XCAR (value), Qspace))
2497 || valid_image_p (value));
2498 #else /* not HAVE_WINDOW_SYSTEM */
2499 valid_p = STRINGP (value);
2500 #endif /* not HAVE_WINDOW_SYSTEM */
2502 if ((EQ (location, Qleft_margin)
2503 || EQ (location, Qright_margin)
2504 || NILP (location))
2505 && valid_p)
2507 space_or_image_found_p = 1;
2509 /* Save current settings of IT so that we can restore them
2510 when we are finished with the glyph property value. */
2511 push_it (it);
2513 if (NILP (location))
2514 it->area = TEXT_AREA;
2515 else if (EQ (location, Qleft_margin))
2516 it->area = LEFT_MARGIN_AREA;
2517 else
2518 it->area = RIGHT_MARGIN_AREA;
2520 if (STRINGP (value))
2522 it->string = value;
2523 it->multibyte_p = STRING_MULTIBYTE (it->string);
2524 it->current.overlay_string_index = -1;
2525 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
2526 it->end_charpos = it->string_nchars
2527 = XSTRING (it->string)->size;
2528 it->method = next_element_from_string;
2529 it->stop_charpos = 0;
2530 it->string_from_display_prop_p = 1;
2532 else if (CONSP (value) && EQ (XCAR (value), Qspace))
2534 it->method = next_element_from_stretch;
2535 it->object = value;
2536 it->current.pos = it->position = start_pos;
2538 #ifdef HAVE_WINDOW_SYSTEM
2539 else
2541 it->what = IT_IMAGE;
2542 it->image_id = lookup_image (it->f, value);
2543 it->position = start_pos;
2544 it->object = NILP (object) ? it->w->buffer : object;
2545 it->method = next_element_from_image;
2547 /* Say that we haven't consumed the characters with
2548 `display' property yet. The call to pop_it in
2549 set_iterator_to_next will clean this up. */
2550 *position = start_pos;
2552 #endif /* HAVE_WINDOW_SYSTEM */
2554 else
2555 /* Invalid property or property not supported. Restore
2556 the position to what it was before. */
2557 *position = start_pos;
2560 return space_or_image_found_p;
2565 /***********************************************************************
2566 `composition' property
2567 ***********************************************************************/
2569 /* Set up iterator IT from `composition' property at its current
2570 position. Called from handle_stop. */
2572 static enum prop_handled
2573 handle_composition_prop (it)
2574 struct it *it;
2576 Lisp_Object prop, string;
2577 int pos, pos_byte, end;
2578 enum prop_handled handled = HANDLED_NORMALLY;
2580 if (STRINGP (it->string))
2582 pos = IT_STRING_CHARPOS (*it);
2583 pos_byte = IT_STRING_BYTEPOS (*it);
2584 string = it->string;
2586 else
2588 pos = IT_CHARPOS (*it);
2589 pos_byte = IT_BYTEPOS (*it);
2590 string = Qnil;
2593 /* If there's a valid composition and point is not inside of the
2594 composition (in the case that the composition is from the current
2595 buffer), draw a glyph composed from the composition components. */
2596 if (find_composition (pos, -1, &pos, &end, &prop, string)
2597 && COMPOSITION_VALID_P (pos, end, prop)
2598 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
2600 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
2602 if (id >= 0)
2604 it->method = next_element_from_composition;
2605 it->cmp_id = id;
2606 it->cmp_len = COMPOSITION_LENGTH (prop);
2607 /* For a terminal, draw only the first character of the
2608 components. */
2609 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
2610 it->len = (STRINGP (it->string)
2611 ? string_char_to_byte (it->string, end)
2612 : CHAR_TO_BYTE (end)) - pos_byte;
2613 it->stop_charpos = end;
2614 handled = HANDLED_RETURN;
2618 return handled;
2623 /***********************************************************************
2624 Overlay strings
2625 ***********************************************************************/
2627 /* The following structure is used to record overlay strings for
2628 later sorting in load_overlay_strings. */
2630 struct overlay_entry
2632 Lisp_Object string;
2633 int priority;
2634 int after_string_p;
2638 /* Set up iterator IT from overlay strings at its current position.
2639 Called from handle_stop. */
2641 static enum prop_handled
2642 handle_overlay_change (it)
2643 struct it *it;
2645 /* Overlays are handled in current_buffer only. */
2646 if (STRINGP (it->string))
2647 return HANDLED_NORMALLY;
2648 else
2649 return (get_overlay_strings (it)
2650 ? HANDLED_RECOMPUTE_PROPS
2651 : HANDLED_NORMALLY);
2655 /* Set up the next overlay string for delivery by IT, if there is an
2656 overlay string to deliver. Called by set_iterator_to_next when the
2657 end of the current overlay string is reached. If there are more
2658 overlay strings to display, IT->string and
2659 IT->current.overlay_string_index are set appropriately here.
2660 Otherwise IT->string is set to nil. */
2662 static void
2663 next_overlay_string (it)
2664 struct it *it;
2666 ++it->current.overlay_string_index;
2667 if (it->current.overlay_string_index == it->n_overlay_strings)
2669 /* No more overlay strings. Restore IT's settings to what
2670 they were before overlay strings were processed, and
2671 continue to deliver from current_buffer. */
2672 pop_it (it);
2673 xassert (it->stop_charpos >= BEGV
2674 && it->stop_charpos <= it->end_charpos);
2675 it->string = Qnil;
2676 it->current.overlay_string_index = -1;
2677 SET_TEXT_POS (it->current.string_pos, -1, -1);
2678 it->n_overlay_strings = 0;
2679 it->method = next_element_from_buffer;
2681 else
2683 /* There are more overlay strings to process. If
2684 IT->current.overlay_string_index has advanced to a position
2685 where we must load IT->overlay_strings with more strings, do
2686 it. */
2687 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
2689 if (it->current.overlay_string_index && i == 0)
2690 load_overlay_strings (it);
2692 /* Initialize IT to deliver display elements from the overlay
2693 string. */
2694 it->string = it->overlay_strings[i];
2695 it->multibyte_p = STRING_MULTIBYTE (it->string);
2696 SET_TEXT_POS (it->current.string_pos, 0, 0);
2697 it->method = next_element_from_string;
2698 it->stop_charpos = 0;
2701 CHECK_IT (it);
2705 /* Compare two overlay_entry structures E1 and E2. Used as a
2706 comparison function for qsort in load_overlay_strings. Overlay
2707 strings for the same position are sorted so that
2709 1. All after-strings come in front of before-strings.
2711 2. Within after-strings, strings are sorted so that overlay strings
2712 from overlays with higher priorities come first.
2714 2. Within before-strings, strings are sorted so that overlay
2715 strings from overlays with higher priorities come last.
2717 Value is analogous to strcmp. */
2720 static int
2721 compare_overlay_entries (e1, e2)
2722 void *e1, *e2;
2724 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
2725 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
2726 int result;
2728 if (entry1->after_string_p != entry2->after_string_p)
2729 /* Let after-strings appear in front of before-strings. */
2730 result = entry1->after_string_p ? -1 : 1;
2731 else if (entry1->after_string_p)
2732 /* After-strings sorted in order of decreasing priority. */
2733 result = entry2->priority - entry1->priority;
2734 else
2735 /* Before-strings sorted in order of increasing priority. */
2736 result = entry1->priority - entry2->priority;
2738 return result;
2742 /* Load the vector IT->overlay_strings with overlay strings from IT's
2743 current buffer position. Set IT->n_overlays to the total number of
2744 overlay strings found.
2746 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
2747 a time. On entry into load_overlay_strings,
2748 IT->current.overlay_string_index gives the number of overlay
2749 strings that have already been loaded by previous calls to this
2750 function.
2752 Overlay strings are sorted so that after-string strings come in
2753 front of before-string strings. Within before and after-strings,
2754 strings are sorted by overlay priority. See also function
2755 compare_overlay_entries. */
2757 static void
2758 load_overlay_strings (it)
2759 struct it *it;
2761 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
2762 Lisp_Object ov, overlay, window, str;
2763 int start, end;
2764 int size = 20;
2765 int n = 0, i, j;
2766 struct overlay_entry *entries
2767 = (struct overlay_entry *) alloca (size * sizeof *entries);
2769 /* Append the overlay string STRING of overlay OVERLAY to vector
2770 `entries' which has size `size' and currently contains `n'
2771 elements. AFTER_P non-zero means STRING is an after-string of
2772 OVERLAY. */
2773 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
2774 do \
2776 Lisp_Object priority; \
2778 if (n == size) \
2780 int new_size = 2 * size; \
2781 struct overlay_entry *old = entries; \
2782 entries = \
2783 (struct overlay_entry *) alloca (new_size \
2784 * sizeof *entries); \
2785 bcopy (old, entries, size * sizeof *entries); \
2786 size = new_size; \
2789 entries[n].string = (STRING); \
2790 priority = Foverlay_get ((OVERLAY), Qpriority); \
2791 entries[n].priority \
2792 = INTEGERP (priority) ? XFASTINT (priority) : 0; \
2793 entries[n].after_string_p = (AFTER_P); \
2794 ++n; \
2796 while (0)
2798 /* Process overlay before the overlay center. */
2799 for (ov = current_buffer->overlays_before;
2800 CONSP (ov);
2801 ov = XCDR (ov))
2803 overlay = XCAR (ov);
2804 xassert (OVERLAYP (overlay));
2805 start = OVERLAY_POSITION (OVERLAY_START (overlay));
2806 end = OVERLAY_POSITION (OVERLAY_END (overlay));
2808 if (end < IT_CHARPOS (*it))
2809 break;
2811 /* Skip this overlay if it doesn't start or end at IT's current
2812 position. */
2813 if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it))
2814 continue;
2816 /* Skip this overlay if it doesn't apply to IT->w. */
2817 window = Foverlay_get (overlay, Qwindow);
2818 if (WINDOWP (window) && XWINDOW (window) != it->w)
2819 continue;
2821 /* If overlay has a non-empty before-string, record it. */
2822 if (start == IT_CHARPOS (*it)
2823 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
2824 && XSTRING (str)->size)
2825 RECORD_OVERLAY_STRING (overlay, str, 0);
2827 /* If overlay has a non-empty after-string, record it. */
2828 if (end == IT_CHARPOS (*it)
2829 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
2830 && XSTRING (str)->size)
2831 RECORD_OVERLAY_STRING (overlay, str, 1);
2834 /* Process overlays after the overlay center. */
2835 for (ov = current_buffer->overlays_after;
2836 CONSP (ov);
2837 ov = XCDR (ov))
2839 overlay = XCAR (ov);
2840 xassert (OVERLAYP (overlay));
2841 start = OVERLAY_POSITION (OVERLAY_START (overlay));
2842 end = OVERLAY_POSITION (OVERLAY_END (overlay));
2844 if (start > IT_CHARPOS (*it))
2845 break;
2847 /* Skip this overlay if it doesn't start or end at IT's current
2848 position. */
2849 if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it))
2850 continue;
2852 /* Skip this overlay if it doesn't apply to IT->w. */
2853 window = Foverlay_get (overlay, Qwindow);
2854 if (WINDOWP (window) && XWINDOW (window) != it->w)
2855 continue;
2857 /* If overlay has a non-empty before-string, record it. */
2858 if (start == IT_CHARPOS (*it)
2859 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
2860 && XSTRING (str)->size)
2861 RECORD_OVERLAY_STRING (overlay, str, 0);
2863 /* If overlay has a non-empty after-string, record it. */
2864 if (end == IT_CHARPOS (*it)
2865 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
2866 && XSTRING (str)->size)
2867 RECORD_OVERLAY_STRING (overlay, str, 1);
2870 #undef RECORD_OVERLAY_STRING
2872 /* Sort entries. */
2873 qsort (entries, n, sizeof *entries, compare_overlay_entries);
2875 /* Record the total number of strings to process. */
2876 it->n_overlay_strings = n;
2878 /* IT->current.overlay_string_index is the number of overlay strings
2879 that have already been consumed by IT. Copy some of the
2880 remaining overlay strings to IT->overlay_strings. */
2881 i = 0;
2882 j = it->current.overlay_string_index;
2883 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
2884 it->overlay_strings[i++] = entries[j++].string;
2886 CHECK_IT (it);
2890 /* Get the first chunk of overlay strings at IT's current buffer
2891 position. Value is non-zero if at least one overlay string was
2892 found. */
2894 static int
2895 get_overlay_strings (it)
2896 struct it *it;
2898 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
2899 process. This fills IT->overlay_strings with strings, and sets
2900 IT->n_overlay_strings to the total number of strings to process.
2901 IT->pos.overlay_string_index has to be set temporarily to zero
2902 because load_overlay_strings needs this; it must be set to -1
2903 when no overlay strings are found because a zero value would
2904 indicate a position in the first overlay string. */
2905 it->current.overlay_string_index = 0;
2906 load_overlay_strings (it);
2908 /* If we found overlay strings, set up IT to deliver display
2909 elements from the first one. Otherwise set up IT to deliver
2910 from current_buffer. */
2911 if (it->n_overlay_strings)
2913 /* Make sure we know settings in current_buffer, so that we can
2914 restore meaningful values when we're done with the overlay
2915 strings. */
2916 compute_stop_pos (it);
2917 xassert (it->face_id >= 0);
2919 /* Save IT's settings. They are restored after all overlay
2920 strings have been processed. */
2921 xassert (it->sp == 0);
2922 push_it (it);
2924 /* Set up IT to deliver display elements from the first overlay
2925 string. */
2926 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
2927 it->stop_charpos = 0;
2928 it->string = it->overlay_strings[0];
2929 it->multibyte_p = STRING_MULTIBYTE (it->string);
2930 xassert (STRINGP (it->string));
2931 it->method = next_element_from_string;
2933 else
2935 it->string = Qnil;
2936 it->current.overlay_string_index = -1;
2937 it->method = next_element_from_buffer;
2940 CHECK_IT (it);
2942 /* Value is non-zero if we found at least one overlay string. */
2943 return STRINGP (it->string);
2948 /***********************************************************************
2949 Saving and restoring state
2950 ***********************************************************************/
2952 /* Save current settings of IT on IT->stack. Called, for example,
2953 before setting up IT for an overlay string, to be able to restore
2954 IT's settings to what they were after the overlay string has been
2955 processed. */
2957 static void
2958 push_it (it)
2959 struct it *it;
2961 struct iterator_stack_entry *p;
2963 xassert (it->sp < 2);
2964 p = it->stack + it->sp;
2966 p->stop_charpos = it->stop_charpos;
2967 xassert (it->face_id >= 0);
2968 p->face_id = it->face_id;
2969 p->string = it->string;
2970 p->pos = it->current;
2971 p->end_charpos = it->end_charpos;
2972 p->string_nchars = it->string_nchars;
2973 p->area = it->area;
2974 p->multibyte_p = it->multibyte_p;
2975 p->space_width = it->space_width;
2976 p->font_height = it->font_height;
2977 p->voffset = it->voffset;
2978 p->string_from_display_prop_p = it->string_from_display_prop_p;
2979 ++it->sp;
2983 /* Restore IT's settings from IT->stack. Called, for example, when no
2984 more overlay strings must be processed, and we return to delivering
2985 display elements from a buffer, or when the end of a string from a
2986 `display' property is reached and we return to delivering display
2987 elements from an overlay string, or from a buffer. */
2989 static void
2990 pop_it (it)
2991 struct it *it;
2993 struct iterator_stack_entry *p;
2995 xassert (it->sp > 0);
2996 --it->sp;
2997 p = it->stack + it->sp;
2998 it->stop_charpos = p->stop_charpos;
2999 it->face_id = p->face_id;
3000 it->string = p->string;
3001 it->current = p->pos;
3002 it->end_charpos = p->end_charpos;
3003 it->string_nchars = p->string_nchars;
3004 it->area = p->area;
3005 it->multibyte_p = p->multibyte_p;
3006 it->space_width = p->space_width;
3007 it->font_height = p->font_height;
3008 it->voffset = p->voffset;
3009 it->string_from_display_prop_p = p->string_from_display_prop_p;
3014 /***********************************************************************
3015 Moving over lines
3016 ***********************************************************************/
3018 /* Set IT's current position to the previous line start. */
3020 static void
3021 back_to_previous_line_start (it)
3022 struct it *it;
3024 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
3025 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
3029 /* Set IT's current position to the next line start. */
3031 static void
3032 forward_to_next_line_start (it)
3033 struct it *it;
3035 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), 1);
3036 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
3040 /* Set IT's current position to the previous visible line start. Skip
3041 invisible text that is so either due to text properties or due to
3042 selective display. Caution: this does not change IT->current_x and
3043 IT->hpos. */
3045 static void
3046 back_to_previous_visible_line_start (it)
3047 struct it *it;
3049 int visible_p = 0;
3051 /* Go back one newline if not on BEGV already. */
3052 if (IT_CHARPOS (*it) > BEGV)
3053 back_to_previous_line_start (it);
3055 /* Move over lines that are invisible because of selective display
3056 or text properties. */
3057 while (IT_CHARPOS (*it) > BEGV
3058 && !visible_p)
3060 visible_p = 1;
3062 /* If selective > 0, then lines indented more than that values
3063 are invisible. */
3064 if (it->selective > 0
3065 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
3066 it->selective))
3067 visible_p = 0;
3068 else
3070 Lisp_Object prop;
3072 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
3073 Qinvisible, it->window);
3074 if (TEXT_PROP_MEANS_INVISIBLE (prop))
3075 visible_p = 0;
3078 /* Back one more newline if the current one is invisible. */
3079 if (!visible_p)
3080 back_to_previous_line_start (it);
3083 xassert (IT_CHARPOS (*it) >= BEGV);
3084 xassert (IT_CHARPOS (*it) == BEGV
3085 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
3086 CHECK_IT (it);
3090 /* Reseat iterator IT at the previous visible line start. Skip
3091 invisible text that is so either due to text properties or due to
3092 selective display. At the end, update IT's overlay information,
3093 face information etc. */
3095 static void
3096 reseat_at_previous_visible_line_start (it)
3097 struct it *it;
3099 back_to_previous_visible_line_start (it);
3100 reseat (it, it->current.pos, 1);
3101 CHECK_IT (it);
3105 /* Reseat iterator IT on the next visible line start in the current
3106 buffer. ON_NEWLINE_P non-zero means position IT on the newline
3107 preceding the line start. Skip over invisible text that is so
3108 because of selective display. Compute faces, overlays etc at the
3109 new position. Note that this function does not skip over text that
3110 is invisible because of text properties. */
3112 static void
3113 reseat_at_next_visible_line_start (it, on_newline_p)
3114 struct it *it;
3115 int on_newline_p;
3117 /* Restore the buffer position when currently not delivering display
3118 elements from the current buffer. This is the case, for example,
3119 when called at the end of a truncated overlay string. */
3120 while (it->sp)
3121 pop_it (it);
3122 it->method = next_element_from_buffer;
3124 /* Otherwise, scan_buffer would not work. */
3125 if (IT_CHARPOS (*it) < ZV)
3127 /* If on a newline, advance past it. Otherwise, find the next
3128 newline which automatically gives us the position following
3129 the newline. */
3130 if (FETCH_BYTE (IT_BYTEPOS (*it)) == '\n')
3132 ++IT_CHARPOS (*it);
3133 ++IT_BYTEPOS (*it);
3135 else
3136 forward_to_next_line_start (it);
3138 /* We must either have reached the end of the buffer or end up
3139 after a newline. */
3140 xassert (IT_CHARPOS (*it) == ZV
3141 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
3143 /* Skip over lines that are invisible because they are indented
3144 more than the value of IT->selective. */
3145 if (it->selective > 0)
3146 while (IT_CHARPOS (*it) < ZV
3147 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
3148 it->selective))
3149 forward_to_next_line_start (it);
3151 /* Position on the newline if we should. */
3152 if (on_newline_p
3153 && IT_CHARPOS (*it) > BEGV
3154 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n')
3156 --IT_CHARPOS (*it);
3157 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
3160 /* Set the iterator there. The 0 as the last parameter of
3161 reseat means don't force a text property lookup. The lookup
3162 is then only done if we've skipped past the iterator's
3163 check_charpos'es. This optimization is important because
3164 text property lookups tend to be expensive. */
3165 reseat (it, it->current.pos, 0);
3168 CHECK_IT (it);
3173 /***********************************************************************
3174 Changing an iterator's position
3175 ***********************************************************************/
3177 /* Change IT's current position to POS in current_buffer. If FORCE_P
3178 is non-zero, always check for text properties at the new position.
3179 Otherwise, text properties are only looked up if POS >=
3180 IT->check_charpos of a property. */
3182 static void
3183 reseat (it, pos, force_p)
3184 struct it *it;
3185 struct text_pos pos;
3186 int force_p;
3188 int original_pos = IT_CHARPOS (*it);
3190 reseat_1 (it, pos, 0);
3192 /* Determine where to check text properties. Avoid doing it
3193 where possible because text property lookup is very expensive. */
3194 if (force_p
3195 || CHARPOS (pos) > it->stop_charpos
3196 || CHARPOS (pos) < original_pos)
3197 handle_stop (it);
3199 CHECK_IT (it);
3203 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
3204 IT->stop_pos to POS, also. */
3206 static void
3207 reseat_1 (it, pos, set_stop_p)
3208 struct it *it;
3209 struct text_pos pos;
3210 int set_stop_p;
3212 /* Don't call this function when scanning a C string. */
3213 xassert (it->s == NULL);
3215 /* POS must be a reasonable value. */
3216 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
3218 it->current.pos = it->position = pos;
3219 XSETBUFFER (it->object, current_buffer);
3220 it->dpvec = NULL;
3221 it->current.dpvec_index = -1;
3222 it->current.overlay_string_index = -1;
3223 IT_STRING_CHARPOS (*it) = -1;
3224 IT_STRING_BYTEPOS (*it) = -1;
3225 it->string = Qnil;
3226 it->method = next_element_from_buffer;
3227 it->sp = 0;
3229 if (set_stop_p)
3230 it->stop_charpos = CHARPOS (pos);
3234 /* Set up IT for displaying a string, starting at CHARPOS in window W.
3235 If S is non-null, it is a C string to iterate over. Otherwise,
3236 STRING gives a Lisp string to iterate over.
3238 If PRECISION > 0, don't return more then PRECISION number of
3239 characters from the string.
3241 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
3242 characters have been returned. FIELD_WIDTH < 0 means an infinite
3243 field width.
3245 MULTIBYTE = 0 means disable processing of multibyte characters,
3246 MULTIBYTE > 0 means enable it,
3247 MULTIBYTE < 0 means use IT->multibyte_p.
3249 IT must be initialized via a prior call to init_iterator before
3250 calling this function. */
3252 static void
3253 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
3254 struct it *it;
3255 unsigned char *s;
3256 Lisp_Object string;
3257 int charpos;
3258 int precision, field_width, multibyte;
3260 /* No region in strings. */
3261 it->region_beg_charpos = it->region_end_charpos = -1;
3263 /* No text property checks performed by default, but see below. */
3264 it->stop_charpos = -1;
3266 /* Set iterator position and end position. */
3267 bzero (&it->current, sizeof it->current);
3268 it->current.overlay_string_index = -1;
3269 it->current.dpvec_index = -1;
3270 xassert (charpos >= 0);
3272 /* Use the setting of MULTIBYTE if specified. */
3273 if (multibyte >= 0)
3274 it->multibyte_p = multibyte > 0;
3276 if (s == NULL)
3278 xassert (STRINGP (string));
3279 it->string = string;
3280 it->s = NULL;
3281 it->end_charpos = it->string_nchars = XSTRING (string)->size;
3282 it->method = next_element_from_string;
3283 it->current.string_pos = string_pos (charpos, string);
3285 else
3287 it->s = s;
3288 it->string = Qnil;
3290 /* Note that we use IT->current.pos, not it->current.string_pos,
3291 for displaying C strings. */
3292 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
3293 if (it->multibyte_p)
3295 it->current.pos = c_string_pos (charpos, s, 1);
3296 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
3298 else
3300 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
3301 it->end_charpos = it->string_nchars = strlen (s);
3304 it->method = next_element_from_c_string;
3307 /* PRECISION > 0 means don't return more than PRECISION characters
3308 from the string. */
3309 if (precision > 0 && it->end_charpos - charpos > precision)
3310 it->end_charpos = it->string_nchars = charpos + precision;
3312 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
3313 characters have been returned. FIELD_WIDTH == 0 means don't pad,
3314 FIELD_WIDTH < 0 means infinite field width. This is useful for
3315 padding with `-' at the end of a mode line. */
3316 if (field_width < 0)
3317 field_width = INFINITY;
3318 if (field_width > it->end_charpos - charpos)
3319 it->end_charpos = charpos + field_width;
3321 /* Use the standard display table for displaying strings. */
3322 if (DISP_TABLE_P (Vstandard_display_table))
3323 it->dp = XCHAR_TABLE (Vstandard_display_table);
3325 it->stop_charpos = charpos;
3326 CHECK_IT (it);
3331 /***********************************************************************
3332 Iteration
3333 ***********************************************************************/
3335 /* Load IT's display element fields with information about the next
3336 display element from the current position of IT. Value is zero if
3337 end of buffer (or C string) is reached. */
3340 get_next_display_element (it)
3341 struct it *it;
3343 /* Non-zero means that we found an display element. Zero means that
3344 we hit the end of what we iterate over. Performance note: the
3345 function pointer `method' used here turns out to be faster than
3346 using a sequence of if-statements. */
3347 int success_p = (*it->method) (it);
3349 if (it->what == IT_CHARACTER)
3351 /* Map via display table or translate control characters.
3352 IT->c, IT->len etc. have been set to the next character by
3353 the function call above. If we have a display table, and it
3354 contains an entry for IT->c, translate it. Don't do this if
3355 IT->c itself comes from a display table, otherwise we could
3356 end up in an infinite recursion. (An alternative could be to
3357 count the recursion depth of this function and signal an
3358 error when a certain maximum depth is reached.) Is it worth
3359 it? */
3360 if (success_p && it->dpvec == NULL)
3362 Lisp_Object dv;
3364 if (it->dp
3365 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
3366 VECTORP (dv)))
3368 struct Lisp_Vector *v = XVECTOR (dv);
3370 /* Return the first character from the display table
3371 entry, if not empty. If empty, don't display the
3372 current character. */
3373 if (v->size)
3375 it->dpvec_char_len = it->len;
3376 it->dpvec = v->contents;
3377 it->dpend = v->contents + v->size;
3378 it->current.dpvec_index = 0;
3379 it->method = next_element_from_display_vector;
3382 success_p = get_next_display_element (it);
3385 /* Translate control characters into `\003' or `^C' form.
3386 Control characters coming from a display table entry are
3387 currently not translated because we use IT->dpvec to hold
3388 the translation. This could easily be changed but I
3389 don't believe that it is worth doing.
3391 Non-printable multibyte characters are also translated
3392 octal form. */
3393 else if ((it->c < ' '
3394 && (it->area != TEXT_AREA
3395 || (it->c != '\n' && it->c != '\t')))
3396 || (it->c >= 127
3397 && it->len == 1)
3398 || !CHAR_PRINTABLE_P (it->c))
3400 /* IT->c is a control character which must be displayed
3401 either as '\003' or as `^C' where the '\\' and '^'
3402 can be defined in the display table. Fill
3403 IT->ctl_chars with glyphs for what we have to
3404 display. Then, set IT->dpvec to these glyphs. */
3405 GLYPH g;
3407 if (it->c < 128 && it->ctl_arrow_p)
3409 /* Set IT->ctl_chars[0] to the glyph for `^'. */
3410 if (it->dp
3411 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
3412 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
3413 g = XINT (DISP_CTRL_GLYPH (it->dp));
3414 else
3415 g = FAST_MAKE_GLYPH ('^', 0);
3416 XSETINT (it->ctl_chars[0], g);
3418 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
3419 XSETINT (it->ctl_chars[1], g);
3421 /* Set up IT->dpvec and return first character from it. */
3422 it->dpvec_char_len = it->len;
3423 it->dpvec = it->ctl_chars;
3424 it->dpend = it->dpvec + 2;
3425 it->current.dpvec_index = 0;
3426 it->method = next_element_from_display_vector;
3427 get_next_display_element (it);
3429 else
3431 unsigned char str[MAX_MULTIBYTE_LENGTH];
3432 int len;
3433 int i;
3434 GLYPH escape_glyph;
3436 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
3437 if (it->dp
3438 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
3439 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
3440 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
3441 else
3442 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
3444 if (SINGLE_BYTE_CHAR_P (it->c))
3445 str[0] = it->c, len = 1;
3446 else
3447 len = CHAR_STRING (it->c, str);
3449 for (i = 0; i < len; i++)
3451 XSETINT (it->ctl_chars[i * 4], escape_glyph);
3452 /* Insert three more glyphs into IT->ctl_chars for
3453 the octal display of the character. */
3454 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
3455 XSETINT (it->ctl_chars[i * 4 + 1], g);
3456 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
3457 XSETINT (it->ctl_chars[i * 4 + 2], g);
3458 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
3459 XSETINT (it->ctl_chars[i * 4 + 3], g);
3462 /* Set up IT->dpvec and return the first character
3463 from it. */
3464 it->dpvec_char_len = it->len;
3465 it->dpvec = it->ctl_chars;
3466 it->dpend = it->dpvec + len * 4;
3467 it->current.dpvec_index = 0;
3468 it->method = next_element_from_display_vector;
3469 get_next_display_element (it);
3474 /* Adjust face id for a multibyte character. There are no
3475 multibyte character in unibyte text. */
3476 if (it->multibyte_p
3477 && success_p
3478 && FRAME_WINDOW_P (it->f))
3480 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3481 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
3485 /* Is this character the last one of a run of characters with
3486 box? If yes, set IT->end_of_box_run_p to 1. */
3487 if (it->face_box_p
3488 && it->s == NULL)
3490 int face_id;
3491 struct face *face;
3493 it->end_of_box_run_p
3494 = ((face_id = face_after_it_pos (it),
3495 face_id != it->face_id)
3496 && (face = FACE_FROM_ID (it->f, face_id),
3497 face->box == FACE_NO_BOX));
3500 /* Value is 0 if end of buffer or string reached. */
3501 return success_p;
3505 /* Move IT to the next display element.
3507 Functions get_next_display_element and set_iterator_to_next are
3508 separate because I find this arrangement easier to handle than a
3509 get_next_display_element function that also increments IT's
3510 position. The way it is we can first look at an iterator's current
3511 display element, decide whether it fits on a line, and if it does,
3512 increment the iterator position. The other way around we probably
3513 would either need a flag indicating whether the iterator has to be
3514 incremented the next time, or we would have to implement a
3515 decrement position function which would not be easy to write. */
3517 void
3518 set_iterator_to_next (it)
3519 struct it *it;
3521 if (it->method == next_element_from_buffer)
3523 /* The current display element of IT is a character from
3524 current_buffer. Advance in the buffer, and maybe skip over
3525 invisible lines that are so because of selective display. */
3526 if (ITERATOR_AT_END_OF_LINE_P (it))
3527 reseat_at_next_visible_line_start (it, 0);
3528 else
3530 xassert (it->len != 0);
3531 IT_BYTEPOS (*it) += it->len;
3532 IT_CHARPOS (*it) += 1;
3533 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
3536 else if (it->method == next_element_from_composition)
3538 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
3539 if (STRINGP (it->string))
3541 IT_STRING_BYTEPOS (*it) += it->len;
3542 IT_STRING_CHARPOS (*it) += it->cmp_len;
3543 it->method = next_element_from_string;
3544 goto consider_string_end;
3546 else
3548 IT_BYTEPOS (*it) += it->len;
3549 IT_CHARPOS (*it) += it->cmp_len;
3550 it->method = next_element_from_buffer;
3553 else if (it->method == next_element_from_c_string)
3555 /* Current display element of IT is from a C string. */
3556 IT_BYTEPOS (*it) += it->len;
3557 IT_CHARPOS (*it) += 1;
3559 else if (it->method == next_element_from_display_vector)
3561 /* Current display element of IT is from a display table entry.
3562 Advance in the display table definition. Reset it to null if
3563 end reached, and continue with characters from buffers/
3564 strings. */
3565 ++it->current.dpvec_index;
3567 /* Restore face of the iterator to what they were before the
3568 display vector entry (these entries may contain faces). */
3569 it->face_id = it->saved_face_id;
3571 if (it->dpvec + it->current.dpvec_index == it->dpend)
3573 if (it->s)
3574 it->method = next_element_from_c_string;
3575 else if (STRINGP (it->string))
3576 it->method = next_element_from_string;
3577 else
3578 it->method = next_element_from_buffer;
3580 it->dpvec = NULL;
3581 it->current.dpvec_index = -1;
3583 /* Skip over characters which were displayed via IT->dpvec. */
3584 if (it->dpvec_char_len < 0)
3585 reseat_at_next_visible_line_start (it, 1);
3586 else if (it->dpvec_char_len > 0)
3588 it->len = it->dpvec_char_len;
3589 set_iterator_to_next (it);
3593 else if (it->method == next_element_from_string)
3595 /* Current display element is a character from a Lisp string. */
3596 xassert (it->s == NULL && STRINGP (it->string));
3597 IT_STRING_BYTEPOS (*it) += it->len;
3598 IT_STRING_CHARPOS (*it) += 1;
3600 consider_string_end:
3602 if (it->current.overlay_string_index >= 0)
3604 /* IT->string is an overlay string. Advance to the
3605 next, if there is one. */
3606 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
3607 next_overlay_string (it);
3609 else
3611 /* IT->string is not an overlay string. If we reached
3612 its end, and there is something on IT->stack, proceed
3613 with what is on the stack. This can be either another
3614 string, this time an overlay string, or a buffer. */
3615 if (IT_STRING_CHARPOS (*it) == XSTRING (it->string)->size
3616 && it->sp > 0)
3618 pop_it (it);
3619 if (!STRINGP (it->string))
3620 it->method = next_element_from_buffer;
3624 else if (it->method == next_element_from_image
3625 || it->method == next_element_from_stretch)
3627 /* The position etc with which we have to proceed are on
3628 the stack. The position may be at the end of a string,
3629 if the `display' property takes up the whole string. */
3630 pop_it (it);
3631 it->image_id = 0;
3632 if (STRINGP (it->string))
3634 it->method = next_element_from_string;
3635 goto consider_string_end;
3637 else
3638 it->method = next_element_from_buffer;
3640 else
3641 /* There are no other methods defined, so this should be a bug. */
3642 abort ();
3644 /* Reset flags indicating start and end of a sequence of
3645 characters with box. */
3646 it->start_of_box_run_p = it->end_of_box_run_p = 0;
3648 xassert (it->method != next_element_from_string
3649 || (STRINGP (it->string)
3650 && IT_STRING_CHARPOS (*it) >= 0));
3654 /* Load IT's display element fields with information about the next
3655 display element which comes from a display table entry or from the
3656 result of translating a control character to one of the forms `^C'
3657 or `\003'. IT->dpvec holds the glyphs to return as characters. */
3659 static int
3660 next_element_from_display_vector (it)
3661 struct it *it;
3663 /* Precondition. */
3664 xassert (it->dpvec && it->current.dpvec_index >= 0);
3666 /* Remember the current face id in case glyphs specify faces.
3667 IT's face is restored in set_iterator_to_next. */
3668 it->saved_face_id = it->face_id;
3670 if (INTEGERP (*it->dpvec)
3671 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
3673 int lface_id;
3674 GLYPH g;
3676 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
3677 it->c = FAST_GLYPH_CHAR (g);
3678 it->len = CHAR_BYTES (it->c);
3680 /* The entry may contain a face id to use. Such a face id is
3681 the id of a Lisp face, not a realized face. A face id of
3682 zero means no face. */
3683 lface_id = FAST_GLYPH_FACE (g);
3684 if (lface_id)
3686 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
3687 if (face_id >= 0)
3689 it->face_id = face_id;
3693 else
3694 /* Display table entry is invalid. Return a space. */
3695 it->c = ' ', it->len = 1;
3697 /* Don't change position and object of the iterator here. They are
3698 still the values of the character that had this display table
3699 entry or was translated, and that's what we want. */
3700 it->what = IT_CHARACTER;
3701 return 1;
3705 /* Load IT with the next display element from Lisp string IT->string.
3706 IT->current.string_pos is the current position within the string.
3707 If IT->current.overlay_string_index >= 0, the Lisp string is an
3708 overlay string. */
3710 static int
3711 next_element_from_string (it)
3712 struct it *it;
3714 struct text_pos position;
3716 xassert (STRINGP (it->string));
3717 xassert (IT_STRING_CHARPOS (*it) >= 0);
3718 position = it->current.string_pos;
3720 /* Time to check for invisible text? */
3721 if (IT_STRING_CHARPOS (*it) < it->end_charpos
3722 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
3724 handle_stop (it);
3726 /* Since a handler may have changed IT->method, we must
3727 recurse here. */
3728 return get_next_display_element (it);
3731 if (it->current.overlay_string_index >= 0)
3733 /* Get the next character from an overlay string. In overlay
3734 strings, There is no field width or padding with spaces to
3735 do. */
3736 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
3738 it->what = IT_EOB;
3739 return 0;
3741 else if (STRING_MULTIBYTE (it->string))
3743 int remaining = (STRING_BYTES (XSTRING (it->string))
3744 - IT_STRING_BYTEPOS (*it));
3745 unsigned char *s = (XSTRING (it->string)->data
3746 + IT_STRING_BYTEPOS (*it));
3747 it->c = string_char_and_length (s, remaining, &it->len);
3749 else
3751 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
3752 it->len = 1;
3755 else
3757 /* Get the next character from a Lisp string that is not an
3758 overlay string. Such strings come from the mode line, for
3759 example. We may have to pad with spaces, or truncate the
3760 string. See also next_element_from_c_string. */
3761 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
3763 it->what = IT_EOB;
3764 return 0;
3766 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
3768 /* Pad with spaces. */
3769 it->c = ' ', it->len = 1;
3770 CHARPOS (position) = BYTEPOS (position) = -1;
3772 else if (STRING_MULTIBYTE (it->string))
3774 int maxlen = (STRING_BYTES (XSTRING (it->string))
3775 - IT_STRING_BYTEPOS (*it));
3776 unsigned char *s = (XSTRING (it->string)->data
3777 + IT_STRING_BYTEPOS (*it));
3778 it->c = string_char_and_length (s, maxlen, &it->len);
3780 else
3782 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
3783 it->len = 1;
3787 /* Record what we have and where it came from. Note that we store a
3788 buffer position in IT->position although it could arguably be a
3789 string position. */
3790 it->what = IT_CHARACTER;
3791 it->object = it->string;
3792 it->position = position;
3793 return 1;
3797 /* Load IT with next display element from C string IT->s.
3798 IT->string_nchars is the maximum number of characters to return
3799 from the string. IT->end_charpos may be greater than
3800 IT->string_nchars when this function is called, in which case we
3801 may have to return padding spaces. Value is zero if end of string
3802 reached, including padding spaces. */
3804 static int
3805 next_element_from_c_string (it)
3806 struct it *it;
3808 int success_p = 1;
3810 xassert (it->s);
3811 it->what = IT_CHARACTER;
3812 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
3813 it->object = Qnil;
3815 /* IT's position can be greater IT->string_nchars in case a field
3816 width or precision has been specified when the iterator was
3817 initialized. */
3818 if (IT_CHARPOS (*it) >= it->end_charpos)
3820 /* End of the game. */
3821 it->what = IT_EOB;
3822 success_p = 0;
3824 else if (IT_CHARPOS (*it) >= it->string_nchars)
3826 /* Pad with spaces. */
3827 it->c = ' ', it->len = 1;
3828 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
3830 else if (it->multibyte_p)
3832 /* Implementation note: The calls to strlen apparently aren't a
3833 performance problem because there is no noticeable performance
3834 difference between Emacs running in unibyte or multibyte mode. */
3835 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
3836 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
3837 maxlen, &it->len);
3839 else
3840 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
3842 return success_p;
3846 /* Set up IT to return characters from an ellipsis, if appropriate.
3847 The definition of the ellipsis glyphs may come from a display table
3848 entry. This function Fills IT with the first glyph from the
3849 ellipsis if an ellipsis is to be displayed. */
3851 static int
3852 next_element_from_ellipsis (it)
3853 struct it *it;
3855 if (it->selective_display_ellipsis_p)
3857 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3859 /* Use the display table definition for `...'. Invalid glyphs
3860 will be handled by the method returning elements from dpvec. */
3861 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3862 it->dpvec_char_len = it->len;
3863 it->dpvec = v->contents;
3864 it->dpend = v->contents + v->size;
3865 it->current.dpvec_index = 0;
3866 it->method = next_element_from_display_vector;
3868 else
3870 /* Use default `...' which is stored in default_invis_vector. */
3871 it->dpvec_char_len = it->len;
3872 it->dpvec = default_invis_vector;
3873 it->dpend = default_invis_vector + 3;
3874 it->current.dpvec_index = 0;
3875 it->method = next_element_from_display_vector;
3878 else
3879 reseat_at_next_visible_line_start (it, 1);
3881 return get_next_display_element (it);
3885 /* Deliver an image display element. The iterator IT is already
3886 filled with image information (done in handle_display_prop). Value
3887 is always 1. */
3890 static int
3891 next_element_from_image (it)
3892 struct it *it;
3894 it->what = IT_IMAGE;
3895 return 1;
3899 /* Fill iterator IT with next display element from a stretch glyph
3900 property. IT->object is the value of the text property. Value is
3901 always 1. */
3903 static int
3904 next_element_from_stretch (it)
3905 struct it *it;
3907 it->what = IT_STRETCH;
3908 return 1;
3912 /* Load IT with the next display element from current_buffer. Value
3913 is zero if end of buffer reached. IT->stop_charpos is the next
3914 position at which to stop and check for text properties or buffer
3915 end. */
3917 static int
3918 next_element_from_buffer (it)
3919 struct it *it;
3921 int success_p = 1;
3923 /* Check this assumption, otherwise, we would never enter the
3924 if-statement, below. */
3925 xassert (IT_CHARPOS (*it) >= BEGV
3926 && IT_CHARPOS (*it) <= it->stop_charpos);
3928 if (IT_CHARPOS (*it) >= it->stop_charpos)
3930 if (IT_CHARPOS (*it) >= it->end_charpos)
3932 int overlay_strings_follow_p;
3934 /* End of the game, except when overlay strings follow that
3935 haven't been returned yet. */
3936 if (it->overlay_strings_at_end_processed_p)
3937 overlay_strings_follow_p = 0;
3938 else
3940 it->overlay_strings_at_end_processed_p = 1;
3941 overlay_strings_follow_p = get_overlay_strings (it);
3944 if (overlay_strings_follow_p)
3945 success_p = get_next_display_element (it);
3946 else
3948 it->what = IT_EOB;
3949 it->position = it->current.pos;
3950 success_p = 0;
3953 else
3955 handle_stop (it);
3956 return get_next_display_element (it);
3959 else
3961 /* No face changes, overlays etc. in sight, so just return a
3962 character from current_buffer. */
3963 unsigned char *p;
3965 /* Maybe run the redisplay end trigger hook. Performance note:
3966 This doesn't seem to cost measurable time. */
3967 if (it->redisplay_end_trigger_charpos
3968 && it->glyph_row
3969 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
3970 run_redisplay_end_trigger_hook (it);
3972 /* Get the next character, maybe multibyte. */
3973 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
3974 if (it->multibyte_p && !ASCII_BYTE_P (*p))
3976 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
3977 - IT_BYTEPOS (*it));
3978 it->c = string_char_and_length (p, maxlen, &it->len);
3980 else
3981 it->c = *p, it->len = 1;
3983 /* Record what we have and where it came from. */
3984 it->what = IT_CHARACTER;;
3985 it->object = it->w->buffer;
3986 it->position = it->current.pos;
3988 /* Normally we return the character found above, except when we
3989 really want to return an ellipsis for selective display. */
3990 if (it->selective)
3992 if (it->c == '\n')
3994 /* A value of selective > 0 means hide lines indented more
3995 than that number of columns. */
3996 if (it->selective > 0
3997 && IT_CHARPOS (*it) + 1 < ZV
3998 && indented_beyond_p (IT_CHARPOS (*it) + 1,
3999 IT_BYTEPOS (*it) + 1,
4000 it->selective))
4002 success_p = next_element_from_ellipsis (it);
4003 it->dpvec_char_len = -1;
4006 else if (it->c == '\r' && it->selective == -1)
4008 /* A value of selective == -1 means that everything from the
4009 CR to the end of the line is invisible, with maybe an
4010 ellipsis displayed for it. */
4011 success_p = next_element_from_ellipsis (it);
4012 it->dpvec_char_len = -1;
4017 /* Value is zero if end of buffer reached. */
4018 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
4019 return success_p;
4023 /* Run the redisplay end trigger hook for IT. */
4025 static void
4026 run_redisplay_end_trigger_hook (it)
4027 struct it *it;
4029 Lisp_Object args[3];
4031 /* IT->glyph_row should be non-null, i.e. we should be actually
4032 displaying something, or otherwise we should not run the hook. */
4033 xassert (it->glyph_row);
4035 /* Set up hook arguments. */
4036 args[0] = Qredisplay_end_trigger_functions;
4037 args[1] = it->window;
4038 XSETINT (args[2], it->redisplay_end_trigger_charpos);
4039 it->redisplay_end_trigger_charpos = 0;
4041 /* Since we are *trying* to run these functions, don't try to run
4042 them again, even if they get an error. */
4043 it->w->redisplay_end_trigger = Qnil;
4044 Frun_hook_with_args (3, args);
4046 /* Notice if it changed the face of the character we are on. */
4047 handle_face_prop (it);
4051 /* Deliver a composition display element. The iterator IT is already
4052 filled with composition information (done in
4053 handle_composition_prop). Value is always 1. */
4055 static int
4056 next_element_from_composition (it)
4057 struct it *it;
4059 it->what = IT_COMPOSITION;
4060 it->position = (STRINGP (it->string)
4061 ? it->current.string_pos
4062 : it->current.pos);
4063 return 1;
4068 /***********************************************************************
4069 Moving an iterator without producing glyphs
4070 ***********************************************************************/
4072 /* Move iterator IT to a specified buffer or X position within one
4073 line on the display without producing glyphs.
4075 Begin to skip at IT's current position. Skip to TO_CHARPOS or TO_X
4076 whichever is reached first.
4078 TO_CHARPOS <= 0 means no TO_CHARPOS is specified.
4080 TO_X < 0 means that no TO_X is specified. TO_X is normally a value
4081 0 <= TO_X <= IT->last_visible_x. This means in particular, that
4082 TO_X includes the amount by which a window is horizontally
4083 scrolled.
4085 Value is
4087 MOVE_POS_MATCH_OR_ZV
4088 - when TO_POS or ZV was reached.
4090 MOVE_X_REACHED
4091 -when TO_X was reached before TO_POS or ZV were reached.
4093 MOVE_LINE_CONTINUED
4094 - when we reached the end of the display area and the line must
4095 be continued.
4097 MOVE_LINE_TRUNCATED
4098 - when we reached the end of the display area and the line is
4099 truncated.
4101 MOVE_NEWLINE_OR_CR
4102 - when we stopped at a line end, i.e. a newline or a CR and selective
4103 display is on. */
4105 static enum move_it_result
4106 move_it_in_display_line_to (it, to_charpos, to_x, op)
4107 struct it *it;
4108 int to_charpos, to_x, op;
4110 enum move_it_result result = MOVE_UNDEFINED;
4111 struct glyph_row *saved_glyph_row;
4113 /* Don't produce glyphs in produce_glyphs. */
4114 saved_glyph_row = it->glyph_row;
4115 it->glyph_row = NULL;
4117 while (1)
4119 int x, i;
4121 /* Stop when ZV or TO_CHARPOS reached. */
4122 if (!get_next_display_element (it)
4123 || ((op & MOVE_TO_POS) != 0
4124 && BUFFERP (it->object)
4125 && IT_CHARPOS (*it) >= to_charpos))
4127 result = MOVE_POS_MATCH_OR_ZV;
4128 break;
4131 /* The call to produce_glyphs will get the metrics of the
4132 display element IT is loaded with. We record in x the
4133 x-position before this display element in case it does not
4134 fit on the line. */
4135 x = it->current_x;
4136 PRODUCE_GLYPHS (it);
4138 if (it->area != TEXT_AREA)
4140 set_iterator_to_next (it);
4141 continue;
4144 /* The number of glyphs we get back in IT->nglyphs will normally
4145 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
4146 character on a terminal frame, or (iii) a line end. For the
4147 second case, IT->nglyphs - 1 padding glyphs will be present
4148 (on X frames, there is only one glyph produced for a
4149 composite character.
4151 The behavior implemented below means, for continuation lines,
4152 that as many spaces of a TAB as fit on the current line are
4153 displayed there. For terminal frames, as many glyphs of a
4154 multi-glyph character are displayed in the current line, too.
4155 This is what the old redisplay code did, and we keep it that
4156 way. Under X, the whole shape of a complex character must
4157 fit on the line or it will be completely displayed in the
4158 next line.
4160 Note that both for tabs and padding glyphs, all glyphs have
4161 the same width. */
4162 if (it->nglyphs)
4164 /* More than one glyph or glyph doesn't fit on line. All
4165 glyphs have the same width. */
4166 int single_glyph_width = it->pixel_width / it->nglyphs;
4167 int new_x;
4169 for (i = 0; i < it->nglyphs; ++i, x = new_x)
4171 new_x = x + single_glyph_width;
4173 /* We want to leave anything reaching TO_X to the caller. */
4174 if ((op & MOVE_TO_X) && new_x > to_x)
4176 it->current_x = x;
4177 result = MOVE_X_REACHED;
4178 break;
4180 else if (/* Lines are continued. */
4181 !it->truncate_lines_p
4182 && (/* And glyph doesn't fit on the line. */
4183 new_x > it->last_visible_x
4184 /* Or it fits exactly and we're on a window
4185 system frame. */
4186 || (new_x == it->last_visible_x
4187 && FRAME_WINDOW_P (it->f))))
4189 if (/* IT->hpos == 0 means the very first glyph
4190 doesn't fit on the line, e.g. a wide image. */
4191 it->hpos == 0
4192 || (new_x == it->last_visible_x
4193 && FRAME_WINDOW_P (it->f)))
4195 ++it->hpos;
4196 it->current_x = new_x;
4197 if (i == it->nglyphs - 1)
4198 set_iterator_to_next (it);
4200 else
4201 it->current_x = x;
4203 result = MOVE_LINE_CONTINUED;
4204 break;
4206 else if (new_x > it->first_visible_x)
4208 /* Glyph is visible. Increment number of glyphs that
4209 would be displayed. */
4210 ++it->hpos;
4212 else
4214 /* Glyph is completely off the left margin of the display
4215 area. Nothing to do. */
4219 if (result != MOVE_UNDEFINED)
4220 break;
4222 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
4224 /* Stop when TO_X specified and reached. This check is
4225 necessary here because of lines consisting of a line end,
4226 only. The line end will not produce any glyphs and we
4227 would never get MOVE_X_REACHED. */
4228 xassert (it->nglyphs == 0);
4229 result = MOVE_X_REACHED;
4230 break;
4233 /* Is this a line end? If yes, we're done. */
4234 if (ITERATOR_AT_END_OF_LINE_P (it))
4236 result = MOVE_NEWLINE_OR_CR;
4237 break;
4240 /* The current display element has been consumed. Advance
4241 to the next. */
4242 set_iterator_to_next (it);
4244 /* Stop if lines are truncated and IT's current x-position is
4245 past the right edge of the window now. */
4246 if (it->truncate_lines_p
4247 && it->current_x >= it->last_visible_x)
4249 result = MOVE_LINE_TRUNCATED;
4250 break;
4254 /* Restore the iterator settings altered at the beginning of this
4255 function. */
4256 it->glyph_row = saved_glyph_row;
4257 return result;
4261 /* Move IT forward to a specified buffer position TO_CHARPOS, TO_X,
4262 TO_Y, TO_VPOS. OP is a bit-mask that specifies where to stop. See
4263 the description of enum move_operation_enum.
4265 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
4266 screen line, this function will set IT to the next position >
4267 TO_CHARPOS. */
4269 void
4270 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
4271 struct it *it;
4272 int to_charpos, to_x, to_y, to_vpos;
4273 int op;
4275 enum move_it_result skip, skip2 = MOVE_X_REACHED;
4276 int line_height;
4278 while (1)
4280 if (op & MOVE_TO_VPOS)
4282 /* If no TO_CHARPOS and no TO_X specified, stop at the
4283 start of the line TO_VPOS. */
4284 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
4286 if (it->vpos == to_vpos)
4287 break;
4288 skip = move_it_in_display_line_to (it, -1, -1, 0);
4290 else
4292 /* TO_VPOS >= 0 means stop at TO_X in the line at
4293 TO_VPOS, or at TO_POS, whichever comes first. */
4294 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
4296 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
4297 break;
4298 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
4300 /* We have reached TO_X but not in the line we want. */
4301 skip = move_it_in_display_line_to (it, to_charpos,
4302 -1, MOVE_TO_POS);
4303 if (skip == MOVE_POS_MATCH_OR_ZV)
4304 break;
4308 else if (op & MOVE_TO_Y)
4310 struct it it_backup;
4311 int done_p;
4313 /* TO_Y specified means stop at TO_X in the line containing
4314 TO_Y---or at TO_CHARPOS if this is reached first. The
4315 problem is that we can't really tell whether the line
4316 contains TO_Y before we have completely scanned it, and
4317 this may skip past TO_X. What we do is to first scan to
4318 TO_X.
4320 If TO_X is not specified, use a TO_X of zero. The reason
4321 is to make the outcome of this function more predictable.
4322 If we didn't use TO_X == 0, we would stop at the end of
4323 the line which is probably not what a caller would expect
4324 to happen. */
4325 skip = move_it_in_display_line_to (it, to_charpos,
4326 ((op & MOVE_TO_X)
4327 ? to_x : 0),
4328 (MOVE_TO_X
4329 | (op & MOVE_TO_POS)));
4331 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
4332 if (skip == MOVE_POS_MATCH_OR_ZV)
4333 break;
4335 /* If TO_X was reached, we would like to know whether TO_Y
4336 is in the line. This can only be said if we know the
4337 total line height which requires us to scan the rest of
4338 the line. */
4339 done_p = 0;
4340 if (skip == MOVE_X_REACHED)
4342 it_backup = *it;
4343 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
4344 op & MOVE_TO_POS);
4347 /* Now, decide whether TO_Y is in this line. */
4348 line_height = it->max_ascent + it->max_descent;
4350 if (to_y >= it->current_y
4351 && to_y < it->current_y + line_height)
4353 if (skip == MOVE_X_REACHED)
4354 /* If TO_Y is in this line and TO_X was reached above,
4355 we scanned too far. We have to restore IT's settings
4356 to the ones before skipping. */
4357 *it = it_backup;
4358 done_p = 1;
4360 else if (skip == MOVE_X_REACHED)
4362 skip = skip2;
4363 if (skip == MOVE_POS_MATCH_OR_ZV)
4364 done_p = 1;
4367 if (done_p)
4368 break;
4370 else
4371 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
4373 switch (skip)
4375 case MOVE_POS_MATCH_OR_ZV:
4376 return;
4378 case MOVE_NEWLINE_OR_CR:
4379 set_iterator_to_next (it);
4380 it->continuation_lines_width = 0;
4381 break;
4383 case MOVE_LINE_TRUNCATED:
4384 it->continuation_lines_width = 0;
4385 reseat_at_next_visible_line_start (it, 0);
4386 if ((op & MOVE_TO_POS) != 0
4387 && IT_CHARPOS (*it) > to_charpos)
4388 goto out;
4389 break;
4391 case MOVE_LINE_CONTINUED:
4392 it->continuation_lines_width += it->current_x;
4393 break;
4395 default:
4396 abort ();
4399 /* Reset/increment for the next run. */
4400 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
4401 it->current_x = it->hpos = 0;
4402 it->current_y += it->max_ascent + it->max_descent;
4403 ++it->vpos;
4404 last_height = it->max_ascent + it->max_descent;
4405 last_max_ascent = it->max_ascent;
4406 it->max_ascent = it->max_descent = 0;
4408 out:;
4412 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
4414 If DY > 0, move IT backward at least that many pixels. DY = 0
4415 means move IT backward to the preceding line start or BEGV. This
4416 function may move over more than DY pixels if IT->current_y - DY
4417 ends up in the middle of a line; in this case IT->current_y will be
4418 set to the top of the line moved to. */
4420 void
4421 move_it_vertically_backward (it, dy)
4422 struct it *it;
4423 int dy;
4425 int nlines, h, line_height;
4426 struct it it2;
4427 int start_pos = IT_CHARPOS (*it);
4429 xassert (dy >= 0);
4431 /* Estimate how many newlines we must move back. */
4432 nlines = max (1, dy / CANON_Y_UNIT (it->f));
4434 /* Set the iterator's position that many lines back. */
4435 while (nlines-- && IT_CHARPOS (*it) > BEGV)
4436 back_to_previous_visible_line_start (it);
4438 /* Reseat the iterator here. When moving backward, we don't want
4439 reseat to skip forward over invisible text, set up the iterator
4440 to deliver from overlay strings at the new position etc. So,
4441 use reseat_1 here. */
4442 reseat_1 (it, it->current.pos, 1);
4444 /* We are now surely at a line start. */
4445 it->current_x = it->hpos = 0;
4447 /* Move forward and see what y-distance we moved. First move to the
4448 start of the next line so that we get its height. We need this
4449 height to be able to tell whether we reached the specified
4450 y-distance. */
4451 it2 = *it;
4452 it2.max_ascent = it2.max_descent = 0;
4453 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
4454 MOVE_TO_POS | MOVE_TO_VPOS);
4455 xassert (IT_CHARPOS (*it) >= BEGV);
4456 line_height = it2.max_ascent + it2.max_descent;
4457 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
4458 xassert (IT_CHARPOS (*it) >= BEGV);
4459 h = it2.current_y - it->current_y;
4460 nlines = it2.vpos - it->vpos;
4462 /* Correct IT's y and vpos position. */
4463 it->vpos -= nlines;
4464 it->current_y -= h;
4466 if (dy == 0)
4468 /* DY == 0 means move to the start of the screen line. The
4469 value of nlines is > 0 if continuation lines were involved. */
4470 if (nlines > 0)
4471 move_it_by_lines (it, nlines, 1);
4472 xassert (IT_CHARPOS (*it) <= start_pos);
4474 else if (nlines)
4476 /* The y-position we try to reach. Note that h has been
4477 subtracted in front of the if-statement. */
4478 int target_y = it->current_y + h - dy;
4480 /* If we did not reach target_y, try to move further backward if
4481 we can. If we moved too far backward, try to move forward. */
4482 if (target_y < it->current_y
4483 && IT_CHARPOS (*it) > BEGV)
4485 move_it_vertically (it, target_y - it->current_y);
4486 xassert (IT_CHARPOS (*it) >= BEGV);
4488 else if (target_y >= it->current_y + line_height
4489 && IT_CHARPOS (*it) < ZV)
4491 move_it_vertically (it, target_y - (it->current_y + line_height));
4492 xassert (IT_CHARPOS (*it) >= BEGV);
4498 /* Move IT by a specified amount of pixel lines DY. DY negative means
4499 move backwards. DY = 0 means move to start of screen line. At the
4500 end, IT will be on the start of a screen line. */
4502 void
4503 move_it_vertically (it, dy)
4504 struct it *it;
4505 int dy;
4507 if (dy <= 0)
4508 move_it_vertically_backward (it, -dy);
4509 else if (dy > 0)
4511 move_it_to (it, ZV, -1, it->current_y + dy, -1,
4512 MOVE_TO_POS | MOVE_TO_Y);
4514 /* If buffer ends in ZV without a newline, move to the start of
4515 the line to satisfy the post-condition. */
4516 if (IT_CHARPOS (*it) == ZV
4517 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
4518 move_it_by_lines (it, 0, 0);
4523 /* Return non-zero if some text between buffer positions START_CHARPOS
4524 and END_CHARPOS is invisible. IT->window is the window for text
4525 property lookup. */
4527 static int
4528 invisible_text_between_p (it, start_charpos, end_charpos)
4529 struct it *it;
4530 int start_charpos, end_charpos;
4532 Lisp_Object prop, limit;
4533 int invisible_found_p;
4535 xassert (it != NULL && start_charpos <= end_charpos);
4537 /* Is text at START invisible? */
4538 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
4539 it->window);
4540 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4541 invisible_found_p = 1;
4542 else
4544 limit = next_single_char_property_change (make_number (start_charpos),
4545 Qinvisible, Qnil,
4546 make_number (end_charpos));
4547 invisible_found_p = XFASTINT (limit) < end_charpos;
4550 return invisible_found_p;
4554 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
4555 negative means move up. DVPOS == 0 means move to the start of the
4556 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
4557 NEED_Y_P is zero, IT->current_y will be left unchanged.
4559 Further optimization ideas: If we would know that IT->f doesn't use
4560 a face with proportional font, we could be faster for
4561 truncate-lines nil. */
4563 void
4564 move_it_by_lines (it, dvpos, need_y_p)
4565 struct it *it;
4566 int dvpos, need_y_p;
4568 struct position pos;
4570 if (!FRAME_WINDOW_P (it->f))
4572 struct text_pos textpos;
4574 /* We can use vmotion on frames without proportional fonts. */
4575 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
4576 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
4577 reseat (it, textpos, 1);
4578 it->vpos += pos.vpos;
4579 it->current_y += pos.vpos;
4581 else if (dvpos == 0)
4583 /* DVPOS == 0 means move to the start of the screen line. */
4584 move_it_vertically_backward (it, 0);
4585 xassert (it->current_x == 0 && it->hpos == 0);
4587 else if (dvpos > 0)
4589 /* If there are no continuation lines, and if there is no
4590 selective display, try the simple method of moving forward
4591 DVPOS newlines, then see where we are. */
4592 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
4594 int shortage = 0, charpos;
4596 if (FETCH_BYTE (IT_BYTEPOS (*it) == '\n'))
4597 charpos = IT_CHARPOS (*it) + 1;
4598 else
4599 charpos = scan_buffer ('\n', IT_CHARPOS (*it), 0, dvpos,
4600 &shortage, 0);
4602 if (!invisible_text_between_p (it, IT_CHARPOS (*it), charpos))
4604 struct text_pos pos;
4605 CHARPOS (pos) = charpos;
4606 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
4607 reseat (it, pos, 1);
4608 it->vpos += dvpos - shortage;
4609 it->hpos = it->current_x = 0;
4610 return;
4614 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
4616 else
4618 struct it it2;
4619 int start_charpos, i;
4621 /* If there are no continuation lines, and if there is no
4622 selective display, try the simple method of moving backward
4623 -DVPOS newlines. */
4624 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
4626 int shortage;
4627 int charpos = IT_CHARPOS (*it);
4628 int bytepos = IT_BYTEPOS (*it);
4630 /* If in the middle of a line, go to its start. */
4631 if (charpos > BEGV && FETCH_BYTE (bytepos - 1) != '\n')
4633 charpos = find_next_newline_no_quit (charpos, -1);
4634 bytepos = CHAR_TO_BYTE (charpos);
4637 if (charpos == BEGV)
4639 struct text_pos pos;
4640 CHARPOS (pos) = charpos;
4641 BYTEPOS (pos) = bytepos;
4642 reseat (it, pos, 1);
4643 it->hpos = it->current_x = 0;
4644 return;
4646 else
4648 charpos = scan_buffer ('\n', charpos - 1, 0, dvpos, &shortage, 0);
4649 if (!invisible_text_between_p (it, charpos, IT_CHARPOS (*it)))
4651 struct text_pos pos;
4652 CHARPOS (pos) = charpos;
4653 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
4654 reseat (it, pos, 1);
4655 it->vpos += dvpos + (shortage ? shortage - 1 : 0);
4656 it->hpos = it->current_x = 0;
4657 return;
4662 /* Go back -DVPOS visible lines and reseat the iterator there. */
4663 start_charpos = IT_CHARPOS (*it);
4664 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
4665 back_to_previous_visible_line_start (it);
4666 reseat (it, it->current.pos, 1);
4667 it->current_x = it->hpos = 0;
4669 /* Above call may have moved too far if continuation lines
4670 are involved. Scan forward and see if it did. */
4671 it2 = *it;
4672 it2.vpos = it2.current_y = 0;
4673 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
4674 it->vpos -= it2.vpos;
4675 it->current_y -= it2.current_y;
4676 it->current_x = it->hpos = 0;
4678 /* If we moved too far, move IT some lines forward. */
4679 if (it2.vpos > -dvpos)
4681 int delta = it2.vpos + dvpos;
4682 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
4689 /***********************************************************************
4690 Messages
4691 ***********************************************************************/
4694 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
4695 to *Messages*. */
4697 void
4698 add_to_log (format, arg1, arg2)
4699 char *format;
4700 Lisp_Object arg1, arg2;
4702 Lisp_Object args[3];
4703 Lisp_Object msg, fmt;
4704 char *buffer;
4705 int len;
4706 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4708 fmt = msg = Qnil;
4709 GCPRO4 (fmt, msg, arg1, arg2);
4711 args[0] = fmt = build_string (format);
4712 args[1] = arg1;
4713 args[2] = arg2;
4714 msg = Fformat (3, args);
4716 len = STRING_BYTES (XSTRING (msg)) + 1;
4717 buffer = (char *) alloca (len);
4718 strcpy (buffer, XSTRING (msg)->data);
4720 message_dolog (buffer, len - 1, 1, 0);
4721 UNGCPRO;
4725 /* Output a newline in the *Messages* buffer if "needs" one. */
4727 void
4728 message_log_maybe_newline ()
4730 if (message_log_need_newline)
4731 message_dolog ("", 0, 1, 0);
4735 /* Add a string M of length LEN to the message log, optionally
4736 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
4737 nonzero, means interpret the contents of M as multibyte. This
4738 function calls low-level routines in order to bypass text property
4739 hooks, etc. which might not be safe to run. */
4741 void
4742 message_dolog (m, len, nlflag, multibyte)
4743 char *m;
4744 int len, nlflag, multibyte;
4746 if (!NILP (Vmessage_log_max))
4748 struct buffer *oldbuf;
4749 Lisp_Object oldpoint, oldbegv, oldzv;
4750 int old_windows_or_buffers_changed = windows_or_buffers_changed;
4751 int point_at_end = 0;
4752 int zv_at_end = 0;
4753 Lisp_Object old_deactivate_mark, tem;
4754 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4756 old_deactivate_mark = Vdeactivate_mark;
4757 oldbuf = current_buffer;
4758 Fset_buffer (Fget_buffer_create (build_string ("*Messages*")));
4759 current_buffer->undo_list = Qt;
4761 oldpoint = Fpoint_marker ();
4762 oldbegv = Fpoint_min_marker ();
4763 oldzv = Fpoint_max_marker ();
4764 GCPRO4 (oldpoint, oldbegv, oldzv, old_deactivate_mark);
4766 if (PT == Z)
4767 point_at_end = 1;
4768 if (ZV == Z)
4769 zv_at_end = 1;
4771 BEGV = BEG;
4772 BEGV_BYTE = BEG_BYTE;
4773 ZV = Z;
4774 ZV_BYTE = Z_BYTE;
4775 TEMP_SET_PT_BOTH (Z, Z_BYTE);
4777 /* Insert the string--maybe converting multibyte to single byte
4778 or vice versa, so that all the text fits the buffer. */
4779 if (multibyte
4780 && NILP (current_buffer->enable_multibyte_characters))
4782 int i, c, nbytes;
4783 unsigned char work[1];
4785 /* Convert a multibyte string to single-byte
4786 for the *Message* buffer. */
4787 for (i = 0; i < len; i += nbytes)
4789 c = string_char_and_length (m + i, len - i, &nbytes);
4790 work[0] = (SINGLE_BYTE_CHAR_P (c)
4792 : multibyte_char_to_unibyte (c, Qnil));
4793 insert_1_both (work, 1, 1, 1, 0, 0);
4796 else if (! multibyte
4797 && ! NILP (current_buffer->enable_multibyte_characters))
4799 int i, c, nbytes;
4800 unsigned char *msg = (unsigned char *) m;
4801 unsigned char str[MAX_MULTIBYTE_LENGTH];
4802 /* Convert a single-byte string to multibyte
4803 for the *Message* buffer. */
4804 for (i = 0; i < len; i++)
4806 c = unibyte_char_to_multibyte (msg[i]);
4807 nbytes = CHAR_STRING (c, str);
4808 insert_1_both (str, 1, nbytes, 1, 0, 0);
4811 else if (len)
4812 insert_1 (m, len, 1, 0, 0);
4814 if (nlflag)
4816 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
4817 insert_1 ("\n", 1, 1, 0, 0);
4819 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
4820 this_bol = PT;
4821 this_bol_byte = PT_BYTE;
4823 if (this_bol > BEG)
4825 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
4826 prev_bol = PT;
4827 prev_bol_byte = PT_BYTE;
4829 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
4830 this_bol, this_bol_byte);
4831 if (dup)
4833 del_range_both (prev_bol, prev_bol_byte,
4834 this_bol, this_bol_byte, 0);
4835 if (dup > 1)
4837 char dupstr[40];
4838 int duplen;
4840 /* If you change this format, don't forget to also
4841 change message_log_check_duplicate. */
4842 sprintf (dupstr, " [%d times]", dup);
4843 duplen = strlen (dupstr);
4844 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
4845 insert_1 (dupstr, duplen, 1, 0, 1);
4850 if (NATNUMP (Vmessage_log_max))
4852 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
4853 -XFASTINT (Vmessage_log_max) - 1, 0);
4854 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
4857 BEGV = XMARKER (oldbegv)->charpos;
4858 BEGV_BYTE = marker_byte_position (oldbegv);
4860 if (zv_at_end)
4862 ZV = Z;
4863 ZV_BYTE = Z_BYTE;
4865 else
4867 ZV = XMARKER (oldzv)->charpos;
4868 ZV_BYTE = marker_byte_position (oldzv);
4871 if (point_at_end)
4872 TEMP_SET_PT_BOTH (Z, Z_BYTE);
4873 else
4874 /* We can't do Fgoto_char (oldpoint) because it will run some
4875 Lisp code. */
4876 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
4877 XMARKER (oldpoint)->bytepos);
4879 UNGCPRO;
4880 free_marker (oldpoint);
4881 free_marker (oldbegv);
4882 free_marker (oldzv);
4884 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
4885 set_buffer_internal (oldbuf);
4886 if (NILP (tem))
4887 windows_or_buffers_changed = old_windows_or_buffers_changed;
4888 message_log_need_newline = !nlflag;
4889 Vdeactivate_mark = old_deactivate_mark;
4894 /* We are at the end of the buffer after just having inserted a newline.
4895 (Note: We depend on the fact we won't be crossing the gap.)
4896 Check to see if the most recent message looks a lot like the previous one.
4897 Return 0 if different, 1 if the new one should just replace it, or a
4898 value N > 1 if we should also append " [N times]". */
4900 static int
4901 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
4902 int prev_bol, this_bol;
4903 int prev_bol_byte, this_bol_byte;
4905 int i;
4906 int len = Z_BYTE - 1 - this_bol_byte;
4907 int seen_dots = 0;
4908 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
4909 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
4911 for (i = 0; i < len; i++)
4913 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.'
4914 && p1[i] != '\n')
4915 seen_dots = 1;
4916 if (p1[i] != p2[i])
4917 return seen_dots;
4919 p1 += len;
4920 if (*p1 == '\n')
4921 return 2;
4922 if (*p1++ == ' ' && *p1++ == '[')
4924 int n = 0;
4925 while (*p1 >= '0' && *p1 <= '9')
4926 n = n * 10 + *p1++ - '0';
4927 if (strncmp (p1, " times]\n", 8) == 0)
4928 return n+1;
4930 return 0;
4934 /* Display an echo area message M with a specified length of LEN
4935 chars. The string may include null characters. If M is 0, clear
4936 out any existing message, and let the mini-buffer text show through.
4938 The buffer M must continue to exist until after the echo area gets
4939 cleared or some other message gets displayed there. This means do
4940 not pass text that is stored in a Lisp string; do not pass text in
4941 a buffer that was alloca'd. */
4943 void
4944 message2 (m, len, multibyte)
4945 char *m;
4946 int len;
4947 int multibyte;
4949 /* First flush out any partial line written with print. */
4950 message_log_maybe_newline ();
4951 if (m)
4952 message_dolog (m, len, 1, multibyte);
4953 message2_nolog (m, len, multibyte);
4957 /* The non-logging counterpart of message2. */
4959 void
4960 message2_nolog (m, len, multibyte)
4961 char *m;
4962 int len;
4964 struct frame *sf = SELECTED_FRAME ();
4965 message_enable_multibyte = multibyte;
4967 if (noninteractive)
4969 if (noninteractive_need_newline)
4970 putc ('\n', stderr);
4971 noninteractive_need_newline = 0;
4972 if (m)
4973 fwrite (m, len, 1, stderr);
4974 if (cursor_in_echo_area == 0)
4975 fprintf (stderr, "\n");
4976 fflush (stderr);
4978 /* A null message buffer means that the frame hasn't really been
4979 initialized yet. Error messages get reported properly by
4980 cmd_error, so this must be just an informative message; toss it. */
4981 else if (INTERACTIVE
4982 && sf->glyphs_initialized_p
4983 && FRAME_MESSAGE_BUF (sf))
4985 Lisp_Object mini_window;
4986 struct frame *f;
4988 /* Get the frame containing the mini-buffer
4989 that the selected frame is using. */
4990 mini_window = FRAME_MINIBUF_WINDOW (sf);
4991 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
4993 FRAME_SAMPLE_VISIBILITY (f);
4994 if (FRAME_VISIBLE_P (sf)
4995 && ! FRAME_VISIBLE_P (f))
4996 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
4998 if (m)
5000 set_message (m, Qnil, len, multibyte);
5001 if (minibuffer_auto_raise)
5002 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
5004 else
5005 clear_message (1, 1);
5007 do_pending_window_change (0);
5008 echo_area_display (1);
5009 do_pending_window_change (0);
5010 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
5011 (*frame_up_to_date_hook) (f);
5016 /* Display an echo area message M with a specified length of NBYTES
5017 bytes. The string may include null characters. If M is not a
5018 string, clear out any existing message, and let the mini-buffer
5019 text show through. */
5021 void
5022 message3 (m, nbytes, multibyte)
5023 Lisp_Object m;
5024 int nbytes;
5025 int multibyte;
5027 struct gcpro gcpro1;
5029 GCPRO1 (m);
5031 /* First flush out any partial line written with print. */
5032 message_log_maybe_newline ();
5033 if (STRINGP (m))
5034 message_dolog (XSTRING (m)->data, nbytes, 1, multibyte);
5035 message3_nolog (m, nbytes, multibyte);
5037 UNGCPRO;
5041 /* The non-logging version of message3. */
5043 void
5044 message3_nolog (m, nbytes, multibyte)
5045 Lisp_Object m;
5046 int nbytes, multibyte;
5048 struct frame *sf = SELECTED_FRAME ();
5049 message_enable_multibyte = multibyte;
5051 if (noninteractive)
5053 if (noninteractive_need_newline)
5054 putc ('\n', stderr);
5055 noninteractive_need_newline = 0;
5056 if (STRINGP (m))
5057 fwrite (XSTRING (m)->data, nbytes, 1, stderr);
5058 if (cursor_in_echo_area == 0)
5059 fprintf (stderr, "\n");
5060 fflush (stderr);
5062 /* A null message buffer means that the frame hasn't really been
5063 initialized yet. Error messages get reported properly by
5064 cmd_error, so this must be just an informative message; toss it. */
5065 else if (INTERACTIVE
5066 && sf->glyphs_initialized_p
5067 && FRAME_MESSAGE_BUF (sf))
5069 Lisp_Object mini_window;
5070 Lisp_Object frame;
5071 struct frame *f;
5073 /* Get the frame containing the mini-buffer
5074 that the selected frame is using. */
5075 mini_window = FRAME_MINIBUF_WINDOW (sf);
5076 frame = XWINDOW (mini_window)->frame;
5077 f = XFRAME (frame);
5079 FRAME_SAMPLE_VISIBILITY (f);
5080 if (FRAME_VISIBLE_P (sf)
5081 && !FRAME_VISIBLE_P (f))
5082 Fmake_frame_visible (frame);
5084 if (STRINGP (m) && XSTRING (m)->size)
5086 set_message (NULL, m, nbytes, multibyte);
5087 if (minibuffer_auto_raise)
5088 Fraise_frame (frame);
5090 else
5091 clear_message (1, 1);
5093 do_pending_window_change (0);
5094 echo_area_display (1);
5095 do_pending_window_change (0);
5096 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
5097 (*frame_up_to_date_hook) (f);
5102 /* Display a null-terminated echo area message M. If M is 0, clear
5103 out any existing message, and let the mini-buffer text show through.
5105 The buffer M must continue to exist until after the echo area gets
5106 cleared or some other message gets displayed there. Do not pass
5107 text that is stored in a Lisp string. Do not pass text in a buffer
5108 that was alloca'd. */
5110 void
5111 message1 (m)
5112 char *m;
5114 message2 (m, (m ? strlen (m) : 0), 0);
5118 /* The non-logging counterpart of message1. */
5120 void
5121 message1_nolog (m)
5122 char *m;
5124 message2_nolog (m, (m ? strlen (m) : 0), 0);
5127 /* Display a message M which contains a single %s
5128 which gets replaced with STRING. */
5130 void
5131 message_with_string (m, string, log)
5132 char *m;
5133 Lisp_Object string;
5134 int log;
5136 if (noninteractive)
5138 if (m)
5140 if (noninteractive_need_newline)
5141 putc ('\n', stderr);
5142 noninteractive_need_newline = 0;
5143 fprintf (stderr, m, XSTRING (string)->data);
5144 if (cursor_in_echo_area == 0)
5145 fprintf (stderr, "\n");
5146 fflush (stderr);
5149 else if (INTERACTIVE)
5151 /* The frame whose minibuffer we're going to display the message on.
5152 It may be larger than the selected frame, so we need
5153 to use its buffer, not the selected frame's buffer. */
5154 Lisp_Object mini_window;
5155 struct frame *f, *sf = SELECTED_FRAME ();
5157 /* Get the frame containing the minibuffer
5158 that the selected frame is using. */
5159 mini_window = FRAME_MINIBUF_WINDOW (sf);
5160 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5162 /* A null message buffer means that the frame hasn't really been
5163 initialized yet. Error messages get reported properly by
5164 cmd_error, so this must be just an informative message; toss it. */
5165 if (FRAME_MESSAGE_BUF (f))
5167 int len;
5168 char *a[1];
5169 a[0] = (char *) XSTRING (string)->data;
5171 len = doprnt (FRAME_MESSAGE_BUF (f),
5172 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5174 if (log)
5175 message2 (FRAME_MESSAGE_BUF (f), len,
5176 STRING_MULTIBYTE (string));
5177 else
5178 message2_nolog (FRAME_MESSAGE_BUF (f), len,
5179 STRING_MULTIBYTE (string));
5181 /* Print should start at the beginning of the message
5182 buffer next time. */
5183 message_buf_print = 0;
5189 /* Dump an informative message to the minibuf. If M is 0, clear out
5190 any existing message, and let the mini-buffer text show through. */
5192 /* VARARGS 1 */
5193 void
5194 message (m, a1, a2, a3)
5195 char *m;
5196 EMACS_INT a1, a2, a3;
5198 if (noninteractive)
5200 if (m)
5202 if (noninteractive_need_newline)
5203 putc ('\n', stderr);
5204 noninteractive_need_newline = 0;
5205 fprintf (stderr, m, a1, a2, a3);
5206 if (cursor_in_echo_area == 0)
5207 fprintf (stderr, "\n");
5208 fflush (stderr);
5211 else if (INTERACTIVE)
5213 /* The frame whose mini-buffer we're going to display the message
5214 on. It may be larger than the selected frame, so we need to
5215 use its buffer, not the selected frame's buffer. */
5216 Lisp_Object mini_window;
5217 struct frame *f, *sf = SELECTED_FRAME ();
5219 /* Get the frame containing the mini-buffer
5220 that the selected frame is using. */
5221 mini_window = FRAME_MINIBUF_WINDOW (sf);
5222 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5224 /* A null message buffer means that the frame hasn't really been
5225 initialized yet. Error messages get reported properly by
5226 cmd_error, so this must be just an informative message; toss
5227 it. */
5228 if (FRAME_MESSAGE_BUF (f))
5230 if (m)
5232 int len;
5233 #ifdef NO_ARG_ARRAY
5234 char *a[3];
5235 a[0] = (char *) a1;
5236 a[1] = (char *) a2;
5237 a[2] = (char *) a3;
5239 len = doprnt (FRAME_MESSAGE_BUF (f),
5240 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5241 #else
5242 len = doprnt (FRAME_MESSAGE_BUF (f),
5243 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
5244 (char **) &a1);
5245 #endif /* NO_ARG_ARRAY */
5247 message2 (FRAME_MESSAGE_BUF (f), len, 0);
5249 else
5250 message1 (0);
5252 /* Print should start at the beginning of the message
5253 buffer next time. */
5254 message_buf_print = 0;
5260 /* The non-logging version of message. */
5262 void
5263 message_nolog (m, a1, a2, a3)
5264 char *m;
5265 EMACS_INT a1, a2, a3;
5267 Lisp_Object old_log_max;
5268 old_log_max = Vmessage_log_max;
5269 Vmessage_log_max = Qnil;
5270 message (m, a1, a2, a3);
5271 Vmessage_log_max = old_log_max;
5275 /* Display the current message in the current mini-buffer. This is
5276 only called from error handlers in process.c, and is not time
5277 critical. */
5279 void
5280 update_echo_area ()
5282 if (!NILP (echo_area_buffer[0]))
5284 Lisp_Object string;
5285 string = Fcurrent_message ();
5286 message3 (string, XSTRING (string)->size,
5287 !NILP (current_buffer->enable_multibyte_characters));
5292 /* Make sure echo area buffers in echo_buffers[] are life. If they
5293 aren't, make new ones. */
5295 static void
5296 ensure_echo_area_buffers ()
5298 int i;
5300 for (i = 0; i < 2; ++i)
5301 if (!BUFFERP (echo_buffer[i])
5302 || NILP (XBUFFER (echo_buffer[i])->name))
5304 char name[30];
5305 sprintf (name, " *Echo Area %d*", i);
5306 echo_buffer[i] = Fget_buffer_create (build_string (name));
5307 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
5312 /* Call FN with args A1..A5 with either the current or last displayed
5313 echo_area_buffer as current buffer.
5315 WHICH zero means use the current message buffer
5316 echo_area_buffer[0]. If that is nil, choose a suitable buffer
5317 from echo_buffer[] and clear it.
5319 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
5320 suitable buffer from echo_buffer[] and clear it.
5322 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
5323 that the current message becomes the last displayed one, make
5324 choose a suitable buffer for echo_area_buffer[0], and clear it.
5326 Value is what FN returns. */
5328 static int
5329 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
5330 struct window *w;
5331 int which;
5332 int (*fn) ();
5333 int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
5335 Lisp_Object buffer;
5336 int this_one, the_other, clear_buffer_p, rc;
5337 int count = specpdl_ptr - specpdl;
5339 /* If buffers aren't life, make new ones. */
5340 ensure_echo_area_buffers ();
5342 clear_buffer_p = 0;
5344 if (which == 0)
5345 this_one = 0, the_other = 1;
5346 else if (which > 0)
5347 this_one = 1, the_other = 0;
5348 else
5350 this_one = 0, the_other = 1;
5351 clear_buffer_p = 1;
5353 /* We need a fresh one in case the current echo buffer equals
5354 the one containing the last displayed echo area message. */
5355 if (!NILP (echo_area_buffer[this_one])
5356 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
5357 echo_area_buffer[this_one] = Qnil;
5360 /* Choose a suitable buffer from echo_buffer[] is we don't
5361 have one. */
5362 if (NILP (echo_area_buffer[this_one]))
5364 echo_area_buffer[this_one]
5365 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
5366 ? echo_buffer[the_other]
5367 : echo_buffer[this_one]);
5368 clear_buffer_p = 1;
5371 buffer = echo_area_buffer[this_one];
5373 record_unwind_protect (unwind_with_echo_area_buffer,
5374 with_echo_area_buffer_unwind_data (w));
5376 /* Make the echo area buffer current. Note that for display
5377 purposes, it is not necessary that the displayed window's buffer
5378 == current_buffer, except for text property lookup. So, let's
5379 only set that buffer temporarily here without doing a full
5380 Fset_window_buffer. We must also change w->pointm, though,
5381 because otherwise an assertions in unshow_buffer fails, and Emacs
5382 aborts. */
5383 set_buffer_internal_1 (XBUFFER (buffer));
5384 if (w)
5386 w->buffer = buffer;
5387 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
5390 current_buffer->undo_list = Qt;
5391 current_buffer->read_only = Qnil;
5393 if (clear_buffer_p && Z > BEG)
5394 del_range (BEG, Z);
5396 xassert (BEGV >= BEG);
5397 xassert (ZV <= Z && ZV >= BEGV);
5399 rc = fn (a1, a2, a3, a4, a5);
5401 xassert (BEGV >= BEG);
5402 xassert (ZV <= Z && ZV >= BEGV);
5404 unbind_to (count, Qnil);
5405 return rc;
5409 /* Save state that should be preserved around the call to the function
5410 FN called in with_echo_area_buffer. */
5412 static Lisp_Object
5413 with_echo_area_buffer_unwind_data (w)
5414 struct window *w;
5416 int i = 0;
5417 Lisp_Object vector;
5419 /* Reduce consing by keeping one vector in
5420 Vwith_echo_area_save_vector. */
5421 vector = Vwith_echo_area_save_vector;
5422 Vwith_echo_area_save_vector = Qnil;
5424 if (NILP (vector))
5425 vector = Fmake_vector (make_number (7), Qnil);
5427 XSETBUFFER (XVECTOR (vector)->contents[i], current_buffer); ++i;
5428 XVECTOR (vector)->contents[i++] = Vdeactivate_mark;
5429 XVECTOR (vector)->contents[i++] = make_number (windows_or_buffers_changed);
5431 if (w)
5433 XSETWINDOW (XVECTOR (vector)->contents[i], w); ++i;
5434 XVECTOR (vector)->contents[i++] = w->buffer;
5435 XVECTOR (vector)->contents[i++]
5436 = make_number (XMARKER (w->pointm)->charpos);
5437 XVECTOR (vector)->contents[i++]
5438 = make_number (XMARKER (w->pointm)->bytepos);
5440 else
5442 int end = i + 4;
5443 while (i < end)
5444 XVECTOR (vector)->contents[i++] = Qnil;
5447 xassert (i == XVECTOR (vector)->size);
5448 return vector;
5452 /* Restore global state from VECTOR which was created by
5453 with_echo_area_buffer_unwind_data. */
5455 static Lisp_Object
5456 unwind_with_echo_area_buffer (vector)
5457 Lisp_Object vector;
5459 int i = 0;
5461 set_buffer_internal_1 (XBUFFER (XVECTOR (vector)->contents[i])); ++i;
5462 Vdeactivate_mark = XVECTOR (vector)->contents[i]; ++i;
5463 windows_or_buffers_changed = XFASTINT (XVECTOR (vector)->contents[i]); ++i;
5465 if (WINDOWP (XVECTOR (vector)->contents[i]))
5467 struct window *w;
5468 Lisp_Object buffer, charpos, bytepos;
5470 w = XWINDOW (XVECTOR (vector)->contents[i]); ++i;
5471 buffer = XVECTOR (vector)->contents[i]; ++i;
5472 charpos = XVECTOR (vector)->contents[i]; ++i;
5473 bytepos = XVECTOR (vector)->contents[i]; ++i;
5475 w->buffer = buffer;
5476 set_marker_both (w->pointm, buffer,
5477 XFASTINT (charpos), XFASTINT (bytepos));
5480 Vwith_echo_area_save_vector = vector;
5481 return Qnil;
5485 /* Set up the echo area for use by print functions. MULTIBYTE_P
5486 non-zero means we will print multibyte. */
5488 void
5489 setup_echo_area_for_printing (multibyte_p)
5490 int multibyte_p;
5492 ensure_echo_area_buffers ();
5494 if (!message_buf_print)
5496 /* A message has been output since the last time we printed.
5497 Choose a fresh echo area buffer. */
5498 if (EQ (echo_area_buffer[1], echo_buffer[0]))
5499 echo_area_buffer[0] = echo_buffer[1];
5500 else
5501 echo_area_buffer[0] = echo_buffer[0];
5503 /* Switch to that buffer and clear it. */
5504 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
5505 if (Z > BEG)
5506 del_range (BEG, Z);
5507 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
5509 /* Set up the buffer for the multibyteness we need. */
5510 if (multibyte_p
5511 != !NILP (current_buffer->enable_multibyte_characters))
5512 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
5514 /* Raise the frame containing the echo area. */
5515 if (minibuffer_auto_raise)
5517 struct frame *sf = SELECTED_FRAME ();
5518 Lisp_Object mini_window;
5519 mini_window = FRAME_MINIBUF_WINDOW (sf);
5520 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
5523 message_log_maybe_newline ();
5524 message_buf_print = 1;
5526 else
5528 if (NILP (echo_area_buffer[0]))
5530 if (EQ (echo_area_buffer[1], echo_buffer[0]))
5531 echo_area_buffer[0] = echo_buffer[1];
5532 else
5533 echo_area_buffer[0] = echo_buffer[0];
5536 if (current_buffer != XBUFFER (echo_area_buffer[0]))
5537 /* Someone switched buffers between print requests. */
5538 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
5543 /* Display an echo area message in window W. Value is non-zero if W's
5544 height is changed. If display_last_displayed_message_p is
5545 non-zero, display the message that was last displayed, otherwise
5546 display the current message. */
5548 static int
5549 display_echo_area (w)
5550 struct window *w;
5552 int i, no_message_p, window_height_changed_p, count;
5554 /* Temporarily disable garbage collections while displaying the echo
5555 area. This is done because a GC can print a message itself.
5556 That message would modify the echo area buffer's contents while a
5557 redisplay of the buffer is going on, and seriously confuse
5558 redisplay. */
5559 count = inhibit_garbage_collection ();
5561 /* If there is no message, we must call display_echo_area_1
5562 nevertheless because it resizes the window. But we will have to
5563 reset the echo_area_buffer in question to nil at the end because
5564 with_echo_area_buffer will sets it to an empty buffer. */
5565 i = display_last_displayed_message_p ? 1 : 0;
5566 no_message_p = NILP (echo_area_buffer[i]);
5568 window_height_changed_p
5569 = with_echo_area_buffer (w, display_last_displayed_message_p,
5570 (int (*) ()) display_echo_area_1, w);
5572 if (no_message_p)
5573 echo_area_buffer[i] = Qnil;
5575 unbind_to (count, Qnil);
5576 return window_height_changed_p;
5580 /* Helper for display_echo_area. Display the current buffer which
5581 contains the current echo area message in window W, a mini-window.
5582 Change the height of W so that all of the message is displayed.
5583 Value is non-zero if height of W was changed. */
5585 static int
5586 display_echo_area_1 (w)
5587 struct window *w;
5589 Lisp_Object window;
5590 struct text_pos start;
5591 int window_height_changed_p = 0;
5593 /* Do this before displaying, so that we have a large enough glyph
5594 matrix for the display. */
5595 window_height_changed_p = resize_mini_window (w, 0);
5597 /* Display. */
5598 clear_glyph_matrix (w->desired_matrix);
5599 XSETWINDOW (window, w);
5600 SET_TEXT_POS (start, BEG, BEG_BYTE);
5601 try_window (window, start);
5603 return window_height_changed_p;
5607 /* Resize the echo area window to exactly the size needed for the
5608 currently displayed message, if there is one. */
5610 void
5611 resize_echo_area_axactly ()
5613 if (BUFFERP (echo_area_buffer[0])
5614 && WINDOWP (echo_area_window))
5616 struct window *w = XWINDOW (echo_area_window);
5617 int resized_p;
5619 resized_p = with_echo_area_buffer (w, 0,
5620 (int (*) ()) resize_mini_window,
5621 w, 1);
5622 if (resized_p)
5624 ++windows_or_buffers_changed;
5625 ++update_mode_lines;
5626 redisplay_internal (0);
5632 /* Resize mini-window W to fit the size of its contents. EXACT:P
5633 means size the window exactly to the size needed. Otherwise, it's
5634 only enlarged until W's buffer is empty. Value is non-zero if
5635 the window height has been changed. */
5638 resize_mini_window (w, exact_p)
5639 struct window *w;
5640 int exact_p;
5642 struct frame *f = XFRAME (w->frame);
5643 int window_height_changed_p = 0;
5645 xassert (MINI_WINDOW_P (w));
5647 /* Nil means don't try to resize. */
5648 if (NILP (Vmax_mini_window_height)
5649 || (FRAME_X_P (f) && f->output_data.x == NULL))
5650 return 0;
5652 if (!FRAME_MINIBUF_ONLY_P (f))
5654 struct it it;
5655 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
5656 int total_height = XFASTINT (root->height) + XFASTINT (w->height);
5657 int height, max_height;
5658 int unit = CANON_Y_UNIT (f);
5659 struct text_pos start;
5661 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
5663 /* Compute the max. number of lines specified by the user. */
5664 if (FLOATP (Vmax_mini_window_height))
5665 max_height = XFLOATINT (Vmax_mini_window_height) * total_height;
5666 else if (INTEGERP (Vmax_mini_window_height))
5667 max_height = XINT (Vmax_mini_window_height);
5668 else
5669 max_height = total_height / 4;
5671 /* Correct that max. height if it's bogus. */
5672 max_height = max (1, max_height);
5673 max_height = min (total_height, max_height);
5675 /* Find out the height of the text in the window. */
5676 if (it.truncate_lines_p)
5677 height = 1;
5678 else
5680 last_height = 0;
5681 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
5682 if (it.max_ascent == 0 && it.max_descent == 0)
5683 height = it.current_y + last_height;
5684 else
5685 height = it.current_y + it.max_ascent + it.max_descent;
5686 height = (height + unit - 1) / unit;
5689 /* Compute a suitable window start. */
5690 if (height > max_height)
5692 height = max_height;
5693 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
5694 move_it_vertically_backward (&it, (height - 1) * unit);
5695 start = it.current.pos;
5697 else
5698 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
5699 SET_MARKER_FROM_TEXT_POS (w->start, start);
5701 /* Let it grow only, until we display an empty message, in which
5702 case the window shrinks again. */
5703 if (height > XFASTINT (w->height))
5705 int old_height = XFASTINT (w->height);
5706 freeze_window_starts (f, 1);
5707 grow_mini_window (w, height - XFASTINT (w->height));
5708 window_height_changed_p = XFASTINT (w->height) != old_height;
5710 else if (height < XFASTINT (w->height)
5711 && (exact_p || BEGV == ZV))
5713 int old_height = XFASTINT (w->height);
5714 freeze_window_starts (f, 0);
5715 shrink_mini_window (w);
5716 window_height_changed_p = XFASTINT (w->height) != old_height;
5720 return window_height_changed_p;
5724 /* Value is the current message, a string, or nil if there is no
5725 current message. */
5727 Lisp_Object
5728 current_message ()
5730 Lisp_Object msg;
5732 if (NILP (echo_area_buffer[0]))
5733 msg = Qnil;
5734 else
5736 with_echo_area_buffer (0, 0, (int (*) ()) current_message_1, &msg);
5737 if (NILP (msg))
5738 echo_area_buffer[0] = Qnil;
5741 return msg;
5745 static int
5746 current_message_1 (msg)
5747 Lisp_Object *msg;
5749 if (Z > BEG)
5750 *msg = make_buffer_string (BEG, Z, 1);
5751 else
5752 *msg = Qnil;
5753 return 0;
5757 /* Push the current message on Vmessage_stack for later restauration
5758 by restore_message. Value is non-zero if the current message isn't
5759 empty. This is a relatively infrequent operation, so it's not
5760 worth optimizing. */
5763 push_message ()
5765 Lisp_Object msg;
5766 msg = current_message ();
5767 Vmessage_stack = Fcons (msg, Vmessage_stack);
5768 return STRINGP (msg);
5772 /* Restore message display from the top of Vmessage_stack. */
5774 void
5775 restore_message ()
5777 Lisp_Object msg;
5779 xassert (CONSP (Vmessage_stack));
5780 msg = XCAR (Vmessage_stack);
5781 if (STRINGP (msg))
5782 message3_nolog (msg, STRING_BYTES (XSTRING (msg)), STRING_MULTIBYTE (msg));
5783 else
5784 message3_nolog (msg, 0, 0);
5788 /* Pop the top-most entry off Vmessage_stack. */
5790 void
5791 pop_message ()
5793 xassert (CONSP (Vmessage_stack));
5794 Vmessage_stack = XCDR (Vmessage_stack);
5798 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
5799 exits. If the stack is not empty, we have a missing pop_message
5800 somewhere. */
5802 void
5803 check_message_stack ()
5805 if (!NILP (Vmessage_stack))
5806 abort ();
5810 /* Truncate to NCHARS what will be displayed in the echo area the next
5811 time we display it---but don't redisplay it now. */
5813 void
5814 truncate_echo_area (nchars)
5815 int nchars;
5817 if (nchars == 0)
5818 echo_area_buffer[0] = Qnil;
5819 /* A null message buffer means that the frame hasn't really been
5820 initialized yet. Error messages get reported properly by
5821 cmd_error, so this must be just an informative message; toss it. */
5822 else if (!noninteractive
5823 && INTERACTIVE
5824 && !NILP (echo_area_buffer[0]))
5826 struct frame *sf = SELECTED_FRAME ();
5827 if (FRAME_MESSAGE_BUF (sf))
5828 with_echo_area_buffer (0, 0, (int (*) ()) truncate_message_1, nchars);
5833 /* Helper function for truncate_echo_area. Truncate the current
5834 message to at most NCHARS characters. */
5836 static int
5837 truncate_message_1 (nchars)
5838 int nchars;
5840 if (BEG + nchars < Z)
5841 del_range (BEG + nchars, Z);
5842 if (Z == BEG)
5843 echo_area_buffer[0] = Qnil;
5844 return 0;
5848 /* Set the current message to a substring of S or STRING.
5850 If STRING is a Lisp string, set the message to the first NBYTES
5851 bytes from STRING. NBYTES zero means use the whole string. If
5852 STRING is multibyte, the message will be displayed multibyte.
5854 If S is not null, set the message to the first LEN bytes of S. LEN
5855 zero means use the whole string. MULTIBYTE_P non-zero means S is
5856 multibyte. Display the message multibyte in that case. */
5858 void
5859 set_message (s, string, nbytes, multibyte_p)
5860 char *s;
5861 Lisp_Object string;
5862 int nbytes;
5864 message_enable_multibyte
5865 = ((s && multibyte_p)
5866 || (STRINGP (string) && STRING_MULTIBYTE (string)));
5868 with_echo_area_buffer (0, -1, (int (*) ()) set_message_1,
5869 s, string, nbytes, multibyte_p);
5870 message_buf_print = 0;
5874 /* Helper function for set_message. Arguments have the same meaning
5875 as there. This function is called with the echo area buffer being
5876 current. */
5878 static int
5879 set_message_1 (s, string, nbytes, multibyte_p)
5880 char *s;
5881 Lisp_Object string;
5882 int nbytes, multibyte_p;
5884 xassert (BEG == Z);
5886 /* Change multibyteness of the echo buffer appropriately. */
5887 if (message_enable_multibyte
5888 != !NILP (current_buffer->enable_multibyte_characters))
5889 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
5891 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
5893 /* Insert new message at BEG. */
5894 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
5896 if (STRINGP (string))
5898 int nchars;
5900 if (nbytes == 0)
5901 nbytes = XSTRING (string)->size_byte;
5902 nchars = string_byte_to_char (string, nbytes);
5904 /* This function takes care of single/multibyte conversion. We
5905 just have to ensure that the echo area buffer has the right
5906 setting of enable_multibyte_characters. */
5907 insert_from_string (string, 0, 0, nchars, nbytes, 1);
5909 else if (s)
5911 if (nbytes == 0)
5912 nbytes = strlen (s);
5914 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
5916 /* Convert from multi-byte to single-byte. */
5917 int i, c, n;
5918 unsigned char work[1];
5920 /* Convert a multibyte string to single-byte. */
5921 for (i = 0; i < nbytes; i += n)
5923 c = string_char_and_length (s + i, nbytes - i, &n);
5924 work[0] = (SINGLE_BYTE_CHAR_P (c)
5926 : multibyte_char_to_unibyte (c, Qnil));
5927 insert_1_both (work, 1, 1, 1, 0, 0);
5930 else if (!multibyte_p
5931 && !NILP (current_buffer->enable_multibyte_characters))
5933 /* Convert from single-byte to multi-byte. */
5934 int i, c, n;
5935 unsigned char *msg = (unsigned char *) s;
5936 unsigned char str[MAX_MULTIBYTE_LENGTH];
5938 /* Convert a single-byte string to multibyte. */
5939 for (i = 0; i < nbytes; i++)
5941 c = unibyte_char_to_multibyte (msg[i]);
5942 n = CHAR_STRING (c, str);
5943 insert_1_both (str, 1, n, 1, 0, 0);
5946 else
5947 insert_1 (s, nbytes, 1, 0, 0);
5950 return 0;
5954 /* Clear messages. CURRENT_P non-zero means clear the current
5955 message. LAST_DISPLAYED_P non-zero means clear the message
5956 last displayed. */
5958 void
5959 clear_message (current_p, last_displayed_p)
5960 int current_p, last_displayed_p;
5962 if (current_p)
5963 echo_area_buffer[0] = Qnil;
5965 if (last_displayed_p)
5966 echo_area_buffer[1] = Qnil;
5968 message_buf_print = 0;
5971 /* Clear garbaged frames.
5973 This function is used where the old redisplay called
5974 redraw_garbaged_frames which in turn called redraw_frame which in
5975 turn called clear_frame. The call to clear_frame was a source of
5976 flickering. I believe a clear_frame is not necessary. It should
5977 suffice in the new redisplay to invalidate all current matrices,
5978 and ensure a complete redisplay of all windows. */
5980 static void
5981 clear_garbaged_frames ()
5983 if (frame_garbaged)
5985 Lisp_Object tail, frame;
5987 FOR_EACH_FRAME (tail, frame)
5989 struct frame *f = XFRAME (frame);
5991 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
5993 clear_current_matrices (f);
5994 f->garbaged = 0;
5998 frame_garbaged = 0;
5999 ++windows_or_buffers_changed;
6004 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
6005 is non-zero update selected_frame. Value is non-zero if the
6006 mini-windows height has been changed. */
6008 static int
6009 echo_area_display (update_frame_p)
6010 int update_frame_p;
6012 Lisp_Object mini_window;
6013 struct window *w;
6014 struct frame *f;
6015 int window_height_changed_p = 0;
6016 struct frame *sf = SELECTED_FRAME ();
6018 mini_window = FRAME_MINIBUF_WINDOW (sf);
6019 w = XWINDOW (mini_window);
6020 f = XFRAME (WINDOW_FRAME (w));
6022 /* Don't display if frame is invisible or not yet initialized. */
6023 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
6024 return 0;
6026 #ifdef HAVE_WINDOW_SYSTEM
6027 /* When Emacs starts, selected_frame may be a visible terminal
6028 frame, even if we run under a window system. If we let this
6029 through, a message would be displayed on the terminal. */
6030 if (EQ (selected_frame, Vterminal_frame)
6031 && !NILP (Vwindow_system))
6032 return 0;
6033 #endif /* HAVE_WINDOW_SYSTEM */
6035 /* Redraw garbaged frames. */
6036 if (frame_garbaged)
6037 clear_garbaged_frames ();
6039 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
6041 echo_area_window = mini_window;
6042 window_height_changed_p = display_echo_area (w);
6043 w->must_be_updated_p = 1;
6045 if (update_frame_p)
6047 /* Not called from redisplay_internal. If we changed
6048 window configuration, we must redisplay thoroughly.
6049 Otherwise, we can do with updating what we displayed
6050 above. */
6051 if (window_height_changed_p)
6053 ++windows_or_buffers_changed;
6054 ++update_mode_lines;
6055 redisplay_internal (0);
6057 else if (FRAME_WINDOW_P (f))
6059 update_single_window (w, 1);
6060 rif->flush_display (f);
6062 else
6063 update_frame (f, 1, 1);
6066 else if (!EQ (mini_window, selected_window))
6067 windows_or_buffers_changed++;
6069 /* Last displayed message is now the current message. */
6070 echo_area_buffer[1] = echo_area_buffer[0];
6072 /* Prevent redisplay optimization in redisplay_internal by resetting
6073 this_line_start_pos. This is done because the mini-buffer now
6074 displays the message instead of its buffer text. */
6075 if (EQ (mini_window, selected_window))
6076 CHARPOS (this_line_start_pos) = 0;
6078 return window_height_changed_p;
6083 /***********************************************************************
6084 Frame Titles
6085 ***********************************************************************/
6088 #ifdef HAVE_WINDOW_SYSTEM
6090 /* A buffer for constructing frame titles in it; allocated from the
6091 heap in init_xdisp and resized as needed in store_frame_title_char. */
6093 static char *frame_title_buf;
6095 /* The buffer's end, and a current output position in it. */
6097 static char *frame_title_buf_end;
6098 static char *frame_title_ptr;
6101 /* Store a single character C for the frame title in frame_title_buf.
6102 Re-allocate frame_title_buf if necessary. */
6104 static void
6105 store_frame_title_char (c)
6106 char c;
6108 /* If output position has reached the end of the allocated buffer,
6109 double the buffer's size. */
6110 if (frame_title_ptr == frame_title_buf_end)
6112 int len = frame_title_ptr - frame_title_buf;
6113 int new_size = 2 * len * sizeof *frame_title_buf;
6114 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
6115 frame_title_buf_end = frame_title_buf + new_size;
6116 frame_title_ptr = frame_title_buf + len;
6119 *frame_title_ptr++ = c;
6123 /* Store part of a frame title in frame_title_buf, beginning at
6124 frame_title_ptr. STR is the string to store. Do not copy more
6125 than PRECISION number of bytes from STR; PRECISION <= 0 means copy
6126 the whole string. Pad with spaces until FIELD_WIDTH number of
6127 characters have been copied; FIELD_WIDTH <= 0 means don't pad.
6128 Called from display_mode_element when it is used to build a frame
6129 title. */
6131 static int
6132 store_frame_title (str, field_width, precision)
6133 unsigned char *str;
6134 int field_width, precision;
6136 int n = 0;
6138 /* Copy at most PRECISION chars from STR. */
6139 while ((precision <= 0 || n < precision)
6140 && *str)
6142 store_frame_title_char (*str++);
6143 ++n;
6146 /* Fill up with spaces until FIELD_WIDTH reached. */
6147 while (field_width > 0
6148 && n < field_width)
6150 store_frame_title_char (' ');
6151 ++n;
6154 return n;
6158 /* Set the title of FRAME, if it has changed. The title format is
6159 Vicon_title_format if FRAME is iconified, otherwise it is
6160 frame_title_format. */
6162 static void
6163 x_consider_frame_title (frame)
6164 Lisp_Object frame;
6166 struct frame *f = XFRAME (frame);
6168 if (FRAME_WINDOW_P (f)
6169 || FRAME_MINIBUF_ONLY_P (f)
6170 || f->explicit_name)
6172 /* Do we have more than one visible frame on this X display? */
6173 Lisp_Object tail;
6174 Lisp_Object fmt;
6175 struct buffer *obuf;
6176 int len;
6177 struct it it;
6179 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
6181 struct frame *tf = XFRAME (XCAR (tail));
6183 if (tf != f
6184 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
6185 && !FRAME_MINIBUF_ONLY_P (tf)
6186 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
6187 break;
6190 /* Set global variable indicating that multiple frames exist. */
6191 multiple_frames = CONSP (tail);
6193 /* Switch to the buffer of selected window of the frame. Set up
6194 frame_title_ptr so that display_mode_element will output into it;
6195 then display the title. */
6196 obuf = current_buffer;
6197 Fset_buffer (XWINDOW (f->selected_window)->buffer);
6198 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
6199 frame_title_ptr = frame_title_buf;
6200 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
6201 NULL, DEFAULT_FACE_ID);
6202 len = display_mode_element (&it, 0, -1, -1, fmt);
6203 frame_title_ptr = NULL;
6204 set_buffer_internal (obuf);
6206 /* Set the title only if it's changed. This avoids consing in
6207 the common case where it hasn't. (If it turns out that we've
6208 already wasted too much time by walking through the list with
6209 display_mode_element, then we might need to optimize at a
6210 higher level than this.) */
6211 if (! STRINGP (f->name)
6212 || STRING_BYTES (XSTRING (f->name)) != len
6213 || bcmp (frame_title_buf, XSTRING (f->name)->data, len) != 0)
6214 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
6218 #else /* not HAVE_WINDOW_SYSTEM */
6220 #define frame_title_ptr ((char *)0)
6221 #define store_frame_title(str, mincol, maxcol) 0
6223 #endif /* not HAVE_WINDOW_SYSTEM */
6228 /***********************************************************************
6229 Menu Bars
6230 ***********************************************************************/
6233 /* Prepare for redisplay by updating menu-bar item lists when
6234 appropriate. This can call eval. */
6236 void
6237 prepare_menu_bars ()
6239 int all_windows;
6240 struct gcpro gcpro1, gcpro2;
6241 struct frame *f;
6242 struct frame *tooltip_frame;
6244 #ifdef HAVE_X_WINDOWS
6245 tooltip_frame = tip_frame;
6246 #else
6247 tooltip_frame = NULL;
6248 #endif
6250 /* Update all frame titles based on their buffer names, etc. We do
6251 this before the menu bars so that the buffer-menu will show the
6252 up-to-date frame titles. */
6253 #ifdef HAVE_WINDOW_SYSTEM
6254 if (windows_or_buffers_changed || update_mode_lines)
6256 Lisp_Object tail, frame;
6258 FOR_EACH_FRAME (tail, frame)
6260 f = XFRAME (frame);
6261 if (f != tooltip_frame
6262 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
6263 x_consider_frame_title (frame);
6266 #endif /* HAVE_WINDOW_SYSTEM */
6268 /* Update the menu bar item lists, if appropriate. This has to be
6269 done before any actual redisplay or generation of display lines. */
6270 all_windows = (update_mode_lines
6271 || buffer_shared > 1
6272 || windows_or_buffers_changed);
6273 if (all_windows)
6275 Lisp_Object tail, frame;
6276 int count = specpdl_ptr - specpdl;
6278 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6280 FOR_EACH_FRAME (tail, frame)
6282 f = XFRAME (frame);
6284 /* Ignore tooltip frame. */
6285 if (f == tooltip_frame)
6286 continue;
6288 /* If a window on this frame changed size, report that to
6289 the user and clear the size-change flag. */
6290 if (FRAME_WINDOW_SIZES_CHANGED (f))
6292 Lisp_Object functions;
6294 /* Clear flag first in case we get an error below. */
6295 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
6296 functions = Vwindow_size_change_functions;
6297 GCPRO2 (tail, functions);
6299 while (CONSP (functions))
6301 call1 (XCAR (functions), frame);
6302 functions = XCDR (functions);
6304 UNGCPRO;
6307 GCPRO1 (tail);
6308 update_menu_bar (f, 0);
6309 #ifdef HAVE_WINDOW_SYSTEM
6310 update_tool_bar (f, 0);
6311 #endif
6312 UNGCPRO;
6315 unbind_to (count, Qnil);
6317 else
6319 struct frame *sf = SELECTED_FRAME ();
6320 update_menu_bar (sf, 1);
6321 #ifdef HAVE_WINDOW_SYSTEM
6322 update_tool_bar (sf, 1);
6323 #endif
6326 /* Motif needs this. See comment in xmenu.c. Turn it off when
6327 pending_menu_activation is not defined. */
6328 #ifdef USE_X_TOOLKIT
6329 pending_menu_activation = 0;
6330 #endif
6334 /* Update the menu bar item list for frame F. This has to be done
6335 before we start to fill in any display lines, because it can call
6336 eval.
6338 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
6340 static void
6341 update_menu_bar (f, save_match_data)
6342 struct frame *f;
6343 int save_match_data;
6345 Lisp_Object window;
6346 register struct window *w;
6348 window = FRAME_SELECTED_WINDOW (f);
6349 w = XWINDOW (window);
6351 if (update_mode_lines)
6352 w->update_mode_line = Qt;
6354 if (FRAME_WINDOW_P (f)
6356 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
6357 FRAME_EXTERNAL_MENU_BAR (f)
6358 #else
6359 FRAME_MENU_BAR_LINES (f) > 0
6360 #endif
6361 : FRAME_MENU_BAR_LINES (f) > 0)
6363 /* If the user has switched buffers or windows, we need to
6364 recompute to reflect the new bindings. But we'll
6365 recompute when update_mode_lines is set too; that means
6366 that people can use force-mode-line-update to request
6367 that the menu bar be recomputed. The adverse effect on
6368 the rest of the redisplay algorithm is about the same as
6369 windows_or_buffers_changed anyway. */
6370 if (windows_or_buffers_changed
6371 || !NILP (w->update_mode_line)
6372 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
6373 < BUF_MODIFF (XBUFFER (w->buffer)))
6374 != !NILP (w->last_had_star))
6375 || ((!NILP (Vtransient_mark_mode)
6376 && !NILP (XBUFFER (w->buffer)->mark_active))
6377 != !NILP (w->region_showing)))
6379 struct buffer *prev = current_buffer;
6380 int count = specpdl_ptr - specpdl;
6382 set_buffer_internal_1 (XBUFFER (w->buffer));
6383 if (save_match_data)
6384 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6385 if (NILP (Voverriding_local_map_menu_flag))
6387 specbind (Qoverriding_terminal_local_map, Qnil);
6388 specbind (Qoverriding_local_map, Qnil);
6391 /* Run the Lucid hook. */
6392 call1 (Vrun_hooks, Qactivate_menubar_hook);
6394 /* If it has changed current-menubar from previous value,
6395 really recompute the menu-bar from the value. */
6396 if (! NILP (Vlucid_menu_bar_dirty_flag))
6397 call0 (Qrecompute_lucid_menubar);
6399 safe_run_hooks (Qmenu_bar_update_hook);
6400 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
6402 /* Redisplay the menu bar in case we changed it. */
6403 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
6404 if (FRAME_WINDOW_P (f))
6405 set_frame_menubar (f, 0, 0);
6406 else
6407 /* On a terminal screen, the menu bar is an ordinary screen
6408 line, and this makes it get updated. */
6409 w->update_mode_line = Qt;
6410 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
6411 /* In the non-toolkit version, the menu bar is an ordinary screen
6412 line, and this makes it get updated. */
6413 w->update_mode_line = Qt;
6414 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
6416 unbind_to (count, Qnil);
6417 set_buffer_internal_1 (prev);
6424 /***********************************************************************
6425 Tool-bars
6426 ***********************************************************************/
6428 #ifdef HAVE_WINDOW_SYSTEM
6430 /* Update the tool-bar item list for frame F. This has to be done
6431 before we start to fill in any display lines. Called from
6432 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
6433 and restore it here. */
6435 static void
6436 update_tool_bar (f, save_match_data)
6437 struct frame *f;
6438 int save_match_data;
6440 if (WINDOWP (f->tool_bar_window)
6441 && XFASTINT (XWINDOW (f->tool_bar_window)->height) > 0)
6443 Lisp_Object window;
6444 struct window *w;
6446 window = FRAME_SELECTED_WINDOW (f);
6447 w = XWINDOW (window);
6449 /* If the user has switched buffers or windows, we need to
6450 recompute to reflect the new bindings. But we'll
6451 recompute when update_mode_lines is set too; that means
6452 that people can use force-mode-line-update to request
6453 that the menu bar be recomputed. The adverse effect on
6454 the rest of the redisplay algorithm is about the same as
6455 windows_or_buffers_changed anyway. */
6456 if (windows_or_buffers_changed
6457 || !NILP (w->update_mode_line)
6458 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
6459 < BUF_MODIFF (XBUFFER (w->buffer)))
6460 != !NILP (w->last_had_star))
6461 || ((!NILP (Vtransient_mark_mode)
6462 && !NILP (XBUFFER (w->buffer)->mark_active))
6463 != !NILP (w->region_showing)))
6465 struct buffer *prev = current_buffer;
6466 int count = specpdl_ptr - specpdl;
6468 /* Set current_buffer to the buffer of the selected
6469 window of the frame, so that we get the right local
6470 keymaps. */
6471 set_buffer_internal_1 (XBUFFER (w->buffer));
6473 /* Save match data, if we must. */
6474 if (save_match_data)
6475 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6477 /* Make sure that we don't accidentally use bogus keymaps. */
6478 if (NILP (Voverriding_local_map_menu_flag))
6480 specbind (Qoverriding_terminal_local_map, Qnil);
6481 specbind (Qoverriding_local_map, Qnil);
6484 /* Build desired tool-bar items from keymaps. */
6485 f->desired_tool_bar_items
6486 = tool_bar_items (f->desired_tool_bar_items,
6487 &f->n_desired_tool_bar_items);
6489 /* Redisplay the tool-bar in case we changed it. */
6490 w->update_mode_line = Qt;
6492 unbind_to (count, Qnil);
6493 set_buffer_internal_1 (prev);
6499 /* Set F->desired_tool_bar_string to a Lisp string representing frame
6500 F's desired tool-bar contents. F->desired_tool_bar_items must have
6501 been set up previously by calling prepare_menu_bars. */
6503 static void
6504 build_desired_tool_bar_string (f)
6505 struct frame *f;
6507 int i, size, size_needed, string_idx;
6508 struct gcpro gcpro1, gcpro2, gcpro3;
6509 Lisp_Object image, plist, props;
6511 image = plist = props = Qnil;
6512 GCPRO3 (image, plist, props);
6514 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
6515 Otherwise, make a new string. */
6517 /* The size of the string we might be able to reuse. */
6518 size = (STRINGP (f->desired_tool_bar_string)
6519 ? XSTRING (f->desired_tool_bar_string)->size
6520 : 0);
6522 /* Each image in the string we build is preceded by a space,
6523 and there is a space at the end. */
6524 size_needed = f->n_desired_tool_bar_items + 1;
6526 /* Reuse f->desired_tool_bar_string, if possible. */
6527 if (size < size_needed)
6528 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
6529 make_number (' '));
6530 else
6532 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
6533 Fremove_text_properties (make_number (0), make_number (size),
6534 props, f->desired_tool_bar_string);
6537 /* Put a `display' property on the string for the images to display,
6538 put a `menu_item' property on tool-bar items with a value that
6539 is the index of the item in F's tool-bar item vector. */
6540 for (i = 0, string_idx = 0;
6541 i < f->n_desired_tool_bar_items;
6542 ++i, string_idx += 1)
6544 #define PROP(IDX) \
6545 (XVECTOR (f->desired_tool_bar_items) \
6546 ->contents[i * TOOL_BAR_ITEM_NSLOTS + (IDX)])
6548 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
6549 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
6550 int margin, relief;
6551 extern Lisp_Object QCrelief, QCmargin, QCalgorithm, Qimage;
6552 extern Lisp_Object Qlaplace;
6554 /* If image is a vector, choose the image according to the
6555 button state. */
6556 image = PROP (TOOL_BAR_ITEM_IMAGES);
6557 if (VECTORP (image))
6559 enum tool_bar_item_image idx;
6561 if (enabled_p)
6562 idx = (selected_p
6563 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
6564 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
6565 else
6566 idx = (selected_p
6567 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
6568 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
6570 xassert (XVECTOR (image)->size >= idx);
6571 image = XVECTOR (image)->contents[idx];
6574 /* Ignore invalid image specifications. */
6575 if (!valid_image_p (image))
6576 continue;
6578 /* Display the tool-bar button pressed, or depressed. */
6579 plist = Fcopy_sequence (XCDR (image));
6581 /* Compute margin and relief to draw. */
6582 relief = tool_bar_button_relief > 0 ? tool_bar_button_relief : 3;
6583 margin = relief + max (0, tool_bar_button_margin);
6585 if (auto_raise_tool_bar_buttons_p)
6587 /* Add a `:relief' property to the image spec if the item is
6588 selected. */
6589 if (selected_p)
6591 plist = Fplist_put (plist, QCrelief, make_number (-relief));
6592 margin -= relief;
6595 else
6597 /* If image is selected, display it pressed, i.e. with a
6598 negative relief. If it's not selected, display it with a
6599 raised relief. */
6600 plist = Fplist_put (plist, QCrelief,
6601 (selected_p
6602 ? make_number (-relief)
6603 : make_number (relief)));
6604 margin -= relief;
6607 /* Put a margin around the image. */
6608 if (margin)
6609 plist = Fplist_put (plist, QCmargin, make_number (margin));
6611 /* If button is not enabled, make the image appear disabled by
6612 applying an appropriate algorithm to it. */
6613 if (!enabled_p)
6614 plist = Fplist_put (plist, QCalgorithm, Qlaplace);
6616 /* Put a `display' text property on the string for the image to
6617 display. Put a `menu-item' property on the string that gives
6618 the start of this item's properties in the tool-bar items
6619 vector. */
6620 image = Fcons (Qimage, plist);
6621 props = list4 (Qdisplay, image,
6622 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS)),
6623 Fadd_text_properties (make_number (string_idx),
6624 make_number (string_idx + 1),
6625 props, f->desired_tool_bar_string);
6626 #undef PROP
6629 UNGCPRO;
6633 /* Display one line of the tool-bar of frame IT->f. */
6635 static void
6636 display_tool_bar_line (it)
6637 struct it *it;
6639 struct glyph_row *row = it->glyph_row;
6640 int max_x = it->last_visible_x;
6641 struct glyph *last;
6643 prepare_desired_row (row);
6644 row->y = it->current_y;
6646 while (it->current_x < max_x)
6648 int x_before, x, n_glyphs_before, i, nglyphs;
6650 /* Get the next display element. */
6651 if (!get_next_display_element (it))
6652 break;
6654 /* Produce glyphs. */
6655 x_before = it->current_x;
6656 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
6657 PRODUCE_GLYPHS (it);
6659 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
6660 i = 0;
6661 x = x_before;
6662 while (i < nglyphs)
6664 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
6666 if (x + glyph->pixel_width > max_x)
6668 /* Glyph doesn't fit on line. */
6669 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
6670 it->current_x = x;
6671 goto out;
6674 ++it->hpos;
6675 x += glyph->pixel_width;
6676 ++i;
6679 /* Stop at line ends. */
6680 if (ITERATOR_AT_END_OF_LINE_P (it))
6681 break;
6683 set_iterator_to_next (it);
6686 out:;
6688 row->displays_text_p = row->used[TEXT_AREA] != 0;
6689 extend_face_to_end_of_line (it);
6690 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
6691 last->right_box_line_p = 1;
6692 compute_line_metrics (it);
6694 /* If line is empty, make it occupy the rest of the tool-bar. */
6695 if (!row->displays_text_p)
6697 row->height = row->phys_height = it->last_visible_y - row->y;
6698 row->ascent = row->phys_ascent = 0;
6701 row->full_width_p = 1;
6702 row->continued_p = 0;
6703 row->truncated_on_left_p = 0;
6704 row->truncated_on_right_p = 0;
6706 it->current_x = it->hpos = 0;
6707 it->current_y += row->height;
6708 ++it->vpos;
6709 ++it->glyph_row;
6713 /* Value is the number of screen lines needed to make all tool-bar
6714 items of frame F visible. */
6716 static int
6717 tool_bar_lines_needed (f)
6718 struct frame *f;
6720 struct window *w = XWINDOW (f->tool_bar_window);
6721 struct it it;
6723 /* Initialize an iterator for iteration over
6724 F->desired_tool_bar_string in the tool-bar window of frame F. */
6725 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
6726 it.first_visible_x = 0;
6727 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
6728 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
6730 while (!ITERATOR_AT_END_P (&it))
6732 it.glyph_row = w->desired_matrix->rows;
6733 clear_glyph_row (it.glyph_row);
6734 display_tool_bar_line (&it);
6737 return (it.current_y + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);
6741 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
6742 height should be changed. */
6744 static int
6745 redisplay_tool_bar (f)
6746 struct frame *f;
6748 struct window *w;
6749 struct it it;
6750 struct glyph_row *row;
6751 int change_height_p = 0;
6753 /* If frame hasn't a tool-bar window or if it is zero-height, don't
6754 do anything. This means you must start with tool-bar-lines
6755 non-zero to get the auto-sizing effect. Or in other words, you
6756 can turn off tool-bars by specifying tool-bar-lines zero. */
6757 if (!WINDOWP (f->tool_bar_window)
6758 || (w = XWINDOW (f->tool_bar_window),
6759 XFASTINT (w->height) == 0))
6760 return 0;
6762 /* Set up an iterator for the tool-bar window. */
6763 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
6764 it.first_visible_x = 0;
6765 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
6766 row = it.glyph_row;
6768 /* Build a string that represents the contents of the tool-bar. */
6769 build_desired_tool_bar_string (f);
6770 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
6772 /* Display as many lines as needed to display all tool-bar items. */
6773 while (it.current_y < it.last_visible_y)
6774 display_tool_bar_line (&it);
6776 /* It doesn't make much sense to try scrolling in the tool-bar
6777 window, so don't do it. */
6778 w->desired_matrix->no_scrolling_p = 1;
6779 w->must_be_updated_p = 1;
6781 if (auto_resize_tool_bars_p)
6783 int nlines;
6785 /* If there are blank lines at the end, except for a partially
6786 visible blank line at the end that is smaller than
6787 CANON_Y_UNIT, change the tool-bar's height. */
6788 row = it.glyph_row - 1;
6789 if (!row->displays_text_p
6790 && row->height >= CANON_Y_UNIT (f))
6791 change_height_p = 1;
6793 /* If row displays tool-bar items, but is partially visible,
6794 change the tool-bar's height. */
6795 if (row->displays_text_p
6796 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
6797 change_height_p = 1;
6799 /* Resize windows as needed by changing the `tool-bar-lines'
6800 frame parameter. */
6801 if (change_height_p
6802 && (nlines = tool_bar_lines_needed (f),
6803 nlines != XFASTINT (w->height)))
6805 extern Lisp_Object Qtool_bar_lines;
6806 Lisp_Object frame;
6808 XSETFRAME (frame, f);
6809 clear_glyph_matrix (w->desired_matrix);
6810 Fmodify_frame_parameters (frame,
6811 Fcons (Fcons (Qtool_bar_lines,
6812 make_number (nlines)),
6813 Qnil));
6814 fonts_changed_p = 1;
6818 return change_height_p;
6822 /* Get information about the tool-bar item which is displayed in GLYPH
6823 on frame F. Return in *PROP_IDX the index where tool-bar item
6824 properties start in F->current_tool_bar_items. Value is zero if
6825 GLYPH doesn't display a tool-bar item. */
6828 tool_bar_item_info (f, glyph, prop_idx)
6829 struct frame *f;
6830 struct glyph *glyph;
6831 int *prop_idx;
6833 Lisp_Object prop;
6834 int success_p;
6836 /* Get the text property `menu-item' at pos. The value of that
6837 property is the start index of this item's properties in
6838 F->current_tool_bar_items. */
6839 prop = Fget_text_property (make_number (glyph->charpos),
6840 Qmenu_item, f->current_tool_bar_string);
6841 if (INTEGERP (prop))
6843 *prop_idx = XINT (prop);
6844 success_p = 1;
6846 else
6847 success_p = 0;
6849 return success_p;
6852 #endif /* HAVE_WINDOW_SYSTEM */
6856 /************************************************************************
6857 Horizontal scrolling
6858 ************************************************************************/
6860 static int hscroll_window_tree P_ ((Lisp_Object));
6861 static int hscroll_windows P_ ((Lisp_Object));
6863 /* For all leaf windows in the window tree rooted at WINDOW, set their
6864 hscroll value so that PT is (i) visible in the window, and (ii) so
6865 that it is not within a certain margin at the window's left and
6866 right border. Value is non-zero if any window's hscroll has been
6867 changed. */
6869 static int
6870 hscroll_window_tree (window)
6871 Lisp_Object window;
6873 int hscrolled_p = 0;
6875 while (WINDOWP (window))
6877 struct window *w = XWINDOW (window);
6879 if (WINDOWP (w->hchild))
6880 hscrolled_p |= hscroll_window_tree (w->hchild);
6881 else if (WINDOWP (w->vchild))
6882 hscrolled_p |= hscroll_window_tree (w->vchild);
6883 else if (w->cursor.vpos >= 0)
6885 int hscroll_margin, text_area_x, text_area_y;
6886 int text_area_width, text_area_height;
6887 struct glyph_row *current_cursor_row
6888 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
6889 struct glyph_row *desired_cursor_row
6890 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
6891 struct glyph_row *cursor_row
6892 = (desired_cursor_row->enabled_p
6893 ? desired_cursor_row
6894 : current_cursor_row);
6896 window_box (w, TEXT_AREA, &text_area_x, &text_area_y,
6897 &text_area_width, &text_area_height);
6899 /* Scroll when cursor is inside this scroll margin. */
6900 hscroll_margin = 5 * CANON_X_UNIT (XFRAME (w->frame));
6902 if ((XFASTINT (w->hscroll)
6903 && w->cursor.x < hscroll_margin)
6904 || (cursor_row->enabled_p
6905 && cursor_row->truncated_on_right_p
6906 && (w->cursor.x > text_area_width - hscroll_margin)))
6908 struct it it;
6909 int hscroll;
6910 struct buffer *saved_current_buffer;
6911 int pt;
6913 /* Find point in a display of infinite width. */
6914 saved_current_buffer = current_buffer;
6915 current_buffer = XBUFFER (w->buffer);
6917 if (w == XWINDOW (selected_window))
6918 pt = BUF_PT (current_buffer);
6919 else
6921 pt = marker_position (w->pointm);
6922 pt = max (BEGV, pt);
6923 pt = min (ZV, pt);
6926 /* Move iterator to pt starting at cursor_row->start in
6927 a line with infinite width. */
6928 init_to_row_start (&it, w, cursor_row);
6929 it.last_visible_x = INFINITY;
6930 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
6931 current_buffer = saved_current_buffer;
6933 /* Center cursor in window. */
6934 hscroll = (max (0, it.current_x - text_area_width / 2)
6935 / CANON_X_UNIT (it.f));
6937 /* Don't call Fset_window_hscroll if value hasn't
6938 changed because it will prevent redisplay
6939 optimizations. */
6940 if (XFASTINT (w->hscroll) != hscroll)
6942 Fset_window_hscroll (window, make_number (hscroll));
6943 hscrolled_p = 1;
6948 window = w->next;
6951 /* Value is non-zero if hscroll of any leaf window has been changed. */
6952 return hscrolled_p;
6956 /* Set hscroll so that cursor is visible and not inside horizontal
6957 scroll margins for all windows in the tree rooted at WINDOW. See
6958 also hscroll_window_tree above. Value is non-zero if any window's
6959 hscroll has been changed. If it has, desired matrices on the frame
6960 of WINDOW are cleared. */
6962 static int
6963 hscroll_windows (window)
6964 Lisp_Object window;
6966 int hscrolled_p;
6968 if (automatic_hscrolling_p)
6970 hscrolled_p = hscroll_window_tree (window);
6971 if (hscrolled_p)
6972 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
6974 else
6975 hscrolled_p = 0;
6976 return hscrolled_p;
6981 /************************************************************************
6982 Redisplay
6983 ************************************************************************/
6985 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
6986 to a non-zero value. This is sometimes handy to have in a debugger
6987 session. */
6989 #if GLYPH_DEBUG
6991 /* First and last unchanged row for try_window_id. */
6993 int debug_first_unchanged_at_end_vpos;
6994 int debug_last_unchanged_at_beg_vpos;
6996 /* Delta vpos and y. */
6998 int debug_dvpos, debug_dy;
7000 /* Delta in characters and bytes for try_window_id. */
7002 int debug_delta, debug_delta_bytes;
7004 /* Values of window_end_pos and window_end_vpos at the end of
7005 try_window_id. */
7007 int debug_end_pos, debug_end_vpos;
7009 /* Append a string to W->desired_matrix->method. FMT is a printf
7010 format string. A1...A9 are a supplement for a variable-length
7011 argument list. If trace_redisplay_p is non-zero also printf the
7012 resulting string to stderr. */
7014 static void
7015 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
7016 struct window *w;
7017 char *fmt;
7018 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
7020 char buffer[512];
7021 char *method = w->desired_matrix->method;
7022 int len = strlen (method);
7023 int size = sizeof w->desired_matrix->method;
7024 int remaining = size - len - 1;
7026 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
7027 if (len && remaining)
7029 method[len] = '|';
7030 --remaining, ++len;
7033 strncpy (method + len, buffer, remaining);
7035 if (trace_redisplay_p)
7036 fprintf (stderr, "%p (%s): %s\n",
7038 ((BUFFERP (w->buffer)
7039 && STRINGP (XBUFFER (w->buffer)->name))
7040 ? (char *) XSTRING (XBUFFER (w->buffer)->name)->data
7041 : "no buffer"),
7042 buffer);
7045 #endif /* GLYPH_DEBUG */
7048 /* This counter is used to clear the face cache every once in a while
7049 in redisplay_internal. It is incremented for each redisplay.
7050 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
7051 cleared. */
7053 #define CLEAR_FACE_CACHE_COUNT 10000
7054 static int clear_face_cache_count;
7056 /* Record the previous terminal frame we displayed. */
7058 static struct frame *previous_terminal_frame;
7060 /* Non-zero while redisplay_internal is in progress. */
7062 int redisplaying_p;
7065 /* Value is non-zero if all changes in window W, which displays
7066 current_buffer, are in the text between START and END. START is a
7067 buffer position, END is given as a distance from Z. Used in
7068 redisplay_internal for display optimization. */
7070 static INLINE int
7071 text_outside_line_unchanged_p (w, start, end)
7072 struct window *w;
7073 int start, end;
7075 int unchanged_p = 1;
7077 /* If text or overlays have changed, see where. */
7078 if (XFASTINT (w->last_modified) < MODIFF
7079 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
7081 /* Gap in the line? */
7082 if (GPT < start || Z - GPT < end)
7083 unchanged_p = 0;
7085 /* Changes start in front of the line, or end after it? */
7086 if (unchanged_p
7087 && (BEG_UNCHANGED < start - 1
7088 || END_UNCHANGED < end))
7089 unchanged_p = 0;
7091 /* If selective display, can't optimize if changes start at the
7092 beginning of the line. */
7093 if (unchanged_p
7094 && INTEGERP (current_buffer->selective_display)
7095 && XINT (current_buffer->selective_display) > 0
7096 && (BEG_UNCHANGED < start || GPT <= start))
7097 unchanged_p = 0;
7100 return unchanged_p;
7104 /* Do a frame update, taking possible shortcuts into account. This is
7105 the main external entry point for redisplay.
7107 If the last redisplay displayed an echo area message and that message
7108 is no longer requested, we clear the echo area or bring back the
7109 mini-buffer if that is in use. */
7111 void
7112 redisplay ()
7114 redisplay_internal (0);
7117 /* Return 1 if point moved out of or into a composition. Otherwise
7118 return 0. PREV_BUF and PREV_PT are the last point buffer and
7119 position. BUF and PT are the current point buffer and position. */
7122 check_point_in_composition (prev_buf, prev_pt, buf, pt)
7123 struct buffer *prev_buf, *buf;
7124 int prev_pt, pt;
7126 int start, end;
7127 Lisp_Object prop;
7128 Lisp_Object buffer;
7130 XSETBUFFER (buffer, buf);
7131 /* Check a composition at the last point if point moved within the
7132 same buffer. */
7133 if (prev_buf == buf)
7135 if (prev_pt == pt)
7136 /* Point didn't move. */
7137 return 0;
7139 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
7140 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
7141 && COMPOSITION_VALID_P (start, end, prop)
7142 && start < prev_pt && end > prev_pt)
7143 /* The last point was within the composition. Return 1 iff
7144 point moved out of the composition. */
7145 return (pt <= start || pt >= end);
7148 /* Check a composition at the current point. */
7149 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
7150 && find_composition (pt, -1, &start, &end, &prop, buffer)
7151 && COMPOSITION_VALID_P (start, end, prop)
7152 && start < pt && end > pt);
7155 /* Reconsider the setting of B->clip_changed which is displayed
7156 in window W. */
7158 static INLINE void
7159 reconsider_clip_changes (w, b)
7160 struct window *w;
7161 struct buffer *b;
7163 if (b->prevent_redisplay_optimizations_p)
7164 b->clip_changed = 1;
7165 else if (b->clip_changed
7166 && !NILP (w->window_end_valid)
7167 && w->current_matrix->buffer == b
7168 && w->current_matrix->zv == BUF_ZV (b)
7169 && w->current_matrix->begv == BUF_BEGV (b))
7170 b->clip_changed = 0;
7172 /* If display wasn't paused, and W is not a tool bar window, see if
7173 point has been moved into or out of a composition. In that case,
7174 we set b->clip_changed to 1 to force updating the screen. If
7175 b->clip_changed has already been set to 1, we can skip this
7176 check. */
7177 if (!b->clip_changed
7178 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
7180 int pt;
7182 if (w == XWINDOW (selected_window))
7183 pt = BUF_PT (current_buffer);
7184 else
7185 pt = marker_position (w->pointm);
7187 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
7188 || pt != XINT (w->last_point))
7189 && check_point_in_composition (w->current_matrix->buffer,
7190 XINT (w->last_point),
7191 XBUFFER (w->buffer), pt))
7192 b->clip_changed = 1;
7197 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
7198 response to any user action; therefore, we should preserve the echo
7199 area. (Actually, our caller does that job.) Perhaps in the future
7200 avoid recentering windows if it is not necessary; currently that
7201 causes some problems. */
7203 static void
7204 redisplay_internal (preserve_echo_area)
7205 int preserve_echo_area;
7207 struct window *w = XWINDOW (selected_window);
7208 struct frame *f = XFRAME (w->frame);
7209 int pause;
7210 int must_finish = 0;
7211 struct text_pos tlbufpos, tlendpos;
7212 int number_of_visible_frames;
7213 int count;
7214 struct frame *sf = SELECTED_FRAME ();
7216 /* Non-zero means redisplay has to consider all windows on all
7217 frames. Zero means, only selected_window is considered. */
7218 int consider_all_windows_p;
7220 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
7222 /* No redisplay if running in batch mode or frame is not yet fully
7223 initialized, or redisplay is explicitly turned off by setting
7224 Vinhibit_redisplay. */
7225 if (noninteractive
7226 || !NILP (Vinhibit_redisplay)
7227 || !f->glyphs_initialized_p)
7228 return;
7230 /* The flag redisplay_performed_directly_p is set by
7231 direct_output_for_insert when it already did the whole screen
7232 update necessary. */
7233 if (redisplay_performed_directly_p)
7235 redisplay_performed_directly_p = 0;
7236 if (!hscroll_windows (selected_window))
7237 return;
7240 #ifdef USE_X_TOOLKIT
7241 if (popup_activated ())
7242 return;
7243 #endif
7245 /* I don't think this happens but let's be paranoid. */
7246 if (redisplaying_p)
7247 return;
7249 /* Record a function that resets redisplaying_p to its old value
7250 when we leave this function. */
7251 count = specpdl_ptr - specpdl;
7252 record_unwind_protect (unwind_redisplay, make_number (redisplaying_p));
7253 ++redisplaying_p;
7255 retry:
7257 reconsider_clip_changes (w, current_buffer);
7259 /* If new fonts have been loaded that make a glyph matrix adjustment
7260 necessary, do it. */
7261 if (fonts_changed_p)
7263 adjust_glyphs (NULL);
7264 ++windows_or_buffers_changed;
7265 fonts_changed_p = 0;
7268 if (! FRAME_WINDOW_P (sf)
7269 && previous_terminal_frame != sf)
7271 /* Since frames on an ASCII terminal share the same display
7272 area, displaying a different frame means redisplay the whole
7273 thing. */
7274 windows_or_buffers_changed++;
7275 SET_FRAME_GARBAGED (sf);
7276 XSETFRAME (Vterminal_frame, sf);
7278 previous_terminal_frame = sf;
7280 /* Set the visible flags for all frames. Do this before checking
7281 for resized or garbaged frames; they want to know if their frames
7282 are visible. See the comment in frame.h for
7283 FRAME_SAMPLE_VISIBILITY. */
7285 Lisp_Object tail, frame;
7287 number_of_visible_frames = 0;
7289 FOR_EACH_FRAME (tail, frame)
7291 struct frame *f = XFRAME (frame);
7293 FRAME_SAMPLE_VISIBILITY (f);
7294 if (FRAME_VISIBLE_P (f))
7295 ++number_of_visible_frames;
7296 clear_desired_matrices (f);
7300 /* Notice any pending interrupt request to change frame size. */
7301 do_pending_window_change (1);
7303 /* Clear frames marked as garbaged. */
7304 if (frame_garbaged)
7305 clear_garbaged_frames ();
7307 /* Build menubar and tool-bar items. */
7308 prepare_menu_bars ();
7310 if (windows_or_buffers_changed)
7311 update_mode_lines++;
7313 /* Detect case that we need to write or remove a star in the mode line. */
7314 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
7316 w->update_mode_line = Qt;
7317 if (buffer_shared > 1)
7318 update_mode_lines++;
7321 /* If %c is in the mode line, update it if needed. */
7322 if (!NILP (w->column_number_displayed)
7323 /* This alternative quickly identifies a common case
7324 where no change is needed. */
7325 && !(PT == XFASTINT (w->last_point)
7326 && XFASTINT (w->last_modified) >= MODIFF
7327 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
7328 && XFASTINT (w->column_number_displayed) != current_column ())
7329 w->update_mode_line = Qt;
7331 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
7333 /* The variable buffer_shared is set in redisplay_window and
7334 indicates that we redisplay a buffer in different windows. See
7335 there. */
7336 consider_all_windows_p = update_mode_lines || buffer_shared > 1;
7338 /* If specs for an arrow have changed, do thorough redisplay
7339 to ensure we remove any arrow that should no longer exist. */
7340 if (! EQ (COERCE_MARKER (Voverlay_arrow_position), last_arrow_position)
7341 || ! EQ (Voverlay_arrow_string, last_arrow_string))
7342 consider_all_windows_p = windows_or_buffers_changed = 1;
7344 /* Normally the message* functions will have already displayed and
7345 updated the echo area, but the frame may have been trashed, or
7346 the update may have been preempted, so display the echo area
7347 again here. Checking both message buffers captures the case that
7348 the echo area should be cleared. */
7349 if (!NILP (echo_area_buffer[0]) || !NILP (echo_area_buffer[1]))
7351 int window_height_changed_p = echo_area_display (0);
7352 must_finish = 1;
7354 if (fonts_changed_p)
7355 goto retry;
7356 else if (window_height_changed_p)
7358 consider_all_windows_p = 1;
7359 ++update_mode_lines;
7360 ++windows_or_buffers_changed;
7362 /* If window configuration was changed, frames may have been
7363 marked garbaged. Clear them or we will experience
7364 surprises wrt scrolling. */
7365 if (frame_garbaged)
7366 clear_garbaged_frames ();
7369 else if (w == XWINDOW (minibuf_window)
7370 && (current_buffer->clip_changed
7371 || XFASTINT (w->last_modified) < MODIFF
7372 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
7373 && resize_mini_window (w, 0))
7375 /* Resized active mini-window to fit the size of what it is
7376 showing if its contents might have changed. */
7377 must_finish = 1;
7378 consider_all_windows_p = 1;
7379 ++windows_or_buffers_changed;
7380 ++update_mode_lines;
7382 /* If window configuration was changed, frames may have been
7383 marked garbaged. Clear them or we will experience
7384 surprises wrt scrolling. */
7385 if (frame_garbaged)
7386 clear_garbaged_frames ();
7390 /* If showing the region, and mark has changed, we must redisplay
7391 the whole window. The assignment to this_line_start_pos prevents
7392 the optimization directly below this if-statement. */
7393 if (((!NILP (Vtransient_mark_mode)
7394 && !NILP (XBUFFER (w->buffer)->mark_active))
7395 != !NILP (w->region_showing))
7396 || (!NILP (w->region_showing)
7397 && !EQ (w->region_showing,
7398 Fmarker_position (XBUFFER (w->buffer)->mark))))
7399 CHARPOS (this_line_start_pos) = 0;
7401 /* Optimize the case that only the line containing the cursor in the
7402 selected window has changed. Variables starting with this_ are
7403 set in display_line and record information about the line
7404 containing the cursor. */
7405 tlbufpos = this_line_start_pos;
7406 tlendpos = this_line_end_pos;
7407 if (!consider_all_windows_p
7408 && CHARPOS (tlbufpos) > 0
7409 && NILP (w->update_mode_line)
7410 && !current_buffer->clip_changed
7411 && FRAME_VISIBLE_P (XFRAME (w->frame))
7412 && !FRAME_OBSCURED_P (XFRAME (w->frame))
7413 /* Make sure recorded data applies to current buffer, etc. */
7414 && this_line_buffer == current_buffer
7415 && current_buffer == XBUFFER (w->buffer)
7416 && NILP (w->force_start)
7417 /* Point must be on the line that we have info recorded about. */
7418 && PT >= CHARPOS (tlbufpos)
7419 && PT <= Z - CHARPOS (tlendpos)
7420 /* All text outside that line, including its final newline,
7421 must be unchanged */
7422 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
7423 CHARPOS (tlendpos)))
7425 if (CHARPOS (tlbufpos) > BEGV
7426 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
7427 && (CHARPOS (tlbufpos) == ZV
7428 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
7429 /* Former continuation line has disappeared by becoming empty */
7430 goto cancel;
7431 else if (XFASTINT (w->last_modified) < MODIFF
7432 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
7433 || MINI_WINDOW_P (w))
7435 /* We have to handle the case of continuation around a
7436 wide-column character (See the comment in indent.c around
7437 line 885).
7439 For instance, in the following case:
7441 -------- Insert --------
7442 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
7443 J_I_ ==> J_I_ `^^' are cursors.
7444 ^^ ^^
7445 -------- --------
7447 As we have to redraw the line above, we should goto cancel. */
7449 struct it it;
7450 int line_height_before = this_line_pixel_height;
7452 /* Note that start_display will handle the case that the
7453 line starting at tlbufpos is a continuation lines. */
7454 start_display (&it, w, tlbufpos);
7456 /* Implementation note: It this still necessary? */
7457 if (it.current_x != this_line_start_x)
7458 goto cancel;
7460 TRACE ((stderr, "trying display optimization 1\n"));
7461 w->cursor.vpos = -1;
7462 overlay_arrow_seen = 0;
7463 it.vpos = this_line_vpos;
7464 it.current_y = this_line_y;
7465 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
7466 display_line (&it);
7468 /* If line contains point, is not continued,
7469 and ends at same distance from eob as before, we win */
7470 if (w->cursor.vpos >= 0
7471 /* Line is not continued, otherwise this_line_start_pos
7472 would have been set to 0 in display_line. */
7473 && CHARPOS (this_line_start_pos)
7474 /* Line ends as before. */
7475 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
7476 /* Line has same height as before. Otherwise other lines
7477 would have to be shifted up or down. */
7478 && this_line_pixel_height == line_height_before)
7480 /* If this is not the window's last line, we must adjust
7481 the charstarts of the lines below. */
7482 if (it.current_y < it.last_visible_y)
7484 struct glyph_row *row
7485 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
7486 int delta, delta_bytes;
7488 if (Z - CHARPOS (tlendpos) == ZV)
7490 /* This line ends at end of (accessible part of)
7491 buffer. There is no newline to count. */
7492 delta = (Z
7493 - CHARPOS (tlendpos)
7494 - MATRIX_ROW_START_CHARPOS (row));
7495 delta_bytes = (Z_BYTE
7496 - BYTEPOS (tlendpos)
7497 - MATRIX_ROW_START_BYTEPOS (row));
7499 else
7501 /* This line ends in a newline. Must take
7502 account of the newline and the rest of the
7503 text that follows. */
7504 delta = (Z
7505 - CHARPOS (tlendpos)
7506 - MATRIX_ROW_START_CHARPOS (row));
7507 delta_bytes = (Z_BYTE
7508 - BYTEPOS (tlendpos)
7509 - MATRIX_ROW_START_BYTEPOS (row));
7512 increment_matrix_positions (w->current_matrix,
7513 this_line_vpos + 1,
7514 w->current_matrix->nrows,
7515 delta, delta_bytes);
7518 /* If this row displays text now but previously didn't,
7519 or vice versa, w->window_end_vpos may have to be
7520 adjusted. */
7521 if ((it.glyph_row - 1)->displays_text_p)
7523 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
7524 XSETINT (w->window_end_vpos, this_line_vpos);
7526 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
7527 && this_line_vpos > 0)
7528 XSETINT (w->window_end_vpos, this_line_vpos - 1);
7529 w->window_end_valid = Qnil;
7531 /* Update hint: No need to try to scroll in update_window. */
7532 w->desired_matrix->no_scrolling_p = 1;
7534 #if GLYPH_DEBUG
7535 *w->desired_matrix->method = 0;
7536 debug_method_add (w, "optimization 1");
7537 #endif
7538 goto update;
7540 else
7541 goto cancel;
7543 else if (/* Cursor position hasn't changed. */
7544 PT == XFASTINT (w->last_point)
7545 /* Make sure the cursor was last displayed
7546 in this window. Otherwise we have to reposition it. */
7547 && 0 <= w->cursor.vpos
7548 && XINT (w->height) > w->cursor.vpos)
7550 if (!must_finish)
7552 do_pending_window_change (1);
7554 /* We used to always goto end_of_redisplay here, but this
7555 isn't enough if we have a blinking cursor. */
7556 if (w->cursor_off_p == w->last_cursor_off_p)
7557 goto end_of_redisplay;
7559 goto update;
7561 /* If highlighting the region, or if the cursor is in the echo area,
7562 then we can't just move the cursor. */
7563 else if (! (!NILP (Vtransient_mark_mode)
7564 && !NILP (current_buffer->mark_active))
7565 && (w == XWINDOW (current_buffer->last_selected_window)
7566 || highlight_nonselected_windows)
7567 && NILP (w->region_showing)
7568 && NILP (Vshow_trailing_whitespace)
7569 && !cursor_in_echo_area)
7571 struct it it;
7572 struct glyph_row *row;
7574 /* Skip from tlbufpos to PT and see where it is. Note that
7575 PT may be in invisible text. If so, we will end at the
7576 next visible position. */
7577 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
7578 NULL, DEFAULT_FACE_ID);
7579 it.current_x = this_line_start_x;
7580 it.current_y = this_line_y;
7581 it.vpos = this_line_vpos;
7583 /* The call to move_it_to stops in front of PT, but
7584 moves over before-strings. */
7585 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
7587 if (it.vpos == this_line_vpos
7588 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
7589 row->enabled_p))
7591 xassert (this_line_vpos == it.vpos);
7592 xassert (this_line_y == it.current_y);
7593 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
7594 goto update;
7596 else
7597 goto cancel;
7600 cancel:
7601 /* Text changed drastically or point moved off of line. */
7602 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
7605 CHARPOS (this_line_start_pos) = 0;
7606 consider_all_windows_p |= buffer_shared > 1;
7607 ++clear_face_cache_count;
7610 /* Build desired matrices. If consider_all_windows_p is non-zero,
7611 do it for all windows on all frames. Otherwise do it for
7612 selected_window, only. */
7614 if (consider_all_windows_p)
7616 Lisp_Object tail, frame;
7618 /* Clear the face cache eventually. */
7619 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
7621 clear_face_cache (0);
7622 clear_face_cache_count = 0;
7625 /* Recompute # windows showing selected buffer. This will be
7626 incremented each time such a window is displayed. */
7627 buffer_shared = 0;
7629 FOR_EACH_FRAME (tail, frame)
7631 struct frame *f = XFRAME (frame);
7632 if (FRAME_WINDOW_P (f) || f == sf)
7634 /* Mark all the scroll bars to be removed; we'll redeem
7635 the ones we want when we redisplay their windows. */
7636 if (condemn_scroll_bars_hook)
7637 (*condemn_scroll_bars_hook) (f);
7639 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
7640 redisplay_windows (FRAME_ROOT_WINDOW (f));
7642 /* Any scroll bars which redisplay_windows should have
7643 nuked should now go away. */
7644 if (judge_scroll_bars_hook)
7645 (*judge_scroll_bars_hook) (f);
7649 else if (FRAME_VISIBLE_P (sf)
7650 && !FRAME_OBSCURED_P (sf))
7651 redisplay_window (selected_window, 1);
7654 /* Compare desired and current matrices, perform output. */
7656 update:
7658 /* If fonts changed, display again. */
7659 if (fonts_changed_p)
7660 goto retry;
7662 /* Prevent various kinds of signals during display update.
7663 stdio is not robust about handling signals,
7664 which can cause an apparent I/O error. */
7665 if (interrupt_input)
7666 unrequest_sigio ();
7667 stop_polling ();
7669 if (consider_all_windows_p)
7671 Lisp_Object tail;
7672 struct frame *f;
7673 int hscrolled_p;
7675 pause = 0;
7676 hscrolled_p = 0;
7678 /* See if we have to hscroll. */
7679 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
7680 if (FRAMEP (XCAR (tail)))
7682 f = XFRAME (XCAR (tail));
7684 if ((FRAME_WINDOW_P (f)
7685 || f == sf)
7686 && FRAME_VISIBLE_P (f)
7687 && !FRAME_OBSCURED_P (f)
7688 && hscroll_windows (f->root_window))
7689 hscrolled_p = 1;
7692 if (hscrolled_p)
7693 goto retry;
7695 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
7697 if (!FRAMEP (XCAR (tail)))
7698 continue;
7700 f = XFRAME (XCAR (tail));
7702 if ((FRAME_WINDOW_P (f) || f == sf)
7703 && FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
7705 /* Mark all windows as to be updated. */
7706 set_window_update_flags (XWINDOW (f->root_window), 1);
7707 pause |= update_frame (f, 0, 0);
7708 if (!pause)
7710 mark_window_display_accurate (f->root_window, 1);
7711 if (frame_up_to_date_hook != 0)
7712 (*frame_up_to_date_hook) (f);
7717 else
7719 if (FRAME_VISIBLE_P (sf)
7720 && !FRAME_OBSCURED_P (sf))
7722 if (hscroll_windows (selected_window))
7723 goto retry;
7725 XWINDOW (selected_window)->must_be_updated_p = 1;
7726 pause = update_frame (sf, 0, 0);
7728 else
7729 pause = 0;
7731 /* We may have called echo_area_display at the top of this
7732 function. If the echo area is on another frame, that may
7733 have put text on a frame other than the selected one, so the
7734 above call to update_frame would not have caught it. Catch
7735 it here. */
7737 Lisp_Object mini_window;
7738 struct frame *mini_frame;
7740 mini_window = FRAME_MINIBUF_WINDOW (sf);
7741 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7743 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
7745 XWINDOW (mini_window)->must_be_updated_p = 1;
7746 pause |= update_frame (mini_frame, 0, 0);
7747 if (!pause && hscroll_windows (mini_window))
7748 goto retry;
7753 /* If display was paused because of pending input, make sure we do a
7754 thorough update the next time. */
7755 if (pause)
7757 /* Prevent the optimization at the beginning of
7758 redisplay_internal that tries a single-line update of the
7759 line containing the cursor in the selected window. */
7760 CHARPOS (this_line_start_pos) = 0;
7762 /* Let the overlay arrow be updated the next time. */
7763 if (!NILP (last_arrow_position))
7765 last_arrow_position = Qt;
7766 last_arrow_string = Qt;
7769 /* If we pause after scrolling, some rows in the current
7770 matrices of some windows are not valid. */
7771 if (!WINDOW_FULL_WIDTH_P (w)
7772 && !FRAME_WINDOW_P (XFRAME (w->frame)))
7773 update_mode_lines = 1;
7776 /* Now text on frame agrees with windows, so put info into the
7777 windows for partial redisplay to follow. */
7778 if (!pause)
7780 register struct buffer *b = XBUFFER (w->buffer);
7782 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
7783 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
7784 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
7785 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
7787 if (consider_all_windows_p)
7788 mark_window_display_accurate (FRAME_ROOT_WINDOW (sf), 1);
7789 else
7791 XSETFASTINT (w->last_point, BUF_PT (b));
7792 w->last_cursor = w->cursor;
7793 w->last_cursor_off_p = w->cursor_off_p;
7795 b->clip_changed = 0;
7796 b->prevent_redisplay_optimizations_p = 0;
7797 w->update_mode_line = Qnil;
7798 XSETFASTINT (w->last_modified, BUF_MODIFF (b));
7799 XSETFASTINT (w->last_overlay_modified, BUF_OVERLAY_MODIFF (b));
7800 w->last_had_star
7801 = (BUF_MODIFF (XBUFFER (w->buffer)) > BUF_SAVE_MODIFF (XBUFFER (w->buffer))
7802 ? Qt : Qnil);
7804 /* Record if we are showing a region, so can make sure to
7805 update it fully at next redisplay. */
7806 w->region_showing = (!NILP (Vtransient_mark_mode)
7807 && (w == XWINDOW (current_buffer->last_selected_window)
7808 || highlight_nonselected_windows)
7809 && !NILP (XBUFFER (w->buffer)->mark_active)
7810 ? Fmarker_position (XBUFFER (w->buffer)->mark)
7811 : Qnil);
7813 w->window_end_valid = w->buffer;
7814 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
7815 last_arrow_string = Voverlay_arrow_string;
7816 if (frame_up_to_date_hook != 0)
7817 (*frame_up_to_date_hook) (sf);
7819 w->current_matrix->buffer = b;
7820 w->current_matrix->begv = BUF_BEGV (b);
7821 w->current_matrix->zv = BUF_ZV (b);
7824 update_mode_lines = 0;
7825 windows_or_buffers_changed = 0;
7828 /* Start SIGIO interrupts coming again. Having them off during the
7829 code above makes it less likely one will discard output, but not
7830 impossible, since there might be stuff in the system buffer here.
7831 But it is much hairier to try to do anything about that. */
7832 if (interrupt_input)
7833 request_sigio ();
7834 start_polling ();
7836 /* If a frame has become visible which was not before, redisplay
7837 again, so that we display it. Expose events for such a frame
7838 (which it gets when becoming visible) don't call the parts of
7839 redisplay constructing glyphs, so simply exposing a frame won't
7840 display anything in this case. So, we have to display these
7841 frames here explicitly. */
7842 if (!pause)
7844 Lisp_Object tail, frame;
7845 int new_count = 0;
7847 FOR_EACH_FRAME (tail, frame)
7849 int this_is_visible = 0;
7851 if (XFRAME (frame)->visible)
7852 this_is_visible = 1;
7853 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
7854 if (XFRAME (frame)->visible)
7855 this_is_visible = 1;
7857 if (this_is_visible)
7858 new_count++;
7861 if (new_count != number_of_visible_frames)
7862 windows_or_buffers_changed++;
7865 /* Change frame size now if a change is pending. */
7866 do_pending_window_change (1);
7868 /* If we just did a pending size change, or have additional
7869 visible frames, redisplay again. */
7870 if (windows_or_buffers_changed && !pause)
7871 goto retry;
7873 end_of_redisplay:;
7875 unbind_to (count, Qnil);
7879 /* Redisplay, but leave alone any recent echo area message unless
7880 another message has been requested in its place.
7882 This is useful in situations where you need to redisplay but no
7883 user action has occurred, making it inappropriate for the message
7884 area to be cleared. See tracking_off and
7885 wait_reading_process_input for examples of these situations. */
7887 void
7888 redisplay_preserve_echo_area ()
7890 if (!NILP (echo_area_buffer[1]))
7892 /* We have a previously displayed message, but no current
7893 message. Redisplay the previous message. */
7894 display_last_displayed_message_p = 1;
7895 redisplay_internal (1);
7896 display_last_displayed_message_p = 0;
7898 else
7899 redisplay_internal (1);
7903 /* Function registered with record_unwind_protect in
7904 redisplay_internal. Clears the flag indicating that a redisplay is
7905 in progress. */
7907 static Lisp_Object
7908 unwind_redisplay (old_redisplaying_p)
7909 Lisp_Object old_redisplaying_p;
7911 redisplaying_p = XFASTINT (old_redisplaying_p);
7912 return Qnil;
7916 /* Mark the display of windows in the window tree rooted at WINDOW as
7917 accurate or inaccurate. If FLAG is non-zero mark display of WINDOW
7918 as accurate. If FLAG is zero arrange for WINDOW to be redisplayed
7919 the next time redisplay_internal is called. */
7921 void
7922 mark_window_display_accurate (window, accurate_p)
7923 Lisp_Object window;
7924 int accurate_p;
7926 struct window *w;
7928 for (; !NILP (window); window = w->next)
7930 w = XWINDOW (window);
7932 if (BUFFERP (w->buffer))
7934 struct buffer *b = XBUFFER (w->buffer);
7936 XSETFASTINT (w->last_modified,
7937 accurate_p ? BUF_MODIFF (b) : 0);
7938 XSETFASTINT (w->last_overlay_modified,
7939 accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
7940 w->last_had_star = (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b)
7941 ? Qt : Qnil);
7943 #if 0 /* I don't think this is necessary because display_line does it.
7944 Let's check it. */
7945 /* Record if we are showing a region, so can make sure to
7946 update it fully at next redisplay. */
7947 w->region_showing
7948 = (!NILP (Vtransient_mark_mode)
7949 && (w == XWINDOW (current_buffer->last_selected_window)
7950 || highlight_nonselected_windows)
7951 && (!NILP (b->mark_active)
7952 ? Fmarker_position (b->mark)
7953 : Qnil));
7954 #endif
7956 if (accurate_p)
7958 b->clip_changed = 0;
7959 b->prevent_redisplay_optimizations_p = 0;
7960 w->current_matrix->buffer = b;
7961 w->current_matrix->begv = BUF_BEGV (b);
7962 w->current_matrix->zv = BUF_ZV (b);
7963 w->last_cursor = w->cursor;
7964 w->last_cursor_off_p = w->cursor_off_p;
7965 if (w == XWINDOW (selected_window))
7966 w->last_point = make_number (BUF_PT (b));
7967 else
7968 w->last_point = make_number (XMARKER (w->pointm)->charpos);
7972 w->window_end_valid = w->buffer;
7973 w->update_mode_line = Qnil;
7975 if (!NILP (w->vchild))
7976 mark_window_display_accurate (w->vchild, accurate_p);
7977 if (!NILP (w->hchild))
7978 mark_window_display_accurate (w->hchild, accurate_p);
7981 if (accurate_p)
7983 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
7984 last_arrow_string = Voverlay_arrow_string;
7986 else
7988 /* Force a thorough redisplay the next time by setting
7989 last_arrow_position and last_arrow_string to t, which is
7990 unequal to any useful value of Voverlay_arrow_... */
7991 last_arrow_position = Qt;
7992 last_arrow_string = Qt;
7997 /* Return value in display table DP (Lisp_Char_Table *) for character
7998 C. Since a display table doesn't have any parent, we don't have to
7999 follow parent. Do not call this function directly but use the
8000 macro DISP_CHAR_VECTOR. */
8002 Lisp_Object
8003 disp_char_vector (dp, c)
8004 struct Lisp_Char_Table *dp;
8005 int c;
8007 int code[4], i;
8008 Lisp_Object val;
8010 if (SINGLE_BYTE_CHAR_P (c))
8011 return (dp->contents[c]);
8013 SPLIT_CHAR (c, code[0], code[1], code[2]);
8014 if (code[1] < 32)
8015 code[1] = -1;
8016 else if (code[2] < 32)
8017 code[2] = -1;
8019 /* Here, the possible range of code[0] (== charset ID) is
8020 128..max_charset. Since the top level char table contains data
8021 for multibyte characters after 256th element, we must increment
8022 code[0] by 128 to get a correct index. */
8023 code[0] += 128;
8024 code[3] = -1; /* anchor */
8026 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
8028 val = dp->contents[code[i]];
8029 if (!SUB_CHAR_TABLE_P (val))
8030 return (NILP (val) ? dp->defalt : val);
8033 /* Here, val is a sub char table. We return the default value of
8034 it. */
8035 return (dp->defalt);
8040 /***********************************************************************
8041 Window Redisplay
8042 ***********************************************************************/
8044 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
8046 static void
8047 redisplay_windows (window)
8048 Lisp_Object window;
8050 while (!NILP (window))
8052 struct window *w = XWINDOW (window);
8054 if (!NILP (w->hchild))
8055 redisplay_windows (w->hchild);
8056 else if (!NILP (w->vchild))
8057 redisplay_windows (w->vchild);
8058 else
8059 redisplay_window (window, 0);
8061 window = w->next;
8066 /* Set cursor position of W. PT is assumed to be displayed in ROW.
8067 DELTA is the number of bytes by which positions recorded in ROW
8068 differ from current buffer positions. */
8070 void
8071 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
8072 struct window *w;
8073 struct glyph_row *row;
8074 struct glyph_matrix *matrix;
8075 int delta, delta_bytes, dy, dvpos;
8077 struct glyph *glyph = row->glyphs[TEXT_AREA];
8078 struct glyph *end = glyph + row->used[TEXT_AREA];
8079 int x = row->x;
8080 int pt_old = PT - delta;
8082 /* Skip over glyphs not having an object at the start of the row.
8083 These are special glyphs like truncation marks on terminal
8084 frames. */
8085 if (row->displays_text_p)
8086 while (glyph < end
8087 && INTEGERP (glyph->object)
8088 && glyph->charpos < 0)
8090 x += glyph->pixel_width;
8091 ++glyph;
8094 while (glyph < end
8095 && !INTEGERP (glyph->object)
8096 && (!BUFFERP (glyph->object)
8097 || glyph->charpos < pt_old))
8099 x += glyph->pixel_width;
8100 ++glyph;
8103 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
8104 w->cursor.x = x;
8105 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
8106 w->cursor.y = row->y + dy;
8108 if (w == XWINDOW (selected_window))
8110 if (!row->continued_p
8111 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
8112 && row->x == 0)
8114 this_line_buffer = XBUFFER (w->buffer);
8116 CHARPOS (this_line_start_pos)
8117 = MATRIX_ROW_START_CHARPOS (row) + delta;
8118 BYTEPOS (this_line_start_pos)
8119 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
8121 CHARPOS (this_line_end_pos)
8122 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
8123 BYTEPOS (this_line_end_pos)
8124 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
8126 this_line_y = w->cursor.y;
8127 this_line_pixel_height = row->height;
8128 this_line_vpos = w->cursor.vpos;
8129 this_line_start_x = row->x;
8131 else
8132 CHARPOS (this_line_start_pos) = 0;
8137 /* Run window scroll functions, if any, for WINDOW with new window
8138 start STARTP. Sets the window start of WINDOW to that position.
8140 We assume that the window's buffer is really current. */
8142 static INLINE struct text_pos
8143 run_window_scroll_functions (window, startp)
8144 Lisp_Object window;
8145 struct text_pos startp;
8147 struct window *w = XWINDOW (window);
8148 SET_MARKER_FROM_TEXT_POS (w->start, startp);
8150 if (current_buffer != XBUFFER (w->buffer))
8151 abort ();
8153 if (!NILP (Vwindow_scroll_functions))
8155 run_hook_with_args_2 (Qwindow_scroll_functions, window,
8156 make_number (CHARPOS (startp)));
8157 SET_TEXT_POS_FROM_MARKER (startp, w->start);
8158 /* In case the hook functions switch buffers. */
8159 if (current_buffer != XBUFFER (w->buffer))
8160 set_buffer_internal_1 (XBUFFER (w->buffer));
8163 return startp;
8167 /* Modify the desired matrix of window W and W->vscroll so that the
8168 line containing the cursor is fully visible. */
8170 static void
8171 make_cursor_line_fully_visible (w)
8172 struct window *w;
8174 struct glyph_matrix *matrix;
8175 struct glyph_row *row;
8176 int header_line_height;
8178 /* It's not always possible to find the cursor, e.g, when a window
8179 is full of overlay strings. Don't do anything in that case. */
8180 if (w->cursor.vpos < 0)
8181 return;
8183 matrix = w->desired_matrix;
8184 row = MATRIX_ROW (matrix, w->cursor.vpos);
8186 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row)
8187 /* The row may be partially visible at the top because we
8188 already have chosen a vscroll to align the bottom of the
8189 row with the bottom of the window. This happens for rows
8190 taller than the window. */
8191 && row->y + row->height < window_box_height (w))
8193 int dy = row->height - row->visible_height;
8194 w->vscroll = 0;
8195 w->cursor.y += dy;
8196 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
8198 else if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)
8199 /* The row may be partially visible at the bottom because
8200 we chose a vscroll to align the row's top with the
8201 window's top. This happens for rows taller than the
8202 window. */
8203 && row->y > WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w))
8205 int dy = - (row->height - row->visible_height);
8206 w->vscroll = dy;
8207 w->cursor.y += dy;
8208 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
8211 /* When we change the cursor y-position of the selected window,
8212 change this_line_y as well so that the display optimization for
8213 the cursor line of the selected window in redisplay_internal uses
8214 the correct y-position. */
8215 if (w == XWINDOW (selected_window))
8216 this_line_y = w->cursor.y;
8220 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
8221 non-zero means only WINDOW is redisplayed in redisplay_internal.
8222 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
8223 in redisplay_window to bring a partially visible line into view in
8224 the case that only the cursor has moved.
8226 Value is
8228 1 if scrolling succeeded
8230 0 if scrolling didn't find point.
8232 -1 if new fonts have been loaded so that we must interrupt
8233 redisplay, adjust glyph matrices, and try again. */
8235 static int
8236 try_scrolling (window, just_this_one_p, scroll_conservatively,
8237 scroll_step, temp_scroll_step)
8238 Lisp_Object window;
8239 int just_this_one_p;
8240 int scroll_conservatively, scroll_step;
8241 int temp_scroll_step;
8243 struct window *w = XWINDOW (window);
8244 struct frame *f = XFRAME (w->frame);
8245 struct text_pos scroll_margin_pos;
8246 struct text_pos pos;
8247 struct text_pos startp;
8248 struct it it;
8249 Lisp_Object window_end;
8250 int this_scroll_margin;
8251 int dy = 0;
8252 int scroll_max;
8253 int line_height, rc;
8254 int amount_to_scroll = 0;
8255 Lisp_Object aggressive;
8256 int height;
8258 #if GLYPH_DEBUG
8259 debug_method_add (w, "try_scrolling");
8260 #endif
8262 SET_TEXT_POS_FROM_MARKER (startp, w->start);
8264 /* Compute scroll margin height in pixels. We scroll when point is
8265 within this distance from the top or bottom of the window. */
8266 if (scroll_margin > 0)
8268 this_scroll_margin = min (scroll_margin, XINT (w->height) / 4);
8269 this_scroll_margin *= CANON_Y_UNIT (f);
8271 else
8272 this_scroll_margin = 0;
8274 /* Compute how much we should try to scroll maximally to bring point
8275 into view. */
8276 if (scroll_step)
8277 scroll_max = scroll_step;
8278 else if (scroll_conservatively)
8279 scroll_max = scroll_conservatively;
8280 else if (temp_scroll_step)
8281 scroll_max = temp_scroll_step;
8282 else if (NUMBERP (current_buffer->scroll_down_aggressively)
8283 || NUMBERP (current_buffer->scroll_up_aggressively))
8284 /* We're trying to scroll because of aggressive scrolling
8285 but no scroll_step is set. Choose an arbitrary one. Maybe
8286 there should be a variable for this. */
8287 scroll_max = 10;
8288 else
8289 scroll_max = 0;
8290 scroll_max *= CANON_Y_UNIT (f);
8292 /* Decide whether we have to scroll down. Start at the window end
8293 and move this_scroll_margin up to find the position of the scroll
8294 margin. */
8295 window_end = Fwindow_end (window, Qt);
8296 CHARPOS (scroll_margin_pos) = XINT (window_end);
8297 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
8298 if (this_scroll_margin)
8300 start_display (&it, w, scroll_margin_pos);
8301 move_it_vertically (&it, - this_scroll_margin);
8302 scroll_margin_pos = it.current.pos;
8305 if (PT >= CHARPOS (scroll_margin_pos))
8307 int y0;
8309 /* Point is in the scroll margin at the bottom of the window, or
8310 below. Compute a new window start that makes point visible. */
8312 /* Compute the distance from the scroll margin to PT.
8313 Give up if the distance is greater than scroll_max. */
8314 start_display (&it, w, scroll_margin_pos);
8315 y0 = it.current_y;
8316 move_it_to (&it, PT, 0, it.last_visible_y, -1,
8317 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
8318 line_height = (it.max_ascent + it.max_descent
8319 ? it.max_ascent + it.max_descent
8320 : last_height);
8321 dy = it.current_y + line_height - y0;
8322 if (dy > scroll_max)
8323 return 0;
8325 /* Move the window start down. If scrolling conservatively,
8326 move it just enough down to make point visible. If
8327 scroll_step is set, move it down by scroll_step. */
8328 start_display (&it, w, startp);
8330 if (scroll_conservatively)
8331 amount_to_scroll = dy;
8332 else if (scroll_step || temp_scroll_step)
8333 amount_to_scroll = scroll_max;
8334 else
8336 aggressive = current_buffer->scroll_down_aggressively;
8337 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
8338 - WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w));
8339 if (NUMBERP (aggressive))
8340 amount_to_scroll = XFLOATINT (aggressive) * height;
8343 if (amount_to_scroll <= 0)
8344 return 0;
8346 move_it_vertically (&it, amount_to_scroll);
8347 startp = it.current.pos;
8349 else
8351 /* See if point is inside the scroll margin at the top of the
8352 window. */
8353 scroll_margin_pos = startp;
8354 if (this_scroll_margin)
8356 start_display (&it, w, startp);
8357 move_it_vertically (&it, this_scroll_margin);
8358 scroll_margin_pos = it.current.pos;
8361 if (PT < CHARPOS (scroll_margin_pos))
8363 /* Point is in the scroll margin at the top of the window or
8364 above what is displayed in the window. */
8365 int y0;
8367 /* Compute the vertical distance from PT to the scroll
8368 margin position. Give up if distance is greater than
8369 scroll_max. */
8370 SET_TEXT_POS (pos, PT, PT_BYTE);
8371 start_display (&it, w, pos);
8372 y0 = it.current_y;
8373 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
8374 it.last_visible_y, -1,
8375 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
8376 dy = it.current_y - y0;
8377 if (dy > scroll_max)
8378 return 0;
8380 /* Compute new window start. */
8381 start_display (&it, w, startp);
8383 if (scroll_conservatively)
8384 amount_to_scroll = dy;
8385 else if (scroll_step || temp_scroll_step)
8386 amount_to_scroll = scroll_max;
8387 else
8389 aggressive = current_buffer->scroll_up_aggressively;
8390 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
8391 - WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w));
8392 if (NUMBERP (aggressive))
8393 amount_to_scroll = XFLOATINT (aggressive) * height;
8396 if (amount_to_scroll <= 0)
8397 return 0;
8399 move_it_vertically (&it, - amount_to_scroll);
8400 startp = it.current.pos;
8404 /* Run window scroll functions. */
8405 startp = run_window_scroll_functions (window, startp);
8407 /* Display the window. Give up if new fonts are loaded, or if point
8408 doesn't appear. */
8409 if (!try_window (window, startp))
8410 rc = -1;
8411 else if (w->cursor.vpos < 0)
8413 clear_glyph_matrix (w->desired_matrix);
8414 rc = 0;
8416 else
8418 /* Maybe forget recorded base line for line number display. */
8419 if (!just_this_one_p
8420 || current_buffer->clip_changed
8421 || BEG_UNCHANGED < CHARPOS (startp))
8422 w->base_line_number = Qnil;
8424 /* If cursor ends up on a partially visible line, shift display
8425 lines up or down. */
8426 make_cursor_line_fully_visible (w);
8427 rc = 1;
8430 return rc;
8434 /* Compute a suitable window start for window W if display of W starts
8435 on a continuation line. Value is non-zero if a new window start
8436 was computed.
8438 The new window start will be computed, based on W's width, starting
8439 from the start of the continued line. It is the start of the
8440 screen line with the minimum distance from the old start W->start. */
8442 static int
8443 compute_window_start_on_continuation_line (w)
8444 struct window *w;
8446 struct text_pos pos, start_pos;
8447 int window_start_changed_p = 0;
8449 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
8451 /* If window start is on a continuation line... Window start may be
8452 < BEGV in case there's invisible text at the start of the
8453 buffer (M-x rmail, for example). */
8454 if (CHARPOS (start_pos) > BEGV
8455 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
8457 struct it it;
8458 struct glyph_row *row;
8460 /* Handle the case that the window start is out of range. */
8461 if (CHARPOS (start_pos) < BEGV)
8462 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
8463 else if (CHARPOS (start_pos) > ZV)
8464 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
8466 /* Find the start of the continued line. This should be fast
8467 because scan_buffer is fast (newline cache). */
8468 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
8469 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
8470 row, DEFAULT_FACE_ID);
8471 reseat_at_previous_visible_line_start (&it);
8473 /* If the line start is "too far" away from the window start,
8474 say it takes too much time to compute a new window start. */
8475 if (CHARPOS (start_pos) - IT_CHARPOS (it)
8476 < XFASTINT (w->height) * XFASTINT (w->width))
8478 int min_distance, distance;
8480 /* Move forward by display lines to find the new window
8481 start. If window width was enlarged, the new start can
8482 be expected to be > the old start. If window width was
8483 decreased, the new window start will be < the old start.
8484 So, we're looking for the display line start with the
8485 minimum distance from the old window start. */
8486 pos = it.current.pos;
8487 min_distance = INFINITY;
8488 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
8489 distance < min_distance)
8491 min_distance = distance;
8492 pos = it.current.pos;
8493 move_it_by_lines (&it, 1, 0);
8496 /* Set the window start there. */
8497 SET_MARKER_FROM_TEXT_POS (w->start, pos);
8498 window_start_changed_p = 1;
8502 return window_start_changed_p;
8506 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
8507 selected_window is redisplayed. */
8509 static void
8510 redisplay_window (window, just_this_one_p)
8511 Lisp_Object window;
8512 int just_this_one_p;
8514 struct window *w = XWINDOW (window);
8515 struct frame *f = XFRAME (w->frame);
8516 struct buffer *buffer = XBUFFER (w->buffer);
8517 struct buffer *old = current_buffer;
8518 struct text_pos lpoint, opoint, startp;
8519 int update_mode_line;
8520 int tem;
8521 struct it it;
8522 /* Record it now because it's overwritten. */
8523 int current_matrix_up_to_date_p = 0;
8524 int temp_scroll_step = 0;
8525 int count = specpdl_ptr - specpdl;
8527 SET_TEXT_POS (lpoint, PT, PT_BYTE);
8528 opoint = lpoint;
8530 /* W must be a leaf window here. */
8531 xassert (!NILP (w->buffer));
8532 #if GLYPH_DEBUG
8533 *w->desired_matrix->method = 0;
8534 #endif
8536 specbind (Qinhibit_point_motion_hooks, Qt);
8538 reconsider_clip_changes (w, buffer);
8540 /* Has the mode line to be updated? */
8541 update_mode_line = (!NILP (w->update_mode_line)
8542 || update_mode_lines
8543 || buffer->clip_changed);
8545 if (MINI_WINDOW_P (w))
8547 if (w == XWINDOW (echo_area_window)
8548 && !NILP (echo_area_buffer[0]))
8550 if (update_mode_line)
8551 /* We may have to update a tty frame's menu bar or a
8552 tool-bar. Example `M-x C-h C-h C-g'. */
8553 goto finish_menu_bars;
8554 else
8555 /* We've already displayed the echo area glyphs in this window. */
8556 goto finish_scroll_bars;
8558 else if (w != XWINDOW (minibuf_window))
8560 /* W is a mini-buffer window, but it's not the currently
8561 active one, so clear it. */
8562 int yb = window_text_bottom_y (w);
8563 struct glyph_row *row;
8564 int y;
8566 for (y = 0, row = w->desired_matrix->rows;
8567 y < yb;
8568 y += row->height, ++row)
8569 blank_row (w, row, y);
8570 goto finish_scroll_bars;
8574 /* Otherwise set up data on this window; select its buffer and point
8575 value. */
8576 /* Really select the buffer, for the sake of buffer-local
8577 variables. */
8578 set_buffer_internal_1 (XBUFFER (w->buffer));
8579 SET_TEXT_POS (opoint, PT, PT_BYTE);
8581 current_matrix_up_to_date_p
8582 = (!NILP (w->window_end_valid)
8583 && !current_buffer->clip_changed
8584 && XFASTINT (w->last_modified) >= MODIFF
8585 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
8587 /* When windows_or_buffers_changed is non-zero, we can't rely on
8588 the window end being valid, so set it to nil there. */
8589 if (windows_or_buffers_changed)
8591 /* If window starts on a continuation line, maybe adjust the
8592 window start in case the window's width changed. */
8593 if (XMARKER (w->start)->buffer == current_buffer)
8594 compute_window_start_on_continuation_line (w);
8596 w->window_end_valid = Qnil;
8599 /* Some sanity checks. */
8600 CHECK_WINDOW_END (w);
8601 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
8602 abort ();
8603 if (BYTEPOS (opoint) < CHARPOS (opoint))
8604 abort ();
8606 /* If %c is in mode line, update it if needed. */
8607 if (!NILP (w->column_number_displayed)
8608 /* This alternative quickly identifies a common case
8609 where no change is needed. */
8610 && !(PT == XFASTINT (w->last_point)
8611 && XFASTINT (w->last_modified) >= MODIFF
8612 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
8613 && XFASTINT (w->column_number_displayed) != current_column ())
8614 update_mode_line = 1;
8616 /* Count number of windows showing the selected buffer. An indirect
8617 buffer counts as its base buffer. */
8618 if (!just_this_one_p)
8620 struct buffer *current_base, *window_base;
8621 current_base = current_buffer;
8622 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
8623 if (current_base->base_buffer)
8624 current_base = current_base->base_buffer;
8625 if (window_base->base_buffer)
8626 window_base = window_base->base_buffer;
8627 if (current_base == window_base)
8628 buffer_shared++;
8631 /* Point refers normally to the selected window. For any other
8632 window, set up appropriate value. */
8633 if (!EQ (window, selected_window))
8635 int new_pt = XMARKER (w->pointm)->charpos;
8636 int new_pt_byte = marker_byte_position (w->pointm);
8637 if (new_pt < BEGV)
8639 new_pt = BEGV;
8640 new_pt_byte = BEGV_BYTE;
8641 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
8643 else if (new_pt > (ZV - 1))
8645 new_pt = ZV;
8646 new_pt_byte = ZV_BYTE;
8647 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
8650 /* We don't use SET_PT so that the point-motion hooks don't run. */
8651 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
8654 /* If any of the character widths specified in the display table
8655 have changed, invalidate the width run cache. It's true that
8656 this may be a bit late to catch such changes, but the rest of
8657 redisplay goes (non-fatally) haywire when the display table is
8658 changed, so why should we worry about doing any better? */
8659 if (current_buffer->width_run_cache)
8661 struct Lisp_Char_Table *disptab = buffer_display_table ();
8663 if (! disptab_matches_widthtab (disptab,
8664 XVECTOR (current_buffer->width_table)))
8666 invalidate_region_cache (current_buffer,
8667 current_buffer->width_run_cache,
8668 BEG, Z);
8669 recompute_width_table (current_buffer, disptab);
8673 /* If window-start is screwed up, choose a new one. */
8674 if (XMARKER (w->start)->buffer != current_buffer)
8675 goto recenter;
8677 SET_TEXT_POS_FROM_MARKER (startp, w->start);
8679 /* If someone specified a new starting point but did not insist,
8680 check whether it can be used. */
8681 if (!NILP (w->optional_new_start)
8682 && CHARPOS (startp) >= BEGV
8683 && CHARPOS (startp) <= ZV)
8685 w->optional_new_start = Qnil;
8686 /* This takes a mini-buffer prompt into account. */
8687 start_display (&it, w, startp);
8688 move_it_to (&it, PT, 0, it.last_visible_y, -1,
8689 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
8690 if (IT_CHARPOS (it) == PT)
8691 w->force_start = Qt;
8694 /* Handle case where place to start displaying has been specified,
8695 unless the specified location is outside the accessible range. */
8696 if (!NILP (w->force_start)
8697 || w->frozen_window_start_p)
8699 w->force_start = Qnil;
8700 w->vscroll = 0;
8701 w->window_end_valid = Qnil;
8703 /* Forget any recorded base line for line number display. */
8704 if (!current_matrix_up_to_date_p
8705 || current_buffer->clip_changed)
8706 w->base_line_number = Qnil;
8708 /* Redisplay the mode line. Select the buffer properly for that.
8709 Also, run the hook window-scroll-functions
8710 because we have scrolled. */
8711 /* Note, we do this after clearing force_start because
8712 if there's an error, it is better to forget about force_start
8713 than to get into an infinite loop calling the hook functions
8714 and having them get more errors. */
8715 if (!update_mode_line
8716 || ! NILP (Vwindow_scroll_functions))
8718 update_mode_line = 1;
8719 w->update_mode_line = Qt;
8720 startp = run_window_scroll_functions (window, startp);
8723 XSETFASTINT (w->last_modified, 0);
8724 XSETFASTINT (w->last_overlay_modified, 0);
8725 if (CHARPOS (startp) < BEGV)
8726 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
8727 else if (CHARPOS (startp) > ZV)
8728 SET_TEXT_POS (startp, ZV, ZV_BYTE);
8730 /* Redisplay, then check if cursor has been set during the
8731 redisplay. Give up if new fonts were loaded. */
8732 if (!try_window (window, startp))
8734 w->force_start = Qt;
8735 clear_glyph_matrix (w->desired_matrix);
8736 goto restore_buffers;
8739 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
8741 /* If point does not appear, or on a line that is not fully
8742 visible, move point so it does appear. The desired
8743 matrix has been built above, so we can use it. */
8744 int height = window_box_height (w) / 2;
8745 struct glyph_row *row = MATRIX_ROW (w->desired_matrix, 0);
8747 while (row->y < height)
8748 ++row;
8750 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
8751 MATRIX_ROW_START_BYTEPOS (row));
8753 if (w != XWINDOW (selected_window))
8754 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
8755 else if (current_buffer == old)
8756 SET_TEXT_POS (lpoint, PT, PT_BYTE);
8758 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
8760 /* If we are highlighting the region, then we just changed
8761 the region, so redisplay to show it. */
8762 if (!NILP (Vtransient_mark_mode)
8763 && !NILP (current_buffer->mark_active))
8765 clear_glyph_matrix (w->desired_matrix);
8766 if (!try_window (window, startp))
8767 goto restore_buffers;
8771 make_cursor_line_fully_visible (w);
8772 #if GLYPH_DEBUG
8773 debug_method_add (w, "forced window start");
8774 #endif
8775 goto done;
8778 /* Handle case where text has not changed, only point, and it has
8779 not moved off the frame. */
8780 if (current_matrix_up_to_date_p
8781 /* Point may be in this window. */
8782 && PT >= CHARPOS (startp)
8783 /* If we don't check this, we are called to move the cursor in a
8784 horizontally split window with a current matrix that doesn't
8785 fit the display. */
8786 && !windows_or_buffers_changed
8787 /* Selective display hasn't changed. */
8788 && !current_buffer->clip_changed
8789 /* If force-mode-line-update was called, really redisplay;
8790 that's how redisplay is forced after e.g. changing
8791 buffer-invisibility-spec. */
8792 && NILP (w->update_mode_line)
8793 /* Can't use this case if highlighting a region. When a
8794 region exists, cursor movement has to do more than just
8795 set the cursor. */
8796 && !(!NILP (Vtransient_mark_mode)
8797 && !NILP (current_buffer->mark_active))
8798 && NILP (w->region_showing)
8799 && NILP (Vshow_trailing_whitespace)
8800 /* Right after splitting windows, last_point may be nil. */
8801 && INTEGERP (w->last_point)
8802 /* This code is not used for mini-buffer for the sake of the case
8803 of redisplaying to replace an echo area message; since in
8804 that case the mini-buffer contents per se are usually
8805 unchanged. This code is of no real use in the mini-buffer
8806 since the handling of this_line_start_pos, etc., in redisplay
8807 handles the same cases. */
8808 && !EQ (window, minibuf_window)
8809 /* When splitting windows or for new windows, it happens that
8810 redisplay is called with a nil window_end_vpos or one being
8811 larger than the window. This should really be fixed in
8812 window.c. I don't have this on my list, now, so we do
8813 approximately the same as the old redisplay code. --gerd. */
8814 && INTEGERP (w->window_end_vpos)
8815 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
8816 && (FRAME_WINDOW_P (f)
8817 || !MARKERP (Voverlay_arrow_position)
8818 || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
8820 int this_scroll_margin;
8821 struct glyph_row *row;
8822 int scroll_p;
8824 #if GLYPH_DEBUG
8825 debug_method_add (w, "cursor movement");
8826 #endif
8828 /* Scroll if point within this distance from the top or bottom
8829 of the window. This is a pixel value. */
8830 this_scroll_margin = max (0, scroll_margin);
8831 this_scroll_margin = min (this_scroll_margin, XFASTINT (w->height) / 4);
8832 this_scroll_margin *= CANON_Y_UNIT (f);
8834 /* Start with the row the cursor was displayed during the last
8835 not paused redisplay. Give up if that row is not valid. */
8836 if (w->last_cursor.vpos >= w->current_matrix->nrows)
8837 goto try_to_scroll;
8838 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
8839 if (row->mode_line_p)
8840 ++row;
8841 if (!row->enabled_p)
8842 goto try_to_scroll;
8844 scroll_p = 0;
8845 if (PT > XFASTINT (w->last_point))
8847 /* Point has moved forward. */
8848 int last_y = window_text_bottom_y (w) - this_scroll_margin;
8850 while (MATRIX_ROW_END_CHARPOS (row) < PT
8851 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
8853 xassert (row->enabled_p);
8854 ++row;
8857 /* The end position of a row equals the start position of
8858 the next row. If PT is there, we would rather display it
8859 in the next line. Exceptions are when the row ends in
8860 the middle of a character, or ends in ZV. */
8861 if (MATRIX_ROW_BOTTOM_Y (row) < last_y
8862 && MATRIX_ROW_END_CHARPOS (row) == PT
8863 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
8864 && !row->ends_at_zv_p)
8866 xassert (row->enabled_p);
8867 ++row;
8870 /* If within the scroll margin, scroll. Note that
8871 MATRIX_ROW_BOTTOM_Y gives the pixel position at which the
8872 next line would be drawn, and that this_scroll_margin can
8873 be zero. */
8874 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
8875 || PT > MATRIX_ROW_END_CHARPOS (row)
8876 /* Line is completely visible last line in window and PT
8877 is to be set in the next line. */
8878 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
8879 && PT == MATRIX_ROW_END_CHARPOS (row)
8880 && !row->ends_at_zv_p
8881 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
8882 scroll_p = 1;
8884 else if (PT < XFASTINT (w->last_point))
8886 /* Cursor has to be moved backward. Note that PT >=
8887 CHARPOS (startp) because of the outer if-statement. */
8888 while (!row->mode_line_p
8889 && (MATRIX_ROW_START_CHARPOS (row) > PT
8890 || (MATRIX_ROW_START_CHARPOS (row) == PT
8891 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
8892 && (row->y > this_scroll_margin
8893 || CHARPOS (startp) == BEGV))
8895 xassert (row->enabled_p);
8896 --row;
8899 /* Consider the following case: Window starts at BEGV, there
8900 is invisible, intangible text at BEGV, so that display
8901 starts at some point START > BEGV. It can happen that
8902 we are called with PT somewhere between BEGV and START.
8903 Try to handle that case. */
8904 if (row < w->current_matrix->rows
8905 || row->mode_line_p)
8907 row = w->current_matrix->rows;
8908 if (row->mode_line_p)
8909 ++row;
8912 /* Due to newlines in overlay strings, we may have to skip
8913 forward over overlay strings. */
8914 while (MATRIX_ROW_END_CHARPOS (row) == PT
8915 && MATRIX_ROW_ENDS_IN_OVERLAY_STRING_P (row)
8916 && !row->ends_at_zv_p)
8917 ++row;
8919 /* If within the scroll margin, scroll. */
8920 if (row->y < this_scroll_margin
8921 && CHARPOS (startp) != BEGV)
8922 scroll_p = 1;
8925 /* if PT is not in the glyph row, give up. */
8926 if (PT < MATRIX_ROW_START_CHARPOS (row)
8927 || PT > MATRIX_ROW_END_CHARPOS (row))
8928 goto try_to_scroll;
8930 /* If we end up in a partially visible line, let's make it fully
8931 visible. This can be done most easily by using the existing
8932 scrolling code. */
8933 if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
8935 temp_scroll_step = 1;
8936 goto try_to_scroll;
8938 else if (scroll_p)
8939 goto try_to_scroll;
8941 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
8942 goto done;
8945 /* If current starting point was originally the beginning of a line
8946 but no longer is, find a new starting point. */
8947 else if (!NILP (w->start_at_line_beg)
8948 && !(CHARPOS (startp) <= BEGV
8949 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
8951 #if GLYPH_DEBUG
8952 debug_method_add (w, "recenter 1");
8953 #endif
8954 goto recenter;
8957 /* Try scrolling with try_window_id. */
8958 else if (/* Windows and buffers haven't changed. */
8959 !windows_or_buffers_changed
8960 /* Window must be either use window-based redisplay or
8961 be full width. */
8962 && (FRAME_WINDOW_P (f)
8963 || (line_ins_del_ok && WINDOW_FULL_WIDTH_P (w)))
8964 && !MINI_WINDOW_P (w)
8965 /* Point is not known NOT to appear in window. */
8966 && PT >= CHARPOS (startp)
8967 && XFASTINT (w->last_modified)
8968 /* Window is not hscrolled. */
8969 && XFASTINT (w->hscroll) == 0
8970 /* Selective display has not changed. */
8971 && !current_buffer->clip_changed
8972 /* Current matrix is up to date. */
8973 && !NILP (w->window_end_valid)
8974 /* Can't use this case if highlighting a region because
8975 a cursor movement will do more than just set the cursor. */
8976 && !(!NILP (Vtransient_mark_mode)
8977 && !NILP (current_buffer->mark_active))
8978 && NILP (w->region_showing)
8979 && NILP (Vshow_trailing_whitespace)
8980 /* Overlay arrow position and string not changed. */
8981 && EQ (last_arrow_position, COERCE_MARKER (Voverlay_arrow_position))
8982 && EQ (last_arrow_string, Voverlay_arrow_string)
8983 /* Value is > 0 if update has been done, it is -1 if we
8984 know that the same window start will not work. It is 0
8985 if unsuccessful for some other reason. */
8986 && (tem = try_window_id (w)) != 0)
8988 #if GLYPH_DEBUG
8989 debug_method_add (w, "try_window_id");
8990 #endif
8992 if (fonts_changed_p)
8993 goto restore_buffers;
8994 if (tem > 0)
8995 goto done;
8996 /* Otherwise try_window_id has returned -1 which means that we
8997 don't want the alternative below this comment to execute. */
8999 else if (CHARPOS (startp) >= BEGV
9000 && CHARPOS (startp) <= ZV
9001 && PT >= CHARPOS (startp)
9002 && (CHARPOS (startp) < ZV
9003 /* Avoid starting at end of buffer. */
9004 || CHARPOS (startp) == BEGV
9005 || (XFASTINT (w->last_modified) >= MODIFF
9006 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
9008 #if GLYPH_DEBUG
9009 debug_method_add (w, "same window start");
9010 #endif
9012 /* Try to redisplay starting at same place as before.
9013 If point has not moved off frame, accept the results. */
9014 if (!current_matrix_up_to_date_p
9015 /* Don't use try_window_reusing_current_matrix in this case
9016 because a window scroll function can have changed the
9017 buffer. */
9018 || !NILP (Vwindow_scroll_functions)
9019 || MINI_WINDOW_P (w)
9020 || !try_window_reusing_current_matrix (w))
9022 IF_DEBUG (debug_method_add (w, "1"));
9023 try_window (window, startp);
9026 if (fonts_changed_p)
9027 goto restore_buffers;
9029 if (w->cursor.vpos >= 0)
9031 if (!just_this_one_p
9032 || current_buffer->clip_changed
9033 || BEG_UNCHANGED < CHARPOS (startp))
9034 /* Forget any recorded base line for line number display. */
9035 w->base_line_number = Qnil;
9037 make_cursor_line_fully_visible (w);
9038 goto done;
9040 else
9041 clear_glyph_matrix (w->desired_matrix);
9044 try_to_scroll:
9046 XSETFASTINT (w->last_modified, 0);
9047 XSETFASTINT (w->last_overlay_modified, 0);
9049 /* Redisplay the mode line. Select the buffer properly for that. */
9050 if (!update_mode_line)
9052 update_mode_line = 1;
9053 w->update_mode_line = Qt;
9056 /* Try to scroll by specified few lines. */
9057 if ((scroll_conservatively
9058 || scroll_step
9059 || temp_scroll_step
9060 || NUMBERP (current_buffer->scroll_up_aggressively)
9061 || NUMBERP (current_buffer->scroll_down_aggressively))
9062 && !current_buffer->clip_changed
9063 && CHARPOS (startp) >= BEGV
9064 && CHARPOS (startp) <= ZV)
9066 /* The function returns -1 if new fonts were loaded, 1 if
9067 successful, 0 if not successful. */
9068 int rc = try_scrolling (window, just_this_one_p,
9069 scroll_conservatively,
9070 scroll_step,
9071 temp_scroll_step);
9072 if (rc > 0)
9073 goto done;
9074 else if (rc < 0)
9075 goto restore_buffers;
9078 /* Finally, just choose place to start which centers point */
9080 recenter:
9082 #if GLYPH_DEBUG
9083 debug_method_add (w, "recenter");
9084 #endif
9086 /* w->vscroll = 0; */
9088 /* Forget any previously recorded base line for line number display. */
9089 if (!current_matrix_up_to_date_p
9090 || current_buffer->clip_changed)
9091 w->base_line_number = Qnil;
9093 /* Move backward half the height of the window. */
9094 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
9095 it.current_y = it.last_visible_y;
9096 move_it_vertically_backward (&it, it.last_visible_y / 2);
9097 xassert (IT_CHARPOS (it) >= BEGV);
9099 /* The function move_it_vertically_backward may move over more
9100 than the specified y-distance. If it->w is small, e.g. a
9101 mini-buffer window, we may end up in front of the window's
9102 display area. Start displaying at the start of the line
9103 containing PT in this case. */
9104 if (it.current_y <= 0)
9106 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
9107 move_it_vertically (&it, 0);
9108 xassert (IT_CHARPOS (it) <= PT);
9109 it.current_y = 0;
9112 it.current_x = it.hpos = 0;
9114 /* Set startp here explicitly in case that helps avoid an infinite loop
9115 in case the window-scroll-functions functions get errors. */
9116 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
9118 /* Run scroll hooks. */
9119 startp = run_window_scroll_functions (window, it.current.pos);
9121 /* Redisplay the window. */
9122 if (!current_matrix_up_to_date_p
9123 || windows_or_buffers_changed
9124 /* Don't use try_window_reusing_current_matrix in this case
9125 because it can have changed the buffer. */
9126 || !NILP (Vwindow_scroll_functions)
9127 || !just_this_one_p
9128 || MINI_WINDOW_P (w)
9129 || !try_window_reusing_current_matrix (w))
9130 try_window (window, startp);
9132 /* If new fonts have been loaded (due to fontsets), give up. We
9133 have to start a new redisplay since we need to re-adjust glyph
9134 matrices. */
9135 if (fonts_changed_p)
9136 goto restore_buffers;
9138 /* If cursor did not appear assume that the middle of the window is
9139 in the first line of the window. Do it again with the next line.
9140 (Imagine a window of height 100, displaying two lines of height
9141 60. Moving back 50 from it->last_visible_y will end in the first
9142 line.) */
9143 if (w->cursor.vpos < 0)
9145 if (!NILP (w->window_end_valid)
9146 && PT >= Z - XFASTINT (w->window_end_pos))
9148 clear_glyph_matrix (w->desired_matrix);
9149 move_it_by_lines (&it, 1, 0);
9150 try_window (window, it.current.pos);
9152 else if (PT < IT_CHARPOS (it))
9154 clear_glyph_matrix (w->desired_matrix);
9155 move_it_by_lines (&it, -1, 0);
9156 try_window (window, it.current.pos);
9158 else
9160 /* Not much we can do about it. */
9164 /* Consider the following case: Window starts at BEGV, there is
9165 invisible, intangible text at BEGV, so that display starts at
9166 some point START > BEGV. It can happen that we are called with
9167 PT somewhere between BEGV and START. Try to handle that case. */
9168 if (w->cursor.vpos < 0)
9170 struct glyph_row *row = w->current_matrix->rows;
9171 if (row->mode_line_p)
9172 ++row;
9173 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
9176 make_cursor_line_fully_visible (w);
9178 done:
9180 SET_TEXT_POS_FROM_MARKER (startp, w->start);
9181 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
9182 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
9183 ? Qt : Qnil);
9185 /* Display the mode line, if we must. */
9186 if ((update_mode_line
9187 /* If window not full width, must redo its mode line
9188 if (a) the window to its side is being redone and
9189 (b) we do a frame-based redisplay. This is a consequence
9190 of how inverted lines are drawn in frame-based redisplay. */
9191 || (!just_this_one_p
9192 && !FRAME_WINDOW_P (f)
9193 && !WINDOW_FULL_WIDTH_P (w))
9194 /* Line number to display. */
9195 || INTEGERP (w->base_line_pos)
9196 /* Column number is displayed and different from the one displayed. */
9197 || (!NILP (w->column_number_displayed)
9198 && XFASTINT (w->column_number_displayed) != current_column ()))
9199 /* This means that the window has a mode line. */
9200 && (WINDOW_WANTS_MODELINE_P (w)
9201 || WINDOW_WANTS_HEADER_LINE_P (w)))
9203 Lisp_Object old_selected_frame;
9205 old_selected_frame = selected_frame;
9207 XSETFRAME (selected_frame, f);
9208 display_mode_lines (w);
9209 selected_frame = old_selected_frame;
9211 /* If mode line height has changed, arrange for a thorough
9212 immediate redisplay using the correct mode line height. */
9213 if (WINDOW_WANTS_MODELINE_P (w)
9214 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
9216 fonts_changed_p = 1;
9217 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
9218 = DESIRED_MODE_LINE_HEIGHT (w);
9221 /* If top line height has changed, arrange for a thorough
9222 immediate redisplay using the correct mode line height. */
9223 if (WINDOW_WANTS_HEADER_LINE_P (w)
9224 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
9226 fonts_changed_p = 1;
9227 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
9228 = DESIRED_HEADER_LINE_HEIGHT (w);
9231 if (fonts_changed_p)
9232 goto restore_buffers;
9235 if (!line_number_displayed
9236 && !BUFFERP (w->base_line_pos))
9238 w->base_line_pos = Qnil;
9239 w->base_line_number = Qnil;
9242 finish_menu_bars:
9244 /* When we reach a frame's selected window, redo the frame's menu bar. */
9245 if (update_mode_line
9246 && EQ (FRAME_SELECTED_WINDOW (f), window))
9248 int redisplay_menu_p = 0;
9250 if (FRAME_WINDOW_P (f))
9252 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
9253 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
9254 #else
9255 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
9256 #endif
9258 else
9259 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
9261 if (redisplay_menu_p)
9262 display_menu_bar (w);
9264 #ifdef HAVE_WINDOW_SYSTEM
9265 if (WINDOWP (f->tool_bar_window)
9266 && (FRAME_TOOL_BAR_LINES (f) > 0
9267 || auto_resize_tool_bars_p))
9268 redisplay_tool_bar (f);
9269 #endif
9272 finish_scroll_bars:
9274 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
9276 int start, end, whole;
9278 /* Calculate the start and end positions for the current window.
9279 At some point, it would be nice to choose between scrollbars
9280 which reflect the whole buffer size, with special markers
9281 indicating narrowing, and scrollbars which reflect only the
9282 visible region.
9284 Note that mini-buffers sometimes aren't displaying any text. */
9285 if (!MINI_WINDOW_P (w)
9286 || (w == XWINDOW (minibuf_window)
9287 && NILP (echo_area_buffer[0])))
9289 whole = ZV - BEGV;
9290 start = marker_position (w->start) - BEGV;
9291 /* I don't think this is guaranteed to be right. For the
9292 moment, we'll pretend it is. */
9293 end = (Z - XFASTINT (w->window_end_pos)) - BEGV;
9295 if (end < start)
9296 end = start;
9297 if (whole < (end - start))
9298 whole = end - start;
9300 else
9301 start = end = whole = 0;
9303 /* Indicate what this scroll bar ought to be displaying now. */
9304 (*set_vertical_scroll_bar_hook) (w, end - start, whole, start);
9306 /* Note that we actually used the scroll bar attached to this
9307 window, so it shouldn't be deleted at the end of redisplay. */
9308 (*redeem_scroll_bar_hook) (w);
9311 restore_buffers:
9313 /* Restore current_buffer and value of point in it. */
9314 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
9315 set_buffer_internal_1 (old);
9316 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
9318 unbind_to (count, Qnil);
9322 /* Build the complete desired matrix of WINDOW with a window start
9323 buffer position POS. Value is non-zero if successful. It is zero
9324 if fonts were loaded during redisplay which makes re-adjusting
9325 glyph matrices necessary. */
9328 try_window (window, pos)
9329 Lisp_Object window;
9330 struct text_pos pos;
9332 struct window *w = XWINDOW (window);
9333 struct it it;
9334 struct glyph_row *last_text_row = NULL;
9336 /* Make POS the new window start. */
9337 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
9339 /* Mark cursor position as unknown. No overlay arrow seen. */
9340 w->cursor.vpos = -1;
9341 overlay_arrow_seen = 0;
9343 /* Initialize iterator and info to start at POS. */
9344 start_display (&it, w, pos);
9346 /* Display all lines of W. */
9347 while (it.current_y < it.last_visible_y)
9349 if (display_line (&it))
9350 last_text_row = it.glyph_row - 1;
9351 if (fonts_changed_p)
9352 return 0;
9355 /* If bottom moved off end of frame, change mode line percentage. */
9356 if (XFASTINT (w->window_end_pos) <= 0
9357 && Z != IT_CHARPOS (it))
9358 w->update_mode_line = Qt;
9360 /* Set window_end_pos to the offset of the last character displayed
9361 on the window from the end of current_buffer. Set
9362 window_end_vpos to its row number. */
9363 if (last_text_row)
9365 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
9366 w->window_end_bytepos
9367 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9368 XSETFASTINT (w->window_end_pos,
9369 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9370 XSETFASTINT (w->window_end_vpos,
9371 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
9372 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
9373 ->displays_text_p);
9375 else
9377 w->window_end_bytepos = 0;
9378 XSETFASTINT (w->window_end_pos, 0);
9379 XSETFASTINT (w->window_end_vpos, 0);
9382 /* But that is not valid info until redisplay finishes. */
9383 w->window_end_valid = Qnil;
9384 return 1;
9389 /************************************************************************
9390 Window redisplay reusing current matrix when buffer has not changed
9391 ************************************************************************/
9393 /* Try redisplay of window W showing an unchanged buffer with a
9394 different window start than the last time it was displayed by
9395 reusing its current matrix. Value is non-zero if successful.
9396 W->start is the new window start. */
9398 static int
9399 try_window_reusing_current_matrix (w)
9400 struct window *w;
9402 struct frame *f = XFRAME (w->frame);
9403 struct glyph_row *row, *bottom_row;
9404 struct it it;
9405 struct run run;
9406 struct text_pos start, new_start;
9407 int nrows_scrolled, i;
9408 struct glyph_row *last_text_row;
9409 struct glyph_row *last_reused_text_row;
9410 struct glyph_row *start_row;
9411 int start_vpos, min_y, max_y;
9413 /* Right now this function doesn't handle terminal frames. */
9414 if (!FRAME_WINDOW_P (f))
9415 return 0;
9417 /* Can't do this if region may have changed. */
9418 if ((!NILP (Vtransient_mark_mode)
9419 && !NILP (current_buffer->mark_active))
9420 || !NILP (w->region_showing)
9421 || !NILP (Vshow_trailing_whitespace))
9422 return 0;
9424 /* If top-line visibility has changed, give up. */
9425 if (WINDOW_WANTS_HEADER_LINE_P (w)
9426 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
9427 return 0;
9429 /* Give up if old or new display is scrolled vertically. We could
9430 make this function handle this, but right now it doesn't. */
9431 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9432 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
9433 return 0;
9435 /* The variable new_start now holds the new window start. The old
9436 start `start' can be determined from the current matrix. */
9437 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
9438 start = start_row->start.pos;
9439 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
9441 /* Clear the desired matrix for the display below. */
9442 clear_glyph_matrix (w->desired_matrix);
9444 if (CHARPOS (new_start) <= CHARPOS (start))
9446 int first_row_y;
9448 IF_DEBUG (debug_method_add (w, "twu1"));
9450 /* Display up to a row that can be reused. The variable
9451 last_text_row is set to the last row displayed that displays
9452 text. */
9453 start_display (&it, w, new_start);
9454 first_row_y = it.current_y;
9455 w->cursor.vpos = -1;
9456 last_text_row = last_reused_text_row = NULL;
9457 while (it.current_y < it.last_visible_y
9458 && IT_CHARPOS (it) < CHARPOS (start)
9459 && !fonts_changed_p)
9460 if (display_line (&it))
9461 last_text_row = it.glyph_row - 1;
9463 /* A value of current_y < last_visible_y means that we stopped
9464 at the previous window start, which in turn means that we
9465 have at least one reusable row. */
9466 if (it.current_y < it.last_visible_y)
9468 nrows_scrolled = it.vpos;
9470 /* Find PT if not already found in the lines displayed. */
9471 if (w->cursor.vpos < 0)
9473 int dy = it.current_y - first_row_y;
9475 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9476 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9478 if (PT >= MATRIX_ROW_START_CHARPOS (row)
9479 && PT < MATRIX_ROW_END_CHARPOS (row))
9481 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
9482 dy, nrows_scrolled);
9483 break;
9486 if (MATRIX_ROW_BOTTOM_Y (row) + dy >= it.last_visible_y)
9487 break;
9489 ++row;
9492 /* Give up if point was not found. This shouldn't
9493 happen often; not more often than with try_window
9494 itself. */
9495 if (w->cursor.vpos < 0)
9497 clear_glyph_matrix (w->desired_matrix);
9498 return 0;
9502 /* Scroll the display. Do it before the current matrix is
9503 changed. The problem here is that update has not yet
9504 run, i.e. part of the current matrix is not up to date.
9505 scroll_run_hook will clear the cursor, and use the
9506 current matrix to get the height of the row the cursor is
9507 in. */
9508 run.current_y = first_row_y;
9509 run.desired_y = it.current_y;
9510 run.height = it.last_visible_y - it.current_y;
9511 if (run.height > 0
9512 && run.current_y != run.desired_y)
9514 update_begin (f);
9515 rif->update_window_begin_hook (w);
9516 rif->scroll_run_hook (w, &run);
9517 rif->update_window_end_hook (w, 0);
9518 update_end (f);
9521 /* Shift current matrix down by nrows_scrolled lines. */
9522 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
9523 rotate_matrix (w->current_matrix,
9524 start_vpos,
9525 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
9526 nrows_scrolled);
9528 /* Disable lines not reused. */
9529 for (i = 0; i < it.vpos; ++i)
9530 MATRIX_ROW (w->current_matrix, i)->enabled_p = 0;
9532 /* Re-compute Y positions. */
9533 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix) + nrows_scrolled;
9534 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
9535 max_y = it.last_visible_y;
9536 while (row < bottom_row)
9538 row->y = it.current_y;
9540 if (row->y < min_y)
9541 row->visible_height = row->height - (min_y - row->y);
9542 else if (row->y + row->height > max_y)
9543 row->visible_height
9544 = row->height - (row->y + row->height - max_y);
9545 else
9546 row->visible_height = row->height;
9548 it.current_y += row->height;
9549 ++it.vpos;
9551 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9552 last_reused_text_row = row;
9553 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
9554 break;
9555 ++row;
9559 /* Update window_end_pos etc.; last_reused_text_row is the last
9560 reused row from the current matrix containing text, if any.
9561 The value of last_text_row is the last displayed line
9562 containing text. */
9563 if (last_reused_text_row)
9565 w->window_end_bytepos
9566 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
9567 XSETFASTINT (w->window_end_pos,
9568 Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
9569 XSETFASTINT (w->window_end_vpos,
9570 MATRIX_ROW_VPOS (last_reused_text_row,
9571 w->current_matrix));
9573 else if (last_text_row)
9575 w->window_end_bytepos
9576 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9577 XSETFASTINT (w->window_end_pos,
9578 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9579 XSETFASTINT (w->window_end_vpos,
9580 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
9582 else
9584 /* This window must be completely empty. */
9585 w->window_end_bytepos = 0;
9586 XSETFASTINT (w->window_end_pos, 0);
9587 XSETFASTINT (w->window_end_vpos, 0);
9589 w->window_end_valid = Qnil;
9591 /* Update hint: don't try scrolling again in update_window. */
9592 w->desired_matrix->no_scrolling_p = 1;
9594 #if GLYPH_DEBUG
9595 debug_method_add (w, "try_window_reusing_current_matrix 1");
9596 #endif
9597 return 1;
9599 else if (CHARPOS (new_start) > CHARPOS (start))
9601 struct glyph_row *pt_row, *row;
9602 struct glyph_row *first_reusable_row;
9603 struct glyph_row *first_row_to_display;
9604 int dy;
9605 int yb = window_text_bottom_y (w);
9607 IF_DEBUG (debug_method_add (w, "twu2"));
9609 /* Find the row starting at new_start, if there is one. Don't
9610 reuse a partially visible line at the end. */
9611 first_reusable_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9612 while (first_reusable_row->enabled_p
9613 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
9614 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
9615 < CHARPOS (new_start)))
9616 ++first_reusable_row;
9618 /* Give up if there is no row to reuse. */
9619 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
9620 || !first_reusable_row->enabled_p
9621 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
9622 != CHARPOS (new_start)))
9623 return 0;
9625 /* We can reuse fully visible rows beginning with
9626 first_reusable_row to the end of the window. Set
9627 first_row_to_display to the first row that cannot be reused.
9628 Set pt_row to the row containing point, if there is any. */
9629 first_row_to_display = first_reusable_row;
9630 pt_row = NULL;
9631 while (MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb)
9633 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
9634 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
9635 pt_row = first_row_to_display;
9637 ++first_row_to_display;
9640 /* Start displaying at the start of first_row_to_display. */
9641 xassert (first_row_to_display->y < yb);
9642 init_to_row_start (&it, w, first_row_to_display);
9643 nrows_scrolled = MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix);
9644 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
9645 - nrows_scrolled);
9646 it.current_y = first_row_to_display->y - first_reusable_row->y;
9648 /* Display lines beginning with first_row_to_display in the
9649 desired matrix. Set last_text_row to the last row displayed
9650 that displays text. */
9651 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
9652 if (pt_row == NULL)
9653 w->cursor.vpos = -1;
9654 last_text_row = NULL;
9655 while (it.current_y < it.last_visible_y && !fonts_changed_p)
9656 if (display_line (&it))
9657 last_text_row = it.glyph_row - 1;
9659 /* Give up If point isn't in a row displayed or reused. */
9660 if (w->cursor.vpos < 0)
9662 clear_glyph_matrix (w->desired_matrix);
9663 return 0;
9666 /* If point is in a reused row, adjust y and vpos of the cursor
9667 position. */
9668 if (pt_row)
9670 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
9671 w->current_matrix);
9672 w->cursor.y -= first_reusable_row->y;
9675 /* Scroll the display. */
9676 run.current_y = first_reusable_row->y;
9677 run.desired_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
9678 run.height = it.last_visible_y - run.current_y;
9679 if (run.height)
9681 struct frame *f = XFRAME (WINDOW_FRAME (w));
9682 update_begin (f);
9683 rif->update_window_begin_hook (w);
9684 rif->scroll_run_hook (w, &run);
9685 rif->update_window_end_hook (w, 0);
9686 update_end (f);
9689 /* Adjust Y positions of reused rows. */
9690 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
9691 row = first_reusable_row;
9692 dy = first_reusable_row->y;
9693 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
9694 max_y = it.last_visible_y;
9695 while (row < first_row_to_display)
9697 row->y -= dy;
9698 if (row->y < min_y)
9699 row->visible_height = row->height - (min_y - row->y);
9700 else if (row->y + row->height > max_y)
9701 row->visible_height
9702 = row->height - (row->y + row->height - max_y);
9703 else
9704 row->visible_height = row->height;
9705 ++row;
9708 /* Disable rows not reused. */
9709 while (row < bottom_row)
9711 row->enabled_p = 0;
9712 ++row;
9715 /* Scroll the current matrix. */
9716 xassert (nrows_scrolled > 0);
9717 rotate_matrix (w->current_matrix,
9718 start_vpos,
9719 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
9720 -nrows_scrolled);
9722 /* Adjust window end. A null value of last_text_row means that
9723 the window end is in reused rows which in turn means that
9724 only its vpos can have changed. */
9725 if (last_text_row)
9727 w->window_end_bytepos
9728 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9729 XSETFASTINT (w->window_end_pos,
9730 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9731 XSETFASTINT (w->window_end_vpos,
9732 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
9734 else
9736 XSETFASTINT (w->window_end_vpos,
9737 XFASTINT (w->window_end_vpos) - nrows_scrolled);
9740 w->window_end_valid = Qnil;
9741 w->desired_matrix->no_scrolling_p = 1;
9743 #if GLYPH_DEBUG
9744 debug_method_add (w, "try_window_reusing_current_matrix 2");
9745 #endif
9746 return 1;
9749 return 0;
9754 /************************************************************************
9755 Window redisplay reusing current matrix when buffer has changed
9756 ************************************************************************/
9758 static struct glyph_row *get_last_unchanged_at_beg_row P_ ((struct window *));
9759 static struct glyph_row *get_first_unchanged_at_end_row P_ ((struct window *,
9760 int *, int *));
9761 static struct glyph_row *
9762 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
9763 struct glyph_row *));
9766 /* Return the last row in MATRIX displaying text. If row START is
9767 non-null, start searching with that row. IT gives the dimensions
9768 of the display. Value is null if matrix is empty; otherwise it is
9769 a pointer to the row found. */
9771 static struct glyph_row *
9772 find_last_row_displaying_text (matrix, it, start)
9773 struct glyph_matrix *matrix;
9774 struct it *it;
9775 struct glyph_row *start;
9777 struct glyph_row *row, *row_found;
9779 /* Set row_found to the last row in IT->w's current matrix
9780 displaying text. The loop looks funny but think of partially
9781 visible lines. */
9782 row_found = NULL;
9783 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
9784 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9786 xassert (row->enabled_p);
9787 row_found = row;
9788 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
9789 break;
9790 ++row;
9793 return row_found;
9797 /* Return the last row in the current matrix of W that is not affected
9798 by changes at the start of current_buffer that occurred since the
9799 last time W was redisplayed. Value is null if no such row exists.
9801 The global variable beg_unchanged has to contain the number of
9802 bytes unchanged at the start of current_buffer. BEG +
9803 beg_unchanged is the buffer position of the first changed byte in
9804 current_buffer. Characters at positions < BEG + beg_unchanged are
9805 at the same buffer positions as they were when the current matrix
9806 was built. */
9808 static struct glyph_row *
9809 get_last_unchanged_at_beg_row (w)
9810 struct window *w;
9812 int first_changed_pos = BEG + BEG_UNCHANGED;
9813 struct glyph_row *row;
9814 struct glyph_row *row_found = NULL;
9815 int yb = window_text_bottom_y (w);
9817 /* Find the last row displaying unchanged text. */
9818 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9819 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
9820 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
9822 if (/* If row ends before first_changed_pos, it is unchanged,
9823 except in some case. */
9824 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
9825 /* When row ends in ZV and we write at ZV it is not
9826 unchanged. */
9827 && !row->ends_at_zv_p
9828 /* When first_changed_pos is the end of a continued line,
9829 row is not unchanged because it may be no longer
9830 continued. */
9831 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
9832 && row->continued_p))
9833 row_found = row;
9835 /* Stop if last visible row. */
9836 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
9837 break;
9839 ++row;
9842 return row_found;
9846 /* Find the first glyph row in the current matrix of W that is not
9847 affected by changes at the end of current_buffer since the last
9848 time the window was redisplayed. Return in *DELTA the number of
9849 chars by which buffer positions in unchanged text at the end of
9850 current_buffer must be adjusted. Return in *DELTA_BYTES the
9851 corresponding number of bytes. Value is null if no such row
9852 exists, i.e. all rows are affected by changes. */
9854 static struct glyph_row *
9855 get_first_unchanged_at_end_row (w, delta, delta_bytes)
9856 struct window *w;
9857 int *delta, *delta_bytes;
9859 struct glyph_row *row;
9860 struct glyph_row *row_found = NULL;
9862 *delta = *delta_bytes = 0;
9864 /* A value of window_end_pos >= end_unchanged means that the window
9865 end is in the range of changed text. If so, there is no
9866 unchanged row at the end of W's current matrix. */
9867 xassert (!NILP (w->window_end_valid));
9868 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
9869 return NULL;
9871 /* Set row to the last row in W's current matrix displaying text. */
9872 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
9874 /* If matrix is entirely empty, no unchanged row exists. */
9875 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9877 /* The value of row is the last glyph row in the matrix having a
9878 meaningful buffer position in it. The end position of row
9879 corresponds to window_end_pos. This allows us to translate
9880 buffer positions in the current matrix to current buffer
9881 positions for characters not in changed text. */
9882 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
9883 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
9884 int last_unchanged_pos, last_unchanged_pos_old;
9885 struct glyph_row *first_text_row
9886 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9888 *delta = Z - Z_old;
9889 *delta_bytes = Z_BYTE - Z_BYTE_old;
9891 /* Set last_unchanged_pos to the buffer position of the last
9892 character in the buffer that has not been changed. Z is the
9893 index + 1 of the last byte in current_buffer, i.e. by
9894 subtracting end_unchanged we get the index of the last
9895 unchanged character, and we have to add BEG to get its buffer
9896 position. */
9897 last_unchanged_pos = Z - END_UNCHANGED + BEG;
9898 last_unchanged_pos_old = last_unchanged_pos - *delta;
9900 /* Search backward from ROW for a row displaying a line that
9901 starts at a minimum position >= last_unchanged_pos_old. */
9902 while (row >= first_text_row)
9904 xassert (row->enabled_p);
9905 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (row));
9907 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
9908 row_found = row;
9909 --row;
9913 xassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
9914 return row_found;
9918 /* Make sure that glyph rows in the current matrix of window W
9919 reference the same glyph memory as corresponding rows in the
9920 frame's frame matrix. This function is called after scrolling W's
9921 current matrix on a terminal frame in try_window_id and
9922 try_window_reusing_current_matrix. */
9924 static void
9925 sync_frame_with_window_matrix_rows (w)
9926 struct window *w;
9928 struct frame *f = XFRAME (w->frame);
9929 struct glyph_row *window_row, *window_row_end, *frame_row;
9931 /* Preconditions: W must be a leaf window and full-width. Its frame
9932 must have a frame matrix. */
9933 xassert (NILP (w->hchild) && NILP (w->vchild));
9934 xassert (WINDOW_FULL_WIDTH_P (w));
9935 xassert (!FRAME_WINDOW_P (f));
9937 /* If W is a full-width window, glyph pointers in W's current matrix
9938 have, by definition, to be the same as glyph pointers in the
9939 corresponding frame matrix. */
9940 window_row = w->current_matrix->rows;
9941 window_row_end = window_row + w->current_matrix->nrows;
9942 frame_row = f->current_matrix->rows + XFASTINT (w->top);
9943 while (window_row < window_row_end)
9945 int area;
9947 for (area = LEFT_MARGIN_AREA; area <= LAST_AREA; ++area)
9948 frame_row->glyphs[area] = window_row->glyphs[area];
9950 /* Disable frame rows whose corresponding window rows have
9951 been disabled in try_window_id. */
9952 if (!window_row->enabled_p)
9953 frame_row->enabled_p = 0;
9955 ++window_row, ++frame_row;
9960 /* Find the glyph row in window W containing CHARPOS. Consider all
9961 rows between START and END (not inclusive). END null means search
9962 all rows to the end of the display area of W. Value is the row
9963 containing CHARPOS or null. */
9965 static struct glyph_row *
9966 row_containing_pos (w, charpos, start, end)
9967 struct window *w;
9968 int charpos;
9969 struct glyph_row *start, *end;
9971 struct glyph_row *row = start;
9972 int last_y;
9974 /* If we happen to start on a header-line, skip that. */
9975 if (row->mode_line_p)
9976 ++row;
9978 if ((end && row >= end) || !row->enabled_p)
9979 return NULL;
9981 last_y = window_text_bottom_y (w);
9983 while ((end == NULL || row < end)
9984 && (MATRIX_ROW_END_CHARPOS (row) < charpos
9985 /* The end position of a row equals the start
9986 position of the next row. If CHARPOS is there, we
9987 would rather display it in the next line, except
9988 when this line ends in ZV. */
9989 || (MATRIX_ROW_END_CHARPOS (row) == charpos
9990 && (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
9991 || !row->ends_at_zv_p)))
9992 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
9993 ++row;
9995 /* Give up if CHARPOS not found. */
9996 if ((end && row >= end)
9997 || charpos < MATRIX_ROW_START_CHARPOS (row)
9998 || charpos > MATRIX_ROW_END_CHARPOS (row))
9999 row = NULL;
10001 return row;
10005 /* Try to redisplay window W by reusing its existing display. W's
10006 current matrix must be up to date when this function is called,
10007 i.e. window_end_valid must not be nil.
10009 Value is
10011 1 if display has been updated
10012 0 if otherwise unsuccessful
10013 -1 if redisplay with same window start is known not to succeed
10015 The following steps are performed:
10017 1. Find the last row in the current matrix of W that is not
10018 affected by changes at the start of current_buffer. If no such row
10019 is found, give up.
10021 2. Find the first row in W's current matrix that is not affected by
10022 changes at the end of current_buffer. Maybe there is no such row.
10024 3. Display lines beginning with the row + 1 found in step 1 to the
10025 row found in step 2 or, if step 2 didn't find a row, to the end of
10026 the window.
10028 4. If cursor is not known to appear on the window, give up.
10030 5. If display stopped at the row found in step 2, scroll the
10031 display and current matrix as needed.
10033 6. Maybe display some lines at the end of W, if we must. This can
10034 happen under various circumstances, like a partially visible line
10035 becoming fully visible, or because newly displayed lines are displayed
10036 in smaller font sizes.
10038 7. Update W's window end information. */
10040 /* Check that window end is what we expect it to be. */
10042 static int
10043 try_window_id (w)
10044 struct window *w;
10046 struct frame *f = XFRAME (w->frame);
10047 struct glyph_matrix *current_matrix = w->current_matrix;
10048 struct glyph_matrix *desired_matrix = w->desired_matrix;
10049 struct glyph_row *last_unchanged_at_beg_row;
10050 struct glyph_row *first_unchanged_at_end_row;
10051 struct glyph_row *row;
10052 struct glyph_row *bottom_row;
10053 int bottom_vpos;
10054 struct it it;
10055 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
10056 struct text_pos start_pos;
10057 struct run run;
10058 int first_unchanged_at_end_vpos = 0;
10059 struct glyph_row *last_text_row, *last_text_row_at_end;
10060 struct text_pos start;
10062 SET_TEXT_POS_FROM_MARKER (start, w->start);
10064 /* Check pre-conditions. Window end must be valid, otherwise
10065 the current matrix would not be up to date. */
10066 xassert (!NILP (w->window_end_valid));
10067 xassert (FRAME_WINDOW_P (XFRAME (w->frame))
10068 || (line_ins_del_ok && WINDOW_FULL_WIDTH_P (w)));
10070 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
10071 only if buffer has really changed. The reason is that the gap is
10072 initially at Z for freshly visited files. The code below would
10073 set end_unchanged to 0 in that case. */
10074 if (MODIFF > SAVE_MODIFF
10075 /* This seems to happen sometimes after saving a buffer. */
10076 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
10078 if (GPT - BEG < BEG_UNCHANGED)
10079 BEG_UNCHANGED = GPT - BEG;
10080 if (Z - GPT < END_UNCHANGED)
10081 END_UNCHANGED = Z - GPT;
10084 /* If window starts after a line end, and the last change is in
10085 front of that newline, then changes don't affect the display.
10086 This case happens with stealth-fontification. Note that although
10087 the display is unchanged, glyph positions in the matrix have to
10088 be adjusted, of course. */
10089 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
10090 if (CHARPOS (start) > BEGV
10091 && Z - END_UNCHANGED < CHARPOS (start) - 1
10092 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n'
10093 && PT < MATRIX_ROW_END_CHARPOS (row))
10095 struct glyph_row *r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
10096 int delta = CHARPOS (start) - MATRIX_ROW_START_CHARPOS (r0);
10098 if (delta)
10100 struct glyph_row *r1 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
10101 int delta_bytes = BYTEPOS (start) - MATRIX_ROW_START_BYTEPOS (r0);
10103 increment_matrix_positions (w->current_matrix,
10104 MATRIX_ROW_VPOS (r0, current_matrix),
10105 MATRIX_ROW_VPOS (r1, current_matrix),
10106 delta, delta_bytes);
10109 #if 0 /* If changes are all in front of the window start, the
10110 distance of the last displayed glyph from Z hasn't
10111 changed. */
10112 w->window_end_pos
10113 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
10114 w->window_end_bytepos
10115 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
10116 #endif
10118 return 1;
10121 /* Return quickly if changes are all below what is displayed in the
10122 window, and if PT is in the window. */
10123 if (BEG_UNCHANGED > MATRIX_ROW_END_CHARPOS (row)
10124 && PT < MATRIX_ROW_END_CHARPOS (row))
10126 /* We have to update window end positions because the buffer's
10127 size has changed. */
10128 w->window_end_pos
10129 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
10130 w->window_end_bytepos
10131 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
10132 return 1;
10135 /* Check that window start agrees with the start of the first glyph
10136 row in its current matrix. Check this after we know the window
10137 start is not in changed text, otherwise positions would not be
10138 comparable. */
10139 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
10140 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
10141 return 0;
10143 /* Compute the position at which we have to start displaying new
10144 lines. Some of the lines at the top of the window might be
10145 reusable because they are not displaying changed text. Find the
10146 last row in W's current matrix not affected by changes at the
10147 start of current_buffer. Value is null if changes start in the
10148 first line of window. */
10149 last_unchanged_at_beg_row = get_last_unchanged_at_beg_row (w);
10150 if (last_unchanged_at_beg_row)
10152 init_to_row_end (&it, w, last_unchanged_at_beg_row);
10153 start_pos = it.current.pos;
10155 /* Start displaying new lines in the desired matrix at the same
10156 vpos we would use in the current matrix, i.e. below
10157 last_unchanged_at_beg_row. */
10158 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
10159 current_matrix);
10160 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
10161 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
10163 xassert (it.hpos == 0 && it.current_x == 0);
10165 else
10167 /* There are no reusable lines at the start of the window.
10168 Start displaying in the first line. */
10169 start_display (&it, w, start);
10170 start_pos = it.current.pos;
10173 /* Find the first row that is not affected by changes at the end of
10174 the buffer. Value will be null if there is no unchanged row, in
10175 which case we must redisplay to the end of the window. delta
10176 will be set to the value by which buffer positions beginning with
10177 first_unchanged_at_end_row have to be adjusted due to text
10178 changes. */
10179 first_unchanged_at_end_row
10180 = get_first_unchanged_at_end_row (w, &delta, &delta_bytes);
10181 IF_DEBUG (debug_delta = delta);
10182 IF_DEBUG (debug_delta_bytes = delta_bytes);
10184 /* Set stop_pos to the buffer position up to which we will have to
10185 display new lines. If first_unchanged_at_end_row != NULL, this
10186 is the buffer position of the start of the line displayed in that
10187 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
10188 that we don't stop at a buffer position. */
10189 stop_pos = 0;
10190 if (first_unchanged_at_end_row)
10192 xassert (last_unchanged_at_beg_row == NULL
10193 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
10195 /* If this is a continuation line, move forward to the next one
10196 that isn't. Changes in lines above affect this line.
10197 Caution: this may move first_unchanged_at_end_row to a row
10198 not displaying text. */
10199 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
10200 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
10201 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
10202 < it.last_visible_y))
10203 ++first_unchanged_at_end_row;
10205 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
10206 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
10207 >= it.last_visible_y))
10208 first_unchanged_at_end_row = NULL;
10209 else
10211 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
10212 + delta);
10213 first_unchanged_at_end_vpos
10214 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
10215 xassert (stop_pos >= Z - END_UNCHANGED);
10218 else if (last_unchanged_at_beg_row == NULL)
10219 return 0;
10222 #if GLYPH_DEBUG
10224 /* Either there is no unchanged row at the end, or the one we have
10225 now displays text. This is a necessary condition for the window
10226 end pos calculation at the end of this function. */
10227 xassert (first_unchanged_at_end_row == NULL
10228 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
10230 debug_last_unchanged_at_beg_vpos
10231 = (last_unchanged_at_beg_row
10232 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
10233 : -1);
10234 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
10236 #endif /* GLYPH_DEBUG != 0 */
10239 /* Display new lines. Set last_text_row to the last new line
10240 displayed which has text on it, i.e. might end up as being the
10241 line where the window_end_vpos is. */
10242 w->cursor.vpos = -1;
10243 last_text_row = NULL;
10244 overlay_arrow_seen = 0;
10245 while (it.current_y < it.last_visible_y
10246 && !fonts_changed_p
10247 && (first_unchanged_at_end_row == NULL
10248 || IT_CHARPOS (it) < stop_pos))
10250 if (display_line (&it))
10251 last_text_row = it.glyph_row - 1;
10254 if (fonts_changed_p)
10255 return -1;
10258 /* Compute differences in buffer positions, y-positions etc. for
10259 lines reused at the bottom of the window. Compute what we can
10260 scroll. */
10261 if (first_unchanged_at_end_row
10262 /* No lines reused because we displayed everything up to the
10263 bottom of the window. */
10264 && it.current_y < it.last_visible_y)
10266 dvpos = (it.vpos
10267 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
10268 current_matrix));
10269 dy = it.current_y - first_unchanged_at_end_row->y;
10270 run.current_y = first_unchanged_at_end_row->y;
10271 run.desired_y = run.current_y + dy;
10272 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
10274 else
10276 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
10277 first_unchanged_at_end_row = NULL;
10279 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
10282 /* Find the cursor if not already found. We have to decide whether
10283 PT will appear on this window (it sometimes doesn't, but this is
10284 not a very frequent case.) This decision has to be made before
10285 the current matrix is altered. A value of cursor.vpos < 0 means
10286 that PT is either in one of the lines beginning at
10287 first_unchanged_at_end_row or below the window. Don't care for
10288 lines that might be displayed later at the window end; as
10289 mentioned, this is not a frequent case. */
10290 if (w->cursor.vpos < 0)
10292 /* Cursor in unchanged rows at the top? */
10293 if (PT < CHARPOS (start_pos)
10294 && last_unchanged_at_beg_row)
10296 row = row_containing_pos (w, PT,
10297 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
10298 last_unchanged_at_beg_row + 1);
10299 xassert (row && row <= last_unchanged_at_beg_row);
10300 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10303 /* Start from first_unchanged_at_end_row looking for PT. */
10304 else if (first_unchanged_at_end_row)
10306 row = row_containing_pos (w, PT - delta,
10307 first_unchanged_at_end_row, NULL);
10308 if (row)
10309 set_cursor_from_row (w, row, w->current_matrix, delta,
10310 delta_bytes, dy, dvpos);
10313 /* Give up if cursor was not found. */
10314 if (w->cursor.vpos < 0)
10316 clear_glyph_matrix (w->desired_matrix);
10317 return -1;
10321 /* Don't let the cursor end in the scroll margins. */
10323 int this_scroll_margin, cursor_height;
10325 this_scroll_margin = max (0, scroll_margin);
10326 this_scroll_margin = min (this_scroll_margin,
10327 XFASTINT (w->height) / 4);
10328 this_scroll_margin *= CANON_Y_UNIT (it.f);
10329 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
10331 if ((w->cursor.y < this_scroll_margin
10332 && CHARPOS (start) > BEGV)
10333 /* Don't take scroll margin into account at the bottom because
10334 old redisplay didn't do it either. */
10335 || w->cursor.y + cursor_height > it.last_visible_y)
10337 w->cursor.vpos = -1;
10338 clear_glyph_matrix (w->desired_matrix);
10339 return -1;
10343 /* Scroll the display. Do it before changing the current matrix so
10344 that xterm.c doesn't get confused about where the cursor glyph is
10345 found. */
10346 if (dy && run.height)
10348 update_begin (f);
10350 if (FRAME_WINDOW_P (f))
10352 rif->update_window_begin_hook (w);
10353 rif->scroll_run_hook (w, &run);
10354 rif->update_window_end_hook (w, 0);
10356 else
10358 /* Terminal frame. In this case, dvpos gives the number of
10359 lines to scroll by; dvpos < 0 means scroll up. */
10360 int first_unchanged_at_end_vpos
10361 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
10362 int from = XFASTINT (w->top) + first_unchanged_at_end_vpos;
10363 int end = XFASTINT (w->top) + window_internal_height (w);
10365 /* Perform the operation on the screen. */
10366 if (dvpos > 0)
10368 /* Scroll last_unchanged_at_beg_row to the end of the
10369 window down dvpos lines. */
10370 set_terminal_window (end);
10372 /* On dumb terminals delete dvpos lines at the end
10373 before inserting dvpos empty lines. */
10374 if (!scroll_region_ok)
10375 ins_del_lines (end - dvpos, -dvpos);
10377 /* Insert dvpos empty lines in front of
10378 last_unchanged_at_beg_row. */
10379 ins_del_lines (from, dvpos);
10381 else if (dvpos < 0)
10383 /* Scroll up last_unchanged_at_beg_vpos to the end of
10384 the window to last_unchanged_at_beg_vpos - |dvpos|. */
10385 set_terminal_window (end);
10387 /* Delete dvpos lines in front of
10388 last_unchanged_at_beg_vpos. ins_del_lines will set
10389 the cursor to the given vpos and emit |dvpos| delete
10390 line sequences. */
10391 ins_del_lines (from + dvpos, dvpos);
10393 /* On a dumb terminal insert dvpos empty lines at the
10394 end. */
10395 if (!scroll_region_ok)
10396 ins_del_lines (end + dvpos, -dvpos);
10399 set_terminal_window (0);
10402 update_end (f);
10405 /* Shift reused rows of the current matrix to the right position.
10406 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
10407 text. */
10408 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
10409 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
10410 if (dvpos < 0)
10412 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
10413 bottom_vpos, dvpos);
10414 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
10415 bottom_vpos, 0);
10417 else if (dvpos > 0)
10419 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
10420 bottom_vpos, dvpos);
10421 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
10422 first_unchanged_at_end_vpos + dvpos, 0);
10425 /* For frame-based redisplay, make sure that current frame and window
10426 matrix are in sync with respect to glyph memory. */
10427 if (!FRAME_WINDOW_P (f))
10428 sync_frame_with_window_matrix_rows (w);
10430 /* Adjust buffer positions in reused rows. */
10431 if (delta)
10432 increment_matrix_positions (current_matrix,
10433 first_unchanged_at_end_vpos + dvpos,
10434 bottom_vpos, delta, delta_bytes);
10436 /* Adjust Y positions. */
10437 if (dy)
10438 shift_glyph_matrix (w, current_matrix,
10439 first_unchanged_at_end_vpos + dvpos,
10440 bottom_vpos, dy);
10442 if (first_unchanged_at_end_row)
10443 first_unchanged_at_end_row += dvpos;
10445 /* If scrolling up, there may be some lines to display at the end of
10446 the window. */
10447 last_text_row_at_end = NULL;
10448 if (dy < 0)
10450 /* Set last_row to the glyph row in the current matrix where the
10451 window end line is found. It has been moved up or down in
10452 the matrix by dvpos. */
10453 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
10454 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
10456 /* If last_row is the window end line, it should display text. */
10457 xassert (last_row->displays_text_p);
10459 /* If window end line was partially visible before, begin
10460 displaying at that line. Otherwise begin displaying with the
10461 line following it. */
10462 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
10464 init_to_row_start (&it, w, last_row);
10465 it.vpos = last_vpos;
10466 it.current_y = last_row->y;
10468 else
10470 init_to_row_end (&it, w, last_row);
10471 it.vpos = 1 + last_vpos;
10472 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
10473 ++last_row;
10476 /* We may start in a continuation line. If so, we have to get
10477 the right continuation_lines_width and current_x. */
10478 it.continuation_lines_width = last_row->continuation_lines_width;
10479 it.hpos = it.current_x = 0;
10481 /* Display the rest of the lines at the window end. */
10482 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
10483 while (it.current_y < it.last_visible_y
10484 && !fonts_changed_p)
10486 /* Is it always sure that the display agrees with lines in
10487 the current matrix? I don't think so, so we mark rows
10488 displayed invalid in the current matrix by setting their
10489 enabled_p flag to zero. */
10490 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
10491 if (display_line (&it))
10492 last_text_row_at_end = it.glyph_row - 1;
10496 /* Update window_end_pos and window_end_vpos. */
10497 if (first_unchanged_at_end_row
10498 && first_unchanged_at_end_row->y < it.last_visible_y
10499 && !last_text_row_at_end)
10501 /* Window end line if one of the preserved rows from the current
10502 matrix. Set row to the last row displaying text in current
10503 matrix starting at first_unchanged_at_end_row, after
10504 scrolling. */
10505 xassert (first_unchanged_at_end_row->displays_text_p);
10506 row = find_last_row_displaying_text (w->current_matrix, &it,
10507 first_unchanged_at_end_row);
10508 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
10510 XSETFASTINT (w->window_end_pos, Z - MATRIX_ROW_END_CHARPOS (row));
10511 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
10512 XSETFASTINT (w->window_end_vpos,
10513 MATRIX_ROW_VPOS (row, w->current_matrix));
10515 else if (last_text_row_at_end)
10517 XSETFASTINT (w->window_end_pos,
10518 Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
10519 w->window_end_bytepos
10520 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
10521 XSETFASTINT (w->window_end_vpos,
10522 MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
10524 else if (last_text_row)
10526 /* We have displayed either to the end of the window or at the
10527 end of the window, i.e. the last row with text is to be found
10528 in the desired matrix. */
10529 XSETFASTINT (w->window_end_pos,
10530 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
10531 w->window_end_bytepos
10532 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
10533 XSETFASTINT (w->window_end_vpos,
10534 MATRIX_ROW_VPOS (last_text_row, desired_matrix));
10536 else if (first_unchanged_at_end_row == NULL
10537 && last_text_row == NULL
10538 && last_text_row_at_end == NULL)
10540 /* Displayed to end of window, but no line containing text was
10541 displayed. Lines were deleted at the end of the window. */
10542 int vpos;
10543 int header_line_p = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
10545 for (vpos = XFASTINT (w->window_end_vpos); vpos > 0; --vpos)
10546 if ((w->desired_matrix->rows[vpos + header_line_p].enabled_p
10547 && w->desired_matrix->rows[vpos + header_line_p].displays_text_p)
10548 || (!w->desired_matrix->rows[vpos + header_line_p].enabled_p
10549 && w->current_matrix->rows[vpos + header_line_p].displays_text_p))
10550 break;
10552 w->window_end_vpos = make_number (vpos);
10554 else
10555 abort ();
10557 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
10558 debug_end_vpos = XFASTINT (w->window_end_vpos));
10560 /* Record that display has not been completed. */
10561 w->window_end_valid = Qnil;
10562 w->desired_matrix->no_scrolling_p = 1;
10563 return 1;
10568 /***********************************************************************
10569 More debugging support
10570 ***********************************************************************/
10572 #if GLYPH_DEBUG
10574 void dump_glyph_row P_ ((struct glyph_matrix *, int, int));
10575 static void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
10578 /* Dump the contents of glyph matrix MATRIX on stderr. If
10579 WITH_GLYPHS_P is non-zero, dump glyph contents as well. */
10581 static void
10582 dump_glyph_matrix (matrix, with_glyphs_p)
10583 struct glyph_matrix *matrix;
10584 int with_glyphs_p;
10586 int i;
10587 for (i = 0; i < matrix->nrows; ++i)
10588 dump_glyph_row (matrix, i, with_glyphs_p);
10592 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
10593 WITH_GLYPH_SP non-zero means dump glyph contents, too. */
10595 void
10596 dump_glyph_row (matrix, vpos, with_glyphs_p)
10597 struct glyph_matrix *matrix;
10598 int vpos, with_glyphs_p;
10600 struct glyph_row *row;
10602 if (vpos < 0 || vpos >= matrix->nrows)
10603 return;
10605 row = MATRIX_ROW (matrix, vpos);
10607 fprintf (stderr, "Row Start End Used oEI><O\\CTZFes X Y W\n");
10608 fprintf (stderr, "=============================================\n");
10610 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d\n",
10611 row - matrix->rows,
10612 MATRIX_ROW_START_CHARPOS (row),
10613 MATRIX_ROW_END_CHARPOS (row),
10614 row->used[TEXT_AREA],
10615 row->contains_overlapping_glyphs_p,
10616 row->enabled_p,
10617 row->inverse_p,
10618 row->truncated_on_left_p,
10619 row->truncated_on_right_p,
10620 row->overlay_arrow_p,
10621 row->continued_p,
10622 MATRIX_ROW_CONTINUATION_LINE_P (row),
10623 row->displays_text_p,
10624 row->ends_at_zv_p,
10625 row->fill_line_p,
10626 row->ends_in_middle_of_char_p,
10627 row->starts_in_middle_of_char_p,
10628 row->x,
10629 row->y,
10630 row->pixel_width);
10631 fprintf (stderr, "%9d %5d\n", row->start.overlay_string_index,
10632 row->end.overlay_string_index);
10633 fprintf (stderr, "%9d %5d\n",
10634 CHARPOS (row->start.string_pos),
10635 CHARPOS (row->end.string_pos));
10636 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
10637 row->end.dpvec_index);
10639 if (with_glyphs_p)
10641 struct glyph *glyph, *glyph_end;
10642 int prev_had_glyphs_p;
10644 glyph = row->glyphs[TEXT_AREA];
10645 glyph_end = glyph + row->used[TEXT_AREA];
10647 /* Glyph for a line end in text. */
10648 if (glyph == glyph_end && glyph->charpos > 0)
10649 ++glyph_end;
10651 if (glyph < glyph_end)
10653 fprintf (stderr, " Glyph Type Pos W Code C Face LR\n");
10654 prev_had_glyphs_p = 1;
10656 else
10657 prev_had_glyphs_p = 0;
10659 while (glyph < glyph_end)
10661 if (glyph->type == CHAR_GLYPH)
10663 fprintf (stderr,
10664 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
10665 glyph - row->glyphs[TEXT_AREA],
10666 'C',
10667 glyph->charpos,
10668 glyph->pixel_width,
10669 glyph->u.ch,
10670 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
10671 ? glyph->u.ch
10672 : '.'),
10673 glyph->face_id,
10674 glyph->left_box_line_p,
10675 glyph->right_box_line_p);
10677 else if (glyph->type == STRETCH_GLYPH)
10679 fprintf (stderr,
10680 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
10681 glyph - row->glyphs[TEXT_AREA],
10682 'S',
10683 glyph->charpos,
10684 glyph->pixel_width,
10686 '.',
10687 glyph->face_id,
10688 glyph->left_box_line_p,
10689 glyph->right_box_line_p);
10691 else if (glyph->type == IMAGE_GLYPH)
10693 fprintf (stderr,
10694 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
10695 glyph - row->glyphs[TEXT_AREA],
10696 'I',
10697 glyph->charpos,
10698 glyph->pixel_width,
10699 glyph->u.img_id,
10700 '.',
10701 glyph->face_id,
10702 glyph->left_box_line_p,
10703 glyph->right_box_line_p);
10705 ++glyph;
10711 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
10712 Sdump_glyph_matrix, 0, 1, "p",
10713 "Dump the current matrix of the selected window to stderr.\n\
10714 Shows contents of glyph row structures. With non-nil optional\n\
10715 parameter WITH-GLYPHS-P, dump glyphs as well.")
10716 (with_glyphs_p)
10717 Lisp_Object with_glyphs_p;
10719 struct window *w = XWINDOW (selected_window);
10720 struct buffer *buffer = XBUFFER (w->buffer);
10722 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
10723 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
10724 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
10725 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
10726 fprintf (stderr, "=============================================\n");
10727 dump_glyph_matrix (w->current_matrix, !NILP (with_glyphs_p));
10728 return Qnil;
10732 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 1, "",
10733 "Dump glyph row ROW to stderr.")
10734 (row)
10735 Lisp_Object row;
10737 CHECK_NUMBER (row, 0);
10738 dump_glyph_row (XWINDOW (selected_window)->current_matrix, XINT (row), 1);
10739 return Qnil;
10743 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row,
10744 0, 0, "", "")
10747 struct frame *sf = SELECTED_FRAME ();
10748 struct glyph_matrix *m = (XWINDOW (sf->tool_bar_window)
10749 ->current_matrix);
10750 dump_glyph_row (m, 0, 1);
10751 return Qnil;
10755 DEFUN ("trace-redisplay-toggle", Ftrace_redisplay_toggle,
10756 Strace_redisplay_toggle, 0, 0, "",
10757 "Toggle tracing of redisplay.")
10760 trace_redisplay_p = !trace_redisplay_p;
10761 return Qnil;
10765 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, 1, "",
10766 "Print STRING to stderr.")
10767 (string)
10768 Lisp_Object string;
10770 CHECK_STRING (string, 0);
10771 fprintf (stderr, "%s", XSTRING (string)->data);
10772 return Qnil;
10775 #endif /* GLYPH_DEBUG */
10779 /***********************************************************************
10780 Building Desired Matrix Rows
10781 ***********************************************************************/
10783 /* Return a temporary glyph row holding the glyphs of an overlay
10784 arrow. Only used for non-window-redisplay windows. */
10786 static struct glyph_row *
10787 get_overlay_arrow_glyph_row (w)
10788 struct window *w;
10790 struct frame *f = XFRAME (WINDOW_FRAME (w));
10791 struct buffer *buffer = XBUFFER (w->buffer);
10792 struct buffer *old = current_buffer;
10793 unsigned char *arrow_string = XSTRING (Voverlay_arrow_string)->data;
10794 int arrow_len = XSTRING (Voverlay_arrow_string)->size;
10795 unsigned char *arrow_end = arrow_string + arrow_len;
10796 unsigned char *p;
10797 struct it it;
10798 int multibyte_p;
10799 int n_glyphs_before;
10801 set_buffer_temp (buffer);
10802 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
10803 it.glyph_row->used[TEXT_AREA] = 0;
10804 SET_TEXT_POS (it.position, 0, 0);
10806 multibyte_p = !NILP (buffer->enable_multibyte_characters);
10807 p = arrow_string;
10808 while (p < arrow_end)
10810 Lisp_Object face, ilisp;
10812 /* Get the next character. */
10813 if (multibyte_p)
10814 it.c = string_char_and_length (p, arrow_len, &it.len);
10815 else
10816 it.c = *p, it.len = 1;
10817 p += it.len;
10819 /* Get its face. */
10820 XSETFASTINT (ilisp, p - arrow_string);
10821 face = Fget_text_property (ilisp, Qface, Voverlay_arrow_string);
10822 it.face_id = compute_char_face (f, it.c, face);
10824 /* Compute its width, get its glyphs. */
10825 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
10826 SET_TEXT_POS (it.position, -1, -1);
10827 PRODUCE_GLYPHS (&it);
10829 /* If this character doesn't fit any more in the line, we have
10830 to remove some glyphs. */
10831 if (it.current_x > it.last_visible_x)
10833 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
10834 break;
10838 set_buffer_temp (old);
10839 return it.glyph_row;
10843 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
10844 glyphs are only inserted for terminal frames since we can't really
10845 win with truncation glyphs when partially visible glyphs are
10846 involved. Which glyphs to insert is determined by
10847 produce_special_glyphs. */
10849 static void
10850 insert_left_trunc_glyphs (it)
10851 struct it *it;
10853 struct it truncate_it;
10854 struct glyph *from, *end, *to, *toend;
10856 xassert (!FRAME_WINDOW_P (it->f));
10858 /* Get the truncation glyphs. */
10859 truncate_it = *it;
10860 truncate_it.current_x = 0;
10861 truncate_it.face_id = DEFAULT_FACE_ID;
10862 truncate_it.glyph_row = &scratch_glyph_row;
10863 truncate_it.glyph_row->used[TEXT_AREA] = 0;
10864 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
10865 truncate_it.object = make_number (0);
10866 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
10868 /* Overwrite glyphs from IT with truncation glyphs. */
10869 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
10870 end = from + truncate_it.glyph_row->used[TEXT_AREA];
10871 to = it->glyph_row->glyphs[TEXT_AREA];
10872 toend = to + it->glyph_row->used[TEXT_AREA];
10874 while (from < end)
10875 *to++ = *from++;
10877 /* There may be padding glyphs left over. Remove them. */
10878 from = to;
10879 while (from < toend && CHAR_GLYPH_PADDING_P (*from))
10880 ++from;
10881 while (from < toend)
10882 *to++ = *from++;
10884 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
10888 /* Compute the pixel height and width of IT->glyph_row.
10890 Most of the time, ascent and height of a display line will be equal
10891 to the max_ascent and max_height values of the display iterator
10892 structure. This is not the case if
10894 1. We hit ZV without displaying anything. In this case, max_ascent
10895 and max_height will be zero.
10897 2. We have some glyphs that don't contribute to the line height.
10898 (The glyph row flag contributes_to_line_height_p is for future
10899 pixmap extensions).
10901 The first case is easily covered by using default values because in
10902 these cases, the line height does not really matter, except that it
10903 must not be zero. */
10905 static void
10906 compute_line_metrics (it)
10907 struct it *it;
10909 struct glyph_row *row = it->glyph_row;
10910 int area, i;
10912 if (FRAME_WINDOW_P (it->f))
10914 int i, header_line_height;
10916 /* The line may consist of one space only, that was added to
10917 place the cursor on it. If so, the row's height hasn't been
10918 computed yet. */
10919 if (row->height == 0)
10921 if (it->max_ascent + it->max_descent == 0)
10922 it->max_descent = it->max_phys_descent = CANON_Y_UNIT (it->f);
10923 row->ascent = it->max_ascent;
10924 row->height = it->max_ascent + it->max_descent;
10925 row->phys_ascent = it->max_phys_ascent;
10926 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
10929 /* Compute the width of this line. */
10930 row->pixel_width = row->x;
10931 for (i = 0; i < row->used[TEXT_AREA]; ++i)
10932 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
10934 xassert (row->pixel_width >= 0);
10935 xassert (row->ascent >= 0 && row->height > 0);
10937 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
10938 || MATRIX_ROW_OVERLAPS_PRED_P (row));
10940 /* If first line's physical ascent is larger than its logical
10941 ascent, use the physical ascent, and make the row taller.
10942 This makes accented characters fully visible. */
10943 if (row == it->w->desired_matrix->rows
10944 && row->phys_ascent > row->ascent)
10946 row->height += row->phys_ascent - row->ascent;
10947 row->ascent = row->phys_ascent;
10950 /* Compute how much of the line is visible. */
10951 row->visible_height = row->height;
10953 header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (it->w);
10954 if (row->y < header_line_height)
10955 row->visible_height -= header_line_height - row->y;
10956 else
10958 int max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (it->w);
10959 if (row->y + row->height > max_y)
10960 row->visible_height -= row->y + row->height - max_y;
10963 else
10965 row->pixel_width = row->used[TEXT_AREA];
10966 row->ascent = row->phys_ascent = 0;
10967 row->height = row->phys_height = row->visible_height = 1;
10970 /* Compute a hash code for this row. */
10971 row->hash = 0;
10972 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
10973 for (i = 0; i < row->used[area]; ++i)
10974 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
10975 + row->glyphs[area][i].u.val
10976 + row->glyphs[area][i].face_id
10977 + row->glyphs[area][i].padding_p
10978 + (row->glyphs[area][i].type << 2));
10980 it->max_ascent = it->max_descent = 0;
10981 it->max_phys_ascent = it->max_phys_descent = 0;
10985 /* Append one space to the glyph row of iterator IT if doing a
10986 window-based redisplay. DEFAULT_FACE_P non-zero means let the
10987 space have the default face, otherwise let it have the same face as
10988 IT->face_id. Value is non-zero if a space was added.
10990 This function is called to make sure that there is always one glyph
10991 at the end of a glyph row that the cursor can be set on under
10992 window-systems. (If there weren't such a glyph we would not know
10993 how wide and tall a box cursor should be displayed).
10995 At the same time this space let's a nicely handle clearing to the
10996 end of the line if the row ends in italic text. */
10998 static int
10999 append_space (it, default_face_p)
11000 struct it *it;
11001 int default_face_p;
11003 if (FRAME_WINDOW_P (it->f))
11005 int n = it->glyph_row->used[TEXT_AREA];
11007 if (it->glyph_row->glyphs[TEXT_AREA] + n
11008 < it->glyph_row->glyphs[1 + TEXT_AREA])
11010 /* Save some values that must not be changed. */
11011 int saved_x = it->current_x;
11012 struct text_pos saved_pos;
11013 int saved_what = it->what;
11014 int saved_face_id = it->face_id;
11015 Lisp_Object saved_object;
11016 struct face *face;
11018 saved_object = it->object;
11019 saved_pos = it->position;
11021 it->what = IT_CHARACTER;
11022 bzero (&it->position, sizeof it->position);
11023 it->object = make_number (0);
11024 it->c = ' ';
11025 it->len = 1;
11027 if (default_face_p)
11028 it->face_id = DEFAULT_FACE_ID;
11029 face = FACE_FROM_ID (it->f, it->face_id);
11030 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
11032 PRODUCE_GLYPHS (it);
11034 it->current_x = saved_x;
11035 it->object = saved_object;
11036 it->position = saved_pos;
11037 it->what = saved_what;
11038 it->face_id = saved_face_id;
11039 return 1;
11043 return 0;
11047 /* Extend the face of the last glyph in the text area of IT->glyph_row
11048 to the end of the display line. Called from display_line.
11049 If the glyph row is empty, add a space glyph to it so that we
11050 know the face to draw. Set the glyph row flag fill_line_p. */
11052 static void
11053 extend_face_to_end_of_line (it)
11054 struct it *it;
11056 struct face *face;
11057 struct frame *f = it->f;
11059 /* If line is already filled, do nothing. */
11060 if (it->current_x >= it->last_visible_x)
11061 return;
11063 /* Face extension extends the background and box of IT->face_id
11064 to the end of the line. If the background equals the background
11065 of the frame, we haven't to do anything. */
11066 face = FACE_FROM_ID (f, it->face_id);
11067 if (FRAME_WINDOW_P (f)
11068 && face->box == FACE_NO_BOX
11069 && face->background == FRAME_BACKGROUND_PIXEL (f)
11070 && !face->stipple)
11071 return;
11073 /* Set the glyph row flag indicating that the face of the last glyph
11074 in the text area has to be drawn to the end of the text area. */
11075 it->glyph_row->fill_line_p = 1;
11077 /* If current character of IT is not ASCII, make sure we have the
11078 ASCII face. This will be automatically undone the next time
11079 get_next_display_element returns a multibyte character. Note
11080 that the character will always be single byte in unibyte text. */
11081 if (!SINGLE_BYTE_CHAR_P (it->c))
11083 it->face_id = FACE_FOR_CHAR (f, face, 0);
11086 if (FRAME_WINDOW_P (f))
11088 /* If the row is empty, add a space with the current face of IT,
11089 so that we know which face to draw. */
11090 if (it->glyph_row->used[TEXT_AREA] == 0)
11092 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
11093 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
11094 it->glyph_row->used[TEXT_AREA] = 1;
11097 else
11099 /* Save some values that must not be changed. */
11100 int saved_x = it->current_x;
11101 struct text_pos saved_pos;
11102 Lisp_Object saved_object;
11103 int saved_what = it->what;
11105 saved_object = it->object;
11106 saved_pos = it->position;
11108 it->what = IT_CHARACTER;
11109 bzero (&it->position, sizeof it->position);
11110 it->object = make_number (0);
11111 it->c = ' ';
11112 it->len = 1;
11114 PRODUCE_GLYPHS (it);
11116 while (it->current_x <= it->last_visible_x)
11117 PRODUCE_GLYPHS (it);
11119 /* Don't count these blanks really. It would let us insert a left
11120 truncation glyph below and make us set the cursor on them, maybe. */
11121 it->current_x = saved_x;
11122 it->object = saved_object;
11123 it->position = saved_pos;
11124 it->what = saved_what;
11129 /* Value is non-zero if text starting at CHARPOS in current_buffer is
11130 trailing whitespace. */
11132 static int
11133 trailing_whitespace_p (charpos)
11134 int charpos;
11136 int bytepos = CHAR_TO_BYTE (charpos);
11137 int c = 0;
11139 while (bytepos < ZV_BYTE
11140 && (c = FETCH_CHAR (bytepos),
11141 c == ' ' || c == '\t'))
11142 ++bytepos;
11144 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
11146 if (bytepos != PT_BYTE)
11147 return 1;
11149 return 0;
11153 /* Highlight trailing whitespace, if any, in ROW. */
11155 void
11156 highlight_trailing_whitespace (f, row)
11157 struct frame *f;
11158 struct glyph_row *row;
11160 int used = row->used[TEXT_AREA];
11162 if (used)
11164 struct glyph *start = row->glyphs[TEXT_AREA];
11165 struct glyph *glyph = start + used - 1;
11167 /* Skip over the space glyph inserted to display the
11168 cursor at the end of a line. */
11169 if (glyph->type == CHAR_GLYPH
11170 && glyph->u.ch == ' '
11171 && INTEGERP (glyph->object))
11172 --glyph;
11174 /* If last glyph is a space or stretch, and it's trailing
11175 whitespace, set the face of all trailing whitespace glyphs in
11176 IT->glyph_row to `trailing-whitespace'. */
11177 if (glyph >= start
11178 && BUFFERP (glyph->object)
11179 && (glyph->type == STRETCH_GLYPH
11180 || (glyph->type == CHAR_GLYPH
11181 && glyph->u.ch == ' '))
11182 && trailing_whitespace_p (glyph->charpos))
11184 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
11186 while (glyph >= start
11187 && BUFFERP (glyph->object)
11188 && (glyph->type == STRETCH_GLYPH
11189 || (glyph->type == CHAR_GLYPH
11190 && glyph->u.ch == ' ')))
11191 (glyph--)->face_id = face_id;
11197 /* Construct the glyph row IT->glyph_row in the desired matrix of
11198 IT->w from text at the current position of IT. See dispextern.h
11199 for an overview of struct it. Value is non-zero if
11200 IT->glyph_row displays text, as opposed to a line displaying ZV
11201 only. */
11203 static int
11204 display_line (it)
11205 struct it *it;
11207 struct glyph_row *row = it->glyph_row;
11209 /* We always start displaying at hpos zero even if hscrolled. */
11210 xassert (it->hpos == 0 && it->current_x == 0);
11212 /* We must not display in a row that's not a text row. */
11213 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
11214 < it->w->desired_matrix->nrows);
11216 /* Is IT->w showing the region? */
11217 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
11219 /* Clear the result glyph row and enable it. */
11220 prepare_desired_row (row);
11222 row->y = it->current_y;
11223 row->start = it->current;
11224 row->continuation_lines_width = it->continuation_lines_width;
11225 row->displays_text_p = 1;
11226 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
11227 it->starts_in_middle_of_char_p = 0;
11229 /* Arrange the overlays nicely for our purposes. Usually, we call
11230 display_line on only one line at a time, in which case this
11231 can't really hurt too much, or we call it on lines which appear
11232 one after another in the buffer, in which case all calls to
11233 recenter_overlay_lists but the first will be pretty cheap. */
11234 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
11236 /* Move over display elements that are not visible because we are
11237 hscrolled. This may stop at an x-position < IT->first_visible_x
11238 if the first glyph is partially visible or if we hit a line end. */
11239 if (it->current_x < it->first_visible_x)
11240 move_it_in_display_line_to (it, ZV, it->first_visible_x,
11241 MOVE_TO_POS | MOVE_TO_X);
11243 /* Get the initial row height. This is either the height of the
11244 text hscrolled, if there is any, or zero. */
11245 row->ascent = it->max_ascent;
11246 row->height = it->max_ascent + it->max_descent;
11247 row->phys_ascent = it->max_phys_ascent;
11248 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
11250 /* Loop generating characters. The loop is left with IT on the next
11251 character to display. */
11252 while (1)
11254 int n_glyphs_before, hpos_before, x_before;
11255 int x, i, nglyphs;
11256 int ascent, descent, phys_ascent, phys_descent;
11258 /* Retrieve the next thing to display. Value is zero if end of
11259 buffer reached. */
11260 if (!get_next_display_element (it))
11262 /* Maybe add a space at the end of this line that is used to
11263 display the cursor there under X. Set the charpos of the
11264 first glyph of blank lines not corresponding to any text
11265 to -1. */
11266 if ((append_space (it, 1) && row->used[TEXT_AREA] == 1)
11267 || row->used[TEXT_AREA] == 0)
11269 row->glyphs[TEXT_AREA]->charpos = -1;
11270 row->displays_text_p = 0;
11272 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines))
11273 row->indicate_empty_line_p = 1;
11276 it->continuation_lines_width = 0;
11277 row->ends_at_zv_p = 1;
11278 break;
11281 /* Now, get the metrics of what we want to display. This also
11282 generates glyphs in `row' (which is IT->glyph_row). */
11283 n_glyphs_before = row->used[TEXT_AREA];
11284 x = it->current_x;
11286 /* Remember the line height so far in case the next element doesn't
11287 fit on the line. */
11288 if (!it->truncate_lines_p)
11290 ascent = it->max_ascent;
11291 descent = it->max_descent;
11292 phys_ascent = it->max_phys_ascent;
11293 phys_descent = it->max_phys_descent;
11296 PRODUCE_GLYPHS (it);
11298 /* If this display element was in marginal areas, continue with
11299 the next one. */
11300 if (it->area != TEXT_AREA)
11302 row->ascent = max (row->ascent, it->max_ascent);
11303 row->height = max (row->height, it->max_ascent + it->max_descent);
11304 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
11305 row->phys_height = max (row->phys_height,
11306 it->max_phys_ascent + it->max_phys_descent);
11307 set_iterator_to_next (it);
11308 continue;
11311 /* Does the display element fit on the line? If we truncate
11312 lines, we should draw past the right edge of the window. If
11313 we don't truncate, we want to stop so that we can display the
11314 continuation glyph before the right margin. If lines are
11315 continued, there are two possible strategies for characters
11316 resulting in more than 1 glyph (e.g. tabs): Display as many
11317 glyphs as possible in this line and leave the rest for the
11318 continuation line, or display the whole element in the next
11319 line. Original redisplay did the former, so we do it also. */
11320 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
11321 hpos_before = it->hpos;
11322 x_before = x;
11324 if (nglyphs == 1
11325 && it->current_x < it->last_visible_x)
11327 ++it->hpos;
11328 row->ascent = max (row->ascent, it->max_ascent);
11329 row->height = max (row->height, it->max_ascent + it->max_descent);
11330 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
11331 row->phys_height = max (row->phys_height,
11332 it->max_phys_ascent + it->max_phys_descent);
11333 if (it->current_x - it->pixel_width < it->first_visible_x)
11334 row->x = x - it->first_visible_x;
11336 else
11338 int new_x;
11339 struct glyph *glyph;
11341 for (i = 0; i < nglyphs; ++i, x = new_x)
11343 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11344 new_x = x + glyph->pixel_width;
11346 if (/* Lines are continued. */
11347 !it->truncate_lines_p
11348 && (/* Glyph doesn't fit on the line. */
11349 new_x > it->last_visible_x
11350 /* Or it fits exactly on a window system frame. */
11351 || (new_x == it->last_visible_x
11352 && FRAME_WINDOW_P (it->f))))
11354 /* End of a continued line. */
11356 if (it->hpos == 0
11357 || (new_x == it->last_visible_x
11358 && FRAME_WINDOW_P (it->f)))
11360 /* Current glyph is the only one on the line or
11361 fits exactly on the line. We must continue
11362 the line because we can't draw the cursor
11363 after the glyph. */
11364 row->continued_p = 1;
11365 it->current_x = new_x;
11366 it->continuation_lines_width += new_x;
11367 ++it->hpos;
11368 if (i == nglyphs - 1)
11369 set_iterator_to_next (it);
11371 else if (CHAR_GLYPH_PADDING_P (*glyph)
11372 && !FRAME_WINDOW_P (it->f))
11374 /* A padding glyph that doesn't fit on this line.
11375 This means the whole character doesn't fit
11376 on the line. */
11377 row->used[TEXT_AREA] = n_glyphs_before;
11379 /* Fill the rest of the row with continuation
11380 glyphs like in 20.x. */
11381 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
11382 < row->glyphs[1 + TEXT_AREA])
11383 produce_special_glyphs (it, IT_CONTINUATION);
11385 row->continued_p = 1;
11386 it->current_x = x_before;
11387 it->continuation_lines_width += x_before;
11389 /* Restore the height to what it was before the
11390 element not fitting on the line. */
11391 it->max_ascent = ascent;
11392 it->max_descent = descent;
11393 it->max_phys_ascent = phys_ascent;
11394 it->max_phys_descent = phys_descent;
11396 else
11398 /* Display element draws past the right edge of
11399 the window. Restore positions to values
11400 before the element. The next line starts
11401 with current_x before the glyph that could
11402 not be displayed, so that TAB works right. */
11403 row->used[TEXT_AREA] = n_glyphs_before + i;
11405 /* Display continuation glyphs. */
11406 if (!FRAME_WINDOW_P (it->f))
11407 produce_special_glyphs (it, IT_CONTINUATION);
11408 row->continued_p = 1;
11410 it->current_x = x;
11411 it->continuation_lines_width += x;
11412 if (nglyphs > 1 && i > 0)
11414 row->ends_in_middle_of_char_p = 1;
11415 it->starts_in_middle_of_char_p = 1;
11418 /* Restore the height to what it was before the
11419 element not fitting on the line. */
11420 it->max_ascent = ascent;
11421 it->max_descent = descent;
11422 it->max_phys_ascent = phys_ascent;
11423 it->max_phys_descent = phys_descent;
11426 break;
11428 else if (new_x > it->first_visible_x)
11430 /* Increment number of glyphs actually displayed. */
11431 ++it->hpos;
11433 if (x < it->first_visible_x)
11434 /* Glyph is partially visible, i.e. row starts at
11435 negative X position. */
11436 row->x = x - it->first_visible_x;
11438 else
11440 /* Glyph is completely off the left margin of the
11441 window. This should not happen because of the
11442 move_it_in_display_line at the start of
11443 this function. */
11444 abort ();
11448 row->ascent = max (row->ascent, it->max_ascent);
11449 row->height = max (row->height, it->max_ascent + it->max_descent);
11450 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
11451 row->phys_height = max (row->phys_height,
11452 it->max_phys_ascent + it->max_phys_descent);
11454 /* End of this display line if row is continued. */
11455 if (row->continued_p)
11456 break;
11459 /* Is this a line end? If yes, we're also done, after making
11460 sure that a non-default face is extended up to the right
11461 margin of the window. */
11462 if (ITERATOR_AT_END_OF_LINE_P (it))
11464 int used_before = row->used[TEXT_AREA];
11466 /* Add a space at the end of the line that is used to
11467 display the cursor there. */
11468 append_space (it, 0);
11470 /* Extend the face to the end of the line. */
11471 extend_face_to_end_of_line (it);
11473 /* Make sure we have the position. */
11474 if (used_before == 0)
11475 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
11477 /* Consume the line end. This skips over invisible lines. */
11478 set_iterator_to_next (it);
11479 it->continuation_lines_width = 0;
11480 break;
11483 /* Proceed with next display element. Note that this skips
11484 over lines invisible because of selective display. */
11485 set_iterator_to_next (it);
11487 /* If we truncate lines, we are done when the last displayed
11488 glyphs reach past the right margin of the window. */
11489 if (it->truncate_lines_p
11490 && (FRAME_WINDOW_P (it->f)
11491 ? (it->current_x >= it->last_visible_x)
11492 : (it->current_x > it->last_visible_x)))
11494 /* Maybe add truncation glyphs. */
11495 if (!FRAME_WINDOW_P (it->f))
11497 --it->glyph_row->used[TEXT_AREA];
11498 produce_special_glyphs (it, IT_TRUNCATION);
11501 row->truncated_on_right_p = 1;
11502 it->continuation_lines_width = 0;
11503 reseat_at_next_visible_line_start (it, 0);
11504 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
11505 it->hpos = hpos_before;
11506 it->current_x = x_before;
11507 break;
11511 /* If line is not empty and hscrolled, maybe insert truncation glyphs
11512 at the left window margin. */
11513 if (it->first_visible_x
11514 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
11516 if (!FRAME_WINDOW_P (it->f))
11517 insert_left_trunc_glyphs (it);
11518 row->truncated_on_left_p = 1;
11521 /* If the start of this line is the overlay arrow-position, then
11522 mark this glyph row as the one containing the overlay arrow.
11523 This is clearly a mess with variable size fonts. It would be
11524 better to let it be displayed like cursors under X. */
11525 if (MARKERP (Voverlay_arrow_position)
11526 && current_buffer == XMARKER (Voverlay_arrow_position)->buffer
11527 && (MATRIX_ROW_START_CHARPOS (row)
11528 == marker_position (Voverlay_arrow_position))
11529 && STRINGP (Voverlay_arrow_string)
11530 && ! overlay_arrow_seen)
11532 /* Overlay arrow in window redisplay is a bitmap. */
11533 if (!FRAME_WINDOW_P (it->f))
11535 struct glyph_row *arrow_row = get_overlay_arrow_glyph_row (it->w);
11536 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
11537 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
11538 struct glyph *p = row->glyphs[TEXT_AREA];
11539 struct glyph *p2, *end;
11541 /* Copy the arrow glyphs. */
11542 while (glyph < arrow_end)
11543 *p++ = *glyph++;
11545 /* Throw away padding glyphs. */
11546 p2 = p;
11547 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
11548 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
11549 ++p2;
11550 if (p2 > p)
11552 while (p2 < end)
11553 *p++ = *p2++;
11554 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
11558 overlay_arrow_seen = 1;
11559 row->overlay_arrow_p = 1;
11562 /* Compute pixel dimensions of this line. */
11563 compute_line_metrics (it);
11565 /* Remember the position at which this line ends. */
11566 row->end = it->current;
11568 /* Maybe set the cursor. */
11569 if (it->w->cursor.vpos < 0
11570 && PT >= MATRIX_ROW_START_CHARPOS (row)
11571 && PT <= MATRIX_ROW_END_CHARPOS (row))
11573 /* Also see redisplay_window, case cursor movement in unchanged
11574 window. */
11575 if (MATRIX_ROW_END_CHARPOS (row) == PT
11576 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
11577 && !row->ends_at_zv_p)
11579 else
11580 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
11583 /* Highlight trailing whitespace. */
11584 if (!NILP (Vshow_trailing_whitespace))
11585 highlight_trailing_whitespace (it->f, it->glyph_row);
11587 /* Prepare for the next line. This line starts horizontally at (X
11588 HPOS) = (0 0). Vertical positions are incremented. As a
11589 convenience for the caller, IT->glyph_row is set to the next
11590 row to be used. */
11591 it->current_x = it->hpos = 0;
11592 it->current_y += row->height;
11593 ++it->vpos;
11594 ++it->glyph_row;
11595 return row->displays_text_p;
11600 /***********************************************************************
11601 Menu Bar
11602 ***********************************************************************/
11604 /* Redisplay the menu bar in the frame for window W.
11606 The menu bar of X frames that don't have X toolkit support is
11607 displayed in a special window W->frame->menu_bar_window.
11609 The menu bar of terminal frames is treated specially as far as
11610 glyph matrices are concerned. Menu bar lines are not part of
11611 windows, so the update is done directly on the frame matrix rows
11612 for the menu bar. */
11614 static void
11615 display_menu_bar (w)
11616 struct window *w;
11618 struct frame *f = XFRAME (WINDOW_FRAME (w));
11619 struct it it;
11620 Lisp_Object items;
11621 int i;
11623 /* Don't do all this for graphical frames. */
11624 #ifdef HAVE_NTGUI
11625 if (!NILP (Vwindow_system))
11626 return;
11627 #endif
11628 #ifdef USE_X_TOOLKIT
11629 if (FRAME_X_P (f))
11630 return;
11631 #endif
11633 #ifdef USE_X_TOOLKIT
11634 xassert (!FRAME_WINDOW_P (f));
11635 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
11636 it.first_visible_x = 0;
11637 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
11638 #else /* not USE_X_TOOLKIT */
11639 if (FRAME_WINDOW_P (f))
11641 /* Menu bar lines are displayed in the desired matrix of the
11642 dummy window menu_bar_window. */
11643 struct window *menu_w;
11644 xassert (WINDOWP (f->menu_bar_window));
11645 menu_w = XWINDOW (f->menu_bar_window);
11646 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
11647 MENU_FACE_ID);
11648 it.first_visible_x = 0;
11649 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
11651 else
11653 /* This is a TTY frame, i.e. character hpos/vpos are used as
11654 pixel x/y. */
11655 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
11656 MENU_FACE_ID);
11657 it.first_visible_x = 0;
11658 it.last_visible_x = FRAME_WIDTH (f);
11660 #endif /* not USE_X_TOOLKIT */
11662 /* Clear all rows of the menu bar. */
11663 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
11665 struct glyph_row *row = it.glyph_row + i;
11666 clear_glyph_row (row);
11667 row->enabled_p = 1;
11668 row->full_width_p = 1;
11671 /* Make the first line of the menu bar appear in reverse video. */
11672 it.glyph_row->inverse_p = mode_line_inverse_video != 0;
11674 /* Display all items of the menu bar. */
11675 items = FRAME_MENU_BAR_ITEMS (it.f);
11676 for (i = 0; i < XVECTOR (items)->size; i += 4)
11678 Lisp_Object string;
11680 /* Stop at nil string. */
11681 string = XVECTOR (items)->contents[i + 1];
11682 if (NILP (string))
11683 break;
11685 /* Remember where item was displayed. */
11686 XSETFASTINT (XVECTOR (items)->contents[i + 3], it.hpos);
11688 /* Display the item, pad with one space. */
11689 if (it.current_x < it.last_visible_x)
11690 display_string (NULL, string, Qnil, 0, 0, &it,
11691 XSTRING (string)->size + 1, 0, 0, -1);
11694 /* Fill out the line with spaces. */
11695 if (it.current_x < it.last_visible_x)
11696 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
11698 /* Compute the total height of the lines. */
11699 compute_line_metrics (&it);
11704 /***********************************************************************
11705 Mode Line
11706 ***********************************************************************/
11708 /* Display the mode and/or top line of window W. */
11710 static void
11711 display_mode_lines (w)
11712 struct window *w;
11714 /* These will be set while the mode line specs are processed. */
11715 line_number_displayed = 0;
11716 w->column_number_displayed = Qnil;
11718 if (WINDOW_WANTS_MODELINE_P (w))
11719 display_mode_line (w, MODE_LINE_FACE_ID,
11720 current_buffer->mode_line_format);
11722 if (WINDOW_WANTS_HEADER_LINE_P (w))
11723 display_mode_line (w, HEADER_LINE_FACE_ID,
11724 current_buffer->header_line_format);
11728 /* Display mode or top line of window W. FACE_ID specifies which line
11729 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
11730 FORMAT is the mode line format to display. */
11732 static void
11733 display_mode_line (w, face_id, format)
11734 struct window *w;
11735 enum face_id face_id;
11736 Lisp_Object format;
11738 struct it it;
11739 struct face *face;
11741 init_iterator (&it, w, -1, -1, NULL, face_id);
11742 prepare_desired_row (it.glyph_row);
11744 /* Temporarily make frame's keyboard the current kboard so that
11745 kboard-local variables in the mode_line_format will get the right
11746 values. */
11747 push_frame_kboard (it.f);
11748 display_mode_element (&it, 0, 0, 0, format);
11749 pop_frame_kboard ();
11751 /* Fill up with spaces. */
11752 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
11754 compute_line_metrics (&it);
11755 it.glyph_row->full_width_p = 1;
11756 it.glyph_row->mode_line_p = 1;
11757 it.glyph_row->inverse_p = mode_line_inverse_video != 0;
11758 it.glyph_row->continued_p = 0;
11759 it.glyph_row->truncated_on_left_p = 0;
11760 it.glyph_row->truncated_on_right_p = 0;
11762 /* Make a 3D mode-line have a shadow at its right end. */
11763 face = FACE_FROM_ID (it.f, face_id);
11764 extend_face_to_end_of_line (&it);
11765 if (face->box != FACE_NO_BOX)
11767 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
11768 + it.glyph_row->used[TEXT_AREA] - 1);
11769 last->right_box_line_p = 1;
11774 /* Contribute ELT to the mode line for window IT->w. How it
11775 translates into text depends on its data type.
11777 IT describes the display environment in which we display, as usual.
11779 DEPTH is the depth in recursion. It is used to prevent
11780 infinite recursion here.
11782 FIELD_WIDTH is the number of characters the display of ELT should
11783 occupy in the mode line, and PRECISION is the maximum number of
11784 characters to display from ELT's representation. See
11785 display_string for details. *
11787 Returns the hpos of the end of the text generated by ELT. */
11789 static int
11790 display_mode_element (it, depth, field_width, precision, elt)
11791 struct it *it;
11792 int depth;
11793 int field_width, precision;
11794 Lisp_Object elt;
11796 int n = 0, field, prec;
11798 tail_recurse:
11799 if (depth > 10)
11800 goto invalid;
11802 depth++;
11804 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
11806 case Lisp_String:
11808 /* A string: output it and check for %-constructs within it. */
11809 unsigned char c;
11810 unsigned char *this = XSTRING (elt)->data;
11811 unsigned char *lisp_string = this;
11813 while ((precision <= 0 || n < precision)
11814 && *this
11815 && (frame_title_ptr
11816 || it->current_x < it->last_visible_x))
11818 unsigned char *last = this;
11820 /* Advance to end of string or next format specifier. */
11821 while ((c = *this++) != '\0' && c != '%')
11824 if (this - 1 != last)
11826 /* Output to end of string or up to '%'. Field width
11827 is length of string. Don't output more than
11828 PRECISION allows us. */
11829 prec = --this - last;
11830 if (precision > 0 && prec > precision - n)
11831 prec = precision - n;
11833 if (frame_title_ptr)
11834 n += store_frame_title (last, prec, prec);
11835 else
11836 n += display_string (NULL, elt, Qnil, 0, last - lisp_string,
11837 it, 0, prec, 0, -1);
11839 else /* c == '%' */
11841 unsigned char *percent_position = this;
11843 /* Get the specified minimum width. Zero means
11844 don't pad. */
11845 field = 0;
11846 while ((c = *this++) >= '0' && c <= '9')
11847 field = field * 10 + c - '0';
11849 /* Don't pad beyond the total padding allowed. */
11850 if (field_width - n > 0 && field > field_width - n)
11851 field = field_width - n;
11853 /* Note that either PRECISION <= 0 or N < PRECISION. */
11854 prec = precision - n;
11856 if (c == 'M')
11857 n += display_mode_element (it, depth, field, prec,
11858 Vglobal_mode_string);
11859 else if (c != 0)
11861 unsigned char *spec
11862 = decode_mode_spec (it->w, c, field, prec);
11864 if (frame_title_ptr)
11865 n += store_frame_title (spec, field, prec);
11866 else
11868 int nglyphs_before
11869 = it->glyph_row->used[TEXT_AREA];
11870 int charpos
11871 = percent_position - XSTRING (elt)->data;
11872 int nwritten
11873 = display_string (spec, Qnil, elt, charpos, 0, it,
11874 field, prec, 0, -1);
11876 /* Assign to the glyphs written above the
11877 string where the `%x' came from, position
11878 of the `%'. */
11879 if (nwritten > 0)
11881 struct glyph *glyph
11882 = (it->glyph_row->glyphs[TEXT_AREA]
11883 + nglyphs_before);
11884 int i;
11886 for (i = 0; i < nwritten; ++i)
11888 glyph[i].object = elt;
11889 glyph[i].charpos = charpos;
11892 n += nwritten;
11899 break;
11901 case Lisp_Symbol:
11902 /* A symbol: process the value of the symbol recursively
11903 as if it appeared here directly. Avoid error if symbol void.
11904 Special case: if value of symbol is a string, output the string
11905 literally. */
11907 register Lisp_Object tem;
11908 tem = Fboundp (elt);
11909 if (!NILP (tem))
11911 tem = Fsymbol_value (elt);
11912 /* If value is a string, output that string literally:
11913 don't check for % within it. */
11914 if (STRINGP (tem))
11916 prec = XSTRING (tem)->size;
11917 if (precision > 0 && prec > precision - n)
11918 prec = precision - n;
11919 if (frame_title_ptr)
11920 n += store_frame_title (XSTRING (tem)->data, -1, prec);
11921 else
11922 n += display_string (NULL, tem, Qnil, 0, 0, it,
11923 0, prec, 0, -1);
11925 else if (!EQ (tem, elt))
11927 /* Give up right away for nil or t. */
11928 elt = tem;
11929 goto tail_recurse;
11933 break;
11935 case Lisp_Cons:
11937 register Lisp_Object car, tem;
11939 /* A cons cell: three distinct cases.
11940 If first element is a string or a cons, process all the elements
11941 and effectively concatenate them.
11942 If first element is a negative number, truncate displaying cdr to
11943 at most that many characters. If positive, pad (with spaces)
11944 to at least that many characters.
11945 If first element is a symbol, process the cadr or caddr recursively
11946 according to whether the symbol's value is non-nil or nil. */
11947 car = XCAR (elt);
11948 if (EQ (car, QCeval) && CONSP (XCDR (elt)))
11950 /* An element of the form (:eval FORM) means evaluate FORM
11951 and use the result as mode line elements. */
11952 struct gcpro gcpro1;
11953 Lisp_Object spec;
11955 spec = eval_form (XCAR (XCDR (elt)));
11956 GCPRO1 (spec);
11957 n += display_mode_element (it, depth, field_width - n,
11958 precision - n, spec);
11959 UNGCPRO;
11961 else if (SYMBOLP (car))
11963 tem = Fboundp (car);
11964 elt = XCDR (elt);
11965 if (!CONSP (elt))
11966 goto invalid;
11967 /* elt is now the cdr, and we know it is a cons cell.
11968 Use its car if CAR has a non-nil value. */
11969 if (!NILP (tem))
11971 tem = Fsymbol_value (car);
11972 if (!NILP (tem))
11974 elt = XCAR (elt);
11975 goto tail_recurse;
11978 /* Symbol's value is nil (or symbol is unbound)
11979 Get the cddr of the original list
11980 and if possible find the caddr and use that. */
11981 elt = XCDR (elt);
11982 if (NILP (elt))
11983 break;
11984 else if (!CONSP (elt))
11985 goto invalid;
11986 elt = XCAR (elt);
11987 goto tail_recurse;
11989 else if (INTEGERP (car))
11991 register int lim = XINT (car);
11992 elt = XCDR (elt);
11993 if (lim < 0)
11995 /* Negative int means reduce maximum width. */
11996 if (precision <= 0)
11997 precision = -lim;
11998 else
11999 precision = min (precision, -lim);
12001 else if (lim > 0)
12003 /* Padding specified. Don't let it be more than
12004 current maximum. */
12005 if (precision > 0)
12006 lim = min (precision, lim);
12008 /* If that's more padding than already wanted, queue it.
12009 But don't reduce padding already specified even if
12010 that is beyond the current truncation point. */
12011 field_width = max (lim, field_width);
12013 goto tail_recurse;
12015 else if (STRINGP (car) || CONSP (car))
12017 register int limit = 50;
12018 /* Limit is to protect against circular lists. */
12019 while (CONSP (elt)
12020 && --limit > 0
12021 && (precision <= 0 || n < precision))
12023 n += display_mode_element (it, depth, field_width - n,
12024 precision - n, XCAR (elt));
12025 elt = XCDR (elt);
12029 break;
12031 default:
12032 invalid:
12033 if (frame_title_ptr)
12034 n += store_frame_title ("*invalid*", 0, precision - n);
12035 else
12036 n += display_string ("*invalid*", Qnil, Qnil, 0, 0, it, 0,
12037 precision - n, 0, 0);
12038 return n;
12041 /* Pad to FIELD_WIDTH. */
12042 if (field_width > 0 && n < field_width)
12044 if (frame_title_ptr)
12045 n += store_frame_title ("", field_width - n, 0);
12046 else
12047 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
12048 0, 0, 0);
12051 return n;
12055 /* Write a null-terminated, right justified decimal representation of
12056 the positive integer D to BUF using a minimal field width WIDTH. */
12058 static void
12059 pint2str (buf, width, d)
12060 register char *buf;
12061 register int width;
12062 register int d;
12064 register char *p = buf;
12066 if (d <= 0)
12067 *p++ = '0';
12068 else
12070 while (d > 0)
12072 *p++ = d % 10 + '0';
12073 d /= 10;
12077 for (width -= (int) (p - buf); width > 0; --width)
12078 *p++ = ' ';
12079 *p-- = '\0';
12080 while (p > buf)
12082 d = *buf;
12083 *buf++ = *p;
12084 *p-- = d;
12088 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
12089 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
12090 type of CODING_SYSTEM. Return updated pointer into BUF. */
12092 static unsigned char invalid_eol_type[] = "(*invalid*)";
12094 static char *
12095 decode_mode_spec_coding (coding_system, buf, eol_flag)
12096 Lisp_Object coding_system;
12097 register char *buf;
12098 int eol_flag;
12100 Lisp_Object val;
12101 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
12102 unsigned char *eol_str;
12103 int eol_str_len;
12104 /* The EOL conversion we are using. */
12105 Lisp_Object eoltype;
12107 val = Fget (coding_system, Qcoding_system);
12109 if (!VECTORP (val)) /* Not yet decided. */
12111 if (multibyte)
12112 *buf++ = '-';
12113 if (eol_flag)
12114 eoltype = eol_mnemonic_undecided;
12115 /* Don't mention EOL conversion if it isn't decided. */
12117 else
12119 Lisp_Object eolvalue;
12121 eolvalue = Fget (coding_system, Qeol_type);
12123 if (multibyte)
12124 *buf++ = XFASTINT (XVECTOR (val)->contents[1]);
12126 if (eol_flag)
12128 /* The EOL conversion that is normal on this system. */
12130 if (NILP (eolvalue)) /* Not yet decided. */
12131 eoltype = eol_mnemonic_undecided;
12132 else if (VECTORP (eolvalue)) /* Not yet decided. */
12133 eoltype = eol_mnemonic_undecided;
12134 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
12135 eoltype = (XFASTINT (eolvalue) == 0
12136 ? eol_mnemonic_unix
12137 : (XFASTINT (eolvalue) == 1
12138 ? eol_mnemonic_dos : eol_mnemonic_mac));
12142 if (eol_flag)
12144 /* Mention the EOL conversion if it is not the usual one. */
12145 if (STRINGP (eoltype))
12147 eol_str = XSTRING (eoltype)->data;
12148 eol_str_len = XSTRING (eoltype)->size;
12150 else if (INTEGERP (eoltype)
12151 && CHAR_VALID_P (XINT (eoltype), 0))
12153 eol_str = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
12154 eol_str_len = CHAR_STRING (XINT (eoltype), eol_str);
12156 else
12158 eol_str = invalid_eol_type;
12159 eol_str_len = sizeof (invalid_eol_type) - 1;
12161 bcopy (eol_str, buf, eol_str_len);
12162 buf += eol_str_len;
12165 return buf;
12168 /* Return a string for the output of a mode line %-spec for window W,
12169 generated by character C. PRECISION >= 0 means don't return a
12170 string longer than that value. FIELD_WIDTH > 0 means pad the
12171 string returned with spaces to that value. */
12173 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
12175 static char *
12176 decode_mode_spec (w, c, field_width, precision)
12177 struct window *w;
12178 register int c;
12179 int field_width, precision;
12181 Lisp_Object obj;
12182 struct frame *f = XFRAME (WINDOW_FRAME (w));
12183 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
12184 struct buffer *b = XBUFFER (w->buffer);
12186 obj = Qnil;
12188 switch (c)
12190 case '*':
12191 if (!NILP (b->read_only))
12192 return "%";
12193 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
12194 return "*";
12195 return "-";
12197 case '+':
12198 /* This differs from %* only for a modified read-only buffer. */
12199 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
12200 return "*";
12201 if (!NILP (b->read_only))
12202 return "%";
12203 return "-";
12205 case '&':
12206 /* This differs from %* in ignoring read-only-ness. */
12207 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
12208 return "*";
12209 return "-";
12211 case '%':
12212 return "%";
12214 case '[':
12216 int i;
12217 char *p;
12219 if (command_loop_level > 5)
12220 return "[[[... ";
12221 p = decode_mode_spec_buf;
12222 for (i = 0; i < command_loop_level; i++)
12223 *p++ = '[';
12224 *p = 0;
12225 return decode_mode_spec_buf;
12228 case ']':
12230 int i;
12231 char *p;
12233 if (command_loop_level > 5)
12234 return " ...]]]";
12235 p = decode_mode_spec_buf;
12236 for (i = 0; i < command_loop_level; i++)
12237 *p++ = ']';
12238 *p = 0;
12239 return decode_mode_spec_buf;
12242 case '-':
12244 register int i;
12246 /* Let lots_of_dashes be a string of infinite length. */
12247 if (field_width <= 0
12248 || field_width > sizeof (lots_of_dashes))
12250 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
12251 decode_mode_spec_buf[i] = '-';
12252 decode_mode_spec_buf[i] = '\0';
12253 return decode_mode_spec_buf;
12255 else
12256 return lots_of_dashes;
12259 case 'b':
12260 obj = b->name;
12261 break;
12263 case 'c':
12265 int col = current_column ();
12266 XSETFASTINT (w->column_number_displayed, col);
12267 pint2str (decode_mode_spec_buf, field_width, col);
12268 return decode_mode_spec_buf;
12271 case 'F':
12272 /* %F displays the frame name. */
12273 if (!NILP (f->title))
12274 return (char *) XSTRING (f->title)->data;
12275 if (f->explicit_name || ! FRAME_WINDOW_P (f))
12276 return (char *) XSTRING (f->name)->data;
12277 return "Emacs";
12279 case 'f':
12280 obj = b->filename;
12281 break;
12283 case 'l':
12285 int startpos = XMARKER (w->start)->charpos;
12286 int startpos_byte = marker_byte_position (w->start);
12287 int line, linepos, linepos_byte, topline;
12288 int nlines, junk;
12289 int height = XFASTINT (w->height);
12291 /* If we decided that this buffer isn't suitable for line numbers,
12292 don't forget that too fast. */
12293 if (EQ (w->base_line_pos, w->buffer))
12294 goto no_value;
12295 /* But do forget it, if the window shows a different buffer now. */
12296 else if (BUFFERP (w->base_line_pos))
12297 w->base_line_pos = Qnil;
12299 /* If the buffer is very big, don't waste time. */
12300 if (INTEGERP (Vline_number_display_limit)
12301 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
12303 w->base_line_pos = Qnil;
12304 w->base_line_number = Qnil;
12305 goto no_value;
12308 if (!NILP (w->base_line_number)
12309 && !NILP (w->base_line_pos)
12310 && XFASTINT (w->base_line_pos) <= startpos)
12312 line = XFASTINT (w->base_line_number);
12313 linepos = XFASTINT (w->base_line_pos);
12314 linepos_byte = buf_charpos_to_bytepos (b, linepos);
12316 else
12318 line = 1;
12319 linepos = BUF_BEGV (b);
12320 linepos_byte = BUF_BEGV_BYTE (b);
12323 /* Count lines from base line to window start position. */
12324 nlines = display_count_lines (linepos, linepos_byte,
12325 startpos_byte,
12326 startpos, &junk);
12328 topline = nlines + line;
12330 /* Determine a new base line, if the old one is too close
12331 or too far away, or if we did not have one.
12332 "Too close" means it's plausible a scroll-down would
12333 go back past it. */
12334 if (startpos == BUF_BEGV (b))
12336 XSETFASTINT (w->base_line_number, topline);
12337 XSETFASTINT (w->base_line_pos, BUF_BEGV (b));
12339 else if (nlines < height + 25 || nlines > height * 3 + 50
12340 || linepos == BUF_BEGV (b))
12342 int limit = BUF_BEGV (b);
12343 int limit_byte = BUF_BEGV_BYTE (b);
12344 int position;
12345 int distance = (height * 2 + 30) * line_number_display_limit_width;
12347 if (startpos - distance > limit)
12349 limit = startpos - distance;
12350 limit_byte = CHAR_TO_BYTE (limit);
12353 nlines = display_count_lines (startpos, startpos_byte,
12354 limit_byte,
12355 - (height * 2 + 30),
12356 &position);
12357 /* If we couldn't find the lines we wanted within
12358 line_number_display_limit_width chars per line,
12359 give up on line numbers for this window. */
12360 if (position == limit_byte && limit == startpos - distance)
12362 w->base_line_pos = w->buffer;
12363 w->base_line_number = Qnil;
12364 goto no_value;
12367 XSETFASTINT (w->base_line_number, topline - nlines);
12368 XSETFASTINT (w->base_line_pos, BYTE_TO_CHAR (position));
12371 /* Now count lines from the start pos to point. */
12372 nlines = display_count_lines (startpos, startpos_byte,
12373 PT_BYTE, PT, &junk);
12375 /* Record that we did display the line number. */
12376 line_number_displayed = 1;
12378 /* Make the string to show. */
12379 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
12380 return decode_mode_spec_buf;
12381 no_value:
12383 char* p = decode_mode_spec_buf;
12384 int pad = field_width - 2;
12385 while (pad-- > 0)
12386 *p++ = ' ';
12387 *p++ = '?';
12388 *p++ = '?';
12389 *p = '\0';
12390 return decode_mode_spec_buf;
12393 break;
12395 case 'm':
12396 obj = b->mode_name;
12397 break;
12399 case 'n':
12400 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
12401 return " Narrow";
12402 break;
12404 case 'p':
12406 int pos = marker_position (w->start);
12407 int total = BUF_ZV (b) - BUF_BEGV (b);
12409 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
12411 if (pos <= BUF_BEGV (b))
12412 return "All";
12413 else
12414 return "Bottom";
12416 else if (pos <= BUF_BEGV (b))
12417 return "Top";
12418 else
12420 if (total > 1000000)
12421 /* Do it differently for a large value, to avoid overflow. */
12422 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
12423 else
12424 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
12425 /* We can't normally display a 3-digit number,
12426 so get us a 2-digit number that is close. */
12427 if (total == 100)
12428 total = 99;
12429 sprintf (decode_mode_spec_buf, "%2d%%", total);
12430 return decode_mode_spec_buf;
12434 /* Display percentage of size above the bottom of the screen. */
12435 case 'P':
12437 int toppos = marker_position (w->start);
12438 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
12439 int total = BUF_ZV (b) - BUF_BEGV (b);
12441 if (botpos >= BUF_ZV (b))
12443 if (toppos <= BUF_BEGV (b))
12444 return "All";
12445 else
12446 return "Bottom";
12448 else
12450 if (total > 1000000)
12451 /* Do it differently for a large value, to avoid overflow. */
12452 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
12453 else
12454 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
12455 /* We can't normally display a 3-digit number,
12456 so get us a 2-digit number that is close. */
12457 if (total == 100)
12458 total = 99;
12459 if (toppos <= BUF_BEGV (b))
12460 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
12461 else
12462 sprintf (decode_mode_spec_buf, "%2d%%", total);
12463 return decode_mode_spec_buf;
12467 case 's':
12468 /* status of process */
12469 obj = Fget_buffer_process (w->buffer);
12470 if (NILP (obj))
12471 return "no process";
12472 #ifdef subprocesses
12473 obj = Fsymbol_name (Fprocess_status (obj));
12474 #endif
12475 break;
12477 case 't': /* indicate TEXT or BINARY */
12478 #ifdef MODE_LINE_BINARY_TEXT
12479 return MODE_LINE_BINARY_TEXT (b);
12480 #else
12481 return "T";
12482 #endif
12484 case 'z':
12485 /* coding-system (not including end-of-line format) */
12486 case 'Z':
12487 /* coding-system (including end-of-line type) */
12489 int eol_flag = (c == 'Z');
12490 char *p = decode_mode_spec_buf;
12492 if (! FRAME_WINDOW_P (f))
12494 /* No need to mention EOL here--the terminal never needs
12495 to do EOL conversion. */
12496 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
12497 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
12499 p = decode_mode_spec_coding (b->buffer_file_coding_system,
12500 p, eol_flag);
12502 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
12503 #ifdef subprocesses
12504 obj = Fget_buffer_process (Fcurrent_buffer ());
12505 if (PROCESSP (obj))
12507 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
12508 p, eol_flag);
12509 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
12510 p, eol_flag);
12512 #endif /* subprocesses */
12513 #endif /* 0 */
12514 *p = 0;
12515 return decode_mode_spec_buf;
12519 if (STRINGP (obj))
12520 return (char *) XSTRING (obj)->data;
12521 else
12522 return "";
12526 /* Count up to COUNT lines starting from START / START_BYTE.
12527 But don't go beyond LIMIT_BYTE.
12528 Return the number of lines thus found (always nonnegative).
12530 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
12532 static int
12533 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
12534 int start, start_byte, limit_byte, count;
12535 int *byte_pos_ptr;
12537 register unsigned char *cursor;
12538 unsigned char *base;
12540 register int ceiling;
12541 register unsigned char *ceiling_addr;
12542 int orig_count = count;
12544 /* If we are not in selective display mode,
12545 check only for newlines. */
12546 int selective_display = (!NILP (current_buffer->selective_display)
12547 && !INTEGERP (current_buffer->selective_display));
12549 if (count > 0)
12551 while (start_byte < limit_byte)
12553 ceiling = BUFFER_CEILING_OF (start_byte);
12554 ceiling = min (limit_byte - 1, ceiling);
12555 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
12556 base = (cursor = BYTE_POS_ADDR (start_byte));
12557 while (1)
12559 if (selective_display)
12560 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
12562 else
12563 while (*cursor != '\n' && ++cursor != ceiling_addr)
12566 if (cursor != ceiling_addr)
12568 if (--count == 0)
12570 start_byte += cursor - base + 1;
12571 *byte_pos_ptr = start_byte;
12572 return orig_count;
12574 else
12575 if (++cursor == ceiling_addr)
12576 break;
12578 else
12579 break;
12581 start_byte += cursor - base;
12584 else
12586 while (start_byte > limit_byte)
12588 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
12589 ceiling = max (limit_byte, ceiling);
12590 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
12591 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
12592 while (1)
12594 if (selective_display)
12595 while (--cursor != ceiling_addr
12596 && *cursor != '\n' && *cursor != 015)
12598 else
12599 while (--cursor != ceiling_addr && *cursor != '\n')
12602 if (cursor != ceiling_addr)
12604 if (++count == 0)
12606 start_byte += cursor - base + 1;
12607 *byte_pos_ptr = start_byte;
12608 /* When scanning backwards, we should
12609 not count the newline posterior to which we stop. */
12610 return - orig_count - 1;
12613 else
12614 break;
12616 /* Here we add 1 to compensate for the last decrement
12617 of CURSOR, which took it past the valid range. */
12618 start_byte += cursor - base + 1;
12622 *byte_pos_ptr = limit_byte;
12624 if (count < 0)
12625 return - orig_count + count;
12626 return orig_count - count;
12632 /***********************************************************************
12633 Displaying strings
12634 ***********************************************************************/
12636 /* Display a NUL-terminated string, starting with index START.
12638 If STRING is non-null, display that C string. Otherwise, the Lisp
12639 string LISP_STRING is displayed.
12641 If FACE_STRING is not nil, FACE_STRING_POS is a position in
12642 FACE_STRING. Display STRING or LISP_STRING with the face at
12643 FACE_STRING_POS in FACE_STRING:
12645 Display the string in the environment given by IT, but use the
12646 standard display table, temporarily.
12648 FIELD_WIDTH is the minimum number of output glyphs to produce.
12649 If STRING has fewer characters than FIELD_WIDTH, pad to the right
12650 with spaces. If STRING has more characters, more than FIELD_WIDTH
12651 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
12653 PRECISION is the maximum number of characters to output from
12654 STRING. PRECISION < 0 means don't truncate the string.
12656 This is roughly equivalent to printf format specifiers:
12658 FIELD_WIDTH PRECISION PRINTF
12659 ----------------------------------------
12660 -1 -1 %s
12661 -1 10 %.10s
12662 10 -1 %10s
12663 20 10 %20.10s
12665 MULTIBYTE zero means do not display multibyte chars, > 0 means do
12666 display them, and < 0 means obey the current buffer's value of
12667 enable_multibyte_characters.
12669 Value is the number of glyphs produced. */
12671 static int
12672 display_string (string, lisp_string, face_string, face_string_pos,
12673 start, it, field_width, precision, max_x, multibyte)
12674 unsigned char *string;
12675 Lisp_Object lisp_string;
12676 Lisp_Object face_string;
12677 int face_string_pos;
12678 int start;
12679 struct it *it;
12680 int field_width, precision, max_x;
12681 int multibyte;
12683 int hpos_at_start = it->hpos;
12684 int saved_face_id = it->face_id;
12685 struct glyph_row *row = it->glyph_row;
12687 /* Initialize the iterator IT for iteration over STRING beginning
12688 with index START. We assume that IT may be modified here (which
12689 means that display_line has to do something when displaying a
12690 mini-buffer prompt, which it does). */
12691 reseat_to_string (it, string, lisp_string, start,
12692 precision, field_width, multibyte);
12694 /* If displaying STRING, set up the face of the iterator
12695 from LISP_STRING, if that's given. */
12696 if (STRINGP (face_string))
12698 int endptr;
12699 struct face *face;
12701 it->face_id
12702 = face_at_string_position (it->w, face_string, face_string_pos,
12703 0, it->region_beg_charpos,
12704 it->region_end_charpos,
12705 &endptr, it->base_face_id);
12706 face = FACE_FROM_ID (it->f, it->face_id);
12707 it->face_box_p = face->box != FACE_NO_BOX;
12710 /* Set max_x to the maximum allowed X position. Don't let it go
12711 beyond the right edge of the window. */
12712 if (max_x <= 0)
12713 max_x = it->last_visible_x;
12714 else
12715 max_x = min (max_x, it->last_visible_x);
12717 /* Skip over display elements that are not visible. because IT->w is
12718 hscrolled. */
12719 if (it->current_x < it->first_visible_x)
12720 move_it_in_display_line_to (it, 100000, it->first_visible_x,
12721 MOVE_TO_POS | MOVE_TO_X);
12723 row->ascent = it->max_ascent;
12724 row->height = it->max_ascent + it->max_descent;
12725 row->phys_ascent = it->max_phys_ascent;
12726 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
12728 /* This condition is for the case that we are called with current_x
12729 past last_visible_x. */
12730 while (it->current_x < max_x)
12732 int x_before, x, n_glyphs_before, i, nglyphs;
12734 /* Get the next display element. */
12735 if (!get_next_display_element (it))
12736 break;
12738 /* Produce glyphs. */
12739 x_before = it->current_x;
12740 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
12741 PRODUCE_GLYPHS (it);
12743 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
12744 i = 0;
12745 x = x_before;
12746 while (i < nglyphs)
12748 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
12750 if (!it->truncate_lines_p
12751 && x + glyph->pixel_width > max_x)
12753 /* End of continued line or max_x reached. */
12754 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
12755 it->current_x = x;
12756 break;
12758 else if (x + glyph->pixel_width > it->first_visible_x)
12760 /* Glyph is at least partially visible. */
12761 ++it->hpos;
12762 if (x < it->first_visible_x)
12763 it->glyph_row->x = x - it->first_visible_x;
12765 else
12767 /* Glyph is off the left margin of the display area.
12768 Should not happen. */
12769 abort ();
12772 row->ascent = max (row->ascent, it->max_ascent);
12773 row->height = max (row->height, it->max_ascent + it->max_descent);
12774 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
12775 row->phys_height = max (row->phys_height,
12776 it->max_phys_ascent + it->max_phys_descent);
12777 x += glyph->pixel_width;
12778 ++i;
12781 /* Stop if max_x reached. */
12782 if (i < nglyphs)
12783 break;
12785 /* Stop at line ends. */
12786 if (ITERATOR_AT_END_OF_LINE_P (it))
12788 it->continuation_lines_width = 0;
12789 break;
12792 set_iterator_to_next (it);
12794 /* Stop if truncating at the right edge. */
12795 if (it->truncate_lines_p
12796 && it->current_x >= it->last_visible_x)
12798 /* Add truncation mark, but don't do it if the line is
12799 truncated at a padding space. */
12800 if (IT_CHARPOS (*it) < it->string_nchars)
12802 if (!FRAME_WINDOW_P (it->f))
12803 produce_special_glyphs (it, IT_TRUNCATION);
12804 it->glyph_row->truncated_on_right_p = 1;
12806 break;
12810 /* Maybe insert a truncation at the left. */
12811 if (it->first_visible_x
12812 && IT_CHARPOS (*it) > 0)
12814 if (!FRAME_WINDOW_P (it->f))
12815 insert_left_trunc_glyphs (it);
12816 it->glyph_row->truncated_on_left_p = 1;
12819 it->face_id = saved_face_id;
12821 /* Value is number of columns displayed. */
12822 return it->hpos - hpos_at_start;
12827 /* This is like a combination of memq and assq. Return 1 if PROPVAL
12828 appears as an element of LIST or as the car of an element of LIST.
12829 If PROPVAL is a list, compare each element against LIST in that
12830 way, and return 1 if any element of PROPVAL is found in LIST.
12831 Otherwise return 0. This function cannot quit. */
12834 invisible_p (propval, list)
12835 register Lisp_Object propval;
12836 Lisp_Object list;
12838 register Lisp_Object tail, proptail;
12839 for (tail = list; CONSP (tail); tail = XCDR (tail))
12841 register Lisp_Object tem;
12842 tem = XCAR (tail);
12843 if (EQ (propval, tem))
12844 return 1;
12845 if (CONSP (tem) && EQ (propval, XCAR (tem)))
12846 return 1;
12848 if (CONSP (propval))
12849 for (proptail = propval; CONSP (proptail);
12850 proptail = XCDR (proptail))
12852 Lisp_Object propelt;
12853 propelt = XCAR (proptail);
12854 for (tail = list; CONSP (tail); tail = XCDR (tail))
12856 register Lisp_Object tem;
12857 tem = XCAR (tail);
12858 if (EQ (propelt, tem))
12859 return 1;
12860 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
12861 return 1;
12864 return 0;
12868 /* Return 1 if PROPVAL appears as the car of an element of LIST and
12869 the cdr of that element is non-nil. If PROPVAL is a list, check
12870 each element of PROPVAL in that way, and the first time some
12871 element is found, return 1 if the cdr of that element is non-nil.
12872 Otherwise return 0. This function cannot quit. */
12875 invisible_ellipsis_p (propval, list)
12876 register Lisp_Object propval;
12877 Lisp_Object list;
12879 register Lisp_Object tail, proptail;
12881 for (tail = list; CONSP (tail); tail = XCDR (tail))
12883 register Lisp_Object tem;
12884 tem = XCAR (tail);
12885 if (CONSP (tem) && EQ (propval, XCAR (tem)))
12886 return ! NILP (XCDR (tem));
12889 if (CONSP (propval))
12890 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
12892 Lisp_Object propelt;
12893 propelt = XCAR (proptail);
12894 for (tail = list; CONSP (tail); tail = XCDR (tail))
12896 register Lisp_Object tem;
12897 tem = XCAR (tail);
12898 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
12899 return ! NILP (XCDR (tem));
12903 return 0;
12908 /***********************************************************************
12909 Initialization
12910 ***********************************************************************/
12912 void
12913 syms_of_xdisp ()
12915 Vwith_echo_area_save_vector = Qnil;
12916 staticpro (&Vwith_echo_area_save_vector);
12918 Vmessage_stack = Qnil;
12919 staticpro (&Vmessage_stack);
12921 Qinhibit_redisplay = intern ("inhibit-redisplay");
12922 staticpro (&Qinhibit_redisplay);
12924 #if GLYPH_DEBUG
12925 defsubr (&Sdump_glyph_matrix);
12926 defsubr (&Sdump_glyph_row);
12927 defsubr (&Sdump_tool_bar_row);
12928 defsubr (&Strace_redisplay_toggle);
12929 defsubr (&Strace_to_stderr);
12930 #endif
12932 staticpro (&Qmenu_bar_update_hook);
12933 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
12935 staticpro (&Qoverriding_terminal_local_map);
12936 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
12938 staticpro (&Qoverriding_local_map);
12939 Qoverriding_local_map = intern ("overriding-local-map");
12941 staticpro (&Qwindow_scroll_functions);
12942 Qwindow_scroll_functions = intern ("window-scroll-functions");
12944 staticpro (&Qredisplay_end_trigger_functions);
12945 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
12947 staticpro (&Qinhibit_point_motion_hooks);
12948 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
12950 QCdata = intern (":data");
12951 staticpro (&QCdata);
12952 Qdisplay = intern ("display");
12953 staticpro (&Qdisplay);
12954 Qspace_width = intern ("space-width");
12955 staticpro (&Qspace_width);
12956 Qraise = intern ("raise");
12957 staticpro (&Qraise);
12958 Qspace = intern ("space");
12959 staticpro (&Qspace);
12960 Qmargin = intern ("margin");
12961 staticpro (&Qmargin);
12962 Qleft_margin = intern ("left-margin");
12963 staticpro (&Qleft_margin);
12964 Qright_margin = intern ("right-margin");
12965 staticpro (&Qright_margin);
12966 Qalign_to = intern ("align-to");
12967 staticpro (&Qalign_to);
12968 QCalign_to = intern (":align-to");
12969 staticpro (&QCalign_to);
12970 Qrelative_width = intern ("relative-width");
12971 staticpro (&Qrelative_width);
12972 QCrelative_width = intern (":relative-width");
12973 staticpro (&QCrelative_width);
12974 QCrelative_height = intern (":relative-height");
12975 staticpro (&QCrelative_height);
12976 QCeval = intern (":eval");
12977 staticpro (&QCeval);
12978 Qwhen = intern ("when");
12979 staticpro (&Qwhen);
12980 QCfile = intern (":file");
12981 staticpro (&QCfile);
12982 Qfontified = intern ("fontified");
12983 staticpro (&Qfontified);
12984 Qfontification_functions = intern ("fontification-functions");
12985 staticpro (&Qfontification_functions);
12986 Qtrailing_whitespace = intern ("trailing-whitespace");
12987 staticpro (&Qtrailing_whitespace);
12988 Qimage = intern ("image");
12989 staticpro (&Qimage);
12990 Qmessage_truncate_lines = intern ("message-truncate-lines");
12991 staticpro (&Qmessage_truncate_lines);
12993 last_arrow_position = Qnil;
12994 last_arrow_string = Qnil;
12995 staticpro (&last_arrow_position);
12996 staticpro (&last_arrow_string);
12998 echo_buffer[0] = echo_buffer[1] = Qnil;
12999 staticpro (&echo_buffer[0]);
13000 staticpro (&echo_buffer[1]);
13002 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
13003 staticpro (&echo_area_buffer[0]);
13004 staticpro (&echo_area_buffer[1]);
13006 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
13007 "Non-nil means highlight trailing whitespace.\n\
13008 The face used for trailing whitespace is `trailing-whitespace'.");
13009 Vshow_trailing_whitespace = Qnil;
13011 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
13012 "Non-nil means don't actually do any redisplay.\n\
13013 This is used for internal purposes.");
13014 Vinhibit_redisplay = Qnil;
13016 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
13017 "String (or mode line construct) included (normally) in `mode-line-format'.");
13018 Vglobal_mode_string = Qnil;
13020 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
13021 "Marker for where to display an arrow on top of the buffer text.\n\
13022 This must be the beginning of a line in order to work.\n\
13023 See also `overlay-arrow-string'.");
13024 Voverlay_arrow_position = Qnil;
13026 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
13027 "String to display as an arrow. See also `overlay-arrow-position'.");
13028 Voverlay_arrow_string = Qnil;
13030 DEFVAR_INT ("scroll-step", &scroll_step,
13031 "*The number of lines to try scrolling a window by when point moves out.\n\
13032 If that fails to bring point back on frame, point is centered instead.\n\
13033 If this is zero, point is always centered after it moves off frame.");
13035 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
13036 "*Scroll up to this many lines, to bring point back on screen.\n\
13037 A value of zero means to scroll the text to center point vertically\n\
13038 in the window.");
13039 scroll_conservatively = 0;
13041 DEFVAR_INT ("scroll-margin", &scroll_margin,
13042 "*Number of lines of margin at the top and bottom of a window.\n\
13043 Recenter the window whenever point gets within this many lines\n\
13044 of the top or bottom of the window.");
13045 scroll_margin = 0;
13047 #if GLYPH_DEBUG
13048 DEFVAR_INT ("debug-end-pos", &debug_end_pos, "Don't ask");
13049 #endif
13051 DEFVAR_BOOL ("truncate-partial-width-windows",
13052 &truncate_partial_width_windows,
13053 "*Non-nil means truncate lines in all windows less than full frame wide.");
13054 truncate_partial_width_windows = 1;
13056 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
13057 "*Non-nil means use inverse video for the mode line.");
13058 mode_line_inverse_video = 1;
13060 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
13061 "*Maximum buffer size for which line number should be displayed.\n\
13062 If the buffer is bigger than this, the line number does not appear\n\
13063 in the mode line. A value of nil means no limit.");
13064 Vline_number_display_limit = Qnil;
13066 DEFVAR_INT ("line-number-display-limit-width",
13067 &line_number_display_limit_width,
13068 "*Maximum line width (in characters) for line number display.\n\
13069 If the average length of the lines near point is bigger than this, then the\n\
13070 line number may be omitted from the mode line.");
13071 line_number_display_limit_width = 200;
13073 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
13074 "*Non-nil means highlight region even in nonselected windows.");
13075 highlight_nonselected_windows = 0;
13077 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
13078 "Non-nil if more than one frame is visible on this display.\n\
13079 Minibuffer-only frames don't count, but iconified frames do.\n\
13080 This variable is not guaranteed to be accurate except while processing\n\
13081 `frame-title-format' and `icon-title-format'.");
13083 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
13084 "Template for displaying the title bar of visible frames.\n\
13085 \(Assuming the window manager supports this feature.)\n\
13086 This variable has the same structure as `mode-line-format' (which see),\n\
13087 and is used only on frames for which no explicit name has been set\n\
13088 \(see `modify-frame-parameters').");
13089 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
13090 "Template for displaying the title bar of an iconified frame.\n\
13091 \(Assuming the window manager supports this feature.)\n\
13092 This variable has the same structure as `mode-line-format' (which see),\n\
13093 and is used only on frames for which no explicit name has been set\n\
13094 \(see `modify-frame-parameters').");
13095 Vicon_title_format
13096 = Vframe_title_format
13097 = Fcons (intern ("multiple-frames"),
13098 Fcons (build_string ("%b"),
13099 Fcons (Fcons (build_string (""),
13100 Fcons (intern ("invocation-name"),
13101 Fcons (build_string ("@"),
13102 Fcons (intern ("system-name"),
13103 Qnil)))),
13104 Qnil)));
13106 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
13107 "Maximum number of lines to keep in the message log buffer.\n\
13108 If nil, disable message logging. If t, log messages but don't truncate\n\
13109 the buffer when it becomes large.");
13110 XSETFASTINT (Vmessage_log_max, 50);
13112 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
13113 "Functions called before redisplay, if window sizes have changed.\n\
13114 The value should be a list of functions that take one argument.\n\
13115 Just before redisplay, for each frame, if any of its windows have changed\n\
13116 size since the last redisplay, or have been split or deleted,\n\
13117 all the functions in the list are called, with the frame as argument.");
13118 Vwindow_size_change_functions = Qnil;
13120 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
13121 "List of Functions to call before redisplaying a window with scrolling.\n\
13122 Each function is called with two arguments, the window\n\
13123 and its new display-start position. Note that the value of `window-end'\n\
13124 is not valid when these functions are called.");
13125 Vwindow_scroll_functions = Qnil;
13127 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
13128 "*Non-nil means automatically resize tool-bars.\n\
13129 This increases a tool-bar's height if not all tool-bar items are visible.\n\
13130 It decreases a tool-bar's height when it would display blank lines\n\
13131 otherwise.");
13132 auto_resize_tool_bars_p = 1;
13134 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
13135 "*Non-nil means raise tool-bar buttons when the mouse moves over them.");
13136 auto_raise_tool_bar_buttons_p = 1;
13138 DEFVAR_INT ("tool-bar-button-margin", &tool_bar_button_margin,
13139 "*Margin around tool-bar buttons in pixels.");
13140 tool_bar_button_margin = 1;
13142 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
13143 "Relief thickness of tool-bar buttons.");
13144 tool_bar_button_relief = 3;
13146 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
13147 "List of functions to call to fontify regions of text.\n\
13148 Each function is called with one argument POS. Functions must\n\
13149 fontify a region starting at POS in the current buffer, and give\n\
13150 fontified regions the property `fontified'.\n\
13151 This variable automatically becomes buffer-local when set.");
13152 Vfontification_functions = Qnil;
13153 Fmake_local_variable (Qfontification_functions);
13155 DEFVAR_BOOL ("unibyte-display-via-language-environment",
13156 &unibyte_display_via_language_environment,
13157 "*Non-nil means display unibyte text according to language environment.\n\
13158 Specifically this means that unibyte non-ASCII characters\n\
13159 are displayed by converting them to the equivalent multibyte characters\n\
13160 according to the current language environment. As a result, they are\n\
13161 displayed according to the current fontset.");
13162 unibyte_display_via_language_environment = 0;
13164 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
13165 "*Maximum height for resizing mini-windows.\n\
13166 If a float, it specifies a fraction of the mini-window frame's height.\n\
13167 If an integer, it specifies a number of lines.\n\
13168 If nil, don't resize.");
13169 Vmax_mini_window_height = make_float (0.25);
13171 DEFVAR_BOOL ("cursor-in-non-selected-windows",
13172 &cursor_in_non_selected_windows,
13173 "*Non-nil means display a hollow cursor in non-selected windows.\n\
13174 Nil means don't display a cursor there.");
13175 cursor_in_non_selected_windows = 1;
13177 DEFVAR_BOOL ("automatic-hscrolling", &automatic_hscrolling_p,
13178 "*Non-nil means scroll the display automatically to make point visible.");
13179 automatic_hscrolling_p = 1;
13181 DEFVAR_LISP ("image-types", &Vimage_types,
13182 "List of supported image types.\n\
13183 Each element of the list is a symbol for a supported image type.");
13184 Vimage_types = Qnil;
13186 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
13187 "If non-nil, messages are truncated instead of resizing the echo area.\n\
13188 Bind this around calls to `message' to let it take effect.");
13189 message_truncate_lines = 0;
13193 /* Initialize this module when Emacs starts. */
13195 void
13196 init_xdisp ()
13198 Lisp_Object root_window;
13199 struct window *mini_w;
13201 CHARPOS (this_line_start_pos) = 0;
13203 mini_w = XWINDOW (minibuf_window);
13204 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
13206 if (!noninteractive)
13208 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
13209 int i;
13211 XSETFASTINT (XWINDOW (root_window)->top, FRAME_TOP_MARGIN (f));
13212 set_window_height (root_window,
13213 FRAME_HEIGHT (f) - 1 - FRAME_TOP_MARGIN (f),
13215 XSETFASTINT (mini_w->top, FRAME_HEIGHT (f) - 1);
13216 set_window_height (minibuf_window, 1, 0);
13218 XSETFASTINT (XWINDOW (root_window)->width, FRAME_WIDTH (f));
13219 XSETFASTINT (mini_w->width, FRAME_WIDTH (f));
13221 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
13222 scratch_glyph_row.glyphs[TEXT_AREA + 1]
13223 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
13225 /* The default ellipsis glyphs `...'. */
13226 for (i = 0; i < 3; ++i)
13227 XSETFASTINT (default_invis_vector[i], '.');
13230 #ifdef HAVE_WINDOW_SYSTEM
13232 /* Allocate the buffer for frame titles. */
13233 int size = 100;
13234 frame_title_buf = (char *) xmalloc (size);
13235 frame_title_buf_end = frame_title_buf + size;
13236 frame_title_ptr = NULL;
13238 #endif /* HAVE_WINDOW_SYSTEM */