20.6, 20.7 changes
[emacs.git] / src / xdisp.c
blob1e1f5ed65e57026490f70c03daa2df1f8a9a1e16
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 static int line_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 static Lisp_Object Vmax_mini_window_height;
485 /* Non-zero means we want a hollow cursor in windows that are not
486 selected. Zero means there's no cursor in such windows. */
488 int cursor_in_non_selected_windows;
490 /* A scratch glyph row with contents used for generating truncation
491 glyphs. Also used in direct_output_for_insert. */
493 #define MAX_SCRATCH_GLYPHS 100
494 struct glyph_row scratch_glyph_row;
495 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
497 /* Ascent and height of the last line processed by move_it_to. */
499 static int last_max_ascent, last_height;
501 /* The maximum distance to look ahead for text properties. Values
502 that are too small let us call compute_char_face and similar
503 functions too often which is expensive. Values that are too large
504 let us call compute_char_face and alike too often because we
505 might not be interested in text properties that far away. */
507 #define TEXT_PROP_DISTANCE_LIMIT 100
509 /* Non-zero means print traces of redisplay if compiled with
510 GLYPH_DEBUG != 0. */
512 #if GLYPH_DEBUG
513 int trace_redisplay_p;
514 #endif
516 /* Non-zero means automatically scroll windows horizontally to make
517 point visible. */
519 int automatic_hscrolling_p;
521 /* A list of symbols, one for each supported image type. */
523 Lisp_Object Vimage_types;
525 /* Value returned from text property handlers (see below). */
527 enum prop_handled
529 HANDLED_NORMALLY,
530 HANDLED_RECOMPUTE_PROPS,
531 HANDLED_OVERLAY_STRING_CONSUMED,
532 HANDLED_RETURN
535 /* A description of text properties that redisplay is interested
536 in. */
538 struct props
540 /* The name of the property. */
541 Lisp_Object *name;
543 /* A unique index for the property. */
544 enum prop_idx idx;
546 /* A handler function called to set up iterator IT from the property
547 at IT's current position. Value is used to steer handle_stop. */
548 enum prop_handled (*handler) P_ ((struct it *it));
551 static enum prop_handled handle_face_prop P_ ((struct it *));
552 static enum prop_handled handle_invisible_prop P_ ((struct it *));
553 static enum prop_handled handle_display_prop P_ ((struct it *));
554 static enum prop_handled handle_composition_prop P_ ((struct it *));
555 static enum prop_handled handle_overlay_change P_ ((struct it *));
556 static enum prop_handled handle_fontified_prop P_ ((struct it *));
558 /* Properties handled by iterators. */
560 static struct props it_props[] =
562 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
563 /* Handle `face' before `display' because some sub-properties of
564 `display' need to know the face. */
565 {&Qface, FACE_PROP_IDX, handle_face_prop},
566 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
567 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
568 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
569 {NULL, 0, NULL}
572 /* Value is the position described by X. If X is a marker, value is
573 the marker_position of X. Otherwise, value is X. */
575 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
577 /* Enumeration returned by some move_it_.* functions internally. */
579 enum move_it_result
581 /* Not used. Undefined value. */
582 MOVE_UNDEFINED,
584 /* Move ended at the requested buffer position or ZV. */
585 MOVE_POS_MATCH_OR_ZV,
587 /* Move ended at the requested X pixel position. */
588 MOVE_X_REACHED,
590 /* Move within a line ended at the end of a line that must be
591 continued. */
592 MOVE_LINE_CONTINUED,
594 /* Move within a line ended at the end of a line that would
595 be displayed truncated. */
596 MOVE_LINE_TRUNCATED,
598 /* Move within a line ended at a line end. */
599 MOVE_NEWLINE_OR_CR
604 /* Function prototypes. */
606 static void ensure_echo_area_buffers P_ ((void));
607 static struct glyph_row *row_containing_pos P_ ((struct window *, int,
608 struct glyph_row *,
609 struct glyph_row *));
610 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
611 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
612 static void clear_garbaged_frames P_ ((void));
613 static int current_message_1 P_ ((Lisp_Object *));
614 static int truncate_message_1 P_ ((int));
615 static int set_message_1 P_ ((char *s, Lisp_Object, int, int));
616 static int display_echo_area P_ ((struct window *));
617 static int display_echo_area_1 P_ ((struct window *));
618 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
619 static int string_char_and_length P_ ((unsigned char *, int, int *));
620 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
621 struct text_pos));
622 static int compute_window_start_on_continuation_line P_ ((struct window *));
623 static Lisp_Object eval_handler P_ ((Lisp_Object));
624 static Lisp_Object eval_form P_ ((Lisp_Object));
625 static void insert_left_trunc_glyphs P_ ((struct it *));
626 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
627 static void extend_face_to_end_of_line P_ ((struct it *));
628 static int append_space P_ ((struct it *, int));
629 static void make_cursor_line_fully_visible P_ ((struct window *));
630 static int try_scrolling P_ ((Lisp_Object, int, int, int, int));
631 static int trailing_whitespace_p P_ ((int));
632 static int message_log_check_duplicate P_ ((int, int, int, int));
633 int invisible_p P_ ((Lisp_Object, Lisp_Object));
634 int invisible_ellipsis_p P_ ((Lisp_Object, Lisp_Object));
635 static void push_it P_ ((struct it *));
636 static void pop_it P_ ((struct it *));
637 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
638 static void redisplay_internal P_ ((int));
639 static int echo_area_display P_ ((int));
640 static void redisplay_windows P_ ((Lisp_Object));
641 static void redisplay_window P_ ((Lisp_Object, int));
642 static void update_menu_bar P_ ((struct frame *, int));
643 static int try_window_reusing_current_matrix P_ ((struct window *));
644 static int try_window_id P_ ((struct window *));
645 static int display_line P_ ((struct it *));
646 static void display_mode_lines P_ ((struct window *));
647 static void display_mode_line P_ ((struct window *, enum face_id,
648 Lisp_Object));
649 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object));
650 static char *decode_mode_spec P_ ((struct window *, int, int, int));
651 static void display_menu_bar P_ ((struct window *));
652 static int display_count_lines P_ ((int, int, int, int, int *));
653 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
654 int, int, struct it *, int, int, int, int));
655 static void compute_line_metrics P_ ((struct it *));
656 static void run_redisplay_end_trigger_hook P_ ((struct it *));
657 static int get_overlay_strings P_ ((struct it *));
658 static void next_overlay_string P_ ((struct it *));
659 void set_iterator_to_next P_ ((struct it *));
660 static void reseat P_ ((struct it *, struct text_pos, int));
661 static void reseat_1 P_ ((struct it *, struct text_pos, int));
662 static void back_to_previous_visible_line_start P_ ((struct it *));
663 static void reseat_at_previous_visible_line_start P_ ((struct it *));
664 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
665 static int next_element_from_display_vector P_ ((struct it *));
666 static int next_element_from_string P_ ((struct it *));
667 static int next_element_from_c_string P_ ((struct it *));
668 static int next_element_from_buffer P_ ((struct it *));
669 static int next_element_from_composition P_ ((struct it *));
670 static int next_element_from_image P_ ((struct it *));
671 static int next_element_from_stretch P_ ((struct it *));
672 static void load_overlay_strings P_ ((struct it *));
673 static void init_from_display_pos P_ ((struct it *, struct window *,
674 struct display_pos *));
675 static void reseat_to_string P_ ((struct it *, unsigned char *,
676 Lisp_Object, int, int, int, int));
677 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
678 int, int, int));
679 void move_it_vertically_backward P_ ((struct it *, int));
680 static void init_to_row_start P_ ((struct it *, struct window *,
681 struct glyph_row *));
682 static void init_to_row_end P_ ((struct it *, struct window *,
683 struct glyph_row *));
684 static void back_to_previous_line_start P_ ((struct it *));
685 static void forward_to_next_line_start P_ ((struct it *));
686 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
687 Lisp_Object, int));
688 static struct text_pos string_pos P_ ((int, Lisp_Object));
689 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
690 static int number_of_chars P_ ((unsigned char *, int));
691 static void compute_stop_pos P_ ((struct it *));
692 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
693 Lisp_Object));
694 static int face_before_or_after_it_pos P_ ((struct it *, int));
695 static int next_overlay_change P_ ((int));
696 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
697 Lisp_Object, struct text_pos *));
699 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
700 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
702 #ifdef HAVE_WINDOW_SYSTEM
704 static void update_tool_bar P_ ((struct frame *, int));
705 static void build_desired_tool_bar_string P_ ((struct frame *f));
706 static int redisplay_tool_bar P_ ((struct frame *));
707 static void display_tool_bar_line P_ ((struct it *));
709 #endif /* HAVE_WINDOW_SYSTEM */
712 /***********************************************************************
713 Window display dimensions
714 ***********************************************************************/
716 /* Return the window-relative maximum y + 1 for glyph rows displaying
717 text in window W. This is the height of W minus the height of a
718 mode line, if any. */
720 INLINE int
721 window_text_bottom_y (w)
722 struct window *w;
724 struct frame *f = XFRAME (w->frame);
725 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
727 if (WINDOW_WANTS_MODELINE_P (w))
728 height -= CURRENT_MODE_LINE_HEIGHT (w);
729 return height;
733 /* Return the pixel width of display area AREA of window W. AREA < 0
734 means return the total width of W, not including bitmap areas to
735 the left and right of the window. */
737 INLINE int
738 window_box_width (w, area)
739 struct window *w;
740 int area;
742 struct frame *f = XFRAME (w->frame);
743 int width = XFASTINT (w->width);
745 if (!w->pseudo_window_p)
747 width -= FRAME_SCROLL_BAR_WIDTH (f) + FRAME_FLAGS_AREA_COLS (f);
749 if (area == TEXT_AREA)
751 if (INTEGERP (w->left_margin_width))
752 width -= XFASTINT (w->left_margin_width);
753 if (INTEGERP (w->right_margin_width))
754 width -= XFASTINT (w->right_margin_width);
756 else if (area == LEFT_MARGIN_AREA)
757 width = (INTEGERP (w->left_margin_width)
758 ? XFASTINT (w->left_margin_width) : 0);
759 else if (area == RIGHT_MARGIN_AREA)
760 width = (INTEGERP (w->right_margin_width)
761 ? XFASTINT (w->right_margin_width) : 0);
764 return width * CANON_X_UNIT (f);
768 /* Return the pixel height of the display area of window W, not
769 including mode lines of W, if any.. */
771 INLINE int
772 window_box_height (w)
773 struct window *w;
775 struct frame *f = XFRAME (w->frame);
776 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
778 if (WINDOW_WANTS_MODELINE_P (w))
779 height -= CURRENT_MODE_LINE_HEIGHT (w);
781 if (WINDOW_WANTS_HEADER_LINE_P (w))
782 height -= CURRENT_HEADER_LINE_HEIGHT (w);
784 return height;
788 /* Return the frame-relative coordinate of the left edge of display
789 area AREA of window W. AREA < 0 means return the left edge of the
790 whole window, to the right of any bitmap area at the left side of
791 W. */
793 INLINE int
794 window_box_left (w, area)
795 struct window *w;
796 int area;
798 struct frame *f = XFRAME (w->frame);
799 int x = FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
801 if (!w->pseudo_window_p)
803 x += (WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f)
804 + FRAME_LEFT_FLAGS_AREA_WIDTH (f));
806 if (area == TEXT_AREA)
807 x += window_box_width (w, LEFT_MARGIN_AREA);
808 else if (area == RIGHT_MARGIN_AREA)
809 x += (window_box_width (w, LEFT_MARGIN_AREA)
810 + window_box_width (w, TEXT_AREA));
813 return x;
817 /* Return the frame-relative coordinate of the right edge of display
818 area AREA of window W. AREA < 0 means return the left edge of the
819 whole window, to the left of any bitmap area at the right side of
820 W. */
822 INLINE int
823 window_box_right (w, area)
824 struct window *w;
825 int area;
827 return window_box_left (w, area) + window_box_width (w, area);
831 /* Get the bounding box of the display area AREA of window W, without
832 mode lines, in frame-relative coordinates. AREA < 0 means the
833 whole window, not including bitmap areas to the left and right of
834 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
835 coordinates of the upper-left corner of the box. Return in
836 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
838 INLINE void
839 window_box (w, area, box_x, box_y, box_width, box_height)
840 struct window *w;
841 int area;
842 int *box_x, *box_y, *box_width, *box_height;
844 struct frame *f = XFRAME (w->frame);
846 *box_width = window_box_width (w, area);
847 *box_height = window_box_height (w);
848 *box_x = window_box_left (w, area);
849 *box_y = (FRAME_INTERNAL_BORDER_WIDTH_SAFE (f)
850 + XFASTINT (w->top) * CANON_Y_UNIT (f));
851 if (WINDOW_WANTS_HEADER_LINE_P (w))
852 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
856 /* Get the bounding box of the display area AREA of window W, without
857 mode lines. AREA < 0 means the whole window, not including bitmap
858 areas to the left and right of the window. Return in *TOP_LEFT_X
859 and TOP_LEFT_Y the frame-relative pixel coordinates of the
860 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
861 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
862 box. */
864 INLINE void
865 window_box_edges (w, area, top_left_x, top_left_y,
866 bottom_right_x, bottom_right_y)
867 struct window *w;
868 int area;
869 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
871 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
872 bottom_right_y);
873 *bottom_right_x += *top_left_x;
874 *bottom_right_y += *top_left_y;
879 /***********************************************************************
880 Utilities
881 ***********************************************************************/
883 /* Return the next character from STR which is MAXLEN bytes long.
884 Return in *LEN the length of the character. This is like
885 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
886 we find one, we return a `?', but with the length of the invalid
887 character. */
889 static INLINE int
890 string_char_and_length (str, maxlen, len)
891 unsigned char *str;
892 int maxlen, *len;
894 int c;
896 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
897 if (!CHAR_VALID_P (c, 1))
898 /* We may not change the length here because other places in Emacs
899 don't use this function, i.e. they silently accept invalid
900 characters. */
901 c = '?';
903 return c;
908 /* Given a position POS containing a valid character and byte position
909 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
911 static struct text_pos
912 string_pos_nchars_ahead (pos, string, nchars)
913 struct text_pos pos;
914 Lisp_Object string;
915 int nchars;
917 xassert (STRINGP (string) && nchars >= 0);
919 if (STRING_MULTIBYTE (string))
921 int rest = STRING_BYTES (XSTRING (string)) - BYTEPOS (pos);
922 unsigned char *p = XSTRING (string)->data + BYTEPOS (pos);
923 int len;
925 while (nchars--)
927 string_char_and_length (p, rest, &len);
928 p += len, rest -= len;
929 xassert (rest >= 0);
930 CHARPOS (pos) += 1;
931 BYTEPOS (pos) += len;
934 else
935 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
937 return pos;
941 /* Value is the text position, i.e. character and byte position,
942 for character position CHARPOS in STRING. */
944 static INLINE struct text_pos
945 string_pos (charpos, string)
946 int charpos;
947 Lisp_Object string;
949 struct text_pos pos;
950 xassert (STRINGP (string));
951 xassert (charpos >= 0);
952 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
953 return pos;
957 /* Value is a text position, i.e. character and byte position, for
958 character position CHARPOS in C string S. MULTIBYTE_P non-zero
959 means recognize multibyte characters. */
961 static struct text_pos
962 c_string_pos (charpos, s, multibyte_p)
963 int charpos;
964 unsigned char *s;
965 int multibyte_p;
967 struct text_pos pos;
969 xassert (s != NULL);
970 xassert (charpos >= 0);
972 if (multibyte_p)
974 int rest = strlen (s), len;
976 SET_TEXT_POS (pos, 0, 0);
977 while (charpos--)
979 string_char_and_length (s, rest, &len);
980 s += len, rest -= len;
981 xassert (rest >= 0);
982 CHARPOS (pos) += 1;
983 BYTEPOS (pos) += len;
986 else
987 SET_TEXT_POS (pos, charpos, charpos);
989 return pos;
993 /* Value is the number of characters in C string S. MULTIBYTE_P
994 non-zero means recognize multibyte characters. */
996 static int
997 number_of_chars (s, multibyte_p)
998 unsigned char *s;
999 int multibyte_p;
1001 int nchars;
1003 if (multibyte_p)
1005 int rest = strlen (s), len;
1006 unsigned char *p = (unsigned char *) s;
1008 for (nchars = 0; rest > 0; ++nchars)
1010 string_char_and_length (p, rest, &len);
1011 rest -= len, p += len;
1014 else
1015 nchars = strlen (s);
1017 return nchars;
1021 /* Compute byte position NEWPOS->bytepos corresponding to
1022 NEWPOS->charpos. POS is a known position in string STRING.
1023 NEWPOS->charpos must be >= POS.charpos. */
1025 static void
1026 compute_string_pos (newpos, pos, string)
1027 struct text_pos *newpos, pos;
1028 Lisp_Object string;
1030 xassert (STRINGP (string));
1031 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1033 if (STRING_MULTIBYTE (string))
1034 *newpos = string_pos_nchars_ahead (pos, string,
1035 CHARPOS (*newpos) - CHARPOS (pos));
1036 else
1037 BYTEPOS (*newpos) = CHARPOS (*newpos);
1042 /***********************************************************************
1043 Lisp form evaluation
1044 ***********************************************************************/
1046 /* Error handler for eval_form. */
1048 static Lisp_Object
1049 eval_handler (arg)
1050 Lisp_Object arg;
1052 return Qnil;
1056 /* Evaluate SEXPR and return the result, or nil if something went
1057 wrong. */
1059 static Lisp_Object
1060 eval_form (sexpr)
1061 Lisp_Object sexpr;
1063 int count = specpdl_ptr - specpdl;
1064 Lisp_Object val;
1065 specbind (Qinhibit_redisplay, Qt);
1066 val = internal_condition_case_1 (Feval, sexpr, Qerror, eval_handler);
1067 return unbind_to (count, val);
1072 /***********************************************************************
1073 Debugging
1074 ***********************************************************************/
1076 #if 0
1078 /* Define CHECK_IT to perform sanity checks on iterators.
1079 This is for debugging. It is too slow to do unconditionally. */
1081 static void
1082 check_it (it)
1083 struct it *it;
1085 if (it->method == next_element_from_string)
1087 xassert (STRINGP (it->string));
1088 xassert (IT_STRING_CHARPOS (*it) >= 0);
1090 else if (it->method == next_element_from_buffer)
1092 /* Check that character and byte positions agree. */
1093 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1096 if (it->dpvec)
1097 xassert (it->current.dpvec_index >= 0);
1098 else
1099 xassert (it->current.dpvec_index < 0);
1102 #define CHECK_IT(IT) check_it ((IT))
1104 #else /* not 0 */
1106 #define CHECK_IT(IT) (void) 0
1108 #endif /* not 0 */
1111 #if GLYPH_DEBUG
1113 /* Check that the window end of window W is what we expect it
1114 to be---the last row in the current matrix displaying text. */
1116 static void
1117 check_window_end (w)
1118 struct window *w;
1120 if (!MINI_WINDOW_P (w)
1121 && !NILP (w->window_end_valid))
1123 struct glyph_row *row;
1124 xassert ((row = MATRIX_ROW (w->current_matrix,
1125 XFASTINT (w->window_end_vpos)),
1126 !row->enabled_p
1127 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1128 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1132 #define CHECK_WINDOW_END(W) check_window_end ((W))
1134 #else /* not GLYPH_DEBUG */
1136 #define CHECK_WINDOW_END(W) (void) 0
1138 #endif /* not GLYPH_DEBUG */
1142 /***********************************************************************
1143 Iterator initialization
1144 ***********************************************************************/
1146 /* Initialize IT for displaying current_buffer in window W, starting
1147 at character position CHARPOS. CHARPOS < 0 means that no buffer
1148 position is specified which is useful when the iterator is assigned
1149 a position later. BYTEPOS is the byte position corresponding to
1150 CHARPOS. BYTEPOS <= 0 means compute it from CHARPOS.
1152 If ROW is not null, calls to produce_glyphs with IT as parameter
1153 will produce glyphs in that row.
1155 BASE_FACE_ID is the id of a base face to use. It must be one of
1156 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID or
1157 HEADER_LINE_FACE_ID for displaying mode lines, or TOOL_BAR_FACE_ID for
1158 displaying the tool-bar.
1160 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID or
1161 HEADER_LINE_FACE_ID, the iterator will be initialized to use the
1162 corresponding mode line glyph row of the desired matrix of W. */
1164 void
1165 init_iterator (it, w, charpos, bytepos, row, base_face_id)
1166 struct it *it;
1167 struct window *w;
1168 int charpos, bytepos;
1169 struct glyph_row *row;
1170 enum face_id base_face_id;
1172 int highlight_region_p;
1174 /* Some precondition checks. */
1175 xassert (w != NULL && it != NULL);
1176 xassert (charpos < 0 || (charpos > 0 && charpos <= ZV));
1178 /* If face attributes have been changed since the last redisplay,
1179 free realized faces now because they depend on face definitions
1180 that might have changed. */
1181 if (face_change_count)
1183 face_change_count = 0;
1184 free_all_realized_faces (Qnil);
1187 /* Use one of the mode line rows of W's desired matrix if
1188 appropriate. */
1189 if (row == NULL)
1191 if (base_face_id == MODE_LINE_FACE_ID)
1192 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
1193 else if (base_face_id == HEADER_LINE_FACE_ID)
1194 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
1197 /* Clear IT. */
1198 bzero (it, sizeof *it);
1199 it->current.overlay_string_index = -1;
1200 it->current.dpvec_index = -1;
1201 it->base_face_id = base_face_id;
1203 /* The window in which we iterate over current_buffer: */
1204 XSETWINDOW (it->window, w);
1205 it->w = w;
1206 it->f = XFRAME (w->frame);
1208 /* Extra space between lines (on window systems only). */
1209 if (base_face_id == DEFAULT_FACE_ID
1210 && FRAME_WINDOW_P (it->f))
1212 if (NATNUMP (current_buffer->extra_line_spacing))
1213 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
1214 else if (it->f->extra_line_spacing > 0)
1215 it->extra_line_spacing = it->f->extra_line_spacing;
1218 /* If realized faces have been removed, e.g. because of face
1219 attribute changes of named faces, recompute them. */
1220 if (FRAME_FACE_CACHE (it->f)->used == 0)
1221 recompute_basic_faces (it->f);
1223 /* Current value of the `space-width', and 'height' properties. */
1224 it->space_width = Qnil;
1225 it->font_height = Qnil;
1227 /* Are control characters displayed as `^C'? */
1228 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
1230 /* -1 means everything between a CR and the following line end
1231 is invisible. >0 means lines indented more than this value are
1232 invisible. */
1233 it->selective = (INTEGERP (current_buffer->selective_display)
1234 ? XFASTINT (current_buffer->selective_display)
1235 : (!NILP (current_buffer->selective_display)
1236 ? -1 : 0));
1237 it->selective_display_ellipsis_p
1238 = !NILP (current_buffer->selective_display_ellipses);
1240 /* Display table to use. */
1241 it->dp = window_display_table (w);
1243 /* Are multibyte characters enabled in current_buffer? */
1244 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
1246 /* Non-zero if we should highlight the region. */
1247 highlight_region_p
1248 = (!NILP (Vtransient_mark_mode)
1249 && !NILP (current_buffer->mark_active)
1250 && XMARKER (current_buffer->mark)->buffer != 0);
1252 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
1253 start and end of a visible region in window IT->w. Set both to
1254 -1 to indicate no region. */
1255 if (highlight_region_p
1256 /* Maybe highlight only in selected window. */
1257 && (/* Either show region everywhere. */
1258 highlight_nonselected_windows
1259 /* Or show region in the selected window. */
1260 || w == XWINDOW (selected_window)
1261 /* Or show the region if we are in the mini-buffer and W is
1262 the window the mini-buffer refers to. */
1263 || (MINI_WINDOW_P (XWINDOW (selected_window))
1264 && w == XWINDOW (Vminibuf_scroll_window))))
1266 int charpos = marker_position (current_buffer->mark);
1267 it->region_beg_charpos = min (PT, charpos);
1268 it->region_end_charpos = max (PT, charpos);
1270 else
1271 it->region_beg_charpos = it->region_end_charpos = -1;
1273 /* Get the position at which the redisplay_end_trigger hook should
1274 be run, if it is to be run at all. */
1275 if (MARKERP (w->redisplay_end_trigger)
1276 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
1277 it->redisplay_end_trigger_charpos
1278 = marker_position (w->redisplay_end_trigger);
1279 else if (INTEGERP (w->redisplay_end_trigger))
1280 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
1282 /* Correct bogus values of tab_width. */
1283 it->tab_width = XINT (current_buffer->tab_width);
1284 if (it->tab_width <= 0 || it->tab_width > 1000)
1285 it->tab_width = 8;
1287 /* Are lines in the display truncated? */
1288 it->truncate_lines_p
1289 = (base_face_id != DEFAULT_FACE_ID
1290 || XINT (it->w->hscroll)
1291 || (truncate_partial_width_windows
1292 && !WINDOW_FULL_WIDTH_P (it->w))
1293 || !NILP (current_buffer->truncate_lines));
1295 /* Get dimensions of truncation and continuation glyphs. These are
1296 displayed as bitmaps under X, so we don't need them for such
1297 frames. */
1298 if (!FRAME_WINDOW_P (it->f))
1300 if (it->truncate_lines_p)
1302 /* We will need the truncation glyph. */
1303 xassert (it->glyph_row == NULL);
1304 produce_special_glyphs (it, IT_TRUNCATION);
1305 it->truncation_pixel_width = it->pixel_width;
1307 else
1309 /* We will need the continuation glyph. */
1310 xassert (it->glyph_row == NULL);
1311 produce_special_glyphs (it, IT_CONTINUATION);
1312 it->continuation_pixel_width = it->pixel_width;
1315 /* Reset these values to zero becaue the produce_special_glyphs
1316 above has changed them. */
1317 it->pixel_width = it->ascent = it->descent = 0;
1318 it->phys_ascent = it->phys_descent = 0;
1321 /* Set this after getting the dimensions of truncation and
1322 continuation glyphs, so that we don't produce glyphs when calling
1323 produce_special_glyphs, above. */
1324 it->glyph_row = row;
1325 it->area = TEXT_AREA;
1327 /* Get the dimensions of the display area. The display area
1328 consists of the visible window area plus a horizontally scrolled
1329 part to the left of the window. All x-values are relative to the
1330 start of this total display area. */
1331 if (base_face_id != DEFAULT_FACE_ID)
1333 /* Mode lines, menu bar in terminal frames. */
1334 it->first_visible_x = 0;
1335 it->last_visible_x = XFASTINT (w->width) * CANON_X_UNIT (it->f);
1337 else
1339 it->first_visible_x
1340 = XFASTINT (it->w->hscroll) * CANON_X_UNIT (it->f);
1341 it->last_visible_x = (it->first_visible_x
1342 + window_box_width (w, TEXT_AREA));
1344 /* If we truncate lines, leave room for the truncator glyph(s) at
1345 the right margin. Otherwise, leave room for the continuation
1346 glyph(s). Truncation and continuation glyphs are not inserted
1347 for window-based redisplay. */
1348 if (!FRAME_WINDOW_P (it->f))
1350 if (it->truncate_lines_p)
1351 it->last_visible_x -= it->truncation_pixel_width;
1352 else
1353 it->last_visible_x -= it->continuation_pixel_width;
1356 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
1357 it->current_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w) + w->vscroll;
1360 /* Leave room for a border glyph. */
1361 if (!FRAME_WINDOW_P (it->f)
1362 && !WINDOW_RIGHTMOST_P (it->w))
1363 it->last_visible_x -= 1;
1365 it->last_visible_y = window_text_bottom_y (w);
1367 /* For mode lines and alike, arrange for the first glyph having a
1368 left box line if the face specifies a box. */
1369 if (base_face_id != DEFAULT_FACE_ID)
1371 struct face *face;
1373 it->face_id = base_face_id;
1375 /* If we have a boxed mode line, make the first character appear
1376 with a left box line. */
1377 face = FACE_FROM_ID (it->f, base_face_id);
1378 if (face->box != FACE_NO_BOX)
1379 it->start_of_box_run_p = 1;
1382 /* If a buffer position was specified, set the iterator there,
1383 getting overlays and face properties from that position. */
1384 if (charpos > 0)
1386 it->end_charpos = ZV;
1387 it->face_id = -1;
1388 IT_CHARPOS (*it) = charpos;
1390 /* Compute byte position if not specified. */
1391 if (bytepos <= 0)
1392 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
1393 else
1394 IT_BYTEPOS (*it) = bytepos;
1396 /* Compute faces etc. */
1397 reseat (it, it->current.pos, 1);
1400 CHECK_IT (it);
1404 /* Initialize IT for the display of window W with window start POS. */
1406 void
1407 start_display (it, w, pos)
1408 struct it *it;
1409 struct window *w;
1410 struct text_pos pos;
1412 int start_at_line_beg_p;
1413 struct glyph_row *row;
1414 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
1415 int first_y;
1417 row = w->desired_matrix->rows + first_vpos;
1418 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
1419 first_y = it->current_y;
1421 /* If window start is not at a line start, move back to the line
1422 start. This makes sure that we take continuation lines into
1423 account. */
1424 start_at_line_beg_p = (CHARPOS (pos) == BEGV
1425 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
1426 if (!start_at_line_beg_p)
1427 reseat_at_previous_visible_line_start (it);
1429 /* If window start is not at a line start, skip forward to POS to
1430 get the correct continuation_lines_width and current_x. */
1431 if (!start_at_line_beg_p)
1433 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
1435 /* If lines are continued, this line may end in the middle of a
1436 multi-glyph character (e.g. a control character displayed as
1437 \003, or in the middle of an overlay string). In this case
1438 move_it_to above will not have taken us to the start of
1439 the continuation line but to the end of the continued line. */
1440 if (!it->truncate_lines_p && it->current_x > 0)
1442 if (it->current.dpvec_index >= 0
1443 || it->current.overlay_string_index >= 0)
1445 set_iterator_to_next (it);
1446 move_it_in_display_line_to (it, -1, -1, 0);
1448 it->continuation_lines_width += it->current_x;
1451 it->current_y = first_y;
1452 it->vpos = 0;
1453 it->current_x = it->hpos = 0;
1456 #if 0 /* Don't assert the following because start_display is sometimes
1457 called intentionally with a window start that is not at a
1458 line start. Please leave this code in as a comment. */
1460 /* Window start should be on a line start, now. */
1461 xassert (it->continuation_lines_width
1462 || IT_CHARPOS (it) == BEGV
1463 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
1464 #endif /* 0 */
1468 /* Initialize IT for stepping through current_buffer in window W,
1469 starting at position POS that includes overlay string and display
1470 vector/ control character translation position information. */
1472 static void
1473 init_from_display_pos (it, w, pos)
1474 struct it *it;
1475 struct window *w;
1476 struct display_pos *pos;
1478 /* Keep in mind: the call to reseat in init_iterator skips invisible
1479 text, so we might end up at a position different from POS. This
1480 is only a problem when POS is a row start after a newline and an
1481 overlay starts there with an after-string, and the overlay has an
1482 invisible property. Since we don't skip invisible text in
1483 display_line and elsewhere immediately after consuming the
1484 newline before the row start, such a POS will not be in a string,
1485 but the call to init_iterator below will move us to the
1486 after-string. */
1487 init_iterator (it, w, CHARPOS (pos->pos), BYTEPOS (pos->pos),
1488 NULL, DEFAULT_FACE_ID);
1490 /* If position is within an overlay string, set up IT to
1491 the right overlay string. */
1492 if (pos->overlay_string_index >= 0)
1494 int relative_index;
1496 /* We already have the first chunk of overlay strings in
1497 IT->overlay_strings. Load more until the one for
1498 pos->overlay_string_index is in IT->overlay_strings. */
1499 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
1501 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
1502 it->current.overlay_string_index = 0;
1503 while (n--)
1505 load_overlay_strings (it);
1506 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
1510 it->current.overlay_string_index = pos->overlay_string_index;
1511 relative_index = (it->current.overlay_string_index
1512 % OVERLAY_STRING_CHUNK_SIZE);
1513 it->string = it->overlay_strings[relative_index];
1514 it->current.string_pos = pos->string_pos;
1515 it->method = next_element_from_string;
1517 else if (CHARPOS (pos->string_pos) >= 0)
1519 /* Recorded position is not in an overlay string, but in another
1520 string. This can only be a string from a `display' property.
1521 IT should already be filled with that string. */
1522 it->current.string_pos = pos->string_pos;
1523 xassert (STRINGP (it->string));
1526 /* Restore position in display vector translations or control
1527 character translations. */
1528 if (pos->dpvec_index >= 0)
1530 /* This fills IT->dpvec. */
1531 get_next_display_element (it);
1532 xassert (it->dpvec && it->current.dpvec_index == 0);
1533 it->current.dpvec_index = pos->dpvec_index;
1536 CHECK_IT (it);
1540 /* Initialize IT for stepping through current_buffer in window W
1541 starting at ROW->start. */
1543 static void
1544 init_to_row_start (it, w, row)
1545 struct it *it;
1546 struct window *w;
1547 struct glyph_row *row;
1549 init_from_display_pos (it, w, &row->start);
1550 it->continuation_lines_width = row->continuation_lines_width;
1551 CHECK_IT (it);
1555 /* Initialize IT for stepping through current_buffer in window W
1556 starting in the line following ROW, i.e. starting at ROW->end. */
1558 static void
1559 init_to_row_end (it, w, row)
1560 struct it *it;
1561 struct window *w;
1562 struct glyph_row *row;
1564 init_from_display_pos (it, w, &row->end);
1566 if (row->continued_p)
1567 it->continuation_lines_width = (row->continuation_lines_width
1568 + row->pixel_width);
1569 CHECK_IT (it);
1575 /***********************************************************************
1576 Text properties
1577 ***********************************************************************/
1579 /* Called when IT reaches IT->stop_charpos. Handle text property and
1580 overlay changes. Set IT->stop_charpos to the next position where
1581 to stop. */
1583 static void
1584 handle_stop (it)
1585 struct it *it;
1587 enum prop_handled handled;
1588 int handle_overlay_change_p = 1;
1589 struct props *p;
1591 it->dpvec = NULL;
1592 it->current.dpvec_index = -1;
1596 handled = HANDLED_NORMALLY;
1598 /* Call text property handlers. */
1599 for (p = it_props; p->handler; ++p)
1601 handled = p->handler (it);
1603 if (handled == HANDLED_RECOMPUTE_PROPS)
1604 break;
1605 else if (handled == HANDLED_RETURN)
1606 return;
1607 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
1608 handle_overlay_change_p = 0;
1611 if (handled != HANDLED_RECOMPUTE_PROPS)
1613 /* Don't check for overlay strings below when set to deliver
1614 characters from a display vector. */
1615 if (it->method == next_element_from_display_vector)
1616 handle_overlay_change_p = 0;
1618 /* Handle overlay changes. */
1619 if (handle_overlay_change_p)
1620 handled = handle_overlay_change (it);
1622 /* Determine where to stop next. */
1623 if (handled == HANDLED_NORMALLY)
1624 compute_stop_pos (it);
1627 while (handled == HANDLED_RECOMPUTE_PROPS);
1631 /* Compute IT->stop_charpos from text property and overlay change
1632 information for IT's current position. */
1634 static void
1635 compute_stop_pos (it)
1636 struct it *it;
1638 register INTERVAL iv, next_iv;
1639 Lisp_Object object, limit, position;
1641 /* If nowhere else, stop at the end. */
1642 it->stop_charpos = it->end_charpos;
1644 if (STRINGP (it->string))
1646 /* Strings are usually short, so don't limit the search for
1647 properties. */
1648 object = it->string;
1649 limit = Qnil;
1650 XSETFASTINT (position, IT_STRING_CHARPOS (*it));
1652 else
1654 int charpos;
1656 /* If next overlay change is in front of the current stop pos
1657 (which is IT->end_charpos), stop there. Note: value of
1658 next_overlay_change is point-max if no overlay change
1659 follows. */
1660 charpos = next_overlay_change (IT_CHARPOS (*it));
1661 if (charpos < it->stop_charpos)
1662 it->stop_charpos = charpos;
1664 /* If showing the region, we have to stop at the region
1665 start or end because the face might change there. */
1666 if (it->region_beg_charpos > 0)
1668 if (IT_CHARPOS (*it) < it->region_beg_charpos)
1669 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
1670 else if (IT_CHARPOS (*it) < it->region_end_charpos)
1671 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
1674 /* Set up variables for computing the stop position from text
1675 property changes. */
1676 XSETBUFFER (object, current_buffer);
1677 XSETFASTINT (limit, IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
1678 XSETFASTINT (position, IT_CHARPOS (*it));
1682 /* Get the interval containing IT's position. Value is a null
1683 interval if there isn't such an interval. */
1684 iv = validate_interval_range (object, &position, &position, 0);
1685 if (!NULL_INTERVAL_P (iv))
1687 Lisp_Object values_here[LAST_PROP_IDX];
1688 struct props *p;
1690 /* Get properties here. */
1691 for (p = it_props; p->handler; ++p)
1692 values_here[p->idx] = textget (iv->plist, *p->name);
1694 /* Look for an interval following iv that has different
1695 properties. */
1696 for (next_iv = next_interval (iv);
1697 (!NULL_INTERVAL_P (next_iv)
1698 && (NILP (limit)
1699 || XFASTINT (limit) > next_iv->position));
1700 next_iv = next_interval (next_iv))
1702 for (p = it_props; p->handler; ++p)
1704 Lisp_Object new_value;
1706 new_value = textget (next_iv->plist, *p->name);
1707 if (!EQ (values_here[p->idx], new_value))
1708 break;
1711 if (p->handler)
1712 break;
1715 if (!NULL_INTERVAL_P (next_iv))
1717 if (INTEGERP (limit)
1718 && next_iv->position >= XFASTINT (limit))
1719 /* No text property change up to limit. */
1720 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
1721 else
1722 /* Text properties change in next_iv. */
1723 it->stop_charpos = min (it->stop_charpos, next_iv->position);
1727 xassert (STRINGP (it->string)
1728 || (it->stop_charpos >= BEGV
1729 && it->stop_charpos >= IT_CHARPOS (*it)));
1733 /* Return the position of the next overlay change after POS in
1734 current_buffer. Value is point-max if no overlay change
1735 follows. This is like `next-overlay-change' but doesn't use
1736 xmalloc. */
1738 static int
1739 next_overlay_change (pos)
1740 int pos;
1742 int noverlays;
1743 int endpos;
1744 Lisp_Object *overlays;
1745 int len;
1746 int i;
1748 /* Get all overlays at the given position. */
1749 len = 10;
1750 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1751 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL);
1752 if (noverlays > len)
1754 len = noverlays;
1755 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1756 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL);
1759 /* If any of these overlays ends before endpos,
1760 use its ending point instead. */
1761 for (i = 0; i < noverlays; ++i)
1763 Lisp_Object oend;
1764 int oendpos;
1766 oend = OVERLAY_END (overlays[i]);
1767 oendpos = OVERLAY_POSITION (oend);
1768 endpos = min (endpos, oendpos);
1771 return endpos;
1776 /***********************************************************************
1777 Fontification
1778 ***********************************************************************/
1780 /* Handle changes in the `fontified' property of the current buffer by
1781 calling hook functions from Qfontification_functions to fontify
1782 regions of text. */
1784 static enum prop_handled
1785 handle_fontified_prop (it)
1786 struct it *it;
1788 Lisp_Object prop, pos;
1789 enum prop_handled handled = HANDLED_NORMALLY;
1791 /* Get the value of the `fontified' property at IT's current buffer
1792 position. (The `fontified' property doesn't have a special
1793 meaning in strings.) If the value is nil, call functions from
1794 Qfontification_functions. */
1795 if (!STRINGP (it->string)
1796 && it->s == NULL
1797 && !NILP (Vfontification_functions)
1798 && (pos = make_number (IT_CHARPOS (*it)),
1799 prop = Fget_char_property (pos, Qfontified, Qnil),
1800 NILP (prop)))
1802 Lisp_Object args[2];
1804 /* Run the hook functions. */
1805 args[0] = Qfontification_functions;
1806 args[1] = pos;
1807 Frun_hook_with_args (2, args);
1809 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
1810 something. This avoids an endless loop if they failed to
1811 fontify the text for which reason ever. */
1812 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
1813 handled = HANDLED_RECOMPUTE_PROPS;
1816 return handled;
1821 /***********************************************************************
1822 Faces
1823 ***********************************************************************/
1825 /* Set up iterator IT from face properties at its current position.
1826 Called from handle_stop. */
1828 static enum prop_handled
1829 handle_face_prop (it)
1830 struct it *it;
1832 int new_face_id, next_stop;
1834 if (!STRINGP (it->string))
1836 new_face_id
1837 = face_at_buffer_position (it->w,
1838 IT_CHARPOS (*it),
1839 it->region_beg_charpos,
1840 it->region_end_charpos,
1841 &next_stop,
1842 (IT_CHARPOS (*it)
1843 + TEXT_PROP_DISTANCE_LIMIT),
1846 /* Is this a start of a run of characters with box face?
1847 Caveat: this can be called for a freshly initialized
1848 iterator; face_id is -1 is this case. We know that the new
1849 face will not change until limit, i.e. if the new face has a
1850 box, all characters up to limit will have one. But, as
1851 usual, we don't know whether limit is really the end. */
1852 if (new_face_id != it->face_id)
1854 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
1856 /* If new face has a box but old face has not, this is
1857 the start of a run of characters with box, i.e. it has
1858 a shadow on the left side. The value of face_id of the
1859 iterator will be -1 if this is the initial call that gets
1860 the face. In this case, we have to look in front of IT's
1861 position and see whether there is a face != new_face_id. */
1862 it->start_of_box_run_p
1863 = (new_face->box != FACE_NO_BOX
1864 && (it->face_id >= 0
1865 || IT_CHARPOS (*it) == BEG
1866 || new_face_id != face_before_it_pos (it)));
1867 it->face_box_p = new_face->box != FACE_NO_BOX;
1870 else
1872 new_face_id
1873 = face_at_string_position (it->w,
1874 it->string,
1875 IT_STRING_CHARPOS (*it),
1876 (it->current.overlay_string_index >= 0
1877 ? IT_CHARPOS (*it)
1878 : 0),
1879 it->region_beg_charpos,
1880 it->region_end_charpos,
1881 &next_stop,
1882 it->base_face_id);
1884 #if 0 /* This shouldn't be neccessary. Let's check it. */
1885 /* If IT is used to display a mode line we would really like to
1886 use the mode line face instead of the frame's default face. */
1887 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
1888 && new_face_id == DEFAULT_FACE_ID)
1889 new_face_id = MODE_LINE_FACE_ID;
1890 #endif
1892 /* Is this a start of a run of characters with box? Caveat:
1893 this can be called for a freshly allocated iterator; face_id
1894 is -1 is this case. We know that the new face will not
1895 change until the next check pos, i.e. if the new face has a
1896 box, all characters up to that position will have a
1897 box. But, as usual, we don't know whether that position
1898 is really the end. */
1899 if (new_face_id != it->face_id)
1901 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
1902 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
1904 /* If new face has a box but old face hasn't, this is the
1905 start of a run of characters with box, i.e. it has a
1906 shadow on the left side. */
1907 it->start_of_box_run_p
1908 = new_face->box && (old_face == NULL || !old_face->box);
1909 it->face_box_p = new_face->box != FACE_NO_BOX;
1913 it->face_id = new_face_id;
1914 return HANDLED_NORMALLY;
1918 /* Compute the face one character before or after the current position
1919 of IT. BEFORE_P non-zero means get the face in front of IT's
1920 position. Value is the id of the face. */
1922 static int
1923 face_before_or_after_it_pos (it, before_p)
1924 struct it *it;
1925 int before_p;
1927 int face_id, limit;
1928 int next_check_charpos;
1929 struct text_pos pos;
1931 xassert (it->s == NULL);
1933 if (STRINGP (it->string))
1935 /* No face change past the end of the string (for the case
1936 we are padding with spaces). No face change before the
1937 string start. */
1938 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size
1939 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
1940 return it->face_id;
1942 /* Set pos to the position before or after IT's current position. */
1943 if (before_p)
1944 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
1945 else
1946 /* For composition, we must check the character after the
1947 composition. */
1948 pos = (it->what == IT_COMPOSITION
1949 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
1950 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
1952 /* Get the face for ASCII, or unibyte. */
1953 face_id
1954 = face_at_string_position (it->w,
1955 it->string,
1956 CHARPOS (pos),
1957 (it->current.overlay_string_index >= 0
1958 ? IT_CHARPOS (*it)
1959 : 0),
1960 it->region_beg_charpos,
1961 it->region_end_charpos,
1962 &next_check_charpos,
1963 it->base_face_id);
1965 /* Correct the face for charsets different from ASCII. Do it
1966 for the multibyte case only. The face returned above is
1967 suitable for unibyte text if IT->string is unibyte. */
1968 if (STRING_MULTIBYTE (it->string))
1970 unsigned char *p = XSTRING (it->string)->data + BYTEPOS (pos);
1971 int rest = STRING_BYTES (XSTRING (it->string)) - BYTEPOS (pos);
1972 int c, len;
1973 struct face *face = FACE_FROM_ID (it->f, face_id);
1975 c = string_char_and_length (p, rest, &len);
1976 face_id = FACE_FOR_CHAR (it->f, face, c);
1979 else
1981 if ((IT_CHARPOS (*it) >= ZV && !before_p)
1982 || (IT_CHARPOS (*it) <= BEGV && before_p))
1983 return it->face_id;
1985 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
1986 pos = it->current.pos;
1988 if (before_p)
1989 DEC_TEXT_POS (pos, it->multibyte_p);
1990 else
1992 if (it->what == IT_COMPOSITION)
1993 /* For composition, we must check the position after the
1994 composition. */
1995 pos.charpos += it->cmp_len, pos.bytepos += it->len;
1996 else
1997 INC_TEXT_POS (pos, it->multibyte_p);
1999 /* Determine face for CHARSET_ASCII, or unibyte. */
2000 face_id = face_at_buffer_position (it->w,
2001 CHARPOS (pos),
2002 it->region_beg_charpos,
2003 it->region_end_charpos,
2004 &next_check_charpos,
2005 limit, 0);
2007 /* Correct the face for charsets different from ASCII. Do it
2008 for the multibyte case only. The face returned above is
2009 suitable for unibyte text if current_buffer is unibyte. */
2010 if (it->multibyte_p)
2012 int c = FETCH_MULTIBYTE_CHAR (CHARPOS (pos));
2013 struct face *face = FACE_FROM_ID (it->f, face_id);
2014 face_id = FACE_FOR_CHAR (it->f, face, c);
2018 return face_id;
2023 /***********************************************************************
2024 Invisible text
2025 ***********************************************************************/
2027 /* Set up iterator IT from invisible properties at its current
2028 position. Called from handle_stop. */
2030 static enum prop_handled
2031 handle_invisible_prop (it)
2032 struct it *it;
2034 enum prop_handled handled = HANDLED_NORMALLY;
2036 if (STRINGP (it->string))
2038 extern Lisp_Object Qinvisible;
2039 Lisp_Object prop, end_charpos, limit, charpos;
2041 /* Get the value of the invisible text property at the
2042 current position. Value will be nil if there is no such
2043 property. */
2044 XSETFASTINT (charpos, IT_STRING_CHARPOS (*it));
2045 prop = Fget_text_property (charpos, Qinvisible, it->string);
2047 if (!NILP (prop)
2048 && IT_STRING_CHARPOS (*it) < it->end_charpos)
2050 handled = HANDLED_RECOMPUTE_PROPS;
2052 /* Get the position at which the next change of the
2053 invisible text property can be found in IT->string.
2054 Value will be nil if the property value is the same for
2055 all the rest of IT->string. */
2056 XSETINT (limit, XSTRING (it->string)->size);
2057 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
2058 it->string, limit);
2060 /* Text at current position is invisible. The next
2061 change in the property is at position end_charpos.
2062 Move IT's current position to that position. */
2063 if (INTEGERP (end_charpos)
2064 && XFASTINT (end_charpos) < XFASTINT (limit))
2066 struct text_pos old;
2067 old = it->current.string_pos;
2068 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
2069 compute_string_pos (&it->current.string_pos, old, it->string);
2071 else
2073 /* The rest of the string is invisible. If this is an
2074 overlay string, proceed with the next overlay string
2075 or whatever comes and return a character from there. */
2076 if (it->current.overlay_string_index >= 0)
2078 next_overlay_string (it);
2079 /* Don't check for overlay strings when we just
2080 finished processing them. */
2081 handled = HANDLED_OVERLAY_STRING_CONSUMED;
2083 else
2085 struct Lisp_String *s = XSTRING (it->string);
2086 IT_STRING_CHARPOS (*it) = s->size;
2087 IT_STRING_BYTEPOS (*it) = STRING_BYTES (s);
2092 else
2094 int visible_p, newpos, next_stop;
2095 Lisp_Object pos, prop;
2097 /* First of all, is there invisible text at this position? */
2098 XSETFASTINT (pos, IT_CHARPOS (*it));
2099 prop = Fget_char_property (pos, Qinvisible, it->window);
2101 /* If we are on invisible text, skip over it. */
2102 if (TEXT_PROP_MEANS_INVISIBLE (prop)
2103 && IT_CHARPOS (*it) < it->end_charpos)
2105 /* Record whether we have to display an ellipsis for the
2106 invisible text. */
2107 int display_ellipsis_p
2108 = TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (prop);
2110 handled = HANDLED_RECOMPUTE_PROPS;
2112 /* Loop skipping over invisible text. The loop is left at
2113 ZV or with IT on the first char being visible again. */
2116 /* Try to skip some invisible text. Return value is the
2117 position reached which can be equal to IT's position
2118 if there is nothing invisible here. This skips both
2119 over invisible text properties and overlays with
2120 invisible property. */
2121 newpos = skip_invisible (IT_CHARPOS (*it),
2122 &next_stop, ZV, it->window);
2124 /* If we skipped nothing at all we weren't at invisible
2125 text in the first place. If everything to the end of
2126 the buffer was skipped, end the loop. */
2127 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
2128 visible_p = 1;
2129 else
2131 /* We skipped some characters but not necessarily
2132 all there are. Check if we ended up on visible
2133 text. Fget_char_property returns the property of
2134 the char before the given position, i.e. if we
2135 get visible_p = 1, this means that the char at
2136 newpos is visible. */
2137 XSETFASTINT (pos, newpos);
2138 prop = Fget_char_property (pos, Qinvisible, it->window);
2139 visible_p = !TEXT_PROP_MEANS_INVISIBLE (prop);
2142 /* If we ended up on invisible text, proceed to
2143 skip starting with next_stop. */
2144 if (!visible_p)
2145 IT_CHARPOS (*it) = next_stop;
2147 while (!visible_p);
2149 /* The position newpos is now either ZV or on visible text. */
2150 IT_CHARPOS (*it) = newpos;
2151 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
2153 /* Maybe return `...' next for the end of the invisible text. */
2154 if (display_ellipsis_p)
2156 if (it->dp
2157 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
2159 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
2160 it->dpvec = v->contents;
2161 it->dpend = v->contents + v->size;
2163 else
2165 /* Default `...'. */
2166 it->dpvec = default_invis_vector;
2167 it->dpend = default_invis_vector + 3;
2170 /* The ellipsis display does not replace the display of
2171 the character at the new position. Indicate this by
2172 setting IT->dpvec_char_len to zero. */
2173 it->dpvec_char_len = 0;
2175 it->current.dpvec_index = 0;
2176 it->method = next_element_from_display_vector;
2181 return handled;
2186 /***********************************************************************
2187 'display' property
2188 ***********************************************************************/
2190 /* Set up iterator IT from `display' property at its current position.
2191 Called from handle_stop. */
2193 static enum prop_handled
2194 handle_display_prop (it)
2195 struct it *it;
2197 Lisp_Object prop, object;
2198 struct text_pos *position;
2199 int space_or_image_found_p;
2201 if (STRINGP (it->string))
2203 object = it->string;
2204 position = &it->current.string_pos;
2206 else
2208 object = Qnil;
2209 position = &it->current.pos;
2212 /* Reset those iterator values set from display property values. */
2213 it->font_height = Qnil;
2214 it->space_width = Qnil;
2215 it->voffset = 0;
2217 /* We don't support recursive `display' properties, i.e. string
2218 values that have a string `display' property, that have a string
2219 `display' property etc. */
2220 if (!it->string_from_display_prop_p)
2221 it->area = TEXT_AREA;
2223 prop = Fget_char_property (make_number (position->charpos),
2224 Qdisplay, object);
2225 if (NILP (prop))
2226 return HANDLED_NORMALLY;
2228 space_or_image_found_p = 0;
2229 if (CONSP (prop)
2230 && CONSP (XCAR (prop))
2231 && !EQ (Qmargin, XCAR (XCAR (prop))))
2233 /* A list of sub-properties. */
2234 while (CONSP (prop))
2236 if (handle_single_display_prop (it, XCAR (prop), object, position))
2237 space_or_image_found_p = 1;
2238 prop = XCDR (prop);
2241 else if (VECTORP (prop))
2243 int i;
2244 for (i = 0; i < XVECTOR (prop)->size; ++i)
2245 if (handle_single_display_prop (it, XVECTOR (prop)->contents[i],
2246 object, position))
2247 space_or_image_found_p = 1;
2249 else
2251 if (handle_single_display_prop (it, prop, object, position))
2252 space_or_image_found_p = 1;
2255 return space_or_image_found_p ? HANDLED_RETURN : HANDLED_NORMALLY;
2259 /* Value is the position of the end of the `display' property starting
2260 at START_POS in OBJECT. */
2262 static struct text_pos
2263 display_prop_end (it, object, start_pos)
2264 struct it *it;
2265 Lisp_Object object;
2266 struct text_pos start_pos;
2268 Lisp_Object end;
2269 struct text_pos end_pos;
2271 end = next_single_char_property_change (make_number (CHARPOS (start_pos)),
2272 Qdisplay, object, Qnil);
2273 CHARPOS (end_pos) = XFASTINT (end);
2274 if (STRINGP (object))
2275 compute_string_pos (&end_pos, start_pos, it->string);
2276 else
2277 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
2279 return end_pos;
2283 /* Set up IT from a single `display' sub-property value PROP. OBJECT
2284 is the object in which the `display' property was found. *POSITION
2285 is the position at which it was found.
2287 If PROP is a `space' or `image' sub-property, set *POSITION to the
2288 end position of the `display' property.
2290 Value is non-zero if a `space' or `image' property value was found. */
2292 static int
2293 handle_single_display_prop (it, prop, object, position)
2294 struct it *it;
2295 Lisp_Object prop;
2296 Lisp_Object object;
2297 struct text_pos *position;
2299 Lisp_Object value;
2300 int space_or_image_found_p = 0;
2302 Lisp_Object form;
2304 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
2305 evaluated. If the result is nil, VALUE is ignored. */
2306 form = Qt;
2307 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
2309 prop = XCDR (prop);
2310 if (!CONSP (prop))
2311 return 0;
2312 form = XCAR (prop);
2313 prop = XCDR (prop);
2316 if (!NILP (form) && !EQ (form, Qt))
2318 struct gcpro gcpro1;
2319 struct text_pos end_pos, pt;
2321 GCPRO1 (form);
2322 end_pos = display_prop_end (it, object, *position);
2324 /* Temporarily set point to the end position, and then evaluate
2325 the form. This makes `(eolp)' work as FORM. */
2326 if (BUFFERP (object))
2328 CHARPOS (pt) = PT;
2329 BYTEPOS (pt) = PT_BYTE;
2330 TEMP_SET_PT_BOTH (CHARPOS (end_pos), BYTEPOS (end_pos));
2333 form = eval_form (form);
2335 if (BUFFERP (object))
2336 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
2337 UNGCPRO;
2340 if (NILP (form))
2341 return 0;
2343 if (CONSP (prop)
2344 && EQ (XCAR (prop), Qheight)
2345 && CONSP (XCDR (prop)))
2347 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2348 return 0;
2350 /* `(height HEIGHT)'. */
2351 it->font_height = XCAR (XCDR (prop));
2352 if (!NILP (it->font_height))
2354 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2355 int new_height = -1;
2357 if (CONSP (it->font_height)
2358 && (EQ (XCAR (it->font_height), Qplus)
2359 || EQ (XCAR (it->font_height), Qminus))
2360 && CONSP (XCDR (it->font_height))
2361 && INTEGERP (XCAR (XCDR (it->font_height))))
2363 /* `(+ N)' or `(- N)' where N is an integer. */
2364 int steps = XINT (XCAR (XCDR (it->font_height)));
2365 if (EQ (XCAR (it->font_height), Qplus))
2366 steps = - steps;
2367 it->face_id = smaller_face (it->f, it->face_id, steps);
2369 else if (SYMBOLP (it->font_height))
2371 /* Call function with current height as argument.
2372 Value is the new height. */
2373 Lisp_Object form, height;
2374 struct gcpro gcpro1;
2376 height = face->lface[LFACE_HEIGHT_INDEX];
2377 form = Fcons (it->font_height, Fcons (height, Qnil));
2378 GCPRO1 (form);
2379 height = eval_form (form);
2380 if (NUMBERP (height))
2381 new_height = XFLOATINT (height);
2382 UNGCPRO;
2384 else if (NUMBERP (it->font_height))
2386 /* Value is a multiple of the canonical char height. */
2387 struct face *face;
2389 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
2390 new_height = (XFLOATINT (it->font_height)
2391 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
2393 else
2395 /* Evaluate IT->font_height with `height' bound to the
2396 current specified height to get the new height. */
2397 Lisp_Object value;
2398 int count = specpdl_ptr - specpdl;
2400 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
2401 value = eval_form (it->font_height);
2402 unbind_to (count, Qnil);
2404 if (NUMBERP (value))
2405 new_height = XFLOATINT (value);
2408 if (new_height > 0)
2409 it->face_id = face_with_height (it->f, it->face_id, new_height);
2412 else if (CONSP (prop)
2413 && EQ (XCAR (prop), Qspace_width)
2414 && CONSP (XCDR (prop)))
2416 /* `(space_width WIDTH)'. */
2417 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2418 return 0;
2420 value = XCAR (XCDR (prop));
2421 if (NUMBERP (value) && XFLOATINT (value) > 0)
2422 it->space_width = value;
2424 else if (CONSP (prop)
2425 && EQ (XCAR (prop), Qraise)
2426 && CONSP (XCDR (prop)))
2428 /* `(raise FACTOR)'. */
2429 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2430 return 0;
2432 #ifdef HAVE_WINDOW_SYSTEM
2433 value = XCAR (XCDR (prop));
2434 if (NUMBERP (value))
2436 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2437 it->voffset = - (XFLOATINT (value)
2438 * (FONT_HEIGHT (face->font)));
2440 #endif /* HAVE_WINDOW_SYSTEM */
2442 else if (!it->string_from_display_prop_p)
2444 /* `((margin left-margin) VALUE)' or `((margin right-margin)
2445 VALUE) or `((margin nil) VALUE)' or VALUE. */
2446 Lisp_Object location, value;
2447 struct text_pos start_pos;
2448 int valid_p;
2450 /* Characters having this form of property are not displayed, so
2451 we have to find the end of the property. */
2452 start_pos = *position;
2453 *position = display_prop_end (it, object, start_pos);
2454 value = Qnil;
2456 /* Let's stop at the new position and assume that all
2457 text properties change there. */
2458 it->stop_charpos = position->charpos;
2460 location = Qunbound;
2461 if (CONSP (prop) && CONSP (XCAR (prop)))
2463 Lisp_Object tem;
2465 value = XCDR (prop);
2466 if (CONSP (value))
2467 value = XCAR (value);
2469 tem = XCAR (prop);
2470 if (EQ (XCAR (tem), Qmargin)
2471 && (tem = XCDR (tem),
2472 tem = CONSP (tem) ? XCAR (tem) : Qnil,
2473 (NILP (tem)
2474 || EQ (tem, Qleft_margin)
2475 || EQ (tem, Qright_margin))))
2476 location = tem;
2479 if (EQ (location, Qunbound))
2481 location = Qnil;
2482 value = prop;
2485 #ifdef HAVE_WINDOW_SYSTEM
2486 if (FRAME_TERMCAP_P (it->f))
2487 valid_p = STRINGP (value);
2488 else
2489 valid_p = (STRINGP (value)
2490 || (CONSP (value) && EQ (XCAR (value), Qspace))
2491 || valid_image_p (value));
2492 #else /* not HAVE_WINDOW_SYSTEM */
2493 valid_p = STRINGP (value);
2494 #endif /* not HAVE_WINDOW_SYSTEM */
2496 if ((EQ (location, Qleft_margin)
2497 || EQ (location, Qright_margin)
2498 || NILP (location))
2499 && valid_p)
2501 space_or_image_found_p = 1;
2503 /* Save current settings of IT so that we can restore them
2504 when we are finished with the glyph property value. */
2505 push_it (it);
2507 if (NILP (location))
2508 it->area = TEXT_AREA;
2509 else if (EQ (location, Qleft_margin))
2510 it->area = LEFT_MARGIN_AREA;
2511 else
2512 it->area = RIGHT_MARGIN_AREA;
2514 if (STRINGP (value))
2516 it->string = value;
2517 it->multibyte_p = STRING_MULTIBYTE (it->string);
2518 it->current.overlay_string_index = -1;
2519 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
2520 it->end_charpos = it->string_nchars
2521 = XSTRING (it->string)->size;
2522 it->method = next_element_from_string;
2523 it->stop_charpos = 0;
2524 it->string_from_display_prop_p = 1;
2526 else if (CONSP (value) && EQ (XCAR (value), Qspace))
2528 it->method = next_element_from_stretch;
2529 it->object = value;
2530 it->current.pos = it->position = start_pos;
2532 #ifdef HAVE_WINDOW_SYSTEM
2533 else
2535 it->what = IT_IMAGE;
2536 it->image_id = lookup_image (it->f, value);
2537 it->position = start_pos;
2538 it->object = NILP (object) ? it->w->buffer : object;
2539 it->method = next_element_from_image;
2541 /* Say that we haven't consumed the characters with
2542 `display' property yet. The call to pop_it in
2543 set_iterator_to_next will clean this up. */
2544 *position = start_pos;
2546 #endif /* HAVE_WINDOW_SYSTEM */
2548 else
2549 /* Invalid property or property not supported. Restore
2550 the position to what it was before. */
2551 *position = start_pos;
2554 return space_or_image_found_p;
2559 /***********************************************************************
2560 `composition' property
2561 ***********************************************************************/
2563 /* Set up iterator IT from `composition' property at its current
2564 position. Called from handle_stop. */
2566 static enum prop_handled
2567 handle_composition_prop (it)
2568 struct it *it;
2570 Lisp_Object prop, string;
2571 int pos, pos_byte, end;
2572 enum prop_handled handled = HANDLED_NORMALLY;
2574 if (STRINGP (it->string))
2576 pos = IT_STRING_CHARPOS (*it);
2577 pos_byte = IT_STRING_BYTEPOS (*it);
2578 string = it->string;
2580 else
2582 pos = IT_CHARPOS (*it);
2583 pos_byte = IT_BYTEPOS (*it);
2584 string = Qnil;
2587 /* If there's a valid composition and point is not inside of the
2588 composition (in the case that the composition is from the current
2589 buffer), draw a glyph composed from the composition components. */
2590 if (find_composition (pos, -1, &pos, &end, &prop, string)
2591 && COMPOSITION_VALID_P (pos, end, prop)
2592 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
2594 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
2596 if (id >= 0)
2598 it->method = next_element_from_composition;
2599 it->cmp_id = id;
2600 it->cmp_len = COMPOSITION_LENGTH (prop);
2601 /* For a terminal, draw only the first character of the
2602 components. */
2603 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
2604 it->len = (STRINGP (it->string)
2605 ? string_char_to_byte (it->string, end)
2606 : CHAR_TO_BYTE (end)) - pos_byte;
2607 it->stop_charpos = end;
2608 handled = HANDLED_RETURN;
2612 return handled;
2617 /***********************************************************************
2618 Overlay strings
2619 ***********************************************************************/
2621 /* The following structure is used to record overlay strings for
2622 later sorting in load_overlay_strings. */
2624 struct overlay_entry
2626 Lisp_Object string;
2627 int priority;
2628 int after_string_p;
2632 /* Set up iterator IT from overlay strings at its current position.
2633 Called from handle_stop. */
2635 static enum prop_handled
2636 handle_overlay_change (it)
2637 struct it *it;
2639 /* Overlays are handled in current_buffer only. */
2640 if (STRINGP (it->string))
2641 return HANDLED_NORMALLY;
2642 else
2643 return (get_overlay_strings (it)
2644 ? HANDLED_RECOMPUTE_PROPS
2645 : HANDLED_NORMALLY);
2649 /* Set up the next overlay string for delivery by IT, if there is an
2650 overlay string to deliver. Called by set_iterator_to_next when the
2651 end of the current overlay string is reached. If there are more
2652 overlay strings to display, IT->string and
2653 IT->current.overlay_string_index are set appropriately here.
2654 Otherwise IT->string is set to nil. */
2656 static void
2657 next_overlay_string (it)
2658 struct it *it;
2660 ++it->current.overlay_string_index;
2661 if (it->current.overlay_string_index == it->n_overlay_strings)
2663 /* No more overlay strings. Restore IT's settings to what
2664 they were before overlay strings were processed, and
2665 continue to deliver from current_buffer. */
2666 pop_it (it);
2667 xassert (it->stop_charpos >= BEGV
2668 && it->stop_charpos <= it->end_charpos);
2669 it->string = Qnil;
2670 it->current.overlay_string_index = -1;
2671 SET_TEXT_POS (it->current.string_pos, -1, -1);
2672 it->n_overlay_strings = 0;
2673 it->method = next_element_from_buffer;
2675 else
2677 /* There are more overlay strings to process. If
2678 IT->current.overlay_string_index has advanced to a position
2679 where we must load IT->overlay_strings with more strings, do
2680 it. */
2681 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
2683 if (it->current.overlay_string_index && i == 0)
2684 load_overlay_strings (it);
2686 /* Initialize IT to deliver display elements from the overlay
2687 string. */
2688 it->string = it->overlay_strings[i];
2689 it->multibyte_p = STRING_MULTIBYTE (it->string);
2690 SET_TEXT_POS (it->current.string_pos, 0, 0);
2691 it->method = next_element_from_string;
2692 it->stop_charpos = 0;
2695 CHECK_IT (it);
2699 /* Compare two overlay_entry structures E1 and E2. Used as a
2700 comparison function for qsort in load_overlay_strings. Overlay
2701 strings for the same position are sorted so that
2703 1. All after-strings come in front of before-strings.
2705 2. Within after-strings, strings are sorted so that overlay strings
2706 from overlays with higher priorities come first.
2708 2. Within before-strings, strings are sorted so that overlay
2709 strings from overlays with higher priorities come last.
2711 Value is analogous to strcmp. */
2714 static int
2715 compare_overlay_entries (e1, e2)
2716 void *e1, *e2;
2718 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
2719 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
2720 int result;
2722 if (entry1->after_string_p != entry2->after_string_p)
2723 /* Let after-strings appear in front of before-strings. */
2724 result = entry1->after_string_p ? -1 : 1;
2725 else if (entry1->after_string_p)
2726 /* After-strings sorted in order of decreasing priority. */
2727 result = entry2->priority - entry1->priority;
2728 else
2729 /* Before-strings sorted in order of increasing priority. */
2730 result = entry1->priority - entry2->priority;
2732 return result;
2736 /* Load the vector IT->overlay_strings with overlay strings from IT's
2737 current buffer position. Set IT->n_overlays to the total number of
2738 overlay strings found.
2740 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
2741 a time. On entry into load_overlay_strings,
2742 IT->current.overlay_string_index gives the number of overlay
2743 strings that have already been loaded by previous calls to this
2744 function.
2746 Overlay strings are sorted so that after-string strings come in
2747 front of before-string strings. Within before and after-strings,
2748 strings are sorted by overlay priority. See also function
2749 compare_overlay_entries. */
2751 static void
2752 load_overlay_strings (it)
2753 struct it *it;
2755 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
2756 Lisp_Object ov, overlay, window, str;
2757 int start, end;
2758 int size = 20;
2759 int n = 0, i, j;
2760 struct overlay_entry *entries
2761 = (struct overlay_entry *) alloca (size * sizeof *entries);
2763 /* Append the overlay string STRING of overlay OVERLAY to vector
2764 `entries' which has size `size' and currently contains `n'
2765 elements. AFTER_P non-zero means STRING is an after-string of
2766 OVERLAY. */
2767 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
2768 do \
2770 Lisp_Object priority; \
2772 if (n == size) \
2774 int new_size = 2 * size; \
2775 struct overlay_entry *old = entries; \
2776 entries = \
2777 (struct overlay_entry *) alloca (new_size \
2778 * sizeof *entries); \
2779 bcopy (old, entries, size * sizeof *entries); \
2780 size = new_size; \
2783 entries[n].string = (STRING); \
2784 priority = Foverlay_get ((OVERLAY), Qpriority); \
2785 entries[n].priority \
2786 = INTEGERP (priority) ? XFASTINT (priority) : 0; \
2787 entries[n].after_string_p = (AFTER_P); \
2788 ++n; \
2790 while (0)
2792 /* Process overlay before the overlay center. */
2793 for (ov = current_buffer->overlays_before;
2794 CONSP (ov);
2795 ov = XCDR (ov))
2797 overlay = XCAR (ov);
2798 xassert (OVERLAYP (overlay));
2799 start = OVERLAY_POSITION (OVERLAY_START (overlay));
2800 end = OVERLAY_POSITION (OVERLAY_END (overlay));
2802 if (end < IT_CHARPOS (*it))
2803 break;
2805 /* Skip this overlay if it doesn't start or end at IT's current
2806 position. */
2807 if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it))
2808 continue;
2810 /* Skip this overlay if it doesn't apply to IT->w. */
2811 window = Foverlay_get (overlay, Qwindow);
2812 if (WINDOWP (window) && XWINDOW (window) != it->w)
2813 continue;
2815 /* If overlay has a non-empty before-string, record it. */
2816 if (start == IT_CHARPOS (*it)
2817 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
2818 && XSTRING (str)->size)
2819 RECORD_OVERLAY_STRING (overlay, str, 0);
2821 /* If overlay has a non-empty after-string, record it. */
2822 if (end == IT_CHARPOS (*it)
2823 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
2824 && XSTRING (str)->size)
2825 RECORD_OVERLAY_STRING (overlay, str, 1);
2828 /* Process overlays after the overlay center. */
2829 for (ov = current_buffer->overlays_after;
2830 CONSP (ov);
2831 ov = XCDR (ov))
2833 overlay = XCAR (ov);
2834 xassert (OVERLAYP (overlay));
2835 start = OVERLAY_POSITION (OVERLAY_START (overlay));
2836 end = OVERLAY_POSITION (OVERLAY_END (overlay));
2838 if (start > IT_CHARPOS (*it))
2839 break;
2841 /* Skip this overlay if it doesn't start or end at IT's current
2842 position. */
2843 if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it))
2844 continue;
2846 /* Skip this overlay if it doesn't apply to IT->w. */
2847 window = Foverlay_get (overlay, Qwindow);
2848 if (WINDOWP (window) && XWINDOW (window) != it->w)
2849 continue;
2851 /* If overlay has a non-empty before-string, record it. */
2852 if (start == IT_CHARPOS (*it)
2853 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
2854 && XSTRING (str)->size)
2855 RECORD_OVERLAY_STRING (overlay, str, 0);
2857 /* If overlay has a non-empty after-string, record it. */
2858 if (end == IT_CHARPOS (*it)
2859 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
2860 && XSTRING (str)->size)
2861 RECORD_OVERLAY_STRING (overlay, str, 1);
2864 #undef RECORD_OVERLAY_STRING
2866 /* Sort entries. */
2867 qsort (entries, n, sizeof *entries, compare_overlay_entries);
2869 /* Record the total number of strings to process. */
2870 it->n_overlay_strings = n;
2872 /* IT->current.overlay_string_index is the number of overlay strings
2873 that have already been consumed by IT. Copy some of the
2874 remaining overlay strings to IT->overlay_strings. */
2875 i = 0;
2876 j = it->current.overlay_string_index;
2877 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
2878 it->overlay_strings[i++] = entries[j++].string;
2880 CHECK_IT (it);
2884 /* Get the first chunk of overlay strings at IT's current buffer
2885 position. Value is non-zero if at least one overlay string was
2886 found. */
2888 static int
2889 get_overlay_strings (it)
2890 struct it *it;
2892 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
2893 process. This fills IT->overlay_strings with strings, and sets
2894 IT->n_overlay_strings to the total number of strings to process.
2895 IT->pos.overlay_string_index has to be set temporarily to zero
2896 because load_overlay_strings needs this; it must be set to -1
2897 when no overlay strings are found because a zero value would
2898 indicate a position in the first overlay string. */
2899 it->current.overlay_string_index = 0;
2900 load_overlay_strings (it);
2902 /* If we found overlay strings, set up IT to deliver display
2903 elements from the first one. Otherwise set up IT to deliver
2904 from current_buffer. */
2905 if (it->n_overlay_strings)
2907 /* Make sure we know settings in current_buffer, so that we can
2908 restore meaningful values when we're done with the overlay
2909 strings. */
2910 compute_stop_pos (it);
2911 xassert (it->face_id >= 0);
2913 /* Save IT's settings. They are restored after all overlay
2914 strings have been processed. */
2915 xassert (it->sp == 0);
2916 push_it (it);
2918 /* Set up IT to deliver display elements from the first overlay
2919 string. */
2920 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
2921 it->stop_charpos = 0;
2922 it->string = it->overlay_strings[0];
2923 it->multibyte_p = STRING_MULTIBYTE (it->string);
2924 xassert (STRINGP (it->string));
2925 it->method = next_element_from_string;
2927 else
2929 it->string = Qnil;
2930 it->current.overlay_string_index = -1;
2931 it->method = next_element_from_buffer;
2934 CHECK_IT (it);
2936 /* Value is non-zero if we found at least one overlay string. */
2937 return STRINGP (it->string);
2942 /***********************************************************************
2943 Saving and restoring state
2944 ***********************************************************************/
2946 /* Save current settings of IT on IT->stack. Called, for example,
2947 before setting up IT for an overlay string, to be able to restore
2948 IT's settings to what they were after the overlay string has been
2949 processed. */
2951 static void
2952 push_it (it)
2953 struct it *it;
2955 struct iterator_stack_entry *p;
2957 xassert (it->sp < 2);
2958 p = it->stack + it->sp;
2960 p->stop_charpos = it->stop_charpos;
2961 xassert (it->face_id >= 0);
2962 p->face_id = it->face_id;
2963 p->string = it->string;
2964 p->pos = it->current;
2965 p->end_charpos = it->end_charpos;
2966 p->string_nchars = it->string_nchars;
2967 p->area = it->area;
2968 p->multibyte_p = it->multibyte_p;
2969 p->space_width = it->space_width;
2970 p->font_height = it->font_height;
2971 p->voffset = it->voffset;
2972 p->string_from_display_prop_p = it->string_from_display_prop_p;
2973 ++it->sp;
2977 /* Restore IT's settings from IT->stack. Called, for example, when no
2978 more overlay strings must be processed, and we return to delivering
2979 display elements from a buffer, or when the end of a string from a
2980 `display' property is reached and we return to delivering display
2981 elements from an overlay string, or from a buffer. */
2983 static void
2984 pop_it (it)
2985 struct it *it;
2987 struct iterator_stack_entry *p;
2989 xassert (it->sp > 0);
2990 --it->sp;
2991 p = it->stack + it->sp;
2992 it->stop_charpos = p->stop_charpos;
2993 it->face_id = p->face_id;
2994 it->string = p->string;
2995 it->current = p->pos;
2996 it->end_charpos = p->end_charpos;
2997 it->string_nchars = p->string_nchars;
2998 it->area = p->area;
2999 it->multibyte_p = p->multibyte_p;
3000 it->space_width = p->space_width;
3001 it->font_height = p->font_height;
3002 it->voffset = p->voffset;
3003 it->string_from_display_prop_p = p->string_from_display_prop_p;
3008 /***********************************************************************
3009 Moving over lines
3010 ***********************************************************************/
3012 /* Set IT's current position to the previous line start. */
3014 static void
3015 back_to_previous_line_start (it)
3016 struct it *it;
3018 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
3019 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
3023 /* Set IT's current position to the next line start. */
3025 static void
3026 forward_to_next_line_start (it)
3027 struct it *it;
3029 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), 1);
3030 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
3034 /* Set IT's current position to the previous visible line start. Skip
3035 invisible text that is so either due to text properties or due to
3036 selective display. Caution: this does not change IT->current_x and
3037 IT->hpos. */
3039 static void
3040 back_to_previous_visible_line_start (it)
3041 struct it *it;
3043 int visible_p = 0;
3045 /* Go back one newline if not on BEGV already. */
3046 if (IT_CHARPOS (*it) > BEGV)
3047 back_to_previous_line_start (it);
3049 /* Move over lines that are invisible because of selective display
3050 or text properties. */
3051 while (IT_CHARPOS (*it) > BEGV
3052 && !visible_p)
3054 visible_p = 1;
3056 /* If selective > 0, then lines indented more than that values
3057 are invisible. */
3058 if (it->selective > 0
3059 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
3060 it->selective))
3061 visible_p = 0;
3062 else
3064 Lisp_Object prop;
3066 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
3067 Qinvisible, it->window);
3068 if (TEXT_PROP_MEANS_INVISIBLE (prop))
3069 visible_p = 0;
3072 /* Back one more newline if the current one is invisible. */
3073 if (!visible_p)
3074 back_to_previous_line_start (it);
3077 xassert (IT_CHARPOS (*it) >= BEGV);
3078 xassert (IT_CHARPOS (*it) == BEGV
3079 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
3080 CHECK_IT (it);
3084 /* Reseat iterator IT at the previous visible line start. Skip
3085 invisible text that is so either due to text properties or due to
3086 selective display. At the end, update IT's overlay information,
3087 face information etc. */
3089 static void
3090 reseat_at_previous_visible_line_start (it)
3091 struct it *it;
3093 back_to_previous_visible_line_start (it);
3094 reseat (it, it->current.pos, 1);
3095 CHECK_IT (it);
3099 /* Reseat iterator IT on the next visible line start in the current
3100 buffer. ON_NEWLINE_P non-zero means position IT on the newline
3101 preceding the line start. Skip over invisible text that is so
3102 because of selective display. Compute faces, overlays etc at the
3103 new position. Note that this function does not skip over text that
3104 is invisible because of text properties. */
3106 static void
3107 reseat_at_next_visible_line_start (it, on_newline_p)
3108 struct it *it;
3109 int on_newline_p;
3111 /* Restore the buffer position when currently not delivering display
3112 elements from the current buffer. This is the case, for example,
3113 when called at the end of a truncated overlay string. */
3114 while (it->sp)
3115 pop_it (it);
3116 it->method = next_element_from_buffer;
3118 /* Otherwise, scan_buffer would not work. */
3119 if (IT_CHARPOS (*it) < ZV)
3121 /* If on a newline, advance past it. Otherwise, find the next
3122 newline which automatically gives us the position following
3123 the newline. */
3124 if (FETCH_BYTE (IT_BYTEPOS (*it)) == '\n')
3126 ++IT_CHARPOS (*it);
3127 ++IT_BYTEPOS (*it);
3129 else
3130 forward_to_next_line_start (it);
3132 /* We must either have reached the end of the buffer or end up
3133 after a newline. */
3134 xassert (IT_CHARPOS (*it) == ZV
3135 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
3137 /* Skip over lines that are invisible because they are indented
3138 more than the value of IT->selective. */
3139 if (it->selective > 0)
3140 while (IT_CHARPOS (*it) < ZV
3141 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
3142 it->selective))
3143 forward_to_next_line_start (it);
3145 /* Position on the newline if we should. */
3146 if (on_newline_p
3147 && IT_CHARPOS (*it) > BEGV
3148 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n')
3150 --IT_CHARPOS (*it);
3151 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
3154 /* Set the iterator there. The 0 as the last parameter of
3155 reseat means don't force a text property lookup. The lookup
3156 is then only done if we've skipped past the iterator's
3157 check_charpos'es. This optimization is important because
3158 text property lookups tend to be expensive. */
3159 reseat (it, it->current.pos, 0);
3162 CHECK_IT (it);
3167 /***********************************************************************
3168 Changing an iterator's position
3169 ***********************************************************************/
3171 /* Change IT's current position to POS in current_buffer. If FORCE_P
3172 is non-zero, always check for text properties at the new position.
3173 Otherwise, text properties are only looked up if POS >=
3174 IT->check_charpos of a property. */
3176 static void
3177 reseat (it, pos, force_p)
3178 struct it *it;
3179 struct text_pos pos;
3180 int force_p;
3182 int original_pos = IT_CHARPOS (*it);
3184 reseat_1 (it, pos, 0);
3186 /* Determine where to check text properties. Avoid doing it
3187 where possible because text property lookup is very expensive. */
3188 if (force_p
3189 || CHARPOS (pos) > it->stop_charpos
3190 || CHARPOS (pos) < original_pos)
3191 handle_stop (it);
3193 CHECK_IT (it);
3197 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
3198 IT->stop_pos to POS, also. */
3200 static void
3201 reseat_1 (it, pos, set_stop_p)
3202 struct it *it;
3203 struct text_pos pos;
3204 int set_stop_p;
3206 /* Don't call this function when scanning a C string. */
3207 xassert (it->s == NULL);
3209 /* POS must be a reasonable value. */
3210 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
3212 it->current.pos = it->position = pos;
3213 XSETBUFFER (it->object, current_buffer);
3214 it->dpvec = NULL;
3215 it->current.dpvec_index = -1;
3216 it->current.overlay_string_index = -1;
3217 IT_STRING_CHARPOS (*it) = -1;
3218 IT_STRING_BYTEPOS (*it) = -1;
3219 it->string = Qnil;
3220 it->method = next_element_from_buffer;
3221 it->sp = 0;
3223 if (set_stop_p)
3224 it->stop_charpos = CHARPOS (pos);
3228 /* Set up IT for displaying a string, starting at CHARPOS in window W.
3229 If S is non-null, it is a C string to iterate over. Otherwise,
3230 STRING gives a Lisp string to iterate over.
3232 If PRECISION > 0, don't return more then PRECISION number of
3233 characters from the string.
3235 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
3236 characters have been returned. FIELD_WIDTH < 0 means an infinite
3237 field width.
3239 MULTIBYTE = 0 means disable processing of multibyte characters,
3240 MULTIBYTE > 0 means enable it,
3241 MULTIBYTE < 0 means use IT->multibyte_p.
3243 IT must be initialized via a prior call to init_iterator before
3244 calling this function. */
3246 static void
3247 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
3248 struct it *it;
3249 unsigned char *s;
3250 Lisp_Object string;
3251 int charpos;
3252 int precision, field_width, multibyte;
3254 /* No region in strings. */
3255 it->region_beg_charpos = it->region_end_charpos = -1;
3257 /* No text property checks performed by default, but see below. */
3258 it->stop_charpos = -1;
3260 /* Set iterator position and end position. */
3261 bzero (&it->current, sizeof it->current);
3262 it->current.overlay_string_index = -1;
3263 it->current.dpvec_index = -1;
3264 xassert (charpos >= 0);
3266 /* Use the setting of MULTIBYTE if specified. */
3267 if (multibyte >= 0)
3268 it->multibyte_p = multibyte > 0;
3270 if (s == NULL)
3272 xassert (STRINGP (string));
3273 it->string = string;
3274 it->s = NULL;
3275 it->end_charpos = it->string_nchars = XSTRING (string)->size;
3276 it->method = next_element_from_string;
3277 it->current.string_pos = string_pos (charpos, string);
3279 else
3281 it->s = s;
3282 it->string = Qnil;
3284 /* Note that we use IT->current.pos, not it->current.string_pos,
3285 for displaying C strings. */
3286 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
3287 if (it->multibyte_p)
3289 it->current.pos = c_string_pos (charpos, s, 1);
3290 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
3292 else
3294 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
3295 it->end_charpos = it->string_nchars = strlen (s);
3298 it->method = next_element_from_c_string;
3301 /* PRECISION > 0 means don't return more than PRECISION characters
3302 from the string. */
3303 if (precision > 0 && it->end_charpos - charpos > precision)
3304 it->end_charpos = it->string_nchars = charpos + precision;
3306 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
3307 characters have been returned. FIELD_WIDTH == 0 means don't pad,
3308 FIELD_WIDTH < 0 means infinite field width. This is useful for
3309 padding with `-' at the end of a mode line. */
3310 if (field_width < 0)
3311 field_width = INFINITY;
3312 if (field_width > it->end_charpos - charpos)
3313 it->end_charpos = charpos + field_width;
3315 /* Use the standard display table for displaying strings. */
3316 if (DISP_TABLE_P (Vstandard_display_table))
3317 it->dp = XCHAR_TABLE (Vstandard_display_table);
3319 it->stop_charpos = charpos;
3320 CHECK_IT (it);
3325 /***********************************************************************
3326 Iteration
3327 ***********************************************************************/
3329 /* Load IT's display element fields with information about the next
3330 display element from the current position of IT. Value is zero if
3331 end of buffer (or C string) is reached. */
3334 get_next_display_element (it)
3335 struct it *it;
3337 /* Non-zero means that we found an display element. Zero means that
3338 we hit the end of what we iterate over. Performance note: the
3339 function pointer `method' used here turns out to be faster than
3340 using a sequence of if-statements. */
3341 int success_p = (*it->method) (it);
3343 if (it->what == IT_CHARACTER)
3345 /* Map via display table or translate control characters.
3346 IT->c, IT->len etc. have been set to the next character by
3347 the function call above. If we have a display table, and it
3348 contains an entry for IT->c, translate it. Don't do this if
3349 IT->c itself comes from a display table, otherwise we could
3350 end up in an infinite recursion. (An alternative could be to
3351 count the recursion depth of this function and signal an
3352 error when a certain maximum depth is reached.) Is it worth
3353 it? */
3354 if (success_p && it->dpvec == NULL)
3356 Lisp_Object dv;
3358 if (it->dp
3359 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
3360 VECTORP (dv)))
3362 struct Lisp_Vector *v = XVECTOR (dv);
3364 /* Return the first character from the display table
3365 entry, if not empty. If empty, don't display the
3366 current character. */
3367 if (v->size)
3369 it->dpvec_char_len = it->len;
3370 it->dpvec = v->contents;
3371 it->dpend = v->contents + v->size;
3372 it->current.dpvec_index = 0;
3373 it->method = next_element_from_display_vector;
3376 success_p = get_next_display_element (it);
3379 /* Translate control characters into `\003' or `^C' form.
3380 Control characters coming from a display table entry are
3381 currently not translated because we use IT->dpvec to hold
3382 the translation. This could easily be changed but I
3383 don't believe that it is worth doing.
3385 Non-printable multibyte characters are also translated
3386 octal form. */
3387 else if ((it->c < ' '
3388 && (it->area != TEXT_AREA
3389 || (it->c != '\n' && it->c != '\t')))
3390 || (it->c >= 127
3391 && it->len == 1)
3392 || !CHAR_PRINTABLE_P (it->c))
3394 /* IT->c is a control character which must be displayed
3395 either as '\003' or as `^C' where the '\\' and '^'
3396 can be defined in the display table. Fill
3397 IT->ctl_chars with glyphs for what we have to
3398 display. Then, set IT->dpvec to these glyphs. */
3399 GLYPH g;
3401 if (it->c < 128 && it->ctl_arrow_p)
3403 /* Set IT->ctl_chars[0] to the glyph for `^'. */
3404 if (it->dp
3405 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
3406 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
3407 g = XINT (DISP_CTRL_GLYPH (it->dp));
3408 else
3409 g = FAST_MAKE_GLYPH ('^', 0);
3410 XSETINT (it->ctl_chars[0], g);
3412 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
3413 XSETINT (it->ctl_chars[1], g);
3415 /* Set up IT->dpvec and return first character from it. */
3416 it->dpvec_char_len = it->len;
3417 it->dpvec = it->ctl_chars;
3418 it->dpend = it->dpvec + 2;
3419 it->current.dpvec_index = 0;
3420 it->method = next_element_from_display_vector;
3421 get_next_display_element (it);
3423 else
3425 unsigned char str[MAX_MULTIBYTE_LENGTH];
3426 int len;
3427 int i;
3428 GLYPH escape_glyph;
3430 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
3431 if (it->dp
3432 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
3433 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
3434 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
3435 else
3436 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
3438 if (SINGLE_BYTE_CHAR_P (it->c))
3439 str[0] = it->c, len = 1;
3440 else
3441 len = CHAR_STRING (it->c, str);
3443 for (i = 0; i < len; i++)
3445 XSETINT (it->ctl_chars[i * 4], escape_glyph);
3446 /* Insert three more glyphs into IT->ctl_chars for
3447 the octal display of the character. */
3448 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
3449 XSETINT (it->ctl_chars[i * 4 + 1], g);
3450 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
3451 XSETINT (it->ctl_chars[i * 4 + 2], g);
3452 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
3453 XSETINT (it->ctl_chars[i * 4 + 3], g);
3456 /* Set up IT->dpvec and return the first character
3457 from it. */
3458 it->dpvec_char_len = it->len;
3459 it->dpvec = it->ctl_chars;
3460 it->dpend = it->dpvec + len * 4;
3461 it->current.dpvec_index = 0;
3462 it->method = next_element_from_display_vector;
3463 get_next_display_element (it);
3468 /* Adjust face id for a multibyte character. There are no
3469 multibyte character in unibyte text. */
3470 if (it->multibyte_p
3471 && success_p
3472 && FRAME_WINDOW_P (it->f))
3474 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3475 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
3479 /* Is this character the last one of a run of characters with
3480 box? If yes, set IT->end_of_box_run_p to 1. */
3481 if (it->face_box_p
3482 && it->s == NULL)
3484 int face_id;
3485 struct face *face;
3487 it->end_of_box_run_p
3488 = ((face_id = face_after_it_pos (it),
3489 face_id != it->face_id)
3490 && (face = FACE_FROM_ID (it->f, face_id),
3491 face->box == FACE_NO_BOX));
3494 /* Value is 0 if end of buffer or string reached. */
3495 return success_p;
3499 /* Move IT to the next display element.
3501 Functions get_next_display_element and set_iterator_to_next are
3502 separate because I find this arrangement easier to handle than a
3503 get_next_display_element function that also increments IT's
3504 position. The way it is we can first look at an iterator's current
3505 display element, decide whether it fits on a line, and if it does,
3506 increment the iterator position. The other way around we probably
3507 would either need a flag indicating whether the iterator has to be
3508 incremented the next time, or we would have to implement a
3509 decrement position function which would not be easy to write. */
3511 void
3512 set_iterator_to_next (it)
3513 struct it *it;
3515 if (it->method == next_element_from_buffer)
3517 /* The current display element of IT is a character from
3518 current_buffer. Advance in the buffer, and maybe skip over
3519 invisible lines that are so because of selective display. */
3520 if (ITERATOR_AT_END_OF_LINE_P (it))
3521 reseat_at_next_visible_line_start (it, 0);
3522 else
3524 xassert (it->len != 0);
3525 IT_BYTEPOS (*it) += it->len;
3526 IT_CHARPOS (*it) += 1;
3527 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
3530 else if (it->method == next_element_from_composition)
3532 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
3533 if (STRINGP (it->string))
3535 IT_STRING_BYTEPOS (*it) += it->len;
3536 IT_STRING_CHARPOS (*it) += it->cmp_len;
3537 it->method = next_element_from_string;
3538 goto consider_string_end;
3540 else
3542 IT_BYTEPOS (*it) += it->len;
3543 IT_CHARPOS (*it) += it->cmp_len;
3544 it->method = next_element_from_buffer;
3547 else if (it->method == next_element_from_c_string)
3549 /* Current display element of IT is from a C string. */
3550 IT_BYTEPOS (*it) += it->len;
3551 IT_CHARPOS (*it) += 1;
3553 else if (it->method == next_element_from_display_vector)
3555 /* Current display element of IT is from a display table entry.
3556 Advance in the display table definition. Reset it to null if
3557 end reached, and continue with characters from buffers/
3558 strings. */
3559 ++it->current.dpvec_index;
3561 /* Restore face of the iterator to what they were before the
3562 display vector entry (these entries may contain faces). */
3563 it->face_id = it->saved_face_id;
3565 if (it->dpvec + it->current.dpvec_index == it->dpend)
3567 if (it->s)
3568 it->method = next_element_from_c_string;
3569 else if (STRINGP (it->string))
3570 it->method = next_element_from_string;
3571 else
3572 it->method = next_element_from_buffer;
3574 it->dpvec = NULL;
3575 it->current.dpvec_index = -1;
3577 /* Skip over characters which were displayed via IT->dpvec. */
3578 if (it->dpvec_char_len < 0)
3579 reseat_at_next_visible_line_start (it, 1);
3580 else if (it->dpvec_char_len > 0)
3582 it->len = it->dpvec_char_len;
3583 set_iterator_to_next (it);
3587 else if (it->method == next_element_from_string)
3589 /* Current display element is a character from a Lisp string. */
3590 xassert (it->s == NULL && STRINGP (it->string));
3591 IT_STRING_BYTEPOS (*it) += it->len;
3592 IT_STRING_CHARPOS (*it) += 1;
3594 consider_string_end:
3596 if (it->current.overlay_string_index >= 0)
3598 /* IT->string is an overlay string. Advance to the
3599 next, if there is one. */
3600 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
3601 next_overlay_string (it);
3603 else
3605 /* IT->string is not an overlay string. If we reached
3606 its end, and there is something on IT->stack, proceed
3607 with what is on the stack. This can be either another
3608 string, this time an overlay string, or a buffer. */
3609 if (IT_STRING_CHARPOS (*it) == XSTRING (it->string)->size
3610 && it->sp > 0)
3612 pop_it (it);
3613 if (!STRINGP (it->string))
3614 it->method = next_element_from_buffer;
3618 else if (it->method == next_element_from_image
3619 || it->method == next_element_from_stretch)
3621 /* The position etc with which we have to proceed are on
3622 the stack. The position may be at the end of a string,
3623 if the `display' property takes up the whole string. */
3624 pop_it (it);
3625 it->image_id = 0;
3626 if (STRINGP (it->string))
3628 it->method = next_element_from_string;
3629 goto consider_string_end;
3631 else
3632 it->method = next_element_from_buffer;
3634 else
3635 /* There are no other methods defined, so this should be a bug. */
3636 abort ();
3638 /* Reset flags indicating start and end of a sequence of
3639 characters with box. */
3640 it->start_of_box_run_p = it->end_of_box_run_p = 0;
3642 xassert (it->method != next_element_from_string
3643 || (STRINGP (it->string)
3644 && IT_STRING_CHARPOS (*it) >= 0));
3648 /* Load IT's display element fields with information about the next
3649 display element which comes from a display table entry or from the
3650 result of translating a control character to one of the forms `^C'
3651 or `\003'. IT->dpvec holds the glyphs to return as characters. */
3653 static int
3654 next_element_from_display_vector (it)
3655 struct it *it;
3657 /* Precondition. */
3658 xassert (it->dpvec && it->current.dpvec_index >= 0);
3660 /* Remember the current face id in case glyphs specify faces.
3661 IT's face is restored in set_iterator_to_next. */
3662 it->saved_face_id = it->face_id;
3664 if (INTEGERP (*it->dpvec)
3665 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
3667 int lface_id;
3668 GLYPH g;
3670 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
3671 it->c = FAST_GLYPH_CHAR (g);
3672 it->len = CHAR_BYTES (it->c);
3674 /* The entry may contain a face id to use. Such a face id is
3675 the id of a Lisp face, not a realized face. A face id of
3676 zero means no face. */
3677 lface_id = FAST_GLYPH_FACE (g);
3678 if (lface_id)
3680 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
3681 if (face_id >= 0)
3683 it->face_id = face_id;
3687 else
3688 /* Display table entry is invalid. Return a space. */
3689 it->c = ' ', it->len = 1;
3691 /* Don't change position and object of the iterator here. They are
3692 still the values of the character that had this display table
3693 entry or was translated, and that's what we want. */
3694 it->what = IT_CHARACTER;
3695 return 1;
3699 /* Load IT with the next display element from Lisp string IT->string.
3700 IT->current.string_pos is the current position within the string.
3701 If IT->current.overlay_string_index >= 0, the Lisp string is an
3702 overlay string. */
3704 static int
3705 next_element_from_string (it)
3706 struct it *it;
3708 struct text_pos position;
3710 xassert (STRINGP (it->string));
3711 xassert (IT_STRING_CHARPOS (*it) >= 0);
3712 position = it->current.string_pos;
3714 /* Time to check for invisible text? */
3715 if (IT_STRING_CHARPOS (*it) < it->end_charpos
3716 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
3718 handle_stop (it);
3720 /* Since a handler may have changed IT->method, we must
3721 recurse here. */
3722 return get_next_display_element (it);
3725 if (it->current.overlay_string_index >= 0)
3727 /* Get the next character from an overlay string. In overlay
3728 strings, There is no field width or padding with spaces to
3729 do. */
3730 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
3732 it->what = IT_EOB;
3733 return 0;
3735 else if (STRING_MULTIBYTE (it->string))
3737 int remaining = (STRING_BYTES (XSTRING (it->string))
3738 - IT_STRING_BYTEPOS (*it));
3739 unsigned char *s = (XSTRING (it->string)->data
3740 + IT_STRING_BYTEPOS (*it));
3741 it->c = string_char_and_length (s, remaining, &it->len);
3743 else
3745 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
3746 it->len = 1;
3749 else
3751 /* Get the next character from a Lisp string that is not an
3752 overlay string. Such strings come from the mode line, for
3753 example. We may have to pad with spaces, or truncate the
3754 string. See also next_element_from_c_string. */
3755 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
3757 it->what = IT_EOB;
3758 return 0;
3760 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
3762 /* Pad with spaces. */
3763 it->c = ' ', it->len = 1;
3764 CHARPOS (position) = BYTEPOS (position) = -1;
3766 else if (STRING_MULTIBYTE (it->string))
3768 int maxlen = (STRING_BYTES (XSTRING (it->string))
3769 - IT_STRING_BYTEPOS (*it));
3770 unsigned char *s = (XSTRING (it->string)->data
3771 + IT_STRING_BYTEPOS (*it));
3772 it->c = string_char_and_length (s, maxlen, &it->len);
3774 else
3776 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
3777 it->len = 1;
3781 /* Record what we have and where it came from. Note that we store a
3782 buffer position in IT->position although it could arguably be a
3783 string position. */
3784 it->what = IT_CHARACTER;
3785 it->object = it->string;
3786 it->position = position;
3787 return 1;
3791 /* Load IT with next display element from C string IT->s.
3792 IT->string_nchars is the maximum number of characters to return
3793 from the string. IT->end_charpos may be greater than
3794 IT->string_nchars when this function is called, in which case we
3795 may have to return padding spaces. Value is zero if end of string
3796 reached, including padding spaces. */
3798 static int
3799 next_element_from_c_string (it)
3800 struct it *it;
3802 int success_p = 1;
3804 xassert (it->s);
3805 it->what = IT_CHARACTER;
3806 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
3807 it->object = Qnil;
3809 /* IT's position can be greater IT->string_nchars in case a field
3810 width or precision has been specified when the iterator was
3811 initialized. */
3812 if (IT_CHARPOS (*it) >= it->end_charpos)
3814 /* End of the game. */
3815 it->what = IT_EOB;
3816 success_p = 0;
3818 else if (IT_CHARPOS (*it) >= it->string_nchars)
3820 /* Pad with spaces. */
3821 it->c = ' ', it->len = 1;
3822 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
3824 else if (it->multibyte_p)
3826 /* Implementation note: The calls to strlen apparently aren't a
3827 performance problem because there is no noticeable performance
3828 difference between Emacs running in unibyte or multibyte mode. */
3829 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
3830 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
3831 maxlen, &it->len);
3833 else
3834 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
3836 return success_p;
3840 /* Set up IT to return characters from an ellipsis, if appropriate.
3841 The definition of the ellipsis glyphs may come from a display table
3842 entry. This function Fills IT with the first glyph from the
3843 ellipsis if an ellipsis is to be displayed. */
3845 static int
3846 next_element_from_ellipsis (it)
3847 struct it *it;
3849 if (it->selective_display_ellipsis_p)
3851 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3853 /* Use the display table definition for `...'. Invalid glyphs
3854 will be handled by the method returning elements from dpvec. */
3855 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3856 it->dpvec_char_len = it->len;
3857 it->dpvec = v->contents;
3858 it->dpend = v->contents + v->size;
3859 it->current.dpvec_index = 0;
3860 it->method = next_element_from_display_vector;
3862 else
3864 /* Use default `...' which is stored in default_invis_vector. */
3865 it->dpvec_char_len = it->len;
3866 it->dpvec = default_invis_vector;
3867 it->dpend = default_invis_vector + 3;
3868 it->current.dpvec_index = 0;
3869 it->method = next_element_from_display_vector;
3872 else
3873 reseat_at_next_visible_line_start (it, 1);
3875 return get_next_display_element (it);
3879 /* Deliver an image display element. The iterator IT is already
3880 filled with image information (done in handle_display_prop). Value
3881 is always 1. */
3884 static int
3885 next_element_from_image (it)
3886 struct it *it;
3888 it->what = IT_IMAGE;
3889 return 1;
3893 /* Fill iterator IT with next display element from a stretch glyph
3894 property. IT->object is the value of the text property. Value is
3895 always 1. */
3897 static int
3898 next_element_from_stretch (it)
3899 struct it *it;
3901 it->what = IT_STRETCH;
3902 return 1;
3906 /* Load IT with the next display element from current_buffer. Value
3907 is zero if end of buffer reached. IT->stop_charpos is the next
3908 position at which to stop and check for text properties or buffer
3909 end. */
3911 static int
3912 next_element_from_buffer (it)
3913 struct it *it;
3915 int success_p = 1;
3917 /* Check this assumption, otherwise, we would never enter the
3918 if-statement, below. */
3919 xassert (IT_CHARPOS (*it) >= BEGV
3920 && IT_CHARPOS (*it) <= it->stop_charpos);
3922 if (IT_CHARPOS (*it) >= it->stop_charpos)
3924 if (IT_CHARPOS (*it) >= it->end_charpos)
3926 int overlay_strings_follow_p;
3928 /* End of the game, except when overlay strings follow that
3929 haven't been returned yet. */
3930 if (it->overlay_strings_at_end_processed_p)
3931 overlay_strings_follow_p = 0;
3932 else
3934 it->overlay_strings_at_end_processed_p = 1;
3935 overlay_strings_follow_p = get_overlay_strings (it);
3938 if (overlay_strings_follow_p)
3939 success_p = get_next_display_element (it);
3940 else
3942 it->what = IT_EOB;
3943 it->position = it->current.pos;
3944 success_p = 0;
3947 else
3949 handle_stop (it);
3950 return get_next_display_element (it);
3953 else
3955 /* No face changes, overlays etc. in sight, so just return a
3956 character from current_buffer. */
3957 unsigned char *p;
3959 /* Maybe run the redisplay end trigger hook. Performance note:
3960 This doesn't seem to cost measurable time. */
3961 if (it->redisplay_end_trigger_charpos
3962 && it->glyph_row
3963 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
3964 run_redisplay_end_trigger_hook (it);
3966 /* Get the next character, maybe multibyte. */
3967 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
3968 if (it->multibyte_p && !ASCII_BYTE_P (*p))
3970 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
3971 - IT_BYTEPOS (*it));
3972 it->c = string_char_and_length (p, maxlen, &it->len);
3974 else
3975 it->c = *p, it->len = 1;
3977 /* Record what we have and where it came from. */
3978 it->what = IT_CHARACTER;;
3979 it->object = it->w->buffer;
3980 it->position = it->current.pos;
3982 /* Normally we return the character found above, except when we
3983 really want to return an ellipsis for selective display. */
3984 if (it->selective)
3986 if (it->c == '\n')
3988 /* A value of selective > 0 means hide lines indented more
3989 than that number of columns. */
3990 if (it->selective > 0
3991 && IT_CHARPOS (*it) + 1 < ZV
3992 && indented_beyond_p (IT_CHARPOS (*it) + 1,
3993 IT_BYTEPOS (*it) + 1,
3994 it->selective))
3996 success_p = next_element_from_ellipsis (it);
3997 it->dpvec_char_len = -1;
4000 else if (it->c == '\r' && it->selective == -1)
4002 /* A value of selective == -1 means that everything from the
4003 CR to the end of the line is invisible, with maybe an
4004 ellipsis displayed for it. */
4005 success_p = next_element_from_ellipsis (it);
4006 it->dpvec_char_len = -1;
4011 /* Value is zero if end of buffer reached. */
4012 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
4013 return success_p;
4017 /* Run the redisplay end trigger hook for IT. */
4019 static void
4020 run_redisplay_end_trigger_hook (it)
4021 struct it *it;
4023 Lisp_Object args[3];
4025 /* IT->glyph_row should be non-null, i.e. we should be actually
4026 displaying something, or otherwise we should not run the hook. */
4027 xassert (it->glyph_row);
4029 /* Set up hook arguments. */
4030 args[0] = Qredisplay_end_trigger_functions;
4031 args[1] = it->window;
4032 XSETINT (args[2], it->redisplay_end_trigger_charpos);
4033 it->redisplay_end_trigger_charpos = 0;
4035 /* Since we are *trying* to run these functions, don't try to run
4036 them again, even if they get an error. */
4037 it->w->redisplay_end_trigger = Qnil;
4038 Frun_hook_with_args (3, args);
4040 /* Notice if it changed the face of the character we are on. */
4041 handle_face_prop (it);
4045 /* Deliver a composition display element. The iterator IT is already
4046 filled with composition information (done in
4047 handle_composition_prop). Value is always 1. */
4049 static int
4050 next_element_from_composition (it)
4051 struct it *it;
4053 it->what = IT_COMPOSITION;
4054 it->position = (STRINGP (it->string)
4055 ? it->current.string_pos
4056 : it->current.pos);
4057 return 1;
4062 /***********************************************************************
4063 Moving an iterator without producing glyphs
4064 ***********************************************************************/
4066 /* Move iterator IT to a specified buffer or X position within one
4067 line on the display without producing glyphs.
4069 Begin to skip at IT's current position. Skip to TO_CHARPOS or TO_X
4070 whichever is reached first.
4072 TO_CHARPOS <= 0 means no TO_CHARPOS is specified.
4074 TO_X < 0 means that no TO_X is specified. TO_X is normally a value
4075 0 <= TO_X <= IT->last_visible_x. This means in particular, that
4076 TO_X includes the amount by which a window is horizontally
4077 scrolled.
4079 Value is
4081 MOVE_POS_MATCH_OR_ZV
4082 - when TO_POS or ZV was reached.
4084 MOVE_X_REACHED
4085 -when TO_X was reached before TO_POS or ZV were reached.
4087 MOVE_LINE_CONTINUED
4088 - when we reached the end of the display area and the line must
4089 be continued.
4091 MOVE_LINE_TRUNCATED
4092 - when we reached the end of the display area and the line is
4093 truncated.
4095 MOVE_NEWLINE_OR_CR
4096 - when we stopped at a line end, i.e. a newline or a CR and selective
4097 display is on. */
4099 static enum move_it_result
4100 move_it_in_display_line_to (it, to_charpos, to_x, op)
4101 struct it *it;
4102 int to_charpos, to_x, op;
4104 enum move_it_result result = MOVE_UNDEFINED;
4105 struct glyph_row *saved_glyph_row;
4107 /* Don't produce glyphs in produce_glyphs. */
4108 saved_glyph_row = it->glyph_row;
4109 it->glyph_row = NULL;
4111 while (1)
4113 int x, i;
4115 /* Stop when ZV or TO_CHARPOS reached. */
4116 if (!get_next_display_element (it)
4117 || ((op & MOVE_TO_POS) != 0
4118 && BUFFERP (it->object)
4119 && IT_CHARPOS (*it) >= to_charpos))
4121 result = MOVE_POS_MATCH_OR_ZV;
4122 break;
4125 /* The call to produce_glyphs will get the metrics of the
4126 display element IT is loaded with. We record in x the
4127 x-position before this display element in case it does not
4128 fit on the line. */
4129 x = it->current_x;
4130 PRODUCE_GLYPHS (it);
4132 if (it->area != TEXT_AREA)
4134 set_iterator_to_next (it);
4135 continue;
4138 /* The number of glyphs we get back in IT->nglyphs will normally
4139 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
4140 character on a terminal frame, or (iii) a line end. For the
4141 second case, IT->nglyphs - 1 padding glyphs will be present
4142 (on X frames, there is only one glyph produced for a
4143 composite character.
4145 The behavior implemented below means, for continuation lines,
4146 that as many spaces of a TAB as fit on the current line are
4147 displayed there. For terminal frames, as many glyphs of a
4148 multi-glyph character are displayed in the current line, too.
4149 This is what the old redisplay code did, and we keep it that
4150 way. Under X, the whole shape of a complex character must
4151 fit on the line or it will be completely displayed in the
4152 next line.
4154 Note that both for tabs and padding glyphs, all glyphs have
4155 the same width. */
4156 if (it->nglyphs)
4158 /* More than one glyph or glyph doesn't fit on line. All
4159 glyphs have the same width. */
4160 int single_glyph_width = it->pixel_width / it->nglyphs;
4161 int new_x;
4163 for (i = 0; i < it->nglyphs; ++i, x = new_x)
4165 new_x = x + single_glyph_width;
4167 /* We want to leave anything reaching TO_X to the caller. */
4168 if ((op & MOVE_TO_X) && new_x > to_x)
4170 it->current_x = x;
4171 result = MOVE_X_REACHED;
4172 break;
4174 else if (/* Lines are continued. */
4175 !it->truncate_lines_p
4176 && (/* And glyph doesn't fit on the line. */
4177 new_x > it->last_visible_x
4178 /* Or it fits exactly and we're on a window
4179 system frame. */
4180 || (new_x == it->last_visible_x
4181 && FRAME_WINDOW_P (it->f))))
4183 if (/* IT->hpos == 0 means the very first glyph
4184 doesn't fit on the line, e.g. a wide image. */
4185 it->hpos == 0
4186 || (new_x == it->last_visible_x
4187 && FRAME_WINDOW_P (it->f)))
4189 ++it->hpos;
4190 it->current_x = new_x;
4191 if (i == it->nglyphs - 1)
4192 set_iterator_to_next (it);
4194 else
4195 it->current_x = x;
4197 result = MOVE_LINE_CONTINUED;
4198 break;
4200 else if (new_x > it->first_visible_x)
4202 /* Glyph is visible. Increment number of glyphs that
4203 would be displayed. */
4204 ++it->hpos;
4206 else
4208 /* Glyph is completely off the left margin of the display
4209 area. Nothing to do. */
4213 if (result != MOVE_UNDEFINED)
4214 break;
4216 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
4218 /* Stop when TO_X specified and reached. This check is
4219 necessary here because of lines consisting of a line end,
4220 only. The line end will not produce any glyphs and we
4221 would never get MOVE_X_REACHED. */
4222 xassert (it->nglyphs == 0);
4223 result = MOVE_X_REACHED;
4224 break;
4227 /* Is this a line end? If yes, we're done. */
4228 if (ITERATOR_AT_END_OF_LINE_P (it))
4230 result = MOVE_NEWLINE_OR_CR;
4231 break;
4234 /* The current display element has been consumed. Advance
4235 to the next. */
4236 set_iterator_to_next (it);
4238 /* Stop if lines are truncated and IT's current x-position is
4239 past the right edge of the window now. */
4240 if (it->truncate_lines_p
4241 && it->current_x >= it->last_visible_x)
4243 result = MOVE_LINE_TRUNCATED;
4244 break;
4248 /* Restore the iterator settings altered at the beginning of this
4249 function. */
4250 it->glyph_row = saved_glyph_row;
4251 return result;
4255 /* Move IT forward to a specified buffer position TO_CHARPOS, TO_X,
4256 TO_Y, TO_VPOS. OP is a bit-mask that specifies where to stop. See
4257 the description of enum move_operation_enum.
4259 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
4260 screen line, this function will set IT to the next position >
4261 TO_CHARPOS. */
4263 void
4264 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
4265 struct it *it;
4266 int to_charpos, to_x, to_y, to_vpos;
4267 int op;
4269 enum move_it_result skip, skip2 = MOVE_X_REACHED;
4270 int line_height;
4272 while (1)
4274 if (op & MOVE_TO_VPOS)
4276 /* If no TO_CHARPOS and no TO_X specified, stop at the
4277 start of the line TO_VPOS. */
4278 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
4280 if (it->vpos == to_vpos)
4281 break;
4282 skip = move_it_in_display_line_to (it, -1, -1, 0);
4284 else
4286 /* TO_VPOS >= 0 means stop at TO_X in the line at
4287 TO_VPOS, or at TO_POS, whichever comes first. */
4288 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
4290 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
4291 break;
4292 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
4294 /* We have reached TO_X but not in the line we want. */
4295 skip = move_it_in_display_line_to (it, to_charpos,
4296 -1, MOVE_TO_POS);
4297 if (skip == MOVE_POS_MATCH_OR_ZV)
4298 break;
4302 else if (op & MOVE_TO_Y)
4304 struct it it_backup;
4305 int done_p;
4307 /* TO_Y specified means stop at TO_X in the line containing
4308 TO_Y---or at TO_CHARPOS if this is reached first. The
4309 problem is that we can't really tell whether the line
4310 contains TO_Y before we have completely scanned it, and
4311 this may skip past TO_X. What we do is to first scan to
4312 TO_X.
4314 If TO_X is not specified, use a TO_X of zero. The reason
4315 is to make the outcome of this function more predictable.
4316 If we didn't use TO_X == 0, we would stop at the end of
4317 the line which is probably not what a caller would expect
4318 to happen. */
4319 skip = move_it_in_display_line_to (it, to_charpos,
4320 ((op & MOVE_TO_X)
4321 ? to_x : 0),
4322 (MOVE_TO_X
4323 | (op & MOVE_TO_POS)));
4325 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
4326 if (skip == MOVE_POS_MATCH_OR_ZV)
4327 break;
4329 /* If TO_X was reached, we would like to know whether TO_Y
4330 is in the line. This can only be said if we know the
4331 total line height which requires us to scan the rest of
4332 the line. */
4333 done_p = 0;
4334 if (skip == MOVE_X_REACHED)
4336 it_backup = *it;
4337 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
4338 op & MOVE_TO_POS);
4341 /* Now, decide whether TO_Y is in this line. */
4342 line_height = it->max_ascent + it->max_descent;
4344 if (to_y >= it->current_y
4345 && to_y < it->current_y + line_height)
4347 if (skip == MOVE_X_REACHED)
4348 /* If TO_Y is in this line and TO_X was reached above,
4349 we scanned too far. We have to restore IT's settings
4350 to the ones before skipping. */
4351 *it = it_backup;
4352 done_p = 1;
4354 else if (skip == MOVE_X_REACHED)
4356 skip = skip2;
4357 if (skip == MOVE_POS_MATCH_OR_ZV)
4358 done_p = 1;
4361 if (done_p)
4362 break;
4364 else
4365 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
4367 switch (skip)
4369 case MOVE_POS_MATCH_OR_ZV:
4370 return;
4372 case MOVE_NEWLINE_OR_CR:
4373 set_iterator_to_next (it);
4374 it->continuation_lines_width = 0;
4375 break;
4377 case MOVE_LINE_TRUNCATED:
4378 it->continuation_lines_width = 0;
4379 reseat_at_next_visible_line_start (it, 0);
4380 if ((op & MOVE_TO_POS) != 0
4381 && IT_CHARPOS (*it) > to_charpos)
4382 goto out;
4383 break;
4385 case MOVE_LINE_CONTINUED:
4386 it->continuation_lines_width += it->current_x;
4387 break;
4389 default:
4390 abort ();
4393 /* Reset/increment for the next run. */
4394 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
4395 it->current_x = it->hpos = 0;
4396 it->current_y += it->max_ascent + it->max_descent;
4397 ++it->vpos;
4398 last_height = it->max_ascent + it->max_descent;
4399 last_max_ascent = it->max_ascent;
4400 it->max_ascent = it->max_descent = 0;
4402 out:;
4406 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
4408 If DY > 0, move IT backward at least that many pixels. DY = 0
4409 means move IT backward to the preceding line start or BEGV. This
4410 function may move over more than DY pixels if IT->current_y - DY
4411 ends up in the middle of a line; in this case IT->current_y will be
4412 set to the top of the line moved to. */
4414 void
4415 move_it_vertically_backward (it, dy)
4416 struct it *it;
4417 int dy;
4419 int nlines, h, line_height;
4420 struct it it2;
4421 int start_pos = IT_CHARPOS (*it);
4423 xassert (dy >= 0);
4425 /* Estimate how many newlines we must move back. */
4426 nlines = max (1, dy / CANON_Y_UNIT (it->f));
4428 /* Set the iterator's position that many lines back. */
4429 while (nlines-- && IT_CHARPOS (*it) > BEGV)
4430 back_to_previous_visible_line_start (it);
4432 /* Reseat the iterator here. When moving backward, we don't want
4433 reseat to skip forward over invisible text, set up the iterator
4434 to deliver from overlay strings at the new position etc. So,
4435 use reseat_1 here. */
4436 reseat_1 (it, it->current.pos, 1);
4438 /* We are now surely at a line start. */
4439 it->current_x = it->hpos = 0;
4441 /* Move forward and see what y-distance we moved. First move to the
4442 start of the next line so that we get its height. We need this
4443 height to be able to tell whether we reached the specified
4444 y-distance. */
4445 it2 = *it;
4446 it2.max_ascent = it2.max_descent = 0;
4447 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
4448 MOVE_TO_POS | MOVE_TO_VPOS);
4449 xassert (IT_CHARPOS (*it) >= BEGV);
4450 line_height = it2.max_ascent + it2.max_descent;
4451 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
4452 xassert (IT_CHARPOS (*it) >= BEGV);
4453 h = it2.current_y - it->current_y;
4454 nlines = it2.vpos - it->vpos;
4456 /* Correct IT's y and vpos position. */
4457 it->vpos -= nlines;
4458 it->current_y -= h;
4460 if (dy == 0)
4462 /* DY == 0 means move to the start of the screen line. The
4463 value of nlines is > 0 if continuation lines were involved. */
4464 if (nlines > 0)
4465 move_it_by_lines (it, nlines, 1);
4466 xassert (IT_CHARPOS (*it) <= start_pos);
4468 else if (nlines)
4470 /* The y-position we try to reach. Note that h has been
4471 subtracted in front of the if-statement. */
4472 int target_y = it->current_y + h - dy;
4474 /* If we did not reach target_y, try to move further backward if
4475 we can. If we moved too far backward, try to move forward. */
4476 if (target_y < it->current_y
4477 && IT_CHARPOS (*it) > BEGV)
4479 move_it_vertically (it, target_y - it->current_y);
4480 xassert (IT_CHARPOS (*it) >= BEGV);
4482 else if (target_y >= it->current_y + line_height
4483 && IT_CHARPOS (*it) < ZV)
4485 move_it_vertically (it, target_y - (it->current_y + line_height));
4486 xassert (IT_CHARPOS (*it) >= BEGV);
4492 /* Move IT by a specified amount of pixel lines DY. DY negative means
4493 move backwards. DY = 0 means move to start of screen line. At the
4494 end, IT will be on the start of a screen line. */
4496 void
4497 move_it_vertically (it, dy)
4498 struct it *it;
4499 int dy;
4501 if (dy <= 0)
4502 move_it_vertically_backward (it, -dy);
4503 else if (dy > 0)
4505 move_it_to (it, ZV, -1, it->current_y + dy, -1,
4506 MOVE_TO_POS | MOVE_TO_Y);
4508 /* If buffer ends in ZV without a newline, move to the start of
4509 the line to satisfy the post-condition. */
4510 if (IT_CHARPOS (*it) == ZV
4511 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
4512 move_it_by_lines (it, 0, 0);
4517 /* Return non-zero if some text between buffer positions START_CHARPOS
4518 and END_CHARPOS is invisible. IT->window is the window for text
4519 property lookup. */
4521 static int
4522 invisible_text_between_p (it, start_charpos, end_charpos)
4523 struct it *it;
4524 int start_charpos, end_charpos;
4526 Lisp_Object prop, limit;
4527 int invisible_found_p;
4529 xassert (it != NULL && start_charpos <= end_charpos);
4531 /* Is text at START invisible? */
4532 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
4533 it->window);
4534 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4535 invisible_found_p = 1;
4536 else
4538 limit = next_single_char_property_change (make_number (start_charpos),
4539 Qinvisible, Qnil,
4540 make_number (end_charpos));
4541 invisible_found_p = XFASTINT (limit) < end_charpos;
4544 return invisible_found_p;
4548 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
4549 negative means move up. DVPOS == 0 means move to the start of the
4550 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
4551 NEED_Y_P is zero, IT->current_y will be left unchanged.
4553 Further optimization ideas: If we would know that IT->f doesn't use
4554 a face with proportional font, we could be faster for
4555 truncate-lines nil. */
4557 void
4558 move_it_by_lines (it, dvpos, need_y_p)
4559 struct it *it;
4560 int dvpos, need_y_p;
4562 struct position pos;
4564 if (!FRAME_WINDOW_P (it->f))
4566 struct text_pos textpos;
4568 /* We can use vmotion on frames without proportional fonts. */
4569 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
4570 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
4571 reseat (it, textpos, 1);
4572 it->vpos += pos.vpos;
4573 it->current_y += pos.vpos;
4575 else if (dvpos == 0)
4577 /* DVPOS == 0 means move to the start of the screen line. */
4578 move_it_vertically_backward (it, 0);
4579 xassert (it->current_x == 0 && it->hpos == 0);
4581 else if (dvpos > 0)
4583 /* If there are no continuation lines, and if there is no
4584 selective display, try the simple method of moving forward
4585 DVPOS newlines, then see where we are. */
4586 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
4588 int shortage = 0, charpos;
4590 if (FETCH_BYTE (IT_BYTEPOS (*it) == '\n'))
4591 charpos = IT_CHARPOS (*it) + 1;
4592 else
4593 charpos = scan_buffer ('\n', IT_CHARPOS (*it), 0, dvpos,
4594 &shortage, 0);
4596 if (!invisible_text_between_p (it, IT_CHARPOS (*it), charpos))
4598 struct text_pos pos;
4599 CHARPOS (pos) = charpos;
4600 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
4601 reseat (it, pos, 1);
4602 it->vpos += dvpos - shortage;
4603 it->hpos = it->current_x = 0;
4604 return;
4608 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
4610 else
4612 struct it it2;
4613 int start_charpos, i;
4615 /* If there are no continuation lines, and if there is no
4616 selective display, try the simple method of moving backward
4617 -DVPOS newlines. */
4618 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
4620 int shortage;
4621 int charpos = IT_CHARPOS (*it);
4622 int bytepos = IT_BYTEPOS (*it);
4624 /* If in the middle of a line, go to its start. */
4625 if (charpos > BEGV && FETCH_BYTE (bytepos - 1) != '\n')
4627 charpos = find_next_newline_no_quit (charpos, -1);
4628 bytepos = CHAR_TO_BYTE (charpos);
4631 if (charpos == BEGV)
4633 struct text_pos pos;
4634 CHARPOS (pos) = charpos;
4635 BYTEPOS (pos) = bytepos;
4636 reseat (it, pos, 1);
4637 it->hpos = it->current_x = 0;
4638 return;
4640 else
4642 charpos = scan_buffer ('\n', charpos - 1, 0, dvpos, &shortage, 0);
4643 if (!invisible_text_between_p (it, charpos, IT_CHARPOS (*it)))
4645 struct text_pos pos;
4646 CHARPOS (pos) = charpos;
4647 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
4648 reseat (it, pos, 1);
4649 it->vpos += dvpos + (shortage ? shortage - 1 : 0);
4650 it->hpos = it->current_x = 0;
4651 return;
4656 /* Go back -DVPOS visible lines and reseat the iterator there. */
4657 start_charpos = IT_CHARPOS (*it);
4658 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
4659 back_to_previous_visible_line_start (it);
4660 reseat (it, it->current.pos, 1);
4661 it->current_x = it->hpos = 0;
4663 /* Above call may have moved too far if continuation lines
4664 are involved. Scan forward and see if it did. */
4665 it2 = *it;
4666 it2.vpos = it2.current_y = 0;
4667 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
4668 it->vpos -= it2.vpos;
4669 it->current_y -= it2.current_y;
4670 it->current_x = it->hpos = 0;
4672 /* If we moved too far, move IT some lines forward. */
4673 if (it2.vpos > -dvpos)
4675 int delta = it2.vpos + dvpos;
4676 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
4683 /***********************************************************************
4684 Messages
4685 ***********************************************************************/
4688 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
4689 to *Messages*. */
4691 void
4692 add_to_log (format, arg1, arg2)
4693 char *format;
4694 Lisp_Object arg1, arg2;
4696 Lisp_Object args[3];
4697 Lisp_Object msg, fmt;
4698 char *buffer;
4699 int len;
4700 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4702 fmt = msg = Qnil;
4703 GCPRO4 (fmt, msg, arg1, arg2);
4705 args[0] = fmt = build_string (format);
4706 args[1] = arg1;
4707 args[2] = arg2;
4708 msg = Fformat (3, args);
4710 len = STRING_BYTES (XSTRING (msg)) + 1;
4711 buffer = (char *) alloca (len);
4712 strcpy (buffer, XSTRING (msg)->data);
4714 message_dolog (buffer, len - 1, 1, 0);
4715 UNGCPRO;
4719 /* Output a newline in the *Messages* buffer if "needs" one. */
4721 void
4722 message_log_maybe_newline ()
4724 if (message_log_need_newline)
4725 message_dolog ("", 0, 1, 0);
4729 /* Add a string M of length LEN to the message log, optionally
4730 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
4731 nonzero, means interpret the contents of M as multibyte. This
4732 function calls low-level routines in order to bypass text property
4733 hooks, etc. which might not be safe to run. */
4735 void
4736 message_dolog (m, len, nlflag, multibyte)
4737 char *m;
4738 int len, nlflag, multibyte;
4740 if (!NILP (Vmessage_log_max))
4742 struct buffer *oldbuf;
4743 Lisp_Object oldpoint, oldbegv, oldzv;
4744 int old_windows_or_buffers_changed = windows_or_buffers_changed;
4745 int point_at_end = 0;
4746 int zv_at_end = 0;
4747 Lisp_Object old_deactivate_mark, tem;
4748 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4750 old_deactivate_mark = Vdeactivate_mark;
4751 oldbuf = current_buffer;
4752 Fset_buffer (Fget_buffer_create (build_string ("*Messages*")));
4753 current_buffer->undo_list = Qt;
4755 oldpoint = Fpoint_marker ();
4756 oldbegv = Fpoint_min_marker ();
4757 oldzv = Fpoint_max_marker ();
4758 GCPRO4 (oldpoint, oldbegv, oldzv, old_deactivate_mark);
4760 if (PT == Z)
4761 point_at_end = 1;
4762 if (ZV == Z)
4763 zv_at_end = 1;
4765 BEGV = BEG;
4766 BEGV_BYTE = BEG_BYTE;
4767 ZV = Z;
4768 ZV_BYTE = Z_BYTE;
4769 TEMP_SET_PT_BOTH (Z, Z_BYTE);
4771 /* Insert the string--maybe converting multibyte to single byte
4772 or vice versa, so that all the text fits the buffer. */
4773 if (multibyte
4774 && NILP (current_buffer->enable_multibyte_characters))
4776 int i, c, nbytes;
4777 unsigned char work[1];
4779 /* Convert a multibyte string to single-byte
4780 for the *Message* buffer. */
4781 for (i = 0; i < len; i += nbytes)
4783 c = string_char_and_length (m + i, len - i, &nbytes);
4784 work[0] = (SINGLE_BYTE_CHAR_P (c)
4786 : multibyte_char_to_unibyte (c, Qnil));
4787 insert_1_both (work, 1, 1, 1, 0, 0);
4790 else if (! multibyte
4791 && ! NILP (current_buffer->enable_multibyte_characters))
4793 int i, c, nbytes;
4794 unsigned char *msg = (unsigned char *) m;
4795 unsigned char str[MAX_MULTIBYTE_LENGTH];
4796 /* Convert a single-byte string to multibyte
4797 for the *Message* buffer. */
4798 for (i = 0; i < len; i++)
4800 c = unibyte_char_to_multibyte (msg[i]);
4801 nbytes = CHAR_STRING (c, str);
4802 insert_1_both (str, 1, nbytes, 1, 0, 0);
4805 else if (len)
4806 insert_1 (m, len, 1, 0, 0);
4808 if (nlflag)
4810 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
4811 insert_1 ("\n", 1, 1, 0, 0);
4813 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
4814 this_bol = PT;
4815 this_bol_byte = PT_BYTE;
4817 if (this_bol > BEG)
4819 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
4820 prev_bol = PT;
4821 prev_bol_byte = PT_BYTE;
4823 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
4824 this_bol, this_bol_byte);
4825 if (dup)
4827 del_range_both (prev_bol, prev_bol_byte,
4828 this_bol, this_bol_byte, 0);
4829 if (dup > 1)
4831 char dupstr[40];
4832 int duplen;
4834 /* If you change this format, don't forget to also
4835 change message_log_check_duplicate. */
4836 sprintf (dupstr, " [%d times]", dup);
4837 duplen = strlen (dupstr);
4838 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
4839 insert_1 (dupstr, duplen, 1, 0, 1);
4844 if (NATNUMP (Vmessage_log_max))
4846 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
4847 -XFASTINT (Vmessage_log_max) - 1, 0);
4848 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
4851 BEGV = XMARKER (oldbegv)->charpos;
4852 BEGV_BYTE = marker_byte_position (oldbegv);
4854 if (zv_at_end)
4856 ZV = Z;
4857 ZV_BYTE = Z_BYTE;
4859 else
4861 ZV = XMARKER (oldzv)->charpos;
4862 ZV_BYTE = marker_byte_position (oldzv);
4865 if (point_at_end)
4866 TEMP_SET_PT_BOTH (Z, Z_BYTE);
4867 else
4868 /* We can't do Fgoto_char (oldpoint) because it will run some
4869 Lisp code. */
4870 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
4871 XMARKER (oldpoint)->bytepos);
4873 UNGCPRO;
4874 free_marker (oldpoint);
4875 free_marker (oldbegv);
4876 free_marker (oldzv);
4878 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
4879 set_buffer_internal (oldbuf);
4880 if (NILP (tem))
4881 windows_or_buffers_changed = old_windows_or_buffers_changed;
4882 message_log_need_newline = !nlflag;
4883 Vdeactivate_mark = old_deactivate_mark;
4888 /* We are at the end of the buffer after just having inserted a newline.
4889 (Note: We depend on the fact we won't be crossing the gap.)
4890 Check to see if the most recent message looks a lot like the previous one.
4891 Return 0 if different, 1 if the new one should just replace it, or a
4892 value N > 1 if we should also append " [N times]". */
4894 static int
4895 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
4896 int prev_bol, this_bol;
4897 int prev_bol_byte, this_bol_byte;
4899 int i;
4900 int len = Z_BYTE - 1 - this_bol_byte;
4901 int seen_dots = 0;
4902 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
4903 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
4905 for (i = 0; i < len; i++)
4907 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.'
4908 && p1[i] != '\n')
4909 seen_dots = 1;
4910 if (p1[i] != p2[i])
4911 return seen_dots;
4913 p1 += len;
4914 if (*p1 == '\n')
4915 return 2;
4916 if (*p1++ == ' ' && *p1++ == '[')
4918 int n = 0;
4919 while (*p1 >= '0' && *p1 <= '9')
4920 n = n * 10 + *p1++ - '0';
4921 if (strncmp (p1, " times]\n", 8) == 0)
4922 return n+1;
4924 return 0;
4928 /* Display an echo area message M with a specified length of LEN
4929 chars. The string may include null characters. If M is 0, clear
4930 out any existing message, and let the mini-buffer text show through.
4932 The buffer M must continue to exist until after the echo area gets
4933 cleared or some other message gets displayed there. This means do
4934 not pass text that is stored in a Lisp string; do not pass text in
4935 a buffer that was alloca'd. */
4937 void
4938 message2 (m, len, multibyte)
4939 char *m;
4940 int len;
4941 int multibyte;
4943 /* First flush out any partial line written with print. */
4944 message_log_maybe_newline ();
4945 if (m)
4946 message_dolog (m, len, 1, multibyte);
4947 message2_nolog (m, len, multibyte);
4951 /* The non-logging counterpart of message2. */
4953 void
4954 message2_nolog (m, len, multibyte)
4955 char *m;
4956 int len;
4958 struct frame *sf = SELECTED_FRAME ();
4959 message_enable_multibyte = multibyte;
4961 if (noninteractive)
4963 if (noninteractive_need_newline)
4964 putc ('\n', stderr);
4965 noninteractive_need_newline = 0;
4966 if (m)
4967 fwrite (m, len, 1, stderr);
4968 if (cursor_in_echo_area == 0)
4969 fprintf (stderr, "\n");
4970 fflush (stderr);
4972 /* A null message buffer means that the frame hasn't really been
4973 initialized yet. Error messages get reported properly by
4974 cmd_error, so this must be just an informative message; toss it. */
4975 else if (INTERACTIVE
4976 && sf->glyphs_initialized_p
4977 && FRAME_MESSAGE_BUF (sf))
4979 Lisp_Object mini_window;
4980 struct frame *f;
4982 /* Get the frame containing the mini-buffer
4983 that the selected frame is using. */
4984 mini_window = FRAME_MINIBUF_WINDOW (sf);
4985 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
4987 FRAME_SAMPLE_VISIBILITY (f);
4988 if (FRAME_VISIBLE_P (sf)
4989 && ! FRAME_VISIBLE_P (f))
4990 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
4992 if (m)
4994 set_message (m, Qnil, len, multibyte);
4995 if (minibuffer_auto_raise)
4996 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
4998 else
4999 clear_message (1, 1);
5001 do_pending_window_change (0);
5002 echo_area_display (1);
5003 do_pending_window_change (0);
5004 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
5005 (*frame_up_to_date_hook) (f);
5010 /* Display an echo area message M with a specified length of NBYTES
5011 bytes. The string may include null characters. If M is not a
5012 string, clear out any existing message, and let the mini-buffer
5013 text show through. */
5015 void
5016 message3 (m, nbytes, multibyte)
5017 Lisp_Object m;
5018 int nbytes;
5019 int multibyte;
5021 struct gcpro gcpro1;
5023 GCPRO1 (m);
5025 /* First flush out any partial line written with print. */
5026 message_log_maybe_newline ();
5027 if (STRINGP (m))
5028 message_dolog (XSTRING (m)->data, nbytes, 1, multibyte);
5029 message3_nolog (m, nbytes, multibyte);
5031 UNGCPRO;
5035 /* The non-logging version of message3. */
5037 void
5038 message3_nolog (m, nbytes, multibyte)
5039 Lisp_Object m;
5040 int nbytes, multibyte;
5042 struct frame *sf = SELECTED_FRAME ();
5043 message_enable_multibyte = multibyte;
5045 if (noninteractive)
5047 if (noninteractive_need_newline)
5048 putc ('\n', stderr);
5049 noninteractive_need_newline = 0;
5050 if (STRINGP (m))
5051 fwrite (XSTRING (m)->data, nbytes, 1, stderr);
5052 if (cursor_in_echo_area == 0)
5053 fprintf (stderr, "\n");
5054 fflush (stderr);
5056 /* A null message buffer means that the frame hasn't really been
5057 initialized yet. Error messages get reported properly by
5058 cmd_error, so this must be just an informative message; toss it. */
5059 else if (INTERACTIVE
5060 && sf->glyphs_initialized_p
5061 && FRAME_MESSAGE_BUF (sf))
5063 Lisp_Object mini_window;
5064 Lisp_Object frame;
5065 struct frame *f;
5067 /* Get the frame containing the mini-buffer
5068 that the selected frame is using. */
5069 mini_window = FRAME_MINIBUF_WINDOW (sf);
5070 frame = XWINDOW (mini_window)->frame;
5071 f = XFRAME (frame);
5073 FRAME_SAMPLE_VISIBILITY (f);
5074 if (FRAME_VISIBLE_P (sf)
5075 && !FRAME_VISIBLE_P (f))
5076 Fmake_frame_visible (frame);
5078 if (STRINGP (m) && XSTRING (m)->size)
5080 set_message (NULL, m, nbytes, multibyte);
5081 if (minibuffer_auto_raise)
5082 Fraise_frame (frame);
5084 else
5085 clear_message (1, 1);
5087 do_pending_window_change (0);
5088 echo_area_display (1);
5089 do_pending_window_change (0);
5090 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
5091 (*frame_up_to_date_hook) (f);
5096 /* Display a null-terminated echo area message M. If M is 0, clear
5097 out any existing message, and let the mini-buffer text show through.
5099 The buffer M must continue to exist until after the echo area gets
5100 cleared or some other message gets displayed there. Do not pass
5101 text that is stored in a Lisp string. Do not pass text in a buffer
5102 that was alloca'd. */
5104 void
5105 message1 (m)
5106 char *m;
5108 message2 (m, (m ? strlen (m) : 0), 0);
5112 /* The non-logging counterpart of message1. */
5114 void
5115 message1_nolog (m)
5116 char *m;
5118 message2_nolog (m, (m ? strlen (m) : 0), 0);
5121 /* Display a message M which contains a single %s
5122 which gets replaced with STRING. */
5124 void
5125 message_with_string (m, string, log)
5126 char *m;
5127 Lisp_Object string;
5128 int log;
5130 if (noninteractive)
5132 if (m)
5134 if (noninteractive_need_newline)
5135 putc ('\n', stderr);
5136 noninteractive_need_newline = 0;
5137 fprintf (stderr, m, XSTRING (string)->data);
5138 if (cursor_in_echo_area == 0)
5139 fprintf (stderr, "\n");
5140 fflush (stderr);
5143 else if (INTERACTIVE)
5145 /* The frame whose minibuffer we're going to display the message on.
5146 It may be larger than the selected frame, so we need
5147 to use its buffer, not the selected frame's buffer. */
5148 Lisp_Object mini_window;
5149 struct frame *f, *sf = SELECTED_FRAME ();
5151 /* Get the frame containing the minibuffer
5152 that the selected frame is using. */
5153 mini_window = FRAME_MINIBUF_WINDOW (sf);
5154 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5156 /* A null message buffer means that the frame hasn't really been
5157 initialized yet. Error messages get reported properly by
5158 cmd_error, so this must be just an informative message; toss it. */
5159 if (FRAME_MESSAGE_BUF (f))
5161 int len;
5162 char *a[1];
5163 a[0] = (char *) XSTRING (string)->data;
5165 len = doprnt (FRAME_MESSAGE_BUF (f),
5166 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5168 if (log)
5169 message2 (FRAME_MESSAGE_BUF (f), len,
5170 STRING_MULTIBYTE (string));
5171 else
5172 message2_nolog (FRAME_MESSAGE_BUF (f), len,
5173 STRING_MULTIBYTE (string));
5175 /* Print should start at the beginning of the message
5176 buffer next time. */
5177 message_buf_print = 0;
5183 /* Dump an informative message to the minibuf. If M is 0, clear out
5184 any existing message, and let the mini-buffer text show through. */
5186 /* VARARGS 1 */
5187 void
5188 message (m, a1, a2, a3)
5189 char *m;
5190 EMACS_INT a1, a2, a3;
5192 if (noninteractive)
5194 if (m)
5196 if (noninteractive_need_newline)
5197 putc ('\n', stderr);
5198 noninteractive_need_newline = 0;
5199 fprintf (stderr, m, a1, a2, a3);
5200 if (cursor_in_echo_area == 0)
5201 fprintf (stderr, "\n");
5202 fflush (stderr);
5205 else if (INTERACTIVE)
5207 /* The frame whose mini-buffer we're going to display the message
5208 on. It may be larger than the selected frame, so we need to
5209 use its buffer, not the selected frame's buffer. */
5210 Lisp_Object mini_window;
5211 struct frame *f, *sf = SELECTED_FRAME ();
5213 /* Get the frame containing the mini-buffer
5214 that the selected frame is using. */
5215 mini_window = FRAME_MINIBUF_WINDOW (sf);
5216 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5218 /* A null message buffer means that the frame hasn't really been
5219 initialized yet. Error messages get reported properly by
5220 cmd_error, so this must be just an informative message; toss
5221 it. */
5222 if (FRAME_MESSAGE_BUF (f))
5224 if (m)
5226 int len;
5227 #ifdef NO_ARG_ARRAY
5228 char *a[3];
5229 a[0] = (char *) a1;
5230 a[1] = (char *) a2;
5231 a[2] = (char *) a3;
5233 len = doprnt (FRAME_MESSAGE_BUF (f),
5234 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5235 #else
5236 len = doprnt (FRAME_MESSAGE_BUF (f),
5237 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
5238 (char **) &a1);
5239 #endif /* NO_ARG_ARRAY */
5241 message2 (FRAME_MESSAGE_BUF (f), len, 0);
5243 else
5244 message1 (0);
5246 /* Print should start at the beginning of the message
5247 buffer next time. */
5248 message_buf_print = 0;
5254 /* The non-logging version of message. */
5256 void
5257 message_nolog (m, a1, a2, a3)
5258 char *m;
5259 EMACS_INT a1, a2, a3;
5261 Lisp_Object old_log_max;
5262 old_log_max = Vmessage_log_max;
5263 Vmessage_log_max = Qnil;
5264 message (m, a1, a2, a3);
5265 Vmessage_log_max = old_log_max;
5269 /* Display the current message in the current mini-buffer. This is
5270 only called from error handlers in process.c, and is not time
5271 critical. */
5273 void
5274 update_echo_area ()
5276 if (!NILP (echo_area_buffer[0]))
5278 Lisp_Object string;
5279 string = Fcurrent_message ();
5280 message3 (string, XSTRING (string)->size,
5281 !NILP (current_buffer->enable_multibyte_characters));
5286 /* Make sure echo area buffers in echo_buffers[] are life. If they
5287 aren't, make new ones. */
5289 static void
5290 ensure_echo_area_buffers ()
5292 int i;
5294 for (i = 0; i < 2; ++i)
5295 if (!BUFFERP (echo_buffer[i])
5296 || NILP (XBUFFER (echo_buffer[i])->name))
5298 char name[30];
5299 sprintf (name, " *Echo Area %d*", i);
5300 echo_buffer[i] = Fget_buffer_create (build_string (name));
5305 /* Call FN with args A1..A5 with either the current or last displayed
5306 echo_area_buffer as current buffer.
5308 WHICH zero means use the current message buffer
5309 echo_area_buffer[0]. If that is nil, choose a suitable buffer
5310 from echo_buffer[] and clear it.
5312 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
5313 suitable buffer from echo_buffer[] and clear it.
5315 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
5316 that the current message becomes the last displayed one, make
5317 choose a suitable buffer for echo_area_buffer[0], and clear it.
5319 Value is what FN returns. */
5321 static int
5322 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
5323 struct window *w;
5324 int which;
5325 int (*fn) ();
5326 int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
5328 Lisp_Object buffer;
5329 int this_one, the_other, clear_buffer_p, rc;
5330 int count = specpdl_ptr - specpdl;
5332 /* If buffers aren't life, make new ones. */
5333 ensure_echo_area_buffers ();
5335 clear_buffer_p = 0;
5337 if (which == 0)
5338 this_one = 0, the_other = 1;
5339 else if (which > 0)
5340 this_one = 1, the_other = 0;
5341 else
5343 this_one = 0, the_other = 1;
5344 clear_buffer_p = 1;
5346 /* We need a fresh one in case the current echo buffer equals
5347 the one containing the last displayed echo area message. */
5348 if (!NILP (echo_area_buffer[this_one])
5349 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
5350 echo_area_buffer[this_one] = Qnil;
5353 /* Choose a suitable buffer from echo_buffer[] is we don't
5354 have one. */
5355 if (NILP (echo_area_buffer[this_one]))
5357 echo_area_buffer[this_one]
5358 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
5359 ? echo_buffer[the_other]
5360 : echo_buffer[this_one]);
5361 clear_buffer_p = 1;
5364 buffer = echo_area_buffer[this_one];
5366 record_unwind_protect (unwind_with_echo_area_buffer,
5367 with_echo_area_buffer_unwind_data (w));
5369 /* Make the echo area buffer current. Note that for display
5370 purposes, it is not necessary that the displayed window's buffer
5371 == current_buffer, except for text property lookup. So, let's
5372 only set that buffer temporarily here without doing a full
5373 Fset_window_buffer. We must also change w->pointm, though,
5374 because otherwise an assertions in unshow_buffer fails, and Emacs
5375 aborts. */
5376 set_buffer_internal_1 (XBUFFER (buffer));
5377 if (w)
5379 w->buffer = buffer;
5380 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
5382 current_buffer->truncate_lines = Qnil;
5383 current_buffer->undo_list = Qt;
5384 current_buffer->read_only = Qnil;
5386 if (clear_buffer_p && Z > BEG)
5387 del_range (BEG, Z);
5389 xassert (BEGV >= BEG);
5390 xassert (ZV <= Z && ZV >= BEGV);
5392 rc = fn (a1, a2, a3, a4, a5);
5394 xassert (BEGV >= BEG);
5395 xassert (ZV <= Z && ZV >= BEGV);
5397 unbind_to (count, Qnil);
5398 return rc;
5402 /* Save state that should be preserved around the call to the function
5403 FN called in with_echo_area_buffer. */
5405 static Lisp_Object
5406 with_echo_area_buffer_unwind_data (w)
5407 struct window *w;
5409 int i = 0;
5410 Lisp_Object vector;
5412 /* Reduce consing by keeping one vector in
5413 Vwith_echo_area_save_vector. */
5414 vector = Vwith_echo_area_save_vector;
5415 Vwith_echo_area_save_vector = Qnil;
5417 if (NILP (vector))
5418 vector = Fmake_vector (make_number (7), Qnil);
5420 XSETBUFFER (XVECTOR (vector)->contents[i], current_buffer); ++i;
5421 XVECTOR (vector)->contents[i++] = Vdeactivate_mark;
5422 XVECTOR (vector)->contents[i++] = make_number (windows_or_buffers_changed);
5424 if (w)
5426 XSETWINDOW (XVECTOR (vector)->contents[i], w); ++i;
5427 XVECTOR (vector)->contents[i++] = w->buffer;
5428 XVECTOR (vector)->contents[i++]
5429 = make_number (XMARKER (w->pointm)->charpos);
5430 XVECTOR (vector)->contents[i++]
5431 = make_number (XMARKER (w->pointm)->bytepos);
5433 else
5435 int end = i + 4;
5436 while (i < end)
5437 XVECTOR (vector)->contents[i++] = Qnil;
5440 xassert (i == XVECTOR (vector)->size);
5441 return vector;
5445 /* Restore global state from VECTOR which was created by
5446 with_echo_area_buffer_unwind_data. */
5448 static Lisp_Object
5449 unwind_with_echo_area_buffer (vector)
5450 Lisp_Object vector;
5452 int i = 0;
5454 set_buffer_internal_1 (XBUFFER (XVECTOR (vector)->contents[i])); ++i;
5455 Vdeactivate_mark = XVECTOR (vector)->contents[i]; ++i;
5456 windows_or_buffers_changed = XFASTINT (XVECTOR (vector)->contents[i]); ++i;
5458 if (WINDOWP (XVECTOR (vector)->contents[i]))
5460 struct window *w;
5461 Lisp_Object buffer, charpos, bytepos;
5463 w = XWINDOW (XVECTOR (vector)->contents[i]); ++i;
5464 buffer = XVECTOR (vector)->contents[i]; ++i;
5465 charpos = XVECTOR (vector)->contents[i]; ++i;
5466 bytepos = XVECTOR (vector)->contents[i]; ++i;
5468 w->buffer = buffer;
5469 set_marker_both (w->pointm, buffer,
5470 XFASTINT (charpos), XFASTINT (bytepos));
5473 Vwith_echo_area_save_vector = vector;
5474 return Qnil;
5478 /* Set up the echo area for use by print functions. MULTIBYTE_P
5479 non-zero means we will print multibyte. */
5481 void
5482 setup_echo_area_for_printing (multibyte_p)
5483 int multibyte_p;
5485 ensure_echo_area_buffers ();
5487 if (!message_buf_print)
5489 /* A message has been output since the last time we printed.
5490 Choose a fresh echo area buffer. */
5491 if (EQ (echo_area_buffer[1], echo_buffer[0]))
5492 echo_area_buffer[0] = echo_buffer[1];
5493 else
5494 echo_area_buffer[0] = echo_buffer[0];
5496 /* Switch to that buffer and clear it. */
5497 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
5498 if (Z > BEG)
5499 del_range (BEG, Z);
5500 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
5502 /* Set up the buffer for the multibyteness we need. */
5503 if (multibyte_p
5504 != !NILP (current_buffer->enable_multibyte_characters))
5505 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
5507 /* Raise the frame containing the echo area. */
5508 if (minibuffer_auto_raise)
5510 struct frame *sf = SELECTED_FRAME ();
5511 Lisp_Object mini_window;
5512 mini_window = FRAME_MINIBUF_WINDOW (sf);
5513 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
5516 message_buf_print = 1;
5518 else
5520 if (NILP (echo_area_buffer[0]))
5522 if (EQ (echo_area_buffer[1], echo_buffer[0]))
5523 echo_area_buffer[0] = echo_buffer[1];
5524 else
5525 echo_area_buffer[0] = echo_buffer[0];
5528 if (current_buffer != XBUFFER (echo_area_buffer[0]))
5529 /* Someone switched buffers between print requests. */
5530 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
5535 /* Display an echo area message in window W. Value is non-zero if W's
5536 height is changed. If display_last_displayed_message_p is
5537 non-zero, display the message that was last displayed, otherwise
5538 display the current message. */
5540 static int
5541 display_echo_area (w)
5542 struct window *w;
5544 int i, no_message_p, window_height_changed_p, count;
5546 /* Temporarily disable garbage collections while displaying the echo
5547 area. This is done because a GC can print a message itself.
5548 That message would modify the echo area buffer's contents while a
5549 redisplay of the buffer is going on, and seriously confuse
5550 redisplay. */
5551 count = inhibit_garbage_collection ();
5553 /* If there is no message, we must call display_echo_area_1
5554 nevertheless because it resizes the window. But we will have to
5555 reset the echo_area_buffer in question to nil at the end because
5556 with_echo_area_buffer will sets it to an empty buffer. */
5557 i = display_last_displayed_message_p ? 1 : 0;
5558 no_message_p = NILP (echo_area_buffer[i]);
5560 window_height_changed_p
5561 = with_echo_area_buffer (w, display_last_displayed_message_p,
5562 (int (*) ()) display_echo_area_1, w);
5564 if (no_message_p)
5565 echo_area_buffer[i] = Qnil;
5567 unbind_to (count, Qnil);
5568 return window_height_changed_p;
5572 /* Helper for display_echo_area. Display the current buffer which
5573 contains the current echo area message in window W, a mini-window.
5574 Change the height of W so that all of the message is displayed.
5575 Value is non-zero if height of W was changed. */
5577 static int
5578 display_echo_area_1 (w)
5579 struct window *w;
5581 Lisp_Object window;
5582 struct text_pos start;
5583 int window_height_changed_p = 0;
5585 /* Do this before displaying, so that we have a large enough glyph
5586 matrix for the display. */
5587 window_height_changed_p = resize_mini_window (w, 0);
5589 /* Display. */
5590 clear_glyph_matrix (w->desired_matrix);
5591 XSETWINDOW (window, w);
5592 SET_TEXT_POS (start, BEG, BEG_BYTE);
5593 try_window (window, start);
5595 return window_height_changed_p;
5599 /* Resize the echo area window to exactly the size needed for the
5600 currently displayed message, if there is one. */
5602 void
5603 resize_echo_area_axactly ()
5605 if (BUFFERP (echo_area_buffer[0])
5606 && WINDOWP (echo_area_window))
5608 struct window *w = XWINDOW (echo_area_window);
5609 int resized_p;
5611 resized_p = with_echo_area_buffer (w, 0,
5612 (int (*) ()) resize_mini_window,
5613 w, 1);
5614 if (resized_p)
5616 ++windows_or_buffers_changed;
5617 ++update_mode_lines;
5618 redisplay_internal (0);
5624 /* Resize mini-window W to fit the size of its contents. EXACT:P
5625 means size the window exactly to the size needed. Otherwise, it's
5626 only enlarged until W's buffer is empty. Value is non-zero if
5627 the window height has been changed. */
5630 resize_mini_window (w, exact_p)
5631 struct window *w;
5632 int exact_p;
5634 struct frame *f = XFRAME (w->frame);
5635 int window_height_changed_p = 0;
5637 xassert (MINI_WINDOW_P (w));
5639 /* Nil means don't try to resize. */
5640 if (NILP (Vmax_mini_window_height)
5641 || (FRAME_X_P (f) && f->output_data.x == NULL))
5642 return 0;
5644 if (!FRAME_MINIBUF_ONLY_P (f))
5646 struct it it;
5647 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
5648 int total_height = XFASTINT (root->height) + XFASTINT (w->height);
5649 int height, max_height;
5650 int unit = CANON_Y_UNIT (f);
5651 struct text_pos start;
5653 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
5655 /* Compute the max. number of lines specified by the user. */
5656 if (FLOATP (Vmax_mini_window_height))
5657 max_height = XFLOATINT (Vmax_mini_window_height) * total_height;
5658 else if (INTEGERP (Vmax_mini_window_height))
5659 max_height = XINT (Vmax_mini_window_height);
5660 else
5661 max_height = total_height / 4;
5663 /* Correct that max. height if it's bogus. */
5664 max_height = max (1, max_height);
5665 max_height = min (total_height, max_height);
5667 /* Find out the height of the text in the window. */
5668 last_height = 0;
5669 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
5670 if (it.max_ascent == 0 && it.max_descent == 0)
5671 height = it.current_y + last_height;
5672 else
5673 height = it.current_y + it.max_ascent + it.max_descent;
5674 height = (height + unit - 1) / unit;
5676 /* Compute a suitable window start. */
5677 if (height > max_height)
5679 height = max_height;
5680 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
5681 move_it_vertically_backward (&it, (height - 1) * unit);
5682 start = it.current.pos;
5684 else
5685 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
5686 SET_MARKER_FROM_TEXT_POS (w->start, start);
5688 /* Let it grow only, until we display an empty message, in which
5689 case the window shrinks again. */
5690 if (height > XFASTINT (w->height))
5692 int old_height = XFASTINT (w->height);
5693 freeze_window_starts (f, 1);
5694 grow_mini_window (w, height - XFASTINT (w->height));
5695 window_height_changed_p = XFASTINT (w->height) != old_height;
5697 else if (height < XFASTINT (w->height)
5698 && (exact_p || BEGV == ZV))
5700 int old_height = XFASTINT (w->height);
5701 freeze_window_starts (f, 0);
5702 shrink_mini_window (w);
5703 window_height_changed_p = XFASTINT (w->height) != old_height;
5707 return window_height_changed_p;
5711 /* Value is the current message, a string, or nil if there is no
5712 current message. */
5714 Lisp_Object
5715 current_message ()
5717 Lisp_Object msg;
5719 if (NILP (echo_area_buffer[0]))
5720 msg = Qnil;
5721 else
5723 with_echo_area_buffer (0, 0, (int (*) ()) current_message_1, &msg);
5724 if (NILP (msg))
5725 echo_area_buffer[0] = Qnil;
5728 return msg;
5732 static int
5733 current_message_1 (msg)
5734 Lisp_Object *msg;
5736 if (Z > BEG)
5737 *msg = make_buffer_string (BEG, Z, 1);
5738 else
5739 *msg = Qnil;
5740 return 0;
5744 /* Push the current message on Vmessage_stack for later restauration
5745 by restore_message. Value is non-zero if the current message isn't
5746 empty. This is a relatively infrequent operation, so it's not
5747 worth optimizing. */
5750 push_message ()
5752 Lisp_Object msg;
5753 msg = current_message ();
5754 Vmessage_stack = Fcons (msg, Vmessage_stack);
5755 return STRINGP (msg);
5759 /* Restore message display from the top of Vmessage_stack. */
5761 void
5762 restore_message ()
5764 Lisp_Object msg;
5766 xassert (CONSP (Vmessage_stack));
5767 msg = XCAR (Vmessage_stack);
5768 if (STRINGP (msg))
5769 message3_nolog (msg, STRING_BYTES (XSTRING (msg)), STRING_MULTIBYTE (msg));
5770 else
5771 message3_nolog (msg, 0, 0);
5775 /* Pop the top-most entry off Vmessage_stack. */
5777 void
5778 pop_message ()
5780 xassert (CONSP (Vmessage_stack));
5781 Vmessage_stack = XCDR (Vmessage_stack);
5785 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
5786 exits. If the stack is not empty, we have a missing pop_message
5787 somewhere. */
5789 void
5790 check_message_stack ()
5792 if (!NILP (Vmessage_stack))
5793 abort ();
5797 /* Truncate to NCHARS what will be displayed in the echo area the next
5798 time we display it---but don't redisplay it now. */
5800 void
5801 truncate_echo_area (nchars)
5802 int nchars;
5804 if (nchars == 0)
5805 echo_area_buffer[0] = Qnil;
5806 /* A null message buffer means that the frame hasn't really been
5807 initialized yet. Error messages get reported properly by
5808 cmd_error, so this must be just an informative message; toss it. */
5809 else if (!noninteractive
5810 && INTERACTIVE
5811 && !NILP (echo_area_buffer[0]))
5813 struct frame *sf = SELECTED_FRAME ();
5814 if (FRAME_MESSAGE_BUF (sf))
5815 with_echo_area_buffer (0, 0, (int (*) ()) truncate_message_1, nchars);
5820 /* Helper function for truncate_echo_area. Truncate the current
5821 message to at most NCHARS characters. */
5823 static int
5824 truncate_message_1 (nchars)
5825 int nchars;
5827 if (BEG + nchars < Z)
5828 del_range (BEG + nchars, Z);
5829 if (Z == BEG)
5830 echo_area_buffer[0] = Qnil;
5831 return 0;
5835 /* Set the current message to a substring of S or STRING.
5837 If STRING is a Lisp string, set the message to the first NBYTES
5838 bytes from STRING. NBYTES zero means use the whole string. If
5839 STRING is multibyte, the message will be displayed multibyte.
5841 If S is not null, set the message to the first LEN bytes of S. LEN
5842 zero means use the whole string. MULTIBYTE_P non-zero means S is
5843 multibyte. Display the message multibyte in that case. */
5845 void
5846 set_message (s, string, nbytes, multibyte_p)
5847 char *s;
5848 Lisp_Object string;
5849 int nbytes;
5851 message_enable_multibyte
5852 = ((s && multibyte_p)
5853 || (STRINGP (string) && STRING_MULTIBYTE (string)));
5855 with_echo_area_buffer (0, -1, (int (*) ()) set_message_1,
5856 s, string, nbytes, multibyte_p);
5857 message_buf_print = 0;
5861 /* Helper function for set_message. Arguments have the same meaning
5862 as there. This function is called with the echo area buffer being
5863 current. */
5865 static int
5866 set_message_1 (s, string, nbytes, multibyte_p)
5867 char *s;
5868 Lisp_Object string;
5869 int nbytes, multibyte_p;
5871 xassert (BEG == Z);
5873 /* Change multibyteness of the echo buffer appropriately. */
5874 if (message_enable_multibyte
5875 != !NILP (current_buffer->enable_multibyte_characters))
5876 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
5878 /* Insert new message at BEG. */
5879 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
5881 if (STRINGP (string))
5883 int nchars;
5885 if (nbytes == 0)
5886 nbytes = XSTRING (string)->size_byte;
5887 nchars = string_byte_to_char (string, nbytes);
5889 /* This function takes care of single/multibyte conversion. We
5890 just have to ensure that the echo area buffer has the right
5891 setting of enable_multibyte_characters. */
5892 insert_from_string (string, 0, 0, nchars, nbytes, 1);
5894 else if (s)
5896 if (nbytes == 0)
5897 nbytes = strlen (s);
5899 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
5901 /* Convert from multi-byte to single-byte. */
5902 int i, c, n;
5903 unsigned char work[1];
5905 /* Convert a multibyte string to single-byte. */
5906 for (i = 0; i < nbytes; i += n)
5908 c = string_char_and_length (s + i, nbytes - i, &n);
5909 work[0] = (SINGLE_BYTE_CHAR_P (c)
5911 : multibyte_char_to_unibyte (c, Qnil));
5912 insert_1_both (work, 1, 1, 1, 0, 0);
5915 else if (!multibyte_p
5916 && !NILP (current_buffer->enable_multibyte_characters))
5918 /* Convert from single-byte to multi-byte. */
5919 int i, c, n;
5920 unsigned char *msg = (unsigned char *) s;
5921 unsigned char str[MAX_MULTIBYTE_LENGTH];
5923 /* Convert a single-byte string to multibyte. */
5924 for (i = 0; i < nbytes; i++)
5926 c = unibyte_char_to_multibyte (msg[i]);
5927 n = CHAR_STRING (c, str);
5928 insert_1_both (str, 1, n, 1, 0, 0);
5931 else
5932 insert_1 (s, nbytes, 1, 0, 0);
5935 return 0;
5939 /* Clear messages. CURRENT_P non-zero means clear the current
5940 message. LAST_DISPLAYED_P non-zero means clear the message
5941 last displayed. */
5943 void
5944 clear_message (current_p, last_displayed_p)
5945 int current_p, last_displayed_p;
5947 if (current_p)
5948 echo_area_buffer[0] = Qnil;
5950 if (last_displayed_p)
5951 echo_area_buffer[1] = Qnil;
5953 message_buf_print = 0;
5956 /* Clear garbaged frames.
5958 This function is used where the old redisplay called
5959 redraw_garbaged_frames which in turn called redraw_frame which in
5960 turn called clear_frame. The call to clear_frame was a source of
5961 flickering. I believe a clear_frame is not necessary. It should
5962 suffice in the new redisplay to invalidate all current matrices,
5963 and ensure a complete redisplay of all windows. */
5965 static void
5966 clear_garbaged_frames ()
5968 if (frame_garbaged)
5970 Lisp_Object tail, frame;
5972 FOR_EACH_FRAME (tail, frame)
5974 struct frame *f = XFRAME (frame);
5976 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
5978 clear_current_matrices (f);
5979 f->garbaged = 0;
5983 frame_garbaged = 0;
5984 ++windows_or_buffers_changed;
5989 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
5990 is non-zero update selected_frame. Value is non-zero if the
5991 mini-windows height has been changed. */
5993 static int
5994 echo_area_display (update_frame_p)
5995 int update_frame_p;
5997 Lisp_Object mini_window;
5998 struct window *w;
5999 struct frame *f;
6000 int window_height_changed_p = 0;
6001 struct frame *sf = SELECTED_FRAME ();
6003 mini_window = FRAME_MINIBUF_WINDOW (sf);
6004 w = XWINDOW (mini_window);
6005 f = XFRAME (WINDOW_FRAME (w));
6007 /* Don't display if frame is invisible or not yet initialized. */
6008 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
6009 return 0;
6011 #ifdef HAVE_WINDOW_SYSTEM
6012 /* When Emacs starts, selected_frame may be a visible terminal
6013 frame, even if we run under a window system. If we let this
6014 through, a message would be displayed on the terminal. */
6015 if (EQ (selected_frame, Vterminal_frame)
6016 && !NILP (Vwindow_system))
6017 return 0;
6018 #endif /* HAVE_WINDOW_SYSTEM */
6020 /* Redraw garbaged frames. */
6021 if (frame_garbaged)
6022 clear_garbaged_frames ();
6024 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
6026 echo_area_window = mini_window;
6027 window_height_changed_p = display_echo_area (w);
6028 w->must_be_updated_p = 1;
6030 if (update_frame_p)
6032 /* Not called from redisplay_internal. If we changed
6033 window configuration, we must redisplay thoroughly.
6034 Otherwise, we can do with updating what we displayed
6035 above. */
6036 if (window_height_changed_p)
6038 ++windows_or_buffers_changed;
6039 ++update_mode_lines;
6040 redisplay_internal (0);
6042 else if (FRAME_WINDOW_P (f))
6044 update_single_window (w, 1);
6045 rif->flush_display (f);
6047 else
6048 update_frame (f, 1, 1);
6051 else if (!EQ (mini_window, selected_window))
6052 windows_or_buffers_changed++;
6054 /* Last displayed message is now the current message. */
6055 echo_area_buffer[1] = echo_area_buffer[0];
6057 /* Prevent redisplay optimization in redisplay_internal by resetting
6058 this_line_start_pos. This is done because the mini-buffer now
6059 displays the message instead of its buffer text. */
6060 if (EQ (mini_window, selected_window))
6061 CHARPOS (this_line_start_pos) = 0;
6063 return window_height_changed_p;
6068 /***********************************************************************
6069 Frame Titles
6070 ***********************************************************************/
6073 #ifdef HAVE_WINDOW_SYSTEM
6075 /* A buffer for constructing frame titles in it; allocated from the
6076 heap in init_xdisp and resized as needed in store_frame_title_char. */
6078 static char *frame_title_buf;
6080 /* The buffer's end, and a current output position in it. */
6082 static char *frame_title_buf_end;
6083 static char *frame_title_ptr;
6086 /* Store a single character C for the frame title in frame_title_buf.
6087 Re-allocate frame_title_buf if necessary. */
6089 static void
6090 store_frame_title_char (c)
6091 char c;
6093 /* If output position has reached the end of the allocated buffer,
6094 double the buffer's size. */
6095 if (frame_title_ptr == frame_title_buf_end)
6097 int len = frame_title_ptr - frame_title_buf;
6098 int new_size = 2 * len * sizeof *frame_title_buf;
6099 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
6100 frame_title_buf_end = frame_title_buf + new_size;
6101 frame_title_ptr = frame_title_buf + len;
6104 *frame_title_ptr++ = c;
6108 /* Store part of a frame title in frame_title_buf, beginning at
6109 frame_title_ptr. STR is the string to store. Do not copy more
6110 than PRECISION number of bytes from STR; PRECISION <= 0 means copy
6111 the whole string. Pad with spaces until FIELD_WIDTH number of
6112 characters have been copied; FIELD_WIDTH <= 0 means don't pad.
6113 Called from display_mode_element when it is used to build a frame
6114 title. */
6116 static int
6117 store_frame_title (str, field_width, precision)
6118 unsigned char *str;
6119 int field_width, precision;
6121 int n = 0;
6123 /* Copy at most PRECISION chars from STR. */
6124 while ((precision <= 0 || n < precision)
6125 && *str)
6127 store_frame_title_char (*str++);
6128 ++n;
6131 /* Fill up with spaces until FIELD_WIDTH reached. */
6132 while (field_width > 0
6133 && n < field_width)
6135 store_frame_title_char (' ');
6136 ++n;
6139 return n;
6143 /* Set the title of FRAME, if it has changed. The title format is
6144 Vicon_title_format if FRAME is iconified, otherwise it is
6145 frame_title_format. */
6147 static void
6148 x_consider_frame_title (frame)
6149 Lisp_Object frame;
6151 struct frame *f = XFRAME (frame);
6153 if (FRAME_WINDOW_P (f)
6154 || FRAME_MINIBUF_ONLY_P (f)
6155 || f->explicit_name)
6157 /* Do we have more than one visible frame on this X display? */
6158 Lisp_Object tail;
6159 Lisp_Object fmt;
6160 struct buffer *obuf;
6161 int len;
6162 struct it it;
6164 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
6166 struct frame *tf = XFRAME (XCAR (tail));
6168 if (tf != f
6169 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
6170 && !FRAME_MINIBUF_ONLY_P (tf)
6171 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
6172 break;
6175 /* Set global variable indicating that multiple frames exist. */
6176 multiple_frames = CONSP (tail);
6178 /* Switch to the buffer of selected window of the frame. Set up
6179 frame_title_ptr so that display_mode_element will output into it;
6180 then display the title. */
6181 obuf = current_buffer;
6182 Fset_buffer (XWINDOW (f->selected_window)->buffer);
6183 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
6184 frame_title_ptr = frame_title_buf;
6185 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
6186 NULL, DEFAULT_FACE_ID);
6187 len = display_mode_element (&it, 0, -1, -1, fmt);
6188 frame_title_ptr = NULL;
6189 set_buffer_internal (obuf);
6191 /* Set the title only if it's changed. This avoids consing in
6192 the common case where it hasn't. (If it turns out that we've
6193 already wasted too much time by walking through the list with
6194 display_mode_element, then we might need to optimize at a
6195 higher level than this.) */
6196 if (! STRINGP (f->name)
6197 || STRING_BYTES (XSTRING (f->name)) != len
6198 || bcmp (frame_title_buf, XSTRING (f->name)->data, len) != 0)
6199 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
6203 #else /* not HAVE_WINDOW_SYSTEM */
6205 #define frame_title_ptr ((char *)0)
6206 #define store_frame_title(str, mincol, maxcol) 0
6208 #endif /* not HAVE_WINDOW_SYSTEM */
6213 /***********************************************************************
6214 Menu Bars
6215 ***********************************************************************/
6218 /* Prepare for redisplay by updating menu-bar item lists when
6219 appropriate. This can call eval. */
6221 void
6222 prepare_menu_bars ()
6224 int all_windows;
6225 struct gcpro gcpro1, gcpro2;
6226 struct frame *f;
6227 struct frame *tooltip_frame;
6229 #ifdef HAVE_X_WINDOWS
6230 tooltip_frame = tip_frame;
6231 #else
6232 tooltip_frame = NULL;
6233 #endif
6235 /* Update all frame titles based on their buffer names, etc. We do
6236 this before the menu bars so that the buffer-menu will show the
6237 up-to-date frame titles. */
6238 #ifdef HAVE_WINDOW_SYSTEM
6239 if (windows_or_buffers_changed || update_mode_lines)
6241 Lisp_Object tail, frame;
6243 FOR_EACH_FRAME (tail, frame)
6245 f = XFRAME (frame);
6246 if (f != tooltip_frame
6247 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
6248 x_consider_frame_title (frame);
6251 #endif /* HAVE_WINDOW_SYSTEM */
6253 /* Update the menu bar item lists, if appropriate. This has to be
6254 done before any actual redisplay or generation of display lines. */
6255 all_windows = (update_mode_lines
6256 || buffer_shared > 1
6257 || windows_or_buffers_changed);
6258 if (all_windows)
6260 Lisp_Object tail, frame;
6261 int count = specpdl_ptr - specpdl;
6263 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6265 FOR_EACH_FRAME (tail, frame)
6267 f = XFRAME (frame);
6269 /* Ignore tooltip frame. */
6270 if (f == tooltip_frame)
6271 continue;
6273 /* If a window on this frame changed size, report that to
6274 the user and clear the size-change flag. */
6275 if (FRAME_WINDOW_SIZES_CHANGED (f))
6277 Lisp_Object functions;
6279 /* Clear flag first in case we get an error below. */
6280 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
6281 functions = Vwindow_size_change_functions;
6282 GCPRO2 (tail, functions);
6284 while (CONSP (functions))
6286 call1 (XCAR (functions), frame);
6287 functions = XCDR (functions);
6289 UNGCPRO;
6292 GCPRO1 (tail);
6293 update_menu_bar (f, 0);
6294 #ifdef HAVE_WINDOW_SYSTEM
6295 update_tool_bar (f, 0);
6296 #endif
6297 UNGCPRO;
6300 unbind_to (count, Qnil);
6302 else
6304 struct frame *sf = SELECTED_FRAME ();
6305 update_menu_bar (sf, 1);
6306 #ifdef HAVE_WINDOW_SYSTEM
6307 update_tool_bar (sf, 1);
6308 #endif
6311 /* Motif needs this. See comment in xmenu.c. Turn it off when
6312 pending_menu_activation is not defined. */
6313 #ifdef USE_X_TOOLKIT
6314 pending_menu_activation = 0;
6315 #endif
6319 /* Update the menu bar item list for frame F. This has to be done
6320 before we start to fill in any display lines, because it can call
6321 eval.
6323 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
6325 static void
6326 update_menu_bar (f, save_match_data)
6327 struct frame *f;
6328 int save_match_data;
6330 Lisp_Object window;
6331 register struct window *w;
6333 window = FRAME_SELECTED_WINDOW (f);
6334 w = XWINDOW (window);
6336 if (update_mode_lines)
6337 w->update_mode_line = Qt;
6339 if (FRAME_WINDOW_P (f)
6341 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
6342 FRAME_EXTERNAL_MENU_BAR (f)
6343 #else
6344 FRAME_MENU_BAR_LINES (f) > 0
6345 #endif
6346 : FRAME_MENU_BAR_LINES (f) > 0)
6348 /* If the user has switched buffers or windows, we need to
6349 recompute to reflect the new bindings. But we'll
6350 recompute when update_mode_lines is set too; that means
6351 that people can use force-mode-line-update to request
6352 that the menu bar be recomputed. The adverse effect on
6353 the rest of the redisplay algorithm is about the same as
6354 windows_or_buffers_changed anyway. */
6355 if (windows_or_buffers_changed
6356 || !NILP (w->update_mode_line)
6357 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
6358 < BUF_MODIFF (XBUFFER (w->buffer)))
6359 != !NILP (w->last_had_star))
6360 || ((!NILP (Vtransient_mark_mode)
6361 && !NILP (XBUFFER (w->buffer)->mark_active))
6362 != !NILP (w->region_showing)))
6364 struct buffer *prev = current_buffer;
6365 int count = specpdl_ptr - specpdl;
6367 set_buffer_internal_1 (XBUFFER (w->buffer));
6368 if (save_match_data)
6369 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6370 if (NILP (Voverriding_local_map_menu_flag))
6372 specbind (Qoverriding_terminal_local_map, Qnil);
6373 specbind (Qoverriding_local_map, Qnil);
6376 /* Run the Lucid hook. */
6377 call1 (Vrun_hooks, Qactivate_menubar_hook);
6379 /* If it has changed current-menubar from previous value,
6380 really recompute the menu-bar from the value. */
6381 if (! NILP (Vlucid_menu_bar_dirty_flag))
6382 call0 (Qrecompute_lucid_menubar);
6384 safe_run_hooks (Qmenu_bar_update_hook);
6385 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
6387 /* Redisplay the menu bar in case we changed it. */
6388 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
6389 if (FRAME_WINDOW_P (f))
6390 set_frame_menubar (f, 0, 0);
6391 else
6392 /* On a terminal screen, the menu bar is an ordinary screen
6393 line, and this makes it get updated. */
6394 w->update_mode_line = Qt;
6395 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
6396 /* In the non-toolkit version, the menu bar is an ordinary screen
6397 line, and this makes it get updated. */
6398 w->update_mode_line = Qt;
6399 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
6401 unbind_to (count, Qnil);
6402 set_buffer_internal_1 (prev);
6409 /***********************************************************************
6410 Tool-bars
6411 ***********************************************************************/
6413 #ifdef HAVE_WINDOW_SYSTEM
6415 /* Update the tool-bar item list for frame F. This has to be done
6416 before we start to fill in any display lines. Called from
6417 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
6418 and restore it here. */
6420 static void
6421 update_tool_bar (f, save_match_data)
6422 struct frame *f;
6423 int save_match_data;
6425 if (WINDOWP (f->tool_bar_window)
6426 && XFASTINT (XWINDOW (f->tool_bar_window)->height) > 0)
6428 Lisp_Object window;
6429 struct window *w;
6431 window = FRAME_SELECTED_WINDOW (f);
6432 w = XWINDOW (window);
6434 /* If the user has switched buffers or windows, we need to
6435 recompute to reflect the new bindings. But we'll
6436 recompute when update_mode_lines is set too; that means
6437 that people can use force-mode-line-update to request
6438 that the menu bar be recomputed. The adverse effect on
6439 the rest of the redisplay algorithm is about the same as
6440 windows_or_buffers_changed anyway. */
6441 if (windows_or_buffers_changed
6442 || !NILP (w->update_mode_line)
6443 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
6444 < BUF_MODIFF (XBUFFER (w->buffer)))
6445 != !NILP (w->last_had_star))
6446 || ((!NILP (Vtransient_mark_mode)
6447 && !NILP (XBUFFER (w->buffer)->mark_active))
6448 != !NILP (w->region_showing)))
6450 struct buffer *prev = current_buffer;
6451 int count = specpdl_ptr - specpdl;
6453 /* Set current_buffer to the buffer of the selected
6454 window of the frame, so that we get the right local
6455 keymaps. */
6456 set_buffer_internal_1 (XBUFFER (w->buffer));
6458 /* Save match data, if we must. */
6459 if (save_match_data)
6460 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6462 /* Make sure that we don't accidentally use bogus keymaps. */
6463 if (NILP (Voverriding_local_map_menu_flag))
6465 specbind (Qoverriding_terminal_local_map, Qnil);
6466 specbind (Qoverriding_local_map, Qnil);
6469 /* Build desired tool-bar items from keymaps. */
6470 f->desired_tool_bar_items
6471 = tool_bar_items (f->desired_tool_bar_items,
6472 &f->n_desired_tool_bar_items);
6474 /* Redisplay the tool-bar in case we changed it. */
6475 w->update_mode_line = Qt;
6477 unbind_to (count, Qnil);
6478 set_buffer_internal_1 (prev);
6484 /* Set F->desired_tool_bar_string to a Lisp string representing frame
6485 F's desired tool-bar contents. F->desired_tool_bar_items must have
6486 been set up previously by calling prepare_menu_bars. */
6488 static void
6489 build_desired_tool_bar_string (f)
6490 struct frame *f;
6492 int i, size, size_needed, string_idx;
6493 struct gcpro gcpro1, gcpro2, gcpro3;
6494 Lisp_Object image, plist, props;
6496 image = plist = props = Qnil;
6497 GCPRO3 (image, plist, props);
6499 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
6500 Otherwise, make a new string. */
6502 /* The size of the string we might be able to reuse. */
6503 size = (STRINGP (f->desired_tool_bar_string)
6504 ? XSTRING (f->desired_tool_bar_string)->size
6505 : 0);
6507 /* Each image in the string we build is preceded by a space,
6508 and there is a space at the end. */
6509 size_needed = f->n_desired_tool_bar_items + 1;
6511 /* Reuse f->desired_tool_bar_string, if possible. */
6512 if (size < size_needed)
6513 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
6514 make_number (' '));
6515 else
6517 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
6518 Fremove_text_properties (make_number (0), make_number (size),
6519 props, f->desired_tool_bar_string);
6522 /* Put a `display' property on the string for the images to display,
6523 put a `menu_item' property on tool-bar items with a value that
6524 is the index of the item in F's tool-bar item vector. */
6525 for (i = 0, string_idx = 0;
6526 i < f->n_desired_tool_bar_items;
6527 ++i, string_idx += 1)
6529 #define PROP(IDX) \
6530 (XVECTOR (f->desired_tool_bar_items) \
6531 ->contents[i * TOOL_BAR_ITEM_NSLOTS + (IDX)])
6533 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
6534 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
6535 int margin, relief;
6536 extern Lisp_Object QCrelief, QCmargin, QCalgorithm, Qimage;
6537 extern Lisp_Object Qlaplace;
6539 /* If image is a vector, choose the image according to the
6540 button state. */
6541 image = PROP (TOOL_BAR_ITEM_IMAGES);
6542 if (VECTORP (image))
6544 enum tool_bar_item_image idx;
6546 if (enabled_p)
6547 idx = (selected_p
6548 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
6549 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
6550 else
6551 idx = (selected_p
6552 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
6553 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
6555 xassert (XVECTOR (image)->size >= idx);
6556 image = XVECTOR (image)->contents[idx];
6559 /* Ignore invalid image specifications. */
6560 if (!valid_image_p (image))
6561 continue;
6563 /* Display the tool-bar button pressed, or depressed. */
6564 plist = Fcopy_sequence (XCDR (image));
6566 /* Compute margin and relief to draw. */
6567 relief = tool_bar_button_relief > 0 ? tool_bar_button_relief : 3;
6568 margin = relief + max (0, tool_bar_button_margin);
6570 if (auto_raise_tool_bar_buttons_p)
6572 /* Add a `:relief' property to the image spec if the item is
6573 selected. */
6574 if (selected_p)
6576 plist = Fplist_put (plist, QCrelief, make_number (-relief));
6577 margin -= relief;
6580 else
6582 /* If image is selected, display it pressed, i.e. with a
6583 negative relief. If it's not selected, display it with a
6584 raised relief. */
6585 plist = Fplist_put (plist, QCrelief,
6586 (selected_p
6587 ? make_number (-relief)
6588 : make_number (relief)));
6589 margin -= relief;
6592 /* Put a margin around the image. */
6593 if (margin)
6594 plist = Fplist_put (plist, QCmargin, make_number (margin));
6596 /* If button is not enabled, make the image appear disabled by
6597 applying an appropriate algorithm to it. */
6598 if (!enabled_p)
6599 plist = Fplist_put (plist, QCalgorithm, Qlaplace);
6601 /* Put a `display' text property on the string for the image to
6602 display. Put a `menu-item' property on the string that gives
6603 the start of this item's properties in the tool-bar items
6604 vector. */
6605 image = Fcons (Qimage, plist);
6606 props = list4 (Qdisplay, image,
6607 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS)),
6608 Fadd_text_properties (make_number (string_idx),
6609 make_number (string_idx + 1),
6610 props, f->desired_tool_bar_string);
6611 #undef PROP
6614 UNGCPRO;
6618 /* Display one line of the tool-bar of frame IT->f. */
6620 static void
6621 display_tool_bar_line (it)
6622 struct it *it;
6624 struct glyph_row *row = it->glyph_row;
6625 int max_x = it->last_visible_x;
6626 struct glyph *last;
6628 prepare_desired_row (row);
6629 row->y = it->current_y;
6631 while (it->current_x < max_x)
6633 int x_before, x, n_glyphs_before, i, nglyphs;
6635 /* Get the next display element. */
6636 if (!get_next_display_element (it))
6637 break;
6639 /* Produce glyphs. */
6640 x_before = it->current_x;
6641 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
6642 PRODUCE_GLYPHS (it);
6644 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
6645 i = 0;
6646 x = x_before;
6647 while (i < nglyphs)
6649 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
6651 if (x + glyph->pixel_width > max_x)
6653 /* Glyph doesn't fit on line. */
6654 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
6655 it->current_x = x;
6656 goto out;
6659 ++it->hpos;
6660 x += glyph->pixel_width;
6661 ++i;
6664 /* Stop at line ends. */
6665 if (ITERATOR_AT_END_OF_LINE_P (it))
6666 break;
6668 set_iterator_to_next (it);
6671 out:;
6673 row->displays_text_p = row->used[TEXT_AREA] != 0;
6674 extend_face_to_end_of_line (it);
6675 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
6676 last->right_box_line_p = 1;
6677 compute_line_metrics (it);
6679 /* If line is empty, make it occupy the rest of the tool-bar. */
6680 if (!row->displays_text_p)
6682 row->height = row->phys_height = it->last_visible_y - row->y;
6683 row->ascent = row->phys_ascent = 0;
6686 row->full_width_p = 1;
6687 row->continued_p = 0;
6688 row->truncated_on_left_p = 0;
6689 row->truncated_on_right_p = 0;
6691 it->current_x = it->hpos = 0;
6692 it->current_y += row->height;
6693 ++it->vpos;
6694 ++it->glyph_row;
6698 /* Value is the number of screen lines needed to make all tool-bar
6699 items of frame F visible. */
6701 static int
6702 tool_bar_lines_needed (f)
6703 struct frame *f;
6705 struct window *w = XWINDOW (f->tool_bar_window);
6706 struct it it;
6708 /* Initialize an iterator for iteration over
6709 F->desired_tool_bar_string in the tool-bar window of frame F. */
6710 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
6711 it.first_visible_x = 0;
6712 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
6713 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
6715 while (!ITERATOR_AT_END_P (&it))
6717 it.glyph_row = w->desired_matrix->rows;
6718 clear_glyph_row (it.glyph_row);
6719 display_tool_bar_line (&it);
6722 return (it.current_y + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);
6726 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
6727 height should be changed. */
6729 static int
6730 redisplay_tool_bar (f)
6731 struct frame *f;
6733 struct window *w;
6734 struct it it;
6735 struct glyph_row *row;
6736 int change_height_p = 0;
6738 /* If frame hasn't a tool-bar window or if it is zero-height, don't
6739 do anything. This means you must start with tool-bar-lines
6740 non-zero to get the auto-sizing effect. Or in other words, you
6741 can turn off tool-bars by specifying tool-bar-lines zero. */
6742 if (!WINDOWP (f->tool_bar_window)
6743 || (w = XWINDOW (f->tool_bar_window),
6744 XFASTINT (w->height) == 0))
6745 return 0;
6747 /* Set up an iterator for the tool-bar window. */
6748 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
6749 it.first_visible_x = 0;
6750 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
6751 row = it.glyph_row;
6753 /* Build a string that represents the contents of the tool-bar. */
6754 build_desired_tool_bar_string (f);
6755 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
6757 /* Display as many lines as needed to display all tool-bar items. */
6758 while (it.current_y < it.last_visible_y)
6759 display_tool_bar_line (&it);
6761 /* It doesn't make much sense to try scrolling in the tool-bar
6762 window, so don't do it. */
6763 w->desired_matrix->no_scrolling_p = 1;
6764 w->must_be_updated_p = 1;
6766 if (auto_resize_tool_bars_p)
6768 int nlines;
6770 /* If there are blank lines at the end, except for a partially
6771 visible blank line at the end that is smaller than
6772 CANON_Y_UNIT, change the tool-bar's height. */
6773 row = it.glyph_row - 1;
6774 if (!row->displays_text_p
6775 && row->height >= CANON_Y_UNIT (f))
6776 change_height_p = 1;
6778 /* If row displays tool-bar items, but is partially visible,
6779 change the tool-bar's height. */
6780 if (row->displays_text_p
6781 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
6782 change_height_p = 1;
6784 /* Resize windows as needed by changing the `tool-bar-lines'
6785 frame parameter. */
6786 if (change_height_p
6787 && (nlines = tool_bar_lines_needed (f),
6788 nlines != XFASTINT (w->height)))
6790 extern Lisp_Object Qtool_bar_lines;
6791 Lisp_Object frame;
6793 XSETFRAME (frame, f);
6794 clear_glyph_matrix (w->desired_matrix);
6795 Fmodify_frame_parameters (frame,
6796 Fcons (Fcons (Qtool_bar_lines,
6797 make_number (nlines)),
6798 Qnil));
6799 fonts_changed_p = 1;
6803 return change_height_p;
6807 /* Get information about the tool-bar item which is displayed in GLYPH
6808 on frame F. Return in *PROP_IDX the index where tool-bar item
6809 properties start in F->current_tool_bar_items. Value is zero if
6810 GLYPH doesn't display a tool-bar item. */
6813 tool_bar_item_info (f, glyph, prop_idx)
6814 struct frame *f;
6815 struct glyph *glyph;
6816 int *prop_idx;
6818 Lisp_Object prop;
6819 int success_p;
6821 /* Get the text property `menu-item' at pos. The value of that
6822 property is the start index of this item's properties in
6823 F->current_tool_bar_items. */
6824 prop = Fget_text_property (make_number (glyph->charpos),
6825 Qmenu_item, f->current_tool_bar_string);
6826 if (INTEGERP (prop))
6828 *prop_idx = XINT (prop);
6829 success_p = 1;
6831 else
6832 success_p = 0;
6834 return success_p;
6837 #endif /* HAVE_WINDOW_SYSTEM */
6841 /************************************************************************
6842 Horizontal scrolling
6843 ************************************************************************/
6845 static int hscroll_window_tree P_ ((Lisp_Object));
6846 static int hscroll_windows P_ ((Lisp_Object));
6848 /* For all leaf windows in the window tree rooted at WINDOW, set their
6849 hscroll value so that PT is (i) visible in the window, and (ii) so
6850 that it is not within a certain margin at the window's left and
6851 right border. Value is non-zero if any window's hscroll has been
6852 changed. */
6854 static int
6855 hscroll_window_tree (window)
6856 Lisp_Object window;
6858 int hscrolled_p = 0;
6860 while (WINDOWP (window))
6862 struct window *w = XWINDOW (window);
6864 if (WINDOWP (w->hchild))
6865 hscrolled_p |= hscroll_window_tree (w->hchild);
6866 else if (WINDOWP (w->vchild))
6867 hscrolled_p |= hscroll_window_tree (w->vchild);
6868 else if (w->cursor.vpos >= 0)
6870 int hscroll_margin, text_area_x, text_area_y;
6871 int text_area_width, text_area_height;
6872 struct glyph_row *current_cursor_row
6873 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
6874 struct glyph_row *desired_cursor_row
6875 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
6876 struct glyph_row *cursor_row
6877 = (desired_cursor_row->enabled_p
6878 ? desired_cursor_row
6879 : current_cursor_row);
6881 window_box (w, TEXT_AREA, &text_area_x, &text_area_y,
6882 &text_area_width, &text_area_height);
6884 /* Scroll when cursor is inside this scroll margin. */
6885 hscroll_margin = 5 * CANON_X_UNIT (XFRAME (w->frame));
6887 if ((XFASTINT (w->hscroll)
6888 && w->cursor.x < hscroll_margin)
6889 || (cursor_row->enabled_p
6890 && cursor_row->truncated_on_right_p
6891 && (w->cursor.x > text_area_width - hscroll_margin)))
6893 struct it it;
6894 int hscroll;
6895 struct buffer *saved_current_buffer;
6896 int pt;
6898 /* Find point in a display of infinite width. */
6899 saved_current_buffer = current_buffer;
6900 current_buffer = XBUFFER (w->buffer);
6902 if (w == XWINDOW (selected_window))
6903 pt = BUF_PT (current_buffer);
6904 else
6906 pt = marker_position (w->pointm);
6907 pt = max (BEGV, pt);
6908 pt = min (ZV, pt);
6911 /* Move iterator to pt starting at cursor_row->start in
6912 a line with infinite width. */
6913 init_to_row_start (&it, w, cursor_row);
6914 it.last_visible_x = INFINITY;
6915 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
6916 current_buffer = saved_current_buffer;
6918 /* Center cursor in window. */
6919 hscroll = (max (0, it.current_x - text_area_width / 2)
6920 / CANON_X_UNIT (it.f));
6922 /* Don't call Fset_window_hscroll if value hasn't
6923 changed because it will prevent redisplay
6924 optimizations. */
6925 if (XFASTINT (w->hscroll) != hscroll)
6927 Fset_window_hscroll (window, make_number (hscroll));
6928 hscrolled_p = 1;
6933 window = w->next;
6936 /* Value is non-zero if hscroll of any leaf window has been changed. */
6937 return hscrolled_p;
6941 /* Set hscroll so that cursor is visible and not inside horizontal
6942 scroll margins for all windows in the tree rooted at WINDOW. See
6943 also hscroll_window_tree above. Value is non-zero if any window's
6944 hscroll has been changed. If it has, desired matrices on the frame
6945 of WINDOW are cleared. */
6947 static int
6948 hscroll_windows (window)
6949 Lisp_Object window;
6951 int hscrolled_p;
6953 if (automatic_hscrolling_p)
6955 hscrolled_p = hscroll_window_tree (window);
6956 if (hscrolled_p)
6957 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
6959 else
6960 hscrolled_p = 0;
6961 return hscrolled_p;
6966 /************************************************************************
6967 Redisplay
6968 ************************************************************************/
6970 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
6971 to a non-zero value. This is sometimes handy to have in a debugger
6972 session. */
6974 #if GLYPH_DEBUG
6976 /* First and last unchanged row for try_window_id. */
6978 int debug_first_unchanged_at_end_vpos;
6979 int debug_last_unchanged_at_beg_vpos;
6981 /* Delta vpos and y. */
6983 int debug_dvpos, debug_dy;
6985 /* Delta in characters and bytes for try_window_id. */
6987 int debug_delta, debug_delta_bytes;
6989 /* Values of window_end_pos and window_end_vpos at the end of
6990 try_window_id. */
6992 int debug_end_pos, debug_end_vpos;
6994 /* Append a string to W->desired_matrix->method. FMT is a printf
6995 format string. A1...A9 are a supplement for a variable-length
6996 argument list. If trace_redisplay_p is non-zero also printf the
6997 resulting string to stderr. */
6999 static void
7000 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
7001 struct window *w;
7002 char *fmt;
7003 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
7005 char buffer[512];
7006 char *method = w->desired_matrix->method;
7007 int len = strlen (method);
7008 int size = sizeof w->desired_matrix->method;
7009 int remaining = size - len - 1;
7011 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
7012 if (len && remaining)
7014 method[len] = '|';
7015 --remaining, ++len;
7018 strncpy (method + len, buffer, remaining);
7020 if (trace_redisplay_p)
7021 fprintf (stderr, "%p (%s): %s\n",
7023 ((BUFFERP (w->buffer)
7024 && STRINGP (XBUFFER (w->buffer)->name))
7025 ? (char *) XSTRING (XBUFFER (w->buffer)->name)->data
7026 : "no buffer"),
7027 buffer);
7030 #endif /* GLYPH_DEBUG */
7033 /* This counter is used to clear the face cache every once in a while
7034 in redisplay_internal. It is incremented for each redisplay.
7035 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
7036 cleared. */
7038 #define CLEAR_FACE_CACHE_COUNT 10000
7039 static int clear_face_cache_count;
7041 /* Record the previous terminal frame we displayed. */
7043 static struct frame *previous_terminal_frame;
7045 /* Non-zero while redisplay_internal is in progress. */
7047 int redisplaying_p;
7050 /* Value is non-zero if all changes in window W, which displays
7051 current_buffer, are in the text between START and END. START is a
7052 buffer position, END is given as a distance from Z. Used in
7053 redisplay_internal for display optimization. */
7055 static INLINE int
7056 text_outside_line_unchanged_p (w, start, end)
7057 struct window *w;
7058 int start, end;
7060 int unchanged_p = 1;
7062 /* If text or overlays have changed, see where. */
7063 if (XFASTINT (w->last_modified) < MODIFF
7064 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
7066 /* Gap in the line? */
7067 if (GPT < start || Z - GPT < end)
7068 unchanged_p = 0;
7070 /* Changes start in front of the line, or end after it? */
7071 if (unchanged_p
7072 && (BEG_UNCHANGED < start - 1
7073 || END_UNCHANGED < end))
7074 unchanged_p = 0;
7076 /* If selective display, can't optimize if changes start at the
7077 beginning of the line. */
7078 if (unchanged_p
7079 && INTEGERP (current_buffer->selective_display)
7080 && XINT (current_buffer->selective_display) > 0
7081 && (BEG_UNCHANGED < start || GPT <= start))
7082 unchanged_p = 0;
7085 return unchanged_p;
7089 /* Do a frame update, taking possible shortcuts into account. This is
7090 the main external entry point for redisplay.
7092 If the last redisplay displayed an echo area message and that message
7093 is no longer requested, we clear the echo area or bring back the
7094 mini-buffer if that is in use. */
7096 void
7097 redisplay ()
7099 redisplay_internal (0);
7102 /* Return 1 if point moved out of or into a composition. Otherwise
7103 return 0. PREV_BUF and PREV_PT are the last point buffer and
7104 position. BUF and PT are the current point buffer and position. */
7107 check_point_in_composition (prev_buf, prev_pt, buf, pt)
7108 struct buffer *prev_buf, *buf;
7109 int prev_pt, pt;
7111 int start, end;
7112 Lisp_Object prop;
7113 Lisp_Object buffer;
7115 XSETBUFFER (buffer, buf);
7116 /* Check a composition at the last point if point moved within the
7117 same buffer. */
7118 if (prev_buf == buf)
7120 if (prev_pt == pt)
7121 /* Point didn't move. */
7122 return 0;
7124 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
7125 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
7126 && COMPOSITION_VALID_P (start, end, prop)
7127 && start < prev_pt && end > prev_pt)
7128 /* The last point was within the composition. Return 1 iff
7129 point moved out of the composition. */
7130 return (pt <= start || pt >= end);
7133 /* Check a composition at the current point. */
7134 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
7135 && find_composition (pt, -1, &start, &end, &prop, buffer)
7136 && COMPOSITION_VALID_P (start, end, prop)
7137 && start < pt && end > pt);
7140 /* Reconsider the setting of B->clip_changed which is displayed
7141 in window W. */
7143 static INLINE void
7144 reconsider_clip_changes (w, b)
7145 struct window *w;
7146 struct buffer *b;
7148 if (b->prevent_redisplay_optimizations_p)
7149 b->clip_changed = 1;
7150 else if (b->clip_changed
7151 && !NILP (w->window_end_valid)
7152 && w->current_matrix->buffer == b
7153 && w->current_matrix->zv == BUF_ZV (b)
7154 && w->current_matrix->begv == BUF_BEGV (b))
7155 b->clip_changed = 0;
7157 /* If display wasn't paused, and W is not a tool bar window, see if
7158 point has been moved into or out of a composition. In that case,
7159 we set b->clip_changed to 1 to force updating the screen. If
7160 b->clip_changed has already been set to 1, we can skip this
7161 check. */
7162 if (!b->clip_changed
7163 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
7165 int pt;
7167 if (w == XWINDOW (selected_window))
7168 pt = BUF_PT (current_buffer);
7169 else
7170 pt = marker_position (w->pointm);
7172 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
7173 || pt != XINT (w->last_point))
7174 && check_point_in_composition (w->current_matrix->buffer,
7175 XINT (w->last_point),
7176 XBUFFER (w->buffer), pt))
7177 b->clip_changed = 1;
7182 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
7183 response to any user action; therefore, we should preserve the echo
7184 area. (Actually, our caller does that job.) Perhaps in the future
7185 avoid recentering windows if it is not necessary; currently that
7186 causes some problems. */
7188 static void
7189 redisplay_internal (preserve_echo_area)
7190 int preserve_echo_area;
7192 struct window *w = XWINDOW (selected_window);
7193 struct frame *f = XFRAME (w->frame);
7194 int pause;
7195 int must_finish = 0;
7196 struct text_pos tlbufpos, tlendpos;
7197 int number_of_visible_frames;
7198 int count;
7199 struct frame *sf = SELECTED_FRAME ();
7201 /* Non-zero means redisplay has to consider all windows on all
7202 frames. Zero means, only selected_window is considered. */
7203 int consider_all_windows_p;
7205 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
7207 /* No redisplay if running in batch mode or frame is not yet fully
7208 initialized, or redisplay is explicitly turned off by setting
7209 Vinhibit_redisplay. */
7210 if (noninteractive
7211 || !NILP (Vinhibit_redisplay)
7212 || !f->glyphs_initialized_p)
7213 return;
7215 /* The flag redisplay_performed_directly_p is set by
7216 direct_output_for_insert when it already did the whole screen
7217 update necessary. */
7218 if (redisplay_performed_directly_p)
7220 redisplay_performed_directly_p = 0;
7221 if (!hscroll_windows (selected_window))
7222 return;
7225 #ifdef USE_X_TOOLKIT
7226 if (popup_activated ())
7227 return;
7228 #endif
7230 /* I don't think this happens but let's be paranoid. */
7231 if (redisplaying_p)
7232 return;
7234 /* Record a function that resets redisplaying_p to its old value
7235 when we leave this function. */
7236 count = specpdl_ptr - specpdl;
7237 record_unwind_protect (unwind_redisplay, make_number (redisplaying_p));
7238 ++redisplaying_p;
7240 retry:
7242 reconsider_clip_changes (w, current_buffer);
7244 /* If new fonts have been loaded that make a glyph matrix adjustment
7245 necessary, do it. */
7246 if (fonts_changed_p)
7248 adjust_glyphs (NULL);
7249 ++windows_or_buffers_changed;
7250 fonts_changed_p = 0;
7253 if (! FRAME_WINDOW_P (sf)
7254 && previous_terminal_frame != sf)
7256 /* Since frames on an ASCII terminal share the same display
7257 area, displaying a different frame means redisplay the whole
7258 thing. */
7259 windows_or_buffers_changed++;
7260 SET_FRAME_GARBAGED (sf);
7261 XSETFRAME (Vterminal_frame, sf);
7263 previous_terminal_frame = sf;
7265 /* Set the visible flags for all frames. Do this before checking
7266 for resized or garbaged frames; they want to know if their frames
7267 are visible. See the comment in frame.h for
7268 FRAME_SAMPLE_VISIBILITY. */
7270 Lisp_Object tail, frame;
7272 number_of_visible_frames = 0;
7274 FOR_EACH_FRAME (tail, frame)
7276 struct frame *f = XFRAME (frame);
7278 FRAME_SAMPLE_VISIBILITY (f);
7279 if (FRAME_VISIBLE_P (f))
7280 ++number_of_visible_frames;
7281 clear_desired_matrices (f);
7285 /* Notice any pending interrupt request to change frame size. */
7286 do_pending_window_change (1);
7288 /* Clear frames marked as garbaged. */
7289 if (frame_garbaged)
7290 clear_garbaged_frames ();
7292 /* Build menubar and tool-bar items. */
7293 prepare_menu_bars ();
7295 if (windows_or_buffers_changed)
7296 update_mode_lines++;
7298 /* Detect case that we need to write or remove a star in the mode line. */
7299 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
7301 w->update_mode_line = Qt;
7302 if (buffer_shared > 1)
7303 update_mode_lines++;
7306 /* If %c is in the mode line, update it if needed. */
7307 if (!NILP (w->column_number_displayed)
7308 /* This alternative quickly identifies a common case
7309 where no change is needed. */
7310 && !(PT == XFASTINT (w->last_point)
7311 && XFASTINT (w->last_modified) >= MODIFF
7312 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
7313 && XFASTINT (w->column_number_displayed) != current_column ())
7314 w->update_mode_line = Qt;
7316 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
7318 /* The variable buffer_shared is set in redisplay_window and
7319 indicates that we redisplay a buffer in different windows. See
7320 there. */
7321 consider_all_windows_p = update_mode_lines || buffer_shared > 1;
7323 /* If specs for an arrow have changed, do thorough redisplay
7324 to ensure we remove any arrow that should no longer exist. */
7325 if (! EQ (COERCE_MARKER (Voverlay_arrow_position), last_arrow_position)
7326 || ! EQ (Voverlay_arrow_string, last_arrow_string))
7327 consider_all_windows_p = windows_or_buffers_changed = 1;
7329 /* Normally the message* functions will have already displayed and
7330 updated the echo area, but the frame may have been trashed, or
7331 the update may have been preempted, so display the echo area
7332 again here. Checking both message buffers captures the case that
7333 the echo area should be cleared. */
7334 if (!NILP (echo_area_buffer[0]) || !NILP (echo_area_buffer[1]))
7336 int window_height_changed_p = echo_area_display (0);
7337 must_finish = 1;
7339 if (fonts_changed_p)
7340 goto retry;
7341 else if (window_height_changed_p)
7343 consider_all_windows_p = 1;
7344 ++update_mode_lines;
7345 ++windows_or_buffers_changed;
7347 /* If window configuration was changed, frames may have been
7348 marked garbaged. Clear them or we will experience
7349 surprises wrt scrolling. */
7350 if (frame_garbaged)
7351 clear_garbaged_frames ();
7354 else if (w == XWINDOW (minibuf_window)
7355 && (current_buffer->clip_changed
7356 || XFASTINT (w->last_modified) < MODIFF
7357 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
7358 && resize_mini_window (w, 0))
7360 /* Resized active mini-window to fit the size of what it is
7361 showing if its contents might have changed. */
7362 must_finish = 1;
7363 consider_all_windows_p = 1;
7364 ++windows_or_buffers_changed;
7365 ++update_mode_lines;
7367 /* If window configuration was changed, frames may have been
7368 marked garbaged. Clear them or we will experience
7369 surprises wrt scrolling. */
7370 if (frame_garbaged)
7371 clear_garbaged_frames ();
7375 /* If showing the region, and mark has changed, we must redisplay
7376 the whole window. The assignment to this_line_start_pos prevents
7377 the optimization directly below this if-statement. */
7378 if (((!NILP (Vtransient_mark_mode)
7379 && !NILP (XBUFFER (w->buffer)->mark_active))
7380 != !NILP (w->region_showing))
7381 || (!NILP (w->region_showing)
7382 && !EQ (w->region_showing,
7383 Fmarker_position (XBUFFER (w->buffer)->mark))))
7384 CHARPOS (this_line_start_pos) = 0;
7386 /* Optimize the case that only the line containing the cursor in the
7387 selected window has changed. Variables starting with this_ are
7388 set in display_line and record information about the line
7389 containing the cursor. */
7390 tlbufpos = this_line_start_pos;
7391 tlendpos = this_line_end_pos;
7392 if (!consider_all_windows_p
7393 && CHARPOS (tlbufpos) > 0
7394 && NILP (w->update_mode_line)
7395 && !current_buffer->clip_changed
7396 && FRAME_VISIBLE_P (XFRAME (w->frame))
7397 && !FRAME_OBSCURED_P (XFRAME (w->frame))
7398 /* Make sure recorded data applies to current buffer, etc. */
7399 && this_line_buffer == current_buffer
7400 && current_buffer == XBUFFER (w->buffer)
7401 && NILP (w->force_start)
7402 /* Point must be on the line that we have info recorded about. */
7403 && PT >= CHARPOS (tlbufpos)
7404 && PT <= Z - CHARPOS (tlendpos)
7405 /* All text outside that line, including its final newline,
7406 must be unchanged */
7407 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
7408 CHARPOS (tlendpos)))
7410 if (CHARPOS (tlbufpos) > BEGV
7411 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
7412 && (CHARPOS (tlbufpos) == ZV
7413 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
7414 /* Former continuation line has disappeared by becoming empty */
7415 goto cancel;
7416 else if (XFASTINT (w->last_modified) < MODIFF
7417 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
7418 || MINI_WINDOW_P (w))
7420 /* We have to handle the case of continuation around a
7421 wide-column character (See the comment in indent.c around
7422 line 885).
7424 For instance, in the following case:
7426 -------- Insert --------
7427 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
7428 J_I_ ==> J_I_ `^^' are cursors.
7429 ^^ ^^
7430 -------- --------
7432 As we have to redraw the line above, we should goto cancel. */
7434 struct it it;
7435 int line_height_before = this_line_pixel_height;
7437 /* Note that start_display will handle the case that the
7438 line starting at tlbufpos is a continuation lines. */
7439 start_display (&it, w, tlbufpos);
7441 /* Implementation note: It this still necessary? */
7442 if (it.current_x != this_line_start_x)
7443 goto cancel;
7445 TRACE ((stderr, "trying display optimization 1\n"));
7446 w->cursor.vpos = -1;
7447 overlay_arrow_seen = 0;
7448 it.vpos = this_line_vpos;
7449 it.current_y = this_line_y;
7450 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
7451 display_line (&it);
7453 /* If line contains point, is not continued,
7454 and ends at same distance from eob as before, we win */
7455 if (w->cursor.vpos >= 0
7456 /* Line is not continued, otherwise this_line_start_pos
7457 would have been set to 0 in display_line. */
7458 && CHARPOS (this_line_start_pos)
7459 /* Line ends as before. */
7460 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
7461 /* Line has same height as before. Otherwise other lines
7462 would have to be shifted up or down. */
7463 && this_line_pixel_height == line_height_before)
7465 /* If this is not the window's last line, we must adjust
7466 the charstarts of the lines below. */
7467 if (it.current_y < it.last_visible_y)
7469 struct glyph_row *row
7470 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
7471 int delta, delta_bytes;
7473 if (Z - CHARPOS (tlendpos) == ZV)
7475 /* This line ends at end of (accessible part of)
7476 buffer. There is no newline to count. */
7477 delta = (Z
7478 - CHARPOS (tlendpos)
7479 - MATRIX_ROW_START_CHARPOS (row));
7480 delta_bytes = (Z_BYTE
7481 - BYTEPOS (tlendpos)
7482 - MATRIX_ROW_START_BYTEPOS (row));
7484 else
7486 /* This line ends in a newline. Must take
7487 account of the newline and the rest of the
7488 text that follows. */
7489 delta = (Z
7490 - CHARPOS (tlendpos)
7491 - MATRIX_ROW_START_CHARPOS (row));
7492 delta_bytes = (Z_BYTE
7493 - BYTEPOS (tlendpos)
7494 - MATRIX_ROW_START_BYTEPOS (row));
7497 increment_matrix_positions (w->current_matrix,
7498 this_line_vpos + 1,
7499 w->current_matrix->nrows,
7500 delta, delta_bytes);
7503 /* If this row displays text now but previously didn't,
7504 or vice versa, w->window_end_vpos may have to be
7505 adjusted. */
7506 if ((it.glyph_row - 1)->displays_text_p)
7508 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
7509 XSETINT (w->window_end_vpos, this_line_vpos);
7511 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
7512 && this_line_vpos > 0)
7513 XSETINT (w->window_end_vpos, this_line_vpos - 1);
7514 w->window_end_valid = Qnil;
7516 /* Update hint: No need to try to scroll in update_window. */
7517 w->desired_matrix->no_scrolling_p = 1;
7519 #if GLYPH_DEBUG
7520 *w->desired_matrix->method = 0;
7521 debug_method_add (w, "optimization 1");
7522 #endif
7523 goto update;
7525 else
7526 goto cancel;
7528 else if (/* Cursor position hasn't changed. */
7529 PT == XFASTINT (w->last_point)
7530 /* Make sure the cursor was last displayed
7531 in this window. Otherwise we have to reposition it. */
7532 && 0 <= w->cursor.vpos
7533 && XINT (w->height) > w->cursor.vpos)
7535 if (!must_finish)
7537 do_pending_window_change (1);
7539 /* We used to always goto end_of_redisplay here, but this
7540 isn't enough if we have a blinking cursor. */
7541 if (w->cursor_off_p == w->last_cursor_off_p)
7542 goto end_of_redisplay;
7544 goto update;
7546 /* If highlighting the region, or if the cursor is in the echo area,
7547 then we can't just move the cursor. */
7548 else if (! (!NILP (Vtransient_mark_mode)
7549 && !NILP (current_buffer->mark_active))
7550 && (w == XWINDOW (current_buffer->last_selected_window)
7551 || highlight_nonselected_windows)
7552 && NILP (w->region_showing)
7553 && NILP (Vshow_trailing_whitespace)
7554 && !cursor_in_echo_area)
7556 struct it it;
7557 struct glyph_row *row;
7559 /* Skip from tlbufpos to PT and see where it is. Note that
7560 PT may be in invisible text. If so, we will end at the
7561 next visible position. */
7562 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
7563 NULL, DEFAULT_FACE_ID);
7564 it.current_x = this_line_start_x;
7565 it.current_y = this_line_y;
7566 it.vpos = this_line_vpos;
7568 /* The call to move_it_to stops in front of PT, but
7569 moves over before-strings. */
7570 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
7572 if (it.vpos == this_line_vpos
7573 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
7574 row->enabled_p))
7576 xassert (this_line_vpos == it.vpos);
7577 xassert (this_line_y == it.current_y);
7578 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
7579 goto update;
7581 else
7582 goto cancel;
7585 cancel:
7586 /* Text changed drastically or point moved off of line. */
7587 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
7590 CHARPOS (this_line_start_pos) = 0;
7591 consider_all_windows_p |= buffer_shared > 1;
7592 ++clear_face_cache_count;
7595 /* Build desired matrices. If consider_all_windows_p is non-zero,
7596 do it for all windows on all frames. Otherwise do it for
7597 selected_window, only. */
7599 if (consider_all_windows_p)
7601 Lisp_Object tail, frame;
7603 /* Clear the face cache eventually. */
7604 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
7606 clear_face_cache (0);
7607 clear_face_cache_count = 0;
7610 /* Recompute # windows showing selected buffer. This will be
7611 incremented each time such a window is displayed. */
7612 buffer_shared = 0;
7614 FOR_EACH_FRAME (tail, frame)
7616 struct frame *f = XFRAME (frame);
7617 if (FRAME_WINDOW_P (f) || f == sf)
7619 /* Mark all the scroll bars to be removed; we'll redeem
7620 the ones we want when we redisplay their windows. */
7621 if (condemn_scroll_bars_hook)
7622 (*condemn_scroll_bars_hook) (f);
7624 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
7625 redisplay_windows (FRAME_ROOT_WINDOW (f));
7627 /* Any scroll bars which redisplay_windows should have
7628 nuked should now go away. */
7629 if (judge_scroll_bars_hook)
7630 (*judge_scroll_bars_hook) (f);
7634 else if (FRAME_VISIBLE_P (sf)
7635 && !FRAME_OBSCURED_P (sf))
7636 redisplay_window (selected_window, 1);
7639 /* Compare desired and current matrices, perform output. */
7641 update:
7643 /* If fonts changed, display again. */
7644 if (fonts_changed_p)
7645 goto retry;
7647 /* Prevent various kinds of signals during display update.
7648 stdio is not robust about handling signals,
7649 which can cause an apparent I/O error. */
7650 if (interrupt_input)
7651 unrequest_sigio ();
7652 stop_polling ();
7654 if (consider_all_windows_p)
7656 Lisp_Object tail;
7657 struct frame *f;
7658 int hscrolled_p;
7660 pause = 0;
7661 hscrolled_p = 0;
7663 /* See if we have to hscroll. */
7664 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
7665 if (FRAMEP (XCAR (tail)))
7667 f = XFRAME (XCAR (tail));
7669 if ((FRAME_WINDOW_P (f)
7670 || f == sf)
7671 && FRAME_VISIBLE_P (f)
7672 && !FRAME_OBSCURED_P (f)
7673 && hscroll_windows (f->root_window))
7674 hscrolled_p = 1;
7677 if (hscrolled_p)
7678 goto retry;
7680 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
7682 if (!FRAMEP (XCAR (tail)))
7683 continue;
7685 f = XFRAME (XCAR (tail));
7687 if ((FRAME_WINDOW_P (f) || f == sf)
7688 && FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
7690 /* Mark all windows as to be updated. */
7691 set_window_update_flags (XWINDOW (f->root_window), 1);
7692 pause |= update_frame (f, 0, 0);
7693 if (!pause)
7695 mark_window_display_accurate (f->root_window, 1);
7696 if (frame_up_to_date_hook != 0)
7697 (*frame_up_to_date_hook) (f);
7702 else
7704 if (FRAME_VISIBLE_P (sf)
7705 && !FRAME_OBSCURED_P (sf))
7707 if (hscroll_windows (selected_window))
7708 goto retry;
7710 XWINDOW (selected_window)->must_be_updated_p = 1;
7711 pause = update_frame (sf, 0, 0);
7713 else
7714 pause = 0;
7716 /* We may have called echo_area_display at the top of this
7717 function. If the echo area is on another frame, that may
7718 have put text on a frame other than the selected one, so the
7719 above call to update_frame would not have caught it. Catch
7720 it here. */
7722 Lisp_Object mini_window;
7723 struct frame *mini_frame;
7725 mini_window = FRAME_MINIBUF_WINDOW (sf);
7726 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7728 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
7730 XWINDOW (mini_window)->must_be_updated_p = 1;
7731 pause |= update_frame (mini_frame, 0, 0);
7732 if (!pause && hscroll_windows (mini_window))
7733 goto retry;
7738 /* If display was paused because of pending input, make sure we do a
7739 thorough update the next time. */
7740 if (pause)
7742 /* Prevent the optimization at the beginning of
7743 redisplay_internal that tries a single-line update of the
7744 line containing the cursor in the selected window. */
7745 CHARPOS (this_line_start_pos) = 0;
7747 /* Let the overlay arrow be updated the next time. */
7748 if (!NILP (last_arrow_position))
7750 last_arrow_position = Qt;
7751 last_arrow_string = Qt;
7754 /* If we pause after scrolling, some rows in the current
7755 matrices of some windows are not valid. */
7756 if (!WINDOW_FULL_WIDTH_P (w)
7757 && !FRAME_WINDOW_P (XFRAME (w->frame)))
7758 update_mode_lines = 1;
7761 /* Now text on frame agrees with windows, so put info into the
7762 windows for partial redisplay to follow. */
7763 if (!pause)
7765 register struct buffer *b = XBUFFER (w->buffer);
7767 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
7768 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
7769 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
7770 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
7772 if (consider_all_windows_p)
7773 mark_window_display_accurate (FRAME_ROOT_WINDOW (sf), 1);
7774 else
7776 XSETFASTINT (w->last_point, BUF_PT (b));
7777 w->last_cursor = w->cursor;
7778 w->last_cursor_off_p = w->cursor_off_p;
7780 b->clip_changed = 0;
7781 b->prevent_redisplay_optimizations_p = 0;
7782 w->update_mode_line = Qnil;
7783 XSETFASTINT (w->last_modified, BUF_MODIFF (b));
7784 XSETFASTINT (w->last_overlay_modified, BUF_OVERLAY_MODIFF (b));
7785 w->last_had_star
7786 = (BUF_MODIFF (XBUFFER (w->buffer)) > BUF_SAVE_MODIFF (XBUFFER (w->buffer))
7787 ? Qt : Qnil);
7789 /* Record if we are showing a region, so can make sure to
7790 update it fully at next redisplay. */
7791 w->region_showing = (!NILP (Vtransient_mark_mode)
7792 && (w == XWINDOW (current_buffer->last_selected_window)
7793 || highlight_nonselected_windows)
7794 && !NILP (XBUFFER (w->buffer)->mark_active)
7795 ? Fmarker_position (XBUFFER (w->buffer)->mark)
7796 : Qnil);
7798 w->window_end_valid = w->buffer;
7799 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
7800 last_arrow_string = Voverlay_arrow_string;
7801 if (frame_up_to_date_hook != 0)
7802 (*frame_up_to_date_hook) (sf);
7804 w->current_matrix->buffer = b;
7805 w->current_matrix->begv = BUF_BEGV (b);
7806 w->current_matrix->zv = BUF_ZV (b);
7809 update_mode_lines = 0;
7810 windows_or_buffers_changed = 0;
7813 /* Start SIGIO interrupts coming again. Having them off during the
7814 code above makes it less likely one will discard output, but not
7815 impossible, since there might be stuff in the system buffer here.
7816 But it is much hairier to try to do anything about that. */
7817 if (interrupt_input)
7818 request_sigio ();
7819 start_polling ();
7821 /* If a frame has become visible which was not before, redisplay
7822 again, so that we display it. Expose events for such a frame
7823 (which it gets when becoming visible) don't call the parts of
7824 redisplay constructing glyphs, so simply exposing a frame won't
7825 display anything in this case. So, we have to display these
7826 frames here explicitly. */
7827 if (!pause)
7829 Lisp_Object tail, frame;
7830 int new_count = 0;
7832 FOR_EACH_FRAME (tail, frame)
7834 int this_is_visible = 0;
7836 if (XFRAME (frame)->visible)
7837 this_is_visible = 1;
7838 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
7839 if (XFRAME (frame)->visible)
7840 this_is_visible = 1;
7842 if (this_is_visible)
7843 new_count++;
7846 if (new_count != number_of_visible_frames)
7847 windows_or_buffers_changed++;
7850 /* Change frame size now if a change is pending. */
7851 do_pending_window_change (1);
7853 /* If we just did a pending size change, or have additional
7854 visible frames, redisplay again. */
7855 if (windows_or_buffers_changed && !pause)
7856 goto retry;
7858 end_of_redisplay:;
7860 unbind_to (count, Qnil);
7864 /* Redisplay, but leave alone any recent echo area message unless
7865 another message has been requested in its place.
7867 This is useful in situations where you need to redisplay but no
7868 user action has occurred, making it inappropriate for the message
7869 area to be cleared. See tracking_off and
7870 wait_reading_process_input for examples of these situations. */
7872 void
7873 redisplay_preserve_echo_area ()
7875 if (!NILP (echo_area_buffer[1]))
7877 /* We have a previously displayed message, but no current
7878 message. Redisplay the previous message. */
7879 display_last_displayed_message_p = 1;
7880 redisplay_internal (1);
7881 display_last_displayed_message_p = 0;
7883 else
7884 redisplay_internal (1);
7888 /* Function registered with record_unwind_protect in
7889 redisplay_internal. Clears the flag indicating that a redisplay is
7890 in progress. */
7892 static Lisp_Object
7893 unwind_redisplay (old_redisplaying_p)
7894 Lisp_Object old_redisplaying_p;
7896 redisplaying_p = XFASTINT (old_redisplaying_p);
7897 return Qnil;
7901 /* Mark the display of windows in the window tree rooted at WINDOW as
7902 accurate or inaccurate. If FLAG is non-zero mark display of WINDOW
7903 as accurate. If FLAG is zero arrange for WINDOW to be redisplayed
7904 the next time redisplay_internal is called. */
7906 void
7907 mark_window_display_accurate (window, accurate_p)
7908 Lisp_Object window;
7909 int accurate_p;
7911 struct window *w;
7913 for (; !NILP (window); window = w->next)
7915 w = XWINDOW (window);
7917 if (BUFFERP (w->buffer))
7919 struct buffer *b = XBUFFER (w->buffer);
7921 XSETFASTINT (w->last_modified,
7922 accurate_p ? BUF_MODIFF (b) : 0);
7923 XSETFASTINT (w->last_overlay_modified,
7924 accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
7925 w->last_had_star = (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b)
7926 ? Qt : Qnil);
7928 #if 0 /* I don't think this is necessary because display_line does it.
7929 Let's check it. */
7930 /* Record if we are showing a region, so can make sure to
7931 update it fully at next redisplay. */
7932 w->region_showing
7933 = (!NILP (Vtransient_mark_mode)
7934 && (w == XWINDOW (current_buffer->last_selected_window)
7935 || highlight_nonselected_windows)
7936 && (!NILP (b->mark_active)
7937 ? Fmarker_position (b->mark)
7938 : Qnil));
7939 #endif
7941 if (accurate_p)
7943 b->clip_changed = 0;
7944 b->prevent_redisplay_optimizations_p = 0;
7945 w->current_matrix->buffer = b;
7946 w->current_matrix->begv = BUF_BEGV (b);
7947 w->current_matrix->zv = BUF_ZV (b);
7948 w->last_cursor = w->cursor;
7949 w->last_cursor_off_p = w->cursor_off_p;
7950 if (w == XWINDOW (selected_window))
7951 w->last_point = make_number (BUF_PT (b));
7952 else
7953 w->last_point = make_number (XMARKER (w->pointm)->charpos);
7957 w->window_end_valid = w->buffer;
7958 w->update_mode_line = Qnil;
7960 if (!NILP (w->vchild))
7961 mark_window_display_accurate (w->vchild, accurate_p);
7962 if (!NILP (w->hchild))
7963 mark_window_display_accurate (w->hchild, accurate_p);
7966 if (accurate_p)
7968 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
7969 last_arrow_string = Voverlay_arrow_string;
7971 else
7973 /* Force a thorough redisplay the next time by setting
7974 last_arrow_position and last_arrow_string to t, which is
7975 unequal to any useful value of Voverlay_arrow_... */
7976 last_arrow_position = Qt;
7977 last_arrow_string = Qt;
7982 /* Return value in display table DP (Lisp_Char_Table *) for character
7983 C. Since a display table doesn't have any parent, we don't have to
7984 follow parent. Do not call this function directly but use the
7985 macro DISP_CHAR_VECTOR. */
7987 Lisp_Object
7988 disp_char_vector (dp, c)
7989 struct Lisp_Char_Table *dp;
7990 int c;
7992 int code[4], i;
7993 Lisp_Object val;
7995 if (SINGLE_BYTE_CHAR_P (c))
7996 return (dp->contents[c]);
7998 SPLIT_CHAR (c, code[0], code[1], code[2]);
7999 if (code[1] < 32)
8000 code[1] = -1;
8001 else if (code[2] < 32)
8002 code[2] = -1;
8004 /* Here, the possible range of code[0] (== charset ID) is
8005 128..max_charset. Since the top level char table contains data
8006 for multibyte characters after 256th element, we must increment
8007 code[0] by 128 to get a correct index. */
8008 code[0] += 128;
8009 code[3] = -1; /* anchor */
8011 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
8013 val = dp->contents[code[i]];
8014 if (!SUB_CHAR_TABLE_P (val))
8015 return (NILP (val) ? dp->defalt : val);
8018 /* Here, val is a sub char table. We return the default value of
8019 it. */
8020 return (dp->defalt);
8025 /***********************************************************************
8026 Window Redisplay
8027 ***********************************************************************/
8029 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
8031 static void
8032 redisplay_windows (window)
8033 Lisp_Object window;
8035 while (!NILP (window))
8037 struct window *w = XWINDOW (window);
8039 if (!NILP (w->hchild))
8040 redisplay_windows (w->hchild);
8041 else if (!NILP (w->vchild))
8042 redisplay_windows (w->vchild);
8043 else
8044 redisplay_window (window, 0);
8046 window = w->next;
8051 /* Set cursor position of W. PT is assumed to be displayed in ROW.
8052 DELTA is the number of bytes by which positions recorded in ROW
8053 differ from current buffer positions. */
8055 void
8056 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
8057 struct window *w;
8058 struct glyph_row *row;
8059 struct glyph_matrix *matrix;
8060 int delta, delta_bytes, dy, dvpos;
8062 struct glyph *glyph = row->glyphs[TEXT_AREA];
8063 struct glyph *end = glyph + row->used[TEXT_AREA];
8064 int x = row->x;
8065 int pt_old = PT - delta;
8067 /* Skip over glyphs not having an object at the start of the row.
8068 These are special glyphs like truncation marks on terminal
8069 frames. */
8070 if (row->displays_text_p)
8071 while (glyph < end
8072 && INTEGERP (glyph->object)
8073 && glyph->charpos < 0)
8075 x += glyph->pixel_width;
8076 ++glyph;
8079 while (glyph < end
8080 && !INTEGERP (glyph->object)
8081 && (!BUFFERP (glyph->object)
8082 || glyph->charpos < pt_old))
8084 x += glyph->pixel_width;
8085 ++glyph;
8088 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
8089 w->cursor.x = x;
8090 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
8091 w->cursor.y = row->y + dy;
8093 if (w == XWINDOW (selected_window))
8095 if (!row->continued_p
8096 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
8097 && row->x == 0)
8099 this_line_buffer = XBUFFER (w->buffer);
8101 CHARPOS (this_line_start_pos)
8102 = MATRIX_ROW_START_CHARPOS (row) + delta;
8103 BYTEPOS (this_line_start_pos)
8104 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
8106 CHARPOS (this_line_end_pos)
8107 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
8108 BYTEPOS (this_line_end_pos)
8109 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
8111 this_line_y = w->cursor.y;
8112 this_line_pixel_height = row->height;
8113 this_line_vpos = w->cursor.vpos;
8114 this_line_start_x = row->x;
8116 else
8117 CHARPOS (this_line_start_pos) = 0;
8122 /* Run window scroll functions, if any, for WINDOW with new window
8123 start STARTP. Sets the window start of WINDOW to that position.
8125 We assume that the window's buffer is really current. */
8127 static INLINE struct text_pos
8128 run_window_scroll_functions (window, startp)
8129 Lisp_Object window;
8130 struct text_pos startp;
8132 struct window *w = XWINDOW (window);
8133 SET_MARKER_FROM_TEXT_POS (w->start, startp);
8135 if (current_buffer != XBUFFER (w->buffer))
8136 abort ();
8138 if (!NILP (Vwindow_scroll_functions))
8140 run_hook_with_args_2 (Qwindow_scroll_functions, window,
8141 make_number (CHARPOS (startp)));
8142 SET_TEXT_POS_FROM_MARKER (startp, w->start);
8143 /* In case the hook functions switch buffers. */
8144 if (current_buffer != XBUFFER (w->buffer))
8145 set_buffer_internal_1 (XBUFFER (w->buffer));
8148 return startp;
8152 /* Modify the desired matrix of window W and W->vscroll so that the
8153 line containing the cursor is fully visible. */
8155 static void
8156 make_cursor_line_fully_visible (w)
8157 struct window *w;
8159 struct glyph_matrix *matrix;
8160 struct glyph_row *row;
8161 int header_line_height;
8163 /* It's not always possible to find the cursor, e.g, when a window
8164 is full of overlay strings. Don't do anything in that case. */
8165 if (w->cursor.vpos < 0)
8166 return;
8168 matrix = w->desired_matrix;
8169 row = MATRIX_ROW (matrix, w->cursor.vpos);
8171 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row)
8172 /* The row may be partially visible at the top because we
8173 already have chosen a vscroll to align the bottom of the
8174 row with the bottom of the window. This happens for rows
8175 taller than the window. */
8176 && row->y + row->height < window_box_height (w))
8178 int dy = row->height - row->visible_height;
8179 w->vscroll = 0;
8180 w->cursor.y += dy;
8181 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
8183 else if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)
8184 /* The row may be partially visible at the bottom because
8185 we chose a vscroll to align the row's top with the
8186 window's top. This happens for rows taller than the
8187 window. */
8188 && row->y > WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w))
8190 int dy = - (row->height - row->visible_height);
8191 w->vscroll = dy;
8192 w->cursor.y += dy;
8193 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
8196 /* When we change the cursor y-position of the selected window,
8197 change this_line_y as well so that the display optimization for
8198 the cursor line of the selected window in redisplay_internal uses
8199 the correct y-position. */
8200 if (w == XWINDOW (selected_window))
8201 this_line_y = w->cursor.y;
8205 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
8206 non-zero means only WINDOW is redisplayed in redisplay_internal.
8207 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
8208 in redisplay_window to bring a partially visible line into view in
8209 the case that only the cursor has moved.
8211 Value is
8213 1 if scrolling succeeded
8215 0 if scrolling didn't find point.
8217 -1 if new fonts have been loaded so that we must interrupt
8218 redisplay, adjust glyph matrices, and try again. */
8220 static int
8221 try_scrolling (window, just_this_one_p, scroll_conservatively,
8222 scroll_step, temp_scroll_step)
8223 Lisp_Object window;
8224 int just_this_one_p;
8225 int scroll_conservatively, scroll_step;
8226 int temp_scroll_step;
8228 struct window *w = XWINDOW (window);
8229 struct frame *f = XFRAME (w->frame);
8230 struct text_pos scroll_margin_pos;
8231 struct text_pos pos;
8232 struct text_pos startp;
8233 struct it it;
8234 Lisp_Object window_end;
8235 int this_scroll_margin;
8236 int dy = 0;
8237 int scroll_max;
8238 int line_height, rc;
8239 int amount_to_scroll = 0;
8240 Lisp_Object aggressive;
8241 int height;
8243 #if GLYPH_DEBUG
8244 debug_method_add (w, "try_scrolling");
8245 #endif
8247 SET_TEXT_POS_FROM_MARKER (startp, w->start);
8249 /* Compute scroll margin height in pixels. We scroll when point is
8250 within this distance from the top or bottom of the window. */
8251 if (scroll_margin > 0)
8253 this_scroll_margin = min (scroll_margin, XINT (w->height) / 4);
8254 this_scroll_margin *= CANON_Y_UNIT (f);
8256 else
8257 this_scroll_margin = 0;
8259 /* Compute how much we should try to scroll maximally to bring point
8260 into view. */
8261 if (scroll_step)
8262 scroll_max = scroll_step;
8263 else if (scroll_conservatively)
8264 scroll_max = scroll_conservatively;
8265 else if (temp_scroll_step)
8266 scroll_max = temp_scroll_step;
8267 else if (NUMBERP (current_buffer->scroll_down_aggressively)
8268 || NUMBERP (current_buffer->scroll_up_aggressively))
8269 /* We're trying to scroll because of aggressive scrolling
8270 but no scroll_step is set. Choose an arbitrary one. Maybe
8271 there should be a variable for this. */
8272 scroll_max = 10;
8273 else
8274 scroll_max = 0;
8275 scroll_max *= CANON_Y_UNIT (f);
8277 /* Decide whether we have to scroll down. Start at the window end
8278 and move this_scroll_margin up to find the position of the scroll
8279 margin. */
8280 window_end = Fwindow_end (window, Qt);
8281 CHARPOS (scroll_margin_pos) = XINT (window_end);
8282 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
8283 if (this_scroll_margin)
8285 start_display (&it, w, scroll_margin_pos);
8286 move_it_vertically (&it, - this_scroll_margin);
8287 scroll_margin_pos = it.current.pos;
8290 if (PT >= CHARPOS (scroll_margin_pos))
8292 int y0;
8294 /* Point is in the scroll margin at the bottom of the window, or
8295 below. Compute a new window start that makes point visible. */
8297 /* Compute the distance from the scroll margin to PT.
8298 Give up if the distance is greater than scroll_max. */
8299 start_display (&it, w, scroll_margin_pos);
8300 y0 = it.current_y;
8301 move_it_to (&it, PT, 0, it.last_visible_y, -1,
8302 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
8303 line_height = (it.max_ascent + it.max_descent
8304 ? it.max_ascent + it.max_descent
8305 : last_height);
8306 dy = it.current_y + line_height - y0;
8307 if (dy > scroll_max)
8308 return 0;
8310 /* Move the window start down. If scrolling conservatively,
8311 move it just enough down to make point visible. If
8312 scroll_step is set, move it down by scroll_step. */
8313 start_display (&it, w, startp);
8315 if (scroll_conservatively)
8316 amount_to_scroll = dy;
8317 else if (scroll_step || temp_scroll_step)
8318 amount_to_scroll = scroll_max;
8319 else
8321 aggressive = current_buffer->scroll_down_aggressively;
8322 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
8323 - WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w));
8324 if (NUMBERP (aggressive))
8325 amount_to_scroll = XFLOATINT (aggressive) * height;
8328 if (amount_to_scroll <= 0)
8329 return 0;
8331 move_it_vertically (&it, amount_to_scroll);
8332 startp = it.current.pos;
8334 else
8336 /* See if point is inside the scroll margin at the top of the
8337 window. */
8338 scroll_margin_pos = startp;
8339 if (this_scroll_margin)
8341 start_display (&it, w, startp);
8342 move_it_vertically (&it, this_scroll_margin);
8343 scroll_margin_pos = it.current.pos;
8346 if (PT < CHARPOS (scroll_margin_pos))
8348 /* Point is in the scroll margin at the top of the window or
8349 above what is displayed in the window. */
8350 int y0;
8352 /* Compute the vertical distance from PT to the scroll
8353 margin position. Give up if distance is greater than
8354 scroll_max. */
8355 SET_TEXT_POS (pos, PT, PT_BYTE);
8356 start_display (&it, w, pos);
8357 y0 = it.current_y;
8358 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
8359 it.last_visible_y, -1,
8360 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
8361 dy = it.current_y - y0;
8362 if (dy > scroll_max)
8363 return 0;
8365 /* Compute new window start. */
8366 start_display (&it, w, startp);
8368 if (scroll_conservatively)
8369 amount_to_scroll = dy;
8370 else if (scroll_step || temp_scroll_step)
8371 amount_to_scroll = scroll_max;
8372 else
8374 aggressive = current_buffer->scroll_up_aggressively;
8375 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
8376 - WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w));
8377 if (NUMBERP (aggressive))
8378 amount_to_scroll = XFLOATINT (aggressive) * height;
8381 if (amount_to_scroll <= 0)
8382 return 0;
8384 move_it_vertically (&it, - amount_to_scroll);
8385 startp = it.current.pos;
8389 /* Run window scroll functions. */
8390 startp = run_window_scroll_functions (window, startp);
8392 /* Display the window. Give up if new fonts are loaded, or if point
8393 doesn't appear. */
8394 if (!try_window (window, startp))
8395 rc = -1;
8396 else if (w->cursor.vpos < 0)
8398 clear_glyph_matrix (w->desired_matrix);
8399 rc = 0;
8401 else
8403 /* Maybe forget recorded base line for line number display. */
8404 if (!just_this_one_p
8405 || current_buffer->clip_changed
8406 || BEG_UNCHANGED < CHARPOS (startp))
8407 w->base_line_number = Qnil;
8409 /* If cursor ends up on a partially visible line, shift display
8410 lines up or down. */
8411 make_cursor_line_fully_visible (w);
8412 rc = 1;
8415 return rc;
8419 /* Compute a suitable window start for window W if display of W starts
8420 on a continuation line. Value is non-zero if a new window start
8421 was computed.
8423 The new window start will be computed, based on W's width, starting
8424 from the start of the continued line. It is the start of the
8425 screen line with the minimum distance from the old start W->start. */
8427 static int
8428 compute_window_start_on_continuation_line (w)
8429 struct window *w;
8431 struct text_pos pos, start_pos;
8432 int window_start_changed_p = 0;
8434 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
8436 /* If window start is on a continuation line... Window start may be
8437 < BEGV in case there's invisible text at the start of the
8438 buffer (M-x rmail, for example). */
8439 if (CHARPOS (start_pos) > BEGV
8440 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
8442 struct it it;
8443 struct glyph_row *row;
8445 /* Handle the case that the window start is out of range. */
8446 if (CHARPOS (start_pos) < BEGV)
8447 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
8448 else if (CHARPOS (start_pos) > ZV)
8449 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
8451 /* Find the start of the continued line. This should be fast
8452 because scan_buffer is fast (newline cache). */
8453 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
8454 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
8455 row, DEFAULT_FACE_ID);
8456 reseat_at_previous_visible_line_start (&it);
8458 /* If the line start is "too far" away from the window start,
8459 say it takes too much time to compute a new window start. */
8460 if (CHARPOS (start_pos) - IT_CHARPOS (it)
8461 < XFASTINT (w->height) * XFASTINT (w->width))
8463 int min_distance, distance;
8465 /* Move forward by display lines to find the new window
8466 start. If window width was enlarged, the new start can
8467 be expected to be > the old start. If window width was
8468 decreased, the new window start will be < the old start.
8469 So, we're looking for the display line start with the
8470 minimum distance from the old window start. */
8471 pos = it.current.pos;
8472 min_distance = INFINITY;
8473 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
8474 distance < min_distance)
8476 min_distance = distance;
8477 pos = it.current.pos;
8478 move_it_by_lines (&it, 1, 0);
8481 /* Set the window start there. */
8482 SET_MARKER_FROM_TEXT_POS (w->start, pos);
8483 window_start_changed_p = 1;
8487 return window_start_changed_p;
8491 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
8492 selected_window is redisplayed. */
8494 static void
8495 redisplay_window (window, just_this_one_p)
8496 Lisp_Object window;
8497 int just_this_one_p;
8499 struct window *w = XWINDOW (window);
8500 struct frame *f = XFRAME (w->frame);
8501 struct buffer *buffer = XBUFFER (w->buffer);
8502 struct buffer *old = current_buffer;
8503 struct text_pos lpoint, opoint, startp;
8504 int update_mode_line;
8505 int tem;
8506 struct it it;
8507 /* Record it now because it's overwritten. */
8508 int current_matrix_up_to_date_p = 0;
8509 int temp_scroll_step = 0;
8510 int count = specpdl_ptr - specpdl;
8512 SET_TEXT_POS (lpoint, PT, PT_BYTE);
8513 opoint = lpoint;
8515 /* W must be a leaf window here. */
8516 xassert (!NILP (w->buffer));
8517 #if GLYPH_DEBUG
8518 *w->desired_matrix->method = 0;
8519 #endif
8521 specbind (Qinhibit_point_motion_hooks, Qt);
8523 reconsider_clip_changes (w, buffer);
8525 /* Has the mode line to be updated? */
8526 update_mode_line = (!NILP (w->update_mode_line)
8527 || update_mode_lines
8528 || buffer->clip_changed);
8530 if (MINI_WINDOW_P (w))
8532 if (w == XWINDOW (echo_area_window)
8533 && !NILP (echo_area_buffer[0]))
8535 if (update_mode_line)
8536 /* We may have to update a tty frame's menu bar or a
8537 tool-bar. Example `M-x C-h C-h C-g'. */
8538 goto finish_menu_bars;
8539 else
8540 /* We've already displayed the echo area glyphs in this window. */
8541 goto finish_scroll_bars;
8543 else if (w != XWINDOW (minibuf_window))
8545 /* W is a mini-buffer window, but it's not the currently
8546 active one, so clear it. */
8547 int yb = window_text_bottom_y (w);
8548 struct glyph_row *row;
8549 int y;
8551 for (y = 0, row = w->desired_matrix->rows;
8552 y < yb;
8553 y += row->height, ++row)
8554 blank_row (w, row, y);
8555 goto finish_scroll_bars;
8559 /* Otherwise set up data on this window; select its buffer and point
8560 value. */
8561 /* Really select the buffer, for the sake of buffer-local
8562 variables. */
8563 set_buffer_internal_1 (XBUFFER (w->buffer));
8564 SET_TEXT_POS (opoint, PT, PT_BYTE);
8566 current_matrix_up_to_date_p
8567 = (!NILP (w->window_end_valid)
8568 && !current_buffer->clip_changed
8569 && XFASTINT (w->last_modified) >= MODIFF
8570 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
8572 /* When windows_or_buffers_changed is non-zero, we can't rely on
8573 the window end being valid, so set it to nil there. */
8574 if (windows_or_buffers_changed)
8576 /* If window starts on a continuation line, maybe adjust the
8577 window start in case the window's width changed. */
8578 if (XMARKER (w->start)->buffer == current_buffer)
8579 compute_window_start_on_continuation_line (w);
8581 w->window_end_valid = Qnil;
8584 /* Some sanity checks. */
8585 CHECK_WINDOW_END (w);
8586 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
8587 abort ();
8588 if (BYTEPOS (opoint) < CHARPOS (opoint))
8589 abort ();
8591 /* If %c is in mode line, update it if needed. */
8592 if (!NILP (w->column_number_displayed)
8593 /* This alternative quickly identifies a common case
8594 where no change is needed. */
8595 && !(PT == XFASTINT (w->last_point)
8596 && XFASTINT (w->last_modified) >= MODIFF
8597 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
8598 && XFASTINT (w->column_number_displayed) != current_column ())
8599 update_mode_line = 1;
8601 /* Count number of windows showing the selected buffer. An indirect
8602 buffer counts as its base buffer. */
8603 if (!just_this_one_p)
8605 struct buffer *current_base, *window_base;
8606 current_base = current_buffer;
8607 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
8608 if (current_base->base_buffer)
8609 current_base = current_base->base_buffer;
8610 if (window_base->base_buffer)
8611 window_base = window_base->base_buffer;
8612 if (current_base == window_base)
8613 buffer_shared++;
8616 /* Point refers normally to the selected window. For any other
8617 window, set up appropriate value. */
8618 if (!EQ (window, selected_window))
8620 int new_pt = XMARKER (w->pointm)->charpos;
8621 int new_pt_byte = marker_byte_position (w->pointm);
8622 if (new_pt < BEGV)
8624 new_pt = BEGV;
8625 new_pt_byte = BEGV_BYTE;
8626 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
8628 else if (new_pt > (ZV - 1))
8630 new_pt = ZV;
8631 new_pt_byte = ZV_BYTE;
8632 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
8635 /* We don't use SET_PT so that the point-motion hooks don't run. */
8636 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
8639 /* If any of the character widths specified in the display table
8640 have changed, invalidate the width run cache. It's true that
8641 this may be a bit late to catch such changes, but the rest of
8642 redisplay goes (non-fatally) haywire when the display table is
8643 changed, so why should we worry about doing any better? */
8644 if (current_buffer->width_run_cache)
8646 struct Lisp_Char_Table *disptab = buffer_display_table ();
8648 if (! disptab_matches_widthtab (disptab,
8649 XVECTOR (current_buffer->width_table)))
8651 invalidate_region_cache (current_buffer,
8652 current_buffer->width_run_cache,
8653 BEG, Z);
8654 recompute_width_table (current_buffer, disptab);
8658 /* If window-start is screwed up, choose a new one. */
8659 if (XMARKER (w->start)->buffer != current_buffer)
8660 goto recenter;
8662 SET_TEXT_POS_FROM_MARKER (startp, w->start);
8664 /* If someone specified a new starting point but did not insist,
8665 check whether it can be used. */
8666 if (!NILP (w->optional_new_start)
8667 && CHARPOS (startp) >= BEGV
8668 && CHARPOS (startp) <= ZV)
8670 w->optional_new_start = Qnil;
8671 /* This takes a mini-buffer prompt into account. */
8672 start_display (&it, w, startp);
8673 move_it_to (&it, PT, 0, it.last_visible_y, -1,
8674 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
8675 if (IT_CHARPOS (it) == PT)
8676 w->force_start = Qt;
8679 /* Handle case where place to start displaying has been specified,
8680 unless the specified location is outside the accessible range. */
8681 if (!NILP (w->force_start)
8682 || w->frozen_window_start_p)
8684 w->force_start = Qnil;
8685 w->vscroll = 0;
8686 w->window_end_valid = Qnil;
8688 /* Forget any recorded base line for line number display. */
8689 if (!current_matrix_up_to_date_p
8690 || current_buffer->clip_changed)
8691 w->base_line_number = Qnil;
8693 /* Redisplay the mode line. Select the buffer properly for that.
8694 Also, run the hook window-scroll-functions
8695 because we have scrolled. */
8696 /* Note, we do this after clearing force_start because
8697 if there's an error, it is better to forget about force_start
8698 than to get into an infinite loop calling the hook functions
8699 and having them get more errors. */
8700 if (!update_mode_line
8701 || ! NILP (Vwindow_scroll_functions))
8703 update_mode_line = 1;
8704 w->update_mode_line = Qt;
8705 startp = run_window_scroll_functions (window, startp);
8708 XSETFASTINT (w->last_modified, 0);
8709 XSETFASTINT (w->last_overlay_modified, 0);
8710 if (CHARPOS (startp) < BEGV)
8711 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
8712 else if (CHARPOS (startp) > ZV)
8713 SET_TEXT_POS (startp, ZV, ZV_BYTE);
8715 /* Redisplay, then check if cursor has been set during the
8716 redisplay. Give up if new fonts were loaded. */
8717 if (!try_window (window, startp))
8719 w->force_start = Qt;
8720 clear_glyph_matrix (w->desired_matrix);
8721 goto restore_buffers;
8724 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
8726 /* If point does not appear, or on a line that is not fully
8727 visible, move point so it does appear. The desired
8728 matrix has been built above, so we can use it. */
8729 int height = window_box_height (w) / 2;
8730 struct glyph_row *row = MATRIX_ROW (w->desired_matrix, 0);
8732 while (row->y < height)
8733 ++row;
8735 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
8736 MATRIX_ROW_START_BYTEPOS (row));
8738 if (w != XWINDOW (selected_window))
8739 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
8740 else if (current_buffer == old)
8741 SET_TEXT_POS (lpoint, PT, PT_BYTE);
8743 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
8745 /* If we are highlighting the region, then we just changed
8746 the region, so redisplay to show it. */
8747 if (!NILP (Vtransient_mark_mode)
8748 && !NILP (current_buffer->mark_active))
8750 clear_glyph_matrix (w->desired_matrix);
8751 if (!try_window (window, startp))
8752 goto restore_buffers;
8756 make_cursor_line_fully_visible (w);
8757 #if GLYPH_DEBUG
8758 debug_method_add (w, "forced window start");
8759 #endif
8760 goto done;
8763 /* Handle case where text has not changed, only point, and it has
8764 not moved off the frame. */
8765 if (current_matrix_up_to_date_p
8766 /* Point may be in this window. */
8767 && PT >= CHARPOS (startp)
8768 /* If we don't check this, we are called to move the cursor in a
8769 horizontally split window with a current matrix that doesn't
8770 fit the display. */
8771 && !windows_or_buffers_changed
8772 /* Selective display hasn't changed. */
8773 && !current_buffer->clip_changed
8774 /* If force-mode-line-update was called, really redisplay;
8775 that's how redisplay is forced after e.g. changing
8776 buffer-invisibility-spec. */
8777 && NILP (w->update_mode_line)
8778 /* Can't use this case if highlighting a region. When a
8779 region exists, cursor movement has to do more than just
8780 set the cursor. */
8781 && !(!NILP (Vtransient_mark_mode)
8782 && !NILP (current_buffer->mark_active))
8783 && NILP (w->region_showing)
8784 && NILP (Vshow_trailing_whitespace)
8785 /* Right after splitting windows, last_point may be nil. */
8786 && INTEGERP (w->last_point)
8787 /* This code is not used for mini-buffer for the sake of the case
8788 of redisplaying to replace an echo area message; since in
8789 that case the mini-buffer contents per se are usually
8790 unchanged. This code is of no real use in the mini-buffer
8791 since the handling of this_line_start_pos, etc., in redisplay
8792 handles the same cases. */
8793 && !EQ (window, minibuf_window)
8794 /* When splitting windows or for new windows, it happens that
8795 redisplay is called with a nil window_end_vpos or one being
8796 larger than the window. This should really be fixed in
8797 window.c. I don't have this on my list, now, so we do
8798 approximately the same as the old redisplay code. --gerd. */
8799 && INTEGERP (w->window_end_vpos)
8800 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
8801 && (FRAME_WINDOW_P (f)
8802 || !MARKERP (Voverlay_arrow_position)
8803 || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
8805 int this_scroll_margin;
8806 struct glyph_row *row;
8807 int scroll_p;
8809 #if GLYPH_DEBUG
8810 debug_method_add (w, "cursor movement");
8811 #endif
8813 /* Scroll if point within this distance from the top or bottom
8814 of the window. This is a pixel value. */
8815 this_scroll_margin = max (0, scroll_margin);
8816 this_scroll_margin = min (this_scroll_margin, XFASTINT (w->height) / 4);
8817 this_scroll_margin *= CANON_Y_UNIT (f);
8819 /* Start with the row the cursor was displayed during the last
8820 not paused redisplay. Give up if that row is not valid. */
8821 if (w->last_cursor.vpos >= w->current_matrix->nrows)
8822 goto try_to_scroll;
8823 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
8824 if (row->mode_line_p)
8825 ++row;
8826 if (!row->enabled_p)
8827 goto try_to_scroll;
8829 scroll_p = 0;
8830 if (PT > XFASTINT (w->last_point))
8832 /* Point has moved forward. */
8833 int last_y = window_text_bottom_y (w) - this_scroll_margin;
8835 while (MATRIX_ROW_END_CHARPOS (row) < PT
8836 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
8838 xassert (row->enabled_p);
8839 ++row;
8842 /* The end position of a row equals the start position of
8843 the next row. If PT is there, we would rather display it
8844 in the next line. Exceptions are when the row ends in
8845 the middle of a character, or ends in ZV. */
8846 if (MATRIX_ROW_BOTTOM_Y (row) < last_y
8847 && MATRIX_ROW_END_CHARPOS (row) == PT
8848 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
8849 && !row->ends_at_zv_p)
8851 xassert (row->enabled_p);
8852 ++row;
8855 /* If within the scroll margin, scroll. Note that
8856 MATRIX_ROW_BOTTOM_Y gives the pixel position at which the
8857 next line would be drawn, and that this_scroll_margin can
8858 be zero. */
8859 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
8860 || PT > MATRIX_ROW_END_CHARPOS (row)
8861 /* Line is completely visible last line in window and PT
8862 is to be set in the next line. */
8863 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
8864 && PT == MATRIX_ROW_END_CHARPOS (row)
8865 && !row->ends_at_zv_p
8866 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
8867 scroll_p = 1;
8869 else if (PT < XFASTINT (w->last_point))
8871 /* Cursor has to be moved backward. Note that PT >=
8872 CHARPOS (startp) because of the outer if-statement. */
8873 while (!row->mode_line_p
8874 && (MATRIX_ROW_START_CHARPOS (row) > PT
8875 || (MATRIX_ROW_START_CHARPOS (row) == PT
8876 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
8877 && (row->y > this_scroll_margin
8878 || CHARPOS (startp) == BEGV))
8880 xassert (row->enabled_p);
8881 --row;
8884 /* Consider the following case: Window starts at BEGV, there
8885 is invisible, intangible text at BEGV, so that display
8886 starts at some point START > BEGV. It can happen that
8887 we are called with PT somewhere between BEGV and START.
8888 Try to handle that case. */
8889 if (row < w->current_matrix->rows
8890 || row->mode_line_p)
8892 row = w->current_matrix->rows;
8893 if (row->mode_line_p)
8894 ++row;
8897 /* Due to newlines in overlay strings, we may have to skip
8898 forward over overlay strings. */
8899 while (MATRIX_ROW_END_CHARPOS (row) == PT
8900 && MATRIX_ROW_ENDS_IN_OVERLAY_STRING_P (row)
8901 && !row->ends_at_zv_p)
8902 ++row;
8904 /* If within the scroll margin, scroll. */
8905 if (row->y < this_scroll_margin
8906 && CHARPOS (startp) != BEGV)
8907 scroll_p = 1;
8910 /* if PT is not in the glyph row, give up. */
8911 if (PT < MATRIX_ROW_START_CHARPOS (row)
8912 || PT > MATRIX_ROW_END_CHARPOS (row))
8913 goto try_to_scroll;
8915 /* If we end up in a partially visible line, let's make it fully
8916 visible. This can be done most easily by using the existing
8917 scrolling code. */
8918 if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
8920 temp_scroll_step = 1;
8921 goto try_to_scroll;
8923 else if (scroll_p)
8924 goto try_to_scroll;
8926 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
8927 goto done;
8930 /* If current starting point was originally the beginning of a line
8931 but no longer is, find a new starting point. */
8932 else if (!NILP (w->start_at_line_beg)
8933 && !(CHARPOS (startp) <= BEGV
8934 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
8936 #if GLYPH_DEBUG
8937 debug_method_add (w, "recenter 1");
8938 #endif
8939 goto recenter;
8942 /* Try scrolling with try_window_id. */
8943 else if (/* Windows and buffers haven't changed. */
8944 !windows_or_buffers_changed
8945 /* Window must be either use window-based redisplay or
8946 be full width. */
8947 && (FRAME_WINDOW_P (f)
8948 || (line_ins_del_ok && WINDOW_FULL_WIDTH_P (w)))
8949 && !MINI_WINDOW_P (w)
8950 /* Point is not known NOT to appear in window. */
8951 && PT >= CHARPOS (startp)
8952 && XFASTINT (w->last_modified)
8953 /* Window is not hscrolled. */
8954 && XFASTINT (w->hscroll) == 0
8955 /* Selective display has not changed. */
8956 && !current_buffer->clip_changed
8957 /* Current matrix is up to date. */
8958 && !NILP (w->window_end_valid)
8959 /* Can't use this case if highlighting a region because
8960 a cursor movement will do more than just set the cursor. */
8961 && !(!NILP (Vtransient_mark_mode)
8962 && !NILP (current_buffer->mark_active))
8963 && NILP (w->region_showing)
8964 && NILP (Vshow_trailing_whitespace)
8965 /* Overlay arrow position and string not changed. */
8966 && EQ (last_arrow_position, COERCE_MARKER (Voverlay_arrow_position))
8967 && EQ (last_arrow_string, Voverlay_arrow_string)
8968 /* Value is > 0 if update has been done, it is -1 if we
8969 know that the same window start will not work. It is 0
8970 if unsuccessful for some other reason. */
8971 && (tem = try_window_id (w)) != 0)
8973 #if GLYPH_DEBUG
8974 debug_method_add (w, "try_window_id");
8975 #endif
8977 if (fonts_changed_p)
8978 goto restore_buffers;
8979 if (tem > 0)
8980 goto done;
8981 /* Otherwise try_window_id has returned -1 which means that we
8982 don't want the alternative below this comment to execute. */
8984 else if (CHARPOS (startp) >= BEGV
8985 && CHARPOS (startp) <= ZV
8986 && PT >= CHARPOS (startp)
8987 && (CHARPOS (startp) < ZV
8988 /* Avoid starting at end of buffer. */
8989 || CHARPOS (startp) == BEGV
8990 || (XFASTINT (w->last_modified) >= MODIFF
8991 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
8993 #if GLYPH_DEBUG
8994 debug_method_add (w, "same window start");
8995 #endif
8997 /* Try to redisplay starting at same place as before.
8998 If point has not moved off frame, accept the results. */
8999 if (!current_matrix_up_to_date_p
9000 /* Don't use try_window_reusing_current_matrix in this case
9001 because a window scroll function can have changed the
9002 buffer. */
9003 || !NILP (Vwindow_scroll_functions)
9004 || MINI_WINDOW_P (w)
9005 || !try_window_reusing_current_matrix (w))
9007 IF_DEBUG (debug_method_add (w, "1"));
9008 try_window (window, startp);
9011 if (fonts_changed_p)
9012 goto restore_buffers;
9014 if (w->cursor.vpos >= 0)
9016 if (!just_this_one_p
9017 || current_buffer->clip_changed
9018 || BEG_UNCHANGED < CHARPOS (startp))
9019 /* Forget any recorded base line for line number display. */
9020 w->base_line_number = Qnil;
9022 make_cursor_line_fully_visible (w);
9023 goto done;
9025 else
9026 clear_glyph_matrix (w->desired_matrix);
9029 try_to_scroll:
9031 XSETFASTINT (w->last_modified, 0);
9032 XSETFASTINT (w->last_overlay_modified, 0);
9034 /* Redisplay the mode line. Select the buffer properly for that. */
9035 if (!update_mode_line)
9037 update_mode_line = 1;
9038 w->update_mode_line = Qt;
9041 /* Try to scroll by specified few lines. */
9042 if ((scroll_conservatively
9043 || scroll_step
9044 || temp_scroll_step
9045 || NUMBERP (current_buffer->scroll_up_aggressively)
9046 || NUMBERP (current_buffer->scroll_down_aggressively))
9047 && !current_buffer->clip_changed
9048 && CHARPOS (startp) >= BEGV
9049 && CHARPOS (startp) <= ZV)
9051 /* The function returns -1 if new fonts were loaded, 1 if
9052 successful, 0 if not successful. */
9053 int rc = try_scrolling (window, just_this_one_p,
9054 scroll_conservatively,
9055 scroll_step,
9056 temp_scroll_step);
9057 if (rc > 0)
9058 goto done;
9059 else if (rc < 0)
9060 goto restore_buffers;
9063 /* Finally, just choose place to start which centers point */
9065 recenter:
9067 #if GLYPH_DEBUG
9068 debug_method_add (w, "recenter");
9069 #endif
9071 /* w->vscroll = 0; */
9073 /* Forget any previously recorded base line for line number display. */
9074 if (!current_matrix_up_to_date_p
9075 || current_buffer->clip_changed)
9076 w->base_line_number = Qnil;
9078 /* Move backward half the height of the window. */
9079 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
9080 it.current_y = it.last_visible_y;
9081 move_it_vertically_backward (&it, it.last_visible_y / 2);
9082 xassert (IT_CHARPOS (it) >= BEGV);
9084 /* The function move_it_vertically_backward may move over more
9085 than the specified y-distance. If it->w is small, e.g. a
9086 mini-buffer window, we may end up in front of the window's
9087 display area. Start displaying at the start of the line
9088 containing PT in this case. */
9089 if (it.current_y <= 0)
9091 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
9092 move_it_vertically (&it, 0);
9093 xassert (IT_CHARPOS (it) <= PT);
9094 it.current_y = 0;
9097 it.current_x = it.hpos = 0;
9099 /* Set startp here explicitly in case that helps avoid an infinite loop
9100 in case the window-scroll-functions functions get errors. */
9101 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
9103 /* Run scroll hooks. */
9104 startp = run_window_scroll_functions (window, it.current.pos);
9106 /* Redisplay the window. */
9107 if (!current_matrix_up_to_date_p
9108 || windows_or_buffers_changed
9109 /* Don't use try_window_reusing_current_matrix in this case
9110 because it can have changed the buffer. */
9111 || !NILP (Vwindow_scroll_functions)
9112 || !just_this_one_p
9113 || MINI_WINDOW_P (w)
9114 || !try_window_reusing_current_matrix (w))
9115 try_window (window, startp);
9117 /* If new fonts have been loaded (due to fontsets), give up. We
9118 have to start a new redisplay since we need to re-adjust glyph
9119 matrices. */
9120 if (fonts_changed_p)
9121 goto restore_buffers;
9123 /* If cursor did not appear assume that the middle of the window is
9124 in the first line of the window. Do it again with the next line.
9125 (Imagine a window of height 100, displaying two lines of height
9126 60. Moving back 50 from it->last_visible_y will end in the first
9127 line.) */
9128 if (w->cursor.vpos < 0)
9130 if (!NILP (w->window_end_valid)
9131 && PT >= Z - XFASTINT (w->window_end_pos))
9133 clear_glyph_matrix (w->desired_matrix);
9134 move_it_by_lines (&it, 1, 0);
9135 try_window (window, it.current.pos);
9137 else if (PT < IT_CHARPOS (it))
9139 clear_glyph_matrix (w->desired_matrix);
9140 move_it_by_lines (&it, -1, 0);
9141 try_window (window, it.current.pos);
9143 else
9145 /* Not much we can do about it. */
9149 /* Consider the following case: Window starts at BEGV, there is
9150 invisible, intangible text at BEGV, so that display starts at
9151 some point START > BEGV. It can happen that we are called with
9152 PT somewhere between BEGV and START. Try to handle that case. */
9153 if (w->cursor.vpos < 0)
9155 struct glyph_row *row = w->current_matrix->rows;
9156 if (row->mode_line_p)
9157 ++row;
9158 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
9161 make_cursor_line_fully_visible (w);
9163 done:
9165 SET_TEXT_POS_FROM_MARKER (startp, w->start);
9166 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
9167 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
9168 ? Qt : Qnil);
9170 /* Display the mode line, if we must. */
9171 if ((update_mode_line
9172 /* If window not full width, must redo its mode line
9173 if (a) the window to its side is being redone and
9174 (b) we do a frame-based redisplay. This is a consequence
9175 of how inverted lines are drawn in frame-based redisplay. */
9176 || (!just_this_one_p
9177 && !FRAME_WINDOW_P (f)
9178 && !WINDOW_FULL_WIDTH_P (w))
9179 /* Line number to display. */
9180 || INTEGERP (w->base_line_pos)
9181 /* Column number is displayed and different from the one displayed. */
9182 || (!NILP (w->column_number_displayed)
9183 && XFASTINT (w->column_number_displayed) != current_column ()))
9184 /* This means that the window has a mode line. */
9185 && (WINDOW_WANTS_MODELINE_P (w)
9186 || WINDOW_WANTS_HEADER_LINE_P (w)))
9188 Lisp_Object old_selected_frame;
9190 old_selected_frame = selected_frame;
9192 XSETFRAME (selected_frame, f);
9193 display_mode_lines (w);
9194 selected_frame = old_selected_frame;
9196 /* If mode line height has changed, arrange for a thorough
9197 immediate redisplay using the correct mode line height. */
9198 if (WINDOW_WANTS_MODELINE_P (w)
9199 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
9201 fonts_changed_p = 1;
9202 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
9203 = DESIRED_MODE_LINE_HEIGHT (w);
9206 /* If top line height has changed, arrange for a thorough
9207 immediate redisplay using the correct mode line height. */
9208 if (WINDOW_WANTS_HEADER_LINE_P (w)
9209 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
9211 fonts_changed_p = 1;
9212 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
9213 = DESIRED_HEADER_LINE_HEIGHT (w);
9216 if (fonts_changed_p)
9217 goto restore_buffers;
9220 if (!line_number_displayed
9221 && !BUFFERP (w->base_line_pos))
9223 w->base_line_pos = Qnil;
9224 w->base_line_number = Qnil;
9227 finish_menu_bars:
9229 /* When we reach a frame's selected window, redo the frame's menu bar. */
9230 if (update_mode_line
9231 && EQ (FRAME_SELECTED_WINDOW (f), window))
9233 int redisplay_menu_p = 0;
9235 if (FRAME_WINDOW_P (f))
9237 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
9238 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
9239 #else
9240 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
9241 #endif
9243 else
9244 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
9246 if (redisplay_menu_p)
9247 display_menu_bar (w);
9249 #ifdef HAVE_WINDOW_SYSTEM
9250 if (WINDOWP (f->tool_bar_window)
9251 && (FRAME_TOOL_BAR_LINES (f) > 0
9252 || auto_resize_tool_bars_p))
9253 redisplay_tool_bar (f);
9254 #endif
9257 finish_scroll_bars:
9259 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
9261 int start, end, whole;
9263 /* Calculate the start and end positions for the current window.
9264 At some point, it would be nice to choose between scrollbars
9265 which reflect the whole buffer size, with special markers
9266 indicating narrowing, and scrollbars which reflect only the
9267 visible region.
9269 Note that mini-buffers sometimes aren't displaying any text. */
9270 if (!MINI_WINDOW_P (w)
9271 || (w == XWINDOW (minibuf_window)
9272 && NILP (echo_area_buffer[0])))
9274 whole = ZV - BEGV;
9275 start = marker_position (w->start) - BEGV;
9276 /* I don't think this is guaranteed to be right. For the
9277 moment, we'll pretend it is. */
9278 end = (Z - XFASTINT (w->window_end_pos)) - BEGV;
9280 if (end < start)
9281 end = start;
9282 if (whole < (end - start))
9283 whole = end - start;
9285 else
9286 start = end = whole = 0;
9288 /* Indicate what this scroll bar ought to be displaying now. */
9289 (*set_vertical_scroll_bar_hook) (w, end - start, whole, start);
9291 /* Note that we actually used the scroll bar attached to this
9292 window, so it shouldn't be deleted at the end of redisplay. */
9293 (*redeem_scroll_bar_hook) (w);
9296 restore_buffers:
9298 /* Restore current_buffer and value of point in it. */
9299 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
9300 set_buffer_internal_1 (old);
9301 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
9303 unbind_to (count, Qnil);
9307 /* Build the complete desired matrix of WINDOW with a window start
9308 buffer position POS. Value is non-zero if successful. It is zero
9309 if fonts were loaded during redisplay which makes re-adjusting
9310 glyph matrices necessary. */
9313 try_window (window, pos)
9314 Lisp_Object window;
9315 struct text_pos pos;
9317 struct window *w = XWINDOW (window);
9318 struct it it;
9319 struct glyph_row *last_text_row = NULL;
9321 /* Make POS the new window start. */
9322 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
9324 /* Mark cursor position as unknown. No overlay arrow seen. */
9325 w->cursor.vpos = -1;
9326 overlay_arrow_seen = 0;
9328 /* Initialize iterator and info to start at POS. */
9329 start_display (&it, w, pos);
9331 /* Display all lines of W. */
9332 while (it.current_y < it.last_visible_y)
9334 if (display_line (&it))
9335 last_text_row = it.glyph_row - 1;
9336 if (fonts_changed_p)
9337 return 0;
9340 /* If bottom moved off end of frame, change mode line percentage. */
9341 if (XFASTINT (w->window_end_pos) <= 0
9342 && Z != IT_CHARPOS (it))
9343 w->update_mode_line = Qt;
9345 /* Set window_end_pos to the offset of the last character displayed
9346 on the window from the end of current_buffer. Set
9347 window_end_vpos to its row number. */
9348 if (last_text_row)
9350 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
9351 w->window_end_bytepos
9352 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9353 XSETFASTINT (w->window_end_pos,
9354 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9355 XSETFASTINT (w->window_end_vpos,
9356 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
9357 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
9358 ->displays_text_p);
9360 else
9362 w->window_end_bytepos = 0;
9363 XSETFASTINT (w->window_end_pos, 0);
9364 XSETFASTINT (w->window_end_vpos, 0);
9367 /* But that is not valid info until redisplay finishes. */
9368 w->window_end_valid = Qnil;
9369 return 1;
9374 /************************************************************************
9375 Window redisplay reusing current matrix when buffer has not changed
9376 ************************************************************************/
9378 /* Try redisplay of window W showing an unchanged buffer with a
9379 different window start than the last time it was displayed by
9380 reusing its current matrix. Value is non-zero if successful.
9381 W->start is the new window start. */
9383 static int
9384 try_window_reusing_current_matrix (w)
9385 struct window *w;
9387 struct frame *f = XFRAME (w->frame);
9388 struct glyph_row *row, *bottom_row;
9389 struct it it;
9390 struct run run;
9391 struct text_pos start, new_start;
9392 int nrows_scrolled, i;
9393 struct glyph_row *last_text_row;
9394 struct glyph_row *last_reused_text_row;
9395 struct glyph_row *start_row;
9396 int start_vpos, min_y, max_y;
9398 /* Right now this function doesn't handle terminal frames. */
9399 if (!FRAME_WINDOW_P (f))
9400 return 0;
9402 /* Can't do this if region may have changed. */
9403 if ((!NILP (Vtransient_mark_mode)
9404 && !NILP (current_buffer->mark_active))
9405 || !NILP (w->region_showing)
9406 || !NILP (Vshow_trailing_whitespace))
9407 return 0;
9409 /* If top-line visibility has changed, give up. */
9410 if (WINDOW_WANTS_HEADER_LINE_P (w)
9411 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
9412 return 0;
9414 /* Give up if old or new display is scrolled vertically. We could
9415 make this function handle this, but right now it doesn't. */
9416 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9417 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
9418 return 0;
9420 /* The variable new_start now holds the new window start. The old
9421 start `start' can be determined from the current matrix. */
9422 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
9423 start = start_row->start.pos;
9424 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
9426 /* Clear the desired matrix for the display below. */
9427 clear_glyph_matrix (w->desired_matrix);
9429 if (CHARPOS (new_start) <= CHARPOS (start))
9431 int first_row_y;
9433 IF_DEBUG (debug_method_add (w, "twu1"));
9435 /* Display up to a row that can be reused. The variable
9436 last_text_row is set to the last row displayed that displays
9437 text. */
9438 start_display (&it, w, new_start);
9439 first_row_y = it.current_y;
9440 w->cursor.vpos = -1;
9441 last_text_row = last_reused_text_row = NULL;
9442 while (it.current_y < it.last_visible_y
9443 && IT_CHARPOS (it) < CHARPOS (start)
9444 && !fonts_changed_p)
9445 if (display_line (&it))
9446 last_text_row = it.glyph_row - 1;
9448 /* A value of current_y < last_visible_y means that we stopped
9449 at the previous window start, which in turn means that we
9450 have at least one reusable row. */
9451 if (it.current_y < it.last_visible_y)
9453 nrows_scrolled = it.vpos;
9455 /* Find PT if not already found in the lines displayed. */
9456 if (w->cursor.vpos < 0)
9458 int dy = it.current_y - first_row_y;
9460 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9461 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9463 if (PT >= MATRIX_ROW_START_CHARPOS (row)
9464 && PT < MATRIX_ROW_END_CHARPOS (row))
9466 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
9467 dy, nrows_scrolled);
9468 break;
9471 if (MATRIX_ROW_BOTTOM_Y (row) + dy >= it.last_visible_y)
9472 break;
9474 ++row;
9477 /* Give up if point was not found. This shouldn't
9478 happen often; not more often than with try_window
9479 itself. */
9480 if (w->cursor.vpos < 0)
9482 clear_glyph_matrix (w->desired_matrix);
9483 return 0;
9487 /* Scroll the display. Do it before the current matrix is
9488 changed. The problem here is that update has not yet
9489 run, i.e. part of the current matrix is not up to date.
9490 scroll_run_hook will clear the cursor, and use the
9491 current matrix to get the height of the row the cursor is
9492 in. */
9493 run.current_y = first_row_y;
9494 run.desired_y = it.current_y;
9495 run.height = it.last_visible_y - it.current_y;
9496 if (run.height > 0
9497 && run.current_y != run.desired_y)
9499 update_begin (f);
9500 rif->update_window_begin_hook (w);
9501 rif->scroll_run_hook (w, &run);
9502 rif->update_window_end_hook (w, 0);
9503 update_end (f);
9506 /* Shift current matrix down by nrows_scrolled lines. */
9507 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
9508 rotate_matrix (w->current_matrix,
9509 start_vpos,
9510 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
9511 nrows_scrolled);
9513 /* Disable lines not reused. */
9514 for (i = 0; i < it.vpos; ++i)
9515 MATRIX_ROW (w->current_matrix, i)->enabled_p = 0;
9517 /* Re-compute Y positions. */
9518 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix) + nrows_scrolled;
9519 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
9520 max_y = it.last_visible_y;
9521 while (row < bottom_row)
9523 row->y = it.current_y;
9525 if (row->y < min_y)
9526 row->visible_height = row->height - (min_y - row->y);
9527 else if (row->y + row->height > max_y)
9528 row->visible_height
9529 = row->height - (row->y + row->height - max_y);
9530 else
9531 row->visible_height = row->height;
9533 it.current_y += row->height;
9534 ++it.vpos;
9536 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9537 last_reused_text_row = row;
9538 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
9539 break;
9540 ++row;
9544 /* Update window_end_pos etc.; last_reused_text_row is the last
9545 reused row from the current matrix containing text, if any.
9546 The value of last_text_row is the last displayed line
9547 containing text. */
9548 if (last_reused_text_row)
9550 w->window_end_bytepos
9551 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
9552 XSETFASTINT (w->window_end_pos,
9553 Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
9554 XSETFASTINT (w->window_end_vpos,
9555 MATRIX_ROW_VPOS (last_reused_text_row,
9556 w->current_matrix));
9558 else if (last_text_row)
9560 w->window_end_bytepos
9561 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9562 XSETFASTINT (w->window_end_pos,
9563 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9564 XSETFASTINT (w->window_end_vpos,
9565 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
9567 else
9569 /* This window must be completely empty. */
9570 w->window_end_bytepos = 0;
9571 XSETFASTINT (w->window_end_pos, 0);
9572 XSETFASTINT (w->window_end_vpos, 0);
9574 w->window_end_valid = Qnil;
9576 /* Update hint: don't try scrolling again in update_window. */
9577 w->desired_matrix->no_scrolling_p = 1;
9579 #if GLYPH_DEBUG
9580 debug_method_add (w, "try_window_reusing_current_matrix 1");
9581 #endif
9582 return 1;
9584 else if (CHARPOS (new_start) > CHARPOS (start))
9586 struct glyph_row *pt_row, *row;
9587 struct glyph_row *first_reusable_row;
9588 struct glyph_row *first_row_to_display;
9589 int dy;
9590 int yb = window_text_bottom_y (w);
9592 IF_DEBUG (debug_method_add (w, "twu2"));
9594 /* Find the row starting at new_start, if there is one. Don't
9595 reuse a partially visible line at the end. */
9596 first_reusable_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9597 while (first_reusable_row->enabled_p
9598 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
9599 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
9600 < CHARPOS (new_start)))
9601 ++first_reusable_row;
9603 /* Give up if there is no row to reuse. */
9604 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
9605 || !first_reusable_row->enabled_p
9606 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
9607 != CHARPOS (new_start)))
9608 return 0;
9610 /* We can reuse fully visible rows beginning with
9611 first_reusable_row to the end of the window. Set
9612 first_row_to_display to the first row that cannot be reused.
9613 Set pt_row to the row containing point, if there is any. */
9614 first_row_to_display = first_reusable_row;
9615 pt_row = NULL;
9616 while (MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb)
9618 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
9619 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
9620 pt_row = first_row_to_display;
9622 ++first_row_to_display;
9625 /* Start displaying at the start of first_row_to_display. */
9626 xassert (first_row_to_display->y < yb);
9627 init_to_row_start (&it, w, first_row_to_display);
9628 nrows_scrolled = MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix);
9629 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
9630 - nrows_scrolled);
9631 it.current_y = first_row_to_display->y - first_reusable_row->y;
9633 /* Display lines beginning with first_row_to_display in the
9634 desired matrix. Set last_text_row to the last row displayed
9635 that displays text. */
9636 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
9637 if (pt_row == NULL)
9638 w->cursor.vpos = -1;
9639 last_text_row = NULL;
9640 while (it.current_y < it.last_visible_y && !fonts_changed_p)
9641 if (display_line (&it))
9642 last_text_row = it.glyph_row - 1;
9644 /* Give up If point isn't in a row displayed or reused. */
9645 if (w->cursor.vpos < 0)
9647 clear_glyph_matrix (w->desired_matrix);
9648 return 0;
9651 /* If point is in a reused row, adjust y and vpos of the cursor
9652 position. */
9653 if (pt_row)
9655 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
9656 w->current_matrix);
9657 w->cursor.y -= first_reusable_row->y;
9660 /* Scroll the display. */
9661 run.current_y = first_reusable_row->y;
9662 run.desired_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
9663 run.height = it.last_visible_y - run.current_y;
9664 if (run.height)
9666 struct frame *f = XFRAME (WINDOW_FRAME (w));
9667 update_begin (f);
9668 rif->update_window_begin_hook (w);
9669 rif->scroll_run_hook (w, &run);
9670 rif->update_window_end_hook (w, 0);
9671 update_end (f);
9674 /* Adjust Y positions of reused rows. */
9675 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
9676 row = first_reusable_row;
9677 dy = first_reusable_row->y;
9678 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
9679 max_y = it.last_visible_y;
9680 while (row < first_row_to_display)
9682 row->y -= dy;
9683 if (row->y < min_y)
9684 row->visible_height = row->height - (min_y - row->y);
9685 else if (row->y + row->height > max_y)
9686 row->visible_height
9687 = row->height - (row->y + row->height - max_y);
9688 else
9689 row->visible_height = row->height;
9690 ++row;
9693 /* Disable rows not reused. */
9694 while (row < bottom_row)
9696 row->enabled_p = 0;
9697 ++row;
9700 /* Scroll the current matrix. */
9701 xassert (nrows_scrolled > 0);
9702 rotate_matrix (w->current_matrix,
9703 start_vpos,
9704 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
9705 -nrows_scrolled);
9707 /* Adjust window end. A null value of last_text_row means that
9708 the window end is in reused rows which in turn means that
9709 only its vpos can have changed. */
9710 if (last_text_row)
9712 w->window_end_bytepos
9713 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9714 XSETFASTINT (w->window_end_pos,
9715 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9716 XSETFASTINT (w->window_end_vpos,
9717 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
9719 else
9721 XSETFASTINT (w->window_end_vpos,
9722 XFASTINT (w->window_end_vpos) - nrows_scrolled);
9725 w->window_end_valid = Qnil;
9726 w->desired_matrix->no_scrolling_p = 1;
9728 #if GLYPH_DEBUG
9729 debug_method_add (w, "try_window_reusing_current_matrix 2");
9730 #endif
9731 return 1;
9734 return 0;
9739 /************************************************************************
9740 Window redisplay reusing current matrix when buffer has changed
9741 ************************************************************************/
9743 static struct glyph_row *get_last_unchanged_at_beg_row P_ ((struct window *));
9744 static struct glyph_row *get_first_unchanged_at_end_row P_ ((struct window *,
9745 int *, int *));
9746 static struct glyph_row *
9747 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
9748 struct glyph_row *));
9751 /* Return the last row in MATRIX displaying text. If row START is
9752 non-null, start searching with that row. IT gives the dimensions
9753 of the display. Value is null if matrix is empty; otherwise it is
9754 a pointer to the row found. */
9756 static struct glyph_row *
9757 find_last_row_displaying_text (matrix, it, start)
9758 struct glyph_matrix *matrix;
9759 struct it *it;
9760 struct glyph_row *start;
9762 struct glyph_row *row, *row_found;
9764 /* Set row_found to the last row in IT->w's current matrix
9765 displaying text. The loop looks funny but think of partially
9766 visible lines. */
9767 row_found = NULL;
9768 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
9769 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9771 xassert (row->enabled_p);
9772 row_found = row;
9773 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
9774 break;
9775 ++row;
9778 return row_found;
9782 /* Return the last row in the current matrix of W that is not affected
9783 by changes at the start of current_buffer that occurred since the
9784 last time W was redisplayed. Value is null if no such row exists.
9786 The global variable beg_unchanged has to contain the number of
9787 bytes unchanged at the start of current_buffer. BEG +
9788 beg_unchanged is the buffer position of the first changed byte in
9789 current_buffer. Characters at positions < BEG + beg_unchanged are
9790 at the same buffer positions as they were when the current matrix
9791 was built. */
9793 static struct glyph_row *
9794 get_last_unchanged_at_beg_row (w)
9795 struct window *w;
9797 int first_changed_pos = BEG + BEG_UNCHANGED;
9798 struct glyph_row *row;
9799 struct glyph_row *row_found = NULL;
9800 int yb = window_text_bottom_y (w);
9802 /* Find the last row displaying unchanged text. */
9803 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9804 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
9805 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
9807 if (/* If row ends before first_changed_pos, it is unchanged,
9808 except in some case. */
9809 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
9810 /* When row ends in ZV and we write at ZV it is not
9811 unchanged. */
9812 && !row->ends_at_zv_p
9813 /* When first_changed_pos is the end of a continued line,
9814 row is not unchanged because it may be no longer
9815 continued. */
9816 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
9817 && row->continued_p))
9818 row_found = row;
9820 /* Stop if last visible row. */
9821 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
9822 break;
9824 ++row;
9827 return row_found;
9831 /* Find the first glyph row in the current matrix of W that is not
9832 affected by changes at the end of current_buffer since the last
9833 time the window was redisplayed. Return in *DELTA the number of
9834 chars by which buffer positions in unchanged text at the end of
9835 current_buffer must be adjusted. Return in *DELTA_BYTES the
9836 corresponding number of bytes. Value is null if no such row
9837 exists, i.e. all rows are affected by changes. */
9839 static struct glyph_row *
9840 get_first_unchanged_at_end_row (w, delta, delta_bytes)
9841 struct window *w;
9842 int *delta, *delta_bytes;
9844 struct glyph_row *row;
9845 struct glyph_row *row_found = NULL;
9847 *delta = *delta_bytes = 0;
9849 /* A value of window_end_pos >= end_unchanged means that the window
9850 end is in the range of changed text. If so, there is no
9851 unchanged row at the end of W's current matrix. */
9852 xassert (!NILP (w->window_end_valid));
9853 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
9854 return NULL;
9856 /* Set row to the last row in W's current matrix displaying text. */
9857 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
9859 /* If matrix is entirely empty, no unchanged row exists. */
9860 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9862 /* The value of row is the last glyph row in the matrix having a
9863 meaningful buffer position in it. The end position of row
9864 corresponds to window_end_pos. This allows us to translate
9865 buffer positions in the current matrix to current buffer
9866 positions for characters not in changed text. */
9867 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
9868 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
9869 int last_unchanged_pos, last_unchanged_pos_old;
9870 struct glyph_row *first_text_row
9871 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9873 *delta = Z - Z_old;
9874 *delta_bytes = Z_BYTE - Z_BYTE_old;
9876 /* Set last_unchanged_pos to the buffer position of the last
9877 character in the buffer that has not been changed. Z is the
9878 index + 1 of the last byte in current_buffer, i.e. by
9879 subtracting end_unchanged we get the index of the last
9880 unchanged character, and we have to add BEG to get its buffer
9881 position. */
9882 last_unchanged_pos = Z - END_UNCHANGED + BEG;
9883 last_unchanged_pos_old = last_unchanged_pos - *delta;
9885 /* Search backward from ROW for a row displaying a line that
9886 starts at a minimum position >= last_unchanged_pos_old. */
9887 while (row >= first_text_row)
9889 xassert (row->enabled_p);
9890 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (row));
9892 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
9893 row_found = row;
9894 --row;
9898 xassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
9899 return row_found;
9903 /* Make sure that glyph rows in the current matrix of window W
9904 reference the same glyph memory as corresponding rows in the
9905 frame's frame matrix. This function is called after scrolling W's
9906 current matrix on a terminal frame in try_window_id and
9907 try_window_reusing_current_matrix. */
9909 static void
9910 sync_frame_with_window_matrix_rows (w)
9911 struct window *w;
9913 struct frame *f = XFRAME (w->frame);
9914 struct glyph_row *window_row, *window_row_end, *frame_row;
9916 /* Preconditions: W must be a leaf window and full-width. Its frame
9917 must have a frame matrix. */
9918 xassert (NILP (w->hchild) && NILP (w->vchild));
9919 xassert (WINDOW_FULL_WIDTH_P (w));
9920 xassert (!FRAME_WINDOW_P (f));
9922 /* If W is a full-width window, glyph pointers in W's current matrix
9923 have, by definition, to be the same as glyph pointers in the
9924 corresponding frame matrix. */
9925 window_row = w->current_matrix->rows;
9926 window_row_end = window_row + w->current_matrix->nrows;
9927 frame_row = f->current_matrix->rows + XFASTINT (w->top);
9928 while (window_row < window_row_end)
9930 int area;
9932 for (area = LEFT_MARGIN_AREA; area <= LAST_AREA; ++area)
9933 frame_row->glyphs[area] = window_row->glyphs[area];
9935 /* Disable frame rows whose corresponding window rows have
9936 been disabled in try_window_id. */
9937 if (!window_row->enabled_p)
9938 frame_row->enabled_p = 0;
9940 ++window_row, ++frame_row;
9945 /* Find the glyph row in window W containing CHARPOS. Consider all
9946 rows between START and END (not inclusive). END null means search
9947 all rows to the end of the display area of W. Value is the row
9948 containing CHARPOS or null. */
9950 static struct glyph_row *
9951 row_containing_pos (w, charpos, start, end)
9952 struct window *w;
9953 int charpos;
9954 struct glyph_row *start, *end;
9956 struct glyph_row *row = start;
9957 int last_y;
9959 /* If we happen to start on a header-line, skip that. */
9960 if (row->mode_line_p)
9961 ++row;
9963 if ((end && row >= end) || !row->enabled_p)
9964 return NULL;
9966 last_y = window_text_bottom_y (w);
9968 while ((end == NULL || row < end)
9969 && (MATRIX_ROW_END_CHARPOS (row) < charpos
9970 /* The end position of a row equals the start
9971 position of the next row. If CHARPOS is there, we
9972 would rather display it in the next line, except
9973 when this line ends in ZV. */
9974 || (MATRIX_ROW_END_CHARPOS (row) == charpos
9975 && (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
9976 || !row->ends_at_zv_p)))
9977 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
9978 ++row;
9980 /* Give up if CHARPOS not found. */
9981 if ((end && row >= end)
9982 || charpos < MATRIX_ROW_START_CHARPOS (row)
9983 || charpos > MATRIX_ROW_END_CHARPOS (row))
9984 row = NULL;
9986 return row;
9990 /* Try to redisplay window W by reusing its existing display. W's
9991 current matrix must be up to date when this function is called,
9992 i.e. window_end_valid must not be nil.
9994 Value is
9996 1 if display has been updated
9997 0 if otherwise unsuccessful
9998 -1 if redisplay with same window start is known not to succeed
10000 The following steps are performed:
10002 1. Find the last row in the current matrix of W that is not
10003 affected by changes at the start of current_buffer. If no such row
10004 is found, give up.
10006 2. Find the first row in W's current matrix that is not affected by
10007 changes at the end of current_buffer. Maybe there is no such row.
10009 3. Display lines beginning with the row + 1 found in step 1 to the
10010 row found in step 2 or, if step 2 didn't find a row, to the end of
10011 the window.
10013 4. If cursor is not known to appear on the window, give up.
10015 5. If display stopped at the row found in step 2, scroll the
10016 display and current matrix as needed.
10018 6. Maybe display some lines at the end of W, if we must. This can
10019 happen under various circumstances, like a partially visible line
10020 becoming fully visible, or because newly displayed lines are displayed
10021 in smaller font sizes.
10023 7. Update W's window end information. */
10025 /* Check that window end is what we expect it to be. */
10027 static int
10028 try_window_id (w)
10029 struct window *w;
10031 struct frame *f = XFRAME (w->frame);
10032 struct glyph_matrix *current_matrix = w->current_matrix;
10033 struct glyph_matrix *desired_matrix = w->desired_matrix;
10034 struct glyph_row *last_unchanged_at_beg_row;
10035 struct glyph_row *first_unchanged_at_end_row;
10036 struct glyph_row *row;
10037 struct glyph_row *bottom_row;
10038 int bottom_vpos;
10039 struct it it;
10040 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
10041 struct text_pos start_pos;
10042 struct run run;
10043 int first_unchanged_at_end_vpos = 0;
10044 struct glyph_row *last_text_row, *last_text_row_at_end;
10045 struct text_pos start;
10047 SET_TEXT_POS_FROM_MARKER (start, w->start);
10049 /* Check pre-conditions. Window end must be valid, otherwise
10050 the current matrix would not be up to date. */
10051 xassert (!NILP (w->window_end_valid));
10052 xassert (FRAME_WINDOW_P (XFRAME (w->frame))
10053 || (line_ins_del_ok && WINDOW_FULL_WIDTH_P (w)));
10055 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
10056 only if buffer has really changed. The reason is that the gap is
10057 initially at Z for freshly visited files. The code below would
10058 set end_unchanged to 0 in that case. */
10059 if (MODIFF > SAVE_MODIFF
10060 /* This seems to happen sometimes after saving a buffer. */
10061 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
10063 if (GPT - BEG < BEG_UNCHANGED)
10064 BEG_UNCHANGED = GPT - BEG;
10065 if (Z - GPT < END_UNCHANGED)
10066 END_UNCHANGED = Z - GPT;
10069 /* If window starts after a line end, and the last change is in
10070 front of that newline, then changes don't affect the display.
10071 This case happens with stealth-fontification. Note that although
10072 the display is unchanged, glyph positions in the matrix have to
10073 be adjusted, of course. */
10074 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
10075 if (CHARPOS (start) > BEGV
10076 && Z - END_UNCHANGED < CHARPOS (start) - 1
10077 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n'
10078 && PT < MATRIX_ROW_END_CHARPOS (row))
10080 struct glyph_row *r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
10081 int delta = CHARPOS (start) - MATRIX_ROW_START_CHARPOS (r0);
10083 if (delta)
10085 struct glyph_row *r1 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
10086 int delta_bytes = BYTEPOS (start) - MATRIX_ROW_START_BYTEPOS (r0);
10088 increment_matrix_positions (w->current_matrix,
10089 MATRIX_ROW_VPOS (r0, current_matrix),
10090 MATRIX_ROW_VPOS (r1, current_matrix),
10091 delta, delta_bytes);
10094 #if 0 /* If changes are all in front of the window start, the
10095 distance of the last displayed glyph from Z hasn't
10096 changed. */
10097 w->window_end_pos
10098 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
10099 w->window_end_bytepos
10100 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
10101 #endif
10103 return 1;
10106 /* Return quickly if changes are all below what is displayed in the
10107 window, and if PT is in the window. */
10108 if (BEG_UNCHANGED > MATRIX_ROW_END_CHARPOS (row)
10109 && PT < MATRIX_ROW_END_CHARPOS (row))
10111 /* We have to update window end positions because the buffer's
10112 size has changed. */
10113 w->window_end_pos
10114 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
10115 w->window_end_bytepos
10116 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
10117 return 1;
10120 /* Check that window start agrees with the start of the first glyph
10121 row in its current matrix. Check this after we know the window
10122 start is not in changed text, otherwise positions would not be
10123 comparable. */
10124 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
10125 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
10126 return 0;
10128 /* Compute the position at which we have to start displaying new
10129 lines. Some of the lines at the top of the window might be
10130 reusable because they are not displaying changed text. Find the
10131 last row in W's current matrix not affected by changes at the
10132 start of current_buffer. Value is null if changes start in the
10133 first line of window. */
10134 last_unchanged_at_beg_row = get_last_unchanged_at_beg_row (w);
10135 if (last_unchanged_at_beg_row)
10137 init_to_row_end (&it, w, last_unchanged_at_beg_row);
10138 start_pos = it.current.pos;
10140 /* Start displaying new lines in the desired matrix at the same
10141 vpos we would use in the current matrix, i.e. below
10142 last_unchanged_at_beg_row. */
10143 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
10144 current_matrix);
10145 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
10146 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
10148 xassert (it.hpos == 0 && it.current_x == 0);
10150 else
10152 /* There are no reusable lines at the start of the window.
10153 Start displaying in the first line. */
10154 start_display (&it, w, start);
10155 start_pos = it.current.pos;
10158 /* Find the first row that is not affected by changes at the end of
10159 the buffer. Value will be null if there is no unchanged row, in
10160 which case we must redisplay to the end of the window. delta
10161 will be set to the value by which buffer positions beginning with
10162 first_unchanged_at_end_row have to be adjusted due to text
10163 changes. */
10164 first_unchanged_at_end_row
10165 = get_first_unchanged_at_end_row (w, &delta, &delta_bytes);
10166 IF_DEBUG (debug_delta = delta);
10167 IF_DEBUG (debug_delta_bytes = delta_bytes);
10169 /* Set stop_pos to the buffer position up to which we will have to
10170 display new lines. If first_unchanged_at_end_row != NULL, this
10171 is the buffer position of the start of the line displayed in that
10172 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
10173 that we don't stop at a buffer position. */
10174 stop_pos = 0;
10175 if (first_unchanged_at_end_row)
10177 xassert (last_unchanged_at_beg_row == NULL
10178 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
10180 /* If this is a continuation line, move forward to the next one
10181 that isn't. Changes in lines above affect this line.
10182 Caution: this may move first_unchanged_at_end_row to a row
10183 not displaying text. */
10184 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
10185 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
10186 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
10187 < it.last_visible_y))
10188 ++first_unchanged_at_end_row;
10190 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
10191 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
10192 >= it.last_visible_y))
10193 first_unchanged_at_end_row = NULL;
10194 else
10196 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
10197 + delta);
10198 first_unchanged_at_end_vpos
10199 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
10200 xassert (stop_pos >= Z - END_UNCHANGED);
10203 else if (last_unchanged_at_beg_row == NULL)
10204 return 0;
10207 #if GLYPH_DEBUG
10209 /* Either there is no unchanged row at the end, or the one we have
10210 now displays text. This is a necessary condition for the window
10211 end pos calculation at the end of this function. */
10212 xassert (first_unchanged_at_end_row == NULL
10213 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
10215 debug_last_unchanged_at_beg_vpos
10216 = (last_unchanged_at_beg_row
10217 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
10218 : -1);
10219 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
10221 #endif /* GLYPH_DEBUG != 0 */
10224 /* Display new lines. Set last_text_row to the last new line
10225 displayed which has text on it, i.e. might end up as being the
10226 line where the window_end_vpos is. */
10227 w->cursor.vpos = -1;
10228 last_text_row = NULL;
10229 overlay_arrow_seen = 0;
10230 while (it.current_y < it.last_visible_y
10231 && !fonts_changed_p
10232 && (first_unchanged_at_end_row == NULL
10233 || IT_CHARPOS (it) < stop_pos))
10235 if (display_line (&it))
10236 last_text_row = it.glyph_row - 1;
10239 if (fonts_changed_p)
10240 return -1;
10243 /* Compute differences in buffer positions, y-positions etc. for
10244 lines reused at the bottom of the window. Compute what we can
10245 scroll. */
10246 if (first_unchanged_at_end_row
10247 /* No lines reused because we displayed everything up to the
10248 bottom of the window. */
10249 && it.current_y < it.last_visible_y)
10251 dvpos = (it.vpos
10252 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
10253 current_matrix));
10254 dy = it.current_y - first_unchanged_at_end_row->y;
10255 run.current_y = first_unchanged_at_end_row->y;
10256 run.desired_y = run.current_y + dy;
10257 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
10259 else
10261 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
10262 first_unchanged_at_end_row = NULL;
10264 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
10267 /* Find the cursor if not already found. We have to decide whether
10268 PT will appear on this window (it sometimes doesn't, but this is
10269 not a very frequent case.) This decision has to be made before
10270 the current matrix is altered. A value of cursor.vpos < 0 means
10271 that PT is either in one of the lines beginning at
10272 first_unchanged_at_end_row or below the window. Don't care for
10273 lines that might be displayed later at the window end; as
10274 mentioned, this is not a frequent case. */
10275 if (w->cursor.vpos < 0)
10277 /* Cursor in unchanged rows at the top? */
10278 if (PT < CHARPOS (start_pos)
10279 && last_unchanged_at_beg_row)
10281 row = row_containing_pos (w, PT,
10282 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
10283 last_unchanged_at_beg_row + 1);
10284 xassert (row && row <= last_unchanged_at_beg_row);
10285 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10288 /* Start from first_unchanged_at_end_row looking for PT. */
10289 else if (first_unchanged_at_end_row)
10291 row = row_containing_pos (w, PT - delta,
10292 first_unchanged_at_end_row, NULL);
10293 if (row)
10294 set_cursor_from_row (w, row, w->current_matrix, delta,
10295 delta_bytes, dy, dvpos);
10298 /* Give up if cursor was not found. */
10299 if (w->cursor.vpos < 0)
10301 clear_glyph_matrix (w->desired_matrix);
10302 return -1;
10306 /* Don't let the cursor end in the scroll margins. */
10308 int this_scroll_margin, cursor_height;
10310 this_scroll_margin = max (0, scroll_margin);
10311 this_scroll_margin = min (this_scroll_margin,
10312 XFASTINT (w->height) / 4);
10313 this_scroll_margin *= CANON_Y_UNIT (it.f);
10314 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
10316 if ((w->cursor.y < this_scroll_margin
10317 && CHARPOS (start) > BEGV)
10318 /* Don't take scroll margin into account at the bottom because
10319 old redisplay didn't do it either. */
10320 || w->cursor.y + cursor_height > it.last_visible_y)
10322 w->cursor.vpos = -1;
10323 clear_glyph_matrix (w->desired_matrix);
10324 return -1;
10328 /* Scroll the display. Do it before changing the current matrix so
10329 that xterm.c doesn't get confused about where the cursor glyph is
10330 found. */
10331 if (dy && run.height)
10333 update_begin (f);
10335 if (FRAME_WINDOW_P (f))
10337 rif->update_window_begin_hook (w);
10338 rif->scroll_run_hook (w, &run);
10339 rif->update_window_end_hook (w, 0);
10341 else
10343 /* Terminal frame. In this case, dvpos gives the number of
10344 lines to scroll by; dvpos < 0 means scroll up. */
10345 int first_unchanged_at_end_vpos
10346 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
10347 int from = XFASTINT (w->top) + first_unchanged_at_end_vpos;
10348 int end = XFASTINT (w->top) + window_internal_height (w);
10350 /* Perform the operation on the screen. */
10351 if (dvpos > 0)
10353 /* Scroll last_unchanged_at_beg_row to the end of the
10354 window down dvpos lines. */
10355 set_terminal_window (end);
10357 /* On dumb terminals delete dvpos lines at the end
10358 before inserting dvpos empty lines. */
10359 if (!scroll_region_ok)
10360 ins_del_lines (end - dvpos, -dvpos);
10362 /* Insert dvpos empty lines in front of
10363 last_unchanged_at_beg_row. */
10364 ins_del_lines (from, dvpos);
10366 else if (dvpos < 0)
10368 /* Scroll up last_unchanged_at_beg_vpos to the end of
10369 the window to last_unchanged_at_beg_vpos - |dvpos|. */
10370 set_terminal_window (end);
10372 /* Delete dvpos lines in front of
10373 last_unchanged_at_beg_vpos. ins_del_lines will set
10374 the cursor to the given vpos and emit |dvpos| delete
10375 line sequences. */
10376 ins_del_lines (from + dvpos, dvpos);
10378 /* On a dumb terminal insert dvpos empty lines at the
10379 end. */
10380 if (!scroll_region_ok)
10381 ins_del_lines (end + dvpos, -dvpos);
10384 set_terminal_window (0);
10387 update_end (f);
10390 /* Shift reused rows of the current matrix to the right position.
10391 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
10392 text. */
10393 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
10394 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
10395 if (dvpos < 0)
10397 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
10398 bottom_vpos, dvpos);
10399 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
10400 bottom_vpos, 0);
10402 else if (dvpos > 0)
10404 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
10405 bottom_vpos, dvpos);
10406 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
10407 first_unchanged_at_end_vpos + dvpos, 0);
10410 /* For frame-based redisplay, make sure that current frame and window
10411 matrix are in sync with respect to glyph memory. */
10412 if (!FRAME_WINDOW_P (f))
10413 sync_frame_with_window_matrix_rows (w);
10415 /* Adjust buffer positions in reused rows. */
10416 if (delta)
10417 increment_matrix_positions (current_matrix,
10418 first_unchanged_at_end_vpos + dvpos,
10419 bottom_vpos, delta, delta_bytes);
10421 /* Adjust Y positions. */
10422 if (dy)
10423 shift_glyph_matrix (w, current_matrix,
10424 first_unchanged_at_end_vpos + dvpos,
10425 bottom_vpos, dy);
10427 if (first_unchanged_at_end_row)
10428 first_unchanged_at_end_row += dvpos;
10430 /* If scrolling up, there may be some lines to display at the end of
10431 the window. */
10432 last_text_row_at_end = NULL;
10433 if (dy < 0)
10435 /* Set last_row to the glyph row in the current matrix where the
10436 window end line is found. It has been moved up or down in
10437 the matrix by dvpos. */
10438 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
10439 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
10441 /* If last_row is the window end line, it should display text. */
10442 xassert (last_row->displays_text_p);
10444 /* If window end line was partially visible before, begin
10445 displaying at that line. Otherwise begin displaying with the
10446 line following it. */
10447 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
10449 init_to_row_start (&it, w, last_row);
10450 it.vpos = last_vpos;
10451 it.current_y = last_row->y;
10453 else
10455 init_to_row_end (&it, w, last_row);
10456 it.vpos = 1 + last_vpos;
10457 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
10458 ++last_row;
10461 /* We may start in a continuation line. If so, we have to get
10462 the right continuation_lines_width and current_x. */
10463 it.continuation_lines_width = last_row->continuation_lines_width;
10464 it.hpos = it.current_x = 0;
10466 /* Display the rest of the lines at the window end. */
10467 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
10468 while (it.current_y < it.last_visible_y
10469 && !fonts_changed_p)
10471 /* Is it always sure that the display agrees with lines in
10472 the current matrix? I don't think so, so we mark rows
10473 displayed invalid in the current matrix by setting their
10474 enabled_p flag to zero. */
10475 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
10476 if (display_line (&it))
10477 last_text_row_at_end = it.glyph_row - 1;
10481 /* Update window_end_pos and window_end_vpos. */
10482 if (first_unchanged_at_end_row
10483 && first_unchanged_at_end_row->y < it.last_visible_y
10484 && !last_text_row_at_end)
10486 /* Window end line if one of the preserved rows from the current
10487 matrix. Set row to the last row displaying text in current
10488 matrix starting at first_unchanged_at_end_row, after
10489 scrolling. */
10490 xassert (first_unchanged_at_end_row->displays_text_p);
10491 row = find_last_row_displaying_text (w->current_matrix, &it,
10492 first_unchanged_at_end_row);
10493 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
10495 XSETFASTINT (w->window_end_pos, Z - MATRIX_ROW_END_CHARPOS (row));
10496 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
10497 XSETFASTINT (w->window_end_vpos,
10498 MATRIX_ROW_VPOS (row, w->current_matrix));
10500 else if (last_text_row_at_end)
10502 XSETFASTINT (w->window_end_pos,
10503 Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
10504 w->window_end_bytepos
10505 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
10506 XSETFASTINT (w->window_end_vpos,
10507 MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
10509 else if (last_text_row)
10511 /* We have displayed either to the end of the window or at the
10512 end of the window, i.e. the last row with text is to be found
10513 in the desired matrix. */
10514 XSETFASTINT (w->window_end_pos,
10515 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
10516 w->window_end_bytepos
10517 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
10518 XSETFASTINT (w->window_end_vpos,
10519 MATRIX_ROW_VPOS (last_text_row, desired_matrix));
10521 else if (first_unchanged_at_end_row == NULL
10522 && last_text_row == NULL
10523 && last_text_row_at_end == NULL)
10525 /* Displayed to end of window, but no line containing text was
10526 displayed. Lines were deleted at the end of the window. */
10527 int vpos;
10528 int header_line_p = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
10530 for (vpos = XFASTINT (w->window_end_vpos); vpos > 0; --vpos)
10531 if ((w->desired_matrix->rows[vpos + header_line_p].enabled_p
10532 && w->desired_matrix->rows[vpos + header_line_p].displays_text_p)
10533 || (!w->desired_matrix->rows[vpos + header_line_p].enabled_p
10534 && w->current_matrix->rows[vpos + header_line_p].displays_text_p))
10535 break;
10537 w->window_end_vpos = make_number (vpos);
10539 else
10540 abort ();
10542 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
10543 debug_end_vpos = XFASTINT (w->window_end_vpos));
10545 /* Record that display has not been completed. */
10546 w->window_end_valid = Qnil;
10547 w->desired_matrix->no_scrolling_p = 1;
10548 return 1;
10553 /***********************************************************************
10554 More debugging support
10555 ***********************************************************************/
10557 #if GLYPH_DEBUG
10559 void dump_glyph_row P_ ((struct glyph_matrix *, int, int));
10560 static void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
10563 /* Dump the contents of glyph matrix MATRIX on stderr. If
10564 WITH_GLYPHS_P is non-zero, dump glyph contents as well. */
10566 void
10567 dump_glyph_matrix (matrix, with_glyphs_p)
10568 struct glyph_matrix *matrix;
10569 int with_glyphs_p;
10571 int i;
10572 for (i = 0; i < matrix->nrows; ++i)
10573 dump_glyph_row (matrix, i, with_glyphs_p);
10577 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
10578 WITH_GLYPH_SP non-zero means dump glyph contents, too. */
10580 void
10581 dump_glyph_row (matrix, vpos, with_glyphs_p)
10582 struct glyph_matrix *matrix;
10583 int vpos, with_glyphs_p;
10585 struct glyph_row *row;
10587 if (vpos < 0 || vpos >= matrix->nrows)
10588 return;
10590 row = MATRIX_ROW (matrix, vpos);
10592 fprintf (stderr, "Row Start End Used oEI><O\\CTZFes X Y W\n");
10593 fprintf (stderr, "=============================================\n");
10595 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",
10596 row - matrix->rows,
10597 MATRIX_ROW_START_CHARPOS (row),
10598 MATRIX_ROW_END_CHARPOS (row),
10599 row->used[TEXT_AREA],
10600 row->contains_overlapping_glyphs_p,
10601 row->enabled_p,
10602 row->inverse_p,
10603 row->truncated_on_left_p,
10604 row->truncated_on_right_p,
10605 row->overlay_arrow_p,
10606 row->continued_p,
10607 MATRIX_ROW_CONTINUATION_LINE_P (row),
10608 row->displays_text_p,
10609 row->ends_at_zv_p,
10610 row->fill_line_p,
10611 row->ends_in_middle_of_char_p,
10612 row->starts_in_middle_of_char_p,
10613 row->x,
10614 row->y,
10615 row->pixel_width);
10616 fprintf (stderr, "%9d %5d\n", row->start.overlay_string_index,
10617 row->end.overlay_string_index);
10618 fprintf (stderr, "%9d %5d\n",
10619 CHARPOS (row->start.string_pos),
10620 CHARPOS (row->end.string_pos));
10621 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
10622 row->end.dpvec_index);
10624 if (with_glyphs_p)
10626 struct glyph *glyph, *glyph_end;
10627 int prev_had_glyphs_p;
10629 glyph = row->glyphs[TEXT_AREA];
10630 glyph_end = glyph + row->used[TEXT_AREA];
10632 /* Glyph for a line end in text. */
10633 if (glyph == glyph_end && glyph->charpos > 0)
10634 ++glyph_end;
10636 if (glyph < glyph_end)
10638 fprintf (stderr, " Glyph Type Pos W Code C Face LR\n");
10639 prev_had_glyphs_p = 1;
10641 else
10642 prev_had_glyphs_p = 0;
10644 while (glyph < glyph_end)
10646 if (glyph->type == CHAR_GLYPH)
10648 fprintf (stderr,
10649 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
10650 glyph - row->glyphs[TEXT_AREA],
10651 'C',
10652 glyph->charpos,
10653 glyph->pixel_width,
10654 glyph->u.ch,
10655 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
10656 ? glyph->u.ch
10657 : '.'),
10658 glyph->face_id,
10659 glyph->left_box_line_p,
10660 glyph->right_box_line_p);
10662 else if (glyph->type == STRETCH_GLYPH)
10664 fprintf (stderr,
10665 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
10666 glyph - row->glyphs[TEXT_AREA],
10667 'S',
10668 glyph->charpos,
10669 glyph->pixel_width,
10671 '.',
10672 glyph->face_id,
10673 glyph->left_box_line_p,
10674 glyph->right_box_line_p);
10676 else if (glyph->type == IMAGE_GLYPH)
10678 fprintf (stderr,
10679 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
10680 glyph - row->glyphs[TEXT_AREA],
10681 'I',
10682 glyph->charpos,
10683 glyph->pixel_width,
10684 glyph->u.img_id,
10685 '.',
10686 glyph->face_id,
10687 glyph->left_box_line_p,
10688 glyph->right_box_line_p);
10690 ++glyph;
10696 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
10697 Sdump_glyph_matrix, 0, 1, "p",
10698 "Dump the current matrix of the selected window to stderr.\n\
10699 Shows contents of glyph row structures. With non-nil optional\n\
10700 parameter WITH-GLYPHS-P, dump glyphs as well.")
10701 (with_glyphs_p)
10702 Lisp_Object with_glyphs_p;
10704 struct window *w = XWINDOW (selected_window);
10705 struct buffer *buffer = XBUFFER (w->buffer);
10707 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
10708 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
10709 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
10710 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
10711 fprintf (stderr, "=============================================\n");
10712 dump_glyph_matrix (w->current_matrix, !NILP (with_glyphs_p));
10713 return Qnil;
10717 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 1, "",
10718 "Dump glyph row ROW to stderr.")
10719 (row)
10720 Lisp_Object row;
10722 CHECK_NUMBER (row, 0);
10723 dump_glyph_row (XWINDOW (selected_window)->current_matrix, XINT (row), 1);
10724 return Qnil;
10728 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row,
10729 0, 0, "", "")
10732 struct frame *sf = SELECTED_FRAME ();
10733 struct glyph_matrix *m = (XWINDOW (sf->tool_bar_window)
10734 ->current_matrix);
10735 dump_glyph_row (m, 0, 1);
10736 return Qnil;
10740 DEFUN ("trace-redisplay-toggle", Ftrace_redisplay_toggle,
10741 Strace_redisplay_toggle, 0, 0, "",
10742 "Toggle tracing of redisplay.")
10745 trace_redisplay_p = !trace_redisplay_p;
10746 return Qnil;
10750 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, 1, "",
10751 "Print STRING to stderr.")
10752 (string)
10753 Lisp_Object string;
10755 CHECK_STRING (string, 0);
10756 fprintf (stderr, "%s", XSTRING (string)->data);
10757 return Qnil;
10760 #endif /* GLYPH_DEBUG */
10764 /***********************************************************************
10765 Building Desired Matrix Rows
10766 ***********************************************************************/
10768 /* Return a temporary glyph row holding the glyphs of an overlay
10769 arrow. Only used for non-window-redisplay windows. */
10771 static struct glyph_row *
10772 get_overlay_arrow_glyph_row (w)
10773 struct window *w;
10775 struct frame *f = XFRAME (WINDOW_FRAME (w));
10776 struct buffer *buffer = XBUFFER (w->buffer);
10777 struct buffer *old = current_buffer;
10778 unsigned char *arrow_string = XSTRING (Voverlay_arrow_string)->data;
10779 int arrow_len = XSTRING (Voverlay_arrow_string)->size;
10780 unsigned char *arrow_end = arrow_string + arrow_len;
10781 unsigned char *p;
10782 struct it it;
10783 int multibyte_p;
10784 int n_glyphs_before;
10786 set_buffer_temp (buffer);
10787 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
10788 it.glyph_row->used[TEXT_AREA] = 0;
10789 SET_TEXT_POS (it.position, 0, 0);
10791 multibyte_p = !NILP (buffer->enable_multibyte_characters);
10792 p = arrow_string;
10793 while (p < arrow_end)
10795 Lisp_Object face, ilisp;
10797 /* Get the next character. */
10798 if (multibyte_p)
10799 it.c = string_char_and_length (p, arrow_len, &it.len);
10800 else
10801 it.c = *p, it.len = 1;
10802 p += it.len;
10804 /* Get its face. */
10805 XSETFASTINT (ilisp, p - arrow_string);
10806 face = Fget_text_property (ilisp, Qface, Voverlay_arrow_string);
10807 it.face_id = compute_char_face (f, it.c, face);
10809 /* Compute its width, get its glyphs. */
10810 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
10811 SET_TEXT_POS (it.position, -1, -1);
10812 PRODUCE_GLYPHS (&it);
10814 /* If this character doesn't fit any more in the line, we have
10815 to remove some glyphs. */
10816 if (it.current_x > it.last_visible_x)
10818 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
10819 break;
10823 set_buffer_temp (old);
10824 return it.glyph_row;
10828 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
10829 glyphs are only inserted for terminal frames since we can't really
10830 win with truncation glyphs when partially visible glyphs are
10831 involved. Which glyphs to insert is determined by
10832 produce_special_glyphs. */
10834 static void
10835 insert_left_trunc_glyphs (it)
10836 struct it *it;
10838 struct it truncate_it;
10839 struct glyph *from, *end, *to, *toend;
10841 xassert (!FRAME_WINDOW_P (it->f));
10843 /* Get the truncation glyphs. */
10844 truncate_it = *it;
10845 truncate_it.current_x = 0;
10846 truncate_it.face_id = DEFAULT_FACE_ID;
10847 truncate_it.glyph_row = &scratch_glyph_row;
10848 truncate_it.glyph_row->used[TEXT_AREA] = 0;
10849 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
10850 truncate_it.object = make_number (0);
10851 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
10853 /* Overwrite glyphs from IT with truncation glyphs. */
10854 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
10855 end = from + truncate_it.glyph_row->used[TEXT_AREA];
10856 to = it->glyph_row->glyphs[TEXT_AREA];
10857 toend = to + it->glyph_row->used[TEXT_AREA];
10859 while (from < end)
10860 *to++ = *from++;
10862 /* There may be padding glyphs left over. Remove them. */
10863 from = to;
10864 while (from < toend && CHAR_GLYPH_PADDING_P (*from))
10865 ++from;
10866 while (from < toend)
10867 *to++ = *from++;
10869 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
10873 /* Compute the pixel height and width of IT->glyph_row.
10875 Most of the time, ascent and height of a display line will be equal
10876 to the max_ascent and max_height values of the display iterator
10877 structure. This is not the case if
10879 1. We hit ZV without displaying anything. In this case, max_ascent
10880 and max_height will be zero.
10882 2. We have some glyphs that don't contribute to the line height.
10883 (The glyph row flag contributes_to_line_height_p is for future
10884 pixmap extensions).
10886 The first case is easily covered by using default values because in
10887 these cases, the line height does not really matter, except that it
10888 must not be zero. */
10890 static void
10891 compute_line_metrics (it)
10892 struct it *it;
10894 struct glyph_row *row = it->glyph_row;
10895 int area, i;
10897 if (FRAME_WINDOW_P (it->f))
10899 int i, header_line_height;
10901 /* The line may consist of one space only, that was added to
10902 place the cursor on it. If so, the row's height hasn't been
10903 computed yet. */
10904 if (row->height == 0)
10906 if (it->max_ascent + it->max_descent == 0)
10907 it->max_descent = it->max_phys_descent = CANON_Y_UNIT (it->f);
10908 row->ascent = it->max_ascent;
10909 row->height = it->max_ascent + it->max_descent;
10910 row->phys_ascent = it->max_phys_ascent;
10911 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
10914 /* Compute the width of this line. */
10915 row->pixel_width = row->x;
10916 for (i = 0; i < row->used[TEXT_AREA]; ++i)
10917 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
10919 xassert (row->pixel_width >= 0);
10920 xassert (row->ascent >= 0 && row->height > 0);
10922 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
10923 || MATRIX_ROW_OVERLAPS_PRED_P (row));
10925 /* If first line's physical ascent is larger than its logical
10926 ascent, use the physical ascent, and make the row taller.
10927 This makes accented characters fully visible. */
10928 if (row == it->w->desired_matrix->rows
10929 && row->phys_ascent > row->ascent)
10931 row->height += row->phys_ascent - row->ascent;
10932 row->ascent = row->phys_ascent;
10935 /* Compute how much of the line is visible. */
10936 row->visible_height = row->height;
10938 header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (it->w);
10939 if (row->y < header_line_height)
10940 row->visible_height -= header_line_height - row->y;
10941 else
10943 int max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (it->w);
10944 if (row->y + row->height > max_y)
10945 row->visible_height -= row->y + row->height - max_y;
10948 else
10950 row->pixel_width = row->used[TEXT_AREA];
10951 row->ascent = row->phys_ascent = 0;
10952 row->height = row->phys_height = row->visible_height = 1;
10955 /* Compute a hash code for this row. */
10956 row->hash = 0;
10957 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
10958 for (i = 0; i < row->used[area]; ++i)
10959 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
10960 + row->glyphs[area][i].u.val
10961 + row->glyphs[area][i].face_id
10962 + row->glyphs[area][i].padding_p
10963 + (row->glyphs[area][i].type << 2));
10965 it->max_ascent = it->max_descent = 0;
10966 it->max_phys_ascent = it->max_phys_descent = 0;
10970 /* Append one space to the glyph row of iterator IT if doing a
10971 window-based redisplay. DEFAULT_FACE_P non-zero means let the
10972 space have the default face, otherwise let it have the same face as
10973 IT->face_id. Value is non-zero if a space was added.
10975 This function is called to make sure that there is always one glyph
10976 at the end of a glyph row that the cursor can be set on under
10977 window-systems. (If there weren't such a glyph we would not know
10978 how wide and tall a box cursor should be displayed).
10980 At the same time this space let's a nicely handle clearing to the
10981 end of the line if the row ends in italic text. */
10983 static int
10984 append_space (it, default_face_p)
10985 struct it *it;
10986 int default_face_p;
10988 if (FRAME_WINDOW_P (it->f))
10990 int n = it->glyph_row->used[TEXT_AREA];
10992 if (it->glyph_row->glyphs[TEXT_AREA] + n
10993 < it->glyph_row->glyphs[1 + TEXT_AREA])
10995 /* Save some values that must not be changed. */
10996 int saved_x = it->current_x;
10997 struct text_pos saved_pos;
10998 int saved_what = it->what;
10999 int saved_face_id = it->face_id;
11000 Lisp_Object saved_object;
11001 struct face *face;
11003 saved_object = it->object;
11004 saved_pos = it->position;
11006 it->what = IT_CHARACTER;
11007 bzero (&it->position, sizeof it->position);
11008 it->object = make_number (0);
11009 it->c = ' ';
11010 it->len = 1;
11012 if (default_face_p)
11013 it->face_id = DEFAULT_FACE_ID;
11014 face = FACE_FROM_ID (it->f, it->face_id);
11015 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
11017 PRODUCE_GLYPHS (it);
11019 it->current_x = saved_x;
11020 it->object = saved_object;
11021 it->position = saved_pos;
11022 it->what = saved_what;
11023 it->face_id = saved_face_id;
11024 return 1;
11028 return 0;
11032 /* Extend the face of the last glyph in the text area of IT->glyph_row
11033 to the end of the display line. Called from display_line.
11034 If the glyph row is empty, add a space glyph to it so that we
11035 know the face to draw. Set the glyph row flag fill_line_p. */
11037 static void
11038 extend_face_to_end_of_line (it)
11039 struct it *it;
11041 struct face *face;
11042 struct frame *f = it->f;
11044 /* If line is already filled, do nothing. */
11045 if (it->current_x >= it->last_visible_x)
11046 return;
11048 /* Face extension extends the background and box of IT->face_id
11049 to the end of the line. If the background equals the background
11050 of the frame, we haven't to do anything. */
11051 face = FACE_FROM_ID (f, it->face_id);
11052 if (FRAME_WINDOW_P (f)
11053 && face->box == FACE_NO_BOX
11054 && face->background == FRAME_BACKGROUND_PIXEL (f)
11055 && !face->stipple)
11056 return;
11058 /* Set the glyph row flag indicating that the face of the last glyph
11059 in the text area has to be drawn to the end of the text area. */
11060 it->glyph_row->fill_line_p = 1;
11062 /* If current character of IT is not ASCII, make sure we have the
11063 ASCII face. This will be automatically undone the next time
11064 get_next_display_element returns a multibyte character. Note
11065 that the character will always be single byte in unibyte text. */
11066 if (!SINGLE_BYTE_CHAR_P (it->c))
11068 it->face_id = FACE_FOR_CHAR (f, face, 0);
11071 if (FRAME_WINDOW_P (f))
11073 /* If the row is empty, add a space with the current face of IT,
11074 so that we know which face to draw. */
11075 if (it->glyph_row->used[TEXT_AREA] == 0)
11077 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
11078 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
11079 it->glyph_row->used[TEXT_AREA] = 1;
11082 else
11084 /* Save some values that must not be changed. */
11085 int saved_x = it->current_x;
11086 struct text_pos saved_pos;
11087 Lisp_Object saved_object;
11088 int saved_what = it->what;
11090 saved_object = it->object;
11091 saved_pos = it->position;
11093 it->what = IT_CHARACTER;
11094 bzero (&it->position, sizeof it->position);
11095 it->object = make_number (0);
11096 it->c = ' ';
11097 it->len = 1;
11099 PRODUCE_GLYPHS (it);
11101 while (it->current_x <= it->last_visible_x)
11102 PRODUCE_GLYPHS (it);
11104 /* Don't count these blanks really. It would let us insert a left
11105 truncation glyph below and make us set the cursor on them, maybe. */
11106 it->current_x = saved_x;
11107 it->object = saved_object;
11108 it->position = saved_pos;
11109 it->what = saved_what;
11114 /* Value is non-zero if text starting at CHARPOS in current_buffer is
11115 trailing whitespace. */
11117 static int
11118 trailing_whitespace_p (charpos)
11119 int charpos;
11121 int bytepos = CHAR_TO_BYTE (charpos);
11122 int c = 0;
11124 while (bytepos < ZV_BYTE
11125 && (c = FETCH_CHAR (bytepos),
11126 c == ' ' || c == '\t'))
11127 ++bytepos;
11129 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
11131 if (bytepos != PT_BYTE)
11132 return 1;
11134 return 0;
11138 /* Highlight trailing whitespace, if any, in ROW. */
11140 void
11141 highlight_trailing_whitespace (f, row)
11142 struct frame *f;
11143 struct glyph_row *row;
11145 int used = row->used[TEXT_AREA];
11147 if (used)
11149 struct glyph *start = row->glyphs[TEXT_AREA];
11150 struct glyph *glyph = start + used - 1;
11152 /* Skip over the space glyph inserted to display the
11153 cursor at the end of a line. */
11154 if (glyph->type == CHAR_GLYPH
11155 && glyph->u.ch == ' '
11156 && INTEGERP (glyph->object))
11157 --glyph;
11159 /* If last glyph is a space or stretch, and it's trailing
11160 whitespace, set the face of all trailing whitespace glyphs in
11161 IT->glyph_row to `trailing-whitespace'. */
11162 if (glyph >= start
11163 && BUFFERP (glyph->object)
11164 && (glyph->type == STRETCH_GLYPH
11165 || (glyph->type == CHAR_GLYPH
11166 && glyph->u.ch == ' '))
11167 && trailing_whitespace_p (glyph->charpos))
11169 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
11171 while (glyph >= start
11172 && BUFFERP (glyph->object)
11173 && (glyph->type == STRETCH_GLYPH
11174 || (glyph->type == CHAR_GLYPH
11175 && glyph->u.ch == ' ')))
11176 (glyph--)->face_id = face_id;
11182 /* Construct the glyph row IT->glyph_row in the desired matrix of
11183 IT->w from text at the current position of IT. See dispextern.h
11184 for an overview of struct it. Value is non-zero if
11185 IT->glyph_row displays text, as opposed to a line displaying ZV
11186 only. */
11188 static int
11189 display_line (it)
11190 struct it *it;
11192 struct glyph_row *row = it->glyph_row;
11194 /* We always start displaying at hpos zero even if hscrolled. */
11195 xassert (it->hpos == 0 && it->current_x == 0);
11197 /* We must not display in a row that's not a text row. */
11198 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
11199 < it->w->desired_matrix->nrows);
11201 /* Is IT->w showing the region? */
11202 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
11204 /* Clear the result glyph row and enable it. */
11205 prepare_desired_row (row);
11207 row->y = it->current_y;
11208 row->start = it->current;
11209 row->continuation_lines_width = it->continuation_lines_width;
11210 row->displays_text_p = 1;
11211 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
11212 it->starts_in_middle_of_char_p = 0;
11214 /* Arrange the overlays nicely for our purposes. Usually, we call
11215 display_line on only one line at a time, in which case this
11216 can't really hurt too much, or we call it on lines which appear
11217 one after another in the buffer, in which case all calls to
11218 recenter_overlay_lists but the first will be pretty cheap. */
11219 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
11221 /* Move over display elements that are not visible because we are
11222 hscrolled. This may stop at an x-position < IT->first_visible_x
11223 if the first glyph is partially visible or if we hit a line end. */
11224 if (it->current_x < it->first_visible_x)
11225 move_it_in_display_line_to (it, ZV, it->first_visible_x,
11226 MOVE_TO_POS | MOVE_TO_X);
11228 /* Get the initial row height. This is either the height of the
11229 text hscrolled, if there is any, or zero. */
11230 row->ascent = it->max_ascent;
11231 row->height = it->max_ascent + it->max_descent;
11232 row->phys_ascent = it->max_phys_ascent;
11233 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
11235 /* Loop generating characters. The loop is left with IT on the next
11236 character to display. */
11237 while (1)
11239 int n_glyphs_before, hpos_before, x_before;
11240 int x, i, nglyphs;
11241 int ascent, descent, phys_ascent, phys_descent;
11243 /* Retrieve the next thing to display. Value is zero if end of
11244 buffer reached. */
11245 if (!get_next_display_element (it))
11247 /* Maybe add a space at the end of this line that is used to
11248 display the cursor there under X. Set the charpos of the
11249 first glyph of blank lines not corresponding to any text
11250 to -1. */
11251 if ((append_space (it, 1) && row->used[TEXT_AREA] == 1)
11252 || row->used[TEXT_AREA] == 0)
11254 row->glyphs[TEXT_AREA]->charpos = -1;
11255 row->displays_text_p = 0;
11257 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines))
11258 row->indicate_empty_line_p = 1;
11261 it->continuation_lines_width = 0;
11262 row->ends_at_zv_p = 1;
11263 break;
11266 /* Now, get the metrics of what we want to display. This also
11267 generates glyphs in `row' (which is IT->glyph_row). */
11268 n_glyphs_before = row->used[TEXT_AREA];
11269 x = it->current_x;
11271 /* Remember the line height so far in case the next element doesn't
11272 fit on the line. */
11273 if (!it->truncate_lines_p)
11275 ascent = it->max_ascent;
11276 descent = it->max_descent;
11277 phys_ascent = it->max_phys_ascent;
11278 phys_descent = it->max_phys_descent;
11281 PRODUCE_GLYPHS (it);
11283 /* If this display element was in marginal areas, continue with
11284 the next one. */
11285 if (it->area != TEXT_AREA)
11287 row->ascent = max (row->ascent, it->max_ascent);
11288 row->height = max (row->height, it->max_ascent + it->max_descent);
11289 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
11290 row->phys_height = max (row->phys_height,
11291 it->max_phys_ascent + it->max_phys_descent);
11292 set_iterator_to_next (it);
11293 continue;
11296 /* Does the display element fit on the line? If we truncate
11297 lines, we should draw past the right edge of the window. If
11298 we don't truncate, we want to stop so that we can display the
11299 continuation glyph before the right margin. If lines are
11300 continued, there are two possible strategies for characters
11301 resulting in more than 1 glyph (e.g. tabs): Display as many
11302 glyphs as possible in this line and leave the rest for the
11303 continuation line, or display the whole element in the next
11304 line. Original redisplay did the former, so we do it also. */
11305 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
11306 hpos_before = it->hpos;
11307 x_before = x;
11309 if (nglyphs == 1
11310 && it->current_x < it->last_visible_x)
11312 ++it->hpos;
11313 row->ascent = max (row->ascent, it->max_ascent);
11314 row->height = max (row->height, it->max_ascent + it->max_descent);
11315 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
11316 row->phys_height = max (row->phys_height,
11317 it->max_phys_ascent + it->max_phys_descent);
11318 if (it->current_x - it->pixel_width < it->first_visible_x)
11319 row->x = x - it->first_visible_x;
11321 else
11323 int new_x;
11324 struct glyph *glyph;
11326 for (i = 0; i < nglyphs; ++i, x = new_x)
11328 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11329 new_x = x + glyph->pixel_width;
11331 if (/* Lines are continued. */
11332 !it->truncate_lines_p
11333 && (/* Glyph doesn't fit on the line. */
11334 new_x > it->last_visible_x
11335 /* Or it fits exactly on a window system frame. */
11336 || (new_x == it->last_visible_x
11337 && FRAME_WINDOW_P (it->f))))
11339 /* End of a continued line. */
11341 if (it->hpos == 0
11342 || (new_x == it->last_visible_x
11343 && FRAME_WINDOW_P (it->f)))
11345 /* Current glyph is the only one on the line or
11346 fits exactly on the line. We must continue
11347 the line because we can't draw the cursor
11348 after the glyph. */
11349 row->continued_p = 1;
11350 it->current_x = new_x;
11351 it->continuation_lines_width += new_x;
11352 ++it->hpos;
11353 if (i == nglyphs - 1)
11354 set_iterator_to_next (it);
11356 else if (CHAR_GLYPH_PADDING_P (*glyph)
11357 && !FRAME_WINDOW_P (it->f))
11359 /* A padding glyph that doesn't fit on this line.
11360 This means the whole character doesn't fit
11361 on the line. */
11362 row->used[TEXT_AREA] = n_glyphs_before;
11364 /* Fill the rest of the row with continuation
11365 glyphs like in 20.x. */
11366 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
11367 < row->glyphs[1 + TEXT_AREA])
11368 produce_special_glyphs (it, IT_CONTINUATION);
11370 row->continued_p = 1;
11371 it->current_x = x_before;
11372 it->continuation_lines_width += x_before;
11374 /* Restore the height to what it was before the
11375 element not fitting on the line. */
11376 it->max_ascent = ascent;
11377 it->max_descent = descent;
11378 it->max_phys_ascent = phys_ascent;
11379 it->max_phys_descent = phys_descent;
11381 else
11383 /* Display element draws past the right edge of
11384 the window. Restore positions to values
11385 before the element. The next line starts
11386 with current_x before the glyph that could
11387 not be displayed, so that TAB works right. */
11388 row->used[TEXT_AREA] = n_glyphs_before + i;
11390 /* Display continuation glyphs. */
11391 if (!FRAME_WINDOW_P (it->f))
11392 produce_special_glyphs (it, IT_CONTINUATION);
11393 row->continued_p = 1;
11395 it->current_x = x;
11396 it->continuation_lines_width += x;
11397 if (nglyphs > 1 && i > 0)
11399 row->ends_in_middle_of_char_p = 1;
11400 it->starts_in_middle_of_char_p = 1;
11403 /* Restore the height to what it was before the
11404 element not fitting on the line. */
11405 it->max_ascent = ascent;
11406 it->max_descent = descent;
11407 it->max_phys_ascent = phys_ascent;
11408 it->max_phys_descent = phys_descent;
11411 break;
11413 else if (new_x > it->first_visible_x)
11415 /* Increment number of glyphs actually displayed. */
11416 ++it->hpos;
11418 if (x < it->first_visible_x)
11419 /* Glyph is partially visible, i.e. row starts at
11420 negative X position. */
11421 row->x = x - it->first_visible_x;
11423 else
11425 /* Glyph is completely off the left margin of the
11426 window. This should not happen because of the
11427 move_it_in_display_line at the start of
11428 this function. */
11429 abort ();
11433 row->ascent = max (row->ascent, it->max_ascent);
11434 row->height = max (row->height, it->max_ascent + it->max_descent);
11435 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
11436 row->phys_height = max (row->phys_height,
11437 it->max_phys_ascent + it->max_phys_descent);
11439 /* End of this display line if row is continued. */
11440 if (row->continued_p)
11441 break;
11444 /* Is this a line end? If yes, we're also done, after making
11445 sure that a non-default face is extended up to the right
11446 margin of the window. */
11447 if (ITERATOR_AT_END_OF_LINE_P (it))
11449 int used_before = row->used[TEXT_AREA];
11451 /* Add a space at the end of the line that is used to
11452 display the cursor there. */
11453 append_space (it, 0);
11455 /* Extend the face to the end of the line. */
11456 extend_face_to_end_of_line (it);
11458 /* Make sure we have the position. */
11459 if (used_before == 0)
11460 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
11462 /* Consume the line end. This skips over invisible lines. */
11463 set_iterator_to_next (it);
11464 it->continuation_lines_width = 0;
11465 break;
11468 /* Proceed with next display element. Note that this skips
11469 over lines invisible because of selective display. */
11470 set_iterator_to_next (it);
11472 /* If we truncate lines, we are done when the last displayed
11473 glyphs reach past the right margin of the window. */
11474 if (it->truncate_lines_p
11475 && (FRAME_WINDOW_P (it->f)
11476 ? (it->current_x >= it->last_visible_x)
11477 : (it->current_x > it->last_visible_x)))
11479 /* Maybe add truncation glyphs. */
11480 if (!FRAME_WINDOW_P (it->f))
11482 --it->glyph_row->used[TEXT_AREA];
11483 produce_special_glyphs (it, IT_TRUNCATION);
11486 row->truncated_on_right_p = 1;
11487 it->continuation_lines_width = 0;
11488 reseat_at_next_visible_line_start (it, 0);
11489 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
11490 it->hpos = hpos_before;
11491 it->current_x = x_before;
11492 break;
11496 /* If line is not empty and hscrolled, maybe insert truncation glyphs
11497 at the left window margin. */
11498 if (it->first_visible_x
11499 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
11501 if (!FRAME_WINDOW_P (it->f))
11502 insert_left_trunc_glyphs (it);
11503 row->truncated_on_left_p = 1;
11506 /* If the start of this line is the overlay arrow-position, then
11507 mark this glyph row as the one containing the overlay arrow.
11508 This is clearly a mess with variable size fonts. It would be
11509 better to let it be displayed like cursors under X. */
11510 if (MARKERP (Voverlay_arrow_position)
11511 && current_buffer == XMARKER (Voverlay_arrow_position)->buffer
11512 && (MATRIX_ROW_START_CHARPOS (row)
11513 == marker_position (Voverlay_arrow_position))
11514 && STRINGP (Voverlay_arrow_string)
11515 && ! overlay_arrow_seen)
11517 /* Overlay arrow in window redisplay is a bitmap. */
11518 if (!FRAME_WINDOW_P (it->f))
11520 struct glyph_row *arrow_row = get_overlay_arrow_glyph_row (it->w);
11521 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
11522 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
11523 struct glyph *p = row->glyphs[TEXT_AREA];
11524 struct glyph *p2, *end;
11526 /* Copy the arrow glyphs. */
11527 while (glyph < arrow_end)
11528 *p++ = *glyph++;
11530 /* Throw away padding glyphs. */
11531 p2 = p;
11532 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
11533 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
11534 ++p2;
11535 if (p2 > p)
11537 while (p2 < end)
11538 *p++ = *p2++;
11539 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
11543 overlay_arrow_seen = 1;
11544 row->overlay_arrow_p = 1;
11547 /* Compute pixel dimensions of this line. */
11548 compute_line_metrics (it);
11550 /* Remember the position at which this line ends. */
11551 row->end = it->current;
11553 /* Maybe set the cursor. */
11554 if (it->w->cursor.vpos < 0
11555 && PT >= MATRIX_ROW_START_CHARPOS (row)
11556 && PT <= MATRIX_ROW_END_CHARPOS (row))
11558 /* Also see redisplay_window, case cursor movement in unchanged
11559 window. */
11560 if (MATRIX_ROW_END_CHARPOS (row) == PT
11561 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
11562 && !row->ends_at_zv_p)
11564 else
11565 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
11568 /* Highlight trailing whitespace. */
11569 if (!NILP (Vshow_trailing_whitespace))
11570 highlight_trailing_whitespace (it->f, it->glyph_row);
11572 /* Prepare for the next line. This line starts horizontally at (X
11573 HPOS) = (0 0). Vertical positions are incremented. As a
11574 convenience for the caller, IT->glyph_row is set to the next
11575 row to be used. */
11576 it->current_x = it->hpos = 0;
11577 it->current_y += row->height;
11578 ++it->vpos;
11579 ++it->glyph_row;
11580 return row->displays_text_p;
11585 /***********************************************************************
11586 Menu Bar
11587 ***********************************************************************/
11589 /* Redisplay the menu bar in the frame for window W.
11591 The menu bar of X frames that don't have X toolkit support is
11592 displayed in a special window W->frame->menu_bar_window.
11594 The menu bar of terminal frames is treated specially as far as
11595 glyph matrices are concerned. Menu bar lines are not part of
11596 windows, so the update is done directly on the frame matrix rows
11597 for the menu bar. */
11599 static void
11600 display_menu_bar (w)
11601 struct window *w;
11603 struct frame *f = XFRAME (WINDOW_FRAME (w));
11604 struct it it;
11605 Lisp_Object items;
11606 int i;
11608 /* Don't do all this for graphical frames. */
11609 #ifdef HAVE_NTGUI
11610 if (!NILP (Vwindow_system))
11611 return;
11612 #endif
11613 #ifdef USE_X_TOOLKIT
11614 if (FRAME_X_P (f))
11615 return;
11616 #endif
11618 #ifdef USE_X_TOOLKIT
11619 xassert (!FRAME_WINDOW_P (f));
11620 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
11621 it.first_visible_x = 0;
11622 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
11623 #else /* not USE_X_TOOLKIT */
11624 if (FRAME_WINDOW_P (f))
11626 /* Menu bar lines are displayed in the desired matrix of the
11627 dummy window menu_bar_window. */
11628 struct window *menu_w;
11629 xassert (WINDOWP (f->menu_bar_window));
11630 menu_w = XWINDOW (f->menu_bar_window);
11631 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
11632 MENU_FACE_ID);
11633 it.first_visible_x = 0;
11634 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
11636 else
11638 /* This is a TTY frame, i.e. character hpos/vpos are used as
11639 pixel x/y. */
11640 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
11641 MENU_FACE_ID);
11642 it.first_visible_x = 0;
11643 it.last_visible_x = FRAME_WIDTH (f);
11645 #endif /* not USE_X_TOOLKIT */
11647 /* Clear all rows of the menu bar. */
11648 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
11650 struct glyph_row *row = it.glyph_row + i;
11651 clear_glyph_row (row);
11652 row->enabled_p = 1;
11653 row->full_width_p = 1;
11656 /* Make the first line of the menu bar appear in reverse video. */
11657 it.glyph_row->inverse_p = mode_line_inverse_video != 0;
11659 /* Display all items of the menu bar. */
11660 items = FRAME_MENU_BAR_ITEMS (it.f);
11661 for (i = 0; i < XVECTOR (items)->size; i += 4)
11663 Lisp_Object string;
11665 /* Stop at nil string. */
11666 string = XVECTOR (items)->contents[i + 1];
11667 if (NILP (string))
11668 break;
11670 /* Remember where item was displayed. */
11671 XSETFASTINT (XVECTOR (items)->contents[i + 3], it.hpos);
11673 /* Display the item, pad with one space. */
11674 if (it.current_x < it.last_visible_x)
11675 display_string (NULL, string, Qnil, 0, 0, &it,
11676 XSTRING (string)->size + 1, 0, 0, -1);
11679 /* Fill out the line with spaces. */
11680 if (it.current_x < it.last_visible_x)
11681 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
11683 /* Compute the total height of the lines. */
11684 compute_line_metrics (&it);
11689 /***********************************************************************
11690 Mode Line
11691 ***********************************************************************/
11693 /* Display the mode and/or top line of window W. */
11695 static void
11696 display_mode_lines (w)
11697 struct window *w;
11699 /* These will be set while the mode line specs are processed. */
11700 line_number_displayed = 0;
11701 w->column_number_displayed = Qnil;
11703 if (WINDOW_WANTS_MODELINE_P (w))
11704 display_mode_line (w, MODE_LINE_FACE_ID,
11705 current_buffer->mode_line_format);
11707 if (WINDOW_WANTS_HEADER_LINE_P (w))
11708 display_mode_line (w, HEADER_LINE_FACE_ID,
11709 current_buffer->header_line_format);
11713 /* Display mode or top line of window W. FACE_ID specifies which line
11714 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
11715 FORMAT is the mode line format to display. */
11717 static void
11718 display_mode_line (w, face_id, format)
11719 struct window *w;
11720 enum face_id face_id;
11721 Lisp_Object format;
11723 struct it it;
11724 struct face *face;
11726 init_iterator (&it, w, -1, -1, NULL, face_id);
11727 prepare_desired_row (it.glyph_row);
11729 /* Temporarily make frame's keyboard the current kboard so that
11730 kboard-local variables in the mode_line_format will get the right
11731 values. */
11732 push_frame_kboard (it.f);
11733 display_mode_element (&it, 0, 0, 0, format);
11734 pop_frame_kboard ();
11736 /* Fill up with spaces. */
11737 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
11739 compute_line_metrics (&it);
11740 it.glyph_row->full_width_p = 1;
11741 it.glyph_row->mode_line_p = 1;
11742 it.glyph_row->inverse_p = mode_line_inverse_video != 0;
11743 it.glyph_row->continued_p = 0;
11744 it.glyph_row->truncated_on_left_p = 0;
11745 it.glyph_row->truncated_on_right_p = 0;
11747 /* Make a 3D mode-line have a shadow at its right end. */
11748 face = FACE_FROM_ID (it.f, face_id);
11749 extend_face_to_end_of_line (&it);
11750 if (face->box != FACE_NO_BOX)
11752 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
11753 + it.glyph_row->used[TEXT_AREA] - 1);
11754 last->right_box_line_p = 1;
11759 /* Contribute ELT to the mode line for window IT->w. How it
11760 translates into text depends on its data type.
11762 IT describes the display environment in which we display, as usual.
11764 DEPTH is the depth in recursion. It is used to prevent
11765 infinite recursion here.
11767 FIELD_WIDTH is the number of characters the display of ELT should
11768 occupy in the mode line, and PRECISION is the maximum number of
11769 characters to display from ELT's representation. See
11770 display_string for details. *
11772 Returns the hpos of the end of the text generated by ELT. */
11774 static int
11775 display_mode_element (it, depth, field_width, precision, elt)
11776 struct it *it;
11777 int depth;
11778 int field_width, precision;
11779 Lisp_Object elt;
11781 int n = 0, field, prec;
11783 tail_recurse:
11784 if (depth > 10)
11785 goto invalid;
11787 depth++;
11789 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
11791 case Lisp_String:
11793 /* A string: output it and check for %-constructs within it. */
11794 unsigned char c;
11795 unsigned char *this = XSTRING (elt)->data;
11796 unsigned char *lisp_string = this;
11798 while ((precision <= 0 || n < precision)
11799 && *this
11800 && (frame_title_ptr
11801 || it->current_x < it->last_visible_x))
11803 unsigned char *last = this;
11805 /* Advance to end of string or next format specifier. */
11806 while ((c = *this++) != '\0' && c != '%')
11809 if (this - 1 != last)
11811 /* Output to end of string or up to '%'. Field width
11812 is length of string. Don't output more than
11813 PRECISION allows us. */
11814 prec = --this - last;
11815 if (precision > 0 && prec > precision - n)
11816 prec = precision - n;
11818 if (frame_title_ptr)
11819 n += store_frame_title (last, prec, prec);
11820 else
11821 n += display_string (NULL, elt, Qnil, 0, last - lisp_string,
11822 it, 0, prec, 0, -1);
11824 else /* c == '%' */
11826 unsigned char *percent_position = this;
11828 /* Get the specified minimum width. Zero means
11829 don't pad. */
11830 field = 0;
11831 while ((c = *this++) >= '0' && c <= '9')
11832 field = field * 10 + c - '0';
11834 /* Don't pad beyond the total padding allowed. */
11835 if (field_width - n > 0 && field > field_width - n)
11836 field = field_width - n;
11838 /* Note that either PRECISION <= 0 or N < PRECISION. */
11839 prec = precision - n;
11841 if (c == 'M')
11842 n += display_mode_element (it, depth, field, prec,
11843 Vglobal_mode_string);
11844 else if (c != 0)
11846 unsigned char *spec
11847 = decode_mode_spec (it->w, c, field, prec);
11849 if (frame_title_ptr)
11850 n += store_frame_title (spec, field, prec);
11851 else
11853 int nglyphs_before
11854 = it->glyph_row->used[TEXT_AREA];
11855 int charpos
11856 = percent_position - XSTRING (elt)->data;
11857 int nwritten
11858 = display_string (spec, Qnil, elt, charpos, 0, it,
11859 field, prec, 0, -1);
11861 /* Assign to the glyphs written above the
11862 string where the `%x' came from, position
11863 of the `%'. */
11864 if (nwritten > 0)
11866 struct glyph *glyph
11867 = (it->glyph_row->glyphs[TEXT_AREA]
11868 + nglyphs_before);
11869 int i;
11871 for (i = 0; i < nwritten; ++i)
11873 glyph[i].object = elt;
11874 glyph[i].charpos = charpos;
11877 n += nwritten;
11884 break;
11886 case Lisp_Symbol:
11887 /* A symbol: process the value of the symbol recursively
11888 as if it appeared here directly. Avoid error if symbol void.
11889 Special case: if value of symbol is a string, output the string
11890 literally. */
11892 register Lisp_Object tem;
11893 tem = Fboundp (elt);
11894 if (!NILP (tem))
11896 tem = Fsymbol_value (elt);
11897 /* If value is a string, output that string literally:
11898 don't check for % within it. */
11899 if (STRINGP (tem))
11901 prec = XSTRING (tem)->size;
11902 if (precision > 0 && prec > precision - n)
11903 prec = precision - n;
11904 if (frame_title_ptr)
11905 n += store_frame_title (XSTRING (tem)->data, -1, prec);
11906 else
11907 n += display_string (NULL, tem, Qnil, 0, 0, it,
11908 0, prec, 0, -1);
11910 else if (!EQ (tem, elt))
11912 /* Give up right away for nil or t. */
11913 elt = tem;
11914 goto tail_recurse;
11918 break;
11920 case Lisp_Cons:
11922 register Lisp_Object car, tem;
11924 /* A cons cell: three distinct cases.
11925 If first element is a string or a cons, process all the elements
11926 and effectively concatenate them.
11927 If first element is a negative number, truncate displaying cdr to
11928 at most that many characters. If positive, pad (with spaces)
11929 to at least that many characters.
11930 If first element is a symbol, process the cadr or caddr recursively
11931 according to whether the symbol's value is non-nil or nil. */
11932 car = XCAR (elt);
11933 if (EQ (car, QCeval) && CONSP (XCDR (elt)))
11935 /* An element of the form (:eval FORM) means evaluate FORM
11936 and use the result as mode line elements. */
11937 struct gcpro gcpro1;
11938 Lisp_Object spec;
11940 spec = eval_form (XCAR (XCDR (elt)));
11941 GCPRO1 (spec);
11942 n += display_mode_element (it, depth, field_width - n,
11943 precision - n, spec);
11944 UNGCPRO;
11946 else if (SYMBOLP (car))
11948 tem = Fboundp (car);
11949 elt = XCDR (elt);
11950 if (!CONSP (elt))
11951 goto invalid;
11952 /* elt is now the cdr, and we know it is a cons cell.
11953 Use its car if CAR has a non-nil value. */
11954 if (!NILP (tem))
11956 tem = Fsymbol_value (car);
11957 if (!NILP (tem))
11959 elt = XCAR (elt);
11960 goto tail_recurse;
11963 /* Symbol's value is nil (or symbol is unbound)
11964 Get the cddr of the original list
11965 and if possible find the caddr and use that. */
11966 elt = XCDR (elt);
11967 if (NILP (elt))
11968 break;
11969 else if (!CONSP (elt))
11970 goto invalid;
11971 elt = XCAR (elt);
11972 goto tail_recurse;
11974 else if (INTEGERP (car))
11976 register int lim = XINT (car);
11977 elt = XCDR (elt);
11978 if (lim < 0)
11980 /* Negative int means reduce maximum width. */
11981 if (precision <= 0)
11982 precision = -lim;
11983 else
11984 precision = min (precision, -lim);
11986 else if (lim > 0)
11988 /* Padding specified. Don't let it be more than
11989 current maximum. */
11990 if (precision > 0)
11991 lim = min (precision, lim);
11993 /* If that's more padding than already wanted, queue it.
11994 But don't reduce padding already specified even if
11995 that is beyond the current truncation point. */
11996 field_width = max (lim, field_width);
11998 goto tail_recurse;
12000 else if (STRINGP (car) || CONSP (car))
12002 register int limit = 50;
12003 /* Limit is to protect against circular lists. */
12004 while (CONSP (elt)
12005 && --limit > 0
12006 && (precision <= 0 || n < precision))
12008 n += display_mode_element (it, depth, field_width - n,
12009 precision - n, XCAR (elt));
12010 elt = XCDR (elt);
12014 break;
12016 default:
12017 invalid:
12018 if (frame_title_ptr)
12019 n += store_frame_title ("*invalid*", 0, precision - n);
12020 else
12021 n += display_string ("*invalid*", Qnil, Qnil, 0, 0, it, 0,
12022 precision - n, 0, 0);
12023 return n;
12026 /* Pad to FIELD_WIDTH. */
12027 if (field_width > 0 && n < field_width)
12029 if (frame_title_ptr)
12030 n += store_frame_title ("", field_width - n, 0);
12031 else
12032 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
12033 0, 0, 0);
12036 return n;
12040 /* Write a null-terminated, right justified decimal representation of
12041 the positive integer D to BUF using a minimal field width WIDTH. */
12043 static void
12044 pint2str (buf, width, d)
12045 register char *buf;
12046 register int width;
12047 register int d;
12049 register char *p = buf;
12051 if (d <= 0)
12052 *p++ = '0';
12053 else
12055 while (d > 0)
12057 *p++ = d % 10 + '0';
12058 d /= 10;
12062 for (width -= (int) (p - buf); width > 0; --width)
12063 *p++ = ' ';
12064 *p-- = '\0';
12065 while (p > buf)
12067 d = *buf;
12068 *buf++ = *p;
12069 *p-- = d;
12073 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
12074 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
12075 type of CODING_SYSTEM. Return updated pointer into BUF. */
12077 static unsigned char invalid_eol_type[] = "(*invalid*)";
12079 static char *
12080 decode_mode_spec_coding (coding_system, buf, eol_flag)
12081 Lisp_Object coding_system;
12082 register char *buf;
12083 int eol_flag;
12085 Lisp_Object val;
12086 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
12087 unsigned char *eol_str;
12088 int eol_str_len;
12089 /* The EOL conversion we are using. */
12090 Lisp_Object eoltype;
12092 val = Fget (coding_system, Qcoding_system);
12094 if (!VECTORP (val)) /* Not yet decided. */
12096 if (multibyte)
12097 *buf++ = '-';
12098 if (eol_flag)
12099 eoltype = eol_mnemonic_undecided;
12100 /* Don't mention EOL conversion if it isn't decided. */
12102 else
12104 Lisp_Object eolvalue;
12106 eolvalue = Fget (coding_system, Qeol_type);
12108 if (multibyte)
12109 *buf++ = XFASTINT (XVECTOR (val)->contents[1]);
12111 if (eol_flag)
12113 /* The EOL conversion that is normal on this system. */
12115 if (NILP (eolvalue)) /* Not yet decided. */
12116 eoltype = eol_mnemonic_undecided;
12117 else if (VECTORP (eolvalue)) /* Not yet decided. */
12118 eoltype = eol_mnemonic_undecided;
12119 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
12120 eoltype = (XFASTINT (eolvalue) == 0
12121 ? eol_mnemonic_unix
12122 : (XFASTINT (eolvalue) == 1
12123 ? eol_mnemonic_dos : eol_mnemonic_mac));
12127 if (eol_flag)
12129 /* Mention the EOL conversion if it is not the usual one. */
12130 if (STRINGP (eoltype))
12132 eol_str = XSTRING (eoltype)->data;
12133 eol_str_len = XSTRING (eoltype)->size;
12135 else if (INTEGERP (eoltype)
12136 && CHAR_VALID_P (XINT (eoltype), 0))
12138 eol_str = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
12139 eol_str_len = CHAR_STRING (XINT (eoltype), eol_str);
12141 else
12143 eol_str = invalid_eol_type;
12144 eol_str_len = sizeof (invalid_eol_type) - 1;
12146 bcopy (eol_str, buf, eol_str_len);
12147 buf += eol_str_len;
12150 return buf;
12153 /* Return a string for the output of a mode line %-spec for window W,
12154 generated by character C. PRECISION >= 0 means don't return a
12155 string longer than that value. FIELD_WIDTH > 0 means pad the
12156 string returned with spaces to that value. */
12158 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
12160 static char *
12161 decode_mode_spec (w, c, field_width, precision)
12162 struct window *w;
12163 register int c;
12164 int field_width, precision;
12166 Lisp_Object obj;
12167 struct frame *f = XFRAME (WINDOW_FRAME (w));
12168 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
12169 struct buffer *b = XBUFFER (w->buffer);
12171 obj = Qnil;
12173 switch (c)
12175 case '*':
12176 if (!NILP (b->read_only))
12177 return "%";
12178 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
12179 return "*";
12180 return "-";
12182 case '+':
12183 /* This differs from %* only for a modified read-only buffer. */
12184 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
12185 return "*";
12186 if (!NILP (b->read_only))
12187 return "%";
12188 return "-";
12190 case '&':
12191 /* This differs from %* in ignoring read-only-ness. */
12192 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
12193 return "*";
12194 return "-";
12196 case '%':
12197 return "%";
12199 case '[':
12201 int i;
12202 char *p;
12204 if (command_loop_level > 5)
12205 return "[[[... ";
12206 p = decode_mode_spec_buf;
12207 for (i = 0; i < command_loop_level; i++)
12208 *p++ = '[';
12209 *p = 0;
12210 return decode_mode_spec_buf;
12213 case ']':
12215 int i;
12216 char *p;
12218 if (command_loop_level > 5)
12219 return " ...]]]";
12220 p = decode_mode_spec_buf;
12221 for (i = 0; i < command_loop_level; i++)
12222 *p++ = ']';
12223 *p = 0;
12224 return decode_mode_spec_buf;
12227 case '-':
12229 register int i;
12231 /* Let lots_of_dashes be a string of infinite length. */
12232 if (field_width <= 0
12233 || field_width > sizeof (lots_of_dashes))
12235 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
12236 decode_mode_spec_buf[i] = '-';
12237 decode_mode_spec_buf[i] = '\0';
12238 return decode_mode_spec_buf;
12240 else
12241 return lots_of_dashes;
12244 case 'b':
12245 obj = b->name;
12246 break;
12248 case 'c':
12250 int col = current_column ();
12251 XSETFASTINT (w->column_number_displayed, col);
12252 pint2str (decode_mode_spec_buf, field_width, col);
12253 return decode_mode_spec_buf;
12256 case 'F':
12257 /* %F displays the frame name. */
12258 if (!NILP (f->title))
12259 return (char *) XSTRING (f->title)->data;
12260 if (f->explicit_name || ! FRAME_WINDOW_P (f))
12261 return (char *) XSTRING (f->name)->data;
12262 return "Emacs";
12264 case 'f':
12265 obj = b->filename;
12266 break;
12268 case 'l':
12270 int startpos = XMARKER (w->start)->charpos;
12271 int startpos_byte = marker_byte_position (w->start);
12272 int line, linepos, linepos_byte, topline;
12273 int nlines, junk;
12274 int height = XFASTINT (w->height);
12276 /* If we decided that this buffer isn't suitable for line numbers,
12277 don't forget that too fast. */
12278 if (EQ (w->base_line_pos, w->buffer))
12279 goto no_value;
12280 /* But do forget it, if the window shows a different buffer now. */
12281 else if (BUFFERP (w->base_line_pos))
12282 w->base_line_pos = Qnil;
12284 /* If the buffer is very big, don't waste time. */
12285 if (BUF_ZV (b) - BUF_BEGV (b) > line_number_display_limit)
12287 w->base_line_pos = Qnil;
12288 w->base_line_number = Qnil;
12289 goto no_value;
12292 if (!NILP (w->base_line_number)
12293 && !NILP (w->base_line_pos)
12294 && XFASTINT (w->base_line_pos) <= startpos)
12296 line = XFASTINT (w->base_line_number);
12297 linepos = XFASTINT (w->base_line_pos);
12298 linepos_byte = buf_charpos_to_bytepos (b, linepos);
12300 else
12302 line = 1;
12303 linepos = BUF_BEGV (b);
12304 linepos_byte = BUF_BEGV_BYTE (b);
12307 /* Count lines from base line to window start position. */
12308 nlines = display_count_lines (linepos, linepos_byte,
12309 startpos_byte,
12310 startpos, &junk);
12312 topline = nlines + line;
12314 /* Determine a new base line, if the old one is too close
12315 or too far away, or if we did not have one.
12316 "Too close" means it's plausible a scroll-down would
12317 go back past it. */
12318 if (startpos == BUF_BEGV (b))
12320 XSETFASTINT (w->base_line_number, topline);
12321 XSETFASTINT (w->base_line_pos, BUF_BEGV (b));
12323 else if (nlines < height + 25 || nlines > height * 3 + 50
12324 || linepos == BUF_BEGV (b))
12326 int limit = BUF_BEGV (b);
12327 int limit_byte = BUF_BEGV_BYTE (b);
12328 int position;
12329 int distance = (height * 2 + 30) * line_number_display_limit_width;
12331 if (startpos - distance > limit)
12333 limit = startpos - distance;
12334 limit_byte = CHAR_TO_BYTE (limit);
12337 nlines = display_count_lines (startpos, startpos_byte,
12338 limit_byte,
12339 - (height * 2 + 30),
12340 &position);
12341 /* If we couldn't find the lines we wanted within
12342 line_number_display_limit_width chars per line,
12343 give up on line numbers for this window. */
12344 if (position == limit_byte && limit == startpos - distance)
12346 w->base_line_pos = w->buffer;
12347 w->base_line_number = Qnil;
12348 goto no_value;
12351 XSETFASTINT (w->base_line_number, topline - nlines);
12352 XSETFASTINT (w->base_line_pos, BYTE_TO_CHAR (position));
12355 /* Now count lines from the start pos to point. */
12356 nlines = display_count_lines (startpos, startpos_byte,
12357 PT_BYTE, PT, &junk);
12359 /* Record that we did display the line number. */
12360 line_number_displayed = 1;
12362 /* Make the string to show. */
12363 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
12364 return decode_mode_spec_buf;
12365 no_value:
12367 char* p = decode_mode_spec_buf;
12368 int pad = field_width - 2;
12369 while (pad-- > 0)
12370 *p++ = ' ';
12371 *p++ = '?';
12372 *p = '?';
12373 return decode_mode_spec_buf;
12376 break;
12378 case 'm':
12379 obj = b->mode_name;
12380 break;
12382 case 'n':
12383 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
12384 return " Narrow";
12385 break;
12387 case 'p':
12389 int pos = marker_position (w->start);
12390 int total = BUF_ZV (b) - BUF_BEGV (b);
12392 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
12394 if (pos <= BUF_BEGV (b))
12395 return "All";
12396 else
12397 return "Bottom";
12399 else if (pos <= BUF_BEGV (b))
12400 return "Top";
12401 else
12403 if (total > 1000000)
12404 /* Do it differently for a large value, to avoid overflow. */
12405 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
12406 else
12407 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
12408 /* We can't normally display a 3-digit number,
12409 so get us a 2-digit number that is close. */
12410 if (total == 100)
12411 total = 99;
12412 sprintf (decode_mode_spec_buf, "%2d%%", total);
12413 return decode_mode_spec_buf;
12417 /* Display percentage of size above the bottom of the screen. */
12418 case 'P':
12420 int toppos = marker_position (w->start);
12421 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
12422 int total = BUF_ZV (b) - BUF_BEGV (b);
12424 if (botpos >= BUF_ZV (b))
12426 if (toppos <= BUF_BEGV (b))
12427 return "All";
12428 else
12429 return "Bottom";
12431 else
12433 if (total > 1000000)
12434 /* Do it differently for a large value, to avoid overflow. */
12435 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
12436 else
12437 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
12438 /* We can't normally display a 3-digit number,
12439 so get us a 2-digit number that is close. */
12440 if (total == 100)
12441 total = 99;
12442 if (toppos <= BUF_BEGV (b))
12443 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
12444 else
12445 sprintf (decode_mode_spec_buf, "%2d%%", total);
12446 return decode_mode_spec_buf;
12450 case 's':
12451 /* status of process */
12452 obj = Fget_buffer_process (w->buffer);
12453 if (NILP (obj))
12454 return "no process";
12455 #ifdef subprocesses
12456 obj = Fsymbol_name (Fprocess_status (obj));
12457 #endif
12458 break;
12460 case 't': /* indicate TEXT or BINARY */
12461 #ifdef MODE_LINE_BINARY_TEXT
12462 return MODE_LINE_BINARY_TEXT (b);
12463 #else
12464 return "T";
12465 #endif
12467 case 'z':
12468 /* coding-system (not including end-of-line format) */
12469 case 'Z':
12470 /* coding-system (including end-of-line type) */
12472 int eol_flag = (c == 'Z');
12473 char *p = decode_mode_spec_buf;
12475 if (! FRAME_WINDOW_P (f))
12477 /* No need to mention EOL here--the terminal never needs
12478 to do EOL conversion. */
12479 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
12480 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
12482 p = decode_mode_spec_coding (b->buffer_file_coding_system,
12483 p, eol_flag);
12485 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
12486 #ifdef subprocesses
12487 obj = Fget_buffer_process (Fcurrent_buffer ());
12488 if (PROCESSP (obj))
12490 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
12491 p, eol_flag);
12492 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
12493 p, eol_flag);
12495 #endif /* subprocesses */
12496 #endif /* 0 */
12497 *p = 0;
12498 return decode_mode_spec_buf;
12502 if (STRINGP (obj))
12503 return (char *) XSTRING (obj)->data;
12504 else
12505 return "";
12509 /* Count up to COUNT lines starting from START / START_BYTE.
12510 But don't go beyond LIMIT_BYTE.
12511 Return the number of lines thus found (always nonnegative).
12513 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
12515 static int
12516 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
12517 int start, start_byte, limit_byte, count;
12518 int *byte_pos_ptr;
12520 register unsigned char *cursor;
12521 unsigned char *base;
12523 register int ceiling;
12524 register unsigned char *ceiling_addr;
12525 int orig_count = count;
12527 /* If we are not in selective display mode,
12528 check only for newlines. */
12529 int selective_display = (!NILP (current_buffer->selective_display)
12530 && !INTEGERP (current_buffer->selective_display));
12532 if (count > 0)
12534 while (start_byte < limit_byte)
12536 ceiling = BUFFER_CEILING_OF (start_byte);
12537 ceiling = min (limit_byte - 1, ceiling);
12538 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
12539 base = (cursor = BYTE_POS_ADDR (start_byte));
12540 while (1)
12542 if (selective_display)
12543 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
12545 else
12546 while (*cursor != '\n' && ++cursor != ceiling_addr)
12549 if (cursor != ceiling_addr)
12551 if (--count == 0)
12553 start_byte += cursor - base + 1;
12554 *byte_pos_ptr = start_byte;
12555 return orig_count;
12557 else
12558 if (++cursor == ceiling_addr)
12559 break;
12561 else
12562 break;
12564 start_byte += cursor - base;
12567 else
12569 while (start_byte > limit_byte)
12571 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
12572 ceiling = max (limit_byte, ceiling);
12573 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
12574 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
12575 while (1)
12577 if (selective_display)
12578 while (--cursor != ceiling_addr
12579 && *cursor != '\n' && *cursor != 015)
12581 else
12582 while (--cursor != ceiling_addr && *cursor != '\n')
12585 if (cursor != ceiling_addr)
12587 if (++count == 0)
12589 start_byte += cursor - base + 1;
12590 *byte_pos_ptr = start_byte;
12591 /* When scanning backwards, we should
12592 not count the newline posterior to which we stop. */
12593 return - orig_count - 1;
12596 else
12597 break;
12599 /* Here we add 1 to compensate for the last decrement
12600 of CURSOR, which took it past the valid range. */
12601 start_byte += cursor - base + 1;
12605 *byte_pos_ptr = limit_byte;
12607 if (count < 0)
12608 return - orig_count + count;
12609 return orig_count - count;
12615 /***********************************************************************
12616 Displaying strings
12617 ***********************************************************************/
12619 /* Display a NUL-terminated string, starting with index START.
12621 If STRING is non-null, display that C string. Otherwise, the Lisp
12622 string LISP_STRING is displayed.
12624 If FACE_STRING is not nil, FACE_STRING_POS is a position in
12625 FACE_STRING. Display STRING or LISP_STRING with the face at
12626 FACE_STRING_POS in FACE_STRING:
12628 Display the string in the environment given by IT, but use the
12629 standard display table, temporarily.
12631 FIELD_WIDTH is the minimum number of output glyphs to produce.
12632 If STRING has fewer characters than FIELD_WIDTH, pad to the right
12633 with spaces. If STRING has more characters, more than FIELD_WIDTH
12634 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
12636 PRECISION is the maximum number of characters to output from
12637 STRING. PRECISION < 0 means don't truncate the string.
12639 This is roughly equivalent to printf format specifiers:
12641 FIELD_WIDTH PRECISION PRINTF
12642 ----------------------------------------
12643 -1 -1 %s
12644 -1 10 %.10s
12645 10 -1 %10s
12646 20 10 %20.10s
12648 MULTIBYTE zero means do not display multibyte chars, > 0 means do
12649 display them, and < 0 means obey the current buffer's value of
12650 enable_multibyte_characters.
12652 Value is the number of glyphs produced. */
12654 static int
12655 display_string (string, lisp_string, face_string, face_string_pos,
12656 start, it, field_width, precision, max_x, multibyte)
12657 unsigned char *string;
12658 Lisp_Object lisp_string;
12659 Lisp_Object face_string;
12660 int face_string_pos;
12661 int start;
12662 struct it *it;
12663 int field_width, precision, max_x;
12664 int multibyte;
12666 int hpos_at_start = it->hpos;
12667 int saved_face_id = it->face_id;
12668 struct glyph_row *row = it->glyph_row;
12670 /* Initialize the iterator IT for iteration over STRING beginning
12671 with index START. We assume that IT may be modified here (which
12672 means that display_line has to do something when displaying a
12673 mini-buffer prompt, which it does). */
12674 reseat_to_string (it, string, lisp_string, start,
12675 precision, field_width, multibyte);
12677 /* If displaying STRING, set up the face of the iterator
12678 from LISP_STRING, if that's given. */
12679 if (STRINGP (face_string))
12681 int endptr;
12682 struct face *face;
12684 it->face_id
12685 = face_at_string_position (it->w, face_string, face_string_pos,
12686 0, it->region_beg_charpos,
12687 it->region_end_charpos,
12688 &endptr, it->base_face_id);
12689 face = FACE_FROM_ID (it->f, it->face_id);
12690 it->face_box_p = face->box != FACE_NO_BOX;
12693 /* Set max_x to the maximum allowed X position. Don't let it go
12694 beyond the right edge of the window. */
12695 if (max_x <= 0)
12696 max_x = it->last_visible_x;
12697 else
12698 max_x = min (max_x, it->last_visible_x);
12700 /* Skip over display elements that are not visible. because IT->w is
12701 hscrolled. */
12702 if (it->current_x < it->first_visible_x)
12703 move_it_in_display_line_to (it, 100000, it->first_visible_x,
12704 MOVE_TO_POS | MOVE_TO_X);
12706 row->ascent = it->max_ascent;
12707 row->height = it->max_ascent + it->max_descent;
12708 row->phys_ascent = it->max_phys_ascent;
12709 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
12711 /* This condition is for the case that we are called with current_x
12712 past last_visible_x. */
12713 while (it->current_x < max_x)
12715 int x_before, x, n_glyphs_before, i, nglyphs;
12717 /* Get the next display element. */
12718 if (!get_next_display_element (it))
12719 break;
12721 /* Produce glyphs. */
12722 x_before = it->current_x;
12723 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
12724 PRODUCE_GLYPHS (it);
12726 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
12727 i = 0;
12728 x = x_before;
12729 while (i < nglyphs)
12731 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
12733 if (!it->truncate_lines_p
12734 && x + glyph->pixel_width > max_x)
12736 /* End of continued line or max_x reached. */
12737 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
12738 it->current_x = x;
12739 break;
12741 else if (x + glyph->pixel_width > it->first_visible_x)
12743 /* Glyph is at least partially visible. */
12744 ++it->hpos;
12745 if (x < it->first_visible_x)
12746 it->glyph_row->x = x - it->first_visible_x;
12748 else
12750 /* Glyph is off the left margin of the display area.
12751 Should not happen. */
12752 abort ();
12755 row->ascent = max (row->ascent, it->max_ascent);
12756 row->height = max (row->height, it->max_ascent + it->max_descent);
12757 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
12758 row->phys_height = max (row->phys_height,
12759 it->max_phys_ascent + it->max_phys_descent);
12760 x += glyph->pixel_width;
12761 ++i;
12764 /* Stop if max_x reached. */
12765 if (i < nglyphs)
12766 break;
12768 /* Stop at line ends. */
12769 if (ITERATOR_AT_END_OF_LINE_P (it))
12771 it->continuation_lines_width = 0;
12772 break;
12775 set_iterator_to_next (it);
12777 /* Stop if truncating at the right edge. */
12778 if (it->truncate_lines_p
12779 && it->current_x >= it->last_visible_x)
12781 /* Add truncation mark, but don't do it if the line is
12782 truncated at a padding space. */
12783 if (IT_CHARPOS (*it) < it->string_nchars)
12785 if (!FRAME_WINDOW_P (it->f))
12786 produce_special_glyphs (it, IT_TRUNCATION);
12787 it->glyph_row->truncated_on_right_p = 1;
12789 break;
12793 /* Maybe insert a truncation at the left. */
12794 if (it->first_visible_x
12795 && IT_CHARPOS (*it) > 0)
12797 if (!FRAME_WINDOW_P (it->f))
12798 insert_left_trunc_glyphs (it);
12799 it->glyph_row->truncated_on_left_p = 1;
12802 it->face_id = saved_face_id;
12804 /* Value is number of columns displayed. */
12805 return it->hpos - hpos_at_start;
12810 /* This is like a combination of memq and assq. Return 1 if PROPVAL
12811 appears as an element of LIST or as the car of an element of LIST.
12812 If PROPVAL is a list, compare each element against LIST in that
12813 way, and return 1 if any element of PROPVAL is found in LIST.
12814 Otherwise return 0. This function cannot quit. */
12817 invisible_p (propval, list)
12818 register Lisp_Object propval;
12819 Lisp_Object list;
12821 register Lisp_Object tail, proptail;
12822 for (tail = list; CONSP (tail); tail = XCDR (tail))
12824 register Lisp_Object tem;
12825 tem = XCAR (tail);
12826 if (EQ (propval, tem))
12827 return 1;
12828 if (CONSP (tem) && EQ (propval, XCAR (tem)))
12829 return 1;
12831 if (CONSP (propval))
12832 for (proptail = propval; CONSP (proptail);
12833 proptail = XCDR (proptail))
12835 Lisp_Object propelt;
12836 propelt = XCAR (proptail);
12837 for (tail = list; CONSP (tail); tail = XCDR (tail))
12839 register Lisp_Object tem;
12840 tem = XCAR (tail);
12841 if (EQ (propelt, tem))
12842 return 1;
12843 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
12844 return 1;
12847 return 0;
12851 /* Return 1 if PROPVAL appears as the car of an element of LIST and
12852 the cdr of that element is non-nil. If PROPVAL is a list, check
12853 each element of PROPVAL in that way, and the first time some
12854 element is found, return 1 if the cdr of that element is non-nil.
12855 Otherwise return 0. This function cannot quit. */
12858 invisible_ellipsis_p (propval, list)
12859 register Lisp_Object propval;
12860 Lisp_Object list;
12862 register Lisp_Object tail, proptail;
12864 for (tail = list; CONSP (tail); tail = XCDR (tail))
12866 register Lisp_Object tem;
12867 tem = XCAR (tail);
12868 if (CONSP (tem) && EQ (propval, XCAR (tem)))
12869 return ! NILP (XCDR (tem));
12872 if (CONSP (propval))
12873 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
12875 Lisp_Object propelt;
12876 propelt = XCAR (proptail);
12877 for (tail = list; CONSP (tail); tail = XCDR (tail))
12879 register Lisp_Object tem;
12880 tem = XCAR (tail);
12881 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
12882 return ! NILP (XCDR (tem));
12886 return 0;
12891 /***********************************************************************
12892 Initialization
12893 ***********************************************************************/
12895 void
12896 syms_of_xdisp ()
12898 Vwith_echo_area_save_vector = Qnil;
12899 staticpro (&Vwith_echo_area_save_vector);
12901 Vmessage_stack = Qnil;
12902 staticpro (&Vmessage_stack);
12904 Qinhibit_redisplay = intern ("inhibit-redisplay");
12905 staticpro (&Qinhibit_redisplay);
12907 #if GLYPH_DEBUG
12908 defsubr (&Sdump_glyph_matrix);
12909 defsubr (&Sdump_glyph_row);
12910 defsubr (&Sdump_tool_bar_row);
12911 defsubr (&Strace_redisplay_toggle);
12912 defsubr (&Strace_to_stderr);
12913 #endif
12915 staticpro (&Qmenu_bar_update_hook);
12916 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
12918 staticpro (&Qoverriding_terminal_local_map);
12919 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
12921 staticpro (&Qoverriding_local_map);
12922 Qoverriding_local_map = intern ("overriding-local-map");
12924 staticpro (&Qwindow_scroll_functions);
12925 Qwindow_scroll_functions = intern ("window-scroll-functions");
12927 staticpro (&Qredisplay_end_trigger_functions);
12928 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
12930 staticpro (&Qinhibit_point_motion_hooks);
12931 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
12933 QCdata = intern (":data");
12934 staticpro (&QCdata);
12935 Qdisplay = intern ("display");
12936 staticpro (&Qdisplay);
12937 Qspace_width = intern ("space-width");
12938 staticpro (&Qspace_width);
12939 Qraise = intern ("raise");
12940 staticpro (&Qraise);
12941 Qspace = intern ("space");
12942 staticpro (&Qspace);
12943 Qmargin = intern ("margin");
12944 staticpro (&Qmargin);
12945 Qleft_margin = intern ("left-margin");
12946 staticpro (&Qleft_margin);
12947 Qright_margin = intern ("right-margin");
12948 staticpro (&Qright_margin);
12949 Qalign_to = intern ("align-to");
12950 staticpro (&Qalign_to);
12951 QCalign_to = intern (":align-to");
12952 staticpro (&QCalign_to);
12953 Qrelative_width = intern ("relative-width");
12954 staticpro (&Qrelative_width);
12955 QCrelative_width = intern (":relative-width");
12956 staticpro (&QCrelative_width);
12957 QCrelative_height = intern (":relative-height");
12958 staticpro (&QCrelative_height);
12959 QCeval = intern (":eval");
12960 staticpro (&QCeval);
12961 Qwhen = intern ("when");
12962 staticpro (&Qwhen);
12963 QCfile = intern (":file");
12964 staticpro (&QCfile);
12965 Qfontified = intern ("fontified");
12966 staticpro (&Qfontified);
12967 Qfontification_functions = intern ("fontification-functions");
12968 staticpro (&Qfontification_functions);
12969 Qtrailing_whitespace = intern ("trailing-whitespace");
12970 staticpro (&Qtrailing_whitespace);
12971 Qimage = intern ("image");
12972 staticpro (&Qimage);
12974 last_arrow_position = Qnil;
12975 last_arrow_string = Qnil;
12976 staticpro (&last_arrow_position);
12977 staticpro (&last_arrow_string);
12979 echo_buffer[0] = echo_buffer[1] = Qnil;
12980 staticpro (&echo_buffer[0]);
12981 staticpro (&echo_buffer[1]);
12983 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
12984 staticpro (&echo_area_buffer[0]);
12985 staticpro (&echo_area_buffer[1]);
12987 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
12988 "Non-nil means highlight trailing whitespace.\n\
12989 The face used for trailing whitespace is `trailing-whitespace'.");
12990 Vshow_trailing_whitespace = Qnil;
12992 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
12993 "Non-nil means don't actually do any redisplay.\n\
12994 This is used for internal purposes.");
12995 Vinhibit_redisplay = Qnil;
12997 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
12998 "String (or mode line construct) included (normally) in `mode-line-format'.");
12999 Vglobal_mode_string = Qnil;
13001 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
13002 "Marker for where to display an arrow on top of the buffer text.\n\
13003 This must be the beginning of a line in order to work.\n\
13004 See also `overlay-arrow-string'.");
13005 Voverlay_arrow_position = Qnil;
13007 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
13008 "String to display as an arrow. See also `overlay-arrow-position'.");
13009 Voverlay_arrow_string = Qnil;
13011 DEFVAR_INT ("scroll-step", &scroll_step,
13012 "*The number of lines to try scrolling a window by when point moves out.\n\
13013 If that fails to bring point back on frame, point is centered instead.\n\
13014 If this is zero, point is always centered after it moves off frame.");
13016 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
13017 "*Scroll up to this many lines, to bring point back on screen.\n\
13018 A value of zero means to scroll the text to center point vertically\n\
13019 in the window.");
13020 scroll_conservatively = 0;
13022 DEFVAR_INT ("scroll-margin", &scroll_margin,
13023 "*Number of lines of margin at the top and bottom of a window.\n\
13024 Recenter the window whenever point gets within this many lines\n\
13025 of the top or bottom of the window.");
13026 scroll_margin = 0;
13028 #if GLYPH_DEBUG
13029 DEFVAR_INT ("debug-end-pos", &debug_end_pos, "Don't ask");
13030 #endif
13032 DEFVAR_BOOL ("truncate-partial-width-windows",
13033 &truncate_partial_width_windows,
13034 "*Non-nil means truncate lines in all windows less than full frame wide.");
13035 truncate_partial_width_windows = 1;
13037 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
13038 "*Non-nil means use inverse video for the mode line.");
13039 mode_line_inverse_video = 1;
13041 DEFVAR_INT ("line-number-display-limit", &line_number_display_limit,
13042 "*Maximum buffer size for which line number should be displayed.\n\
13043 If the buffer is bigger than this, the line number does not appear\n\
13044 in the mode line.");
13045 line_number_display_limit = 1000000;
13047 DEFVAR_INT ("line-number-display-limit-width", &line_number_display_limit_width,
13048 "*Maximum line width (in characters) for line number display.\n\
13049 If the average length of the lines near point is bigger than this, then the\n\
13050 line number may be omitted from the mode line.");
13051 line_number_display_limit_width = 200;
13053 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
13054 "*Non-nil means highlight region even in nonselected windows.");
13055 highlight_nonselected_windows = 0;
13057 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
13058 "Non-nil if more than one frame is visible on this display.\n\
13059 Minibuffer-only frames don't count, but iconified frames do.\n\
13060 This variable is not guaranteed to be accurate except while processing\n\
13061 `frame-title-format' and `icon-title-format'.");
13063 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
13064 "Template for displaying the title bar of visible frames.\n\
13065 \(Assuming the window manager supports this feature.)\n\
13066 This variable has the same structure as `mode-line-format' (which see),\n\
13067 and is used only on frames for which no explicit name has been set\n\
13068 \(see `modify-frame-parameters').");
13069 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
13070 "Template for displaying the title bar of an iconified frame.\n\
13071 \(Assuming the window manager supports this feature.)\n\
13072 This variable has the same structure as `mode-line-format' (which see),\n\
13073 and is used only on frames for which no explicit name has been set\n\
13074 \(see `modify-frame-parameters').");
13075 Vicon_title_format
13076 = Vframe_title_format
13077 = Fcons (intern ("multiple-frames"),
13078 Fcons (build_string ("%b"),
13079 Fcons (Fcons (build_string (""),
13080 Fcons (intern ("invocation-name"),
13081 Fcons (build_string ("@"),
13082 Fcons (intern ("system-name"),
13083 Qnil)))),
13084 Qnil)));
13086 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
13087 "Maximum number of lines to keep in the message log buffer.\n\
13088 If nil, disable message logging. If t, log messages but don't truncate\n\
13089 the buffer when it becomes large.");
13090 XSETFASTINT (Vmessage_log_max, 50);
13092 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
13093 "Functions called before redisplay, if window sizes have changed.\n\
13094 The value should be a list of functions that take one argument.\n\
13095 Just before redisplay, for each frame, if any of its windows have changed\n\
13096 size since the last redisplay, or have been split or deleted,\n\
13097 all the functions in the list are called, with the frame as argument.");
13098 Vwindow_size_change_functions = Qnil;
13100 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
13101 "List of Functions to call before redisplaying a window with scrolling.\n\
13102 Each function is called with two arguments, the window\n\
13103 and its new display-start position. Note that the value of `window-end'\n\
13104 is not valid when these functions are called.");
13105 Vwindow_scroll_functions = Qnil;
13107 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
13108 "*Non-nil means automatically resize tool-bars.\n\
13109 This increases a tool-bar's height if not all tool-bar items are visible.\n\
13110 It decreases a tool-bar's height when it would display blank lines\n\
13111 otherwise.");
13112 auto_resize_tool_bars_p = 1;
13114 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
13115 "*Non-nil means raise tool-bar buttons when the mouse moves over them.");
13116 auto_raise_tool_bar_buttons_p = 1;
13118 DEFVAR_INT ("tool-bar-button-margin", &tool_bar_button_margin,
13119 "*Margin around tool-bar buttons in pixels.");
13120 tool_bar_button_margin = 1;
13122 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
13123 "Relief thickness of tool-bar buttons.");
13124 tool_bar_button_relief = 3;
13126 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
13127 "List of functions to call to fontify regions of text.\n\
13128 Each function is called with one argument POS. Functions must\n\
13129 fontify a region starting at POS in the current buffer, and give\n\
13130 fontified regions the property `fontified'.\n\
13131 This variable automatically becomes buffer-local when set.");
13132 Vfontification_functions = Qnil;
13133 Fmake_local_variable (Qfontification_functions);
13135 DEFVAR_BOOL ("unibyte-display-via-language-environment",
13136 &unibyte_display_via_language_environment,
13137 "*Non-nil means display unibyte text according to language environment.\n\
13138 Specifically this means that unibyte non-ASCII characters\n\
13139 are displayed by converting them to the equivalent multibyte characters\n\
13140 according to the current language environment. As a result, they are\n\
13141 displayed according to the current fontset.");
13142 unibyte_display_via_language_environment = 0;
13144 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
13145 "*Maximum height for resizing mini-windows.\n\
13146 If a float, it specifies a fraction of the mini-window frame's height.\n\
13147 If an integer, it specifies a number of lines.\n\
13148 If nil, don't resize.");
13149 Vmax_mini_window_height = make_float (0.25);
13151 DEFVAR_BOOL ("cursor-in-non-selected-windows",
13152 &cursor_in_non_selected_windows,
13153 "*Non-nil means display a hollow cursor in non-selected windows.\n\
13154 Nil means don't display a cursor there.");
13155 cursor_in_non_selected_windows = 1;
13157 DEFVAR_BOOL ("automatic-hscrolling", &automatic_hscrolling_p,
13158 "*Non-nil means scroll the display automatically to make point visible.");
13159 automatic_hscrolling_p = 1;
13161 DEFVAR_LISP ("image-types", &Vimage_types,
13162 "List of supported image types.\n\
13163 Each element of the list is a symbol for a supported image type.");
13164 Vimage_types = Qnil;
13168 /* Initialize this module when Emacs starts. */
13170 void
13171 init_xdisp ()
13173 Lisp_Object root_window;
13174 struct window *mini_w;
13176 CHARPOS (this_line_start_pos) = 0;
13178 mini_w = XWINDOW (minibuf_window);
13179 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
13181 if (!noninteractive)
13183 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
13184 int i;
13186 XSETFASTINT (XWINDOW (root_window)->top, FRAME_TOP_MARGIN (f));
13187 set_window_height (root_window,
13188 FRAME_HEIGHT (f) - 1 - FRAME_TOP_MARGIN (f),
13190 XSETFASTINT (mini_w->top, FRAME_HEIGHT (f) - 1);
13191 set_window_height (minibuf_window, 1, 0);
13193 XSETFASTINT (XWINDOW (root_window)->width, FRAME_WIDTH (f));
13194 XSETFASTINT (mini_w->width, FRAME_WIDTH (f));
13196 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
13197 scratch_glyph_row.glyphs[TEXT_AREA + 1]
13198 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
13200 /* The default ellipsis glyphs `...'. */
13201 for (i = 0; i < 3; ++i)
13202 XSETFASTINT (default_invis_vector[i], '.');
13205 #ifdef HAVE_WINDOW_SYSTEM
13207 /* Allocate the buffer for frame titles. */
13208 int size = 100;
13209 frame_title_buf = (char *) xmalloc (size);
13210 frame_title_buf_end = frame_title_buf + size;
13211 frame_title_ptr = NULL;
13213 #endif /* HAVE_WINDOW_SYSTEM */